UNPKG

921 kBJavaScriptView Raw
1/**
2 * @license Paged.js v0.4.3 | MIT | https://gitlab.coko.foundation/pagedjs/pagedjs
3 */
4
5(function (global, factory) {
6 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
7 typeof define === 'function' && define.amd ? define(['exports'], factory) :
8 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Paged = {}));
9})(this, (function (exports) { 'use strict';
10
11 function getBoundingClientRect(element) {
12 if (!element) {
13 return;
14 }
15 let rect;
16 if (typeof element.getBoundingClientRect !== "undefined") {
17 rect = element.getBoundingClientRect();
18 } else {
19 let range = document.createRange();
20 range.selectNode(element);
21 rect = range.getBoundingClientRect();
22 }
23 return rect;
24 }
25
26 function getClientRects(element) {
27 if (!element) {
28 return;
29 }
30 let rect;
31 if (typeof element.getClientRects !== "undefined") {
32 rect = element.getClientRects();
33 } else {
34 let range = document.createRange();
35 range.selectNode(element);
36 rect = range.getClientRects();
37 }
38 return rect;
39 }
40
41 /**
42 * Generates a UUID
43 * based on: http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript
44 * @returns {string} uuid
45 */
46 function UUID() {
47 var d = new Date().getTime();
48 if (typeof performance !== "undefined" && typeof performance.now === "function") {
49 d += performance.now(); //use high-precision timer if available
50 }
51 return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
52 var r = (d + Math.random() * 16) % 16 | 0;
53 d = Math.floor(d / 16);
54 return (c === "x" ? r : (r & 0x3 | 0x8)).toString(16);
55 });
56 }
57
58 function attr(element, attributes) {
59 for (var i = 0; i < attributes.length; i++) {
60 if (element.hasAttribute(attributes[i])) {
61 return element.getAttribute(attributes[i]);
62 }
63 }
64 }
65
66 /* Based on by https://mths.be/cssescape v1.5.1 by @mathias | MIT license
67 * Allows # and .
68 */
69 function querySelectorEscape(value) {
70 if (arguments.length == 0) {
71 throw new TypeError("`CSS.escape` requires an argument.");
72 }
73 var string = String(value);
74
75 var length = string.length;
76 var index = -1;
77 var codeUnit;
78 var result = "";
79 var firstCodeUnit = string.charCodeAt(0);
80 while (++index < length) {
81 codeUnit = string.charCodeAt(index);
82
83
84
85 // Note: there’s no need to special-case astral symbols, surrogate
86 // pairs, or lone surrogates.
87
88 // If the character is NULL (U+0000), then the REPLACEMENT CHARACTER
89 // (U+FFFD).
90 if (codeUnit == 0x0000) {
91 result += "\uFFFD";
92 continue;
93 }
94
95 if (
96 // If the character is in the range [\1-\1F] (U+0001 to U+001F) or is
97 // U+007F, […]
98 (codeUnit >= 0x0001 && codeUnit <= 0x001F) || codeUnit == 0x007F ||
99 // If the character is the first character and is in the range [0-9]
100 // (U+0030 to U+0039), […]
101 (index == 0 && codeUnit >= 0x0030 && codeUnit <= 0x0039) ||
102 // If the character is the second character and is in the range [0-9]
103 // (U+0030 to U+0039) and the first character is a `-` (U+002D), […]
104 (
105 index == 1 &&
106 codeUnit >= 0x0030 && codeUnit <= 0x0039 &&
107 firstCodeUnit == 0x002D
108 )
109 ) {
110 // https://drafts.csswg.org/cssom/#escape-a-character-as-code-point
111 result += "\\" + codeUnit.toString(16) + " ";
112 continue;
113 }
114
115 if (
116 // If the character is the first character and is a `-` (U+002D), and
117 // there is no second character, […]
118 index == 0 &&
119 length == 1 &&
120 codeUnit == 0x002D
121 ) {
122 result += "\\" + string.charAt(index);
123 continue;
124 }
125
126 // support for period character in id
127 if (codeUnit == 0x002E) {
128 if (string.charAt(0) == "#") {
129 result += "\\.";
130 continue;
131 }
132 }
133
134
135 // If the character is not handled by one of the above rules and is
136 // greater than or equal to U+0080, is `-` (U+002D) or `_` (U+005F), or
137 // is in one of the ranges [0-9] (U+0030 to U+0039), [A-Z] (U+0041 to
138 // U+005A), or [a-z] (U+0061 to U+007A), […]
139 if (
140 codeUnit >= 0x0080 ||
141 codeUnit == 0x002D ||
142 codeUnit == 0x005F ||
143 codeUnit == 35 || // Allow #
144 codeUnit == 46 || // Allow .
145 codeUnit >= 0x0030 && codeUnit <= 0x0039 ||
146 codeUnit >= 0x0041 && codeUnit <= 0x005A ||
147 codeUnit >= 0x0061 && codeUnit <= 0x007A
148 ) {
149 // the character itself
150 result += string.charAt(index);
151 continue;
152 }
153
154 // Otherwise, the escaped character.
155 // https://drafts.csswg.org/cssom/#escape-a-character
156 result += "\\" + string.charAt(index);
157
158 }
159 return result;
160 }
161
162 /**
163 * Creates a new pending promise and provides methods to resolve or reject it.
164 * From: https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/Promise.jsm/Deferred#backwards_forwards_compatible
165 * @returns {object} defered
166 */
167 function defer() {
168 this.resolve = null;
169
170 this.reject = null;
171
172 this.id = UUID();
173
174 this.promise = new Promise((resolve, reject) => {
175 this.resolve = resolve;
176 this.reject = reject;
177 });
178 Object.freeze(this);
179 }
180
181 const requestIdleCallback = typeof window !== "undefined" && ("requestIdleCallback" in window ? window.requestIdleCallback : window.requestAnimationFrame);
182
183 function CSSValueToString(obj) {
184 return obj.value + (obj.unit || "");
185 }
186
187 function isElement(node) {
188 return node && node.nodeType === 1;
189 }
190
191 function isText(node) {
192 return node && node.nodeType === 3;
193 }
194
195 function* walk$2(start, limiter) {
196 let node = start;
197
198 while (node) {
199
200 yield node;
201
202 if (node.childNodes.length) {
203 node = node.firstChild;
204 } else if (node.nextSibling) {
205 if (limiter && node === limiter) {
206 node = undefined;
207 break;
208 }
209 node = node.nextSibling;
210 } else {
211 while (node) {
212 node = node.parentNode;
213 if (limiter && node === limiter) {
214 node = undefined;
215 break;
216 }
217 if (node && node.nextSibling) {
218 node = node.nextSibling;
219 break;
220 }
221
222 }
223 }
224 }
225 }
226
227 function nodeAfter(node, limiter) {
228 if (limiter && node === limiter) {
229 return;
230 }
231 let significantNode = nextSignificantNode(node);
232 if (significantNode) {
233 return significantNode;
234 }
235 if (node.parentNode) {
236 while ((node = node.parentNode)) {
237 if (limiter && node === limiter) {
238 return;
239 }
240 significantNode = nextSignificantNode(node);
241 if (significantNode) {
242 return significantNode;
243 }
244 }
245 }
246 }
247
248 function nodeBefore(node, limiter) {
249 if (limiter && node === limiter) {
250 return;
251 }
252 let significantNode = previousSignificantNode(node);
253 if (significantNode) {
254 return significantNode;
255 }
256 if (node.parentNode) {
257 while ((node = node.parentNode)) {
258 if (limiter && node === limiter) {
259 return;
260 }
261 significantNode = previousSignificantNode(node);
262 if (significantNode) {
263 return significantNode;
264 }
265 }
266 }
267 }
268
269 function elementAfter(node, limiter) {
270 let after = nodeAfter(node, limiter);
271
272 while (after && after.nodeType !== 1) {
273 after = nodeAfter(after, limiter);
274 }
275
276 return after;
277 }
278
279 function elementBefore(node, limiter) {
280 let before = nodeBefore(node, limiter);
281
282 while (before && before.nodeType !== 1) {
283 before = nodeBefore(before, limiter);
284 }
285
286 return before;
287 }
288
289 function displayedElementAfter(node, limiter) {
290 let after = elementAfter(node, limiter);
291
292 while (after && after.dataset.undisplayed) {
293 after = elementAfter(after, limiter);
294 }
295
296 return after;
297 }
298
299 function displayedElementBefore(node, limiter) {
300 let before = elementBefore(node, limiter);
301
302 while (before && before.dataset.undisplayed) {
303 before = elementBefore(before, limiter);
304 }
305
306 return before;
307 }
308
309 function rebuildAncestors(node) {
310 let parent, ancestor;
311 let ancestors = [];
312 let added = [];
313
314 let fragment = document.createDocumentFragment();
315
316 // Handle rowspan on table
317 if (node.nodeName === "TR") {
318 let previousRow = node.previousElementSibling;
319 let previousRowDistance = 1;
320 while (previousRow) {
321 // previous row has more columns, might indicate a rowspan.
322 if (previousRow.childElementCount > node.childElementCount) {
323 const initialColumns = Array.from(node.children);
324 while (node.firstChild) {
325 node.firstChild.remove();
326 }
327 let k = 0;
328 for (let j = 0; j < previousRow.children.length; j++) {
329 let column = previousRow.children[j];
330 if (column.rowSpan && column.rowSpan > previousRowDistance) {
331 const duplicatedColumn = column.cloneNode(true);
332 // Adjust rowspan value
333 duplicatedColumn.rowSpan = column.rowSpan - previousRowDistance;
334 // Add the column to the row
335 node.appendChild(duplicatedColumn);
336 } else {
337 // Fill the gap with the initial columns (if exists)
338 const initialColumn = initialColumns[k++];
339 // The initial column can be undefined if the newly created table has less columns than the original table
340 if (initialColumn) {
341 node.appendChild(initialColumn);
342 }
343 }
344 }
345 }
346 previousRow = previousRow.previousElementSibling;
347 previousRowDistance++;
348 }
349 }
350
351 // Gather all ancestors
352 let element = node;
353 while(element.parentNode && element.parentNode.nodeType === 1) {
354 ancestors.unshift(element.parentNode);
355 element = element.parentNode;
356 }
357
358 for (var i = 0; i < ancestors.length; i++) {
359 ancestor = ancestors[i];
360 parent = ancestor.cloneNode(false);
361
362 parent.setAttribute("data-split-from", parent.getAttribute("data-ref"));
363 // ancestor.setAttribute("data-split-to", parent.getAttribute("data-ref"));
364
365 if (parent.hasAttribute("id")) {
366 let dataID = parent.getAttribute("id");
367 parent.setAttribute("data-id", dataID);
368 parent.removeAttribute("id");
369 }
370
371 // This is handled by css :not, but also tidied up here
372 if (parent.hasAttribute("data-break-before")) {
373 parent.removeAttribute("data-break-before");
374 }
375
376 if (parent.hasAttribute("data-previous-break-after")) {
377 parent.removeAttribute("data-previous-break-after");
378 }
379
380 if (added.length) {
381 let container = added[added.length-1];
382 container.appendChild(parent);
383 } else {
384 fragment.appendChild(parent);
385 }
386 added.push(parent);
387
388 // rebuild table rows
389 if (parent.nodeName === "TD" && ancestor.parentElement.contains(ancestor)) {
390 let td = ancestor;
391 let prev = parent;
392 while ((td = td.previousElementSibling)) {
393 let sib = td.cloneNode(false);
394 parent.parentElement.insertBefore(sib, prev);
395 prev = sib;
396 }
397
398 }
399 }
400
401 added = undefined;
402 return fragment;
403 }
404 /*
405 export function split(bound, cutElement, breakAfter) {
406 let needsRemoval = [];
407 let index = indexOf(cutElement);
408
409 if (!breakAfter && index === 0) {
410 return;
411 }
412
413 if (breakAfter && index === (cutElement.parentNode.children.length - 1)) {
414 return;
415 }
416
417 // Create a fragment with rebuilt ancestors
418 let fragment = rebuildAncestors(cutElement);
419
420 // Clone cut
421 if (!breakAfter) {
422 let clone = cutElement.cloneNode(true);
423 let ref = cutElement.parentNode.getAttribute('data-ref');
424 let parent = fragment.querySelector("[data-ref='" + ref + "']");
425 parent.appendChild(clone);
426 needsRemoval.push(cutElement);
427 }
428
429 // Remove all after cut
430 let next = nodeAfter(cutElement, bound);
431 while (next) {
432 let clone = next.cloneNode(true);
433 let ref = next.parentNode.getAttribute('data-ref');
434 let parent = fragment.querySelector("[data-ref='" + ref + "']");
435 parent.appendChild(clone);
436 needsRemoval.push(next);
437 next = nodeAfter(next, bound);
438 }
439
440 // Remove originals
441 needsRemoval.forEach((node) => {
442 if (node) {
443 node.remove();
444 }
445 });
446
447 // Insert after bounds
448 bound.parentNode.insertBefore(fragment, bound.nextSibling);
449 return [bound, bound.nextSibling];
450 }
451 */
452
453 function needsBreakBefore(node) {
454 if( typeof node !== "undefined" &&
455 typeof node.dataset !== "undefined" &&
456 typeof node.dataset.breakBefore !== "undefined" &&
457 (node.dataset.breakBefore === "always" ||
458 node.dataset.breakBefore === "page" ||
459 node.dataset.breakBefore === "left" ||
460 node.dataset.breakBefore === "right" ||
461 node.dataset.breakBefore === "recto" ||
462 node.dataset.breakBefore === "verso")
463 ) {
464 return true;
465 }
466
467 return false;
468 }
469
470 function needsPreviousBreakAfter(node) {
471 if( typeof node !== "undefined" &&
472 typeof node.dataset !== "undefined" &&
473 typeof node.dataset.previousBreakAfter !== "undefined" &&
474 (node.dataset.previousBreakAfter === "always" ||
475 node.dataset.previousBreakAfter === "page" ||
476 node.dataset.previousBreakAfter === "left" ||
477 node.dataset.previousBreakAfter === "right" ||
478 node.dataset.previousBreakAfter === "recto" ||
479 node.dataset.previousBreakAfter === "verso")
480 ) {
481 return true;
482 }
483
484 return false;
485 }
486
487 function needsPageBreak(node, previousSignificantNode) {
488 if (typeof node === "undefined" || !previousSignificantNode || isIgnorable(node)) {
489 return false;
490 }
491 if (node.dataset && node.dataset.undisplayed) {
492 return false;
493 }
494 let previousSignificantNodePage = previousSignificantNode.dataset ? previousSignificantNode.dataset.page : undefined;
495 if (typeof previousSignificantNodePage === "undefined") {
496 const nodeWithNamedPage = getNodeWithNamedPage(previousSignificantNode);
497 if (nodeWithNamedPage) {
498 previousSignificantNodePage = nodeWithNamedPage.dataset.page;
499 }
500 }
501 let currentNodePage = node.dataset ? node.dataset.page : undefined;
502 if (typeof currentNodePage === "undefined") {
503 const nodeWithNamedPage = getNodeWithNamedPage(node, previousSignificantNode);
504 if (nodeWithNamedPage) {
505 currentNodePage = nodeWithNamedPage.dataset.page;
506 }
507 }
508 return currentNodePage !== previousSignificantNodePage;
509 }
510
511 function *words(node) {
512 let currentText = node.nodeValue;
513 let max = currentText.length;
514 let currentOffset = 0;
515 let currentLetter;
516
517 let range;
518 const significantWhitespaces = node.parentElement && node.parentElement.nodeName === "PRE";
519
520 while (currentOffset < max) {
521 currentLetter = currentText[currentOffset];
522 if (/^[\S\u202F\u00A0]$/.test(currentLetter) || significantWhitespaces) {
523 if (!range) {
524 range = document.createRange();
525 range.setStart(node, currentOffset);
526 }
527 } else {
528 if (range) {
529 range.setEnd(node, currentOffset);
530 yield range;
531 range = undefined;
532 }
533 }
534
535 currentOffset += 1;
536 }
537
538 if (range) {
539 range.setEnd(node, currentOffset);
540 yield range;
541 }
542 }
543
544 function *letters(wordRange) {
545 let currentText = wordRange.startContainer;
546 let max = currentText.length;
547 let currentOffset = wordRange.startOffset;
548 // let currentLetter;
549
550 let range;
551
552 while(currentOffset < max) {
553 // currentLetter = currentText[currentOffset];
554 range = document.createRange();
555 range.setStart(currentText, currentOffset);
556 range.setEnd(currentText, currentOffset+1);
557
558 yield range;
559
560 currentOffset += 1;
561 }
562 }
563
564 function isContainer(node) {
565 let container;
566
567 if (typeof node.tagName === "undefined") {
568 return true;
569 }
570
571 if (node.style && node.style.display === "none") {
572 return false;
573 }
574
575 switch (node.tagName) {
576 // Inline
577 case "A":
578 case "ABBR":
579 case "ACRONYM":
580 case "B":
581 case "BDO":
582 case "BIG":
583 case "BR":
584 case "BUTTON":
585 case "CITE":
586 case "CODE":
587 case "DFN":
588 case "EM":
589 case "I":
590 case "IMG":
591 case "INPUT":
592 case "KBD":
593 case "LABEL":
594 case "MAP":
595 case "OBJECT":
596 case "Q":
597 case "SAMP":
598 case "SCRIPT":
599 case "SELECT":
600 case "SMALL":
601 case "SPAN":
602 case "STRONG":
603 case "SUB":
604 case "SUP":
605 case "TEXTAREA":
606 case "TIME":
607 case "TT":
608 case "VAR":
609 case "P":
610 case "H1":
611 case "H2":
612 case "H3":
613 case "H4":
614 case "H5":
615 case "H6":
616 case "FIGCAPTION":
617 case "BLOCKQUOTE":
618 case "PRE":
619 case "LI":
620 case "TD":
621 case "DT":
622 case "DD":
623 case "VIDEO":
624 case "CANVAS":
625 container = false;
626 break;
627 default:
628 container = true;
629 }
630
631 return container;
632 }
633
634 function cloneNode(n, deep=false) {
635 return n.cloneNode(deep);
636 }
637
638 function findElement(node, doc, forceQuery) {
639 const ref = node.getAttribute("data-ref");
640 return findRef(ref, doc, forceQuery);
641 }
642
643 function findRef(ref, doc, forceQuery) {
644 if (!forceQuery && doc.indexOfRefs && doc.indexOfRefs[ref]) {
645 return doc.indexOfRefs[ref];
646 } else {
647 return doc.querySelector(`[data-ref='${ref}']`);
648 }
649 }
650
651 function validNode(node) {
652 if (isText(node)) {
653 return true;
654 }
655
656 if (isElement(node) && node.dataset.ref) {
657 return true;
658 }
659
660 return false;
661 }
662
663 function prevValidNode(node) {
664 while (!validNode(node)) {
665 if (node.previousSibling) {
666 node = node.previousSibling;
667 } else {
668 node = node.parentNode;
669 }
670
671 if (!node) {
672 break;
673 }
674 }
675
676 return node;
677 }
678
679
680 function indexOf$2(node) {
681 let parent = node.parentNode;
682 if (!parent) {
683 return 0;
684 }
685 return Array.prototype.indexOf.call(parent.childNodes, node);
686 }
687
688 function child(node, index) {
689 return node.childNodes[index];
690 }
691
692 function hasContent(node) {
693 if (isElement(node)) {
694 return true;
695 } else if (isText(node) &&
696 node.textContent.trim().length) {
697 return true;
698 }
699 return false;
700 }
701
702 function indexOfTextNode(node, parent) {
703 if (!isText(node)) {
704 return -1;
705 }
706 let nodeTextContent = node.textContent;
707 let child;
708 let index = -1;
709 for (var i = 0; i < parent.childNodes.length; i++) {
710 child = parent.childNodes[i];
711 if (child.nodeType === 3) {
712 let text = parent.childNodes[i].textContent;
713 if (text.includes(nodeTextContent)) {
714 index = i;
715 break;
716 }
717 }
718 }
719
720 return index;
721 }
722
723
724 /**
725 * Throughout, whitespace is defined as one of the characters
726 * "\t" TAB \u0009
727 * "\n" LF \u000A
728 * "\r" CR \u000D
729 * " " SPC \u0020
730 *
731 * This does not use Javascript's "\s" because that includes non-breaking
732 * spaces (and also some other characters).
733 */
734
735 /**
736 * Determine if a node should be ignored by the iterator functions.
737 * taken from https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Whitespace#Whitespace_helper_functions
738 *
739 * @param {Node} node An object implementing the DOM1 |Node| interface.
740 * @return {boolean} true if the node is:
741 * 1) A |Text| node that is all whitespace
742 * 2) A |Comment| node
743 * and otherwise false.
744 */
745 function isIgnorable(node) {
746 return (node.nodeType === 8) || // A comment node
747 ((node.nodeType === 3) && isAllWhitespace(node)); // a text node, all whitespace
748 }
749
750 /**
751 * Determine whether a node's text content is entirely whitespace.
752 *
753 * @param {Node} node A node implementing the |CharacterData| interface (i.e., a |Text|, |Comment|, or |CDATASection| node
754 * @return {boolean} true if all of the text content of |nod| is whitespace, otherwise false.
755 */
756 function isAllWhitespace(node) {
757 return !(/[^\t\n\r ]/.test(node.textContent));
758 }
759
760 /**
761 * Version of |previousSibling| that skips nodes that are entirely
762 * whitespace or comments. (Normally |previousSibling| is a property
763 * of all DOM nodes that gives the sibling node, the node that is
764 * a child of the same parent, that occurs immediately before the
765 * reference node.)
766 *
767 * @param {ChildNode} sib The reference node.
768 * @return {Node|null} Either:
769 * 1) The closest previous sibling to |sib| that is not ignorable according to |is_ignorable|, or
770 * 2) null if no such node exists.
771 */
772 function previousSignificantNode(sib) {
773 while ((sib = sib.previousSibling)) {
774 if (!isIgnorable(sib)) return sib;
775 }
776 return null;
777 }
778
779 function getNodeWithNamedPage(node, limiter) {
780 if (node && node.dataset && node.dataset.page) {
781 return node;
782 }
783 if (node.parentNode) {
784 while ((node = node.parentNode)) {
785 if (limiter && node === limiter) {
786 return;
787 }
788 if (node.dataset && node.dataset.page) {
789 return node;
790 }
791 }
792 }
793 return null;
794 }
795
796 function breakInsideAvoidParentNode(node) {
797 while ((node = node.parentNode)) {
798 if (node && node.dataset && node.dataset.breakInside === "avoid") {
799 return node;
800 }
801 }
802 return null;
803 }
804
805 /**
806 * Find a parent with a given node name.
807 * @param {Node} node - initial Node
808 * @param {string} nodeName - node name (eg. "TD", "TABLE", "STRONG"...)
809 * @param {Node} limiter - go up to the parent until there's no more parent or the current node is equals to the limiter
810 * @returns {Node|undefined} - Either:
811 * 1) The closest parent for a the given node name, or
812 * 2) undefined if no such node exists.
813 */
814 function parentOf(node, nodeName, limiter) {
815 if (limiter && node === limiter) {
816 return;
817 }
818 if (node.parentNode) {
819 while ((node = node.parentNode)) {
820 if (limiter && node === limiter) {
821 return;
822 }
823 if (node.nodeName === nodeName) {
824 return node;
825 }
826 }
827 }
828 }
829
830 /**
831 * Version of |nextSibling| that skips nodes that are entirely
832 * whitespace or comments.
833 *
834 * @param {ChildNode} sib The reference node.
835 * @return {Node|null} Either:
836 * 1) The closest next sibling to |sib| that is not ignorable according to |is_ignorable|, or
837 * 2) null if no such node exists.
838 */
839 function nextSignificantNode(sib) {
840 while ((sib = sib.nextSibling)) {
841 if (!isIgnorable(sib)) return sib;
842 }
843 return null;
844 }
845
846 function filterTree(content, func, what) {
847 const treeWalker = document.createTreeWalker(
848 content || this.dom,
849 what || NodeFilter.SHOW_ALL,
850 func ? { acceptNode: func } : null,
851 false
852 );
853
854 let node;
855 let current;
856 node = treeWalker.nextNode();
857 while(node) {
858 current = node;
859 node = treeWalker.nextNode();
860 current.parentNode.removeChild(current);
861 }
862 }
863
864 /**
865 * BreakToken
866 * @class
867 */
868 class BreakToken {
869
870 constructor(node, offset) {
871 this.node = node;
872 this.offset = offset;
873 }
874
875 equals(otherBreakToken) {
876 if (!otherBreakToken) {
877 return false;
878 }
879 if (this["node"] && otherBreakToken["node"] &&
880 this["node"] !== otherBreakToken["node"]) {
881 return false;
882 }
883 if (this["offset"] && otherBreakToken["offset"] &&
884 this["offset"] !== otherBreakToken["offset"]) {
885 return false;
886 }
887 return true;
888 }
889
890 toJSON(hash) {
891 let node;
892 let index = 0;
893 if (!this.node) {
894 return {};
895 }
896 if (isElement(this.node) && this.node.dataset.ref) {
897 node = this.node.dataset.ref;
898 } else if (hash) {
899 node = this.node.parentElement.dataset.ref;
900 }
901
902 if (this.node.parentElement) {
903 const children = Array.from(this.node.parentElement.childNodes);
904 index = children.indexOf(this.node);
905 }
906
907 return JSON.stringify({
908 "node": node,
909 "index" : index,
910 "offset": this.offset
911 });
912 }
913
914 }
915
916 /**
917 * Render result.
918 * @class
919 */
920 class RenderResult {
921
922 constructor(breakToken, error) {
923 this.breakToken = breakToken;
924 this.error = error;
925 }
926 }
927
928 class OverflowContentError extends Error {
929 constructor(message, items) {
930 super(message);
931 this.items = items;
932 }
933 }
934
935 function getDefaultExportFromCjs (x) {
936 return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
937 }
938
939 var eventEmitter = {exports: {}};
940
941 var d$2 = {exports: {}};
942
943 var isImplemented$6 = function () {
944 var assign = Object.assign, obj;
945 if (typeof assign !== "function") return false;
946 obj = { foo: "raz" };
947 assign(obj, { bar: "dwa" }, { trzy: "trzy" });
948 return (obj.foo + obj.bar + obj.trzy) === "razdwatrzy";
949 };
950
951 var isImplemented$5;
952 var hasRequiredIsImplemented$1;
953
954 function requireIsImplemented$1 () {
955 if (hasRequiredIsImplemented$1) return isImplemented$5;
956 hasRequiredIsImplemented$1 = 1;
957
958 isImplemented$5 = function () {
959 try {
960 Object.keys("primitive");
961 return true;
962 } catch (e) {
963 return false;
964 }
965 };
966 return isImplemented$5;
967 }
968
969 // eslint-disable-next-line no-empty-function
970 var noop$4 = function () {};
971
972 var _undefined = noop$4(); // Support ES3 engines
973
974 var isValue$3 = function (val) {
975 return (val !== _undefined) && (val !== null);
976 };
977
978 var shim$5;
979 var hasRequiredShim$5;
980
981 function requireShim$5 () {
982 if (hasRequiredShim$5) return shim$5;
983 hasRequiredShim$5 = 1;
984
985 var isValue = isValue$3;
986
987 var keys = Object.keys;
988
989 shim$5 = function (object) {
990 return keys(isValue(object) ? Object(object) : object);
991 };
992 return shim$5;
993 }
994
995 var keys;
996 var hasRequiredKeys;
997
998 function requireKeys () {
999 if (hasRequiredKeys) return keys;
1000 hasRequiredKeys = 1;
1001
1002 keys = requireIsImplemented$1()()
1003 ? Object.keys
1004 : requireShim$5();
1005 return keys;
1006 }
1007
1008 var isValue$2 = isValue$3;
1009
1010 var validValue = function (value) {
1011 if (!isValue$2(value)) throw new TypeError("Cannot use null or undefined");
1012 return value;
1013 };
1014
1015 var shim$4;
1016 var hasRequiredShim$4;
1017
1018 function requireShim$4 () {
1019 if (hasRequiredShim$4) return shim$4;
1020 hasRequiredShim$4 = 1;
1021
1022 var keys = requireKeys()
1023 , value = validValue
1024 , max = Math.max;
1025
1026 shim$4 = function (dest, src /*, …srcn*/) {
1027 var error, i, length = max(arguments.length, 2), assign;
1028 dest = Object(value(dest));
1029 assign = function (key) {
1030 try {
1031 dest[key] = src[key];
1032 } catch (e) {
1033 if (!error) error = e;
1034 }
1035 };
1036 for (i = 1; i < length; ++i) {
1037 src = arguments[i];
1038 keys(src).forEach(assign);
1039 }
1040 if (error !== undefined) throw error;
1041 return dest;
1042 };
1043 return shim$4;
1044 }
1045
1046 var assign$2 = isImplemented$6()
1047 ? Object.assign
1048 : requireShim$4();
1049
1050 var isValue$1 = isValue$3;
1051
1052 var forEach$1 = Array.prototype.forEach, create$5 = Object.create;
1053
1054 var process = function (src, obj) {
1055 var key;
1056 for (key in src) obj[key] = src[key];
1057 };
1058
1059 // eslint-disable-next-line no-unused-vars
1060 var normalizeOptions = function (opts1 /*, …options*/) {
1061 var result = create$5(null);
1062 forEach$1.call(arguments, function (options) {
1063 if (!isValue$1(options)) return;
1064 process(Object(options), result);
1065 });
1066 return result;
1067 };
1068
1069 var isCallable$1 = function (obj) {
1070 return typeof obj === "function";
1071 };
1072
1073 var str = "razdwatrzy";
1074
1075 var isImplemented$4 = function () {
1076 if (typeof str.contains !== "function") return false;
1077 return (str.contains("dwa") === true) && (str.contains("foo") === false);
1078 };
1079
1080 var shim$3;
1081 var hasRequiredShim$3;
1082
1083 function requireShim$3 () {
1084 if (hasRequiredShim$3) return shim$3;
1085 hasRequiredShim$3 = 1;
1086
1087 var indexOf = String.prototype.indexOf;
1088
1089 shim$3 = function (searchString/*, position*/) {
1090 return indexOf.call(this, searchString, arguments[1]) > -1;
1091 };
1092 return shim$3;
1093 }
1094
1095 var contains$1 = isImplemented$4()
1096 ? String.prototype.contains
1097 : requireShim$3();
1098
1099 var assign$1 = assign$2
1100 , normalizeOpts = normalizeOptions
1101 , isCallable = isCallable$1
1102 , contains = contains$1
1103
1104 , d$1;
1105
1106 d$1 = d$2.exports = function (dscr, value/*, options*/) {
1107 var c, e, w, options, desc;
1108 if ((arguments.length < 2) || (typeof dscr !== 'string')) {
1109 options = value;
1110 value = dscr;
1111 dscr = null;
1112 } else {
1113 options = arguments[2];
1114 }
1115 if (dscr == null) {
1116 c = w = true;
1117 e = false;
1118 } else {
1119 c = contains.call(dscr, 'c');
1120 e = contains.call(dscr, 'e');
1121 w = contains.call(dscr, 'w');
1122 }
1123
1124 desc = { value: value, configurable: c, enumerable: e, writable: w };
1125 return !options ? desc : assign$1(normalizeOpts(options), desc);
1126 };
1127
1128 d$1.gs = function (dscr, get, set/*, options*/) {
1129 var c, e, options, desc;
1130 if (typeof dscr !== 'string') {
1131 options = set;
1132 set = get;
1133 get = dscr;
1134 dscr = null;
1135 } else {
1136 options = arguments[3];
1137 }
1138 if (get == null) {
1139 get = undefined;
1140 } else if (!isCallable(get)) {
1141 options = get;
1142 get = set = undefined;
1143 } else if (set == null) {
1144 set = undefined;
1145 } else if (!isCallable(set)) {
1146 options = set;
1147 set = undefined;
1148 }
1149 if (dscr == null) {
1150 c = true;
1151 e = false;
1152 } else {
1153 c = contains.call(dscr, 'c');
1154 e = contains.call(dscr, 'e');
1155 }
1156
1157 desc = { get: get, set: set, configurable: c, enumerable: e };
1158 return !options ? desc : assign$1(normalizeOpts(options), desc);
1159 };
1160
1161 var dExports = d$2.exports;
1162
1163 var validCallable = function (fn) {
1164 if (typeof fn !== "function") throw new TypeError(fn + " is not a function");
1165 return fn;
1166 };
1167
1168 (function (module, exports) {
1169
1170 var d = dExports
1171 , callable = validCallable
1172
1173 , apply = Function.prototype.apply, call = Function.prototype.call
1174 , create = Object.create, defineProperty = Object.defineProperty
1175 , defineProperties = Object.defineProperties
1176 , hasOwnProperty = Object.prototype.hasOwnProperty
1177 , descriptor = { configurable: true, enumerable: false, writable: true }
1178
1179 , on, once, off, emit, methods, descriptors, base;
1180
1181 on = function (type, listener) {
1182 var data;
1183
1184 callable(listener);
1185
1186 if (!hasOwnProperty.call(this, '__ee__')) {
1187 data = descriptor.value = create(null);
1188 defineProperty(this, '__ee__', descriptor);
1189 descriptor.value = null;
1190 } else {
1191 data = this.__ee__;
1192 }
1193 if (!data[type]) data[type] = listener;
1194 else if (typeof data[type] === 'object') data[type].push(listener);
1195 else data[type] = [data[type], listener];
1196
1197 return this;
1198 };
1199
1200 once = function (type, listener) {
1201 var once, self;
1202
1203 callable(listener);
1204 self = this;
1205 on.call(this, type, once = function () {
1206 off.call(self, type, once);
1207 apply.call(listener, this, arguments);
1208 });
1209
1210 once.__eeOnceListener__ = listener;
1211 return this;
1212 };
1213
1214 off = function (type, listener) {
1215 var data, listeners, candidate, i;
1216
1217 callable(listener);
1218
1219 if (!hasOwnProperty.call(this, '__ee__')) return this;
1220 data = this.__ee__;
1221 if (!data[type]) return this;
1222 listeners = data[type];
1223
1224 if (typeof listeners === 'object') {
1225 for (i = 0; (candidate = listeners[i]); ++i) {
1226 if ((candidate === listener) ||
1227 (candidate.__eeOnceListener__ === listener)) {
1228 if (listeners.length === 2) data[type] = listeners[i ? 0 : 1];
1229 else listeners.splice(i, 1);
1230 }
1231 }
1232 } else {
1233 if ((listeners === listener) ||
1234 (listeners.__eeOnceListener__ === listener)) {
1235 delete data[type];
1236 }
1237 }
1238
1239 return this;
1240 };
1241
1242 emit = function (type) {
1243 var i, l, listener, listeners, args;
1244
1245 if (!hasOwnProperty.call(this, '__ee__')) return;
1246 listeners = this.__ee__[type];
1247 if (!listeners) return;
1248
1249 if (typeof listeners === 'object') {
1250 l = arguments.length;
1251 args = new Array(l - 1);
1252 for (i = 1; i < l; ++i) args[i - 1] = arguments[i];
1253
1254 listeners = listeners.slice();
1255 for (i = 0; (listener = listeners[i]); ++i) {
1256 apply.call(listener, this, args);
1257 }
1258 } else {
1259 switch (arguments.length) {
1260 case 1:
1261 call.call(listeners, this);
1262 break;
1263 case 2:
1264 call.call(listeners, this, arguments[1]);
1265 break;
1266 case 3:
1267 call.call(listeners, this, arguments[1], arguments[2]);
1268 break;
1269 default:
1270 l = arguments.length;
1271 args = new Array(l - 1);
1272 for (i = 1; i < l; ++i) {
1273 args[i - 1] = arguments[i];
1274 }
1275 apply.call(listeners, this, args);
1276 }
1277 }
1278 };
1279
1280 methods = {
1281 on: on,
1282 once: once,
1283 off: off,
1284 emit: emit
1285 };
1286
1287 descriptors = {
1288 on: d(on),
1289 once: d(once),
1290 off: d(off),
1291 emit: d(emit)
1292 };
1293
1294 base = defineProperties({}, descriptors);
1295
1296 module.exports = exports = function (o) {
1297 return (o == null) ? create(base) : defineProperties(Object(o), descriptors);
1298 };
1299 exports.methods = methods;
1300 } (eventEmitter, eventEmitter.exports));
1301
1302 var eventEmitterExports = eventEmitter.exports;
1303 var EventEmitter = /*@__PURE__*/getDefaultExportFromCjs(eventEmitterExports);
1304
1305 /**
1306 * Hooks allow for injecting functions that must all complete in order before finishing
1307 * They will execute in parallel but all must finish before continuing
1308 * Functions may return a promise if they are asycn.
1309 * From epubjs/src/utils/hooks
1310 * @param {any} context scope of this
1311 * @example this.content = new Hook(this);
1312 */
1313 class Hook {
1314 constructor(context){
1315 this.context = context || this;
1316 this.hooks = [];
1317 }
1318
1319 /**
1320 * Adds a function to be run before a hook completes
1321 * @example this.content.register(function(){...});
1322 * @return {undefined} void
1323 */
1324 register(){
1325 for(var i = 0; i < arguments.length; ++i) {
1326 if (typeof arguments[i] === "function") {
1327 this.hooks.push(arguments[i]);
1328 } else {
1329 // unpack array
1330 for(var j = 0; j < arguments[i].length; ++j) {
1331 this.hooks.push(arguments[i][j]);
1332 }
1333 }
1334 }
1335 }
1336
1337 /**
1338 * Triggers a hook to run all functions
1339 * @example this.content.trigger(args).then(function(){...});
1340 * @return {Promise} results
1341 */
1342 trigger(){
1343 var args = arguments;
1344 var context = this.context;
1345 var promises = [];
1346
1347 this.hooks.forEach(function(task) {
1348 var executing = task.apply(context, args);
1349
1350 if(executing && typeof executing["then"] === "function") {
1351 // Task is a function that returns a promise
1352 promises.push(executing);
1353 } else {
1354 // Otherwise Task resolves immediately, add resolved promise with result
1355 promises.push(new Promise((resolve, reject) => {
1356 resolve(executing);
1357 }));
1358 }
1359 });
1360
1361
1362 return Promise.all(promises);
1363 }
1364
1365 /**
1366 * Triggers a hook to run all functions synchronously
1367 * @example this.content.trigger(args).then(function(){...});
1368 * @return {Array} results
1369 */
1370 triggerSync(){
1371 var args = arguments;
1372 var context = this.context;
1373 var results = [];
1374
1375 this.hooks.forEach(function(task) {
1376 var executing = task.apply(context, args);
1377
1378 results.push(executing);
1379 });
1380
1381
1382 return results;
1383 }
1384
1385 // Adds a function to be run before a hook completes
1386 list(){
1387 return this.hooks;
1388 }
1389
1390 clear(){
1391 return this.hooks = [];
1392 }
1393 }
1394
1395 const MAX_CHARS_PER_BREAK = 1500;
1396
1397 /**
1398 * Layout
1399 * @class
1400 */
1401 class Layout {
1402
1403 constructor(element, hooks, options) {
1404 this.element = element;
1405
1406 this.bounds = this.element.getBoundingClientRect();
1407 this.parentBounds = this.element.offsetParent.getBoundingClientRect();
1408 let gap = parseFloat(window.getComputedStyle(this.element).columnGap);
1409
1410 if (gap) {
1411 let leftMargin = this.bounds.left - this.parentBounds.left;
1412 this.gap = gap - leftMargin;
1413 } else {
1414 this.gap = 0;
1415 }
1416
1417 if (hooks) {
1418 this.hooks = hooks;
1419 } else {
1420 this.hooks = {};
1421 this.hooks.onPageLayout = new Hook();
1422 this.hooks.layout = new Hook();
1423 this.hooks.renderNode = new Hook();
1424 this.hooks.layoutNode = new Hook();
1425 this.hooks.beforeOverflow = new Hook();
1426 this.hooks.onOverflow = new Hook();
1427 this.hooks.afterOverflowRemoved = new Hook();
1428 this.hooks.onBreakToken = new Hook();
1429 this.hooks.beforeRenderResult = new Hook();
1430 }
1431
1432 this.settings = options || {};
1433
1434 this.maxChars = this.settings.maxChars || MAX_CHARS_PER_BREAK;
1435 this.forceRenderBreak = false;
1436 }
1437
1438 async renderTo(wrapper, source, breakToken, bounds = this.bounds) {
1439 let start = this.getStart(source, breakToken);
1440 let walker = walk$2(start, source);
1441
1442 let node;
1443 let prevNode;
1444 let done;
1445 let next;
1446
1447 let hasRenderedContent = false;
1448 let newBreakToken;
1449
1450 let length = 0;
1451
1452 let prevBreakToken = breakToken || new BreakToken(start);
1453
1454 this.hooks && this.hooks.onPageLayout.trigger(wrapper, prevBreakToken, this);
1455
1456 while (!done && !newBreakToken) {
1457 next = walker.next();
1458 prevNode = node;
1459 node = next.value;
1460 done = next.done;
1461
1462 if (!node) {
1463 this.hooks && this.hooks.layout.trigger(wrapper, this);
1464
1465 let imgs = wrapper.querySelectorAll("img");
1466 if (imgs.length) {
1467 await this.waitForImages(imgs);
1468 }
1469
1470 newBreakToken = this.findBreakToken(wrapper, source, bounds, prevBreakToken);
1471
1472 if (newBreakToken && newBreakToken.equals(prevBreakToken)) {
1473 console.warn("Unable to layout item: ", prevNode);
1474 this.hooks && this.hooks.beforeRenderResult.trigger(undefined, wrapper, this);
1475 return new RenderResult(undefined, new OverflowContentError("Unable to layout item", [prevNode]));
1476 }
1477
1478 this.rebuildTableFromBreakToken(newBreakToken, wrapper);
1479
1480 this.hooks && this.hooks.beforeRenderResult.trigger(newBreakToken, wrapper, this);
1481 return new RenderResult(newBreakToken);
1482 }
1483
1484 this.hooks && this.hooks.layoutNode.trigger(node);
1485
1486 // Check if the rendered element has a break set
1487 if (hasRenderedContent && this.shouldBreak(node, start)) {
1488 this.hooks && this.hooks.layout.trigger(wrapper, this);
1489
1490 let imgs = wrapper.querySelectorAll("img");
1491 if (imgs.length) {
1492 await this.waitForImages(imgs);
1493 }
1494
1495 newBreakToken = this.findBreakToken(wrapper, source, bounds, prevBreakToken);
1496
1497 if (!newBreakToken) {
1498 newBreakToken = this.breakAt(node);
1499 } else {
1500 this.rebuildTableFromBreakToken(newBreakToken, wrapper);
1501 }
1502
1503 if (newBreakToken && newBreakToken.equals(prevBreakToken)) {
1504 console.warn("Unable to layout item: ", node);
1505 let after = newBreakToken.node && nodeAfter(newBreakToken.node);
1506 if (after) {
1507 newBreakToken = new BreakToken(after);
1508 } else {
1509 return new RenderResult(undefined, new OverflowContentError("Unable to layout item", [node]));
1510 }
1511 }
1512
1513 length = 0;
1514
1515 break;
1516 }
1517
1518 if (node.dataset && node.dataset.page) {
1519 let named = node.dataset.page;
1520 let page = this.element.closest(".pagedjs_page");
1521 page.classList.add("pagedjs_named_page");
1522 page.classList.add("pagedjs_" + named + "_page");
1523
1524 if (!node.dataset.splitFrom) {
1525 page.classList.add("pagedjs_" + named + "_first_page");
1526 }
1527 }
1528
1529 // Should the Node be a shallow or deep clone
1530 let shallow = isContainer(node);
1531
1532 let rendered = this.append(node, wrapper, breakToken, shallow);
1533
1534 length += rendered.textContent.length;
1535
1536 // Check if layout has content yet
1537 if (!hasRenderedContent) {
1538 hasRenderedContent = hasContent(node);
1539 }
1540
1541 // Skip to the next node if a deep clone was rendered
1542 if (!shallow) {
1543 walker = walk$2(nodeAfter(node, source), source);
1544 }
1545
1546 if (this.forceRenderBreak) {
1547 this.hooks && this.hooks.layout.trigger(wrapper, this);
1548
1549 newBreakToken = this.findBreakToken(wrapper, source, bounds, prevBreakToken);
1550
1551 if (!newBreakToken) {
1552 newBreakToken = this.breakAt(node);
1553 } else {
1554 this.rebuildTableFromBreakToken(newBreakToken, wrapper);
1555 }
1556
1557 length = 0;
1558 this.forceRenderBreak = false;
1559
1560 break;
1561 }
1562
1563 // Only check x characters
1564 if (length >= this.maxChars) {
1565
1566 this.hooks && this.hooks.layout.trigger(wrapper, this);
1567
1568 let imgs = wrapper.querySelectorAll("img");
1569 if (imgs.length) {
1570 await this.waitForImages(imgs);
1571 }
1572
1573 newBreakToken = this.findBreakToken(wrapper, source, bounds, prevBreakToken);
1574
1575 if (newBreakToken) {
1576 length = 0;
1577 this.rebuildTableFromBreakToken(newBreakToken, wrapper);
1578 }
1579
1580 if (newBreakToken && newBreakToken.equals(prevBreakToken)) {
1581 console.warn("Unable to layout item: ", node);
1582 let after = newBreakToken.node && nodeAfter(newBreakToken.node);
1583 if (after) {
1584 newBreakToken = new BreakToken(after);
1585 } else {
1586 this.hooks && this.hooks.beforeRenderResult.trigger(undefined, wrapper, this);
1587 return new RenderResult(undefined, new OverflowContentError("Unable to layout item", [node]));
1588 }
1589 }
1590 }
1591
1592 }
1593
1594 this.hooks && this.hooks.beforeRenderResult.trigger(newBreakToken, wrapper, this);
1595 return new RenderResult(newBreakToken);
1596 }
1597
1598 breakAt(node, offset = 0) {
1599 let newBreakToken = new BreakToken(
1600 node,
1601 offset
1602 );
1603 let breakHooks = this.hooks.onBreakToken.triggerSync(newBreakToken, undefined, node, this);
1604 breakHooks.forEach((newToken) => {
1605 if (typeof newToken != "undefined") {
1606 newBreakToken = newToken;
1607 }
1608 });
1609
1610 return newBreakToken;
1611 }
1612
1613 shouldBreak(node, limiter) {
1614 let previousNode = nodeBefore(node, limiter);
1615 let parentNode = node.parentNode;
1616 let parentBreakBefore = needsBreakBefore(node) && parentNode && !previousNode && needsBreakBefore(parentNode);
1617 let doubleBreakBefore;
1618
1619 if (parentBreakBefore) {
1620 doubleBreakBefore = node.dataset.breakBefore === parentNode.dataset.breakBefore;
1621 }
1622
1623 return !doubleBreakBefore && needsBreakBefore(node) || needsPreviousBreakAfter(node) || needsPageBreak(node, previousNode);
1624 }
1625
1626 forceBreak() {
1627 this.forceRenderBreak = true;
1628 }
1629
1630 getStart(source, breakToken) {
1631 let start;
1632 let node = breakToken && breakToken.node;
1633
1634 if (node) {
1635 start = node;
1636 } else {
1637 start = source.firstChild;
1638 }
1639
1640 return start;
1641 }
1642
1643 append(node, dest, breakToken, shallow = true, rebuild = true) {
1644
1645 let clone = cloneNode(node, !shallow);
1646
1647 if (node.parentNode && isElement(node.parentNode)) {
1648 let parent = findElement(node.parentNode, dest);
1649 // Rebuild chain
1650 if (parent) {
1651 parent.appendChild(clone);
1652 } else if (rebuild) {
1653 let fragment = rebuildAncestors(node);
1654 parent = findElement(node.parentNode, fragment);
1655 if (!parent) {
1656 dest.appendChild(clone);
1657 } else if (breakToken && isText(breakToken.node) && breakToken.offset > 0) {
1658 clone.textContent = clone.textContent.substring(breakToken.offset);
1659 parent.appendChild(clone);
1660 } else {
1661 parent.appendChild(clone);
1662 }
1663
1664 dest.appendChild(fragment);
1665 } else {
1666 dest.appendChild(clone);
1667 }
1668
1669
1670 } else {
1671 dest.appendChild(clone);
1672 }
1673
1674 if (clone.dataset && clone.dataset.ref) {
1675 if (!dest.indexOfRefs) {
1676 dest.indexOfRefs = {};
1677 }
1678 dest.indexOfRefs[clone.dataset.ref] = clone;
1679 }
1680
1681 let nodeHooks = this.hooks.renderNode.triggerSync(clone, node, this);
1682 nodeHooks.forEach((newNode) => {
1683 if (typeof newNode != "undefined") {
1684 clone = newNode;
1685 }
1686 });
1687
1688 return clone;
1689 }
1690
1691 rebuildTableFromBreakToken(breakToken, dest) {
1692 if (!breakToken || !breakToken.node) {
1693 return;
1694 }
1695 let node = breakToken.node;
1696 let td = isElement(node) ? node.closest("td") : node.parentElement.closest("td");
1697 if (td) {
1698 let rendered = findElement(td, dest, true);
1699 if (!rendered) {
1700 return;
1701 }
1702 while ((td = td.nextElementSibling)) {
1703 this.append(td, dest, null, true);
1704 }
1705 }
1706 }
1707
1708 async waitForImages(imgs) {
1709 let results = Array.from(imgs).map(async (img) => {
1710 return this.awaitImageLoaded(img);
1711 });
1712 await Promise.all(results);
1713 }
1714
1715 async awaitImageLoaded(image) {
1716 return new Promise(resolve => {
1717 if (image.complete !== true) {
1718 image.onload = function () {
1719 let {width, height} = window.getComputedStyle(image);
1720 resolve(width, height);
1721 };
1722 image.onerror = function (e) {
1723 let {width, height} = window.getComputedStyle(image);
1724 resolve(width, height, e);
1725 };
1726 } else {
1727 let {width, height} = window.getComputedStyle(image);
1728 resolve(width, height);
1729 }
1730 });
1731 }
1732
1733 avoidBreakInside(node, limiter) {
1734 let breakNode;
1735
1736 if (node === limiter) {
1737 return;
1738 }
1739
1740 while (node.parentNode) {
1741 node = node.parentNode;
1742
1743 if (node === limiter) {
1744 break;
1745 }
1746
1747 if (window.getComputedStyle(node)["break-inside"] === "avoid") {
1748 breakNode = node;
1749 break;
1750 }
1751
1752 }
1753 return breakNode;
1754 }
1755
1756 createBreakToken(overflow, rendered, source) {
1757 let container = overflow.startContainer;
1758 let offset = overflow.startOffset;
1759 let node, renderedNode, parent, index, temp;
1760
1761 if (isElement(container)) {
1762 temp = child(container, offset);
1763
1764 if (isElement(temp)) {
1765 renderedNode = findElement(temp, rendered);
1766
1767 if (!renderedNode) {
1768 // Find closest element with data-ref
1769 let prevNode = prevValidNode(temp);
1770 if (!isElement(prevNode)) {
1771 prevNode = prevNode.parentElement;
1772 }
1773 renderedNode = findElement(prevNode, rendered);
1774 // Check if temp is the last rendered node at its level.
1775 if (!temp.nextSibling) {
1776 // We need to ensure that the previous sibling of temp is fully rendered.
1777 const renderedNodeFromSource = findElement(renderedNode, source);
1778 const walker = document.createTreeWalker(renderedNodeFromSource, NodeFilter.SHOW_ELEMENT);
1779 const lastChildOfRenderedNodeFromSource = walker.lastChild();
1780 const lastChildOfRenderedNodeMatchingFromRendered = findElement(lastChildOfRenderedNodeFromSource, rendered);
1781 // Check if we found that the last child in source
1782 if (!lastChildOfRenderedNodeMatchingFromRendered) {
1783 // Pending content to be rendered before virtual break token
1784 return;
1785 }
1786 // Otherwise we will return a break token as per below
1787 }
1788 // renderedNode is actually the last unbroken box that does not overflow.
1789 // Break Token is therefore the next sibling of renderedNode within source node.
1790 node = findElement(renderedNode, source).nextSibling;
1791 offset = 0;
1792 } else {
1793 node = findElement(renderedNode, source);
1794 offset = 0;
1795 }
1796 } else {
1797 renderedNode = findElement(container, rendered);
1798
1799 if (!renderedNode) {
1800 renderedNode = findElement(prevValidNode(container), rendered);
1801 }
1802
1803 parent = findElement(renderedNode, source);
1804 index = indexOfTextNode(temp, parent);
1805 // No seperatation for the first textNode of an element
1806 if(index === 0) {
1807 node = parent;
1808 offset = 0;
1809 } else {
1810 node = child(parent, index);
1811 offset = 0;
1812 }
1813 }
1814 } else {
1815 renderedNode = findElement(container.parentNode, rendered);
1816
1817 if (!renderedNode) {
1818 renderedNode = findElement(prevValidNode(container.parentNode), rendered);
1819 }
1820
1821 parent = findElement(renderedNode, source);
1822 index = indexOfTextNode(container, parent);
1823
1824 if (index === -1) {
1825 return;
1826 }
1827
1828 node = child(parent, index);
1829
1830 offset += node.textContent.indexOf(container.textContent);
1831 }
1832
1833 if (!node) {
1834 return;
1835 }
1836
1837 return new BreakToken(
1838 node,
1839 offset
1840 );
1841
1842 }
1843
1844 findBreakToken(rendered, source, bounds = this.bounds, prevBreakToken, extract = true) {
1845 let overflow = this.findOverflow(rendered, bounds);
1846 let breakToken, breakLetter;
1847
1848 let overflowHooks = this.hooks.onOverflow.triggerSync(overflow, rendered, bounds, this);
1849 overflowHooks.forEach((newOverflow) => {
1850 if (typeof newOverflow != "undefined") {
1851 overflow = newOverflow;
1852 }
1853 });
1854
1855 if (overflow) {
1856 breakToken = this.createBreakToken(overflow, rendered, source);
1857 // breakToken is nullable
1858 let breakHooks = this.hooks.onBreakToken.triggerSync(breakToken, overflow, rendered, this);
1859 breakHooks.forEach((newToken) => {
1860 if (typeof newToken != "undefined") {
1861 breakToken = newToken;
1862 }
1863 });
1864
1865 // Stop removal if we are in a loop
1866 if (breakToken && breakToken.equals(prevBreakToken)) {
1867 return breakToken;
1868 }
1869
1870 if (breakToken && breakToken["node"] && breakToken["offset"] && breakToken["node"].textContent) {
1871 breakLetter = breakToken["node"].textContent.charAt(breakToken["offset"]);
1872 } else {
1873 breakLetter = undefined;
1874 }
1875
1876 if (breakToken && breakToken.node && extract) {
1877 let removed = this.removeOverflow(overflow, breakLetter);
1878 this.hooks && this.hooks.afterOverflowRemoved.trigger(removed, rendered, this);
1879 }
1880
1881 }
1882 return breakToken;
1883 }
1884
1885 hasOverflow(element, bounds = this.bounds) {
1886 let constrainingElement = element && element.parentNode; // this gets the element, instead of the wrapper for the width workaround
1887 let {width, height} = element.getBoundingClientRect();
1888 let scrollWidth = constrainingElement ? constrainingElement.scrollWidth : 0;
1889 let scrollHeight = constrainingElement ? constrainingElement.scrollHeight : 0;
1890 return Math.max(Math.floor(width), scrollWidth) > Math.round(bounds.width) ||
1891 Math.max(Math.floor(height), scrollHeight) > Math.round(bounds.height);
1892 }
1893
1894 findOverflow(rendered, bounds = this.bounds, gap = this.gap) {
1895 if (!this.hasOverflow(rendered, bounds)) return;
1896
1897 let start = Math.floor(bounds.left);
1898 let end = Math.round(bounds.right + gap);
1899 let vStart = Math.round(bounds.top);
1900 let vEnd = Math.round(bounds.bottom);
1901 let range;
1902
1903 let walker = walk$2(rendered.firstChild, rendered);
1904
1905 // Find Start
1906 let next, done, node, offset, skip, breakAvoid, prev, br;
1907 while (!done) {
1908 next = walker.next();
1909 done = next.done;
1910 node = next.value;
1911 skip = false;
1912 breakAvoid = false;
1913 prev = undefined;
1914 br = undefined;
1915
1916 if (node) {
1917 let pos = getBoundingClientRect(node);
1918 let left = Math.round(pos.left);
1919 let right = Math.floor(pos.right);
1920 let top = Math.round(pos.top);
1921 let bottom = Math.floor(pos.bottom);
1922
1923 if (!range && (left >= end || top >= vEnd)) {
1924 // Check if it is a float
1925 let isFloat = false;
1926
1927 // Check if the node is inside a break-inside: avoid table cell
1928 const insideTableCell = parentOf(node, "TD", rendered);
1929 if (insideTableCell && window.getComputedStyle(insideTableCell)["break-inside"] === "avoid") {
1930 // breaking inside a table cell produces unexpected result, as a workaround, we forcibly avoid break inside in a cell.
1931 // But we take the whole row, not just the cell that is causing the break.
1932 prev = insideTableCell.parentElement;
1933 } else if (isElement(node)) {
1934 let styles = window.getComputedStyle(node);
1935 isFloat = styles.getPropertyValue("float") !== "none";
1936 skip = styles.getPropertyValue("break-inside") === "avoid";
1937 breakAvoid = node.dataset.breakBefore === "avoid" || node.dataset.previousBreakAfter === "avoid";
1938 prev = breakAvoid && nodeBefore(node, rendered);
1939 br = node.tagName === "BR" || node.tagName === "WBR";
1940 }
1941
1942 let tableRow;
1943 if (node.nodeName === "TR") {
1944 tableRow = node;
1945 } else {
1946 tableRow = parentOf(node, "TR", rendered);
1947 }
1948 if (tableRow) {
1949 // honor break-inside="avoid" in parent tbody/thead
1950 let container = tableRow.parentElement;
1951 if (["TBODY", "THEAD"].includes(container.nodeName)) {
1952 let styles = window.getComputedStyle(container);
1953 if (styles.getPropertyValue("break-inside") === "avoid") prev = container;
1954 }
1955
1956 // Check if the node is inside a row with a rowspan
1957 const table = parentOf(tableRow, "TABLE", rendered);
1958 const rowspan = table.querySelector("[colspan]");
1959 if (table && rowspan) {
1960 let columnCount = 0;
1961 for (const cell of Array.from(table.rows[0].cells)) {
1962 columnCount += parseInt(cell.getAttribute("colspan") || "1");
1963 }
1964 if (tableRow.cells.length !== columnCount) {
1965 let previousRow = tableRow.previousElementSibling;
1966 let previousRowColumnCount;
1967 while (previousRow !== null) {
1968 previousRowColumnCount = 0;
1969 for (const cell of Array.from(previousRow.cells)) {
1970 previousRowColumnCount += parseInt(cell.getAttribute("colspan") || "1");
1971 }
1972 if (previousRowColumnCount === columnCount) {
1973 break;
1974 }
1975 previousRow = previousRow.previousElementSibling;
1976 }
1977 if (previousRowColumnCount === columnCount) {
1978 prev = previousRow;
1979 }
1980 }
1981 }
1982 }
1983
1984 if (prev) {
1985 range = document.createRange();
1986 range.selectNode(prev);
1987 break;
1988 }
1989
1990 if (!br && !isFloat && isElement(node)) {
1991 range = document.createRange();
1992 range.selectNode(node);
1993 break;
1994 }
1995
1996 if (isText(node) && node.textContent.trim().length) {
1997 range = document.createRange();
1998 range.selectNode(node);
1999 break;
2000 }
2001
2002 }
2003
2004 if (!range && isText(node) &&
2005 node.textContent.trim().length &&
2006 !breakInsideAvoidParentNode(node.parentNode)) {
2007
2008 let rects = getClientRects(node);
2009 let rect;
2010 left = 0;
2011 top = 0;
2012 for (var i = 0; i != rects.length; i++) {
2013 rect = rects[i];
2014 if (rect.width > 0 && (!left || rect.left > left)) {
2015 left = rect.left;
2016 }
2017 if (rect.height > 0 && (!top || rect.top > top)) {
2018 top = rect.top;
2019 }
2020 }
2021
2022 if (left >= end || top >= vEnd) {
2023 range = document.createRange();
2024 offset = this.textBreak(node, start, end, vStart, vEnd);
2025 if (!offset) {
2026 range = undefined;
2027 } else {
2028 range.setStart(node, offset);
2029 }
2030 break;
2031 }
2032 }
2033
2034 // Skip children
2035 if (skip || (right <= end && bottom <= vEnd)) {
2036 next = nodeAfter(node, rendered);
2037 if (next) {
2038 walker = walk$2(next, rendered);
2039 }
2040
2041 }
2042
2043 }
2044 }
2045
2046 // Find End
2047 if (range) {
2048 range.setEndAfter(rendered.lastChild);
2049 return range;
2050 }
2051
2052 }
2053
2054 findEndToken(rendered, source) {
2055 if (rendered.childNodes.length === 0) {
2056 return;
2057 }
2058
2059 let lastChild = rendered.lastChild;
2060
2061 let lastNodeIndex;
2062 while (lastChild && lastChild.lastChild) {
2063 if (!validNode(lastChild)) {
2064 // Only get elements with refs
2065 lastChild = lastChild.previousSibling;
2066 } else if (!validNode(lastChild.lastChild)) {
2067 // Deal with invalid dom items
2068 lastChild = prevValidNode(lastChild.lastChild);
2069 break;
2070 } else {
2071 lastChild = lastChild.lastChild;
2072 }
2073 }
2074
2075 if (isText(lastChild)) {
2076
2077 if (lastChild.parentNode.dataset.ref) {
2078 lastNodeIndex = indexOf$2(lastChild);
2079 lastChild = lastChild.parentNode;
2080 } else {
2081 lastChild = lastChild.previousSibling;
2082 }
2083 }
2084
2085 let original = findElement(lastChild, source);
2086
2087 if (lastNodeIndex) {
2088 original = original.childNodes[lastNodeIndex];
2089 }
2090
2091 let after = nodeAfter(original);
2092
2093 return this.breakAt(after);
2094 }
2095
2096 textBreak(node, start, end, vStart, vEnd) {
2097 let wordwalker = words(node);
2098 let left = 0;
2099 let right = 0;
2100 let top = 0;
2101 let bottom = 0;
2102 let word, next, done, pos;
2103 let offset;
2104 while (!done) {
2105 next = wordwalker.next();
2106 word = next.value;
2107 done = next.done;
2108
2109 if (!word) {
2110 break;
2111 }
2112
2113 pos = getBoundingClientRect(word);
2114
2115 left = Math.floor(pos.left);
2116 right = Math.floor(pos.right);
2117 top = Math.floor(pos.top);
2118 bottom = Math.floor(pos.bottom);
2119
2120 if (left >= end || top >= vEnd) {
2121 offset = word.startOffset;
2122 break;
2123 }
2124
2125 if (right > end || bottom > vEnd) {
2126 let letterwalker = letters(word);
2127 let letter, nextLetter, doneLetter;
2128
2129 while (!doneLetter) {
2130 nextLetter = letterwalker.next();
2131 letter = nextLetter.value;
2132 doneLetter = nextLetter.done;
2133
2134 if (!letter) {
2135 break;
2136 }
2137
2138 pos = getBoundingClientRect(letter);
2139 left = Math.floor(pos.left);
2140 top = Math.floor(pos.top);
2141
2142 if (left >= end || top >= vEnd) {
2143 offset = letter.startOffset;
2144 done = true;
2145
2146 break;
2147 }
2148 }
2149 }
2150
2151 }
2152
2153 return offset;
2154 }
2155
2156 removeOverflow(overflow, breakLetter) {
2157 let {startContainer} = overflow;
2158 let extracted = overflow.extractContents();
2159
2160 this.hyphenateAtBreak(startContainer, breakLetter);
2161
2162 return extracted;
2163 }
2164
2165 hyphenateAtBreak(startContainer, breakLetter) {
2166 if (isText(startContainer)) {
2167 let startText = startContainer.textContent;
2168 let prevLetter = startText[startText.length - 1];
2169
2170 // Add a hyphen if previous character is a letter or soft hyphen
2171 if (
2172 (breakLetter && /^\w|\u00AD$/.test(prevLetter) && /^\w|\u00AD$/.test(breakLetter)) ||
2173 (!breakLetter && /^\w|\u00AD$/.test(prevLetter))
2174 ) {
2175 startContainer.parentNode.classList.add("pagedjs_hyphen");
2176 startContainer.textContent += this.settings.hyphenGlyph || "\u2011";
2177 }
2178 }
2179 }
2180
2181 equalTokens(a, b) {
2182 if (!a || !b) {
2183 return false;
2184 }
2185 if (a["node"] && b["node"] && a["node"] !== b["node"]) {
2186 return false;
2187 }
2188 if (a["offset"] && b["offset"] && a["offset"] !== b["offset"]) {
2189 return false;
2190 }
2191 return true;
2192 }
2193 }
2194
2195 EventEmitter(Layout.prototype);
2196
2197 /**
2198 * Render a page
2199 * @class
2200 */
2201 class Page {
2202 constructor(pagesArea, pageTemplate, blank, hooks, options) {
2203 this.pagesArea = pagesArea;
2204 this.pageTemplate = pageTemplate;
2205 this.blank = blank;
2206
2207 this.width = undefined;
2208 this.height = undefined;
2209
2210 this.hooks = hooks;
2211
2212 this.settings = options || {};
2213
2214 // this.element = this.create(this.pageTemplate);
2215 }
2216
2217 create(template, after) {
2218 //let documentFragment = document.createRange().createContextualFragment( TEMPLATE );
2219 //let page = documentFragment.children[0];
2220 let clone = document.importNode(this.pageTemplate.content, true);
2221
2222 let page, index;
2223 if (after) {
2224 this.pagesArea.insertBefore(clone, after.nextElementSibling);
2225 index = Array.prototype.indexOf.call(this.pagesArea.children, after.nextElementSibling);
2226 page = this.pagesArea.children[index];
2227 } else {
2228 this.pagesArea.appendChild(clone);
2229 page = this.pagesArea.lastChild;
2230 }
2231
2232 let pagebox = page.querySelector(".pagedjs_pagebox");
2233 let area = page.querySelector(".pagedjs_page_content");
2234 let footnotesArea = page.querySelector(".pagedjs_footnote_area");
2235
2236
2237 let size = area.getBoundingClientRect();
2238
2239
2240 area.style.columnWidth = Math.round(size.width) + "px";
2241 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))";
2242 // area.style.overflow = "scroll";
2243
2244 this.width = Math.round(size.width);
2245 this.height = Math.round(size.height);
2246
2247 this.element = page;
2248 this.pagebox = pagebox;
2249 this.area = area;
2250 this.footnotesArea = footnotesArea;
2251
2252 return page;
2253 }
2254
2255 createWrapper() {
2256 let wrapper = document.createElement("div");
2257
2258 this.area.appendChild(wrapper);
2259
2260 this.wrapper = wrapper;
2261
2262 return wrapper;
2263 }
2264
2265 index(pgnum) {
2266 this.position = pgnum;
2267
2268 let page = this.element;
2269 // let pagebox = this.pagebox;
2270
2271 let index = pgnum + 1;
2272
2273 let id = `page-${index}`;
2274
2275 this.id = id;
2276
2277 // page.dataset.pageNumber = index;
2278
2279 page.dataset.pageNumber = index;
2280 page.setAttribute("id", id);
2281
2282 if (this.name) {
2283 page.classList.add("pagedjs_" + this.name + "_page");
2284 }
2285
2286 if (this.blank) {
2287 page.classList.add("pagedjs_blank_page");
2288 }
2289
2290 if (pgnum === 0) {
2291 page.classList.add("pagedjs_first_page");
2292 }
2293
2294 if (pgnum % 2 !== 1) {
2295 page.classList.remove("pagedjs_left_page");
2296 page.classList.add("pagedjs_right_page");
2297 } else {
2298 page.classList.remove("pagedjs_right_page");
2299 page.classList.add("pagedjs_left_page");
2300 }
2301 }
2302
2303 /*
2304 size(width, height) {
2305 if (width === this.width && height === this.height) {
2306 return;
2307 }
2308 this.width = width;
2309 this.height = height;
2310
2311 this.element.style.width = Math.round(width) + "px";
2312 this.element.style.height = Math.round(height) + "px";
2313 this.element.style.columnWidth = Math.round(width) + "px";
2314 }
2315 */
2316
2317 async layout(contents, breakToken, maxChars) {
2318
2319 this.clear();
2320
2321 this.startToken = breakToken;
2322
2323 let settings = this.settings;
2324 if (!settings.maxChars && maxChars) {
2325 settings.maxChars = maxChars;
2326 }
2327
2328 this.layoutMethod = new Layout(this.area, this.hooks, settings);
2329
2330 let renderResult = await this.layoutMethod.renderTo(this.wrapper, contents, breakToken);
2331 let newBreakToken = renderResult.breakToken;
2332
2333 this.addListeners(contents);
2334
2335 this.endToken = newBreakToken;
2336
2337 return newBreakToken;
2338 }
2339
2340 async append(contents, breakToken) {
2341
2342 if (!this.layoutMethod) {
2343 return this.layout(contents, breakToken);
2344 }
2345
2346 let renderResult = await this.layoutMethod.renderTo(this.wrapper, contents, breakToken);
2347 let newBreakToken = renderResult.breakToken;
2348
2349 this.endToken = newBreakToken;
2350
2351 return newBreakToken;
2352 }
2353
2354 getByParent(ref, entries) {
2355 let e;
2356 for (var i = 0; i < entries.length; i++) {
2357 e = entries[i];
2358 if (e.dataset.ref === ref) {
2359 return e;
2360 }
2361 }
2362 }
2363
2364 onOverflow(func) {
2365 this._onOverflow = func;
2366 }
2367
2368 onUnderflow(func) {
2369 this._onUnderflow = func;
2370 }
2371
2372 clear() {
2373 this.removeListeners();
2374 this.wrapper && this.wrapper.remove();
2375 this.createWrapper();
2376 }
2377
2378 addListeners(contents) {
2379 if (typeof ResizeObserver !== "undefined") {
2380 this.addResizeObserver(contents);
2381 } else {
2382 this._checkOverflowAfterResize = this.checkOverflowAfterResize.bind(this, contents);
2383 this.element.addEventListener("overflow", this._checkOverflowAfterResize, false);
2384 this.element.addEventListener("underflow", this._checkOverflowAfterResize, false);
2385 }
2386 // TODO: fall back to mutation observer?
2387
2388 this._onScroll = function () {
2389 if (this.listening) {
2390 this.element.scrollLeft = 0;
2391 }
2392 }.bind(this);
2393
2394 // Keep scroll left from changing
2395 this.element.addEventListener("scroll", this._onScroll);
2396
2397 this.listening = true;
2398
2399 return true;
2400 }
2401
2402 removeListeners() {
2403 this.listening = false;
2404
2405 if (typeof ResizeObserver !== "undefined" && this.ro) {
2406 this.ro.disconnect();
2407 } else if (this.element) {
2408 this.element.removeEventListener("overflow", this._checkOverflowAfterResize, false);
2409 this.element.removeEventListener("underflow", this._checkOverflowAfterResize, false);
2410 }
2411
2412 this.element && this.element.removeEventListener("scroll", this._onScroll);
2413
2414 }
2415
2416 addResizeObserver(contents) {
2417 let wrapper = this.wrapper;
2418 let prevHeight = wrapper.getBoundingClientRect().height;
2419 this.ro = new ResizeObserver(entries => {
2420
2421 if (!this.listening) {
2422 return;
2423 }
2424 requestAnimationFrame(() => {
2425 for (let entry of entries) {
2426 const cr = entry.contentRect;
2427
2428 if (cr.height > prevHeight) {
2429 this.checkOverflowAfterResize(contents);
2430 prevHeight = wrapper.getBoundingClientRect().height;
2431 } else if (cr.height < prevHeight) { // TODO: calc line height && (prevHeight - cr.height) >= 22
2432 this.checkUnderflowAfterResize(contents);
2433 prevHeight = cr.height;
2434 }
2435 }
2436 });
2437 });
2438
2439 this.ro.observe(wrapper);
2440 }
2441
2442 checkOverflowAfterResize(contents) {
2443 if (!this.listening || !this.layoutMethod) {
2444 return;
2445 }
2446
2447 let newBreakToken = this.layoutMethod.findBreakToken(this.wrapper, contents, this.startToken);
2448
2449 if (newBreakToken) {
2450 this.endToken = newBreakToken;
2451 this._onOverflow && this._onOverflow(newBreakToken);
2452 }
2453 }
2454
2455 checkUnderflowAfterResize(contents) {
2456 if (!this.listening || !this.layoutMethod) {
2457 return;
2458 }
2459
2460 let endToken = this.layoutMethod.findEndToken(this.wrapper, contents);
2461
2462 if (endToken) {
2463 this._onUnderflow && this._onUnderflow(endToken);
2464 }
2465 }
2466
2467
2468 destroy() {
2469 this.removeListeners();
2470
2471 this.element.remove();
2472
2473 this.element = undefined;
2474 this.wrapper = undefined;
2475 }
2476 }
2477
2478 EventEmitter(Page.prototype);
2479
2480 /**
2481 * Render a flow of text offscreen
2482 * @class
2483 */
2484 class ContentParser {
2485
2486 constructor(content, cb) {
2487 if (content && content.nodeType) {
2488 // handle dom
2489 this.dom = this.add(content);
2490 } else if (typeof content === "string") {
2491 this.dom = this.parse(content);
2492 }
2493
2494 return this.dom;
2495 }
2496
2497 parse(markup, mime) {
2498 let range = document.createRange();
2499 let fragment = range.createContextualFragment(markup);
2500
2501 this.addRefs(fragment);
2502
2503 return fragment;
2504 }
2505
2506 add(contents) {
2507 // let fragment = document.createDocumentFragment();
2508 //
2509 // let children = [...contents.childNodes];
2510 // for (let child of children) {
2511 // let clone = child.cloneNode(true);
2512 // fragment.appendChild(clone);
2513 // }
2514
2515 this.addRefs(contents);
2516
2517 return contents;
2518 }
2519
2520 addRefs(content) {
2521 var treeWalker = document.createTreeWalker(
2522 content,
2523 NodeFilter.SHOW_ELEMENT,
2524 null,
2525 false
2526 );
2527
2528 let node = treeWalker.nextNode();
2529 while(node) {
2530
2531 if (!node.hasAttribute("data-ref")) {
2532 let uuid = UUID();
2533 node.setAttribute("data-ref", uuid);
2534 }
2535
2536 if (node.id) {
2537 node.setAttribute("data-id", node.id);
2538 }
2539
2540 // node.setAttribute("data-children", node.childNodes.length);
2541
2542 // node.setAttribute("data-text", node.textContent.trim().length);
2543 node = treeWalker.nextNode();
2544 }
2545 }
2546
2547 find(ref) {
2548 return this.refs[ref];
2549 }
2550
2551 destroy() {
2552 this.refs = undefined;
2553 this.dom = undefined;
2554 }
2555 }
2556
2557 /**
2558 * Queue for handling tasks one at a time
2559 * @class
2560 * @param {scope} context what this will resolve to in the tasks
2561 */
2562 class Queue {
2563 constructor(context){
2564 this._q = [];
2565 this.context = context;
2566 this.tick = requestAnimationFrame;
2567 this.running = false;
2568 this.paused = false;
2569 }
2570
2571 /**
2572 * Add an item to the queue
2573 * @return {Promise} enqueued
2574 */
2575 enqueue() {
2576 var deferred, promise;
2577 var queued;
2578 var task = [].shift.call(arguments);
2579 var args = arguments;
2580
2581 // Handle single args without context
2582 // if(args && !Array.isArray(args)) {
2583 // args = [args];
2584 // }
2585 if(!task) {
2586 throw new Error("No Task Provided");
2587 }
2588
2589 if(typeof task === "function"){
2590
2591 deferred = new defer();
2592 promise = deferred.promise;
2593
2594 queued = {
2595 "task" : task,
2596 "args" : args,
2597 //"context" : context,
2598 "deferred" : deferred,
2599 "promise" : promise
2600 };
2601
2602 } else {
2603 // Task is a promise
2604 queued = {
2605 "promise" : task
2606 };
2607
2608 }
2609
2610 this._q.push(queued);
2611
2612 // Wait to start queue flush
2613 if (this.paused == false && !this.running) {
2614 this.run();
2615 }
2616
2617 return queued.promise;
2618 }
2619
2620 /**
2621 * Run one item
2622 * @return {Promise} dequeued
2623 */
2624 dequeue(){
2625 var inwait, task, result;
2626
2627 if(this._q.length && !this.paused) {
2628 inwait = this._q.shift();
2629 task = inwait.task;
2630 if(task){
2631 // console.log(task)
2632
2633 result = task.apply(this.context, inwait.args);
2634
2635 if(result && typeof result["then"] === "function") {
2636 // Task is a function that returns a promise
2637 return result.then(function(){
2638 inwait.deferred.resolve.apply(this.context, arguments);
2639 }.bind(this), function() {
2640 inwait.deferred.reject.apply(this.context, arguments);
2641 }.bind(this));
2642 } else {
2643 // Task resolves immediately
2644 inwait.deferred.resolve.apply(this.context, result);
2645 return inwait.promise;
2646 }
2647
2648
2649
2650 } else if(inwait.promise) {
2651 // Task is a promise
2652 return inwait.promise;
2653 }
2654
2655 } else {
2656 inwait = new defer();
2657 inwait.deferred.resolve();
2658 return inwait.promise;
2659 }
2660
2661 }
2662
2663 // Run All Immediately
2664 dump(){
2665 while(this._q.length) {
2666 this.dequeue();
2667 }
2668 }
2669
2670 /**
2671 * Run all tasks sequentially, at convince
2672 * @return {Promise} all run
2673 */
2674 run(){
2675
2676 if(!this.running){
2677 this.running = true;
2678 this.defered = new defer();
2679 }
2680
2681 this.tick.call(window, () => {
2682
2683 if(this._q.length) {
2684
2685 this.dequeue()
2686 .then(function(){
2687 this.run();
2688 }.bind(this));
2689
2690 } else {
2691 this.defered.resolve();
2692 this.running = undefined;
2693 }
2694
2695 });
2696
2697 // Unpause
2698 if(this.paused == true) {
2699 this.paused = false;
2700 }
2701
2702 return this.defered.promise;
2703 }
2704
2705 /**
2706 * Flush all, as quickly as possible
2707 * @return {Promise} ran
2708 */
2709 flush(){
2710
2711 if(this.running){
2712 return this.running;
2713 }
2714
2715 if(this._q.length) {
2716 this.running = this.dequeue()
2717 .then(function(){
2718 this.running = undefined;
2719 return this.flush();
2720 }.bind(this));
2721
2722 return this.running;
2723 }
2724
2725 }
2726
2727 /**
2728 * Clear all items in wait
2729 * @return {void}
2730 */
2731 clear(){
2732 this._q = [];
2733 }
2734
2735 /**
2736 * Get the number of tasks in the queue
2737 * @return {number} tasks
2738 */
2739 length(){
2740 return this._q.length;
2741 }
2742
2743 /**
2744 * Pause a running queue
2745 * @return {void}
2746 */
2747 pause(){
2748 this.paused = true;
2749 }
2750
2751 /**
2752 * End the queue
2753 * @return {void}
2754 */
2755 stop(){
2756 this._q = [];
2757 this.running = false;
2758 this.paused = true;
2759 }
2760 }
2761
2762 const TEMPLATE = `
2763<div class="pagedjs_page">
2764 <div class="pagedjs_sheet">
2765 <div class="pagedjs_bleed pagedjs_bleed-top">
2766 <div class="pagedjs_marks-crop"></div>
2767 <div class="pagedjs_marks-middle">
2768 <div class="pagedjs_marks-cross"></div>
2769 </div>
2770 <div class="pagedjs_marks-crop"></div>
2771 </div>
2772 <div class="pagedjs_bleed pagedjs_bleed-bottom">
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-left">
2779 <div class="pagedjs_marks-crop"></div>
2780 <div class="pagedjs_marks-middle">
2781 <div class="pagedjs_marks-cross"></div>
2782 </div> <div class="pagedjs_marks-crop"></div>
2783 </div>
2784 <div class="pagedjs_bleed pagedjs_bleed-right">
2785 <div class="pagedjs_marks-crop"></div>
2786 <div class="pagedjs_marks-middle">
2787 <div class="pagedjs_marks-cross"></div>
2788 </div>
2789 <div class="pagedjs_marks-crop"></div>
2790 </div>
2791 <div class="pagedjs_pagebox">
2792 <div class="pagedjs_margin-top-left-corner-holder">
2793 <div class="pagedjs_margin pagedjs_margin-top-left-corner"><div class="pagedjs_margin-content"></div></div>
2794 </div>
2795 <div class="pagedjs_margin-top">
2796 <div class="pagedjs_margin pagedjs_margin-top-left"><div class="pagedjs_margin-content"></div></div>
2797 <div class="pagedjs_margin pagedjs_margin-top-center"><div class="pagedjs_margin-content"></div></div>
2798 <div class="pagedjs_margin pagedjs_margin-top-right"><div class="pagedjs_margin-content"></div></div>
2799 </div>
2800 <div class="pagedjs_margin-top-right-corner-holder">
2801 <div class="pagedjs_margin pagedjs_margin-top-right-corner"><div class="pagedjs_margin-content"></div></div>
2802 </div>
2803 <div class="pagedjs_margin-right">
2804 <div class="pagedjs_margin pagedjs_margin-right-top"><div class="pagedjs_margin-content"></div></div>
2805 <div class="pagedjs_margin pagedjs_margin-right-middle"><div class="pagedjs_margin-content"></div></div>
2806 <div class="pagedjs_margin pagedjs_margin-right-bottom"><div class="pagedjs_margin-content"></div></div>
2807 </div>
2808 <div class="pagedjs_margin-left">
2809 <div class="pagedjs_margin pagedjs_margin-left-top"><div class="pagedjs_margin-content"></div></div>
2810 <div class="pagedjs_margin pagedjs_margin-left-middle"><div class="pagedjs_margin-content"></div></div>
2811 <div class="pagedjs_margin pagedjs_margin-left-bottom"><div class="pagedjs_margin-content"></div></div>
2812 </div>
2813 <div class="pagedjs_margin-bottom-left-corner-holder">
2814 <div class="pagedjs_margin pagedjs_margin-bottom-left-corner"><div class="pagedjs_margin-content"></div></div>
2815 </div>
2816 <div class="pagedjs_margin-bottom">
2817 <div class="pagedjs_margin pagedjs_margin-bottom-left"><div class="pagedjs_margin-content"></div></div>
2818 <div class="pagedjs_margin pagedjs_margin-bottom-center"><div class="pagedjs_margin-content"></div></div>
2819 <div class="pagedjs_margin pagedjs_margin-bottom-right"><div class="pagedjs_margin-content"></div></div>
2820 </div>
2821 <div class="pagedjs_margin-bottom-right-corner-holder">
2822 <div class="pagedjs_margin pagedjs_margin-bottom-right-corner"><div class="pagedjs_margin-content"></div></div>
2823 </div>
2824 <div class="pagedjs_area">
2825 <div class="pagedjs_page_content"></div>
2826 <div class="pagedjs_footnote_area">
2827 <div class="pagedjs_footnote_content pagedjs_footnote_empty">
2828 <div class="pagedjs_footnote_inner_content"></div>
2829 </div>
2830 </div>
2831 </div>
2832 </div>
2833 </div>
2834</div>`;
2835
2836 /**
2837 * Chop up text into flows
2838 * @class
2839 */
2840 class Chunker {
2841 constructor(content, renderTo, options) {
2842 // this.preview = preview;
2843
2844 this.settings = options || {};
2845
2846 this.hooks = {};
2847 this.hooks.beforeParsed = new Hook(this);
2848 this.hooks.filter = new Hook(this);
2849 this.hooks.afterParsed = new Hook(this);
2850 this.hooks.beforePageLayout = new Hook(this);
2851 this.hooks.onPageLayout = new Hook(this);
2852 this.hooks.layout = new Hook(this);
2853 this.hooks.renderNode = new Hook(this);
2854 this.hooks.layoutNode = new Hook(this);
2855 this.hooks.onOverflow = new Hook(this);
2856 this.hooks.afterOverflowRemoved = new Hook(this);
2857 this.hooks.onBreakToken = new Hook();
2858 this.hooks.beforeRenderResult = new Hook(this);
2859 this.hooks.afterPageLayout = new Hook(this);
2860 this.hooks.finalizePage = new Hook(this);
2861 this.hooks.afterRendered = new Hook(this);
2862
2863 this.pages = [];
2864 this.total = 0;
2865
2866 this.q = new Queue(this);
2867 this.stopped = false;
2868 this.rendered = false;
2869
2870 this.content = content;
2871
2872 this.charsPerBreak = [];
2873 this.maxChars;
2874
2875 if (content) {
2876 this.flow(content, renderTo);
2877 }
2878 }
2879
2880 setup(renderTo) {
2881 this.pagesArea = document.createElement("div");
2882 this.pagesArea.classList.add("pagedjs_pages");
2883
2884 if (renderTo) {
2885 renderTo.appendChild(this.pagesArea);
2886 } else {
2887 document.querySelector("body").appendChild(this.pagesArea);
2888 }
2889
2890 this.pageTemplate = document.createElement("template");
2891 this.pageTemplate.innerHTML = TEMPLATE;
2892
2893 }
2894
2895 async flow(content, renderTo) {
2896 let parsed;
2897
2898 await this.hooks.beforeParsed.trigger(content, this);
2899
2900 parsed = new ContentParser(content);
2901
2902 this.hooks.filter.triggerSync(parsed);
2903
2904 this.source = parsed;
2905 this.breakToken = undefined;
2906
2907 if (this.pagesArea && this.pageTemplate) {
2908 this.q.clear();
2909 this.removePages();
2910 } else {
2911 this.setup(renderTo);
2912 }
2913
2914 this.emit("rendering", parsed);
2915
2916 await this.hooks.afterParsed.trigger(parsed, this);
2917
2918 await this.loadFonts();
2919
2920 let rendered = await this.render(parsed, this.breakToken);
2921 while (rendered.canceled) {
2922 this.start();
2923 rendered = await this.render(parsed, this.breakToken);
2924 }
2925
2926 this.rendered = true;
2927 this.pagesArea.style.setProperty("--pagedjs-page-count", this.total);
2928
2929 await this.hooks.afterRendered.trigger(this.pages, this);
2930
2931 this.emit("rendered", this.pages);
2932
2933
2934
2935 return this;
2936 }
2937
2938 // oversetPages() {
2939 // let overset = [];
2940 // for (let i = 0; i < this.pages.length; i++) {
2941 // let page = this.pages[i];
2942 // if (page.overset) {
2943 // overset.push(page);
2944 // // page.overset = false;
2945 // }
2946 // }
2947 // return overset;
2948 // }
2949 //
2950 // async handleOverset(parsed) {
2951 // let overset = this.oversetPages();
2952 // if (overset.length) {
2953 // console.log("overset", overset);
2954 // let index = this.pages.indexOf(overset[0]) + 1;
2955 // console.log("INDEX", index);
2956 //
2957 // // Remove pages
2958 // // this.removePages(index);
2959 //
2960 // // await this.render(parsed, overset[0].overset);
2961 //
2962 // // return this.handleOverset(parsed);
2963 // }
2964 // }
2965
2966 async render(parsed, startAt) {
2967 let renderer = this.layout(parsed, startAt);
2968
2969 let done = false;
2970 let result;
2971 while (!done) {
2972 result = await this.q.enqueue(() => { return this.renderAsync(renderer); });
2973 done = result.done;
2974 }
2975
2976 return result;
2977 }
2978
2979 start() {
2980 this.rendered = false;
2981 this.stopped = false;
2982 }
2983
2984 stop() {
2985 this.stopped = true;
2986 // this.q.clear();
2987 }
2988
2989 renderOnIdle(renderer) {
2990 return new Promise(resolve => {
2991 requestIdleCallback(async () => {
2992 if (this.stopped) {
2993 return resolve({ done: true, canceled: true });
2994 }
2995 let result = await renderer.next();
2996 if (this.stopped) {
2997 resolve({ done: true, canceled: true });
2998 } else {
2999 resolve(result);
3000 }
3001 });
3002 });
3003 }
3004
3005 async renderAsync(renderer) {
3006 if (this.stopped) {
3007 return { done: true, canceled: true };
3008 }
3009 let result = await renderer.next();
3010 if (this.stopped) {
3011 return { done: true, canceled: true };
3012 } else {
3013 return result;
3014 }
3015 }
3016
3017 async handleBreaks(node, force) {
3018 let currentPage = this.total + 1;
3019 let currentPosition = currentPage % 2 === 0 ? "left" : "right";
3020 // TODO: Recto and Verso should reverse for rtl languages
3021 let currentSide = currentPage % 2 === 0 ? "verso" : "recto";
3022 let previousBreakAfter;
3023 let breakBefore;
3024 let page;
3025
3026 if (currentPage === 1) {
3027 return;
3028 }
3029
3030 if (node &&
3031 typeof node.dataset !== "undefined" &&
3032 typeof node.dataset.previousBreakAfter !== "undefined") {
3033 previousBreakAfter = node.dataset.previousBreakAfter;
3034 }
3035
3036 if (node &&
3037 typeof node.dataset !== "undefined" &&
3038 typeof node.dataset.breakBefore !== "undefined") {
3039 breakBefore = node.dataset.breakBefore;
3040 }
3041
3042 if (force) {
3043 page = this.addPage(true);
3044 } else if( previousBreakAfter &&
3045 (previousBreakAfter === "left" || previousBreakAfter === "right") &&
3046 previousBreakAfter !== currentPosition) {
3047 page = this.addPage(true);
3048 } else if( previousBreakAfter &&
3049 (previousBreakAfter === "verso" || previousBreakAfter === "recto") &&
3050 previousBreakAfter !== currentSide) {
3051 page = this.addPage(true);
3052 } else if( breakBefore &&
3053 (breakBefore === "left" || breakBefore === "right") &&
3054 breakBefore !== currentPosition) {
3055 page = this.addPage(true);
3056 } else if( breakBefore &&
3057 (breakBefore === "verso" || breakBefore === "recto") &&
3058 breakBefore !== currentSide) {
3059 page = this.addPage(true);
3060 }
3061
3062 if (page) {
3063 await this.hooks.beforePageLayout.trigger(page, undefined, undefined, this);
3064 this.emit("page", page);
3065 // await this.hooks.layout.trigger(page.element, page, undefined, this);
3066 await this.hooks.afterPageLayout.trigger(page.element, page, undefined, this);
3067 await this.hooks.finalizePage.trigger(page.element, page, undefined, this);
3068 this.emit("renderedPage", page);
3069 }
3070 }
3071
3072 async *layout(content, startAt) {
3073 let breakToken = startAt || false;
3074 let tokens = [];
3075
3076 while (breakToken !== undefined && (true)) {
3077
3078 if (breakToken && breakToken.node) {
3079 await this.handleBreaks(breakToken.node);
3080 } else {
3081 await this.handleBreaks(content.firstChild);
3082 }
3083
3084 let page = this.addPage();
3085
3086 await this.hooks.beforePageLayout.trigger(page, content, breakToken, this);
3087 this.emit("page", page);
3088
3089 // Layout content in the page, starting from the breakToken
3090 breakToken = await page.layout(content, breakToken, this.maxChars);
3091
3092 if (breakToken) {
3093 let newToken = breakToken.toJSON(true);
3094 if (tokens.lastIndexOf(newToken) > -1) {
3095 // loop
3096 let err = new OverflowContentError("Layout repeated", [breakToken.node]);
3097 console.error("Layout repeated at: ", breakToken.node);
3098 return err;
3099 } else {
3100 tokens.push(newToken);
3101 }
3102 }
3103
3104 await this.hooks.afterPageLayout.trigger(page.element, page, breakToken, this);
3105 await this.hooks.finalizePage.trigger(page.element, page, undefined, this);
3106 this.emit("renderedPage", page);
3107
3108 this.recoredCharLength(page.wrapper.textContent.length);
3109
3110 yield breakToken;
3111
3112 // Stop if we get undefined, showing we have reached the end of the content
3113 }
3114
3115
3116 }
3117
3118 recoredCharLength(length) {
3119 if (length === 0) {
3120 return;
3121 }
3122
3123 this.charsPerBreak.push(length);
3124
3125 // Keep the length of the last few breaks
3126 if (this.charsPerBreak.length > 4) {
3127 this.charsPerBreak.shift();
3128 }
3129
3130 this.maxChars = this.charsPerBreak.reduce((a, b) => a + b, 0) / (this.charsPerBreak.length);
3131 }
3132
3133 removePages(fromIndex=0) {
3134
3135 if (fromIndex >= this.pages.length) {
3136 return;
3137 }
3138
3139 // Remove pages
3140 for (let i = fromIndex; i < this.pages.length; i++) {
3141 this.pages[i].destroy();
3142 }
3143
3144 if (fromIndex > 0) {
3145 this.pages.splice(fromIndex);
3146 } else {
3147 this.pages = [];
3148 }
3149
3150 this.total = this.pages.length;
3151 }
3152
3153 addPage(blank) {
3154 let lastPage = this.pages[this.pages.length - 1];
3155 // Create a new page from the template
3156 let page = new Page(this.pagesArea, this.pageTemplate, blank, this.hooks, this.settings);
3157
3158 this.pages.push(page);
3159
3160 // Create the pages
3161 page.create(undefined, lastPage && lastPage.element);
3162
3163 page.index(this.total);
3164
3165 if (!blank) {
3166 // Listen for page overflow
3167 page.onOverflow((overflowToken) => {
3168 console.warn("overflow on", page.id, overflowToken);
3169
3170 // Only reflow while rendering
3171 if (this.rendered) {
3172 return;
3173 }
3174
3175 let index = this.pages.indexOf(page) + 1;
3176
3177 // Stop the rendering
3178 this.stop();
3179
3180 // Set the breakToken to resume at
3181 this.breakToken = overflowToken;
3182
3183 // Remove pages
3184 this.removePages(index);
3185
3186 if (this.rendered === true) {
3187 this.rendered = false;
3188
3189 this.q.enqueue(async () => {
3190
3191 this.start();
3192
3193 await this.render(this.source, this.breakToken);
3194
3195 this.rendered = true;
3196
3197 });
3198 }
3199
3200
3201 });
3202
3203 page.onUnderflow((overflowToken) => {
3204 // console.log("underflow on", page.id, overflowToken);
3205
3206 // page.append(this.source, overflowToken);
3207
3208 });
3209 }
3210
3211 this.total = this.pages.length;
3212
3213 return page;
3214 }
3215 /*
3216 insertPage(index, blank) {
3217 let lastPage = this.pages[index];
3218 // Create a new page from the template
3219 let page = new Page(this.pagesArea, this.pageTemplate, blank, this.hooks);
3220
3221 let total = this.pages.splice(index, 0, page);
3222
3223 // Create the pages
3224 page.create(undefined, lastPage && lastPage.element);
3225
3226 page.index(index + 1);
3227
3228 for (let i = index + 2; i < this.pages.length; i++) {
3229 this.pages[i].index(i);
3230 }
3231
3232 if (!blank) {
3233 // Listen for page overflow
3234 page.onOverflow((overflowToken) => {
3235 if (total < this.pages.length) {
3236 this.pages[total].layout(this.source, overflowToken);
3237 } else {
3238 let newPage = this.addPage();
3239 newPage.layout(this.source, overflowToken);
3240 }
3241 });
3242
3243 page.onUnderflow(() => {
3244 // console.log("underflow on", page.id);
3245 });
3246 }
3247
3248 this.total += 1;
3249
3250 return page;
3251 }
3252 */
3253
3254 async clonePage(originalPage) {
3255 let lastPage = this.pages[this.pages.length - 1];
3256
3257 let page = new Page(this.pagesArea, this.pageTemplate, false, this.hooks);
3258
3259 this.pages.push(page);
3260
3261 // Create the pages
3262 page.create(undefined, lastPage && lastPage.element);
3263
3264 page.index(this.total);
3265
3266 await this.hooks.beforePageLayout.trigger(page, undefined, undefined, this);
3267 this.emit("page", page);
3268
3269 for (const className of originalPage.element.classList) {
3270 if (className !== "pagedjs_left_page" && className !== "pagedjs_right_page") {
3271 page.element.classList.add(className);
3272 }
3273 }
3274
3275 await this.hooks.afterPageLayout.trigger(page.element, page, undefined, this);
3276 await this.hooks.finalizePage.trigger(page.element, page, undefined, this);
3277 this.emit("renderedPage", page);
3278 }
3279
3280 loadFonts() {
3281 let fontPromises = [];
3282 (document.fonts || []).forEach((fontFace) => {
3283 if (fontFace.status !== "loaded") {
3284 let fontLoaded = fontFace.load().then((r) => {
3285 return fontFace.family;
3286 }, (r) => {
3287 console.warn("Failed to preload font-family:", fontFace.family);
3288 return fontFace.family;
3289 });
3290 fontPromises.push(fontLoaded);
3291 }
3292 });
3293 return Promise.all(fontPromises).catch((err) => {
3294 console.warn(err);
3295 });
3296 }
3297
3298 destroy() {
3299 this.pagesArea.remove();
3300 this.pageTemplate.remove();
3301 }
3302
3303 }
3304
3305 EventEmitter(Chunker.prototype);
3306
3307 var syntax = {exports: {}};
3308
3309 var create$4 = {};
3310
3311 //
3312 // list
3313 // ┌──────┐
3314 // ┌──────────────┼─head │
3315 // │ │ tail─┼──────────────┐
3316 // │ └──────┘ │
3317 // ▼ ▼
3318 // item item item item
3319 // ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐
3320 // null ◀──┼─prev │◀───┼─prev │◀───┼─prev │◀───┼─prev │
3321 // │ next─┼───▶│ next─┼───▶│ next─┼───▶│ next─┼──▶ null
3322 // ├──────┤ ├──────┤ ├──────┤ ├──────┤
3323 // │ data │ │ data │ │ data │ │ data │
3324 // └──────┘ └──────┘ └──────┘ └──────┘
3325 //
3326
3327 function createItem(data) {
3328 return {
3329 prev: null,
3330 next: null,
3331 data: data
3332 };
3333 }
3334
3335 function allocateCursor(node, prev, next) {
3336 var cursor;
3337
3338 if (cursors !== null) {
3339 cursor = cursors;
3340 cursors = cursors.cursor;
3341 cursor.prev = prev;
3342 cursor.next = next;
3343 cursor.cursor = node.cursor;
3344 } else {
3345 cursor = {
3346 prev: prev,
3347 next: next,
3348 cursor: node.cursor
3349 };
3350 }
3351
3352 node.cursor = cursor;
3353
3354 return cursor;
3355 }
3356
3357 function releaseCursor(node) {
3358 var cursor = node.cursor;
3359
3360 node.cursor = cursor.cursor;
3361 cursor.prev = null;
3362 cursor.next = null;
3363 cursor.cursor = cursors;
3364 cursors = cursor;
3365 }
3366
3367 var cursors = null;
3368 var List$6 = function() {
3369 this.cursor = null;
3370 this.head = null;
3371 this.tail = null;
3372 };
3373
3374 List$6.createItem = createItem;
3375 List$6.prototype.createItem = createItem;
3376
3377 List$6.prototype.updateCursors = function(prevOld, prevNew, nextOld, nextNew) {
3378 var cursor = this.cursor;
3379
3380 while (cursor !== null) {
3381 if (cursor.prev === prevOld) {
3382 cursor.prev = prevNew;
3383 }
3384
3385 if (cursor.next === nextOld) {
3386 cursor.next = nextNew;
3387 }
3388
3389 cursor = cursor.cursor;
3390 }
3391 };
3392
3393 List$6.prototype.getSize = function() {
3394 var size = 0;
3395 var cursor = this.head;
3396
3397 while (cursor) {
3398 size++;
3399 cursor = cursor.next;
3400 }
3401
3402 return size;
3403 };
3404
3405 List$6.prototype.fromArray = function(array) {
3406 var cursor = null;
3407
3408 this.head = null;
3409
3410 for (var i = 0; i < array.length; i++) {
3411 var item = createItem(array[i]);
3412
3413 if (cursor !== null) {
3414 cursor.next = item;
3415 } else {
3416 this.head = item;
3417 }
3418
3419 item.prev = cursor;
3420 cursor = item;
3421 }
3422
3423 this.tail = cursor;
3424
3425 return this;
3426 };
3427
3428 List$6.prototype.toArray = function() {
3429 var cursor = this.head;
3430 var result = [];
3431
3432 while (cursor) {
3433 result.push(cursor.data);
3434 cursor = cursor.next;
3435 }
3436
3437 return result;
3438 };
3439
3440 List$6.prototype.toJSON = List$6.prototype.toArray;
3441
3442 List$6.prototype.isEmpty = function() {
3443 return this.head === null;
3444 };
3445
3446 List$6.prototype.first = function() {
3447 return this.head && this.head.data;
3448 };
3449
3450 List$6.prototype.last = function() {
3451 return this.tail && this.tail.data;
3452 };
3453
3454 List$6.prototype.each = function(fn, context) {
3455 var item;
3456
3457 if (context === undefined) {
3458 context = this;
3459 }
3460
3461 // push cursor
3462 var cursor = allocateCursor(this, null, this.head);
3463
3464 while (cursor.next !== null) {
3465 item = cursor.next;
3466 cursor.next = item.next;
3467
3468 fn.call(context, item.data, item, this);
3469 }
3470
3471 // pop cursor
3472 releaseCursor(this);
3473 };
3474
3475 List$6.prototype.forEach = List$6.prototype.each;
3476
3477 List$6.prototype.eachRight = function(fn, context) {
3478 var item;
3479
3480 if (context === undefined) {
3481 context = this;
3482 }
3483
3484 // push cursor
3485 var cursor = allocateCursor(this, this.tail, null);
3486
3487 while (cursor.prev !== null) {
3488 item = cursor.prev;
3489 cursor.prev = item.prev;
3490
3491 fn.call(context, item.data, item, this);
3492 }
3493
3494 // pop cursor
3495 releaseCursor(this);
3496 };
3497
3498 List$6.prototype.forEachRight = List$6.prototype.eachRight;
3499
3500 List$6.prototype.reduce = function(fn, initialValue, context) {
3501 var item;
3502
3503 if (context === undefined) {
3504 context = this;
3505 }
3506
3507 // push cursor
3508 var cursor = allocateCursor(this, null, this.head);
3509 var acc = initialValue;
3510
3511 while (cursor.next !== null) {
3512 item = cursor.next;
3513 cursor.next = item.next;
3514
3515 acc = fn.call(context, acc, item.data, item, this);
3516 }
3517
3518 // pop cursor
3519 releaseCursor(this);
3520
3521 return acc;
3522 };
3523
3524 List$6.prototype.reduceRight = function(fn, initialValue, context) {
3525 var item;
3526
3527 if (context === undefined) {
3528 context = this;
3529 }
3530
3531 // push cursor
3532 var cursor = allocateCursor(this, this.tail, null);
3533 var acc = initialValue;
3534
3535 while (cursor.prev !== null) {
3536 item = cursor.prev;
3537 cursor.prev = item.prev;
3538
3539 acc = fn.call(context, acc, item.data, item, this);
3540 }
3541
3542 // pop cursor
3543 releaseCursor(this);
3544
3545 return acc;
3546 };
3547
3548 List$6.prototype.nextUntil = function(start, fn, context) {
3549 if (start === null) {
3550 return;
3551 }
3552
3553 var item;
3554
3555 if (context === undefined) {
3556 context = this;
3557 }
3558
3559 // push cursor
3560 var cursor = allocateCursor(this, null, start);
3561
3562 while (cursor.next !== null) {
3563 item = cursor.next;
3564 cursor.next = item.next;
3565
3566 if (fn.call(context, item.data, item, this)) {
3567 break;
3568 }
3569 }
3570
3571 // pop cursor
3572 releaseCursor(this);
3573 };
3574
3575 List$6.prototype.prevUntil = function(start, fn, context) {
3576 if (start === null) {
3577 return;
3578 }
3579
3580 var item;
3581
3582 if (context === undefined) {
3583 context = this;
3584 }
3585
3586 // push cursor
3587 var cursor = allocateCursor(this, start, null);
3588
3589 while (cursor.prev !== null) {
3590 item = cursor.prev;
3591 cursor.prev = item.prev;
3592
3593 if (fn.call(context, item.data, item, this)) {
3594 break;
3595 }
3596 }
3597
3598 // pop cursor
3599 releaseCursor(this);
3600 };
3601
3602 List$6.prototype.some = function(fn, context) {
3603 var cursor = this.head;
3604
3605 if (context === undefined) {
3606 context = this;
3607 }
3608
3609 while (cursor !== null) {
3610 if (fn.call(context, cursor.data, cursor, this)) {
3611 return true;
3612 }
3613
3614 cursor = cursor.next;
3615 }
3616
3617 return false;
3618 };
3619
3620 List$6.prototype.map = function(fn, context) {
3621 var result = new List$6();
3622 var cursor = this.head;
3623
3624 if (context === undefined) {
3625 context = this;
3626 }
3627
3628 while (cursor !== null) {
3629 result.appendData(fn.call(context, cursor.data, cursor, this));
3630 cursor = cursor.next;
3631 }
3632
3633 return result;
3634 };
3635
3636 List$6.prototype.filter = function(fn, context) {
3637 var result = new List$6();
3638 var cursor = this.head;
3639
3640 if (context === undefined) {
3641 context = this;
3642 }
3643
3644 while (cursor !== null) {
3645 if (fn.call(context, cursor.data, cursor, this)) {
3646 result.appendData(cursor.data);
3647 }
3648 cursor = cursor.next;
3649 }
3650
3651 return result;
3652 };
3653
3654 List$6.prototype.clear = function() {
3655 this.head = null;
3656 this.tail = null;
3657 };
3658
3659 List$6.prototype.copy = function() {
3660 var result = new List$6();
3661 var cursor = this.head;
3662
3663 while (cursor !== null) {
3664 result.insert(createItem(cursor.data));
3665 cursor = cursor.next;
3666 }
3667
3668 return result;
3669 };
3670
3671 List$6.prototype.prepend = function(item) {
3672 // head
3673 // ^
3674 // item
3675 this.updateCursors(null, item, this.head, item);
3676
3677 // insert to the beginning of the list
3678 if (this.head !== null) {
3679 // new item <- first item
3680 this.head.prev = item;
3681
3682 // new item -> first item
3683 item.next = this.head;
3684 } else {
3685 // if list has no head, then it also has no tail
3686 // in this case tail points to the new item
3687 this.tail = item;
3688 }
3689
3690 // head always points to new item
3691 this.head = item;
3692
3693 return this;
3694 };
3695
3696 List$6.prototype.prependData = function(data) {
3697 return this.prepend(createItem(data));
3698 };
3699
3700 List$6.prototype.append = function(item) {
3701 return this.insert(item);
3702 };
3703
3704 List$6.prototype.appendData = function(data) {
3705 return this.insert(createItem(data));
3706 };
3707
3708 List$6.prototype.insert = function(item, before) {
3709 if (before !== undefined && before !== null) {
3710 // prev before
3711 // ^
3712 // item
3713 this.updateCursors(before.prev, item, before, item);
3714
3715 if (before.prev === null) {
3716 // insert to the beginning of list
3717 if (this.head !== before) {
3718 throw new Error('before doesn\'t belong to list');
3719 }
3720
3721 // since head points to before therefore list doesn't empty
3722 // no need to check tail
3723 this.head = item;
3724 before.prev = item;
3725 item.next = before;
3726
3727 this.updateCursors(null, item);
3728 } else {
3729
3730 // insert between two items
3731 before.prev.next = item;
3732 item.prev = before.prev;
3733
3734 before.prev = item;
3735 item.next = before;
3736 }
3737 } else {
3738 // tail
3739 // ^
3740 // item
3741 this.updateCursors(this.tail, item, null, item);
3742
3743 // insert to the ending of the list
3744 if (this.tail !== null) {
3745 // last item -> new item
3746 this.tail.next = item;
3747
3748 // last item <- new item
3749 item.prev = this.tail;
3750 } else {
3751 // if list has no tail, then it also has no head
3752 // in this case head points to new item
3753 this.head = item;
3754 }
3755
3756 // tail always points to new item
3757 this.tail = item;
3758 }
3759
3760 return this;
3761 };
3762
3763 List$6.prototype.insertData = function(data, before) {
3764 return this.insert(createItem(data), before);
3765 };
3766
3767 List$6.prototype.remove = function(item) {
3768 // item
3769 // ^
3770 // prev next
3771 this.updateCursors(item, item.prev, item, item.next);
3772
3773 if (item.prev !== null) {
3774 item.prev.next = item.next;
3775 } else {
3776 if (this.head !== item) {
3777 throw new Error('item doesn\'t belong to list');
3778 }
3779
3780 this.head = item.next;
3781 }
3782
3783 if (item.next !== null) {
3784 item.next.prev = item.prev;
3785 } else {
3786 if (this.tail !== item) {
3787 throw new Error('item doesn\'t belong to list');
3788 }
3789
3790 this.tail = item.prev;
3791 }
3792
3793 item.prev = null;
3794 item.next = null;
3795
3796 return item;
3797 };
3798
3799 List$6.prototype.push = function(data) {
3800 this.insert(createItem(data));
3801 };
3802
3803 List$6.prototype.pop = function() {
3804 if (this.tail !== null) {
3805 return this.remove(this.tail);
3806 }
3807 };
3808
3809 List$6.prototype.unshift = function(data) {
3810 this.prepend(createItem(data));
3811 };
3812
3813 List$6.prototype.shift = function() {
3814 if (this.head !== null) {
3815 return this.remove(this.head);
3816 }
3817 };
3818
3819 List$6.prototype.prependList = function(list) {
3820 return this.insertList(list, this.head);
3821 };
3822
3823 List$6.prototype.appendList = function(list) {
3824 return this.insertList(list);
3825 };
3826
3827 List$6.prototype.insertList = function(list, before) {
3828 // ignore empty lists
3829 if (list.head === null) {
3830 return this;
3831 }
3832
3833 if (before !== undefined && before !== null) {
3834 this.updateCursors(before.prev, list.tail, before, list.head);
3835
3836 // insert in the middle of dist list
3837 if (before.prev !== null) {
3838 // before.prev <-> list.head
3839 before.prev.next = list.head;
3840 list.head.prev = before.prev;
3841 } else {
3842 this.head = list.head;
3843 }
3844
3845 before.prev = list.tail;
3846 list.tail.next = before;
3847 } else {
3848 this.updateCursors(this.tail, list.tail, null, list.head);
3849
3850 // insert to end of the list
3851 if (this.tail !== null) {
3852 // if destination list has a tail, then it also has a head,
3853 // but head doesn't change
3854
3855 // dest tail -> source head
3856 this.tail.next = list.head;
3857
3858 // dest tail <- source head
3859 list.head.prev = this.tail;
3860 } else {
3861 // if list has no a tail, then it also has no a head
3862 // in this case points head to new item
3863 this.head = list.head;
3864 }
3865
3866 // tail always start point to new item
3867 this.tail = list.tail;
3868 }
3869
3870 list.head = null;
3871 list.tail = null;
3872
3873 return this;
3874 };
3875
3876 List$6.prototype.replace = function(oldItem, newItemOrList) {
3877 if ('head' in newItemOrList) {
3878 this.insertList(newItemOrList, oldItem);
3879 } else {
3880 this.insert(newItemOrList, oldItem);
3881 }
3882
3883 this.remove(oldItem);
3884 };
3885
3886 var List_1 = List$6;
3887
3888 var createCustomError$3 = function createCustomError(name, message) {
3889 // use Object.create(), because some VMs prevent setting line/column otherwise
3890 // (iOS Safari 10 even throws an exception)
3891 var error = Object.create(SyntaxError.prototype);
3892 var errorStack = new Error();
3893
3894 error.name = name;
3895 error.message = message;
3896
3897 Object.defineProperty(error, 'stack', {
3898 get: function() {
3899 return (errorStack.stack || '').replace(/^(.+\n){1,3}/, name + ': ' + message + '\n');
3900 }
3901 });
3902
3903 return error;
3904 };
3905
3906 var createCustomError$2 = createCustomError$3;
3907 var MAX_LINE_LENGTH = 100;
3908 var OFFSET_CORRECTION = 60;
3909 var TAB_REPLACEMENT = ' ';
3910
3911 function sourceFragment(error, extraLines) {
3912 function processLines(start, end) {
3913 return lines.slice(start, end).map(function(line, idx) {
3914 var num = String(start + idx + 1);
3915
3916 while (num.length < maxNumLength) {
3917 num = ' ' + num;
3918 }
3919
3920 return num + ' |' + line;
3921 }).join('\n');
3922 }
3923
3924 var lines = error.source.split(/\r\n?|\n|\f/);
3925 var line = error.line;
3926 var column = error.column;
3927 var startLine = Math.max(1, line - extraLines) - 1;
3928 var endLine = Math.min(line + extraLines, lines.length + 1);
3929 var maxNumLength = Math.max(4, String(endLine).length) + 1;
3930 var cutLeft = 0;
3931
3932 // column correction according to replaced tab before column
3933 column += (TAB_REPLACEMENT.length - 1) * (lines[line - 1].substr(0, column - 1).match(/\t/g) || []).length;
3934
3935 if (column > MAX_LINE_LENGTH) {
3936 cutLeft = column - OFFSET_CORRECTION + 3;
3937 column = OFFSET_CORRECTION - 2;
3938 }
3939
3940 for (var i = startLine; i <= endLine; i++) {
3941 if (i >= 0 && i < lines.length) {
3942 lines[i] = lines[i].replace(/\t/g, TAB_REPLACEMENT);
3943 lines[i] =
3944 (cutLeft > 0 && lines[i].length > cutLeft ? '\u2026' : '') +
3945 lines[i].substr(cutLeft, MAX_LINE_LENGTH - 2) +
3946 (lines[i].length > cutLeft + MAX_LINE_LENGTH - 1 ? '\u2026' : '');
3947 }
3948 }
3949
3950 return [
3951 processLines(startLine, line),
3952 new Array(column + maxNumLength + 2).join('-') + '^',
3953 processLines(line, endLine)
3954 ].filter(Boolean).join('\n');
3955 }
3956
3957 var SyntaxError$4 = function(message, source, offset, line, column) {
3958 var error = createCustomError$2('SyntaxError', message);
3959
3960 error.source = source;
3961 error.offset = offset;
3962 error.line = line;
3963 error.column = column;
3964
3965 error.sourceFragment = function(extraLines) {
3966 return sourceFragment(error, isNaN(extraLines) ? 0 : extraLines);
3967 };
3968 Object.defineProperty(error, 'formattedMessage', {
3969 get: function() {
3970 return (
3971 'Parse error: ' + error.message + '\n' +
3972 sourceFragment(error, 2)
3973 );
3974 }
3975 });
3976
3977 // for backward capability
3978 error.parseError = {
3979 offset: offset,
3980 line: line,
3981 column: column
3982 };
3983
3984 return error;
3985 };
3986
3987 var _SyntaxError$1 = SyntaxError$4;
3988
3989 // CSS Syntax Module Level 3
3990 // https://www.w3.org/TR/css-syntax-3/
3991 var TYPE$H = {
3992 EOF: 0, // <EOF-token>
3993 Ident: 1, // <ident-token>
3994 Function: 2, // <function-token>
3995 AtKeyword: 3, // <at-keyword-token>
3996 Hash: 4, // <hash-token>
3997 String: 5, // <string-token>
3998 BadString: 6, // <bad-string-token>
3999 Url: 7, // <url-token>
4000 BadUrl: 8, // <bad-url-token>
4001 Delim: 9, // <delim-token>
4002 Number: 10, // <number-token>
4003 Percentage: 11, // <percentage-token>
4004 Dimension: 12, // <dimension-token>
4005 WhiteSpace: 13, // <whitespace-token>
4006 CDO: 14, // <CDO-token>
4007 CDC: 15, // <CDC-token>
4008 Colon: 16, // <colon-token> :
4009 Semicolon: 17, // <semicolon-token> ;
4010 Comma: 18, // <comma-token> ,
4011 LeftSquareBracket: 19, // <[-token>
4012 RightSquareBracket: 20, // <]-token>
4013 LeftParenthesis: 21, // <(-token>
4014 RightParenthesis: 22, // <)-token>
4015 LeftCurlyBracket: 23, // <{-token>
4016 RightCurlyBracket: 24, // <}-token>
4017 Comment: 25
4018 };
4019
4020 var NAME$3 = Object.keys(TYPE$H).reduce(function(result, key) {
4021 result[TYPE$H[key]] = key;
4022 return result;
4023 }, {});
4024
4025 var _const = {
4026 TYPE: TYPE$H,
4027 NAME: NAME$3
4028 };
4029
4030 var EOF$1 = 0;
4031
4032 // https://drafts.csswg.org/css-syntax-3/
4033 // § 4.2. Definitions
4034
4035 // digit
4036 // A code point between U+0030 DIGIT ZERO (0) and U+0039 DIGIT NINE (9).
4037 function isDigit$5(code) {
4038 return code >= 0x0030 && code <= 0x0039;
4039 }
4040
4041 // hex digit
4042 // A digit, or a code point between U+0041 LATIN CAPITAL LETTER A (A) and U+0046 LATIN CAPITAL LETTER F (F),
4043 // or a code point between U+0061 LATIN SMALL LETTER A (a) and U+0066 LATIN SMALL LETTER F (f).
4044 function isHexDigit$4(code) {
4045 return (
4046 isDigit$5(code) || // 0 .. 9
4047 (code >= 0x0041 && code <= 0x0046) || // A .. F
4048 (code >= 0x0061 && code <= 0x0066) // a .. f
4049 );
4050 }
4051
4052 // uppercase letter
4053 // A code point between U+0041 LATIN CAPITAL LETTER A (A) and U+005A LATIN CAPITAL LETTER Z (Z).
4054 function isUppercaseLetter$1(code) {
4055 return code >= 0x0041 && code <= 0x005A;
4056 }
4057
4058 // lowercase letter
4059 // A code point between U+0061 LATIN SMALL LETTER A (a) and U+007A LATIN SMALL LETTER Z (z).
4060 function isLowercaseLetter(code) {
4061 return code >= 0x0061 && code <= 0x007A;
4062 }
4063
4064 // letter
4065 // An uppercase letter or a lowercase letter.
4066 function isLetter(code) {
4067 return isUppercaseLetter$1(code) || isLowercaseLetter(code);
4068 }
4069
4070 // non-ASCII code point
4071 // A code point with a value equal to or greater than U+0080 <control>.
4072 function isNonAscii(code) {
4073 return code >= 0x0080;
4074 }
4075
4076 // name-start code point
4077 // A letter, a non-ASCII code point, or U+005F LOW LINE (_).
4078 function isNameStart(code) {
4079 return isLetter(code) || isNonAscii(code) || code === 0x005F;
4080 }
4081
4082 // name code point
4083 // A name-start code point, a digit, or U+002D HYPHEN-MINUS (-).
4084 function isName$2(code) {
4085 return isNameStart(code) || isDigit$5(code) || code === 0x002D;
4086 }
4087
4088 // non-printable code point
4089 // A code point between U+0000 NULL and U+0008 BACKSPACE, or U+000B LINE TABULATION,
4090 // or a code point between U+000E SHIFT OUT and U+001F INFORMATION SEPARATOR ONE, or U+007F DELETE.
4091 function isNonPrintable(code) {
4092 return (
4093 (code >= 0x0000 && code <= 0x0008) ||
4094 (code === 0x000B) ||
4095 (code >= 0x000E && code <= 0x001F) ||
4096 (code === 0x007F)
4097 );
4098 }
4099
4100 // newline
4101 // U+000A LINE FEED. Note that U+000D CARRIAGE RETURN and U+000C FORM FEED are not included in this definition,
4102 // as they are converted to U+000A LINE FEED during preprocessing.
4103 // TODO: we doesn't do a preprocessing, so check a code point for U+000D CARRIAGE RETURN and U+000C FORM FEED
4104 function isNewline$1(code) {
4105 return code === 0x000A || code === 0x000D || code === 0x000C;
4106 }
4107
4108 // whitespace
4109 // A newline, U+0009 CHARACTER TABULATION, or U+0020 SPACE.
4110 function isWhiteSpace$2(code) {
4111 return isNewline$1(code) || code === 0x0020 || code === 0x0009;
4112 }
4113
4114 // § 4.3.8. Check if two code points are a valid escape
4115 function isValidEscape$2(first, second) {
4116 // If the first code point is not U+005C REVERSE SOLIDUS (\), return false.
4117 if (first !== 0x005C) {
4118 return false;
4119 }
4120
4121 // Otherwise, if the second code point is a newline or EOF, return false.
4122 if (isNewline$1(second) || second === EOF$1) {
4123 return false;
4124 }
4125
4126 // Otherwise, return true.
4127 return true;
4128 }
4129
4130 // § 4.3.9. Check if three code points would start an identifier
4131 function isIdentifierStart$2(first, second, third) {
4132 // Look at the first code point:
4133
4134 // U+002D HYPHEN-MINUS
4135 if (first === 0x002D) {
4136 // If the second code point is a name-start code point or a U+002D HYPHEN-MINUS,
4137 // or the second and third code points are a valid escape, return true. Otherwise, return false.
4138 return (
4139 isNameStart(second) ||
4140 second === 0x002D ||
4141 isValidEscape$2(second, third)
4142 );
4143 }
4144
4145 // name-start code point
4146 if (isNameStart(first)) {
4147 // Return true.
4148 return true;
4149 }
4150
4151 // U+005C REVERSE SOLIDUS (\)
4152 if (first === 0x005C) {
4153 // If the first and second code points are a valid escape, return true. Otherwise, return false.
4154 return isValidEscape$2(first, second);
4155 }
4156
4157 // anything else
4158 // Return false.
4159 return false;
4160 }
4161
4162 // § 4.3.10. Check if three code points would start a number
4163 function isNumberStart$1(first, second, third) {
4164 // Look at the first code point:
4165
4166 // U+002B PLUS SIGN (+)
4167 // U+002D HYPHEN-MINUS (-)
4168 if (first === 0x002B || first === 0x002D) {
4169 // If the second code point is a digit, return true.
4170 if (isDigit$5(second)) {
4171 return 2;
4172 }
4173
4174 // Otherwise, if the second code point is a U+002E FULL STOP (.)
4175 // and the third code point is a digit, return true.
4176 // Otherwise, return false.
4177 return second === 0x002E && isDigit$5(third) ? 3 : 0;
4178 }
4179
4180 // U+002E FULL STOP (.)
4181 if (first === 0x002E) {
4182 // If the second code point is a digit, return true. Otherwise, return false.
4183 return isDigit$5(second) ? 2 : 0;
4184 }
4185
4186 // digit
4187 if (isDigit$5(first)) {
4188 // Return true.
4189 return 1;
4190 }
4191
4192 // anything else
4193 // Return false.
4194 return 0;
4195 }
4196
4197 //
4198 // Misc
4199 //
4200
4201 // detect BOM (https://en.wikipedia.org/wiki/Byte_order_mark)
4202 function isBOM$2(code) {
4203 // UTF-16BE
4204 if (code === 0xFEFF) {
4205 return 1;
4206 }
4207
4208 // UTF-16LE
4209 if (code === 0xFFFE) {
4210 return 1;
4211 }
4212
4213 return 0;
4214 }
4215
4216 // Fast code category
4217 //
4218 // https://drafts.csswg.org/css-syntax/#tokenizer-definitions
4219 // > non-ASCII code point
4220 // > A code point with a value equal to or greater than U+0080 <control>
4221 // > name-start code point
4222 // > A letter, a non-ASCII code point, or U+005F LOW LINE (_).
4223 // > name code point
4224 // > A name-start code point, a digit, or U+002D HYPHEN-MINUS (-)
4225 // That means only ASCII code points has a special meaning and we define a maps for 0..127 codes only
4226 var CATEGORY = new Array(0x80);
4227 charCodeCategory$1.Eof = 0x80;
4228 charCodeCategory$1.WhiteSpace = 0x82;
4229 charCodeCategory$1.Digit = 0x83;
4230 charCodeCategory$1.NameStart = 0x84;
4231 charCodeCategory$1.NonPrintable = 0x85;
4232
4233 for (var i = 0; i < CATEGORY.length; i++) {
4234 switch (true) {
4235 case isWhiteSpace$2(i):
4236 CATEGORY[i] = charCodeCategory$1.WhiteSpace;
4237 break;
4238
4239 case isDigit$5(i):
4240 CATEGORY[i] = charCodeCategory$1.Digit;
4241 break;
4242
4243 case isNameStart(i):
4244 CATEGORY[i] = charCodeCategory$1.NameStart;
4245 break;
4246
4247 case isNonPrintable(i):
4248 CATEGORY[i] = charCodeCategory$1.NonPrintable;
4249 break;
4250
4251 default:
4252 CATEGORY[i] = i || charCodeCategory$1.Eof;
4253 }
4254 }
4255
4256 function charCodeCategory$1(code) {
4257 return code < 0x80 ? CATEGORY[code] : charCodeCategory$1.NameStart;
4258 }
4259 var charCodeDefinitions$1 = {
4260 isDigit: isDigit$5,
4261 isHexDigit: isHexDigit$4,
4262 isUppercaseLetter: isUppercaseLetter$1,
4263 isLowercaseLetter: isLowercaseLetter,
4264 isLetter: isLetter,
4265 isNonAscii: isNonAscii,
4266 isNameStart: isNameStart,
4267 isName: isName$2,
4268 isNonPrintable: isNonPrintable,
4269 isNewline: isNewline$1,
4270 isWhiteSpace: isWhiteSpace$2,
4271 isValidEscape: isValidEscape$2,
4272 isIdentifierStart: isIdentifierStart$2,
4273 isNumberStart: isNumberStart$1,
4274
4275 isBOM: isBOM$2,
4276 charCodeCategory: charCodeCategory$1
4277 };
4278
4279 var charCodeDef = charCodeDefinitions$1;
4280 var isDigit$4 = charCodeDef.isDigit;
4281 var isHexDigit$3 = charCodeDef.isHexDigit;
4282 var isUppercaseLetter = charCodeDef.isUppercaseLetter;
4283 var isName$1 = charCodeDef.isName;
4284 var isWhiteSpace$1 = charCodeDef.isWhiteSpace;
4285 var isValidEscape$1 = charCodeDef.isValidEscape;
4286
4287 function getCharCode(source, offset) {
4288 return offset < source.length ? source.charCodeAt(offset) : 0;
4289 }
4290
4291 function getNewlineLength$1(source, offset, code) {
4292 if (code === 13 /* \r */ && getCharCode(source, offset + 1) === 10 /* \n */) {
4293 return 2;
4294 }
4295
4296 return 1;
4297 }
4298
4299 function cmpChar$5(testStr, offset, referenceCode) {
4300 var code = testStr.charCodeAt(offset);
4301
4302 // code.toLowerCase() for A..Z
4303 if (isUppercaseLetter(code)) {
4304 code = code | 32;
4305 }
4306
4307 return code === referenceCode;
4308 }
4309
4310 function cmpStr$6(testStr, start, end, referenceStr) {
4311 if (end - start !== referenceStr.length) {
4312 return false;
4313 }
4314
4315 if (start < 0 || end > testStr.length) {
4316 return false;
4317 }
4318
4319 for (var i = start; i < end; i++) {
4320 var testCode = testStr.charCodeAt(i);
4321 var referenceCode = referenceStr.charCodeAt(i - start);
4322
4323 // testCode.toLowerCase() for A..Z
4324 if (isUppercaseLetter(testCode)) {
4325 testCode = testCode | 32;
4326 }
4327
4328 if (testCode !== referenceCode) {
4329 return false;
4330 }
4331 }
4332
4333 return true;
4334 }
4335
4336 function findWhiteSpaceStart$1(source, offset) {
4337 for (; offset >= 0; offset--) {
4338 if (!isWhiteSpace$1(source.charCodeAt(offset))) {
4339 break;
4340 }
4341 }
4342
4343 return offset + 1;
4344 }
4345
4346 function findWhiteSpaceEnd$1(source, offset) {
4347 for (; offset < source.length; offset++) {
4348 if (!isWhiteSpace$1(source.charCodeAt(offset))) {
4349 break;
4350 }
4351 }
4352
4353 return offset;
4354 }
4355
4356 function findDecimalNumberEnd(source, offset) {
4357 for (; offset < source.length; offset++) {
4358 if (!isDigit$4(source.charCodeAt(offset))) {
4359 break;
4360 }
4361 }
4362
4363 return offset;
4364 }
4365
4366 // § 4.3.7. Consume an escaped code point
4367 function consumeEscaped$1(source, offset) {
4368 // It assumes that the U+005C REVERSE SOLIDUS (\) has already been consumed and
4369 // that the next input code point has already been verified to be part of a valid escape.
4370 offset += 2;
4371
4372 // hex digit
4373 if (isHexDigit$3(getCharCode(source, offset - 1))) {
4374 // Consume as many hex digits as possible, but no more than 5.
4375 // Note that this means 1-6 hex digits have been consumed in total.
4376 for (var maxOffset = Math.min(source.length, offset + 5); offset < maxOffset; offset++) {
4377 if (!isHexDigit$3(getCharCode(source, offset))) {
4378 break;
4379 }
4380 }
4381
4382 // If the next input code point is whitespace, consume it as well.
4383 var code = getCharCode(source, offset);
4384 if (isWhiteSpace$1(code)) {
4385 offset += getNewlineLength$1(source, offset, code);
4386 }
4387 }
4388
4389 return offset;
4390 }
4391
4392 // §4.3.11. Consume a name
4393 // Note: This algorithm does not do the verification of the first few code points that are necessary
4394 // to ensure the returned code points would constitute an <ident-token>. If that is the intended use,
4395 // ensure that the stream starts with an identifier before calling this algorithm.
4396 function consumeName$1(source, offset) {
4397 // Let result initially be an empty string.
4398 // Repeatedly consume the next input code point from the stream:
4399 for (; offset < source.length; offset++) {
4400 var code = source.charCodeAt(offset);
4401
4402 // name code point
4403 if (isName$1(code)) {
4404 // Append the code point to result.
4405 continue;
4406 }
4407
4408 // the stream starts with a valid escape
4409 if (isValidEscape$1(code, getCharCode(source, offset + 1))) {
4410 // Consume an escaped code point. Append the returned code point to result.
4411 offset = consumeEscaped$1(source, offset) - 1;
4412 continue;
4413 }
4414
4415 // anything else
4416 // Reconsume the current input code point. Return result.
4417 break;
4418 }
4419
4420 return offset;
4421 }
4422
4423 // §4.3.12. Consume a number
4424 function consumeNumber$5(source, offset) {
4425 var code = source.charCodeAt(offset);
4426
4427 // 2. If the next input code point is U+002B PLUS SIGN (+) or U+002D HYPHEN-MINUS (-),
4428 // consume it and append it to repr.
4429 if (code === 0x002B || code === 0x002D) {
4430 code = source.charCodeAt(offset += 1);
4431 }
4432
4433 // 3. While the next input code point is a digit, consume it and append it to repr.
4434 if (isDigit$4(code)) {
4435 offset = findDecimalNumberEnd(source, offset + 1);
4436 code = source.charCodeAt(offset);
4437 }
4438
4439 // 4. If the next 2 input code points are U+002E FULL STOP (.) followed by a digit, then:
4440 if (code === 0x002E && isDigit$4(source.charCodeAt(offset + 1))) {
4441 // 4.1 Consume them.
4442 // 4.2 Append them to repr.
4443 code = source.charCodeAt(offset += 2);
4444
4445 // 4.3 Set type to "number".
4446 // TODO
4447
4448 // 4.4 While the next input code point is a digit, consume it and append it to repr.
4449
4450 offset = findDecimalNumberEnd(source, offset);
4451 }
4452
4453 // 5. If the next 2 or 3 input code points are U+0045 LATIN CAPITAL LETTER E (E)
4454 // or U+0065 LATIN SMALL LETTER E (e), ... , followed by a digit, then:
4455 if (cmpChar$5(source, offset, 101 /* e */)) {
4456 var sign = 0;
4457 code = source.charCodeAt(offset + 1);
4458
4459 // ... optionally followed by U+002D HYPHEN-MINUS (-) or U+002B PLUS SIGN (+) ...
4460 if (code === 0x002D || code === 0x002B) {
4461 sign = 1;
4462 code = source.charCodeAt(offset + 2);
4463 }
4464
4465 // ... followed by a digit
4466 if (isDigit$4(code)) {
4467 // 5.1 Consume them.
4468 // 5.2 Append them to repr.
4469
4470 // 5.3 Set type to "number".
4471 // TODO
4472
4473 // 5.4 While the next input code point is a digit, consume it and append it to repr.
4474 offset = findDecimalNumberEnd(source, offset + 1 + sign + 1);
4475 }
4476 }
4477
4478 return offset;
4479 }
4480
4481 // § 4.3.14. Consume the remnants of a bad url
4482 // ... its sole use is to consume enough of the input stream to reach a recovery point
4483 // where normal tokenizing can resume.
4484 function consumeBadUrlRemnants$1(source, offset) {
4485 // Repeatedly consume the next input code point from the stream:
4486 for (; offset < source.length; offset++) {
4487 var code = source.charCodeAt(offset);
4488
4489 // U+0029 RIGHT PARENTHESIS ())
4490 // EOF
4491 if (code === 0x0029) {
4492 // Return.
4493 offset++;
4494 break;
4495 }
4496
4497 if (isValidEscape$1(code, getCharCode(source, offset + 1))) {
4498 // Consume an escaped code point.
4499 // Note: This allows an escaped right parenthesis ("\)") to be encountered
4500 // without ending the <bad-url-token>. This is otherwise identical to
4501 // the "anything else" clause.
4502 offset = consumeEscaped$1(source, offset);
4503 }
4504 }
4505
4506 return offset;
4507 }
4508
4509 var utils$2 = {
4510 consumeEscaped: consumeEscaped$1,
4511 consumeName: consumeName$1,
4512 consumeNumber: consumeNumber$5,
4513 consumeBadUrlRemnants: consumeBadUrlRemnants$1,
4514
4515 cmpChar: cmpChar$5,
4516 cmpStr: cmpStr$6,
4517
4518 getNewlineLength: getNewlineLength$1,
4519 findWhiteSpaceStart: findWhiteSpaceStart$1,
4520 findWhiteSpaceEnd: findWhiteSpaceEnd$1
4521 };
4522
4523 var constants$2 = _const;
4524 var TYPE$G = constants$2.TYPE;
4525 var NAME$2 = constants$2.NAME;
4526
4527 var utils$1 = utils$2;
4528 var cmpStr$5 = utils$1.cmpStr;
4529
4530 var EOF = TYPE$G.EOF;
4531 var WHITESPACE$c = TYPE$G.WhiteSpace;
4532 var COMMENT$a = TYPE$G.Comment;
4533
4534 var OFFSET_MASK$1 = 0x00FFFFFF;
4535 var TYPE_SHIFT$1 = 24;
4536
4537 var TokenStream$4 = function() {
4538 this.offsetAndType = null;
4539 this.balance = null;
4540
4541 this.reset();
4542 };
4543
4544 TokenStream$4.prototype = {
4545 reset: function() {
4546 this.eof = false;
4547 this.tokenIndex = -1;
4548 this.tokenType = 0;
4549 this.tokenStart = this.firstCharOffset;
4550 this.tokenEnd = this.firstCharOffset;
4551 },
4552
4553 lookupType: function(offset) {
4554 offset += this.tokenIndex;
4555
4556 if (offset < this.tokenCount) {
4557 return this.offsetAndType[offset] >> TYPE_SHIFT$1;
4558 }
4559
4560 return EOF;
4561 },
4562 lookupOffset: function(offset) {
4563 offset += this.tokenIndex;
4564
4565 if (offset < this.tokenCount) {
4566 return this.offsetAndType[offset - 1] & OFFSET_MASK$1;
4567 }
4568
4569 return this.source.length;
4570 },
4571 lookupValue: function(offset, referenceStr) {
4572 offset += this.tokenIndex;
4573
4574 if (offset < this.tokenCount) {
4575 return cmpStr$5(
4576 this.source,
4577 this.offsetAndType[offset - 1] & OFFSET_MASK$1,
4578 this.offsetAndType[offset] & OFFSET_MASK$1,
4579 referenceStr
4580 );
4581 }
4582
4583 return false;
4584 },
4585 getTokenStart: function(tokenIndex) {
4586 if (tokenIndex === this.tokenIndex) {
4587 return this.tokenStart;
4588 }
4589
4590 if (tokenIndex > 0) {
4591 return tokenIndex < this.tokenCount
4592 ? this.offsetAndType[tokenIndex - 1] & OFFSET_MASK$1
4593 : this.offsetAndType[this.tokenCount] & OFFSET_MASK$1;
4594 }
4595
4596 return this.firstCharOffset;
4597 },
4598
4599 // TODO: -> skipUntilBalanced
4600 getRawLength: function(startToken, mode) {
4601 var cursor = startToken;
4602 var balanceEnd;
4603 var offset = this.offsetAndType[Math.max(cursor - 1, 0)] & OFFSET_MASK$1;
4604 var type;
4605
4606 loop:
4607 for (; cursor < this.tokenCount; cursor++) {
4608 balanceEnd = this.balance[cursor];
4609
4610 // stop scanning on balance edge that points to offset before start token
4611 if (balanceEnd < startToken) {
4612 break loop;
4613 }
4614
4615 type = this.offsetAndType[cursor] >> TYPE_SHIFT$1;
4616
4617 // check token is stop type
4618 switch (mode(type, this.source, offset)) {
4619 case 1:
4620 break loop;
4621
4622 case 2:
4623 cursor++;
4624 break loop;
4625
4626 default:
4627 // fast forward to the end of balanced block
4628 if (this.balance[balanceEnd] === cursor) {
4629 cursor = balanceEnd;
4630 }
4631
4632 offset = this.offsetAndType[cursor] & OFFSET_MASK$1;
4633 }
4634 }
4635
4636 return cursor - this.tokenIndex;
4637 },
4638 isBalanceEdge: function(pos) {
4639 return this.balance[this.tokenIndex] < pos;
4640 },
4641 isDelim: function(code, offset) {
4642 if (offset) {
4643 return (
4644 this.lookupType(offset) === TYPE$G.Delim &&
4645 this.source.charCodeAt(this.lookupOffset(offset)) === code
4646 );
4647 }
4648
4649 return (
4650 this.tokenType === TYPE$G.Delim &&
4651 this.source.charCodeAt(this.tokenStart) === code
4652 );
4653 },
4654
4655 getTokenValue: function() {
4656 return this.source.substring(this.tokenStart, this.tokenEnd);
4657 },
4658 getTokenLength: function() {
4659 return this.tokenEnd - this.tokenStart;
4660 },
4661 substrToCursor: function(start) {
4662 return this.source.substring(start, this.tokenStart);
4663 },
4664
4665 skipWS: function() {
4666 for (var i = this.tokenIndex, skipTokenCount = 0; i < this.tokenCount; i++, skipTokenCount++) {
4667 if ((this.offsetAndType[i] >> TYPE_SHIFT$1) !== WHITESPACE$c) {
4668 break;
4669 }
4670 }
4671
4672 if (skipTokenCount > 0) {
4673 this.skip(skipTokenCount);
4674 }
4675 },
4676 skipSC: function() {
4677 while (this.tokenType === WHITESPACE$c || this.tokenType === COMMENT$a) {
4678 this.next();
4679 }
4680 },
4681 skip: function(tokenCount) {
4682 var next = this.tokenIndex + tokenCount;
4683
4684 if (next < this.tokenCount) {
4685 this.tokenIndex = next;
4686 this.tokenStart = this.offsetAndType[next - 1] & OFFSET_MASK$1;
4687 next = this.offsetAndType[next];
4688 this.tokenType = next >> TYPE_SHIFT$1;
4689 this.tokenEnd = next & OFFSET_MASK$1;
4690 } else {
4691 this.tokenIndex = this.tokenCount;
4692 this.next();
4693 }
4694 },
4695 next: function() {
4696 var next = this.tokenIndex + 1;
4697
4698 if (next < this.tokenCount) {
4699 this.tokenIndex = next;
4700 this.tokenStart = this.tokenEnd;
4701 next = this.offsetAndType[next];
4702 this.tokenType = next >> TYPE_SHIFT$1;
4703 this.tokenEnd = next & OFFSET_MASK$1;
4704 } else {
4705 this.tokenIndex = this.tokenCount;
4706 this.eof = true;
4707 this.tokenType = EOF;
4708 this.tokenStart = this.tokenEnd = this.source.length;
4709 }
4710 },
4711
4712 forEachToken(fn) {
4713 for (var i = 0, offset = this.firstCharOffset; i < this.tokenCount; i++) {
4714 var start = offset;
4715 var item = this.offsetAndType[i];
4716 var end = item & OFFSET_MASK$1;
4717 var type = item >> TYPE_SHIFT$1;
4718
4719 offset = end;
4720
4721 fn(type, start, end, i);
4722 }
4723 },
4724
4725 dump() {
4726 var tokens = new Array(this.tokenCount);
4727
4728 this.forEachToken((type, start, end, index) => {
4729 tokens[index] = {
4730 idx: index,
4731 type: NAME$2[type],
4732 chunk: this.source.substring(start, end),
4733 balance: this.balance[index]
4734 };
4735 });
4736
4737 return tokens;
4738 }
4739 };
4740
4741 var TokenStream_1 = TokenStream$4;
4742
4743 function noop$3(value) {
4744 return value;
4745 }
4746
4747 function generateMultiplier(multiplier) {
4748 if (multiplier.min === 0 && multiplier.max === 0) {
4749 return '*';
4750 }
4751
4752 if (multiplier.min === 0 && multiplier.max === 1) {
4753 return '?';
4754 }
4755
4756 if (multiplier.min === 1 && multiplier.max === 0) {
4757 return multiplier.comma ? '#' : '+';
4758 }
4759
4760 if (multiplier.min === 1 && multiplier.max === 1) {
4761 return '';
4762 }
4763
4764 return (
4765 (multiplier.comma ? '#' : '') +
4766 (multiplier.min === multiplier.max
4767 ? '{' + multiplier.min + '}'
4768 : '{' + multiplier.min + ',' + (multiplier.max !== 0 ? multiplier.max : '') + '}'
4769 )
4770 );
4771 }
4772
4773 function generateTypeOpts(node) {
4774 switch (node.type) {
4775 case 'Range':
4776 return (
4777 ' [' +
4778 (node.min === null ? '-∞' : node.min) +
4779 ',' +
4780 (node.max === null ? '∞' : node.max) +
4781 ']'
4782 );
4783
4784 default:
4785 throw new Error('Unknown node type `' + node.type + '`');
4786 }
4787 }
4788
4789 function generateSequence(node, decorate, forceBraces, compact) {
4790 var combinator = node.combinator === ' ' || compact ? node.combinator : ' ' + node.combinator + ' ';
4791 var result = node.terms.map(function(term) {
4792 return generate$2(term, decorate, forceBraces, compact);
4793 }).join(combinator);
4794
4795 if (node.explicit || forceBraces) {
4796 result = (compact || result[0] === ',' ? '[' : '[ ') + result + (compact ? ']' : ' ]');
4797 }
4798
4799 return result;
4800 }
4801
4802 function generate$2(node, decorate, forceBraces, compact) {
4803 var result;
4804
4805 switch (node.type) {
4806 case 'Group':
4807 result =
4808 generateSequence(node, decorate, forceBraces, compact) +
4809 (node.disallowEmpty ? '!' : '');
4810 break;
4811
4812 case 'Multiplier':
4813 // return since node is a composition
4814 return (
4815 generate$2(node.term, decorate, forceBraces, compact) +
4816 decorate(generateMultiplier(node), node)
4817 );
4818
4819 case 'Type':
4820 result = '<' + node.name + (node.opts ? decorate(generateTypeOpts(node.opts), node.opts) : '') + '>';
4821 break;
4822
4823 case 'Property':
4824 result = '<\'' + node.name + '\'>';
4825 break;
4826
4827 case 'Keyword':
4828 result = node.name;
4829 break;
4830
4831 case 'AtKeyword':
4832 result = '@' + node.name;
4833 break;
4834
4835 case 'Function':
4836 result = node.name + '(';
4837 break;
4838
4839 case 'String':
4840 case 'Token':
4841 result = node.value;
4842 break;
4843
4844 case 'Comma':
4845 result = ',';
4846 break;
4847
4848 default:
4849 throw new Error('Unknown node type `' + node.type + '`');
4850 }
4851
4852 return decorate(result, node);
4853 }
4854
4855 var generate_1 = function(node, options) {
4856 var decorate = noop$3;
4857 var forceBraces = false;
4858 var compact = false;
4859
4860 if (typeof options === 'function') {
4861 decorate = options;
4862 } else if (options) {
4863 forceBraces = Boolean(options.forceBraces);
4864 compact = Boolean(options.compact);
4865 if (typeof options.decorate === 'function') {
4866 decorate = options.decorate;
4867 }
4868 }
4869
4870 return generate$2(node, decorate, forceBraces, compact);
4871 };
4872
4873 const createCustomError$1 = createCustomError$3;
4874 const generate$1 = generate_1;
4875 const defaultLoc = { offset: 0, line: 1, column: 1 };
4876
4877 function locateMismatch(matchResult, node) {
4878 const tokens = matchResult.tokens;
4879 const longestMatch = matchResult.longestMatch;
4880 const mismatchNode = longestMatch < tokens.length ? tokens[longestMatch].node || null : null;
4881 const badNode = mismatchNode !== node ? mismatchNode : null;
4882 let mismatchOffset = 0;
4883 let mismatchLength = 0;
4884 let entries = 0;
4885 let css = '';
4886 let start;
4887 let end;
4888
4889 for (let i = 0; i < tokens.length; i++) {
4890 const token = tokens[i].value;
4891
4892 if (i === longestMatch) {
4893 mismatchLength = token.length;
4894 mismatchOffset = css.length;
4895 }
4896
4897 if (badNode !== null && tokens[i].node === badNode) {
4898 if (i <= longestMatch) {
4899 entries++;
4900 } else {
4901 entries = 0;
4902 }
4903 }
4904
4905 css += token;
4906 }
4907
4908 if (longestMatch === tokens.length || entries > 1) { // last
4909 start = fromLoc(badNode || node, 'end') || buildLoc(defaultLoc, css);
4910 end = buildLoc(start);
4911 } else {
4912 start = fromLoc(badNode, 'start') ||
4913 buildLoc(fromLoc(node, 'start') || defaultLoc, css.slice(0, mismatchOffset));
4914 end = fromLoc(badNode, 'end') ||
4915 buildLoc(start, css.substr(mismatchOffset, mismatchLength));
4916 }
4917
4918 return {
4919 css,
4920 mismatchOffset,
4921 mismatchLength,
4922 start,
4923 end
4924 };
4925 }
4926
4927 function fromLoc(node, point) {
4928 const value = node && node.loc && node.loc[point];
4929
4930 if (value) {
4931 return 'line' in value ? buildLoc(value) : value;
4932 }
4933
4934 return null;
4935 }
4936
4937 function buildLoc({ offset, line, column }, extra) {
4938 const loc = {
4939 offset,
4940 line,
4941 column
4942 };
4943
4944 if (extra) {
4945 const lines = extra.split(/\n|\r\n?|\f/);
4946
4947 loc.offset += extra.length;
4948 loc.line += lines.length - 1;
4949 loc.column = lines.length === 1 ? loc.column + extra.length : lines.pop().length + 1;
4950 }
4951
4952 return loc;
4953 }
4954
4955 const SyntaxReferenceError$1 = function(type, referenceName) {
4956 const error = createCustomError$1(
4957 'SyntaxReferenceError',
4958 type + (referenceName ? ' `' + referenceName + '`' : '')
4959 );
4960
4961 error.reference = referenceName;
4962
4963 return error;
4964 };
4965
4966 const SyntaxMatchError$1 = function(message, syntax, node, matchResult) {
4967 const error = createCustomError$1('SyntaxMatchError', message);
4968 const {
4969 css,
4970 mismatchOffset,
4971 mismatchLength,
4972 start,
4973 end
4974 } = locateMismatch(matchResult, node);
4975
4976 error.rawMessage = message;
4977 error.syntax = syntax ? generate$1(syntax) : '<generic>';
4978 error.css = css;
4979 error.mismatchOffset = mismatchOffset;
4980 error.mismatchLength = mismatchLength;
4981 error.message = message + '\n' +
4982 ' syntax: ' + error.syntax + '\n' +
4983 ' value: ' + (css || '<empty string>') + '\n' +
4984 ' --------' + new Array(error.mismatchOffset + 1).join('-') + '^';
4985
4986 Object.assign(error, start);
4987 error.loc = {
4988 source: (node && node.loc && node.loc.source) || '<unknown>',
4989 start,
4990 end
4991 };
4992
4993 return error;
4994 };
4995
4996 var error = {
4997 SyntaxReferenceError: SyntaxReferenceError$1,
4998 SyntaxMatchError: SyntaxMatchError$1
4999 };
5000
5001 var hasOwnProperty$7 = Object.prototype.hasOwnProperty;
5002 var keywords$1 = Object.create(null);
5003 var properties$1 = Object.create(null);
5004 var HYPHENMINUS$5 = 45; // '-'.charCodeAt()
5005
5006 function isCustomProperty$1(str, offset) {
5007 offset = offset || 0;
5008
5009 return str.length - offset >= 2 &&
5010 str.charCodeAt(offset) === HYPHENMINUS$5 &&
5011 str.charCodeAt(offset + 1) === HYPHENMINUS$5;
5012 }
5013
5014 function getVendorPrefix(str, offset) {
5015 offset = offset || 0;
5016
5017 // verdor prefix should be at least 3 chars length
5018 if (str.length - offset >= 3) {
5019 // vendor prefix starts with hyper minus following non-hyper minus
5020 if (str.charCodeAt(offset) === HYPHENMINUS$5 &&
5021 str.charCodeAt(offset + 1) !== HYPHENMINUS$5) {
5022 // vendor prefix should contain a hyper minus at the ending
5023 var secondDashIndex = str.indexOf('-', offset + 2);
5024
5025 if (secondDashIndex !== -1) {
5026 return str.substring(offset, secondDashIndex + 1);
5027 }
5028 }
5029 }
5030
5031 return '';
5032 }
5033
5034 function getKeywordDescriptor(keyword) {
5035 if (hasOwnProperty$7.call(keywords$1, keyword)) {
5036 return keywords$1[keyword];
5037 }
5038
5039 var name = keyword.toLowerCase();
5040
5041 if (hasOwnProperty$7.call(keywords$1, name)) {
5042 return keywords$1[keyword] = keywords$1[name];
5043 }
5044
5045 var custom = isCustomProperty$1(name, 0);
5046 var vendor = !custom ? getVendorPrefix(name, 0) : '';
5047
5048 return keywords$1[keyword] = Object.freeze({
5049 basename: name.substr(vendor.length),
5050 name: name,
5051 vendor: vendor,
5052 prefix: vendor,
5053 custom: custom
5054 });
5055 }
5056
5057 function getPropertyDescriptor(property) {
5058 if (hasOwnProperty$7.call(properties$1, property)) {
5059 return properties$1[property];
5060 }
5061
5062 var name = property;
5063 var hack = property[0];
5064
5065 if (hack === '/') {
5066 hack = property[1] === '/' ? '//' : '/';
5067 } else if (hack !== '_' &&
5068 hack !== '*' &&
5069 hack !== '$' &&
5070 hack !== '#' &&
5071 hack !== '+' &&
5072 hack !== '&') {
5073 hack = '';
5074 }
5075
5076 var custom = isCustomProperty$1(name, hack.length);
5077
5078 // re-use result when possible (the same as for lower case)
5079 if (!custom) {
5080 name = name.toLowerCase();
5081 if (hasOwnProperty$7.call(properties$1, name)) {
5082 return properties$1[property] = properties$1[name];
5083 }
5084 }
5085
5086 var vendor = !custom ? getVendorPrefix(name, hack.length) : '';
5087 var prefix = name.substr(0, hack.length + vendor.length);
5088
5089 return properties$1[property] = Object.freeze({
5090 basename: name.substr(prefix.length),
5091 name: name.substr(hack.length),
5092 hack: hack,
5093 vendor: vendor,
5094 prefix: prefix,
5095 custom: custom
5096 });
5097 }
5098
5099 var names$2 = {
5100 keyword: getKeywordDescriptor,
5101 property: getPropertyDescriptor,
5102 isCustomProperty: isCustomProperty$1,
5103 vendorPrefix: getVendorPrefix
5104 };
5105
5106 var MIN_SIZE = 16 * 1024;
5107 var SafeUint32Array = typeof Uint32Array !== 'undefined' ? Uint32Array : Array; // fallback on Array when TypedArray is not supported
5108
5109 var adoptBuffer$2 = function adoptBuffer(buffer, size) {
5110 if (buffer === null || buffer.length < size) {
5111 return new SafeUint32Array(Math.max(size + 1024, MIN_SIZE));
5112 }
5113
5114 return buffer;
5115 };
5116
5117 var TokenStream$3 = TokenStream_1;
5118 var adoptBuffer$1 = adoptBuffer$2;
5119
5120 var constants$1 = _const;
5121 var TYPE$F = constants$1.TYPE;
5122
5123 var charCodeDefinitions = charCodeDefinitions$1;
5124 var isNewline = charCodeDefinitions.isNewline;
5125 var isName = charCodeDefinitions.isName;
5126 var isValidEscape = charCodeDefinitions.isValidEscape;
5127 var isNumberStart = charCodeDefinitions.isNumberStart;
5128 var isIdentifierStart$1 = charCodeDefinitions.isIdentifierStart;
5129 var charCodeCategory = charCodeDefinitions.charCodeCategory;
5130 var isBOM$1 = charCodeDefinitions.isBOM;
5131
5132 var utils = utils$2;
5133 var cmpStr$4 = utils.cmpStr;
5134 var getNewlineLength = utils.getNewlineLength;
5135 var findWhiteSpaceEnd = utils.findWhiteSpaceEnd;
5136 var consumeEscaped = utils.consumeEscaped;
5137 var consumeName = utils.consumeName;
5138 var consumeNumber$4 = utils.consumeNumber;
5139 var consumeBadUrlRemnants = utils.consumeBadUrlRemnants;
5140
5141 var OFFSET_MASK = 0x00FFFFFF;
5142 var TYPE_SHIFT = 24;
5143
5144 function tokenize$3(source, stream) {
5145 function getCharCode(offset) {
5146 return offset < sourceLength ? source.charCodeAt(offset) : 0;
5147 }
5148
5149 // § 4.3.3. Consume a numeric token
5150 function consumeNumericToken() {
5151 // Consume a number and let number be the result.
5152 offset = consumeNumber$4(source, offset);
5153
5154 // If the next 3 input code points would start an identifier, then:
5155 if (isIdentifierStart$1(getCharCode(offset), getCharCode(offset + 1), getCharCode(offset + 2))) {
5156 // Create a <dimension-token> with the same value and type flag as number, and a unit set initially to the empty string.
5157 // Consume a name. Set the <dimension-token>’s unit to the returned value.
5158 // Return the <dimension-token>.
5159 type = TYPE$F.Dimension;
5160 offset = consumeName(source, offset);
5161 return;
5162 }
5163
5164 // Otherwise, if the next input code point is U+0025 PERCENTAGE SIGN (%), consume it.
5165 if (getCharCode(offset) === 0x0025) {
5166 // Create a <percentage-token> with the same value as number, and return it.
5167 type = TYPE$F.Percentage;
5168 offset++;
5169 return;
5170 }
5171
5172 // Otherwise, create a <number-token> with the same value and type flag as number, and return it.
5173 type = TYPE$F.Number;
5174 }
5175
5176 // § 4.3.4. Consume an ident-like token
5177 function consumeIdentLikeToken() {
5178 const nameStartOffset = offset;
5179
5180 // Consume a name, and let string be the result.
5181 offset = consumeName(source, offset);
5182
5183 // If string’s value is an ASCII case-insensitive match for "url",
5184 // and the next input code point is U+0028 LEFT PARENTHESIS ((), consume it.
5185 if (cmpStr$4(source, nameStartOffset, offset, 'url') && getCharCode(offset) === 0x0028) {
5186 // While the next two input code points are whitespace, consume the next input code point.
5187 offset = findWhiteSpaceEnd(source, offset + 1);
5188
5189 // If the next one or two input code points are U+0022 QUOTATION MARK ("), U+0027 APOSTROPHE ('),
5190 // or whitespace followed by U+0022 QUOTATION MARK (") or U+0027 APOSTROPHE ('),
5191 // then create a <function-token> with its value set to string and return it.
5192 if (getCharCode(offset) === 0x0022 ||
5193 getCharCode(offset) === 0x0027) {
5194 type = TYPE$F.Function;
5195 offset = nameStartOffset + 4;
5196 return;
5197 }
5198
5199 // Otherwise, consume a url token, and return it.
5200 consumeUrlToken();
5201 return;
5202 }
5203
5204 // Otherwise, if the next input code point is U+0028 LEFT PARENTHESIS ((), consume it.
5205 // Create a <function-token> with its value set to string and return it.
5206 if (getCharCode(offset) === 0x0028) {
5207 type = TYPE$F.Function;
5208 offset++;
5209 return;
5210 }
5211
5212 // Otherwise, create an <ident-token> with its value set to string and return it.
5213 type = TYPE$F.Ident;
5214 }
5215
5216 // § 4.3.5. Consume a string token
5217 function consumeStringToken(endingCodePoint) {
5218 // This algorithm may be called with an ending code point, which denotes the code point
5219 // that ends the string. If an ending code point is not specified,
5220 // the current input code point is used.
5221 if (!endingCodePoint) {
5222 endingCodePoint = getCharCode(offset++);
5223 }
5224
5225 // Initially create a <string-token> with its value set to the empty string.
5226 type = TYPE$F.String;
5227
5228 // Repeatedly consume the next input code point from the stream:
5229 for (; offset < source.length; offset++) {
5230 var code = source.charCodeAt(offset);
5231
5232 switch (charCodeCategory(code)) {
5233 // ending code point
5234 case endingCodePoint:
5235 // Return the <string-token>.
5236 offset++;
5237 return;
5238
5239 // EOF
5240 case charCodeCategory.Eof:
5241 // This is a parse error. Return the <string-token>.
5242 return;
5243
5244 // newline
5245 case charCodeCategory.WhiteSpace:
5246 if (isNewline(code)) {
5247 // This is a parse error. Reconsume the current input code point,
5248 // create a <bad-string-token>, and return it.
5249 offset += getNewlineLength(source, offset, code);
5250 type = TYPE$F.BadString;
5251 return;
5252 }
5253 break;
5254
5255 // U+005C REVERSE SOLIDUS (\)
5256 case 0x005C:
5257 // If the next input code point is EOF, do nothing.
5258 if (offset === source.length - 1) {
5259 break;
5260 }
5261
5262 var nextCode = getCharCode(offset + 1);
5263
5264 // Otherwise, if the next input code point is a newline, consume it.
5265 if (isNewline(nextCode)) {
5266 offset += getNewlineLength(source, offset + 1, nextCode);
5267 } else if (isValidEscape(code, nextCode)) {
5268 // Otherwise, (the stream starts with a valid escape) consume
5269 // an escaped code point and append the returned code point to
5270 // the <string-token>’s value.
5271 offset = consumeEscaped(source, offset) - 1;
5272 }
5273 break;
5274
5275 // anything else
5276 // Append the current input code point to the <string-token>’s value.
5277 }
5278 }
5279 }
5280
5281 // § 4.3.6. Consume a url token
5282 // Note: This algorithm assumes that the initial "url(" has already been consumed.
5283 // This algorithm also assumes that it’s being called to consume an "unquoted" value, like url(foo).
5284 // A quoted value, like url("foo"), is parsed as a <function-token>. Consume an ident-like token
5285 // automatically handles this distinction; this algorithm shouldn’t be called directly otherwise.
5286 function consumeUrlToken() {
5287 // Initially create a <url-token> with its value set to the empty string.
5288 type = TYPE$F.Url;
5289
5290 // Consume as much whitespace as possible.
5291 offset = findWhiteSpaceEnd(source, offset);
5292
5293 // Repeatedly consume the next input code point from the stream:
5294 for (; offset < source.length; offset++) {
5295 var code = source.charCodeAt(offset);
5296
5297 switch (charCodeCategory(code)) {
5298 // U+0029 RIGHT PARENTHESIS ())
5299 case 0x0029:
5300 // Return the <url-token>.
5301 offset++;
5302 return;
5303
5304 // EOF
5305 case charCodeCategory.Eof:
5306 // This is a parse error. Return the <url-token>.
5307 return;
5308
5309 // whitespace
5310 case charCodeCategory.WhiteSpace:
5311 // Consume as much whitespace as possible.
5312 offset = findWhiteSpaceEnd(source, offset);
5313
5314 // If the next input code point is U+0029 RIGHT PARENTHESIS ()) or EOF,
5315 // consume it and return the <url-token>
5316 // (if EOF was encountered, this is a parse error);
5317 if (getCharCode(offset) === 0x0029 || offset >= source.length) {
5318 if (offset < source.length) {
5319 offset++;
5320 }
5321 return;
5322 }
5323
5324 // otherwise, consume the remnants of a bad url, create a <bad-url-token>,
5325 // and return it.
5326 offset = consumeBadUrlRemnants(source, offset);
5327 type = TYPE$F.BadUrl;
5328 return;
5329
5330 // U+0022 QUOTATION MARK (")
5331 // U+0027 APOSTROPHE (')
5332 // U+0028 LEFT PARENTHESIS (()
5333 // non-printable code point
5334 case 0x0022:
5335 case 0x0027:
5336 case 0x0028:
5337 case charCodeCategory.NonPrintable:
5338 // This is a parse error. Consume the remnants of a bad url,
5339 // create a <bad-url-token>, and return it.
5340 offset = consumeBadUrlRemnants(source, offset);
5341 type = TYPE$F.BadUrl;
5342 return;
5343
5344 // U+005C REVERSE SOLIDUS (\)
5345 case 0x005C:
5346 // If the stream starts with a valid escape, consume an escaped code point and
5347 // append the returned code point to the <url-token>’s value.
5348 if (isValidEscape(code, getCharCode(offset + 1))) {
5349 offset = consumeEscaped(source, offset) - 1;
5350 break;
5351 }
5352
5353 // Otherwise, this is a parse error. Consume the remnants of a bad url,
5354 // create a <bad-url-token>, and return it.
5355 offset = consumeBadUrlRemnants(source, offset);
5356 type = TYPE$F.BadUrl;
5357 return;
5358
5359 // anything else
5360 // Append the current input code point to the <url-token>’s value.
5361 }
5362 }
5363 }
5364
5365 if (!stream) {
5366 stream = new TokenStream$3();
5367 }
5368
5369 // ensure source is a string
5370 source = String(source || '');
5371
5372 var sourceLength = source.length;
5373 var offsetAndType = adoptBuffer$1(stream.offsetAndType, sourceLength + 1); // +1 because of eof-token
5374 var balance = adoptBuffer$1(stream.balance, sourceLength + 1);
5375 var tokenCount = 0;
5376 var start = isBOM$1(getCharCode(0));
5377 var offset = start;
5378 var balanceCloseType = 0;
5379 var balanceStart = 0;
5380 var balancePrev = 0;
5381
5382 // https://drafts.csswg.org/css-syntax-3/#consume-token
5383 // § 4.3.1. Consume a token
5384 while (offset < sourceLength) {
5385 var code = source.charCodeAt(offset);
5386 var type = 0;
5387
5388 balance[tokenCount] = sourceLength;
5389
5390 switch (charCodeCategory(code)) {
5391 // whitespace
5392 case charCodeCategory.WhiteSpace:
5393 // Consume as much whitespace as possible. Return a <whitespace-token>.
5394 type = TYPE$F.WhiteSpace;
5395 offset = findWhiteSpaceEnd(source, offset + 1);
5396 break;
5397
5398 // U+0022 QUOTATION MARK (")
5399 case 0x0022:
5400 // Consume a string token and return it.
5401 consumeStringToken();
5402 break;
5403
5404 // U+0023 NUMBER SIGN (#)
5405 case 0x0023:
5406 // If the next input code point is a name code point or the next two input code points are a valid escape, then:
5407 if (isName(getCharCode(offset + 1)) || isValidEscape(getCharCode(offset + 1), getCharCode(offset + 2))) {
5408 // Create a <hash-token>.
5409 type = TYPE$F.Hash;
5410
5411 // If the next 3 input code points would start an identifier, set the <hash-token>’s type flag to "id".
5412 // if (isIdentifierStart(getCharCode(offset + 1), getCharCode(offset + 2), getCharCode(offset + 3))) {
5413 // // TODO: set id flag
5414 // }
5415
5416 // Consume a name, and set the <hash-token>’s value to the returned string.
5417 offset = consumeName(source, offset + 1);
5418
5419 // Return the <hash-token>.
5420 } else {
5421 // Otherwise, return a <delim-token> with its value set to the current input code point.
5422 type = TYPE$F.Delim;
5423 offset++;
5424 }
5425
5426 break;
5427
5428 // U+0027 APOSTROPHE (')
5429 case 0x0027:
5430 // Consume a string token and return it.
5431 consumeStringToken();
5432 break;
5433
5434 // U+0028 LEFT PARENTHESIS (()
5435 case 0x0028:
5436 // Return a <(-token>.
5437 type = TYPE$F.LeftParenthesis;
5438 offset++;
5439 break;
5440
5441 // U+0029 RIGHT PARENTHESIS ())
5442 case 0x0029:
5443 // Return a <)-token>.
5444 type = TYPE$F.RightParenthesis;
5445 offset++;
5446 break;
5447
5448 // U+002B PLUS SIGN (+)
5449 case 0x002B:
5450 // If the input stream starts with a number, ...
5451 if (isNumberStart(code, getCharCode(offset + 1), getCharCode(offset + 2))) {
5452 // ... reconsume the current input code point, consume a numeric token, and return it.
5453 consumeNumericToken();
5454 } else {
5455 // Otherwise, return a <delim-token> with its value set to the current input code point.
5456 type = TYPE$F.Delim;
5457 offset++;
5458 }
5459 break;
5460
5461 // U+002C COMMA (,)
5462 case 0x002C:
5463 // Return a <comma-token>.
5464 type = TYPE$F.Comma;
5465 offset++;
5466 break;
5467
5468 // U+002D HYPHEN-MINUS (-)
5469 case 0x002D:
5470 // If the input stream starts with a number, reconsume the current input code point, consume a numeric token, and return it.
5471 if (isNumberStart(code, getCharCode(offset + 1), getCharCode(offset + 2))) {
5472 consumeNumericToken();
5473 } else {
5474 // 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>.
5475 if (getCharCode(offset + 1) === 0x002D &&
5476 getCharCode(offset + 2) === 0x003E) {
5477 type = TYPE$F.CDC;
5478 offset = offset + 3;
5479 } else {
5480 // Otherwise, if the input stream starts with an identifier, ...
5481 if (isIdentifierStart$1(code, getCharCode(offset + 1), getCharCode(offset + 2))) {
5482 // ... reconsume the current input code point, consume an ident-like token, and return it.
5483 consumeIdentLikeToken();
5484 } else {
5485 // Otherwise, return a <delim-token> with its value set to the current input code point.
5486 type = TYPE$F.Delim;
5487 offset++;
5488 }
5489 }
5490 }
5491 break;
5492
5493 // U+002E FULL STOP (.)
5494 case 0x002E:
5495 // If the input stream starts with a number, ...
5496 if (isNumberStart(code, getCharCode(offset + 1), getCharCode(offset + 2))) {
5497 // ... reconsume the current input code point, consume a numeric token, and return it.
5498 consumeNumericToken();
5499 } else {
5500 // Otherwise, return a <delim-token> with its value set to the current input code point.
5501 type = TYPE$F.Delim;
5502 offset++;
5503 }
5504
5505 break;
5506
5507 // U+002F SOLIDUS (/)
5508 case 0x002F:
5509 // If the next two input code point are U+002F SOLIDUS (/) followed by a U+002A ASTERISK (*),
5510 if (getCharCode(offset + 1) === 0x002A) {
5511 // ... consume them and all following code points up to and including the first U+002A ASTERISK (*)
5512 // followed by a U+002F SOLIDUS (/), or up to an EOF code point.
5513 type = TYPE$F.Comment;
5514 offset = source.indexOf('*/', offset + 2) + 2;
5515 if (offset === 1) {
5516 offset = source.length;
5517 }
5518 } else {
5519 type = TYPE$F.Delim;
5520 offset++;
5521 }
5522 break;
5523
5524 // U+003A COLON (:)
5525 case 0x003A:
5526 // Return a <colon-token>.
5527 type = TYPE$F.Colon;
5528 offset++;
5529 break;
5530
5531 // U+003B SEMICOLON (;)
5532 case 0x003B:
5533 // Return a <semicolon-token>.
5534 type = TYPE$F.Semicolon;
5535 offset++;
5536 break;
5537
5538 // U+003C LESS-THAN SIGN (<)
5539 case 0x003C:
5540 // If the next 3 input code points are U+0021 EXCLAMATION MARK U+002D HYPHEN-MINUS U+002D HYPHEN-MINUS (!--), ...
5541 if (getCharCode(offset + 1) === 0x0021 &&
5542 getCharCode(offset + 2) === 0x002D &&
5543 getCharCode(offset + 3) === 0x002D) {
5544 // ... consume them and return a <CDO-token>.
5545 type = TYPE$F.CDO;
5546 offset = offset + 4;
5547 } else {
5548 // Otherwise, return a <delim-token> with its value set to the current input code point.
5549 type = TYPE$F.Delim;
5550 offset++;
5551 }
5552
5553 break;
5554
5555 // U+0040 COMMERCIAL AT (@)
5556 case 0x0040:
5557 // If the next 3 input code points would start an identifier, ...
5558 if (isIdentifierStart$1(getCharCode(offset + 1), getCharCode(offset + 2), getCharCode(offset + 3))) {
5559 // ... consume a name, create an <at-keyword-token> with its value set to the returned value, and return it.
5560 type = TYPE$F.AtKeyword;
5561 offset = consumeName(source, offset + 1);
5562 } else {
5563 // Otherwise, return a <delim-token> with its value set to the current input code point.
5564 type = TYPE$F.Delim;
5565 offset++;
5566 }
5567
5568 break;
5569
5570 // U+005B LEFT SQUARE BRACKET ([)
5571 case 0x005B:
5572 // Return a <[-token>.
5573 type = TYPE$F.LeftSquareBracket;
5574 offset++;
5575 break;
5576
5577 // U+005C REVERSE SOLIDUS (\)
5578 case 0x005C:
5579 // If the input stream starts with a valid escape, ...
5580 if (isValidEscape(code, getCharCode(offset + 1))) {
5581 // ... reconsume the current input code point, consume an ident-like token, and return it.
5582 consumeIdentLikeToken();
5583 } else {
5584 // Otherwise, this is a parse error. Return a <delim-token> with its value set to the current input code point.
5585 type = TYPE$F.Delim;
5586 offset++;
5587 }
5588 break;
5589
5590 // U+005D RIGHT SQUARE BRACKET (])
5591 case 0x005D:
5592 // Return a <]-token>.
5593 type = TYPE$F.RightSquareBracket;
5594 offset++;
5595 break;
5596
5597 // U+007B LEFT CURLY BRACKET ({)
5598 case 0x007B:
5599 // Return a <{-token>.
5600 type = TYPE$F.LeftCurlyBracket;
5601 offset++;
5602 break;
5603
5604 // U+007D RIGHT CURLY BRACKET (})
5605 case 0x007D:
5606 // Return a <}-token>.
5607 type = TYPE$F.RightCurlyBracket;
5608 offset++;
5609 break;
5610
5611 // digit
5612 case charCodeCategory.Digit:
5613 // Reconsume the current input code point, consume a numeric token, and return it.
5614 consumeNumericToken();
5615 break;
5616
5617 // name-start code point
5618 case charCodeCategory.NameStart:
5619 // Reconsume the current input code point, consume an ident-like token, and return it.
5620 consumeIdentLikeToken();
5621 break;
5622
5623 // EOF
5624 case charCodeCategory.Eof:
5625 // Return an <EOF-token>.
5626 break;
5627
5628 // anything else
5629 default:
5630 // Return a <delim-token> with its value set to the current input code point.
5631 type = TYPE$F.Delim;
5632 offset++;
5633 }
5634
5635 switch (type) {
5636 case balanceCloseType:
5637 balancePrev = balanceStart & OFFSET_MASK;
5638 balanceStart = balance[balancePrev];
5639 balanceCloseType = balanceStart >> TYPE_SHIFT;
5640 balance[tokenCount] = balancePrev;
5641 balance[balancePrev++] = tokenCount;
5642 for (; balancePrev < tokenCount; balancePrev++) {
5643 if (balance[balancePrev] === sourceLength) {
5644 balance[balancePrev] = tokenCount;
5645 }
5646 }
5647 break;
5648
5649 case TYPE$F.LeftParenthesis:
5650 case TYPE$F.Function:
5651 balance[tokenCount] = balanceStart;
5652 balanceCloseType = TYPE$F.RightParenthesis;
5653 balanceStart = (balanceCloseType << TYPE_SHIFT) | tokenCount;
5654 break;
5655
5656 case TYPE$F.LeftSquareBracket:
5657 balance[tokenCount] = balanceStart;
5658 balanceCloseType = TYPE$F.RightSquareBracket;
5659 balanceStart = (balanceCloseType << TYPE_SHIFT) | tokenCount;
5660 break;
5661
5662 case TYPE$F.LeftCurlyBracket:
5663 balance[tokenCount] = balanceStart;
5664 balanceCloseType = TYPE$F.RightCurlyBracket;
5665 balanceStart = (balanceCloseType << TYPE_SHIFT) | tokenCount;
5666 break;
5667 }
5668
5669 offsetAndType[tokenCount++] = (type << TYPE_SHIFT) | offset;
5670 }
5671
5672 // finalize buffers
5673 offsetAndType[tokenCount] = (TYPE$F.EOF << TYPE_SHIFT) | offset; // <EOF-token>
5674 balance[tokenCount] = sourceLength;
5675 balance[sourceLength] = sourceLength; // prevents false positive balance match with any token
5676 while (balanceStart !== 0) {
5677 balancePrev = balanceStart & OFFSET_MASK;
5678 balanceStart = balance[balancePrev];
5679 balance[balancePrev] = sourceLength;
5680 }
5681
5682 // update stream
5683 stream.source = source;
5684 stream.firstCharOffset = start;
5685 stream.offsetAndType = offsetAndType;
5686 stream.tokenCount = tokenCount;
5687 stream.balance = balance;
5688 stream.reset();
5689 stream.next();
5690
5691 return stream;
5692 }
5693
5694 // extend tokenizer with constants
5695 Object.keys(constants$1).forEach(function(key) {
5696 tokenize$3[key] = constants$1[key];
5697 });
5698
5699 // extend tokenizer with static methods from utils
5700 Object.keys(charCodeDefinitions).forEach(function(key) {
5701 tokenize$3[key] = charCodeDefinitions[key];
5702 });
5703 Object.keys(utils).forEach(function(key) {
5704 tokenize$3[key] = utils[key];
5705 });
5706
5707 var tokenizer$3 = tokenize$3;
5708
5709 var isDigit$3 = tokenizer$3.isDigit;
5710 var cmpChar$4 = tokenizer$3.cmpChar;
5711 var TYPE$E = tokenizer$3.TYPE;
5712
5713 var DELIM$6 = TYPE$E.Delim;
5714 var WHITESPACE$b = TYPE$E.WhiteSpace;
5715 var COMMENT$9 = TYPE$E.Comment;
5716 var IDENT$i = TYPE$E.Ident;
5717 var NUMBER$9 = TYPE$E.Number;
5718 var DIMENSION$7 = TYPE$E.Dimension;
5719 var PLUSSIGN$8 = 0x002B; // U+002B PLUS SIGN (+)
5720 var HYPHENMINUS$4 = 0x002D; // U+002D HYPHEN-MINUS (-)
5721 var N$4 = 0x006E; // U+006E LATIN SMALL LETTER N (n)
5722 var DISALLOW_SIGN$1 = true;
5723 var ALLOW_SIGN$1 = false;
5724
5725 function isDelim$1(token, code) {
5726 return token !== null && token.type === DELIM$6 && token.value.charCodeAt(0) === code;
5727 }
5728
5729 function skipSC(token, offset, getNextToken) {
5730 while (token !== null && (token.type === WHITESPACE$b || token.type === COMMENT$9)) {
5731 token = getNextToken(++offset);
5732 }
5733
5734 return offset;
5735 }
5736
5737 function checkInteger$1(token, valueOffset, disallowSign, offset) {
5738 if (!token) {
5739 return 0;
5740 }
5741
5742 var code = token.value.charCodeAt(valueOffset);
5743
5744 if (code === PLUSSIGN$8 || code === HYPHENMINUS$4) {
5745 if (disallowSign) {
5746 // Number sign is not allowed
5747 return 0;
5748 }
5749 valueOffset++;
5750 }
5751
5752 for (; valueOffset < token.value.length; valueOffset++) {
5753 if (!isDigit$3(token.value.charCodeAt(valueOffset))) {
5754 // Integer is expected
5755 return 0;
5756 }
5757 }
5758
5759 return offset + 1;
5760 }
5761
5762 // ... <signed-integer>
5763 // ... ['+' | '-'] <signless-integer>
5764 function consumeB$1(token, offset_, getNextToken) {
5765 var sign = false;
5766 var offset = skipSC(token, offset_, getNextToken);
5767
5768 token = getNextToken(offset);
5769
5770 if (token === null) {
5771 return offset_;
5772 }
5773
5774 if (token.type !== NUMBER$9) {
5775 if (isDelim$1(token, PLUSSIGN$8) || isDelim$1(token, HYPHENMINUS$4)) {
5776 sign = true;
5777 offset = skipSC(getNextToken(++offset), offset, getNextToken);
5778 token = getNextToken(offset);
5779
5780 if (token === null && token.type !== NUMBER$9) {
5781 return 0;
5782 }
5783 } else {
5784 return offset_;
5785 }
5786 }
5787
5788 if (!sign) {
5789 var code = token.value.charCodeAt(0);
5790 if (code !== PLUSSIGN$8 && code !== HYPHENMINUS$4) {
5791 // Number sign is expected
5792 return 0;
5793 }
5794 }
5795
5796 return checkInteger$1(token, sign ? 0 : 1, sign, offset);
5797 }
5798
5799 // An+B microsyntax https://www.w3.org/TR/css-syntax-3/#anb
5800 var genericAnPlusB = function anPlusB(token, getNextToken) {
5801 /* eslint-disable brace-style*/
5802 var offset = 0;
5803
5804 if (!token) {
5805 return 0;
5806 }
5807
5808 // <integer>
5809 if (token.type === NUMBER$9) {
5810 return checkInteger$1(token, 0, ALLOW_SIGN$1, offset); // b
5811 }
5812
5813 // -n
5814 // -n <signed-integer>
5815 // -n ['+' | '-'] <signless-integer>
5816 // -n- <signless-integer>
5817 // <dashndashdigit-ident>
5818 else if (token.type === IDENT$i && token.value.charCodeAt(0) === HYPHENMINUS$4) {
5819 // expect 1st char is N
5820 if (!cmpChar$4(token.value, 1, N$4)) {
5821 return 0;
5822 }
5823
5824 switch (token.value.length) {
5825 // -n
5826 // -n <signed-integer>
5827 // -n ['+' | '-'] <signless-integer>
5828 case 2:
5829 return consumeB$1(getNextToken(++offset), offset, getNextToken);
5830
5831 // -n- <signless-integer>
5832 case 3:
5833 if (token.value.charCodeAt(2) !== HYPHENMINUS$4) {
5834 return 0;
5835 }
5836
5837 offset = skipSC(getNextToken(++offset), offset, getNextToken);
5838 token = getNextToken(offset);
5839
5840 return checkInteger$1(token, 0, DISALLOW_SIGN$1, offset);
5841
5842 // <dashndashdigit-ident>
5843 default:
5844 if (token.value.charCodeAt(2) !== HYPHENMINUS$4) {
5845 return 0;
5846 }
5847
5848 return checkInteger$1(token, 3, DISALLOW_SIGN$1, offset);
5849 }
5850 }
5851
5852 // '+'? n
5853 // '+'? n <signed-integer>
5854 // '+'? n ['+' | '-'] <signless-integer>
5855 // '+'? n- <signless-integer>
5856 // '+'? <ndashdigit-ident>
5857 else if (token.type === IDENT$i || (isDelim$1(token, PLUSSIGN$8) && getNextToken(offset + 1).type === IDENT$i)) {
5858 // just ignore a plus
5859 if (token.type !== IDENT$i) {
5860 token = getNextToken(++offset);
5861 }
5862
5863 if (token === null || !cmpChar$4(token.value, 0, N$4)) {
5864 return 0;
5865 }
5866
5867 switch (token.value.length) {
5868 // '+'? n
5869 // '+'? n <signed-integer>
5870 // '+'? n ['+' | '-'] <signless-integer>
5871 case 1:
5872 return consumeB$1(getNextToken(++offset), offset, getNextToken);
5873
5874 // '+'? n- <signless-integer>
5875 case 2:
5876 if (token.value.charCodeAt(1) !== HYPHENMINUS$4) {
5877 return 0;
5878 }
5879
5880 offset = skipSC(getNextToken(++offset), offset, getNextToken);
5881 token = getNextToken(offset);
5882
5883 return checkInteger$1(token, 0, DISALLOW_SIGN$1, offset);
5884
5885 // '+'? <ndashdigit-ident>
5886 default:
5887 if (token.value.charCodeAt(1) !== HYPHENMINUS$4) {
5888 return 0;
5889 }
5890
5891 return checkInteger$1(token, 2, DISALLOW_SIGN$1, offset);
5892 }
5893 }
5894
5895 // <ndashdigit-dimension>
5896 // <ndash-dimension> <signless-integer>
5897 // <n-dimension>
5898 // <n-dimension> <signed-integer>
5899 // <n-dimension> ['+' | '-'] <signless-integer>
5900 else if (token.type === DIMENSION$7) {
5901 var code = token.value.charCodeAt(0);
5902 var sign = code === PLUSSIGN$8 || code === HYPHENMINUS$4 ? 1 : 0;
5903
5904 for (var i = sign; i < token.value.length; i++) {
5905 if (!isDigit$3(token.value.charCodeAt(i))) {
5906 break;
5907 }
5908 }
5909
5910 if (i === sign) {
5911 // Integer is expected
5912 return 0;
5913 }
5914
5915 if (!cmpChar$4(token.value, i, N$4)) {
5916 return 0;
5917 }
5918
5919 // <n-dimension>
5920 // <n-dimension> <signed-integer>
5921 // <n-dimension> ['+' | '-'] <signless-integer>
5922 if (i + 1 === token.value.length) {
5923 return consumeB$1(getNextToken(++offset), offset, getNextToken);
5924 } else {
5925 if (token.value.charCodeAt(i + 1) !== HYPHENMINUS$4) {
5926 return 0;
5927 }
5928
5929 // <ndash-dimension> <signless-integer>
5930 if (i + 2 === token.value.length) {
5931 offset = skipSC(getNextToken(++offset), offset, getNextToken);
5932 token = getNextToken(offset);
5933
5934 return checkInteger$1(token, 0, DISALLOW_SIGN$1, offset);
5935 }
5936 // <ndashdigit-dimension>
5937 else {
5938 return checkInteger$1(token, i + 2, DISALLOW_SIGN$1, offset);
5939 }
5940 }
5941 }
5942
5943 return 0;
5944 };
5945
5946 var isHexDigit$2 = tokenizer$3.isHexDigit;
5947 var cmpChar$3 = tokenizer$3.cmpChar;
5948 var TYPE$D = tokenizer$3.TYPE;
5949
5950 var IDENT$h = TYPE$D.Ident;
5951 var DELIM$5 = TYPE$D.Delim;
5952 var NUMBER$8 = TYPE$D.Number;
5953 var DIMENSION$6 = TYPE$D.Dimension;
5954 var PLUSSIGN$7 = 0x002B; // U+002B PLUS SIGN (+)
5955 var HYPHENMINUS$3 = 0x002D; // U+002D HYPHEN-MINUS (-)
5956 var QUESTIONMARK$2 = 0x003F; // U+003F QUESTION MARK (?)
5957 var U$2 = 0x0075; // U+0075 LATIN SMALL LETTER U (u)
5958
5959 function isDelim(token, code) {
5960 return token !== null && token.type === DELIM$5 && token.value.charCodeAt(0) === code;
5961 }
5962
5963 function startsWith$1(token, code) {
5964 return token.value.charCodeAt(0) === code;
5965 }
5966
5967 function hexSequence(token, offset, allowDash) {
5968 for (var pos = offset, hexlen = 0; pos < token.value.length; pos++) {
5969 var code = token.value.charCodeAt(pos);
5970
5971 if (code === HYPHENMINUS$3 && allowDash && hexlen !== 0) {
5972 if (hexSequence(token, offset + hexlen + 1, false) > 0) {
5973 return 6; // dissallow following question marks
5974 }
5975
5976 return 0; // dash at the ending of a hex sequence is not allowed
5977 }
5978
5979 if (!isHexDigit$2(code)) {
5980 return 0; // not a hex digit
5981 }
5982
5983 if (++hexlen > 6) {
5984 return 0; // too many hex digits
5985 } }
5986
5987 return hexlen;
5988 }
5989
5990 function withQuestionMarkSequence(consumed, length, getNextToken) {
5991 if (!consumed) {
5992 return 0; // nothing consumed
5993 }
5994
5995 while (isDelim(getNextToken(length), QUESTIONMARK$2)) {
5996 if (++consumed > 6) {
5997 return 0; // too many question marks
5998 }
5999
6000 length++;
6001 }
6002
6003 return length;
6004 }
6005
6006 // https://drafts.csswg.org/css-syntax/#urange
6007 // Informally, the <urange> production has three forms:
6008 // U+0001
6009 // Defines a range consisting of a single code point, in this case the code point "1".
6010 // U+0001-00ff
6011 // Defines a range of codepoints between the first and the second value, in this case
6012 // the range between "1" and "ff" (255 in decimal) inclusive.
6013 // U+00??
6014 // Defines a range of codepoints where the "?" characters range over all hex digits,
6015 // in this case defining the same as the value U+0000-00ff.
6016 // In each form, a maximum of 6 digits is allowed for each hexadecimal number (if you treat "?" as a hexadecimal digit).
6017 //
6018 // <urange> =
6019 // u '+' <ident-token> '?'* |
6020 // u <dimension-token> '?'* |
6021 // u <number-token> '?'* |
6022 // u <number-token> <dimension-token> |
6023 // u <number-token> <number-token> |
6024 // u '+' '?'+
6025 var genericUrange = function urange(token, getNextToken) {
6026 var length = 0;
6027
6028 // should start with `u` or `U`
6029 if (token === null || token.type !== IDENT$h || !cmpChar$3(token.value, 0, U$2)) {
6030 return 0;
6031 }
6032
6033 token = getNextToken(++length);
6034 if (token === null) {
6035 return 0;
6036 }
6037
6038 // u '+' <ident-token> '?'*
6039 // u '+' '?'+
6040 if (isDelim(token, PLUSSIGN$7)) {
6041 token = getNextToken(++length);
6042 if (token === null) {
6043 return 0;
6044 }
6045
6046 if (token.type === IDENT$h) {
6047 // u '+' <ident-token> '?'*
6048 return withQuestionMarkSequence(hexSequence(token, 0, true), ++length, getNextToken);
6049 }
6050
6051 if (isDelim(token, QUESTIONMARK$2)) {
6052 // u '+' '?'+
6053 return withQuestionMarkSequence(1, ++length, getNextToken);
6054 }
6055
6056 // Hex digit or question mark is expected
6057 return 0;
6058 }
6059
6060 // u <number-token> '?'*
6061 // u <number-token> <dimension-token>
6062 // u <number-token> <number-token>
6063 if (token.type === NUMBER$8) {
6064 if (!startsWith$1(token, PLUSSIGN$7)) {
6065 return 0;
6066 }
6067
6068 var consumedHexLength = hexSequence(token, 1, true);
6069 if (consumedHexLength === 0) {
6070 return 0;
6071 }
6072
6073 token = getNextToken(++length);
6074 if (token === null) {
6075 // u <number-token> <eof>
6076 return length;
6077 }
6078
6079 if (token.type === DIMENSION$6 || token.type === NUMBER$8) {
6080 // u <number-token> <dimension-token>
6081 // u <number-token> <number-token>
6082 if (!startsWith$1(token, HYPHENMINUS$3) || !hexSequence(token, 1, false)) {
6083 return 0;
6084 }
6085
6086 return length + 1;
6087 }
6088
6089 // u <number-token> '?'*
6090 return withQuestionMarkSequence(consumedHexLength, length, getNextToken);
6091 }
6092
6093 // u <dimension-token> '?'*
6094 if (token.type === DIMENSION$6) {
6095 if (!startsWith$1(token, PLUSSIGN$7)) {
6096 return 0;
6097 }
6098
6099 return withQuestionMarkSequence(hexSequence(token, 1, true), ++length, getNextToken);
6100 }
6101
6102 return 0;
6103 };
6104
6105 var tokenizer$2 = tokenizer$3;
6106 var isIdentifierStart = tokenizer$2.isIdentifierStart;
6107 var isHexDigit$1 = tokenizer$2.isHexDigit;
6108 var isDigit$2 = tokenizer$2.isDigit;
6109 var cmpStr$3 = tokenizer$2.cmpStr;
6110 var consumeNumber$3 = tokenizer$2.consumeNumber;
6111 var TYPE$C = tokenizer$2.TYPE;
6112 var anPlusB = genericAnPlusB;
6113 var urange = genericUrange;
6114
6115 var cssWideKeywords$1 = ['unset', 'initial', 'inherit'];
6116 var calcFunctionNames = ['calc(', '-moz-calc(', '-webkit-calc('];
6117
6118 // https://www.w3.org/TR/css-values-3/#lengths
6119 var LENGTH = {
6120 // absolute length units
6121 'px': true,
6122 'mm': true,
6123 'cm': true,
6124 'in': true,
6125 'pt': true,
6126 'pc': true,
6127 'q': true,
6128
6129 // relative length units
6130 'em': true,
6131 'ex': true,
6132 'ch': true,
6133 'rem': true,
6134
6135 // viewport-percentage lengths
6136 'vh': true,
6137 'vw': true,
6138 'vmin': true,
6139 'vmax': true,
6140 'vm': true
6141 };
6142
6143 var ANGLE = {
6144 'deg': true,
6145 'grad': true,
6146 'rad': true,
6147 'turn': true
6148 };
6149
6150 var TIME = {
6151 's': true,
6152 'ms': true
6153 };
6154
6155 var FREQUENCY = {
6156 'hz': true,
6157 'khz': true
6158 };
6159
6160 // https://www.w3.org/TR/css-values-3/#resolution (https://drafts.csswg.org/css-values/#resolution)
6161 var RESOLUTION = {
6162 'dpi': true,
6163 'dpcm': true,
6164 'dppx': true,
6165 'x': true // https://github.com/w3c/csswg-drafts/issues/461
6166 };
6167
6168 // https://drafts.csswg.org/css-grid/#fr-unit
6169 var FLEX = {
6170 'fr': true
6171 };
6172
6173 // https://www.w3.org/TR/css3-speech/#mixing-props-voice-volume
6174 var DECIBEL = {
6175 'db': true
6176 };
6177
6178 // https://www.w3.org/TR/css3-speech/#voice-props-voice-pitch
6179 var SEMITONES = {
6180 'st': true
6181 };
6182
6183 // safe char code getter
6184 function charCode(str, index) {
6185 return index < str.length ? str.charCodeAt(index) : 0;
6186 }
6187
6188 function eqStr(actual, expected) {
6189 return cmpStr$3(actual, 0, actual.length, expected);
6190 }
6191
6192 function eqStrAny(actual, expected) {
6193 for (var i = 0; i < expected.length; i++) {
6194 if (eqStr(actual, expected[i])) {
6195 return true;
6196 }
6197 }
6198
6199 return false;
6200 }
6201
6202 // IE postfix hack, i.e. 123\0 or 123px\9
6203 function isPostfixIeHack(str, offset) {
6204 if (offset !== str.length - 2) {
6205 return false;
6206 }
6207
6208 return (
6209 str.charCodeAt(offset) === 0x005C && // U+005C REVERSE SOLIDUS (\)
6210 isDigit$2(str.charCodeAt(offset + 1))
6211 );
6212 }
6213
6214 function outOfRange(opts, value, numEnd) {
6215 if (opts && opts.type === 'Range') {
6216 var num = Number(
6217 numEnd !== undefined && numEnd !== value.length
6218 ? value.substr(0, numEnd)
6219 : value
6220 );
6221
6222 if (isNaN(num)) {
6223 return true;
6224 }
6225
6226 if (opts.min !== null && num < opts.min) {
6227 return true;
6228 }
6229
6230 if (opts.max !== null && num > opts.max) {
6231 return true;
6232 }
6233 }
6234
6235 return false;
6236 }
6237
6238 function consumeFunction(token, getNextToken) {
6239 var startIdx = token.index;
6240 var length = 0;
6241
6242 // balanced token consuming
6243 do {
6244 length++;
6245
6246 if (token.balance <= startIdx) {
6247 break;
6248 }
6249 } while (token = getNextToken(length));
6250
6251 return length;
6252 }
6253
6254 // TODO: implement
6255 // can be used wherever <length>, <frequency>, <angle>, <time>, <percentage>, <number>, or <integer> values are allowed
6256 // https://drafts.csswg.org/css-values/#calc-notation
6257 function calc(next) {
6258 return function(token, getNextToken, opts) {
6259 if (token === null) {
6260 return 0;
6261 }
6262
6263 if (token.type === TYPE$C.Function && eqStrAny(token.value, calcFunctionNames)) {
6264 return consumeFunction(token, getNextToken);
6265 }
6266
6267 return next(token, getNextToken, opts);
6268 };
6269 }
6270
6271 function tokenType(expectedTokenType) {
6272 return function(token) {
6273 if (token === null || token.type !== expectedTokenType) {
6274 return 0;
6275 }
6276
6277 return 1;
6278 };
6279 }
6280
6281 function func(name) {
6282 name = name + '(';
6283
6284 return function(token, getNextToken) {
6285 if (token !== null && eqStr(token.value, name)) {
6286 return consumeFunction(token, getNextToken);
6287 }
6288
6289 return 0;
6290 };
6291 }
6292
6293 // =========================
6294 // Complex types
6295 //
6296
6297 // https://drafts.csswg.org/css-values-4/#custom-idents
6298 // 4.2. Author-defined Identifiers: the <custom-ident> type
6299 // Some properties accept arbitrary author-defined identifiers as a component value.
6300 // This generic data type is denoted by <custom-ident>, and represents any valid CSS identifier
6301 // that would not be misinterpreted as a pre-defined keyword in that property’s value definition.
6302 //
6303 // See also: https://developer.mozilla.org/en-US/docs/Web/CSS/custom-ident
6304 function customIdent(token) {
6305 if (token === null || token.type !== TYPE$C.Ident) {
6306 return 0;
6307 }
6308
6309 var name = token.value.toLowerCase();
6310
6311 // The CSS-wide keywords are not valid <custom-ident>s
6312 if (eqStrAny(name, cssWideKeywords$1)) {
6313 return 0;
6314 }
6315
6316 // The default keyword is reserved and is also not a valid <custom-ident>
6317 if (eqStr(name, 'default')) {
6318 return 0;
6319 }
6320
6321 // TODO: ignore property specific keywords (as described https://developer.mozilla.org/en-US/docs/Web/CSS/custom-ident)
6322 // Specifications using <custom-ident> must specify clearly what other keywords
6323 // are excluded from <custom-ident>, if any—for example by saying that any pre-defined keywords
6324 // in that property’s value definition are excluded. Excluded keywords are excluded
6325 // in all ASCII case permutations.
6326
6327 return 1;
6328 }
6329
6330 // https://drafts.csswg.org/css-variables/#typedef-custom-property-name
6331 // A custom property is any property whose name starts with two dashes (U+002D HYPHEN-MINUS), like --foo.
6332 // The <custom-property-name> production corresponds to this: it’s defined as any valid identifier
6333 // that starts with two dashes, except -- itself, which is reserved for future use by CSS.
6334 // NOTE: Current implementation treat `--` as a valid name since most (all?) major browsers treat it as valid.
6335 function customPropertyName(token) {
6336 // ... defined as any valid identifier
6337 if (token === null || token.type !== TYPE$C.Ident) {
6338 return 0;
6339 }
6340
6341 // ... that starts with two dashes (U+002D HYPHEN-MINUS)
6342 if (charCode(token.value, 0) !== 0x002D || charCode(token.value, 1) !== 0x002D) {
6343 return 0;
6344 }
6345
6346 return 1;
6347 }
6348
6349 // https://drafts.csswg.org/css-color-4/#hex-notation
6350 // The syntax of a <hex-color> is a <hash-token> token whose value consists of 3, 4, 6, or 8 hexadecimal digits.
6351 // In other words, a hex color is written as a hash character, "#", followed by some number of digits 0-9 or
6352 // letters a-f (the case of the letters doesn’t matter - #00ff00 is identical to #00FF00).
6353 function hexColor(token) {
6354 if (token === null || token.type !== TYPE$C.Hash) {
6355 return 0;
6356 }
6357
6358 var length = token.value.length;
6359
6360 // valid values (length): #rgb (4), #rgba (5), #rrggbb (7), #rrggbbaa (9)
6361 if (length !== 4 && length !== 5 && length !== 7 && length !== 9) {
6362 return 0;
6363 }
6364
6365 for (var i = 1; i < length; i++) {
6366 if (!isHexDigit$1(token.value.charCodeAt(i))) {
6367 return 0;
6368 }
6369 }
6370
6371 return 1;
6372 }
6373
6374 function idSelector(token) {
6375 if (token === null || token.type !== TYPE$C.Hash) {
6376 return 0;
6377 }
6378
6379 if (!isIdentifierStart(charCode(token.value, 1), charCode(token.value, 2), charCode(token.value, 3))) {
6380 return 0;
6381 }
6382
6383 return 1;
6384 }
6385
6386 // https://drafts.csswg.org/css-syntax/#any-value
6387 // It represents the entirety of what a valid declaration can have as its value.
6388 function declarationValue(token, getNextToken) {
6389 if (!token) {
6390 return 0;
6391 }
6392
6393 var length = 0;
6394 var level = 0;
6395 var startIdx = token.index;
6396
6397 // The <declaration-value> production matches any sequence of one or more tokens,
6398 // so long as the sequence ...
6399 scan:
6400 do {
6401 switch (token.type) {
6402 // ... does not contain <bad-string-token>, <bad-url-token>,
6403 case TYPE$C.BadString:
6404 case TYPE$C.BadUrl:
6405 break scan;
6406
6407 // ... unmatched <)-token>, <]-token>, or <}-token>,
6408 case TYPE$C.RightCurlyBracket:
6409 case TYPE$C.RightParenthesis:
6410 case TYPE$C.RightSquareBracket:
6411 if (token.balance > token.index || token.balance < startIdx) {
6412 break scan;
6413 }
6414
6415 level--;
6416 break;
6417
6418 // ... or top-level <semicolon-token> tokens
6419 case TYPE$C.Semicolon:
6420 if (level === 0) {
6421 break scan;
6422 }
6423
6424 break;
6425
6426 // ... or <delim-token> tokens with a value of "!"
6427 case TYPE$C.Delim:
6428 if (token.value === '!' && level === 0) {
6429 break scan;
6430 }
6431
6432 break;
6433
6434 case TYPE$C.Function:
6435 case TYPE$C.LeftParenthesis:
6436 case TYPE$C.LeftSquareBracket:
6437 case TYPE$C.LeftCurlyBracket:
6438 level++;
6439 break;
6440 }
6441
6442 length++;
6443
6444 // until balance closing
6445 if (token.balance <= startIdx) {
6446 break;
6447 }
6448 } while (token = getNextToken(length));
6449
6450 return length;
6451 }
6452
6453 // https://drafts.csswg.org/css-syntax/#any-value
6454 // The <any-value> production is identical to <declaration-value>, but also
6455 // allows top-level <semicolon-token> tokens and <delim-token> tokens
6456 // with a value of "!". It represents the entirety of what valid CSS can be in any context.
6457 function anyValue(token, getNextToken) {
6458 if (!token) {
6459 return 0;
6460 }
6461
6462 var startIdx = token.index;
6463 var length = 0;
6464
6465 // The <any-value> production matches any sequence of one or more tokens,
6466 // so long as the sequence ...
6467 scan:
6468 do {
6469 switch (token.type) {
6470 // ... does not contain <bad-string-token>, <bad-url-token>,
6471 case TYPE$C.BadString:
6472 case TYPE$C.BadUrl:
6473 break scan;
6474
6475 // ... unmatched <)-token>, <]-token>, or <}-token>,
6476 case TYPE$C.RightCurlyBracket:
6477 case TYPE$C.RightParenthesis:
6478 case TYPE$C.RightSquareBracket:
6479 if (token.balance > token.index || token.balance < startIdx) {
6480 break scan;
6481 }
6482
6483 break;
6484 }
6485
6486 length++;
6487
6488 // until balance closing
6489 if (token.balance <= startIdx) {
6490 break;
6491 }
6492 } while (token = getNextToken(length));
6493
6494 return length;
6495 }
6496
6497 // =========================
6498 // Dimensions
6499 //
6500
6501 function dimension(type) {
6502 return function(token, getNextToken, opts) {
6503 if (token === null || token.type !== TYPE$C.Dimension) {
6504 return 0;
6505 }
6506
6507 var numberEnd = consumeNumber$3(token.value, 0);
6508
6509 // check unit
6510 if (type !== null) {
6511 // check for IE postfix hack, i.e. 123px\0 or 123px\9
6512 var reverseSolidusOffset = token.value.indexOf('\\', numberEnd);
6513 var unit = reverseSolidusOffset === -1 || !isPostfixIeHack(token.value, reverseSolidusOffset)
6514 ? token.value.substr(numberEnd)
6515 : token.value.substring(numberEnd, reverseSolidusOffset);
6516
6517 if (type.hasOwnProperty(unit.toLowerCase()) === false) {
6518 return 0;
6519 }
6520 }
6521
6522 // check range if specified
6523 if (outOfRange(opts, token.value, numberEnd)) {
6524 return 0;
6525 }
6526
6527 return 1;
6528 };
6529 }
6530
6531 // =========================
6532 // Percentage
6533 //
6534
6535 // §5.5. Percentages: the <percentage> type
6536 // https://drafts.csswg.org/css-values-4/#percentages
6537 function percentage(token, getNextToken, opts) {
6538 // ... corresponds to the <percentage-token> production
6539 if (token === null || token.type !== TYPE$C.Percentage) {
6540 return 0;
6541 }
6542
6543 // check range if specified
6544 if (outOfRange(opts, token.value, token.value.length - 1)) {
6545 return 0;
6546 }
6547
6548 return 1;
6549 }
6550
6551 // =========================
6552 // Numeric
6553 //
6554
6555 // https://drafts.csswg.org/css-values-4/#numbers
6556 // The value <zero> represents a literal number with the value 0. Expressions that merely
6557 // evaluate to a <number> with the value 0 (for example, calc(0)) do not match <zero>;
6558 // only literal <number-token>s do.
6559 function zero(next) {
6560 if (typeof next !== 'function') {
6561 next = function() {
6562 return 0;
6563 };
6564 }
6565
6566 return function(token, getNextToken, opts) {
6567 if (token !== null && token.type === TYPE$C.Number) {
6568 if (Number(token.value) === 0) {
6569 return 1;
6570 }
6571 }
6572
6573 return next(token, getNextToken, opts);
6574 };
6575 }
6576
6577 // § 5.3. Real Numbers: the <number> type
6578 // https://drafts.csswg.org/css-values-4/#numbers
6579 // Number values are denoted by <number>, and represent real numbers, possibly with a fractional component.
6580 // ... It corresponds to the <number-token> production
6581 function number(token, getNextToken, opts) {
6582 if (token === null) {
6583 return 0;
6584 }
6585
6586 var numberEnd = consumeNumber$3(token.value, 0);
6587 var isNumber = numberEnd === token.value.length;
6588 if (!isNumber && !isPostfixIeHack(token.value, numberEnd)) {
6589 return 0;
6590 }
6591
6592 // check range if specified
6593 if (outOfRange(opts, token.value, numberEnd)) {
6594 return 0;
6595 }
6596
6597 return 1;
6598 }
6599
6600 // §5.2. Integers: the <integer> type
6601 // https://drafts.csswg.org/css-values-4/#integers
6602 function integer(token, getNextToken, opts) {
6603 // ... corresponds to a subset of the <number-token> production
6604 if (token === null || token.type !== TYPE$C.Number) {
6605 return 0;
6606 }
6607
6608 // The first digit of an integer may be immediately preceded by `-` or `+` to indicate the integer’s sign.
6609 var i = token.value.charCodeAt(0) === 0x002B || // U+002B PLUS SIGN (+)
6610 token.value.charCodeAt(0) === 0x002D ? 1 : 0; // U+002D HYPHEN-MINUS (-)
6611
6612 // When written literally, an integer is one or more decimal digits 0 through 9 ...
6613 for (; i < token.value.length; i++) {
6614 if (!isDigit$2(token.value.charCodeAt(i))) {
6615 return 0;
6616 }
6617 }
6618
6619 // check range if specified
6620 if (outOfRange(opts, token.value, i)) {
6621 return 0;
6622 }
6623
6624 return 1;
6625 }
6626
6627 var generic$1 = {
6628 // token types
6629 'ident-token': tokenType(TYPE$C.Ident),
6630 'function-token': tokenType(TYPE$C.Function),
6631 'at-keyword-token': tokenType(TYPE$C.AtKeyword),
6632 'hash-token': tokenType(TYPE$C.Hash),
6633 'string-token': tokenType(TYPE$C.String),
6634 'bad-string-token': tokenType(TYPE$C.BadString),
6635 'url-token': tokenType(TYPE$C.Url),
6636 'bad-url-token': tokenType(TYPE$C.BadUrl),
6637 'delim-token': tokenType(TYPE$C.Delim),
6638 'number-token': tokenType(TYPE$C.Number),
6639 'percentage-token': tokenType(TYPE$C.Percentage),
6640 'dimension-token': tokenType(TYPE$C.Dimension),
6641 'whitespace-token': tokenType(TYPE$C.WhiteSpace),
6642 'CDO-token': tokenType(TYPE$C.CDO),
6643 'CDC-token': tokenType(TYPE$C.CDC),
6644 'colon-token': tokenType(TYPE$C.Colon),
6645 'semicolon-token': tokenType(TYPE$C.Semicolon),
6646 'comma-token': tokenType(TYPE$C.Comma),
6647 '[-token': tokenType(TYPE$C.LeftSquareBracket),
6648 ']-token': tokenType(TYPE$C.RightSquareBracket),
6649 '(-token': tokenType(TYPE$C.LeftParenthesis),
6650 ')-token': tokenType(TYPE$C.RightParenthesis),
6651 '{-token': tokenType(TYPE$C.LeftCurlyBracket),
6652 '}-token': tokenType(TYPE$C.RightCurlyBracket),
6653
6654 // token type aliases
6655 'string': tokenType(TYPE$C.String),
6656 'ident': tokenType(TYPE$C.Ident),
6657
6658 // complex types
6659 'custom-ident': customIdent,
6660 'custom-property-name': customPropertyName,
6661 'hex-color': hexColor,
6662 'id-selector': idSelector, // element( <id-selector> )
6663 'an-plus-b': anPlusB,
6664 'urange': urange,
6665 'declaration-value': declarationValue,
6666 'any-value': anyValue,
6667
6668 // dimensions
6669 'dimension': calc(dimension(null)),
6670 'angle': calc(dimension(ANGLE)),
6671 'decibel': calc(dimension(DECIBEL)),
6672 'frequency': calc(dimension(FREQUENCY)),
6673 'flex': calc(dimension(FLEX)),
6674 'length': calc(zero(dimension(LENGTH))),
6675 'resolution': calc(dimension(RESOLUTION)),
6676 'semitones': calc(dimension(SEMITONES)),
6677 'time': calc(dimension(TIME)),
6678
6679 // percentage
6680 'percentage': calc(percentage),
6681
6682 // numeric
6683 'zero': zero(),
6684 'number': calc(number),
6685 'integer': calc(integer),
6686
6687 // old IE stuff
6688 '-ms-legacy-expression': func('expression')
6689 };
6690
6691 var createCustomError = createCustomError$3;
6692
6693 var _SyntaxError = function SyntaxError(message, input, offset) {
6694 var error = createCustomError('SyntaxError', message);
6695
6696 error.input = input;
6697 error.offset = offset;
6698 error.rawMessage = message;
6699 error.message = error.rawMessage + '\n' +
6700 ' ' + error.input + '\n' +
6701 '--' + new Array((error.offset || error.input.length) + 1).join('-') + '^';
6702
6703 return error;
6704 };
6705
6706 var SyntaxError$3 = _SyntaxError;
6707
6708 var TAB$1 = 9;
6709 var N$3 = 10;
6710 var F$2 = 12;
6711 var R$2 = 13;
6712 var SPACE$2 = 32;
6713
6714 var Tokenizer$1 = function(str) {
6715 this.str = str;
6716 this.pos = 0;
6717 };
6718
6719 Tokenizer$1.prototype = {
6720 charCodeAt: function(pos) {
6721 return pos < this.str.length ? this.str.charCodeAt(pos) : 0;
6722 },
6723 charCode: function() {
6724 return this.charCodeAt(this.pos);
6725 },
6726 nextCharCode: function() {
6727 return this.charCodeAt(this.pos + 1);
6728 },
6729 nextNonWsCode: function(pos) {
6730 return this.charCodeAt(this.findWsEnd(pos));
6731 },
6732 findWsEnd: function(pos) {
6733 for (; pos < this.str.length; pos++) {
6734 var code = this.str.charCodeAt(pos);
6735 if (code !== R$2 && code !== N$3 && code !== F$2 && code !== SPACE$2 && code !== TAB$1) {
6736 break;
6737 }
6738 }
6739
6740 return pos;
6741 },
6742 substringToPos: function(end) {
6743 return this.str.substring(this.pos, this.pos = end);
6744 },
6745 eat: function(code) {
6746 if (this.charCode() !== code) {
6747 this.error('Expect `' + String.fromCharCode(code) + '`');
6748 }
6749
6750 this.pos++;
6751 },
6752 peek: function() {
6753 return this.pos < this.str.length ? this.str.charAt(this.pos++) : '';
6754 },
6755 error: function(message) {
6756 throw new SyntaxError$3(message, this.str, this.pos);
6757 }
6758 };
6759
6760 var tokenizer$1 = Tokenizer$1;
6761
6762 var Tokenizer = tokenizer$1;
6763 var TAB = 9;
6764 var N$2 = 10;
6765 var F$1 = 12;
6766 var R$1 = 13;
6767 var SPACE$1 = 32;
6768 var EXCLAMATIONMARK$3 = 33; // !
6769 var NUMBERSIGN$4 = 35; // #
6770 var AMPERSAND$1 = 38; // &
6771 var APOSTROPHE = 39; // '
6772 var LEFTPARENTHESIS$7 = 40; // (
6773 var RIGHTPARENTHESIS$7 = 41; // )
6774 var ASTERISK$6 = 42; // *
6775 var PLUSSIGN$6 = 43; // +
6776 var COMMA$4 = 44; // ,
6777 var HYPERMINUS = 45; // -
6778 var LESSTHANSIGN = 60; // <
6779 var GREATERTHANSIGN$2 = 62; // >
6780 var QUESTIONMARK$1 = 63; // ?
6781 var COMMERCIALAT = 64; // @
6782 var LEFTSQUAREBRACKET$4 = 91; // [
6783 var RIGHTSQUAREBRACKET$2 = 93; // ]
6784 var LEFTCURLYBRACKET$4 = 123; // {
6785 var VERTICALLINE$3 = 124; // |
6786 var RIGHTCURLYBRACKET$2 = 125; // }
6787 var INFINITY = 8734; // ∞
6788 var NAME_CHAR = createCharMap(function(ch) {
6789 return /[a-zA-Z0-9\-]/.test(ch);
6790 });
6791 var COMBINATOR_PRECEDENCE = {
6792 ' ': 1,
6793 '&&': 2,
6794 '||': 3,
6795 '|': 4
6796 };
6797
6798 function createCharMap(fn) {
6799 var array = typeof Uint32Array === 'function' ? new Uint32Array(128) : new Array(128);
6800 for (var i = 0; i < 128; i++) {
6801 array[i] = fn(String.fromCharCode(i)) ? 1 : 0;
6802 }
6803 return array;
6804 }
6805
6806 function scanSpaces(tokenizer) {
6807 return tokenizer.substringToPos(
6808 tokenizer.findWsEnd(tokenizer.pos)
6809 );
6810 }
6811
6812 function scanWord(tokenizer) {
6813 var end = tokenizer.pos;
6814
6815 for (; end < tokenizer.str.length; end++) {
6816 var code = tokenizer.str.charCodeAt(end);
6817 if (code >= 128 || NAME_CHAR[code] === 0) {
6818 break;
6819 }
6820 }
6821
6822 if (tokenizer.pos === end) {
6823 tokenizer.error('Expect a keyword');
6824 }
6825
6826 return tokenizer.substringToPos(end);
6827 }
6828
6829 function scanNumber(tokenizer) {
6830 var end = tokenizer.pos;
6831
6832 for (; end < tokenizer.str.length; end++) {
6833 var code = tokenizer.str.charCodeAt(end);
6834 if (code < 48 || code > 57) {
6835 break;
6836 }
6837 }
6838
6839 if (tokenizer.pos === end) {
6840 tokenizer.error('Expect a number');
6841 }
6842
6843 return tokenizer.substringToPos(end);
6844 }
6845
6846 function scanString(tokenizer) {
6847 var end = tokenizer.str.indexOf('\'', tokenizer.pos + 1);
6848
6849 if (end === -1) {
6850 tokenizer.pos = tokenizer.str.length;
6851 tokenizer.error('Expect an apostrophe');
6852 }
6853
6854 return tokenizer.substringToPos(end + 1);
6855 }
6856
6857 function readMultiplierRange(tokenizer) {
6858 var min = null;
6859 var max = null;
6860
6861 tokenizer.eat(LEFTCURLYBRACKET$4);
6862
6863 min = scanNumber(tokenizer);
6864
6865 if (tokenizer.charCode() === COMMA$4) {
6866 tokenizer.pos++;
6867 if (tokenizer.charCode() !== RIGHTCURLYBRACKET$2) {
6868 max = scanNumber(tokenizer);
6869 }
6870 } else {
6871 max = min;
6872 }
6873
6874 tokenizer.eat(RIGHTCURLYBRACKET$2);
6875
6876 return {
6877 min: Number(min),
6878 max: max ? Number(max) : 0
6879 };
6880 }
6881
6882 function readMultiplier(tokenizer) {
6883 var range = null;
6884 var comma = false;
6885
6886 switch (tokenizer.charCode()) {
6887 case ASTERISK$6:
6888 tokenizer.pos++;
6889
6890 range = {
6891 min: 0,
6892 max: 0
6893 };
6894
6895 break;
6896
6897 case PLUSSIGN$6:
6898 tokenizer.pos++;
6899
6900 range = {
6901 min: 1,
6902 max: 0
6903 };
6904
6905 break;
6906
6907 case QUESTIONMARK$1:
6908 tokenizer.pos++;
6909
6910 range = {
6911 min: 0,
6912 max: 1
6913 };
6914
6915 break;
6916
6917 case NUMBERSIGN$4:
6918 tokenizer.pos++;
6919
6920 comma = true;
6921
6922 if (tokenizer.charCode() === LEFTCURLYBRACKET$4) {
6923 range = readMultiplierRange(tokenizer);
6924 } else {
6925 range = {
6926 min: 1,
6927 max: 0
6928 };
6929 }
6930
6931 break;
6932
6933 case LEFTCURLYBRACKET$4:
6934 range = readMultiplierRange(tokenizer);
6935 break;
6936
6937 default:
6938 return null;
6939 }
6940
6941 return {
6942 type: 'Multiplier',
6943 comma: comma,
6944 min: range.min,
6945 max: range.max,
6946 term: null
6947 };
6948 }
6949
6950 function maybeMultiplied(tokenizer, node) {
6951 var multiplier = readMultiplier(tokenizer);
6952
6953 if (multiplier !== null) {
6954 multiplier.term = node;
6955 return multiplier;
6956 }
6957
6958 return node;
6959 }
6960
6961 function maybeToken(tokenizer) {
6962 var ch = tokenizer.peek();
6963
6964 if (ch === '') {
6965 return null;
6966 }
6967
6968 return {
6969 type: 'Token',
6970 value: ch
6971 };
6972 }
6973
6974 function readProperty$1(tokenizer) {
6975 var name;
6976
6977 tokenizer.eat(LESSTHANSIGN);
6978 tokenizer.eat(APOSTROPHE);
6979
6980 name = scanWord(tokenizer);
6981
6982 tokenizer.eat(APOSTROPHE);
6983 tokenizer.eat(GREATERTHANSIGN$2);
6984
6985 return maybeMultiplied(tokenizer, {
6986 type: 'Property',
6987 name: name
6988 });
6989 }
6990
6991 // https://drafts.csswg.org/css-values-3/#numeric-ranges
6992 // 4.1. Range Restrictions and Range Definition Notation
6993 //
6994 // Range restrictions can be annotated in the numeric type notation using CSS bracketed
6995 // range notation—[min,max]—within the angle brackets, after the identifying keyword,
6996 // indicating a closed range between (and including) min and max.
6997 // For example, <integer [0, 10]> indicates an integer between 0 and 10, inclusive.
6998 function readTypeRange(tokenizer) {
6999 // use null for Infinity to make AST format JSON serializable/deserializable
7000 var min = null; // -Infinity
7001 var max = null; // Infinity
7002 var sign = 1;
7003
7004 tokenizer.eat(LEFTSQUAREBRACKET$4);
7005
7006 if (tokenizer.charCode() === HYPERMINUS) {
7007 tokenizer.peek();
7008 sign = -1;
7009 }
7010
7011 if (sign == -1 && tokenizer.charCode() === INFINITY) {
7012 tokenizer.peek();
7013 } else {
7014 min = sign * Number(scanNumber(tokenizer));
7015 }
7016
7017 scanSpaces(tokenizer);
7018 tokenizer.eat(COMMA$4);
7019 scanSpaces(tokenizer);
7020
7021 if (tokenizer.charCode() === INFINITY) {
7022 tokenizer.peek();
7023 } else {
7024 sign = 1;
7025
7026 if (tokenizer.charCode() === HYPERMINUS) {
7027 tokenizer.peek();
7028 sign = -1;
7029 }
7030
7031 max = sign * Number(scanNumber(tokenizer));
7032 }
7033
7034 tokenizer.eat(RIGHTSQUAREBRACKET$2);
7035
7036 // If no range is indicated, either by using the bracketed range notation
7037 // or in the property description, then [−∞,∞] is assumed.
7038 if (min === null && max === null) {
7039 return null;
7040 }
7041
7042 return {
7043 type: 'Range',
7044 min: min,
7045 max: max
7046 };
7047 }
7048
7049 function readType(tokenizer) {
7050 var name;
7051 var opts = null;
7052
7053 tokenizer.eat(LESSTHANSIGN);
7054 name = scanWord(tokenizer);
7055
7056 if (tokenizer.charCode() === LEFTPARENTHESIS$7 &&
7057 tokenizer.nextCharCode() === RIGHTPARENTHESIS$7) {
7058 tokenizer.pos += 2;
7059 name += '()';
7060 }
7061
7062 if (tokenizer.charCodeAt(tokenizer.findWsEnd(tokenizer.pos)) === LEFTSQUAREBRACKET$4) {
7063 scanSpaces(tokenizer);
7064 opts = readTypeRange(tokenizer);
7065 }
7066
7067 tokenizer.eat(GREATERTHANSIGN$2);
7068
7069 return maybeMultiplied(tokenizer, {
7070 type: 'Type',
7071 name: name,
7072 opts: opts
7073 });
7074 }
7075
7076 function readKeywordOrFunction(tokenizer) {
7077 var name;
7078
7079 name = scanWord(tokenizer);
7080
7081 if (tokenizer.charCode() === LEFTPARENTHESIS$7) {
7082 tokenizer.pos++;
7083
7084 return {
7085 type: 'Function',
7086 name: name
7087 };
7088 }
7089
7090 return maybeMultiplied(tokenizer, {
7091 type: 'Keyword',
7092 name: name
7093 });
7094 }
7095
7096 function regroupTerms(terms, combinators) {
7097 function createGroup(terms, combinator) {
7098 return {
7099 type: 'Group',
7100 terms: terms,
7101 combinator: combinator,
7102 disallowEmpty: false,
7103 explicit: false
7104 };
7105 }
7106
7107 combinators = Object.keys(combinators).sort(function(a, b) {
7108 return COMBINATOR_PRECEDENCE[a] - COMBINATOR_PRECEDENCE[b];
7109 });
7110
7111 while (combinators.length > 0) {
7112 var combinator = combinators.shift();
7113 for (var i = 0, subgroupStart = 0; i < terms.length; i++) {
7114 var term = terms[i];
7115 if (term.type === 'Combinator') {
7116 if (term.value === combinator) {
7117 if (subgroupStart === -1) {
7118 subgroupStart = i - 1;
7119 }
7120 terms.splice(i, 1);
7121 i--;
7122 } else {
7123 if (subgroupStart !== -1 && i - subgroupStart > 1) {
7124 terms.splice(
7125 subgroupStart,
7126 i - subgroupStart,
7127 createGroup(terms.slice(subgroupStart, i), combinator)
7128 );
7129 i = subgroupStart + 1;
7130 }
7131 subgroupStart = -1;
7132 }
7133 }
7134 }
7135
7136 if (subgroupStart !== -1 && combinators.length) {
7137 terms.splice(
7138 subgroupStart,
7139 i - subgroupStart,
7140 createGroup(terms.slice(subgroupStart, i), combinator)
7141 );
7142 }
7143 }
7144
7145 return combinator;
7146 }
7147
7148 function readImplicitGroup(tokenizer) {
7149 var terms = [];
7150 var combinators = {};
7151 var token;
7152 var prevToken = null;
7153 var prevTokenPos = tokenizer.pos;
7154
7155 while (token = peek(tokenizer)) {
7156 if (token.type !== 'Spaces') {
7157 if (token.type === 'Combinator') {
7158 // check for combinator in group beginning and double combinator sequence
7159 if (prevToken === null || prevToken.type === 'Combinator') {
7160 tokenizer.pos = prevTokenPos;
7161 tokenizer.error('Unexpected combinator');
7162 }
7163
7164 combinators[token.value] = true;
7165 } else if (prevToken !== null && prevToken.type !== 'Combinator') {
7166 combinators[' '] = true; // a b
7167 terms.push({
7168 type: 'Combinator',
7169 value: ' '
7170 });
7171 }
7172
7173 terms.push(token);
7174 prevToken = token;
7175 prevTokenPos = tokenizer.pos;
7176 }
7177 }
7178
7179 // check for combinator in group ending
7180 if (prevToken !== null && prevToken.type === 'Combinator') {
7181 tokenizer.pos -= prevTokenPos;
7182 tokenizer.error('Unexpected combinator');
7183 }
7184
7185 return {
7186 type: 'Group',
7187 terms: terms,
7188 combinator: regroupTerms(terms, combinators) || ' ',
7189 disallowEmpty: false,
7190 explicit: false
7191 };
7192 }
7193
7194 function readGroup(tokenizer) {
7195 var result;
7196
7197 tokenizer.eat(LEFTSQUAREBRACKET$4);
7198 result = readImplicitGroup(tokenizer);
7199 tokenizer.eat(RIGHTSQUAREBRACKET$2);
7200
7201 result.explicit = true;
7202
7203 if (tokenizer.charCode() === EXCLAMATIONMARK$3) {
7204 tokenizer.pos++;
7205 result.disallowEmpty = true;
7206 }
7207
7208 return result;
7209 }
7210
7211 function peek(tokenizer) {
7212 var code = tokenizer.charCode();
7213
7214 if (code < 128 && NAME_CHAR[code] === 1) {
7215 return readKeywordOrFunction(tokenizer);
7216 }
7217
7218 switch (code) {
7219 case RIGHTSQUAREBRACKET$2:
7220 // don't eat, stop scan a group
7221 break;
7222
7223 case LEFTSQUAREBRACKET$4:
7224 return maybeMultiplied(tokenizer, readGroup(tokenizer));
7225
7226 case LESSTHANSIGN:
7227 return tokenizer.nextCharCode() === APOSTROPHE
7228 ? readProperty$1(tokenizer)
7229 : readType(tokenizer);
7230
7231 case VERTICALLINE$3:
7232 return {
7233 type: 'Combinator',
7234 value: tokenizer.substringToPos(
7235 tokenizer.nextCharCode() === VERTICALLINE$3
7236 ? tokenizer.pos + 2
7237 : tokenizer.pos + 1
7238 )
7239 };
7240
7241 case AMPERSAND$1:
7242 tokenizer.pos++;
7243 tokenizer.eat(AMPERSAND$1);
7244
7245 return {
7246 type: 'Combinator',
7247 value: '&&'
7248 };
7249
7250 case COMMA$4:
7251 tokenizer.pos++;
7252 return {
7253 type: 'Comma'
7254 };
7255
7256 case APOSTROPHE:
7257 return maybeMultiplied(tokenizer, {
7258 type: 'String',
7259 value: scanString(tokenizer)
7260 });
7261
7262 case SPACE$1:
7263 case TAB:
7264 case N$2:
7265 case R$1:
7266 case F$1:
7267 return {
7268 type: 'Spaces',
7269 value: scanSpaces(tokenizer)
7270 };
7271
7272 case COMMERCIALAT:
7273 code = tokenizer.nextCharCode();
7274
7275 if (code < 128 && NAME_CHAR[code] === 1) {
7276 tokenizer.pos++;
7277 return {
7278 type: 'AtKeyword',
7279 name: scanWord(tokenizer)
7280 };
7281 }
7282
7283 return maybeToken(tokenizer);
7284
7285 case ASTERISK$6:
7286 case PLUSSIGN$6:
7287 case QUESTIONMARK$1:
7288 case NUMBERSIGN$4:
7289 case EXCLAMATIONMARK$3:
7290 // prohibited tokens (used as a multiplier start)
7291 break;
7292
7293 case LEFTCURLYBRACKET$4:
7294 // LEFTCURLYBRACKET is allowed since mdn/data uses it w/o quoting
7295 // check next char isn't a number, because it's likely a disjoined multiplier
7296 code = tokenizer.nextCharCode();
7297
7298 if (code < 48 || code > 57) {
7299 return maybeToken(tokenizer);
7300 }
7301
7302 break;
7303
7304 default:
7305 return maybeToken(tokenizer);
7306 }
7307 }
7308
7309 function parse$2(source) {
7310 var tokenizer = new Tokenizer(source);
7311 var result = readImplicitGroup(tokenizer);
7312
7313 if (tokenizer.pos !== source.length) {
7314 tokenizer.error('Unexpected input');
7315 }
7316
7317 // reduce redundant groups with single group term
7318 if (result.terms.length === 1 && result.terms[0].type === 'Group') {
7319 result = result.terms[0];
7320 }
7321
7322 return result;
7323 }
7324
7325 // warm up parse to elimitate code branches that never execute
7326 // fix soft deoptimizations (insufficient type feedback)
7327 parse$2('[a&&<b>#|<\'c\'>*||e() f{2} /,(% g#{1,2} h{2,})]!');
7328
7329 var parse_1 = parse$2;
7330
7331 var noop$2 = function() {};
7332
7333 function ensureFunction$1(value) {
7334 return typeof value === 'function' ? value : noop$2;
7335 }
7336
7337 var walk$1 = function(node, options, context) {
7338 function walk(node) {
7339 enter.call(context, node);
7340
7341 switch (node.type) {
7342 case 'Group':
7343 node.terms.forEach(walk);
7344 break;
7345
7346 case 'Multiplier':
7347 walk(node.term);
7348 break;
7349
7350 case 'Type':
7351 case 'Property':
7352 case 'Keyword':
7353 case 'AtKeyword':
7354 case 'Function':
7355 case 'String':
7356 case 'Token':
7357 case 'Comma':
7358 break;
7359
7360 default:
7361 throw new Error('Unknown type: ' + node.type);
7362 }
7363
7364 leave.call(context, node);
7365 }
7366
7367 var enter = noop$2;
7368 var leave = noop$2;
7369
7370 if (typeof options === 'function') {
7371 enter = options;
7372 } else if (options) {
7373 enter = ensureFunction$1(options.enter);
7374 leave = ensureFunction$1(options.leave);
7375 }
7376
7377 if (enter === noop$2 && leave === noop$2) {
7378 throw new Error('Neither `enter` nor `leave` walker handler is set or both aren\'t a function');
7379 }
7380
7381 walk(node);
7382 };
7383
7384 var tokenize$2 = tokenizer$3;
7385 var TokenStream$2 = TokenStream_1;
7386 var tokenStream = new TokenStream$2();
7387 var astToTokens = {
7388 decorator: function(handlers) {
7389 var curNode = null;
7390 var prev = { len: 0, node: null };
7391 var nodes = [prev];
7392 var buffer = '';
7393
7394 return {
7395 children: handlers.children,
7396 node: function(node) {
7397 var tmp = curNode;
7398 curNode = node;
7399 handlers.node.call(this, node);
7400 curNode = tmp;
7401 },
7402 chunk: function(chunk) {
7403 buffer += chunk;
7404 if (prev.node !== curNode) {
7405 nodes.push({
7406 len: chunk.length,
7407 node: curNode
7408 });
7409 } else {
7410 prev.len += chunk.length;
7411 }
7412 },
7413 result: function() {
7414 return prepareTokens$1(buffer, nodes);
7415 }
7416 };
7417 }
7418 };
7419
7420 function prepareTokens$1(str, nodes) {
7421 var tokens = [];
7422 var nodesOffset = 0;
7423 var nodesIndex = 0;
7424 var currentNode = nodes ? nodes[nodesIndex].node : null;
7425
7426 tokenize$2(str, tokenStream);
7427
7428 while (!tokenStream.eof) {
7429 if (nodes) {
7430 while (nodesIndex < nodes.length && nodesOffset + nodes[nodesIndex].len <= tokenStream.tokenStart) {
7431 nodesOffset += nodes[nodesIndex++].len;
7432 currentNode = nodes[nodesIndex].node;
7433 }
7434 }
7435
7436 tokens.push({
7437 type: tokenStream.tokenType,
7438 value: tokenStream.getTokenValue(),
7439 index: tokenStream.tokenIndex, // TODO: remove it, temporary solution
7440 balance: tokenStream.balance[tokenStream.tokenIndex], // TODO: remove it, temporary solution
7441 node: currentNode
7442 });
7443 tokenStream.next();
7444 // console.log({ ...tokens[tokens.length - 1], node: undefined });
7445 }
7446
7447 return tokens;
7448 }
7449
7450 var prepareTokens_1 = function(value, syntax) {
7451 if (typeof value === 'string') {
7452 return prepareTokens$1(value, null);
7453 }
7454
7455 return syntax.generate(value, astToTokens);
7456 };
7457
7458 var parse$1 = parse_1;
7459
7460 var MATCH$1 = { type: 'Match' };
7461 var MISMATCH$1 = { type: 'Mismatch' };
7462 var DISALLOW_EMPTY$1 = { type: 'DisallowEmpty' };
7463 var LEFTPARENTHESIS$6 = 40; // (
7464 var RIGHTPARENTHESIS$6 = 41; // )
7465
7466 function createCondition(match, thenBranch, elseBranch) {
7467 // reduce node count
7468 if (thenBranch === MATCH$1 && elseBranch === MISMATCH$1) {
7469 return match;
7470 }
7471
7472 if (match === MATCH$1 && thenBranch === MATCH$1 && elseBranch === MATCH$1) {
7473 return match;
7474 }
7475
7476 if (match.type === 'If' && match.else === MISMATCH$1 && thenBranch === MATCH$1) {
7477 thenBranch = match.then;
7478 match = match.match;
7479 }
7480
7481 return {
7482 type: 'If',
7483 match: match,
7484 then: thenBranch,
7485 else: elseBranch
7486 };
7487 }
7488
7489 function isFunctionType(name) {
7490 return (
7491 name.length > 2 &&
7492 name.charCodeAt(name.length - 2) === LEFTPARENTHESIS$6 &&
7493 name.charCodeAt(name.length - 1) === RIGHTPARENTHESIS$6
7494 );
7495 }
7496
7497 function isEnumCapatible(term) {
7498 return (
7499 term.type === 'Keyword' ||
7500 term.type === 'AtKeyword' ||
7501 term.type === 'Function' ||
7502 term.type === 'Type' && isFunctionType(term.name)
7503 );
7504 }
7505
7506 function buildGroupMatchGraph(combinator, terms, atLeastOneTermMatched) {
7507 switch (combinator) {
7508 case ' ':
7509 // Juxtaposing components means that all of them must occur, in the given order.
7510 //
7511 // a b c
7512 // =
7513 // match a
7514 // then match b
7515 // then match c
7516 // then MATCH
7517 // else MISMATCH
7518 // else MISMATCH
7519 // else MISMATCH
7520 var result = MATCH$1;
7521
7522 for (var i = terms.length - 1; i >= 0; i--) {
7523 var term = terms[i];
7524
7525 result = createCondition(
7526 term,
7527 result,
7528 MISMATCH$1
7529 );
7530 }
7531 return result;
7532
7533 case '|':
7534 // A bar (|) separates two or more alternatives: exactly one of them must occur.
7535 //
7536 // a | b | c
7537 // =
7538 // match a
7539 // then MATCH
7540 // else match b
7541 // then MATCH
7542 // else match c
7543 // then MATCH
7544 // else MISMATCH
7545
7546 var result = MISMATCH$1;
7547 var map = null;
7548
7549 for (var i = terms.length - 1; i >= 0; i--) {
7550 var term = terms[i];
7551
7552 // reduce sequence of keywords into a Enum
7553 if (isEnumCapatible(term)) {
7554 if (map === null && i > 0 && isEnumCapatible(terms[i - 1])) {
7555 map = Object.create(null);
7556 result = createCondition(
7557 {
7558 type: 'Enum',
7559 map: map
7560 },
7561 MATCH$1,
7562 result
7563 );
7564 }
7565
7566 if (map !== null) {
7567 var key = (isFunctionType(term.name) ? term.name.slice(0, -1) : term.name).toLowerCase();
7568 if (key in map === false) {
7569 map[key] = term;
7570 continue;
7571 }
7572 }
7573 }
7574
7575 map = null;
7576
7577 // create a new conditonal node
7578 result = createCondition(
7579 term,
7580 MATCH$1,
7581 result
7582 );
7583 }
7584 return result;
7585
7586 case '&&':
7587 // A double ampersand (&&) separates two or more components,
7588 // all of which must occur, in any order.
7589
7590 // Use MatchOnce for groups with a large number of terms,
7591 // since &&-groups produces at least N!-node trees
7592 if (terms.length > 5) {
7593 return {
7594 type: 'MatchOnce',
7595 terms: terms,
7596 all: true
7597 };
7598 }
7599
7600 // Use a combination tree for groups with small number of terms
7601 //
7602 // a && b && c
7603 // =
7604 // match a
7605 // then [b && c]
7606 // else match b
7607 // then [a && c]
7608 // else match c
7609 // then [a && b]
7610 // else MISMATCH
7611 //
7612 // a && b
7613 // =
7614 // match a
7615 // then match b
7616 // then MATCH
7617 // else MISMATCH
7618 // else match b
7619 // then match a
7620 // then MATCH
7621 // else MISMATCH
7622 // else MISMATCH
7623 var result = MISMATCH$1;
7624
7625 for (var i = terms.length - 1; i >= 0; i--) {
7626 var term = terms[i];
7627 var thenClause;
7628
7629 if (terms.length > 1) {
7630 thenClause = buildGroupMatchGraph(
7631 combinator,
7632 terms.filter(function(newGroupTerm) {
7633 return newGroupTerm !== term;
7634 }),
7635 false
7636 );
7637 } else {
7638 thenClause = MATCH$1;
7639 }
7640
7641 result = createCondition(
7642 term,
7643 thenClause,
7644 result
7645 );
7646 }
7647 return result;
7648
7649 case '||':
7650 // A double bar (||) separates two or more options:
7651 // one or more of them must occur, in any order.
7652
7653 // Use MatchOnce for groups with a large number of terms,
7654 // since ||-groups produces at least N!-node trees
7655 if (terms.length > 5) {
7656 return {
7657 type: 'MatchOnce',
7658 terms: terms,
7659 all: false
7660 };
7661 }
7662
7663 // Use a combination tree for groups with small number of terms
7664 //
7665 // a || b || c
7666 // =
7667 // match a
7668 // then [b || c]
7669 // else match b
7670 // then [a || c]
7671 // else match c
7672 // then [a || b]
7673 // else MISMATCH
7674 //
7675 // a || b
7676 // =
7677 // match a
7678 // then match b
7679 // then MATCH
7680 // else MATCH
7681 // else match b
7682 // then match a
7683 // then MATCH
7684 // else MATCH
7685 // else MISMATCH
7686 var result = atLeastOneTermMatched ? MATCH$1 : MISMATCH$1;
7687
7688 for (var i = terms.length - 1; i >= 0; i--) {
7689 var term = terms[i];
7690 var thenClause;
7691
7692 if (terms.length > 1) {
7693 thenClause = buildGroupMatchGraph(
7694 combinator,
7695 terms.filter(function(newGroupTerm) {
7696 return newGroupTerm !== term;
7697 }),
7698 true
7699 );
7700 } else {
7701 thenClause = MATCH$1;
7702 }
7703
7704 result = createCondition(
7705 term,
7706 thenClause,
7707 result
7708 );
7709 }
7710 return result;
7711 }
7712 }
7713
7714 function buildMultiplierMatchGraph(node) {
7715 var result = MATCH$1;
7716 var matchTerm = buildMatchGraph$1(node.term);
7717
7718 if (node.max === 0) {
7719 // disable repeating of empty match to prevent infinite loop
7720 matchTerm = createCondition(
7721 matchTerm,
7722 DISALLOW_EMPTY$1,
7723 MISMATCH$1
7724 );
7725
7726 // an occurrence count is not limited, make a cycle;
7727 // to collect more terms on each following matching mismatch
7728 result = createCondition(
7729 matchTerm,
7730 null, // will be a loop
7731 MISMATCH$1
7732 );
7733
7734 result.then = createCondition(
7735 MATCH$1,
7736 MATCH$1,
7737 result // make a loop
7738 );
7739
7740 if (node.comma) {
7741 result.then.else = createCondition(
7742 { type: 'Comma', syntax: node },
7743 result,
7744 MISMATCH$1
7745 );
7746 }
7747 } else {
7748 // create a match node chain for [min .. max] interval with optional matches
7749 for (var i = node.min || 1; i <= node.max; i++) {
7750 if (node.comma && result !== MATCH$1) {
7751 result = createCondition(
7752 { type: 'Comma', syntax: node },
7753 result,
7754 MISMATCH$1
7755 );
7756 }
7757
7758 result = createCondition(
7759 matchTerm,
7760 createCondition(
7761 MATCH$1,
7762 MATCH$1,
7763 result
7764 ),
7765 MISMATCH$1
7766 );
7767 }
7768 }
7769
7770 if (node.min === 0) {
7771 // allow zero match
7772 result = createCondition(
7773 MATCH$1,
7774 MATCH$1,
7775 result
7776 );
7777 } else {
7778 // create a match node chain to collect [0 ... min - 1] required matches
7779 for (var i = 0; i < node.min - 1; i++) {
7780 if (node.comma && result !== MATCH$1) {
7781 result = createCondition(
7782 { type: 'Comma', syntax: node },
7783 result,
7784 MISMATCH$1
7785 );
7786 }
7787
7788 result = createCondition(
7789 matchTerm,
7790 result,
7791 MISMATCH$1
7792 );
7793 }
7794 }
7795
7796 return result;
7797 }
7798
7799 function buildMatchGraph$1(node) {
7800 if (typeof node === 'function') {
7801 return {
7802 type: 'Generic',
7803 fn: node
7804 };
7805 }
7806
7807 switch (node.type) {
7808 case 'Group':
7809 var result = buildGroupMatchGraph(
7810 node.combinator,
7811 node.terms.map(buildMatchGraph$1),
7812 false
7813 );
7814
7815 if (node.disallowEmpty) {
7816 result = createCondition(
7817 result,
7818 DISALLOW_EMPTY$1,
7819 MISMATCH$1
7820 );
7821 }
7822
7823 return result;
7824
7825 case 'Multiplier':
7826 return buildMultiplierMatchGraph(node);
7827
7828 case 'Type':
7829 case 'Property':
7830 return {
7831 type: node.type,
7832 name: node.name,
7833 syntax: node
7834 };
7835
7836 case 'Keyword':
7837 return {
7838 type: node.type,
7839 name: node.name.toLowerCase(),
7840 syntax: node
7841 };
7842
7843 case 'AtKeyword':
7844 return {
7845 type: node.type,
7846 name: '@' + node.name.toLowerCase(),
7847 syntax: node
7848 };
7849
7850 case 'Function':
7851 return {
7852 type: node.type,
7853 name: node.name.toLowerCase() + '(',
7854 syntax: node
7855 };
7856
7857 case 'String':
7858 // convert a one char length String to a Token
7859 if (node.value.length === 3) {
7860 return {
7861 type: 'Token',
7862 value: node.value.charAt(1),
7863 syntax: node
7864 };
7865 }
7866
7867 // otherwise use it as is
7868 return {
7869 type: node.type,
7870 value: node.value.substr(1, node.value.length - 2).replace(/\\'/g, '\''),
7871 syntax: node
7872 };
7873
7874 case 'Token':
7875 return {
7876 type: node.type,
7877 value: node.value,
7878 syntax: node
7879 };
7880
7881 case 'Comma':
7882 return {
7883 type: node.type,
7884 syntax: node
7885 };
7886
7887 default:
7888 throw new Error('Unknown node type:', node.type);
7889 }
7890 }
7891
7892 var matchGraph$1 = {
7893 MATCH: MATCH$1,
7894 MISMATCH: MISMATCH$1,
7895 DISALLOW_EMPTY: DISALLOW_EMPTY$1,
7896 buildMatchGraph: function(syntaxTree, ref) {
7897 if (typeof syntaxTree === 'string') {
7898 syntaxTree = parse$1(syntaxTree);
7899 }
7900
7901 return {
7902 type: 'MatchGraph',
7903 match: buildMatchGraph$1(syntaxTree),
7904 syntax: ref || null,
7905 source: syntaxTree
7906 };
7907 }
7908 };
7909
7910 var hasOwnProperty$6 = Object.prototype.hasOwnProperty;
7911 var matchGraph = matchGraph$1;
7912 var MATCH = matchGraph.MATCH;
7913 var MISMATCH = matchGraph.MISMATCH;
7914 var DISALLOW_EMPTY = matchGraph.DISALLOW_EMPTY;
7915 var TYPE$B = _const.TYPE;
7916
7917 var STUB = 0;
7918 var TOKEN = 1;
7919 var OPEN_SYNTAX = 2;
7920 var CLOSE_SYNTAX = 3;
7921
7922 var EXIT_REASON_MATCH = 'Match';
7923 var EXIT_REASON_MISMATCH = 'Mismatch';
7924 var EXIT_REASON_ITERATION_LIMIT = 'Maximum iteration number exceeded (please fill an issue on https://github.com/csstree/csstree/issues)';
7925
7926 var ITERATION_LIMIT = 15000;
7927 var totalIterationCount = 0;
7928
7929 function reverseList(list) {
7930 var prev = null;
7931 var next = null;
7932 var item = list;
7933
7934 while (item !== null) {
7935 next = item.prev;
7936 item.prev = prev;
7937 prev = item;
7938 item = next;
7939 }
7940
7941 return prev;
7942 }
7943
7944 function areStringsEqualCaseInsensitive(testStr, referenceStr) {
7945 if (testStr.length !== referenceStr.length) {
7946 return false;
7947 }
7948
7949 for (var i = 0; i < testStr.length; i++) {
7950 var testCode = testStr.charCodeAt(i);
7951 var referenceCode = referenceStr.charCodeAt(i);
7952
7953 // testCode.toLowerCase() for U+0041 LATIN CAPITAL LETTER A (A) .. U+005A LATIN CAPITAL LETTER Z (Z).
7954 if (testCode >= 0x0041 && testCode <= 0x005A) {
7955 testCode = testCode | 32;
7956 }
7957
7958 if (testCode !== referenceCode) {
7959 return false;
7960 }
7961 }
7962
7963 return true;
7964 }
7965
7966 function isContextEdgeDelim(token) {
7967 if (token.type !== TYPE$B.Delim) {
7968 return false;
7969 }
7970
7971 // Fix matching for unicode-range: U+30??, U+FF00-FF9F
7972 // Probably we need to check out previous match instead
7973 return token.value !== '?';
7974 }
7975
7976 function isCommaContextStart(token) {
7977 if (token === null) {
7978 return true;
7979 }
7980
7981 return (
7982 token.type === TYPE$B.Comma ||
7983 token.type === TYPE$B.Function ||
7984 token.type === TYPE$B.LeftParenthesis ||
7985 token.type === TYPE$B.LeftSquareBracket ||
7986 token.type === TYPE$B.LeftCurlyBracket ||
7987 isContextEdgeDelim(token)
7988 );
7989 }
7990
7991 function isCommaContextEnd(token) {
7992 if (token === null) {
7993 return true;
7994 }
7995
7996 return (
7997 token.type === TYPE$B.RightParenthesis ||
7998 token.type === TYPE$B.RightSquareBracket ||
7999 token.type === TYPE$B.RightCurlyBracket ||
8000 token.type === TYPE$B.Delim
8001 );
8002 }
8003
8004 function internalMatch(tokens, state, syntaxes) {
8005 function moveToNextToken() {
8006 do {
8007 tokenIndex++;
8008 token = tokenIndex < tokens.length ? tokens[tokenIndex] : null;
8009 } while (token !== null && (token.type === TYPE$B.WhiteSpace || token.type === TYPE$B.Comment));
8010 }
8011
8012 function getNextToken(offset) {
8013 var nextIndex = tokenIndex + offset;
8014
8015 return nextIndex < tokens.length ? tokens[nextIndex] : null;
8016 }
8017
8018 function stateSnapshotFromSyntax(nextState, prev) {
8019 return {
8020 nextState: nextState,
8021 matchStack: matchStack,
8022 syntaxStack: syntaxStack,
8023 thenStack: thenStack,
8024 tokenIndex: tokenIndex,
8025 prev: prev
8026 };
8027 }
8028
8029 function pushThenStack(nextState) {
8030 thenStack = {
8031 nextState: nextState,
8032 matchStack: matchStack,
8033 syntaxStack: syntaxStack,
8034 prev: thenStack
8035 };
8036 }
8037
8038 function pushElseStack(nextState) {
8039 elseStack = stateSnapshotFromSyntax(nextState, elseStack);
8040 }
8041
8042 function addTokenToMatch() {
8043 matchStack = {
8044 type: TOKEN,
8045 syntax: state.syntax,
8046 token: token,
8047 prev: matchStack
8048 };
8049
8050 moveToNextToken();
8051 syntaxStash = null;
8052
8053 if (tokenIndex > longestMatch) {
8054 longestMatch = tokenIndex;
8055 }
8056 }
8057
8058 function openSyntax() {
8059 syntaxStack = {
8060 syntax: state.syntax,
8061 opts: state.syntax.opts || (syntaxStack !== null && syntaxStack.opts) || null,
8062 prev: syntaxStack
8063 };
8064
8065 matchStack = {
8066 type: OPEN_SYNTAX,
8067 syntax: state.syntax,
8068 token: matchStack.token,
8069 prev: matchStack
8070 };
8071 }
8072
8073 function closeSyntax() {
8074 if (matchStack.type === OPEN_SYNTAX) {
8075 matchStack = matchStack.prev;
8076 } else {
8077 matchStack = {
8078 type: CLOSE_SYNTAX,
8079 syntax: syntaxStack.syntax,
8080 token: matchStack.token,
8081 prev: matchStack
8082 };
8083 }
8084
8085 syntaxStack = syntaxStack.prev;
8086 }
8087
8088 var syntaxStack = null;
8089 var thenStack = null;
8090 var elseStack = null;
8091
8092 // null – stashing allowed, nothing stashed
8093 // false – stashing disabled, nothing stashed
8094 // anithing else – fail stashable syntaxes, some syntax stashed
8095 var syntaxStash = null;
8096
8097 var iterationCount = 0; // count iterations and prevent infinite loop
8098 var exitReason = null;
8099
8100 var token = null;
8101 var tokenIndex = -1;
8102 var longestMatch = 0;
8103 var matchStack = {
8104 type: STUB,
8105 syntax: null,
8106 token: null,
8107 prev: null
8108 };
8109
8110 moveToNextToken();
8111
8112 while (exitReason === null && ++iterationCount < ITERATION_LIMIT) {
8113 // function mapList(list, fn) {
8114 // var result = [];
8115 // while (list) {
8116 // result.unshift(fn(list));
8117 // list = list.prev;
8118 // }
8119 // return result;
8120 // }
8121 // console.log('--\n',
8122 // '#' + iterationCount,
8123 // require('util').inspect({
8124 // 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),
8125 // token: token && token.value,
8126 // tokenIndex,
8127 // syntax: syntax.type + (syntax.id ? ' #' + syntax.id : '')
8128 // }, { depth: null })
8129 // );
8130 switch (state.type) {
8131 case 'Match':
8132 if (thenStack === null) {
8133 // turn to MISMATCH when some tokens left unmatched
8134 if (token !== null) {
8135 // doesn't mismatch if just one token left and it's an IE hack
8136 if (tokenIndex !== tokens.length - 1 || (token.value !== '\\0' && token.value !== '\\9')) {
8137 state = MISMATCH;
8138 break;
8139 }
8140 }
8141
8142 // break the main loop, return a result - MATCH
8143 exitReason = EXIT_REASON_MATCH;
8144 break;
8145 }
8146
8147 // go to next syntax (`then` branch)
8148 state = thenStack.nextState;
8149
8150 // check match is not empty
8151 if (state === DISALLOW_EMPTY) {
8152 if (thenStack.matchStack === matchStack) {
8153 state = MISMATCH;
8154 break;
8155 } else {
8156 state = MATCH;
8157 }
8158 }
8159
8160 // close syntax if needed
8161 while (thenStack.syntaxStack !== syntaxStack) {
8162 closeSyntax();
8163 }
8164
8165 // pop stack
8166 thenStack = thenStack.prev;
8167 break;
8168
8169 case 'Mismatch':
8170 // when some syntax is stashed
8171 if (syntaxStash !== null && syntaxStash !== false) {
8172 // there is no else branches or a branch reduce match stack
8173 if (elseStack === null || tokenIndex > elseStack.tokenIndex) {
8174 // restore state from the stash
8175 elseStack = syntaxStash;
8176 syntaxStash = false; // disable stashing
8177 }
8178 } else if (elseStack === null) {
8179 // no else branches -> break the main loop
8180 // return a result - MISMATCH
8181 exitReason = EXIT_REASON_MISMATCH;
8182 break;
8183 }
8184
8185 // go to next syntax (`else` branch)
8186 state = elseStack.nextState;
8187
8188 // restore all the rest stack states
8189 thenStack = elseStack.thenStack;
8190 syntaxStack = elseStack.syntaxStack;
8191 matchStack = elseStack.matchStack;
8192 tokenIndex = elseStack.tokenIndex;
8193 token = tokenIndex < tokens.length ? tokens[tokenIndex] : null;
8194
8195 // pop stack
8196 elseStack = elseStack.prev;
8197 break;
8198
8199 case 'MatchGraph':
8200 state = state.match;
8201 break;
8202
8203 case 'If':
8204 // IMPORTANT: else stack push must go first,
8205 // since it stores the state of thenStack before changes
8206 if (state.else !== MISMATCH) {
8207 pushElseStack(state.else);
8208 }
8209
8210 if (state.then !== MATCH) {
8211 pushThenStack(state.then);
8212 }
8213
8214 state = state.match;
8215 break;
8216
8217 case 'MatchOnce':
8218 state = {
8219 type: 'MatchOnceBuffer',
8220 syntax: state,
8221 index: 0,
8222 mask: 0
8223 };
8224 break;
8225
8226 case 'MatchOnceBuffer':
8227 var terms = state.syntax.terms;
8228
8229 if (state.index === terms.length) {
8230 // no matches at all or it's required all terms to be matched
8231 if (state.mask === 0 || state.syntax.all) {
8232 state = MISMATCH;
8233 break;
8234 }
8235
8236 // a partial match is ok
8237 state = MATCH;
8238 break;
8239 }
8240
8241 // all terms are matched
8242 if (state.mask === (1 << terms.length) - 1) {
8243 state = MATCH;
8244 break;
8245 }
8246
8247 for (; state.index < terms.length; state.index++) {
8248 var matchFlag = 1 << state.index;
8249
8250 if ((state.mask & matchFlag) === 0) {
8251 // IMPORTANT: else stack push must go first,
8252 // since it stores the state of thenStack before changes
8253 pushElseStack(state);
8254 pushThenStack({
8255 type: 'AddMatchOnce',
8256 syntax: state.syntax,
8257 mask: state.mask | matchFlag
8258 });
8259
8260 // match
8261 state = terms[state.index++];
8262 break;
8263 }
8264 }
8265 break;
8266
8267 case 'AddMatchOnce':
8268 state = {
8269 type: 'MatchOnceBuffer',
8270 syntax: state.syntax,
8271 index: 0,
8272 mask: state.mask
8273 };
8274 break;
8275
8276 case 'Enum':
8277 if (token !== null) {
8278 var name = token.value.toLowerCase();
8279
8280 // drop \0 and \9 hack from keyword name
8281 if (name.indexOf('\\') !== -1) {
8282 name = name.replace(/\\[09].*$/, '');
8283 }
8284
8285 if (hasOwnProperty$6.call(state.map, name)) {
8286 state = state.map[name];
8287 break;
8288 }
8289 }
8290
8291 state = MISMATCH;
8292 break;
8293
8294 case 'Generic':
8295 var opts = syntaxStack !== null ? syntaxStack.opts : null;
8296 var lastTokenIndex = tokenIndex + Math.floor(state.fn(token, getNextToken, opts));
8297
8298 if (!isNaN(lastTokenIndex) && lastTokenIndex > tokenIndex) {
8299 while (tokenIndex < lastTokenIndex) {
8300 addTokenToMatch();
8301 }
8302
8303 state = MATCH;
8304 } else {
8305 state = MISMATCH;
8306 }
8307
8308 break;
8309
8310 case 'Type':
8311 case 'Property':
8312 var syntaxDict = state.type === 'Type' ? 'types' : 'properties';
8313 var dictSyntax = hasOwnProperty$6.call(syntaxes, syntaxDict) ? syntaxes[syntaxDict][state.name] : null;
8314
8315 if (!dictSyntax || !dictSyntax.match) {
8316 throw new Error(
8317 'Bad syntax reference: ' +
8318 (state.type === 'Type'
8319 ? '<' + state.name + '>'
8320 : '<\'' + state.name + '\'>')
8321 );
8322 }
8323
8324 // stash a syntax for types with low priority
8325 if (syntaxStash !== false && token !== null && state.type === 'Type') {
8326 var lowPriorityMatching =
8327 // https://drafts.csswg.org/css-values-4/#custom-idents
8328 // When parsing positionally-ambiguous keywords in a property value, a <custom-ident> production
8329 // can only claim the keyword if no other unfulfilled production can claim it.
8330 (state.name === 'custom-ident' && token.type === TYPE$B.Ident) ||
8331
8332 // https://drafts.csswg.org/css-values-4/#lengths
8333 // ... if a `0` could be parsed as either a <number> or a <length> in a property (such as line-height),
8334 // it must parse as a <number>
8335 (state.name === 'length' && token.value === '0');
8336
8337 if (lowPriorityMatching) {
8338 if (syntaxStash === null) {
8339 syntaxStash = stateSnapshotFromSyntax(state, elseStack);
8340 }
8341
8342 state = MISMATCH;
8343 break;
8344 }
8345 }
8346
8347 openSyntax();
8348 state = dictSyntax.match;
8349 break;
8350
8351 case 'Keyword':
8352 var name = state.name;
8353
8354 if (token !== null) {
8355 var keywordName = token.value;
8356
8357 // drop \0 and \9 hack from keyword name
8358 if (keywordName.indexOf('\\') !== -1) {
8359 keywordName = keywordName.replace(/\\[09].*$/, '');
8360 }
8361
8362 if (areStringsEqualCaseInsensitive(keywordName, name)) {
8363 addTokenToMatch();
8364 state = MATCH;
8365 break;
8366 }
8367 }
8368
8369 state = MISMATCH;
8370 break;
8371
8372 case 'AtKeyword':
8373 case 'Function':
8374 if (token !== null && areStringsEqualCaseInsensitive(token.value, state.name)) {
8375 addTokenToMatch();
8376 state = MATCH;
8377 break;
8378 }
8379
8380 state = MISMATCH;
8381 break;
8382
8383 case 'Token':
8384 if (token !== null && token.value === state.value) {
8385 addTokenToMatch();
8386 state = MATCH;
8387 break;
8388 }
8389
8390 state = MISMATCH;
8391 break;
8392
8393 case 'Comma':
8394 if (token !== null && token.type === TYPE$B.Comma) {
8395 if (isCommaContextStart(matchStack.token)) {
8396 state = MISMATCH;
8397 } else {
8398 addTokenToMatch();
8399 state = isCommaContextEnd(token) ? MISMATCH : MATCH;
8400 }
8401 } else {
8402 state = isCommaContextStart(matchStack.token) || isCommaContextEnd(token) ? MATCH : MISMATCH;
8403 }
8404
8405 break;
8406
8407 case 'String':
8408 var string = '';
8409
8410 for (var lastTokenIndex = tokenIndex; lastTokenIndex < tokens.length && string.length < state.value.length; lastTokenIndex++) {
8411 string += tokens[lastTokenIndex].value;
8412 }
8413
8414 if (areStringsEqualCaseInsensitive(string, state.value)) {
8415 while (tokenIndex < lastTokenIndex) {
8416 addTokenToMatch();
8417 }
8418
8419 state = MATCH;
8420 } else {
8421 state = MISMATCH;
8422 }
8423
8424 break;
8425
8426 default:
8427 throw new Error('Unknown node type: ' + state.type);
8428 }
8429 }
8430
8431 totalIterationCount += iterationCount;
8432
8433 switch (exitReason) {
8434 case null:
8435 console.warn('[csstree-match] BREAK after ' + ITERATION_LIMIT + ' iterations');
8436 exitReason = EXIT_REASON_ITERATION_LIMIT;
8437 matchStack = null;
8438 break;
8439
8440 case EXIT_REASON_MATCH:
8441 while (syntaxStack !== null) {
8442 closeSyntax();
8443 }
8444 break;
8445
8446 default:
8447 matchStack = null;
8448 }
8449
8450 return {
8451 tokens: tokens,
8452 reason: exitReason,
8453 iterations: iterationCount,
8454 match: matchStack,
8455 longestMatch: longestMatch
8456 };
8457 }
8458
8459 function matchAsList(tokens, matchGraph, syntaxes) {
8460 var matchResult = internalMatch(tokens, matchGraph, syntaxes || {});
8461
8462 if (matchResult.match !== null) {
8463 var item = reverseList(matchResult.match).prev;
8464
8465 matchResult.match = [];
8466
8467 while (item !== null) {
8468 switch (item.type) {
8469 case STUB:
8470 break;
8471
8472 case OPEN_SYNTAX:
8473 case CLOSE_SYNTAX:
8474 matchResult.match.push({
8475 type: item.type,
8476 syntax: item.syntax
8477 });
8478 break;
8479
8480 default:
8481 matchResult.match.push({
8482 token: item.token.value,
8483 node: item.token.node
8484 });
8485 break;
8486 }
8487
8488 item = item.prev;
8489 }
8490 }
8491
8492 return matchResult;
8493 }
8494
8495 function matchAsTree$1(tokens, matchGraph, syntaxes) {
8496 var matchResult = internalMatch(tokens, matchGraph, syntaxes || {});
8497
8498 if (matchResult.match === null) {
8499 return matchResult;
8500 }
8501
8502 var item = matchResult.match;
8503 var host = matchResult.match = {
8504 syntax: matchGraph.syntax || null,
8505 match: []
8506 };
8507 var hostStack = [host];
8508
8509 // revert a list and start with 2nd item since 1st is a stub item
8510 item = reverseList(item).prev;
8511
8512 // build a tree
8513 while (item !== null) {
8514 switch (item.type) {
8515 case OPEN_SYNTAX:
8516 host.match.push(host = {
8517 syntax: item.syntax,
8518 match: []
8519 });
8520 hostStack.push(host);
8521 break;
8522
8523 case CLOSE_SYNTAX:
8524 hostStack.pop();
8525 host = hostStack[hostStack.length - 1];
8526 break;
8527
8528 default:
8529 host.match.push({
8530 syntax: item.syntax || null,
8531 token: item.token.value,
8532 node: item.token.node
8533 });
8534 }
8535
8536 item = item.prev;
8537 }
8538
8539 return matchResult;
8540 }
8541
8542 var match = {
8543 matchAsList: matchAsList,
8544 matchAsTree: matchAsTree$1,
8545 getTotalIterationCount: function() {
8546 return totalIterationCount;
8547 }
8548 };
8549
8550 function getTrace(node) {
8551 function shouldPutToTrace(syntax) {
8552 if (syntax === null) {
8553 return false;
8554 }
8555
8556 return (
8557 syntax.type === 'Type' ||
8558 syntax.type === 'Property' ||
8559 syntax.type === 'Keyword'
8560 );
8561 }
8562
8563 function hasMatch(matchNode) {
8564 if (Array.isArray(matchNode.match)) {
8565 // use for-loop for better perfomance
8566 for (var i = 0; i < matchNode.match.length; i++) {
8567 if (hasMatch(matchNode.match[i])) {
8568 if (shouldPutToTrace(matchNode.syntax)) {
8569 result.unshift(matchNode.syntax);
8570 }
8571
8572 return true;
8573 }
8574 }
8575 } else if (matchNode.node === node) {
8576 result = shouldPutToTrace(matchNode.syntax)
8577 ? [matchNode.syntax]
8578 : [];
8579
8580 return true;
8581 }
8582
8583 return false;
8584 }
8585
8586 var result = null;
8587
8588 if (this.matched !== null) {
8589 hasMatch(this.matched);
8590 }
8591
8592 return result;
8593 }
8594
8595 function testNode(match, node, fn) {
8596 var trace = getTrace.call(match, node);
8597
8598 if (trace === null) {
8599 return false;
8600 }
8601
8602 return trace.some(fn);
8603 }
8604
8605 function isType(node, type) {
8606 return testNode(this, node, function(matchNode) {
8607 return matchNode.type === 'Type' && matchNode.name === type;
8608 });
8609 }
8610
8611 function isProperty(node, property) {
8612 return testNode(this, node, function(matchNode) {
8613 return matchNode.type === 'Property' && matchNode.name === property;
8614 });
8615 }
8616
8617 function isKeyword(node) {
8618 return testNode(this, node, function(matchNode) {
8619 return matchNode.type === 'Keyword';
8620 });
8621 }
8622
8623 var trace$1 = {
8624 getTrace: getTrace,
8625 isType: isType,
8626 isProperty: isProperty,
8627 isKeyword: isKeyword
8628 };
8629
8630 var List$5 = List_1;
8631
8632 function getFirstMatchNode(matchNode) {
8633 if ('node' in matchNode) {
8634 return matchNode.node;
8635 }
8636
8637 return getFirstMatchNode(matchNode.match[0]);
8638 }
8639
8640 function getLastMatchNode(matchNode) {
8641 if ('node' in matchNode) {
8642 return matchNode.node;
8643 }
8644
8645 return getLastMatchNode(matchNode.match[matchNode.match.length - 1]);
8646 }
8647
8648 function matchFragments(lexer, ast, match, type, name) {
8649 function findFragments(matchNode) {
8650 if (matchNode.syntax !== null &&
8651 matchNode.syntax.type === type &&
8652 matchNode.syntax.name === name) {
8653 var start = getFirstMatchNode(matchNode);
8654 var end = getLastMatchNode(matchNode);
8655
8656 lexer.syntax.walk(ast, function(node, item, list) {
8657 if (node === start) {
8658 var nodes = new List$5();
8659
8660 do {
8661 nodes.appendData(item.data);
8662
8663 if (item.data === end) {
8664 break;
8665 }
8666
8667 item = item.next;
8668 } while (item !== null);
8669
8670 fragments.push({
8671 parent: list,
8672 nodes: nodes
8673 });
8674 }
8675 });
8676 }
8677
8678 if (Array.isArray(matchNode.match)) {
8679 matchNode.match.forEach(findFragments);
8680 }
8681 }
8682
8683 var fragments = [];
8684
8685 if (match.matched !== null) {
8686 findFragments(match.matched);
8687 }
8688
8689 return fragments;
8690 }
8691
8692 var search$1 = {
8693 matchFragments: matchFragments
8694 };
8695
8696 var List$4 = List_1;
8697 var hasOwnProperty$5 = Object.prototype.hasOwnProperty;
8698
8699 function isValidNumber(value) {
8700 // Number.isInteger(value) && value >= 0
8701 return (
8702 typeof value === 'number' &&
8703 isFinite(value) &&
8704 Math.floor(value) === value &&
8705 value >= 0
8706 );
8707 }
8708
8709 function isValidLocation(loc) {
8710 return (
8711 Boolean(loc) &&
8712 isValidNumber(loc.offset) &&
8713 isValidNumber(loc.line) &&
8714 isValidNumber(loc.column)
8715 );
8716 }
8717
8718 function createNodeStructureChecker(type, fields) {
8719 return function checkNode(node, warn) {
8720 if (!node || node.constructor !== Object) {
8721 return warn(node, 'Type of node should be an Object');
8722 }
8723
8724 for (var key in node) {
8725 var valid = true;
8726
8727 if (hasOwnProperty$5.call(node, key) === false) {
8728 continue;
8729 }
8730
8731 if (key === 'type') {
8732 if (node.type !== type) {
8733 warn(node, 'Wrong node type `' + node.type + '`, expected `' + type + '`');
8734 }
8735 } else if (key === 'loc') {
8736 if (node.loc === null) {
8737 continue;
8738 } else if (node.loc && node.loc.constructor === Object) {
8739 if (typeof node.loc.source !== 'string') {
8740 key += '.source';
8741 } else if (!isValidLocation(node.loc.start)) {
8742 key += '.start';
8743 } else if (!isValidLocation(node.loc.end)) {
8744 key += '.end';
8745 } else {
8746 continue;
8747 }
8748 }
8749
8750 valid = false;
8751 } else if (fields.hasOwnProperty(key)) {
8752 for (var i = 0, valid = false; !valid && i < fields[key].length; i++) {
8753 var fieldType = fields[key][i];
8754
8755 switch (fieldType) {
8756 case String:
8757 valid = typeof node[key] === 'string';
8758 break;
8759
8760 case Boolean:
8761 valid = typeof node[key] === 'boolean';
8762 break;
8763
8764 case null:
8765 valid = node[key] === null;
8766 break;
8767
8768 default:
8769 if (typeof fieldType === 'string') {
8770 valid = node[key] && node[key].type === fieldType;
8771 } else if (Array.isArray(fieldType)) {
8772 valid = node[key] instanceof List$4;
8773 }
8774 }
8775 }
8776 } else {
8777 warn(node, 'Unknown field `' + key + '` for ' + type + ' node type');
8778 }
8779
8780 if (!valid) {
8781 warn(node, 'Bad value for `' + type + '.' + key + '`');
8782 }
8783 }
8784
8785 for (var key in fields) {
8786 if (hasOwnProperty$5.call(fields, key) &&
8787 hasOwnProperty$5.call(node, key) === false) {
8788 warn(node, 'Field `' + type + '.' + key + '` is missed');
8789 }
8790 }
8791 };
8792 }
8793
8794 function processStructure(name, nodeType) {
8795 var structure = nodeType.structure;
8796 var fields = {
8797 type: String,
8798 loc: true
8799 };
8800 var docs = {
8801 type: '"' + name + '"'
8802 };
8803
8804 for (var key in structure) {
8805 if (hasOwnProperty$5.call(structure, key) === false) {
8806 continue;
8807 }
8808
8809 var docsTypes = [];
8810 var fieldTypes = fields[key] = Array.isArray(structure[key])
8811 ? structure[key].slice()
8812 : [structure[key]];
8813
8814 for (var i = 0; i < fieldTypes.length; i++) {
8815 var fieldType = fieldTypes[i];
8816 if (fieldType === String || fieldType === Boolean) {
8817 docsTypes.push(fieldType.name);
8818 } else if (fieldType === null) {
8819 docsTypes.push('null');
8820 } else if (typeof fieldType === 'string') {
8821 docsTypes.push('<' + fieldType + '>');
8822 } else if (Array.isArray(fieldType)) {
8823 docsTypes.push('List'); // TODO: use type enum
8824 } else {
8825 throw new Error('Wrong value `' + fieldType + '` in `' + name + '.' + key + '` structure definition');
8826 }
8827 }
8828
8829 docs[key] = docsTypes.join(' | ');
8830 }
8831
8832 return {
8833 docs: docs,
8834 check: createNodeStructureChecker(name, fields)
8835 };
8836 }
8837
8838 var structure = {
8839 getStructureFromConfig: function(config) {
8840 var structure = {};
8841
8842 if (config.node) {
8843 for (var name in config.node) {
8844 if (hasOwnProperty$5.call(config.node, name)) {
8845 var nodeType = config.node[name];
8846
8847 if (nodeType.structure) {
8848 structure[name] = processStructure(name, nodeType);
8849 } else {
8850 throw new Error('Missed `structure` field in `' + name + '` node type definition');
8851 }
8852 }
8853 }
8854 }
8855
8856 return structure;
8857 }
8858 };
8859
8860 var SyntaxReferenceError = error.SyntaxReferenceError;
8861 var SyntaxMatchError = error.SyntaxMatchError;
8862 var names$1 = names$2;
8863 var generic = generic$1;
8864 var parse = parse_1;
8865 var generate = generate_1;
8866 var walk = walk$1;
8867 var prepareTokens = prepareTokens_1;
8868 var buildMatchGraph = matchGraph$1.buildMatchGraph;
8869 var matchAsTree = match.matchAsTree;
8870 var trace = trace$1;
8871 var search = search$1;
8872 var getStructureFromConfig = structure.getStructureFromConfig;
8873 var cssWideKeywords = buildMatchGraph('inherit | initial | unset');
8874 var cssWideKeywordsWithExpression = buildMatchGraph('inherit | initial | unset | <-ms-legacy-expression>');
8875
8876 function dumpMapSyntax(map, compact, syntaxAsAst) {
8877 var result = {};
8878
8879 for (var name in map) {
8880 if (map[name].syntax) {
8881 result[name] = syntaxAsAst
8882 ? map[name].syntax
8883 : generate(map[name].syntax, { compact: compact });
8884 }
8885 }
8886
8887 return result;
8888 }
8889
8890 function dumpAtruleMapSyntax(map, compact, syntaxAsAst) {
8891 const result = {};
8892
8893 for (const [name, atrule] of Object.entries(map)) {
8894 result[name] = {
8895 prelude: atrule.prelude && (
8896 syntaxAsAst
8897 ? atrule.prelude.syntax
8898 : generate(atrule.prelude.syntax, { compact })
8899 ),
8900 descriptors: atrule.descriptors && dumpMapSyntax(atrule.descriptors, compact, syntaxAsAst)
8901 };
8902 }
8903
8904 return result;
8905 }
8906
8907 function valueHasVar(tokens) {
8908 for (var i = 0; i < tokens.length; i++) {
8909 if (tokens[i].value.toLowerCase() === 'var(') {
8910 return true;
8911 }
8912 }
8913
8914 return false;
8915 }
8916
8917 function buildMatchResult(match, error, iterations) {
8918 return {
8919 matched: match,
8920 iterations: iterations,
8921 error: error,
8922 getTrace: trace.getTrace,
8923 isType: trace.isType,
8924 isProperty: trace.isProperty,
8925 isKeyword: trace.isKeyword
8926 };
8927 }
8928
8929 function matchSyntax(lexer, syntax, value, useCommon) {
8930 var tokens = prepareTokens(value, lexer.syntax);
8931 var result;
8932
8933 if (valueHasVar(tokens)) {
8934 return buildMatchResult(null, new Error('Matching for a tree with var() is not supported'));
8935 }
8936
8937 if (useCommon) {
8938 result = matchAsTree(tokens, lexer.valueCommonSyntax, lexer);
8939 }
8940
8941 if (!useCommon || !result.match) {
8942 result = matchAsTree(tokens, syntax.match, lexer);
8943 if (!result.match) {
8944 return buildMatchResult(
8945 null,
8946 new SyntaxMatchError(result.reason, syntax.syntax, value, result),
8947 result.iterations
8948 );
8949 }
8950 }
8951
8952 return buildMatchResult(result.match, null, result.iterations);
8953 }
8954
8955 var Lexer$1 = function(config, syntax, structure) {
8956 this.valueCommonSyntax = cssWideKeywords;
8957 this.syntax = syntax;
8958 this.generic = false;
8959 this.atrules = {};
8960 this.properties = {};
8961 this.types = {};
8962 this.structure = structure || getStructureFromConfig(config);
8963
8964 if (config) {
8965 if (config.types) {
8966 for (var name in config.types) {
8967 this.addType_(name, config.types[name]);
8968 }
8969 }
8970
8971 if (config.generic) {
8972 this.generic = true;
8973 for (var name in generic) {
8974 this.addType_(name, generic[name]);
8975 }
8976 }
8977
8978 if (config.atrules) {
8979 for (var name in config.atrules) {
8980 this.addAtrule_(name, config.atrules[name]);
8981 }
8982 }
8983
8984 if (config.properties) {
8985 for (var name in config.properties) {
8986 this.addProperty_(name, config.properties[name]);
8987 }
8988 }
8989 }
8990 };
8991
8992 Lexer$1.prototype = {
8993 structure: {},
8994 checkStructure: function(ast) {
8995 function collectWarning(node, message) {
8996 warns.push({
8997 node: node,
8998 message: message
8999 });
9000 }
9001
9002 var structure = this.structure;
9003 var warns = [];
9004
9005 this.syntax.walk(ast, function(node) {
9006 if (structure.hasOwnProperty(node.type)) {
9007 structure[node.type].check(node, collectWarning);
9008 } else {
9009 collectWarning(node, 'Unknown node type `' + node.type + '`');
9010 }
9011 });
9012
9013 return warns.length ? warns : false;
9014 },
9015
9016 createDescriptor: function(syntax, type, name, parent = null) {
9017 var ref = {
9018 type: type,
9019 name: name
9020 };
9021 var descriptor = {
9022 type: type,
9023 name: name,
9024 parent: parent,
9025 syntax: null,
9026 match: null
9027 };
9028
9029 if (typeof syntax === 'function') {
9030 descriptor.match = buildMatchGraph(syntax, ref);
9031 } else {
9032 if (typeof syntax === 'string') {
9033 // lazy parsing on first access
9034 Object.defineProperty(descriptor, 'syntax', {
9035 get: function() {
9036 Object.defineProperty(descriptor, 'syntax', {
9037 value: parse(syntax)
9038 });
9039
9040 return descriptor.syntax;
9041 }
9042 });
9043 } else {
9044 descriptor.syntax = syntax;
9045 }
9046
9047 // lazy graph build on first access
9048 Object.defineProperty(descriptor, 'match', {
9049 get: function() {
9050 Object.defineProperty(descriptor, 'match', {
9051 value: buildMatchGraph(descriptor.syntax, ref)
9052 });
9053
9054 return descriptor.match;
9055 }
9056 });
9057 }
9058
9059 return descriptor;
9060 },
9061 addAtrule_: function(name, syntax) {
9062 if (!syntax) {
9063 return;
9064 }
9065
9066 this.atrules[name] = {
9067 type: 'Atrule',
9068 name: name,
9069 prelude: syntax.prelude ? this.createDescriptor(syntax.prelude, 'AtrulePrelude', name) : null,
9070 descriptors: syntax.descriptors
9071 ? Object.keys(syntax.descriptors).reduce((res, descName) => {
9072 res[descName] = this.createDescriptor(syntax.descriptors[descName], 'AtruleDescriptor', descName, name);
9073 return res;
9074 }, {})
9075 : null
9076 };
9077 },
9078 addProperty_: function(name, syntax) {
9079 if (!syntax) {
9080 return;
9081 }
9082
9083 this.properties[name] = this.createDescriptor(syntax, 'Property', name);
9084 },
9085 addType_: function(name, syntax) {
9086 if (!syntax) {
9087 return;
9088 }
9089
9090 this.types[name] = this.createDescriptor(syntax, 'Type', name);
9091
9092 if (syntax === generic['-ms-legacy-expression']) {
9093 this.valueCommonSyntax = cssWideKeywordsWithExpression;
9094 }
9095 },
9096
9097 checkAtruleName: function(atruleName) {
9098 if (!this.getAtrule(atruleName)) {
9099 return new SyntaxReferenceError('Unknown at-rule', '@' + atruleName);
9100 }
9101 },
9102 checkAtrulePrelude: function(atruleName, prelude) {
9103 let error = this.checkAtruleName(atruleName);
9104
9105 if (error) {
9106 return error;
9107 }
9108
9109 var atrule = this.getAtrule(atruleName);
9110
9111 if (!atrule.prelude && prelude) {
9112 return new SyntaxError('At-rule `@' + atruleName + '` should not contain a prelude');
9113 }
9114
9115 if (atrule.prelude && !prelude) {
9116 return new SyntaxError('At-rule `@' + atruleName + '` should contain a prelude');
9117 }
9118 },
9119 checkAtruleDescriptorName: function(atruleName, descriptorName) {
9120 let error = this.checkAtruleName(atruleName);
9121
9122 if (error) {
9123 return error;
9124 }
9125
9126 var atrule = this.getAtrule(atruleName);
9127 var descriptor = names$1.keyword(descriptorName);
9128
9129 if (!atrule.descriptors) {
9130 return new SyntaxError('At-rule `@' + atruleName + '` has no known descriptors');
9131 }
9132
9133 if (!atrule.descriptors[descriptor.name] &&
9134 !atrule.descriptors[descriptor.basename]) {
9135 return new SyntaxReferenceError('Unknown at-rule descriptor', descriptorName);
9136 }
9137 },
9138 checkPropertyName: function(propertyName) {
9139 var property = names$1.property(propertyName);
9140
9141 // don't match syntax for a custom property
9142 if (property.custom) {
9143 return new Error('Lexer matching doesn\'t applicable for custom properties');
9144 }
9145
9146 if (!this.getProperty(propertyName)) {
9147 return new SyntaxReferenceError('Unknown property', propertyName);
9148 }
9149 },
9150
9151 matchAtrulePrelude: function(atruleName, prelude) {
9152 var error = this.checkAtrulePrelude(atruleName, prelude);
9153
9154 if (error) {
9155 return buildMatchResult(null, error);
9156 }
9157
9158 if (!prelude) {
9159 return buildMatchResult(null, null);
9160 }
9161
9162 return matchSyntax(this, this.getAtrule(atruleName).prelude, prelude, false);
9163 },
9164 matchAtruleDescriptor: function(atruleName, descriptorName, value) {
9165 var error = this.checkAtruleDescriptorName(atruleName, descriptorName);
9166
9167 if (error) {
9168 return buildMatchResult(null, error);
9169 }
9170
9171 var atrule = this.getAtrule(atruleName);
9172 var descriptor = names$1.keyword(descriptorName);
9173
9174 return matchSyntax(this, atrule.descriptors[descriptor.name] || atrule.descriptors[descriptor.basename], value, false);
9175 },
9176 matchDeclaration: function(node) {
9177 if (node.type !== 'Declaration') {
9178 return buildMatchResult(null, new Error('Not a Declaration node'));
9179 }
9180
9181 return this.matchProperty(node.property, node.value);
9182 },
9183 matchProperty: function(propertyName, value) {
9184 var error = this.checkPropertyName(propertyName);
9185
9186 if (error) {
9187 return buildMatchResult(null, error);
9188 }
9189
9190 return matchSyntax(this, this.getProperty(propertyName), value, true);
9191 },
9192 matchType: function(typeName, value) {
9193 var typeSyntax = this.getType(typeName);
9194
9195 if (!typeSyntax) {
9196 return buildMatchResult(null, new SyntaxReferenceError('Unknown type', typeName));
9197 }
9198
9199 return matchSyntax(this, typeSyntax, value, false);
9200 },
9201 match: function(syntax, value) {
9202 if (typeof syntax !== 'string' && (!syntax || !syntax.type)) {
9203 return buildMatchResult(null, new SyntaxReferenceError('Bad syntax'));
9204 }
9205
9206 if (typeof syntax === 'string' || !syntax.match) {
9207 syntax = this.createDescriptor(syntax, 'Type', 'anonymous');
9208 }
9209
9210 return matchSyntax(this, syntax, value, false);
9211 },
9212
9213 findValueFragments: function(propertyName, value, type, name) {
9214 return search.matchFragments(this, value, this.matchProperty(propertyName, value), type, name);
9215 },
9216 findDeclarationValueFragments: function(declaration, type, name) {
9217 return search.matchFragments(this, declaration.value, this.matchDeclaration(declaration), type, name);
9218 },
9219 findAllFragments: function(ast, type, name) {
9220 var result = [];
9221
9222 this.syntax.walk(ast, {
9223 visit: 'Declaration',
9224 enter: function(declaration) {
9225 result.push.apply(result, this.findDeclarationValueFragments(declaration, type, name));
9226 }.bind(this)
9227 });
9228
9229 return result;
9230 },
9231
9232 getAtrule: function(atruleName, fallbackBasename = true) {
9233 var atrule = names$1.keyword(atruleName);
9234 var atruleEntry = atrule.vendor && fallbackBasename
9235 ? this.atrules[atrule.name] || this.atrules[atrule.basename]
9236 : this.atrules[atrule.name];
9237
9238 return atruleEntry || null;
9239 },
9240 getAtrulePrelude: function(atruleName, fallbackBasename = true) {
9241 const atrule = this.getAtrule(atruleName, fallbackBasename);
9242
9243 return atrule && atrule.prelude || null;
9244 },
9245 getAtruleDescriptor: function(atruleName, name) {
9246 return this.atrules.hasOwnProperty(atruleName) && this.atrules.declarators
9247 ? this.atrules[atruleName].declarators[name] || null
9248 : null;
9249 },
9250 getProperty: function(propertyName, fallbackBasename = true) {
9251 var property = names$1.property(propertyName);
9252 var propertyEntry = property.vendor && fallbackBasename
9253 ? this.properties[property.name] || this.properties[property.basename]
9254 : this.properties[property.name];
9255
9256 return propertyEntry || null;
9257 },
9258 getType: function(name) {
9259 return this.types.hasOwnProperty(name) ? this.types[name] : null;
9260 },
9261
9262 validate: function() {
9263 function validate(syntax, name, broken, descriptor) {
9264 if (broken.hasOwnProperty(name)) {
9265 return broken[name];
9266 }
9267
9268 broken[name] = false;
9269 if (descriptor.syntax !== null) {
9270 walk(descriptor.syntax, function(node) {
9271 if (node.type !== 'Type' && node.type !== 'Property') {
9272 return;
9273 }
9274
9275 var map = node.type === 'Type' ? syntax.types : syntax.properties;
9276 var brokenMap = node.type === 'Type' ? brokenTypes : brokenProperties;
9277
9278 if (!map.hasOwnProperty(node.name) || validate(syntax, node.name, brokenMap, map[node.name])) {
9279 broken[name] = true;
9280 }
9281 }, this);
9282 }
9283 }
9284
9285 var brokenTypes = {};
9286 var brokenProperties = {};
9287
9288 for (var key in this.types) {
9289 validate(this, key, brokenTypes, this.types[key]);
9290 }
9291
9292 for (var key in this.properties) {
9293 validate(this, key, brokenProperties, this.properties[key]);
9294 }
9295
9296 brokenTypes = Object.keys(brokenTypes).filter(function(name) {
9297 return brokenTypes[name];
9298 });
9299 brokenProperties = Object.keys(brokenProperties).filter(function(name) {
9300 return brokenProperties[name];
9301 });
9302
9303 if (brokenTypes.length || brokenProperties.length) {
9304 return {
9305 types: brokenTypes,
9306 properties: brokenProperties
9307 };
9308 }
9309
9310 return null;
9311 },
9312 dump: function(syntaxAsAst, pretty) {
9313 return {
9314 generic: this.generic,
9315 types: dumpMapSyntax(this.types, !pretty, syntaxAsAst),
9316 properties: dumpMapSyntax(this.properties, !pretty, syntaxAsAst),
9317 atrules: dumpAtruleMapSyntax(this.atrules, !pretty, syntaxAsAst)
9318 };
9319 },
9320 toString: function() {
9321 return JSON.stringify(this.dump());
9322 }
9323 };
9324
9325 var Lexer_1 = Lexer$1;
9326
9327 var definitionSyntax$1 = {
9328 SyntaxError: _SyntaxError,
9329 parse: parse_1,
9330 generate: generate_1,
9331 walk: walk$1
9332 };
9333
9334 var adoptBuffer = adoptBuffer$2;
9335 var isBOM = tokenizer$3.isBOM;
9336
9337 var N$1 = 10;
9338 var F = 12;
9339 var R = 13;
9340
9341 function computeLinesAndColumns(host, source) {
9342 var sourceLength = source.length;
9343 var lines = adoptBuffer(host.lines, sourceLength); // +1
9344 var line = host.startLine;
9345 var columns = adoptBuffer(host.columns, sourceLength);
9346 var column = host.startColumn;
9347 var startOffset = source.length > 0 ? isBOM(source.charCodeAt(0)) : 0;
9348
9349 for (var i = startOffset; i < sourceLength; i++) { // -1
9350 var code = source.charCodeAt(i);
9351
9352 lines[i] = line;
9353 columns[i] = column++;
9354
9355 if (code === N$1 || code === R || code === F) {
9356 if (code === R && i + 1 < sourceLength && source.charCodeAt(i + 1) === N$1) {
9357 i++;
9358 lines[i] = line;
9359 columns[i] = column;
9360 }
9361
9362 line++;
9363 column = 1;
9364 }
9365 }
9366
9367 lines[i] = line;
9368 columns[i] = column;
9369
9370 host.lines = lines;
9371 host.columns = columns;
9372 }
9373
9374 var OffsetToLocation$1 = function() {
9375 this.lines = null;
9376 this.columns = null;
9377 this.linesAndColumnsComputed = false;
9378 };
9379
9380 OffsetToLocation$1.prototype = {
9381 setSource: function(source, startOffset, startLine, startColumn) {
9382 this.source = source;
9383 this.startOffset = typeof startOffset === 'undefined' ? 0 : startOffset;
9384 this.startLine = typeof startLine === 'undefined' ? 1 : startLine;
9385 this.startColumn = typeof startColumn === 'undefined' ? 1 : startColumn;
9386 this.linesAndColumnsComputed = false;
9387 },
9388
9389 ensureLinesAndColumnsComputed: function() {
9390 if (!this.linesAndColumnsComputed) {
9391 computeLinesAndColumns(this, this.source);
9392 this.linesAndColumnsComputed = true;
9393 }
9394 },
9395 getLocation: function(offset, filename) {
9396 this.ensureLinesAndColumnsComputed();
9397
9398 return {
9399 source: filename,
9400 offset: this.startOffset + offset,
9401 line: this.lines[offset],
9402 column: this.columns[offset]
9403 };
9404 },
9405 getLocationRange: function(start, end, filename) {
9406 this.ensureLinesAndColumnsComputed();
9407
9408 return {
9409 source: filename,
9410 start: {
9411 offset: this.startOffset + start,
9412 line: this.lines[start],
9413 column: this.columns[start]
9414 },
9415 end: {
9416 offset: this.startOffset + end,
9417 line: this.lines[end],
9418 column: this.columns[end]
9419 }
9420 };
9421 }
9422 };
9423
9424 var OffsetToLocation_1 = OffsetToLocation$1;
9425
9426 var TYPE$A = tokenizer$3.TYPE;
9427 var WHITESPACE$a = TYPE$A.WhiteSpace;
9428 var COMMENT$8 = TYPE$A.Comment;
9429
9430 var sequence$1 = function readSequence(recognizer) {
9431 var children = this.createList();
9432 var child = null;
9433 var context = {
9434 recognizer: recognizer,
9435 space: null,
9436 ignoreWS: false,
9437 ignoreWSAfter: false
9438 };
9439
9440 this.scanner.skipSC();
9441
9442 while (!this.scanner.eof) {
9443 switch (this.scanner.tokenType) {
9444 case COMMENT$8:
9445 this.scanner.next();
9446 continue;
9447
9448 case WHITESPACE$a:
9449 if (context.ignoreWS) {
9450 this.scanner.next();
9451 } else {
9452 context.space = this.WhiteSpace();
9453 }
9454 continue;
9455 }
9456
9457 child = recognizer.getNode.call(this, context);
9458
9459 if (child === undefined) {
9460 break;
9461 }
9462
9463 if (context.space !== null) {
9464 children.push(context.space);
9465 context.space = null;
9466 }
9467
9468 children.push(child);
9469
9470 if (context.ignoreWSAfter) {
9471 context.ignoreWSAfter = false;
9472 context.ignoreWS = true;
9473 } else {
9474 context.ignoreWS = false;
9475 }
9476 }
9477
9478 return children;
9479 };
9480
9481 var OffsetToLocation = OffsetToLocation_1;
9482 var SyntaxError$2 = _SyntaxError$1;
9483 var TokenStream$1 = TokenStream_1;
9484 var List$3 = List_1;
9485 var tokenize$1 = tokenizer$3;
9486 var constants = _const;
9487 var { findWhiteSpaceStart, cmpStr: cmpStr$2 } = utils$2;
9488 var sequence = sequence$1;
9489 var noop$1 = function() {};
9490
9491 var TYPE$z = constants.TYPE;
9492 var NAME$1 = constants.NAME;
9493 var WHITESPACE$9 = TYPE$z.WhiteSpace;
9494 var COMMENT$7 = TYPE$z.Comment;
9495 var IDENT$g = TYPE$z.Ident;
9496 var FUNCTION$6 = TYPE$z.Function;
9497 var URL$4 = TYPE$z.Url;
9498 var HASH$5 = TYPE$z.Hash;
9499 var PERCENTAGE$3 = TYPE$z.Percentage;
9500 var NUMBER$7 = TYPE$z.Number;
9501 var NUMBERSIGN$3 = 0x0023; // U+0023 NUMBER SIGN (#)
9502 var NULL = 0;
9503
9504 function createParseContext(name) {
9505 return function() {
9506 return this[name]();
9507 };
9508 }
9509
9510 function processConfig(config) {
9511 var parserConfig = {
9512 context: {},
9513 scope: {},
9514 atrule: {},
9515 pseudo: {}
9516 };
9517
9518 if (config.parseContext) {
9519 for (var name in config.parseContext) {
9520 switch (typeof config.parseContext[name]) {
9521 case 'function':
9522 parserConfig.context[name] = config.parseContext[name];
9523 break;
9524
9525 case 'string':
9526 parserConfig.context[name] = createParseContext(config.parseContext[name]);
9527 break;
9528 }
9529 }
9530 }
9531
9532 if (config.scope) {
9533 for (var name in config.scope) {
9534 parserConfig.scope[name] = config.scope[name];
9535 }
9536 }
9537
9538 if (config.atrule) {
9539 for (var name in config.atrule) {
9540 var atrule = config.atrule[name];
9541
9542 if (atrule.parse) {
9543 parserConfig.atrule[name] = atrule.parse;
9544 }
9545 }
9546 }
9547
9548 if (config.pseudo) {
9549 for (var name in config.pseudo) {
9550 var pseudo = config.pseudo[name];
9551
9552 if (pseudo.parse) {
9553 parserConfig.pseudo[name] = pseudo.parse;
9554 }
9555 }
9556 }
9557
9558 if (config.node) {
9559 for (var name in config.node) {
9560 parserConfig[name] = config.node[name].parse;
9561 }
9562 }
9563
9564 return parserConfig;
9565 }
9566
9567 var create$3 = function createParser(config) {
9568 var parser = {
9569 scanner: new TokenStream$1(),
9570 locationMap: new OffsetToLocation(),
9571
9572 filename: '<unknown>',
9573 needPositions: false,
9574 onParseError: noop$1,
9575 onParseErrorThrow: false,
9576 parseAtrulePrelude: true,
9577 parseRulePrelude: true,
9578 parseValue: true,
9579 parseCustomProperty: false,
9580
9581 readSequence: sequence,
9582
9583 createList: function() {
9584 return new List$3();
9585 },
9586 createSingleNodeList: function(node) {
9587 return new List$3().appendData(node);
9588 },
9589 getFirstListNode: function(list) {
9590 return list && list.first();
9591 },
9592 getLastListNode: function(list) {
9593 return list.last();
9594 },
9595
9596 parseWithFallback: function(consumer, fallback) {
9597 var startToken = this.scanner.tokenIndex;
9598
9599 try {
9600 return consumer.call(this);
9601 } catch (e) {
9602 if (this.onParseErrorThrow) {
9603 throw e;
9604 }
9605
9606 var fallbackNode = fallback.call(this, startToken);
9607
9608 this.onParseErrorThrow = true;
9609 this.onParseError(e, fallbackNode);
9610 this.onParseErrorThrow = false;
9611
9612 return fallbackNode;
9613 }
9614 },
9615
9616 lookupNonWSType: function(offset) {
9617 do {
9618 var type = this.scanner.lookupType(offset++);
9619 if (type !== WHITESPACE$9) {
9620 return type;
9621 }
9622 } while (type !== NULL);
9623
9624 return NULL;
9625 },
9626
9627 eat: function(tokenType) {
9628 if (this.scanner.tokenType !== tokenType) {
9629 var offset = this.scanner.tokenStart;
9630 var message = NAME$1[tokenType] + ' is expected';
9631
9632 // tweak message and offset
9633 switch (tokenType) {
9634 case IDENT$g:
9635 // when identifier is expected but there is a function or url
9636 if (this.scanner.tokenType === FUNCTION$6 || this.scanner.tokenType === URL$4) {
9637 offset = this.scanner.tokenEnd - 1;
9638 message = 'Identifier is expected but function found';
9639 } else {
9640 message = 'Identifier is expected';
9641 }
9642 break;
9643
9644 case HASH$5:
9645 if (this.scanner.isDelim(NUMBERSIGN$3)) {
9646 this.scanner.next();
9647 offset++;
9648 message = 'Name is expected';
9649 }
9650 break;
9651
9652 case PERCENTAGE$3:
9653 if (this.scanner.tokenType === NUMBER$7) {
9654 offset = this.scanner.tokenEnd;
9655 message = 'Percent sign is expected';
9656 }
9657 break;
9658
9659 default:
9660 // when test type is part of another token show error for current position + 1
9661 // e.g. eat(HYPHENMINUS) will fail on "-foo", but pointing on "-" is odd
9662 if (this.scanner.source.charCodeAt(this.scanner.tokenStart) === tokenType) {
9663 offset = offset + 1;
9664 }
9665 }
9666
9667 this.error(message, offset);
9668 }
9669
9670 this.scanner.next();
9671 },
9672
9673 consume: function(tokenType) {
9674 var value = this.scanner.getTokenValue();
9675
9676 this.eat(tokenType);
9677
9678 return value;
9679 },
9680 consumeFunctionName: function() {
9681 var name = this.scanner.source.substring(this.scanner.tokenStart, this.scanner.tokenEnd - 1);
9682
9683 this.eat(FUNCTION$6);
9684
9685 return name;
9686 },
9687
9688 getLocation: function(start, end) {
9689 if (this.needPositions) {
9690 return this.locationMap.getLocationRange(
9691 start,
9692 end,
9693 this.filename
9694 );
9695 }
9696
9697 return null;
9698 },
9699 getLocationFromList: function(list) {
9700 if (this.needPositions) {
9701 var head = this.getFirstListNode(list);
9702 var tail = this.getLastListNode(list);
9703 return this.locationMap.getLocationRange(
9704 head !== null ? head.loc.start.offset - this.locationMap.startOffset : this.scanner.tokenStart,
9705 tail !== null ? tail.loc.end.offset - this.locationMap.startOffset : this.scanner.tokenStart,
9706 this.filename
9707 );
9708 }
9709
9710 return null;
9711 },
9712
9713 error: function(message, offset) {
9714 var location = typeof offset !== 'undefined' && offset < this.scanner.source.length
9715 ? this.locationMap.getLocation(offset)
9716 : this.scanner.eof
9717 ? this.locationMap.getLocation(findWhiteSpaceStart(this.scanner.source, this.scanner.source.length - 1))
9718 : this.locationMap.getLocation(this.scanner.tokenStart);
9719
9720 throw new SyntaxError$2(
9721 message || 'Unexpected input',
9722 this.scanner.source,
9723 location.offset,
9724 location.line,
9725 location.column
9726 );
9727 }
9728 };
9729
9730 config = processConfig(config || {});
9731 for (var key in config) {
9732 parser[key] = config[key];
9733 }
9734
9735 return function(source, options) {
9736 options = options || {};
9737
9738 var context = options.context || 'default';
9739 var onComment = options.onComment;
9740 var ast;
9741
9742 tokenize$1(source, parser.scanner);
9743 parser.locationMap.setSource(
9744 source,
9745 options.offset,
9746 options.line,
9747 options.column
9748 );
9749
9750 parser.filename = options.filename || '<unknown>';
9751 parser.needPositions = Boolean(options.positions);
9752 parser.onParseError = typeof options.onParseError === 'function' ? options.onParseError : noop$1;
9753 parser.onParseErrorThrow = false;
9754 parser.parseAtrulePrelude = 'parseAtrulePrelude' in options ? Boolean(options.parseAtrulePrelude) : true;
9755 parser.parseRulePrelude = 'parseRulePrelude' in options ? Boolean(options.parseRulePrelude) : true;
9756 parser.parseValue = 'parseValue' in options ? Boolean(options.parseValue) : true;
9757 parser.parseCustomProperty = 'parseCustomProperty' in options ? Boolean(options.parseCustomProperty) : false;
9758
9759 if (!parser.context.hasOwnProperty(context)) {
9760 throw new Error('Unknown context `' + context + '`');
9761 }
9762
9763 if (typeof onComment === 'function') {
9764 parser.scanner.forEachToken((type, start, end) => {
9765 if (type === COMMENT$7) {
9766 const loc = parser.getLocation(start, end);
9767 const value = cmpStr$2(source, end - 2, end, '*/')
9768 ? source.slice(start + 2, end - 2)
9769 : source.slice(start + 2, end);
9770
9771 onComment(value, loc);
9772 }
9773 });
9774 }
9775
9776 ast = parser.context[context].call(parser, options);
9777
9778 if (!parser.scanner.eof) {
9779 parser.error();
9780 }
9781
9782 return ast;
9783 };
9784 };
9785
9786 var sourceMapGenerator = {};
9787
9788 var base64Vlq = {};
9789
9790 var base64$1 = {};
9791
9792 /* -*- Mode: js; js-indent-level: 2; -*- */
9793
9794 /*
9795 * Copyright 2011 Mozilla Foundation and contributors
9796 * Licensed under the New BSD license. See LICENSE or:
9797 * http://opensource.org/licenses/BSD-3-Clause
9798 */
9799
9800 var intToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split('');
9801
9802 /**
9803 * Encode an integer in the range of 0 to 63 to a single base 64 digit.
9804 */
9805 base64$1.encode = function (number) {
9806 if (0 <= number && number < intToCharMap.length) {
9807 return intToCharMap[number];
9808 }
9809 throw new TypeError("Must be between 0 and 63: " + number);
9810 };
9811
9812 /**
9813 * Decode a single base 64 character code digit to an integer. Returns -1 on
9814 * failure.
9815 */
9816 base64$1.decode = function (charCode) {
9817 var bigA = 65; // 'A'
9818 var bigZ = 90; // 'Z'
9819
9820 var littleA = 97; // 'a'
9821 var littleZ = 122; // 'z'
9822
9823 var zero = 48; // '0'
9824 var nine = 57; // '9'
9825
9826 var plus = 43; // '+'
9827 var slash = 47; // '/'
9828
9829 var littleOffset = 26;
9830 var numberOffset = 52;
9831
9832 // 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ
9833 if (bigA <= charCode && charCode <= bigZ) {
9834 return (charCode - bigA);
9835 }
9836
9837 // 26 - 51: abcdefghijklmnopqrstuvwxyz
9838 if (littleA <= charCode && charCode <= littleZ) {
9839 return (charCode - littleA + littleOffset);
9840 }
9841
9842 // 52 - 61: 0123456789
9843 if (zero <= charCode && charCode <= nine) {
9844 return (charCode - zero + numberOffset);
9845 }
9846
9847 // 62: +
9848 if (charCode == plus) {
9849 return 62;
9850 }
9851
9852 // 63: /
9853 if (charCode == slash) {
9854 return 63;
9855 }
9856
9857 // Invalid base64 digit.
9858 return -1;
9859 };
9860
9861 /* -*- Mode: js; js-indent-level: 2; -*- */
9862
9863 /*
9864 * Copyright 2011 Mozilla Foundation and contributors
9865 * Licensed under the New BSD license. See LICENSE or:
9866 * http://opensource.org/licenses/BSD-3-Clause
9867 *
9868 * Based on the Base 64 VLQ implementation in Closure Compiler:
9869 * https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java
9870 *
9871 * Copyright 2011 The Closure Compiler Authors. All rights reserved.
9872 * Redistribution and use in source and binary forms, with or without
9873 * modification, are permitted provided that the following conditions are
9874 * met:
9875 *
9876 * * Redistributions of source code must retain the above copyright
9877 * notice, this list of conditions and the following disclaimer.
9878 * * Redistributions in binary form must reproduce the above
9879 * copyright notice, this list of conditions and the following
9880 * disclaimer in the documentation and/or other materials provided
9881 * with the distribution.
9882 * * Neither the name of Google Inc. nor the names of its
9883 * contributors may be used to endorse or promote products derived
9884 * from this software without specific prior written permission.
9885 *
9886 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
9887 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
9888 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
9889 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
9890 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
9891 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9892 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
9893 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
9894 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
9895 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
9896 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
9897 */
9898
9899 var base64 = base64$1;
9900
9901 // A single base 64 digit can contain 6 bits of data. For the base 64 variable
9902 // length quantities we use in the source map spec, the first bit is the sign,
9903 // the next four bits are the actual value, and the 6th bit is the
9904 // continuation bit. The continuation bit tells us whether there are more
9905 // digits in this value following this digit.
9906 //
9907 // Continuation
9908 // | Sign
9909 // | |
9910 // V V
9911 // 101011
9912
9913 var VLQ_BASE_SHIFT = 5;
9914
9915 // binary: 100000
9916 var VLQ_BASE = 1 << VLQ_BASE_SHIFT;
9917
9918 // binary: 011111
9919 var VLQ_BASE_MASK = VLQ_BASE - 1;
9920
9921 // binary: 100000
9922 var VLQ_CONTINUATION_BIT = VLQ_BASE;
9923
9924 /**
9925 * Converts from a two-complement value to a value where the sign bit is
9926 * placed in the least significant bit. For example, as decimals:
9927 * 1 becomes 2 (10 binary), -1 becomes 3 (11 binary)
9928 * 2 becomes 4 (100 binary), -2 becomes 5 (101 binary)
9929 */
9930 function toVLQSigned(aValue) {
9931 return aValue < 0
9932 ? ((-aValue) << 1) + 1
9933 : (aValue << 1) + 0;
9934 }
9935
9936 /**
9937 * Converts to a two-complement value from a value where the sign bit is
9938 * placed in the least significant bit. For example, as decimals:
9939 * 2 (10 binary) becomes 1, 3 (11 binary) becomes -1
9940 * 4 (100 binary) becomes 2, 5 (101 binary) becomes -2
9941 */
9942 function fromVLQSigned(aValue) {
9943 var isNegative = (aValue & 1) === 1;
9944 var shifted = aValue >> 1;
9945 return isNegative
9946 ? -shifted
9947 : shifted;
9948 }
9949
9950 /**
9951 * Returns the base 64 VLQ encoded value.
9952 */
9953 base64Vlq.encode = function base64VLQ_encode(aValue) {
9954 var encoded = "";
9955 var digit;
9956
9957 var vlq = toVLQSigned(aValue);
9958
9959 do {
9960 digit = vlq & VLQ_BASE_MASK;
9961 vlq >>>= VLQ_BASE_SHIFT;
9962 if (vlq > 0) {
9963 // There are still more digits in this value, so we must make sure the
9964 // continuation bit is marked.
9965 digit |= VLQ_CONTINUATION_BIT;
9966 }
9967 encoded += base64.encode(digit);
9968 } while (vlq > 0);
9969
9970 return encoded;
9971 };
9972
9973 /**
9974 * Decodes the next base 64 VLQ value from the given string and returns the
9975 * value and the rest of the string via the out parameter.
9976 */
9977 base64Vlq.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) {
9978 var strLen = aStr.length;
9979 var result = 0;
9980 var shift = 0;
9981 var continuation, digit;
9982
9983 do {
9984 if (aIndex >= strLen) {
9985 throw new Error("Expected more digits in base 64 VLQ value.");
9986 }
9987
9988 digit = base64.decode(aStr.charCodeAt(aIndex++));
9989 if (digit === -1) {
9990 throw new Error("Invalid base64 digit: " + aStr.charAt(aIndex - 1));
9991 }
9992
9993 continuation = !!(digit & VLQ_CONTINUATION_BIT);
9994 digit &= VLQ_BASE_MASK;
9995 result = result + (digit << shift);
9996 shift += VLQ_BASE_SHIFT;
9997 } while (continuation);
9998
9999 aOutParam.value = fromVLQSigned(result);
10000 aOutParam.rest = aIndex;
10001 };
10002
10003 var util$3 = {};
10004
10005 /* -*- Mode: js; js-indent-level: 2; -*- */
10006
10007 (function (exports) {
10008 /*
10009 * Copyright 2011 Mozilla Foundation and contributors
10010 * Licensed under the New BSD license. See LICENSE or:
10011 * http://opensource.org/licenses/BSD-3-Clause
10012 */
10013
10014 /**
10015 * This is a helper function for getting values from parameter/options
10016 * objects.
10017 *
10018 * @param args The object we are extracting values from
10019 * @param name The name of the property we are getting.
10020 * @param defaultValue An optional value to return if the property is missing
10021 * from the object. If this is not specified and the property is missing, an
10022 * error will be thrown.
10023 */
10024 function getArg(aArgs, aName, aDefaultValue) {
10025 if (aName in aArgs) {
10026 return aArgs[aName];
10027 } else if (arguments.length === 3) {
10028 return aDefaultValue;
10029 } else {
10030 throw new Error('"' + aName + '" is a required argument.');
10031 }
10032 }
10033 exports.getArg = getArg;
10034
10035 var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/;
10036 var dataUrlRegexp = /^data:.+\,.+$/;
10037
10038 function urlParse(aUrl) {
10039 var match = aUrl.match(urlRegexp);
10040 if (!match) {
10041 return null;
10042 }
10043 return {
10044 scheme: match[1],
10045 auth: match[2],
10046 host: match[3],
10047 port: match[4],
10048 path: match[5]
10049 };
10050 }
10051 exports.urlParse = urlParse;
10052
10053 function urlGenerate(aParsedUrl) {
10054 var url = '';
10055 if (aParsedUrl.scheme) {
10056 url += aParsedUrl.scheme + ':';
10057 }
10058 url += '//';
10059 if (aParsedUrl.auth) {
10060 url += aParsedUrl.auth + '@';
10061 }
10062 if (aParsedUrl.host) {
10063 url += aParsedUrl.host;
10064 }
10065 if (aParsedUrl.port) {
10066 url += ":" + aParsedUrl.port;
10067 }
10068 if (aParsedUrl.path) {
10069 url += aParsedUrl.path;
10070 }
10071 return url;
10072 }
10073 exports.urlGenerate = urlGenerate;
10074
10075 /**
10076 * Normalizes a path, or the path portion of a URL:
10077 *
10078 * - Replaces consecutive slashes with one slash.
10079 * - Removes unnecessary '.' parts.
10080 * - Removes unnecessary '<dir>/..' parts.
10081 *
10082 * Based on code in the Node.js 'path' core module.
10083 *
10084 * @param aPath The path or url to normalize.
10085 */
10086 function normalize(aPath) {
10087 var path = aPath;
10088 var url = urlParse(aPath);
10089 if (url) {
10090 if (!url.path) {
10091 return aPath;
10092 }
10093 path = url.path;
10094 }
10095 var isAbsolute = exports.isAbsolute(path);
10096
10097 var parts = path.split(/\/+/);
10098 for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {
10099 part = parts[i];
10100 if (part === '.') {
10101 parts.splice(i, 1);
10102 } else if (part === '..') {
10103 up++;
10104 } else if (up > 0) {
10105 if (part === '') {
10106 // The first part is blank if the path is absolute. Trying to go
10107 // above the root is a no-op. Therefore we can remove all '..' parts
10108 // directly after the root.
10109 parts.splice(i + 1, up);
10110 up = 0;
10111 } else {
10112 parts.splice(i, 2);
10113 up--;
10114 }
10115 }
10116 }
10117 path = parts.join('/');
10118
10119 if (path === '') {
10120 path = isAbsolute ? '/' : '.';
10121 }
10122
10123 if (url) {
10124 url.path = path;
10125 return urlGenerate(url);
10126 }
10127 return path;
10128 }
10129 exports.normalize = normalize;
10130
10131 /**
10132 * Joins two paths/URLs.
10133 *
10134 * @param aRoot The root path or URL.
10135 * @param aPath The path or URL to be joined with the root.
10136 *
10137 * - If aPath is a URL or a data URI, aPath is returned, unless aPath is a
10138 * scheme-relative URL: Then the scheme of aRoot, if any, is prepended
10139 * first.
10140 * - Otherwise aPath is a path. If aRoot is a URL, then its path portion
10141 * is updated with the result and aRoot is returned. Otherwise the result
10142 * is returned.
10143 * - If aPath is absolute, the result is aPath.
10144 * - Otherwise the two paths are joined with a slash.
10145 * - Joining for example 'http://' and 'www.example.com' is also supported.
10146 */
10147 function join(aRoot, aPath) {
10148 if (aRoot === "") {
10149 aRoot = ".";
10150 }
10151 if (aPath === "") {
10152 aPath = ".";
10153 }
10154 var aPathUrl = urlParse(aPath);
10155 var aRootUrl = urlParse(aRoot);
10156 if (aRootUrl) {
10157 aRoot = aRootUrl.path || '/';
10158 }
10159
10160 // `join(foo, '//www.example.org')`
10161 if (aPathUrl && !aPathUrl.scheme) {
10162 if (aRootUrl) {
10163 aPathUrl.scheme = aRootUrl.scheme;
10164 }
10165 return urlGenerate(aPathUrl);
10166 }
10167
10168 if (aPathUrl || aPath.match(dataUrlRegexp)) {
10169 return aPath;
10170 }
10171
10172 // `join('http://', 'www.example.com')`
10173 if (aRootUrl && !aRootUrl.host && !aRootUrl.path) {
10174 aRootUrl.host = aPath;
10175 return urlGenerate(aRootUrl);
10176 }
10177
10178 var joined = aPath.charAt(0) === '/'
10179 ? aPath
10180 : normalize(aRoot.replace(/\/+$/, '') + '/' + aPath);
10181
10182 if (aRootUrl) {
10183 aRootUrl.path = joined;
10184 return urlGenerate(aRootUrl);
10185 }
10186 return joined;
10187 }
10188 exports.join = join;
10189
10190 exports.isAbsolute = function (aPath) {
10191 return aPath.charAt(0) === '/' || urlRegexp.test(aPath);
10192 };
10193
10194 /**
10195 * Make a path relative to a URL or another path.
10196 *
10197 * @param aRoot The root path or URL.
10198 * @param aPath The path or URL to be made relative to aRoot.
10199 */
10200 function relative(aRoot, aPath) {
10201 if (aRoot === "") {
10202 aRoot = ".";
10203 }
10204
10205 aRoot = aRoot.replace(/\/$/, '');
10206
10207 // It is possible for the path to be above the root. In this case, simply
10208 // checking whether the root is a prefix of the path won't work. Instead, we
10209 // need to remove components from the root one by one, until either we find
10210 // a prefix that fits, or we run out of components to remove.
10211 var level = 0;
10212 while (aPath.indexOf(aRoot + '/') !== 0) {
10213 var index = aRoot.lastIndexOf("/");
10214 if (index < 0) {
10215 return aPath;
10216 }
10217
10218 // If the only part of the root that is left is the scheme (i.e. http://,
10219 // file:///, etc.), one or more slashes (/), or simply nothing at all, we
10220 // have exhausted all components, so the path is not relative to the root.
10221 aRoot = aRoot.slice(0, index);
10222 if (aRoot.match(/^([^\/]+:\/)?\/*$/)) {
10223 return aPath;
10224 }
10225
10226 ++level;
10227 }
10228
10229 // Make sure we add a "../" for each component we removed from the root.
10230 return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1);
10231 }
10232 exports.relative = relative;
10233
10234 var supportsNullProto = (function () {
10235 var obj = Object.create(null);
10236 return !('__proto__' in obj);
10237 }());
10238
10239 function identity (s) {
10240 return s;
10241 }
10242
10243 /**
10244 * Because behavior goes wacky when you set `__proto__` on objects, we
10245 * have to prefix all the strings in our set with an arbitrary character.
10246 *
10247 * See https://github.com/mozilla/source-map/pull/31 and
10248 * https://github.com/mozilla/source-map/issues/30
10249 *
10250 * @param String aStr
10251 */
10252 function toSetString(aStr) {
10253 if (isProtoString(aStr)) {
10254 return '$' + aStr;
10255 }
10256
10257 return aStr;
10258 }
10259 exports.toSetString = supportsNullProto ? identity : toSetString;
10260
10261 function fromSetString(aStr) {
10262 if (isProtoString(aStr)) {
10263 return aStr.slice(1);
10264 }
10265
10266 return aStr;
10267 }
10268 exports.fromSetString = supportsNullProto ? identity : fromSetString;
10269
10270 function isProtoString(s) {
10271 if (!s) {
10272 return false;
10273 }
10274
10275 var length = s.length;
10276
10277 if (length < 9 /* "__proto__".length */) {
10278 return false;
10279 }
10280
10281 if (s.charCodeAt(length - 1) !== 95 /* '_' */ ||
10282 s.charCodeAt(length - 2) !== 95 /* '_' */ ||
10283 s.charCodeAt(length - 3) !== 111 /* 'o' */ ||
10284 s.charCodeAt(length - 4) !== 116 /* 't' */ ||
10285 s.charCodeAt(length - 5) !== 111 /* 'o' */ ||
10286 s.charCodeAt(length - 6) !== 114 /* 'r' */ ||
10287 s.charCodeAt(length - 7) !== 112 /* 'p' */ ||
10288 s.charCodeAt(length - 8) !== 95 /* '_' */ ||
10289 s.charCodeAt(length - 9) !== 95 /* '_' */) {
10290 return false;
10291 }
10292
10293 for (var i = length - 10; i >= 0; i--) {
10294 if (s.charCodeAt(i) !== 36 /* '$' */) {
10295 return false;
10296 }
10297 }
10298
10299 return true;
10300 }
10301
10302 /**
10303 * Comparator between two mappings where the original positions are compared.
10304 *
10305 * Optionally pass in `true` as `onlyCompareGenerated` to consider two
10306 * mappings with the same original source/line/column, but different generated
10307 * line and column the same. Useful when searching for a mapping with a
10308 * stubbed out mapping.
10309 */
10310 function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {
10311 var cmp = strcmp(mappingA.source, mappingB.source);
10312 if (cmp !== 0) {
10313 return cmp;
10314 }
10315
10316 cmp = mappingA.originalLine - mappingB.originalLine;
10317 if (cmp !== 0) {
10318 return cmp;
10319 }
10320
10321 cmp = mappingA.originalColumn - mappingB.originalColumn;
10322 if (cmp !== 0 || onlyCompareOriginal) {
10323 return cmp;
10324 }
10325
10326 cmp = mappingA.generatedColumn - mappingB.generatedColumn;
10327 if (cmp !== 0) {
10328 return cmp;
10329 }
10330
10331 cmp = mappingA.generatedLine - mappingB.generatedLine;
10332 if (cmp !== 0) {
10333 return cmp;
10334 }
10335
10336 return strcmp(mappingA.name, mappingB.name);
10337 }
10338 exports.compareByOriginalPositions = compareByOriginalPositions;
10339
10340 /**
10341 * Comparator between two mappings with deflated source and name indices where
10342 * the generated positions are compared.
10343 *
10344 * Optionally pass in `true` as `onlyCompareGenerated` to consider two
10345 * mappings with the same generated line and column, but different
10346 * source/name/original line and column the same. Useful when searching for a
10347 * mapping with a stubbed out mapping.
10348 */
10349 function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) {
10350 var cmp = mappingA.generatedLine - mappingB.generatedLine;
10351 if (cmp !== 0) {
10352 return cmp;
10353 }
10354
10355 cmp = mappingA.generatedColumn - mappingB.generatedColumn;
10356 if (cmp !== 0 || onlyCompareGenerated) {
10357 return cmp;
10358 }
10359
10360 cmp = strcmp(mappingA.source, mappingB.source);
10361 if (cmp !== 0) {
10362 return cmp;
10363 }
10364
10365 cmp = mappingA.originalLine - mappingB.originalLine;
10366 if (cmp !== 0) {
10367 return cmp;
10368 }
10369
10370 cmp = mappingA.originalColumn - mappingB.originalColumn;
10371 if (cmp !== 0) {
10372 return cmp;
10373 }
10374
10375 return strcmp(mappingA.name, mappingB.name);
10376 }
10377 exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated;
10378
10379 function strcmp(aStr1, aStr2) {
10380 if (aStr1 === aStr2) {
10381 return 0;
10382 }
10383
10384 if (aStr1 === null) {
10385 return 1; // aStr2 !== null
10386 }
10387
10388 if (aStr2 === null) {
10389 return -1; // aStr1 !== null
10390 }
10391
10392 if (aStr1 > aStr2) {
10393 return 1;
10394 }
10395
10396 return -1;
10397 }
10398
10399 /**
10400 * Comparator between two mappings with inflated source and name strings where
10401 * the generated positions are compared.
10402 */
10403 function compareByGeneratedPositionsInflated(mappingA, mappingB) {
10404 var cmp = mappingA.generatedLine - mappingB.generatedLine;
10405 if (cmp !== 0) {
10406 return cmp;
10407 }
10408
10409 cmp = mappingA.generatedColumn - mappingB.generatedColumn;
10410 if (cmp !== 0) {
10411 return cmp;
10412 }
10413
10414 cmp = strcmp(mappingA.source, mappingB.source);
10415 if (cmp !== 0) {
10416 return cmp;
10417 }
10418
10419 cmp = mappingA.originalLine - mappingB.originalLine;
10420 if (cmp !== 0) {
10421 return cmp;
10422 }
10423
10424 cmp = mappingA.originalColumn - mappingB.originalColumn;
10425 if (cmp !== 0) {
10426 return cmp;
10427 }
10428
10429 return strcmp(mappingA.name, mappingB.name);
10430 }
10431 exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated;
10432
10433 /**
10434 * Strip any JSON XSSI avoidance prefix from the string (as documented
10435 * in the source maps specification), and then parse the string as
10436 * JSON.
10437 */
10438 function parseSourceMapInput(str) {
10439 return JSON.parse(str.replace(/^\)]}'[^\n]*\n/, ''));
10440 }
10441 exports.parseSourceMapInput = parseSourceMapInput;
10442
10443 /**
10444 * Compute the URL of a source given the the source root, the source's
10445 * URL, and the source map's URL.
10446 */
10447 function computeSourceURL(sourceRoot, sourceURL, sourceMapURL) {
10448 sourceURL = sourceURL || '';
10449
10450 if (sourceRoot) {
10451 // This follows what Chrome does.
10452 if (sourceRoot[sourceRoot.length - 1] !== '/' && sourceURL[0] !== '/') {
10453 sourceRoot += '/';
10454 }
10455 // The spec says:
10456 // Line 4: An optional source root, useful for relocating source
10457 // files on a server or removing repeated values in the
10458 // “sources” entry. This value is prepended to the individual
10459 // entries in the “source” field.
10460 sourceURL = sourceRoot + sourceURL;
10461 }
10462
10463 // Historically, SourceMapConsumer did not take the sourceMapURL as
10464 // a parameter. This mode is still somewhat supported, which is why
10465 // this code block is conditional. However, it's preferable to pass
10466 // the source map URL to SourceMapConsumer, so that this function
10467 // can implement the source URL resolution algorithm as outlined in
10468 // the spec. This block is basically the equivalent of:
10469 // new URL(sourceURL, sourceMapURL).toString()
10470 // ... except it avoids using URL, which wasn't available in the
10471 // older releases of node still supported by this library.
10472 //
10473 // The spec says:
10474 // If the sources are not absolute URLs after prepending of the
10475 // “sourceRoot”, the sources are resolved relative to the
10476 // SourceMap (like resolving script src in a html document).
10477 if (sourceMapURL) {
10478 var parsed = urlParse(sourceMapURL);
10479 if (!parsed) {
10480 throw new Error("sourceMapURL could not be parsed");
10481 }
10482 if (parsed.path) {
10483 // Strip the last path component, but keep the "/".
10484 var index = parsed.path.lastIndexOf('/');
10485 if (index >= 0) {
10486 parsed.path = parsed.path.substring(0, index + 1);
10487 }
10488 }
10489 sourceURL = join(urlGenerate(parsed), sourceURL);
10490 }
10491
10492 return normalize(sourceURL);
10493 }
10494 exports.computeSourceURL = computeSourceURL;
10495 } (util$3));
10496
10497 var arraySet = {};
10498
10499 /* -*- Mode: js; js-indent-level: 2; -*- */
10500
10501 /*
10502 * Copyright 2011 Mozilla Foundation and contributors
10503 * Licensed under the New BSD license. See LICENSE or:
10504 * http://opensource.org/licenses/BSD-3-Clause
10505 */
10506
10507 var util$2 = util$3;
10508 var has$1 = Object.prototype.hasOwnProperty;
10509 var hasNativeMap = typeof Map !== "undefined";
10510
10511 /**
10512 * A data structure which is a combination of an array and a set. Adding a new
10513 * member is O(1), testing for membership is O(1), and finding the index of an
10514 * element is O(1). Removing elements from the set is not supported. Only
10515 * strings are supported for membership.
10516 */
10517 function ArraySet$1() {
10518 this._array = [];
10519 this._set = hasNativeMap ? new Map() : Object.create(null);
10520 }
10521
10522 /**
10523 * Static method for creating ArraySet instances from an existing array.
10524 */
10525 ArraySet$1.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) {
10526 var set = new ArraySet$1();
10527 for (var i = 0, len = aArray.length; i < len; i++) {
10528 set.add(aArray[i], aAllowDuplicates);
10529 }
10530 return set;
10531 };
10532
10533 /**
10534 * Return how many unique items are in this ArraySet. If duplicates have been
10535 * added, than those do not count towards the size.
10536 *
10537 * @returns Number
10538 */
10539 ArraySet$1.prototype.size = function ArraySet_size() {
10540 return hasNativeMap ? this._set.size : Object.getOwnPropertyNames(this._set).length;
10541 };
10542
10543 /**
10544 * Add the given string to this set.
10545 *
10546 * @param String aStr
10547 */
10548 ArraySet$1.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) {
10549 var sStr = hasNativeMap ? aStr : util$2.toSetString(aStr);
10550 var isDuplicate = hasNativeMap ? this.has(aStr) : has$1.call(this._set, sStr);
10551 var idx = this._array.length;
10552 if (!isDuplicate || aAllowDuplicates) {
10553 this._array.push(aStr);
10554 }
10555 if (!isDuplicate) {
10556 if (hasNativeMap) {
10557 this._set.set(aStr, idx);
10558 } else {
10559 this._set[sStr] = idx;
10560 }
10561 }
10562 };
10563
10564 /**
10565 * Is the given string a member of this set?
10566 *
10567 * @param String aStr
10568 */
10569 ArraySet$1.prototype.has = function ArraySet_has(aStr) {
10570 if (hasNativeMap) {
10571 return this._set.has(aStr);
10572 } else {
10573 var sStr = util$2.toSetString(aStr);
10574 return has$1.call(this._set, sStr);
10575 }
10576 };
10577
10578 /**
10579 * What is the index of the given string in the array?
10580 *
10581 * @param String aStr
10582 */
10583 ArraySet$1.prototype.indexOf = function ArraySet_indexOf(aStr) {
10584 if (hasNativeMap) {
10585 var idx = this._set.get(aStr);
10586 if (idx >= 0) {
10587 return idx;
10588 }
10589 } else {
10590 var sStr = util$2.toSetString(aStr);
10591 if (has$1.call(this._set, sStr)) {
10592 return this._set[sStr];
10593 }
10594 }
10595
10596 throw new Error('"' + aStr + '" is not in the set.');
10597 };
10598
10599 /**
10600 * What is the element at the given index?
10601 *
10602 * @param Number aIdx
10603 */
10604 ArraySet$1.prototype.at = function ArraySet_at(aIdx) {
10605 if (aIdx >= 0 && aIdx < this._array.length) {
10606 return this._array[aIdx];
10607 }
10608 throw new Error('No element indexed by ' + aIdx);
10609 };
10610
10611 /**
10612 * Returns the array representation of this set (which has the proper indices
10613 * indicated by indexOf). Note that this is a copy of the internal array used
10614 * for storing the members so that no one can mess with internal state.
10615 */
10616 ArraySet$1.prototype.toArray = function ArraySet_toArray() {
10617 return this._array.slice();
10618 };
10619
10620 arraySet.ArraySet = ArraySet$1;
10621
10622 var mappingList = {};
10623
10624 /* -*- Mode: js; js-indent-level: 2; -*- */
10625
10626 /*
10627 * Copyright 2014 Mozilla Foundation and contributors
10628 * Licensed under the New BSD license. See LICENSE or:
10629 * http://opensource.org/licenses/BSD-3-Clause
10630 */
10631
10632 var util$1 = util$3;
10633
10634 /**
10635 * Determine whether mappingB is after mappingA with respect to generated
10636 * position.
10637 */
10638 function generatedPositionAfter(mappingA, mappingB) {
10639 // Optimized for most common case
10640 var lineA = mappingA.generatedLine;
10641 var lineB = mappingB.generatedLine;
10642 var columnA = mappingA.generatedColumn;
10643 var columnB = mappingB.generatedColumn;
10644 return lineB > lineA || lineB == lineA && columnB >= columnA ||
10645 util$1.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0;
10646 }
10647
10648 /**
10649 * A data structure to provide a sorted view of accumulated mappings in a
10650 * performance conscious manner. It trades a neglibable overhead in general
10651 * case for a large speedup in case of mappings being added in order.
10652 */
10653 function MappingList$1() {
10654 this._array = [];
10655 this._sorted = true;
10656 // Serves as infimum
10657 this._last = {generatedLine: -1, generatedColumn: 0};
10658 }
10659
10660 /**
10661 * Iterate through internal items. This method takes the same arguments that
10662 * `Array.prototype.forEach` takes.
10663 *
10664 * NOTE: The order of the mappings is NOT guaranteed.
10665 */
10666 MappingList$1.prototype.unsortedForEach =
10667 function MappingList_forEach(aCallback, aThisArg) {
10668 this._array.forEach(aCallback, aThisArg);
10669 };
10670
10671 /**
10672 * Add the given source mapping.
10673 *
10674 * @param Object aMapping
10675 */
10676 MappingList$1.prototype.add = function MappingList_add(aMapping) {
10677 if (generatedPositionAfter(this._last, aMapping)) {
10678 this._last = aMapping;
10679 this._array.push(aMapping);
10680 } else {
10681 this._sorted = false;
10682 this._array.push(aMapping);
10683 }
10684 };
10685
10686 /**
10687 * Returns the flat, sorted array of mappings. The mappings are sorted by
10688 * generated position.
10689 *
10690 * WARNING: This method returns internal data without copying, for
10691 * performance. The return value must NOT be mutated, and should be treated as
10692 * an immutable borrow. If you want to take ownership, you must make your own
10693 * copy.
10694 */
10695 MappingList$1.prototype.toArray = function MappingList_toArray() {
10696 if (!this._sorted) {
10697 this._array.sort(util$1.compareByGeneratedPositionsInflated);
10698 this._sorted = true;
10699 }
10700 return this._array;
10701 };
10702
10703 mappingList.MappingList = MappingList$1;
10704
10705 /* -*- Mode: js; js-indent-level: 2; -*- */
10706
10707 /*
10708 * Copyright 2011 Mozilla Foundation and contributors
10709 * Licensed under the New BSD license. See LICENSE or:
10710 * http://opensource.org/licenses/BSD-3-Clause
10711 */
10712
10713 var base64VLQ = base64Vlq;
10714 var util = util$3;
10715 var ArraySet = arraySet.ArraySet;
10716 var MappingList = mappingList.MappingList;
10717
10718 /**
10719 * An instance of the SourceMapGenerator represents a source map which is
10720 * being built incrementally. You may pass an object with the following
10721 * properties:
10722 *
10723 * - file: The filename of the generated source.
10724 * - sourceRoot: A root for all relative URLs in this source map.
10725 */
10726 function SourceMapGenerator$1(aArgs) {
10727 if (!aArgs) {
10728 aArgs = {};
10729 }
10730 this._file = util.getArg(aArgs, 'file', null);
10731 this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null);
10732 this._skipValidation = util.getArg(aArgs, 'skipValidation', false);
10733 this._sources = new ArraySet();
10734 this._names = new ArraySet();
10735 this._mappings = new MappingList();
10736 this._sourcesContents = null;
10737 }
10738
10739 SourceMapGenerator$1.prototype._version = 3;
10740
10741 /**
10742 * Creates a new SourceMapGenerator based on a SourceMapConsumer
10743 *
10744 * @param aSourceMapConsumer The SourceMap.
10745 */
10746 SourceMapGenerator$1.fromSourceMap =
10747 function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) {
10748 var sourceRoot = aSourceMapConsumer.sourceRoot;
10749 var generator = new SourceMapGenerator$1({
10750 file: aSourceMapConsumer.file,
10751 sourceRoot: sourceRoot
10752 });
10753 aSourceMapConsumer.eachMapping(function (mapping) {
10754 var newMapping = {
10755 generated: {
10756 line: mapping.generatedLine,
10757 column: mapping.generatedColumn
10758 }
10759 };
10760
10761 if (mapping.source != null) {
10762 newMapping.source = mapping.source;
10763 if (sourceRoot != null) {
10764 newMapping.source = util.relative(sourceRoot, newMapping.source);
10765 }
10766
10767 newMapping.original = {
10768 line: mapping.originalLine,
10769 column: mapping.originalColumn
10770 };
10771
10772 if (mapping.name != null) {
10773 newMapping.name = mapping.name;
10774 }
10775 }
10776
10777 generator.addMapping(newMapping);
10778 });
10779 aSourceMapConsumer.sources.forEach(function (sourceFile) {
10780 var sourceRelative = sourceFile;
10781 if (sourceRoot !== null) {
10782 sourceRelative = util.relative(sourceRoot, sourceFile);
10783 }
10784
10785 if (!generator._sources.has(sourceRelative)) {
10786 generator._sources.add(sourceRelative);
10787 }
10788
10789 var content = aSourceMapConsumer.sourceContentFor(sourceFile);
10790 if (content != null) {
10791 generator.setSourceContent(sourceFile, content);
10792 }
10793 });
10794 return generator;
10795 };
10796
10797 /**
10798 * Add a single mapping from original source line and column to the generated
10799 * source's line and column for this source map being created. The mapping
10800 * object should have the following properties:
10801 *
10802 * - generated: An object with the generated line and column positions.
10803 * - original: An object with the original line and column positions.
10804 * - source: The original source file (relative to the sourceRoot).
10805 * - name: An optional original token name for this mapping.
10806 */
10807 SourceMapGenerator$1.prototype.addMapping =
10808 function SourceMapGenerator_addMapping(aArgs) {
10809 var generated = util.getArg(aArgs, 'generated');
10810 var original = util.getArg(aArgs, 'original', null);
10811 var source = util.getArg(aArgs, 'source', null);
10812 var name = util.getArg(aArgs, 'name', null);
10813
10814 if (!this._skipValidation) {
10815 this._validateMapping(generated, original, source, name);
10816 }
10817
10818 if (source != null) {
10819 source = String(source);
10820 if (!this._sources.has(source)) {
10821 this._sources.add(source);
10822 }
10823 }
10824
10825 if (name != null) {
10826 name = String(name);
10827 if (!this._names.has(name)) {
10828 this._names.add(name);
10829 }
10830 }
10831
10832 this._mappings.add({
10833 generatedLine: generated.line,
10834 generatedColumn: generated.column,
10835 originalLine: original != null && original.line,
10836 originalColumn: original != null && original.column,
10837 source: source,
10838 name: name
10839 });
10840 };
10841
10842 /**
10843 * Set the source content for a source file.
10844 */
10845 SourceMapGenerator$1.prototype.setSourceContent =
10846 function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) {
10847 var source = aSourceFile;
10848 if (this._sourceRoot != null) {
10849 source = util.relative(this._sourceRoot, source);
10850 }
10851
10852 if (aSourceContent != null) {
10853 // Add the source content to the _sourcesContents map.
10854 // Create a new _sourcesContents map if the property is null.
10855 if (!this._sourcesContents) {
10856 this._sourcesContents = Object.create(null);
10857 }
10858 this._sourcesContents[util.toSetString(source)] = aSourceContent;
10859 } else if (this._sourcesContents) {
10860 // Remove the source file from the _sourcesContents map.
10861 // If the _sourcesContents map is empty, set the property to null.
10862 delete this._sourcesContents[util.toSetString(source)];
10863 if (Object.keys(this._sourcesContents).length === 0) {
10864 this._sourcesContents = null;
10865 }
10866 }
10867 };
10868
10869 /**
10870 * Applies the mappings of a sub-source-map for a specific source file to the
10871 * source map being generated. Each mapping to the supplied source file is
10872 * rewritten using the supplied source map. Note: The resolution for the
10873 * resulting mappings is the minimium of this map and the supplied map.
10874 *
10875 * @param aSourceMapConsumer The source map to be applied.
10876 * @param aSourceFile Optional. The filename of the source file.
10877 * If omitted, SourceMapConsumer's file property will be used.
10878 * @param aSourceMapPath Optional. The dirname of the path to the source map
10879 * to be applied. If relative, it is relative to the SourceMapConsumer.
10880 * This parameter is needed when the two source maps aren't in the same
10881 * directory, and the source map to be applied contains relative source
10882 * paths. If so, those relative source paths need to be rewritten
10883 * relative to the SourceMapGenerator.
10884 */
10885 SourceMapGenerator$1.prototype.applySourceMap =
10886 function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) {
10887 var sourceFile = aSourceFile;
10888 // If aSourceFile is omitted, we will use the file property of the SourceMap
10889 if (aSourceFile == null) {
10890 if (aSourceMapConsumer.file == null) {
10891 throw new Error(
10892 'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' +
10893 'or the source map\'s "file" property. Both were omitted.'
10894 );
10895 }
10896 sourceFile = aSourceMapConsumer.file;
10897 }
10898 var sourceRoot = this._sourceRoot;
10899 // Make "sourceFile" relative if an absolute Url is passed.
10900 if (sourceRoot != null) {
10901 sourceFile = util.relative(sourceRoot, sourceFile);
10902 }
10903 // Applying the SourceMap can add and remove items from the sources and
10904 // the names array.
10905 var newSources = new ArraySet();
10906 var newNames = new ArraySet();
10907
10908 // Find mappings for the "sourceFile"
10909 this._mappings.unsortedForEach(function (mapping) {
10910 if (mapping.source === sourceFile && mapping.originalLine != null) {
10911 // Check if it can be mapped by the source map, then update the mapping.
10912 var original = aSourceMapConsumer.originalPositionFor({
10913 line: mapping.originalLine,
10914 column: mapping.originalColumn
10915 });
10916 if (original.source != null) {
10917 // Copy mapping
10918 mapping.source = original.source;
10919 if (aSourceMapPath != null) {
10920 mapping.source = util.join(aSourceMapPath, mapping.source);
10921 }
10922 if (sourceRoot != null) {
10923 mapping.source = util.relative(sourceRoot, mapping.source);
10924 }
10925 mapping.originalLine = original.line;
10926 mapping.originalColumn = original.column;
10927 if (original.name != null) {
10928 mapping.name = original.name;
10929 }
10930 }
10931 }
10932
10933 var source = mapping.source;
10934 if (source != null && !newSources.has(source)) {
10935 newSources.add(source);
10936 }
10937
10938 var name = mapping.name;
10939 if (name != null && !newNames.has(name)) {
10940 newNames.add(name);
10941 }
10942
10943 }, this);
10944 this._sources = newSources;
10945 this._names = newNames;
10946
10947 // Copy sourcesContents of applied map.
10948 aSourceMapConsumer.sources.forEach(function (sourceFile) {
10949 var content = aSourceMapConsumer.sourceContentFor(sourceFile);
10950 if (content != null) {
10951 if (aSourceMapPath != null) {
10952 sourceFile = util.join(aSourceMapPath, sourceFile);
10953 }
10954 if (sourceRoot != null) {
10955 sourceFile = util.relative(sourceRoot, sourceFile);
10956 }
10957 this.setSourceContent(sourceFile, content);
10958 }
10959 }, this);
10960 };
10961
10962 /**
10963 * A mapping can have one of the three levels of data:
10964 *
10965 * 1. Just the generated position.
10966 * 2. The Generated position, original position, and original source.
10967 * 3. Generated and original position, original source, as well as a name
10968 * token.
10969 *
10970 * To maintain consistency, we validate that any new mapping being added falls
10971 * in to one of these categories.
10972 */
10973 SourceMapGenerator$1.prototype._validateMapping =
10974 function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource,
10975 aName) {
10976 // When aOriginal is truthy but has empty values for .line and .column,
10977 // it is most likely a programmer error. In this case we throw a very
10978 // specific error message to try to guide them the right way.
10979 // For example: https://github.com/Polymer/polymer-bundler/pull/519
10980 if (aOriginal && typeof aOriginal.line !== 'number' && typeof aOriginal.column !== 'number') {
10981 throw new Error(
10982 'original.line and original.column are not numbers -- you probably meant to omit ' +
10983 'the original mapping entirely and only map the generated position. If so, pass ' +
10984 'null for the original mapping instead of an object with empty or null values.'
10985 );
10986 }
10987
10988 if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
10989 && aGenerated.line > 0 && aGenerated.column >= 0
10990 && !aOriginal && !aSource && !aName) {
10991 // Case 1.
10992 return;
10993 }
10994 else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
10995 && aOriginal && 'line' in aOriginal && 'column' in aOriginal
10996 && aGenerated.line > 0 && aGenerated.column >= 0
10997 && aOriginal.line > 0 && aOriginal.column >= 0
10998 && aSource) {
10999 // Cases 2 and 3.
11000 return;
11001 }
11002 else {
11003 throw new Error('Invalid mapping: ' + JSON.stringify({
11004 generated: aGenerated,
11005 source: aSource,
11006 original: aOriginal,
11007 name: aName
11008 }));
11009 }
11010 };
11011
11012 /**
11013 * Serialize the accumulated mappings in to the stream of base 64 VLQs
11014 * specified by the source map format.
11015 */
11016 SourceMapGenerator$1.prototype._serializeMappings =
11017 function SourceMapGenerator_serializeMappings() {
11018 var previousGeneratedColumn = 0;
11019 var previousGeneratedLine = 1;
11020 var previousOriginalColumn = 0;
11021 var previousOriginalLine = 0;
11022 var previousName = 0;
11023 var previousSource = 0;
11024 var result = '';
11025 var next;
11026 var mapping;
11027 var nameIdx;
11028 var sourceIdx;
11029
11030 var mappings = this._mappings.toArray();
11031 for (var i = 0, len = mappings.length; i < len; i++) {
11032 mapping = mappings[i];
11033 next = '';
11034
11035 if (mapping.generatedLine !== previousGeneratedLine) {
11036 previousGeneratedColumn = 0;
11037 while (mapping.generatedLine !== previousGeneratedLine) {
11038 next += ';';
11039 previousGeneratedLine++;
11040 }
11041 }
11042 else {
11043 if (i > 0) {
11044 if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) {
11045 continue;
11046 }
11047 next += ',';
11048 }
11049 }
11050
11051 next += base64VLQ.encode(mapping.generatedColumn
11052 - previousGeneratedColumn);
11053 previousGeneratedColumn = mapping.generatedColumn;
11054
11055 if (mapping.source != null) {
11056 sourceIdx = this._sources.indexOf(mapping.source);
11057 next += base64VLQ.encode(sourceIdx - previousSource);
11058 previousSource = sourceIdx;
11059
11060 // lines are stored 0-based in SourceMap spec version 3
11061 next += base64VLQ.encode(mapping.originalLine - 1
11062 - previousOriginalLine);
11063 previousOriginalLine = mapping.originalLine - 1;
11064
11065 next += base64VLQ.encode(mapping.originalColumn
11066 - previousOriginalColumn);
11067 previousOriginalColumn = mapping.originalColumn;
11068
11069 if (mapping.name != null) {
11070 nameIdx = this._names.indexOf(mapping.name);
11071 next += base64VLQ.encode(nameIdx - previousName);
11072 previousName = nameIdx;
11073 }
11074 }
11075
11076 result += next;
11077 }
11078
11079 return result;
11080 };
11081
11082 SourceMapGenerator$1.prototype._generateSourcesContent =
11083 function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) {
11084 return aSources.map(function (source) {
11085 if (!this._sourcesContents) {
11086 return null;
11087 }
11088 if (aSourceRoot != null) {
11089 source = util.relative(aSourceRoot, source);
11090 }
11091 var key = util.toSetString(source);
11092 return Object.prototype.hasOwnProperty.call(this._sourcesContents, key)
11093 ? this._sourcesContents[key]
11094 : null;
11095 }, this);
11096 };
11097
11098 /**
11099 * Externalize the source map.
11100 */
11101 SourceMapGenerator$1.prototype.toJSON =
11102 function SourceMapGenerator_toJSON() {
11103 var map = {
11104 version: this._version,
11105 sources: this._sources.toArray(),
11106 names: this._names.toArray(),
11107 mappings: this._serializeMappings()
11108 };
11109 if (this._file != null) {
11110 map.file = this._file;
11111 }
11112 if (this._sourceRoot != null) {
11113 map.sourceRoot = this._sourceRoot;
11114 }
11115 if (this._sourcesContents) {
11116 map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot);
11117 }
11118
11119 return map;
11120 };
11121
11122 /**
11123 * Render the source map being generated to a string.
11124 */
11125 SourceMapGenerator$1.prototype.toString =
11126 function SourceMapGenerator_toString() {
11127 return JSON.stringify(this.toJSON());
11128 };
11129
11130 sourceMapGenerator.SourceMapGenerator = SourceMapGenerator$1;
11131
11132 var SourceMapGenerator = sourceMapGenerator.SourceMapGenerator;
11133 var trackNodes = {
11134 Atrule: true,
11135 Selector: true,
11136 Declaration: true
11137 };
11138
11139 var sourceMap$1 = function generateSourceMap(handlers) {
11140 var map = new SourceMapGenerator();
11141 var line = 1;
11142 var column = 0;
11143 var generated = {
11144 line: 1,
11145 column: 0
11146 };
11147 var original = {
11148 line: 0, // should be zero to add first mapping
11149 column: 0
11150 };
11151 var sourceMappingActive = false;
11152 var activatedGenerated = {
11153 line: 1,
11154 column: 0
11155 };
11156 var activatedMapping = {
11157 generated: activatedGenerated
11158 };
11159
11160 var handlersNode = handlers.node;
11161 handlers.node = function(node) {
11162 if (node.loc && node.loc.start && trackNodes.hasOwnProperty(node.type)) {
11163 var nodeLine = node.loc.start.line;
11164 var nodeColumn = node.loc.start.column - 1;
11165
11166 if (original.line !== nodeLine ||
11167 original.column !== nodeColumn) {
11168 original.line = nodeLine;
11169 original.column = nodeColumn;
11170
11171 generated.line = line;
11172 generated.column = column;
11173
11174 if (sourceMappingActive) {
11175 sourceMappingActive = false;
11176 if (generated.line !== activatedGenerated.line ||
11177 generated.column !== activatedGenerated.column) {
11178 map.addMapping(activatedMapping);
11179 }
11180 }
11181
11182 sourceMappingActive = true;
11183 map.addMapping({
11184 source: node.loc.source,
11185 original: original,
11186 generated: generated
11187 });
11188 }
11189 }
11190
11191 handlersNode.call(this, node);
11192
11193 if (sourceMappingActive && trackNodes.hasOwnProperty(node.type)) {
11194 activatedGenerated.line = line;
11195 activatedGenerated.column = column;
11196 }
11197 };
11198
11199 var handlersChunk = handlers.chunk;
11200 handlers.chunk = function(chunk) {
11201 for (var i = 0; i < chunk.length; i++) {
11202 if (chunk.charCodeAt(i) === 10) { // \n
11203 line++;
11204 column = 0;
11205 } else {
11206 column++;
11207 }
11208 }
11209
11210 handlersChunk(chunk);
11211 };
11212
11213 var handlersResult = handlers.result;
11214 handlers.result = function() {
11215 if (sourceMappingActive) {
11216 map.addMapping(activatedMapping);
11217 }
11218
11219 return {
11220 css: handlersResult(),
11221 map: map
11222 };
11223 };
11224
11225 return handlers;
11226 };
11227
11228 var sourceMap = sourceMap$1;
11229 var hasOwnProperty$4 = Object.prototype.hasOwnProperty;
11230
11231 function processChildren(node, delimeter) {
11232 var list = node.children;
11233 var prev = null;
11234
11235 if (typeof delimeter !== 'function') {
11236 list.forEach(this.node, this);
11237 } else {
11238 list.forEach(function(node) {
11239 if (prev !== null) {
11240 delimeter.call(this, prev);
11241 }
11242
11243 this.node(node);
11244 prev = node;
11245 }, this);
11246 }
11247 }
11248
11249 var create$2 = function createGenerator(config) {
11250 function processNode(node) {
11251 if (hasOwnProperty$4.call(types, node.type)) {
11252 types[node.type].call(this, node);
11253 } else {
11254 throw new Error('Unknown node type: ' + node.type);
11255 }
11256 }
11257
11258 var types = {};
11259
11260 if (config.node) {
11261 for (var name in config.node) {
11262 types[name] = config.node[name].generate;
11263 }
11264 }
11265
11266 return function(node, options) {
11267 var buffer = '';
11268 var handlers = {
11269 children: processChildren,
11270 node: processNode,
11271 chunk: function(chunk) {
11272 buffer += chunk;
11273 },
11274 result: function() {
11275 return buffer;
11276 }
11277 };
11278
11279 if (options) {
11280 if (typeof options.decorator === 'function') {
11281 handlers = options.decorator(handlers);
11282 }
11283
11284 if (options.sourceMap) {
11285 handlers = sourceMap(handlers);
11286 }
11287 }
11288
11289 handlers.node(node);
11290
11291 return handlers.result();
11292 };
11293 };
11294
11295 var List$2 = List_1;
11296
11297 var create$1 = function createConvertors(walk) {
11298 return {
11299 fromPlainObject: function(ast) {
11300 walk(ast, {
11301 enter: function(node) {
11302 if (node.children && node.children instanceof List$2 === false) {
11303 node.children = new List$2().fromArray(node.children);
11304 }
11305 }
11306 });
11307
11308 return ast;
11309 },
11310 toPlainObject: function(ast) {
11311 walk(ast, {
11312 leave: function(node) {
11313 if (node.children && node.children instanceof List$2) {
11314 node.children = node.children.toArray();
11315 }
11316 }
11317 });
11318
11319 return ast;
11320 }
11321 };
11322 };
11323
11324 var hasOwnProperty$3 = Object.prototype.hasOwnProperty;
11325 var noop = function() {};
11326
11327 function ensureFunction(value) {
11328 return typeof value === 'function' ? value : noop;
11329 }
11330
11331 function invokeForType(fn, type) {
11332 return function(node, item, list) {
11333 if (node.type === type) {
11334 fn.call(this, node, item, list);
11335 }
11336 };
11337 }
11338
11339 function getWalkersFromStructure(name, nodeType) {
11340 var structure = nodeType.structure;
11341 var walkers = [];
11342
11343 for (var key in structure) {
11344 if (hasOwnProperty$3.call(structure, key) === false) {
11345 continue;
11346 }
11347
11348 var fieldTypes = structure[key];
11349 var walker = {
11350 name: key,
11351 type: false,
11352 nullable: false
11353 };
11354
11355 if (!Array.isArray(structure[key])) {
11356 fieldTypes = [structure[key]];
11357 }
11358
11359 for (var i = 0; i < fieldTypes.length; i++) {
11360 var fieldType = fieldTypes[i];
11361 if (fieldType === null) {
11362 walker.nullable = true;
11363 } else if (typeof fieldType === 'string') {
11364 walker.type = 'node';
11365 } else if (Array.isArray(fieldType)) {
11366 walker.type = 'list';
11367 }
11368 }
11369
11370 if (walker.type) {
11371 walkers.push(walker);
11372 }
11373 }
11374
11375 if (walkers.length) {
11376 return {
11377 context: nodeType.walkContext,
11378 fields: walkers
11379 };
11380 }
11381
11382 return null;
11383 }
11384
11385 function getTypesFromConfig(config) {
11386 var types = {};
11387
11388 for (var name in config.node) {
11389 if (hasOwnProperty$3.call(config.node, name)) {
11390 var nodeType = config.node[name];
11391
11392 if (!nodeType.structure) {
11393 throw new Error('Missed `structure` field in `' + name + '` node type definition');
11394 }
11395
11396 types[name] = getWalkersFromStructure(name, nodeType);
11397 }
11398 }
11399
11400 return types;
11401 }
11402
11403 function createTypeIterator(config, reverse) {
11404 var fields = config.fields.slice();
11405 var contextName = config.context;
11406 var useContext = typeof contextName === 'string';
11407
11408 if (reverse) {
11409 fields.reverse();
11410 }
11411
11412 return function(node, context, walk, walkReducer) {
11413 var prevContextValue;
11414
11415 if (useContext) {
11416 prevContextValue = context[contextName];
11417 context[contextName] = node;
11418 }
11419
11420 for (var i = 0; i < fields.length; i++) {
11421 var field = fields[i];
11422 var ref = node[field.name];
11423
11424 if (!field.nullable || ref) {
11425 if (field.type === 'list') {
11426 var breakWalk = reverse
11427 ? ref.reduceRight(walkReducer, false)
11428 : ref.reduce(walkReducer, false);
11429
11430 if (breakWalk) {
11431 return true;
11432 }
11433 } else if (walk(ref)) {
11434 return true;
11435 }
11436 }
11437 }
11438
11439 if (useContext) {
11440 context[contextName] = prevContextValue;
11441 }
11442 };
11443 }
11444
11445 function createFastTraveralMap(iterators) {
11446 return {
11447 Atrule: {
11448 StyleSheet: iterators.StyleSheet,
11449 Atrule: iterators.Atrule,
11450 Rule: iterators.Rule,
11451 Block: iterators.Block
11452 },
11453 Rule: {
11454 StyleSheet: iterators.StyleSheet,
11455 Atrule: iterators.Atrule,
11456 Rule: iterators.Rule,
11457 Block: iterators.Block
11458 },
11459 Declaration: {
11460 StyleSheet: iterators.StyleSheet,
11461 Atrule: iterators.Atrule,
11462 Rule: iterators.Rule,
11463 Block: iterators.Block,
11464 DeclarationList: iterators.DeclarationList
11465 }
11466 };
11467 }
11468
11469 var create = function createWalker(config) {
11470 var types = getTypesFromConfig(config);
11471 var iteratorsNatural = {};
11472 var iteratorsReverse = {};
11473 var breakWalk = Symbol('break-walk');
11474 var skipNode = Symbol('skip-node');
11475
11476 for (var name in types) {
11477 if (hasOwnProperty$3.call(types, name) && types[name] !== null) {
11478 iteratorsNatural[name] = createTypeIterator(types[name], false);
11479 iteratorsReverse[name] = createTypeIterator(types[name], true);
11480 }
11481 }
11482
11483 var fastTraversalIteratorsNatural = createFastTraveralMap(iteratorsNatural);
11484 var fastTraversalIteratorsReverse = createFastTraveralMap(iteratorsReverse);
11485
11486 var walk = function(root, options) {
11487 function walkNode(node, item, list) {
11488 var enterRet = enter.call(context, node, item, list);
11489
11490 if (enterRet === breakWalk) {
11491 debugger;
11492 return true;
11493 }
11494
11495 if (enterRet === skipNode) {
11496 return false;
11497 }
11498
11499 if (iterators.hasOwnProperty(node.type)) {
11500 if (iterators[node.type](node, context, walkNode, walkReducer)) {
11501 return true;
11502 }
11503 }
11504
11505 if (leave.call(context, node, item, list) === breakWalk) {
11506 return true;
11507 }
11508
11509 return false;
11510 }
11511
11512 var walkReducer = (ret, data, item, list) => ret || walkNode(data, item, list);
11513 var enter = noop;
11514 var leave = noop;
11515 var iterators = iteratorsNatural;
11516 var context = {
11517 break: breakWalk,
11518 skip: skipNode,
11519
11520 root: root,
11521 stylesheet: null,
11522 atrule: null,
11523 atrulePrelude: null,
11524 rule: null,
11525 selector: null,
11526 block: null,
11527 declaration: null,
11528 function: null
11529 };
11530
11531 if (typeof options === 'function') {
11532 enter = options;
11533 } else if (options) {
11534 enter = ensureFunction(options.enter);
11535 leave = ensureFunction(options.leave);
11536
11537 if (options.reverse) {
11538 iterators = iteratorsReverse;
11539 }
11540
11541 if (options.visit) {
11542 if (fastTraversalIteratorsNatural.hasOwnProperty(options.visit)) {
11543 iterators = options.reverse
11544 ? fastTraversalIteratorsReverse[options.visit]
11545 : fastTraversalIteratorsNatural[options.visit];
11546 } else if (!types.hasOwnProperty(options.visit)) {
11547 throw new Error('Bad value `' + options.visit + '` for `visit` option (should be: ' + Object.keys(types).join(', ') + ')');
11548 }
11549
11550 enter = invokeForType(enter, options.visit);
11551 leave = invokeForType(leave, options.visit);
11552 }
11553 }
11554
11555 if (enter === noop && leave === noop) {
11556 throw new Error('Neither `enter` nor `leave` walker handler is set or both aren\'t a function');
11557 }
11558
11559 walkNode(root);
11560 };
11561
11562 walk.break = breakWalk;
11563 walk.skip = skipNode;
11564
11565 walk.find = function(ast, fn) {
11566 var found = null;
11567
11568 walk(ast, function(node, item, list) {
11569 if (fn.call(this, node, item, list)) {
11570 found = node;
11571 return breakWalk;
11572 }
11573 });
11574
11575 return found;
11576 };
11577
11578 walk.findLast = function(ast, fn) {
11579 var found = null;
11580
11581 walk(ast, {
11582 reverse: true,
11583 enter: function(node, item, list) {
11584 if (fn.call(this, node, item, list)) {
11585 found = node;
11586 return breakWalk;
11587 }
11588 }
11589 });
11590
11591 return found;
11592 };
11593
11594 walk.findAll = function(ast, fn) {
11595 var found = [];
11596
11597 walk(ast, function(node, item, list) {
11598 if (fn.call(this, node, item, list)) {
11599 found.push(node);
11600 }
11601 });
11602
11603 return found;
11604 };
11605
11606 return walk;
11607 };
11608
11609 var List$1 = List_1;
11610
11611 var clone$1 = function clone(node) {
11612 var result = {};
11613
11614 for (var key in node) {
11615 var value = node[key];
11616
11617 if (value) {
11618 if (Array.isArray(value) || value instanceof List$1) {
11619 value = value.map(clone);
11620 } else if (value.constructor === Object) {
11621 value = clone(value);
11622 }
11623 }
11624
11625 result[key] = value;
11626 }
11627
11628 return result;
11629 };
11630
11631 const hasOwnProperty$2 = Object.prototype.hasOwnProperty;
11632 const shape$1 = {
11633 generic: true,
11634 types: appendOrAssign,
11635 atrules: {
11636 prelude: appendOrAssignOrNull,
11637 descriptors: appendOrAssignOrNull
11638 },
11639 properties: appendOrAssign,
11640 parseContext: assign,
11641 scope: deepAssign,
11642 atrule: ['parse'],
11643 pseudo: ['parse'],
11644 node: ['name', 'structure', 'parse', 'generate', 'walkContext']
11645 };
11646
11647 function isObject$2(value) {
11648 return value && value.constructor === Object;
11649 }
11650
11651 function copy(value) {
11652 return isObject$2(value)
11653 ? Object.assign({}, value)
11654 : value;
11655 }
11656
11657 function assign(dest, src) {
11658 return Object.assign(dest, src);
11659 }
11660
11661 function deepAssign(dest, src) {
11662 for (const key in src) {
11663 if (hasOwnProperty$2.call(src, key)) {
11664 if (isObject$2(dest[key])) {
11665 deepAssign(dest[key], copy(src[key]));
11666 } else {
11667 dest[key] = copy(src[key]);
11668 }
11669 }
11670 }
11671
11672 return dest;
11673 }
11674
11675 function append(a, b) {
11676 if (typeof b === 'string' && /^\s*\|/.test(b)) {
11677 return typeof a === 'string'
11678 ? a + b
11679 : b.replace(/^\s*\|\s*/, '');
11680 }
11681
11682 return b || null;
11683 }
11684
11685 function appendOrAssign(a, b) {
11686 if (typeof b === 'string') {
11687 return append(a, b);
11688 }
11689
11690 const result = Object.assign({}, a);
11691 for (let key in b) {
11692 if (hasOwnProperty$2.call(b, key)) {
11693 result[key] = append(hasOwnProperty$2.call(a, key) ? a[key] : undefined, b[key]);
11694 }
11695 }
11696
11697 return result;
11698 }
11699
11700 function appendOrAssignOrNull(a, b) {
11701 const result = appendOrAssign(a, b);
11702
11703 return !isObject$2(result) || Object.keys(result).length
11704 ? result
11705 : null;
11706 }
11707
11708 function mix$1(dest, src, shape) {
11709 for (const key in shape) {
11710 if (hasOwnProperty$2.call(shape, key) === false) {
11711 continue;
11712 }
11713
11714 if (shape[key] === true) {
11715 if (key in src) {
11716 if (hasOwnProperty$2.call(src, key)) {
11717 dest[key] = copy(src[key]);
11718 }
11719 }
11720 } else if (shape[key]) {
11721 if (typeof shape[key] === 'function') {
11722 const fn = shape[key];
11723 dest[key] = fn({}, dest[key]);
11724 dest[key] = fn(dest[key] || {}, src[key]);
11725 } else if (isObject$2(shape[key])) {
11726 const result = {};
11727
11728 for (let name in dest[key]) {
11729 result[name] = mix$1({}, dest[key][name], shape[key]);
11730 }
11731
11732 for (let name in src[key]) {
11733 result[name] = mix$1(result[name] || {}, src[key][name], shape[key]);
11734 }
11735
11736 dest[key] = result;
11737 } else if (Array.isArray(shape[key])) {
11738 const res = {};
11739 const innerShape = shape[key].reduce(function(s, k) {
11740 s[k] = true;
11741 return s;
11742 }, {});
11743
11744 for (const [name, value] of Object.entries(dest[key] || {})) {
11745 res[name] = {};
11746 if (value) {
11747 mix$1(res[name], value, innerShape);
11748 }
11749 }
11750
11751 for (const name in src[key]) {
11752 if (hasOwnProperty$2.call(src[key], name)) {
11753 if (!res[name]) {
11754 res[name] = {};
11755 }
11756
11757 if (src[key] && src[key][name]) {
11758 mix$1(res[name], src[key][name], innerShape);
11759 }
11760 }
11761 }
11762
11763 dest[key] = res;
11764 }
11765 }
11766 }
11767 return dest;
11768 }
11769
11770 var mix_1 = (dest, src) => mix$1(dest, src, shape$1);
11771
11772 var List = List_1;
11773 var SyntaxError$1 = _SyntaxError$1;
11774 var TokenStream = TokenStream_1;
11775 var Lexer = Lexer_1;
11776 var definitionSyntax = definitionSyntax$1;
11777 var tokenize = tokenizer$3;
11778 var createParser = create$3;
11779 var createGenerator = create$2;
11780 var createConvertor = create$1;
11781 var createWalker = create;
11782 var clone = clone$1;
11783 var names = names$2;
11784 var mix = mix_1;
11785
11786 function createSyntax(config) {
11787 var parse = createParser(config);
11788 var walk = createWalker(config);
11789 var generate = createGenerator(config);
11790 var convert = createConvertor(walk);
11791
11792 var syntax = {
11793 List: List,
11794 SyntaxError: SyntaxError$1,
11795 TokenStream: TokenStream,
11796 Lexer: Lexer,
11797
11798 vendorPrefix: names.vendorPrefix,
11799 keyword: names.keyword,
11800 property: names.property,
11801 isCustomProperty: names.isCustomProperty,
11802
11803 definitionSyntax: definitionSyntax,
11804 lexer: null,
11805 createLexer: function(config) {
11806 return new Lexer(config, syntax, syntax.lexer.structure);
11807 },
11808
11809 tokenize: tokenize,
11810 parse: parse,
11811 walk: walk,
11812 generate: generate,
11813
11814 find: walk.find,
11815 findLast: walk.findLast,
11816 findAll: walk.findAll,
11817
11818 clone: clone,
11819 fromPlainObject: convert.fromPlainObject,
11820 toPlainObject: convert.toPlainObject,
11821
11822 createSyntax: function(config) {
11823 return createSyntax(mix({}, config));
11824 },
11825 fork: function(extension) {
11826 var base = mix({}, config); // copy of config
11827 return createSyntax(
11828 typeof extension === 'function'
11829 ? extension(base, Object.assign)
11830 : mix(base, extension)
11831 );
11832 }
11833 };
11834
11835 syntax.lexer = new Lexer({
11836 generic: true,
11837 types: config.types,
11838 atrules: config.atrules,
11839 properties: config.properties,
11840 node: config.node
11841 }, syntax);
11842
11843 return syntax;
11844 }
11845 create$4.create = function(config) {
11846 return createSyntax(mix({}, config));
11847 };
11848
11849 var require$$0 = {
11850 "@charset": {
11851 syntax: "@charset \"<charset>\";",
11852 groups: [
11853 "CSS Charsets"
11854 ],
11855 status: "standard",
11856 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/@charset"
11857 },
11858 "@counter-style": {
11859 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}",
11860 interfaces: [
11861 "CSSCounterStyleRule"
11862 ],
11863 groups: [
11864 "CSS Counter Styles"
11865 ],
11866 descriptors: {
11867 "additive-symbols": {
11868 syntax: "[ <integer> && <symbol> ]#",
11869 media: "all",
11870 initial: "n/a (required)",
11871 percentages: "no",
11872 computed: "asSpecified",
11873 order: "orderOfAppearance",
11874 status: "standard"
11875 },
11876 fallback: {
11877 syntax: "<counter-style-name>",
11878 media: "all",
11879 initial: "decimal",
11880 percentages: "no",
11881 computed: "asSpecified",
11882 order: "uniqueOrder",
11883 status: "standard"
11884 },
11885 negative: {
11886 syntax: "<symbol> <symbol>?",
11887 media: "all",
11888 initial: "\"-\" hyphen-minus",
11889 percentages: "no",
11890 computed: "asSpecified",
11891 order: "orderOfAppearance",
11892 status: "standard"
11893 },
11894 pad: {
11895 syntax: "<integer> && <symbol>",
11896 media: "all",
11897 initial: "0 \"\"",
11898 percentages: "no",
11899 computed: "asSpecified",
11900 order: "uniqueOrder",
11901 status: "standard"
11902 },
11903 prefix: {
11904 syntax: "<symbol>",
11905 media: "all",
11906 initial: "\"\"",
11907 percentages: "no",
11908 computed: "asSpecified",
11909 order: "uniqueOrder",
11910 status: "standard"
11911 },
11912 range: {
11913 syntax: "[ [ <integer> | infinite ]{2} ]# | auto",
11914 media: "all",
11915 initial: "auto",
11916 percentages: "no",
11917 computed: "asSpecified",
11918 order: "orderOfAppearance",
11919 status: "standard"
11920 },
11921 "speak-as": {
11922 syntax: "auto | bullets | numbers | words | spell-out | <counter-style-name>",
11923 media: "all",
11924 initial: "auto",
11925 percentages: "no",
11926 computed: "asSpecified",
11927 order: "uniqueOrder",
11928 status: "standard"
11929 },
11930 suffix: {
11931 syntax: "<symbol>",
11932 media: "all",
11933 initial: "\". \"",
11934 percentages: "no",
11935 computed: "asSpecified",
11936 order: "uniqueOrder",
11937 status: "standard"
11938 },
11939 symbols: {
11940 syntax: "<symbol>+",
11941 media: "all",
11942 initial: "n/a (required)",
11943 percentages: "no",
11944 computed: "asSpecified",
11945 order: "orderOfAppearance",
11946 status: "standard"
11947 },
11948 system: {
11949 syntax: "cyclic | numeric | alphabetic | symbolic | additive | [ fixed <integer>? ] | [ extends <counter-style-name> ]",
11950 media: "all",
11951 initial: "symbolic",
11952 percentages: "no",
11953 computed: "asSpecified",
11954 order: "uniqueOrder",
11955 status: "standard"
11956 }
11957 },
11958 status: "standard",
11959 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/@counter-style"
11960 },
11961 "@document": {
11962 syntax: "@document [ <url> | url-prefix(<string>) | domain(<string>) | media-document(<string>) | regexp(<string>) ]# {\n <group-rule-body>\n}",
11963 interfaces: [
11964 "CSSGroupingRule",
11965 "CSSConditionRule"
11966 ],
11967 groups: [
11968 "CSS Conditional Rules"
11969 ],
11970 status: "nonstandard",
11971 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/@document"
11972 },
11973 "@font-face": {
11974 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}",
11975 interfaces: [
11976 "CSSFontFaceRule"
11977 ],
11978 groups: [
11979 "CSS Fonts"
11980 ],
11981 descriptors: {
11982 "font-display": {
11983 syntax: "[ auto | block | swap | fallback | optional ]",
11984 media: "visual",
11985 percentages: "no",
11986 initial: "auto",
11987 computed: "asSpecified",
11988 order: "uniqueOrder",
11989 status: "experimental"
11990 },
11991 "font-family": {
11992 syntax: "<family-name>",
11993 media: "all",
11994 initial: "n/a (required)",
11995 percentages: "no",
11996 computed: "asSpecified",
11997 order: "uniqueOrder",
11998 status: "standard"
11999 },
12000 "font-feature-settings": {
12001 syntax: "normal | <feature-tag-value>#",
12002 media: "all",
12003 initial: "normal",
12004 percentages: "no",
12005 computed: "asSpecified",
12006 order: "orderOfAppearance",
12007 status: "standard"
12008 },
12009 "font-variation-settings": {
12010 syntax: "normal | [ <string> <number> ]#",
12011 media: "all",
12012 initial: "normal",
12013 percentages: "no",
12014 computed: "asSpecified",
12015 order: "orderOfAppearance",
12016 status: "standard"
12017 },
12018 "font-stretch": {
12019 syntax: "<font-stretch-absolute>{1,2}",
12020 media: "all",
12021 initial: "normal",
12022 percentages: "no",
12023 computed: "asSpecified",
12024 order: "uniqueOrder",
12025 status: "standard"
12026 },
12027 "font-style": {
12028 syntax: "normal | italic | oblique <angle>{0,2}",
12029 media: "all",
12030 initial: "normal",
12031 percentages: "no",
12032 computed: "asSpecified",
12033 order: "uniqueOrder",
12034 status: "standard"
12035 },
12036 "font-weight": {
12037 syntax: "<font-weight-absolute>{1,2}",
12038 media: "all",
12039 initial: "normal",
12040 percentages: "no",
12041 computed: "asSpecified",
12042 order: "uniqueOrder",
12043 status: "standard"
12044 },
12045 "font-variant": {
12046 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 ]",
12047 media: "all",
12048 initial: "normal",
12049 percentages: "no",
12050 computed: "asSpecified",
12051 order: "orderOfAppearance",
12052 status: "standard"
12053 },
12054 src: {
12055 syntax: "[ <url> [ format( <string># ) ]? | local( <family-name> ) ]#",
12056 media: "all",
12057 initial: "n/a (required)",
12058 percentages: "no",
12059 computed: "asSpecified",
12060 order: "orderOfAppearance",
12061 status: "standard"
12062 },
12063 "unicode-range": {
12064 syntax: "<unicode-range>#",
12065 media: "all",
12066 initial: "U+0-10FFFF",
12067 percentages: "no",
12068 computed: "asSpecified",
12069 order: "orderOfAppearance",
12070 status: "standard"
12071 }
12072 },
12073 status: "standard",
12074 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/@font-face"
12075 },
12076 "@font-feature-values": {
12077 syntax: "@font-feature-values <family-name># {\n <feature-value-block-list>\n}",
12078 interfaces: [
12079 "CSSFontFeatureValuesRule"
12080 ],
12081 groups: [
12082 "CSS Fonts"
12083 ],
12084 status: "standard",
12085 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/@font-feature-values"
12086 },
12087 "@import": {
12088 syntax: "@import [ <string> | <url> ] [ <media-query-list> ]?;",
12089 groups: [
12090 "Media Queries"
12091 ],
12092 status: "standard",
12093 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/@import"
12094 },
12095 "@keyframes": {
12096 syntax: "@keyframes <keyframes-name> {\n <keyframe-block-list>\n}",
12097 interfaces: [
12098 "CSSKeyframeRule",
12099 "CSSKeyframesRule"
12100 ],
12101 groups: [
12102 "CSS Animations"
12103 ],
12104 status: "standard",
12105 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/@keyframes"
12106 },
12107 "@media": {
12108 syntax: "@media <media-query-list> {\n <group-rule-body>\n}",
12109 interfaces: [
12110 "CSSGroupingRule",
12111 "CSSConditionRule",
12112 "CSSMediaRule",
12113 "CSSCustomMediaRule"
12114 ],
12115 groups: [
12116 "CSS Conditional Rules",
12117 "Media Queries"
12118 ],
12119 status: "standard",
12120 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/@media"
12121 },
12122 "@namespace": {
12123 syntax: "@namespace <namespace-prefix>? [ <string> | <url> ];",
12124 groups: [
12125 "CSS Namespaces"
12126 ],
12127 status: "standard",
12128 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/@namespace"
12129 },
12130 "@page": {
12131 syntax: "@page <page-selector-list> {\n <page-body>\n}",
12132 interfaces: [
12133 "CSSPageRule"
12134 ],
12135 groups: [
12136 "CSS Pages"
12137 ],
12138 descriptors: {
12139 bleed: {
12140 syntax: "auto | <length>",
12141 media: [
12142 "visual",
12143 "paged"
12144 ],
12145 initial: "auto",
12146 percentages: "no",
12147 computed: "asSpecified",
12148 order: "uniqueOrder",
12149 status: "standard"
12150 },
12151 marks: {
12152 syntax: "none | [ crop || cross ]",
12153 media: [
12154 "visual",
12155 "paged"
12156 ],
12157 initial: "none",
12158 percentages: "no",
12159 computed: "asSpecified",
12160 order: "orderOfAppearance",
12161 status: "standard"
12162 },
12163 size: {
12164 syntax: "<length>{1,2} | auto | [ <page-size> || [ portrait | landscape ] ]",
12165 media: [
12166 "visual",
12167 "paged"
12168 ],
12169 initial: "auto",
12170 percentages: "no",
12171 computed: "asSpecifiedRelativeToAbsoluteLengths",
12172 order: "orderOfAppearance",
12173 status: "standard"
12174 }
12175 },
12176 status: "standard",
12177 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/@page"
12178 },
12179 "@property": {
12180 syntax: "@property <custom-property-name> {\n <declaration-list>\n}",
12181 interfaces: [
12182 "CSS",
12183 "CSSPropertyRule"
12184 ],
12185 groups: [
12186 "CSS Houdini"
12187 ],
12188 descriptors: {
12189 syntax: {
12190 syntax: "<string>",
12191 media: "all",
12192 percentages: "no",
12193 initial: "n/a (required)",
12194 computed: "asSpecified",
12195 order: "uniqueOrder",
12196 status: "experimental"
12197 },
12198 inherits: {
12199 syntax: "true | false",
12200 media: "all",
12201 percentages: "no",
12202 initial: "auto",
12203 computed: "asSpecified",
12204 order: "uniqueOrder",
12205 status: "experimental"
12206 },
12207 "initial-value": {
12208 syntax: "<string>",
12209 media: "all",
12210 initial: "n/a (required)",
12211 percentages: "no",
12212 computed: "asSpecified",
12213 order: "uniqueOrder",
12214 status: "experimental"
12215 }
12216 },
12217 status: "experimental",
12218 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/@property"
12219 },
12220 "@supports": {
12221 syntax: "@supports <supports-condition> {\n <group-rule-body>\n}",
12222 interfaces: [
12223 "CSSGroupingRule",
12224 "CSSConditionRule",
12225 "CSSSupportsRule"
12226 ],
12227 groups: [
12228 "CSS Conditional Rules"
12229 ],
12230 status: "standard",
12231 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/@supports"
12232 },
12233 "@viewport": {
12234 syntax: "@viewport {\n <group-rule-body>\n}",
12235 interfaces: [
12236 "CSSViewportRule"
12237 ],
12238 groups: [
12239 "CSS Device Adaptation"
12240 ],
12241 descriptors: {
12242 height: {
12243 syntax: "<viewport-length>{1,2}",
12244 media: [
12245 "visual",
12246 "continuous"
12247 ],
12248 initial: [
12249 "min-height",
12250 "max-height"
12251 ],
12252 percentages: [
12253 "min-height",
12254 "max-height"
12255 ],
12256 computed: [
12257 "min-height",
12258 "max-height"
12259 ],
12260 order: "orderOfAppearance",
12261 status: "standard"
12262 },
12263 "max-height": {
12264 syntax: "<viewport-length>",
12265 media: [
12266 "visual",
12267 "continuous"
12268 ],
12269 initial: "auto",
12270 percentages: "referToHeightOfInitialViewport",
12271 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
12272 order: "uniqueOrder",
12273 status: "standard"
12274 },
12275 "max-width": {
12276 syntax: "<viewport-length>",
12277 media: [
12278 "visual",
12279 "continuous"
12280 ],
12281 initial: "auto",
12282 percentages: "referToWidthOfInitialViewport",
12283 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
12284 order: "uniqueOrder",
12285 status: "standard"
12286 },
12287 "max-zoom": {
12288 syntax: "auto | <number> | <percentage>",
12289 media: [
12290 "visual",
12291 "continuous"
12292 ],
12293 initial: "auto",
12294 percentages: "the zoom factor itself",
12295 computed: "autoNonNegativeOrPercentage",
12296 order: "uniqueOrder",
12297 status: "standard"
12298 },
12299 "min-height": {
12300 syntax: "<viewport-length>",
12301 media: [
12302 "visual",
12303 "continuous"
12304 ],
12305 initial: "auto",
12306 percentages: "referToHeightOfInitialViewport",
12307 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
12308 order: "uniqueOrder",
12309 status: "standard"
12310 },
12311 "min-width": {
12312 syntax: "<viewport-length>",
12313 media: [
12314 "visual",
12315 "continuous"
12316 ],
12317 initial: "auto",
12318 percentages: "referToWidthOfInitialViewport",
12319 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
12320 order: "uniqueOrder",
12321 status: "standard"
12322 },
12323 "min-zoom": {
12324 syntax: "auto | <number> | <percentage>",
12325 media: [
12326 "visual",
12327 "continuous"
12328 ],
12329 initial: "auto",
12330 percentages: "the zoom factor itself",
12331 computed: "autoNonNegativeOrPercentage",
12332 order: "uniqueOrder",
12333 status: "standard"
12334 },
12335 orientation: {
12336 syntax: "auto | portrait | landscape",
12337 media: [
12338 "visual",
12339 "continuous"
12340 ],
12341 initial: "auto",
12342 percentages: "referToSizeOfBoundingBox",
12343 computed: "asSpecified",
12344 order: "uniqueOrder",
12345 status: "standard"
12346 },
12347 "user-zoom": {
12348 syntax: "zoom | fixed",
12349 media: [
12350 "visual",
12351 "continuous"
12352 ],
12353 initial: "zoom",
12354 percentages: "referToSizeOfBoundingBox",
12355 computed: "asSpecified",
12356 order: "uniqueOrder",
12357 status: "standard"
12358 },
12359 "viewport-fit": {
12360 syntax: "auto | contain | cover",
12361 media: [
12362 "visual",
12363 "continuous"
12364 ],
12365 initial: "auto",
12366 percentages: "no",
12367 computed: "asSpecified",
12368 order: "uniqueOrder",
12369 status: "standard"
12370 },
12371 width: {
12372 syntax: "<viewport-length>{1,2}",
12373 media: [
12374 "visual",
12375 "continuous"
12376 ],
12377 initial: [
12378 "min-width",
12379 "max-width"
12380 ],
12381 percentages: [
12382 "min-width",
12383 "max-width"
12384 ],
12385 computed: [
12386 "min-width",
12387 "max-width"
12388 ],
12389 order: "orderOfAppearance",
12390 status: "standard"
12391 },
12392 zoom: {
12393 syntax: "auto | <number> | <percentage>",
12394 media: [
12395 "visual",
12396 "continuous"
12397 ],
12398 initial: "auto",
12399 percentages: "the zoom factor itself",
12400 computed: "autoNonNegativeOrPercentage",
12401 order: "uniqueOrder",
12402 status: "standard"
12403 }
12404 },
12405 status: "standard",
12406 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/@viewport"
12407 }
12408 };
12409
12410 var all = {
12411 syntax: "initial | inherit | unset | revert",
12412 media: "noPracticalMedia",
12413 inherited: false,
12414 animationType: "eachOfShorthandPropertiesExceptUnicodeBiDiAndDirection",
12415 percentages: "no",
12416 groups: [
12417 "CSS Miscellaneous"
12418 ],
12419 initial: "noPracticalInitialValue",
12420 appliesto: "allElements",
12421 computed: "asSpecifiedAppliesToEachProperty",
12422 order: "uniqueOrder",
12423 status: "standard",
12424 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/all"
12425 };
12426 var animation = {
12427 syntax: "<single-animation>#",
12428 media: "visual",
12429 inherited: false,
12430 animationType: "discrete",
12431 percentages: "no",
12432 groups: [
12433 "CSS Animations"
12434 ],
12435 initial: [
12436 "animation-name",
12437 "animation-duration",
12438 "animation-timing-function",
12439 "animation-delay",
12440 "animation-iteration-count",
12441 "animation-direction",
12442 "animation-fill-mode",
12443 "animation-play-state"
12444 ],
12445 appliesto: "allElementsAndPseudos",
12446 computed: [
12447 "animation-name",
12448 "animation-duration",
12449 "animation-timing-function",
12450 "animation-delay",
12451 "animation-direction",
12452 "animation-iteration-count",
12453 "animation-fill-mode",
12454 "animation-play-state"
12455 ],
12456 order: "orderOfAppearance",
12457 status: "standard",
12458 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/animation"
12459 };
12460 var appearance = {
12461 syntax: "none | auto | textfield | menulist-button | <compat-auto>",
12462 media: "all",
12463 inherited: false,
12464 animationType: "discrete",
12465 percentages: "no",
12466 groups: [
12467 "CSS Basic User Interface"
12468 ],
12469 initial: "auto",
12470 appliesto: "allElements",
12471 computed: "asSpecified",
12472 order: "perGrammar",
12473 status: "experimental",
12474 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/appearance"
12475 };
12476 var azimuth = {
12477 syntax: "<angle> | [ [ left-side | far-left | left | center-left | center | center-right | right | far-right | right-side ] || behind ] | leftwards | rightwards",
12478 media: "aural",
12479 inherited: true,
12480 animationType: "discrete",
12481 percentages: "no",
12482 groups: [
12483 "CSS Speech"
12484 ],
12485 initial: "center",
12486 appliesto: "allElements",
12487 computed: "normalizedAngle",
12488 order: "orderOfAppearance",
12489 status: "obsolete",
12490 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/azimuth"
12491 };
12492 var background = {
12493 syntax: "[ <bg-layer> , ]* <final-bg-layer>",
12494 media: "visual",
12495 inherited: false,
12496 animationType: [
12497 "background-color",
12498 "background-image",
12499 "background-clip",
12500 "background-position",
12501 "background-size",
12502 "background-repeat",
12503 "background-attachment"
12504 ],
12505 percentages: [
12506 "background-position",
12507 "background-size"
12508 ],
12509 groups: [
12510 "CSS Backgrounds and Borders"
12511 ],
12512 initial: [
12513 "background-image",
12514 "background-position",
12515 "background-size",
12516 "background-repeat",
12517 "background-origin",
12518 "background-clip",
12519 "background-attachment",
12520 "background-color"
12521 ],
12522 appliesto: "allElements",
12523 computed: [
12524 "background-image",
12525 "background-position",
12526 "background-size",
12527 "background-repeat",
12528 "background-origin",
12529 "background-clip",
12530 "background-attachment",
12531 "background-color"
12532 ],
12533 order: "orderOfAppearance",
12534 alsoAppliesTo: [
12535 "::first-letter",
12536 "::first-line",
12537 "::placeholder"
12538 ],
12539 status: "standard",
12540 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/background"
12541 };
12542 var border = {
12543 syntax: "<line-width> || <line-style> || <color>",
12544 media: "visual",
12545 inherited: false,
12546 animationType: [
12547 "border-color",
12548 "border-style",
12549 "border-width"
12550 ],
12551 percentages: "no",
12552 groups: [
12553 "CSS Backgrounds and Borders"
12554 ],
12555 initial: [
12556 "border-width",
12557 "border-style",
12558 "border-color"
12559 ],
12560 appliesto: "allElements",
12561 computed: [
12562 "border-width",
12563 "border-style",
12564 "border-color"
12565 ],
12566 order: "orderOfAppearance",
12567 alsoAppliesTo: [
12568 "::first-letter"
12569 ],
12570 status: "standard",
12571 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border"
12572 };
12573 var bottom = {
12574 syntax: "<length> | <percentage> | auto",
12575 media: "visual",
12576 inherited: false,
12577 animationType: "lpc",
12578 percentages: "referToContainingBlockHeight",
12579 groups: [
12580 "CSS Positioning"
12581 ],
12582 initial: "auto",
12583 appliesto: "positionedElements",
12584 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
12585 order: "uniqueOrder",
12586 status: "standard",
12587 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/bottom"
12588 };
12589 var clear = {
12590 syntax: "none | left | right | both | inline-start | inline-end",
12591 media: "visual",
12592 inherited: false,
12593 animationType: "discrete",
12594 percentages: "no",
12595 groups: [
12596 "CSS Positioning"
12597 ],
12598 initial: "none",
12599 appliesto: "blockLevelElements",
12600 computed: "asSpecified",
12601 order: "uniqueOrder",
12602 status: "standard",
12603 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/clear"
12604 };
12605 var clip = {
12606 syntax: "<shape> | auto",
12607 media: "visual",
12608 inherited: false,
12609 animationType: "rectangle",
12610 percentages: "no",
12611 groups: [
12612 "CSS Masking"
12613 ],
12614 initial: "auto",
12615 appliesto: "absolutelyPositionedElements",
12616 computed: "autoOrRectangle",
12617 order: "uniqueOrder",
12618 status: "standard",
12619 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/clip"
12620 };
12621 var color$1 = {
12622 syntax: "<color>",
12623 media: "visual",
12624 inherited: true,
12625 animationType: "color",
12626 percentages: "no",
12627 groups: [
12628 "CSS Color"
12629 ],
12630 initial: "variesFromBrowserToBrowser",
12631 appliesto: "allElements",
12632 computed: "translucentValuesRGBAOtherwiseRGB",
12633 order: "uniqueOrder",
12634 alsoAppliesTo: [
12635 "::first-letter",
12636 "::first-line",
12637 "::placeholder"
12638 ],
12639 status: "standard",
12640 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/color"
12641 };
12642 var columns = {
12643 syntax: "<'column-width'> || <'column-count'>",
12644 media: "visual",
12645 inherited: false,
12646 animationType: [
12647 "column-width",
12648 "column-count"
12649 ],
12650 percentages: "no",
12651 groups: [
12652 "CSS Columns"
12653 ],
12654 initial: [
12655 "column-width",
12656 "column-count"
12657 ],
12658 appliesto: "blockContainersExceptTableWrappers",
12659 computed: [
12660 "column-width",
12661 "column-count"
12662 ],
12663 order: "perGrammar",
12664 status: "standard",
12665 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/columns"
12666 };
12667 var contain = {
12668 syntax: "none | strict | content | [ size || layout || style || paint ]",
12669 media: "all",
12670 inherited: false,
12671 animationType: "discrete",
12672 percentages: "no",
12673 groups: [
12674 "CSS Containment"
12675 ],
12676 initial: "none",
12677 appliesto: "allElements",
12678 computed: "asSpecified",
12679 order: "perGrammar",
12680 status: "standard",
12681 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/contain"
12682 };
12683 var content = {
12684 syntax: "normal | none | [ <content-replacement> | <content-list> ] [/ <string> ]?",
12685 media: "all",
12686 inherited: false,
12687 animationType: "discrete",
12688 percentages: "no",
12689 groups: [
12690 "CSS Generated Content"
12691 ],
12692 initial: "normal",
12693 appliesto: "beforeAndAfterPseudos",
12694 computed: "normalOnElementsForPseudosNoneAbsoluteURIStringOrAsSpecified",
12695 order: "uniqueOrder",
12696 status: "standard",
12697 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/content"
12698 };
12699 var cursor = {
12700 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 ] ]",
12701 media: [
12702 "visual",
12703 "interactive"
12704 ],
12705 inherited: true,
12706 animationType: "discrete",
12707 percentages: "no",
12708 groups: [
12709 "CSS Basic User Interface"
12710 ],
12711 initial: "auto",
12712 appliesto: "allElements",
12713 computed: "asSpecifiedURLsAbsolute",
12714 order: "uniqueOrder",
12715 status: "standard",
12716 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/cursor"
12717 };
12718 var direction = {
12719 syntax: "ltr | rtl",
12720 media: "visual",
12721 inherited: true,
12722 animationType: "discrete",
12723 percentages: "no",
12724 groups: [
12725 "CSS Writing Modes"
12726 ],
12727 initial: "ltr",
12728 appliesto: "allElements",
12729 computed: "asSpecified",
12730 order: "uniqueOrder",
12731 status: "standard",
12732 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/direction"
12733 };
12734 var display = {
12735 syntax: "[ <display-outside> || <display-inside> ] | <display-listitem> | <display-internal> | <display-box> | <display-legacy>",
12736 media: "all",
12737 inherited: false,
12738 animationType: "discrete",
12739 percentages: "no",
12740 groups: [
12741 "CSS Display"
12742 ],
12743 initial: "inline",
12744 appliesto: "allElements",
12745 computed: "asSpecifiedExceptPositionedFloatingAndRootElementsKeywordMaybeDifferent",
12746 order: "uniqueOrder",
12747 status: "standard",
12748 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/display"
12749 };
12750 var filter = {
12751 syntax: "none | <filter-function-list>",
12752 media: "visual",
12753 inherited: false,
12754 animationType: "filterList",
12755 percentages: "no",
12756 groups: [
12757 "Filter Effects"
12758 ],
12759 initial: "none",
12760 appliesto: "allElementsSVGContainerElements",
12761 computed: "asSpecified",
12762 order: "uniqueOrder",
12763 status: "standard",
12764 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/filter"
12765 };
12766 var flex = {
12767 syntax: "none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]",
12768 media: "visual",
12769 inherited: false,
12770 animationType: [
12771 "flex-grow",
12772 "flex-shrink",
12773 "flex-basis"
12774 ],
12775 percentages: "no",
12776 groups: [
12777 "CSS Flexible Box Layout"
12778 ],
12779 initial: [
12780 "flex-grow",
12781 "flex-shrink",
12782 "flex-basis"
12783 ],
12784 appliesto: "flexItemsAndInFlowPseudos",
12785 computed: [
12786 "flex-grow",
12787 "flex-shrink",
12788 "flex-basis"
12789 ],
12790 order: "orderOfAppearance",
12791 status: "standard",
12792 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/flex"
12793 };
12794 var float = {
12795 syntax: "left | right | none | inline-start | inline-end",
12796 media: "visual",
12797 inherited: false,
12798 animationType: "discrete",
12799 percentages: "no",
12800 groups: [
12801 "CSS Positioning"
12802 ],
12803 initial: "none",
12804 appliesto: "allElementsNoEffectIfDisplayNone",
12805 computed: "asSpecified",
12806 order: "uniqueOrder",
12807 status: "standard",
12808 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/float"
12809 };
12810 var font = {
12811 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",
12812 media: "visual",
12813 inherited: true,
12814 animationType: [
12815 "font-style",
12816 "font-variant",
12817 "font-weight",
12818 "font-stretch",
12819 "font-size",
12820 "line-height",
12821 "font-family"
12822 ],
12823 percentages: [
12824 "font-size",
12825 "line-height"
12826 ],
12827 groups: [
12828 "CSS Fonts"
12829 ],
12830 initial: [
12831 "font-style",
12832 "font-variant",
12833 "font-weight",
12834 "font-stretch",
12835 "font-size",
12836 "line-height",
12837 "font-family"
12838 ],
12839 appliesto: "allElements",
12840 computed: [
12841 "font-style",
12842 "font-variant",
12843 "font-weight",
12844 "font-stretch",
12845 "font-size",
12846 "line-height",
12847 "font-family"
12848 ],
12849 order: "orderOfAppearance",
12850 alsoAppliesTo: [
12851 "::first-letter",
12852 "::first-line",
12853 "::placeholder"
12854 ],
12855 status: "standard",
12856 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font"
12857 };
12858 var gap = {
12859 syntax: "<'row-gap'> <'column-gap'>?",
12860 media: "visual",
12861 inherited: false,
12862 animationType: [
12863 "row-gap",
12864 "column-gap"
12865 ],
12866 percentages: "no",
12867 groups: [
12868 "CSS Box Alignment"
12869 ],
12870 initial: [
12871 "row-gap",
12872 "column-gap"
12873 ],
12874 appliesto: "multiColumnElementsFlexContainersGridContainers",
12875 computed: [
12876 "row-gap",
12877 "column-gap"
12878 ],
12879 order: "uniqueOrder",
12880 status: "standard",
12881 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/gap"
12882 };
12883 var grid = {
12884 syntax: "<'grid-template'> | <'grid-template-rows'> / [ auto-flow && dense? ] <'grid-auto-columns'>? | [ auto-flow && dense? ] <'grid-auto-rows'>? / <'grid-template-columns'>",
12885 media: "visual",
12886 inherited: false,
12887 animationType: "discrete",
12888 percentages: [
12889 "grid-template-rows",
12890 "grid-template-columns",
12891 "grid-auto-rows",
12892 "grid-auto-columns"
12893 ],
12894 groups: [
12895 "CSS Grid Layout"
12896 ],
12897 initial: [
12898 "grid-template-rows",
12899 "grid-template-columns",
12900 "grid-template-areas",
12901 "grid-auto-rows",
12902 "grid-auto-columns",
12903 "grid-auto-flow",
12904 "grid-column-gap",
12905 "grid-row-gap",
12906 "column-gap",
12907 "row-gap"
12908 ],
12909 appliesto: "gridContainers",
12910 computed: [
12911 "grid-template-rows",
12912 "grid-template-columns",
12913 "grid-template-areas",
12914 "grid-auto-rows",
12915 "grid-auto-columns",
12916 "grid-auto-flow",
12917 "grid-column-gap",
12918 "grid-row-gap",
12919 "column-gap",
12920 "row-gap"
12921 ],
12922 order: "uniqueOrder",
12923 status: "standard",
12924 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid"
12925 };
12926 var height = {
12927 syntax: "auto | <length> | <percentage> | min-content | max-content | fit-content(<length-percentage>)",
12928 media: "visual",
12929 inherited: false,
12930 animationType: "lpc",
12931 percentages: "regardingHeightOfGeneratedBoxContainingBlockPercentagesRelativeToContainingBlock",
12932 groups: [
12933 "CSS Box Model"
12934 ],
12935 initial: "auto",
12936 appliesto: "allElementsButNonReplacedAndTableColumns",
12937 computed: "percentageAutoOrAbsoluteLength",
12938 order: "uniqueOrder",
12939 status: "standard",
12940 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/height"
12941 };
12942 var hyphens = {
12943 syntax: "none | manual | auto",
12944 media: "visual",
12945 inherited: true,
12946 animationType: "discrete",
12947 percentages: "no",
12948 groups: [
12949 "CSS Text"
12950 ],
12951 initial: "manual",
12952 appliesto: "allElements",
12953 computed: "asSpecified",
12954 order: "uniqueOrder",
12955 status: "standard",
12956 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/hyphens"
12957 };
12958 var inset = {
12959 syntax: "<'top'>{1,4}",
12960 media: "visual",
12961 inherited: false,
12962 animationType: "lpc",
12963 percentages: "logicalHeightOfContainingBlock",
12964 groups: [
12965 "CSS Logical Properties"
12966 ],
12967 initial: "auto",
12968 appliesto: "positionedElements",
12969 computed: "sameAsBoxOffsets",
12970 order: "uniqueOrder",
12971 status: "standard",
12972 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/inset"
12973 };
12974 var isolation = {
12975 syntax: "auto | isolate",
12976 media: "visual",
12977 inherited: false,
12978 animationType: "discrete",
12979 percentages: "no",
12980 groups: [
12981 "Compositing and Blending"
12982 ],
12983 initial: "auto",
12984 appliesto: "allElementsSVGContainerGraphicsAndGraphicsReferencingElements",
12985 computed: "asSpecified",
12986 order: "uniqueOrder",
12987 status: "standard",
12988 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/isolation"
12989 };
12990 var left = {
12991 syntax: "<length> | <percentage> | auto",
12992 media: "visual",
12993 inherited: false,
12994 animationType: "lpc",
12995 percentages: "referToWidthOfContainingBlock",
12996 groups: [
12997 "CSS Positioning"
12998 ],
12999 initial: "auto",
13000 appliesto: "positionedElements",
13001 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
13002 order: "uniqueOrder",
13003 status: "standard",
13004 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/left"
13005 };
13006 var margin = {
13007 syntax: "[ <length> | <percentage> | auto ]{1,4}",
13008 media: "visual",
13009 inherited: false,
13010 animationType: "length",
13011 percentages: "referToWidthOfContainingBlock",
13012 groups: [
13013 "CSS Box Model"
13014 ],
13015 initial: [
13016 "margin-bottom",
13017 "margin-left",
13018 "margin-right",
13019 "margin-top"
13020 ],
13021 appliesto: "allElementsExceptTableDisplayTypes",
13022 computed: [
13023 "margin-bottom",
13024 "margin-left",
13025 "margin-right",
13026 "margin-top"
13027 ],
13028 order: "uniqueOrder",
13029 alsoAppliesTo: [
13030 "::first-letter",
13031 "::first-line"
13032 ],
13033 status: "standard",
13034 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/margin"
13035 };
13036 var mask = {
13037 syntax: "<mask-layer>#",
13038 media: "visual",
13039 inherited: false,
13040 animationType: [
13041 "mask-image",
13042 "mask-mode",
13043 "mask-repeat",
13044 "mask-position",
13045 "mask-clip",
13046 "mask-origin",
13047 "mask-size",
13048 "mask-composite"
13049 ],
13050 percentages: [
13051 "mask-position"
13052 ],
13053 groups: [
13054 "CSS Masking"
13055 ],
13056 initial: [
13057 "mask-image",
13058 "mask-mode",
13059 "mask-repeat",
13060 "mask-position",
13061 "mask-clip",
13062 "mask-origin",
13063 "mask-size",
13064 "mask-composite"
13065 ],
13066 appliesto: "allElementsSVGContainerElements",
13067 computed: [
13068 "mask-image",
13069 "mask-mode",
13070 "mask-repeat",
13071 "mask-position",
13072 "mask-clip",
13073 "mask-origin",
13074 "mask-size",
13075 "mask-composite"
13076 ],
13077 order: "perGrammar",
13078 stacking: true,
13079 status: "standard",
13080 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask"
13081 };
13082 var offset = {
13083 syntax: "[ <'offset-position'>? [ <'offset-path'> [ <'offset-distance'> || <'offset-rotate'> ]? ]? ]! [ / <'offset-anchor'> ]?",
13084 media: "visual",
13085 inherited: false,
13086 animationType: [
13087 "offset-position",
13088 "offset-path",
13089 "offset-distance",
13090 "offset-anchor",
13091 "offset-rotate"
13092 ],
13093 percentages: [
13094 "offset-position",
13095 "offset-distance",
13096 "offset-anchor"
13097 ],
13098 groups: [
13099 "CSS Motion Path"
13100 ],
13101 initial: [
13102 "offset-position",
13103 "offset-path",
13104 "offset-distance",
13105 "offset-anchor",
13106 "offset-rotate"
13107 ],
13108 appliesto: "transformableElements",
13109 computed: [
13110 "offset-position",
13111 "offset-path",
13112 "offset-distance",
13113 "offset-anchor",
13114 "offset-rotate"
13115 ],
13116 order: "perGrammar",
13117 stacking: true,
13118 status: "standard",
13119 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/offset"
13120 };
13121 var opacity = {
13122 syntax: "<alpha-value>",
13123 media: "visual",
13124 inherited: false,
13125 animationType: "number",
13126 percentages: "no",
13127 groups: [
13128 "CSS Color"
13129 ],
13130 initial: "1.0",
13131 appliesto: "allElements",
13132 computed: "specifiedValueClipped0To1",
13133 order: "uniqueOrder",
13134 alsoAppliesTo: [
13135 "::placeholder"
13136 ],
13137 status: "standard",
13138 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/opacity"
13139 };
13140 var order = {
13141 syntax: "<integer>",
13142 media: "visual",
13143 inherited: false,
13144 animationType: "integer",
13145 percentages: "no",
13146 groups: [
13147 "CSS Flexible Box Layout"
13148 ],
13149 initial: "0",
13150 appliesto: "flexItemsGridItemsAbsolutelyPositionedContainerChildren",
13151 computed: "asSpecified",
13152 order: "uniqueOrder",
13153 status: "standard",
13154 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/order"
13155 };
13156 var orphans = {
13157 syntax: "<integer>",
13158 media: "visual",
13159 inherited: true,
13160 animationType: "discrete",
13161 percentages: "no",
13162 groups: [
13163 "CSS Fragmentation"
13164 ],
13165 initial: "2",
13166 appliesto: "blockContainerElements",
13167 computed: "asSpecified",
13168 order: "perGrammar",
13169 status: "standard",
13170 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/orphans"
13171 };
13172 var outline = {
13173 syntax: "[ <'outline-color'> || <'outline-style'> || <'outline-width'> ]",
13174 media: [
13175 "visual",
13176 "interactive"
13177 ],
13178 inherited: false,
13179 animationType: [
13180 "outline-color",
13181 "outline-width",
13182 "outline-style"
13183 ],
13184 percentages: "no",
13185 groups: [
13186 "CSS Basic User Interface"
13187 ],
13188 initial: [
13189 "outline-color",
13190 "outline-style",
13191 "outline-width"
13192 ],
13193 appliesto: "allElements",
13194 computed: [
13195 "outline-color",
13196 "outline-width",
13197 "outline-style"
13198 ],
13199 order: "orderOfAppearance",
13200 status: "standard",
13201 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/outline"
13202 };
13203 var overflow = {
13204 syntax: "[ visible | hidden | clip | scroll | auto ]{1,2}",
13205 media: "visual",
13206 inherited: false,
13207 animationType: "discrete",
13208 percentages: "no",
13209 groups: [
13210 "CSS Overflow"
13211 ],
13212 initial: "visible",
13213 appliesto: "blockContainersFlexContainersGridContainers",
13214 computed: [
13215 "overflow-x",
13216 "overflow-y"
13217 ],
13218 order: "uniqueOrder",
13219 status: "standard",
13220 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/overflow"
13221 };
13222 var padding = {
13223 syntax: "[ <length> | <percentage> ]{1,4}",
13224 media: "visual",
13225 inherited: false,
13226 animationType: "length",
13227 percentages: "referToWidthOfContainingBlock",
13228 groups: [
13229 "CSS Box Model"
13230 ],
13231 initial: [
13232 "padding-bottom",
13233 "padding-left",
13234 "padding-right",
13235 "padding-top"
13236 ],
13237 appliesto: "allElementsExceptInternalTableDisplayTypes",
13238 computed: [
13239 "padding-bottom",
13240 "padding-left",
13241 "padding-right",
13242 "padding-top"
13243 ],
13244 order: "uniqueOrder",
13245 alsoAppliesTo: [
13246 "::first-letter",
13247 "::first-line"
13248 ],
13249 status: "standard",
13250 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/padding"
13251 };
13252 var perspective = {
13253 syntax: "none | <length>",
13254 media: "visual",
13255 inherited: false,
13256 animationType: "length",
13257 percentages: "no",
13258 groups: [
13259 "CSS Transforms"
13260 ],
13261 initial: "none",
13262 appliesto: "transformableElements",
13263 computed: "absoluteLengthOrNone",
13264 order: "uniqueOrder",
13265 stacking: true,
13266 status: "standard",
13267 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/perspective"
13268 };
13269 var position$1 = {
13270 syntax: "static | relative | absolute | sticky | fixed",
13271 media: "visual",
13272 inherited: false,
13273 animationType: "discrete",
13274 percentages: "no",
13275 groups: [
13276 "CSS Positioning"
13277 ],
13278 initial: "static",
13279 appliesto: "allElements",
13280 computed: "asSpecified",
13281 order: "uniqueOrder",
13282 stacking: true,
13283 status: "standard",
13284 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/position"
13285 };
13286 var quotes = {
13287 syntax: "none | auto | [ <string> <string> ]+",
13288 media: "visual",
13289 inherited: true,
13290 animationType: "discrete",
13291 percentages: "no",
13292 groups: [
13293 "CSS Generated Content"
13294 ],
13295 initial: "dependsOnUserAgent",
13296 appliesto: "allElements",
13297 computed: "asSpecified",
13298 order: "uniqueOrder",
13299 status: "standard",
13300 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/quotes"
13301 };
13302 var resize = {
13303 syntax: "none | both | horizontal | vertical | block | inline",
13304 media: "visual",
13305 inherited: false,
13306 animationType: "discrete",
13307 percentages: "no",
13308 groups: [
13309 "CSS Basic User Interface"
13310 ],
13311 initial: "none",
13312 appliesto: "elementsWithOverflowNotVisibleAndReplacedElements",
13313 computed: "asSpecified",
13314 order: "uniqueOrder",
13315 status: "standard",
13316 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/resize"
13317 };
13318 var right = {
13319 syntax: "<length> | <percentage> | auto",
13320 media: "visual",
13321 inherited: false,
13322 animationType: "lpc",
13323 percentages: "referToWidthOfContainingBlock",
13324 groups: [
13325 "CSS Positioning"
13326 ],
13327 initial: "auto",
13328 appliesto: "positionedElements",
13329 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
13330 order: "uniqueOrder",
13331 status: "standard",
13332 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/right"
13333 };
13334 var rotate = {
13335 syntax: "none | <angle> | [ x | y | z | <number>{3} ] && <angle>",
13336 media: "visual",
13337 inherited: false,
13338 animationType: "transform",
13339 percentages: "no",
13340 groups: [
13341 "CSS Transforms"
13342 ],
13343 initial: "none",
13344 appliesto: "transformableElements",
13345 computed: "asSpecified",
13346 order: "perGrammar",
13347 stacking: true,
13348 status: "standard",
13349 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/rotate"
13350 };
13351 var scale = {
13352 syntax: "none | <number>{1,3}",
13353 media: "visual",
13354 inherited: false,
13355 animationType: "transform",
13356 percentages: "no",
13357 groups: [
13358 "CSS Transforms"
13359 ],
13360 initial: "none",
13361 appliesto: "transformableElements",
13362 computed: "asSpecified",
13363 order: "perGrammar",
13364 stacking: true,
13365 status: "standard",
13366 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scale"
13367 };
13368 var top = {
13369 syntax: "<length> | <percentage> | auto",
13370 media: "visual",
13371 inherited: false,
13372 animationType: "lpc",
13373 percentages: "referToContainingBlockHeight",
13374 groups: [
13375 "CSS Positioning"
13376 ],
13377 initial: "auto",
13378 appliesto: "positionedElements",
13379 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
13380 order: "uniqueOrder",
13381 status: "standard",
13382 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/top"
13383 };
13384 var transform = {
13385 syntax: "none | <transform-list>",
13386 media: "visual",
13387 inherited: false,
13388 animationType: "transform",
13389 percentages: "referToSizeOfBoundingBox",
13390 groups: [
13391 "CSS Transforms"
13392 ],
13393 initial: "none",
13394 appliesto: "transformableElements",
13395 computed: "asSpecifiedRelativeToAbsoluteLengths",
13396 order: "uniqueOrder",
13397 stacking: true,
13398 status: "standard",
13399 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/transform"
13400 };
13401 var transition = {
13402 syntax: "<single-transition>#",
13403 media: "interactive",
13404 inherited: false,
13405 animationType: "discrete",
13406 percentages: "no",
13407 groups: [
13408 "CSS Transitions"
13409 ],
13410 initial: [
13411 "transition-delay",
13412 "transition-duration",
13413 "transition-property",
13414 "transition-timing-function"
13415 ],
13416 appliesto: "allElementsAndPseudos",
13417 computed: [
13418 "transition-delay",
13419 "transition-duration",
13420 "transition-property",
13421 "transition-timing-function"
13422 ],
13423 order: "orderOfAppearance",
13424 status: "standard",
13425 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/transition"
13426 };
13427 var translate = {
13428 syntax: "none | <length-percentage> [ <length-percentage> <length>? ]?",
13429 media: "visual",
13430 inherited: false,
13431 animationType: "transform",
13432 percentages: "referToSizeOfBoundingBox",
13433 groups: [
13434 "CSS Transforms"
13435 ],
13436 initial: "none",
13437 appliesto: "transformableElements",
13438 computed: "asSpecifiedRelativeToAbsoluteLengths",
13439 order: "perGrammar",
13440 stacking: true,
13441 status: "standard",
13442 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/translate"
13443 };
13444 var visibility = {
13445 syntax: "visible | hidden | collapse",
13446 media: "visual",
13447 inherited: true,
13448 animationType: "visibility",
13449 percentages: "no",
13450 groups: [
13451 "CSS Box Model"
13452 ],
13453 initial: "visible",
13454 appliesto: "allElements",
13455 computed: "asSpecified",
13456 order: "uniqueOrder",
13457 status: "standard",
13458 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/visibility"
13459 };
13460 var widows = {
13461 syntax: "<integer>",
13462 media: "visual",
13463 inherited: true,
13464 animationType: "discrete",
13465 percentages: "no",
13466 groups: [
13467 "CSS Fragmentation"
13468 ],
13469 initial: "2",
13470 appliesto: "blockContainerElements",
13471 computed: "asSpecified",
13472 order: "perGrammar",
13473 status: "standard",
13474 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/widows"
13475 };
13476 var width = {
13477 syntax: "auto | <length> | <percentage> | min-content | max-content | fit-content(<length-percentage>)",
13478 media: "visual",
13479 inherited: false,
13480 animationType: "lpc",
13481 percentages: "referToWidthOfContainingBlock",
13482 groups: [
13483 "CSS Box Model"
13484 ],
13485 initial: "auto",
13486 appliesto: "allElementsButNonReplacedAndTableRows",
13487 computed: "percentageAutoOrAbsoluteLength",
13488 order: "lengthOrPercentageBeforeKeywordIfBothPresent",
13489 status: "standard",
13490 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/width"
13491 };
13492 var zoom = {
13493 syntax: "normal | reset | <number> | <percentage>",
13494 media: "visual",
13495 inherited: false,
13496 animationType: "integer",
13497 percentages: "no",
13498 groups: [
13499 "Microsoft Extensions"
13500 ],
13501 initial: "normal",
13502 appliesto: "allElements",
13503 computed: "asSpecified",
13504 order: "uniqueOrder",
13505 status: "nonstandard",
13506 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/zoom"
13507 };
13508 var require$$1 = {
13509 "--*": {
13510 syntax: "<declaration-value>",
13511 media: "all",
13512 inherited: true,
13513 animationType: "discrete",
13514 percentages: "no",
13515 groups: [
13516 "CSS Variables"
13517 ],
13518 initial: "seeProse",
13519 appliesto: "allElements",
13520 computed: "asSpecifiedWithVarsSubstituted",
13521 order: "perGrammar",
13522 status: "experimental",
13523 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/--*"
13524 },
13525 "-ms-accelerator": {
13526 syntax: "false | true",
13527 media: "visual",
13528 inherited: false,
13529 animationType: "discrete",
13530 percentages: "no",
13531 groups: [
13532 "Microsoft Extensions"
13533 ],
13534 initial: "false",
13535 appliesto: "allElements",
13536 computed: "asSpecified",
13537 order: "uniqueOrder",
13538 status: "nonstandard",
13539 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-accelerator"
13540 },
13541 "-ms-block-progression": {
13542 syntax: "tb | rl | bt | lr",
13543 media: "visual",
13544 inherited: false,
13545 animationType: "discrete",
13546 percentages: "no",
13547 groups: [
13548 "Microsoft Extensions"
13549 ],
13550 initial: "tb",
13551 appliesto: "allElements",
13552 computed: "asSpecified",
13553 order: "uniqueOrder",
13554 status: "nonstandard",
13555 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-block-progression"
13556 },
13557 "-ms-content-zoom-chaining": {
13558 syntax: "none | chained",
13559 media: "interactive",
13560 inherited: false,
13561 animationType: "discrete",
13562 percentages: "no",
13563 groups: [
13564 "Microsoft Extensions"
13565 ],
13566 initial: "none",
13567 appliesto: "nonReplacedBlockAndInlineBlockElements",
13568 computed: "asSpecified",
13569 order: "uniqueOrder",
13570 status: "nonstandard",
13571 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-content-zoom-chaining"
13572 },
13573 "-ms-content-zooming": {
13574 syntax: "none | zoom",
13575 media: "interactive",
13576 inherited: false,
13577 animationType: "discrete",
13578 percentages: "no",
13579 groups: [
13580 "Microsoft Extensions"
13581 ],
13582 initial: "zoomForTheTopLevelNoneForTheRest",
13583 appliesto: "nonReplacedBlockAndInlineBlockElements",
13584 computed: "asSpecified",
13585 order: "uniqueOrder",
13586 status: "nonstandard",
13587 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-content-zooming"
13588 },
13589 "-ms-content-zoom-limit": {
13590 syntax: "<'-ms-content-zoom-limit-min'> <'-ms-content-zoom-limit-max'>",
13591 media: "interactive",
13592 inherited: false,
13593 animationType: "discrete",
13594 percentages: [
13595 "-ms-content-zoom-limit-max",
13596 "-ms-content-zoom-limit-min"
13597 ],
13598 groups: [
13599 "Microsoft Extensions"
13600 ],
13601 initial: [
13602 "-ms-content-zoom-limit-max",
13603 "-ms-content-zoom-limit-min"
13604 ],
13605 appliesto: "nonReplacedBlockAndInlineBlockElements",
13606 computed: [
13607 "-ms-content-zoom-limit-max",
13608 "-ms-content-zoom-limit-min"
13609 ],
13610 order: "uniqueOrder",
13611 status: "nonstandard",
13612 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-content-zoom-limit"
13613 },
13614 "-ms-content-zoom-limit-max": {
13615 syntax: "<percentage>",
13616 media: "interactive",
13617 inherited: false,
13618 animationType: "discrete",
13619 percentages: "maxZoomFactor",
13620 groups: [
13621 "Microsoft Extensions"
13622 ],
13623 initial: "400%",
13624 appliesto: "nonReplacedBlockAndInlineBlockElements",
13625 computed: "asSpecified",
13626 order: "uniqueOrder",
13627 status: "nonstandard",
13628 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-content-zoom-limit-max"
13629 },
13630 "-ms-content-zoom-limit-min": {
13631 syntax: "<percentage>",
13632 media: "interactive",
13633 inherited: false,
13634 animationType: "discrete",
13635 percentages: "minZoomFactor",
13636 groups: [
13637 "Microsoft Extensions"
13638 ],
13639 initial: "100%",
13640 appliesto: "nonReplacedBlockAndInlineBlockElements",
13641 computed: "asSpecified",
13642 order: "uniqueOrder",
13643 status: "nonstandard",
13644 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-content-zoom-limit-min"
13645 },
13646 "-ms-content-zoom-snap": {
13647 syntax: "<'-ms-content-zoom-snap-type'> || <'-ms-content-zoom-snap-points'>",
13648 media: "interactive",
13649 inherited: false,
13650 animationType: "discrete",
13651 percentages: "no",
13652 groups: [
13653 "Microsoft Extensions"
13654 ],
13655 initial: [
13656 "-ms-content-zoom-snap-type",
13657 "-ms-content-zoom-snap-points"
13658 ],
13659 appliesto: "nonReplacedBlockAndInlineBlockElements",
13660 computed: [
13661 "-ms-content-zoom-snap-type",
13662 "-ms-content-zoom-snap-points"
13663 ],
13664 order: "uniqueOrder",
13665 status: "nonstandard",
13666 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-content-zoom-snap"
13667 },
13668 "-ms-content-zoom-snap-points": {
13669 syntax: "snapInterval( <percentage>, <percentage> ) | snapList( <percentage># )",
13670 media: "interactive",
13671 inherited: false,
13672 animationType: "discrete",
13673 percentages: "no",
13674 groups: [
13675 "Microsoft Extensions"
13676 ],
13677 initial: "snapInterval(0%, 100%)",
13678 appliesto: "nonReplacedBlockAndInlineBlockElements",
13679 computed: "asSpecified",
13680 order: "uniqueOrder",
13681 status: "nonstandard",
13682 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-content-zoom-snap-points"
13683 },
13684 "-ms-content-zoom-snap-type": {
13685 syntax: "none | proximity | mandatory",
13686 media: "interactive",
13687 inherited: false,
13688 animationType: "discrete",
13689 percentages: "no",
13690 groups: [
13691 "Microsoft Extensions"
13692 ],
13693 initial: "none",
13694 appliesto: "nonReplacedBlockAndInlineBlockElements",
13695 computed: "asSpecified",
13696 order: "uniqueOrder",
13697 status: "nonstandard",
13698 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-content-zoom-snap-type"
13699 },
13700 "-ms-filter": {
13701 syntax: "<string>",
13702 media: "visual",
13703 inherited: false,
13704 animationType: "discrete",
13705 percentages: "no",
13706 groups: [
13707 "Microsoft Extensions"
13708 ],
13709 initial: "\"\"",
13710 appliesto: "allElements",
13711 computed: "asSpecified",
13712 order: "uniqueOrder",
13713 status: "nonstandard",
13714 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-filter"
13715 },
13716 "-ms-flow-from": {
13717 syntax: "[ none | <custom-ident> ]#",
13718 media: "visual",
13719 inherited: false,
13720 animationType: "discrete",
13721 percentages: "no",
13722 groups: [
13723 "Microsoft Extensions"
13724 ],
13725 initial: "none",
13726 appliesto: "nonReplacedElements",
13727 computed: "asSpecified",
13728 order: "uniqueOrder",
13729 status: "nonstandard",
13730 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-flow-from"
13731 },
13732 "-ms-flow-into": {
13733 syntax: "[ none | <custom-ident> ]#",
13734 media: "visual",
13735 inherited: false,
13736 animationType: "discrete",
13737 percentages: "no",
13738 groups: [
13739 "Microsoft Extensions"
13740 ],
13741 initial: "none",
13742 appliesto: "iframeElements",
13743 computed: "asSpecified",
13744 order: "uniqueOrder",
13745 status: "nonstandard",
13746 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-flow-into"
13747 },
13748 "-ms-grid-columns": {
13749 syntax: "none | <track-list> | <auto-track-list>",
13750 media: "visual",
13751 inherited: false,
13752 animationType: "simpleListOfLpcDifferenceLpc",
13753 percentages: "referToDimensionOfContentArea",
13754 groups: [
13755 "CSS Grid Layout"
13756 ],
13757 initial: "none",
13758 appliesto: "gridContainers",
13759 computed: "asSpecifiedRelativeToAbsoluteLengths",
13760 order: "uniqueOrder",
13761 status: "nonstandard",
13762 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-grid-columns"
13763 },
13764 "-ms-grid-rows": {
13765 syntax: "none | <track-list> | <auto-track-list>",
13766 media: "visual",
13767 inherited: false,
13768 animationType: "simpleListOfLpcDifferenceLpc",
13769 percentages: "referToDimensionOfContentArea",
13770 groups: [
13771 "CSS Grid Layout"
13772 ],
13773 initial: "none",
13774 appliesto: "gridContainers",
13775 computed: "asSpecifiedRelativeToAbsoluteLengths",
13776 order: "uniqueOrder",
13777 status: "nonstandard",
13778 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-grid-rows"
13779 },
13780 "-ms-high-contrast-adjust": {
13781 syntax: "auto | none",
13782 media: "visual",
13783 inherited: true,
13784 animationType: "discrete",
13785 percentages: "no",
13786 groups: [
13787 "Microsoft Extensions"
13788 ],
13789 initial: "auto",
13790 appliesto: "allElements",
13791 computed: "asSpecified",
13792 order: "uniqueOrder",
13793 status: "nonstandard",
13794 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-high-contrast-adjust"
13795 },
13796 "-ms-hyphenate-limit-chars": {
13797 syntax: "auto | <integer>{1,3}",
13798 media: "visual",
13799 inherited: true,
13800 animationType: "discrete",
13801 percentages: "no",
13802 groups: [
13803 "Microsoft Extensions"
13804 ],
13805 initial: "auto",
13806 appliesto: "allElements",
13807 computed: "asSpecified",
13808 order: "uniqueOrder",
13809 status: "nonstandard",
13810 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-hyphenate-limit-chars"
13811 },
13812 "-ms-hyphenate-limit-lines": {
13813 syntax: "no-limit | <integer>",
13814 media: "visual",
13815 inherited: true,
13816 animationType: "discrete",
13817 percentages: "no",
13818 groups: [
13819 "Microsoft Extensions"
13820 ],
13821 initial: "no-limit",
13822 appliesto: "blockContainerElements",
13823 computed: "asSpecified",
13824 order: "uniqueOrder",
13825 status: "nonstandard",
13826 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-hyphenate-limit-lines"
13827 },
13828 "-ms-hyphenate-limit-zone": {
13829 syntax: "<percentage> | <length>",
13830 media: "visual",
13831 inherited: true,
13832 animationType: "discrete",
13833 percentages: "referToLineBoxWidth",
13834 groups: [
13835 "Microsoft Extensions"
13836 ],
13837 initial: "0",
13838 appliesto: "blockContainerElements",
13839 computed: "asSpecified",
13840 order: "uniqueOrder",
13841 status: "nonstandard",
13842 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-hyphenate-limit-zone"
13843 },
13844 "-ms-ime-align": {
13845 syntax: "auto | after",
13846 media: "visual",
13847 inherited: false,
13848 animationType: "discrete",
13849 percentages: "no",
13850 groups: [
13851 "Microsoft Extensions"
13852 ],
13853 initial: "auto",
13854 appliesto: "allElements",
13855 computed: "asSpecified",
13856 order: "uniqueOrder",
13857 status: "nonstandard",
13858 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-ime-align"
13859 },
13860 "-ms-overflow-style": {
13861 syntax: "auto | none | scrollbar | -ms-autohiding-scrollbar",
13862 media: "interactive",
13863 inherited: true,
13864 animationType: "discrete",
13865 percentages: "no",
13866 groups: [
13867 "Microsoft Extensions"
13868 ],
13869 initial: "auto",
13870 appliesto: "nonReplacedBlockAndInlineBlockElements",
13871 computed: "asSpecified",
13872 order: "uniqueOrder",
13873 status: "nonstandard",
13874 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-overflow-style"
13875 },
13876 "-ms-scrollbar-3dlight-color": {
13877 syntax: "<color>",
13878 media: "visual",
13879 inherited: true,
13880 animationType: "discrete",
13881 percentages: "no",
13882 groups: [
13883 "Microsoft Extensions"
13884 ],
13885 initial: "dependsOnUserAgent",
13886 appliesto: "allElements",
13887 computed: "asSpecified",
13888 order: "uniqueOrder",
13889 status: "nonstandard",
13890 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scrollbar-3dlight-color"
13891 },
13892 "-ms-scrollbar-arrow-color": {
13893 syntax: "<color>",
13894 media: "visual",
13895 inherited: true,
13896 animationType: "discrete",
13897 percentages: "no",
13898 groups: [
13899 "Microsoft Extensions"
13900 ],
13901 initial: "ButtonText",
13902 appliesto: "allElements",
13903 computed: "asSpecified",
13904 order: "uniqueOrder",
13905 status: "nonstandard",
13906 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scrollbar-arrow-color"
13907 },
13908 "-ms-scrollbar-base-color": {
13909 syntax: "<color>",
13910 media: "visual",
13911 inherited: true,
13912 animationType: "discrete",
13913 percentages: "no",
13914 groups: [
13915 "Microsoft Extensions"
13916 ],
13917 initial: "dependsOnUserAgent",
13918 appliesto: "allElements",
13919 computed: "asSpecified",
13920 order: "uniqueOrder",
13921 status: "nonstandard",
13922 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scrollbar-base-color"
13923 },
13924 "-ms-scrollbar-darkshadow-color": {
13925 syntax: "<color>",
13926 media: "visual",
13927 inherited: true,
13928 animationType: "discrete",
13929 percentages: "no",
13930 groups: [
13931 "Microsoft Extensions"
13932 ],
13933 initial: "ThreeDDarkShadow",
13934 appliesto: "allElements",
13935 computed: "asSpecified",
13936 order: "uniqueOrder",
13937 status: "nonstandard",
13938 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scrollbar-darkshadow-color"
13939 },
13940 "-ms-scrollbar-face-color": {
13941 syntax: "<color>",
13942 media: "visual",
13943 inherited: true,
13944 animationType: "discrete",
13945 percentages: "no",
13946 groups: [
13947 "Microsoft Extensions"
13948 ],
13949 initial: "ThreeDFace",
13950 appliesto: "allElements",
13951 computed: "asSpecified",
13952 order: "uniqueOrder",
13953 status: "nonstandard",
13954 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scrollbar-face-color"
13955 },
13956 "-ms-scrollbar-highlight-color": {
13957 syntax: "<color>",
13958 media: "visual",
13959 inherited: true,
13960 animationType: "discrete",
13961 percentages: "no",
13962 groups: [
13963 "Microsoft Extensions"
13964 ],
13965 initial: "ThreeDHighlight",
13966 appliesto: "allElements",
13967 computed: "asSpecified",
13968 order: "uniqueOrder",
13969 status: "nonstandard",
13970 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scrollbar-highlight-color"
13971 },
13972 "-ms-scrollbar-shadow-color": {
13973 syntax: "<color>",
13974 media: "visual",
13975 inherited: true,
13976 animationType: "discrete",
13977 percentages: "no",
13978 groups: [
13979 "Microsoft Extensions"
13980 ],
13981 initial: "ThreeDDarkShadow",
13982 appliesto: "allElements",
13983 computed: "asSpecified",
13984 order: "uniqueOrder",
13985 status: "nonstandard",
13986 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scrollbar-shadow-color"
13987 },
13988 "-ms-scrollbar-track-color": {
13989 syntax: "<color>",
13990 media: "visual",
13991 inherited: true,
13992 animationType: "discrete",
13993 percentages: "no",
13994 groups: [
13995 "Microsoft Extensions"
13996 ],
13997 initial: "Scrollbar",
13998 appliesto: "allElements",
13999 computed: "asSpecified",
14000 order: "uniqueOrder",
14001 status: "nonstandard",
14002 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scrollbar-track-color"
14003 },
14004 "-ms-scroll-chaining": {
14005 syntax: "chained | none",
14006 media: "interactive",
14007 inherited: false,
14008 animationType: "discrete",
14009 percentages: "no",
14010 groups: [
14011 "Microsoft Extensions"
14012 ],
14013 initial: "chained",
14014 appliesto: "nonReplacedBlockAndInlineBlockElements",
14015 computed: "asSpecified",
14016 order: "uniqueOrder",
14017 status: "nonstandard",
14018 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scroll-chaining"
14019 },
14020 "-ms-scroll-limit": {
14021 syntax: "<'-ms-scroll-limit-x-min'> <'-ms-scroll-limit-y-min'> <'-ms-scroll-limit-x-max'> <'-ms-scroll-limit-y-max'>",
14022 media: "interactive",
14023 inherited: false,
14024 animationType: "discrete",
14025 percentages: "no",
14026 groups: [
14027 "Microsoft Extensions"
14028 ],
14029 initial: [
14030 "-ms-scroll-limit-x-min",
14031 "-ms-scroll-limit-y-min",
14032 "-ms-scroll-limit-x-max",
14033 "-ms-scroll-limit-y-max"
14034 ],
14035 appliesto: "nonReplacedBlockAndInlineBlockElements",
14036 computed: [
14037 "-ms-scroll-limit-x-min",
14038 "-ms-scroll-limit-y-min",
14039 "-ms-scroll-limit-x-max",
14040 "-ms-scroll-limit-y-max"
14041 ],
14042 order: "uniqueOrder",
14043 status: "nonstandard",
14044 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scroll-limit"
14045 },
14046 "-ms-scroll-limit-x-max": {
14047 syntax: "auto | <length>",
14048 media: "interactive",
14049 inherited: false,
14050 animationType: "discrete",
14051 percentages: "no",
14052 groups: [
14053 "Microsoft Extensions"
14054 ],
14055 initial: "auto",
14056 appliesto: "nonReplacedBlockAndInlineBlockElements",
14057 computed: "asSpecified",
14058 order: "uniqueOrder",
14059 status: "nonstandard",
14060 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scroll-limit-x-max"
14061 },
14062 "-ms-scroll-limit-x-min": {
14063 syntax: "<length>",
14064 media: "interactive",
14065 inherited: false,
14066 animationType: "discrete",
14067 percentages: "no",
14068 groups: [
14069 "Microsoft Extensions"
14070 ],
14071 initial: "0",
14072 appliesto: "nonReplacedBlockAndInlineBlockElements",
14073 computed: "asSpecified",
14074 order: "uniqueOrder",
14075 status: "nonstandard",
14076 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scroll-limit-x-min"
14077 },
14078 "-ms-scroll-limit-y-max": {
14079 syntax: "auto | <length>",
14080 media: "interactive",
14081 inherited: false,
14082 animationType: "discrete",
14083 percentages: "no",
14084 groups: [
14085 "Microsoft Extensions"
14086 ],
14087 initial: "auto",
14088 appliesto: "nonReplacedBlockAndInlineBlockElements",
14089 computed: "asSpecified",
14090 order: "uniqueOrder",
14091 status: "nonstandard",
14092 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scroll-limit-y-max"
14093 },
14094 "-ms-scroll-limit-y-min": {
14095 syntax: "<length>",
14096 media: "interactive",
14097 inherited: false,
14098 animationType: "discrete",
14099 percentages: "no",
14100 groups: [
14101 "Microsoft Extensions"
14102 ],
14103 initial: "0",
14104 appliesto: "nonReplacedBlockAndInlineBlockElements",
14105 computed: "asSpecified",
14106 order: "uniqueOrder",
14107 status: "nonstandard",
14108 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scroll-limit-y-min"
14109 },
14110 "-ms-scroll-rails": {
14111 syntax: "none | railed",
14112 media: "interactive",
14113 inherited: false,
14114 animationType: "discrete",
14115 percentages: "no",
14116 groups: [
14117 "Microsoft Extensions"
14118 ],
14119 initial: "railed",
14120 appliesto: "nonReplacedBlockAndInlineBlockElements",
14121 computed: "asSpecified",
14122 order: "uniqueOrder",
14123 status: "nonstandard",
14124 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scroll-rails"
14125 },
14126 "-ms-scroll-snap-points-x": {
14127 syntax: "snapInterval( <length-percentage>, <length-percentage> ) | snapList( <length-percentage># )",
14128 media: "interactive",
14129 inherited: false,
14130 animationType: "discrete",
14131 percentages: "no",
14132 groups: [
14133 "Microsoft Extensions"
14134 ],
14135 initial: "snapInterval(0px, 100%)",
14136 appliesto: "nonReplacedBlockAndInlineBlockElements",
14137 computed: "asSpecified",
14138 order: "uniqueOrder",
14139 status: "nonstandard",
14140 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scroll-snap-points-x"
14141 },
14142 "-ms-scroll-snap-points-y": {
14143 syntax: "snapInterval( <length-percentage>, <length-percentage> ) | snapList( <length-percentage># )",
14144 media: "interactive",
14145 inherited: false,
14146 animationType: "discrete",
14147 percentages: "no",
14148 groups: [
14149 "Microsoft Extensions"
14150 ],
14151 initial: "snapInterval(0px, 100%)",
14152 appliesto: "nonReplacedBlockAndInlineBlockElements",
14153 computed: "asSpecified",
14154 order: "uniqueOrder",
14155 status: "nonstandard",
14156 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scroll-snap-points-y"
14157 },
14158 "-ms-scroll-snap-type": {
14159 syntax: "none | proximity | mandatory",
14160 media: "interactive",
14161 inherited: false,
14162 animationType: "discrete",
14163 percentages: "no",
14164 groups: [
14165 "Microsoft Extensions"
14166 ],
14167 initial: "none",
14168 appliesto: "nonReplacedBlockAndInlineBlockElements",
14169 computed: "asSpecified",
14170 order: "uniqueOrder",
14171 status: "nonstandard",
14172 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scroll-snap-type"
14173 },
14174 "-ms-scroll-snap-x": {
14175 syntax: "<'-ms-scroll-snap-type'> <'-ms-scroll-snap-points-x'>",
14176 media: "interactive",
14177 inherited: false,
14178 animationType: "discrete",
14179 percentages: "no",
14180 groups: [
14181 "Microsoft Extensions"
14182 ],
14183 initial: [
14184 "-ms-scroll-snap-type",
14185 "-ms-scroll-snap-points-x"
14186 ],
14187 appliesto: "nonReplacedBlockAndInlineBlockElements",
14188 computed: [
14189 "-ms-scroll-snap-type",
14190 "-ms-scroll-snap-points-x"
14191 ],
14192 order: "uniqueOrder",
14193 status: "nonstandard",
14194 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scroll-snap-x"
14195 },
14196 "-ms-scroll-snap-y": {
14197 syntax: "<'-ms-scroll-snap-type'> <'-ms-scroll-snap-points-y'>",
14198 media: "interactive",
14199 inherited: false,
14200 animationType: "discrete",
14201 percentages: "no",
14202 groups: [
14203 "Microsoft Extensions"
14204 ],
14205 initial: [
14206 "-ms-scroll-snap-type",
14207 "-ms-scroll-snap-points-y"
14208 ],
14209 appliesto: "nonReplacedBlockAndInlineBlockElements",
14210 computed: [
14211 "-ms-scroll-snap-type",
14212 "-ms-scroll-snap-points-y"
14213 ],
14214 order: "uniqueOrder",
14215 status: "nonstandard",
14216 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scroll-snap-y"
14217 },
14218 "-ms-scroll-translation": {
14219 syntax: "none | vertical-to-horizontal",
14220 media: "interactive",
14221 inherited: true,
14222 animationType: "discrete",
14223 percentages: "no",
14224 groups: [
14225 "Microsoft Extensions"
14226 ],
14227 initial: "none",
14228 appliesto: "allElements",
14229 computed: "asSpecified",
14230 order: "uniqueOrder",
14231 status: "nonstandard",
14232 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scroll-translation"
14233 },
14234 "-ms-text-autospace": {
14235 syntax: "none | ideograph-alpha | ideograph-numeric | ideograph-parenthesis | ideograph-space",
14236 media: "visual",
14237 inherited: false,
14238 animationType: "discrete",
14239 percentages: "no",
14240 groups: [
14241 "Microsoft Extensions"
14242 ],
14243 initial: "none",
14244 appliesto: "allElements",
14245 computed: "asSpecified",
14246 order: "uniqueOrder",
14247 status: "nonstandard",
14248 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-text-autospace"
14249 },
14250 "-ms-touch-select": {
14251 syntax: "grippers | none",
14252 media: "interactive",
14253 inherited: true,
14254 animationType: "discrete",
14255 percentages: "no",
14256 groups: [
14257 "Microsoft Extensions"
14258 ],
14259 initial: "grippers",
14260 appliesto: "allElements",
14261 computed: "asSpecified",
14262 order: "uniqueOrder",
14263 status: "nonstandard",
14264 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-touch-select"
14265 },
14266 "-ms-user-select": {
14267 syntax: "none | element | text",
14268 media: "interactive",
14269 inherited: false,
14270 animationType: "discrete",
14271 percentages: "no",
14272 groups: [
14273 "Microsoft Extensions"
14274 ],
14275 initial: "text",
14276 appliesto: "nonReplacedElements",
14277 computed: "asSpecified",
14278 order: "uniqueOrder",
14279 status: "nonstandard",
14280 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-user-select"
14281 },
14282 "-ms-wrap-flow": {
14283 syntax: "auto | both | start | end | maximum | clear",
14284 media: "visual",
14285 inherited: false,
14286 animationType: "discrete",
14287 percentages: "no",
14288 groups: [
14289 "Microsoft Extensions"
14290 ],
14291 initial: "auto",
14292 appliesto: "blockLevelElements",
14293 computed: "asSpecified",
14294 order: "uniqueOrder",
14295 status: "nonstandard",
14296 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-wrap-flow"
14297 },
14298 "-ms-wrap-margin": {
14299 syntax: "<length>",
14300 media: "visual",
14301 inherited: false,
14302 animationType: "discrete",
14303 percentages: "no",
14304 groups: [
14305 "Microsoft Extensions"
14306 ],
14307 initial: "0",
14308 appliesto: "exclusionElements",
14309 computed: "asSpecified",
14310 order: "uniqueOrder",
14311 status: "nonstandard",
14312 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-wrap-margin"
14313 },
14314 "-ms-wrap-through": {
14315 syntax: "wrap | none",
14316 media: "visual",
14317 inherited: false,
14318 animationType: "discrete",
14319 percentages: "no",
14320 groups: [
14321 "Microsoft Extensions"
14322 ],
14323 initial: "wrap",
14324 appliesto: "blockLevelElements",
14325 computed: "asSpecified",
14326 order: "uniqueOrder",
14327 status: "nonstandard",
14328 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-wrap-through"
14329 },
14330 "-moz-appearance": {
14331 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",
14332 media: "visual",
14333 inherited: false,
14334 animationType: "discrete",
14335 percentages: "no",
14336 groups: [
14337 "Mozilla Extensions",
14338 "WebKit Extensions"
14339 ],
14340 initial: "noneButOverriddenInUserAgentCSS",
14341 appliesto: "allElements",
14342 computed: "asSpecified",
14343 order: "uniqueOrder",
14344 status: "nonstandard",
14345 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/appearance"
14346 },
14347 "-moz-binding": {
14348 syntax: "<url> | none",
14349 media: "visual",
14350 inherited: false,
14351 animationType: "discrete",
14352 percentages: "no",
14353 groups: [
14354 "Mozilla Extensions"
14355 ],
14356 initial: "none",
14357 appliesto: "allElementsExceptGeneratedContentOrPseudoElements",
14358 computed: "asSpecified",
14359 order: "uniqueOrder",
14360 status: "nonstandard",
14361 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-binding"
14362 },
14363 "-moz-border-bottom-colors": {
14364 syntax: "<color>+ | none",
14365 media: "visual",
14366 inherited: false,
14367 animationType: "discrete",
14368 percentages: "no",
14369 groups: [
14370 "Mozilla Extensions"
14371 ],
14372 initial: "none",
14373 appliesto: "allElements",
14374 computed: "asSpecified",
14375 order: "uniqueOrder",
14376 status: "nonstandard",
14377 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-border-bottom-colors"
14378 },
14379 "-moz-border-left-colors": {
14380 syntax: "<color>+ | none",
14381 media: "visual",
14382 inherited: false,
14383 animationType: "discrete",
14384 percentages: "no",
14385 groups: [
14386 "Mozilla Extensions"
14387 ],
14388 initial: "none",
14389 appliesto: "allElements",
14390 computed: "asSpecified",
14391 order: "uniqueOrder",
14392 status: "nonstandard",
14393 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-border-left-colors"
14394 },
14395 "-moz-border-right-colors": {
14396 syntax: "<color>+ | none",
14397 media: "visual",
14398 inherited: false,
14399 animationType: "discrete",
14400 percentages: "no",
14401 groups: [
14402 "Mozilla Extensions"
14403 ],
14404 initial: "none",
14405 appliesto: "allElements",
14406 computed: "asSpecified",
14407 order: "uniqueOrder",
14408 status: "nonstandard",
14409 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-border-right-colors"
14410 },
14411 "-moz-border-top-colors": {
14412 syntax: "<color>+ | none",
14413 media: "visual",
14414 inherited: false,
14415 animationType: "discrete",
14416 percentages: "no",
14417 groups: [
14418 "Mozilla Extensions"
14419 ],
14420 initial: "none",
14421 appliesto: "allElements",
14422 computed: "asSpecified",
14423 order: "uniqueOrder",
14424 status: "nonstandard",
14425 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-border-top-colors"
14426 },
14427 "-moz-context-properties": {
14428 syntax: "none | [ fill | fill-opacity | stroke | stroke-opacity ]#",
14429 media: "visual",
14430 inherited: true,
14431 animationType: "discrete",
14432 percentages: "no",
14433 groups: [
14434 "Mozilla Extensions"
14435 ],
14436 initial: "none",
14437 appliesto: "allElementsThatCanReferenceImages",
14438 computed: "asSpecified",
14439 order: "uniqueOrder",
14440 status: "nonstandard",
14441 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-context-properties"
14442 },
14443 "-moz-float-edge": {
14444 syntax: "border-box | content-box | margin-box | padding-box",
14445 media: "visual",
14446 inherited: false,
14447 animationType: "discrete",
14448 percentages: "no",
14449 groups: [
14450 "Mozilla Extensions"
14451 ],
14452 initial: "content-box",
14453 appliesto: "allElements",
14454 computed: "asSpecified",
14455 order: "uniqueOrder",
14456 status: "nonstandard",
14457 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-float-edge"
14458 },
14459 "-moz-force-broken-image-icon": {
14460 syntax: "<integer [0,1]>",
14461 media: "visual",
14462 inherited: false,
14463 animationType: "discrete",
14464 percentages: "no",
14465 groups: [
14466 "Mozilla Extensions"
14467 ],
14468 initial: "0",
14469 appliesto: "images",
14470 computed: "asSpecified",
14471 order: "uniqueOrder",
14472 status: "nonstandard",
14473 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-force-broken-image-icon"
14474 },
14475 "-moz-image-region": {
14476 syntax: "<shape> | auto",
14477 media: "visual",
14478 inherited: true,
14479 animationType: "discrete",
14480 percentages: "no",
14481 groups: [
14482 "Mozilla Extensions"
14483 ],
14484 initial: "auto",
14485 appliesto: "xulImageElements",
14486 computed: "asSpecified",
14487 order: "uniqueOrder",
14488 status: "nonstandard",
14489 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-image-region"
14490 },
14491 "-moz-orient": {
14492 syntax: "inline | block | horizontal | vertical",
14493 media: "visual",
14494 inherited: false,
14495 animationType: "discrete",
14496 percentages: "no",
14497 groups: [
14498 "Mozilla Extensions"
14499 ],
14500 initial: "inline",
14501 appliesto: "anyElementEffectOnProgressAndMeter",
14502 computed: "asSpecified",
14503 order: "uniqueOrder",
14504 status: "nonstandard",
14505 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-orient"
14506 },
14507 "-moz-outline-radius": {
14508 syntax: "<outline-radius>{1,4} [ / <outline-radius>{1,4} ]?",
14509 media: "visual",
14510 inherited: false,
14511 animationType: [
14512 "-moz-outline-radius-topleft",
14513 "-moz-outline-radius-topright",
14514 "-moz-outline-radius-bottomright",
14515 "-moz-outline-radius-bottomleft"
14516 ],
14517 percentages: [
14518 "-moz-outline-radius-topleft",
14519 "-moz-outline-radius-topright",
14520 "-moz-outline-radius-bottomright",
14521 "-moz-outline-radius-bottomleft"
14522 ],
14523 groups: [
14524 "Mozilla Extensions"
14525 ],
14526 initial: [
14527 "-moz-outline-radius-topleft",
14528 "-moz-outline-radius-topright",
14529 "-moz-outline-radius-bottomright",
14530 "-moz-outline-radius-bottomleft"
14531 ],
14532 appliesto: "allElements",
14533 computed: [
14534 "-moz-outline-radius-topleft",
14535 "-moz-outline-radius-topright",
14536 "-moz-outline-radius-bottomright",
14537 "-moz-outline-radius-bottomleft"
14538 ],
14539 order: "uniqueOrder",
14540 status: "nonstandard",
14541 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-outline-radius"
14542 },
14543 "-moz-outline-radius-bottomleft": {
14544 syntax: "<outline-radius>",
14545 media: "visual",
14546 inherited: false,
14547 animationType: "lpc",
14548 percentages: "referToDimensionOfBorderBox",
14549 groups: [
14550 "Mozilla Extensions"
14551 ],
14552 initial: "0",
14553 appliesto: "allElements",
14554 computed: "asSpecified",
14555 order: "uniqueOrder",
14556 status: "nonstandard",
14557 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-outline-radius-bottomleft"
14558 },
14559 "-moz-outline-radius-bottomright": {
14560 syntax: "<outline-radius>",
14561 media: "visual",
14562 inherited: false,
14563 animationType: "lpc",
14564 percentages: "referToDimensionOfBorderBox",
14565 groups: [
14566 "Mozilla Extensions"
14567 ],
14568 initial: "0",
14569 appliesto: "allElements",
14570 computed: "asSpecified",
14571 order: "uniqueOrder",
14572 status: "nonstandard",
14573 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-outline-radius-bottomright"
14574 },
14575 "-moz-outline-radius-topleft": {
14576 syntax: "<outline-radius>",
14577 media: "visual",
14578 inherited: false,
14579 animationType: "lpc",
14580 percentages: "referToDimensionOfBorderBox",
14581 groups: [
14582 "Mozilla Extensions"
14583 ],
14584 initial: "0",
14585 appliesto: "allElements",
14586 computed: "asSpecified",
14587 order: "uniqueOrder",
14588 status: "nonstandard",
14589 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-outline-radius-topleft"
14590 },
14591 "-moz-outline-radius-topright": {
14592 syntax: "<outline-radius>",
14593 media: "visual",
14594 inherited: false,
14595 animationType: "lpc",
14596 percentages: "referToDimensionOfBorderBox",
14597 groups: [
14598 "Mozilla Extensions"
14599 ],
14600 initial: "0",
14601 appliesto: "allElements",
14602 computed: "asSpecified",
14603 order: "uniqueOrder",
14604 status: "nonstandard",
14605 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-outline-radius-topright"
14606 },
14607 "-moz-stack-sizing": {
14608 syntax: "ignore | stretch-to-fit",
14609 media: "visual",
14610 inherited: true,
14611 animationType: "discrete",
14612 percentages: "no",
14613 groups: [
14614 "Mozilla Extensions"
14615 ],
14616 initial: "stretch-to-fit",
14617 appliesto: "allElements",
14618 computed: "asSpecified",
14619 order: "uniqueOrder",
14620 status: "nonstandard",
14621 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-stack-sizing"
14622 },
14623 "-moz-text-blink": {
14624 syntax: "none | blink",
14625 media: "visual",
14626 inherited: false,
14627 animationType: "discrete",
14628 percentages: "no",
14629 groups: [
14630 "Mozilla Extensions"
14631 ],
14632 initial: "none",
14633 appliesto: "allElements",
14634 computed: "asSpecified",
14635 order: "uniqueOrder",
14636 status: "nonstandard",
14637 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-text-blink"
14638 },
14639 "-moz-user-focus": {
14640 syntax: "ignore | normal | select-after | select-before | select-menu | select-same | select-all | none",
14641 media: "interactive",
14642 inherited: false,
14643 animationType: "discrete",
14644 percentages: "no",
14645 groups: [
14646 "Mozilla Extensions"
14647 ],
14648 initial: "none",
14649 appliesto: "allElements",
14650 computed: "asSpecified",
14651 order: "uniqueOrder",
14652 status: "nonstandard",
14653 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-user-focus"
14654 },
14655 "-moz-user-input": {
14656 syntax: "auto | none | enabled | disabled",
14657 media: "visual",
14658 inherited: true,
14659 animationType: "discrete",
14660 percentages: "no",
14661 groups: [
14662 "Mozilla Extensions"
14663 ],
14664 initial: "auto",
14665 appliesto: "allElements",
14666 computed: "asSpecified",
14667 order: "uniqueOrder",
14668 status: "nonstandard",
14669 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-user-input"
14670 },
14671 "-moz-user-modify": {
14672 syntax: "read-only | read-write | write-only",
14673 media: "interactive",
14674 inherited: true,
14675 animationType: "discrete",
14676 percentages: "no",
14677 groups: [
14678 "Mozilla Extensions"
14679 ],
14680 initial: "read-only",
14681 appliesto: "allElements",
14682 computed: "asSpecified",
14683 order: "uniqueOrder",
14684 status: "nonstandard",
14685 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-user-modify"
14686 },
14687 "-moz-window-dragging": {
14688 syntax: "drag | no-drag",
14689 media: "visual",
14690 inherited: false,
14691 animationType: "discrete",
14692 percentages: "no",
14693 groups: [
14694 "Mozilla Extensions"
14695 ],
14696 initial: "drag",
14697 appliesto: "allElementsCreatingNativeWindows",
14698 computed: "asSpecified",
14699 order: "uniqueOrder",
14700 status: "nonstandard",
14701 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-window-dragging"
14702 },
14703 "-moz-window-shadow": {
14704 syntax: "default | menu | tooltip | sheet | none",
14705 media: "visual",
14706 inherited: false,
14707 animationType: "discrete",
14708 percentages: "no",
14709 groups: [
14710 "Mozilla Extensions"
14711 ],
14712 initial: "default",
14713 appliesto: "allElementsCreatingNativeWindows",
14714 computed: "asSpecified",
14715 order: "uniqueOrder",
14716 status: "nonstandard",
14717 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-window-shadow"
14718 },
14719 "-webkit-appearance": {
14720 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",
14721 media: "visual",
14722 inherited: false,
14723 animationType: "discrete",
14724 percentages: "no",
14725 groups: [
14726 "WebKit Extensions"
14727 ],
14728 initial: "noneButOverriddenInUserAgentCSS",
14729 appliesto: "allElements",
14730 computed: "asSpecified",
14731 order: "uniqueOrder",
14732 status: "nonstandard",
14733 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/appearance"
14734 },
14735 "-webkit-border-before": {
14736 syntax: "<'border-width'> || <'border-style'> || <'color'>",
14737 media: "visual",
14738 inherited: true,
14739 animationType: "discrete",
14740 percentages: [
14741 "-webkit-border-before-width"
14742 ],
14743 groups: [
14744 "WebKit Extensions"
14745 ],
14746 initial: [
14747 "border-width",
14748 "border-style",
14749 "color"
14750 ],
14751 appliesto: "allElements",
14752 computed: [
14753 "border-width",
14754 "border-style",
14755 "color"
14756 ],
14757 order: "uniqueOrder",
14758 status: "nonstandard",
14759 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-border-before"
14760 },
14761 "-webkit-border-before-color": {
14762 syntax: "<'color'>",
14763 media: "visual",
14764 inherited: true,
14765 animationType: "discrete",
14766 percentages: "no",
14767 groups: [
14768 "WebKit Extensions"
14769 ],
14770 initial: "currentcolor",
14771 appliesto: "allElements",
14772 computed: "computedColor",
14773 order: "uniqueOrder",
14774 status: "nonstandard"
14775 },
14776 "-webkit-border-before-style": {
14777 syntax: "<'border-style'>",
14778 media: "visual",
14779 inherited: true,
14780 animationType: "discrete",
14781 percentages: "no",
14782 groups: [
14783 "WebKit Extensions"
14784 ],
14785 initial: "none",
14786 appliesto: "allElements",
14787 computed: "asSpecified",
14788 order: "uniqueOrder",
14789 status: "nonstandard"
14790 },
14791 "-webkit-border-before-width": {
14792 syntax: "<'border-width'>",
14793 media: "visual",
14794 inherited: true,
14795 animationType: "discrete",
14796 percentages: "logicalWidthOfContainingBlock",
14797 groups: [
14798 "WebKit Extensions"
14799 ],
14800 initial: "medium",
14801 appliesto: "allElements",
14802 computed: "absoluteLengthZeroIfBorderStyleNoneOrHidden",
14803 order: "uniqueOrder",
14804 status: "nonstandard"
14805 },
14806 "-webkit-box-reflect": {
14807 syntax: "[ above | below | right | left ]? <length>? <image>?",
14808 media: "visual",
14809 inherited: false,
14810 animationType: "discrete",
14811 percentages: "no",
14812 groups: [
14813 "WebKit Extensions"
14814 ],
14815 initial: "none",
14816 appliesto: "allElements",
14817 computed: "asSpecified",
14818 order: "uniqueOrder",
14819 status: "nonstandard",
14820 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-box-reflect"
14821 },
14822 "-webkit-line-clamp": {
14823 syntax: "none | <integer>",
14824 media: "visual",
14825 inherited: false,
14826 animationType: "byComputedValueType",
14827 percentages: "no",
14828 groups: [
14829 "WebKit Extensions",
14830 "CSS Overflow"
14831 ],
14832 initial: "none",
14833 appliesto: "allElements",
14834 computed: "asSpecified",
14835 order: "uniqueOrder",
14836 status: "standard",
14837 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-line-clamp"
14838 },
14839 "-webkit-mask": {
14840 syntax: "[ <mask-reference> || <position> [ / <bg-size> ]? || <repeat-style> || [ <box> | border | padding | content | text ] || [ <box> | border | padding | content ] ]#",
14841 media: "visual",
14842 inherited: false,
14843 animationType: "discrete",
14844 percentages: "no",
14845 groups: [
14846 "WebKit Extensions"
14847 ],
14848 initial: [
14849 "-webkit-mask-image",
14850 "-webkit-mask-repeat",
14851 "-webkit-mask-attachment",
14852 "-webkit-mask-position",
14853 "-webkit-mask-origin",
14854 "-webkit-mask-clip"
14855 ],
14856 appliesto: "allElements",
14857 computed: [
14858 "-webkit-mask-image",
14859 "-webkit-mask-repeat",
14860 "-webkit-mask-attachment",
14861 "-webkit-mask-position",
14862 "-webkit-mask-origin",
14863 "-webkit-mask-clip"
14864 ],
14865 order: "uniqueOrder",
14866 status: "nonstandard",
14867 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask"
14868 },
14869 "-webkit-mask-attachment": {
14870 syntax: "<attachment>#",
14871 media: "visual",
14872 inherited: false,
14873 animationType: "discrete",
14874 percentages: "no",
14875 groups: [
14876 "WebKit Extensions"
14877 ],
14878 initial: "scroll",
14879 appliesto: "allElements",
14880 computed: "asSpecified",
14881 order: "orderOfAppearance",
14882 status: "nonstandard",
14883 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-mask-attachment"
14884 },
14885 "-webkit-mask-clip": {
14886 syntax: "[ <box> | border | padding | content | text ]#",
14887 media: "visual",
14888 inherited: false,
14889 animationType: "discrete",
14890 percentages: "no",
14891 groups: [
14892 "WebKit Extensions"
14893 ],
14894 initial: "border",
14895 appliesto: "allElements",
14896 computed: "asSpecified",
14897 order: "orderOfAppearance",
14898 status: "nonstandard",
14899 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-clip"
14900 },
14901 "-webkit-mask-composite": {
14902 syntax: "<composite-style>#",
14903 media: "visual",
14904 inherited: false,
14905 animationType: "discrete",
14906 percentages: "no",
14907 groups: [
14908 "WebKit Extensions"
14909 ],
14910 initial: "source-over",
14911 appliesto: "allElements",
14912 computed: "asSpecified",
14913 order: "orderOfAppearance",
14914 status: "nonstandard",
14915 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-mask-composite"
14916 },
14917 "-webkit-mask-image": {
14918 syntax: "<mask-reference>#",
14919 media: "visual",
14920 inherited: false,
14921 animationType: "discrete",
14922 percentages: "no",
14923 groups: [
14924 "WebKit Extensions"
14925 ],
14926 initial: "none",
14927 appliesto: "allElements",
14928 computed: "absoluteURIOrNone",
14929 order: "orderOfAppearance",
14930 status: "nonstandard",
14931 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-image"
14932 },
14933 "-webkit-mask-origin": {
14934 syntax: "[ <box> | border | padding | content ]#",
14935 media: "visual",
14936 inherited: false,
14937 animationType: "discrete",
14938 percentages: "no",
14939 groups: [
14940 "WebKit Extensions"
14941 ],
14942 initial: "padding",
14943 appliesto: "allElements",
14944 computed: "asSpecified",
14945 order: "orderOfAppearance",
14946 status: "nonstandard",
14947 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-origin"
14948 },
14949 "-webkit-mask-position": {
14950 syntax: "<position>#",
14951 media: "visual",
14952 inherited: false,
14953 animationType: "discrete",
14954 percentages: "referToSizeOfElement",
14955 groups: [
14956 "WebKit Extensions"
14957 ],
14958 initial: "0% 0%",
14959 appliesto: "allElements",
14960 computed: "absoluteLengthOrPercentage",
14961 order: "orderOfAppearance",
14962 status: "nonstandard",
14963 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-position"
14964 },
14965 "-webkit-mask-position-x": {
14966 syntax: "[ <length-percentage> | left | center | right ]#",
14967 media: "visual",
14968 inherited: false,
14969 animationType: "discrete",
14970 percentages: "referToSizeOfElement",
14971 groups: [
14972 "WebKit Extensions"
14973 ],
14974 initial: "0%",
14975 appliesto: "allElements",
14976 computed: "absoluteLengthOrPercentage",
14977 order: "orderOfAppearance",
14978 status: "nonstandard",
14979 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-mask-position-x"
14980 },
14981 "-webkit-mask-position-y": {
14982 syntax: "[ <length-percentage> | top | center | bottom ]#",
14983 media: "visual",
14984 inherited: false,
14985 animationType: "discrete",
14986 percentages: "referToSizeOfElement",
14987 groups: [
14988 "WebKit Extensions"
14989 ],
14990 initial: "0%",
14991 appliesto: "allElements",
14992 computed: "absoluteLengthOrPercentage",
14993 order: "orderOfAppearance",
14994 status: "nonstandard",
14995 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-mask-position-y"
14996 },
14997 "-webkit-mask-repeat": {
14998 syntax: "<repeat-style>#",
14999 media: "visual",
15000 inherited: false,
15001 animationType: "discrete",
15002 percentages: "no",
15003 groups: [
15004 "WebKit Extensions"
15005 ],
15006 initial: "repeat",
15007 appliesto: "allElements",
15008 computed: "asSpecified",
15009 order: "orderOfAppearance",
15010 status: "nonstandard",
15011 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-repeat"
15012 },
15013 "-webkit-mask-repeat-x": {
15014 syntax: "repeat | no-repeat | space | round",
15015 media: "visual",
15016 inherited: false,
15017 animationType: "discrete",
15018 percentages: "no",
15019 groups: [
15020 "WebKit Extensions"
15021 ],
15022 initial: "repeat",
15023 appliesto: "allElements",
15024 computed: "asSpecified",
15025 order: "orderOfAppearance",
15026 status: "nonstandard",
15027 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-mask-repeat-x"
15028 },
15029 "-webkit-mask-repeat-y": {
15030 syntax: "repeat | no-repeat | space | round",
15031 media: "visual",
15032 inherited: false,
15033 animationType: "discrete",
15034 percentages: "no",
15035 groups: [
15036 "WebKit Extensions"
15037 ],
15038 initial: "repeat",
15039 appliesto: "allElements",
15040 computed: "absoluteLengthOrPercentage",
15041 order: "orderOfAppearance",
15042 status: "nonstandard",
15043 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-mask-repeat-y"
15044 },
15045 "-webkit-mask-size": {
15046 syntax: "<bg-size>#",
15047 media: "visual",
15048 inherited: false,
15049 animationType: "discrete",
15050 percentages: "relativeToBackgroundPositioningArea",
15051 groups: [
15052 "WebKit Extensions"
15053 ],
15054 initial: "auto auto",
15055 appliesto: "allElements",
15056 computed: "asSpecified",
15057 order: "orderOfAppearance",
15058 status: "nonstandard",
15059 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-size"
15060 },
15061 "-webkit-overflow-scrolling": {
15062 syntax: "auto | touch",
15063 media: "visual",
15064 inherited: true,
15065 animationType: "discrete",
15066 percentages: "no",
15067 groups: [
15068 "WebKit Extensions"
15069 ],
15070 initial: "auto",
15071 appliesto: "scrollingBoxes",
15072 computed: "asSpecified",
15073 order: "orderOfAppearance",
15074 status: "nonstandard",
15075 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-overflow-scrolling"
15076 },
15077 "-webkit-tap-highlight-color": {
15078 syntax: "<color>",
15079 media: "visual",
15080 inherited: false,
15081 animationType: "discrete",
15082 percentages: "no",
15083 groups: [
15084 "WebKit Extensions"
15085 ],
15086 initial: "black",
15087 appliesto: "allElements",
15088 computed: "asSpecified",
15089 order: "uniqueOrder",
15090 status: "nonstandard",
15091 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-tap-highlight-color"
15092 },
15093 "-webkit-text-fill-color": {
15094 syntax: "<color>",
15095 media: "visual",
15096 inherited: true,
15097 animationType: "color",
15098 percentages: "no",
15099 groups: [
15100 "WebKit Extensions"
15101 ],
15102 initial: "currentcolor",
15103 appliesto: "allElements",
15104 computed: "computedColor",
15105 order: "uniqueOrder",
15106 status: "nonstandard",
15107 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-text-fill-color"
15108 },
15109 "-webkit-text-stroke": {
15110 syntax: "<length> || <color>",
15111 media: "visual",
15112 inherited: true,
15113 animationType: [
15114 "-webkit-text-stroke-width",
15115 "-webkit-text-stroke-color"
15116 ],
15117 percentages: "no",
15118 groups: [
15119 "WebKit Extensions"
15120 ],
15121 initial: [
15122 "-webkit-text-stroke-width",
15123 "-webkit-text-stroke-color"
15124 ],
15125 appliesto: "allElements",
15126 computed: [
15127 "-webkit-text-stroke-width",
15128 "-webkit-text-stroke-color"
15129 ],
15130 order: "canonicalOrder",
15131 status: "nonstandard",
15132 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-text-stroke"
15133 },
15134 "-webkit-text-stroke-color": {
15135 syntax: "<color>",
15136 media: "visual",
15137 inherited: true,
15138 animationType: "color",
15139 percentages: "no",
15140 groups: [
15141 "WebKit Extensions"
15142 ],
15143 initial: "currentcolor",
15144 appliesto: "allElements",
15145 computed: "computedColor",
15146 order: "uniqueOrder",
15147 status: "nonstandard",
15148 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-text-stroke-color"
15149 },
15150 "-webkit-text-stroke-width": {
15151 syntax: "<length>",
15152 media: "visual",
15153 inherited: true,
15154 animationType: "discrete",
15155 percentages: "no",
15156 groups: [
15157 "WebKit Extensions"
15158 ],
15159 initial: "0",
15160 appliesto: "allElements",
15161 computed: "absoluteLength",
15162 order: "uniqueOrder",
15163 status: "nonstandard",
15164 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-text-stroke-width"
15165 },
15166 "-webkit-touch-callout": {
15167 syntax: "default | none",
15168 media: "visual",
15169 inherited: true,
15170 animationType: "discrete",
15171 percentages: "no",
15172 groups: [
15173 "WebKit Extensions"
15174 ],
15175 initial: "default",
15176 appliesto: "allElements",
15177 computed: "asSpecified",
15178 order: "uniqueOrder",
15179 status: "nonstandard",
15180 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-touch-callout"
15181 },
15182 "-webkit-user-modify": {
15183 syntax: "read-only | read-write | read-write-plaintext-only",
15184 media: "interactive",
15185 inherited: true,
15186 animationType: "discrete",
15187 percentages: "no",
15188 groups: [
15189 "WebKit Extensions"
15190 ],
15191 initial: "read-only",
15192 appliesto: "allElements",
15193 computed: "asSpecified",
15194 order: "uniqueOrder",
15195 status: "nonstandard"
15196 },
15197 "align-content": {
15198 syntax: "normal | <baseline-position> | <content-distribution> | <overflow-position>? <content-position>",
15199 media: "visual",
15200 inherited: false,
15201 animationType: "discrete",
15202 percentages: "no",
15203 groups: [
15204 "CSS Box Alignment"
15205 ],
15206 initial: "normal",
15207 appliesto: "multilineFlexContainers",
15208 computed: "asSpecified",
15209 order: "uniqueOrder",
15210 status: "standard",
15211 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/align-content"
15212 },
15213 "align-items": {
15214 syntax: "normal | stretch | <baseline-position> | [ <overflow-position>? <self-position> ]",
15215 media: "visual",
15216 inherited: false,
15217 animationType: "discrete",
15218 percentages: "no",
15219 groups: [
15220 "CSS Box Alignment"
15221 ],
15222 initial: "normal",
15223 appliesto: "allElements",
15224 computed: "asSpecified",
15225 order: "uniqueOrder",
15226 status: "standard",
15227 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/align-items"
15228 },
15229 "align-self": {
15230 syntax: "auto | normal | stretch | <baseline-position> | <overflow-position>? <self-position>",
15231 media: "visual",
15232 inherited: false,
15233 animationType: "discrete",
15234 percentages: "no",
15235 groups: [
15236 "CSS Box Alignment"
15237 ],
15238 initial: "auto",
15239 appliesto: "flexItemsGridItemsAndAbsolutelyPositionedBoxes",
15240 computed: "autoOnAbsolutelyPositionedElementsValueOfAlignItemsOnParent",
15241 order: "uniqueOrder",
15242 status: "standard",
15243 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/align-self"
15244 },
15245 "align-tracks": {
15246 syntax: "[ normal | <baseline-position> | <content-distribution> | <overflow-position>? <content-position> ]#",
15247 media: "visual",
15248 inherited: false,
15249 animationType: "discrete",
15250 percentages: "no",
15251 groups: [
15252 "CSS Grid Layout"
15253 ],
15254 initial: "normal",
15255 appliesto: "gridContainersWithMasonryLayoutInTheirBlockAxis",
15256 computed: "asSpecified",
15257 order: "uniqueOrder",
15258 status: "experimental",
15259 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/align-tracks"
15260 },
15261 all: all,
15262 animation: animation,
15263 "animation-delay": {
15264 syntax: "<time>#",
15265 media: "visual",
15266 inherited: false,
15267 animationType: "discrete",
15268 percentages: "no",
15269 groups: [
15270 "CSS Animations"
15271 ],
15272 initial: "0s",
15273 appliesto: "allElementsAndPseudos",
15274 computed: "asSpecified",
15275 order: "uniqueOrder",
15276 status: "standard",
15277 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/animation-delay"
15278 },
15279 "animation-direction": {
15280 syntax: "<single-animation-direction>#",
15281 media: "visual",
15282 inherited: false,
15283 animationType: "discrete",
15284 percentages: "no",
15285 groups: [
15286 "CSS Animations"
15287 ],
15288 initial: "normal",
15289 appliesto: "allElementsAndPseudos",
15290 computed: "asSpecified",
15291 order: "uniqueOrder",
15292 status: "standard",
15293 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/animation-direction"
15294 },
15295 "animation-duration": {
15296 syntax: "<time>#",
15297 media: "visual",
15298 inherited: false,
15299 animationType: "discrete",
15300 percentages: "no",
15301 groups: [
15302 "CSS Animations"
15303 ],
15304 initial: "0s",
15305 appliesto: "allElementsAndPseudos",
15306 computed: "asSpecified",
15307 order: "uniqueOrder",
15308 status: "standard",
15309 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/animation-duration"
15310 },
15311 "animation-fill-mode": {
15312 syntax: "<single-animation-fill-mode>#",
15313 media: "visual",
15314 inherited: false,
15315 animationType: "discrete",
15316 percentages: "no",
15317 groups: [
15318 "CSS Animations"
15319 ],
15320 initial: "none",
15321 appliesto: "allElementsAndPseudos",
15322 computed: "asSpecified",
15323 order: "uniqueOrder",
15324 status: "standard",
15325 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/animation-fill-mode"
15326 },
15327 "animation-iteration-count": {
15328 syntax: "<single-animation-iteration-count>#",
15329 media: "visual",
15330 inherited: false,
15331 animationType: "discrete",
15332 percentages: "no",
15333 groups: [
15334 "CSS Animations"
15335 ],
15336 initial: "1",
15337 appliesto: "allElementsAndPseudos",
15338 computed: "asSpecified",
15339 order: "uniqueOrder",
15340 status: "standard",
15341 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/animation-iteration-count"
15342 },
15343 "animation-name": {
15344 syntax: "[ none | <keyframes-name> ]#",
15345 media: "visual",
15346 inherited: false,
15347 animationType: "discrete",
15348 percentages: "no",
15349 groups: [
15350 "CSS Animations"
15351 ],
15352 initial: "none",
15353 appliesto: "allElementsAndPseudos",
15354 computed: "asSpecified",
15355 order: "uniqueOrder",
15356 status: "standard",
15357 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/animation-name"
15358 },
15359 "animation-play-state": {
15360 syntax: "<single-animation-play-state>#",
15361 media: "visual",
15362 inherited: false,
15363 animationType: "discrete",
15364 percentages: "no",
15365 groups: [
15366 "CSS Animations"
15367 ],
15368 initial: "running",
15369 appliesto: "allElementsAndPseudos",
15370 computed: "asSpecified",
15371 order: "uniqueOrder",
15372 status: "standard",
15373 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/animation-play-state"
15374 },
15375 "animation-timing-function": {
15376 syntax: "<timing-function>#",
15377 media: "visual",
15378 inherited: false,
15379 animationType: "discrete",
15380 percentages: "no",
15381 groups: [
15382 "CSS Animations"
15383 ],
15384 initial: "ease",
15385 appliesto: "allElementsAndPseudos",
15386 computed: "asSpecified",
15387 order: "uniqueOrder",
15388 status: "standard",
15389 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/animation-timing-function"
15390 },
15391 appearance: appearance,
15392 "aspect-ratio": {
15393 syntax: "auto | <ratio>",
15394 media: "all",
15395 inherited: false,
15396 animationType: "discrete",
15397 percentages: "no",
15398 groups: [
15399 "CSS Basic User Interface"
15400 ],
15401 initial: "auto",
15402 appliesto: "allElementsExceptInlineBoxesAndInternalRubyOrTableBoxes",
15403 computed: "asSpecified",
15404 order: "perGrammar",
15405 status: "experimental",
15406 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/aspect-ratio"
15407 },
15408 azimuth: azimuth,
15409 "backdrop-filter": {
15410 syntax: "none | <filter-function-list>",
15411 media: "visual",
15412 inherited: false,
15413 animationType: "filterList",
15414 percentages: "no",
15415 groups: [
15416 "Filter Effects"
15417 ],
15418 initial: "none",
15419 appliesto: "allElementsSVGContainerElements",
15420 computed: "asSpecified",
15421 order: "uniqueOrder",
15422 status: "standard",
15423 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/backdrop-filter"
15424 },
15425 "backface-visibility": {
15426 syntax: "visible | hidden",
15427 media: "visual",
15428 inherited: false,
15429 animationType: "discrete",
15430 percentages: "no",
15431 groups: [
15432 "CSS Transforms"
15433 ],
15434 initial: "visible",
15435 appliesto: "transformableElements",
15436 computed: "asSpecified",
15437 order: "uniqueOrder",
15438 status: "standard",
15439 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/backface-visibility"
15440 },
15441 background: background,
15442 "background-attachment": {
15443 syntax: "<attachment>#",
15444 media: "visual",
15445 inherited: false,
15446 animationType: "discrete",
15447 percentages: "no",
15448 groups: [
15449 "CSS Backgrounds and Borders"
15450 ],
15451 initial: "scroll",
15452 appliesto: "allElements",
15453 computed: "asSpecified",
15454 order: "uniqueOrder",
15455 alsoAppliesTo: [
15456 "::first-letter",
15457 "::first-line",
15458 "::placeholder"
15459 ],
15460 status: "standard",
15461 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/background-attachment"
15462 },
15463 "background-blend-mode": {
15464 syntax: "<blend-mode>#",
15465 media: "none",
15466 inherited: false,
15467 animationType: "discrete",
15468 percentages: "no",
15469 groups: [
15470 "Compositing and Blending"
15471 ],
15472 initial: "normal",
15473 appliesto: "allElementsSVGContainerGraphicsAndGraphicsReferencingElements",
15474 computed: "asSpecified",
15475 order: "uniqueOrder",
15476 alsoAppliesTo: [
15477 "::first-letter",
15478 "::first-line",
15479 "::placeholder"
15480 ],
15481 status: "standard",
15482 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/background-blend-mode"
15483 },
15484 "background-clip": {
15485 syntax: "<box>#",
15486 media: "visual",
15487 inherited: false,
15488 animationType: "discrete",
15489 percentages: "no",
15490 groups: [
15491 "CSS Backgrounds and Borders"
15492 ],
15493 initial: "border-box",
15494 appliesto: "allElements",
15495 computed: "asSpecified",
15496 order: "uniqueOrder",
15497 alsoAppliesTo: [
15498 "::first-letter",
15499 "::first-line",
15500 "::placeholder"
15501 ],
15502 status: "standard",
15503 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/background-clip"
15504 },
15505 "background-color": {
15506 syntax: "<color>",
15507 media: "visual",
15508 inherited: false,
15509 animationType: "color",
15510 percentages: "no",
15511 groups: [
15512 "CSS Backgrounds and Borders"
15513 ],
15514 initial: "transparent",
15515 appliesto: "allElements",
15516 computed: "computedColor",
15517 order: "uniqueOrder",
15518 alsoAppliesTo: [
15519 "::first-letter",
15520 "::first-line",
15521 "::placeholder"
15522 ],
15523 status: "standard",
15524 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/background-color"
15525 },
15526 "background-image": {
15527 syntax: "<bg-image>#",
15528 media: "visual",
15529 inherited: false,
15530 animationType: "discrete",
15531 percentages: "no",
15532 groups: [
15533 "CSS Backgrounds and Borders"
15534 ],
15535 initial: "none",
15536 appliesto: "allElements",
15537 computed: "asSpecifiedURLsAbsolute",
15538 order: "uniqueOrder",
15539 alsoAppliesTo: [
15540 "::first-letter",
15541 "::first-line",
15542 "::placeholder"
15543 ],
15544 status: "standard",
15545 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/background-image"
15546 },
15547 "background-origin": {
15548 syntax: "<box>#",
15549 media: "visual",
15550 inherited: false,
15551 animationType: "discrete",
15552 percentages: "no",
15553 groups: [
15554 "CSS Backgrounds and Borders"
15555 ],
15556 initial: "padding-box",
15557 appliesto: "allElements",
15558 computed: "asSpecified",
15559 order: "uniqueOrder",
15560 alsoAppliesTo: [
15561 "::first-letter",
15562 "::first-line",
15563 "::placeholder"
15564 ],
15565 status: "standard",
15566 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/background-origin"
15567 },
15568 "background-position": {
15569 syntax: "<bg-position>#",
15570 media: "visual",
15571 inherited: false,
15572 animationType: "repeatableListOfSimpleListOfLpc",
15573 percentages: "referToSizeOfBackgroundPositioningAreaMinusBackgroundImageSize",
15574 groups: [
15575 "CSS Backgrounds and Borders"
15576 ],
15577 initial: "0% 0%",
15578 appliesto: "allElements",
15579 computed: "listEachItemTwoKeywordsOriginOffsets",
15580 order: "uniqueOrder",
15581 alsoAppliesTo: [
15582 "::first-letter",
15583 "::first-line",
15584 "::placeholder"
15585 ],
15586 status: "standard",
15587 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/background-position"
15588 },
15589 "background-position-x": {
15590 syntax: "[ center | [ [ left | right | x-start | x-end ]? <length-percentage>? ]! ]#",
15591 media: "visual",
15592 inherited: false,
15593 animationType: "discrete",
15594 percentages: "referToWidthOfBackgroundPositioningAreaMinusBackgroundImageHeight",
15595 groups: [
15596 "CSS Backgrounds and Borders"
15597 ],
15598 initial: "left",
15599 appliesto: "allElements",
15600 computed: "listEachItemConsistingOfAbsoluteLengthPercentageAndOrigin",
15601 order: "uniqueOrder",
15602 status: "experimental",
15603 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/background-position-x"
15604 },
15605 "background-position-y": {
15606 syntax: "[ center | [ [ top | bottom | y-start | y-end ]? <length-percentage>? ]! ]#",
15607 media: "visual",
15608 inherited: false,
15609 animationType: "discrete",
15610 percentages: "referToHeightOfBackgroundPositioningAreaMinusBackgroundImageHeight",
15611 groups: [
15612 "CSS Backgrounds and Borders"
15613 ],
15614 initial: "top",
15615 appliesto: "allElements",
15616 computed: "listEachItemConsistingOfAbsoluteLengthPercentageAndOrigin",
15617 order: "uniqueOrder",
15618 status: "experimental",
15619 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/background-position-y"
15620 },
15621 "background-repeat": {
15622 syntax: "<repeat-style>#",
15623 media: "visual",
15624 inherited: false,
15625 animationType: "discrete",
15626 percentages: "no",
15627 groups: [
15628 "CSS Backgrounds and Borders"
15629 ],
15630 initial: "repeat",
15631 appliesto: "allElements",
15632 computed: "listEachItemHasTwoKeywordsOnePerDimension",
15633 order: "uniqueOrder",
15634 alsoAppliesTo: [
15635 "::first-letter",
15636 "::first-line",
15637 "::placeholder"
15638 ],
15639 status: "standard",
15640 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/background-repeat"
15641 },
15642 "background-size": {
15643 syntax: "<bg-size>#",
15644 media: "visual",
15645 inherited: false,
15646 animationType: "repeatableListOfSimpleListOfLpc",
15647 percentages: "relativeToBackgroundPositioningArea",
15648 groups: [
15649 "CSS Backgrounds and Borders"
15650 ],
15651 initial: "auto auto",
15652 appliesto: "allElements",
15653 computed: "asSpecifiedRelativeToAbsoluteLengths",
15654 order: "uniqueOrder",
15655 alsoAppliesTo: [
15656 "::first-letter",
15657 "::first-line",
15658 "::placeholder"
15659 ],
15660 status: "standard",
15661 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/background-size"
15662 },
15663 "block-overflow": {
15664 syntax: "clip | ellipsis | <string>",
15665 media: "visual",
15666 inherited: true,
15667 animationType: "discrete",
15668 percentages: "no",
15669 groups: [
15670 "CSS Overflow"
15671 ],
15672 initial: "clip",
15673 appliesto: "blockContainers",
15674 computed: "asSpecified",
15675 order: "perGrammar",
15676 status: "experimental"
15677 },
15678 "block-size": {
15679 syntax: "<'width'>",
15680 media: "visual",
15681 inherited: false,
15682 animationType: "lpc",
15683 percentages: "blockSizeOfContainingBlock",
15684 groups: [
15685 "CSS Logical Properties"
15686 ],
15687 initial: "auto",
15688 appliesto: "sameAsWidthAndHeight",
15689 computed: "sameAsWidthAndHeight",
15690 order: "uniqueOrder",
15691 status: "standard",
15692 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/block-size"
15693 },
15694 border: border,
15695 "border-block": {
15696 syntax: "<'border-top-width'> || <'border-top-style'> || <'color'>",
15697 media: "visual",
15698 inherited: false,
15699 animationType: "discrete",
15700 percentages: "no",
15701 groups: [
15702 "CSS Logical Properties"
15703 ],
15704 initial: [
15705 "border-top-width",
15706 "border-top-style",
15707 "border-top-color"
15708 ],
15709 appliesto: "allElements",
15710 computed: [
15711 "border-top-width",
15712 "border-top-style",
15713 "border-top-color"
15714 ],
15715 order: "uniqueOrder",
15716 status: "standard",
15717 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-block"
15718 },
15719 "border-block-color": {
15720 syntax: "<'border-top-color'>{1,2}",
15721 media: "visual",
15722 inherited: false,
15723 animationType: "discrete",
15724 percentages: "no",
15725 groups: [
15726 "CSS Logical Properties"
15727 ],
15728 initial: "currentcolor",
15729 appliesto: "allElements",
15730 computed: "computedColor",
15731 order: "uniqueOrder",
15732 status: "standard",
15733 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-block-color"
15734 },
15735 "border-block-style": {
15736 syntax: "<'border-top-style'>",
15737 media: "visual",
15738 inherited: false,
15739 animationType: "discrete",
15740 percentages: "no",
15741 groups: [
15742 "CSS Logical Properties"
15743 ],
15744 initial: "none",
15745 appliesto: "allElements",
15746 computed: "asSpecified",
15747 order: "uniqueOrder",
15748 status: "standard",
15749 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-block-style"
15750 },
15751 "border-block-width": {
15752 syntax: "<'border-top-width'>",
15753 media: "visual",
15754 inherited: false,
15755 animationType: "discrete",
15756 percentages: "logicalWidthOfContainingBlock",
15757 groups: [
15758 "CSS Logical Properties"
15759 ],
15760 initial: "medium",
15761 appliesto: "allElements",
15762 computed: "absoluteLengthZeroIfBorderStyleNoneOrHidden",
15763 order: "uniqueOrder",
15764 status: "standard",
15765 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-block-width"
15766 },
15767 "border-block-end": {
15768 syntax: "<'border-top-width'> || <'border-top-style'> || <'color'>",
15769 media: "visual",
15770 inherited: false,
15771 animationType: [
15772 "border-block-end-color",
15773 "border-block-end-style",
15774 "border-block-end-width"
15775 ],
15776 percentages: "no",
15777 groups: [
15778 "CSS Logical Properties"
15779 ],
15780 initial: [
15781 "border-top-width",
15782 "border-top-style",
15783 "border-top-color"
15784 ],
15785 appliesto: "allElements",
15786 computed: [
15787 "border-top-width",
15788 "border-top-style",
15789 "border-top-color"
15790 ],
15791 order: "uniqueOrder",
15792 status: "standard",
15793 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-block-end"
15794 },
15795 "border-block-end-color": {
15796 syntax: "<'border-top-color'>",
15797 media: "visual",
15798 inherited: false,
15799 animationType: "color",
15800 percentages: "no",
15801 groups: [
15802 "CSS Logical Properties"
15803 ],
15804 initial: "currentcolor",
15805 appliesto: "allElements",
15806 computed: "computedColor",
15807 order: "uniqueOrder",
15808 status: "standard",
15809 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-block-end-color"
15810 },
15811 "border-block-end-style": {
15812 syntax: "<'border-top-style'>",
15813 media: "visual",
15814 inherited: false,
15815 animationType: "discrete",
15816 percentages: "no",
15817 groups: [
15818 "CSS Logical Properties"
15819 ],
15820 initial: "none",
15821 appliesto: "allElements",
15822 computed: "asSpecified",
15823 order: "uniqueOrder",
15824 status: "standard",
15825 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-block-end-style"
15826 },
15827 "border-block-end-width": {
15828 syntax: "<'border-top-width'>",
15829 media: "visual",
15830 inherited: false,
15831 animationType: "length",
15832 percentages: "logicalWidthOfContainingBlock",
15833 groups: [
15834 "CSS Logical Properties"
15835 ],
15836 initial: "medium",
15837 appliesto: "allElements",
15838 computed: "absoluteLengthZeroIfBorderStyleNoneOrHidden",
15839 order: "uniqueOrder",
15840 status: "standard",
15841 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-block-end-width"
15842 },
15843 "border-block-start": {
15844 syntax: "<'border-top-width'> || <'border-top-style'> || <'color'>",
15845 media: "visual",
15846 inherited: false,
15847 animationType: [
15848 "border-block-start-color",
15849 "border-block-start-style",
15850 "border-block-start-width"
15851 ],
15852 percentages: "no",
15853 groups: [
15854 "CSS Logical Properties"
15855 ],
15856 initial: [
15857 "border-width",
15858 "border-style",
15859 "color"
15860 ],
15861 appliesto: "allElements",
15862 computed: [
15863 "border-width",
15864 "border-style",
15865 "border-block-start-color"
15866 ],
15867 order: "uniqueOrder",
15868 status: "standard",
15869 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-block-start"
15870 },
15871 "border-block-start-color": {
15872 syntax: "<'border-top-color'>",
15873 media: "visual",
15874 inherited: false,
15875 animationType: "color",
15876 percentages: "no",
15877 groups: [
15878 "CSS Logical Properties"
15879 ],
15880 initial: "currentcolor",
15881 appliesto: "allElements",
15882 computed: "computedColor",
15883 order: "uniqueOrder",
15884 status: "standard",
15885 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-block-start-color"
15886 },
15887 "border-block-start-style": {
15888 syntax: "<'border-top-style'>",
15889 media: "visual",
15890 inherited: false,
15891 animationType: "discrete",
15892 percentages: "no",
15893 groups: [
15894 "CSS Logical Properties"
15895 ],
15896 initial: "none",
15897 appliesto: "allElements",
15898 computed: "asSpecified",
15899 order: "uniqueOrder",
15900 status: "standard",
15901 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-block-start-style"
15902 },
15903 "border-block-start-width": {
15904 syntax: "<'border-top-width'>",
15905 media: "visual",
15906 inherited: false,
15907 animationType: "length",
15908 percentages: "logicalWidthOfContainingBlock",
15909 groups: [
15910 "CSS Logical Properties"
15911 ],
15912 initial: "medium",
15913 appliesto: "allElements",
15914 computed: "absoluteLengthZeroIfBorderStyleNoneOrHidden",
15915 order: "uniqueOrder",
15916 status: "standard",
15917 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-block-start-width"
15918 },
15919 "border-bottom": {
15920 syntax: "<line-width> || <line-style> || <color>",
15921 media: "visual",
15922 inherited: false,
15923 animationType: [
15924 "border-bottom-color",
15925 "border-bottom-style",
15926 "border-bottom-width"
15927 ],
15928 percentages: "no",
15929 groups: [
15930 "CSS Backgrounds and Borders"
15931 ],
15932 initial: [
15933 "border-bottom-width",
15934 "border-bottom-style",
15935 "border-bottom-color"
15936 ],
15937 appliesto: "allElements",
15938 computed: [
15939 "border-bottom-width",
15940 "border-bottom-style",
15941 "border-bottom-color"
15942 ],
15943 order: "orderOfAppearance",
15944 alsoAppliesTo: [
15945 "::first-letter"
15946 ],
15947 status: "standard",
15948 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-bottom"
15949 },
15950 "border-bottom-color": {
15951 syntax: "<'border-top-color'>",
15952 media: "visual",
15953 inherited: false,
15954 animationType: "color",
15955 percentages: "no",
15956 groups: [
15957 "CSS Backgrounds and Borders"
15958 ],
15959 initial: "currentcolor",
15960 appliesto: "allElements",
15961 computed: "computedColor",
15962 order: "uniqueOrder",
15963 alsoAppliesTo: [
15964 "::first-letter"
15965 ],
15966 status: "standard",
15967 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-bottom-color"
15968 },
15969 "border-bottom-left-radius": {
15970 syntax: "<length-percentage>{1,2}",
15971 media: "visual",
15972 inherited: false,
15973 animationType: "lpc",
15974 percentages: "referToDimensionOfBorderBox",
15975 groups: [
15976 "CSS Backgrounds and Borders"
15977 ],
15978 initial: "0",
15979 appliesto: "allElementsUAsNotRequiredWhenCollapse",
15980 computed: "twoAbsoluteLengthOrPercentages",
15981 order: "uniqueOrder",
15982 alsoAppliesTo: [
15983 "::first-letter"
15984 ],
15985 status: "standard",
15986 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-bottom-left-radius"
15987 },
15988 "border-bottom-right-radius": {
15989 syntax: "<length-percentage>{1,2}",
15990 media: "visual",
15991 inherited: false,
15992 animationType: "lpc",
15993 percentages: "referToDimensionOfBorderBox",
15994 groups: [
15995 "CSS Backgrounds and Borders"
15996 ],
15997 initial: "0",
15998 appliesto: "allElementsUAsNotRequiredWhenCollapse",
15999 computed: "twoAbsoluteLengthOrPercentages",
16000 order: "uniqueOrder",
16001 alsoAppliesTo: [
16002 "::first-letter"
16003 ],
16004 status: "standard",
16005 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-bottom-right-radius"
16006 },
16007 "border-bottom-style": {
16008 syntax: "<line-style>",
16009 media: "visual",
16010 inherited: false,
16011 animationType: "discrete",
16012 percentages: "no",
16013 groups: [
16014 "CSS Backgrounds and Borders"
16015 ],
16016 initial: "none",
16017 appliesto: "allElements",
16018 computed: "asSpecified",
16019 order: "uniqueOrder",
16020 alsoAppliesTo: [
16021 "::first-letter"
16022 ],
16023 status: "standard",
16024 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-bottom-style"
16025 },
16026 "border-bottom-width": {
16027 syntax: "<line-width>",
16028 media: "visual",
16029 inherited: false,
16030 animationType: "length",
16031 percentages: "no",
16032 groups: [
16033 "CSS Backgrounds and Borders"
16034 ],
16035 initial: "medium",
16036 appliesto: "allElements",
16037 computed: "absoluteLengthOr0IfBorderBottomStyleNoneOrHidden",
16038 order: "uniqueOrder",
16039 alsoAppliesTo: [
16040 "::first-letter"
16041 ],
16042 status: "standard",
16043 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-bottom-width"
16044 },
16045 "border-collapse": {
16046 syntax: "collapse | separate",
16047 media: "visual",
16048 inherited: true,
16049 animationType: "discrete",
16050 percentages: "no",
16051 groups: [
16052 "CSS Table"
16053 ],
16054 initial: "separate",
16055 appliesto: "tableElements",
16056 computed: "asSpecified",
16057 order: "uniqueOrder",
16058 status: "standard",
16059 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-collapse"
16060 },
16061 "border-color": {
16062 syntax: "<color>{1,4}",
16063 media: "visual",
16064 inherited: false,
16065 animationType: [
16066 "border-bottom-color",
16067 "border-left-color",
16068 "border-right-color",
16069 "border-top-color"
16070 ],
16071 percentages: "no",
16072 groups: [
16073 "CSS Backgrounds and Borders"
16074 ],
16075 initial: [
16076 "border-top-color",
16077 "border-right-color",
16078 "border-bottom-color",
16079 "border-left-color"
16080 ],
16081 appliesto: "allElements",
16082 computed: [
16083 "border-bottom-color",
16084 "border-left-color",
16085 "border-right-color",
16086 "border-top-color"
16087 ],
16088 order: "uniqueOrder",
16089 alsoAppliesTo: [
16090 "::first-letter"
16091 ],
16092 status: "standard",
16093 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-color"
16094 },
16095 "border-end-end-radius": {
16096 syntax: "<length-percentage>{1,2}",
16097 media: "visual",
16098 inherited: false,
16099 animationType: "lpc",
16100 percentages: "referToDimensionOfBorderBox",
16101 groups: [
16102 "CSS Logical Properties"
16103 ],
16104 initial: "0",
16105 appliesto: "allElementsUAsNotRequiredWhenCollapse",
16106 computed: "twoAbsoluteLengthOrPercentages",
16107 order: "uniqueOrder",
16108 alsoAppliesTo: [
16109 "::first-letter"
16110 ],
16111 status: "standard",
16112 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-end-end-radius"
16113 },
16114 "border-end-start-radius": {
16115 syntax: "<length-percentage>{1,2}",
16116 media: "visual",
16117 inherited: false,
16118 animationType: "lpc",
16119 percentages: "referToDimensionOfBorderBox",
16120 groups: [
16121 "CSS Logical Properties"
16122 ],
16123 initial: "0",
16124 appliesto: "allElementsUAsNotRequiredWhenCollapse",
16125 computed: "twoAbsoluteLengthOrPercentages",
16126 order: "uniqueOrder",
16127 alsoAppliesTo: [
16128 "::first-letter"
16129 ],
16130 status: "standard",
16131 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-end-start-radius"
16132 },
16133 "border-image": {
16134 syntax: "<'border-image-source'> || <'border-image-slice'> [ / <'border-image-width'> | / <'border-image-width'>? / <'border-image-outset'> ]? || <'border-image-repeat'>",
16135 media: "visual",
16136 inherited: false,
16137 animationType: "discrete",
16138 percentages: [
16139 "border-image-slice",
16140 "border-image-width"
16141 ],
16142 groups: [
16143 "CSS Backgrounds and Borders"
16144 ],
16145 initial: [
16146 "border-image-source",
16147 "border-image-slice",
16148 "border-image-width",
16149 "border-image-outset",
16150 "border-image-repeat"
16151 ],
16152 appliesto: "allElementsExceptTableElementsWhenCollapse",
16153 computed: [
16154 "border-image-outset",
16155 "border-image-repeat",
16156 "border-image-slice",
16157 "border-image-source",
16158 "border-image-width"
16159 ],
16160 order: "uniqueOrder",
16161 alsoAppliesTo: [
16162 "::first-letter"
16163 ],
16164 status: "standard",
16165 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-image"
16166 },
16167 "border-image-outset": {
16168 syntax: "[ <length> | <number> ]{1,4}",
16169 media: "visual",
16170 inherited: false,
16171 animationType: "byComputedValueType",
16172 percentages: "no",
16173 groups: [
16174 "CSS Backgrounds and Borders"
16175 ],
16176 initial: "0",
16177 appliesto: "allElementsExceptTableElementsWhenCollapse",
16178 computed: "asSpecifiedRelativeToAbsoluteLengths",
16179 order: "uniqueOrder",
16180 alsoAppliesTo: [
16181 "::first-letter"
16182 ],
16183 status: "standard",
16184 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-image-outset"
16185 },
16186 "border-image-repeat": {
16187 syntax: "[ stretch | repeat | round | space ]{1,2}",
16188 media: "visual",
16189 inherited: false,
16190 animationType: "discrete",
16191 percentages: "no",
16192 groups: [
16193 "CSS Backgrounds and Borders"
16194 ],
16195 initial: "stretch",
16196 appliesto: "allElementsExceptTableElementsWhenCollapse",
16197 computed: "asSpecified",
16198 order: "uniqueOrder",
16199 alsoAppliesTo: [
16200 "::first-letter"
16201 ],
16202 status: "standard",
16203 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-image-repeat"
16204 },
16205 "border-image-slice": {
16206 syntax: "<number-percentage>{1,4} && fill?",
16207 media: "visual",
16208 inherited: false,
16209 animationType: "byComputedValueType",
16210 percentages: "referToSizeOfBorderImage",
16211 groups: [
16212 "CSS Backgrounds and Borders"
16213 ],
16214 initial: "100%",
16215 appliesto: "allElementsExceptTableElementsWhenCollapse",
16216 computed: "oneToFourPercentagesOrAbsoluteLengthsPlusFill",
16217 order: "percentagesOrLengthsFollowedByFill",
16218 alsoAppliesTo: [
16219 "::first-letter"
16220 ],
16221 status: "standard",
16222 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-image-slice"
16223 },
16224 "border-image-source": {
16225 syntax: "none | <image>",
16226 media: "visual",
16227 inherited: false,
16228 animationType: "discrete",
16229 percentages: "no",
16230 groups: [
16231 "CSS Backgrounds and Borders"
16232 ],
16233 initial: "none",
16234 appliesto: "allElementsExceptTableElementsWhenCollapse",
16235 computed: "noneOrImageWithAbsoluteURI",
16236 order: "uniqueOrder",
16237 alsoAppliesTo: [
16238 "::first-letter"
16239 ],
16240 status: "standard",
16241 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-image-source"
16242 },
16243 "border-image-width": {
16244 syntax: "[ <length-percentage> | <number> | auto ]{1,4}",
16245 media: "visual",
16246 inherited: false,
16247 animationType: "byComputedValueType",
16248 percentages: "referToWidthOrHeightOfBorderImageArea",
16249 groups: [
16250 "CSS Backgrounds and Borders"
16251 ],
16252 initial: "1",
16253 appliesto: "allElementsExceptTableElementsWhenCollapse",
16254 computed: "asSpecifiedRelativeToAbsoluteLengths",
16255 order: "uniqueOrder",
16256 alsoAppliesTo: [
16257 "::first-letter"
16258 ],
16259 status: "standard",
16260 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-image-width"
16261 },
16262 "border-inline": {
16263 syntax: "<'border-top-width'> || <'border-top-style'> || <'color'>",
16264 media: "visual",
16265 inherited: false,
16266 animationType: "discrete",
16267 percentages: "no",
16268 groups: [
16269 "CSS Logical Properties"
16270 ],
16271 initial: [
16272 "border-top-width",
16273 "border-top-style",
16274 "border-top-color"
16275 ],
16276 appliesto: "allElements",
16277 computed: [
16278 "border-top-width",
16279 "border-top-style",
16280 "border-top-color"
16281 ],
16282 order: "uniqueOrder",
16283 status: "standard",
16284 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-inline"
16285 },
16286 "border-inline-end": {
16287 syntax: "<'border-top-width'> || <'border-top-style'> || <'color'>",
16288 media: "visual",
16289 inherited: false,
16290 animationType: [
16291 "border-inline-end-color",
16292 "border-inline-end-style",
16293 "border-inline-end-width"
16294 ],
16295 percentages: "no",
16296 groups: [
16297 "CSS Logical Properties"
16298 ],
16299 initial: [
16300 "border-width",
16301 "border-style",
16302 "color"
16303 ],
16304 appliesto: "allElements",
16305 computed: [
16306 "border-width",
16307 "border-style",
16308 "border-inline-end-color"
16309 ],
16310 order: "uniqueOrder",
16311 status: "standard",
16312 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-inline-end"
16313 },
16314 "border-inline-color": {
16315 syntax: "<'border-top-color'>{1,2}",
16316 media: "visual",
16317 inherited: false,
16318 animationType: "discrete",
16319 percentages: "no",
16320 groups: [
16321 "CSS Logical Properties"
16322 ],
16323 initial: "currentcolor",
16324 appliesto: "allElements",
16325 computed: "computedColor",
16326 order: "uniqueOrder",
16327 status: "standard",
16328 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-inline-color"
16329 },
16330 "border-inline-style": {
16331 syntax: "<'border-top-style'>",
16332 media: "visual",
16333 inherited: false,
16334 animationType: "discrete",
16335 percentages: "no",
16336 groups: [
16337 "CSS Logical Properties"
16338 ],
16339 initial: "none",
16340 appliesto: "allElements",
16341 computed: "asSpecified",
16342 order: "uniqueOrder",
16343 status: "standard",
16344 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-inline-style"
16345 },
16346 "border-inline-width": {
16347 syntax: "<'border-top-width'>",
16348 media: "visual",
16349 inherited: false,
16350 animationType: "discrete",
16351 percentages: "logicalWidthOfContainingBlock",
16352 groups: [
16353 "CSS Logical Properties"
16354 ],
16355 initial: "medium",
16356 appliesto: "allElements",
16357 computed: "absoluteLengthZeroIfBorderStyleNoneOrHidden",
16358 order: "uniqueOrder",
16359 status: "standard",
16360 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-inline-width"
16361 },
16362 "border-inline-end-color": {
16363 syntax: "<'border-top-color'>",
16364 media: "visual",
16365 inherited: false,
16366 animationType: "color",
16367 percentages: "no",
16368 groups: [
16369 "CSS Logical Properties"
16370 ],
16371 initial: "currentcolor",
16372 appliesto: "allElements",
16373 computed: "computedColor",
16374 order: "uniqueOrder",
16375 status: "standard",
16376 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-inline-end-color"
16377 },
16378 "border-inline-end-style": {
16379 syntax: "<'border-top-style'>",
16380 media: "visual",
16381 inherited: false,
16382 animationType: "discrete",
16383 percentages: "no",
16384 groups: [
16385 "CSS Logical Properties"
16386 ],
16387 initial: "none",
16388 appliesto: "allElements",
16389 computed: "asSpecified",
16390 order: "uniqueOrder",
16391 status: "standard",
16392 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-inline-end-style"
16393 },
16394 "border-inline-end-width": {
16395 syntax: "<'border-top-width'>",
16396 media: "visual",
16397 inherited: false,
16398 animationType: "length",
16399 percentages: "logicalWidthOfContainingBlock",
16400 groups: [
16401 "CSS Logical Properties"
16402 ],
16403 initial: "medium",
16404 appliesto: "allElements",
16405 computed: "absoluteLengthZeroIfBorderStyleNoneOrHidden",
16406 order: "uniqueOrder",
16407 status: "standard",
16408 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-inline-end-width"
16409 },
16410 "border-inline-start": {
16411 syntax: "<'border-top-width'> || <'border-top-style'> || <'color'>",
16412 media: "visual",
16413 inherited: false,
16414 animationType: [
16415 "border-inline-start-color",
16416 "border-inline-start-style",
16417 "border-inline-start-width"
16418 ],
16419 percentages: "no",
16420 groups: [
16421 "CSS Logical Properties"
16422 ],
16423 initial: [
16424 "border-width",
16425 "border-style",
16426 "color"
16427 ],
16428 appliesto: "allElements",
16429 computed: [
16430 "border-width",
16431 "border-style",
16432 "border-inline-start-color"
16433 ],
16434 order: "uniqueOrder",
16435 status: "standard",
16436 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-inline-start"
16437 },
16438 "border-inline-start-color": {
16439 syntax: "<'border-top-color'>",
16440 media: "visual",
16441 inherited: false,
16442 animationType: "color",
16443 percentages: "no",
16444 groups: [
16445 "CSS Logical Properties"
16446 ],
16447 initial: "currentcolor",
16448 appliesto: "allElements",
16449 computed: "computedColor",
16450 order: "uniqueOrder",
16451 status: "standard",
16452 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-inline-start-color"
16453 },
16454 "border-inline-start-style": {
16455 syntax: "<'border-top-style'>",
16456 media: "visual",
16457 inherited: false,
16458 animationType: "discrete",
16459 percentages: "no",
16460 groups: [
16461 "CSS Logical Properties"
16462 ],
16463 initial: "none",
16464 appliesto: "allElements",
16465 computed: "asSpecified",
16466 order: "uniqueOrder",
16467 status: "standard",
16468 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-inline-start-style"
16469 },
16470 "border-inline-start-width": {
16471 syntax: "<'border-top-width'>",
16472 media: "visual",
16473 inherited: false,
16474 animationType: "length",
16475 percentages: "logicalWidthOfContainingBlock",
16476 groups: [
16477 "CSS Logical Properties"
16478 ],
16479 initial: "medium",
16480 appliesto: "allElements",
16481 computed: "absoluteLengthZeroIfBorderStyleNoneOrHidden",
16482 order: "uniqueOrder",
16483 status: "standard",
16484 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-inline-start-width"
16485 },
16486 "border-left": {
16487 syntax: "<line-width> || <line-style> || <color>",
16488 media: "visual",
16489 inherited: false,
16490 animationType: [
16491 "border-left-color",
16492 "border-left-style",
16493 "border-left-width"
16494 ],
16495 percentages: "no",
16496 groups: [
16497 "CSS Backgrounds and Borders"
16498 ],
16499 initial: [
16500 "border-left-width",
16501 "border-left-style",
16502 "border-left-color"
16503 ],
16504 appliesto: "allElements",
16505 computed: [
16506 "border-left-width",
16507 "border-left-style",
16508 "border-left-color"
16509 ],
16510 order: "orderOfAppearance",
16511 alsoAppliesTo: [
16512 "::first-letter"
16513 ],
16514 status: "standard",
16515 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-left"
16516 },
16517 "border-left-color": {
16518 syntax: "<color>",
16519 media: "visual",
16520 inherited: false,
16521 animationType: "color",
16522 percentages: "no",
16523 groups: [
16524 "CSS Backgrounds and Borders"
16525 ],
16526 initial: "currentcolor",
16527 appliesto: "allElements",
16528 computed: "computedColor",
16529 order: "uniqueOrder",
16530 alsoAppliesTo: [
16531 "::first-letter"
16532 ],
16533 status: "standard",
16534 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-left-color"
16535 },
16536 "border-left-style": {
16537 syntax: "<line-style>",
16538 media: "visual",
16539 inherited: false,
16540 animationType: "discrete",
16541 percentages: "no",
16542 groups: [
16543 "CSS Backgrounds and Borders"
16544 ],
16545 initial: "none",
16546 appliesto: "allElements",
16547 computed: "asSpecified",
16548 order: "uniqueOrder",
16549 alsoAppliesTo: [
16550 "::first-letter"
16551 ],
16552 status: "standard",
16553 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-left-style"
16554 },
16555 "border-left-width": {
16556 syntax: "<line-width>",
16557 media: "visual",
16558 inherited: false,
16559 animationType: "length",
16560 percentages: "no",
16561 groups: [
16562 "CSS Backgrounds and Borders"
16563 ],
16564 initial: "medium",
16565 appliesto: "allElements",
16566 computed: "absoluteLengthOr0IfBorderLeftStyleNoneOrHidden",
16567 order: "uniqueOrder",
16568 alsoAppliesTo: [
16569 "::first-letter"
16570 ],
16571 status: "standard",
16572 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-left-width"
16573 },
16574 "border-radius": {
16575 syntax: "<length-percentage>{1,4} [ / <length-percentage>{1,4} ]?",
16576 media: "visual",
16577 inherited: false,
16578 animationType: [
16579 "border-top-left-radius",
16580 "border-top-right-radius",
16581 "border-bottom-right-radius",
16582 "border-bottom-left-radius"
16583 ],
16584 percentages: "referToDimensionOfBorderBox",
16585 groups: [
16586 "CSS Backgrounds and Borders"
16587 ],
16588 initial: [
16589 "border-top-left-radius",
16590 "border-top-right-radius",
16591 "border-bottom-right-radius",
16592 "border-bottom-left-radius"
16593 ],
16594 appliesto: "allElementsUAsNotRequiredWhenCollapse",
16595 computed: [
16596 "border-bottom-left-radius",
16597 "border-bottom-right-radius",
16598 "border-top-left-radius",
16599 "border-top-right-radius"
16600 ],
16601 order: "uniqueOrder",
16602 alsoAppliesTo: [
16603 "::first-letter"
16604 ],
16605 status: "standard",
16606 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-radius"
16607 },
16608 "border-right": {
16609 syntax: "<line-width> || <line-style> || <color>",
16610 media: "visual",
16611 inherited: false,
16612 animationType: [
16613 "border-right-color",
16614 "border-right-style",
16615 "border-right-width"
16616 ],
16617 percentages: "no",
16618 groups: [
16619 "CSS Backgrounds and Borders"
16620 ],
16621 initial: [
16622 "border-right-width",
16623 "border-right-style",
16624 "border-right-color"
16625 ],
16626 appliesto: "allElements",
16627 computed: [
16628 "border-right-width",
16629 "border-right-style",
16630 "border-right-color"
16631 ],
16632 order: "orderOfAppearance",
16633 alsoAppliesTo: [
16634 "::first-letter"
16635 ],
16636 status: "standard",
16637 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-right"
16638 },
16639 "border-right-color": {
16640 syntax: "<color>",
16641 media: "visual",
16642 inherited: false,
16643 animationType: "color",
16644 percentages: "no",
16645 groups: [
16646 "CSS Backgrounds and Borders"
16647 ],
16648 initial: "currentcolor",
16649 appliesto: "allElements",
16650 computed: "computedColor",
16651 order: "uniqueOrder",
16652 alsoAppliesTo: [
16653 "::first-letter"
16654 ],
16655 status: "standard",
16656 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-right-color"
16657 },
16658 "border-right-style": {
16659 syntax: "<line-style>",
16660 media: "visual",
16661 inherited: false,
16662 animationType: "discrete",
16663 percentages: "no",
16664 groups: [
16665 "CSS Backgrounds and Borders"
16666 ],
16667 initial: "none",
16668 appliesto: "allElements",
16669 computed: "asSpecified",
16670 order: "uniqueOrder",
16671 alsoAppliesTo: [
16672 "::first-letter"
16673 ],
16674 status: "standard",
16675 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-right-style"
16676 },
16677 "border-right-width": {
16678 syntax: "<line-width>",
16679 media: "visual",
16680 inherited: false,
16681 animationType: "length",
16682 percentages: "no",
16683 groups: [
16684 "CSS Backgrounds and Borders"
16685 ],
16686 initial: "medium",
16687 appliesto: "allElements",
16688 computed: "absoluteLengthOr0IfBorderRightStyleNoneOrHidden",
16689 order: "uniqueOrder",
16690 alsoAppliesTo: [
16691 "::first-letter"
16692 ],
16693 status: "standard",
16694 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-right-width"
16695 },
16696 "border-spacing": {
16697 syntax: "<length> <length>?",
16698 media: "visual",
16699 inherited: true,
16700 animationType: "discrete",
16701 percentages: "no",
16702 groups: [
16703 "CSS Table"
16704 ],
16705 initial: "0",
16706 appliesto: "tableElements",
16707 computed: "twoAbsoluteLengths",
16708 order: "uniqueOrder",
16709 status: "standard",
16710 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-spacing"
16711 },
16712 "border-start-end-radius": {
16713 syntax: "<length-percentage>{1,2}",
16714 media: "visual",
16715 inherited: false,
16716 animationType: "lpc",
16717 percentages: "referToDimensionOfBorderBox",
16718 groups: [
16719 "CSS Logical Properties"
16720 ],
16721 initial: "0",
16722 appliesto: "allElementsUAsNotRequiredWhenCollapse",
16723 computed: "twoAbsoluteLengthOrPercentages",
16724 order: "uniqueOrder",
16725 alsoAppliesTo: [
16726 "::first-letter"
16727 ],
16728 status: "standard",
16729 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-start-end-radius"
16730 },
16731 "border-start-start-radius": {
16732 syntax: "<length-percentage>{1,2}",
16733 media: "visual",
16734 inherited: false,
16735 animationType: "lpc",
16736 percentages: "referToDimensionOfBorderBox",
16737 groups: [
16738 "CSS Logical Properties"
16739 ],
16740 initial: "0",
16741 appliesto: "allElementsUAsNotRequiredWhenCollapse",
16742 computed: "twoAbsoluteLengthOrPercentages",
16743 order: "uniqueOrder",
16744 alsoAppliesTo: [
16745 "::first-letter"
16746 ],
16747 status: "standard",
16748 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-start-start-radius"
16749 },
16750 "border-style": {
16751 syntax: "<line-style>{1,4}",
16752 media: "visual",
16753 inherited: false,
16754 animationType: "discrete",
16755 percentages: "no",
16756 groups: [
16757 "CSS Backgrounds and Borders"
16758 ],
16759 initial: [
16760 "border-top-style",
16761 "border-right-style",
16762 "border-bottom-style",
16763 "border-left-style"
16764 ],
16765 appliesto: "allElements",
16766 computed: [
16767 "border-bottom-style",
16768 "border-left-style",
16769 "border-right-style",
16770 "border-top-style"
16771 ],
16772 order: "uniqueOrder",
16773 alsoAppliesTo: [
16774 "::first-letter"
16775 ],
16776 status: "standard",
16777 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-style"
16778 },
16779 "border-top": {
16780 syntax: "<line-width> || <line-style> || <color>",
16781 media: "visual",
16782 inherited: false,
16783 animationType: [
16784 "border-top-color",
16785 "border-top-style",
16786 "border-top-width"
16787 ],
16788 percentages: "no",
16789 groups: [
16790 "CSS Backgrounds and Borders"
16791 ],
16792 initial: [
16793 "border-top-width",
16794 "border-top-style",
16795 "border-top-color"
16796 ],
16797 appliesto: "allElements",
16798 computed: [
16799 "border-top-width",
16800 "border-top-style",
16801 "border-top-color"
16802 ],
16803 order: "orderOfAppearance",
16804 alsoAppliesTo: [
16805 "::first-letter"
16806 ],
16807 status: "standard",
16808 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-top"
16809 },
16810 "border-top-color": {
16811 syntax: "<color>",
16812 media: "visual",
16813 inherited: false,
16814 animationType: "color",
16815 percentages: "no",
16816 groups: [
16817 "CSS Backgrounds and Borders"
16818 ],
16819 initial: "currentcolor",
16820 appliesto: "allElements",
16821 computed: "computedColor",
16822 order: "uniqueOrder",
16823 alsoAppliesTo: [
16824 "::first-letter"
16825 ],
16826 status: "standard",
16827 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-top-color"
16828 },
16829 "border-top-left-radius": {
16830 syntax: "<length-percentage>{1,2}",
16831 media: "visual",
16832 inherited: false,
16833 animationType: "lpc",
16834 percentages: "referToDimensionOfBorderBox",
16835 groups: [
16836 "CSS Backgrounds and Borders"
16837 ],
16838 initial: "0",
16839 appliesto: "allElementsUAsNotRequiredWhenCollapse",
16840 computed: "twoAbsoluteLengthOrPercentages",
16841 order: "uniqueOrder",
16842 alsoAppliesTo: [
16843 "::first-letter"
16844 ],
16845 status: "standard",
16846 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-top-left-radius"
16847 },
16848 "border-top-right-radius": {
16849 syntax: "<length-percentage>{1,2}",
16850 media: "visual",
16851 inherited: false,
16852 animationType: "lpc",
16853 percentages: "referToDimensionOfBorderBox",
16854 groups: [
16855 "CSS Backgrounds and Borders"
16856 ],
16857 initial: "0",
16858 appliesto: "allElementsUAsNotRequiredWhenCollapse",
16859 computed: "twoAbsoluteLengthOrPercentages",
16860 order: "uniqueOrder",
16861 alsoAppliesTo: [
16862 "::first-letter"
16863 ],
16864 status: "standard",
16865 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-top-right-radius"
16866 },
16867 "border-top-style": {
16868 syntax: "<line-style>",
16869 media: "visual",
16870 inherited: false,
16871 animationType: "discrete",
16872 percentages: "no",
16873 groups: [
16874 "CSS Backgrounds and Borders"
16875 ],
16876 initial: "none",
16877 appliesto: "allElements",
16878 computed: "asSpecified",
16879 order: "uniqueOrder",
16880 alsoAppliesTo: [
16881 "::first-letter"
16882 ],
16883 status: "standard",
16884 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-top-style"
16885 },
16886 "border-top-width": {
16887 syntax: "<line-width>",
16888 media: "visual",
16889 inherited: false,
16890 animationType: "length",
16891 percentages: "no",
16892 groups: [
16893 "CSS Backgrounds and Borders"
16894 ],
16895 initial: "medium",
16896 appliesto: "allElements",
16897 computed: "absoluteLengthOr0IfBorderTopStyleNoneOrHidden",
16898 order: "uniqueOrder",
16899 alsoAppliesTo: [
16900 "::first-letter"
16901 ],
16902 status: "standard",
16903 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-top-width"
16904 },
16905 "border-width": {
16906 syntax: "<line-width>{1,4}",
16907 media: "visual",
16908 inherited: false,
16909 animationType: [
16910 "border-bottom-width",
16911 "border-left-width",
16912 "border-right-width",
16913 "border-top-width"
16914 ],
16915 percentages: "no",
16916 groups: [
16917 "CSS Backgrounds and Borders"
16918 ],
16919 initial: [
16920 "border-top-width",
16921 "border-right-width",
16922 "border-bottom-width",
16923 "border-left-width"
16924 ],
16925 appliesto: "allElements",
16926 computed: [
16927 "border-bottom-width",
16928 "border-left-width",
16929 "border-right-width",
16930 "border-top-width"
16931 ],
16932 order: "uniqueOrder",
16933 alsoAppliesTo: [
16934 "::first-letter"
16935 ],
16936 status: "standard",
16937 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-width"
16938 },
16939 bottom: bottom,
16940 "box-align": {
16941 syntax: "start | center | end | baseline | stretch",
16942 media: "visual",
16943 inherited: false,
16944 animationType: "discrete",
16945 percentages: "no",
16946 groups: [
16947 "Mozilla Extensions",
16948 "WebKit Extensions"
16949 ],
16950 initial: "stretch",
16951 appliesto: "elementsWithDisplayBoxOrInlineBox",
16952 computed: "asSpecified",
16953 order: "uniqueOrder",
16954 status: "nonstandard",
16955 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/box-align"
16956 },
16957 "box-decoration-break": {
16958 syntax: "slice | clone",
16959 media: "visual",
16960 inherited: false,
16961 animationType: "discrete",
16962 percentages: "no",
16963 groups: [
16964 "CSS Fragmentation"
16965 ],
16966 initial: "slice",
16967 appliesto: "allElements",
16968 computed: "asSpecified",
16969 order: "uniqueOrder",
16970 status: "standard",
16971 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/box-decoration-break"
16972 },
16973 "box-direction": {
16974 syntax: "normal | reverse | inherit",
16975 media: "visual",
16976 inherited: false,
16977 animationType: "discrete",
16978 percentages: "no",
16979 groups: [
16980 "Mozilla Extensions",
16981 "WebKit Extensions"
16982 ],
16983 initial: "normal",
16984 appliesto: "elementsWithDisplayBoxOrInlineBox",
16985 computed: "asSpecified",
16986 order: "uniqueOrder",
16987 status: "nonstandard",
16988 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/box-direction"
16989 },
16990 "box-flex": {
16991 syntax: "<number>",
16992 media: "visual",
16993 inherited: false,
16994 animationType: "discrete",
16995 percentages: "no",
16996 groups: [
16997 "Mozilla Extensions",
16998 "WebKit Extensions"
16999 ],
17000 initial: "0",
17001 appliesto: "directChildrenOfElementsWithDisplayMozBoxMozInlineBox",
17002 computed: "asSpecified",
17003 order: "uniqueOrder",
17004 status: "nonstandard",
17005 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/box-flex"
17006 },
17007 "box-flex-group": {
17008 syntax: "<integer>",
17009 media: "visual",
17010 inherited: false,
17011 animationType: "discrete",
17012 percentages: "no",
17013 groups: [
17014 "Mozilla Extensions",
17015 "WebKit Extensions"
17016 ],
17017 initial: "1",
17018 appliesto: "inFlowChildrenOfBoxElements",
17019 computed: "asSpecified",
17020 order: "uniqueOrder",
17021 status: "nonstandard",
17022 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/box-flex-group"
17023 },
17024 "box-lines": {
17025 syntax: "single | multiple",
17026 media: "visual",
17027 inherited: false,
17028 animationType: "discrete",
17029 percentages: "no",
17030 groups: [
17031 "Mozilla Extensions",
17032 "WebKit Extensions"
17033 ],
17034 initial: "single",
17035 appliesto: "boxElements",
17036 computed: "asSpecified",
17037 order: "uniqueOrder",
17038 status: "nonstandard",
17039 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/box-lines"
17040 },
17041 "box-ordinal-group": {
17042 syntax: "<integer>",
17043 media: "visual",
17044 inherited: false,
17045 animationType: "discrete",
17046 percentages: "no",
17047 groups: [
17048 "Mozilla Extensions",
17049 "WebKit Extensions"
17050 ],
17051 initial: "1",
17052 appliesto: "childrenOfBoxElements",
17053 computed: "asSpecified",
17054 order: "uniqueOrder",
17055 status: "nonstandard",
17056 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/box-ordinal-group"
17057 },
17058 "box-orient": {
17059 syntax: "horizontal | vertical | inline-axis | block-axis | inherit",
17060 media: "visual",
17061 inherited: false,
17062 animationType: "discrete",
17063 percentages: "no",
17064 groups: [
17065 "Mozilla Extensions",
17066 "WebKit Extensions"
17067 ],
17068 initial: "inlineAxisHorizontalInXUL",
17069 appliesto: "elementsWithDisplayBoxOrInlineBox",
17070 computed: "asSpecified",
17071 order: "uniqueOrder",
17072 status: "nonstandard",
17073 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/box-orient"
17074 },
17075 "box-pack": {
17076 syntax: "start | center | end | justify",
17077 media: "visual",
17078 inherited: false,
17079 animationType: "discrete",
17080 percentages: "no",
17081 groups: [
17082 "Mozilla Extensions",
17083 "WebKit Extensions"
17084 ],
17085 initial: "start",
17086 appliesto: "elementsWithDisplayMozBoxMozInlineBox",
17087 computed: "asSpecified",
17088 order: "uniqueOrder",
17089 status: "nonstandard",
17090 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/box-pack"
17091 },
17092 "box-shadow": {
17093 syntax: "none | <shadow>#",
17094 media: "visual",
17095 inherited: false,
17096 animationType: "shadowList",
17097 percentages: "no",
17098 groups: [
17099 "CSS Backgrounds and Borders"
17100 ],
17101 initial: "none",
17102 appliesto: "allElements",
17103 computed: "absoluteLengthsSpecifiedColorAsSpecified",
17104 order: "uniqueOrder",
17105 alsoAppliesTo: [
17106 "::first-letter"
17107 ],
17108 status: "standard",
17109 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/box-shadow"
17110 },
17111 "box-sizing": {
17112 syntax: "content-box | border-box",
17113 media: "visual",
17114 inherited: false,
17115 animationType: "discrete",
17116 percentages: "no",
17117 groups: [
17118 "CSS Basic User Interface"
17119 ],
17120 initial: "content-box",
17121 appliesto: "allElementsAcceptingWidthOrHeight",
17122 computed: "asSpecified",
17123 order: "uniqueOrder",
17124 status: "standard",
17125 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/box-sizing"
17126 },
17127 "break-after": {
17128 syntax: "auto | avoid | always | all | avoid-page | page | left | right | recto | verso | avoid-column | column | avoid-region | region",
17129 media: "visual",
17130 inherited: false,
17131 animationType: "discrete",
17132 percentages: "no",
17133 groups: [
17134 "CSS Fragmentation"
17135 ],
17136 initial: "auto",
17137 appliesto: "blockLevelElements",
17138 computed: "asSpecified",
17139 order: "uniqueOrder",
17140 status: "standard",
17141 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/break-after"
17142 },
17143 "break-before": {
17144 syntax: "auto | avoid | always | all | avoid-page | page | left | right | recto | verso | avoid-column | column | avoid-region | region",
17145 media: "visual",
17146 inherited: false,
17147 animationType: "discrete",
17148 percentages: "no",
17149 groups: [
17150 "CSS Fragmentation"
17151 ],
17152 initial: "auto",
17153 appliesto: "blockLevelElements",
17154 computed: "asSpecified",
17155 order: "uniqueOrder",
17156 status: "standard",
17157 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/break-before"
17158 },
17159 "break-inside": {
17160 syntax: "auto | avoid | avoid-page | avoid-column | avoid-region",
17161 media: "visual",
17162 inherited: false,
17163 animationType: "discrete",
17164 percentages: "no",
17165 groups: [
17166 "CSS Fragmentation"
17167 ],
17168 initial: "auto",
17169 appliesto: "blockLevelElements",
17170 computed: "asSpecified",
17171 order: "uniqueOrder",
17172 status: "standard",
17173 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/break-inside"
17174 },
17175 "caption-side": {
17176 syntax: "top | bottom | block-start | block-end | inline-start | inline-end",
17177 media: "visual",
17178 inherited: true,
17179 animationType: "discrete",
17180 percentages: "no",
17181 groups: [
17182 "CSS Table"
17183 ],
17184 initial: "top",
17185 appliesto: "tableCaptionElements",
17186 computed: "asSpecified",
17187 order: "uniqueOrder",
17188 status: "standard",
17189 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/caption-side"
17190 },
17191 "caret-color": {
17192 syntax: "auto | <color>",
17193 media: "interactive",
17194 inherited: true,
17195 animationType: "color",
17196 percentages: "no",
17197 groups: [
17198 "CSS Basic User Interface"
17199 ],
17200 initial: "auto",
17201 appliesto: "allElements",
17202 computed: "asAutoOrColor",
17203 order: "perGrammar",
17204 status: "standard",
17205 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/caret-color"
17206 },
17207 clear: clear,
17208 clip: clip,
17209 "clip-path": {
17210 syntax: "<clip-source> | [ <basic-shape> || <geometry-box> ] | none",
17211 media: "visual",
17212 inherited: false,
17213 animationType: "basicShapeOtherwiseNo",
17214 percentages: "referToReferenceBoxWhenSpecifiedOtherwiseBorderBox",
17215 groups: [
17216 "CSS Masking"
17217 ],
17218 initial: "none",
17219 appliesto: "allElementsSVGContainerElements",
17220 computed: "asSpecifiedURLsAbsolute",
17221 order: "uniqueOrder",
17222 status: "standard",
17223 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/clip-path"
17224 },
17225 color: color$1,
17226 "color-adjust": {
17227 syntax: "economy | exact",
17228 media: "visual",
17229 inherited: true,
17230 animationType: "discrete",
17231 percentages: "no",
17232 groups: [
17233 "CSS Color"
17234 ],
17235 initial: "economy",
17236 appliesto: "allElements",
17237 computed: "asSpecified",
17238 order: "perGrammar",
17239 status: "standard",
17240 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/color-adjust"
17241 },
17242 "column-count": {
17243 syntax: "<integer> | auto",
17244 media: "visual",
17245 inherited: false,
17246 animationType: "integer",
17247 percentages: "no",
17248 groups: [
17249 "CSS Columns"
17250 ],
17251 initial: "auto",
17252 appliesto: "blockContainersExceptTableWrappers",
17253 computed: "asSpecified",
17254 order: "perGrammar",
17255 status: "standard",
17256 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/column-count"
17257 },
17258 "column-fill": {
17259 syntax: "auto | balance | balance-all",
17260 media: "visualInContinuousMediaNoEffectInOverflowColumns",
17261 inherited: false,
17262 animationType: "discrete",
17263 percentages: "no",
17264 groups: [
17265 "CSS Columns"
17266 ],
17267 initial: "balance",
17268 appliesto: "multicolElements",
17269 computed: "asSpecified",
17270 order: "perGrammar",
17271 status: "standard",
17272 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/column-fill"
17273 },
17274 "column-gap": {
17275 syntax: "normal | <length-percentage>",
17276 media: "visual",
17277 inherited: false,
17278 animationType: "lpc",
17279 percentages: "referToDimensionOfContentArea",
17280 groups: [
17281 "CSS Box Alignment"
17282 ],
17283 initial: "normal",
17284 appliesto: "multiColumnElementsFlexContainersGridContainers",
17285 computed: "asSpecifiedWithLengthsAbsoluteAndNormalComputingToZeroExceptMultiColumn",
17286 order: "perGrammar",
17287 status: "standard",
17288 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/column-gap"
17289 },
17290 "column-rule": {
17291 syntax: "<'column-rule-width'> || <'column-rule-style'> || <'column-rule-color'>",
17292 media: "visual",
17293 inherited: false,
17294 animationType: [
17295 "column-rule-color",
17296 "column-rule-style",
17297 "column-rule-width"
17298 ],
17299 percentages: "no",
17300 groups: [
17301 "CSS Columns"
17302 ],
17303 initial: [
17304 "column-rule-width",
17305 "column-rule-style",
17306 "column-rule-color"
17307 ],
17308 appliesto: "multicolElements",
17309 computed: [
17310 "column-rule-color",
17311 "column-rule-style",
17312 "column-rule-width"
17313 ],
17314 order: "perGrammar",
17315 status: "standard",
17316 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/column-rule"
17317 },
17318 "column-rule-color": {
17319 syntax: "<color>",
17320 media: "visual",
17321 inherited: false,
17322 animationType: "color",
17323 percentages: "no",
17324 groups: [
17325 "CSS Columns"
17326 ],
17327 initial: "currentcolor",
17328 appliesto: "multicolElements",
17329 computed: "computedColor",
17330 order: "perGrammar",
17331 status: "standard",
17332 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/column-rule-color"
17333 },
17334 "column-rule-style": {
17335 syntax: "<'border-style'>",
17336 media: "visual",
17337 inherited: false,
17338 animationType: "discrete",
17339 percentages: "no",
17340 groups: [
17341 "CSS Columns"
17342 ],
17343 initial: "none",
17344 appliesto: "multicolElements",
17345 computed: "asSpecified",
17346 order: "perGrammar",
17347 status: "standard",
17348 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/column-rule-style"
17349 },
17350 "column-rule-width": {
17351 syntax: "<'border-width'>",
17352 media: "visual",
17353 inherited: false,
17354 animationType: "length",
17355 percentages: "no",
17356 groups: [
17357 "CSS Columns"
17358 ],
17359 initial: "medium",
17360 appliesto: "multicolElements",
17361 computed: "absoluteLength0IfColumnRuleStyleNoneOrHidden",
17362 order: "perGrammar",
17363 status: "standard",
17364 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/column-rule-width"
17365 },
17366 "column-span": {
17367 syntax: "none | all",
17368 media: "visual",
17369 inherited: false,
17370 animationType: "discrete",
17371 percentages: "no",
17372 groups: [
17373 "CSS Columns"
17374 ],
17375 initial: "none",
17376 appliesto: "inFlowBlockLevelElements",
17377 computed: "asSpecified",
17378 order: "perGrammar",
17379 status: "standard",
17380 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/column-span"
17381 },
17382 "column-width": {
17383 syntax: "<length> | auto",
17384 media: "visual",
17385 inherited: false,
17386 animationType: "length",
17387 percentages: "no",
17388 groups: [
17389 "CSS Columns"
17390 ],
17391 initial: "auto",
17392 appliesto: "blockContainersExceptTableWrappers",
17393 computed: "absoluteLengthZeroOrLarger",
17394 order: "perGrammar",
17395 status: "standard",
17396 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/column-width"
17397 },
17398 columns: columns,
17399 contain: contain,
17400 content: content,
17401 "counter-increment": {
17402 syntax: "[ <custom-ident> <integer>? ]+ | none",
17403 media: "all",
17404 inherited: false,
17405 animationType: "discrete",
17406 percentages: "no",
17407 groups: [
17408 "CSS Counter Styles"
17409 ],
17410 initial: "none",
17411 appliesto: "allElements",
17412 computed: "asSpecified",
17413 order: "uniqueOrder",
17414 status: "standard",
17415 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/counter-increment"
17416 },
17417 "counter-reset": {
17418 syntax: "[ <custom-ident> <integer>? ]+ | none",
17419 media: "all",
17420 inherited: false,
17421 animationType: "discrete",
17422 percentages: "no",
17423 groups: [
17424 "CSS Counter Styles"
17425 ],
17426 initial: "none",
17427 appliesto: "allElements",
17428 computed: "asSpecified",
17429 order: "uniqueOrder",
17430 status: "standard",
17431 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/counter-reset"
17432 },
17433 "counter-set": {
17434 syntax: "[ <custom-ident> <integer>? ]+ | none",
17435 media: "all",
17436 inherited: false,
17437 animationType: "discrete",
17438 percentages: "no",
17439 groups: [
17440 "CSS Counter Styles"
17441 ],
17442 initial: "none",
17443 appliesto: "allElements",
17444 computed: "asSpecified",
17445 order: "uniqueOrder",
17446 status: "standard",
17447 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/counter-set"
17448 },
17449 cursor: cursor,
17450 direction: direction,
17451 display: display,
17452 "empty-cells": {
17453 syntax: "show | hide",
17454 media: "visual",
17455 inherited: true,
17456 animationType: "discrete",
17457 percentages: "no",
17458 groups: [
17459 "CSS Table"
17460 ],
17461 initial: "show",
17462 appliesto: "tableCellElements",
17463 computed: "asSpecified",
17464 order: "uniqueOrder",
17465 status: "standard",
17466 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/empty-cells"
17467 },
17468 filter: filter,
17469 flex: flex,
17470 "flex-basis": {
17471 syntax: "content | <'width'>",
17472 media: "visual",
17473 inherited: false,
17474 animationType: "lpc",
17475 percentages: "referToFlexContainersInnerMainSize",
17476 groups: [
17477 "CSS Flexible Box Layout"
17478 ],
17479 initial: "auto",
17480 appliesto: "flexItemsAndInFlowPseudos",
17481 computed: "asSpecifiedRelativeToAbsoluteLengths",
17482 order: "lengthOrPercentageBeforeKeywordIfBothPresent",
17483 status: "standard",
17484 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/flex-basis"
17485 },
17486 "flex-direction": {
17487 syntax: "row | row-reverse | column | column-reverse",
17488 media: "visual",
17489 inherited: false,
17490 animationType: "discrete",
17491 percentages: "no",
17492 groups: [
17493 "CSS Flexible Box Layout"
17494 ],
17495 initial: "row",
17496 appliesto: "flexContainers",
17497 computed: "asSpecified",
17498 order: "uniqueOrder",
17499 status: "standard",
17500 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/flex-direction"
17501 },
17502 "flex-flow": {
17503 syntax: "<'flex-direction'> || <'flex-wrap'>",
17504 media: "visual",
17505 inherited: false,
17506 animationType: "discrete",
17507 percentages: "no",
17508 groups: [
17509 "CSS Flexible Box Layout"
17510 ],
17511 initial: [
17512 "flex-direction",
17513 "flex-wrap"
17514 ],
17515 appliesto: "flexContainers",
17516 computed: [
17517 "flex-direction",
17518 "flex-wrap"
17519 ],
17520 order: "orderOfAppearance",
17521 status: "standard",
17522 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/flex-flow"
17523 },
17524 "flex-grow": {
17525 syntax: "<number>",
17526 media: "visual",
17527 inherited: false,
17528 animationType: "number",
17529 percentages: "no",
17530 groups: [
17531 "CSS Flexible Box Layout"
17532 ],
17533 initial: "0",
17534 appliesto: "flexItemsAndInFlowPseudos",
17535 computed: "asSpecified",
17536 order: "uniqueOrder",
17537 status: "standard",
17538 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/flex-grow"
17539 },
17540 "flex-shrink": {
17541 syntax: "<number>",
17542 media: "visual",
17543 inherited: false,
17544 animationType: "number",
17545 percentages: "no",
17546 groups: [
17547 "CSS Flexible Box Layout"
17548 ],
17549 initial: "1",
17550 appliesto: "flexItemsAndInFlowPseudos",
17551 computed: "asSpecified",
17552 order: "uniqueOrder",
17553 status: "standard",
17554 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/flex-shrink"
17555 },
17556 "flex-wrap": {
17557 syntax: "nowrap | wrap | wrap-reverse",
17558 media: "visual",
17559 inherited: false,
17560 animationType: "discrete",
17561 percentages: "no",
17562 groups: [
17563 "CSS Flexible Box Layout"
17564 ],
17565 initial: "nowrap",
17566 appliesto: "flexContainers",
17567 computed: "asSpecified",
17568 order: "uniqueOrder",
17569 status: "standard",
17570 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/flex-wrap"
17571 },
17572 float: float,
17573 font: font,
17574 "font-family": {
17575 syntax: "[ <family-name> | <generic-family> ]#",
17576 media: "visual",
17577 inherited: true,
17578 animationType: "discrete",
17579 percentages: "no",
17580 groups: [
17581 "CSS Fonts"
17582 ],
17583 initial: "dependsOnUserAgent",
17584 appliesto: "allElements",
17585 computed: "asSpecified",
17586 order: "uniqueOrder",
17587 alsoAppliesTo: [
17588 "::first-letter",
17589 "::first-line",
17590 "::placeholder"
17591 ],
17592 status: "standard",
17593 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-family"
17594 },
17595 "font-feature-settings": {
17596 syntax: "normal | <feature-tag-value>#",
17597 media: "visual",
17598 inherited: true,
17599 animationType: "discrete",
17600 percentages: "no",
17601 groups: [
17602 "CSS Fonts"
17603 ],
17604 initial: "normal",
17605 appliesto: "allElements",
17606 computed: "asSpecified",
17607 order: "uniqueOrder",
17608 alsoAppliesTo: [
17609 "::first-letter",
17610 "::first-line",
17611 "::placeholder"
17612 ],
17613 status: "standard",
17614 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-feature-settings"
17615 },
17616 "font-kerning": {
17617 syntax: "auto | normal | none",
17618 media: "visual",
17619 inherited: true,
17620 animationType: "discrete",
17621 percentages: "no",
17622 groups: [
17623 "CSS Fonts"
17624 ],
17625 initial: "auto",
17626 appliesto: "allElements",
17627 computed: "asSpecified",
17628 order: "uniqueOrder",
17629 alsoAppliesTo: [
17630 "::first-letter",
17631 "::first-line",
17632 "::placeholder"
17633 ],
17634 status: "standard",
17635 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-kerning"
17636 },
17637 "font-language-override": {
17638 syntax: "normal | <string>",
17639 media: "visual",
17640 inherited: true,
17641 animationType: "discrete",
17642 percentages: "no",
17643 groups: [
17644 "CSS Fonts"
17645 ],
17646 initial: "normal",
17647 appliesto: "allElements",
17648 computed: "asSpecified",
17649 order: "uniqueOrder",
17650 alsoAppliesTo: [
17651 "::first-letter",
17652 "::first-line",
17653 "::placeholder"
17654 ],
17655 status: "standard",
17656 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-language-override"
17657 },
17658 "font-optical-sizing": {
17659 syntax: "auto | none",
17660 media: "visual",
17661 inherited: true,
17662 animationType: "discrete",
17663 percentages: "no",
17664 groups: [
17665 "CSS Fonts"
17666 ],
17667 initial: "auto",
17668 appliesto: "allElements",
17669 computed: "asSpecified",
17670 order: "perGrammar",
17671 alsoAppliesTo: [
17672 "::first-letter",
17673 "::first-line",
17674 "::placeholder"
17675 ],
17676 status: "standard",
17677 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-optical-sizing"
17678 },
17679 "font-variation-settings": {
17680 syntax: "normal | [ <string> <number> ]#",
17681 media: "visual",
17682 inherited: true,
17683 animationType: "transform",
17684 percentages: "no",
17685 groups: [
17686 "CSS Fonts"
17687 ],
17688 initial: "normal",
17689 appliesto: "allElements",
17690 computed: "asSpecified",
17691 order: "perGrammar",
17692 alsoAppliesTo: [
17693 "::first-letter",
17694 "::first-line",
17695 "::placeholder"
17696 ],
17697 status: "standard",
17698 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-variation-settings"
17699 },
17700 "font-size": {
17701 syntax: "<absolute-size> | <relative-size> | <length-percentage>",
17702 media: "visual",
17703 inherited: true,
17704 animationType: "length",
17705 percentages: "referToParentElementsFontSize",
17706 groups: [
17707 "CSS Fonts"
17708 ],
17709 initial: "medium",
17710 appliesto: "allElements",
17711 computed: "asSpecifiedRelativeToAbsoluteLengths",
17712 order: "uniqueOrder",
17713 alsoAppliesTo: [
17714 "::first-letter",
17715 "::first-line",
17716 "::placeholder"
17717 ],
17718 status: "standard",
17719 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-size"
17720 },
17721 "font-size-adjust": {
17722 syntax: "none | <number>",
17723 media: "visual",
17724 inherited: true,
17725 animationType: "number",
17726 percentages: "no",
17727 groups: [
17728 "CSS Fonts"
17729 ],
17730 initial: "none",
17731 appliesto: "allElements",
17732 computed: "asSpecified",
17733 order: "uniqueOrder",
17734 alsoAppliesTo: [
17735 "::first-letter",
17736 "::first-line",
17737 "::placeholder"
17738 ],
17739 status: "standard",
17740 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-size-adjust"
17741 },
17742 "font-smooth": {
17743 syntax: "auto | never | always | <absolute-size> | <length>",
17744 media: "visual",
17745 inherited: true,
17746 animationType: "discrete",
17747 percentages: "no",
17748 groups: [
17749 "CSS Fonts"
17750 ],
17751 initial: "auto",
17752 appliesto: "allElements",
17753 computed: "asSpecified",
17754 order: "uniqueOrder",
17755 status: "nonstandard",
17756 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-smooth"
17757 },
17758 "font-stretch": {
17759 syntax: "<font-stretch-absolute>",
17760 media: "visual",
17761 inherited: true,
17762 animationType: "fontStretch",
17763 percentages: "no",
17764 groups: [
17765 "CSS Fonts"
17766 ],
17767 initial: "normal",
17768 appliesto: "allElements",
17769 computed: "asSpecified",
17770 order: "uniqueOrder",
17771 alsoAppliesTo: [
17772 "::first-letter",
17773 "::first-line",
17774 "::placeholder"
17775 ],
17776 status: "standard",
17777 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-stretch"
17778 },
17779 "font-style": {
17780 syntax: "normal | italic | oblique <angle>?",
17781 media: "visual",
17782 inherited: true,
17783 animationType: "discrete",
17784 percentages: "no",
17785 groups: [
17786 "CSS Fonts"
17787 ],
17788 initial: "normal",
17789 appliesto: "allElements",
17790 computed: "asSpecified",
17791 order: "uniqueOrder",
17792 alsoAppliesTo: [
17793 "::first-letter",
17794 "::first-line",
17795 "::placeholder"
17796 ],
17797 status: "standard",
17798 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-style"
17799 },
17800 "font-synthesis": {
17801 syntax: "none | [ weight || style ]",
17802 media: "visual",
17803 inherited: true,
17804 animationType: "discrete",
17805 percentages: "no",
17806 groups: [
17807 "CSS Fonts"
17808 ],
17809 initial: "weight style",
17810 appliesto: "allElements",
17811 computed: "asSpecified",
17812 order: "orderOfAppearance",
17813 alsoAppliesTo: [
17814 "::first-letter",
17815 "::first-line",
17816 "::placeholder"
17817 ],
17818 status: "standard",
17819 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-synthesis"
17820 },
17821 "font-variant": {
17822 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 ]",
17823 media: "visual",
17824 inherited: true,
17825 animationType: "discrete",
17826 percentages: "no",
17827 groups: [
17828 "CSS Fonts"
17829 ],
17830 initial: "normal",
17831 appliesto: "allElements",
17832 computed: "asSpecified",
17833 order: "uniqueOrder",
17834 alsoAppliesTo: [
17835 "::first-letter",
17836 "::first-line",
17837 "::placeholder"
17838 ],
17839 status: "standard",
17840 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-variant"
17841 },
17842 "font-variant-alternates": {
17843 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> ) ]",
17844 media: "visual",
17845 inherited: true,
17846 animationType: "discrete",
17847 percentages: "no",
17848 groups: [
17849 "CSS Fonts"
17850 ],
17851 initial: "normal",
17852 appliesto: "allElements",
17853 computed: "asSpecified",
17854 order: "orderOfAppearance",
17855 alsoAppliesTo: [
17856 "::first-letter",
17857 "::first-line",
17858 "::placeholder"
17859 ],
17860 status: "standard",
17861 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-variant-alternates"
17862 },
17863 "font-variant-caps": {
17864 syntax: "normal | small-caps | all-small-caps | petite-caps | all-petite-caps | unicase | titling-caps",
17865 media: "visual",
17866 inherited: true,
17867 animationType: "discrete",
17868 percentages: "no",
17869 groups: [
17870 "CSS Fonts"
17871 ],
17872 initial: "normal",
17873 appliesto: "allElements",
17874 computed: "asSpecified",
17875 order: "uniqueOrder",
17876 alsoAppliesTo: [
17877 "::first-letter",
17878 "::first-line",
17879 "::placeholder"
17880 ],
17881 status: "standard",
17882 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-variant-caps"
17883 },
17884 "font-variant-east-asian": {
17885 syntax: "normal | [ <east-asian-variant-values> || <east-asian-width-values> || ruby ]",
17886 media: "visual",
17887 inherited: true,
17888 animationType: "discrete",
17889 percentages: "no",
17890 groups: [
17891 "CSS Fonts"
17892 ],
17893 initial: "normal",
17894 appliesto: "allElements",
17895 computed: "asSpecified",
17896 order: "orderOfAppearance",
17897 alsoAppliesTo: [
17898 "::first-letter",
17899 "::first-line",
17900 "::placeholder"
17901 ],
17902 status: "standard",
17903 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-variant-east-asian"
17904 },
17905 "font-variant-ligatures": {
17906 syntax: "normal | none | [ <common-lig-values> || <discretionary-lig-values> || <historical-lig-values> || <contextual-alt-values> ]",
17907 media: "visual",
17908 inherited: true,
17909 animationType: "discrete",
17910 percentages: "no",
17911 groups: [
17912 "CSS Fonts"
17913 ],
17914 initial: "normal",
17915 appliesto: "allElements",
17916 computed: "asSpecified",
17917 order: "orderOfAppearance",
17918 alsoAppliesTo: [
17919 "::first-letter",
17920 "::first-line",
17921 "::placeholder"
17922 ],
17923 status: "standard",
17924 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-variant-ligatures"
17925 },
17926 "font-variant-numeric": {
17927 syntax: "normal | [ <numeric-figure-values> || <numeric-spacing-values> || <numeric-fraction-values> || ordinal || slashed-zero ]",
17928 media: "visual",
17929 inherited: true,
17930 animationType: "discrete",
17931 percentages: "no",
17932 groups: [
17933 "CSS Fonts"
17934 ],
17935 initial: "normal",
17936 appliesto: "allElements",
17937 computed: "asSpecified",
17938 order: "orderOfAppearance",
17939 alsoAppliesTo: [
17940 "::first-letter",
17941 "::first-line",
17942 "::placeholder"
17943 ],
17944 status: "standard",
17945 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-variant-numeric"
17946 },
17947 "font-variant-position": {
17948 syntax: "normal | sub | super",
17949 media: "visual",
17950 inherited: true,
17951 animationType: "discrete",
17952 percentages: "no",
17953 groups: [
17954 "CSS Fonts"
17955 ],
17956 initial: "normal",
17957 appliesto: "allElements",
17958 computed: "asSpecified",
17959 order: "uniqueOrder",
17960 alsoAppliesTo: [
17961 "::first-letter",
17962 "::first-line",
17963 "::placeholder"
17964 ],
17965 status: "standard",
17966 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-variant-position"
17967 },
17968 "font-weight": {
17969 syntax: "<font-weight-absolute> | bolder | lighter",
17970 media: "visual",
17971 inherited: true,
17972 animationType: "fontWeight",
17973 percentages: "no",
17974 groups: [
17975 "CSS Fonts"
17976 ],
17977 initial: "normal",
17978 appliesto: "allElements",
17979 computed: "keywordOrNumericalValueBolderLighterTransformedToRealValue",
17980 order: "uniqueOrder",
17981 alsoAppliesTo: [
17982 "::first-letter",
17983 "::first-line",
17984 "::placeholder"
17985 ],
17986 status: "standard",
17987 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-weight"
17988 },
17989 gap: gap,
17990 grid: grid,
17991 "grid-area": {
17992 syntax: "<grid-line> [ / <grid-line> ]{0,3}",
17993 media: "visual",
17994 inherited: false,
17995 animationType: "discrete",
17996 percentages: "no",
17997 groups: [
17998 "CSS Grid Layout"
17999 ],
18000 initial: [
18001 "grid-row-start",
18002 "grid-column-start",
18003 "grid-row-end",
18004 "grid-column-end"
18005 ],
18006 appliesto: "gridItemsAndBoxesWithinGridContainer",
18007 computed: [
18008 "grid-row-start",
18009 "grid-column-start",
18010 "grid-row-end",
18011 "grid-column-end"
18012 ],
18013 order: "uniqueOrder",
18014 status: "standard",
18015 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-area"
18016 },
18017 "grid-auto-columns": {
18018 syntax: "<track-size>+",
18019 media: "visual",
18020 inherited: false,
18021 animationType: "discrete",
18022 percentages: "referToDimensionOfContentArea",
18023 groups: [
18024 "CSS Grid Layout"
18025 ],
18026 initial: "auto",
18027 appliesto: "gridContainers",
18028 computed: "percentageAsSpecifiedOrAbsoluteLength",
18029 order: "uniqueOrder",
18030 status: "standard",
18031 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-auto-columns"
18032 },
18033 "grid-auto-flow": {
18034 syntax: "[ row | column ] || dense",
18035 media: "visual",
18036 inherited: false,
18037 animationType: "discrete",
18038 percentages: "no",
18039 groups: [
18040 "CSS Grid Layout"
18041 ],
18042 initial: "row",
18043 appliesto: "gridContainers",
18044 computed: "asSpecified",
18045 order: "uniqueOrder",
18046 status: "standard",
18047 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-auto-flow"
18048 },
18049 "grid-auto-rows": {
18050 syntax: "<track-size>+",
18051 media: "visual",
18052 inherited: false,
18053 animationType: "discrete",
18054 percentages: "referToDimensionOfContentArea",
18055 groups: [
18056 "CSS Grid Layout"
18057 ],
18058 initial: "auto",
18059 appliesto: "gridContainers",
18060 computed: "percentageAsSpecifiedOrAbsoluteLength",
18061 order: "uniqueOrder",
18062 status: "standard",
18063 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-auto-rows"
18064 },
18065 "grid-column": {
18066 syntax: "<grid-line> [ / <grid-line> ]?",
18067 media: "visual",
18068 inherited: false,
18069 animationType: "discrete",
18070 percentages: "no",
18071 groups: [
18072 "CSS Grid Layout"
18073 ],
18074 initial: [
18075 "grid-column-start",
18076 "grid-column-end"
18077 ],
18078 appliesto: "gridItemsAndBoxesWithinGridContainer",
18079 computed: [
18080 "grid-column-start",
18081 "grid-column-end"
18082 ],
18083 order: "uniqueOrder",
18084 status: "standard",
18085 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-column"
18086 },
18087 "grid-column-end": {
18088 syntax: "<grid-line>",
18089 media: "visual",
18090 inherited: false,
18091 animationType: "discrete",
18092 percentages: "no",
18093 groups: [
18094 "CSS Grid Layout"
18095 ],
18096 initial: "auto",
18097 appliesto: "gridItemsAndBoxesWithinGridContainer",
18098 computed: "asSpecified",
18099 order: "uniqueOrder",
18100 status: "standard",
18101 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-column-end"
18102 },
18103 "grid-column-gap": {
18104 syntax: "<length-percentage>",
18105 media: "visual",
18106 inherited: false,
18107 animationType: "length",
18108 percentages: "referToDimensionOfContentArea",
18109 groups: [
18110 "CSS Grid Layout"
18111 ],
18112 initial: "0",
18113 appliesto: "gridContainers",
18114 computed: "percentageAsSpecifiedOrAbsoluteLength",
18115 order: "uniqueOrder",
18116 status: "obsolete",
18117 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/column-gap"
18118 },
18119 "grid-column-start": {
18120 syntax: "<grid-line>",
18121 media: "visual",
18122 inherited: false,
18123 animationType: "discrete",
18124 percentages: "no",
18125 groups: [
18126 "CSS Grid Layout"
18127 ],
18128 initial: "auto",
18129 appliesto: "gridItemsAndBoxesWithinGridContainer",
18130 computed: "asSpecified",
18131 order: "uniqueOrder",
18132 status: "standard",
18133 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-column-start"
18134 },
18135 "grid-gap": {
18136 syntax: "<'grid-row-gap'> <'grid-column-gap'>?",
18137 media: "visual",
18138 inherited: false,
18139 animationType: [
18140 "grid-row-gap",
18141 "grid-column-gap"
18142 ],
18143 percentages: "no",
18144 groups: [
18145 "CSS Grid Layout"
18146 ],
18147 initial: [
18148 "grid-row-gap",
18149 "grid-column-gap"
18150 ],
18151 appliesto: "gridContainers",
18152 computed: [
18153 "grid-row-gap",
18154 "grid-column-gap"
18155 ],
18156 order: "uniqueOrder",
18157 status: "obsolete",
18158 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/gap"
18159 },
18160 "grid-row": {
18161 syntax: "<grid-line> [ / <grid-line> ]?",
18162 media: "visual",
18163 inherited: false,
18164 animationType: "discrete",
18165 percentages: "no",
18166 groups: [
18167 "CSS Grid Layout"
18168 ],
18169 initial: [
18170 "grid-row-start",
18171 "grid-row-end"
18172 ],
18173 appliesto: "gridItemsAndBoxesWithinGridContainer",
18174 computed: [
18175 "grid-row-start",
18176 "grid-row-end"
18177 ],
18178 order: "uniqueOrder",
18179 status: "standard",
18180 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-row"
18181 },
18182 "grid-row-end": {
18183 syntax: "<grid-line>",
18184 media: "visual",
18185 inherited: false,
18186 animationType: "discrete",
18187 percentages: "no",
18188 groups: [
18189 "CSS Grid Layout"
18190 ],
18191 initial: "auto",
18192 appliesto: "gridItemsAndBoxesWithinGridContainer",
18193 computed: "asSpecified",
18194 order: "uniqueOrder",
18195 status: "standard",
18196 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-row-end"
18197 },
18198 "grid-row-gap": {
18199 syntax: "<length-percentage>",
18200 media: "visual",
18201 inherited: false,
18202 animationType: "length",
18203 percentages: "referToDimensionOfContentArea",
18204 groups: [
18205 "CSS Grid Layout"
18206 ],
18207 initial: "0",
18208 appliesto: "gridContainers",
18209 computed: "percentageAsSpecifiedOrAbsoluteLength",
18210 order: "uniqueOrder",
18211 status: "obsolete",
18212 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/row-gap"
18213 },
18214 "grid-row-start": {
18215 syntax: "<grid-line>",
18216 media: "visual",
18217 inherited: false,
18218 animationType: "discrete",
18219 percentages: "no",
18220 groups: [
18221 "CSS Grid Layout"
18222 ],
18223 initial: "auto",
18224 appliesto: "gridItemsAndBoxesWithinGridContainer",
18225 computed: "asSpecified",
18226 order: "uniqueOrder",
18227 status: "standard",
18228 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-row-start"
18229 },
18230 "grid-template": {
18231 syntax: "none | [ <'grid-template-rows'> / <'grid-template-columns'> ] | [ <line-names>? <string> <track-size>? <line-names>? ]+ [ / <explicit-track-list> ]?",
18232 media: "visual",
18233 inherited: false,
18234 animationType: "discrete",
18235 percentages: [
18236 "grid-template-columns",
18237 "grid-template-rows"
18238 ],
18239 groups: [
18240 "CSS Grid Layout"
18241 ],
18242 initial: [
18243 "grid-template-columns",
18244 "grid-template-rows",
18245 "grid-template-areas"
18246 ],
18247 appliesto: "gridContainers",
18248 computed: [
18249 "grid-template-columns",
18250 "grid-template-rows",
18251 "grid-template-areas"
18252 ],
18253 order: "uniqueOrder",
18254 status: "standard",
18255 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-template"
18256 },
18257 "grid-template-areas": {
18258 syntax: "none | <string>+",
18259 media: "visual",
18260 inherited: false,
18261 animationType: "discrete",
18262 percentages: "no",
18263 groups: [
18264 "CSS Grid Layout"
18265 ],
18266 initial: "none",
18267 appliesto: "gridContainers",
18268 computed: "asSpecified",
18269 order: "uniqueOrder",
18270 status: "standard",
18271 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-template-areas"
18272 },
18273 "grid-template-columns": {
18274 syntax: "none | <track-list> | <auto-track-list> | subgrid <line-name-list>?",
18275 media: "visual",
18276 inherited: false,
18277 animationType: "simpleListOfLpcDifferenceLpc",
18278 percentages: "referToDimensionOfContentArea",
18279 groups: [
18280 "CSS Grid Layout"
18281 ],
18282 initial: "none",
18283 appliesto: "gridContainers",
18284 computed: "asSpecifiedRelativeToAbsoluteLengths",
18285 order: "uniqueOrder",
18286 status: "standard",
18287 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-template-columns"
18288 },
18289 "grid-template-rows": {
18290 syntax: "none | <track-list> | <auto-track-list> | subgrid <line-name-list>?",
18291 media: "visual",
18292 inherited: false,
18293 animationType: "simpleListOfLpcDifferenceLpc",
18294 percentages: "referToDimensionOfContentArea",
18295 groups: [
18296 "CSS Grid Layout"
18297 ],
18298 initial: "none",
18299 appliesto: "gridContainers",
18300 computed: "asSpecifiedRelativeToAbsoluteLengths",
18301 order: "uniqueOrder",
18302 status: "standard",
18303 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-template-rows"
18304 },
18305 "hanging-punctuation": {
18306 syntax: "none | [ first || [ force-end | allow-end ] || last ]",
18307 media: "visual",
18308 inherited: true,
18309 animationType: "discrete",
18310 percentages: "no",
18311 groups: [
18312 "CSS Text"
18313 ],
18314 initial: "none",
18315 appliesto: "allElements",
18316 computed: "asSpecified",
18317 order: "uniqueOrder",
18318 status: "standard",
18319 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/hanging-punctuation"
18320 },
18321 height: height,
18322 hyphens: hyphens,
18323 "image-orientation": {
18324 syntax: "from-image | <angle> | [ <angle>? flip ]",
18325 media: "visual",
18326 inherited: true,
18327 animationType: "discrete",
18328 percentages: "no",
18329 groups: [
18330 "CSS Images"
18331 ],
18332 initial: "from-image",
18333 appliesto: "allElements",
18334 computed: "angleRoundedToNextQuarter",
18335 order: "uniqueOrder",
18336 status: "standard",
18337 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/image-orientation"
18338 },
18339 "image-rendering": {
18340 syntax: "auto | crisp-edges | pixelated",
18341 media: "visual",
18342 inherited: true,
18343 animationType: "discrete",
18344 percentages: "no",
18345 groups: [
18346 "CSS Images"
18347 ],
18348 initial: "auto",
18349 appliesto: "allElements",
18350 computed: "asSpecified",
18351 order: "uniqueOrder",
18352 status: "standard",
18353 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/image-rendering"
18354 },
18355 "image-resolution": {
18356 syntax: "[ from-image || <resolution> ] && snap?",
18357 media: "visual",
18358 inherited: true,
18359 animationType: "discrete",
18360 percentages: "no",
18361 groups: [
18362 "CSS Images"
18363 ],
18364 initial: "1dppx",
18365 appliesto: "allElements",
18366 computed: "asSpecifiedWithExceptionOfResolution",
18367 order: "uniqueOrder",
18368 status: "experimental"
18369 },
18370 "ime-mode": {
18371 syntax: "auto | normal | active | inactive | disabled",
18372 media: "interactive",
18373 inherited: false,
18374 animationType: "discrete",
18375 percentages: "no",
18376 groups: [
18377 "CSS Basic User Interface"
18378 ],
18379 initial: "auto",
18380 appliesto: "textFields",
18381 computed: "asSpecified",
18382 order: "uniqueOrder",
18383 status: "obsolete",
18384 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/ime-mode"
18385 },
18386 "initial-letter": {
18387 syntax: "normal | [ <number> <integer>? ]",
18388 media: "visual",
18389 inherited: false,
18390 animationType: "discrete",
18391 percentages: "no",
18392 groups: [
18393 "CSS Inline"
18394 ],
18395 initial: "normal",
18396 appliesto: "firstLetterPseudoElementsAndInlineLevelFirstChildren",
18397 computed: "asSpecified",
18398 order: "uniqueOrder",
18399 status: "experimental",
18400 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/initial-letter"
18401 },
18402 "initial-letter-align": {
18403 syntax: "[ auto | alphabetic | hanging | ideographic ]",
18404 media: "visual",
18405 inherited: false,
18406 animationType: "discrete",
18407 percentages: "no",
18408 groups: [
18409 "CSS Inline"
18410 ],
18411 initial: "auto",
18412 appliesto: "firstLetterPseudoElementsAndInlineLevelFirstChildren",
18413 computed: "asSpecified",
18414 order: "uniqueOrder",
18415 status: "experimental",
18416 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/initial-letter-align"
18417 },
18418 "inline-size": {
18419 syntax: "<'width'>",
18420 media: "visual",
18421 inherited: false,
18422 animationType: "lpc",
18423 percentages: "inlineSizeOfContainingBlock",
18424 groups: [
18425 "CSS Logical Properties"
18426 ],
18427 initial: "auto",
18428 appliesto: "sameAsWidthAndHeight",
18429 computed: "sameAsWidthAndHeight",
18430 order: "uniqueOrder",
18431 status: "standard",
18432 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/inline-size"
18433 },
18434 inset: inset,
18435 "inset-block": {
18436 syntax: "<'top'>{1,2}",
18437 media: "visual",
18438 inherited: false,
18439 animationType: "lpc",
18440 percentages: "logicalHeightOfContainingBlock",
18441 groups: [
18442 "CSS Logical Properties"
18443 ],
18444 initial: "auto",
18445 appliesto: "positionedElements",
18446 computed: "sameAsBoxOffsets",
18447 order: "uniqueOrder",
18448 status: "standard",
18449 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/inset-block"
18450 },
18451 "inset-block-end": {
18452 syntax: "<'top'>",
18453 media: "visual",
18454 inherited: false,
18455 animationType: "lpc",
18456 percentages: "logicalHeightOfContainingBlock",
18457 groups: [
18458 "CSS Logical Properties"
18459 ],
18460 initial: "auto",
18461 appliesto: "positionedElements",
18462 computed: "sameAsBoxOffsets",
18463 order: "uniqueOrder",
18464 status: "standard",
18465 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/inset-block-end"
18466 },
18467 "inset-block-start": {
18468 syntax: "<'top'>",
18469 media: "visual",
18470 inherited: false,
18471 animationType: "lpc",
18472 percentages: "logicalHeightOfContainingBlock",
18473 groups: [
18474 "CSS Logical Properties"
18475 ],
18476 initial: "auto",
18477 appliesto: "positionedElements",
18478 computed: "sameAsBoxOffsets",
18479 order: "uniqueOrder",
18480 status: "standard",
18481 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/inset-block-start"
18482 },
18483 "inset-inline": {
18484 syntax: "<'top'>{1,2}",
18485 media: "visual",
18486 inherited: false,
18487 animationType: "lpc",
18488 percentages: "logicalWidthOfContainingBlock",
18489 groups: [
18490 "CSS Logical Properties"
18491 ],
18492 initial: "auto",
18493 appliesto: "positionedElements",
18494 computed: "sameAsBoxOffsets",
18495 order: "uniqueOrder",
18496 status: "standard",
18497 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/inset-inline"
18498 },
18499 "inset-inline-end": {
18500 syntax: "<'top'>",
18501 media: "visual",
18502 inherited: false,
18503 animationType: "lpc",
18504 percentages: "logicalWidthOfContainingBlock",
18505 groups: [
18506 "CSS Logical Properties"
18507 ],
18508 initial: "auto",
18509 appliesto: "positionedElements",
18510 computed: "sameAsBoxOffsets",
18511 order: "uniqueOrder",
18512 status: "standard",
18513 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/inset-inline-end"
18514 },
18515 "inset-inline-start": {
18516 syntax: "<'top'>",
18517 media: "visual",
18518 inherited: false,
18519 animationType: "lpc",
18520 percentages: "logicalWidthOfContainingBlock",
18521 groups: [
18522 "CSS Logical Properties"
18523 ],
18524 initial: "auto",
18525 appliesto: "positionedElements",
18526 computed: "sameAsBoxOffsets",
18527 order: "uniqueOrder",
18528 status: "standard",
18529 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/inset-inline-start"
18530 },
18531 isolation: isolation,
18532 "justify-content": {
18533 syntax: "normal | <content-distribution> | <overflow-position>? [ <content-position> | left | right ]",
18534 media: "visual",
18535 inherited: false,
18536 animationType: "discrete",
18537 percentages: "no",
18538 groups: [
18539 "CSS Box Alignment"
18540 ],
18541 initial: "normal",
18542 appliesto: "flexContainers",
18543 computed: "asSpecified",
18544 order: "uniqueOrder",
18545 status: "standard",
18546 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/justify-content"
18547 },
18548 "justify-items": {
18549 syntax: "normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | legacy | legacy && [ left | right | center ]",
18550 media: "visual",
18551 inherited: false,
18552 animationType: "discrete",
18553 percentages: "no",
18554 groups: [
18555 "CSS Box Alignment"
18556 ],
18557 initial: "legacy",
18558 appliesto: "allElements",
18559 computed: "asSpecified",
18560 order: "perGrammar",
18561 status: "standard",
18562 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/justify-items"
18563 },
18564 "justify-self": {
18565 syntax: "auto | normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ]",
18566 media: "visual",
18567 inherited: false,
18568 animationType: "discrete",
18569 percentages: "no",
18570 groups: [
18571 "CSS Box Alignment"
18572 ],
18573 initial: "auto",
18574 appliesto: "blockLevelBoxesAndAbsolutelyPositionedBoxesAndGridItems",
18575 computed: "asSpecified",
18576 order: "uniqueOrder",
18577 status: "standard",
18578 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/justify-self"
18579 },
18580 "justify-tracks": {
18581 syntax: "[ normal | <content-distribution> | <overflow-position>? [ <content-position> | left | right ] ]#",
18582 media: "visual",
18583 inherited: false,
18584 animationType: "discrete",
18585 percentages: "no",
18586 groups: [
18587 "CSS Grid Layout"
18588 ],
18589 initial: "normal",
18590 appliesto: "gridContainersWithMasonryLayoutInTheirInlineAxis",
18591 computed: "asSpecified",
18592 order: "uniqueOrder",
18593 status: "experimental",
18594 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/justify-tracks"
18595 },
18596 left: left,
18597 "letter-spacing": {
18598 syntax: "normal | <length>",
18599 media: "visual",
18600 inherited: true,
18601 animationType: "length",
18602 percentages: "no",
18603 groups: [
18604 "CSS Text"
18605 ],
18606 initial: "normal",
18607 appliesto: "allElements",
18608 computed: "optimumValueOfAbsoluteLengthOrNormal",
18609 order: "uniqueOrder",
18610 alsoAppliesTo: [
18611 "::first-letter",
18612 "::first-line"
18613 ],
18614 status: "standard",
18615 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/letter-spacing"
18616 },
18617 "line-break": {
18618 syntax: "auto | loose | normal | strict | anywhere",
18619 media: "visual",
18620 inherited: true,
18621 animationType: "discrete",
18622 percentages: "no",
18623 groups: [
18624 "CSS Text"
18625 ],
18626 initial: "auto",
18627 appliesto: "allElements",
18628 computed: "asSpecified",
18629 order: "uniqueOrder",
18630 status: "standard",
18631 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/line-break"
18632 },
18633 "line-clamp": {
18634 syntax: "none | <integer>",
18635 media: "visual",
18636 inherited: false,
18637 animationType: "integer",
18638 percentages: "no",
18639 groups: [
18640 "CSS Overflow"
18641 ],
18642 initial: "none",
18643 appliesto: "blockContainersExceptMultiColumnContainers",
18644 computed: "asSpecified",
18645 order: "perGrammar",
18646 status: "experimental"
18647 },
18648 "line-height": {
18649 syntax: "normal | <number> | <length> | <percentage>",
18650 media: "visual",
18651 inherited: true,
18652 animationType: "numberOrLength",
18653 percentages: "referToElementFontSize",
18654 groups: [
18655 "CSS Fonts"
18656 ],
18657 initial: "normal",
18658 appliesto: "allElements",
18659 computed: "absoluteLengthOrAsSpecified",
18660 order: "uniqueOrder",
18661 alsoAppliesTo: [
18662 "::first-letter",
18663 "::first-line",
18664 "::placeholder"
18665 ],
18666 status: "standard",
18667 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/line-height"
18668 },
18669 "line-height-step": {
18670 syntax: "<length>",
18671 media: "visual",
18672 inherited: true,
18673 animationType: "discrete",
18674 percentages: "no",
18675 groups: [
18676 "CSS Fonts"
18677 ],
18678 initial: "0",
18679 appliesto: "blockContainers",
18680 computed: "absoluteLength",
18681 order: "perGrammar",
18682 status: "experimental",
18683 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/line-height-step"
18684 },
18685 "list-style": {
18686 syntax: "<'list-style-type'> || <'list-style-position'> || <'list-style-image'>",
18687 media: "visual",
18688 inherited: true,
18689 animationType: "discrete",
18690 percentages: "no",
18691 groups: [
18692 "CSS Lists and Counters"
18693 ],
18694 initial: [
18695 "list-style-type",
18696 "list-style-position",
18697 "list-style-image"
18698 ],
18699 appliesto: "listItems",
18700 computed: [
18701 "list-style-image",
18702 "list-style-position",
18703 "list-style-type"
18704 ],
18705 order: "orderOfAppearance",
18706 status: "standard",
18707 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/list-style"
18708 },
18709 "list-style-image": {
18710 syntax: "<url> | none",
18711 media: "visual",
18712 inherited: true,
18713 animationType: "discrete",
18714 percentages: "no",
18715 groups: [
18716 "CSS Lists and Counters"
18717 ],
18718 initial: "none",
18719 appliesto: "listItems",
18720 computed: "noneOrImageWithAbsoluteURI",
18721 order: "uniqueOrder",
18722 status: "standard",
18723 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/list-style-image"
18724 },
18725 "list-style-position": {
18726 syntax: "inside | outside",
18727 media: "visual",
18728 inherited: true,
18729 animationType: "discrete",
18730 percentages: "no",
18731 groups: [
18732 "CSS Lists and Counters"
18733 ],
18734 initial: "outside",
18735 appliesto: "listItems",
18736 computed: "asSpecified",
18737 order: "uniqueOrder",
18738 status: "standard",
18739 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/list-style-position"
18740 },
18741 "list-style-type": {
18742 syntax: "<counter-style> | <string> | none",
18743 media: "visual",
18744 inherited: true,
18745 animationType: "discrete",
18746 percentages: "no",
18747 groups: [
18748 "CSS Lists and Counters"
18749 ],
18750 initial: "disc",
18751 appliesto: "listItems",
18752 computed: "asSpecified",
18753 order: "uniqueOrder",
18754 status: "standard",
18755 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/list-style-type"
18756 },
18757 margin: margin,
18758 "margin-block": {
18759 syntax: "<'margin-left'>{1,2}",
18760 media: "visual",
18761 inherited: false,
18762 animationType: "discrete",
18763 percentages: "dependsOnLayoutModel",
18764 groups: [
18765 "CSS Logical Properties"
18766 ],
18767 initial: "0",
18768 appliesto: "sameAsMargin",
18769 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
18770 order: "uniqueOrder",
18771 status: "standard",
18772 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/margin-block"
18773 },
18774 "margin-block-end": {
18775 syntax: "<'margin-left'>",
18776 media: "visual",
18777 inherited: false,
18778 animationType: "length",
18779 percentages: "dependsOnLayoutModel",
18780 groups: [
18781 "CSS Logical Properties"
18782 ],
18783 initial: "0",
18784 appliesto: "sameAsMargin",
18785 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
18786 order: "uniqueOrder",
18787 status: "standard",
18788 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/margin-block-end"
18789 },
18790 "margin-block-start": {
18791 syntax: "<'margin-left'>",
18792 media: "visual",
18793 inherited: false,
18794 animationType: "length",
18795 percentages: "dependsOnLayoutModel",
18796 groups: [
18797 "CSS Logical Properties"
18798 ],
18799 initial: "0",
18800 appliesto: "sameAsMargin",
18801 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
18802 order: "uniqueOrder",
18803 status: "standard",
18804 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/margin-block-start"
18805 },
18806 "margin-bottom": {
18807 syntax: "<length> | <percentage> | auto",
18808 media: "visual",
18809 inherited: false,
18810 animationType: "length",
18811 percentages: "referToWidthOfContainingBlock",
18812 groups: [
18813 "CSS Box Model"
18814 ],
18815 initial: "0",
18816 appliesto: "allElementsExceptTableDisplayTypes",
18817 computed: "percentageAsSpecifiedOrAbsoluteLength",
18818 order: "uniqueOrder",
18819 alsoAppliesTo: [
18820 "::first-letter",
18821 "::first-line"
18822 ],
18823 status: "standard",
18824 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/margin-bottom"
18825 },
18826 "margin-inline": {
18827 syntax: "<'margin-left'>{1,2}",
18828 media: "visual",
18829 inherited: false,
18830 animationType: "discrete",
18831 percentages: "dependsOnLayoutModel",
18832 groups: [
18833 "CSS Logical Properties"
18834 ],
18835 initial: "0",
18836 appliesto: "sameAsMargin",
18837 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
18838 order: "uniqueOrder",
18839 status: "standard",
18840 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/margin-inline"
18841 },
18842 "margin-inline-end": {
18843 syntax: "<'margin-left'>",
18844 media: "visual",
18845 inherited: false,
18846 animationType: "length",
18847 percentages: "dependsOnLayoutModel",
18848 groups: [
18849 "CSS Logical Properties"
18850 ],
18851 initial: "0",
18852 appliesto: "sameAsMargin",
18853 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
18854 order: "uniqueOrder",
18855 status: "standard",
18856 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/margin-inline-end"
18857 },
18858 "margin-inline-start": {
18859 syntax: "<'margin-left'>",
18860 media: "visual",
18861 inherited: false,
18862 animationType: "length",
18863 percentages: "dependsOnLayoutModel",
18864 groups: [
18865 "CSS Logical Properties"
18866 ],
18867 initial: "0",
18868 appliesto: "sameAsMargin",
18869 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
18870 order: "uniqueOrder",
18871 status: "standard",
18872 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/margin-inline-start"
18873 },
18874 "margin-left": {
18875 syntax: "<length> | <percentage> | auto",
18876 media: "visual",
18877 inherited: false,
18878 animationType: "length",
18879 percentages: "referToWidthOfContainingBlock",
18880 groups: [
18881 "CSS Box Model"
18882 ],
18883 initial: "0",
18884 appliesto: "allElementsExceptTableDisplayTypes",
18885 computed: "percentageAsSpecifiedOrAbsoluteLength",
18886 order: "uniqueOrder",
18887 alsoAppliesTo: [
18888 "::first-letter",
18889 "::first-line"
18890 ],
18891 status: "standard",
18892 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/margin-left"
18893 },
18894 "margin-right": {
18895 syntax: "<length> | <percentage> | auto",
18896 media: "visual",
18897 inherited: false,
18898 animationType: "length",
18899 percentages: "referToWidthOfContainingBlock",
18900 groups: [
18901 "CSS Box Model"
18902 ],
18903 initial: "0",
18904 appliesto: "allElementsExceptTableDisplayTypes",
18905 computed: "percentageAsSpecifiedOrAbsoluteLength",
18906 order: "uniqueOrder",
18907 alsoAppliesTo: [
18908 "::first-letter",
18909 "::first-line"
18910 ],
18911 status: "standard",
18912 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/margin-right"
18913 },
18914 "margin-top": {
18915 syntax: "<length> | <percentage> | auto",
18916 media: "visual",
18917 inherited: false,
18918 animationType: "length",
18919 percentages: "referToWidthOfContainingBlock",
18920 groups: [
18921 "CSS Box Model"
18922 ],
18923 initial: "0",
18924 appliesto: "allElementsExceptTableDisplayTypes",
18925 computed: "percentageAsSpecifiedOrAbsoluteLength",
18926 order: "uniqueOrder",
18927 alsoAppliesTo: [
18928 "::first-letter",
18929 "::first-line"
18930 ],
18931 status: "standard",
18932 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/margin-top"
18933 },
18934 "margin-trim": {
18935 syntax: "none | in-flow | all",
18936 media: "visual",
18937 inherited: false,
18938 animationType: "discrete",
18939 percentages: "no",
18940 groups: [
18941 "CSS Box Model"
18942 ],
18943 initial: "none",
18944 appliesto: "blockContainersAndMultiColumnContainers",
18945 computed: "asSpecified",
18946 order: "perGrammar",
18947 alsoAppliesTo: [
18948 "::first-letter",
18949 "::first-line"
18950 ],
18951 status: "experimental",
18952 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/margin-trim"
18953 },
18954 mask: mask,
18955 "mask-border": {
18956 syntax: "<'mask-border-source'> || <'mask-border-slice'> [ / <'mask-border-width'>? [ / <'mask-border-outset'> ]? ]? || <'mask-border-repeat'> || <'mask-border-mode'>",
18957 media: "visual",
18958 inherited: false,
18959 animationType: [
18960 "mask-border-mode",
18961 "mask-border-outset",
18962 "mask-border-repeat",
18963 "mask-border-slice",
18964 "mask-border-source",
18965 "mask-border-width"
18966 ],
18967 percentages: [
18968 "mask-border-slice",
18969 "mask-border-width"
18970 ],
18971 groups: [
18972 "CSS Masking"
18973 ],
18974 initial: [
18975 "mask-border-mode",
18976 "mask-border-outset",
18977 "mask-border-repeat",
18978 "mask-border-slice",
18979 "mask-border-source",
18980 "mask-border-width"
18981 ],
18982 appliesto: "allElementsSVGContainerElements",
18983 computed: [
18984 "mask-border-mode",
18985 "mask-border-outset",
18986 "mask-border-repeat",
18987 "mask-border-slice",
18988 "mask-border-source",
18989 "mask-border-width"
18990 ],
18991 order: "perGrammar",
18992 stacking: true,
18993 status: "standard",
18994 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-border"
18995 },
18996 "mask-border-mode": {
18997 syntax: "luminance | alpha",
18998 media: "visual",
18999 inherited: false,
19000 animationType: "discrete",
19001 percentages: "no",
19002 groups: [
19003 "CSS Masking"
19004 ],
19005 initial: "alpha",
19006 appliesto: "allElementsSVGContainerElements",
19007 computed: "asSpecified",
19008 order: "perGrammar",
19009 status: "standard",
19010 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-border-mode"
19011 },
19012 "mask-border-outset": {
19013 syntax: "[ <length> | <number> ]{1,4}",
19014 media: "visual",
19015 inherited: false,
19016 animationType: "discrete",
19017 percentages: "no",
19018 groups: [
19019 "CSS Masking"
19020 ],
19021 initial: "0",
19022 appliesto: "allElementsSVGContainerElements",
19023 computed: "asSpecifiedRelativeToAbsoluteLengths",
19024 order: "perGrammar",
19025 status: "standard",
19026 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-border-outset"
19027 },
19028 "mask-border-repeat": {
19029 syntax: "[ stretch | repeat | round | space ]{1,2}",
19030 media: "visual",
19031 inherited: false,
19032 animationType: "discrete",
19033 percentages: "no",
19034 groups: [
19035 "CSS Masking"
19036 ],
19037 initial: "stretch",
19038 appliesto: "allElementsSVGContainerElements",
19039 computed: "asSpecified",
19040 order: "perGrammar",
19041 status: "standard",
19042 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-border-repeat"
19043 },
19044 "mask-border-slice": {
19045 syntax: "<number-percentage>{1,4} fill?",
19046 media: "visual",
19047 inherited: false,
19048 animationType: "discrete",
19049 percentages: "referToSizeOfMaskBorderImage",
19050 groups: [
19051 "CSS Masking"
19052 ],
19053 initial: "0",
19054 appliesto: "allElementsSVGContainerElements",
19055 computed: "asSpecified",
19056 order: "perGrammar",
19057 status: "standard",
19058 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-border-slice"
19059 },
19060 "mask-border-source": {
19061 syntax: "none | <image>",
19062 media: "visual",
19063 inherited: false,
19064 animationType: "discrete",
19065 percentages: "no",
19066 groups: [
19067 "CSS Masking"
19068 ],
19069 initial: "none",
19070 appliesto: "allElementsSVGContainerElements",
19071 computed: "asSpecifiedURLsAbsolute",
19072 order: "perGrammar",
19073 status: "standard",
19074 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-border-source"
19075 },
19076 "mask-border-width": {
19077 syntax: "[ <length-percentage> | <number> | auto ]{1,4}",
19078 media: "visual",
19079 inherited: false,
19080 animationType: "discrete",
19081 percentages: "relativeToMaskBorderImageArea",
19082 groups: [
19083 "CSS Masking"
19084 ],
19085 initial: "auto",
19086 appliesto: "allElementsSVGContainerElements",
19087 computed: "asSpecifiedRelativeToAbsoluteLengths",
19088 order: "perGrammar",
19089 status: "standard",
19090 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-border-width"
19091 },
19092 "mask-clip": {
19093 syntax: "[ <geometry-box> | no-clip ]#",
19094 media: "visual",
19095 inherited: false,
19096 animationType: "discrete",
19097 percentages: "no",
19098 groups: [
19099 "CSS Masking"
19100 ],
19101 initial: "border-box",
19102 appliesto: "allElementsSVGContainerElements",
19103 computed: "asSpecified",
19104 order: "perGrammar",
19105 status: "standard",
19106 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-clip"
19107 },
19108 "mask-composite": {
19109 syntax: "<compositing-operator>#",
19110 media: "visual",
19111 inherited: false,
19112 animationType: "discrete",
19113 percentages: "no",
19114 groups: [
19115 "CSS Masking"
19116 ],
19117 initial: "add",
19118 appliesto: "allElementsSVGContainerElements",
19119 computed: "asSpecified",
19120 order: "perGrammar",
19121 status: "standard",
19122 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-composite"
19123 },
19124 "mask-image": {
19125 syntax: "<mask-reference>#",
19126 media: "visual",
19127 inherited: false,
19128 animationType: "discrete",
19129 percentages: "no",
19130 groups: [
19131 "CSS Masking"
19132 ],
19133 initial: "none",
19134 appliesto: "allElementsSVGContainerElements",
19135 computed: "asSpecifiedURLsAbsolute",
19136 order: "perGrammar",
19137 status: "standard",
19138 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-image"
19139 },
19140 "mask-mode": {
19141 syntax: "<masking-mode>#",
19142 media: "visual",
19143 inherited: false,
19144 animationType: "discrete",
19145 percentages: "no",
19146 groups: [
19147 "CSS Masking"
19148 ],
19149 initial: "match-source",
19150 appliesto: "allElementsSVGContainerElements",
19151 computed: "asSpecified",
19152 order: "perGrammar",
19153 status: "standard",
19154 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-mode"
19155 },
19156 "mask-origin": {
19157 syntax: "<geometry-box>#",
19158 media: "visual",
19159 inherited: false,
19160 animationType: "discrete",
19161 percentages: "no",
19162 groups: [
19163 "CSS Masking"
19164 ],
19165 initial: "border-box",
19166 appliesto: "allElementsSVGContainerElements",
19167 computed: "asSpecified",
19168 order: "perGrammar",
19169 status: "standard",
19170 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-origin"
19171 },
19172 "mask-position": {
19173 syntax: "<position>#",
19174 media: "visual",
19175 inherited: false,
19176 animationType: "repeatableListOfSimpleListOfLpc",
19177 percentages: "referToSizeOfMaskPaintingArea",
19178 groups: [
19179 "CSS Masking"
19180 ],
19181 initial: "center",
19182 appliesto: "allElementsSVGContainerElements",
19183 computed: "consistsOfTwoKeywordsForOriginAndOffsets",
19184 order: "perGrammar",
19185 status: "standard",
19186 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-position"
19187 },
19188 "mask-repeat": {
19189 syntax: "<repeat-style>#",
19190 media: "visual",
19191 inherited: false,
19192 animationType: "discrete",
19193 percentages: "no",
19194 groups: [
19195 "CSS Masking"
19196 ],
19197 initial: "no-repeat",
19198 appliesto: "allElementsSVGContainerElements",
19199 computed: "consistsOfTwoDimensionKeywords",
19200 order: "perGrammar",
19201 status: "standard",
19202 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-repeat"
19203 },
19204 "mask-size": {
19205 syntax: "<bg-size>#",
19206 media: "visual",
19207 inherited: false,
19208 animationType: "repeatableListOfSimpleListOfLpc",
19209 percentages: "no",
19210 groups: [
19211 "CSS Masking"
19212 ],
19213 initial: "auto",
19214 appliesto: "allElementsSVGContainerElements",
19215 computed: "asSpecifiedRelativeToAbsoluteLengths",
19216 order: "perGrammar",
19217 status: "standard",
19218 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-size"
19219 },
19220 "mask-type": {
19221 syntax: "luminance | alpha",
19222 media: "visual",
19223 inherited: false,
19224 animationType: "discrete",
19225 percentages: "no",
19226 groups: [
19227 "CSS Masking"
19228 ],
19229 initial: "luminance",
19230 appliesto: "maskElements",
19231 computed: "asSpecified",
19232 order: "perGrammar",
19233 status: "standard",
19234 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-type"
19235 },
19236 "masonry-auto-flow": {
19237 syntax: "[ pack | next ] || [ definite-first | ordered ]",
19238 media: "visual",
19239 inherited: false,
19240 animationType: "discrete",
19241 percentages: "no",
19242 groups: [
19243 "CSS Grid Layout"
19244 ],
19245 initial: "pack",
19246 appliesto: "gridContainersWithMasonryLayout",
19247 computed: "asSpecified",
19248 order: "uniqueOrder",
19249 status: "experimental",
19250 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/masonry-auto-flow"
19251 },
19252 "math-style": {
19253 syntax: "normal | compact",
19254 media: "visual",
19255 inherited: true,
19256 animationType: "notAnimatable",
19257 percentages: "no",
19258 groups: [
19259 "MathML"
19260 ],
19261 initial: "normal",
19262 appliesto: "allElements",
19263 computed: "asSpecified",
19264 order: "perGrammar",
19265 status: "standard",
19266 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/math-style"
19267 },
19268 "max-block-size": {
19269 syntax: "<'max-width'>",
19270 media: "visual",
19271 inherited: false,
19272 animationType: "lpc",
19273 percentages: "blockSizeOfContainingBlock",
19274 groups: [
19275 "CSS Logical Properties"
19276 ],
19277 initial: "0",
19278 appliesto: "sameAsWidthAndHeight",
19279 computed: "sameAsMaxWidthAndMaxHeight",
19280 order: "uniqueOrder",
19281 status: "standard",
19282 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/max-block-size"
19283 },
19284 "max-height": {
19285 syntax: "none | <length-percentage> | min-content | max-content | fit-content(<length-percentage>)",
19286 media: "visual",
19287 inherited: false,
19288 animationType: "lpc",
19289 percentages: "regardingHeightOfGeneratedBoxContainingBlockPercentagesNone",
19290 groups: [
19291 "CSS Box Model"
19292 ],
19293 initial: "none",
19294 appliesto: "allElementsButNonReplacedAndTableColumns",
19295 computed: "percentageAsSpecifiedAbsoluteLengthOrNone",
19296 order: "uniqueOrder",
19297 status: "standard",
19298 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/max-height"
19299 },
19300 "max-inline-size": {
19301 syntax: "<'max-width'>",
19302 media: "visual",
19303 inherited: false,
19304 animationType: "lpc",
19305 percentages: "inlineSizeOfContainingBlock",
19306 groups: [
19307 "CSS Logical Properties"
19308 ],
19309 initial: "0",
19310 appliesto: "sameAsWidthAndHeight",
19311 computed: "sameAsMaxWidthAndMaxHeight",
19312 order: "uniqueOrder",
19313 status: "standard",
19314 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/max-inline-size"
19315 },
19316 "max-lines": {
19317 syntax: "none | <integer>",
19318 media: "visual",
19319 inherited: false,
19320 animationType: "integer",
19321 percentages: "no",
19322 groups: [
19323 "CSS Overflow"
19324 ],
19325 initial: "none",
19326 appliesto: "blockContainersExceptMultiColumnContainers",
19327 computed: "asSpecified",
19328 order: "perGrammar",
19329 status: "experimental"
19330 },
19331 "max-width": {
19332 syntax: "none | <length-percentage> | min-content | max-content | fit-content(<length-percentage>)",
19333 media: "visual",
19334 inherited: false,
19335 animationType: "lpc",
19336 percentages: "referToWidthOfContainingBlock",
19337 groups: [
19338 "CSS Box Model"
19339 ],
19340 initial: "none",
19341 appliesto: "allElementsButNonReplacedAndTableRows",
19342 computed: "percentageAsSpecifiedAbsoluteLengthOrNone",
19343 order: "uniqueOrder",
19344 status: "standard",
19345 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/max-width"
19346 },
19347 "min-block-size": {
19348 syntax: "<'min-width'>",
19349 media: "visual",
19350 inherited: false,
19351 animationType: "lpc",
19352 percentages: "blockSizeOfContainingBlock",
19353 groups: [
19354 "CSS Logical Properties"
19355 ],
19356 initial: "0",
19357 appliesto: "sameAsWidthAndHeight",
19358 computed: "sameAsMinWidthAndMinHeight",
19359 order: "uniqueOrder",
19360 status: "standard",
19361 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/min-block-size"
19362 },
19363 "min-height": {
19364 syntax: "auto | <length> | <percentage> | min-content | max-content | fit-content(<length-percentage>)",
19365 media: "visual",
19366 inherited: false,
19367 animationType: "lpc",
19368 percentages: "regardingHeightOfGeneratedBoxContainingBlockPercentages0",
19369 groups: [
19370 "CSS Box Model"
19371 ],
19372 initial: "auto",
19373 appliesto: "allElementsButNonReplacedAndTableColumns",
19374 computed: "percentageAsSpecifiedOrAbsoluteLength",
19375 order: "uniqueOrder",
19376 status: "standard",
19377 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/min-height"
19378 },
19379 "min-inline-size": {
19380 syntax: "<'min-width'>",
19381 media: "visual",
19382 inherited: false,
19383 animationType: "lpc",
19384 percentages: "inlineSizeOfContainingBlock",
19385 groups: [
19386 "CSS Logical Properties"
19387 ],
19388 initial: "0",
19389 appliesto: "sameAsWidthAndHeight",
19390 computed: "sameAsMinWidthAndMinHeight",
19391 order: "uniqueOrder",
19392 status: "standard",
19393 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/min-inline-size"
19394 },
19395 "min-width": {
19396 syntax: "auto | <length> | <percentage> | min-content | max-content | fit-content(<length-percentage>)",
19397 media: "visual",
19398 inherited: false,
19399 animationType: "lpc",
19400 percentages: "referToWidthOfContainingBlock",
19401 groups: [
19402 "CSS Box Model"
19403 ],
19404 initial: "auto",
19405 appliesto: "allElementsButNonReplacedAndTableRows",
19406 computed: "percentageAsSpecifiedOrAbsoluteLength",
19407 order: "uniqueOrder",
19408 status: "standard",
19409 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/min-width"
19410 },
19411 "mix-blend-mode": {
19412 syntax: "<blend-mode>",
19413 media: "visual",
19414 inherited: false,
19415 animationType: "discrete",
19416 percentages: "no",
19417 groups: [
19418 "Compositing and Blending"
19419 ],
19420 initial: "normal",
19421 appliesto: "allElements",
19422 computed: "asSpecified",
19423 order: "uniqueOrder",
19424 stacking: true,
19425 status: "standard",
19426 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mix-blend-mode"
19427 },
19428 "object-fit": {
19429 syntax: "fill | contain | cover | none | scale-down",
19430 media: "visual",
19431 inherited: false,
19432 animationType: "discrete",
19433 percentages: "no",
19434 groups: [
19435 "CSS Images"
19436 ],
19437 initial: "fill",
19438 appliesto: "replacedElements",
19439 computed: "asSpecified",
19440 order: "uniqueOrder",
19441 status: "standard",
19442 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/object-fit"
19443 },
19444 "object-position": {
19445 syntax: "<position>",
19446 media: "visual",
19447 inherited: true,
19448 animationType: "repeatableListOfSimpleListOfLpc",
19449 percentages: "referToWidthAndHeightOfElement",
19450 groups: [
19451 "CSS Images"
19452 ],
19453 initial: "50% 50%",
19454 appliesto: "replacedElements",
19455 computed: "asSpecified",
19456 order: "uniqueOrder",
19457 status: "standard",
19458 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/object-position"
19459 },
19460 offset: offset,
19461 "offset-anchor": {
19462 syntax: "auto | <position>",
19463 media: "visual",
19464 inherited: false,
19465 animationType: "position",
19466 percentages: "relativeToWidthAndHeight",
19467 groups: [
19468 "CSS Motion Path"
19469 ],
19470 initial: "auto",
19471 appliesto: "transformableElements",
19472 computed: "forLengthAbsoluteValueOtherwisePercentage",
19473 order: "perGrammar",
19474 status: "standard"
19475 },
19476 "offset-distance": {
19477 syntax: "<length-percentage>",
19478 media: "visual",
19479 inherited: false,
19480 animationType: "lpc",
19481 percentages: "referToTotalPathLength",
19482 groups: [
19483 "CSS Motion Path"
19484 ],
19485 initial: "0",
19486 appliesto: "transformableElements",
19487 computed: "forLengthAbsoluteValueOtherwisePercentage",
19488 order: "perGrammar",
19489 status: "standard",
19490 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/offset-distance"
19491 },
19492 "offset-path": {
19493 syntax: "none | ray( [ <angle> && <size> && contain? ] ) | <path()> | <url> | [ <basic-shape> || <geometry-box> ]",
19494 media: "visual",
19495 inherited: false,
19496 animationType: "angleOrBasicShapeOrPath",
19497 percentages: "no",
19498 groups: [
19499 "CSS Motion Path"
19500 ],
19501 initial: "none",
19502 appliesto: "transformableElements",
19503 computed: "asSpecified",
19504 order: "perGrammar",
19505 stacking: true,
19506 status: "standard",
19507 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/offset-path"
19508 },
19509 "offset-position": {
19510 syntax: "auto | <position>",
19511 media: "visual",
19512 inherited: false,
19513 animationType: "position",
19514 percentages: "referToSizeOfContainingBlock",
19515 groups: [
19516 "CSS Motion Path"
19517 ],
19518 initial: "auto",
19519 appliesto: "transformableElements",
19520 computed: "forLengthAbsoluteValueOtherwisePercentage",
19521 order: "perGrammar",
19522 status: "experimental"
19523 },
19524 "offset-rotate": {
19525 syntax: "[ auto | reverse ] || <angle>",
19526 media: "visual",
19527 inherited: false,
19528 animationType: "angleOrBasicShapeOrPath",
19529 percentages: "no",
19530 groups: [
19531 "CSS Motion Path"
19532 ],
19533 initial: "auto",
19534 appliesto: "transformableElements",
19535 computed: "asSpecified",
19536 order: "perGrammar",
19537 status: "standard",
19538 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/offset-rotate"
19539 },
19540 opacity: opacity,
19541 order: order,
19542 orphans: orphans,
19543 outline: outline,
19544 "outline-color": {
19545 syntax: "<color> | invert",
19546 media: [
19547 "visual",
19548 "interactive"
19549 ],
19550 inherited: false,
19551 animationType: "color",
19552 percentages: "no",
19553 groups: [
19554 "CSS Basic User Interface"
19555 ],
19556 initial: "invertOrCurrentColor",
19557 appliesto: "allElements",
19558 computed: "invertForTranslucentColorRGBAOtherwiseRGB",
19559 order: "uniqueOrder",
19560 status: "standard",
19561 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/outline-color"
19562 },
19563 "outline-offset": {
19564 syntax: "<length>",
19565 media: [
19566 "visual",
19567 "interactive"
19568 ],
19569 inherited: false,
19570 animationType: "length",
19571 percentages: "no",
19572 groups: [
19573 "CSS Basic User Interface"
19574 ],
19575 initial: "0",
19576 appliesto: "allElements",
19577 computed: "asSpecifiedRelativeToAbsoluteLengths",
19578 order: "uniqueOrder",
19579 status: "standard",
19580 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/outline-offset"
19581 },
19582 "outline-style": {
19583 syntax: "auto | <'border-style'>",
19584 media: [
19585 "visual",
19586 "interactive"
19587 ],
19588 inherited: false,
19589 animationType: "discrete",
19590 percentages: "no",
19591 groups: [
19592 "CSS Basic User Interface"
19593 ],
19594 initial: "none",
19595 appliesto: "allElements",
19596 computed: "asSpecified",
19597 order: "uniqueOrder",
19598 status: "standard",
19599 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/outline-style"
19600 },
19601 "outline-width": {
19602 syntax: "<line-width>",
19603 media: [
19604 "visual",
19605 "interactive"
19606 ],
19607 inherited: false,
19608 animationType: "length",
19609 percentages: "no",
19610 groups: [
19611 "CSS Basic User Interface"
19612 ],
19613 initial: "medium",
19614 appliesto: "allElements",
19615 computed: "absoluteLength0ForNone",
19616 order: "uniqueOrder",
19617 status: "standard",
19618 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/outline-width"
19619 },
19620 overflow: overflow,
19621 "overflow-anchor": {
19622 syntax: "auto | none",
19623 media: "visual",
19624 inherited: false,
19625 animationType: "discrete",
19626 percentages: "no",
19627 groups: [
19628 "CSS Scroll Anchoring"
19629 ],
19630 initial: "auto",
19631 appliesto: "allElements",
19632 computed: "asSpecified",
19633 order: "perGrammar",
19634 status: "standard"
19635 },
19636 "overflow-block": {
19637 syntax: "visible | hidden | clip | scroll | auto",
19638 media: "visual",
19639 inherited: false,
19640 animationType: "discrete",
19641 percentages: "no",
19642 groups: [
19643 "CSS Overflow"
19644 ],
19645 initial: "auto",
19646 appliesto: "blockContainersFlexContainersGridContainers",
19647 computed: "asSpecifiedButVisibleOrClipReplacedToAutoOrHiddenIfOtherValueDifferent",
19648 order: "perGrammar",
19649 status: "standard"
19650 },
19651 "overflow-clip-box": {
19652 syntax: "padding-box | content-box",
19653 media: "visual",
19654 inherited: false,
19655 animationType: "discrete",
19656 percentages: "no",
19657 groups: [
19658 "Mozilla Extensions"
19659 ],
19660 initial: "padding-box",
19661 appliesto: "allElements",
19662 computed: "asSpecified",
19663 order: "uniqueOrder",
19664 status: "nonstandard",
19665 mdn_url: "https://developer.mozilla.org/docs/Mozilla/CSS/overflow-clip-box"
19666 },
19667 "overflow-inline": {
19668 syntax: "visible | hidden | clip | scroll | auto",
19669 media: "visual",
19670 inherited: false,
19671 animationType: "discrete",
19672 percentages: "no",
19673 groups: [
19674 "CSS Overflow"
19675 ],
19676 initial: "auto",
19677 appliesto: "blockContainersFlexContainersGridContainers",
19678 computed: "asSpecifiedButVisibleOrClipReplacedToAutoOrHiddenIfOtherValueDifferent",
19679 order: "perGrammar",
19680 status: "standard"
19681 },
19682 "overflow-wrap": {
19683 syntax: "normal | break-word | anywhere",
19684 media: "visual",
19685 inherited: true,
19686 animationType: "discrete",
19687 percentages: "no",
19688 groups: [
19689 "CSS Text"
19690 ],
19691 initial: "normal",
19692 appliesto: "nonReplacedInlineElements",
19693 computed: "asSpecified",
19694 order: "uniqueOrder",
19695 status: "standard",
19696 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/overflow-wrap"
19697 },
19698 "overflow-x": {
19699 syntax: "visible | hidden | clip | scroll | auto",
19700 media: "visual",
19701 inherited: false,
19702 animationType: "discrete",
19703 percentages: "no",
19704 groups: [
19705 "CSS Overflow"
19706 ],
19707 initial: "visible",
19708 appliesto: "blockContainersFlexContainersGridContainers",
19709 computed: "asSpecifiedButVisibleOrClipReplacedToAutoOrHiddenIfOtherValueDifferent",
19710 order: "uniqueOrder",
19711 status: "standard",
19712 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/overflow-x"
19713 },
19714 "overflow-y": {
19715 syntax: "visible | hidden | clip | scroll | auto",
19716 media: "visual",
19717 inherited: false,
19718 animationType: "discrete",
19719 percentages: "no",
19720 groups: [
19721 "CSS Overflow"
19722 ],
19723 initial: "visible",
19724 appliesto: "blockContainersFlexContainersGridContainers",
19725 computed: "asSpecifiedButVisibleOrClipReplacedToAutoOrHiddenIfOtherValueDifferent",
19726 order: "uniqueOrder",
19727 status: "standard",
19728 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/overflow-y"
19729 },
19730 "overscroll-behavior": {
19731 syntax: "[ contain | none | auto ]{1,2}",
19732 media: "visual",
19733 inherited: false,
19734 animationType: "discrete",
19735 percentages: "no",
19736 groups: [
19737 "CSS Box Model"
19738 ],
19739 initial: "auto",
19740 appliesto: "nonReplacedBlockAndInlineBlockElements",
19741 computed: "asSpecified",
19742 order: "uniqueOrder",
19743 status: "standard",
19744 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/overscroll-behavior"
19745 },
19746 "overscroll-behavior-block": {
19747 syntax: "contain | none | auto",
19748 media: "visual",
19749 inherited: false,
19750 animationType: "discrete",
19751 percentages: "no",
19752 groups: [
19753 "CSS Box Model"
19754 ],
19755 initial: "auto",
19756 appliesto: "nonReplacedBlockAndInlineBlockElements",
19757 computed: "asSpecified",
19758 order: "uniqueOrder",
19759 status: "standard",
19760 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/overscroll-behavior-block"
19761 },
19762 "overscroll-behavior-inline": {
19763 syntax: "contain | none | auto",
19764 media: "visual",
19765 inherited: false,
19766 animationType: "discrete",
19767 percentages: "no",
19768 groups: [
19769 "CSS Box Model"
19770 ],
19771 initial: "auto",
19772 appliesto: "nonReplacedBlockAndInlineBlockElements",
19773 computed: "asSpecified",
19774 order: "uniqueOrder",
19775 status: "standard",
19776 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/overscroll-behavior-inline"
19777 },
19778 "overscroll-behavior-x": {
19779 syntax: "contain | none | auto",
19780 media: "visual",
19781 inherited: false,
19782 animationType: "discrete",
19783 percentages: "no",
19784 groups: [
19785 "CSS Box Model"
19786 ],
19787 initial: "auto",
19788 appliesto: "nonReplacedBlockAndInlineBlockElements",
19789 computed: "asSpecified",
19790 order: "uniqueOrder",
19791 status: "standard",
19792 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/overscroll-behavior-x"
19793 },
19794 "overscroll-behavior-y": {
19795 syntax: "contain | none | auto",
19796 media: "visual",
19797 inherited: false,
19798 animationType: "discrete",
19799 percentages: "no",
19800 groups: [
19801 "CSS Box Model"
19802 ],
19803 initial: "auto",
19804 appliesto: "nonReplacedBlockAndInlineBlockElements",
19805 computed: "asSpecified",
19806 order: "uniqueOrder",
19807 status: "standard",
19808 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/overscroll-behavior-y"
19809 },
19810 padding: padding,
19811 "padding-block": {
19812 syntax: "<'padding-left'>{1,2}",
19813 media: "visual",
19814 inherited: false,
19815 animationType: "discrete",
19816 percentages: "logicalWidthOfContainingBlock",
19817 groups: [
19818 "CSS Logical Properties"
19819 ],
19820 initial: "0",
19821 appliesto: "allElements",
19822 computed: "asLength",
19823 order: "uniqueOrder",
19824 status: "standard",
19825 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/padding-block"
19826 },
19827 "padding-block-end": {
19828 syntax: "<'padding-left'>",
19829 media: "visual",
19830 inherited: false,
19831 animationType: "length",
19832 percentages: "logicalWidthOfContainingBlock",
19833 groups: [
19834 "CSS Logical Properties"
19835 ],
19836 initial: "0",
19837 appliesto: "allElements",
19838 computed: "asLength",
19839 order: "uniqueOrder",
19840 status: "standard",
19841 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/padding-block-end"
19842 },
19843 "padding-block-start": {
19844 syntax: "<'padding-left'>",
19845 media: "visual",
19846 inherited: false,
19847 animationType: "length",
19848 percentages: "logicalWidthOfContainingBlock",
19849 groups: [
19850 "CSS Logical Properties"
19851 ],
19852 initial: "0",
19853 appliesto: "allElements",
19854 computed: "asLength",
19855 order: "uniqueOrder",
19856 status: "standard",
19857 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/padding-block-start"
19858 },
19859 "padding-bottom": {
19860 syntax: "<length> | <percentage>",
19861 media: "visual",
19862 inherited: false,
19863 animationType: "length",
19864 percentages: "referToWidthOfContainingBlock",
19865 groups: [
19866 "CSS Box Model"
19867 ],
19868 initial: "0",
19869 appliesto: "allElementsExceptInternalTableDisplayTypes",
19870 computed: "percentageAsSpecifiedOrAbsoluteLength",
19871 order: "uniqueOrder",
19872 alsoAppliesTo: [
19873 "::first-letter",
19874 "::first-line"
19875 ],
19876 status: "standard",
19877 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/padding-bottom"
19878 },
19879 "padding-inline": {
19880 syntax: "<'padding-left'>{1,2}",
19881 media: "visual",
19882 inherited: false,
19883 animationType: "discrete",
19884 percentages: "logicalWidthOfContainingBlock",
19885 groups: [
19886 "CSS Logical Properties"
19887 ],
19888 initial: "0",
19889 appliesto: "allElements",
19890 computed: "asLength",
19891 order: "uniqueOrder",
19892 status: "standard",
19893 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/padding-inline"
19894 },
19895 "padding-inline-end": {
19896 syntax: "<'padding-left'>",
19897 media: "visual",
19898 inherited: false,
19899 animationType: "length",
19900 percentages: "logicalWidthOfContainingBlock",
19901 groups: [
19902 "CSS Logical Properties"
19903 ],
19904 initial: "0",
19905 appliesto: "allElements",
19906 computed: "asLength",
19907 order: "uniqueOrder",
19908 status: "standard",
19909 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/padding-inline-end"
19910 },
19911 "padding-inline-start": {
19912 syntax: "<'padding-left'>",
19913 media: "visual",
19914 inherited: false,
19915 animationType: "length",
19916 percentages: "logicalWidthOfContainingBlock",
19917 groups: [
19918 "CSS Logical Properties"
19919 ],
19920 initial: "0",
19921 appliesto: "allElements",
19922 computed: "asLength",
19923 order: "uniqueOrder",
19924 status: "standard",
19925 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/padding-inline-start"
19926 },
19927 "padding-left": {
19928 syntax: "<length> | <percentage>",
19929 media: "visual",
19930 inherited: false,
19931 animationType: "length",
19932 percentages: "referToWidthOfContainingBlock",
19933 groups: [
19934 "CSS Box Model"
19935 ],
19936 initial: "0",
19937 appliesto: "allElementsExceptInternalTableDisplayTypes",
19938 computed: "percentageAsSpecifiedOrAbsoluteLength",
19939 order: "uniqueOrder",
19940 alsoAppliesTo: [
19941 "::first-letter",
19942 "::first-line"
19943 ],
19944 status: "standard",
19945 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/padding-left"
19946 },
19947 "padding-right": {
19948 syntax: "<length> | <percentage>",
19949 media: "visual",
19950 inherited: false,
19951 animationType: "length",
19952 percentages: "referToWidthOfContainingBlock",
19953 groups: [
19954 "CSS Box Model"
19955 ],
19956 initial: "0",
19957 appliesto: "allElementsExceptInternalTableDisplayTypes",
19958 computed: "percentageAsSpecifiedOrAbsoluteLength",
19959 order: "uniqueOrder",
19960 alsoAppliesTo: [
19961 "::first-letter",
19962 "::first-line"
19963 ],
19964 status: "standard",
19965 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/padding-right"
19966 },
19967 "padding-top": {
19968 syntax: "<length> | <percentage>",
19969 media: "visual",
19970 inherited: false,
19971 animationType: "length",
19972 percentages: "referToWidthOfContainingBlock",
19973 groups: [
19974 "CSS Box Model"
19975 ],
19976 initial: "0",
19977 appliesto: "allElementsExceptInternalTableDisplayTypes",
19978 computed: "percentageAsSpecifiedOrAbsoluteLength",
19979 order: "uniqueOrder",
19980 alsoAppliesTo: [
19981 "::first-letter",
19982 "::first-line"
19983 ],
19984 status: "standard",
19985 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/padding-top"
19986 },
19987 "page-break-after": {
19988 syntax: "auto | always | avoid | left | right | recto | verso",
19989 media: [
19990 "visual",
19991 "paged"
19992 ],
19993 inherited: false,
19994 animationType: "discrete",
19995 percentages: "no",
19996 groups: [
19997 "CSS Pages"
19998 ],
19999 initial: "auto",
20000 appliesto: "blockElementsInNormalFlow",
20001 computed: "asSpecified",
20002 order: "uniqueOrder",
20003 status: "standard",
20004 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/page-break-after"
20005 },
20006 "page-break-before": {
20007 syntax: "auto | always | avoid | left | right | recto | verso",
20008 media: [
20009 "visual",
20010 "paged"
20011 ],
20012 inherited: false,
20013 animationType: "discrete",
20014 percentages: "no",
20015 groups: [
20016 "CSS Pages"
20017 ],
20018 initial: "auto",
20019 appliesto: "blockElementsInNormalFlow",
20020 computed: "asSpecified",
20021 order: "uniqueOrder",
20022 status: "standard",
20023 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/page-break-before"
20024 },
20025 "page-break-inside": {
20026 syntax: "auto | avoid",
20027 media: [
20028 "visual",
20029 "paged"
20030 ],
20031 inherited: false,
20032 animationType: "discrete",
20033 percentages: "no",
20034 groups: [
20035 "CSS Pages"
20036 ],
20037 initial: "auto",
20038 appliesto: "blockElementsInNormalFlow",
20039 computed: "asSpecified",
20040 order: "uniqueOrder",
20041 status: "standard",
20042 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/page-break-inside"
20043 },
20044 "paint-order": {
20045 syntax: "normal | [ fill || stroke || markers ]",
20046 media: "visual",
20047 inherited: true,
20048 animationType: "discrete",
20049 percentages: "no",
20050 groups: [
20051 "CSS Text"
20052 ],
20053 initial: "normal",
20054 appliesto: "textElements",
20055 computed: "asSpecified",
20056 order: "uniqueOrder",
20057 status: "standard",
20058 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/paint-order"
20059 },
20060 perspective: perspective,
20061 "perspective-origin": {
20062 syntax: "<position>",
20063 media: "visual",
20064 inherited: false,
20065 animationType: "simpleListOfLpc",
20066 percentages: "referToSizeOfBoundingBox",
20067 groups: [
20068 "CSS Transforms"
20069 ],
20070 initial: "50% 50%",
20071 appliesto: "transformableElements",
20072 computed: "forLengthAbsoluteValueOtherwisePercentage",
20073 order: "oneOrTwoValuesLengthAbsoluteKeywordsPercentages",
20074 status: "standard",
20075 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/perspective-origin"
20076 },
20077 "place-content": {
20078 syntax: "<'align-content'> <'justify-content'>?",
20079 media: "visual",
20080 inherited: false,
20081 animationType: "discrete",
20082 percentages: "no",
20083 groups: [
20084 "CSS Box Alignment"
20085 ],
20086 initial: "normal",
20087 appliesto: "multilineFlexContainers",
20088 computed: "asSpecified",
20089 order: "uniqueOrder",
20090 status: "standard",
20091 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/place-content"
20092 },
20093 "place-items": {
20094 syntax: "<'align-items'> <'justify-items'>?",
20095 media: "visual",
20096 inherited: false,
20097 animationType: "discrete",
20098 percentages: "no",
20099 groups: [
20100 "CSS Box Alignment"
20101 ],
20102 initial: [
20103 "align-items",
20104 "justify-items"
20105 ],
20106 appliesto: "allElements",
20107 computed: [
20108 "align-items",
20109 "justify-items"
20110 ],
20111 order: "uniqueOrder",
20112 status: "standard",
20113 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/place-items"
20114 },
20115 "place-self": {
20116 syntax: "<'align-self'> <'justify-self'>?",
20117 media: "visual",
20118 inherited: false,
20119 animationType: "discrete",
20120 percentages: "no",
20121 groups: [
20122 "CSS Box Alignment"
20123 ],
20124 initial: [
20125 "align-self",
20126 "justify-self"
20127 ],
20128 appliesto: "blockLevelBoxesAndAbsolutelyPositionedBoxesAndGridItems",
20129 computed: [
20130 "align-self",
20131 "justify-self"
20132 ],
20133 order: "uniqueOrder",
20134 status: "standard",
20135 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/place-self"
20136 },
20137 "pointer-events": {
20138 syntax: "auto | none | visiblePainted | visibleFill | visibleStroke | visible | painted | fill | stroke | all | inherit",
20139 media: "visual",
20140 inherited: true,
20141 animationType: "discrete",
20142 percentages: "no",
20143 groups: [
20144 "Pointer Events"
20145 ],
20146 initial: "auto",
20147 appliesto: "allElements",
20148 computed: "asSpecified",
20149 order: "uniqueOrder",
20150 status: "standard",
20151 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/pointer-events"
20152 },
20153 position: position$1,
20154 quotes: quotes,
20155 resize: resize,
20156 right: right,
20157 rotate: rotate,
20158 "row-gap": {
20159 syntax: "normal | <length-percentage>",
20160 media: "visual",
20161 inherited: false,
20162 animationType: "lpc",
20163 percentages: "referToDimensionOfContentArea",
20164 groups: [
20165 "CSS Box Alignment"
20166 ],
20167 initial: "normal",
20168 appliesto: "multiColumnElementsFlexContainersGridContainers",
20169 computed: "asSpecifiedWithLengthsAbsoluteAndNormalComputingToZeroExceptMultiColumn",
20170 order: "perGrammar",
20171 status: "standard",
20172 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/row-gap"
20173 },
20174 "ruby-align": {
20175 syntax: "start | center | space-between | space-around",
20176 media: "visual",
20177 inherited: true,
20178 animationType: "discrete",
20179 percentages: "no",
20180 groups: [
20181 "CSS Ruby"
20182 ],
20183 initial: "space-around",
20184 appliesto: "rubyBasesAnnotationsBaseAnnotationContainers",
20185 computed: "asSpecified",
20186 order: "uniqueOrder",
20187 status: "experimental",
20188 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/ruby-align"
20189 },
20190 "ruby-merge": {
20191 syntax: "separate | collapse | auto",
20192 media: "visual",
20193 inherited: true,
20194 animationType: "discrete",
20195 percentages: "no",
20196 groups: [
20197 "CSS Ruby"
20198 ],
20199 initial: "separate",
20200 appliesto: "rubyAnnotationsContainers",
20201 computed: "asSpecified",
20202 order: "uniqueOrder",
20203 status: "experimental"
20204 },
20205 "ruby-position": {
20206 syntax: "over | under | inter-character",
20207 media: "visual",
20208 inherited: true,
20209 animationType: "discrete",
20210 percentages: "no",
20211 groups: [
20212 "CSS Ruby"
20213 ],
20214 initial: "over",
20215 appliesto: "rubyAnnotationsContainers",
20216 computed: "asSpecified",
20217 order: "uniqueOrder",
20218 status: "experimental",
20219 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/ruby-position"
20220 },
20221 scale: scale,
20222 "scrollbar-color": {
20223 syntax: "auto | dark | light | <color>{2}",
20224 media: "visual",
20225 inherited: true,
20226 animationType: "color",
20227 percentages: "no",
20228 groups: [
20229 "CSS Scrollbars"
20230 ],
20231 initial: "auto",
20232 appliesto: "scrollingBoxes",
20233 computed: "asSpecified",
20234 order: "perGrammar",
20235 status: "standard",
20236 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scrollbar-color"
20237 },
20238 "scrollbar-gutter": {
20239 syntax: "auto | [ stable | always ] && both? && force?",
20240 media: "visual",
20241 inherited: false,
20242 animationType: "discrete",
20243 percentages: "no",
20244 groups: [
20245 "CSS Overflow"
20246 ],
20247 initial: "auto",
20248 appliesto: "allElements",
20249 computed: "asSpecified",
20250 order: "perGrammar",
20251 status: "standard",
20252 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scrollbar-gutter"
20253 },
20254 "scrollbar-width": {
20255 syntax: "auto | thin | none",
20256 media: "visual",
20257 inherited: false,
20258 animationType: "discrete",
20259 percentages: "no",
20260 groups: [
20261 "CSS Scrollbars"
20262 ],
20263 initial: "auto",
20264 appliesto: "scrollingBoxes",
20265 computed: "asSpecified",
20266 order: "perGrammar",
20267 status: "standard",
20268 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scrollbar-width"
20269 },
20270 "scroll-behavior": {
20271 syntax: "auto | smooth",
20272 media: "visual",
20273 inherited: false,
20274 animationType: "discrete",
20275 percentages: "no",
20276 groups: [
20277 "CSSOM View"
20278 ],
20279 initial: "auto",
20280 appliesto: "scrollingBoxes",
20281 computed: "asSpecified",
20282 order: "uniqueOrder",
20283 status: "standard",
20284 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-behavior"
20285 },
20286 "scroll-margin": {
20287 syntax: "<length>{1,4}",
20288 media: "visual",
20289 inherited: false,
20290 animationType: "byComputedValueType",
20291 percentages: "no",
20292 groups: [
20293 "CSS Scroll Snap"
20294 ],
20295 initial: "0",
20296 appliesto: "allElements",
20297 computed: "asSpecified",
20298 order: "perGrammar",
20299 status: "standard",
20300 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-margin"
20301 },
20302 "scroll-margin-block": {
20303 syntax: "<length>{1,2}",
20304 media: "visual",
20305 inherited: false,
20306 animationType: "byComputedValueType",
20307 percentages: "no",
20308 groups: [
20309 "CSS Scroll Snap"
20310 ],
20311 initial: "0",
20312 appliesto: "allElements",
20313 computed: "asSpecified",
20314 order: "perGrammar",
20315 status: "standard",
20316 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-margin-block"
20317 },
20318 "scroll-margin-block-start": {
20319 syntax: "<length>",
20320 media: "visual",
20321 inherited: false,
20322 animationType: "byComputedValueType",
20323 percentages: "no",
20324 groups: [
20325 "CSS Scroll Snap"
20326 ],
20327 initial: "0",
20328 appliesto: "allElements",
20329 computed: "asSpecified",
20330 order: "perGrammar",
20331 status: "standard",
20332 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-margin-block-start"
20333 },
20334 "scroll-margin-block-end": {
20335 syntax: "<length>",
20336 media: "visual",
20337 inherited: false,
20338 animationType: "byComputedValueType",
20339 percentages: "no",
20340 groups: [
20341 "CSS Scroll Snap"
20342 ],
20343 initial: "0",
20344 appliesto: "allElements",
20345 computed: "asSpecified",
20346 order: "perGrammar",
20347 status: "standard",
20348 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-margin-block-end"
20349 },
20350 "scroll-margin-bottom": {
20351 syntax: "<length>",
20352 media: "visual",
20353 inherited: false,
20354 animationType: "byComputedValueType",
20355 percentages: "no",
20356 groups: [
20357 "CSS Scroll Snap"
20358 ],
20359 initial: "0",
20360 appliesto: "allElements",
20361 computed: "asSpecified",
20362 order: "perGrammar",
20363 status: "standard",
20364 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-margin-bottom"
20365 },
20366 "scroll-margin-inline": {
20367 syntax: "<length>{1,2}",
20368 media: "visual",
20369 inherited: false,
20370 animationType: "byComputedValueType",
20371 percentages: "no",
20372 groups: [
20373 "CSS Scroll Snap"
20374 ],
20375 initial: "0",
20376 appliesto: "allElements",
20377 computed: "asSpecified",
20378 order: "perGrammar",
20379 status: "standard",
20380 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-margin-inline"
20381 },
20382 "scroll-margin-inline-start": {
20383 syntax: "<length>",
20384 media: "visual",
20385 inherited: false,
20386 animationType: "byComputedValueType",
20387 percentages: "no",
20388 groups: [
20389 "CSS Scroll Snap"
20390 ],
20391 initial: "0",
20392 appliesto: "allElements",
20393 computed: "asSpecified",
20394 order: "perGrammar",
20395 status: "standard",
20396 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-margin-inline-start"
20397 },
20398 "scroll-margin-inline-end": {
20399 syntax: "<length>",
20400 media: "visual",
20401 inherited: false,
20402 animationType: "byComputedValueType",
20403 percentages: "no",
20404 groups: [
20405 "CSS Scroll Snap"
20406 ],
20407 initial: "0",
20408 appliesto: "allElements",
20409 computed: "asSpecified",
20410 order: "perGrammar",
20411 status: "standard",
20412 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-margin-inline-end"
20413 },
20414 "scroll-margin-left": {
20415 syntax: "<length>",
20416 media: "visual",
20417 inherited: false,
20418 animationType: "byComputedValueType",
20419 percentages: "no",
20420 groups: [
20421 "CSS Scroll Snap"
20422 ],
20423 initial: "0",
20424 appliesto: "allElements",
20425 computed: "asSpecified",
20426 order: "perGrammar",
20427 status: "standard",
20428 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-margin-left"
20429 },
20430 "scroll-margin-right": {
20431 syntax: "<length>",
20432 media: "visual",
20433 inherited: false,
20434 animationType: "byComputedValueType",
20435 percentages: "no",
20436 groups: [
20437 "CSS Scroll Snap"
20438 ],
20439 initial: "0",
20440 appliesto: "allElements",
20441 computed: "asSpecified",
20442 order: "perGrammar",
20443 status: "standard",
20444 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-margin-right"
20445 },
20446 "scroll-margin-top": {
20447 syntax: "<length>",
20448 media: "visual",
20449 inherited: false,
20450 animationType: "byComputedValueType",
20451 percentages: "no",
20452 groups: [
20453 "CSS Scroll Snap"
20454 ],
20455 initial: "0",
20456 appliesto: "allElements",
20457 computed: "asSpecified",
20458 order: "perGrammar",
20459 status: "standard",
20460 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-margin-top"
20461 },
20462 "scroll-padding": {
20463 syntax: "[ auto | <length-percentage> ]{1,4}",
20464 media: "visual",
20465 inherited: false,
20466 animationType: "byComputedValueType",
20467 percentages: "relativeToTheScrollContainersScrollport",
20468 groups: [
20469 "CSS Scroll Snap"
20470 ],
20471 initial: "auto",
20472 appliesto: "scrollContainers",
20473 computed: "asSpecified",
20474 order: "perGrammar",
20475 status: "standard",
20476 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-padding"
20477 },
20478 "scroll-padding-block": {
20479 syntax: "[ auto | <length-percentage> ]{1,2}",
20480 media: "visual",
20481 inherited: false,
20482 animationType: "byComputedValueType",
20483 percentages: "relativeToTheScrollContainersScrollport",
20484 groups: [
20485 "CSS Scroll Snap"
20486 ],
20487 initial: "auto",
20488 appliesto: "scrollContainers",
20489 computed: "asSpecified",
20490 order: "perGrammar",
20491 status: "standard",
20492 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-padding-block"
20493 },
20494 "scroll-padding-block-start": {
20495 syntax: "auto | <length-percentage>",
20496 media: "visual",
20497 inherited: false,
20498 animationType: "byComputedValueType",
20499 percentages: "relativeToTheScrollContainersScrollport",
20500 groups: [
20501 "CSS Scroll Snap"
20502 ],
20503 initial: "auto",
20504 appliesto: "scrollContainers",
20505 computed: "asSpecified",
20506 order: "perGrammar",
20507 status: "standard",
20508 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-padding-block-start"
20509 },
20510 "scroll-padding-block-end": {
20511 syntax: "auto | <length-percentage>",
20512 media: "visual",
20513 inherited: false,
20514 animationType: "byComputedValueType",
20515 percentages: "relativeToTheScrollContainersScrollport",
20516 groups: [
20517 "CSS Scroll Snap"
20518 ],
20519 initial: "auto",
20520 appliesto: "scrollContainers",
20521 computed: "asSpecified",
20522 order: "perGrammar",
20523 status: "standard",
20524 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-padding-block-end"
20525 },
20526 "scroll-padding-bottom": {
20527 syntax: "auto | <length-percentage>",
20528 media: "visual",
20529 inherited: false,
20530 animationType: "byComputedValueType",
20531 percentages: "relativeToTheScrollContainersScrollport",
20532 groups: [
20533 "CSS Scroll Snap"
20534 ],
20535 initial: "auto",
20536 appliesto: "scrollContainers",
20537 computed: "asSpecified",
20538 order: "perGrammar",
20539 status: "standard",
20540 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-padding-bottom"
20541 },
20542 "scroll-padding-inline": {
20543 syntax: "[ auto | <length-percentage> ]{1,2}",
20544 media: "visual",
20545 inherited: false,
20546 animationType: "byComputedValueType",
20547 percentages: "relativeToTheScrollContainersScrollport",
20548 groups: [
20549 "CSS Scroll Snap"
20550 ],
20551 initial: "auto",
20552 appliesto: "scrollContainers",
20553 computed: "asSpecified",
20554 order: "perGrammar",
20555 status: "standard",
20556 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-padding-inline"
20557 },
20558 "scroll-padding-inline-start": {
20559 syntax: "auto | <length-percentage>",
20560 media: "visual",
20561 inherited: false,
20562 animationType: "byComputedValueType",
20563 percentages: "relativeToTheScrollContainersScrollport",
20564 groups: [
20565 "CSS Scroll Snap"
20566 ],
20567 initial: "auto",
20568 appliesto: "scrollContainers",
20569 computed: "asSpecified",
20570 order: "perGrammar",
20571 status: "standard",
20572 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-padding-inline-start"
20573 },
20574 "scroll-padding-inline-end": {
20575 syntax: "auto | <length-percentage>",
20576 media: "visual",
20577 inherited: false,
20578 animationType: "byComputedValueType",
20579 percentages: "relativeToTheScrollContainersScrollport",
20580 groups: [
20581 "CSS Scroll Snap"
20582 ],
20583 initial: "auto",
20584 appliesto: "scrollContainers",
20585 computed: "asSpecified",
20586 order: "perGrammar",
20587 status: "standard",
20588 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-padding-inline-end"
20589 },
20590 "scroll-padding-left": {
20591 syntax: "auto | <length-percentage>",
20592 media: "visual",
20593 inherited: false,
20594 animationType: "byComputedValueType",
20595 percentages: "relativeToTheScrollContainersScrollport",
20596 groups: [
20597 "CSS Scroll Snap"
20598 ],
20599 initial: "auto",
20600 appliesto: "scrollContainers",
20601 computed: "asSpecified",
20602 order: "perGrammar",
20603 status: "standard",
20604 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-padding-left"
20605 },
20606 "scroll-padding-right": {
20607 syntax: "auto | <length-percentage>",
20608 media: "visual",
20609 inherited: false,
20610 animationType: "byComputedValueType",
20611 percentages: "relativeToTheScrollContainersScrollport",
20612 groups: [
20613 "CSS Scroll Snap"
20614 ],
20615 initial: "auto",
20616 appliesto: "scrollContainers",
20617 computed: "asSpecified",
20618 order: "perGrammar",
20619 status: "standard",
20620 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-padding-right"
20621 },
20622 "scroll-padding-top": {
20623 syntax: "auto | <length-percentage>",
20624 media: "visual",
20625 inherited: false,
20626 animationType: "byComputedValueType",
20627 percentages: "relativeToTheScrollContainersScrollport",
20628 groups: [
20629 "CSS Scroll Snap"
20630 ],
20631 initial: "auto",
20632 appliesto: "scrollContainers",
20633 computed: "asSpecified",
20634 order: "perGrammar",
20635 status: "standard",
20636 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-padding-top"
20637 },
20638 "scroll-snap-align": {
20639 syntax: "[ none | start | end | center ]{1,2}",
20640 media: "visual",
20641 inherited: false,
20642 animationType: "discrete",
20643 percentages: "no",
20644 groups: [
20645 "CSS Scroll Snap"
20646 ],
20647 initial: "none",
20648 appliesto: "allElements",
20649 computed: "asSpecified",
20650 order: "perGrammar",
20651 status: "standard",
20652 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-snap-align"
20653 },
20654 "scroll-snap-coordinate": {
20655 syntax: "none | <position>#",
20656 media: "interactive",
20657 inherited: false,
20658 animationType: "position",
20659 percentages: "referToBorderBox",
20660 groups: [
20661 "CSS Scroll Snap"
20662 ],
20663 initial: "none",
20664 appliesto: "allElements",
20665 computed: "asSpecifiedRelativeToAbsoluteLengths",
20666 order: "uniqueOrder",
20667 status: "obsolete",
20668 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-snap-coordinate"
20669 },
20670 "scroll-snap-destination": {
20671 syntax: "<position>",
20672 media: "interactive",
20673 inherited: false,
20674 animationType: "position",
20675 percentages: "relativeToScrollContainerPaddingBoxAxis",
20676 groups: [
20677 "CSS Scroll Snap"
20678 ],
20679 initial: "0px 0px",
20680 appliesto: "scrollContainers",
20681 computed: "asSpecifiedRelativeToAbsoluteLengths",
20682 order: "uniqueOrder",
20683 status: "obsolete",
20684 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-snap-destination"
20685 },
20686 "scroll-snap-points-x": {
20687 syntax: "none | repeat( <length-percentage> )",
20688 media: "interactive",
20689 inherited: false,
20690 animationType: "discrete",
20691 percentages: "relativeToScrollContainerPaddingBoxAxis",
20692 groups: [
20693 "CSS Scroll Snap"
20694 ],
20695 initial: "none",
20696 appliesto: "scrollContainers",
20697 computed: "asSpecifiedRelativeToAbsoluteLengths",
20698 order: "uniqueOrder",
20699 status: "obsolete",
20700 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-snap-points-x"
20701 },
20702 "scroll-snap-points-y": {
20703 syntax: "none | repeat( <length-percentage> )",
20704 media: "interactive",
20705 inherited: false,
20706 animationType: "discrete",
20707 percentages: "relativeToScrollContainerPaddingBoxAxis",
20708 groups: [
20709 "CSS Scroll Snap"
20710 ],
20711 initial: "none",
20712 appliesto: "scrollContainers",
20713 computed: "asSpecifiedRelativeToAbsoluteLengths",
20714 order: "uniqueOrder",
20715 status: "obsolete",
20716 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-snap-points-y"
20717 },
20718 "scroll-snap-stop": {
20719 syntax: "normal | always",
20720 media: "visual",
20721 inherited: false,
20722 animationType: "discrete",
20723 percentages: "no",
20724 groups: [
20725 "CSS Scroll Snap"
20726 ],
20727 initial: "normal",
20728 appliesto: "allElements",
20729 computed: "asSpecified",
20730 order: "perGrammar",
20731 status: "standard",
20732 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-snap-stop"
20733 },
20734 "scroll-snap-type": {
20735 syntax: "none | [ x | y | block | inline | both ] [ mandatory | proximity ]?",
20736 media: "interactive",
20737 inherited: false,
20738 animationType: "discrete",
20739 percentages: "no",
20740 groups: [
20741 "CSS Scroll Snap"
20742 ],
20743 initial: "none",
20744 appliesto: "allElements",
20745 computed: "asSpecified",
20746 order: "uniqueOrder",
20747 status: "standard",
20748 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-snap-type"
20749 },
20750 "scroll-snap-type-x": {
20751 syntax: "none | mandatory | proximity",
20752 media: "interactive",
20753 inherited: false,
20754 animationType: "discrete",
20755 percentages: "no",
20756 groups: [
20757 "CSS Scroll Snap"
20758 ],
20759 initial: "none",
20760 appliesto: "scrollContainers",
20761 computed: "asSpecified",
20762 order: "uniqueOrder",
20763 status: "obsolete",
20764 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-snap-type-x"
20765 },
20766 "scroll-snap-type-y": {
20767 syntax: "none | mandatory | proximity",
20768 media: "interactive",
20769 inherited: false,
20770 animationType: "discrete",
20771 percentages: "no",
20772 groups: [
20773 "CSS Scroll Snap"
20774 ],
20775 initial: "none",
20776 appliesto: "scrollContainers",
20777 computed: "asSpecified",
20778 order: "uniqueOrder",
20779 status: "obsolete",
20780 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-snap-type-y"
20781 },
20782 "shape-image-threshold": {
20783 syntax: "<alpha-value>",
20784 media: "visual",
20785 inherited: false,
20786 animationType: "number",
20787 percentages: "no",
20788 groups: [
20789 "CSS Shapes"
20790 ],
20791 initial: "0.0",
20792 appliesto: "floats",
20793 computed: "specifiedValueNumberClipped0To1",
20794 order: "uniqueOrder",
20795 status: "standard",
20796 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/shape-image-threshold"
20797 },
20798 "shape-margin": {
20799 syntax: "<length-percentage>",
20800 media: "visual",
20801 inherited: false,
20802 animationType: "lpc",
20803 percentages: "referToWidthOfContainingBlock",
20804 groups: [
20805 "CSS Shapes"
20806 ],
20807 initial: "0",
20808 appliesto: "floats",
20809 computed: "asSpecifiedRelativeToAbsoluteLengths",
20810 order: "uniqueOrder",
20811 status: "standard",
20812 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/shape-margin"
20813 },
20814 "shape-outside": {
20815 syntax: "none | <shape-box> || <basic-shape> | <image>",
20816 media: "visual",
20817 inherited: false,
20818 animationType: "basicShapeOtherwiseNo",
20819 percentages: "no",
20820 groups: [
20821 "CSS Shapes"
20822 ],
20823 initial: "none",
20824 appliesto: "floats",
20825 computed: "asDefinedForBasicShapeWithAbsoluteURIOtherwiseAsSpecified",
20826 order: "uniqueOrder",
20827 status: "standard",
20828 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/shape-outside"
20829 },
20830 "tab-size": {
20831 syntax: "<integer> | <length>",
20832 media: "visual",
20833 inherited: true,
20834 animationType: "length",
20835 percentages: "no",
20836 groups: [
20837 "CSS Text"
20838 ],
20839 initial: "8",
20840 appliesto: "blockContainers",
20841 computed: "specifiedIntegerOrAbsoluteLength",
20842 order: "uniqueOrder",
20843 status: "standard",
20844 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/tab-size"
20845 },
20846 "table-layout": {
20847 syntax: "auto | fixed",
20848 media: "visual",
20849 inherited: false,
20850 animationType: "discrete",
20851 percentages: "no",
20852 groups: [
20853 "CSS Table"
20854 ],
20855 initial: "auto",
20856 appliesto: "tableElements",
20857 computed: "asSpecified",
20858 order: "uniqueOrder",
20859 status: "standard",
20860 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/table-layout"
20861 },
20862 "text-align": {
20863 syntax: "start | end | left | right | center | justify | match-parent",
20864 media: "visual",
20865 inherited: true,
20866 animationType: "discrete",
20867 percentages: "no",
20868 groups: [
20869 "CSS Text"
20870 ],
20871 initial: "startOrNamelessValueIfLTRRightIfRTL",
20872 appliesto: "blockContainers",
20873 computed: "asSpecifiedExceptMatchParent",
20874 order: "orderOfAppearance",
20875 alsoAppliesTo: [
20876 "::placeholder"
20877 ],
20878 status: "standard",
20879 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-align"
20880 },
20881 "text-align-last": {
20882 syntax: "auto | start | end | left | right | center | justify",
20883 media: "visual",
20884 inherited: true,
20885 animationType: "discrete",
20886 percentages: "no",
20887 groups: [
20888 "CSS Text"
20889 ],
20890 initial: "auto",
20891 appliesto: "blockContainers",
20892 computed: "asSpecified",
20893 order: "uniqueOrder",
20894 status: "standard",
20895 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-align-last"
20896 },
20897 "text-combine-upright": {
20898 syntax: "none | all | [ digits <integer>? ]",
20899 media: "visual",
20900 inherited: true,
20901 animationType: "notAnimatable",
20902 percentages: "no",
20903 groups: [
20904 "CSS Writing Modes"
20905 ],
20906 initial: "none",
20907 appliesto: "nonReplacedInlineElements",
20908 computed: "keywordPlusIntegerIfDigits",
20909 order: "uniqueOrder",
20910 status: "standard",
20911 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-combine-upright"
20912 },
20913 "text-decoration": {
20914 syntax: "<'text-decoration-line'> || <'text-decoration-style'> || <'text-decoration-color'> || <'text-decoration-thickness'>",
20915 media: "visual",
20916 inherited: false,
20917 animationType: [
20918 "text-decoration-color",
20919 "text-decoration-style",
20920 "text-decoration-line",
20921 "text-decoration-thickness"
20922 ],
20923 percentages: "no",
20924 groups: [
20925 "CSS Text Decoration"
20926 ],
20927 initial: [
20928 "text-decoration-color",
20929 "text-decoration-style",
20930 "text-decoration-line"
20931 ],
20932 appliesto: "allElements",
20933 computed: [
20934 "text-decoration-line",
20935 "text-decoration-style",
20936 "text-decoration-color",
20937 "text-decoration-thickness"
20938 ],
20939 order: "orderOfAppearance",
20940 alsoAppliesTo: [
20941 "::first-letter",
20942 "::first-line",
20943 "::placeholder"
20944 ],
20945 status: "standard",
20946 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-decoration"
20947 },
20948 "text-decoration-color": {
20949 syntax: "<color>",
20950 media: "visual",
20951 inherited: false,
20952 animationType: "color",
20953 percentages: "no",
20954 groups: [
20955 "CSS Text Decoration"
20956 ],
20957 initial: "currentcolor",
20958 appliesto: "allElements",
20959 computed: "computedColor",
20960 order: "uniqueOrder",
20961 alsoAppliesTo: [
20962 "::first-letter",
20963 "::first-line",
20964 "::placeholder"
20965 ],
20966 status: "standard",
20967 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-decoration-color"
20968 },
20969 "text-decoration-line": {
20970 syntax: "none | [ underline || overline || line-through || blink ] | spelling-error | grammar-error",
20971 media: "visual",
20972 inherited: false,
20973 animationType: "discrete",
20974 percentages: "no",
20975 groups: [
20976 "CSS Text Decoration"
20977 ],
20978 initial: "none",
20979 appliesto: "allElements",
20980 computed: "asSpecified",
20981 order: "orderOfAppearance",
20982 alsoAppliesTo: [
20983 "::first-letter",
20984 "::first-line",
20985 "::placeholder"
20986 ],
20987 status: "standard",
20988 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-decoration-line"
20989 },
20990 "text-decoration-skip": {
20991 syntax: "none | [ objects || [ spaces | [ leading-spaces || trailing-spaces ] ] || edges || box-decoration ]",
20992 media: "visual",
20993 inherited: true,
20994 animationType: "discrete",
20995 percentages: "no",
20996 groups: [
20997 "CSS Text Decoration"
20998 ],
20999 initial: "objects",
21000 appliesto: "allElements",
21001 computed: "asSpecified",
21002 order: "orderOfAppearance",
21003 status: "experimental",
21004 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-decoration-skip"
21005 },
21006 "text-decoration-skip-ink": {
21007 syntax: "auto | all | none",
21008 media: "visual",
21009 inherited: true,
21010 animationType: "discrete",
21011 percentages: "no",
21012 groups: [
21013 "CSS Text Decoration"
21014 ],
21015 initial: "auto",
21016 appliesto: "allElements",
21017 computed: "asSpecified",
21018 order: "orderOfAppearance",
21019 status: "standard",
21020 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-decoration-skip-ink"
21021 },
21022 "text-decoration-style": {
21023 syntax: "solid | double | dotted | dashed | wavy",
21024 media: "visual",
21025 inherited: false,
21026 animationType: "discrete",
21027 percentages: "no",
21028 groups: [
21029 "CSS Text Decoration"
21030 ],
21031 initial: "solid",
21032 appliesto: "allElements",
21033 computed: "asSpecified",
21034 order: "uniqueOrder",
21035 alsoAppliesTo: [
21036 "::first-letter",
21037 "::first-line",
21038 "::placeholder"
21039 ],
21040 status: "standard",
21041 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-decoration-style"
21042 },
21043 "text-decoration-thickness": {
21044 syntax: "auto | from-font | <length> | <percentage> ",
21045 media: "visual",
21046 inherited: false,
21047 animationType: "byComputedValueType",
21048 percentages: "referToElementFontSize",
21049 groups: [
21050 "CSS Text Decoration"
21051 ],
21052 initial: "auto",
21053 appliesto: "allElements",
21054 computed: "asSpecified",
21055 order: "uniqueOrder",
21056 alsoAppliesTo: [
21057 "::first-letter",
21058 "::first-line",
21059 "::placeholder"
21060 ],
21061 status: "standard",
21062 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-decoration-thickness"
21063 },
21064 "text-emphasis": {
21065 syntax: "<'text-emphasis-style'> || <'text-emphasis-color'>",
21066 media: "visual",
21067 inherited: false,
21068 animationType: [
21069 "text-emphasis-color",
21070 "text-emphasis-style"
21071 ],
21072 percentages: "no",
21073 groups: [
21074 "CSS Text Decoration"
21075 ],
21076 initial: [
21077 "text-emphasis-style",
21078 "text-emphasis-color"
21079 ],
21080 appliesto: "allElements",
21081 computed: [
21082 "text-emphasis-style",
21083 "text-emphasis-color"
21084 ],
21085 order: "orderOfAppearance",
21086 status: "standard",
21087 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-emphasis"
21088 },
21089 "text-emphasis-color": {
21090 syntax: "<color>",
21091 media: "visual",
21092 inherited: false,
21093 animationType: "color",
21094 percentages: "no",
21095 groups: [
21096 "CSS Text Decoration"
21097 ],
21098 initial: "currentcolor",
21099 appliesto: "allElements",
21100 computed: "computedColor",
21101 order: "uniqueOrder",
21102 status: "standard",
21103 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-emphasis-color"
21104 },
21105 "text-emphasis-position": {
21106 syntax: "[ over | under ] && [ right | left ]",
21107 media: "visual",
21108 inherited: false,
21109 animationType: "discrete",
21110 percentages: "no",
21111 groups: [
21112 "CSS Text Decoration"
21113 ],
21114 initial: "over right",
21115 appliesto: "allElements",
21116 computed: "asSpecified",
21117 order: "uniqueOrder",
21118 status: "standard",
21119 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-emphasis-position"
21120 },
21121 "text-emphasis-style": {
21122 syntax: "none | [ [ filled | open ] || [ dot | circle | double-circle | triangle | sesame ] ] | <string>",
21123 media: "visual",
21124 inherited: false,
21125 animationType: "discrete",
21126 percentages: "no",
21127 groups: [
21128 "CSS Text Decoration"
21129 ],
21130 initial: "none",
21131 appliesto: "allElements",
21132 computed: "asSpecified",
21133 order: "uniqueOrder",
21134 status: "standard",
21135 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-emphasis-style"
21136 },
21137 "text-indent": {
21138 syntax: "<length-percentage> && hanging? && each-line?",
21139 media: "visual",
21140 inherited: true,
21141 animationType: "lpc",
21142 percentages: "referToWidthOfContainingBlock",
21143 groups: [
21144 "CSS Text"
21145 ],
21146 initial: "0",
21147 appliesto: "blockContainers",
21148 computed: "percentageOrAbsoluteLengthPlusKeywords",
21149 order: "lengthOrPercentageBeforeKeywords",
21150 status: "standard",
21151 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-indent"
21152 },
21153 "text-justify": {
21154 syntax: "auto | inter-character | inter-word | none",
21155 media: "visual",
21156 inherited: true,
21157 animationType: "discrete",
21158 percentages: "no",
21159 groups: [
21160 "CSS Text"
21161 ],
21162 initial: "auto",
21163 appliesto: "inlineLevelAndTableCellElements",
21164 computed: "asSpecified",
21165 order: "uniqueOrder",
21166 status: "standard",
21167 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-justify"
21168 },
21169 "text-orientation": {
21170 syntax: "mixed | upright | sideways",
21171 media: "visual",
21172 inherited: true,
21173 animationType: "discrete",
21174 percentages: "no",
21175 groups: [
21176 "CSS Writing Modes"
21177 ],
21178 initial: "mixed",
21179 appliesto: "allElementsExceptTableRowGroupsRowsColumnGroupsAndColumns",
21180 computed: "asSpecified",
21181 order: "uniqueOrder",
21182 status: "standard",
21183 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-orientation"
21184 },
21185 "text-overflow": {
21186 syntax: "[ clip | ellipsis | <string> ]{1,2}",
21187 media: "visual",
21188 inherited: false,
21189 animationType: "discrete",
21190 percentages: "no",
21191 groups: [
21192 "CSS Basic User Interface"
21193 ],
21194 initial: "clip",
21195 appliesto: "blockContainerElements",
21196 computed: "asSpecified",
21197 order: "uniqueOrder",
21198 alsoAppliesTo: [
21199 "::placeholder"
21200 ],
21201 status: "standard",
21202 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-overflow"
21203 },
21204 "text-rendering": {
21205 syntax: "auto | optimizeSpeed | optimizeLegibility | geometricPrecision",
21206 media: "visual",
21207 inherited: true,
21208 animationType: "discrete",
21209 percentages: "no",
21210 groups: [
21211 "CSS Miscellaneous"
21212 ],
21213 initial: "auto",
21214 appliesto: "textElements",
21215 computed: "asSpecified",
21216 order: "uniqueOrder",
21217 status: "standard",
21218 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-rendering"
21219 },
21220 "text-shadow": {
21221 syntax: "none | <shadow-t>#",
21222 media: "visual",
21223 inherited: true,
21224 animationType: "shadowList",
21225 percentages: "no",
21226 groups: [
21227 "CSS Text Decoration"
21228 ],
21229 initial: "none",
21230 appliesto: "allElements",
21231 computed: "colorPlusThreeAbsoluteLengths",
21232 order: "uniqueOrder",
21233 alsoAppliesTo: [
21234 "::first-letter",
21235 "::first-line",
21236 "::placeholder"
21237 ],
21238 status: "standard",
21239 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-shadow"
21240 },
21241 "text-size-adjust": {
21242 syntax: "none | auto | <percentage>",
21243 media: "visual",
21244 inherited: true,
21245 animationType: "discrete",
21246 percentages: "referToSizeOfFont",
21247 groups: [
21248 "CSS Text"
21249 ],
21250 initial: "autoForSmartphoneBrowsersSupportingInflation",
21251 appliesto: "allElements",
21252 computed: "asSpecified",
21253 order: "uniqueOrder",
21254 status: "experimental",
21255 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-size-adjust"
21256 },
21257 "text-transform": {
21258 syntax: "none | capitalize | uppercase | lowercase | full-width | full-size-kana",
21259 media: "visual",
21260 inherited: true,
21261 animationType: "discrete",
21262 percentages: "no",
21263 groups: [
21264 "CSS Text"
21265 ],
21266 initial: "none",
21267 appliesto: "allElements",
21268 computed: "asSpecified",
21269 order: "uniqueOrder",
21270 alsoAppliesTo: [
21271 "::first-letter",
21272 "::first-line",
21273 "::placeholder"
21274 ],
21275 status: "standard",
21276 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-transform"
21277 },
21278 "text-underline-offset": {
21279 syntax: "auto | <length> | <percentage> ",
21280 media: "visual",
21281 inherited: true,
21282 animationType: "byComputedValueType",
21283 percentages: "referToElementFontSize",
21284 groups: [
21285 "CSS Text Decoration"
21286 ],
21287 initial: "auto",
21288 appliesto: "allElements",
21289 computed: "asSpecified",
21290 order: "uniqueOrder",
21291 alsoAppliesTo: [
21292 "::first-letter",
21293 "::first-line",
21294 "::placeholder"
21295 ],
21296 status: "standard",
21297 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-underline-offset"
21298 },
21299 "text-underline-position": {
21300 syntax: "auto | from-font | [ under || [ left | right ] ]",
21301 media: "visual",
21302 inherited: true,
21303 animationType: "discrete",
21304 percentages: "no",
21305 groups: [
21306 "CSS Text Decoration"
21307 ],
21308 initial: "auto",
21309 appliesto: "allElements",
21310 computed: "asSpecified",
21311 order: "orderOfAppearance",
21312 status: "standard",
21313 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-underline-position"
21314 },
21315 top: top,
21316 "touch-action": {
21317 syntax: "auto | none | [ [ pan-x | pan-left | pan-right ] || [ pan-y | pan-up | pan-down ] || pinch-zoom ] | manipulation",
21318 media: "visual",
21319 inherited: false,
21320 animationType: "discrete",
21321 percentages: "no",
21322 groups: [
21323 "Pointer Events"
21324 ],
21325 initial: "auto",
21326 appliesto: "allElementsExceptNonReplacedInlineElementsTableRowsColumnsRowColumnGroups",
21327 computed: "asSpecified",
21328 order: "uniqueOrder",
21329 status: "standard",
21330 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/touch-action"
21331 },
21332 transform: transform,
21333 "transform-box": {
21334 syntax: "content-box | border-box | fill-box | stroke-box | view-box",
21335 media: "visual",
21336 inherited: false,
21337 animationType: "discrete",
21338 percentages: "no",
21339 groups: [
21340 "CSS Transforms"
21341 ],
21342 initial: "view-box",
21343 appliesto: "transformableElements",
21344 computed: "asSpecified",
21345 order: "perGrammar",
21346 status: "standard",
21347 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/transform-box"
21348 },
21349 "transform-origin": {
21350 syntax: "[ <length-percentage> | left | center | right | top | bottom ] | [ [ <length-percentage> | left | center | right ] && [ <length-percentage> | top | center | bottom ] ] <length>?",
21351 media: "visual",
21352 inherited: false,
21353 animationType: "simpleListOfLpc",
21354 percentages: "referToSizeOfBoundingBox",
21355 groups: [
21356 "CSS Transforms"
21357 ],
21358 initial: "50% 50% 0",
21359 appliesto: "transformableElements",
21360 computed: "forLengthAbsoluteValueOtherwisePercentage",
21361 order: "oneOrTwoValuesLengthAbsoluteKeywordsPercentages",
21362 status: "standard",
21363 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/transform-origin"
21364 },
21365 "transform-style": {
21366 syntax: "flat | preserve-3d",
21367 media: "visual",
21368 inherited: false,
21369 animationType: "discrete",
21370 percentages: "no",
21371 groups: [
21372 "CSS Transforms"
21373 ],
21374 initial: "flat",
21375 appliesto: "transformableElements",
21376 computed: "asSpecified",
21377 order: "uniqueOrder",
21378 stacking: true,
21379 status: "standard",
21380 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/transform-style"
21381 },
21382 transition: transition,
21383 "transition-delay": {
21384 syntax: "<time>#",
21385 media: "interactive",
21386 inherited: false,
21387 animationType: "discrete",
21388 percentages: "no",
21389 groups: [
21390 "CSS Transitions"
21391 ],
21392 initial: "0s",
21393 appliesto: "allElementsAndPseudos",
21394 computed: "asSpecified",
21395 order: "uniqueOrder",
21396 status: "standard",
21397 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/transition-delay"
21398 },
21399 "transition-duration": {
21400 syntax: "<time>#",
21401 media: "interactive",
21402 inherited: false,
21403 animationType: "discrete",
21404 percentages: "no",
21405 groups: [
21406 "CSS Transitions"
21407 ],
21408 initial: "0s",
21409 appliesto: "allElementsAndPseudos",
21410 computed: "asSpecified",
21411 order: "uniqueOrder",
21412 status: "standard",
21413 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/transition-duration"
21414 },
21415 "transition-property": {
21416 syntax: "none | <single-transition-property>#",
21417 media: "visual",
21418 inherited: false,
21419 animationType: "discrete",
21420 percentages: "no",
21421 groups: [
21422 "CSS Transitions"
21423 ],
21424 initial: "all",
21425 appliesto: "allElementsAndPseudos",
21426 computed: "asSpecified",
21427 order: "uniqueOrder",
21428 status: "standard",
21429 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/transition-property"
21430 },
21431 "transition-timing-function": {
21432 syntax: "<timing-function>#",
21433 media: "interactive",
21434 inherited: false,
21435 animationType: "discrete",
21436 percentages: "no",
21437 groups: [
21438 "CSS Transitions"
21439 ],
21440 initial: "ease",
21441 appliesto: "allElementsAndPseudos",
21442 computed: "asSpecified",
21443 order: "uniqueOrder",
21444 status: "standard",
21445 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/transition-timing-function"
21446 },
21447 translate: translate,
21448 "unicode-bidi": {
21449 syntax: "normal | embed | isolate | bidi-override | isolate-override | plaintext",
21450 media: "visual",
21451 inherited: false,
21452 animationType: "discrete",
21453 percentages: "no",
21454 groups: [
21455 "CSS Writing Modes"
21456 ],
21457 initial: "normal",
21458 appliesto: "allElementsSomeValuesNoEffectOnNonInlineElements",
21459 computed: "asSpecified",
21460 order: "uniqueOrder",
21461 status: "standard",
21462 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/unicode-bidi"
21463 },
21464 "user-select": {
21465 syntax: "auto | text | none | contain | all",
21466 media: "visual",
21467 inherited: false,
21468 animationType: "discrete",
21469 percentages: "no",
21470 groups: [
21471 "CSS Basic User Interface"
21472 ],
21473 initial: "auto",
21474 appliesto: "allElements",
21475 computed: "asSpecified",
21476 order: "uniqueOrder",
21477 status: "nonstandard",
21478 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/user-select"
21479 },
21480 "vertical-align": {
21481 syntax: "baseline | sub | super | text-top | text-bottom | middle | top | bottom | <percentage> | <length>",
21482 media: "visual",
21483 inherited: false,
21484 animationType: "length",
21485 percentages: "referToLineHeight",
21486 groups: [
21487 "CSS Table"
21488 ],
21489 initial: "baseline",
21490 appliesto: "inlineLevelAndTableCellElements",
21491 computed: "absoluteLengthOrKeyword",
21492 order: "uniqueOrder",
21493 alsoAppliesTo: [
21494 "::first-letter",
21495 "::first-line",
21496 "::placeholder"
21497 ],
21498 status: "standard",
21499 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/vertical-align"
21500 },
21501 visibility: visibility,
21502 "white-space": {
21503 syntax: "normal | pre | nowrap | pre-wrap | pre-line | break-spaces",
21504 media: "visual",
21505 inherited: true,
21506 animationType: "discrete",
21507 percentages: "no",
21508 groups: [
21509 "CSS Text"
21510 ],
21511 initial: "normal",
21512 appliesto: "allElements",
21513 computed: "asSpecified",
21514 order: "uniqueOrder",
21515 status: "standard",
21516 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/white-space"
21517 },
21518 widows: widows,
21519 width: width,
21520 "will-change": {
21521 syntax: "auto | <animateable-feature>#",
21522 media: "all",
21523 inherited: false,
21524 animationType: "discrete",
21525 percentages: "no",
21526 groups: [
21527 "CSS Will Change"
21528 ],
21529 initial: "auto",
21530 appliesto: "allElements",
21531 computed: "asSpecified",
21532 order: "uniqueOrder",
21533 status: "standard",
21534 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/will-change"
21535 },
21536 "word-break": {
21537 syntax: "normal | break-all | keep-all | break-word",
21538 media: "visual",
21539 inherited: true,
21540 animationType: "discrete",
21541 percentages: "no",
21542 groups: [
21543 "CSS Text"
21544 ],
21545 initial: "normal",
21546 appliesto: "allElements",
21547 computed: "asSpecified",
21548 order: "uniqueOrder",
21549 status: "standard",
21550 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/word-break"
21551 },
21552 "word-spacing": {
21553 syntax: "normal | <length-percentage>",
21554 media: "visual",
21555 inherited: true,
21556 animationType: "length",
21557 percentages: "referToWidthOfAffectedGlyph",
21558 groups: [
21559 "CSS Text"
21560 ],
21561 initial: "normal",
21562 appliesto: "allElements",
21563 computed: "optimumMinAndMaxValueOfAbsoluteLengthPercentageOrNormal",
21564 order: "uniqueOrder",
21565 alsoAppliesTo: [
21566 "::first-letter",
21567 "::first-line",
21568 "::placeholder"
21569 ],
21570 status: "standard",
21571 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/word-spacing"
21572 },
21573 "word-wrap": {
21574 syntax: "normal | break-word",
21575 media: "visual",
21576 inherited: true,
21577 animationType: "discrete",
21578 percentages: "no",
21579 groups: [
21580 "CSS Text"
21581 ],
21582 initial: "normal",
21583 appliesto: "nonReplacedInlineElements",
21584 computed: "asSpecified",
21585 order: "uniqueOrder",
21586 status: "standard",
21587 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/overflow-wrap"
21588 },
21589 "writing-mode": {
21590 syntax: "horizontal-tb | vertical-rl | vertical-lr | sideways-rl | sideways-lr",
21591 media: "visual",
21592 inherited: true,
21593 animationType: "discrete",
21594 percentages: "no",
21595 groups: [
21596 "CSS Writing Modes"
21597 ],
21598 initial: "horizontal-tb",
21599 appliesto: "allElementsExceptTableRowColumnGroupsTableRowsColumns",
21600 computed: "asSpecified",
21601 order: "uniqueOrder",
21602 status: "standard",
21603 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/writing-mode"
21604 },
21605 "z-index": {
21606 syntax: "auto | <integer>",
21607 media: "visual",
21608 inherited: false,
21609 animationType: "integer",
21610 percentages: "no",
21611 groups: [
21612 "CSS Positioning"
21613 ],
21614 initial: "auto",
21615 appliesto: "positionedElements",
21616 computed: "asSpecified",
21617 order: "uniqueOrder",
21618 stacking: true,
21619 status: "standard",
21620 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/z-index"
21621 },
21622 zoom: zoom
21623 };
21624
21625 var attachment = {
21626 syntax: "scroll | fixed | local"
21627 };
21628 var box = {
21629 syntax: "border-box | padding-box | content-box"
21630 };
21631 var color = {
21632 syntax: "<rgb()> | <rgba()> | <hsl()> | <hsla()> | <hex-color> | <named-color> | currentcolor | <deprecated-system-color>"
21633 };
21634 var combinator = {
21635 syntax: "'>' | '+' | '~' | [ '||' ]"
21636 };
21637 var gradient = {
21638 syntax: "<linear-gradient()> | <repeating-linear-gradient()> | <radial-gradient()> | <repeating-radial-gradient()> | <conic-gradient()>"
21639 };
21640 var hue = {
21641 syntax: "<number> | <angle>"
21642 };
21643 var image = {
21644 syntax: "<url> | <image()> | <image-set()> | <element()> | <paint()> | <cross-fade()> | <gradient>"
21645 };
21646 var nth$1 = {
21647 syntax: "<an-plus-b> | even | odd"
21648 };
21649 var position = {
21650 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> ] ]"
21651 };
21652 var quote = {
21653 syntax: "open-quote | close-quote | no-open-quote | no-close-quote"
21654 };
21655 var shadow = {
21656 syntax: "inset? && <length>{2,4} && <color>?"
21657 };
21658 var shape = {
21659 syntax: "rect(<top>, <right>, <bottom>, <left>)"
21660 };
21661 var size = {
21662 syntax: "closest-side | farthest-side | closest-corner | farthest-corner | <length> | <length-percentage>{2}"
21663 };
21664 var symbol = {
21665 syntax: "<string> | <image> | <custom-ident>"
21666 };
21667 var target = {
21668 syntax: "<target-counter()> | <target-counters()> | <target-text()>"
21669 };
21670 var require$$2 = {
21671 "absolute-size": {
21672 syntax: "xx-small | x-small | small | medium | large | x-large | xx-large | xxx-large"
21673 },
21674 "alpha-value": {
21675 syntax: "<number> | <percentage>"
21676 },
21677 "angle-percentage": {
21678 syntax: "<angle> | <percentage>"
21679 },
21680 "angular-color-hint": {
21681 syntax: "<angle-percentage>"
21682 },
21683 "angular-color-stop": {
21684 syntax: "<color> && <color-stop-angle>?"
21685 },
21686 "angular-color-stop-list": {
21687 syntax: "[ <angular-color-stop> [, <angular-color-hint>]? ]# , <angular-color-stop>"
21688 },
21689 "animateable-feature": {
21690 syntax: "scroll-position | contents | <custom-ident>"
21691 },
21692 attachment: attachment,
21693 "attr()": {
21694 syntax: "attr( <attr-name> <type-or-unit>? [, <attr-fallback> ]? )"
21695 },
21696 "attr-matcher": {
21697 syntax: "[ '~' | '|' | '^' | '$' | '*' ]? '='"
21698 },
21699 "attr-modifier": {
21700 syntax: "i | s"
21701 },
21702 "attribute-selector": {
21703 syntax: "'[' <wq-name> ']' | '[' <wq-name> <attr-matcher> [ <string-token> | <ident-token> ] <attr-modifier>? ']'"
21704 },
21705 "auto-repeat": {
21706 syntax: "repeat( [ auto-fill | auto-fit ] , [ <line-names>? <fixed-size> ]+ <line-names>? )"
21707 },
21708 "auto-track-list": {
21709 syntax: "[ <line-names>? [ <fixed-size> | <fixed-repeat> ] ]* <line-names>? <auto-repeat>\n[ <line-names>? [ <fixed-size> | <fixed-repeat> ] ]* <line-names>?"
21710 },
21711 "baseline-position": {
21712 syntax: "[ first | last ]? baseline"
21713 },
21714 "basic-shape": {
21715 syntax: "<inset()> | <circle()> | <ellipse()> | <polygon()> | <path()>"
21716 },
21717 "bg-image": {
21718 syntax: "none | <image>"
21719 },
21720 "bg-layer": {
21721 syntax: "<bg-image> || <bg-position> [ / <bg-size> ]? || <repeat-style> || <attachment> || <box> || <box>"
21722 },
21723 "bg-position": {
21724 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>? ] ]"
21725 },
21726 "bg-size": {
21727 syntax: "[ <length-percentage> | auto ]{1,2} | cover | contain"
21728 },
21729 "blur()": {
21730 syntax: "blur( <length> )"
21731 },
21732 "blend-mode": {
21733 syntax: "normal | multiply | screen | overlay | darken | lighten | color-dodge | color-burn | hard-light | soft-light | difference | exclusion | hue | saturation | color | luminosity"
21734 },
21735 box: box,
21736 "brightness()": {
21737 syntax: "brightness( <number-percentage> )"
21738 },
21739 "calc()": {
21740 syntax: "calc( <calc-sum> )"
21741 },
21742 "calc-sum": {
21743 syntax: "<calc-product> [ [ '+' | '-' ] <calc-product> ]*"
21744 },
21745 "calc-product": {
21746 syntax: "<calc-value> [ '*' <calc-value> | '/' <number> ]*"
21747 },
21748 "calc-value": {
21749 syntax: "<number> | <dimension> | <percentage> | ( <calc-sum> )"
21750 },
21751 "cf-final-image": {
21752 syntax: "<image> | <color>"
21753 },
21754 "cf-mixing-image": {
21755 syntax: "<percentage>? && <image>"
21756 },
21757 "circle()": {
21758 syntax: "circle( [ <shape-radius> ]? [ at <position> ]? )"
21759 },
21760 "clamp()": {
21761 syntax: "clamp( <calc-sum>#{3} )"
21762 },
21763 "class-selector": {
21764 syntax: "'.' <ident-token>"
21765 },
21766 "clip-source": {
21767 syntax: "<url>"
21768 },
21769 color: color,
21770 "color-stop": {
21771 syntax: "<color-stop-length> | <color-stop-angle>"
21772 },
21773 "color-stop-angle": {
21774 syntax: "<angle-percentage>{1,2}"
21775 },
21776 "color-stop-length": {
21777 syntax: "<length-percentage>{1,2}"
21778 },
21779 "color-stop-list": {
21780 syntax: "[ <linear-color-stop> [, <linear-color-hint>]? ]# , <linear-color-stop>"
21781 },
21782 combinator: combinator,
21783 "common-lig-values": {
21784 syntax: "[ common-ligatures | no-common-ligatures ]"
21785 },
21786 "compat-auto": {
21787 syntax: "searchfield | textarea | push-button | slider-horizontal | checkbox | radio | square-button | menulist | listbox | meter | progress-bar | button"
21788 },
21789 "composite-style": {
21790 syntax: "clear | copy | source-over | source-in | source-out | source-atop | destination-over | destination-in | destination-out | destination-atop | xor"
21791 },
21792 "compositing-operator": {
21793 syntax: "add | subtract | intersect | exclude"
21794 },
21795 "compound-selector": {
21796 syntax: "[ <type-selector>? <subclass-selector>* [ <pseudo-element-selector> <pseudo-class-selector>* ]* ]!"
21797 },
21798 "compound-selector-list": {
21799 syntax: "<compound-selector>#"
21800 },
21801 "complex-selector": {
21802 syntax: "<compound-selector> [ <combinator>? <compound-selector> ]*"
21803 },
21804 "complex-selector-list": {
21805 syntax: "<complex-selector>#"
21806 },
21807 "conic-gradient()": {
21808 syntax: "conic-gradient( [ from <angle> ]? [ at <position> ]?, <angular-color-stop-list> )"
21809 },
21810 "contextual-alt-values": {
21811 syntax: "[ contextual | no-contextual ]"
21812 },
21813 "content-distribution": {
21814 syntax: "space-between | space-around | space-evenly | stretch"
21815 },
21816 "content-list": {
21817 syntax: "[ <string> | contents | <image> | <quote> | <target> | <leader()> ]+"
21818 },
21819 "content-position": {
21820 syntax: "center | start | end | flex-start | flex-end"
21821 },
21822 "content-replacement": {
21823 syntax: "<image>"
21824 },
21825 "contrast()": {
21826 syntax: "contrast( [ <number-percentage> ] )"
21827 },
21828 "counter()": {
21829 syntax: "counter( <custom-ident>, <counter-style>? )"
21830 },
21831 "counter-style": {
21832 syntax: "<counter-style-name> | symbols()"
21833 },
21834 "counter-style-name": {
21835 syntax: "<custom-ident>"
21836 },
21837 "counters()": {
21838 syntax: "counters( <custom-ident>, <string>, <counter-style>? )"
21839 },
21840 "cross-fade()": {
21841 syntax: "cross-fade( <cf-mixing-image> , <cf-final-image>? )"
21842 },
21843 "cubic-bezier-timing-function": {
21844 syntax: "ease | ease-in | ease-out | ease-in-out | cubic-bezier(<number [0,1]>, <number>, <number [0,1]>, <number>)"
21845 },
21846 "deprecated-system-color": {
21847 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"
21848 },
21849 "discretionary-lig-values": {
21850 syntax: "[ discretionary-ligatures | no-discretionary-ligatures ]"
21851 },
21852 "display-box": {
21853 syntax: "contents | none"
21854 },
21855 "display-inside": {
21856 syntax: "flow | flow-root | table | flex | grid | ruby"
21857 },
21858 "display-internal": {
21859 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"
21860 },
21861 "display-legacy": {
21862 syntax: "inline-block | inline-list-item | inline-table | inline-flex | inline-grid"
21863 },
21864 "display-listitem": {
21865 syntax: "<display-outside>? && [ flow | flow-root ]? && list-item"
21866 },
21867 "display-outside": {
21868 syntax: "block | inline | run-in"
21869 },
21870 "drop-shadow()": {
21871 syntax: "drop-shadow( <length>{2,3} <color>? )"
21872 },
21873 "east-asian-variant-values": {
21874 syntax: "[ jis78 | jis83 | jis90 | jis04 | simplified | traditional ]"
21875 },
21876 "east-asian-width-values": {
21877 syntax: "[ full-width | proportional-width ]"
21878 },
21879 "element()": {
21880 syntax: "element( <id-selector> )"
21881 },
21882 "ellipse()": {
21883 syntax: "ellipse( [ <shape-radius>{2} ]? [ at <position> ]? )"
21884 },
21885 "ending-shape": {
21886 syntax: "circle | ellipse"
21887 },
21888 "env()": {
21889 syntax: "env( <custom-ident> , <declaration-value>? )"
21890 },
21891 "explicit-track-list": {
21892 syntax: "[ <line-names>? <track-size> ]+ <line-names>?"
21893 },
21894 "family-name": {
21895 syntax: "<string> | <custom-ident>+"
21896 },
21897 "feature-tag-value": {
21898 syntax: "<string> [ <integer> | on | off ]?"
21899 },
21900 "feature-type": {
21901 syntax: "@stylistic | @historical-forms | @styleset | @character-variant | @swash | @ornaments | @annotation"
21902 },
21903 "feature-value-block": {
21904 syntax: "<feature-type> '{' <feature-value-declaration-list> '}'"
21905 },
21906 "feature-value-block-list": {
21907 syntax: "<feature-value-block>+"
21908 },
21909 "feature-value-declaration": {
21910 syntax: "<custom-ident>: <integer>+;"
21911 },
21912 "feature-value-declaration-list": {
21913 syntax: "<feature-value-declaration>"
21914 },
21915 "feature-value-name": {
21916 syntax: "<custom-ident>"
21917 },
21918 "fill-rule": {
21919 syntax: "nonzero | evenodd"
21920 },
21921 "filter-function": {
21922 syntax: "<blur()> | <brightness()> | <contrast()> | <drop-shadow()> | <grayscale()> | <hue-rotate()> | <invert()> | <opacity()> | <saturate()> | <sepia()>"
21923 },
21924 "filter-function-list": {
21925 syntax: "[ <filter-function> | <url> ]+"
21926 },
21927 "final-bg-layer": {
21928 syntax: "<'background-color'> || <bg-image> || <bg-position> [ / <bg-size> ]? || <repeat-style> || <attachment> || <box> || <box>"
21929 },
21930 "fit-content()": {
21931 syntax: "fit-content( [ <length> | <percentage> ] )"
21932 },
21933 "fixed-breadth": {
21934 syntax: "<length-percentage>"
21935 },
21936 "fixed-repeat": {
21937 syntax: "repeat( [ <positive-integer> ] , [ <line-names>? <fixed-size> ]+ <line-names>? )"
21938 },
21939 "fixed-size": {
21940 syntax: "<fixed-breadth> | minmax( <fixed-breadth> , <track-breadth> ) | minmax( <inflexible-breadth> , <fixed-breadth> )"
21941 },
21942 "font-stretch-absolute": {
21943 syntax: "normal | ultra-condensed | extra-condensed | condensed | semi-condensed | semi-expanded | expanded | extra-expanded | ultra-expanded | <percentage>"
21944 },
21945 "font-variant-css21": {
21946 syntax: "[ normal | small-caps ]"
21947 },
21948 "font-weight-absolute": {
21949 syntax: "normal | bold | <number [1,1000]>"
21950 },
21951 "frequency-percentage": {
21952 syntax: "<frequency> | <percentage>"
21953 },
21954 "general-enclosed": {
21955 syntax: "[ <function-token> <any-value> ) ] | ( <ident> <any-value> )"
21956 },
21957 "generic-family": {
21958 syntax: "serif | sans-serif | cursive | fantasy | monospace"
21959 },
21960 "generic-name": {
21961 syntax: "serif | sans-serif | cursive | fantasy | monospace"
21962 },
21963 "geometry-box": {
21964 syntax: "<shape-box> | fill-box | stroke-box | view-box"
21965 },
21966 gradient: gradient,
21967 "grayscale()": {
21968 syntax: "grayscale( <number-percentage> )"
21969 },
21970 "grid-line": {
21971 syntax: "auto | <custom-ident> | [ <integer> && <custom-ident>? ] | [ span && [ <integer> || <custom-ident> ] ]"
21972 },
21973 "historical-lig-values": {
21974 syntax: "[ historical-ligatures | no-historical-ligatures ]"
21975 },
21976 "hsl()": {
21977 syntax: "hsl( <hue> <percentage> <percentage> [ / <alpha-value> ]? ) | hsl( <hue>, <percentage>, <percentage>, <alpha-value>? )"
21978 },
21979 "hsla()": {
21980 syntax: "hsla( <hue> <percentage> <percentage> [ / <alpha-value> ]? ) | hsla( <hue>, <percentage>, <percentage>, <alpha-value>? )"
21981 },
21982 hue: hue,
21983 "hue-rotate()": {
21984 syntax: "hue-rotate( <angle> )"
21985 },
21986 "id-selector": {
21987 syntax: "<hash-token>"
21988 },
21989 image: image,
21990 "image()": {
21991 syntax: "image( <image-tags>? [ <image-src>? , <color>? ]! )"
21992 },
21993 "image-set()": {
21994 syntax: "image-set( <image-set-option># )"
21995 },
21996 "image-set-option": {
21997 syntax: "[ <image> | <string> ] <resolution>"
21998 },
21999 "image-src": {
22000 syntax: "<url> | <string>"
22001 },
22002 "image-tags": {
22003 syntax: "ltr | rtl"
22004 },
22005 "inflexible-breadth": {
22006 syntax: "<length> | <percentage> | min-content | max-content | auto"
22007 },
22008 "inset()": {
22009 syntax: "inset( <length-percentage>{1,4} [ round <'border-radius'> ]? )"
22010 },
22011 "invert()": {
22012 syntax: "invert( <number-percentage> )"
22013 },
22014 "keyframes-name": {
22015 syntax: "<custom-ident> | <string>"
22016 },
22017 "keyframe-block": {
22018 syntax: "<keyframe-selector># {\n <declaration-list>\n}"
22019 },
22020 "keyframe-block-list": {
22021 syntax: "<keyframe-block>+"
22022 },
22023 "keyframe-selector": {
22024 syntax: "from | to | <percentage>"
22025 },
22026 "leader()": {
22027 syntax: "leader( <leader-type> )"
22028 },
22029 "leader-type": {
22030 syntax: "dotted | solid | space | <string>"
22031 },
22032 "length-percentage": {
22033 syntax: "<length> | <percentage>"
22034 },
22035 "line-names": {
22036 syntax: "'[' <custom-ident>* ']'"
22037 },
22038 "line-name-list": {
22039 syntax: "[ <line-names> | <name-repeat> ]+"
22040 },
22041 "line-style": {
22042 syntax: "none | hidden | dotted | dashed | solid | double | groove | ridge | inset | outset"
22043 },
22044 "line-width": {
22045 syntax: "<length> | thin | medium | thick"
22046 },
22047 "linear-color-hint": {
22048 syntax: "<length-percentage>"
22049 },
22050 "linear-color-stop": {
22051 syntax: "<color> <color-stop-length>?"
22052 },
22053 "linear-gradient()": {
22054 syntax: "linear-gradient( [ <angle> | to <side-or-corner> ]? , <color-stop-list> )"
22055 },
22056 "mask-layer": {
22057 syntax: "<mask-reference> || <position> [ / <bg-size> ]? || <repeat-style> || <geometry-box> || [ <geometry-box> | no-clip ] || <compositing-operator> || <masking-mode>"
22058 },
22059 "mask-position": {
22060 syntax: "[ <length-percentage> | left | center | right ] [ <length-percentage> | top | center | bottom ]?"
22061 },
22062 "mask-reference": {
22063 syntax: "none | <image> | <mask-source>"
22064 },
22065 "mask-source": {
22066 syntax: "<url>"
22067 },
22068 "masking-mode": {
22069 syntax: "alpha | luminance | match-source"
22070 },
22071 "matrix()": {
22072 syntax: "matrix( <number>#{6} )"
22073 },
22074 "matrix3d()": {
22075 syntax: "matrix3d( <number>#{16} )"
22076 },
22077 "max()": {
22078 syntax: "max( <calc-sum># )"
22079 },
22080 "media-and": {
22081 syntax: "<media-in-parens> [ and <media-in-parens> ]+"
22082 },
22083 "media-condition": {
22084 syntax: "<media-not> | <media-and> | <media-or> | <media-in-parens>"
22085 },
22086 "media-condition-without-or": {
22087 syntax: "<media-not> | <media-and> | <media-in-parens>"
22088 },
22089 "media-feature": {
22090 syntax: "( [ <mf-plain> | <mf-boolean> | <mf-range> ] )"
22091 },
22092 "media-in-parens": {
22093 syntax: "( <media-condition> ) | <media-feature> | <general-enclosed>"
22094 },
22095 "media-not": {
22096 syntax: "not <media-in-parens>"
22097 },
22098 "media-or": {
22099 syntax: "<media-in-parens> [ or <media-in-parens> ]+"
22100 },
22101 "media-query": {
22102 syntax: "<media-condition> | [ not | only ]? <media-type> [ and <media-condition-without-or> ]?"
22103 },
22104 "media-query-list": {
22105 syntax: "<media-query>#"
22106 },
22107 "media-type": {
22108 syntax: "<ident>"
22109 },
22110 "mf-boolean": {
22111 syntax: "<mf-name>"
22112 },
22113 "mf-name": {
22114 syntax: "<ident>"
22115 },
22116 "mf-plain": {
22117 syntax: "<mf-name> : <mf-value>"
22118 },
22119 "mf-range": {
22120 syntax: "<mf-name> [ '<' | '>' ]? '='? <mf-value>\n| <mf-value> [ '<' | '>' ]? '='? <mf-name>\n| <mf-value> '<' '='? <mf-name> '<' '='? <mf-value>\n| <mf-value> '>' '='? <mf-name> '>' '='? <mf-value>"
22121 },
22122 "mf-value": {
22123 syntax: "<number> | <dimension> | <ident> | <ratio>"
22124 },
22125 "min()": {
22126 syntax: "min( <calc-sum># )"
22127 },
22128 "minmax()": {
22129 syntax: "minmax( [ <length> | <percentage> | min-content | max-content | auto ] , [ <length> | <percentage> | <flex> | min-content | max-content | auto ] )"
22130 },
22131 "named-color": {
22132 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"
22133 },
22134 "namespace-prefix": {
22135 syntax: "<ident>"
22136 },
22137 "ns-prefix": {
22138 syntax: "[ <ident-token> | '*' ]? '|'"
22139 },
22140 "number-percentage": {
22141 syntax: "<number> | <percentage>"
22142 },
22143 "numeric-figure-values": {
22144 syntax: "[ lining-nums | oldstyle-nums ]"
22145 },
22146 "numeric-fraction-values": {
22147 syntax: "[ diagonal-fractions | stacked-fractions ]"
22148 },
22149 "numeric-spacing-values": {
22150 syntax: "[ proportional-nums | tabular-nums ]"
22151 },
22152 nth: nth$1,
22153 "opacity()": {
22154 syntax: "opacity( [ <number-percentage> ] )"
22155 },
22156 "overflow-position": {
22157 syntax: "unsafe | safe"
22158 },
22159 "outline-radius": {
22160 syntax: "<length> | <percentage>"
22161 },
22162 "page-body": {
22163 syntax: "<declaration>? [ ; <page-body> ]? | <page-margin-box> <page-body>"
22164 },
22165 "page-margin-box": {
22166 syntax: "<page-margin-box-type> '{' <declaration-list> '}'"
22167 },
22168 "page-margin-box-type": {
22169 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"
22170 },
22171 "page-selector-list": {
22172 syntax: "[ <page-selector># ]?"
22173 },
22174 "page-selector": {
22175 syntax: "<pseudo-page>+ | <ident> <pseudo-page>*"
22176 },
22177 "path()": {
22178 syntax: "path( [ <fill-rule>, ]? <string> )"
22179 },
22180 "paint()": {
22181 syntax: "paint( <ident>, <declaration-value>? )"
22182 },
22183 "perspective()": {
22184 syntax: "perspective( <length> )"
22185 },
22186 "polygon()": {
22187 syntax: "polygon( <fill-rule>? , [ <length-percentage> <length-percentage> ]# )"
22188 },
22189 position: position,
22190 "pseudo-class-selector": {
22191 syntax: "':' <ident-token> | ':' <function-token> <any-value> ')'"
22192 },
22193 "pseudo-element-selector": {
22194 syntax: "':' <pseudo-class-selector>"
22195 },
22196 "pseudo-page": {
22197 syntax: ": [ left | right | first | blank ]"
22198 },
22199 quote: quote,
22200 "radial-gradient()": {
22201 syntax: "radial-gradient( [ <ending-shape> || <size> ]? [ at <position> ]? , <color-stop-list> )"
22202 },
22203 "relative-selector": {
22204 syntax: "<combinator>? <complex-selector>"
22205 },
22206 "relative-selector-list": {
22207 syntax: "<relative-selector>#"
22208 },
22209 "relative-size": {
22210 syntax: "larger | smaller"
22211 },
22212 "repeat-style": {
22213 syntax: "repeat-x | repeat-y | [ repeat | space | round | no-repeat ]{1,2}"
22214 },
22215 "repeating-linear-gradient()": {
22216 syntax: "repeating-linear-gradient( [ <angle> | to <side-or-corner> ]? , <color-stop-list> )"
22217 },
22218 "repeating-radial-gradient()": {
22219 syntax: "repeating-radial-gradient( [ <ending-shape> || <size> ]? [ at <position> ]? , <color-stop-list> )"
22220 },
22221 "rgb()": {
22222 syntax: "rgb( <percentage>{3} [ / <alpha-value> ]? ) | rgb( <number>{3} [ / <alpha-value> ]? ) | rgb( <percentage>#{3} , <alpha-value>? ) | rgb( <number>#{3} , <alpha-value>? )"
22223 },
22224 "rgba()": {
22225 syntax: "rgba( <percentage>{3} [ / <alpha-value> ]? ) | rgba( <number>{3} [ / <alpha-value> ]? ) | rgba( <percentage>#{3} , <alpha-value>? ) | rgba( <number>#{3} , <alpha-value>? )"
22226 },
22227 "rotate()": {
22228 syntax: "rotate( [ <angle> | <zero> ] )"
22229 },
22230 "rotate3d()": {
22231 syntax: "rotate3d( <number> , <number> , <number> , [ <angle> | <zero> ] )"
22232 },
22233 "rotateX()": {
22234 syntax: "rotateX( [ <angle> | <zero> ] )"
22235 },
22236 "rotateY()": {
22237 syntax: "rotateY( [ <angle> | <zero> ] )"
22238 },
22239 "rotateZ()": {
22240 syntax: "rotateZ( [ <angle> | <zero> ] )"
22241 },
22242 "saturate()": {
22243 syntax: "saturate( <number-percentage> )"
22244 },
22245 "scale()": {
22246 syntax: "scale( <number> , <number>? )"
22247 },
22248 "scale3d()": {
22249 syntax: "scale3d( <number> , <number> , <number> )"
22250 },
22251 "scaleX()": {
22252 syntax: "scaleX( <number> )"
22253 },
22254 "scaleY()": {
22255 syntax: "scaleY( <number> )"
22256 },
22257 "scaleZ()": {
22258 syntax: "scaleZ( <number> )"
22259 },
22260 "self-position": {
22261 syntax: "center | start | end | self-start | self-end | flex-start | flex-end"
22262 },
22263 "shape-radius": {
22264 syntax: "<length-percentage> | closest-side | farthest-side"
22265 },
22266 "skew()": {
22267 syntax: "skew( [ <angle> | <zero> ] , [ <angle> | <zero> ]? )"
22268 },
22269 "skewX()": {
22270 syntax: "skewX( [ <angle> | <zero> ] )"
22271 },
22272 "skewY()": {
22273 syntax: "skewY( [ <angle> | <zero> ] )"
22274 },
22275 "sepia()": {
22276 syntax: "sepia( <number-percentage> )"
22277 },
22278 shadow: shadow,
22279 "shadow-t": {
22280 syntax: "[ <length>{2,3} && <color>? ]"
22281 },
22282 shape: shape,
22283 "shape-box": {
22284 syntax: "<box> | margin-box"
22285 },
22286 "side-or-corner": {
22287 syntax: "[ left | right ] || [ top | bottom ]"
22288 },
22289 "single-animation": {
22290 syntax: "<time> || <timing-function> || <time> || <single-animation-iteration-count> || <single-animation-direction> || <single-animation-fill-mode> || <single-animation-play-state> || [ none | <keyframes-name> ]"
22291 },
22292 "single-animation-direction": {
22293 syntax: "normal | reverse | alternate | alternate-reverse"
22294 },
22295 "single-animation-fill-mode": {
22296 syntax: "none | forwards | backwards | both"
22297 },
22298 "single-animation-iteration-count": {
22299 syntax: "infinite | <number>"
22300 },
22301 "single-animation-play-state": {
22302 syntax: "running | paused"
22303 },
22304 "single-transition": {
22305 syntax: "[ none | <single-transition-property> ] || <time> || <timing-function> || <time>"
22306 },
22307 "single-transition-property": {
22308 syntax: "all | <custom-ident>"
22309 },
22310 size: size,
22311 "step-position": {
22312 syntax: "jump-start | jump-end | jump-none | jump-both | start | end"
22313 },
22314 "step-timing-function": {
22315 syntax: "step-start | step-end | steps(<integer>[, <step-position>]?)"
22316 },
22317 "subclass-selector": {
22318 syntax: "<id-selector> | <class-selector> | <attribute-selector> | <pseudo-class-selector>"
22319 },
22320 "supports-condition": {
22321 syntax: "not <supports-in-parens> | <supports-in-parens> [ and <supports-in-parens> ]* | <supports-in-parens> [ or <supports-in-parens> ]*"
22322 },
22323 "supports-in-parens": {
22324 syntax: "( <supports-condition> ) | <supports-feature> | <general-enclosed>"
22325 },
22326 "supports-feature": {
22327 syntax: "<supports-decl> | <supports-selector-fn>"
22328 },
22329 "supports-decl": {
22330 syntax: "( <declaration> )"
22331 },
22332 "supports-selector-fn": {
22333 syntax: "selector( <complex-selector> )"
22334 },
22335 symbol: symbol,
22336 target: target,
22337 "target-counter()": {
22338 syntax: "target-counter( [ <string> | <url> ] , <custom-ident> , <counter-style>? )"
22339 },
22340 "target-counters()": {
22341 syntax: "target-counters( [ <string> | <url> ] , <custom-ident> , <string> , <counter-style>? )"
22342 },
22343 "target-text()": {
22344 syntax: "target-text( [ <string> | <url> ] , [ content | before | after | first-letter ]? )"
22345 },
22346 "time-percentage": {
22347 syntax: "<time> | <percentage>"
22348 },
22349 "timing-function": {
22350 syntax: "linear | <cubic-bezier-timing-function> | <step-timing-function>"
22351 },
22352 "track-breadth": {
22353 syntax: "<length-percentage> | <flex> | min-content | max-content | auto"
22354 },
22355 "track-list": {
22356 syntax: "[ <line-names>? [ <track-size> | <track-repeat> ] ]+ <line-names>?"
22357 },
22358 "track-repeat": {
22359 syntax: "repeat( [ <positive-integer> ] , [ <line-names>? <track-size> ]+ <line-names>? )"
22360 },
22361 "track-size": {
22362 syntax: "<track-breadth> | minmax( <inflexible-breadth> , <track-breadth> ) | fit-content( [ <length> | <percentage> ] )"
22363 },
22364 "transform-function": {
22365 syntax: "<matrix()> | <translate()> | <translateX()> | <translateY()> | <scale()> | <scaleX()> | <scaleY()> | <rotate()> | <skew()> | <skewX()> | <skewY()> | <matrix3d()> | <translate3d()> | <translateZ()> | <scale3d()> | <scaleZ()> | <rotate3d()> | <rotateX()> | <rotateY()> | <rotateZ()> | <perspective()>"
22366 },
22367 "transform-list": {
22368 syntax: "<transform-function>+"
22369 },
22370 "translate()": {
22371 syntax: "translate( <length-percentage> , <length-percentage>? )"
22372 },
22373 "translate3d()": {
22374 syntax: "translate3d( <length-percentage> , <length-percentage> , <length> )"
22375 },
22376 "translateX()": {
22377 syntax: "translateX( <length-percentage> )"
22378 },
22379 "translateY()": {
22380 syntax: "translateY( <length-percentage> )"
22381 },
22382 "translateZ()": {
22383 syntax: "translateZ( <length> )"
22384 },
22385 "type-or-unit": {
22386 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 | %"
22387 },
22388 "type-selector": {
22389 syntax: "<wq-name> | <ns-prefix>? '*'"
22390 },
22391 "var()": {
22392 syntax: "var( <custom-property-name> , <declaration-value>? )"
22393 },
22394 "viewport-length": {
22395 syntax: "auto | <length-percentage>"
22396 },
22397 "wq-name": {
22398 syntax: "<ns-prefix>? <ident-token>"
22399 }
22400 };
22401
22402 var atrules = {
22403 charset: {
22404 prelude: "<string>"
22405 },
22406 "font-face": {
22407 descriptors: {
22408 "unicode-range": {
22409 comment: "replaces <unicode-range>, an old production name",
22410 syntax: "<urange>#"
22411 }
22412 }
22413 }
22414 };
22415 var properties = {
22416 "-moz-background-clip": {
22417 comment: "deprecated syntax in old Firefox, https://developer.mozilla.org/en/docs/Web/CSS/background-clip",
22418 syntax: "padding | border"
22419 },
22420 "-moz-border-radius-bottomleft": {
22421 comment: "https://developer.mozilla.org/en-US/docs/Web/CSS/border-bottom-left-radius",
22422 syntax: "<'border-bottom-left-radius'>"
22423 },
22424 "-moz-border-radius-bottomright": {
22425 comment: "https://developer.mozilla.org/en-US/docs/Web/CSS/border-bottom-right-radius",
22426 syntax: "<'border-bottom-right-radius'>"
22427 },
22428 "-moz-border-radius-topleft": {
22429 comment: "https://developer.mozilla.org/en-US/docs/Web/CSS/border-top-left-radius",
22430 syntax: "<'border-top-left-radius'>"
22431 },
22432 "-moz-border-radius-topright": {
22433 comment: "https://developer.mozilla.org/en-US/docs/Web/CSS/border-bottom-right-radius",
22434 syntax: "<'border-bottom-right-radius'>"
22435 },
22436 "-moz-control-character-visibility": {
22437 comment: "firefox specific keywords, https://bugzilla.mozilla.org/show_bug.cgi?id=947588",
22438 syntax: "visible | hidden"
22439 },
22440 "-moz-osx-font-smoothing": {
22441 comment: "misssed old syntax https://developer.mozilla.org/en-US/docs/Web/CSS/font-smooth",
22442 syntax: "auto | grayscale"
22443 },
22444 "-moz-user-select": {
22445 comment: "https://developer.mozilla.org/en-US/docs/Web/CSS/user-select",
22446 syntax: "none | text | all | -moz-none"
22447 },
22448 "-ms-flex-align": {
22449 comment: "misssed old syntax implemented in IE, https://www.w3.org/TR/2012/WD-css3-flexbox-20120322/#flex-align",
22450 syntax: "start | end | center | baseline | stretch"
22451 },
22452 "-ms-flex-item-align": {
22453 comment: "misssed old syntax implemented in IE, https://www.w3.org/TR/2012/WD-css3-flexbox-20120322/#flex-align",
22454 syntax: "auto | start | end | center | baseline | stretch"
22455 },
22456 "-ms-flex-line-pack": {
22457 comment: "misssed old syntax implemented in IE, https://www.w3.org/TR/2012/WD-css3-flexbox-20120322/#flex-line-pack",
22458 syntax: "start | end | center | justify | distribute | stretch"
22459 },
22460 "-ms-flex-negative": {
22461 comment: "misssed old syntax implemented in IE; TODO: find references for comfirmation",
22462 syntax: "<'flex-shrink'>"
22463 },
22464 "-ms-flex-pack": {
22465 comment: "misssed old syntax implemented in IE, https://www.w3.org/TR/2012/WD-css3-flexbox-20120322/#flex-pack",
22466 syntax: "start | end | center | justify | distribute"
22467 },
22468 "-ms-flex-order": {
22469 comment: "misssed old syntax implemented in IE; https://msdn.microsoft.com/en-us/library/jj127303(v=vs.85).aspx",
22470 syntax: "<integer>"
22471 },
22472 "-ms-flex-positive": {
22473 comment: "misssed old syntax implemented in IE; TODO: find references for comfirmation",
22474 syntax: "<'flex-grow'>"
22475 },
22476 "-ms-flex-preferred-size": {
22477 comment: "misssed old syntax implemented in IE; TODO: find references for comfirmation",
22478 syntax: "<'flex-basis'>"
22479 },
22480 "-ms-interpolation-mode": {
22481 comment: "https://msdn.microsoft.com/en-us/library/ff521095(v=vs.85).aspx",
22482 syntax: "nearest-neighbor | bicubic"
22483 },
22484 "-ms-grid-column-align": {
22485 comment: "add this property first since it uses as fallback for flexbox, https://msdn.microsoft.com/en-us/library/windows/apps/hh466338.aspx",
22486 syntax: "start | end | center | stretch"
22487 },
22488 "-ms-grid-row-align": {
22489 comment: "add this property first since it uses as fallback for flexbox, https://msdn.microsoft.com/en-us/library/windows/apps/hh466348.aspx",
22490 syntax: "start | end | center | stretch"
22491 },
22492 "-ms-hyphenate-limit-last": {
22493 comment: "misssed old syntax implemented in IE; https://www.w3.org/TR/css-text-4/#hyphenate-line-limits",
22494 syntax: "none | always | column | page | spread"
22495 },
22496 "-webkit-appearance": {
22497 comment: "webkit specific keywords",
22498 references: [
22499 "http://css-infos.net/property/-webkit-appearance"
22500 ],
22501 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"
22502 },
22503 "-webkit-background-clip": {
22504 comment: "https://developer.mozilla.org/en/docs/Web/CSS/background-clip",
22505 syntax: "[ <box> | border | padding | content | text ]#"
22506 },
22507 "-webkit-column-break-after": {
22508 comment: "added, http://help.dottoro.com/lcrthhhv.php",
22509 syntax: "always | auto | avoid"
22510 },
22511 "-webkit-column-break-before": {
22512 comment: "added, http://help.dottoro.com/lcxquvkf.php",
22513 syntax: "always | auto | avoid"
22514 },
22515 "-webkit-column-break-inside": {
22516 comment: "added, http://help.dottoro.com/lclhnthl.php",
22517 syntax: "always | auto | avoid"
22518 },
22519 "-webkit-font-smoothing": {
22520 comment: "https://developer.mozilla.org/en-US/docs/Web/CSS/font-smooth",
22521 syntax: "auto | none | antialiased | subpixel-antialiased"
22522 },
22523 "-webkit-mask-box-image": {
22524 comment: "missed; https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-mask-box-image",
22525 syntax: "[ <url> | <gradient> | none ] [ <length-percentage>{4} <-webkit-mask-box-repeat>{2} ]?"
22526 },
22527 "-webkit-print-color-adjust": {
22528 comment: "missed",
22529 references: [
22530 "https://developer.mozilla.org/en/docs/Web/CSS/-webkit-print-color-adjust"
22531 ],
22532 syntax: "economy | exact"
22533 },
22534 "-webkit-text-security": {
22535 comment: "missed; http://help.dottoro.com/lcbkewgt.php",
22536 syntax: "none | circle | disc | square"
22537 },
22538 "-webkit-user-drag": {
22539 comment: "missed; http://help.dottoro.com/lcbixvwm.php",
22540 syntax: "none | element | auto"
22541 },
22542 "-webkit-user-select": {
22543 comment: "auto is supported by old webkit, https://developer.mozilla.org/en-US/docs/Web/CSS/user-select",
22544 syntax: "auto | none | text | all"
22545 },
22546 "alignment-baseline": {
22547 comment: "added SVG property",
22548 references: [
22549 "https://www.w3.org/TR/SVG/text.html#AlignmentBaselineProperty"
22550 ],
22551 syntax: "auto | baseline | before-edge | text-before-edge | middle | central | after-edge | text-after-edge | ideographic | alphabetic | hanging | mathematical"
22552 },
22553 "baseline-shift": {
22554 comment: "added SVG property",
22555 references: [
22556 "https://www.w3.org/TR/SVG/text.html#BaselineShiftProperty"
22557 ],
22558 syntax: "baseline | sub | super | <svg-length>"
22559 },
22560 behavior: {
22561 comment: "added old IE property https://msdn.microsoft.com/en-us/library/ms530723(v=vs.85).aspx",
22562 syntax: "<url>+"
22563 },
22564 "clip-rule": {
22565 comment: "added SVG property",
22566 references: [
22567 "https://www.w3.org/TR/SVG/masking.html#ClipRuleProperty"
22568 ],
22569 syntax: "nonzero | evenodd"
22570 },
22571 cue: {
22572 comment: "https://www.w3.org/TR/css3-speech/#property-index",
22573 syntax: "<'cue-before'> <'cue-after'>?"
22574 },
22575 "cue-after": {
22576 comment: "https://www.w3.org/TR/css3-speech/#property-index",
22577 syntax: "<url> <decibel>? | none"
22578 },
22579 "cue-before": {
22580 comment: "https://www.w3.org/TR/css3-speech/#property-index",
22581 syntax: "<url> <decibel>? | none"
22582 },
22583 cursor: {
22584 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",
22585 references: [
22586 "https://www.sitepoint.com/css3-cursor-styles/"
22587 ],
22588 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 ] ]"
22589 },
22590 display: {
22591 comment: "extended with -ms-flexbox",
22592 syntax: "| <-non-standard-display>"
22593 },
22594 position: {
22595 comment: "extended with -webkit-sticky",
22596 syntax: "| -webkit-sticky"
22597 },
22598 "dominant-baseline": {
22599 comment: "added SVG property",
22600 references: [
22601 "https://www.w3.org/TR/SVG/text.html#DominantBaselineProperty"
22602 ],
22603 syntax: "auto | use-script | no-change | reset-size | ideographic | alphabetic | hanging | mathematical | central | middle | text-after-edge | text-before-edge"
22604 },
22605 "image-rendering": {
22606 comment: "extended with <-non-standard-image-rendering>, added SVG keywords optimizeSpeed and optimizeQuality",
22607 references: [
22608 "https://developer.mozilla.org/en/docs/Web/CSS/image-rendering",
22609 "https://www.w3.org/TR/SVG/painting.html#ImageRenderingProperty"
22610 ],
22611 syntax: "| optimizeSpeed | optimizeQuality | <-non-standard-image-rendering>"
22612 },
22613 fill: {
22614 comment: "added SVG property",
22615 references: [
22616 "https://www.w3.org/TR/SVG/painting.html#FillProperty"
22617 ],
22618 syntax: "<paint>"
22619 },
22620 "fill-opacity": {
22621 comment: "added SVG property",
22622 references: [
22623 "https://www.w3.org/TR/SVG/painting.html#FillProperty"
22624 ],
22625 syntax: "<number-zero-one>"
22626 },
22627 "fill-rule": {
22628 comment: "added SVG property",
22629 references: [
22630 "https://www.w3.org/TR/SVG/painting.html#FillProperty"
22631 ],
22632 syntax: "nonzero | evenodd"
22633 },
22634 filter: {
22635 comment: "extend with IE legacy syntaxes",
22636 syntax: "| <-ms-filter-function-list>"
22637 },
22638 "glyph-orientation-horizontal": {
22639 comment: "added SVG property",
22640 references: [
22641 "https://www.w3.org/TR/SVG/text.html#GlyphOrientationHorizontalProperty"
22642 ],
22643 syntax: "<angle>"
22644 },
22645 "glyph-orientation-vertical": {
22646 comment: "added SVG property",
22647 references: [
22648 "https://www.w3.org/TR/SVG/text.html#GlyphOrientationVerticalProperty"
22649 ],
22650 syntax: "<angle>"
22651 },
22652 kerning: {
22653 comment: "added SVG property",
22654 references: [
22655 "https://www.w3.org/TR/SVG/text.html#KerningProperty"
22656 ],
22657 syntax: "auto | <svg-length>"
22658 },
22659 "letter-spacing": {
22660 comment: "fix syntax <length> -> <length-percentage>",
22661 references: [
22662 "https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/letter-spacing"
22663 ],
22664 syntax: "normal | <length-percentage>"
22665 },
22666 marker: {
22667 comment: "added SVG property",
22668 references: [
22669 "https://www.w3.org/TR/SVG/painting.html#MarkerProperties"
22670 ],
22671 syntax: "none | <url>"
22672 },
22673 "marker-end": {
22674 comment: "added SVG property",
22675 references: [
22676 "https://www.w3.org/TR/SVG/painting.html#MarkerProperties"
22677 ],
22678 syntax: "none | <url>"
22679 },
22680 "marker-mid": {
22681 comment: "added SVG property",
22682 references: [
22683 "https://www.w3.org/TR/SVG/painting.html#MarkerProperties"
22684 ],
22685 syntax: "none | <url>"
22686 },
22687 "marker-start": {
22688 comment: "added SVG property",
22689 references: [
22690 "https://www.w3.org/TR/SVG/painting.html#MarkerProperties"
22691 ],
22692 syntax: "none | <url>"
22693 },
22694 "max-width": {
22695 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",
22696 syntax: "none | <length-percentage> | min-content | max-content | fit-content(<length-percentage>) | <-non-standard-width>"
22697 },
22698 width: {
22699 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)",
22700 syntax: "| fit-content | -moz-fit-content | -webkit-fit-content"
22701 },
22702 "min-width": {
22703 comment: "extend by non-standard width keywords https://developer.mozilla.org/en-US/docs/Web/CSS/width",
22704 syntax: "auto | <length-percentage> | min-content | max-content | fit-content(<length-percentage>) | <-non-standard-width>"
22705 },
22706 overflow: {
22707 comment: "extend by vendor keywords https://developer.mozilla.org/en-US/docs/Web/CSS/overflow",
22708 syntax: "| <-non-standard-overflow>"
22709 },
22710 pause: {
22711 comment: "https://www.w3.org/TR/css3-speech/#property-index",
22712 syntax: "<'pause-before'> <'pause-after'>?"
22713 },
22714 "pause-after": {
22715 comment: "https://www.w3.org/TR/css3-speech/#property-index",
22716 syntax: "<time> | none | x-weak | weak | medium | strong | x-strong"
22717 },
22718 "pause-before": {
22719 comment: "https://www.w3.org/TR/css3-speech/#property-index",
22720 syntax: "<time> | none | x-weak | weak | medium | strong | x-strong"
22721 },
22722 rest: {
22723 comment: "https://www.w3.org/TR/css3-speech/#property-index",
22724 syntax: "<'rest-before'> <'rest-after'>?"
22725 },
22726 "rest-after": {
22727 comment: "https://www.w3.org/TR/css3-speech/#property-index",
22728 syntax: "<time> | none | x-weak | weak | medium | strong | x-strong"
22729 },
22730 "rest-before": {
22731 comment: "https://www.w3.org/TR/css3-speech/#property-index",
22732 syntax: "<time> | none | x-weak | weak | medium | strong | x-strong"
22733 },
22734 "shape-rendering": {
22735 comment: "added SVG property",
22736 references: [
22737 "https://www.w3.org/TR/SVG/painting.html#ShapeRenderingPropert"
22738 ],
22739 syntax: "auto | optimizeSpeed | crispEdges | geometricPrecision"
22740 },
22741 src: {
22742 comment: "added @font-face's src property https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/src",
22743 syntax: "[ <url> [ format( <string># ) ]? | local( <family-name> ) ]#"
22744 },
22745 speak: {
22746 comment: "https://www.w3.org/TR/css3-speech/#property-index",
22747 syntax: "auto | none | normal"
22748 },
22749 "speak-as": {
22750 comment: "https://www.w3.org/TR/css3-speech/#property-index",
22751 syntax: "normal | spell-out || digits || [ literal-punctuation | no-punctuation ]"
22752 },
22753 stroke: {
22754 comment: "added SVG property",
22755 references: [
22756 "https://www.w3.org/TR/SVG/painting.html#StrokeProperties"
22757 ],
22758 syntax: "<paint>"
22759 },
22760 "stroke-dasharray": {
22761 comment: "added SVG property; a list of comma and/or white space separated <length>s and <percentage>s",
22762 references: [
22763 "https://www.w3.org/TR/SVG/painting.html#StrokeProperties"
22764 ],
22765 syntax: "none | [ <svg-length>+ ]#"
22766 },
22767 "stroke-dashoffset": {
22768 comment: "added SVG property",
22769 references: [
22770 "https://www.w3.org/TR/SVG/painting.html#StrokeProperties"
22771 ],
22772 syntax: "<svg-length>"
22773 },
22774 "stroke-linecap": {
22775 comment: "added SVG property",
22776 references: [
22777 "https://www.w3.org/TR/SVG/painting.html#StrokeProperties"
22778 ],
22779 syntax: "butt | round | square"
22780 },
22781 "stroke-linejoin": {
22782 comment: "added SVG property",
22783 references: [
22784 "https://www.w3.org/TR/SVG/painting.html#StrokeProperties"
22785 ],
22786 syntax: "miter | round | bevel"
22787 },
22788 "stroke-miterlimit": {
22789 comment: "added SVG property (<miterlimit> = <number-one-or-greater>) ",
22790 references: [
22791 "https://www.w3.org/TR/SVG/painting.html#StrokeProperties"
22792 ],
22793 syntax: "<number-one-or-greater>"
22794 },
22795 "stroke-opacity": {
22796 comment: "added SVG property",
22797 references: [
22798 "https://www.w3.org/TR/SVG/painting.html#StrokeProperties"
22799 ],
22800 syntax: "<number-zero-one>"
22801 },
22802 "stroke-width": {
22803 comment: "added SVG property",
22804 references: [
22805 "https://www.w3.org/TR/SVG/painting.html#StrokeProperties"
22806 ],
22807 syntax: "<svg-length>"
22808 },
22809 "text-anchor": {
22810 comment: "added SVG property",
22811 references: [
22812 "https://www.w3.org/TR/SVG/text.html#TextAlignmentProperties"
22813 ],
22814 syntax: "start | middle | end"
22815 },
22816 "unicode-bidi": {
22817 comment: "added prefixed keywords https://developer.mozilla.org/en-US/docs/Web/CSS/unicode-bidi",
22818 syntax: "| -moz-isolate | -moz-isolate-override | -moz-plaintext | -webkit-isolate | -webkit-isolate-override | -webkit-plaintext"
22819 },
22820 "unicode-range": {
22821 comment: "added missed property https://developer.mozilla.org/en-US/docs/Web/CSS/%40font-face/unicode-range",
22822 syntax: "<urange>#"
22823 },
22824 "voice-balance": {
22825 comment: "https://www.w3.org/TR/css3-speech/#property-index",
22826 syntax: "<number> | left | center | right | leftwards | rightwards"
22827 },
22828 "voice-duration": {
22829 comment: "https://www.w3.org/TR/css3-speech/#property-index",
22830 syntax: "auto | <time>"
22831 },
22832 "voice-family": {
22833 comment: "<name> -> <family-name>, https://www.w3.org/TR/css3-speech/#property-index",
22834 syntax: "[ [ <family-name> | <generic-voice> ] , ]* [ <family-name> | <generic-voice> ] | preserve"
22835 },
22836 "voice-pitch": {
22837 comment: "https://www.w3.org/TR/css3-speech/#property-index",
22838 syntax: "<frequency> && absolute | [ [ x-low | low | medium | high | x-high ] || [ <frequency> | <semitones> | <percentage> ] ]"
22839 },
22840 "voice-range": {
22841 comment: "https://www.w3.org/TR/css3-speech/#property-index",
22842 syntax: "<frequency> && absolute | [ [ x-low | low | medium | high | x-high ] || [ <frequency> | <semitones> | <percentage> ] ]"
22843 },
22844 "voice-rate": {
22845 comment: "https://www.w3.org/TR/css3-speech/#property-index",
22846 syntax: "[ normal | x-slow | slow | medium | fast | x-fast ] || <percentage>"
22847 },
22848 "voice-stress": {
22849 comment: "https://www.w3.org/TR/css3-speech/#property-index",
22850 syntax: "normal | strong | moderate | none | reduced"
22851 },
22852 "voice-volume": {
22853 comment: "https://www.w3.org/TR/css3-speech/#property-index",
22854 syntax: "silent | [ [ x-soft | soft | medium | loud | x-loud ] || <decibel> ]"
22855 },
22856 "writing-mode": {
22857 comment: "extend with SVG keywords",
22858 syntax: "| <svg-writing-mode>"
22859 }
22860 };
22861 var syntaxes = {
22862 "-legacy-gradient": {
22863 comment: "added collection of legacy gradient syntaxes",
22864 syntax: "<-webkit-gradient()> | <-legacy-linear-gradient> | <-legacy-repeating-linear-gradient> | <-legacy-radial-gradient> | <-legacy-repeating-radial-gradient>"
22865 },
22866 "-legacy-linear-gradient": {
22867 comment: "like standard syntax but w/o `to` keyword https://developer.mozilla.org/en-US/docs/Web/CSS/linear-gradient",
22868 syntax: "-moz-linear-gradient( <-legacy-linear-gradient-arguments> ) | -webkit-linear-gradient( <-legacy-linear-gradient-arguments> ) | -o-linear-gradient( <-legacy-linear-gradient-arguments> )"
22869 },
22870 "-legacy-repeating-linear-gradient": {
22871 comment: "like standard syntax but w/o `to` keyword https://developer.mozilla.org/en-US/docs/Web/CSS/linear-gradient",
22872 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> )"
22873 },
22874 "-legacy-linear-gradient-arguments": {
22875 comment: "like standard syntax but w/o `to` keyword https://developer.mozilla.org/en-US/docs/Web/CSS/linear-gradient",
22876 syntax: "[ <angle> | <side-or-corner> ]? , <color-stop-list>"
22877 },
22878 "-legacy-radial-gradient": {
22879 comment: "deprecated syntax that implemented by some browsers https://www.w3.org/TR/2011/WD-css3-images-20110908/#radial-gradients",
22880 syntax: "-moz-radial-gradient( <-legacy-radial-gradient-arguments> ) | -webkit-radial-gradient( <-legacy-radial-gradient-arguments> ) | -o-radial-gradient( <-legacy-radial-gradient-arguments> )"
22881 },
22882 "-legacy-repeating-radial-gradient": {
22883 comment: "deprecated syntax that implemented by some browsers https://www.w3.org/TR/2011/WD-css3-images-20110908/#radial-gradients",
22884 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> )"
22885 },
22886 "-legacy-radial-gradient-arguments": {
22887 comment: "deprecated syntax that implemented by some browsers https://www.w3.org/TR/2011/WD-css3-images-20110908/#radial-gradients",
22888 syntax: "[ <position> , ]? [ [ [ <-legacy-radial-gradient-shape> || <-legacy-radial-gradient-size> ] | [ <length> | <percentage> ]{2} ] , ]? <color-stop-list>"
22889 },
22890 "-legacy-radial-gradient-size": {
22891 comment: "before a standard it contains 2 extra keywords (`contain` and `cover`) https://www.w3.org/TR/2011/WD-css3-images-20110908/#ltsize",
22892 syntax: "closest-side | closest-corner | farthest-side | farthest-corner | contain | cover"
22893 },
22894 "-legacy-radial-gradient-shape": {
22895 comment: "define to double sure it doesn't extends in future https://www.w3.org/TR/2011/WD-css3-images-20110908/#ltshape",
22896 syntax: "circle | ellipse"
22897 },
22898 "-non-standard-font": {
22899 comment: "non standard fonts",
22900 references: [
22901 "https://webkit.org/blog/3709/using-the-system-font-in-web-content/"
22902 ],
22903 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"
22904 },
22905 "-non-standard-color": {
22906 comment: "non standard colors",
22907 references: [
22908 "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",
22909 "https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#Mozilla_Color_Preference_Extensions"
22910 ],
22911 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"
22912 },
22913 "-non-standard-image-rendering": {
22914 comment: "non-standard keywords http://phrogz.net/tmp/canvas_image_zoom.html",
22915 syntax: "optimize-contrast | -moz-crisp-edges | -o-crisp-edges | -webkit-optimize-contrast"
22916 },
22917 "-non-standard-overflow": {
22918 comment: "non-standard keywords https://developer.mozilla.org/en-US/docs/Web/CSS/overflow",
22919 syntax: "-moz-scrollbars-none | -moz-scrollbars-horizontal | -moz-scrollbars-vertical | -moz-hidden-unscrollable"
22920 },
22921 "-non-standard-width": {
22922 comment: "non-standard keywords https://developer.mozilla.org/en-US/docs/Web/CSS/width",
22923 syntax: "fill-available | min-intrinsic | intrinsic | -moz-available | -moz-fit-content | -moz-min-content | -moz-max-content | -webkit-min-content | -webkit-max-content"
22924 },
22925 "-webkit-gradient()": {
22926 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 )",
22927 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>]* )"
22928 },
22929 "-webkit-gradient-color-stop": {
22930 comment: "first Apple proposal gradient syntax https://webkit.org/blog/175/introducing-css-gradients/",
22931 syntax: "from( <color> ) | color-stop( [ <number-zero-one> | <percentage> ] , <color> ) | to( <color> )"
22932 },
22933 "-webkit-gradient-point": {
22934 comment: "first Apple proposal gradient syntax https://webkit.org/blog/175/introducing-css-gradients/",
22935 syntax: "[ left | center | right | <length-percentage> ] [ top | center | bottom | <length-percentage> ]"
22936 },
22937 "-webkit-gradient-radius": {
22938 comment: "first Apple proposal gradient syntax https://webkit.org/blog/175/introducing-css-gradients/",
22939 syntax: "<length> | <percentage>"
22940 },
22941 "-webkit-gradient-type": {
22942 comment: "first Apple proposal gradient syntax https://webkit.org/blog/175/introducing-css-gradients/",
22943 syntax: "linear | radial"
22944 },
22945 "-webkit-mask-box-repeat": {
22946 comment: "missed; https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-mask-box-image",
22947 syntax: "repeat | stretch | round"
22948 },
22949 "-webkit-mask-clip-style": {
22950 comment: "missed; there is no enough information about `-webkit-mask-clip` property, but looks like all those keywords are working",
22951 syntax: "border | border-box | padding | padding-box | content | content-box | text"
22952 },
22953 "-ms-filter-function-list": {
22954 comment: "https://developer.mozilla.org/en-US/docs/Web/CSS/-ms-filter",
22955 syntax: "<-ms-filter-function>+"
22956 },
22957 "-ms-filter-function": {
22958 comment: "https://developer.mozilla.org/en-US/docs/Web/CSS/-ms-filter",
22959 syntax: "<-ms-filter-function-progid> | <-ms-filter-function-legacy>"
22960 },
22961 "-ms-filter-function-progid": {
22962 comment: "https://developer.mozilla.org/en-US/docs/Web/CSS/-ms-filter",
22963 syntax: "'progid:' [ <ident-token> '.' ]* [ <ident-token> | <function-token> <any-value>? ) ]"
22964 },
22965 "-ms-filter-function-legacy": {
22966 comment: "https://developer.mozilla.org/en-US/docs/Web/CSS/-ms-filter",
22967 syntax: "<ident-token> | <function-token> <any-value>? )"
22968 },
22969 "-ms-filter": {
22970 syntax: "<string>"
22971 },
22972 age: {
22973 comment: "https://www.w3.org/TR/css3-speech/#voice-family",
22974 syntax: "child | young | old"
22975 },
22976 "attr-name": {
22977 syntax: "<wq-name>"
22978 },
22979 "attr-fallback": {
22980 syntax: "<any-value>"
22981 },
22982 "border-radius": {
22983 comment: "missed, https://drafts.csswg.org/css-backgrounds-3/#the-border-radius",
22984 syntax: "<length-percentage>{1,2}"
22985 },
22986 bottom: {
22987 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",
22988 syntax: "<length> | auto"
22989 },
22990 "content-list": {
22991 comment: "missed -> https://drafts.csswg.org/css-content/#typedef-content-list (document-url, <target> and leader() is omitted util stabilization)",
22992 syntax: "[ <string> | contents | <image> | <quote> | <target> | <leader()> | <attr()> | counter( <ident>, <'list-style-type'>? ) ]+"
22993 },
22994 "element()": {
22995 comment: "https://drafts.csswg.org/css-gcpm/#element-syntax & https://drafts.csswg.org/css-images-4/#element-notation",
22996 syntax: "element( <custom-ident> , [ first | start | last | first-except ]? ) | element( <id-selector> )"
22997 },
22998 "generic-voice": {
22999 comment: "https://www.w3.org/TR/css3-speech/#voice-family",
23000 syntax: "[ <age>? <gender> <integer>? ]"
23001 },
23002 gender: {
23003 comment: "https://www.w3.org/TR/css3-speech/#voice-family",
23004 syntax: "male | female | neutral"
23005 },
23006 "generic-family": {
23007 comment: "added -apple-system",
23008 references: [
23009 "https://webkit.org/blog/3709/using-the-system-font-in-web-content/"
23010 ],
23011 syntax: "| -apple-system"
23012 },
23013 gradient: {
23014 comment: "added legacy syntaxes support",
23015 syntax: "| <-legacy-gradient>"
23016 },
23017 left: {
23018 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",
23019 syntax: "<length> | auto"
23020 },
23021 "mask-image": {
23022 comment: "missed; https://drafts.fxtf.org/css-masking-1/#the-mask-image",
23023 syntax: "<mask-reference>#"
23024 },
23025 "name-repeat": {
23026 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",
23027 syntax: "repeat( [ <positive-integer> | auto-fill ], <line-names>+)"
23028 },
23029 "named-color": {
23030 comment: "added non standard color names",
23031 syntax: "| <-non-standard-color>"
23032 },
23033 paint: {
23034 comment: "used by SVG https://www.w3.org/TR/SVG/painting.html#SpecifyingPaint",
23035 syntax: "none | <color> | <url> [ none | <color> ]? | context-fill | context-stroke"
23036 },
23037 "page-size": {
23038 comment: "https://www.w3.org/TR/css-page-3/#typedef-page-size-page-size",
23039 syntax: "A5 | A4 | A3 | B5 | B4 | JIS-B5 | JIS-B4 | letter | legal | ledger"
23040 },
23041 ratio: {
23042 comment: "missed, https://drafts.csswg.org/mediaqueries-4/#typedef-ratio",
23043 syntax: "<integer> / <integer>"
23044 },
23045 right: {
23046 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",
23047 syntax: "<length> | auto"
23048 },
23049 shape: {
23050 comment: "missed spaces in function body and add backwards compatible syntax",
23051 syntax: "rect( <top>, <right>, <bottom>, <left> ) | rect( <top> <right> <bottom> <left> )"
23052 },
23053 "svg-length": {
23054 comment: "All coordinates and lengths in SVG can be specified with or without a unit identifier",
23055 references: [
23056 "https://www.w3.org/TR/SVG11/coords.html#Units"
23057 ],
23058 syntax: "<percentage> | <length> | <number>"
23059 },
23060 "svg-writing-mode": {
23061 comment: "SVG specific keywords (deprecated for CSS)",
23062 references: [
23063 "https://developer.mozilla.org/en/docs/Web/CSS/writing-mode",
23064 "https://www.w3.org/TR/SVG/text.html#WritingModeProperty"
23065 ],
23066 syntax: "lr-tb | rl-tb | tb-rl | lr | rl | tb"
23067 },
23068 top: {
23069 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",
23070 syntax: "<length> | auto"
23071 },
23072 "track-group": {
23073 comment: "used by old grid-columns and grid-rows syntax v0",
23074 syntax: "'(' [ <string>* <track-minmax> <string>* ]+ ')' [ '[' <positive-integer> ']' ]? | <track-minmax>"
23075 },
23076 "track-list-v0": {
23077 comment: "used by old grid-columns and grid-rows syntax v0",
23078 syntax: "[ <string>* <track-group> <string>* ]+ | none"
23079 },
23080 "track-minmax": {
23081 comment: "used by old grid-columns and grid-rows syntax v0",
23082 syntax: "minmax( <track-breadth> , <track-breadth> ) | auto | <track-breadth> | fit-content"
23083 },
23084 x: {
23085 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",
23086 syntax: "<number>"
23087 },
23088 y: {
23089 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",
23090 syntax: "<number>"
23091 },
23092 declaration: {
23093 comment: "missed, restored by https://drafts.csswg.org/css-syntax",
23094 syntax: "<ident-token> : <declaration-value>? [ '!' important ]?"
23095 },
23096 "declaration-list": {
23097 comment: "missed, restored by https://drafts.csswg.org/css-syntax",
23098 syntax: "[ <declaration>? ';' ]* <declaration>?"
23099 },
23100 url: {
23101 comment: "https://drafts.csswg.org/css-values-4/#urls",
23102 syntax: "url( <string> <url-modifier>* ) | <url-token>"
23103 },
23104 "url-modifier": {
23105 comment: "https://drafts.csswg.org/css-values-4/#typedef-url-modifier",
23106 syntax: "<ident> | <function-token> <any-value> )"
23107 },
23108 "number-zero-one": {
23109 syntax: "<number [0,1]>"
23110 },
23111 "number-one-or-greater": {
23112 syntax: "<number [1,∞]>"
23113 },
23114 "positive-integer": {
23115 syntax: "<integer [0,∞]>"
23116 },
23117 "-non-standard-display": {
23118 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"
23119 }
23120 };
23121 var require$$3 = {
23122 atrules: atrules,
23123 properties: properties,
23124 syntaxes: syntaxes
23125 };
23126
23127 const mdnAtrules = require$$0;
23128 const mdnProperties = require$$1;
23129 const mdnSyntaxes = require$$2;
23130 const patch = require$$3;
23131 const extendSyntax = /^\s*\|\s*/;
23132
23133 function preprocessAtrules(dict) {
23134 const result = Object.create(null);
23135
23136 for (const atruleName in dict) {
23137 const atrule = dict[atruleName];
23138 let descriptors = null;
23139
23140 if (atrule.descriptors) {
23141 descriptors = Object.create(null);
23142
23143 for (const descriptor in atrule.descriptors) {
23144 descriptors[descriptor] = atrule.descriptors[descriptor].syntax;
23145 }
23146 }
23147
23148 result[atruleName.substr(1)] = {
23149 prelude: atrule.syntax.trim().match(/^@\S+\s+([^;\{]*)/)[1].trim() || null,
23150 descriptors
23151 };
23152 }
23153
23154 return result;
23155 }
23156
23157 function patchDictionary(dict, patchDict) {
23158 const result = {};
23159
23160 // copy all syntaxes for an original dict
23161 for (const key in dict) {
23162 result[key] = dict[key].syntax || dict[key];
23163 }
23164
23165 // apply a patch
23166 for (const key in patchDict) {
23167 if (key in dict) {
23168 if (patchDict[key].syntax) {
23169 result[key] = extendSyntax.test(patchDict[key].syntax)
23170 ? result[key] + ' ' + patchDict[key].syntax.trim()
23171 : patchDict[key].syntax;
23172 } else {
23173 delete result[key];
23174 }
23175 } else {
23176 if (patchDict[key].syntax) {
23177 result[key] = patchDict[key].syntax.replace(extendSyntax, '');
23178 }
23179 }
23180 }
23181
23182 return result;
23183 }
23184
23185 function unpackSyntaxes(dict) {
23186 const result = {};
23187
23188 for (const key in dict) {
23189 result[key] = dict[key].syntax;
23190 }
23191
23192 return result;
23193 }
23194
23195 function patchAtrules(dict, patchDict) {
23196 const result = {};
23197
23198 // copy all syntaxes for an original dict
23199 for (const key in dict) {
23200 const patchDescriptors = (patchDict[key] && patchDict[key].descriptors) || null;
23201
23202 result[key] = {
23203 prelude: key in patchDict && 'prelude' in patchDict[key]
23204 ? patchDict[key].prelude
23205 : dict[key].prelude || null,
23206 descriptors: dict[key].descriptors
23207 ? patchDictionary(dict[key].descriptors, patchDescriptors || {})
23208 : patchDescriptors && unpackSyntaxes(patchDescriptors)
23209 };
23210 }
23211
23212 // apply a patch
23213 for (const key in patchDict) {
23214 if (!hasOwnProperty.call(dict, key)) {
23215 result[key] = {
23216 prelude: patchDict[key].prelude || null,
23217 descriptors: patchDict[key].descriptors && unpackSyntaxes(patchDict[key].descriptors)
23218 };
23219 }
23220 }
23221
23222 return result;
23223 }
23224
23225 var data$1 = {
23226 types: patchDictionary(mdnSyntaxes, patch.syntaxes),
23227 atrules: patchAtrules(preprocessAtrules(mdnAtrules), patch.atrules),
23228 properties: patchDictionary(mdnProperties, patch.properties)
23229 };
23230
23231 var cmpChar$2 = tokenizer$3.cmpChar;
23232 var isDigit$1 = tokenizer$3.isDigit;
23233 var TYPE$y = tokenizer$3.TYPE;
23234
23235 var WHITESPACE$8 = TYPE$y.WhiteSpace;
23236 var COMMENT$6 = TYPE$y.Comment;
23237 var IDENT$f = TYPE$y.Ident;
23238 var NUMBER$6 = TYPE$y.Number;
23239 var DIMENSION$5 = TYPE$y.Dimension;
23240 var PLUSSIGN$5 = 0x002B; // U+002B PLUS SIGN (+)
23241 var HYPHENMINUS$2 = 0x002D; // U+002D HYPHEN-MINUS (-)
23242 var N = 0x006E; // U+006E LATIN SMALL LETTER N (n)
23243 var DISALLOW_SIGN = true;
23244 var ALLOW_SIGN = false;
23245
23246 function checkInteger(offset, disallowSign) {
23247 var pos = this.scanner.tokenStart + offset;
23248 var code = this.scanner.source.charCodeAt(pos);
23249
23250 if (code === PLUSSIGN$5 || code === HYPHENMINUS$2) {
23251 if (disallowSign) {
23252 this.error('Number sign is not allowed');
23253 }
23254 pos++;
23255 }
23256
23257 for (; pos < this.scanner.tokenEnd; pos++) {
23258 if (!isDigit$1(this.scanner.source.charCodeAt(pos))) {
23259 this.error('Integer is expected', pos);
23260 }
23261 }
23262 }
23263
23264 function checkTokenIsInteger(disallowSign) {
23265 return checkInteger.call(this, 0, disallowSign);
23266 }
23267
23268 function expectCharCode(offset, code) {
23269 if (!cmpChar$2(this.scanner.source, this.scanner.tokenStart + offset, code)) {
23270 var msg = '';
23271
23272 switch (code) {
23273 case N:
23274 msg = 'N is expected';
23275 break;
23276 case HYPHENMINUS$2:
23277 msg = 'HyphenMinus is expected';
23278 break;
23279 }
23280
23281 this.error(msg, this.scanner.tokenStart + offset);
23282 }
23283 }
23284
23285 // ... <signed-integer>
23286 // ... ['+' | '-'] <signless-integer>
23287 function consumeB() {
23288 var offset = 0;
23289 var sign = 0;
23290 var type = this.scanner.tokenType;
23291
23292 while (type === WHITESPACE$8 || type === COMMENT$6) {
23293 type = this.scanner.lookupType(++offset);
23294 }
23295
23296 if (type !== NUMBER$6) {
23297 if (this.scanner.isDelim(PLUSSIGN$5, offset) ||
23298 this.scanner.isDelim(HYPHENMINUS$2, offset)) {
23299 sign = this.scanner.isDelim(PLUSSIGN$5, offset) ? PLUSSIGN$5 : HYPHENMINUS$2;
23300
23301 do {
23302 type = this.scanner.lookupType(++offset);
23303 } while (type === WHITESPACE$8 || type === COMMENT$6);
23304
23305 if (type !== NUMBER$6) {
23306 this.scanner.skip(offset);
23307 checkTokenIsInteger.call(this, DISALLOW_SIGN);
23308 }
23309 } else {
23310 return null;
23311 }
23312 }
23313
23314 if (offset > 0) {
23315 this.scanner.skip(offset);
23316 }
23317
23318 if (sign === 0) {
23319 type = this.scanner.source.charCodeAt(this.scanner.tokenStart);
23320 if (type !== PLUSSIGN$5 && type !== HYPHENMINUS$2) {
23321 this.error('Number sign is expected');
23322 }
23323 }
23324
23325 checkTokenIsInteger.call(this, sign !== 0);
23326 return sign === HYPHENMINUS$2 ? '-' + this.consume(NUMBER$6) : this.consume(NUMBER$6);
23327 }
23328
23329 // An+B microsyntax https://www.w3.org/TR/css-syntax-3/#anb
23330 var AnPlusB = {
23331 name: 'AnPlusB',
23332 structure: {
23333 a: [String, null],
23334 b: [String, null]
23335 },
23336 parse: function() {
23337 /* eslint-disable brace-style*/
23338 var start = this.scanner.tokenStart;
23339 var a = null;
23340 var b = null;
23341
23342 // <integer>
23343 if (this.scanner.tokenType === NUMBER$6) {
23344 checkTokenIsInteger.call(this, ALLOW_SIGN);
23345 b = this.consume(NUMBER$6);
23346 }
23347
23348 // -n
23349 // -n <signed-integer>
23350 // -n ['+' | '-'] <signless-integer>
23351 // -n- <signless-integer>
23352 // <dashndashdigit-ident>
23353 else if (this.scanner.tokenType === IDENT$f && cmpChar$2(this.scanner.source, this.scanner.tokenStart, HYPHENMINUS$2)) {
23354 a = '-1';
23355
23356 expectCharCode.call(this, 1, N);
23357
23358 switch (this.scanner.getTokenLength()) {
23359 // -n
23360 // -n <signed-integer>
23361 // -n ['+' | '-'] <signless-integer>
23362 case 2:
23363 this.scanner.next();
23364 b = consumeB.call(this);
23365 break;
23366
23367 // -n- <signless-integer>
23368 case 3:
23369 expectCharCode.call(this, 2, HYPHENMINUS$2);
23370
23371 this.scanner.next();
23372 this.scanner.skipSC();
23373
23374 checkTokenIsInteger.call(this, DISALLOW_SIGN);
23375
23376 b = '-' + this.consume(NUMBER$6);
23377 break;
23378
23379 // <dashndashdigit-ident>
23380 default:
23381 expectCharCode.call(this, 2, HYPHENMINUS$2);
23382 checkInteger.call(this, 3, DISALLOW_SIGN);
23383 this.scanner.next();
23384
23385 b = this.scanner.substrToCursor(start + 2);
23386 }
23387 }
23388
23389 // '+'? n
23390 // '+'? n <signed-integer>
23391 // '+'? n ['+' | '-'] <signless-integer>
23392 // '+'? n- <signless-integer>
23393 // '+'? <ndashdigit-ident>
23394 else if (this.scanner.tokenType === IDENT$f || (this.scanner.isDelim(PLUSSIGN$5) && this.scanner.lookupType(1) === IDENT$f)) {
23395 var sign = 0;
23396 a = '1';
23397
23398 // just ignore a plus
23399 if (this.scanner.isDelim(PLUSSIGN$5)) {
23400 sign = 1;
23401 this.scanner.next();
23402 }
23403
23404 expectCharCode.call(this, 0, N);
23405
23406 switch (this.scanner.getTokenLength()) {
23407 // '+'? n
23408 // '+'? n <signed-integer>
23409 // '+'? n ['+' | '-'] <signless-integer>
23410 case 1:
23411 this.scanner.next();
23412 b = consumeB.call(this);
23413 break;
23414
23415 // '+'? n- <signless-integer>
23416 case 2:
23417 expectCharCode.call(this, 1, HYPHENMINUS$2);
23418
23419 this.scanner.next();
23420 this.scanner.skipSC();
23421
23422 checkTokenIsInteger.call(this, DISALLOW_SIGN);
23423
23424 b = '-' + this.consume(NUMBER$6);
23425 break;
23426
23427 // '+'? <ndashdigit-ident>
23428 default:
23429 expectCharCode.call(this, 1, HYPHENMINUS$2);
23430 checkInteger.call(this, 2, DISALLOW_SIGN);
23431 this.scanner.next();
23432
23433 b = this.scanner.substrToCursor(start + sign + 1);
23434 }
23435 }
23436
23437 // <ndashdigit-dimension>
23438 // <ndash-dimension> <signless-integer>
23439 // <n-dimension>
23440 // <n-dimension> <signed-integer>
23441 // <n-dimension> ['+' | '-'] <signless-integer>
23442 else if (this.scanner.tokenType === DIMENSION$5) {
23443 var code = this.scanner.source.charCodeAt(this.scanner.tokenStart);
23444 var sign = code === PLUSSIGN$5 || code === HYPHENMINUS$2;
23445
23446 for (var i = this.scanner.tokenStart + sign; i < this.scanner.tokenEnd; i++) {
23447 if (!isDigit$1(this.scanner.source.charCodeAt(i))) {
23448 break;
23449 }
23450 }
23451
23452 if (i === this.scanner.tokenStart + sign) {
23453 this.error('Integer is expected', this.scanner.tokenStart + sign);
23454 }
23455
23456 expectCharCode.call(this, i - this.scanner.tokenStart, N);
23457 a = this.scanner.source.substring(start, i);
23458
23459 // <n-dimension>
23460 // <n-dimension> <signed-integer>
23461 // <n-dimension> ['+' | '-'] <signless-integer>
23462 if (i + 1 === this.scanner.tokenEnd) {
23463 this.scanner.next();
23464 b = consumeB.call(this);
23465 } else {
23466 expectCharCode.call(this, i - this.scanner.tokenStart + 1, HYPHENMINUS$2);
23467
23468 // <ndash-dimension> <signless-integer>
23469 if (i + 2 === this.scanner.tokenEnd) {
23470 this.scanner.next();
23471 this.scanner.skipSC();
23472 checkTokenIsInteger.call(this, DISALLOW_SIGN);
23473 b = '-' + this.consume(NUMBER$6);
23474 }
23475 // <ndashdigit-dimension>
23476 else {
23477 checkInteger.call(this, i - this.scanner.tokenStart + 2, DISALLOW_SIGN);
23478 this.scanner.next();
23479 b = this.scanner.substrToCursor(i + 1);
23480 }
23481 }
23482 } else {
23483 this.error();
23484 }
23485
23486 if (a !== null && a.charCodeAt(0) === PLUSSIGN$5) {
23487 a = a.substr(1);
23488 }
23489
23490 if (b !== null && b.charCodeAt(0) === PLUSSIGN$5) {
23491 b = b.substr(1);
23492 }
23493
23494 return {
23495 type: 'AnPlusB',
23496 loc: this.getLocation(start, this.scanner.tokenStart),
23497 a: a,
23498 b: b
23499 };
23500 },
23501 generate: function(node) {
23502 var a = node.a !== null && node.a !== undefined;
23503 var b = node.b !== null && node.b !== undefined;
23504
23505 if (a) {
23506 this.chunk(
23507 node.a === '+1' ? '+n' : // eslint-disable-line operator-linebreak, indent
23508 node.a === '1' ? 'n' : // eslint-disable-line operator-linebreak, indent
23509 node.a === '-1' ? '-n' : // eslint-disable-line operator-linebreak, indent
23510 node.a + 'n' // eslint-disable-line operator-linebreak, indent
23511 );
23512
23513 if (b) {
23514 b = String(node.b);
23515 if (b.charAt(0) === '-' || b.charAt(0) === '+') {
23516 this.chunk(b.charAt(0));
23517 this.chunk(b.substr(1));
23518 } else {
23519 this.chunk('+');
23520 this.chunk(b);
23521 }
23522 }
23523 } else {
23524 this.chunk(String(node.b));
23525 }
23526 }
23527 };
23528
23529 var tokenizer = tokenizer$3;
23530 var TYPE$x = tokenizer.TYPE;
23531
23532 var WhiteSpace$1 = TYPE$x.WhiteSpace;
23533 var Semicolon = TYPE$x.Semicolon;
23534 var LeftCurlyBracket = TYPE$x.LeftCurlyBracket;
23535 var Delim = TYPE$x.Delim;
23536 var EXCLAMATIONMARK$2 = 0x0021; // U+0021 EXCLAMATION MARK (!)
23537
23538 function getOffsetExcludeWS() {
23539 if (this.scanner.tokenIndex > 0) {
23540 if (this.scanner.lookupType(-1) === WhiteSpace$1) {
23541 return this.scanner.tokenIndex > 1
23542 ? this.scanner.getTokenStart(this.scanner.tokenIndex - 1)
23543 : this.scanner.firstCharOffset;
23544 }
23545 }
23546
23547 return this.scanner.tokenStart;
23548 }
23549
23550 // 0, 0, false
23551 function balanceEnd() {
23552 return 0;
23553 }
23554
23555 // LEFTCURLYBRACKET, 0, false
23556 function leftCurlyBracket(tokenType) {
23557 return tokenType === LeftCurlyBracket ? 1 : 0;
23558 }
23559
23560 // LEFTCURLYBRACKET, SEMICOLON, false
23561 function leftCurlyBracketOrSemicolon(tokenType) {
23562 return tokenType === LeftCurlyBracket || tokenType === Semicolon ? 1 : 0;
23563 }
23564
23565 // EXCLAMATIONMARK, SEMICOLON, false
23566 function exclamationMarkOrSemicolon(tokenType, source, offset) {
23567 if (tokenType === Delim && source.charCodeAt(offset) === EXCLAMATIONMARK$2) {
23568 return 1;
23569 }
23570
23571 return tokenType === Semicolon ? 1 : 0;
23572 }
23573
23574 // 0, SEMICOLON, true
23575 function semicolonIncluded(tokenType) {
23576 return tokenType === Semicolon ? 2 : 0;
23577 }
23578
23579 var Raw = {
23580 name: 'Raw',
23581 structure: {
23582 value: String
23583 },
23584 parse: function(startToken, mode, excludeWhiteSpace) {
23585 var startOffset = this.scanner.getTokenStart(startToken);
23586 var endOffset;
23587
23588 this.scanner.skip(
23589 this.scanner.getRawLength(startToken, mode || balanceEnd)
23590 );
23591
23592 if (excludeWhiteSpace && this.scanner.tokenStart > startOffset) {
23593 endOffset = getOffsetExcludeWS.call(this);
23594 } else {
23595 endOffset = this.scanner.tokenStart;
23596 }
23597
23598 return {
23599 type: 'Raw',
23600 loc: this.getLocation(startOffset, endOffset),
23601 value: this.scanner.source.substring(startOffset, endOffset)
23602 };
23603 },
23604 generate: function(node) {
23605 this.chunk(node.value);
23606 },
23607
23608 mode: {
23609 default: balanceEnd,
23610 leftCurlyBracket: leftCurlyBracket,
23611 leftCurlyBracketOrSemicolon: leftCurlyBracketOrSemicolon,
23612 exclamationMarkOrSemicolon: exclamationMarkOrSemicolon,
23613 semicolonIncluded: semicolonIncluded
23614 }
23615 };
23616
23617 var TYPE$w = tokenizer$3.TYPE;
23618 var rawMode$5 = Raw.mode;
23619
23620 var ATKEYWORD$2 = TYPE$w.AtKeyword;
23621 var SEMICOLON$4 = TYPE$w.Semicolon;
23622 var LEFTCURLYBRACKET$3 = TYPE$w.LeftCurlyBracket;
23623 var RIGHTCURLYBRACKET$1 = TYPE$w.RightCurlyBracket;
23624
23625 function consumeRaw$5(startToken) {
23626 return this.Raw(startToken, rawMode$5.leftCurlyBracketOrSemicolon, true);
23627 }
23628
23629 function isDeclarationBlockAtrule() {
23630 for (var offset = 1, type; type = this.scanner.lookupType(offset); offset++) {
23631 if (type === RIGHTCURLYBRACKET$1) {
23632 return true;
23633 }
23634
23635 if (type === LEFTCURLYBRACKET$3 ||
23636 type === ATKEYWORD$2) {
23637 return false;
23638 }
23639 }
23640
23641 return false;
23642 }
23643
23644 var Atrule = {
23645 name: 'Atrule',
23646 structure: {
23647 name: String,
23648 prelude: ['AtrulePrelude', 'Raw', null],
23649 block: ['Block', null]
23650 },
23651 parse: function() {
23652 var start = this.scanner.tokenStart;
23653 var name;
23654 var nameLowerCase;
23655 var prelude = null;
23656 var block = null;
23657
23658 this.eat(ATKEYWORD$2);
23659
23660 name = this.scanner.substrToCursor(start + 1);
23661 nameLowerCase = name.toLowerCase();
23662 this.scanner.skipSC();
23663
23664 // parse prelude
23665 if (this.scanner.eof === false &&
23666 this.scanner.tokenType !== LEFTCURLYBRACKET$3 &&
23667 this.scanner.tokenType !== SEMICOLON$4) {
23668 if (this.parseAtrulePrelude) {
23669 prelude = this.parseWithFallback(this.AtrulePrelude.bind(this, name), consumeRaw$5);
23670
23671 // turn empty AtrulePrelude into null
23672 if (prelude.type === 'AtrulePrelude' && prelude.children.head === null) {
23673 prelude = null;
23674 }
23675 } else {
23676 prelude = consumeRaw$5.call(this, this.scanner.tokenIndex);
23677 }
23678
23679 this.scanner.skipSC();
23680 }
23681
23682 switch (this.scanner.tokenType) {
23683 case SEMICOLON$4:
23684 this.scanner.next();
23685 break;
23686
23687 case LEFTCURLYBRACKET$3:
23688 if (this.atrule.hasOwnProperty(nameLowerCase) &&
23689 typeof this.atrule[nameLowerCase].block === 'function') {
23690 block = this.atrule[nameLowerCase].block.call(this);
23691 } else {
23692 // TODO: should consume block content as Raw?
23693 block = this.Block(isDeclarationBlockAtrule.call(this));
23694 }
23695
23696 break;
23697 }
23698
23699 return {
23700 type: 'Atrule',
23701 loc: this.getLocation(start, this.scanner.tokenStart),
23702 name: name,
23703 prelude: prelude,
23704 block: block
23705 };
23706 },
23707 generate: function(node) {
23708 this.chunk('@');
23709 this.chunk(node.name);
23710
23711 if (node.prelude !== null) {
23712 this.chunk(' ');
23713 this.node(node.prelude);
23714 }
23715
23716 if (node.block) {
23717 this.node(node.block);
23718 } else {
23719 this.chunk(';');
23720 }
23721 },
23722 walkContext: 'atrule'
23723 };
23724
23725 var TYPE$v = tokenizer$3.TYPE;
23726
23727 var SEMICOLON$3 = TYPE$v.Semicolon;
23728 var LEFTCURLYBRACKET$2 = TYPE$v.LeftCurlyBracket;
23729
23730 var AtrulePrelude = {
23731 name: 'AtrulePrelude',
23732 structure: {
23733 children: [[]]
23734 },
23735 parse: function(name) {
23736 var children = null;
23737
23738 if (name !== null) {
23739 name = name.toLowerCase();
23740 }
23741
23742 this.scanner.skipSC();
23743
23744 if (this.atrule.hasOwnProperty(name) &&
23745 typeof this.atrule[name].prelude === 'function') {
23746 // custom consumer
23747 children = this.atrule[name].prelude.call(this);
23748 } else {
23749 // default consumer
23750 children = this.readSequence(this.scope.AtrulePrelude);
23751 }
23752
23753 this.scanner.skipSC();
23754
23755 if (this.scanner.eof !== true &&
23756 this.scanner.tokenType !== LEFTCURLYBRACKET$2 &&
23757 this.scanner.tokenType !== SEMICOLON$3) {
23758 this.error('Semicolon or block is expected');
23759 }
23760
23761 if (children === null) {
23762 children = this.createList();
23763 }
23764
23765 return {
23766 type: 'AtrulePrelude',
23767 loc: this.getLocationFromList(children),
23768 children: children
23769 };
23770 },
23771 generate: function(node) {
23772 this.children(node);
23773 },
23774 walkContext: 'atrulePrelude'
23775 };
23776
23777 var TYPE$u = tokenizer$3.TYPE;
23778
23779 var IDENT$e = TYPE$u.Ident;
23780 var STRING$3 = TYPE$u.String;
23781 var COLON$6 = TYPE$u.Colon;
23782 var LEFTSQUAREBRACKET$3 = TYPE$u.LeftSquareBracket;
23783 var RIGHTSQUAREBRACKET$1 = TYPE$u.RightSquareBracket;
23784 var DOLLARSIGN$1 = 0x0024; // U+0024 DOLLAR SIGN ($)
23785 var ASTERISK$5 = 0x002A; // U+002A ASTERISK (*)
23786 var EQUALSSIGN = 0x003D; // U+003D EQUALS SIGN (=)
23787 var CIRCUMFLEXACCENT = 0x005E; // U+005E (^)
23788 var VERTICALLINE$2 = 0x007C; // U+007C VERTICAL LINE (|)
23789 var TILDE$2 = 0x007E; // U+007E TILDE (~)
23790
23791 function getAttributeName() {
23792 if (this.scanner.eof) {
23793 this.error('Unexpected end of input');
23794 }
23795
23796 var start = this.scanner.tokenStart;
23797 var expectIdent = false;
23798 var checkColon = true;
23799
23800 if (this.scanner.isDelim(ASTERISK$5)) {
23801 expectIdent = true;
23802 checkColon = false;
23803 this.scanner.next();
23804 } else if (!this.scanner.isDelim(VERTICALLINE$2)) {
23805 this.eat(IDENT$e);
23806 }
23807
23808 if (this.scanner.isDelim(VERTICALLINE$2)) {
23809 if (this.scanner.source.charCodeAt(this.scanner.tokenStart + 1) !== EQUALSSIGN) {
23810 this.scanner.next();
23811 this.eat(IDENT$e);
23812 } else if (expectIdent) {
23813 this.error('Identifier is expected', this.scanner.tokenEnd);
23814 }
23815 } else if (expectIdent) {
23816 this.error('Vertical line is expected');
23817 }
23818
23819 if (checkColon && this.scanner.tokenType === COLON$6) {
23820 this.scanner.next();
23821 this.eat(IDENT$e);
23822 }
23823
23824 return {
23825 type: 'Identifier',
23826 loc: this.getLocation(start, this.scanner.tokenStart),
23827 name: this.scanner.substrToCursor(start)
23828 };
23829 }
23830
23831 function getOperator() {
23832 var start = this.scanner.tokenStart;
23833 var code = this.scanner.source.charCodeAt(start);
23834
23835 if (code !== EQUALSSIGN && // =
23836 code !== TILDE$2 && // ~=
23837 code !== CIRCUMFLEXACCENT && // ^=
23838 code !== DOLLARSIGN$1 && // $=
23839 code !== ASTERISK$5 && // *=
23840 code !== VERTICALLINE$2 // |=
23841 ) {
23842 this.error('Attribute selector (=, ~=, ^=, $=, *=, |=) is expected');
23843 }
23844
23845 this.scanner.next();
23846
23847 if (code !== EQUALSSIGN) {
23848 if (!this.scanner.isDelim(EQUALSSIGN)) {
23849 this.error('Equal sign is expected');
23850 }
23851
23852 this.scanner.next();
23853 }
23854
23855 return this.scanner.substrToCursor(start);
23856 }
23857
23858 // '[' <wq-name> ']'
23859 // '[' <wq-name> <attr-matcher> [ <string-token> | <ident-token> ] <attr-modifier>? ']'
23860 var AttributeSelector = {
23861 name: 'AttributeSelector',
23862 structure: {
23863 name: 'Identifier',
23864 matcher: [String, null],
23865 value: ['String', 'Identifier', null],
23866 flags: [String, null]
23867 },
23868 parse: function() {
23869 var start = this.scanner.tokenStart;
23870 var name;
23871 var matcher = null;
23872 var value = null;
23873 var flags = null;
23874
23875 this.eat(LEFTSQUAREBRACKET$3);
23876 this.scanner.skipSC();
23877
23878 name = getAttributeName.call(this);
23879 this.scanner.skipSC();
23880
23881 if (this.scanner.tokenType !== RIGHTSQUAREBRACKET$1) {
23882 // avoid case `[name i]`
23883 if (this.scanner.tokenType !== IDENT$e) {
23884 matcher = getOperator.call(this);
23885
23886 this.scanner.skipSC();
23887
23888 value = this.scanner.tokenType === STRING$3
23889 ? this.String()
23890 : this.Identifier();
23891
23892 this.scanner.skipSC();
23893 }
23894
23895 // attribute flags
23896 if (this.scanner.tokenType === IDENT$e) {
23897 flags = this.scanner.getTokenValue();
23898 this.scanner.next();
23899
23900 this.scanner.skipSC();
23901 }
23902 }
23903
23904 this.eat(RIGHTSQUAREBRACKET$1);
23905
23906 return {
23907 type: 'AttributeSelector',
23908 loc: this.getLocation(start, this.scanner.tokenStart),
23909 name: name,
23910 matcher: matcher,
23911 value: value,
23912 flags: flags
23913 };
23914 },
23915 generate: function(node) {
23916 var flagsPrefix = ' ';
23917
23918 this.chunk('[');
23919 this.node(node.name);
23920
23921 if (node.matcher !== null) {
23922 this.chunk(node.matcher);
23923
23924 if (node.value !== null) {
23925 this.node(node.value);
23926
23927 // space between string and flags is not required
23928 if (node.value.type === 'String') {
23929 flagsPrefix = '';
23930 }
23931 }
23932 }
23933
23934 if (node.flags !== null) {
23935 this.chunk(flagsPrefix);
23936 this.chunk(node.flags);
23937 }
23938
23939 this.chunk(']');
23940 }
23941 };
23942
23943 var TYPE$t = tokenizer$3.TYPE;
23944 var rawMode$4 = Raw.mode;
23945
23946 var WHITESPACE$7 = TYPE$t.WhiteSpace;
23947 var COMMENT$5 = TYPE$t.Comment;
23948 var SEMICOLON$2 = TYPE$t.Semicolon;
23949 var ATKEYWORD$1 = TYPE$t.AtKeyword;
23950 var LEFTCURLYBRACKET$1 = TYPE$t.LeftCurlyBracket;
23951 var RIGHTCURLYBRACKET = TYPE$t.RightCurlyBracket;
23952
23953 function consumeRaw$4(startToken) {
23954 return this.Raw(startToken, null, true);
23955 }
23956 function consumeRule() {
23957 return this.parseWithFallback(this.Rule, consumeRaw$4);
23958 }
23959 function consumeRawDeclaration(startToken) {
23960 return this.Raw(startToken, rawMode$4.semicolonIncluded, true);
23961 }
23962 function consumeDeclaration() {
23963 if (this.scanner.tokenType === SEMICOLON$2) {
23964 return consumeRawDeclaration.call(this, this.scanner.tokenIndex);
23965 }
23966
23967 var node = this.parseWithFallback(this.Declaration, consumeRawDeclaration);
23968
23969 if (this.scanner.tokenType === SEMICOLON$2) {
23970 this.scanner.next();
23971 }
23972
23973 return node;
23974 }
23975
23976 var Block = {
23977 name: 'Block',
23978 structure: {
23979 children: [[
23980 'Atrule',
23981 'Rule',
23982 'Declaration'
23983 ]]
23984 },
23985 parse: function(isDeclaration) {
23986 var consumer = isDeclaration ? consumeDeclaration : consumeRule;
23987
23988 var start = this.scanner.tokenStart;
23989 var children = this.createList();
23990
23991 this.eat(LEFTCURLYBRACKET$1);
23992
23993 scan:
23994 while (!this.scanner.eof) {
23995 switch (this.scanner.tokenType) {
23996 case RIGHTCURLYBRACKET:
23997 break scan;
23998
23999 case WHITESPACE$7:
24000 case COMMENT$5:
24001 this.scanner.next();
24002 break;
24003
24004 case ATKEYWORD$1:
24005 children.push(this.parseWithFallback(this.Atrule, consumeRaw$4));
24006 break;
24007
24008 default:
24009 children.push(consumer.call(this));
24010 }
24011 }
24012
24013 if (!this.scanner.eof) {
24014 this.eat(RIGHTCURLYBRACKET);
24015 }
24016
24017 return {
24018 type: 'Block',
24019 loc: this.getLocation(start, this.scanner.tokenStart),
24020 children: children
24021 };
24022 },
24023 generate: function(node) {
24024 this.chunk('{');
24025 this.children(node, function(prev) {
24026 if (prev.type === 'Declaration') {
24027 this.chunk(';');
24028 }
24029 });
24030 this.chunk('}');
24031 },
24032 walkContext: 'block'
24033 };
24034
24035 var TYPE$s = tokenizer$3.TYPE;
24036
24037 var LEFTSQUAREBRACKET$2 = TYPE$s.LeftSquareBracket;
24038 var RIGHTSQUAREBRACKET = TYPE$s.RightSquareBracket;
24039
24040 var Brackets = {
24041 name: 'Brackets',
24042 structure: {
24043 children: [[]]
24044 },
24045 parse: function(readSequence, recognizer) {
24046 var start = this.scanner.tokenStart;
24047 var children = null;
24048
24049 this.eat(LEFTSQUAREBRACKET$2);
24050
24051 children = readSequence.call(this, recognizer);
24052
24053 if (!this.scanner.eof) {
24054 this.eat(RIGHTSQUAREBRACKET);
24055 }
24056
24057 return {
24058 type: 'Brackets',
24059 loc: this.getLocation(start, this.scanner.tokenStart),
24060 children: children
24061 };
24062 },
24063 generate: function(node) {
24064 this.chunk('[');
24065 this.children(node);
24066 this.chunk(']');
24067 }
24068 };
24069
24070 var CDC$1 = tokenizer$3.TYPE.CDC;
24071
24072 var CDC_1 = {
24073 name: 'CDC',
24074 structure: [],
24075 parse: function() {
24076 var start = this.scanner.tokenStart;
24077
24078 this.eat(CDC$1); // -->
24079
24080 return {
24081 type: 'CDC',
24082 loc: this.getLocation(start, this.scanner.tokenStart)
24083 };
24084 },
24085 generate: function() {
24086 this.chunk('-->');
24087 }
24088 };
24089
24090 var CDO$1 = tokenizer$3.TYPE.CDO;
24091
24092 var CDO_1 = {
24093 name: 'CDO',
24094 structure: [],
24095 parse: function() {
24096 var start = this.scanner.tokenStart;
24097
24098 this.eat(CDO$1); // <!--
24099
24100 return {
24101 type: 'CDO',
24102 loc: this.getLocation(start, this.scanner.tokenStart)
24103 };
24104 },
24105 generate: function() {
24106 this.chunk('<!--');
24107 }
24108 };
24109
24110 var TYPE$r = tokenizer$3.TYPE;
24111
24112 var IDENT$d = TYPE$r.Ident;
24113 var FULLSTOP$2 = 0x002E; // U+002E FULL STOP (.)
24114
24115 // '.' ident
24116 var ClassSelector = {
24117 name: 'ClassSelector',
24118 structure: {
24119 name: String
24120 },
24121 parse: function() {
24122 if (!this.scanner.isDelim(FULLSTOP$2)) {
24123 this.error('Full stop is expected');
24124 }
24125
24126 this.scanner.next();
24127
24128 return {
24129 type: 'ClassSelector',
24130 loc: this.getLocation(this.scanner.tokenStart - 1, this.scanner.tokenEnd),
24131 name: this.consume(IDENT$d)
24132 };
24133 },
24134 generate: function(node) {
24135 this.chunk('.');
24136 this.chunk(node.name);
24137 }
24138 };
24139
24140 var TYPE$q = tokenizer$3.TYPE;
24141
24142 var IDENT$c = TYPE$q.Ident;
24143 var PLUSSIGN$4 = 0x002B; // U+002B PLUS SIGN (+)
24144 var SOLIDUS$5 = 0x002F; // U+002F SOLIDUS (/)
24145 var GREATERTHANSIGN$1 = 0x003E; // U+003E GREATER-THAN SIGN (>)
24146 var TILDE$1 = 0x007E; // U+007E TILDE (~)
24147
24148 // + | > | ~ | /deep/
24149 var Combinator = {
24150 name: 'Combinator',
24151 structure: {
24152 name: String
24153 },
24154 parse: function() {
24155 var start = this.scanner.tokenStart;
24156 var code = this.scanner.source.charCodeAt(this.scanner.tokenStart);
24157
24158 switch (code) {
24159 case GREATERTHANSIGN$1:
24160 case PLUSSIGN$4:
24161 case TILDE$1:
24162 this.scanner.next();
24163 break;
24164
24165 case SOLIDUS$5:
24166 this.scanner.next();
24167
24168 if (this.scanner.tokenType !== IDENT$c || this.scanner.lookupValue(0, 'deep') === false) {
24169 this.error('Identifier `deep` is expected');
24170 }
24171
24172 this.scanner.next();
24173
24174 if (!this.scanner.isDelim(SOLIDUS$5)) {
24175 this.error('Solidus is expected');
24176 }
24177
24178 this.scanner.next();
24179 break;
24180
24181 default:
24182 this.error('Combinator is expected');
24183 }
24184
24185 return {
24186 type: 'Combinator',
24187 loc: this.getLocation(start, this.scanner.tokenStart),
24188 name: this.scanner.substrToCursor(start)
24189 };
24190 },
24191 generate: function(node) {
24192 this.chunk(node.name);
24193 }
24194 };
24195
24196 var TYPE$p = tokenizer$3.TYPE;
24197
24198 var COMMENT$4 = TYPE$p.Comment;
24199 var ASTERISK$4 = 0x002A; // U+002A ASTERISK (*)
24200 var SOLIDUS$4 = 0x002F; // U+002F SOLIDUS (/)
24201
24202 // '/*' .* '*/'
24203 var Comment = {
24204 name: 'Comment',
24205 structure: {
24206 value: String
24207 },
24208 parse: function() {
24209 var start = this.scanner.tokenStart;
24210 var end = this.scanner.tokenEnd;
24211
24212 this.eat(COMMENT$4);
24213
24214 if ((end - start + 2) >= 2 &&
24215 this.scanner.source.charCodeAt(end - 2) === ASTERISK$4 &&
24216 this.scanner.source.charCodeAt(end - 1) === SOLIDUS$4) {
24217 end -= 2;
24218 }
24219
24220 return {
24221 type: 'Comment',
24222 loc: this.getLocation(start, this.scanner.tokenStart),
24223 value: this.scanner.source.substring(start + 2, end)
24224 };
24225 },
24226 generate: function(node) {
24227 this.chunk('/*');
24228 this.chunk(node.value);
24229 this.chunk('*/');
24230 }
24231 };
24232
24233 var isCustomProperty = names$2.isCustomProperty;
24234 var TYPE$o = tokenizer$3.TYPE;
24235 var rawMode$3 = Raw.mode;
24236
24237 var IDENT$b = TYPE$o.Ident;
24238 var HASH$4 = TYPE$o.Hash;
24239 var COLON$5 = TYPE$o.Colon;
24240 var SEMICOLON$1 = TYPE$o.Semicolon;
24241 var DELIM$4 = TYPE$o.Delim;
24242 var WHITESPACE$6 = TYPE$o.WhiteSpace;
24243 var EXCLAMATIONMARK$1 = 0x0021; // U+0021 EXCLAMATION MARK (!)
24244 var NUMBERSIGN$2 = 0x0023; // U+0023 NUMBER SIGN (#)
24245 var DOLLARSIGN = 0x0024; // U+0024 DOLLAR SIGN ($)
24246 var AMPERSAND = 0x0026; // U+0026 ANPERSAND (&)
24247 var ASTERISK$3 = 0x002A; // U+002A ASTERISK (*)
24248 var PLUSSIGN$3 = 0x002B; // U+002B PLUS SIGN (+)
24249 var SOLIDUS$3 = 0x002F; // U+002F SOLIDUS (/)
24250
24251 function consumeValueRaw(startToken) {
24252 return this.Raw(startToken, rawMode$3.exclamationMarkOrSemicolon, true);
24253 }
24254
24255 function consumeCustomPropertyRaw(startToken) {
24256 return this.Raw(startToken, rawMode$3.exclamationMarkOrSemicolon, false);
24257 }
24258
24259 function consumeValue() {
24260 var startValueToken = this.scanner.tokenIndex;
24261 var value = this.Value();
24262
24263 if (value.type !== 'Raw' &&
24264 this.scanner.eof === false &&
24265 this.scanner.tokenType !== SEMICOLON$1 &&
24266 this.scanner.isDelim(EXCLAMATIONMARK$1) === false &&
24267 this.scanner.isBalanceEdge(startValueToken) === false) {
24268 this.error();
24269 }
24270
24271 return value;
24272 }
24273
24274 var Declaration = {
24275 name: 'Declaration',
24276 structure: {
24277 important: [Boolean, String],
24278 property: String,
24279 value: ['Value', 'Raw']
24280 },
24281 parse: function() {
24282 var start = this.scanner.tokenStart;
24283 var startToken = this.scanner.tokenIndex;
24284 var property = readProperty.call(this);
24285 var customProperty = isCustomProperty(property);
24286 var parseValue = customProperty ? this.parseCustomProperty : this.parseValue;
24287 var consumeRaw = customProperty ? consumeCustomPropertyRaw : consumeValueRaw;
24288 var important = false;
24289 var value;
24290
24291 this.scanner.skipSC();
24292 this.eat(COLON$5);
24293
24294 const valueStart = this.scanner.tokenIndex;
24295
24296 if (!customProperty) {
24297 this.scanner.skipSC();
24298 }
24299
24300 if (parseValue) {
24301 value = this.parseWithFallback(consumeValue, consumeRaw);
24302 } else {
24303 value = consumeRaw.call(this, this.scanner.tokenIndex);
24304 }
24305
24306 if (customProperty && value.type === 'Value' && value.children.isEmpty()) {
24307 for (let offset = valueStart - this.scanner.tokenIndex; offset <= 0; offset++) {
24308 if (this.scanner.lookupType(offset) === WHITESPACE$6) {
24309 value.children.appendData({
24310 type: 'WhiteSpace',
24311 loc: null,
24312 value: ' '
24313 });
24314 break;
24315 }
24316 }
24317 }
24318
24319 if (this.scanner.isDelim(EXCLAMATIONMARK$1)) {
24320 important = getImportant.call(this);
24321 this.scanner.skipSC();
24322 }
24323
24324 // Do not include semicolon to range per spec
24325 // https://drafts.csswg.org/css-syntax/#declaration-diagram
24326
24327 if (this.scanner.eof === false &&
24328 this.scanner.tokenType !== SEMICOLON$1 &&
24329 this.scanner.isBalanceEdge(startToken) === false) {
24330 this.error();
24331 }
24332
24333 return {
24334 type: 'Declaration',
24335 loc: this.getLocation(start, this.scanner.tokenStart),
24336 important: important,
24337 property: property,
24338 value: value
24339 };
24340 },
24341 generate: function(node) {
24342 this.chunk(node.property);
24343 this.chunk(':');
24344 this.node(node.value);
24345
24346 if (node.important) {
24347 this.chunk(node.important === true ? '!important' : '!' + node.important);
24348 }
24349 },
24350 walkContext: 'declaration'
24351 };
24352
24353 function readProperty() {
24354 var start = this.scanner.tokenStart;
24355
24356 // hacks
24357 if (this.scanner.tokenType === DELIM$4) {
24358 switch (this.scanner.source.charCodeAt(this.scanner.tokenStart)) {
24359 case ASTERISK$3:
24360 case DOLLARSIGN:
24361 case PLUSSIGN$3:
24362 case NUMBERSIGN$2:
24363 case AMPERSAND:
24364 this.scanner.next();
24365 break;
24366
24367 // TODO: not sure we should support this hack
24368 case SOLIDUS$3:
24369 this.scanner.next();
24370 if (this.scanner.isDelim(SOLIDUS$3)) {
24371 this.scanner.next();
24372 }
24373 break;
24374 }
24375 }
24376
24377 if (this.scanner.tokenType === HASH$4) {
24378 this.eat(HASH$4);
24379 } else {
24380 this.eat(IDENT$b);
24381 }
24382
24383 return this.scanner.substrToCursor(start);
24384 }
24385
24386 // ! ws* important
24387 function getImportant() {
24388 this.eat(DELIM$4);
24389 this.scanner.skipSC();
24390
24391 var important = this.consume(IDENT$b);
24392
24393 // store original value in case it differ from `important`
24394 // for better original source restoring and hacks like `!ie` support
24395 return important === 'important' ? true : important;
24396 }
24397
24398 var TYPE$n = tokenizer$3.TYPE;
24399 var rawMode$2 = Raw.mode;
24400
24401 var WHITESPACE$5 = TYPE$n.WhiteSpace;
24402 var COMMENT$3 = TYPE$n.Comment;
24403 var SEMICOLON = TYPE$n.Semicolon;
24404
24405 function consumeRaw$3(startToken) {
24406 return this.Raw(startToken, rawMode$2.semicolonIncluded, true);
24407 }
24408
24409 var DeclarationList = {
24410 name: 'DeclarationList',
24411 structure: {
24412 children: [[
24413 'Declaration'
24414 ]]
24415 },
24416 parse: function() {
24417 var children = this.createList();
24418
24419 while (!this.scanner.eof) {
24420 switch (this.scanner.tokenType) {
24421 case WHITESPACE$5:
24422 case COMMENT$3:
24423 case SEMICOLON:
24424 this.scanner.next();
24425 break;
24426
24427 default:
24428 children.push(this.parseWithFallback(this.Declaration, consumeRaw$3));
24429 }
24430 }
24431
24432 return {
24433 type: 'DeclarationList',
24434 loc: this.getLocationFromList(children),
24435 children: children
24436 };
24437 },
24438 generate: function(node) {
24439 this.children(node, function(prev) {
24440 if (prev.type === 'Declaration') {
24441 this.chunk(';');
24442 }
24443 });
24444 }
24445 };
24446
24447 var consumeNumber$2 = utils$2.consumeNumber;
24448 var TYPE$m = tokenizer$3.TYPE;
24449
24450 var DIMENSION$4 = TYPE$m.Dimension;
24451
24452 var Dimension = {
24453 name: 'Dimension',
24454 structure: {
24455 value: String,
24456 unit: String
24457 },
24458 parse: function() {
24459 var start = this.scanner.tokenStart;
24460 var numberEnd = consumeNumber$2(this.scanner.source, start);
24461
24462 this.eat(DIMENSION$4);
24463
24464 return {
24465 type: 'Dimension',
24466 loc: this.getLocation(start, this.scanner.tokenStart),
24467 value: this.scanner.source.substring(start, numberEnd),
24468 unit: this.scanner.source.substring(numberEnd, this.scanner.tokenStart)
24469 };
24470 },
24471 generate: function(node) {
24472 this.chunk(node.value);
24473 this.chunk(node.unit);
24474 }
24475 };
24476
24477 var TYPE$l = tokenizer$3.TYPE;
24478
24479 var RIGHTPARENTHESIS$5 = TYPE$l.RightParenthesis;
24480
24481 // <function-token> <sequence> )
24482 var _Function = {
24483 name: 'Function',
24484 structure: {
24485 name: String,
24486 children: [[]]
24487 },
24488 parse: function(readSequence, recognizer) {
24489 var start = this.scanner.tokenStart;
24490 var name = this.consumeFunctionName();
24491 var nameLowerCase = name.toLowerCase();
24492 var children;
24493
24494 children = recognizer.hasOwnProperty(nameLowerCase)
24495 ? recognizer[nameLowerCase].call(this, recognizer)
24496 : readSequence.call(this, recognizer);
24497
24498 if (!this.scanner.eof) {
24499 this.eat(RIGHTPARENTHESIS$5);
24500 }
24501
24502 return {
24503 type: 'Function',
24504 loc: this.getLocation(start, this.scanner.tokenStart),
24505 name: name,
24506 children: children
24507 };
24508 },
24509 generate: function(node) {
24510 this.chunk(node.name);
24511 this.chunk('(');
24512 this.children(node);
24513 this.chunk(')');
24514 },
24515 walkContext: 'function'
24516 };
24517
24518 var TYPE$k = tokenizer$3.TYPE;
24519
24520 var HASH$3 = TYPE$k.Hash;
24521
24522 // '#' ident
24523 var Hash = {
24524 name: 'Hash',
24525 structure: {
24526 value: String
24527 },
24528 parse: function() {
24529 var start = this.scanner.tokenStart;
24530
24531 this.eat(HASH$3);
24532
24533 return {
24534 type: 'Hash',
24535 loc: this.getLocation(start, this.scanner.tokenStart),
24536 value: this.scanner.substrToCursor(start + 1)
24537 };
24538 },
24539 generate: function(node) {
24540 this.chunk('#');
24541 this.chunk(node.value);
24542 }
24543 };
24544
24545 var TYPE$j = tokenizer$3.TYPE;
24546
24547 var IDENT$a = TYPE$j.Ident;
24548
24549 var Identifier = {
24550 name: 'Identifier',
24551 structure: {
24552 name: String
24553 },
24554 parse: function() {
24555 return {
24556 type: 'Identifier',
24557 loc: this.getLocation(this.scanner.tokenStart, this.scanner.tokenEnd),
24558 name: this.consume(IDENT$a)
24559 };
24560 },
24561 generate: function(node) {
24562 this.chunk(node.name);
24563 }
24564 };
24565
24566 var TYPE$i = tokenizer$3.TYPE;
24567
24568 var HASH$2 = TYPE$i.Hash;
24569
24570 // <hash-token>
24571 var IdSelector = {
24572 name: 'IdSelector',
24573 structure: {
24574 name: String
24575 },
24576 parse: function() {
24577 var start = this.scanner.tokenStart;
24578
24579 // TODO: check value is an ident
24580 this.eat(HASH$2);
24581
24582 return {
24583 type: 'IdSelector',
24584 loc: this.getLocation(start, this.scanner.tokenStart),
24585 name: this.scanner.substrToCursor(start + 1)
24586 };
24587 },
24588 generate: function(node) {
24589 this.chunk('#');
24590 this.chunk(node.name);
24591 }
24592 };
24593
24594 var TYPE$h = tokenizer$3.TYPE;
24595
24596 var IDENT$9 = TYPE$h.Ident;
24597 var NUMBER$5 = TYPE$h.Number;
24598 var DIMENSION$3 = TYPE$h.Dimension;
24599 var LEFTPARENTHESIS$5 = TYPE$h.LeftParenthesis;
24600 var RIGHTPARENTHESIS$4 = TYPE$h.RightParenthesis;
24601 var COLON$4 = TYPE$h.Colon;
24602 var DELIM$3 = TYPE$h.Delim;
24603
24604 var MediaFeature = {
24605 name: 'MediaFeature',
24606 structure: {
24607 name: String,
24608 value: ['Identifier', 'Number', 'Dimension', 'Ratio', null]
24609 },
24610 parse: function() {
24611 var start = this.scanner.tokenStart;
24612 var name;
24613 var value = null;
24614
24615 this.eat(LEFTPARENTHESIS$5);
24616 this.scanner.skipSC();
24617
24618 name = this.consume(IDENT$9);
24619 this.scanner.skipSC();
24620
24621 if (this.scanner.tokenType !== RIGHTPARENTHESIS$4) {
24622 this.eat(COLON$4);
24623 this.scanner.skipSC();
24624
24625 switch (this.scanner.tokenType) {
24626 case NUMBER$5:
24627 if (this.lookupNonWSType(1) === DELIM$3) {
24628 value = this.Ratio();
24629 } else {
24630 value = this.Number();
24631 }
24632
24633 break;
24634
24635 case DIMENSION$3:
24636 value = this.Dimension();
24637 break;
24638
24639 case IDENT$9:
24640 value = this.Identifier();
24641
24642 break;
24643
24644 default:
24645 this.error('Number, dimension, ratio or identifier is expected');
24646 }
24647
24648 this.scanner.skipSC();
24649 }
24650
24651 this.eat(RIGHTPARENTHESIS$4);
24652
24653 return {
24654 type: 'MediaFeature',
24655 loc: this.getLocation(start, this.scanner.tokenStart),
24656 name: name,
24657 value: value
24658 };
24659 },
24660 generate: function(node) {
24661 this.chunk('(');
24662 this.chunk(node.name);
24663 if (node.value !== null) {
24664 this.chunk(':');
24665 this.node(node.value);
24666 }
24667 this.chunk(')');
24668 }
24669 };
24670
24671 var TYPE$g = tokenizer$3.TYPE;
24672
24673 var WHITESPACE$4 = TYPE$g.WhiteSpace;
24674 var COMMENT$2 = TYPE$g.Comment;
24675 var IDENT$8 = TYPE$g.Ident;
24676 var LEFTPARENTHESIS$4 = TYPE$g.LeftParenthesis;
24677
24678 var MediaQuery = {
24679 name: 'MediaQuery',
24680 structure: {
24681 children: [[
24682 'Identifier',
24683 'MediaFeature',
24684 'WhiteSpace'
24685 ]]
24686 },
24687 parse: function() {
24688 this.scanner.skipSC();
24689
24690 var children = this.createList();
24691 var child = null;
24692 var space = null;
24693
24694 scan:
24695 while (!this.scanner.eof) {
24696 switch (this.scanner.tokenType) {
24697 case COMMENT$2:
24698 this.scanner.next();
24699 continue;
24700
24701 case WHITESPACE$4:
24702 space = this.WhiteSpace();
24703 continue;
24704
24705 case IDENT$8:
24706 child = this.Identifier();
24707 break;
24708
24709 case LEFTPARENTHESIS$4:
24710 child = this.MediaFeature();
24711 break;
24712
24713 default:
24714 break scan;
24715 }
24716
24717 if (space !== null) {
24718 children.push(space);
24719 space = null;
24720 }
24721
24722 children.push(child);
24723 }
24724
24725 if (child === null) {
24726 this.error('Identifier or parenthesis is expected');
24727 }
24728
24729 return {
24730 type: 'MediaQuery',
24731 loc: this.getLocationFromList(children),
24732 children: children
24733 };
24734 },
24735 generate: function(node) {
24736 this.children(node);
24737 }
24738 };
24739
24740 var COMMA$3 = tokenizer$3.TYPE.Comma;
24741
24742 var MediaQueryList = {
24743 name: 'MediaQueryList',
24744 structure: {
24745 children: [[
24746 'MediaQuery'
24747 ]]
24748 },
24749 parse: function(relative) {
24750 var children = this.createList();
24751
24752 this.scanner.skipSC();
24753
24754 while (!this.scanner.eof) {
24755 children.push(this.MediaQuery(relative));
24756
24757 if (this.scanner.tokenType !== COMMA$3) {
24758 break;
24759 }
24760
24761 this.scanner.next();
24762 }
24763
24764 return {
24765 type: 'MediaQueryList',
24766 loc: this.getLocationFromList(children),
24767 children: children
24768 };
24769 },
24770 generate: function(node) {
24771 this.children(node, function() {
24772 this.chunk(',');
24773 });
24774 }
24775 };
24776
24777 var Nth = {
24778 name: 'Nth',
24779 structure: {
24780 nth: ['AnPlusB', 'Identifier'],
24781 selector: ['SelectorList', null]
24782 },
24783 parse: function(allowOfClause) {
24784 this.scanner.skipSC();
24785
24786 var start = this.scanner.tokenStart;
24787 var end = start;
24788 var selector = null;
24789 var query;
24790
24791 if (this.scanner.lookupValue(0, 'odd') || this.scanner.lookupValue(0, 'even')) {
24792 query = this.Identifier();
24793 } else {
24794 query = this.AnPlusB();
24795 }
24796
24797 this.scanner.skipSC();
24798
24799 if (allowOfClause && this.scanner.lookupValue(0, 'of')) {
24800 this.scanner.next();
24801
24802 selector = this.SelectorList();
24803
24804 if (this.needPositions) {
24805 end = this.getLastListNode(selector.children).loc.end.offset;
24806 }
24807 } else {
24808 if (this.needPositions) {
24809 end = query.loc.end.offset;
24810 }
24811 }
24812
24813 return {
24814 type: 'Nth',
24815 loc: this.getLocation(start, end),
24816 nth: query,
24817 selector: selector
24818 };
24819 },
24820 generate: function(node) {
24821 this.node(node.nth);
24822 if (node.selector !== null) {
24823 this.chunk(' of ');
24824 this.node(node.selector);
24825 }
24826 }
24827 };
24828
24829 var NUMBER$4 = tokenizer$3.TYPE.Number;
24830
24831 var _Number = {
24832 name: 'Number',
24833 structure: {
24834 value: String
24835 },
24836 parse: function() {
24837 return {
24838 type: 'Number',
24839 loc: this.getLocation(this.scanner.tokenStart, this.scanner.tokenEnd),
24840 value: this.consume(NUMBER$4)
24841 };
24842 },
24843 generate: function(node) {
24844 this.chunk(node.value);
24845 }
24846 };
24847
24848 // '/' | '*' | ',' | ':' | '+' | '-'
24849 var Operator = {
24850 name: 'Operator',
24851 structure: {
24852 value: String
24853 },
24854 parse: function() {
24855 var start = this.scanner.tokenStart;
24856
24857 this.scanner.next();
24858
24859 return {
24860 type: 'Operator',
24861 loc: this.getLocation(start, this.scanner.tokenStart),
24862 value: this.scanner.substrToCursor(start)
24863 };
24864 },
24865 generate: function(node) {
24866 this.chunk(node.value);
24867 }
24868 };
24869
24870 var TYPE$f = tokenizer$3.TYPE;
24871
24872 var LEFTPARENTHESIS$3 = TYPE$f.LeftParenthesis;
24873 var RIGHTPARENTHESIS$3 = TYPE$f.RightParenthesis;
24874
24875 var Parentheses = {
24876 name: 'Parentheses',
24877 structure: {
24878 children: [[]]
24879 },
24880 parse: function(readSequence, recognizer) {
24881 var start = this.scanner.tokenStart;
24882 var children = null;
24883
24884 this.eat(LEFTPARENTHESIS$3);
24885
24886 children = readSequence.call(this, recognizer);
24887
24888 if (!this.scanner.eof) {
24889 this.eat(RIGHTPARENTHESIS$3);
24890 }
24891
24892 return {
24893 type: 'Parentheses',
24894 loc: this.getLocation(start, this.scanner.tokenStart),
24895 children: children
24896 };
24897 },
24898 generate: function(node) {
24899 this.chunk('(');
24900 this.children(node);
24901 this.chunk(')');
24902 }
24903 };
24904
24905 var consumeNumber$1 = utils$2.consumeNumber;
24906 var TYPE$e = tokenizer$3.TYPE;
24907
24908 var PERCENTAGE$2 = TYPE$e.Percentage;
24909
24910 var Percentage = {
24911 name: 'Percentage',
24912 structure: {
24913 value: String
24914 },
24915 parse: function() {
24916 var start = this.scanner.tokenStart;
24917 var numberEnd = consumeNumber$1(this.scanner.source, start);
24918
24919 this.eat(PERCENTAGE$2);
24920
24921 return {
24922 type: 'Percentage',
24923 loc: this.getLocation(start, this.scanner.tokenStart),
24924 value: this.scanner.source.substring(start, numberEnd)
24925 };
24926 },
24927 generate: function(node) {
24928 this.chunk(node.value);
24929 this.chunk('%');
24930 }
24931 };
24932
24933 var TYPE$d = tokenizer$3.TYPE;
24934
24935 var IDENT$7 = TYPE$d.Ident;
24936 var FUNCTION$5 = TYPE$d.Function;
24937 var COLON$3 = TYPE$d.Colon;
24938 var RIGHTPARENTHESIS$2 = TYPE$d.RightParenthesis;
24939
24940 // : [ <ident> | <function-token> <any-value>? ) ]
24941 var PseudoClassSelector = {
24942 name: 'PseudoClassSelector',
24943 structure: {
24944 name: String,
24945 children: [['Raw'], null]
24946 },
24947 parse: function() {
24948 var start = this.scanner.tokenStart;
24949 var children = null;
24950 var name;
24951 var nameLowerCase;
24952
24953 this.eat(COLON$3);
24954
24955 if (this.scanner.tokenType === FUNCTION$5) {
24956 name = this.consumeFunctionName();
24957 nameLowerCase = name.toLowerCase();
24958
24959 if (this.pseudo.hasOwnProperty(nameLowerCase)) {
24960 this.scanner.skipSC();
24961 children = this.pseudo[nameLowerCase].call(this);
24962 this.scanner.skipSC();
24963 } else {
24964 children = this.createList();
24965 children.push(
24966 this.Raw(this.scanner.tokenIndex, null, false)
24967 );
24968 }
24969
24970 this.eat(RIGHTPARENTHESIS$2);
24971 } else {
24972 name = this.consume(IDENT$7);
24973 }
24974
24975 return {
24976 type: 'PseudoClassSelector',
24977 loc: this.getLocation(start, this.scanner.tokenStart),
24978 name: name,
24979 children: children
24980 };
24981 },
24982 generate: function(node) {
24983 this.chunk(':');
24984 this.chunk(node.name);
24985
24986 if (node.children !== null) {
24987 this.chunk('(');
24988 this.children(node);
24989 this.chunk(')');
24990 }
24991 },
24992 walkContext: 'function'
24993 };
24994
24995 var TYPE$c = tokenizer$3.TYPE;
24996
24997 var IDENT$6 = TYPE$c.Ident;
24998 var FUNCTION$4 = TYPE$c.Function;
24999 var COLON$2 = TYPE$c.Colon;
25000 var RIGHTPARENTHESIS$1 = TYPE$c.RightParenthesis;
25001
25002 // :: [ <ident> | <function-token> <any-value>? ) ]
25003 var PseudoElementSelector = {
25004 name: 'PseudoElementSelector',
25005 structure: {
25006 name: String,
25007 children: [['Raw'], null]
25008 },
25009 parse: function() {
25010 var start = this.scanner.tokenStart;
25011 var children = null;
25012 var name;
25013 var nameLowerCase;
25014
25015 this.eat(COLON$2);
25016 this.eat(COLON$2);
25017
25018 if (this.scanner.tokenType === FUNCTION$4) {
25019 name = this.consumeFunctionName();
25020 nameLowerCase = name.toLowerCase();
25021
25022 if (this.pseudo.hasOwnProperty(nameLowerCase)) {
25023 this.scanner.skipSC();
25024 children = this.pseudo[nameLowerCase].call(this);
25025 this.scanner.skipSC();
25026 } else {
25027 children = this.createList();
25028 children.push(
25029 this.Raw(this.scanner.tokenIndex, null, false)
25030 );
25031 }
25032
25033 this.eat(RIGHTPARENTHESIS$1);
25034 } else {
25035 name = this.consume(IDENT$6);
25036 }
25037
25038 return {
25039 type: 'PseudoElementSelector',
25040 loc: this.getLocation(start, this.scanner.tokenStart),
25041 name: name,
25042 children: children
25043 };
25044 },
25045 generate: function(node) {
25046 this.chunk('::');
25047 this.chunk(node.name);
25048
25049 if (node.children !== null) {
25050 this.chunk('(');
25051 this.children(node);
25052 this.chunk(')');
25053 }
25054 },
25055 walkContext: 'function'
25056 };
25057
25058 var isDigit = tokenizer$3.isDigit;
25059 var TYPE$b = tokenizer$3.TYPE;
25060
25061 var NUMBER$3 = TYPE$b.Number;
25062 var DELIM$2 = TYPE$b.Delim;
25063 var SOLIDUS$2 = 0x002F; // U+002F SOLIDUS (/)
25064 var FULLSTOP$1 = 0x002E; // U+002E FULL STOP (.)
25065
25066 // Terms of <ratio> should be a positive numbers (not zero or negative)
25067 // (see https://drafts.csswg.org/mediaqueries-3/#values)
25068 // However, -o-min-device-pixel-ratio takes fractional values as a ratio's term
25069 // and this is using by various sites. Therefore we relax checking on parse
25070 // to test a term is unsigned number without an exponent part.
25071 // Additional checking may be applied on lexer validation.
25072 function consumeNumber() {
25073 this.scanner.skipWS();
25074
25075 var value = this.consume(NUMBER$3);
25076
25077 for (var i = 0; i < value.length; i++) {
25078 var code = value.charCodeAt(i);
25079 if (!isDigit(code) && code !== FULLSTOP$1) {
25080 this.error('Unsigned number is expected', this.scanner.tokenStart - value.length + i);
25081 }
25082 }
25083
25084 if (Number(value) === 0) {
25085 this.error('Zero number is not allowed', this.scanner.tokenStart - value.length);
25086 }
25087
25088 return value;
25089 }
25090
25091 // <positive-integer> S* '/' S* <positive-integer>
25092 var Ratio = {
25093 name: 'Ratio',
25094 structure: {
25095 left: String,
25096 right: String
25097 },
25098 parse: function() {
25099 var start = this.scanner.tokenStart;
25100 var left = consumeNumber.call(this);
25101 var right;
25102
25103 this.scanner.skipWS();
25104
25105 if (!this.scanner.isDelim(SOLIDUS$2)) {
25106 this.error('Solidus is expected');
25107 }
25108 this.eat(DELIM$2);
25109 right = consumeNumber.call(this);
25110
25111 return {
25112 type: 'Ratio',
25113 loc: this.getLocation(start, this.scanner.tokenStart),
25114 left: left,
25115 right: right
25116 };
25117 },
25118 generate: function(node) {
25119 this.chunk(node.left);
25120 this.chunk('/');
25121 this.chunk(node.right);
25122 }
25123 };
25124
25125 var TYPE$a = tokenizer$3.TYPE;
25126 var rawMode$1 = Raw.mode;
25127
25128 var LEFTCURLYBRACKET = TYPE$a.LeftCurlyBracket;
25129
25130 function consumeRaw$2(startToken) {
25131 return this.Raw(startToken, rawMode$1.leftCurlyBracket, true);
25132 }
25133
25134 function consumePrelude() {
25135 var prelude = this.SelectorList();
25136
25137 if (prelude.type !== 'Raw' &&
25138 this.scanner.eof === false &&
25139 this.scanner.tokenType !== LEFTCURLYBRACKET) {
25140 this.error();
25141 }
25142
25143 return prelude;
25144 }
25145
25146 var Rule = {
25147 name: 'Rule',
25148 structure: {
25149 prelude: ['SelectorList', 'Raw'],
25150 block: ['Block']
25151 },
25152 parse: function() {
25153 var startToken = this.scanner.tokenIndex;
25154 var startOffset = this.scanner.tokenStart;
25155 var prelude;
25156 var block;
25157
25158 if (this.parseRulePrelude) {
25159 prelude = this.parseWithFallback(consumePrelude, consumeRaw$2);
25160 } else {
25161 prelude = consumeRaw$2.call(this, startToken);
25162 }
25163
25164 block = this.Block(true);
25165
25166 return {
25167 type: 'Rule',
25168 loc: this.getLocation(startOffset, this.scanner.tokenStart),
25169 prelude: prelude,
25170 block: block
25171 };
25172 },
25173 generate: function(node) {
25174 this.node(node.prelude);
25175 this.node(node.block);
25176 },
25177 walkContext: 'rule'
25178 };
25179
25180 var Selector = {
25181 name: 'Selector',
25182 structure: {
25183 children: [[
25184 'TypeSelector',
25185 'IdSelector',
25186 'ClassSelector',
25187 'AttributeSelector',
25188 'PseudoClassSelector',
25189 'PseudoElementSelector',
25190 'Combinator',
25191 'WhiteSpace'
25192 ]]
25193 },
25194 parse: function() {
25195 var children = this.readSequence(this.scope.Selector);
25196
25197 // nothing were consumed
25198 if (this.getFirstListNode(children) === null) {
25199 this.error('Selector is expected');
25200 }
25201
25202 return {
25203 type: 'Selector',
25204 loc: this.getLocationFromList(children),
25205 children: children
25206 };
25207 },
25208 generate: function(node) {
25209 this.children(node);
25210 }
25211 };
25212
25213 var TYPE$9 = tokenizer$3.TYPE;
25214
25215 var COMMA$2 = TYPE$9.Comma;
25216
25217 var SelectorList = {
25218 name: 'SelectorList',
25219 structure: {
25220 children: [[
25221 'Selector',
25222 'Raw'
25223 ]]
25224 },
25225 parse: function() {
25226 var children = this.createList();
25227
25228 while (!this.scanner.eof) {
25229 children.push(this.Selector());
25230
25231 if (this.scanner.tokenType === COMMA$2) {
25232 this.scanner.next();
25233 continue;
25234 }
25235
25236 break;
25237 }
25238
25239 return {
25240 type: 'SelectorList',
25241 loc: this.getLocationFromList(children),
25242 children: children
25243 };
25244 },
25245 generate: function(node) {
25246 this.children(node, function() {
25247 this.chunk(',');
25248 });
25249 },
25250 walkContext: 'selector'
25251 };
25252
25253 var STRING$2 = tokenizer$3.TYPE.String;
25254
25255 var _String = {
25256 name: 'String',
25257 structure: {
25258 value: String
25259 },
25260 parse: function() {
25261 return {
25262 type: 'String',
25263 loc: this.getLocation(this.scanner.tokenStart, this.scanner.tokenEnd),
25264 value: this.consume(STRING$2)
25265 };
25266 },
25267 generate: function(node) {
25268 this.chunk(node.value);
25269 }
25270 };
25271
25272 var TYPE$8 = tokenizer$3.TYPE;
25273
25274 var WHITESPACE$3 = TYPE$8.WhiteSpace;
25275 var COMMENT$1 = TYPE$8.Comment;
25276 var ATKEYWORD = TYPE$8.AtKeyword;
25277 var CDO = TYPE$8.CDO;
25278 var CDC = TYPE$8.CDC;
25279 var EXCLAMATIONMARK = 0x0021; // U+0021 EXCLAMATION MARK (!)
25280
25281 function consumeRaw$1(startToken) {
25282 return this.Raw(startToken, null, false);
25283 }
25284
25285 var StyleSheet = {
25286 name: 'StyleSheet',
25287 structure: {
25288 children: [[
25289 'Comment',
25290 'CDO',
25291 'CDC',
25292 'Atrule',
25293 'Rule',
25294 'Raw'
25295 ]]
25296 },
25297 parse: function() {
25298 var start = this.scanner.tokenStart;
25299 var children = this.createList();
25300 var child;
25301
25302 while (!this.scanner.eof) {
25303 switch (this.scanner.tokenType) {
25304 case WHITESPACE$3:
25305 this.scanner.next();
25306 continue;
25307
25308 case COMMENT$1:
25309 // ignore comments except exclamation comments (i.e. /*! .. */) on top level
25310 if (this.scanner.source.charCodeAt(this.scanner.tokenStart + 2) !== EXCLAMATIONMARK) {
25311 this.scanner.next();
25312 continue;
25313 }
25314
25315 child = this.Comment();
25316 break;
25317
25318 case CDO: // <!--
25319 child = this.CDO();
25320 break;
25321
25322 case CDC: // -->
25323 child = this.CDC();
25324 break;
25325
25326 // CSS Syntax Module Level 3
25327 // §2.2 Error handling
25328 // At the "top level" of a stylesheet, an <at-keyword-token> starts an at-rule.
25329 case ATKEYWORD:
25330 child = this.parseWithFallback(this.Atrule, consumeRaw$1);
25331 break;
25332
25333 // Anything else starts a qualified rule ...
25334 default:
25335 child = this.parseWithFallback(this.Rule, consumeRaw$1);
25336 }
25337
25338 children.push(child);
25339 }
25340
25341 return {
25342 type: 'StyleSheet',
25343 loc: this.getLocation(start, this.scanner.tokenStart),
25344 children: children
25345 };
25346 },
25347 generate: function(node) {
25348 this.children(node);
25349 },
25350 walkContext: 'stylesheet'
25351 };
25352
25353 var TYPE$7 = tokenizer$3.TYPE;
25354
25355 var IDENT$5 = TYPE$7.Ident;
25356 var ASTERISK$2 = 0x002A; // U+002A ASTERISK (*)
25357 var VERTICALLINE$1 = 0x007C; // U+007C VERTICAL LINE (|)
25358
25359 function eatIdentifierOrAsterisk() {
25360 if (this.scanner.tokenType !== IDENT$5 &&
25361 this.scanner.isDelim(ASTERISK$2) === false) {
25362 this.error('Identifier or asterisk is expected');
25363 }
25364
25365 this.scanner.next();
25366 }
25367
25368 // ident
25369 // ident|ident
25370 // ident|*
25371 // *
25372 // *|ident
25373 // *|*
25374 // |ident
25375 // |*
25376 var TypeSelector = {
25377 name: 'TypeSelector',
25378 structure: {
25379 name: String
25380 },
25381 parse: function() {
25382 var start = this.scanner.tokenStart;
25383
25384 if (this.scanner.isDelim(VERTICALLINE$1)) {
25385 this.scanner.next();
25386 eatIdentifierOrAsterisk.call(this);
25387 } else {
25388 eatIdentifierOrAsterisk.call(this);
25389
25390 if (this.scanner.isDelim(VERTICALLINE$1)) {
25391 this.scanner.next();
25392 eatIdentifierOrAsterisk.call(this);
25393 }
25394 }
25395
25396 return {
25397 type: 'TypeSelector',
25398 loc: this.getLocation(start, this.scanner.tokenStart),
25399 name: this.scanner.substrToCursor(start)
25400 };
25401 },
25402 generate: function(node) {
25403 this.chunk(node.name);
25404 }
25405 };
25406
25407 var isHexDigit = tokenizer$3.isHexDigit;
25408 var cmpChar$1 = tokenizer$3.cmpChar;
25409 var TYPE$6 = tokenizer$3.TYPE;
25410 var NAME = tokenizer$3.NAME;
25411
25412 var IDENT$4 = TYPE$6.Ident;
25413 var NUMBER$2 = TYPE$6.Number;
25414 var DIMENSION$2 = TYPE$6.Dimension;
25415 var PLUSSIGN$2 = 0x002B; // U+002B PLUS SIGN (+)
25416 var HYPHENMINUS$1 = 0x002D; // U+002D HYPHEN-MINUS (-)
25417 var QUESTIONMARK = 0x003F; // U+003F QUESTION MARK (?)
25418 var U$1 = 0x0075; // U+0075 LATIN SMALL LETTER U (u)
25419
25420 function eatHexSequence(offset, allowDash) {
25421 for (var pos = this.scanner.tokenStart + offset, len = 0; pos < this.scanner.tokenEnd; pos++) {
25422 var code = this.scanner.source.charCodeAt(pos);
25423
25424 if (code === HYPHENMINUS$1 && allowDash && len !== 0) {
25425 if (eatHexSequence.call(this, offset + len + 1, false) === 0) {
25426 this.error();
25427 }
25428
25429 return -1;
25430 }
25431
25432 if (!isHexDigit(code)) {
25433 this.error(
25434 allowDash && len !== 0
25435 ? 'HyphenMinus' + (len < 6 ? ' or hex digit' : '') + ' is expected'
25436 : (len < 6 ? 'Hex digit is expected' : 'Unexpected input'),
25437 pos
25438 );
25439 }
25440
25441 if (++len > 6) {
25442 this.error('Too many hex digits', pos);
25443 } }
25444
25445 this.scanner.next();
25446 return len;
25447 }
25448
25449 function eatQuestionMarkSequence(max) {
25450 var count = 0;
25451
25452 while (this.scanner.isDelim(QUESTIONMARK)) {
25453 if (++count > max) {
25454 this.error('Too many question marks');
25455 }
25456
25457 this.scanner.next();
25458 }
25459 }
25460
25461 function startsWith(code) {
25462 if (this.scanner.source.charCodeAt(this.scanner.tokenStart) !== code) {
25463 this.error(NAME[code] + ' is expected');
25464 }
25465 }
25466
25467 // https://drafts.csswg.org/css-syntax/#urange
25468 // Informally, the <urange> production has three forms:
25469 // U+0001
25470 // Defines a range consisting of a single code point, in this case the code point "1".
25471 // U+0001-00ff
25472 // Defines a range of codepoints between the first and the second value, in this case
25473 // the range between "1" and "ff" (255 in decimal) inclusive.
25474 // U+00??
25475 // Defines a range of codepoints where the "?" characters range over all hex digits,
25476 // in this case defining the same as the value U+0000-00ff.
25477 // In each form, a maximum of 6 digits is allowed for each hexadecimal number (if you treat "?" as a hexadecimal digit).
25478 //
25479 // <urange> =
25480 // u '+' <ident-token> '?'* |
25481 // u <dimension-token> '?'* |
25482 // u <number-token> '?'* |
25483 // u <number-token> <dimension-token> |
25484 // u <number-token> <number-token> |
25485 // u '+' '?'+
25486 function scanUnicodeRange() {
25487 var hexLength = 0;
25488
25489 // u '+' <ident-token> '?'*
25490 // u '+' '?'+
25491 if (this.scanner.isDelim(PLUSSIGN$2)) {
25492 this.scanner.next();
25493
25494 if (this.scanner.tokenType === IDENT$4) {
25495 hexLength = eatHexSequence.call(this, 0, true);
25496 if (hexLength > 0) {
25497 eatQuestionMarkSequence.call(this, 6 - hexLength);
25498 }
25499 return;
25500 }
25501
25502 if (this.scanner.isDelim(QUESTIONMARK)) {
25503 this.scanner.next();
25504 eatQuestionMarkSequence.call(this, 5);
25505 return;
25506 }
25507
25508 this.error('Hex digit or question mark is expected');
25509 return;
25510 }
25511
25512 // u <number-token> '?'*
25513 // u <number-token> <dimension-token>
25514 // u <number-token> <number-token>
25515 if (this.scanner.tokenType === NUMBER$2) {
25516 startsWith.call(this, PLUSSIGN$2);
25517 hexLength = eatHexSequence.call(this, 1, true);
25518
25519 if (this.scanner.isDelim(QUESTIONMARK)) {
25520 eatQuestionMarkSequence.call(this, 6 - hexLength);
25521 return;
25522 }
25523
25524 if (this.scanner.tokenType === DIMENSION$2 ||
25525 this.scanner.tokenType === NUMBER$2) {
25526 startsWith.call(this, HYPHENMINUS$1);
25527 eatHexSequence.call(this, 1, false);
25528 return;
25529 }
25530
25531 return;
25532 }
25533
25534 // u <dimension-token> '?'*
25535 if (this.scanner.tokenType === DIMENSION$2) {
25536 startsWith.call(this, PLUSSIGN$2);
25537 hexLength = eatHexSequence.call(this, 1, true);
25538
25539 if (hexLength > 0) {
25540 eatQuestionMarkSequence.call(this, 6 - hexLength);
25541 }
25542
25543 return;
25544 }
25545
25546 this.error();
25547 }
25548
25549 var UnicodeRange = {
25550 name: 'UnicodeRange',
25551 structure: {
25552 value: String
25553 },
25554 parse: function() {
25555 var start = this.scanner.tokenStart;
25556
25557 // U or u
25558 if (!cmpChar$1(this.scanner.source, start, U$1)) {
25559 this.error('U is expected');
25560 }
25561
25562 if (!cmpChar$1(this.scanner.source, start + 1, PLUSSIGN$2)) {
25563 this.error('Plus sign is expected');
25564 }
25565
25566 this.scanner.next();
25567 scanUnicodeRange.call(this);
25568
25569 return {
25570 type: 'UnicodeRange',
25571 loc: this.getLocation(start, this.scanner.tokenStart),
25572 value: this.scanner.substrToCursor(start)
25573 };
25574 },
25575 generate: function(node) {
25576 this.chunk(node.value);
25577 }
25578 };
25579
25580 var isWhiteSpace = tokenizer$3.isWhiteSpace;
25581 var cmpStr$1 = tokenizer$3.cmpStr;
25582 var TYPE$5 = tokenizer$3.TYPE;
25583
25584 var FUNCTION$3 = TYPE$5.Function;
25585 var URL$3 = TYPE$5.Url;
25586 var RIGHTPARENTHESIS = TYPE$5.RightParenthesis;
25587
25588 // <url-token> | <function-token> <string> )
25589 var Url = {
25590 name: 'Url',
25591 structure: {
25592 value: ['String', 'Raw']
25593 },
25594 parse: function() {
25595 var start = this.scanner.tokenStart;
25596 var value;
25597
25598 switch (this.scanner.tokenType) {
25599 case URL$3:
25600 var rawStart = start + 4;
25601 var rawEnd = this.scanner.tokenEnd - 1;
25602
25603 while (rawStart < rawEnd && isWhiteSpace(this.scanner.source.charCodeAt(rawStart))) {
25604 rawStart++;
25605 }
25606
25607 while (rawStart < rawEnd && isWhiteSpace(this.scanner.source.charCodeAt(rawEnd - 1))) {
25608 rawEnd--;
25609 }
25610
25611 value = {
25612 type: 'Raw',
25613 loc: this.getLocation(rawStart, rawEnd),
25614 value: this.scanner.source.substring(rawStart, rawEnd)
25615 };
25616
25617 this.eat(URL$3);
25618 break;
25619
25620 case FUNCTION$3:
25621 if (!cmpStr$1(this.scanner.source, this.scanner.tokenStart, this.scanner.tokenEnd, 'url(')) {
25622 this.error('Function name must be `url`');
25623 }
25624
25625 this.eat(FUNCTION$3);
25626 this.scanner.skipSC();
25627 value = this.String();
25628 this.scanner.skipSC();
25629 this.eat(RIGHTPARENTHESIS);
25630 break;
25631
25632 default:
25633 this.error('Url or Function is expected');
25634 }
25635
25636 return {
25637 type: 'Url',
25638 loc: this.getLocation(start, this.scanner.tokenStart),
25639 value: value
25640 };
25641 },
25642 generate: function(node) {
25643 this.chunk('url');
25644 this.chunk('(');
25645 this.node(node.value);
25646 this.chunk(')');
25647 }
25648 };
25649
25650 var Value = {
25651 name: 'Value',
25652 structure: {
25653 children: [[]]
25654 },
25655 parse: function() {
25656 var start = this.scanner.tokenStart;
25657 var children = this.readSequence(this.scope.Value);
25658
25659 return {
25660 type: 'Value',
25661 loc: this.getLocation(start, this.scanner.tokenStart),
25662 children: children
25663 };
25664 },
25665 generate: function(node) {
25666 this.children(node);
25667 }
25668 };
25669
25670 var WHITESPACE$2 = tokenizer$3.TYPE.WhiteSpace;
25671 var SPACE = Object.freeze({
25672 type: 'WhiteSpace',
25673 loc: null,
25674 value: ' '
25675 });
25676
25677 var WhiteSpace = {
25678 name: 'WhiteSpace',
25679 structure: {
25680 value: String
25681 },
25682 parse: function() {
25683 this.eat(WHITESPACE$2);
25684 return SPACE;
25685
25686 // return {
25687 // type: 'WhiteSpace',
25688 // loc: this.getLocation(this.scanner.tokenStart, this.scanner.tokenEnd),
25689 // value: this.consume(WHITESPACE)
25690 // };
25691 },
25692 generate: function(node) {
25693 this.chunk(node.value);
25694 }
25695 };
25696
25697 var node = {
25698 AnPlusB: AnPlusB,
25699 Atrule: Atrule,
25700 AtrulePrelude: AtrulePrelude,
25701 AttributeSelector: AttributeSelector,
25702 Block: Block,
25703 Brackets: Brackets,
25704 CDC: CDC_1,
25705 CDO: CDO_1,
25706 ClassSelector: ClassSelector,
25707 Combinator: Combinator,
25708 Comment: Comment,
25709 Declaration: Declaration,
25710 DeclarationList: DeclarationList,
25711 Dimension: Dimension,
25712 Function: _Function,
25713 Hash: Hash,
25714 Identifier: Identifier,
25715 IdSelector: IdSelector,
25716 MediaFeature: MediaFeature,
25717 MediaQuery: MediaQuery,
25718 MediaQueryList: MediaQueryList,
25719 Nth: Nth,
25720 Number: _Number,
25721 Operator: Operator,
25722 Parentheses: Parentheses,
25723 Percentage: Percentage,
25724 PseudoClassSelector: PseudoClassSelector,
25725 PseudoElementSelector: PseudoElementSelector,
25726 Ratio: Ratio,
25727 Raw: Raw,
25728 Rule: Rule,
25729 Selector: Selector,
25730 SelectorList: SelectorList,
25731 String: _String,
25732 StyleSheet: StyleSheet,
25733 TypeSelector: TypeSelector,
25734 UnicodeRange: UnicodeRange,
25735 Url: Url,
25736 Value: Value,
25737 WhiteSpace: WhiteSpace
25738 };
25739
25740 var data = data$1;
25741
25742 var lexer = {
25743 generic: true,
25744 types: data.types,
25745 atrules: data.atrules,
25746 properties: data.properties,
25747 node: node
25748 };
25749
25750 var cmpChar = tokenizer$3.cmpChar;
25751 var cmpStr = tokenizer$3.cmpStr;
25752 var TYPE$4 = tokenizer$3.TYPE;
25753
25754 var IDENT$3 = TYPE$4.Ident;
25755 var STRING$1 = TYPE$4.String;
25756 var NUMBER$1 = TYPE$4.Number;
25757 var FUNCTION$2 = TYPE$4.Function;
25758 var URL$2 = TYPE$4.Url;
25759 var HASH$1 = TYPE$4.Hash;
25760 var DIMENSION$1 = TYPE$4.Dimension;
25761 var PERCENTAGE$1 = TYPE$4.Percentage;
25762 var LEFTPARENTHESIS$2 = TYPE$4.LeftParenthesis;
25763 var LEFTSQUAREBRACKET$1 = TYPE$4.LeftSquareBracket;
25764 var COMMA$1 = TYPE$4.Comma;
25765 var DELIM$1 = TYPE$4.Delim;
25766 var NUMBERSIGN$1 = 0x0023; // U+0023 NUMBER SIGN (#)
25767 var ASTERISK$1 = 0x002A; // U+002A ASTERISK (*)
25768 var PLUSSIGN$1 = 0x002B; // U+002B PLUS SIGN (+)
25769 var HYPHENMINUS = 0x002D; // U+002D HYPHEN-MINUS (-)
25770 var SOLIDUS$1 = 0x002F; // U+002F SOLIDUS (/)
25771 var U = 0x0075; // U+0075 LATIN SMALL LETTER U (u)
25772
25773 var _default = function defaultRecognizer(context) {
25774 switch (this.scanner.tokenType) {
25775 case HASH$1:
25776 return this.Hash();
25777
25778 case COMMA$1:
25779 context.space = null;
25780 context.ignoreWSAfter = true;
25781 return this.Operator();
25782
25783 case LEFTPARENTHESIS$2:
25784 return this.Parentheses(this.readSequence, context.recognizer);
25785
25786 case LEFTSQUAREBRACKET$1:
25787 return this.Brackets(this.readSequence, context.recognizer);
25788
25789 case STRING$1:
25790 return this.String();
25791
25792 case DIMENSION$1:
25793 return this.Dimension();
25794
25795 case PERCENTAGE$1:
25796 return this.Percentage();
25797
25798 case NUMBER$1:
25799 return this.Number();
25800
25801 case FUNCTION$2:
25802 return cmpStr(this.scanner.source, this.scanner.tokenStart, this.scanner.tokenEnd, 'url(')
25803 ? this.Url()
25804 : this.Function(this.readSequence, context.recognizer);
25805
25806 case URL$2:
25807 return this.Url();
25808
25809 case IDENT$3:
25810 // check for unicode range, it should start with u+ or U+
25811 if (cmpChar(this.scanner.source, this.scanner.tokenStart, U) &&
25812 cmpChar(this.scanner.source, this.scanner.tokenStart + 1, PLUSSIGN$1)) {
25813 return this.UnicodeRange();
25814 } else {
25815 return this.Identifier();
25816 }
25817
25818 case DELIM$1:
25819 var code = this.scanner.source.charCodeAt(this.scanner.tokenStart);
25820
25821 if (code === SOLIDUS$1 ||
25822 code === ASTERISK$1 ||
25823 code === PLUSSIGN$1 ||
25824 code === HYPHENMINUS) {
25825 return this.Operator(); // TODO: replace with Delim
25826 }
25827
25828 // TODO: produce a node with Delim node type
25829
25830 if (code === NUMBERSIGN$1) {
25831 this.error('Hex or identifier is expected', this.scanner.tokenStart + 1);
25832 }
25833
25834 break;
25835 }
25836 };
25837
25838 var atrulePrelude = {
25839 getNode: _default
25840 };
25841
25842 var TYPE$3 = tokenizer$3.TYPE;
25843
25844 var DELIM = TYPE$3.Delim;
25845 var IDENT$2 = TYPE$3.Ident;
25846 var DIMENSION = TYPE$3.Dimension;
25847 var PERCENTAGE = TYPE$3.Percentage;
25848 var NUMBER = TYPE$3.Number;
25849 var HASH = TYPE$3.Hash;
25850 var COLON$1 = TYPE$3.Colon;
25851 var LEFTSQUAREBRACKET = TYPE$3.LeftSquareBracket;
25852 var NUMBERSIGN = 0x0023; // U+0023 NUMBER SIGN (#)
25853 var ASTERISK = 0x002A; // U+002A ASTERISK (*)
25854 var PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+)
25855 var SOLIDUS = 0x002F; // U+002F SOLIDUS (/)
25856 var FULLSTOP = 0x002E; // U+002E FULL STOP (.)
25857 var GREATERTHANSIGN = 0x003E; // U+003E GREATER-THAN SIGN (>)
25858 var VERTICALLINE = 0x007C; // U+007C VERTICAL LINE (|)
25859 var TILDE = 0x007E; // U+007E TILDE (~)
25860
25861 function getNode(context) {
25862 switch (this.scanner.tokenType) {
25863 case LEFTSQUAREBRACKET:
25864 return this.AttributeSelector();
25865
25866 case HASH:
25867 return this.IdSelector();
25868
25869 case COLON$1:
25870 if (this.scanner.lookupType(1) === COLON$1) {
25871 return this.PseudoElementSelector();
25872 } else {
25873 return this.PseudoClassSelector();
25874 }
25875
25876 case IDENT$2:
25877 return this.TypeSelector();
25878
25879 case NUMBER:
25880 case PERCENTAGE:
25881 return this.Percentage();
25882
25883 case DIMENSION:
25884 // throws when .123ident
25885 if (this.scanner.source.charCodeAt(this.scanner.tokenStart) === FULLSTOP) {
25886 this.error('Identifier is expected', this.scanner.tokenStart + 1);
25887 }
25888 break;
25889
25890 case DELIM:
25891 var code = this.scanner.source.charCodeAt(this.scanner.tokenStart);
25892
25893 switch (code) {
25894 case PLUSSIGN:
25895 case GREATERTHANSIGN:
25896 case TILDE:
25897 context.space = null;
25898 context.ignoreWSAfter = true;
25899 return this.Combinator();
25900
25901 case SOLIDUS: // /deep/
25902 return this.Combinator();
25903
25904 case FULLSTOP:
25905 return this.ClassSelector();
25906
25907 case ASTERISK:
25908 case VERTICALLINE:
25909 return this.TypeSelector();
25910
25911 case NUMBERSIGN:
25912 return this.IdSelector();
25913 }
25914
25915 break;
25916 }
25917 }
25918 var selector = {
25919 getNode: getNode
25920 };
25921
25922 // legacy IE function
25923 // expression( <any-value> )
25924 var expression = function() {
25925 return this.createSingleNodeList(
25926 this.Raw(this.scanner.tokenIndex, null, false)
25927 );
25928 };
25929
25930 var TYPE$2 = tokenizer$3.TYPE;
25931 var rawMode = Raw.mode;
25932
25933 var COMMA = TYPE$2.Comma;
25934 var WHITESPACE$1 = TYPE$2.WhiteSpace;
25935
25936 // var( <ident> , <value>? )
25937 var _var = function() {
25938 var children = this.createList();
25939
25940 this.scanner.skipSC();
25941
25942 // NOTE: Don't check more than a first argument is an ident, rest checks are for lexer
25943 children.push(this.Identifier());
25944
25945 this.scanner.skipSC();
25946
25947 if (this.scanner.tokenType === COMMA) {
25948 children.push(this.Operator());
25949
25950 const startIndex = this.scanner.tokenIndex;
25951 const value = this.parseCustomProperty
25952 ? this.Value(null)
25953 : this.Raw(this.scanner.tokenIndex, rawMode.exclamationMarkOrSemicolon, false);
25954
25955 if (value.type === 'Value' && value.children.isEmpty()) {
25956 for (let offset = startIndex - this.scanner.tokenIndex; offset <= 0; offset++) {
25957 if (this.scanner.lookupType(offset) === WHITESPACE$1) {
25958 value.children.appendData({
25959 type: 'WhiteSpace',
25960 loc: null,
25961 value: ' '
25962 });
25963 break;
25964 }
25965 }
25966 }
25967
25968 children.push(value);
25969 }
25970
25971 return children;
25972 };
25973
25974 var value$2 = {
25975 getNode: _default,
25976 'expression': expression,
25977 'var': _var
25978 };
25979
25980 var scope = {
25981 AtrulePrelude: atrulePrelude,
25982 Selector: selector,
25983 Value: value$2
25984 };
25985
25986 var fontFace = {
25987 parse: {
25988 prelude: null,
25989 block: function() {
25990 return this.Block(true);
25991 }
25992 }
25993 };
25994
25995 var TYPE$1 = tokenizer$3.TYPE;
25996
25997 var STRING = TYPE$1.String;
25998 var IDENT$1 = TYPE$1.Ident;
25999 var URL$1 = TYPE$1.Url;
26000 var FUNCTION$1 = TYPE$1.Function;
26001 var LEFTPARENTHESIS$1 = TYPE$1.LeftParenthesis;
26002
26003 var _import = {
26004 parse: {
26005 prelude: function() {
26006 var children = this.createList();
26007
26008 this.scanner.skipSC();
26009
26010 switch (this.scanner.tokenType) {
26011 case STRING:
26012 children.push(this.String());
26013 break;
26014
26015 case URL$1:
26016 case FUNCTION$1:
26017 children.push(this.Url());
26018 break;
26019
26020 default:
26021 this.error('String or url() is expected');
26022 }
26023
26024 if (this.lookupNonWSType(0) === IDENT$1 ||
26025 this.lookupNonWSType(0) === LEFTPARENTHESIS$1) {
26026 children.push(this.WhiteSpace());
26027 children.push(this.MediaQueryList());
26028 }
26029
26030 return children;
26031 },
26032 block: null
26033 }
26034 };
26035
26036 var media = {
26037 parse: {
26038 prelude: function() {
26039 return this.createSingleNodeList(
26040 this.MediaQueryList()
26041 );
26042 },
26043 block: function() {
26044 return this.Block(false);
26045 }
26046 }
26047 };
26048
26049 var page = {
26050 parse: {
26051 prelude: function() {
26052 return this.createSingleNodeList(
26053 this.SelectorList()
26054 );
26055 },
26056 block: function() {
26057 return this.Block(true);
26058 }
26059 }
26060 };
26061
26062 var TYPE = tokenizer$3.TYPE;
26063
26064 var WHITESPACE = TYPE.WhiteSpace;
26065 var COMMENT = TYPE.Comment;
26066 var IDENT = TYPE.Ident;
26067 var FUNCTION = TYPE.Function;
26068 var COLON = TYPE.Colon;
26069 var LEFTPARENTHESIS = TYPE.LeftParenthesis;
26070
26071 function consumeRaw() {
26072 return this.createSingleNodeList(
26073 this.Raw(this.scanner.tokenIndex, null, false)
26074 );
26075 }
26076
26077 function parentheses() {
26078 this.scanner.skipSC();
26079
26080 if (this.scanner.tokenType === IDENT &&
26081 this.lookupNonWSType(1) === COLON) {
26082 return this.createSingleNodeList(
26083 this.Declaration()
26084 );
26085 }
26086
26087 return readSequence.call(this);
26088 }
26089
26090 function readSequence() {
26091 var children = this.createList();
26092 var space = null;
26093 var child;
26094
26095 this.scanner.skipSC();
26096
26097 scan:
26098 while (!this.scanner.eof) {
26099 switch (this.scanner.tokenType) {
26100 case WHITESPACE:
26101 space = this.WhiteSpace();
26102 continue;
26103
26104 case COMMENT:
26105 this.scanner.next();
26106 continue;
26107
26108 case FUNCTION:
26109 child = this.Function(consumeRaw, this.scope.AtrulePrelude);
26110 break;
26111
26112 case IDENT:
26113 child = this.Identifier();
26114 break;
26115
26116 case LEFTPARENTHESIS:
26117 child = this.Parentheses(parentheses, this.scope.AtrulePrelude);
26118 break;
26119
26120 default:
26121 break scan;
26122 }
26123
26124 if (space !== null) {
26125 children.push(space);
26126 space = null;
26127 }
26128
26129 children.push(child);
26130 }
26131
26132 return children;
26133 }
26134
26135 var supports = {
26136 parse: {
26137 prelude: function() {
26138 var children = readSequence.call(this);
26139
26140 if (this.getFirstListNode(children) === null) {
26141 this.error('Condition is expected');
26142 }
26143
26144 return children;
26145 },
26146 block: function() {
26147 return this.Block(false);
26148 }
26149 }
26150 };
26151
26152 var atrule = {
26153 'font-face': fontFace,
26154 'import': _import,
26155 'media': media,
26156 'page': page,
26157 'supports': supports
26158 };
26159
26160 var dir = {
26161 parse: function() {
26162 return this.createSingleNodeList(
26163 this.Identifier()
26164 );
26165 }
26166 };
26167
26168 var has = {
26169 parse: function() {
26170 return this.createSingleNodeList(
26171 this.SelectorList()
26172 );
26173 }
26174 };
26175
26176 var lang = {
26177 parse: function() {
26178 return this.createSingleNodeList(
26179 this.Identifier()
26180 );
26181 }
26182 };
26183
26184 var selectorList = {
26185 parse: function selectorList() {
26186 return this.createSingleNodeList(
26187 this.SelectorList()
26188 );
26189 }
26190 };
26191
26192 var matches = selectorList;
26193
26194 var not = selectorList;
26195
26196 var ALLOW_OF_CLAUSE = true;
26197
26198 var nthWithOfClause = {
26199 parse: function nthWithOfClause() {
26200 return this.createSingleNodeList(
26201 this.Nth(ALLOW_OF_CLAUSE)
26202 );
26203 }
26204 };
26205
26206 var nthChild = nthWithOfClause;
26207
26208 var nthLastChild = nthWithOfClause;
26209
26210 var DISALLOW_OF_CLAUSE = false;
26211
26212 var nth = {
26213 parse: function nth() {
26214 return this.createSingleNodeList(
26215 this.Nth(DISALLOW_OF_CLAUSE)
26216 );
26217 }
26218 };
26219
26220 var nthLastOfType = nth;
26221
26222 var nthOfType = nth;
26223
26224 var slotted = {
26225 parse: function compoundSelector() {
26226 return this.createSingleNodeList(
26227 this.Selector()
26228 );
26229 }
26230 };
26231
26232 var pseudo = {
26233 'dir': dir,
26234 'has': has,
26235 'lang': lang,
26236 'matches': matches,
26237 'not': not,
26238 'nth-child': nthChild,
26239 'nth-last-child': nthLastChild,
26240 'nth-last-of-type': nthLastOfType,
26241 'nth-of-type': nthOfType,
26242 'slotted': slotted
26243 };
26244
26245 var parser = {
26246 parseContext: {
26247 default: 'StyleSheet',
26248 stylesheet: 'StyleSheet',
26249 atrule: 'Atrule',
26250 atrulePrelude: function(options) {
26251 return this.AtrulePrelude(options.atrule ? String(options.atrule) : null);
26252 },
26253 mediaQueryList: 'MediaQueryList',
26254 mediaQuery: 'MediaQuery',
26255 rule: 'Rule',
26256 selectorList: 'SelectorList',
26257 selector: 'Selector',
26258 block: function() {
26259 return this.Block(true);
26260 },
26261 declarationList: 'DeclarationList',
26262 declaration: 'Declaration',
26263 value: 'Value'
26264 },
26265 scope: scope,
26266 atrule: atrule,
26267 pseudo: pseudo,
26268 node: node
26269 };
26270
26271 var walker = {
26272 node: node
26273 };
26274
26275 var _args = [
26276 [
26277 "css-tree@1.1.3",
26278 "/home/gitlab-runner/builds/BQJy2NwB/0/pagedjs/pagedjs"
26279 ]
26280 ];
26281 var _from = "css-tree@1.1.3";
26282 var _id = "css-tree@1.1.3";
26283 var _inBundle = false;
26284 var _integrity = "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==";
26285 var _location = "/css-tree";
26286 var _phantomChildren = {
26287 };
26288 var _requested = {
26289 type: "version",
26290 registry: true,
26291 raw: "css-tree@1.1.3",
26292 name: "css-tree",
26293 escapedName: "css-tree",
26294 rawSpec: "1.1.3",
26295 saveSpec: null,
26296 fetchSpec: "1.1.3"
26297 };
26298 var _requiredBy = [
26299 "/"
26300 ];
26301 var _resolved = "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz";
26302 var _spec = "1.1.3";
26303 var _where = "/home/gitlab-runner/builds/BQJy2NwB/0/pagedjs/pagedjs";
26304 var author = {
26305 name: "Roman Dvornov",
26306 email: "rdvornov@gmail.com",
26307 url: "https://github.com/lahmatiy"
26308 };
26309 var bugs = {
26310 url: "https://github.com/csstree/csstree/issues"
26311 };
26312 var dependencies = {
26313 "mdn-data": "2.0.14",
26314 "source-map": "^0.6.1"
26315 };
26316 var 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";
26317 var devDependencies = {
26318 "@rollup/plugin-commonjs": "^11.0.2",
26319 "@rollup/plugin-json": "^4.0.2",
26320 "@rollup/plugin-node-resolve": "^7.1.1",
26321 coveralls: "^3.0.9",
26322 eslint: "^6.8.0",
26323 "json-to-ast": "^2.1.0",
26324 mocha: "^6.2.3",
26325 nyc: "^14.1.1",
26326 rollup: "^1.32.1",
26327 "rollup-plugin-terser": "^5.3.0"
26328 };
26329 var engines = {
26330 node: ">=8.0.0"
26331 };
26332 var files = [
26333 "data",
26334 "dist",
26335 "lib"
26336 ];
26337 var homepage = "https://github.com/csstree/csstree#readme";
26338 var jsdelivr = "dist/csstree.min.js";
26339 var keywords = [
26340 "css",
26341 "ast",
26342 "tokenizer",
26343 "parser",
26344 "walker",
26345 "lexer",
26346 "generator",
26347 "utils",
26348 "syntax",
26349 "validation"
26350 ];
26351 var license = "MIT";
26352 var main = "lib/index.js";
26353 var name = "css-tree";
26354 var repository = {
26355 type: "git",
26356 url: "git+https://github.com/csstree/csstree.git"
26357 };
26358 var scripts = {
26359 build: "rollup --config",
26360 coverage: "nyc npm test",
26361 coveralls: "nyc report --reporter=text-lcov | coveralls",
26362 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",
26363 lint: "eslint data lib scripts test && node scripts/review-syntax-patch --lint && node scripts/update-docs --lint",
26364 "lint-and-test": "npm run lint && npm test",
26365 prepublishOnly: "npm run build",
26366 "review:syntax-patch": "node scripts/review-syntax-patch",
26367 test: "mocha --reporter progress",
26368 travis: "nyc npm run lint-and-test && npm run coveralls",
26369 "update:docs": "node scripts/update-docs"
26370 };
26371 var unpkg = "dist/csstree.min.js";
26372 var version = "1.1.3";
26373 var require$$4 = {
26374 _args: _args,
26375 _from: _from,
26376 _id: _id,
26377 _inBundle: _inBundle,
26378 _integrity: _integrity,
26379 _location: _location,
26380 _phantomChildren: _phantomChildren,
26381 _requested: _requested,
26382 _requiredBy: _requiredBy,
26383 _resolved: _resolved,
26384 _spec: _spec,
26385 _where: _where,
26386 author: author,
26387 bugs: bugs,
26388 dependencies: dependencies,
26389 description: description,
26390 devDependencies: devDependencies,
26391 engines: engines,
26392 files: files,
26393 homepage: homepage,
26394 jsdelivr: jsdelivr,
26395 keywords: keywords,
26396 license: license,
26397 main: main,
26398 name: name,
26399 repository: repository,
26400 scripts: scripts,
26401 unpkg: unpkg,
26402 version: version
26403 };
26404
26405 function merge() {
26406 var dest = {};
26407
26408 for (var i = 0; i < arguments.length; i++) {
26409 var src = arguments[i];
26410 for (var key in src) {
26411 dest[key] = src[key];
26412 }
26413 }
26414
26415 return dest;
26416 }
26417
26418 syntax.exports = create$4.create(
26419 merge(
26420 lexer,
26421 parser,
26422 walker
26423 )
26424 );
26425 syntax.exports.version = require$$4.version;
26426
26427 var syntaxExports = syntax.exports;
26428
26429 var lib = syntaxExports;
26430
26431 var csstree = /*@__PURE__*/getDefaultExportFromCjs(lib);
26432
26433 class Sheet {
26434 constructor(url, hooks) {
26435
26436 if (hooks) {
26437 this.hooks = hooks;
26438 } else {
26439 this.hooks = {};
26440 this.hooks.onUrl = new Hook(this);
26441 this.hooks.onAtPage = new Hook(this);
26442 this.hooks.onAtMedia = new Hook(this);
26443 this.hooks.onRule = new Hook(this);
26444 this.hooks.onDeclaration = new Hook(this);
26445 this.hooks.onSelector = new Hook(this);
26446 this.hooks.onPseudoSelector = new Hook(this);
26447
26448 this.hooks.onContent = new Hook(this);
26449 this.hooks.onImport = new Hook(this);
26450
26451 this.hooks.beforeTreeParse = new Hook(this);
26452 this.hooks.beforeTreeWalk = new Hook(this);
26453 this.hooks.afterTreeWalk = new Hook(this);
26454 }
26455
26456 try {
26457 this.url = new URL(url, window.location.href);
26458 } catch (e) {
26459 this.url = new URL(window.location.href);
26460 }
26461 }
26462
26463
26464
26465 // parse
26466 async parse(text) {
26467 this.text = text;
26468
26469 await this.hooks.beforeTreeParse.trigger(this.text, this);
26470
26471 // send to csstree
26472 this.ast = csstree.parse(this._text);
26473
26474 await this.hooks.beforeTreeWalk.trigger(this.ast);
26475
26476 // Replace urls
26477 this.replaceUrls(this.ast);
26478
26479 // Scope
26480 this.id = UUID();
26481 // this.addScope(this.ast, this.uuid);
26482
26483 // Replace IDs with data-id
26484 this.replaceIds(this.ast);
26485
26486 this.imported = [];
26487
26488 // Trigger Hooks
26489 this.urls(this.ast);
26490 this.rules(this.ast);
26491 this.atrules(this.ast);
26492
26493 await this.hooks.afterTreeWalk.trigger(this.ast, this);
26494
26495 // return ast
26496 return this.ast;
26497 }
26498
26499
26500
26501 insertRule(rule) {
26502 let inserted = this.ast.children.appendData(rule);
26503
26504 this.declarations(rule);
26505
26506 return inserted;
26507 }
26508
26509 urls(ast) {
26510 csstree.walk(ast, {
26511 visit: "Url",
26512 enter: (node, item, list) => {
26513 this.hooks.onUrl.trigger(node, item, list);
26514 }
26515 });
26516 }
26517
26518 atrules(ast) {
26519 csstree.walk(ast, {
26520 visit: "Atrule",
26521 enter: (node, item, list) => {
26522 const basename = csstree.keyword(node.name).basename;
26523
26524 if (basename === "page") {
26525 this.hooks.onAtPage.trigger(node, item, list);
26526 this.declarations(node, item, list);
26527 }
26528
26529 if (basename === "media") {
26530 this.hooks.onAtMedia.trigger(node, item, list);
26531 this.declarations(node, item, list);
26532 }
26533
26534 if (basename === "import") {
26535 this.hooks.onImport.trigger(node, item, list);
26536 this.imports(node, item, list);
26537 }
26538 }
26539 });
26540 }
26541
26542
26543 rules(ast) {
26544 csstree.walk(ast, {
26545 visit: "Rule",
26546 enter: (ruleNode, ruleItem, rulelist) => {
26547
26548 this.hooks.onRule.trigger(ruleNode, ruleItem, rulelist);
26549 this.declarations(ruleNode, ruleItem, rulelist);
26550 this.onSelector(ruleNode, ruleItem, rulelist);
26551
26552 }
26553 });
26554 }
26555
26556 declarations(ruleNode, ruleItem, rulelist) {
26557 csstree.walk(ruleNode, {
26558 visit: "Declaration",
26559 enter: (declarationNode, dItem, dList) => {
26560
26561 this.hooks.onDeclaration.trigger(declarationNode, dItem, dList, {ruleNode, ruleItem, rulelist});
26562
26563 if (declarationNode.property === "content") {
26564 csstree.walk(declarationNode, {
26565 visit: "Function",
26566 enter: (funcNode, fItem, fList) => {
26567 this.hooks.onContent.trigger(funcNode, fItem, fList, {declarationNode, dItem, dList}, {ruleNode, ruleItem, rulelist});
26568 }
26569 });
26570 }
26571
26572 }
26573 });
26574 }
26575
26576 // add pseudo elements to parser
26577 onSelector(ruleNode, ruleItem, rulelist) {
26578 csstree.walk(ruleNode, {
26579 visit: "Selector",
26580 enter: (selectNode, selectItem, selectList) => {
26581 this.hooks.onSelector.trigger(selectNode, selectItem, selectList, {ruleNode, ruleItem, rulelist});
26582
26583 if (selectNode.children.forEach(node => {if (node.type === "PseudoElementSelector") {
26584 csstree.walk(node, {
26585 visit: "PseudoElementSelector",
26586 enter: (pseudoNode, pItem, pList) => {
26587 this.hooks.onPseudoSelector.trigger(pseudoNode, pItem, pList, {selectNode, selectItem, selectList}, {ruleNode, ruleItem, rulelist});
26588 }
26589 });
26590 }}));
26591 }
26592 });
26593 }
26594
26595 replaceUrls(ast) {
26596 csstree.walk(ast, {
26597 visit: "Url",
26598 enter: (node, item, list) => {
26599 let content = node.value.value;
26600 if ((node.value.type === "Raw" && content.startsWith("data:")) || (node.value.type === "String" && (content.startsWith("\"data:") || content.startsWith("'data:")))) ; else {
26601 let href = content.replace(/["']/g, "");
26602 let url = new URL(href, this.url);
26603 node.value.value = url.toString();
26604 }
26605 }
26606 });
26607 }
26608
26609 addScope(ast, id) {
26610 // Get all selector lists
26611 // add an id
26612 csstree.walk(ast, {
26613 visit: "Selector",
26614 enter: (node, item, list) => {
26615 let children = node.children;
26616 children.prepend(children.createItem({
26617 type: "WhiteSpace",
26618 value: " "
26619 }));
26620 children.prepend(children.createItem({
26621 type: "IdSelector",
26622 name: id,
26623 loc: null,
26624 children: null
26625 }));
26626 }
26627 });
26628 }
26629
26630 getNamedPageSelectors(ast) {
26631 let namedPageSelectors = {};
26632 csstree.walk(ast, {
26633 visit: "Rule",
26634 enter: (node, item, list) => {
26635 csstree.walk(node, {
26636 visit: "Declaration",
26637 enter: (declaration, dItem, dList) => {
26638 if (declaration.property === "page") {
26639 let value = declaration.value.children.first();
26640 let name = value.name;
26641 let selector = csstree.generate(node.prelude);
26642 namedPageSelectors[name] = {
26643 name: name,
26644 selector: selector
26645 };
26646
26647 // dList.remove(dItem);
26648
26649 // Add in page break
26650 declaration.property = "break-before";
26651 value.type = "Identifier";
26652 value.name = "always";
26653
26654 }
26655 }
26656 });
26657 }
26658 });
26659 return namedPageSelectors;
26660 }
26661
26662 replaceIds(ast) {
26663 csstree.walk(ast, {
26664 visit: "Rule",
26665 enter: (node, item, list) => {
26666
26667 csstree.walk(node, {
26668 visit: "IdSelector",
26669 enter: (idNode, idItem, idList) => {
26670 let name = idNode.name;
26671 idNode.flags = null;
26672 idNode.matcher = "=";
26673 idNode.name = {type: "Identifier", loc: null, name: "data-id"};
26674 idNode.type = "AttributeSelector";
26675 idNode.value = {type: "String", loc: null, value: `"${name}"`};
26676 }
26677 });
26678 }
26679 });
26680 }
26681
26682 imports(node, item, list) {
26683 // console.log("import", node, item, list);
26684 let queries = [];
26685 csstree.walk(node, {
26686 visit: "MediaQuery",
26687 enter: (mqNode, mqItem, mqList) => {
26688 csstree.walk(mqNode, {
26689 visit: "Identifier",
26690 enter: (identNode, identItem, identList) => {
26691 queries.push(identNode.name);
26692 }
26693 });
26694 }
26695 });
26696
26697 // Just basic media query support for now
26698 let shouldNotApply = queries.some((query, index) => {
26699 let q = query;
26700 if (q === "not") {
26701 q = queries[index + 1];
26702 return !(q === "screen" || q === "speech");
26703 } else {
26704 return (q === "screen" || q === "speech");
26705 }
26706 });
26707
26708 if (shouldNotApply) {
26709 return;
26710 }
26711
26712 csstree.walk(node, {
26713 visit: "String",
26714 enter: (urlNode, urlItem, urlList) => {
26715 let href = urlNode.value.replace(/["']/g, "");
26716 let url = new URL(href, this.url);
26717 let value = url.toString();
26718
26719 this.imported.push(value);
26720
26721 // Remove the original
26722 list.remove(item);
26723 }
26724 });
26725 }
26726
26727 set text(t) {
26728 this._text = t;
26729 }
26730
26731 get text() {
26732 return this._text;
26733 }
26734
26735 // generate string
26736 toString(ast) {
26737 return csstree.generate(ast || this.ast);
26738 }
26739 }
26740
26741 var baseStyles = `
26742:root {
26743 --pagedjs-width: 8.5in;
26744 --pagedjs-height: 11in;
26745 --pagedjs-width-right: 8.5in;
26746 --pagedjs-height-right: 11in;
26747 --pagedjs-width-left: 8.5in;
26748 --pagedjs-height-left: 11in;
26749 --pagedjs-pagebox-width: 8.5in;
26750 --pagedjs-pagebox-height: 11in;
26751 --pagedjs-footnotes-height: 0mm;
26752 --pagedjs-margin-top: 1in;
26753 --pagedjs-margin-right: 1in;
26754 --pagedjs-margin-bottom: 1in;
26755 --pagedjs-margin-left: 1in;
26756 --pagedjs-padding-top: 0mm;
26757 --pagedjs-padding-right: 0mm;
26758 --pagedjs-padding-bottom: 0mm;
26759 --pagedjs-padding-left: 0mm;
26760 --pagedjs-border-top: 0mm;
26761 --pagedjs-border-right: 0mm;
26762 --pagedjs-border-bottom: 0mm;
26763 --pagedjs-border-left: 0mm;
26764 --pagedjs-bleed-top: 0mm;
26765 --pagedjs-bleed-right: 0mm;
26766 --pagedjs-bleed-bottom: 0mm;
26767 --pagedjs-bleed-left: 0mm;
26768 --pagedjs-bleed-right-top: 0mm;
26769 --pagedjs-bleed-right-right: 0mm;
26770 --pagedjs-bleed-right-bottom: 0mm;
26771 --pagedjs-bleed-right-left: 0mm;
26772 --pagedjs-bleed-left-top: 0mm;
26773 --pagedjs-bleed-left-right: 0mm;
26774 --pagedjs-bleed-left-bottom: 0mm;
26775 --pagedjs-bleed-left-left: 0mm;
26776 --pagedjs-crop-color: black;
26777 --pagedjs-crop-shadow: white;
26778 --pagedjs-crop-offset: 2mm;
26779 --pagedjs-crop-stroke: 1px;
26780 --pagedjs-cross-size: 5mm;
26781 --pagedjs-mark-cross-display: none;
26782 --pagedjs-mark-crop-display: none;
26783 --pagedjs-page-count: 0;
26784 --pagedjs-page-counter-increment: 1;
26785 --pagedjs-footnotes-count: 0;
26786 --pagedjs-column-gap-offset: 1000px;
26787}
26788
26789@page {
26790 size: letter;
26791 margin: 0;
26792}
26793
26794.pagedjs_sheet {
26795 box-sizing: border-box;
26796 width: var(--pagedjs-width);
26797 height: var(--pagedjs-height);
26798 overflow: hidden;
26799 position: relative;
26800 display: grid;
26801 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);
26802 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);
26803}
26804
26805.pagedjs_right_page .pagedjs_sheet {
26806 width: var(--pagedjs-width-right);
26807 height: var(--pagedjs-height-right);
26808 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);
26809 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);
26810}
26811
26812.pagedjs_left_page .pagedjs_sheet {
26813 width: var(--pagedjs-width-left);
26814 height: var(--pagedjs-height-left);
26815 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);
26816 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);
26817}
26818
26819.pagedjs_bleed {
26820 display: flex;
26821 align-items: center;
26822 justify-content: center;
26823 flex-wrap: nowrap;
26824 overflow: hidden;
26825}
26826
26827.pagedjs_bleed-top {
26828 grid-column: bleed-left / -1;
26829 grid-row: bleed-top;
26830 flex-direction: row;
26831}
26832
26833.pagedjs_bleed-bottom {
26834 grid-column: bleed-left / -1;
26835 grid-row: bleed-bottom;
26836 flex-direction: row;
26837}
26838
26839.pagedjs_bleed-left {
26840 grid-column: bleed-left;
26841 grid-row: bleed-top / -1;
26842 flex-direction: column;
26843}
26844
26845.pagedjs_bleed-right {
26846 grid-column: bleed-right;
26847 grid-row: bleed-top / -1;
26848 flex-direction: column;
26849}
26850
26851.pagedjs_marks-crop {
26852 display: var(--pagedjs-mark-crop-display);
26853 flex-grow: 0;
26854 flex-shrink: 0;
26855 z-index: 9999999999;
26856}
26857
26858.pagedjs_bleed-top .pagedjs_marks-crop:nth-child(1),
26859.pagedjs_bleed-bottom .pagedjs_marks-crop:nth-child(1) {
26860 width: calc(var(--pagedjs-bleed-left) - var(--pagedjs-crop-stroke));
26861 border-right: var(--pagedjs-crop-stroke) solid var(--pagedjs-crop-color);
26862 box-shadow: 1px 0px 0px 0px var(--pagedjs-crop-shadow);
26863}
26864
26865.pagedjs_right_page .pagedjs_bleed-top .pagedjs_marks-crop:nth-child(1),
26866.pagedjs_right_page .pagedjs_bleed-bottom .pagedjs_marks-crop:nth-child(1) {
26867 width: calc(var(--pagedjs-bleed-right-left) - var(--pagedjs-crop-stroke));
26868}
26869
26870.pagedjs_left_page .pagedjs_bleed-top .pagedjs_marks-crop:nth-child(1),
26871.pagedjs_left_page .pagedjs_bleed-bottom .pagedjs_marks-crop:nth-child(1) {
26872 width: calc(var(--pagedjs-bleed-left-left) - var(--pagedjs-crop-stroke));
26873}
26874
26875.pagedjs_bleed-top .pagedjs_marks-crop:nth-child(3),
26876.pagedjs_bleed-bottom .pagedjs_marks-crop:nth-child(3) {
26877 width: calc(var(--pagedjs-bleed-right) - var(--pagedjs-crop-stroke));
26878 border-left: var(--pagedjs-crop-stroke) solid var(--pagedjs-crop-color);
26879 box-shadow: -1px 0px 0px 0px var(--pagedjs-crop-shadow);
26880}
26881
26882.pagedjs_right_page .pagedjs_bleed-top .pagedjs_marks-crop:nth-child(3),
26883.pagedjs_right_page .pagedjs_bleed-bottom .pagedjs_marks-crop:nth-child(3) {
26884 width: calc(var(--pagedjs-bleed-right-right) - var(--pagedjs-crop-stroke));
26885}
26886
26887.pagedjs_left_page .pagedjs_bleed-top .pagedjs_marks-crop:nth-child(3),
26888.pagedjs_left_page .pagedjs_bleed-bottom .pagedjs_marks-crop:nth-child(3) {
26889 width: calc(var(--pagedjs-bleed-left-right) - var(--pagedjs-crop-stroke));
26890}
26891
26892.pagedjs_bleed-top .pagedjs_marks-crop {
26893 align-self: flex-start;
26894 height: calc(var(--pagedjs-bleed-top) - var(--pagedjs-crop-offset));
26895}
26896
26897.pagedjs_right_page .pagedjs_bleed-top .pagedjs_marks-crop {
26898 height: calc(var(--pagedjs-bleed-right-top) - var(--pagedjs-crop-offset));
26899}
26900
26901.pagedjs_left_page .pagedjs_bleed-top .pagedjs_marks-crop {
26902 height: calc(var(--pagedjs-bleed-left-top) - var(--pagedjs-crop-offset));
26903}
26904
26905.pagedjs_bleed-bottom .pagedjs_marks-crop {
26906 align-self: flex-end;
26907 height: calc(var(--pagedjs-bleed-bottom) - var(--pagedjs-crop-offset));
26908}
26909
26910.pagedjs_right_page .pagedjs_bleed-bottom .pagedjs_marks-crop {
26911 height: calc(var(--pagedjs-bleed-right-bottom) - var(--pagedjs-crop-offset));
26912}
26913
26914.pagedjs_left_page .pagedjs_bleed-bottom .pagedjs_marks-crop {
26915 height: calc(var(--pagedjs-bleed-left-bottom) - var(--pagedjs-crop-offset));
26916}
26917
26918.pagedjs_bleed-left .pagedjs_marks-crop:nth-child(1),
26919.pagedjs_bleed-right .pagedjs_marks-crop:nth-child(1) {
26920 height: calc(var(--pagedjs-bleed-top) - var(--pagedjs-crop-stroke));
26921 border-bottom: var(--pagedjs-crop-stroke) solid var(--pagedjs-crop-color);
26922 box-shadow: 0px 1px 0px 0px var(--pagedjs-crop-shadow);
26923}
26924
26925.pagedjs_right_page .pagedjs_bleed-left .pagedjs_marks-crop:nth-child(1),
26926.pagedjs_right_page .pagedjs_bleed-right .pagedjs_marks-crop:nth-child(1) {
26927 height: calc(var(--pagedjs-bleed-right-top) - var(--pagedjs-crop-stroke));
26928}
26929
26930.pagedjs_left_page .pagedjs_bleed-left .pagedjs_marks-crop:nth-child(1),
26931.pagedjs_left_page .pagedjs_bleed-right .pagedjs_marks-crop:nth-child(1) {
26932 height: calc(var(--pagedjs-bleed-left-top) - var(--pagedjs-crop-stroke));
26933}
26934
26935.pagedjs_bleed-left .pagedjs_marks-crop:nth-child(3),
26936.pagedjs_bleed-right .pagedjs_marks-crop:nth-child(3) {
26937 height: calc(var(--pagedjs-bleed-bottom) - var(--pagedjs-crop-stroke));
26938 border-top: var(--pagedjs-crop-stroke) solid var(--pagedjs-crop-color);
26939 box-shadow: 0px -1px 0px 0px var(--pagedjs-crop-shadow);
26940}
26941
26942.pagedjs_right_page .pagedjs_bleed-left .pagedjs_marks-crop:nth-child(3),
26943.pagedjs_right_page .pagedjs_bleed-right .pagedjs_marks-crop:nth-child(3) {
26944 height: calc(var(--pagedjs-bleed-right-bottom) - var(--pagedjs-crop-stroke));
26945}
26946
26947.pagedjs_left_page .pagedjs_bleed-left .pagedjs_marks-crop:nth-child(3),
26948.pagedjs_left_page .pagedjs_bleed-right .pagedjs_marks-crop:nth-child(3) {
26949 height: calc(var(--pagedjs-bleed-left-bottom) - var(--pagedjs-crop-stroke));
26950}
26951
26952.pagedjs_bleed-left .pagedjs_marks-crop {
26953 width: calc(var(--pagedjs-bleed-left) - var(--pagedjs-crop-offset));
26954 align-self: flex-start;
26955}
26956
26957.pagedjs_right_page .pagedjs_bleed-left .pagedjs_marks-crop {
26958 width: calc(var(--pagedjs-bleed-right-left) - var(--pagedjs-crop-offset));
26959}
26960
26961.pagedjs_left_page .pagedjs_bleed-left .pagedjs_marks-crop {
26962 width: calc(var(--pagedjs-bleed-left-left) - var(--pagedjs-crop-offset));
26963}
26964
26965.pagedjs_bleed-right .pagedjs_marks-crop {
26966 width: calc(var(--pagedjs-bleed-right) - var(--pagedjs-crop-offset));
26967 align-self: flex-end;
26968}
26969
26970.pagedjs_right_page .pagedjs_bleed-right .pagedjs_marks-crop {
26971 width: calc(var(--pagedjs-bleed-right-right) - var(--pagedjs-crop-offset));
26972}
26973
26974.pagedjs_left_page .pagedjs_bleed-right .pagedjs_marks-crop {
26975 width: calc(var(--pagedjs-bleed-left-right) - var(--pagedjs-crop-offset));
26976}
26977
26978.pagedjs_marks-middle {
26979 display: flex;
26980 flex-grow: 1;
26981 flex-shrink: 0;
26982 align-items: center;
26983 justify-content: center;
26984}
26985
26986.pagedjs_marks-cross {
26987 display: var(--pagedjs-mark-cross-display);
26988 background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iTGF5ZXJfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiIHdpZHRoPSIzMi41MzdweCIgaGVpZ2h0PSIzMi41MzdweCIgdmlld0JveD0iMC4xMDQgMC4xMDQgMzIuNTM3IDMyLjUzNyIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwLjEwNCAwLjEwNCAzMi41MzcgMzIuNTM3IiB4bWw6c3BhY2U9InByZXNlcnZlIj48cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IiNGRkZGRkYiIHN0cm9rZS13aWR0aD0iMy4zODkzIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIGQ9Ik0yOS45MzEsMTYuMzczYzAsNy40ODktNi4wNjgsMTMuNTYtMTMuNTU4LDEzLjU2Yy03LjQ4MywwLTEzLjU1Ny02LjA3Mi0xMy41NTctMTMuNTZjMC03LjQ4Niw2LjA3NC0xMy41NTQsMTMuNTU3LTEzLjU1NEMyMy44NjIsMi44MTksMjkuOTMxLDguODg3LDI5LjkzMSwxNi4zNzN6Ii8+PGxpbmUgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjRkZGRkZGIiBzdHJva2Utd2lkdGg9IjMuMzg5MyIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiB4MT0iMC4xMDQiIHkxPSIxNi4zNzMiIHgyPSIzMi42NDIiIHkyPSIxNi4zNzMiLz48bGluZSBmaWxsPSJub25lIiBzdHJva2U9IiNGRkZGRkYiIHN0cm9rZS13aWR0aD0iMy4zODkzIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHgxPSIxNi4zNzMiIHkxPSIwLjEwNCIgeDI9IjE2LjM3MyIgeTI9IjMyLjY0MiIvPjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iI0ZGRkZGRiIgc3Ryb2tlLXdpZHRoPSIzLjM4OTMiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgZD0iTTI0LjUwOCwxNi4zNzNjMCw0LjQ5Ni0zLjYzOCw4LjEzNS04LjEzNSw4LjEzNWMtNC40OTEsMC04LjEzNS0zLjYzOC04LjEzNS04LjEzNWMwLTQuNDg5LDMuNjQ0LTguMTM1LDguMTM1LTguMTM1QzIwLjg2OSw4LjIzOSwyNC41MDgsMTEuODg0LDI0LjUwOCwxNi4zNzN6Ii8+PHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwMDAwIiBzdHJva2Utd2lkdGg9IjAuNjc3OCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBkPSJNMjkuOTMxLDE2LjM3M2MwLDcuNDg5LTYuMDY4LDEzLjU2LTEzLjU1OCwxMy41NmMtNy40ODMsMC0xMy41NTctNi4wNzItMTMuNTU3LTEzLjU2YzAtNy40ODYsNi4wNzQtMTMuNTU0LDEzLjU1Ny0xMy41NTRDMjMuODYyLDIuODE5LDI5LjkzMSw4Ljg4NywyOS45MzEsMTYuMzczeiIvPjxsaW5lIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMDAwMCIgc3Ryb2tlLXdpZHRoPSIwLjY3NzgiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgeDE9IjAuMTA0IiB5MT0iMTYuMzczIiB4Mj0iMzIuNjQyIiB5Mj0iMTYuMzczIi8+PGxpbmUgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwMDAwIiBzdHJva2Utd2lkdGg9IjAuNjc3OCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiB4MT0iMTYuMzczIiB5MT0iMC4xMDQiIHgyPSIxNi4zNzMiIHkyPSIzMi42NDIiLz48cGF0aCBkPSJNMjQuNTA4LDE2LjM3M2MwLDQuNDk2LTMuNjM4LDguMTM1LTguMTM1LDguMTM1Yy00LjQ5MSwwLTguMTM1LTMuNjM4LTguMTM1LTguMTM1YzAtNC40ODksMy42NDQtOC4xMzUsOC4xMzUtOC4xMzVDMjAuODY5LDguMjM5LDI0LjUwOCwxMS44ODQsMjQuNTA4LDE2LjM3MyIvPjxsaW5lIGZpbGw9Im5vbmUiIHN0cm9rZT0iI0ZGRkZGRiIgc3Ryb2tlLXdpZHRoPSIwLjY3NzgiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgeDE9IjguMjM5IiB5MT0iMTYuMzczIiB4Mj0iMjQuNTA4IiB5Mj0iMTYuMzczIi8+PGxpbmUgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjRkZGRkZGIiBzdHJva2Utd2lkdGg9IjAuNjc3OCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiB4MT0iMTYuMzczIiB5MT0iOC4yMzkiIHgyPSIxNi4zNzMiIHkyPSIyNC41MDgiLz48L3N2Zz4=);
26989 background-repeat: no-repeat;
26990 background-position: 50% 50%;
26991 background-size: var(--pagedjs-cross-size);
26992
26993 z-index: 2147483647;
26994 width: var(--pagedjs-cross-size);
26995 height: var(--pagedjs-cross-size);
26996}
26997
26998.pagedjs_pagebox {
26999 box-sizing: border-box;
27000 width: var(--pagedjs-pagebox-width);
27001 height: var(--pagedjs-pagebox-height);
27002 position: relative;
27003 display: grid;
27004 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);
27005 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);
27006 grid-column: sheet-center;
27007 grid-row: sheet-middle;
27008}
27009
27010.pagedjs_pagebox * {
27011 box-sizing: border-box;
27012}
27013
27014.pagedjs_margin-top {
27015 width: calc(var(--pagedjs-pagebox-width) - var(--pagedjs-margin-left) - var(--pagedjs-margin-right));
27016 height: var(--pagedjs-margin-top);
27017 grid-column: center;
27018 grid-row: header;
27019 flex-wrap: nowrap;
27020 display: grid;
27021 grid-template-columns: repeat(3, 1fr);
27022 grid-template-rows: 100%;
27023}
27024
27025.pagedjs_margin-top-left-corner-holder {
27026 width: var(--pagedjs-margin-left);
27027 height: var(--pagedjs-margin-top);
27028 display: flex;
27029 grid-column: left;
27030 grid-row: header;
27031}
27032
27033.pagedjs_margin-top-right-corner-holder {
27034 width: var(--pagedjs-margin-right);
27035 height: var(--pagedjs-margin-top);
27036 display: flex;
27037 grid-column: right;
27038 grid-row: header;
27039}
27040
27041.pagedjs_margin-top-left-corner {
27042 width: var(--pagedjs-margin-left);
27043}
27044
27045.pagedjs_margin-top-right-corner {
27046 width: var(--pagedjs-margin-right);
27047}
27048
27049.pagedjs_margin-right {
27050 height: calc(var(--pagedjs-pagebox-height) - var(--pagedjs-margin-top) - var(--pagedjs-margin-bottom));
27051 width: var(--pagedjs-margin-right);
27052 right: 0;
27053 grid-column: right;
27054 grid-row: page;
27055 display: grid;
27056 grid-template-rows: repeat(3, 33.3333%);
27057 grid-template-columns: 100%;
27058}
27059
27060.pagedjs_margin-bottom {
27061 width: calc(var(--pagedjs-pagebox-width) - var(--pagedjs-margin-left) - var(--pagedjs-margin-right));
27062 height: var(--pagedjs-margin-bottom);
27063 grid-column: center;
27064 grid-row: footer;
27065 display: grid;
27066 grid-template-columns: repeat(3, 1fr);
27067 grid-template-rows: 100%;
27068}
27069
27070.pagedjs_margin-bottom-left-corner-holder {
27071 width: var(--pagedjs-margin-left);
27072 height: var(--pagedjs-margin-bottom);
27073 display: flex;
27074 grid-column: left;
27075 grid-row: footer;
27076}
27077
27078.pagedjs_margin-bottom-right-corner-holder {
27079 width: var(--pagedjs-margin-right);
27080 height: var(--pagedjs-margin-bottom);
27081 display: flex;
27082 grid-column: right;
27083 grid-row: footer;
27084}
27085
27086.pagedjs_margin-bottom-left-corner {
27087 width: var(--pagedjs-margin-left);
27088}
27089
27090.pagedjs_margin-bottom-right-corner {
27091 width: var(--pagedjs-margin-right);
27092}
27093
27094
27095
27096.pagedjs_margin-left {
27097 height: calc(var(--pagedjs-pagebox-height) - var(--pagedjs-margin-top) - var(--pagedjs-margin-bottom));
27098 width: var(--pagedjs-margin-left);
27099 grid-column: left;
27100 grid-row: page;
27101 display: grid;
27102 grid-template-rows: repeat(3, 33.33333%);
27103 grid-template-columns: 100%;
27104}
27105
27106.pagedjs_pages .pagedjs_pagebox .pagedjs_margin:not(.hasContent) {
27107 visibility: hidden;
27108}
27109
27110.pagedjs_pagebox > .pagedjs_area {
27111 grid-column: center;
27112 grid-row: page;
27113 width: 100%;
27114 height: 100%;
27115 padding: var(--pagedjs-padding-top) var(--pagedjs-padding-right) var(--pagedjs-padding-bottom) var(--pagedjs-padding-left);
27116 border-top: var(--pagedjs-border-top);
27117 border-right: var(--pagedjs-border-right);
27118 border-bottom: var(--pagedjs-border-bottom);
27119 border-left: var(--pagedjs-border-left);
27120}
27121
27122.pagedjs_pagebox > .pagedjs_area > .pagedjs_page_content {
27123 width: 100%;
27124 height: calc(100% - var(--pagedjs-footnotes-height));
27125 position: relative;
27126 column-fill: auto;
27127}
27128
27129.pagedjs_pagebox > .pagedjs_area > .pagedjs_page_content > div {
27130 height: inherit;
27131}
27132
27133.pagedjs_pagebox > .pagedjs_area > .pagedjs_footnote_area {
27134 position: relative;
27135 overflow: hidden;
27136 height: var(--pagedjs-footnotes-height);
27137 display: flex;
27138 justify-content: flex-end;
27139 flex-flow: column;
27140}
27141
27142.pagedjs_pagebox > .pagedjs_area > .pagedjs_footnote_area > .pagedjs_footnote_content {
27143 overflow: hidden;
27144}
27145
27146.pagedjs_pagebox > .pagedjs_area > .pagedjs_footnote_area > .pagedjs_footnote_inner_content {
27147 overflow: hidden;
27148}
27149
27150.pagedjs_area [data-footnote-call] {
27151 all: unset;
27152 counter-increment: footnote;
27153}
27154
27155.pagedjs_area [data-split-from] {
27156 counter-increment: unset;
27157 counter-reset: unset;
27158}
27159
27160[data-footnote-call]::after {
27161 vertical-align: super;
27162 font-size: 65%;
27163 line-height: normal;
27164 content: counter(footnote);
27165}
27166
27167@supports ( font-variant-position: super ) {
27168 [data-footnote-call]::after {
27169 vertical-align: baseline;
27170 font-size: 100%;
27171 line-height: inherit;
27172 font-variant-position: super;
27173 }
27174}
27175
27176.pagedjs_footnote_empty {
27177 display: none;
27178}
27179
27180.pagedjs_area [data-split-from] {
27181 counter-increment: unset;
27182 counter-reset: unset;
27183}
27184
27185[data-footnote-marker] {
27186 text-indent: 0;
27187 display: list-item;
27188 list-style-position: inside;
27189}
27190
27191[data-footnote-marker][data-split-from] {
27192 list-style: none;
27193}
27194
27195[data-footnote-marker]:not([data-split-from]) {
27196 counter-increment: footnote-marker;
27197}
27198
27199[data-footnote-marker]::marker {
27200 content: counter(footnote-marker) ". ";
27201}
27202
27203[data-footnote-marker][data-split-from]::marker {
27204 content: unset;
27205}
27206
27207.pagedjs_area .pagedjs_footnote_inner_content [data-note-display="inline"] {
27208 display: inline;
27209}
27210
27211.pagedjs_page {
27212 counter-increment: page var(--pagedjs-page-counter-increment);
27213 width: var(--pagedjs-width);
27214 height: var(--pagedjs-height);
27215}
27216
27217.pagedjs_page.pagedjs_right_page {
27218 width: var(--pagedjs-width-right);
27219 height: var(--pagedjs-height-right);
27220}
27221
27222.pagedjs_page.pagedjs_left_page {
27223 width: var(--pagedjs-width-left);
27224 height: var(--pagedjs-height-left);
27225}
27226
27227.pagedjs_pages {
27228 counter-reset: pages var(--pagedjs-page-count) footnote var(--pagedjs-footnotes-count) footnote-marker var(--pagedjs-footnotes-count);
27229}
27230
27231.pagedjs_pagebox .pagedjs_margin-top-left-corner,
27232.pagedjs_pagebox .pagedjs_margin-top-right-corner,
27233.pagedjs_pagebox .pagedjs_margin-bottom-left-corner,
27234.pagedjs_pagebox .pagedjs_margin-bottom-right-corner,
27235.pagedjs_pagebox .pagedjs_margin-top-left,
27236.pagedjs_pagebox .pagedjs_margin-top-right,
27237.pagedjs_pagebox .pagedjs_margin-bottom-left,
27238.pagedjs_pagebox .pagedjs_margin-bottom-right,
27239.pagedjs_pagebox .pagedjs_margin-top-center,
27240.pagedjs_pagebox .pagedjs_margin-bottom-center,
27241.pagedjs_pagebox .pagedjs_margin-top-center,
27242.pagedjs_pagebox .pagedjs_margin-bottom-center,
27243.pagedjs_margin-right-middle,
27244.pagedjs_margin-left-middle {
27245 display: flex;
27246 align-items: center;
27247}
27248
27249.pagedjs_margin-right-top,
27250.pagedjs_margin-left-top {
27251 display: flex;
27252 align-items: flex-top;
27253}
27254
27255
27256.pagedjs_margin-right-bottom,
27257.pagedjs_margin-left-bottom {
27258 display: flex;
27259 align-items: flex-end;
27260}
27261
27262
27263
27264/*
27265.pagedjs_pagebox .pagedjs_margin-top-center,
27266.pagedjs_pagebox .pagedjs_margin-bottom-center {
27267 height: 100%;
27268 display: none;
27269 align-items: center;
27270 flex: 1 0 33%;
27271 margin: 0 auto;
27272}
27273
27274.pagedjs_pagebox .pagedjs_margin-top-left-corner,
27275.pagedjs_pagebox .pagedjs_margin-top-right-corner,
27276.pagedjs_pagebox .pagedjs_margin-bottom-right-corner,
27277.pagedjs_pagebox .pagedjs_margin-bottom-left-corner {
27278 display: none;
27279 align-items: center;
27280}
27281
27282.pagedjs_pagebox .pagedjs_margin-left-top,
27283.pagedjs_pagebox .pagedjs_margin-right-top {
27284 display: none;
27285 align-items: flex-start;
27286}
27287
27288.pagedjs_pagebox .pagedjs_margin-right-middle,
27289.pagedjs_pagebox .pagedjs_margin-left-middle {
27290 display: none;
27291 align-items: center;
27292}
27293
27294.pagedjs_pagebox .pagedjs_margin-left-bottom,
27295.pagedjs_pagebox .pagedjs_margin-right-bottom {
27296 display: none;
27297 align-items: flex-end;
27298}
27299*/
27300
27301.pagedjs_pagebox .pagedjs_margin-top-left,
27302.pagedjs_pagebox .pagedjs_margin-top-right-corner,
27303.pagedjs_pagebox .pagedjs_margin-bottom-left,
27304.pagedjs_pagebox .pagedjs_margin-bottom-right-corner { text-align: left; }
27305
27306.pagedjs_pagebox .pagedjs_margin-top-left-corner,
27307.pagedjs_pagebox .pagedjs_margin-top-right,
27308.pagedjs_pagebox .pagedjs_margin-bottom-left-corner,
27309.pagedjs_pagebox .pagedjs_margin-bottom-right { text-align: right; }
27310
27311.pagedjs_pagebox .pagedjs_margin-top-center,
27312.pagedjs_pagebox .pagedjs_margin-bottom-center,
27313.pagedjs_pagebox .pagedjs_margin-left-top,
27314.pagedjs_pagebox .pagedjs_margin-left-middle,
27315.pagedjs_pagebox .pagedjs_margin-left-bottom,
27316.pagedjs_pagebox .pagedjs_margin-right-top,
27317.pagedjs_pagebox .pagedjs_margin-right-middle,
27318.pagedjs_pagebox .pagedjs_margin-right-bottom { text-align: center; }
27319
27320.pagedjs_pages .pagedjs_margin .pagedjs_margin-content {
27321 width: 100%;
27322}
27323
27324.pagedjs_pages .pagedjs_margin-left .pagedjs_margin-content::after,
27325.pagedjs_pages .pagedjs_margin-top .pagedjs_margin-content::after,
27326.pagedjs_pages .pagedjs_margin-right .pagedjs_margin-content::after,
27327.pagedjs_pages .pagedjs_margin-bottom .pagedjs_margin-content::after {
27328 display: block;
27329}
27330
27331.pagedjs_pages > .pagedjs_page > .pagedjs_sheet > .pagedjs_pagebox > .pagedjs_area > div [data-split-to] {
27332 margin-bottom: unset;
27333 padding-bottom: unset;
27334}
27335
27336.pagedjs_pages > .pagedjs_page > .pagedjs_sheet > .pagedjs_pagebox > .pagedjs_area > div [data-split-from] {
27337 text-indent: unset;
27338 margin-top: unset;
27339 padding-top: unset;
27340 initial-letter: unset;
27341}
27342
27343.pagedjs_pages > .pagedjs_page > .pagedjs_sheet > .pagedjs_pagebox > .pagedjs_area > div [data-split-from] > *::first-letter,
27344.pagedjs_pages > .pagedjs_page > .pagedjs_sheet > .pagedjs_pagebox > .pagedjs_area > div [data-split-from]::first-letter {
27345 color: unset;
27346 font-size: unset;
27347 font-weight: unset;
27348 font-family: unset;
27349 color: unset;
27350 line-height: unset;
27351 float: unset;
27352 padding: unset;
27353 margin: unset;
27354}
27355
27356.pagedjs_pages > .pagedjs_page > .pagedjs_sheet > .pagedjs_pagebox > .pagedjs_area > div [data-split-to]:not([data-footnote-call]):after,
27357.pagedjs_pages > .pagedjs_page > .pagedjs_sheet > .pagedjs_pagebox > .pagedjs_area > div [data-split-to]:not([data-footnote-call])::after {
27358 content: unset;
27359}
27360
27361.pagedjs_pages > .pagedjs_page > .pagedjs_sheet > .pagedjs_pagebox > .pagedjs_area > div [data-split-from]:not([data-footnote-call]):before,
27362.pagedjs_pages > .pagedjs_page > .pagedjs_sheet > .pagedjs_pagebox > .pagedjs_area > div [data-split-from]:not([data-footnote-call])::before {
27363 content: unset;
27364}
27365
27366.pagedjs_pages > .pagedjs_page > .pagedjs_sheet > .pagedjs_pagebox > .pagedjs_area > div li[data-split-from]:first-of-type {
27367 list-style: none;
27368}
27369
27370/*
27371[data-page]:not([data-split-from]),
27372[data-break-before="page"]:not([data-split-from]),
27373[data-break-before="always"]:not([data-split-from]),
27374[data-break-before="left"]:not([data-split-from]),
27375[data-break-before="right"]:not([data-split-from]),
27376[data-break-before="recto"]:not([data-split-from]),
27377[data-break-before="verso"]:not([data-split-from])
27378{
27379 break-before: column;
27380}
27381
27382[data-page]:not([data-split-to]),
27383[data-break-after="page"]:not([data-split-to]),
27384[data-break-after="always"]:not([data-split-to]),
27385[data-break-after="left"]:not([data-split-to]),
27386[data-break-after="right"]:not([data-split-to]),
27387[data-break-after="recto"]:not([data-split-to]),
27388[data-break-after="verso"]:not([data-split-to])
27389{
27390 break-after: column;
27391}
27392*/
27393
27394.pagedjs_clear-after::after {
27395 content: none !important;
27396}
27397
27398[data-align-last-split-element='justify'] {
27399 text-align-last: justify;
27400}
27401
27402
27403@media print {
27404 html {
27405 width: 100%;
27406 height: 100%;
27407 -webkit-print-color-adjust: exact;
27408 print-color-adjust: exact;
27409 }
27410 body {
27411 margin: 0;
27412 padding: 0;
27413 width: 100% !important;
27414 height: 100% !important;
27415 min-width: 100%;
27416 max-width: 100%;
27417 min-height: 100%;
27418 max-height: 100%;
27419 }
27420 .pagedjs_pages {
27421 width: auto;
27422 display: block !important;
27423 transform: none !important;
27424 height: 100% !important;
27425 min-height: 100%;
27426 max-height: 100%;
27427 overflow: visible;
27428 }
27429 .pagedjs_page {
27430 margin: 0;
27431 padding: 0;
27432 max-height: 100%;
27433 min-height: 100%;
27434 height: 100% !important;
27435 page-break-after: always;
27436 break-after: page;
27437 }
27438 .pagedjs_sheet {
27439 margin: 0;
27440 padding: 0;
27441 max-height: 100%;
27442 min-height: 100%;
27443 height: 100% !important;
27444 }
27445}
27446`;
27447
27448 async function request(url, options={}) {
27449 return new Promise(function(resolve, reject) {
27450 let request = new XMLHttpRequest();
27451
27452 request.open(options.method || "get", url, true);
27453
27454 for (let i in options.headers) {
27455 request.setRequestHeader(i, options.headers[i]);
27456 }
27457
27458 request.withCredentials = options.credentials === "include";
27459
27460 request.onload = () => {
27461 // Chrome returns a status code of 0 for local files
27462 const status = request.status === 0 && url.startsWith("file://") ? 200 : request.status;
27463 resolve(new Response(request.responseText, {status}));
27464 };
27465
27466 request.onerror = reject;
27467
27468 request.send(options.body || null);
27469 });
27470 }
27471
27472 class Polisher {
27473 constructor(setup) {
27474 this.sheets = [];
27475 this.inserted = [];
27476
27477 this.hooks = {};
27478 this.hooks.onUrl = new Hook(this);
27479 this.hooks.onAtPage = new Hook(this);
27480 this.hooks.onAtMedia = new Hook(this);
27481 this.hooks.onRule = new Hook(this);
27482 this.hooks.onDeclaration = new Hook(this);
27483 this.hooks.onContent = new Hook(this);
27484 this.hooks.onSelector = new Hook(this);
27485 this.hooks.onPseudoSelector = new Hook(this);
27486
27487 this.hooks.onImport = new Hook(this);
27488
27489 this.hooks.beforeTreeParse = new Hook(this);
27490 this.hooks.beforeTreeWalk = new Hook(this);
27491 this.hooks.afterTreeWalk = new Hook(this);
27492
27493 if (setup !== false) {
27494 this.setup();
27495 }
27496 }
27497
27498 setup() {
27499 this.base = this.insert(baseStyles);
27500 this.styleEl = document.createElement("style");
27501 document.head.appendChild(this.styleEl);
27502 this.styleSheet = this.styleEl.sheet;
27503 return this.styleSheet;
27504 }
27505
27506 async add() {
27507 let fetched = [];
27508 let urls = [];
27509
27510 for (var i = 0; i < arguments.length; i++) {
27511 let f;
27512
27513 if (typeof arguments[i] === "object") {
27514 for (let url in arguments[i]) {
27515 let obj = arguments[i];
27516 f = new Promise(function(resolve, reject) {
27517 urls.push(url);
27518 resolve(obj[url]);
27519 });
27520 }
27521 } else {
27522 urls.push(arguments[i]);
27523 f = request(arguments[i]).then((response) => {
27524 return response.text();
27525 });
27526 }
27527
27528
27529 fetched.push(f);
27530 }
27531
27532 return await Promise.all(fetched)
27533 .then(async (originals) => {
27534 let text = "";
27535 for (let index = 0; index < originals.length; index++) {
27536 text = await this.convertViaSheet(originals[index], urls[index]);
27537 this.insert(text);
27538 }
27539 return text;
27540 });
27541 }
27542
27543 async convertViaSheet(cssStr, href) {
27544 let sheet = new Sheet(href, this.hooks);
27545 await sheet.parse(cssStr);
27546
27547 // Insert the imported sheets first
27548 for (let url of sheet.imported) {
27549 let str = await request(url).then((response) => {
27550 return response.text();
27551 });
27552 let text = await this.convertViaSheet(str, url);
27553 this.insert(text);
27554 }
27555
27556 this.sheets.push(sheet);
27557
27558 if (typeof sheet.width !== "undefined") {
27559 this.width = sheet.width;
27560 }
27561 if (typeof sheet.height !== "undefined") {
27562 this.height = sheet.height;
27563 }
27564 if (typeof sheet.orientation !== "undefined") {
27565 this.orientation = sheet.orientation;
27566 }
27567 return sheet.toString();
27568 }
27569
27570 insert(text){
27571 let head = document.querySelector("head");
27572 let style = document.createElement("style");
27573 style.setAttribute("data-pagedjs-inserted-styles", "true");
27574
27575 style.appendChild(document.createTextNode(text));
27576
27577 head.appendChild(style);
27578
27579 this.inserted.push(style);
27580 return style;
27581 }
27582
27583 destroy() {
27584 this.styleEl.remove();
27585 this.inserted.forEach((s) => {
27586 s.remove();
27587 });
27588 this.sheets = [];
27589 }
27590 }
27591
27592 class Handler {
27593 constructor(chunker, polisher, caller) {
27594 let hooks = Object.assign({}, chunker && chunker.hooks, polisher && polisher.hooks, caller && caller.hooks);
27595 this.chunker = chunker;
27596 this.polisher = polisher;
27597 this.caller = caller;
27598
27599 for (let name in hooks) {
27600 if (name in this) {
27601 let hook = hooks[name];
27602 hook.register(this[name].bind(this));
27603 }
27604 }
27605 }
27606 }
27607
27608 EventEmitter(Handler.prototype);
27609
27610 // https://www.w3.org/TR/css3-page/#page-size-prop
27611
27612 var pageSizes = {
27613 "A0": {
27614 width: {
27615 value: 841,
27616 unit: "mm"
27617 },
27618 height: {
27619 value: 1189,
27620 unit: "mm"
27621 }
27622 },
27623 "A1": {
27624 width: {
27625 value: 594,
27626 unit: "mm"
27627 },
27628 height: {
27629 value: 841,
27630 unit: "mm"
27631 }
27632 },
27633 "A2": {
27634 width: {
27635 value: 420,
27636 unit: "mm"
27637 },
27638 height: {
27639 value: 594,
27640 unit: "mm"
27641 }
27642 },
27643 "A3": {
27644 width: {
27645 value: 297,
27646 unit: "mm"
27647 },
27648 height: {
27649 value: 420,
27650 unit: "mm"
27651 }
27652 },
27653 "A4": {
27654 width: {
27655 value: 210,
27656 unit: "mm"
27657 },
27658 height: {
27659 value: 297,
27660 unit: "mm"
27661 }
27662 },
27663 "A5": {
27664 width: {
27665 value: 148,
27666 unit: "mm"
27667 },
27668 height: {
27669 value: 210,
27670 unit: "mm"
27671 }
27672 },
27673 "A6": {
27674 width: {
27675 value: 105,
27676 unit: "mm"
27677 },
27678 height: {
27679 value: 148,
27680 unit: "mm"
27681 }
27682 },
27683 "A7": {
27684 width: {
27685 value: 74,
27686 unit: "mm"
27687 },
27688 height: {
27689 value: 105,
27690 unit: "mm"
27691 }
27692 },
27693 "A8": {
27694 width: {
27695 value: 52,
27696 unit: "mm"
27697 },
27698 height: {
27699 value: 74,
27700 unit: "mm"
27701 }
27702 },
27703 "A9": {
27704 width: {
27705 value: 37,
27706 unit: "mm"
27707 },
27708 height: {
27709 value: 52,
27710 unit: "mm"
27711 }
27712 },
27713 "A10": {
27714 width: {
27715 value: 26,
27716 unit: "mm"
27717 },
27718 height: {
27719 value: 37,
27720 unit: "mm"
27721 }
27722 },
27723 "B4": {
27724 width: {
27725 value: 250,
27726 unit: "mm"
27727 },
27728 height: {
27729 value: 353,
27730 unit: "mm"
27731 }
27732 },
27733 "B5": {
27734 width: {
27735 value: 176,
27736 unit: "mm"
27737 },
27738 height: {
27739 value: 250,
27740 unit: "mm"
27741 }
27742 },
27743 "letter": {
27744 width: {
27745 value: 8.5,
27746 unit: "in"
27747 },
27748 height: {
27749 value: 11,
27750 unit: "in"
27751 }
27752 },
27753 "legal": {
27754 width: {
27755 value: 8.5,
27756 unit: "in"
27757 },
27758 height: {
27759 value: 14,
27760 unit: "in"
27761 }
27762 },
27763 "ledger": {
27764 width: {
27765 value: 11,
27766 unit: "in"
27767 },
27768 height: {
27769 value: 17,
27770 unit: "in"
27771 }
27772 }
27773 };
27774
27775 class AtPage extends Handler {
27776 constructor(chunker, polisher, caller) {
27777 super(chunker, polisher, caller);
27778
27779 this.pages = {};
27780
27781 this.width = undefined;
27782 this.height = undefined;
27783 this.orientation = undefined;
27784 this.marginalia = {};
27785 }
27786
27787 pageModel(selector) {
27788 return {
27789 selector: selector,
27790 name: undefined,
27791 psuedo: undefined,
27792 nth: undefined,
27793 marginalia: {},
27794 width: undefined,
27795 height: undefined,
27796 orientation: undefined,
27797 margin: {
27798 top: {},
27799 right: {},
27800 left: {},
27801 bottom: {}
27802 },
27803 padding: {
27804 top: {},
27805 right: {},
27806 left: {},
27807 bottom: {}
27808 },
27809 border: {
27810 top: {},
27811 right: {},
27812 left: {},
27813 bottom: {}
27814 },
27815 backgroundOrigin: undefined,
27816 block: {},
27817 marks: undefined,
27818 notes: undefined,
27819 added: false
27820 };
27821 }
27822
27823 // Find and Remove @page rules
27824 onAtPage(node, item, list) {
27825 let page, marginalia;
27826 let selector = "";
27827 let named, psuedo, nth;
27828 let needsMerge = false;
27829
27830 if (node.prelude) {
27831 named = this.getTypeSelector(node);
27832 psuedo = this.getPsuedoSelector(node);
27833 nth = this.getNthSelector(node);
27834 selector = csstree.generate(node.prelude);
27835 } else {
27836 selector = "*";
27837 }
27838
27839 if (selector in this.pages) {
27840 // this.pages[selector] = Object.assign(this.pages[selector], page);
27841 // console.log("after", selector, this.pages[selector]);
27842
27843 // this.pages[selector].added = false;
27844 page = this.pages[selector];
27845 marginalia = this.replaceMarginalia(node);
27846 needsMerge = true;
27847 // Mark page for getting classes added again
27848 page.added = false;
27849 } else {
27850 page = this.pageModel(selector);
27851 marginalia = this.replaceMarginalia(node);
27852 this.pages[selector] = page;
27853 }
27854
27855 page.name = named;
27856 page.psuedo = psuedo;
27857 page.nth = nth;
27858
27859 if (needsMerge) {
27860 page.marginalia = Object.assign(page.marginalia, marginalia);
27861 } else {
27862 page.marginalia = marginalia;
27863 }
27864
27865 let notes = this.replaceNotes(node);
27866 page.notes = notes;
27867
27868 let declarations = this.replaceDeclarations(node);
27869
27870 if (declarations.size) {
27871 page.size = declarations.size;
27872 page.width = declarations.size.width;
27873 page.height = declarations.size.height;
27874 page.orientation = declarations.size.orientation;
27875 page.format = declarations.size.format;
27876 }
27877
27878 if (declarations.bleed && declarations.bleed[0] != "auto") {
27879 switch (declarations.bleed.length) {
27880 case 4: // top right bottom left
27881 page.bleed = {
27882 top: declarations.bleed[0],
27883 right: declarations.bleed[1],
27884 bottom: declarations.bleed[2],
27885 left: declarations.bleed[3]
27886 };
27887 break;
27888 case 3: // top right bottom right
27889 page.bleed = {
27890 top: declarations.bleed[0],
27891 right: declarations.bleed[1],
27892 bottom: declarations.bleed[2],
27893 left: declarations.bleed[1]
27894 };
27895 break;
27896 case 2: // top right top right
27897 page.bleed = {
27898 top: declarations.bleed[0],
27899 right: declarations.bleed[1],
27900 bottom: declarations.bleed[0],
27901 left: declarations.bleed[1]
27902 };
27903 break;
27904 default:
27905 page.bleed = {
27906 top: declarations.bleed[0],
27907 right: declarations.bleed[0],
27908 bottom: declarations.bleed[0],
27909 left: declarations.bleed[0]
27910 };
27911 }
27912 }
27913
27914 if (declarations.marks) {
27915 if (!declarations.bleed || declarations.bleed && declarations.bleed[0] === "auto") {
27916 // Spec say 6pt, but needs more space for marks
27917 page.bleed = {
27918 top: { value: 6, unit: "mm" },
27919 right: { value: 6, unit: "mm" },
27920 bottom: { value: 6, unit: "mm" },
27921 left: { value: 6, unit: "mm" }
27922 };
27923 }
27924
27925 page.marks = declarations.marks;
27926 }
27927
27928 if (declarations.margin) {
27929 page.margin = declarations.margin;
27930 }
27931 if (declarations.padding) {
27932 page.padding = declarations.padding;
27933 }
27934
27935 if (declarations.border) {
27936 page.border = declarations.border;
27937 }
27938
27939 if (declarations.marks) {
27940 page.marks = declarations.marks;
27941 }
27942
27943 if (needsMerge) {
27944 page.block.children.appendList(node.block.children);
27945 } else {
27946 page.block = node.block;
27947 }
27948
27949 // Remove the rule
27950 list.remove(item);
27951 }
27952
27953 /* Handled in breaks */
27954 /*
27955 afterParsed(parsed) {
27956 for (let b in this.named) {
27957 // Find elements
27958 let elements = parsed.querySelectorAll(b);
27959 // Add break data
27960 for (var i = 0; i < elements.length; i++) {
27961 elements[i].setAttribute("data-page", this.named[b]);
27962 }
27963 }
27964 }
27965 */
27966
27967 afterTreeWalk(ast, sheet) {
27968 let dirtyPage = "*" in this.pages && this.pages["*"].added === false;
27969
27970 this.addPageClasses(this.pages, ast, sheet);
27971
27972 if (dirtyPage) {
27973 let width = this.pages["*"].width;
27974 let height = this.pages["*"].height;
27975 let format = this.pages["*"].format;
27976 let orientation = this.pages["*"].orientation;
27977 let bleed = this.pages["*"].bleed;
27978 let marks = this.pages["*"].marks;
27979 let bleedverso = undefined;
27980 let bleedrecto = undefined;
27981
27982 if (":left" in this.pages) {
27983 bleedverso = this.pages[":left"].bleed;
27984 }
27985
27986 if (":right" in this.pages) {
27987 bleedrecto = this.pages[":right"].bleed;
27988 }
27989
27990 if ((width && height) &&
27991 (this.width !== width || this.height !== height)) {
27992 this.width = width;
27993 this.height = height;
27994 this.format = format;
27995 this.orientation = orientation;
27996
27997 this.addRootVars(ast, width, height, orientation, bleed, bleedrecto, bleedverso, marks);
27998 this.addRootPage(ast, this.pages["*"].size, bleed, bleedrecto, bleedverso);
27999
28000 this.emit("size", { width, height, orientation, format, bleed });
28001 this.emit("atpages", this.pages);
28002 }
28003
28004 }
28005 }
28006
28007 getTypeSelector(ast) {
28008 // Find page name
28009 let name;
28010
28011 csstree.walk(ast, {
28012 visit: "TypeSelector",
28013 enter: (node, item, list) => {
28014 name = node.name;
28015 }
28016 });
28017
28018 return name;
28019 }
28020
28021 getPsuedoSelector(ast) {
28022 // Find if it has :left & :right & :black & :first
28023 let name;
28024 csstree.walk(ast, {
28025 visit: "PseudoClassSelector",
28026 enter: (node, item, list) => {
28027 if (node.name !== "nth") {
28028 name = node.name;
28029 }
28030 }
28031 });
28032
28033 return name;
28034 }
28035
28036 getNthSelector(ast) {
28037 // Find if it has :nth
28038 let nth;
28039 csstree.walk(ast, {
28040 visit: "PseudoClassSelector",
28041 enter: (node, item, list) => {
28042 if (node.name === "nth" && node.children) {
28043 let raw = node.children.first();
28044 nth = raw.value;
28045 }
28046 }
28047 });
28048
28049 return nth;
28050 }
28051
28052 replaceMarginalia(ast) {
28053 let parsed = {};
28054 const MARGINS = [
28055 "top-left-corner", "top-left", "top", "top-center", "top-right", "top-right-corner",
28056 "bottom-left-corner", "bottom-left", "bottom", "bottom-center", "bottom-right", "bottom-right-corner",
28057 "left-top", "left-middle", "left", "left-bottom", "top-right-corner",
28058 "right-top", "right-middle", "right", "right-bottom", "right-right-corner"
28059 ];
28060 csstree.walk(ast.block, {
28061 visit: "Atrule",
28062 enter: (node, item, list) => {
28063 let name = node.name;
28064 if (MARGINS.includes(name)) {
28065 if (name === "top") {
28066 name = "top-center";
28067 }
28068 if (name === "right") {
28069 name = "right-middle";
28070 }
28071 if (name === "left") {
28072 name = "left-middle";
28073 }
28074 if (name === "bottom") {
28075 name = "bottom-center";
28076 }
28077 parsed[name] = node.block;
28078 list.remove(item);
28079 }
28080 }
28081 });
28082
28083 return parsed;
28084 }
28085
28086 replaceNotes(ast) {
28087 let parsed = {};
28088
28089 csstree.walk(ast.block, {
28090 visit: "Atrule",
28091 enter: (node, item, list) => {
28092 let name = node.name;
28093 if (name === "footnote") {
28094 parsed[name] = node.block;
28095 list.remove(item);
28096 }
28097 }
28098 });
28099
28100 return parsed;
28101 }
28102
28103 replaceDeclarations(ast) {
28104 let parsed = {};
28105
28106 csstree.walk(ast.block, {
28107 visit: "Declaration",
28108 enter: (declaration, dItem, dList) => {
28109 let prop = csstree.property(declaration.property).name;
28110 // let value = declaration.value;
28111
28112 if (prop === "marks") {
28113 parsed.marks = [];
28114 csstree.walk(declaration, {
28115 visit: "Identifier",
28116 enter: (ident) => {
28117 parsed.marks.push(ident.name);
28118 }
28119 });
28120 dList.remove(dItem);
28121 } else if (prop === "margin") {
28122 parsed.margin = this.getMargins(declaration);
28123 dList.remove(dItem);
28124
28125 } else if (prop.indexOf("margin-") === 0) {
28126 let m = prop.substring("margin-".length);
28127 if (!parsed.margin) {
28128 parsed.margin = {
28129 top: {},
28130 right: {},
28131 left: {},
28132 bottom: {}
28133 };
28134 }
28135 parsed.margin[m] = declaration.value.children.first();
28136 dList.remove(dItem);
28137
28138 } else if (prop === "padding") {
28139 parsed.padding = this.getPaddings(declaration.value);
28140 dList.remove(dItem);
28141
28142 } else if (prop.indexOf("padding-") === 0) {
28143 let p = prop.substring("padding-".length);
28144 if (!parsed.padding) {
28145 parsed.padding = {
28146 top: {},
28147 right: {},
28148 left: {},
28149 bottom: {}
28150 };
28151 }
28152 parsed.padding[p] = declaration.value.children.first();
28153 dList.remove(dItem);
28154 }
28155
28156 else if (prop === "border") {
28157 if (!parsed.border) {
28158 parsed.border = {
28159 top: {},
28160 right: {},
28161 left: {},
28162 bottom: {}
28163 };
28164 }
28165 parsed.border.top = csstree.generate(declaration.value);
28166 parsed.border.right = csstree.generate(declaration.value);
28167 parsed.border.left = csstree.generate(declaration.value);
28168 parsed.border.bottom = csstree.generate(declaration.value);
28169
28170 dList.remove(dItem);
28171
28172 }
28173
28174 else if (prop.indexOf("border-") === 0) {
28175 if (!parsed.border) {
28176 parsed.border = {
28177 top: {},
28178 right: {},
28179 left: {},
28180 bottom: {}
28181 };
28182 }
28183 let p = prop.substring("border-".length);
28184
28185 parsed.border[p] = csstree.generate(declaration.value);
28186 dList.remove(dItem);
28187
28188 }
28189
28190 else if (prop === "size") {
28191 parsed.size = this.getSize(declaration);
28192 dList.remove(dItem);
28193 } else if (prop === "bleed") {
28194 parsed.bleed = [];
28195
28196 csstree.walk(declaration, {
28197 enter: (subNode) => {
28198 switch (subNode.type) {
28199 case "String": // bleed: "auto"
28200 if (subNode.value.indexOf("auto") > -1) {
28201 parsed.bleed.push("auto");
28202 }
28203 break;
28204 case "Dimension": // bleed: 1in 2in, bleed: 20px ect.
28205 parsed.bleed.push({
28206 value: subNode.value,
28207 unit: subNode.unit
28208 });
28209 break;
28210 case "Number":
28211 parsed.bleed.push({
28212 value: subNode.value,
28213 unit: "px"
28214 });
28215 break;
28216 // ignore
28217 }
28218
28219 }
28220 });
28221
28222 dList.remove(dItem);
28223 }
28224
28225 }
28226 });
28227
28228 return parsed;
28229
28230 }
28231 getSize(declaration) {
28232 let width, height, orientation, format;
28233
28234 // Get size: Xmm Ymm
28235 csstree.walk(declaration, {
28236 visit: "Dimension",
28237 enter: (node, item, list) => {
28238 let { value, unit } = node;
28239 if (typeof width === "undefined") {
28240 width = { value, unit };
28241 } else if (typeof height === "undefined") {
28242 height = { value, unit };
28243 }
28244 }
28245 });
28246
28247 // Get size: "A4"
28248 csstree.walk(declaration, {
28249 visit: "String",
28250 enter: (node, item, list) => {
28251 let name = node.value.replace(/["|']/g, "");
28252 let s = pageSizes[name];
28253 if (s) {
28254 width = s.width;
28255 height = s.height;
28256 }
28257 }
28258 });
28259
28260 // Get Format or Landscape or Portrait
28261 csstree.walk(declaration, {
28262 visit: "Identifier",
28263 enter: (node, item, list) => {
28264 let name = node.name;
28265 if (name === "landscape" || name === "portrait") {
28266 orientation = node.name;
28267 } else if (name !== "auto") {
28268 let s = pageSizes[name];
28269 if (s) {
28270 width = s.width;
28271 height = s.height;
28272 }
28273 format = name;
28274 }
28275 }
28276 });
28277
28278 return {
28279 width,
28280 height,
28281 orientation,
28282 format
28283 };
28284 }
28285
28286 getMargins(declaration) {
28287 let margins = [];
28288 let margin = {
28289 top: {},
28290 right: {},
28291 left: {},
28292 bottom: {}
28293 };
28294
28295 csstree.walk(declaration, {
28296 enter: (node) => {
28297 switch (node.type) {
28298 case "Dimension": // margin: 1in 2in, margin: 20px, etc...
28299 margins.push(node);
28300 break;
28301 case "Number": // margin: 0
28302 margins.push({value: node.value, unit: "px"});
28303 break;
28304 // ignore
28305 }
28306 }
28307 });
28308
28309 if (margins.length === 1) {
28310 for (let m in margin) {
28311 margin[m] = margins[0];
28312 }
28313 } else if (margins.length === 2) {
28314 margin.top = margins[0];
28315 margin.right = margins[1];
28316 margin.bottom = margins[0];
28317 margin.left = margins[1];
28318 } else if (margins.length === 3) {
28319 margin.top = margins[0];
28320 margin.right = margins[1];
28321 margin.bottom = margins[2];
28322 margin.left = margins[1];
28323 } else if (margins.length === 4) {
28324 margin.top = margins[0];
28325 margin.right = margins[1];
28326 margin.bottom = margins[2];
28327 margin.left = margins[3];
28328 }
28329
28330 return margin;
28331 }
28332
28333 getPaddings(declaration) {
28334 let paddings = [];
28335 let padding = {
28336 top: {},
28337 right: {},
28338 left: {},
28339 bottom: {}
28340 };
28341
28342 csstree.walk(declaration, {
28343 enter: (node) => {
28344 switch (node.type) {
28345 case "Dimension": // padding: 1in 2in, padding: 20px, etc...
28346 paddings.push(node);
28347 break;
28348 case "Number": // padding: 0
28349 paddings.push({value: node.value, unit: "px"});
28350 break;
28351 // ignore
28352 }
28353 }
28354 });
28355 if (paddings.length === 1) {
28356 for (let p in padding) {
28357 padding[p] = paddings[0];
28358 }
28359 } else if (paddings.length === 2) {
28360
28361 padding.top = paddings[0];
28362 padding.right = paddings[1];
28363 padding.bottom = paddings[0];
28364 padding.left = paddings[1];
28365 } else if (paddings.length === 3) {
28366
28367 padding.top = paddings[0];
28368 padding.right = paddings[1];
28369 padding.bottom = paddings[2];
28370 padding.left = paddings[1];
28371 } else if (paddings.length === 4) {
28372
28373 padding.top = paddings[0];
28374 padding.right = paddings[1];
28375 padding.bottom = paddings[2];
28376 padding.left = paddings[3];
28377 }
28378 return padding;
28379 }
28380
28381 // get values for the border on the @page to pass them to the element with the .pagedjs_area class
28382 getBorders(declaration) {
28383 let border = {
28384 top: {},
28385 right: {},
28386 left: {},
28387 bottom: {}
28388 };
28389
28390 if (declaration.prop == "border") {
28391 border.top = csstree.generate(declaration.value);
28392 border.right = csstree.generate(declaration.value);
28393 border.bottom = csstree.generate(declaration.value);
28394 border.left = csstree.generate(declaration.value);
28395
28396 }
28397 else if (declaration.prop == "border-top") {
28398 border.top = csstree.generate(declaration.value);
28399 }
28400 else if (declaration.prop == "border-right") {
28401 border.right = csstree.generate(declaration.value);
28402
28403 }
28404 else if (declaration.prop == "border-bottom") {
28405 border.bottom = csstree.generate(declaration.value);
28406
28407 }
28408 else if (declaration.prop == "border-left") {
28409 border.left = csstree.generate(declaration.value);
28410 }
28411
28412 return border;
28413 }
28414
28415
28416 addPageClasses(pages, ast, sheet) {
28417 // First add * page
28418 if ("*" in pages && pages["*"].added === false) {
28419 let p = this.createPage(pages["*"], ast.children, sheet);
28420 sheet.insertRule(p);
28421 pages["*"].added = true;
28422 }
28423 // Add :left & :right
28424 if (":left" in pages && pages[":left"].added === false) {
28425 let left = this.createPage(pages[":left"], ast.children, sheet);
28426 sheet.insertRule(left);
28427 pages[":left"].added = true;
28428 }
28429 if (":right" in pages && pages[":right"].added === false) {
28430 let right = this.createPage(pages[":right"], ast.children, sheet);
28431 sheet.insertRule(right);
28432 pages[":right"].added = true;
28433 }
28434 // Add :first & :blank
28435 if (":first" in pages && pages[":first"].added === false) {
28436 let first = this.createPage(pages[":first"], ast.children, sheet);
28437 sheet.insertRule(first);
28438 pages[":first"].added = true;
28439 }
28440 if (":blank" in pages && pages[":blank"].added === false) {
28441 let blank = this.createPage(pages[":blank"], ast.children, sheet);
28442 sheet.insertRule(blank);
28443 pages[":blank"].added = true;
28444 }
28445 // Add nth pages
28446 for (let pg in pages) {
28447 if (pages[pg].nth && pages[pg].added === false) {
28448 let nth = this.createPage(pages[pg], ast.children, sheet);
28449 sheet.insertRule(nth);
28450 pages[pg].added = true;
28451 }
28452 }
28453
28454 // Add named pages
28455 for (let pg in pages) {
28456 if (pages[pg].name && pages[pg].added === false) {
28457 let named = this.createPage(pages[pg], ast.children, sheet);
28458 sheet.insertRule(named);
28459 pages[pg].added = true;
28460 }
28461 }
28462
28463 }
28464
28465 createPage(page, ruleList, sheet) {
28466
28467 let selectors = this.selectorsForPage(page);
28468 let children = page.block.children.copy();
28469 let block = {
28470 type: "Block",
28471 loc: 0,
28472 children: children
28473 };
28474
28475
28476 let rule = this.createRule(selectors, block);
28477
28478 this.addMarginVars(page.margin, children, children.first());
28479 this.addPaddingVars(page.padding, children, children.first());
28480 this.addBorderVars(page.border, children, children.first());
28481
28482
28483 if (page.width) {
28484 this.addDimensions(page.width, page.height, page.orientation, children, children.first());
28485 }
28486
28487 if (page.marginalia) {
28488 this.addMarginaliaStyles(page, ruleList, rule, sheet);
28489 this.addMarginaliaContent(page, ruleList, rule, sheet);
28490 }
28491
28492 if(page.notes) {
28493 this.addNotesStyles(page.notes, page, ruleList, rule, sheet);
28494 }
28495
28496 return rule;
28497 }
28498
28499 addMarginVars(margin, list, item) {
28500 // variables for margins
28501 for (let m in margin) {
28502 if (typeof margin[m].value !== "undefined") {
28503 let value = margin[m].value + (margin[m].unit || "");
28504 let mVar = list.createItem({
28505 type: "Declaration",
28506 property: "--pagedjs-margin-" + m,
28507 value: {
28508 type: "Raw",
28509 value: value
28510 }
28511 });
28512 list.append(mVar, item);
28513
28514 }
28515 }
28516 }
28517
28518 addPaddingVars(padding, list, item) {
28519 // variables for padding
28520 for (let p in padding) {
28521
28522 if (typeof padding[p].value !== "undefined") {
28523 let value = padding[p].value + (padding[p].unit || "");
28524 let pVar = list.createItem({
28525 type: "Declaration",
28526 property: "--pagedjs-padding-" + p,
28527 value: {
28528 type: "Raw",
28529 value: value
28530 }
28531 });
28532
28533 list.append(pVar, item);
28534 }
28535
28536 }
28537 }
28538
28539 addBorderVars(border, list, item) {
28540 // variables for borders
28541 for (const name of Object.keys(border)) {
28542 const value = border[name];
28543 // value is an empty object when undefined
28544 if (typeof value === "string") {
28545 const borderItem = list.createItem({
28546 type: "Declaration",
28547 property: "--pagedjs-border-" + name,
28548 value: {
28549 type: "Raw",
28550 value: value
28551 }
28552 });
28553 list.append(borderItem, item);
28554 }
28555 }
28556 }
28557
28558 addDimensions(width, height, orientation, list, item) {
28559 let widthString, heightString;
28560
28561 widthString = CSSValueToString(width);
28562 heightString = CSSValueToString(height);
28563
28564 if (orientation && orientation !== "portrait") {
28565 // reverse for orientation
28566 [widthString, heightString] = [heightString, widthString];
28567 }
28568
28569 // width variable
28570 let wVar = this.createVariable("--pagedjs-pagebox-width", widthString);
28571 list.appendData(wVar);
28572
28573 // height variable
28574 let hVar = this.createVariable("--pagedjs-pagebox-height", heightString);
28575 list.appendData(hVar);
28576
28577 // let w = this.createDimension("width", width);
28578 // let h = this.createDimension("height", height);
28579 // list.appendData(w);
28580 // list.appendData(h);
28581 }
28582
28583 addMarginaliaStyles(page, list, item, sheet) {
28584 for (let loc in page.marginalia) {
28585 let block = csstree.clone(page.marginalia[loc]);
28586 let hasContent = false;
28587
28588 if (block.children.isEmpty()) {
28589 continue;
28590 }
28591
28592 csstree.walk(block, {
28593 visit: "Declaration",
28594 enter: (node, item, list) => {
28595 if (node.property === "content") {
28596 if (node.value.children && node.value.children.first().name === "none") {
28597 hasContent = false;
28598 } else {
28599 hasContent = true;
28600 }
28601 list.remove(item);
28602 }
28603 if (node.property === "vertical-align") {
28604 csstree.walk(node, {
28605 visit: "Identifier",
28606 enter: (identNode, identItem, identlist) => {
28607 let name = identNode.name;
28608 if (name === "top") {
28609 identNode.name = "flex-start";
28610 } else if (name === "middle") {
28611 identNode.name = "center";
28612 } else if (name === "bottom") {
28613 identNode.name = "flex-end";
28614 }
28615 }
28616 });
28617 node.property = "align-items";
28618 }
28619
28620 if (node.property === "width" &&
28621 (loc === "top-left" ||
28622 loc === "top-center" ||
28623 loc === "top-right" ||
28624 loc === "bottom-left" ||
28625 loc === "bottom-center" ||
28626 loc === "bottom-right")) {
28627 let c = csstree.clone(node);
28628 c.property = "max-width";
28629 list.appendData(c);
28630 }
28631
28632 if (node.property === "height" &&
28633 (loc === "left-top" ||
28634 loc === "left-middle" ||
28635 loc === "left-bottom" ||
28636 loc === "right-top" ||
28637 loc === "right-middle" ||
28638 loc === "right-bottom")) {
28639 let c = csstree.clone(node);
28640 c.property = "max-height";
28641 list.appendData(c);
28642 }
28643 }
28644 });
28645
28646 let marginSelectors = this.selectorsForPageMargin(page, loc);
28647 let marginRule = this.createRule(marginSelectors, block);
28648
28649 list.appendData(marginRule);
28650
28651 let sel = csstree.generate({
28652 type: "Selector",
28653 children: marginSelectors
28654 });
28655
28656 this.marginalia[sel] = {
28657 page: page,
28658 selector: sel,
28659 block: page.marginalia[loc],
28660 hasContent: hasContent
28661 };
28662
28663 }
28664 }
28665
28666 addMarginaliaContent(page, list, item, sheet) {
28667 let displayNone;
28668 // Just content
28669 for (let loc in page.marginalia) {
28670 let content = csstree.clone(page.marginalia[loc]);
28671 csstree.walk(content, {
28672 visit: "Declaration",
28673 enter: (node, item, list) => {
28674 if (node.property !== "content") {
28675 list.remove(item);
28676 }
28677
28678 if (node.value.children && node.value.children.first().name === "none") {
28679 displayNone = true;
28680 }
28681 }
28682 });
28683
28684 if (content.children.isEmpty()) {
28685 continue;
28686 }
28687
28688 let displaySelectors = this.selectorsForPageMargin(page, loc);
28689 let displayDeclaration;
28690
28691 displaySelectors.insertData({
28692 type: "Combinator",
28693 name: ">"
28694 });
28695
28696 displaySelectors.insertData({
28697 type: "ClassSelector",
28698 name: "pagedjs_margin-content"
28699 });
28700
28701 displaySelectors.insertData({
28702 type: "Combinator",
28703 name: ">"
28704 });
28705
28706 displaySelectors.insertData({
28707 type: "TypeSelector",
28708 name: "*"
28709 });
28710
28711 if (displayNone) {
28712 displayDeclaration = this.createDeclaration("display", "none");
28713 } else {
28714 displayDeclaration = this.createDeclaration("display", "block");
28715 }
28716
28717 let displayRule = this.createRule(displaySelectors, [displayDeclaration]);
28718 sheet.insertRule(displayRule);
28719
28720 // insert content rule
28721 let contentSelectors = this.selectorsForPageMargin(page, loc);
28722
28723 contentSelectors.insertData({
28724 type: "Combinator",
28725 name: ">"
28726 });
28727
28728 contentSelectors.insertData({
28729 type: "ClassSelector",
28730 name: "pagedjs_margin-content"
28731 });
28732
28733 contentSelectors.insertData({
28734 type: "PseudoElementSelector",
28735 name: "after",
28736 children: null
28737 });
28738
28739 let contentRule = this.createRule(contentSelectors, content);
28740 sheet.insertRule(contentRule);
28741 }
28742 }
28743
28744 addRootVars(ast, width, height, orientation, bleed, bleedrecto, bleedverso, marks) {
28745 let rules = [];
28746 let selectors = new csstree.List();
28747 selectors.insertData({
28748 type: "PseudoClassSelector",
28749 name: "root",
28750 children: null
28751 });
28752
28753 let widthString, heightString;
28754 let widthStringRight, heightStringRight;
28755 let widthStringLeft, heightStringLeft;
28756
28757 if (!bleed) {
28758 widthString = CSSValueToString(width);
28759 heightString = CSSValueToString(height);
28760 widthStringRight = CSSValueToString(width);
28761 heightStringRight = CSSValueToString(height);
28762 widthStringLeft = CSSValueToString(width);
28763 heightStringLeft = CSSValueToString(height);
28764 } else {
28765 widthString = `calc( ${CSSValueToString(width)} + ${CSSValueToString(bleed.left)} + ${CSSValueToString(bleed.right)} )`;
28766 heightString = `calc( ${CSSValueToString(height)} + ${CSSValueToString(bleed.top)} + ${CSSValueToString(bleed.bottom)} )`;
28767
28768 widthStringRight = `calc( ${CSSValueToString(width)} + ${CSSValueToString(bleed.left)} + ${CSSValueToString(bleed.right)} )`;
28769 heightStringRight = `calc( ${CSSValueToString(height)} + ${CSSValueToString(bleed.top)} + ${CSSValueToString(bleed.bottom)} )`;
28770
28771 widthStringLeft = `calc( ${CSSValueToString(width)} + ${CSSValueToString(bleed.left)} + ${CSSValueToString(bleed.right)} )`;
28772 heightStringLeft = `calc( ${CSSValueToString(height)} + ${CSSValueToString(bleed.top)} + ${CSSValueToString(bleed.bottom)} )`;
28773
28774 let bleedTop = this.createVariable("--pagedjs-bleed-top", CSSValueToString(bleed.top));
28775 let bleedRight = this.createVariable("--pagedjs-bleed-right", CSSValueToString(bleed.right));
28776 let bleedBottom = this.createVariable("--pagedjs-bleed-bottom", CSSValueToString(bleed.bottom));
28777 let bleedLeft = this.createVariable("--pagedjs-bleed-left", CSSValueToString(bleed.left));
28778
28779 let bleedTopRecto = this.createVariable("--pagedjs-bleed-right-top", CSSValueToString(bleed.top));
28780 let bleedRightRecto = this.createVariable("--pagedjs-bleed-right-right", CSSValueToString(bleed.right));
28781 let bleedBottomRecto = this.createVariable("--pagedjs-bleed-right-bottom", CSSValueToString(bleed.bottom));
28782 let bleedLeftRecto = this.createVariable("--pagedjs-bleed-right-left", CSSValueToString(bleed.left));
28783
28784 let bleedTopVerso = this.createVariable("--pagedjs-bleed-left-top", CSSValueToString(bleed.top));
28785 let bleedRightVerso = this.createVariable("--pagedjs-bleed-left-right", CSSValueToString(bleed.right));
28786 let bleedBottomVerso = this.createVariable("--pagedjs-bleed-left-bottom", CSSValueToString(bleed.bottom));
28787 let bleedLeftVerso = this.createVariable("--pagedjs-bleed-left-left", CSSValueToString(bleed.left));
28788
28789 if (bleedrecto) {
28790 bleedTopRecto = this.createVariable("--pagedjs-bleed-right-top", CSSValueToString(bleedrecto.top));
28791 bleedRightRecto = this.createVariable("--pagedjs-bleed-right-right", CSSValueToString(bleedrecto.right));
28792 bleedBottomRecto = this.createVariable("--pagedjs-bleed-right-bottom", CSSValueToString(bleedrecto.bottom));
28793 bleedLeftRecto = this.createVariable("--pagedjs-bleed-right-left", CSSValueToString(bleedrecto.left));
28794
28795 widthStringRight = `calc( ${CSSValueToString(width)} + ${CSSValueToString(bleedrecto.left)} + ${CSSValueToString(bleedrecto.right)} )`;
28796 heightStringRight = `calc( ${CSSValueToString(height)} + ${CSSValueToString(bleedrecto.top)} + ${CSSValueToString(bleedrecto.bottom)} )`;
28797 }
28798 if (bleedverso) {
28799 bleedTopVerso = this.createVariable("--pagedjs-bleed-left-top", CSSValueToString(bleedverso.top));
28800 bleedRightVerso = this.createVariable("--pagedjs-bleed-left-right", CSSValueToString(bleedverso.right));
28801 bleedBottomVerso = this.createVariable("--pagedjs-bleed-left-bottom", CSSValueToString(bleedverso.bottom));
28802 bleedLeftVerso = this.createVariable("--pagedjs-bleed-left-left", CSSValueToString(bleedverso.left));
28803
28804 widthStringLeft = `calc( ${CSSValueToString(width)} + ${CSSValueToString(bleedverso.left)} + ${CSSValueToString(bleedverso.right)} )`;
28805 heightStringLeft = `calc( ${CSSValueToString(height)} + ${CSSValueToString(bleedverso.top)} + ${CSSValueToString(bleedverso.bottom)} )`;
28806 }
28807
28808 let pageWidthVar = this.createVariable("--pagedjs-width", CSSValueToString(width));
28809 let pageHeightVar = this.createVariable("--pagedjs-height", CSSValueToString(height));
28810
28811 rules.push(
28812 bleedTop,
28813 bleedRight,
28814 bleedBottom,
28815 bleedLeft,
28816 bleedTopRecto,
28817 bleedRightRecto,
28818 bleedBottomRecto,
28819 bleedLeftRecto,
28820 bleedTopVerso,
28821 bleedRightVerso,
28822 bleedBottomVerso,
28823 bleedLeftVerso,
28824 pageWidthVar,
28825 pageHeightVar
28826 );
28827 }
28828
28829 if (marks) {
28830 marks.forEach((mark) => {
28831 let markDisplay = this.createVariable("--pagedjs-mark-" + mark + "-display", "block");
28832 rules.push(markDisplay);
28833 });
28834 }
28835
28836 // orientation variable
28837 if (orientation) {
28838 let oVar = this.createVariable("--pagedjs-orientation", orientation);
28839 rules.push(oVar);
28840
28841 if (orientation !== "portrait") {
28842 // reverse for orientation
28843 [widthString, heightString] = [heightString, widthString];
28844 [widthStringRight, heightStringRight] = [heightStringRight, widthStringRight];
28845 [widthStringLeft, heightStringLeft] = [heightStringLeft, widthStringLeft];
28846 }
28847 }
28848
28849 let wVar = this.createVariable("--pagedjs-width", widthString);
28850 let hVar = this.createVariable("--pagedjs-height", heightString);
28851
28852 let wVarR = this.createVariable("--pagedjs-width-right", widthStringRight);
28853 let hVarR = this.createVariable("--pagedjs-height-right", heightStringRight);
28854
28855 let wVarL = this.createVariable("--pagedjs-width-left", widthStringLeft);
28856 let hVarL = this.createVariable("--pagedjs-height-left", heightStringLeft);
28857
28858 rules.push(wVar, hVar, wVarR, hVarR, wVarL, hVarL);
28859
28860 let rule = this.createRule(selectors, rules);
28861
28862 ast.children.appendData(rule);
28863 }
28864
28865
28866 addNotesStyles(notes, page, list, item, sheet) {
28867
28868 for (const note in notes) {
28869 let selectors = this.selectorsForPage(page);
28870
28871 selectors.insertData({
28872 type: "Combinator",
28873 name: " "
28874 });
28875
28876 selectors.insertData({
28877 type: "ClassSelector",
28878 name: "pagedjs_" + note + "_content"
28879 });
28880
28881 let notesRule = this.createRule(selectors, notes[note]);
28882
28883 list.appendData(notesRule);
28884 }
28885
28886 }
28887
28888 /*
28889 @page {
28890 size: var(--pagedjs-width) var(--pagedjs-height);
28891 margin: 0;
28892 padding: 0;
28893 }
28894 */
28895 addRootPage(ast, size, bleed, bleedrecto, bleedverso) {
28896 let { width, height, orientation, format } = size;
28897 let children = new csstree.List();
28898 let childrenLeft = new csstree.List();
28899 let childrenRight = new csstree.List();
28900 let dimensions = new csstree.List();
28901 let dimensionsLeft = new csstree.List();
28902 let dimensionsRight = new csstree.List();
28903
28904 if (bleed) {
28905 let widthCalculations = new csstree.List();
28906 let heightCalculations = new csstree.List();
28907
28908 // width
28909 widthCalculations.appendData({
28910 type: "Dimension",
28911 unit: width.unit,
28912 value: width.value
28913 });
28914
28915 widthCalculations.appendData({
28916 type: "WhiteSpace",
28917 value: " "
28918 });
28919
28920 widthCalculations.appendData({
28921 type: "Operator",
28922 value: "+"
28923 });
28924
28925 widthCalculations.appendData({
28926 type: "WhiteSpace",
28927 value: " "
28928 });
28929
28930 widthCalculations.appendData({
28931 type: "Dimension",
28932 unit: bleed.left.unit,
28933 value: bleed.left.value
28934 });
28935
28936 widthCalculations.appendData({
28937 type: "WhiteSpace",
28938 value: " "
28939 });
28940
28941 widthCalculations.appendData({
28942 type: "Operator",
28943 value: "+"
28944 });
28945
28946 widthCalculations.appendData({
28947 type: "WhiteSpace",
28948 value: " "
28949 });
28950
28951 widthCalculations.appendData({
28952 type: "Dimension",
28953 unit: bleed.right.unit,
28954 value: bleed.right.value
28955 });
28956
28957 // height
28958 heightCalculations.appendData({
28959 type: "Dimension",
28960 unit: height.unit,
28961 value: height.value
28962 });
28963
28964 heightCalculations.appendData({
28965 type: "WhiteSpace",
28966 value: " "
28967 });
28968
28969 heightCalculations.appendData({
28970 type: "Operator",
28971 value: "+"
28972 });
28973
28974 heightCalculations.appendData({
28975 type: "WhiteSpace",
28976 value: " "
28977 });
28978
28979 heightCalculations.appendData({
28980 type: "Dimension",
28981 unit: bleed.top.unit,
28982 value: bleed.top.value
28983 });
28984
28985 heightCalculations.appendData({
28986 type: "WhiteSpace",
28987 value: " "
28988 });
28989
28990 heightCalculations.appendData({
28991 type: "Operator",
28992 value: "+"
28993 });
28994
28995 heightCalculations.appendData({
28996 type: "WhiteSpace",
28997 value: " "
28998 });
28999
29000 heightCalculations.appendData({
29001 type: "Dimension",
29002 unit: bleed.bottom.unit,
29003 value: bleed.bottom.value
29004 });
29005
29006 dimensions.appendData({
29007 type: "Function",
29008 name: "calc",
29009 children: widthCalculations
29010 });
29011
29012 dimensions.appendData({
29013 type: "WhiteSpace",
29014 value: " "
29015 });
29016
29017 dimensions.appendData({
29018 type: "Function",
29019 name: "calc",
29020 children: heightCalculations
29021 });
29022
29023 } else if (format) {
29024 dimensions.appendData({
29025 type: "Identifier",
29026 name: format
29027 });
29028
29029 if (orientation) {
29030 dimensions.appendData({
29031 type: "WhiteSpace",
29032 value: " "
29033 });
29034
29035 dimensions.appendData({
29036 type: "Identifier",
29037 name: orientation
29038 });
29039 }
29040 } else {
29041 dimensions.appendData({
29042 type: "Dimension",
29043 unit: width.unit,
29044 value: width.value
29045 });
29046
29047 dimensions.appendData({
29048 type: "WhiteSpace",
29049 value: " "
29050 });
29051
29052 dimensions.appendData({
29053 type: "Dimension",
29054 unit: height.unit,
29055 value: height.value
29056 });
29057 }
29058
29059 children.appendData({
29060 type: "Declaration",
29061 property: "size",
29062 loc: null,
29063 value: {
29064 type: "Value",
29065 children: dimensions
29066 }
29067 });
29068
29069 children.appendData({
29070 type: "Declaration",
29071 property: "margin",
29072 loc: null,
29073 value: {
29074 type: "Value",
29075 children: [{
29076 type: "Dimension",
29077 unit: "px",
29078 value: 0
29079 }]
29080 }
29081 });
29082
29083 children.appendData({
29084 type: "Declaration",
29085 property: "padding",
29086 loc: null,
29087 value: {
29088 type: "Value",
29089 children: [{
29090 type: "Dimension",
29091 unit: "px",
29092 value: 0
29093 }]
29094 }
29095 });
29096
29097 children.appendData({
29098 type: "Declaration",
29099 property: "padding",
29100 loc: null,
29101 value: {
29102 type: "Value",
29103 children: [{
29104 type: "Dimension",
29105 unit: "px",
29106 value: 0
29107 }]
29108 }
29109 });
29110
29111 let rule = ast.children.createItem({
29112 type: "Atrule",
29113 prelude: null,
29114 name: "page",
29115 block: {
29116 type: "Block",
29117 loc: null,
29118 children: children
29119 }
29120 });
29121
29122 ast.children.append(rule);
29123
29124 if (bleedverso) {
29125 let widthCalculationsLeft = new csstree.List();
29126 let heightCalculationsLeft = new csstree.List();
29127
29128 // width
29129 widthCalculationsLeft.appendData({
29130 type: "Dimension",
29131 unit: width.unit,
29132 value: width.value
29133 });
29134
29135 widthCalculationsLeft.appendData({
29136 type: "WhiteSpace",
29137 value: " "
29138 });
29139
29140 widthCalculationsLeft.appendData({
29141 type: "Operator",
29142 value: "+"
29143 });
29144
29145 widthCalculationsLeft.appendData({
29146 type: "WhiteSpace",
29147 value: " "
29148 });
29149
29150 widthCalculationsLeft.appendData({
29151 type: "Dimension",
29152 unit: bleedverso.left.unit,
29153 value: bleedverso.left.value
29154 });
29155
29156 widthCalculationsLeft.appendData({
29157 type: "WhiteSpace",
29158 value: " "
29159 });
29160
29161 widthCalculationsLeft.appendData({
29162 type: "Operator",
29163 value: "+"
29164 });
29165
29166 widthCalculationsLeft.appendData({
29167 type: "WhiteSpace",
29168 value: " "
29169 });
29170
29171 widthCalculationsLeft.appendData({
29172 type: "Dimension",
29173 unit: bleedverso.right.unit,
29174 value: bleedverso.right.value
29175 });
29176
29177 // height
29178 heightCalculationsLeft.appendData({
29179 type: "Dimension",
29180 unit: height.unit,
29181 value: height.value
29182 });
29183
29184 heightCalculationsLeft.appendData({
29185 type: "WhiteSpace",
29186 value: " "
29187 });
29188
29189 heightCalculationsLeft.appendData({
29190 type: "Operator",
29191 value: "+"
29192 });
29193
29194 heightCalculationsLeft.appendData({
29195 type: "WhiteSpace",
29196 value: " "
29197 });
29198
29199 heightCalculationsLeft.appendData({
29200 type: "Dimension",
29201 unit: bleedverso.top.unit,
29202 value: bleedverso.top.value
29203 });
29204
29205 heightCalculationsLeft.appendData({
29206 type: "WhiteSpace",
29207 value: " "
29208 });
29209
29210 heightCalculationsLeft.appendData({
29211 type: "Operator",
29212 value: "+"
29213 });
29214
29215 heightCalculationsLeft.appendData({
29216 type: "WhiteSpace",
29217 value: " "
29218 });
29219
29220 heightCalculationsLeft.appendData({
29221 type: "Dimension",
29222 unit: bleedverso.bottom.unit,
29223 value: bleedverso.bottom.value
29224 });
29225
29226 dimensionsLeft.appendData({
29227 type: "Function",
29228 name: "calc",
29229 children: widthCalculationsLeft
29230 });
29231
29232 dimensionsLeft.appendData({
29233 type: "WhiteSpace",
29234 value: " "
29235 });
29236
29237 dimensionsLeft.appendData({
29238 type: "Function",
29239 name: "calc",
29240 children: heightCalculationsLeft
29241 });
29242
29243 childrenLeft.appendData({
29244 type: "Declaration",
29245 property: "size",
29246 loc: null,
29247 value: {
29248 type: "Value",
29249 children: dimensionsLeft
29250 }
29251 });
29252
29253 let ruleLeft = ast.children.createItem({
29254 type: "Atrule",
29255 prelude: null,
29256 name: "page :left",
29257 block: {
29258 type: "Block",
29259 loc: null,
29260 children: childrenLeft
29261 }
29262 });
29263
29264 ast.children.append(ruleLeft);
29265
29266 }
29267
29268 if (bleedrecto) {
29269 let widthCalculationsRight = new csstree.List();
29270 let heightCalculationsRight = new csstree.List();
29271
29272 // width
29273 widthCalculationsRight.appendData({
29274 type: "Dimension",
29275 unit: width.unit,
29276 value: width.value
29277 });
29278
29279 widthCalculationsRight.appendData({
29280 type: "WhiteSpace",
29281 value: " "
29282 });
29283
29284 widthCalculationsRight.appendData({
29285 type: "Operator",
29286 value: "+"
29287 });
29288
29289 widthCalculationsRight.appendData({
29290 type: "WhiteSpace",
29291 value: " "
29292 });
29293
29294 widthCalculationsRight.appendData({
29295 type: "Dimension",
29296 unit: bleedrecto.left.unit,
29297 value: bleedrecto.left.value
29298 });
29299
29300 widthCalculationsRight.appendData({
29301 type: "WhiteSpace",
29302 value: " "
29303 });
29304
29305 widthCalculationsRight.appendData({
29306 type: "Operator",
29307 value: "+"
29308 });
29309
29310 widthCalculationsRight.appendData({
29311 type: "WhiteSpace",
29312 value: " "
29313 });
29314
29315 widthCalculationsRight.appendData({
29316 type: "Dimension",
29317 unit: bleedrecto.right.unit,
29318 value: bleedrecto.right.value
29319 });
29320
29321 // height
29322 heightCalculationsRight.appendData({
29323 type: "Dimension",
29324 unit: height.unit,
29325 value: height.value
29326 });
29327
29328 heightCalculationsRight.appendData({
29329 type: "WhiteSpace",
29330 value: " "
29331 });
29332
29333 heightCalculationsRight.appendData({
29334 type: "Operator",
29335 value: "+"
29336 });
29337
29338 heightCalculationsRight.appendData({
29339 type: "WhiteSpace",
29340 value: " "
29341 });
29342
29343 heightCalculationsRight.appendData({
29344 type: "Dimension",
29345 unit: bleedrecto.top.unit,
29346 value: bleedrecto.top.value
29347 });
29348
29349 heightCalculationsRight.appendData({
29350 type: "WhiteSpace",
29351 value: " "
29352 });
29353
29354 heightCalculationsRight.appendData({
29355 type: "Operator",
29356 value: "+"
29357 });
29358
29359 heightCalculationsRight.appendData({
29360 type: "WhiteSpace",
29361 value: " "
29362 });
29363
29364 heightCalculationsRight.appendData({
29365 type: "Dimension",
29366 unit: bleedrecto.bottom.unit,
29367 value: bleedrecto.bottom.value
29368 });
29369
29370 dimensionsRight.appendData({
29371 type: "Function",
29372 name: "calc",
29373 children: widthCalculationsRight
29374 });
29375
29376 dimensionsRight.appendData({
29377 type: "WhiteSpace",
29378 value: " "
29379 });
29380
29381 dimensionsRight.appendData({
29382 type: "Function",
29383 name: "calc",
29384 children: heightCalculationsRight
29385 });
29386
29387 childrenRight.appendData({
29388 type: "Declaration",
29389 property: "size",
29390 loc: null,
29391 value: {
29392 type: "Value",
29393 children: dimensionsRight
29394 }
29395 });
29396
29397 let ruleRight = ast.children.createItem({
29398 type: "Atrule",
29399 prelude: null,
29400 name: "page :right",
29401 block: {
29402 type: "Block",
29403 loc: null,
29404 children: childrenRight
29405 }
29406 });
29407
29408 ast.children.append(ruleRight);
29409
29410 }
29411 }
29412
29413 getNth(nth) {
29414 let n = nth.indexOf("n");
29415 let plus = nth.indexOf("+");
29416 let splitN = nth.split("n");
29417 let splitP = nth.split("+");
29418 let a = null;
29419 let b = null;
29420 if (n > -1) {
29421 a = splitN[0];
29422 if (plus > -1) {
29423 b = splitP[1];
29424 }
29425 } else {
29426 b = nth;
29427 }
29428
29429 return {
29430 type: "Nth",
29431 loc: null,
29432 selector: null,
29433 nth: {
29434 type: "AnPlusB",
29435 loc: null,
29436 a: a,
29437 b: b
29438 }
29439 };
29440 }
29441
29442 addPageAttributes(page, start, pages) {
29443 let namedPages = [start.dataset.page];
29444
29445 if (namedPages && namedPages.length) {
29446 for (const named of namedPages) {
29447 if (!named) {
29448 continue;
29449 }
29450 page.name = named;
29451 page.element.classList.add("pagedjs_named_page");
29452 page.element.classList.add("pagedjs_" + named + "_page");
29453
29454 if (!start.dataset.splitFrom) {
29455 page.element.classList.add("pagedjs_" + named + "_first_page");
29456 }
29457 }
29458 }
29459 }
29460
29461 getStartElement(content, breakToken) {
29462 let node = breakToken && breakToken.node;
29463
29464 if (!content && !breakToken) {
29465 return;
29466 }
29467
29468 // No break
29469 if (!node) {
29470 return content.children[0];
29471 }
29472
29473 // Top level element
29474 if (node.nodeType === 1 && node.parentNode.nodeType === 11) {
29475 return node;
29476 }
29477
29478 // Named page
29479 if (node.nodeType === 1 && node.dataset.page) {
29480 return node;
29481 }
29482
29483 // Get top level Named parent
29484 let fragment = rebuildAncestors(node);
29485 let pages = fragment.querySelectorAll("[data-page]");
29486
29487 if (pages.length) {
29488 return pages[pages.length - 1];
29489 } else {
29490 return fragment.children[0];
29491 }
29492 }
29493
29494 beforePageLayout(page, contents, breakToken, chunker) {
29495 let start = this.getStartElement(contents, breakToken);
29496 if (start) {
29497 this.addPageAttributes(page, start, chunker.pages);
29498 }
29499 // page.element.querySelector('.paged_area').style.color = red;
29500 }
29501
29502 finalizePage(fragment, page, breakToken, chunker) {
29503 for (let m in this.marginalia) {
29504 let margin = this.marginalia[m];
29505 let sels = m.split(" ");
29506
29507 let content;
29508 if (page.element.matches(sels[0]) && margin.hasContent) {
29509 content = page.element.querySelector(sels[1]);
29510 content.classList.add("hasContent");
29511 }
29512 }
29513
29514 // check center
29515 ["top", "bottom"].forEach((loc) => {
29516 let marginGroup = page.element.querySelector(".pagedjs_margin-" + loc);
29517 let center = page.element.querySelector(".pagedjs_margin-" + loc + "-center");
29518 let left = page.element.querySelector(".pagedjs_margin-" + loc + "-left");
29519 let right = page.element.querySelector(".pagedjs_margin-" + loc + "-right");
29520
29521 let centerContent = center.classList.contains("hasContent");
29522 let leftContent = left.classList.contains("hasContent");
29523 let rightContent = right.classList.contains("hasContent");
29524 let centerWidth, leftWidth, rightWidth;
29525
29526 if (leftContent) {
29527 leftWidth = window.getComputedStyle(left)["max-width"];
29528 }
29529
29530 if (rightContent) {
29531 rightWidth = window.getComputedStyle(right)["max-width"];
29532 }
29533
29534
29535 if (centerContent) {
29536 centerWidth = window.getComputedStyle(center)["max-width"];
29537
29538 if (centerWidth === "none" || centerWidth === "auto") {
29539 if (!leftContent && !rightContent) {
29540 marginGroup.style["grid-template-columns"] = "0 1fr 0";
29541 } else if (leftContent) {
29542 if (!rightContent) {
29543 if (leftWidth !== "none" && leftWidth !== "auto") {
29544 marginGroup.style["grid-template-columns"] = leftWidth + " 1fr " + leftWidth;
29545 } else {
29546 marginGroup.style["grid-template-columns"] = "auto auto 1fr";
29547 left.style["white-space"] = "nowrap";
29548 center.style["white-space"] = "nowrap";
29549 let leftOuterWidth = left.offsetWidth;
29550 let centerOuterWidth = center.offsetWidth;
29551 let outerwidths = leftOuterWidth + centerOuterWidth;
29552 let newcenterWidth = centerOuterWidth * 100 / outerwidths;
29553 marginGroup.style["grid-template-columns"] = "minmax(16.66%, 1fr) minmax(33%, " + newcenterWidth + "%) minmax(16.66%, 1fr)";
29554 left.style["white-space"] = "normal";
29555 center.style["white-space"] = "normal";
29556 }
29557 } else {
29558 if (leftWidth !== "none" && leftWidth !== "auto") {
29559 if (rightWidth !== "none" && rightWidth !== "auto") {
29560 marginGroup.style["grid-template-columns"] = leftWidth + " 1fr " + rightWidth;
29561 } else {
29562 marginGroup.style["grid-template-columns"] = leftWidth + " 1fr " + leftWidth;
29563 }
29564 } else {
29565 if (rightWidth !== "none" && rightWidth !== "auto") {
29566 marginGroup.style["grid-template-columns"] = rightWidth + " 1fr " + rightWidth;
29567 } else {
29568 marginGroup.style["grid-template-columns"] = "auto auto 1fr";
29569 left.style["white-space"] = "nowrap";
29570 center.style["white-space"] = "nowrap";
29571 right.style["white-space"] = "nowrap";
29572 let leftOuterWidth = left.offsetWidth;
29573 let centerOuterWidth = center.offsetWidth;
29574 let rightOuterWidth = right.offsetWidth;
29575 let outerwidths = leftOuterWidth + centerOuterWidth + rightOuterWidth;
29576 let newcenterWidth = centerOuterWidth * 100 / outerwidths;
29577 if (newcenterWidth > 40) {
29578 marginGroup.style["grid-template-columns"] = "minmax(16.66%, 1fr) minmax(33%, " + newcenterWidth + "%) minmax(16.66%, 1fr)";
29579 } else {
29580 marginGroup.style["grid-template-columns"] = "repeat(3, 1fr)";
29581 }
29582 left.style["white-space"] = "normal";
29583 center.style["white-space"] = "normal";
29584 right.style["white-space"] = "normal";
29585 }
29586 }
29587 }
29588 } else {
29589 if (rightWidth !== "none" && rightWidth !== "auto") {
29590 marginGroup.style["grid-template-columns"] = rightWidth + " 1fr " + rightWidth;
29591 } else {
29592 marginGroup.style["grid-template-columns"] = "auto auto 1fr";
29593 right.style["white-space"] = "nowrap";
29594 center.style["white-space"] = "nowrap";
29595 let rightOuterWidth = right.offsetWidth;
29596 let centerOuterWidth = center.offsetWidth;
29597 let outerwidths = rightOuterWidth + centerOuterWidth;
29598 let newcenterWidth = centerOuterWidth * 100 / outerwidths;
29599 marginGroup.style["grid-template-columns"] = "minmax(16.66%, 1fr) minmax(33%, " + newcenterWidth + "%) minmax(16.66%, 1fr)";
29600 right.style["white-space"] = "normal";
29601 center.style["white-space"] = "normal";
29602 }
29603 }
29604 } else if (centerWidth !== "none" && centerWidth !== "auto") {
29605 if (leftContent && leftWidth !== "none" && leftWidth !== "auto") {
29606 marginGroup.style["grid-template-columns"] = leftWidth + " " + centerWidth + " 1fr";
29607 } else if (rightContent && rightWidth !== "none" && rightWidth !== "auto") {
29608 marginGroup.style["grid-template-columns"] = "1fr " + centerWidth + " " + rightWidth;
29609 } else {
29610 marginGroup.style["grid-template-columns"] = "1fr " + centerWidth + " 1fr";
29611 }
29612
29613 }
29614
29615 } else {
29616 if (leftContent) {
29617 if (!rightContent) {
29618 marginGroup.style["grid-template-columns"] = "1fr 0 0";
29619 } else {
29620 if (leftWidth !== "none" && leftWidth !== "auto") {
29621 if (rightWidth !== "none" && rightWidth !== "auto") {
29622 marginGroup.style["grid-template-columns"] = leftWidth + " 1fr " + rightWidth;
29623 } else {
29624 marginGroup.style["grid-template-columns"] = leftWidth + " 0 1fr";
29625 }
29626 } else {
29627 if (rightWidth !== "none" && rightWidth !== "auto") {
29628 marginGroup.style["grid-template-columns"] = "1fr 0 " + rightWidth;
29629 } else {
29630 marginGroup.style["grid-template-columns"] = "auto 1fr auto";
29631 left.style["white-space"] = "nowrap";
29632 right.style["white-space"] = "nowrap";
29633 let leftOuterWidth = left.offsetWidth;
29634 let rightOuterWidth = right.offsetWidth;
29635 let outerwidths = leftOuterWidth + rightOuterWidth;
29636 let newLeftWidth = leftOuterWidth * 100 / outerwidths;
29637 marginGroup.style["grid-template-columns"] = "minmax(16.66%, " + newLeftWidth + "%) 0 1fr";
29638 left.style["white-space"] = "normal";
29639 right.style["white-space"] = "normal";
29640 }
29641 }
29642 }
29643 } else {
29644 if (rightWidth !== "none" && rightWidth !== "auto") {
29645 marginGroup.style["grid-template-columns"] = "1fr 0 " + rightWidth;
29646 } else {
29647 marginGroup.style["grid-template-columns"] = "0 0 1fr";
29648 }
29649 }
29650 }
29651 });
29652
29653 // check middle
29654 ["left", "right"].forEach((loc) => {
29655 let middle = page.element.querySelector(".pagedjs_margin-" + loc + "-middle.hasContent");
29656 let marginGroup = page.element.querySelector(".pagedjs_margin-" + loc);
29657 let top = page.element.querySelector(".pagedjs_margin-" + loc + "-top");
29658 let bottom = page.element.querySelector(".pagedjs_margin-" + loc + "-bottom");
29659 let topContent = top.classList.contains("hasContent");
29660 let bottomContent = bottom.classList.contains("hasContent");
29661 let middleHeight, topHeight, bottomHeight;
29662
29663 if (topContent) {
29664 topHeight = window.getComputedStyle(top)["max-height"];
29665 }
29666
29667 if (bottomContent) {
29668 bottomHeight = window.getComputedStyle(bottom)["max-height"];
29669 }
29670
29671 if (middle) {
29672 middleHeight = window.getComputedStyle(middle)["max-height"];
29673
29674 if (middleHeight === "none" || middleHeight === "auto") {
29675 if (!topContent && !bottomContent) {
29676 marginGroup.style["grid-template-rows"] = "0 1fr 0";
29677 } else if (topContent) {
29678 if (!bottomContent) {
29679 if (topHeight !== "none" && topHeight !== "auto") {
29680 marginGroup.style["grid-template-rows"] = topHeight + " calc(100% - " + topHeight + "*2) " + topHeight;
29681 }
29682 } else {
29683 if (topHeight !== "none" && topHeight !== "auto") {
29684 if (bottomHeight !== "none" && bottomHeight !== "auto") {
29685 marginGroup.style["grid-template-rows"] = topHeight + " calc(100% - " + topHeight + " - " + bottomHeight + ") " + bottomHeight;
29686 } else {
29687 marginGroup.style["grid-template-rows"] = topHeight + " calc(100% - " + topHeight + "*2) " + topHeight;
29688 }
29689 } else {
29690 if (bottomHeight !== "none" && bottomHeight !== "auto") {
29691 marginGroup.style["grid-template-rows"] = bottomHeight + " calc(100% - " + bottomHeight + "*2) " + bottomHeight;
29692 }
29693 }
29694 }
29695 } else {
29696 if (bottomHeight !== "none" && bottomHeight !== "auto") {
29697 marginGroup.style["grid-template-rows"] = bottomHeight + " calc(100% - " + bottomHeight + "*2) " + bottomHeight;
29698 }
29699 }
29700 } else {
29701 if (topContent && topHeight !== "none" && topHeight !== "auto") {
29702 marginGroup.style["grid-template-rows"] = topHeight + " " + middleHeight + " calc(100% - (" + topHeight + " + " + middleHeight + "))";
29703 } else if (bottomContent && bottomHeight !== "none" && bottomHeight !== "auto") {
29704 marginGroup.style["grid-template-rows"] = "1fr " + middleHeight + " " + bottomHeight;
29705 } else {
29706 marginGroup.style["grid-template-rows"] = "calc((100% - " + middleHeight + ")/2) " + middleHeight + " calc((100% - " + middleHeight + ")/2)";
29707 }
29708
29709 }
29710
29711 } else {
29712 if (topContent) {
29713 if (!bottomContent) {
29714 marginGroup.style["grid-template-rows"] = "1fr 0 0";
29715 } else {
29716 if (topHeight !== "none" && topHeight !== "auto") {
29717 if (bottomHeight !== "none" && bottomHeight !== "auto") {
29718 marginGroup.style["grid-template-rows"] = topHeight + " 1fr " + bottomHeight;
29719 } else {
29720 marginGroup.style["grid-template-rows"] = topHeight + " 0 1fr";
29721 }
29722 } else {
29723 if (bottomHeight !== "none" && bottomHeight !== "auto") {
29724 marginGroup.style["grid-template-rows"] = "1fr 0 " + bottomHeight;
29725 } else {
29726 marginGroup.style["grid-template-rows"] = "1fr 0 1fr";
29727 }
29728 }
29729 }
29730 } else {
29731 if (bottomHeight !== "none" && bottomHeight !== "auto") {
29732 marginGroup.style["grid-template-rows"] = "1fr 0 " + bottomHeight;
29733 } else {
29734 marginGroup.style["grid-template-rows"] = "0 0 1fr";
29735 }
29736 }
29737 }
29738
29739
29740
29741 });
29742
29743 }
29744
29745 // CSS Tree Helpers
29746
29747 selectorsForPage(page) {
29748 let nthlist;
29749 let nth;
29750
29751 let selectors = new csstree.List();
29752
29753 selectors.insertData({
29754 type: "ClassSelector",
29755 name: "pagedjs_page"
29756 });
29757
29758 // Named page
29759 if (page.name) {
29760 selectors.insertData({
29761 type: "ClassSelector",
29762 name: "pagedjs_named_page"
29763 });
29764
29765 selectors.insertData({
29766 type: "ClassSelector",
29767 name: "pagedjs_" + page.name + "_page"
29768 });
29769 }
29770
29771 // PsuedoSelector
29772 if (page.psuedo && !(page.name && page.psuedo === "first")) {
29773 selectors.insertData({
29774 type: "ClassSelector",
29775 name: "pagedjs_" + page.psuedo + "_page"
29776 });
29777 }
29778
29779 if (page.name && page.psuedo === "first") {
29780 selectors.insertData({
29781 type: "ClassSelector",
29782 name: "pagedjs_" + page.name + "_" + page.psuedo + "_page"
29783 });
29784 }
29785
29786 // Nth
29787 if (page.nth) {
29788 nthlist = new csstree.List();
29789 nth = this.getNth(page.nth);
29790
29791 nthlist.insertData(nth);
29792
29793 selectors.insertData({
29794 type: "PseudoClassSelector",
29795 name: "nth-of-type",
29796 children: nthlist
29797 });
29798 }
29799
29800 return selectors;
29801 }
29802
29803 selectorsForPageMargin(page, margin) {
29804 let selectors = this.selectorsForPage(page);
29805
29806 selectors.insertData({
29807 type: "Combinator",
29808 name: " "
29809 });
29810
29811 selectors.insertData({
29812 type: "ClassSelector",
29813 name: "pagedjs_margin-" + margin
29814 });
29815
29816 return selectors;
29817 }
29818
29819 createDeclaration(property, value, important) {
29820 let children = new csstree.List();
29821
29822 children.insertData({
29823 type: "Identifier",
29824 loc: null,
29825 name: value
29826 });
29827
29828 return {
29829 type: "Declaration",
29830 loc: null,
29831 important: important,
29832 property: property,
29833 value: {
29834 type: "Value",
29835 loc: null,
29836 children: children
29837 }
29838 };
29839 }
29840
29841 createVariable(property, value) {
29842 return {
29843 type: "Declaration",
29844 loc: null,
29845 property: property,
29846 value: {
29847 type: "Raw",
29848 value: value
29849 }
29850 };
29851 }
29852
29853 createCalculatedDimension(property, items, important, operator = "+") {
29854 let children = new csstree.List();
29855 let calculations = new csstree.List();
29856
29857 items.forEach((item, index) => {
29858 calculations.appendData({
29859 type: "Dimension",
29860 unit: item.unit,
29861 value: item.value
29862 });
29863
29864 calculations.appendData({
29865 type: "WhiteSpace",
29866 value: " "
29867 });
29868
29869 if (index + 1 < items.length) {
29870 calculations.appendData({
29871 type: "Operator",
29872 value: operator
29873 });
29874
29875 calculations.appendData({
29876 type: "WhiteSpace",
29877 value: " "
29878 });
29879 }
29880 });
29881
29882 children.insertData({
29883 type: "Function",
29884 loc: null,
29885 name: "calc",
29886 children: calculations
29887 });
29888
29889 return {
29890 type: "Declaration",
29891 loc: null,
29892 important: important,
29893 property: property,
29894 value: {
29895 type: "Value",
29896 loc: null,
29897 children: children
29898 }
29899 };
29900 }
29901
29902 createDimension(property, cssValue, important) {
29903 let children = new csstree.List();
29904
29905 children.insertData({
29906 type: "Dimension",
29907 loc: null,
29908 value: cssValue.value,
29909 unit: cssValue.unit
29910 });
29911
29912 return {
29913 type: "Declaration",
29914 loc: null,
29915 important: important,
29916 property: property,
29917 value: {
29918 type: "Value",
29919 loc: null,
29920 children: children
29921 }
29922 };
29923 }
29924
29925 createBlock(declarations) {
29926 let block = new csstree.List();
29927
29928 declarations.forEach((declaration) => {
29929 block.insertData(declaration);
29930 });
29931
29932 return {
29933 type: "Block",
29934 loc: null,
29935 children: block
29936 };
29937 }
29938
29939 createRule(selectors, block) {
29940 let selectorList = new csstree.List();
29941 selectorList.insertData({
29942 type: "Selector",
29943 children: selectors
29944 });
29945
29946 if (Array.isArray(block)) {
29947 block = this.createBlock(block);
29948 }
29949
29950 return {
29951 type: "Rule",
29952 prelude: {
29953 type: "SelectorList",
29954 children: selectorList
29955 },
29956 block: block
29957 };
29958 }
29959
29960 }
29961
29962 class Breaks extends Handler {
29963 constructor(chunker, polisher, caller) {
29964 super(chunker, polisher, caller);
29965
29966 this.breaks = {};
29967 }
29968
29969 onDeclaration(declaration, dItem, dList, rule) {
29970 let property = declaration.property;
29971
29972 if (property === "page") {
29973 let children = declaration.value.children.first();
29974 let value = children.name;
29975 let selector = csstree.generate(rule.ruleNode.prelude);
29976 let name = value;
29977
29978 let breaker = {
29979 property: property,
29980 value: value,
29981 selector: selector,
29982 name: name
29983 };
29984
29985 selector.split(",").forEach((s) => {
29986 if (!this.breaks[s]) {
29987 this.breaks[s] = [breaker];
29988 } else {
29989 this.breaks[s].push(breaker);
29990 }
29991 });
29992
29993 dList.remove(dItem);
29994 }
29995
29996 if (property === "break-before" ||
29997 property === "break-after" ||
29998 property === "page-break-before" ||
29999 property === "page-break-after"
30000 ) {
30001 let child = declaration.value.children.first();
30002 let value = child.name;
30003 let selector = csstree.generate(rule.ruleNode.prelude);
30004
30005 if (property === "page-break-before") {
30006 property = "break-before";
30007 } else if (property === "page-break-after") {
30008 property = "break-after";
30009 }
30010
30011 let breaker = {
30012 property: property,
30013 value: value,
30014 selector: selector
30015 };
30016
30017 selector.split(",").forEach((s) => {
30018 if (!this.breaks[s]) {
30019 this.breaks[s] = [breaker];
30020 } else {
30021 this.breaks[s].push(breaker);
30022 }
30023 });
30024
30025 // Remove from CSS -- handle right / left in module
30026 dList.remove(dItem);
30027 }
30028 }
30029
30030 afterParsed(parsed) {
30031 this.processBreaks(parsed, this.breaks);
30032 }
30033
30034 processBreaks(parsed, breaks) {
30035 for (let b in breaks) {
30036 // Find elements
30037 let elements = parsed.querySelectorAll(b);
30038 // Add break data
30039 for (var i = 0; i < elements.length; i++) {
30040 for (let prop of breaks[b]) {
30041
30042 if (prop.property === "break-after") {
30043 let nodeAfter = displayedElementAfter(elements[i], parsed);
30044
30045 elements[i].setAttribute("data-break-after", prop.value);
30046
30047 if (nodeAfter) {
30048 nodeAfter.setAttribute("data-previous-break-after", prop.value);
30049 }
30050 } else if (prop.property === "break-before") {
30051 let nodeBefore = displayedElementBefore(elements[i], parsed);
30052
30053 // Breaks are only allowed between siblings, not between a box and its container.
30054 // If we cannot find a node before we should not break!
30055 // https://drafts.csswg.org/css-break-3/#break-propagation
30056 if (nodeBefore) {
30057 if (prop.value === "page" && needsPageBreak(elements[i], nodeBefore)) {
30058 // we ignore this explicit page break because an implicit page break is already needed
30059 continue;
30060 }
30061 elements[i].setAttribute("data-break-before", prop.value);
30062 nodeBefore.setAttribute("data-next-break-before", prop.value);
30063 }
30064 } else if (prop.property === "page") {
30065 elements[i].setAttribute("data-page", prop.value);
30066
30067 let nodeAfter = displayedElementAfter(elements[i], parsed);
30068
30069 if (nodeAfter) {
30070 nodeAfter.setAttribute("data-after-page", prop.value);
30071 }
30072 } else {
30073 elements[i].setAttribute("data-" + prop.property, prop.value);
30074 }
30075 }
30076 }
30077 }
30078 }
30079
30080 mergeBreaks(pageBreaks, newBreaks) {
30081 for (let b in newBreaks) {
30082 if (b in pageBreaks) {
30083 pageBreaks[b] = pageBreaks[b].concat(newBreaks[b]);
30084 } else {
30085 pageBreaks[b] = newBreaks[b];
30086 }
30087 }
30088 return pageBreaks;
30089 }
30090
30091 addBreakAttributes(pageElement, page) {
30092 let before = pageElement.querySelector("[data-break-before]");
30093 let after = pageElement.querySelector("[data-break-after]");
30094 let previousBreakAfter = pageElement.querySelector("[data-previous-break-after]");
30095
30096 if (before) {
30097 if (before.dataset.splitFrom) {
30098 page.splitFrom = before.dataset.splitFrom;
30099 pageElement.setAttribute("data-split-from", before.dataset.splitFrom);
30100 } else if (before.dataset.breakBefore && before.dataset.breakBefore !== "avoid") {
30101 page.breakBefore = before.dataset.breakBefore;
30102 pageElement.setAttribute("data-break-before", before.dataset.breakBefore);
30103 }
30104 }
30105
30106 if (after && after.dataset) {
30107 if (after.dataset.splitTo) {
30108 page.splitTo = after.dataset.splitTo;
30109 pageElement.setAttribute("data-split-to", after.dataset.splitTo);
30110 } else if (after.dataset.breakAfter && after.dataset.breakAfter !== "avoid") {
30111 page.breakAfter = after.dataset.breakAfter;
30112 pageElement.setAttribute("data-break-after", after.dataset.breakAfter);
30113 }
30114 }
30115
30116 if (previousBreakAfter && previousBreakAfter.dataset) {
30117 if (previousBreakAfter.dataset.previousBreakAfter && previousBreakAfter.dataset.previousBreakAfter !== "avoid") {
30118 page.previousBreakAfter = previousBreakAfter.dataset.previousBreakAfter;
30119 }
30120 }
30121 }
30122
30123 afterPageLayout(pageElement, page) {
30124 this.addBreakAttributes(pageElement, page);
30125 }
30126 }
30127
30128 class PrintMedia extends Handler {
30129 constructor(chunker, polisher, caller) {
30130 super(chunker, polisher, caller);
30131 }
30132
30133 onAtMedia(node, item, list) {
30134 let media = this.getMediaName(node);
30135 let rules;
30136 if (media.includes("print")) {
30137 rules = node.block.children;
30138
30139 // Append rules to the end of main rules list
30140 // TODO: this isn't working right, needs to check what is in the prelude
30141 /*
30142 rules.forEach((selectList) => {
30143 if (selectList.prelude) {
30144 selectList.prelude.children.forEach((rule) => {
30145
30146 rule.children.prependData({
30147 type: "Combinator",
30148 name: " "
30149 });
30150
30151 rule.children.prependData({
30152 type: "ClassSelector",
30153 name: "pagedjs_page"
30154 });
30155 });
30156 }
30157 });
30158
30159 list.insertList(rules, item);
30160 */
30161
30162 // Append rules to the end of main rules list
30163 list.appendList(rules);
30164
30165 // Remove rules from the @media block
30166 list.remove(item);
30167 } else if (!media.includes("all") && !media.includes("pagedjs-ignore")) {
30168 list.remove(item);
30169 }
30170
30171 }
30172
30173 getMediaName(node) {
30174 let media = [];
30175
30176 if (typeof node.prelude === "undefined" ||
30177 node.prelude.type !== "AtrulePrelude" ) {
30178 return;
30179 }
30180
30181 csstree.walk(node.prelude, {
30182 visit: "Identifier",
30183 enter: (identNode, iItem, iList) => {
30184 media.push(identNode.name);
30185 }
30186 });
30187 return media;
30188 }
30189
30190
30191 }
30192
30193 class Splits extends Handler {
30194 constructor(chunker, polisher, caller) {
30195 super(chunker, polisher, caller);
30196 }
30197
30198 afterPageLayout(pageElement, page, breakToken, chunker) {
30199 let splits = Array.from(pageElement.querySelectorAll("[data-split-from]"));
30200 let pages = pageElement.parentNode;
30201 let index = Array.prototype.indexOf.call(pages.children, pageElement);
30202 let prevPage;
30203
30204 if (index === 0) {
30205 return;
30206 }
30207
30208 prevPage = pages.children[index - 1];
30209
30210 let from; // Capture the last from element
30211 splits.forEach((split) => {
30212 let ref = split.dataset.ref;
30213 from = prevPage.querySelector("[data-ref='"+ ref +"']:not([data-split-to])");
30214
30215 if (from) {
30216 from.dataset.splitTo = ref;
30217
30218 if (!from.dataset.splitFrom) {
30219 from.dataset.splitOriginal = true;
30220 }
30221 }
30222 });
30223
30224 // Fix alignment on the deepest split element
30225 if (from) {
30226 this.handleAlignment(from);
30227 }
30228 }
30229
30230 handleAlignment(node) {
30231 let styles = window.getComputedStyle(node);
30232 let align = styles["text-align"];
30233 let alignLast = styles["text-align-last"];
30234 node.dataset.lastSplitElement = "true";
30235 if (align === "justify" && alignLast === "auto") {
30236 node.dataset.alignLastSplitElement = "justify";
30237 } else {
30238 node.dataset.alignLastSplitElement = alignLast;
30239 }
30240 }
30241
30242 }
30243
30244 class Counters extends Handler {
30245 constructor(chunker, polisher, caller) {
30246 super(chunker, polisher, caller);
30247
30248 this.styleSheet = polisher.styleSheet;
30249 this.counters = {};
30250 this.resetCountersMap = new Map();
30251 }
30252
30253 onDeclaration(declaration, dItem, dList, rule) {
30254 let property = declaration.property;
30255
30256 if (property === "counter-increment") {
30257 this.handleIncrement(declaration, rule);
30258 // clean up empty declaration
30259 let hasProperities = false;
30260 declaration.value.children.forEach((data) => {
30261 if (data.type && data.type !== "WhiteSpace") {
30262 hasProperities = true;
30263 }
30264 });
30265 if (!hasProperities) {
30266 dList.remove(dItem);
30267 }
30268 } else if (property === "counter-reset") {
30269 this.handleReset(declaration, rule);
30270 // clean up empty declaration
30271 let hasProperities = false;
30272 declaration.value.children.forEach((data) => {
30273 if (data.type && data.type !== "WhiteSpace") {
30274 hasProperities = true;
30275 }
30276 });
30277 if (!hasProperities) {
30278 dList.remove(dItem);
30279 }
30280 }
30281 }
30282
30283 afterParsed(parsed) {
30284 this.processCounters(parsed, this.counters);
30285 this.scopeCounters(this.counters);
30286 }
30287
30288 addCounter(name) {
30289 if (name in this.counters) {
30290 return this.counters[name];
30291 }
30292
30293 this.counters[name] = {
30294 name: name,
30295 increments: {},
30296 resets: {}
30297 };
30298
30299 return this.counters[name];
30300 }
30301
30302 handleIncrement(declaration, rule) {
30303 let increments = [];
30304 let children = declaration.value.children;
30305
30306 children.forEach((data, item) => {
30307 if (data.type && data.type === "Identifier") {
30308 let name = data.name;
30309
30310 if (name === "page" || name.indexOf("target-counter-") === 0) {
30311 return;
30312 }
30313
30314 let whitespace, number, value;
30315 if (item.next && item.next.data.type === "WhiteSpace") {
30316 whitespace = item.next;
30317 }
30318 if (whitespace && whitespace.next && whitespace.next.data.type === "Number") {
30319 number = whitespace.next;
30320 value = parseInt(number.data.value);
30321 }
30322
30323 let selector = csstree.generate(rule.ruleNode.prelude);
30324
30325 let counter;
30326 if (!(name in this.counters)) {
30327 counter = this.addCounter(name);
30328 } else {
30329 counter = this.counters[name];
30330 }
30331 let increment = {
30332 selector: selector,
30333 number: value || 1
30334 };
30335 counter.increments[selector] = increment;
30336 increments.push(increment);
30337
30338 // Remove the parsed resets
30339 children.remove(item);
30340 if (whitespace) {
30341 children.remove(whitespace);
30342 }
30343 if (number) {
30344 children.remove(number);
30345 }
30346 }
30347 });
30348
30349 return increments;
30350 }
30351
30352 handleReset(declaration, rule) {
30353 let children = declaration.value.children;
30354
30355 children.forEach((data, item) => {
30356 if (data.type && data.type === "Identifier") {
30357 let name = data.name;
30358 let whitespace, number, value;
30359 if (item.next && item.next.data.type === "WhiteSpace") {
30360 whitespace = item.next;
30361 }
30362 if (whitespace && whitespace.next) {
30363 if (whitespace.next.data.type === "Number") {
30364 // The counter reset value is specified using a number. E.g. counter-reset: c2 5;
30365 number = whitespace.next;
30366 value = parseInt(number.data.value);
30367 } else if (whitespace.next.data.type === "Function" && whitespace.next.data.name === "var") {
30368 // The counter reset value is specified using a CSS variable (custom property).
30369 // E.g. counter-reset: c2 var(--my-variable);
30370 // See https://developer.mozilla.org/en-US/docs/Web/CSS/var
30371 number = whitespace.next;
30372 // Use the variable name (e.g. '--my-variable') as value for now. The actual value is resolved later by the
30373 // processCounterResets function.
30374 value = whitespace.next.data.children.head.data.name;
30375 }
30376 }
30377
30378 let counter;
30379 let selector;
30380 let prelude = rule.ruleNode.prelude;
30381
30382 if (rule.ruleNode.type === "Atrule" && rule.ruleNode.name === "page") {
30383 selector = ".pagedjs_page";
30384 } else {
30385 selector = csstree.generate(prelude || rule.ruleNode);
30386 }
30387
30388 if (name === "footnote") {
30389 this.addFootnoteMarkerCounter(declaration.value.children);
30390 }
30391
30392 if (!(name in this.counters)) {
30393 counter = this.addCounter(name);
30394 } else {
30395 counter = this.counters[name];
30396 }
30397
30398 let reset = {
30399 selector: selector,
30400 number: value || 0
30401 };
30402
30403 counter.resets[selector] = reset;
30404
30405 if (selector !== ".pagedjs_page") {
30406 // Remove the parsed resets
30407 children.remove(item);
30408 if (whitespace) {
30409 children.remove(whitespace);
30410 }
30411 if (number) {
30412 children.remove(number);
30413 }
30414 }
30415 }
30416 });
30417 }
30418
30419 processCounters(parsed, counters) {
30420 let counter;
30421 for (let c in counters) {
30422 counter = this.counters[c];
30423 this.processCounterIncrements(parsed, counter);
30424 this.processCounterResets(parsed, counter);
30425 if (c !== "page") {
30426 this.addCounterValues(parsed, counter);
30427 }
30428 }
30429 }
30430
30431 scopeCounters(counters) {
30432 let countersArray = [];
30433 for (let c in counters) {
30434 if(c !== "page") {
30435 countersArray.push(`${counters[c].name} 0`);
30436 }
30437 }
30438 // Add to pages to allow cross page scope
30439 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)}`);
30440 }
30441
30442 insertRule(rule) {
30443 this.styleSheet.insertRule(rule, this.styleSheet.cssRules.length);
30444 }
30445
30446 processCounterIncrements(parsed, counter) {
30447 let increment;
30448 for (let inc in counter.increments) {
30449 increment = counter.increments[inc];
30450 // Find elements for increments
30451 let incrementElements = parsed.querySelectorAll(increment.selector);
30452 // Add counter data
30453 for (let i = 0; i < incrementElements.length; i++) {
30454 incrementElements[i].setAttribute("data-counter-"+ counter.name +"-increment", increment.number);
30455 if (incrementElements[i].getAttribute("data-counter-increment")) {
30456 incrementElements[i].setAttribute("data-counter-increment", incrementElements[i].getAttribute("data-counter-increment") + " " + counter.name);
30457 } else {
30458 incrementElements[i].setAttribute("data-counter-increment", counter.name);
30459 }
30460 }
30461 }
30462 }
30463
30464 processCounterResets(parsed, counter) {
30465 let reset;
30466 for (let r in counter.resets) {
30467 reset = counter.resets[r];
30468 // Find elements for resets
30469 let resetElements = parsed.querySelectorAll(reset.selector);
30470 // Add counter data
30471 for (var i = 0; i < resetElements.length; i++) {
30472 let value = reset.number;
30473 if (typeof value === "string" && value.startsWith("--")) {
30474 // The value is specified using a CSS variable (custom property).
30475 // FIXME: We get the variable value only from the inline style of the element because at this point the
30476 // element is detached and thus using:
30477 //
30478 // getComputedStyle(resetElements[i]).getPropertyValue(value)
30479 //
30480 // always returns an empty string. We could try to temporarily attach the element to get its computed style,
30481 // but for now using the inline style is enough for us.
30482 value = resetElements[i].style.getPropertyValue(value) || 0;
30483 }
30484 resetElements[i].setAttribute("data-counter-"+ counter.name +"-reset", value);
30485 if (resetElements[i].getAttribute("data-counter-reset")) {
30486 resetElements[i].setAttribute("data-counter-reset", resetElements[i].getAttribute("data-counter-reset") + " " + counter.name);
30487 } else {
30488 resetElements[i].setAttribute("data-counter-reset", counter.name);
30489 }
30490 }
30491 }
30492 }
30493
30494 addCounterValues(parsed, counter) {
30495 let counterName = counter.name;
30496
30497 if (counterName === "page" || counterName === "footnote") {
30498 return;
30499 }
30500
30501 let elements = parsed.querySelectorAll("[data-counter-"+ counterName +"-reset], [data-counter-"+ counterName +"-increment]");
30502
30503 let count = 0;
30504 let element;
30505 let increment, reset;
30506 let resetValue, incrementValue, resetDelta;
30507 let incrementArray;
30508
30509 for (let i = 0; i < elements.length; i++) {
30510 element = elements[i];
30511 resetDelta = 0;
30512 incrementArray = [];
30513
30514 if (element.hasAttribute("data-counter-"+ counterName +"-reset")) {
30515 reset = element.getAttribute("data-counter-"+ counterName +"-reset");
30516 resetValue = parseInt(reset);
30517
30518 // Use negative increment value inplace of reset
30519 resetDelta = resetValue - count;
30520 incrementArray.push(`${counterName} ${resetDelta}`);
30521
30522 count = resetValue;
30523 }
30524
30525 if (element.hasAttribute("data-counter-"+ counterName +"-increment")) {
30526
30527 increment = element.getAttribute("data-counter-"+ counterName +"-increment");
30528 incrementValue = parseInt(increment);
30529
30530 count += incrementValue;
30531
30532 element.setAttribute("data-counter-"+counterName+"-value", count);
30533
30534 incrementArray.push(`${counterName} ${incrementValue}`);
30535 }
30536
30537 if (incrementArray.length > 0) {
30538 this.incrementCounterForElement(element, incrementArray);
30539 }
30540
30541 }
30542 }
30543
30544 addFootnoteMarkerCounter(list) {
30545 let markers = [];
30546 csstree.walk(list, {
30547 visit: "Identifier",
30548 enter: (identNode, iItem, iList) => {
30549 markers.push(identNode.name);
30550 }
30551 });
30552
30553 // Already added
30554 if (markers.includes("footnote-maker")) {
30555 return;
30556 }
30557
30558 list.insertData({
30559 type: "WhiteSpace",
30560 value: " "
30561 });
30562
30563 list.insertData({
30564 type: "Identifier",
30565 name: "footnote-marker"
30566 });
30567
30568 list.insertData({
30569 type: "WhiteSpace",
30570 value: " "
30571 });
30572
30573 list.insertData({
30574 type: "Number",
30575 value: 0
30576 });
30577 }
30578
30579 incrementCounterForElement(element, incrementArray) {
30580 if (!element || !incrementArray || incrementArray.length === 0) return;
30581
30582 const ref = element.dataset.ref;
30583 const increments = Array.from(this.styleSheet.cssRules).filter((rule) => {
30584 return rule.selectorText === `[data-ref="${element.dataset.ref}"]:not([data-split-from])`
30585 && rule.style[0] === "counter-increment";
30586 }).map(rule => rule.style.counterIncrement);
30587
30588 // Merge the current increments by summing the values because we generate both a decrement and an increment when the
30589 // element resets and increments the counter at the same time. E.g. ['c1 -7', 'c1 1'] should lead to 'c1 -6'.
30590 increments.push(this.mergeIncrements(incrementArray,
30591 (prev, next) => (parseInt(prev) || 0) + (parseInt(next) || 0)));
30592
30593 // Keep the last value for each counter when merging with the previous increments. E.g. ['c1 -7 c2 3', 'c1 1']
30594 // should lead to 'c1 1 c2 3'.
30595 const counterIncrement = this.mergeIncrements(increments, (prev, next) => next);
30596 this.insertRule(`[data-ref="${ref}"]:not([data-split-from]) { counter-increment: ${counterIncrement} }`);
30597 }
30598
30599 /**
30600 * Merge multiple values of a counter-increment CSS rule, using the specified operator.
30601 *
30602 * @param {Array} incrementArray the values to merge, e.g. ['c1 1', 'c1 -7 c2 1']
30603 * @param {Function} operator the function used to merge counter values (e.g. keep the last value of a counter or sum
30604 * the counter values)
30605 * @return {string} the merged value of the counter-increment CSS rule
30606 */
30607 mergeIncrements(incrementArray, operator) {
30608 const increments = {};
30609 incrementArray.forEach(increment => {
30610 let values = increment.split(" ");
30611 for (let i = 0; i < values.length; i+=2) {
30612 increments[values[i]] = operator(increments[values[i]], values[i + 1]);
30613 }
30614 });
30615
30616 return Object.entries(increments).map(([key, value]) => `${key} ${value}`).join(" ");
30617 }
30618
30619 afterPageLayout(pageElement, page) {
30620 let resets = [];
30621
30622 let pgreset = pageElement.querySelectorAll("[data-counter-page-reset]:not([data-split-from])");
30623 pgreset.forEach((reset) => {
30624 const ref = reset.dataset && reset.dataset.ref;
30625 if (ref && this.resetCountersMap.has(ref)) ; else {
30626 if (ref) {
30627 this.resetCountersMap.set(ref, "");
30628 }
30629 let value = reset.dataset.counterPageReset;
30630 resets.push(`page ${value}`);
30631 }
30632 });
30633
30634 let notereset = pageElement.querySelectorAll("[data-counter-footnote-reset]:not([data-split-from])");
30635 notereset.forEach((reset) => {
30636 let value = reset.dataset.counterFootnoteReset;
30637 resets.push(`footnote ${value}`);
30638 resets.push(`footnote-marker ${value}`);
30639 });
30640
30641 if (resets.length) {
30642 this.styleSheet.insertRule(`[data-page-number="${pageElement.dataset.pageNumber}"] { counter-increment: none; counter-reset: ${resets.join(" ")} }`, this.styleSheet.cssRules.length);
30643 }
30644 }
30645
30646 }
30647
30648 class Lists extends Handler {
30649 constructor(chunker, polisher, caller) {
30650 super(chunker, polisher, caller);
30651 }
30652 afterParsed(content) {
30653 const orderedLists = content.querySelectorAll("ol");
30654
30655 for (var list of orderedLists) {
30656 this.addDataNumbers(list);
30657 }
30658 }
30659
30660 afterPageLayout(pageElement, page, breakToken, chunker) {
30661 var orderedLists = pageElement.getElementsByTagName("ol");
30662 for (var list of orderedLists) {
30663 if (list.firstElementChild) {
30664 list.start = list.firstElementChild.dataset.itemNum;
30665 }
30666 }
30667 }
30668
30669 addDataNumbers(list) {
30670 let start = 1;
30671 if (list.hasAttribute("start")) {
30672 start = parseInt(list.getAttribute("start"), 10);
30673 if (isNaN(start)) {
30674 start = 1;
30675 }
30676 }
30677 let items = list.children;
30678 for (var i = 0; i < items.length; i++) {
30679 items[i].setAttribute("data-item-num", i + start);
30680 }
30681 }
30682
30683 }
30684
30685 class PositionFixed extends Handler {
30686 constructor(chunker, polisher, caller) {
30687 super(chunker, polisher, caller);
30688 this.styleSheet = polisher.styleSheet;
30689 this.fixedElementsSelector = [];
30690 this.fixedElements = [];
30691 }
30692
30693 onDeclaration(declaration, dItem, dList, rule) {
30694 if (declaration.property === "position" && declaration.value.children.first().name === "fixed") {
30695 let selector = csstree.generate(rule.ruleNode.prelude);
30696 this.fixedElementsSelector.push(selector);
30697 dList.remove(dItem);
30698 }
30699 }
30700
30701 afterParsed(fragment) {
30702 this.fixedElementsSelector.forEach(fixedEl => {
30703 fragment.querySelectorAll(`${fixedEl}`).forEach(el => {
30704 el.style.setProperty("position", "absolute");
30705 this.fixedElements.push(el);
30706 el.remove();
30707 });
30708 });
30709 }
30710
30711 afterPageLayout(pageElement, page, breakToken) {
30712 this.fixedElements.forEach(el => {
30713 const clone = el.cloneNode(true);
30714 pageElement.querySelector(".pagedjs_pagebox").insertAdjacentElement("afterbegin", clone);
30715 });
30716 }
30717 }
30718
30719 class PageCounterIncrement extends Handler {
30720 constructor(chunker, polisher, caller) {
30721 super(chunker, polisher, caller);
30722
30723 this.styleSheet = polisher.styleSheet;
30724 this.pageCounter = {
30725 name: "page",
30726 increments: {},
30727 resets: {}
30728 };
30729 }
30730
30731 onDeclaration(declaration, dItem, dList, rule) {
30732 const property = declaration.property;
30733
30734 if (property === "counter-increment") {
30735 let inc = this.handleIncrement(declaration, rule);
30736 if (inc) {
30737 dList.remove(dItem);
30738 }
30739 }
30740 }
30741
30742 afterParsed(_) {
30743 for (const inc in this.pageCounter.increments) {
30744 const increment = this.pageCounter.increments[inc];
30745 this.insertRule(`${increment.selector} { --pagedjs-page-counter-increment: ${increment.number} }`);
30746 }
30747 }
30748
30749 handleIncrement(declaration, rule) {
30750 const identifier = declaration.value.children.first();
30751 const number = declaration.value.children.getSize() > 1 ? declaration.value.children.last().value : 1;
30752 const name = identifier && identifier.name;
30753
30754 if (name && name.indexOf("target-counter-") === 0) {
30755 return;
30756 }
30757 // A counter named page is automatically created and incremented by 1 on every page of the document,
30758 // unless the counter-increment property in the page context explicitly specifies a different increment for the page counter.
30759 // https://www.w3.org/TR/css-page-3/#page-based-counters
30760 if (name !== "page") {
30761 return;
30762 }
30763 // the counter-increment property is not defined on the page context (i.e. @page rule), ignoring...
30764 if (rule.ruleNode.name === "page" && rule.ruleNode.type === "Atrule") {
30765 return;
30766 }
30767 const selector = csstree.generate(rule.ruleNode.prelude);
30768 return this.pageCounter.increments[selector] = {
30769 selector: selector,
30770 number
30771 };
30772 }
30773
30774 insertRule(rule) {
30775 this.styleSheet.insertRule(rule, this.styleSheet.cssRules.length);
30776 }
30777 }
30778
30779 class NthOfType extends Handler {
30780 constructor(chunker, polisher, caller) {
30781 super(chunker, polisher, caller);
30782
30783 this.styleSheet = polisher.styleSheet;
30784 this.selectors = {};
30785 }
30786
30787 onRule(ruleNode, ruleItem, rulelist) {
30788 let selector = csstree.generate(ruleNode.prelude);
30789 if (selector.match(/:(first|last|nth)-of-type/)) {
30790
30791 let declarations = csstree.generate(ruleNode.block);
30792 declarations = declarations.replace(/[{}]/g,"");
30793
30794 let uuid = "nth-of-type-" + UUID();
30795
30796 selector.split(",").forEach((s) => {
30797 if (!this.selectors[s]) {
30798 this.selectors[s] = [uuid, declarations];
30799 } else {
30800 this.selectors[s][1] = `${this.selectors[s][1]};${declarations}` ;
30801 }
30802 });
30803
30804 rulelist.remove(ruleItem);
30805 }
30806 }
30807
30808 afterParsed(parsed) {
30809 this.processSelectors(parsed, this.selectors);
30810 }
30811
30812 processSelectors(parsed, selectors) {
30813 // add the new attributes to matching elements
30814 for (let s in selectors) {
30815 let elements = parsed.querySelectorAll(s);
30816
30817 for (var i = 0; i < elements.length; i++) {
30818 let dataNthOfType = elements[i].getAttribute("data-nth-of-type");
30819
30820 if (dataNthOfType && dataNthOfType != "") {
30821 dataNthOfType = `${dataNthOfType},${selectors[s][0]}`;
30822 elements[i].setAttribute("data-nth-of-type", dataNthOfType);
30823 } else {
30824 elements[i].setAttribute("data-nth-of-type", selectors[s][0]);
30825 }
30826 }
30827
30828 let rule = `*[data-nth-of-type*='${selectors[s][0]}'] { ${selectors[s][1]}; }`;
30829 this.styleSheet.insertRule(rule, this.styleSheet.cssRules.length);
30830 }
30831 }
30832 }
30833
30834 class Following extends Handler {
30835 constructor(chunker, polisher, caller) {
30836 super(chunker, polisher, caller);
30837
30838 this.styleSheet = polisher.styleSheet;
30839 this.selectors = {};
30840 }
30841
30842 onRule(ruleNode, ruleItem, rulelist) {
30843 let selector = csstree.generate(ruleNode.prelude);
30844 if (selector.match(/\+/)) {
30845
30846 let declarations = csstree.generate(ruleNode.block);
30847 declarations = declarations.replace(/[{}]/g,"");
30848
30849 let uuid = "following-" + UUID();
30850
30851 selector.split(",").forEach((s) => {
30852 if (!this.selectors[s]) {
30853 this.selectors[s] = [uuid, declarations];
30854 } else {
30855 this.selectors[s][1] = `${this.selectors[s][1]};${declarations}` ;
30856 }
30857 });
30858
30859 rulelist.remove(ruleItem);
30860 }
30861 }
30862
30863 afterParsed(parsed) {
30864 this.processSelectors(parsed, this.selectors);
30865 }
30866
30867 processSelectors(parsed, selectors) {
30868 // add the new attributes to matching elements
30869 for (let s in selectors) {
30870 let elements = parsed.querySelectorAll(s);
30871
30872 for (var i = 0; i < elements.length; i++) {
30873 let dataFollowing = elements[i].getAttribute("data-following");
30874
30875 if (dataFollowing && dataFollowing != "") {
30876 dataFollowing = `${dataFollowing},${selectors[s][0]}`;
30877 elements[i].setAttribute("data-following", dataFollowing);
30878 } else {
30879 elements[i].setAttribute("data-following", selectors[s][0]);
30880 }
30881 }
30882
30883 let rule = `*[data-following*='${selectors[s][0]}'] { ${selectors[s][1]}; }`;
30884 this.styleSheet.insertRule(rule, this.styleSheet.cssRules.length);
30885 }
30886 }
30887 }
30888
30889 class Footnotes extends Handler {
30890 constructor(chunker, polisher, caller) {
30891 super(chunker, polisher, caller);
30892
30893 this.footnotes = {};
30894 this.needsLayout = [];
30895 }
30896
30897 onDeclaration(declaration, dItem, dList, rule) {
30898 let property = declaration.property;
30899 if (property === "float") {
30900 let identifier = declaration.value.children && declaration.value.children.first();
30901 let location = identifier && identifier.name;
30902 if (location === "footnote") {
30903 let selector = csstree.generate(rule.ruleNode.prelude);
30904 this.footnotes[selector] = {
30905 selector: selector,
30906 policy: "auto",
30907 display: "block"
30908 };
30909 dList.remove(dItem);
30910 }
30911 }
30912 if (property === "footnote-policy") {
30913 let identifier = declaration.value.children && declaration.value.children.first();
30914 let policy = identifier && identifier.name;
30915 if (policy) {
30916 let selector = csstree.generate(rule.ruleNode.prelude);
30917 let note = this.footnotes[selector];
30918 if (note) {
30919 note.policy = policy;
30920 }
30921 }
30922 }
30923 if (property === "footnote-display") {
30924 let identifier = declaration.value.children && declaration.value.children.first();
30925 let display = identifier && identifier.name;
30926 let selector = csstree.generate(rule.ruleNode.prelude);
30927 if (display && this.footnotes[selector]) {
30928 let note = this.footnotes[selector];
30929 if (note) {
30930 note.display = display;
30931 }
30932 }
30933 }
30934 }
30935
30936 onPseudoSelector(pseudoNode, pItem, pList, selector, rule) {
30937 let name = pseudoNode.name;
30938 if (name === "footnote-marker") {
30939 // switch ::footnote-marker to [data-footnote-marker]::before
30940 let prelude = rule.ruleNode.prelude;
30941 let newPrelude = new csstree.List();
30942
30943 // Can't get remove to work, so just copying everything else
30944 prelude.children.first().children.each((node) => {
30945 if (node.type !== "PseudoElementSelector") {
30946 newPrelude.appendData(node);
30947 }
30948 });
30949
30950 // Add our data call
30951 newPrelude.appendData({
30952 type: "AttributeSelector",
30953 name: {
30954 type: "Identifier",
30955 name: "data-footnote-marker",
30956 },
30957 flags: null,
30958 loc: null,
30959 matcher: null,
30960 value: null
30961 });
30962
30963 // Add new pseudo element
30964 newPrelude.appendData({
30965 type: "PseudoElementSelector",
30966 name: "marker",
30967 loc: null,
30968 children: null
30969 });
30970
30971 prelude.children.first().children = newPrelude;
30972 }
30973
30974 if (name === "footnote-call") {
30975 // switch ::footnote-call to [data-footnote-call]::after
30976
30977 let prelude = rule.ruleNode.prelude;
30978 let newPrelude = new csstree.List();
30979
30980 // Can't get remove to work, so just copying everything else
30981 prelude.children.first().children.each((node) => {
30982 if (node.type !== "PseudoElementSelector") {
30983 newPrelude.appendData(node);
30984 }
30985 });
30986
30987 // Add our data call
30988 newPrelude.appendData({
30989 type: "AttributeSelector",
30990 name: {
30991 type: "Identifier",
30992 name: "data-footnote-call",
30993 },
30994 flags: null,
30995 loc: null,
30996 matcher: null,
30997 value: null
30998 });
30999
31000 // Add new pseudo element
31001 newPrelude.appendData({
31002 type: "PseudoElementSelector",
31003 name: "after",
31004 loc: null,
31005 children: null
31006 });
31007
31008 prelude.children.first().children = newPrelude;
31009 }
31010 }
31011
31012 afterParsed(parsed) {
31013 this.processFootnotes(parsed, this.footnotes);
31014 }
31015
31016 processFootnotes(parsed, notes) {
31017 for (let n in notes) {
31018 // Find elements
31019 let elements = parsed.querySelectorAll(n);
31020 let element;
31021 let note = notes[n];
31022 for (var i = 0; i < elements.length; i++) {
31023 element = elements[i];
31024 // Add note type
31025 element.setAttribute("data-note", "footnote");
31026 element.setAttribute("data-break-before", "avoid");
31027 element.setAttribute("data-note-policy", note.policy || "auto");
31028 element.setAttribute("data-note-display", note.display || "block");
31029 // Mark all parents
31030 this.processFootnoteContainer(element);
31031 }
31032 }
31033 }
31034
31035 processFootnoteContainer(node) {
31036 // Find the container
31037 let element = node.parentElement;
31038 let prevElement = element;
31039 // Walk up the dom until we find a container element
31040 while (element) {
31041 if (isContainer(element)) {
31042 // Add flag to the previous non-container element that will render with children
31043 prevElement.setAttribute("data-has-notes", "true");
31044 break;
31045 }
31046
31047 prevElement = element;
31048 element = element.parentElement;
31049
31050 // If no containers were found and there are no further parents flag the last element
31051 if (!element) {
31052 prevElement.setAttribute("data-has-notes", "true");
31053 }
31054 }
31055 }
31056
31057 renderNode(node) {
31058 if (node.nodeType == 1) {
31059 // Get all notes
31060 let notes;
31061
31062 // Ingnore html element nodes, like mathml
31063 if (!node.dataset) {
31064 return;
31065 }
31066
31067 if (node.dataset.note === "footnote") {
31068 notes = [node];
31069 } else if (node.dataset.hasNotes || node.querySelectorAll("[data-note='footnote']")) {
31070 notes = node.querySelectorAll("[data-note='footnote']");
31071 }
31072
31073 if (notes && notes.length) {
31074 this.findVisibleFootnotes(notes, node);
31075 }
31076 }
31077 }
31078
31079 findVisibleFootnotes(notes, node) {
31080 let area, size, right;
31081 area = node.closest(".pagedjs_page_content");
31082 size = area.getBoundingClientRect();
31083 right = size.left + size.width;
31084
31085 for (let i = 0; i < notes.length; ++i) {
31086 let currentNote = notes[i];
31087 let bounds = currentNote.getBoundingClientRect();
31088 let left = bounds.left;
31089
31090 if (left < right) {
31091 // Add call for the note
31092 this.moveFootnote(currentNote, node.closest(".pagedjs_area"), true);
31093 }
31094 }
31095 }
31096
31097 moveFootnote(node, pageArea, needsNoteCall) {
31098 // let pageArea = node.closest(".pagedjs_area");
31099 let noteArea = pageArea.querySelector(".pagedjs_footnote_area");
31100 let noteContent = noteArea.querySelector(".pagedjs_footnote_content");
31101 let noteInnerContent = noteContent.querySelector(".pagedjs_footnote_inner_content");
31102
31103 if (!isElement(node)) {
31104 return;
31105 }
31106
31107 // Add call for the note
31108 let noteCall;
31109 if (needsNoteCall) {
31110 noteCall = this.createFootnoteCall(node);
31111 }
31112
31113 // Remove the break before attribute for future layout
31114 node.removeAttribute("data-break-before");
31115
31116 // Check if note already exists for overflow
31117 let existing = noteInnerContent.querySelector(`[data-ref="${node.dataset.ref}"]`);
31118 if (existing) {
31119 // Remove the note from the flow but no need to render it again
31120 node.remove();
31121 return;
31122 }
31123
31124 // Add the note node
31125 noteInnerContent.appendChild(node);
31126
31127 // Remove empty class
31128 if (noteContent.classList.contains("pagedjs_footnote_empty")) {
31129 noteContent.classList.remove("pagedjs_footnote_empty");
31130 }
31131
31132 // Add marker
31133 node.dataset.footnoteMarker = node.dataset.ref;
31134
31135 // Add Id
31136 node.id = `note-${node.dataset.ref}`;
31137
31138 // Get note content size
31139 let height = noteContent.scrollHeight;
31140
31141 // Check the noteCall is still on screen
31142 let area = pageArea.querySelector(".pagedjs_page_content");
31143 let size = area.getBoundingClientRect();
31144 let right = size.left + size.width;
31145
31146 // TODO: add a max height in CSS
31147
31148 // Check element sizes
31149 let noteCallBounds = noteCall && noteCall.getBoundingClientRect();
31150 let noteAreaBounds = noteArea.getBoundingClientRect();
31151
31152 // Get the @footnote margins
31153 let noteContentMargins = this.marginsHeight(noteContent);
31154 let noteContentPadding = this.paddingHeight(noteContent);
31155 let noteContentBorders = this.borderHeight(noteContent);
31156 let total = noteContentMargins + noteContentPadding + noteContentBorders;
31157
31158 // Get the top of the @footnote area
31159 let notAreaTop = Math.floor(noteAreaBounds.top);
31160 // If the height isn't set yet, remove the margins from the top
31161 if (noteAreaBounds.height === 0) {
31162 notAreaTop -= this.marginsHeight(noteContent, false);
31163 notAreaTop -= this.paddingHeight(noteContent, false);
31164 notAreaTop -= this.borderHeight(noteContent, false);
31165 }
31166 // Determine the note call position and offset per policy
31167 let notePolicy = node.dataset.notePolicy;
31168 let noteCallPosition = 0;
31169 let noteCallOffset = 0;
31170 if (noteCall) {
31171 // Get the correct line bottom for super or sub styled callouts
31172 let prevSibling = noteCall.previousSibling;
31173 let range = new Range();
31174 if (prevSibling) {
31175 range.setStartBefore(prevSibling);
31176 } else {
31177 range.setStartBefore(noteCall);
31178 }
31179 range.setEndAfter(noteCall);
31180 let rangeBounds = range.getBoundingClientRect();
31181 noteCallPosition = rangeBounds.bottom;
31182 if (!notePolicy || notePolicy === "auto") {
31183 noteCallOffset = Math.ceil(rangeBounds.bottom);
31184 } else if (notePolicy === "line") {
31185 noteCallOffset = Math.ceil(rangeBounds.top);
31186 } else if (notePolicy === "block") {
31187 // Check that there is a previous element on the page
31188 let parentParagraph = noteCall.closest("p").previousElementSibling;
31189 if (parentParagraph) {
31190 noteCallOffset = Math.ceil(
31191 parentParagraph.getBoundingClientRect().bottom
31192 );
31193 } else {
31194 noteCallOffset = Math.ceil(rangeBounds.bottom);
31195 }
31196 }
31197 }
31198
31199 let contentDelta = height + total - noteAreaBounds.height;
31200 // Space between the top of the footnotes area and the bottom of the footnote call
31201 let noteDelta = noteCallPosition ? notAreaTop - noteCallPosition : 0;
31202 // Space needed for the force a break for the policy of the footnote
31203 let notePolicyDelta = noteCallPosition ? Math.floor(noteAreaBounds.top) - noteCallOffset : 0;
31204 let hasNotes = noteArea.querySelector("[data-note='footnote']");
31205 if (needsNoteCall && noteCallBounds.left > right) {
31206 // Note is offscreen and will be chunked to the next page on overflow
31207 node.remove();
31208 } else if (!hasNotes && needsNoteCall && total > noteDelta) {
31209 // No space to add even the footnote area
31210 pageArea.style.setProperty("--pagedjs-footnotes-height", "0px");
31211 // Add a wrapper as this div is removed later
31212 let wrapperDiv = document.createElement("div");
31213 wrapperDiv.appendChild(node);
31214 // Push to the layout queue for the next page
31215 this.needsLayout.push(wrapperDiv);
31216 } else if (!needsNoteCall) {
31217 // Call was previously added, force adding footnote
31218 pageArea.style.setProperty(
31219 "--pagedjs-footnotes-height",
31220 `${height + total}px`
31221 );
31222 } else if (noteCallPosition < noteAreaBounds.top - contentDelta) {
31223 // the current note content will fit without pushing the call to the next page
31224 pageArea.style.setProperty(
31225 "--pagedjs-footnotes-height",
31226 `${height + noteContentMargins + noteContentBorders}px`
31227 );
31228 } else {
31229 // set height to just before note call
31230 pageArea.style.setProperty(
31231 "--pagedjs-footnotes-height",
31232 `${noteAreaBounds.height + notePolicyDelta}px`
31233 );
31234 noteInnerContent.style.height =
31235 noteAreaBounds.height + notePolicyDelta - total + "px";
31236 }
31237 }
31238
31239 createFootnoteCall(node) {
31240 let parentElement = node.parentElement;
31241 let footnoteCall = document.createElement("a");
31242 for (const className of node.classList) {
31243 footnoteCall.classList.add(`${className}`);
31244 }
31245
31246 footnoteCall.dataset.footnoteCall = node.dataset.ref;
31247 footnoteCall.dataset.ref = node.dataset.ref;
31248
31249 // Increment for counters
31250 footnoteCall.dataset.dataCounterFootnoteIncrement = 1;
31251
31252 // Add link
31253 footnoteCall.href = `#note-${node.dataset.ref}`;
31254
31255 parentElement.insertBefore(footnoteCall, node);
31256
31257 return footnoteCall;
31258 }
31259
31260 afterPageLayout(pageElement, page, breakToken, chunker) {
31261 let pageArea = pageElement.querySelector(".pagedjs_area");
31262 let noteArea = page.footnotesArea;
31263 let noteContent = noteArea.querySelector(".pagedjs_footnote_content");
31264 let noteInnerContent = noteArea.querySelector(".pagedjs_footnote_inner_content");
31265
31266 let noteContentBounds = noteContent.getBoundingClientRect();
31267 let { width } = noteContentBounds;
31268
31269 noteInnerContent.style.columnWidth = Math.round(width) + "px";
31270 noteInnerContent.style.columnGap = "calc(var(--pagedjs-margin-right) + var(--pagedjs-margin-left))";
31271
31272 // Get overflow
31273 let layout = new Layout(noteArea, undefined, chunker.settings);
31274 let overflow = layout.findOverflow(noteInnerContent, noteContentBounds);
31275
31276 if (overflow) {
31277 let { startContainer, startOffset } = overflow;
31278 let startIsNode;
31279 if (isElement(startContainer)) {
31280 let start = startContainer.childNodes[startOffset];
31281 startIsNode = isElement(start) && start.hasAttribute("data-footnote-marker");
31282 }
31283
31284 let extracted = overflow.extractContents();
31285
31286 if (!startIsNode) {
31287 let splitChild = extracted.firstElementChild;
31288 splitChild.dataset.splitFrom = splitChild.dataset.ref;
31289
31290 this.handleAlignment(noteInnerContent.lastElementChild);
31291 }
31292
31293 this.needsLayout.push(extracted);
31294
31295 noteContent.style.removeProperty("height");
31296 noteInnerContent.style.removeProperty("height");
31297
31298 let noteInnerContentBounds = noteInnerContent.getBoundingClientRect();
31299 let { height } = noteInnerContentBounds;
31300
31301 // Get the @footnote margins
31302 let noteContentMargins = this.marginsHeight(noteContent);
31303 let noteContentPadding = this.paddingHeight(noteContent);
31304 let noteContentBorders = this.borderHeight(noteContent);
31305 pageArea.style.setProperty(
31306 "--pagedjs-footnotes-height",
31307 `${height + noteContentMargins + noteContentBorders + noteContentPadding}px`
31308 );
31309
31310 // Hide footnote content if empty
31311 if (noteInnerContent.childNodes.length === 0) {
31312 noteContent.classList.add("pagedjs_footnote_empty");
31313 }
31314
31315 if (!breakToken) {
31316 chunker.clonePage(page);
31317 } else {
31318 let breakBefore, previousBreakAfter;
31319 if (
31320 breakToken.node &&
31321 typeof breakToken.node.dataset !== "undefined" &&
31322 typeof breakToken.node.dataset.previousBreakAfter !== "undefined"
31323 ) {
31324 previousBreakAfter = breakToken.node.dataset.previousBreakAfter;
31325 }
31326
31327 if (
31328 breakToken.node &&
31329 typeof breakToken.node.dataset !== "undefined" &&
31330 typeof breakToken.node.dataset.breakBefore !== "undefined"
31331 ) {
31332 breakBefore = breakToken.node.dataset.breakBefore;
31333 }
31334
31335 if (breakBefore || previousBreakAfter) {
31336 chunker.clonePage(page);
31337 }
31338 }
31339 }
31340 noteInnerContent.style.height = "auto";
31341 }
31342
31343 handleAlignment(node) {
31344 let styles = window.getComputedStyle(node);
31345 let alignLast = styles["text-align-last"];
31346 node.dataset.lastSplitElement = "true";
31347 if (alignLast === "auto") {
31348 node.dataset.alignLastSplitElement = "justify";
31349 } else {
31350 node.dataset.alignLastSplitElement = alignLast;
31351 }
31352 }
31353
31354 beforePageLayout(page) {
31355 while (this.needsLayout.length) {
31356 let fragment = this.needsLayout.shift();
31357
31358 Array.from(fragment.childNodes).forEach((node) => {
31359 this.moveFootnote(
31360 node,
31361 page.element.querySelector(".pagedjs_area"),
31362 false
31363 );
31364 });
31365 }
31366 }
31367
31368 afterOverflowRemoved(removed, rendered) {
31369 // Find the page area
31370 let area = rendered.closest(".pagedjs_area");
31371 // Get any rendered footnotes
31372 let notes = area.querySelectorAll(".pagedjs_footnote_area [data-note='footnote']");
31373 for (let n = 0; n < notes.length; n++) {
31374 const note = notes[n];
31375 // Check if the call for that footnote has been removed with the overflow
31376 let call = removed.querySelector(`[data-footnote-call="${note.dataset.ref}"]`);
31377 if (call) {
31378 note.remove();
31379 }
31380 }
31381 // Hide footnote content if empty
31382 let noteInnerContent = area.querySelector(".pagedjs_footnote_inner_content");
31383 if (noteInnerContent && noteInnerContent.childNodes.length === 0) {
31384 noteInnerContent.parentElement.classList.add("pagedjs_footnote_empty");
31385 }
31386 }
31387
31388 marginsHeight(element, total=true) {
31389 let styles = window.getComputedStyle(element);
31390 let marginTop = parseInt(styles.marginTop);
31391 let marginBottom = parseInt(styles.marginBottom);
31392 let margin = 0;
31393 if (marginTop) {
31394 margin += marginTop;
31395 }
31396 if (marginBottom && total) {
31397 margin += marginBottom;
31398 }
31399 return margin;
31400 }
31401
31402 paddingHeight(element, total=true) {
31403 let styles = window.getComputedStyle(element);
31404 let paddingTop = parseInt(styles.paddingTop);
31405 let paddingBottom = parseInt(styles.paddingBottom);
31406 let padding = 0;
31407 if (paddingTop) {
31408 padding += paddingTop;
31409 }
31410 if (paddingBottom && total) {
31411 padding += paddingBottom;
31412 }
31413 return padding;
31414 }
31415
31416 borderHeight(element, total=true) {
31417 let styles = window.getComputedStyle(element);
31418 let borderTop = parseInt(styles.borderTop);
31419 let borderBottom = parseInt(styles.borderBottom);
31420 let borders = 0;
31421 if (borderTop) {
31422 borders += borderTop;
31423 }
31424 if (borderBottom && total) {
31425 borders += borderBottom;
31426 }
31427 return borders;
31428 }
31429 }
31430
31431 var pagedMediaHandlers = [
31432 PrintMedia,
31433 AtPage,
31434 Breaks,
31435 Splits,
31436 Counters,
31437 Lists,
31438 PositionFixed,
31439 PageCounterIncrement,
31440 NthOfType,
31441 Following,
31442 Footnotes
31443 ];
31444
31445 class RunningHeaders extends Handler {
31446 constructor(chunker, polisher, caller) {
31447 super(chunker, polisher, caller);
31448
31449 this.runningSelectors = {};
31450 this.elements = {};
31451 }
31452
31453 onDeclaration(declaration, dItem, dList, rule) {
31454 if (declaration.property === "position") {
31455 let selector = csstree.generate(rule.ruleNode.prelude);
31456 let identifier = declaration.value.children.first().name;
31457
31458 if (identifier === "running") {
31459 let value;
31460 csstree.walk(declaration, {
31461 visit: "Function",
31462 enter: (node, item, list) => {
31463 value = node.children.first().name;
31464 }
31465 });
31466
31467 this.runningSelectors[value] = {
31468 identifier: identifier,
31469 value: value,
31470 selector: selector
31471 };
31472 }
31473 }
31474
31475 if (declaration.property === "content") {
31476
31477 csstree.walk(declaration, {
31478 visit: "Function",
31479 enter: (funcNode, fItem, fList) => {
31480
31481 if (funcNode.name.indexOf("element") > -1) {
31482
31483 let selector = csstree.generate(rule.ruleNode.prelude);
31484
31485 let func = funcNode.name;
31486
31487 let value = funcNode.children.first().name;
31488
31489 let args = [value];
31490
31491 // we only handle first for now
31492 let style = "first";
31493
31494 selector.split(",").forEach((s) => {
31495 // remove before / after
31496 s = s.replace(/::after|::before/, "");
31497
31498 this.elements[s] = {
31499 func: func,
31500 args: args,
31501 value: value,
31502 style: style ,
31503 selector: s,
31504 fullSelector: selector
31505 };
31506 });
31507 }
31508
31509 }
31510 });
31511 }
31512 }
31513
31514 afterParsed(fragment) {
31515 for (let name of Object.keys(this.runningSelectors)) {
31516 let set = this.runningSelectors[name];
31517 let selected = Array.from(fragment.querySelectorAll(set.selector));
31518
31519 if (set.identifier === "running") {
31520 for (let header of selected) {
31521 header.style.display = "none";
31522 }
31523 }
31524
31525 }
31526 }
31527
31528 afterPageLayout(fragment) {
31529 for (let name of Object.keys(this.runningSelectors)) {
31530 let set = this.runningSelectors[name];
31531 let selected = fragment.querySelector(set.selector);
31532 if (selected) {
31533 // let cssVar;
31534 if (set.identifier === "running") {
31535 // cssVar = selected.textContent.replace(/\\([\s\S])|(["|'])/g,"\\$1$2");
31536 // this.styleSheet.insertRule(`:root { --string-${name}: "${cssVar}"; }`, this.styleSheet.cssRules.length);
31537 // fragment.style.setProperty(`--string-${name}`, `"${cssVar}"`);
31538 set.first = selected;
31539 } else {
31540 console.warn(set.value + "needs css replacement");
31541 }
31542 }
31543 }
31544
31545 // move elements
31546 if (!this.orderedSelectors) {
31547 this.orderedSelectors = this.orderSelectors(this.elements);
31548 }
31549
31550 for (let selector of this.orderedSelectors) {
31551 if (selector) {
31552
31553 let el = this.elements[selector];
31554 let selected = fragment.querySelector(selector);
31555 if (selected) {
31556 let running = this.runningSelectors[el.args[0]];
31557 if (running && running.first) {
31558 selected.innerHTML = ""; // Clear node
31559 // selected.classList.add("pagedjs_clear-after"); // Clear ::after
31560 let clone = running.first.cloneNode(true);
31561 clone.style.display = null;
31562 selected.appendChild(clone);
31563 }
31564 }
31565 }
31566 }
31567 }
31568
31569 /**
31570 * Assign a weight to @page selector classes
31571 * 1) page
31572 * 2) left & right
31573 * 3) blank
31574 * 4) first & nth
31575 * 5) named page
31576 * 6) named left & right
31577 * 7) named first & nth
31578 * @param {string} [s] selector string
31579 * @return {int} weight
31580 */
31581 pageWeight(s) {
31582 let weight = 1;
31583 let selector = s.split(" ");
31584 let parts = selector.length && selector[0].split(".");
31585
31586 parts.shift(); // remove empty first part
31587
31588 switch (parts.length) {
31589 case 4:
31590 if (/^pagedjs_[\w-]+_first_page$/.test(parts[3])) {
31591 weight = 7;
31592 } else if (parts[3] === "pagedjs_left_page" || parts[3] === "pagedjs_right_page") {
31593 weight = 6;
31594 }
31595 break;
31596 case 3:
31597 if (parts[1] === "pagedjs_named_page") {
31598 if (parts[2].indexOf(":nth-of-type") > -1) {
31599 weight = 7;
31600 } else {
31601 weight = 5;
31602 }
31603 }
31604 break;
31605 case 2:
31606 if (parts[1] === "pagedjs_first_page") {
31607 weight = 4;
31608 } else if (parts[1] === "pagedjs_blank_page") {
31609 weight = 3;
31610 } else if (parts[1] === "pagedjs_left_page" || parts[1] === "pagedjs_right_page") {
31611 weight = 2;
31612 }
31613 break;
31614 default:
31615 if (parts[0].indexOf(":nth-of-type") > -1) {
31616 weight = 4;
31617 } else {
31618 weight = 1;
31619 }
31620 }
31621
31622 return weight;
31623 }
31624
31625 /**
31626 * Orders the selectors based on weight
31627 *
31628 * Does not try to deduplicate base on specifity of the selector
31629 * Previous matched selector will just be overwritten
31630 * @param {obj} [obj] selectors object
31631 * @return {Array} orderedSelectors
31632 */
31633 orderSelectors(obj) {
31634 let selectors = Object.keys(obj);
31635 let weighted = {
31636 1: [],
31637 2: [],
31638 3: [],
31639 4: [],
31640 5: [],
31641 6: [],
31642 7: []
31643 };
31644
31645 let orderedSelectors = [];
31646
31647 for (let s of selectors) {
31648 let w = this.pageWeight(s);
31649 weighted[w].unshift(s);
31650 }
31651
31652 for (var i = 1; i <= 7; i++) {
31653 orderedSelectors = orderedSelectors.concat(weighted[i]);
31654 }
31655
31656 return orderedSelectors;
31657 }
31658
31659 beforeTreeParse(text, sheet) {
31660 // element(x) is parsed as image element selector, so update element to element-ident
31661 sheet.text = text.replace(/element[\s]*\(([^|^#)]*)\)/g, "element-ident($1)");
31662 }
31663 }
31664
31665 function cleanPseudoContent(el, trim = "\"' ") {
31666 if(el == null) return;
31667 return el
31668 .replace(new RegExp(`^[${trim}]+`), "")
31669 .replace(new RegExp(`[${trim}]+$`), "")
31670 .replace(/["']/g, match => {
31671 return "\\" + match;
31672 })
31673 .replace(/[\n]/g, match => {
31674 return "\\00000A";
31675 });
31676 }
31677
31678 function cleanSelector(el) {
31679 if(el == null) return;
31680 return el
31681 .replace(new RegExp("::footnote-call", "g"), "")
31682 .replace(new RegExp("::footnote-marker", "g"), "");
31683 }
31684
31685 class StringSets extends Handler {
31686 constructor(chunker, polisher, caller) {
31687 super(chunker, polisher, caller);
31688
31689 this.stringSetSelectors = {};
31690 this.type;
31691 // pageLastString = last string variable defined on the page
31692 this.pageLastString;
31693
31694 }
31695
31696 onDeclaration(declaration, dItem, dList, rule) {
31697 if (declaration.property === "string-set") {
31698 let selector = csstree.generate(rule.ruleNode.prelude);
31699
31700 let identifiers = [];
31701 let functions = [];
31702 let values = [];
31703
31704 declaration.value.children.forEach((child) => {
31705 if (child.type === "Identifier") {
31706 identifiers.push(child.name);
31707 }
31708 if (child.type === "Function") {
31709 functions.push(child.name);
31710 child.children.forEach((subchild) => {
31711 if (subchild.type === "Identifier") {
31712 values.push(subchild.name);
31713 }
31714 });
31715 }
31716 });
31717
31718 identifiers.forEach((identifier, index) => {
31719 let func = functions[index];
31720 let value = values[index];
31721 this.stringSetSelectors[identifier] = {
31722 identifier,
31723 func,
31724 value,
31725 selector
31726 };
31727 });
31728
31729 }
31730 }
31731
31732 onContent(funcNode, fItem, fList, declaration, rule) {
31733
31734 if (funcNode.name === "string") {
31735 let identifier = funcNode.children && funcNode.children.first().name;
31736 this.type = funcNode.children.last().name;
31737 funcNode.name = "var";
31738 funcNode.children = new csstree.List();
31739
31740
31741 if(this.type === "first" || this.type === "last" || this.type === "start" || this.type === "first-except"){
31742 funcNode.children.append(
31743 funcNode.children.createItem({
31744 type: "Identifier",
31745 loc: null,
31746 name: "--pagedjs-string-" + this.type + "-" + identifier
31747 })
31748 );
31749 }else {
31750 funcNode.children.append(
31751 funcNode.children.createItem({
31752 type: "Identifier",
31753 loc: null,
31754 name: "--pagedjs-string-first-" + identifier
31755 })
31756 );
31757 }
31758 }
31759 }
31760
31761 afterPageLayout(fragment) {
31762
31763
31764 if ( this.pageLastString === undefined )
31765 {
31766 this.pageLastString = {};
31767 }
31768
31769
31770 for (let name of Object.keys(this.stringSetSelectors)) {
31771
31772 let set = this.stringSetSelectors[name];
31773 let value = set.value;
31774 let func = set.func;
31775 let selected = fragment.querySelectorAll(set.selector);
31776
31777 // Get the last found string for the current identifier
31778 let stringPrevPage = ( name in this.pageLastString ) ? this.pageLastString[name] : "";
31779
31780 let varFirst, varLast, varStart, varFirstExcept;
31781
31782 if(selected.length == 0){
31783 // if there is no sel. on the page
31784 varFirst = stringPrevPage;
31785 varLast = stringPrevPage;
31786 varStart = stringPrevPage;
31787 varFirstExcept = stringPrevPage;
31788 }else {
31789
31790 selected.forEach((sel) => {
31791 // push each content into the array to define in the variable the first and the last element of the page.
31792 if (func === "content") {
31793 this.pageLastString[name] = selected[selected.length - 1].textContent;
31794 }
31795
31796 if (func === "attr") {
31797 this.pageLastString[name] = selected[selected.length - 1].getAttribute(value) || "";
31798 }
31799
31800 });
31801
31802 /* FIRST */
31803
31804 if (func === "content") {
31805 varFirst = selected[0].textContent;
31806 }
31807
31808 if (func === "attr") {
31809 varFirst = selected[0].getAttribute(value) || "";
31810 }
31811
31812
31813 /* LAST */
31814
31815 if (func === "content") {
31816 varLast = selected[selected.length - 1].textContent;
31817 }
31818
31819 if (func === "attr") {
31820 varLast = selected[selected.length - 1].getAttribute(value) || "";
31821 }
31822
31823
31824 /* START */
31825
31826 // Hack to find if the sel. is the first elem of the page / find a better way
31827 let selTop = selected[0].getBoundingClientRect().top;
31828 let pageContent = selected[0].closest(".pagedjs_page_content");
31829 let pageContentTop = pageContent.getBoundingClientRect().top;
31830
31831 if(selTop == pageContentTop){
31832 varStart = varFirst;
31833 }else {
31834 varStart = stringPrevPage;
31835 }
31836
31837 /* FIRST EXCEPT */
31838
31839 varFirstExcept = "";
31840
31841 }
31842
31843 fragment.style.setProperty(`--pagedjs-string-first-${name}`, `"${cleanPseudoContent(varFirst)}`);
31844 fragment.style.setProperty(`--pagedjs-string-last-${name}`, `"${cleanPseudoContent(varLast)}`);
31845 fragment.style.setProperty(`--pagedjs-string-start-${name}`, `"${cleanPseudoContent(varStart)}`);
31846 fragment.style.setProperty(`--pagedjs-string-first-except-${name}`, `"${cleanPseudoContent(varFirstExcept)}`);
31847
31848
31849 }
31850 }
31851
31852
31853 }
31854
31855 class TargetCounters extends Handler {
31856 constructor(chunker, polisher, caller) {
31857 super(chunker, polisher, caller);
31858
31859 this.styleSheet = polisher.styleSheet;
31860
31861 this.counterTargets = {};
31862 }
31863
31864 onContent(funcNode, fItem, fList, declaration, rule) {
31865 if (funcNode.name === "target-counter") {
31866 let selector = csstree.generate(rule.ruleNode.prelude);
31867
31868 let first = funcNode.children.first();
31869 let func = first.name;
31870
31871 let value = csstree.generate(funcNode);
31872
31873 let args = [];
31874
31875 first.children.forEach((child) => {
31876 if (child.type === "Identifier") {
31877
31878 args.push(child.name);
31879 }
31880 });
31881
31882 let counter;
31883 let style;
31884 let styleIdentifier;
31885
31886 funcNode.children.forEach((child) => {
31887 if (child.type === "Identifier") {
31888 if (!counter) {
31889 counter = child.name;
31890 } else if (!style) {
31891 styleIdentifier = csstree.clone(child);
31892 style = child.name;
31893 }
31894 }
31895 });
31896
31897 let variable = "target-counter-" + UUID();
31898
31899 selector.split(",").forEach((s) => {
31900 this.counterTargets[s] = {
31901 func: func,
31902 args: args,
31903 value: value,
31904 counter: counter,
31905 style: style,
31906 selector: s,
31907 fullSelector: selector,
31908 variable: variable
31909 };
31910 });
31911
31912 // Replace with counter
31913 funcNode.name = "counter";
31914 funcNode.children = new csstree.List();
31915 funcNode.children.appendData({
31916 type: "Identifier",
31917 loc: 0,
31918 name: variable
31919 });
31920
31921 if (styleIdentifier) {
31922 funcNode.children.appendData({type: "Operator", loc: null, value: ","});
31923 funcNode.children.appendData(styleIdentifier);
31924 }
31925 }
31926 }
31927
31928 afterPageLayout(fragment, page, breakToken, chunker) {
31929 Object.keys(this.counterTargets).forEach((name) => {
31930 let target = this.counterTargets[name];
31931 let split = target.selector.split(/::?/g);
31932 let query = split[0];
31933
31934 let queried = chunker.pagesArea.querySelectorAll(query + ":not([data-" + target.variable + "])");
31935
31936 queried.forEach((selected, index) => {
31937 // TODO: handle func other than attr
31938 if (target.func !== "attr") {
31939 return;
31940 }
31941 let val = attr(selected, target.args);
31942 let element = chunker.pagesArea.querySelector(querySelectorEscape(val));
31943
31944 if (element) {
31945 let selector = UUID();
31946 selected.setAttribute("data-" + target.variable, selector);
31947 // TODO: handle other counter types (by query)
31948 let pseudo = "";
31949 if (split.length > 1) {
31950 pseudo += "::" + split[1];
31951 }
31952 if (target.counter === "page") {
31953 let pages = chunker.pagesArea.querySelectorAll(".pagedjs_page");
31954 let pg = 0;
31955 for (let i = 0; i < pages.length; i++) {
31956 let page = pages[i];
31957 let styles = window.getComputedStyle(page);
31958 let reset = styles["counter-reset"].replace("page", "").trim();
31959 let increment = styles["counter-increment"].replace("page", "").trim();
31960
31961 if (reset !== "none") {
31962 pg = parseInt(reset);
31963 }
31964 if (increment !== "none") {
31965 pg += parseInt(increment);
31966 }
31967
31968 if (page.contains(element)){
31969 break;
31970 }
31971 }
31972 this.styleSheet.insertRule(`[data-${target.variable}="${selector}"]${pseudo} { counter-reset: ${target.variable} ${pg}; }`, this.styleSheet.cssRules.length);
31973 } else {
31974 let value = element.getAttribute(`data-counter-${target.counter}-value`);
31975 if (value) {
31976 this.styleSheet.insertRule(`[data-${target.variable}="${selector}"]${pseudo} { counter-reset: ${target.variable} ${target.variable} ${parseInt(value)}; }`, this.styleSheet.cssRules.length);
31977 }
31978 }
31979
31980 // force redraw
31981 let el = document.querySelector(`[data-${target.variable}="${selector}"]`);
31982 if (el) {
31983 el.style.display = "none";
31984 el.clientHeight;
31985 el.style.removeProperty("display");
31986 }
31987 }
31988 });
31989 });
31990 }
31991 }
31992
31993 // import { nodeAfter } from "../../utils/dom";
31994
31995 class TargetText extends Handler {
31996 constructor(chunker, polisher, caller) {
31997 super(chunker, polisher, caller);
31998
31999 this.styleSheet = polisher.styleSheet;
32000 this.textTargets = {};
32001 this.beforeContent = "";
32002 this.afterContent = "";
32003 this.selector = {};
32004 }
32005
32006 onContent(funcNode, fItem, fList, declaration, rule) {
32007 if (funcNode.name === "target-text") {
32008 this.selector = csstree.generate(rule.ruleNode.prelude);
32009 let first = funcNode.children.first();
32010 let last = funcNode.children.last();
32011 let func = first.name;
32012
32013 let value = csstree.generate(funcNode);
32014
32015 let args = [];
32016
32017 first.children.forEach(child => {
32018 if (child.type === "Identifier") {
32019 args.push(child.name);
32020 }
32021 });
32022
32023 let style;
32024 if (last !== first) {
32025 style = last.name;
32026 }
32027
32028 let variable = "--pagedjs-" + UUID();
32029
32030 this.selector.split(",").forEach(s => {
32031 this.textTargets[s] = {
32032 func: func,
32033 args: args,
32034 value: value,
32035 style: style || "content",
32036 selector: s,
32037 fullSelector: this.selector,
32038 variable: variable
32039 };
32040 });
32041
32042 // Replace with variable
32043 funcNode.name = "var";
32044 funcNode.children = new csstree.List();
32045 funcNode.children.appendData({
32046 type: "Identifier",
32047 loc: 0,
32048 name: variable
32049 });
32050 }
32051 }
32052
32053 // parse this on the ONCONTENT : get all before and after and replace the value with a variable
32054 onPseudoSelector(pseudoNode, pItem, pList, selector, rule) {
32055 // console.log(pseudoNode);
32056 // console.log(rule);
32057
32058 rule.ruleNode.block.children.forEach(properties => {
32059 if (pseudoNode.name === "before" && properties.property === "content") {
32060 // let beforeVariable = "--pagedjs-" + UUID();
32061
32062 let contenu = properties.value.children;
32063 contenu.forEach(prop => {
32064 if (prop.type === "String") {
32065 this.beforeContent = prop.value;
32066 }
32067 });
32068 } else if (pseudoNode.name === "after" && properties.property === "content") {
32069 properties.value.children.forEach(prop => {
32070 if (prop.type === "String") {
32071 this.afterContent = prop.value;
32072 }
32073 });
32074 }
32075 });
32076 }
32077
32078 afterParsed(fragment) {
32079 Object.keys(this.textTargets).forEach(name => {
32080 let target = this.textTargets[name];
32081 let split = target.selector.split("::");
32082 let query = split[0];
32083 let queried = fragment.querySelectorAll(query);
32084 let textContent;
32085 queried.forEach((selected, index) => {
32086 let val = attr(selected, target.args);
32087 let element = fragment.querySelector(querySelectorEscape(val));
32088 if (element) {
32089 // content & first-letter & before & after refactorized
32090 if (target.style) {
32091 this.selector = UUID();
32092 selected.setAttribute("data-target-text", this.selector);
32093
32094 let psuedo = "";
32095 if (split.length > 1) {
32096 psuedo += "::" + split[1];
32097 }
32098
32099 if (target.style === "before" || target.style === "after") {
32100 const pseudoType = `${target.style}Content`;
32101 textContent = cleanPseudoContent(this[pseudoType]);
32102 } else {
32103 textContent = cleanPseudoContent(element.textContent, " ");
32104 }
32105 textContent = target.style === "first-letter" ? textContent.charAt(0) : textContent;
32106 this.styleSheet.insertRule(`[data-target-text="${this.selector}"]${psuedo} { ${target.variable}: "${textContent}" }`);
32107 } else {
32108 console.warn("missed target", val);
32109 }
32110 }
32111 });
32112 });
32113 }
32114 }
32115
32116 var generatedContentHandlers = [
32117 RunningHeaders,
32118 StringSets,
32119 TargetCounters,
32120 TargetText
32121 ];
32122
32123 class WhiteSpaceFilter extends Handler {
32124 constructor(chunker, polisher, caller) {
32125 super(chunker, polisher, caller);
32126 }
32127
32128 filter(content) {
32129
32130 filterTree(content, (node) => {
32131 return this.filterEmpty(node);
32132 }, NodeFilter.SHOW_TEXT);
32133
32134 }
32135
32136 filterEmpty(node) {
32137 if (node.textContent.length > 1 && isIgnorable(node)) {
32138
32139 // Do not touch the content if text is pre-formatted
32140 let parent = node.parentNode;
32141 let pre = isElement(parent) && parent.closest("pre");
32142 if (pre) {
32143 return NodeFilter.FILTER_REJECT;
32144 }
32145
32146 const previousSibling = previousSignificantNode(node);
32147 const nextSibling = nextSignificantNode(node);
32148
32149 if (nextSibling === null && previousSibling === null) {
32150 // we should not remove a Node that does not have any siblings.
32151 node.textContent = " ";
32152 return NodeFilter.FILTER_REJECT;
32153 }
32154 if (nextSibling === null) {
32155 // we can safely remove this node
32156 return NodeFilter.FILTER_ACCEPT;
32157 }
32158 if (previousSibling === null) {
32159 // we can safely remove this node
32160 return NodeFilter.FILTER_ACCEPT;
32161 }
32162
32163 // replace the content with a single space
32164 node.textContent = " ";
32165
32166 // TODO: we also need to preserve sequences of white spaces when the parent has "white-space" rule:
32167 // pre
32168 // Sequences of white space are preserved. Lines are only broken at newline characters in the source and at <br> elements.
32169 //
32170 // pre-wrap
32171 // Sequences of white space are preserved. Lines are broken at newline characters, at <br>, and as necessary to fill line boxes.
32172 //
32173 // pre-line
32174 // Sequences of white space are collapsed. Lines are broken at newline characters, at <br>, and as necessary to fill line boxes.
32175 //
32176 // break-spaces
32177 // The behavior is identical to that of pre-wrap, except that:
32178 // - Any sequence of preserved white space always takes up space, including at the end of the line.
32179 // - A line breaking opportunity exists after every preserved white space character, including between white space characters.
32180 // - 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).
32181 //
32182 // See: https://developer.mozilla.org/en-US/docs/Web/CSS/white-space#Values
32183
32184 return NodeFilter.FILTER_REJECT;
32185 } else {
32186 return NodeFilter.FILTER_REJECT;
32187 }
32188 }
32189
32190 }
32191
32192 class CommentsFilter extends Handler {
32193 constructor(chunker, polisher, caller) {
32194 super(chunker, polisher, caller);
32195 }
32196
32197 filter(content) {
32198 filterTree(content, null, NodeFilter.SHOW_COMMENT);
32199 }
32200
32201 }
32202
32203 class ScriptsFilter extends Handler {
32204 constructor(chunker, polisher, caller) {
32205 super(chunker, polisher, caller);
32206 }
32207
32208 filter(content) {
32209 content.querySelectorAll("script").forEach( script => { script.remove(); });
32210 }
32211
32212 }
32213
32214 var clearCut = {};
32215
32216 /**
32217 * Originally ported from https://github.com/keeganstreet/specificity/blob/866bf7ab4e7f62a7179c15b13a95af4e1c7b1afa/specificity.js
32218 *
32219 * Calculates the specificity of CSS selectors
32220 * http://www.w3.org/TR/css3-selectors/#specificity
32221 *
32222 * Returns a selector integer value
32223 */
32224
32225 (function (exports) {
32226 // The following regular expressions assume that selectors matching the preceding regular expressions have been removed
32227 var attributeRegex = /(\[[^\]]+\])/g;
32228 var idRegex = /(#[^\s\+>~\.\[:]+)/g;
32229 var classRegex = /(\.[^\s\+>~\.\[:]+)/g;
32230 var pseudoElementRegex = /(::[^\s\+>~\.\[:]+|:first-line|:first-letter|:before|:after)/g;
32231 var pseudoClassRegex = /(:[^\s\+>~\.\[:]+)/g;
32232 var elementRegex = /([^\s\+>~\.\[:]+)/g;
32233 var notRegex = /:not\(([^\)]*)\)/g;
32234 var ruleRegex = /\{[^]*/gm;
32235 var separatorRegex = /[\*\s\+>~]/g;
32236 var straysRegex = /[#\.]/g;
32237
32238 // Find matches for a regular expression in a string and push their details to parts
32239 // Type is "a" for IDs, "b" for classes, attributes and pseudo-classes and "c" for elements and pseudo-elements
32240 var findMatch = function(regex, type, types, selector) {
32241 var matches = selector.match(regex);
32242 if (matches) {
32243 for (var i = 0; i < matches.length; i++) {
32244 types[type]++;
32245 // Replace this simple selector with whitespace so it won't be counted in further simple selectors
32246 selector = selector.replace(matches[i], ' ');
32247 }
32248 }
32249
32250 return selector;
32251 };
32252
32253 // Calculate the specificity for a selector by dividing it into simple selectors and counting them
32254 var calculate = function(selector) {
32255 var commaIndex = selector.indexOf(',');
32256 if (commaIndex !== -1) {
32257 selector = selector.substring(0, commaIndex);
32258 }
32259
32260 var types = {
32261 a: 0,
32262 b: 0,
32263 c: 0
32264 };
32265
32266 // Remove the negation psuedo-class (:not) but leave its argument because specificity is calculated on its argument
32267 selector = selector.replace(notRegex, ' $1 ');
32268
32269 // Remove anything after a left brace in case a user has pasted in a rule, not just a selector
32270 selector = selector.replace(ruleRegex, ' ');
32271
32272 // Add attribute selectors to parts collection (type b)
32273 selector = findMatch(attributeRegex, 'b', types, selector);
32274
32275 // Add ID selectors to parts collection (type a)
32276 selector = findMatch(idRegex, 'a', types, selector);
32277
32278 // Add class selectors to parts collection (type b)
32279 selector = findMatch(classRegex, 'b', types, selector);
32280
32281 // Add pseudo-element selectors to parts collection (type c)
32282 selector = findMatch(pseudoElementRegex, 'c', types, selector);
32283
32284 // Add pseudo-class selectors to parts collection (type b)
32285 selector = findMatch(pseudoClassRegex, 'b', types, selector);
32286
32287 // Remove universal selector and separator characters
32288 selector = selector.replace(separatorRegex, ' ');
32289
32290 // Remove any stray dots or hashes which aren't attached to words
32291 // These may be present if the user is live-editing this selector
32292 selector = selector.replace(straysRegex, ' ');
32293
32294 // The only things left should be element selectors (type c)
32295 findMatch(elementRegex, 'c', types, selector);
32296
32297 return (types.a * 100) + (types.b * 10) + (types.c * 1);
32298 };
32299
32300 var specificityCache = {};
32301
32302 exports.calculateSpecificity = function(selector) {
32303 var specificity = specificityCache[selector];
32304 if (specificity === undefined) {
32305 specificity = calculate(selector);
32306 specificityCache[selector] = specificity;
32307 }
32308 return specificity;
32309 };
32310
32311 var validSelectorCache = {};
32312 var testSelectorElement = null;
32313
32314 exports.isSelectorValid = function(selector) {
32315 var valid = validSelectorCache[selector];
32316 if (valid === undefined) {
32317 if (testSelectorElement == null) {
32318 testSelectorElement = document.createElement('div');
32319 }
32320
32321 try {
32322 testSelectorElement.querySelector(selector);
32323 valid = true;
32324 } catch (error) {
32325 valid = false;
32326 }
32327 validSelectorCache[selector] = valid;
32328 }
32329 return valid;
32330 };
32331
32332 exports.validateSelector = function(selector) {
32333 if (!exports.isSelectorValid(selector)) {
32334 var error = new SyntaxError(selector + ' is not a valid selector');
32335 error.code = 'EBADSELECTOR';
32336 throw error;
32337 }
32338 };
32339 } (clearCut));
32340
32341 class UndisplayedFilter extends Handler {
32342 constructor(chunker, polisher, caller) {
32343 super(chunker, polisher, caller);
32344 this.displayRules = {};
32345 }
32346
32347 onDeclaration(declaration, dItem, dList, rule) {
32348 if (declaration.property === "display") {
32349 let selector = csstree.generate(rule.ruleNode.prelude);
32350 let value = declaration.value.children.first().name;
32351
32352 selector.split(",").forEach((s) => {
32353 this.displayRules[s] = {
32354 value: value,
32355 selector: s,
32356 specificity: clearCut.calculateSpecificity(s),
32357 important: declaration.important
32358 };
32359 });
32360 }
32361 }
32362
32363 filter(content) {
32364 let { matches, selectors } = this.sortDisplayedSelectors(content, this.displayRules);
32365
32366 // Find matching elements that have display styles
32367 for (let i = 0; i < matches.length; i++) {
32368 let element = matches[i];
32369 let selector = selectors[i];
32370 let displayValue = selector[selector.length-1].value;
32371 if(this.removable(element) && displayValue === "none") {
32372 element.dataset.undisplayed = "undisplayed";
32373 }
32374 }
32375
32376 // Find elements that have inline styles
32377 let styledElements = content.querySelectorAll("[style]");
32378 for (let i = 0; i < styledElements.length; i++) {
32379 let element = styledElements[i];
32380 if (this.removable(element)) {
32381 element.dataset.undisplayed = "undisplayed";
32382 }
32383 }
32384 }
32385
32386 sorter(a, b) {
32387 if (a.important && !b.important) {
32388 return 1;
32389 }
32390
32391 if (b.important && !a.important) {
32392 return -1;
32393 }
32394
32395 return a.specificity - b.specificity;
32396 }
32397
32398 sortDisplayedSelectors(content, displayRules=[]) {
32399 let matches = [];
32400 let selectors = [];
32401 for (let d in displayRules) {
32402 let displayItem = displayRules[d];
32403 let selector = displayItem.selector;
32404 let query = [];
32405 try {
32406 try {
32407 query = content.querySelectorAll(selector);
32408 } catch (e) {
32409 query = content.querySelectorAll(cleanSelector(selector));
32410 }
32411 } catch (e) {
32412 query = [];
32413 }
32414 let elements = Array.from(query);
32415 for (let e of elements) {
32416 if (matches.includes(e)) {
32417 let index = matches.indexOf(e);
32418 selectors[index].push(displayItem);
32419 selectors[index] = selectors[index].sort(this.sorter);
32420 } else {
32421 matches.push(e);
32422 selectors.push([displayItem]);
32423 }
32424 }
32425 }
32426
32427 return { matches, selectors };
32428 }
32429
32430 removable(element) {
32431 if (element.style &&
32432 element.style.display !== "" &&
32433 element.style.display !== "none") {
32434 return false;
32435 }
32436
32437 return true;
32438 }
32439 }
32440
32441 var filters = [
32442 WhiteSpaceFilter,
32443 CommentsFilter,
32444 ScriptsFilter,
32445 UndisplayedFilter
32446 ];
32447
32448 var isImplemented$3 = function () {
32449 var from = Array.from, arr, result;
32450 if (typeof from !== "function") return false;
32451 arr = ["raz", "dwa"];
32452 result = from(arr);
32453 return Boolean(result && (result !== arr) && (result[1] === "dwa"));
32454 };
32455
32456 var isImplemented$2;
32457 var hasRequiredIsImplemented;
32458
32459 function requireIsImplemented () {
32460 if (hasRequiredIsImplemented) return isImplemented$2;
32461 hasRequiredIsImplemented = 1;
32462
32463 var validTypes = { object: true, symbol: true };
32464
32465 isImplemented$2 = function () {
32466 var symbol;
32467 if (typeof Symbol !== 'function') return false;
32468 symbol = Symbol('test symbol');
32469 try { String(symbol); } catch (e) { return false; }
32470
32471 // Return 'true' also for polyfills
32472 if (!validTypes[typeof Symbol.iterator]) return false;
32473 if (!validTypes[typeof Symbol.toPrimitive]) return false;
32474 if (!validTypes[typeof Symbol.toStringTag]) return false;
32475
32476 return true;
32477 };
32478 return isImplemented$2;
32479 }
32480
32481 var isSymbol;
32482 var hasRequiredIsSymbol;
32483
32484 function requireIsSymbol () {
32485 if (hasRequiredIsSymbol) return isSymbol;
32486 hasRequiredIsSymbol = 1;
32487
32488 isSymbol = function (x) {
32489 if (!x) return false;
32490 if (typeof x === 'symbol') return true;
32491 if (!x.constructor) return false;
32492 if (x.constructor.name !== 'Symbol') return false;
32493 return (x[x.constructor.toStringTag] === 'Symbol');
32494 };
32495 return isSymbol;
32496 }
32497
32498 var validateSymbol;
32499 var hasRequiredValidateSymbol;
32500
32501 function requireValidateSymbol () {
32502 if (hasRequiredValidateSymbol) return validateSymbol;
32503 hasRequiredValidateSymbol = 1;
32504
32505 var isSymbol = requireIsSymbol();
32506
32507 validateSymbol = function (value) {
32508 if (!isSymbol(value)) throw new TypeError(value + " is not a symbol");
32509 return value;
32510 };
32511 return validateSymbol;
32512 }
32513
32514 var polyfill;
32515 var hasRequiredPolyfill;
32516
32517 function requirePolyfill () {
32518 if (hasRequiredPolyfill) return polyfill;
32519 hasRequiredPolyfill = 1;
32520
32521 var d = dExports
32522 , validateSymbol = requireValidateSymbol()
32523
32524 , create = Object.create, defineProperties = Object.defineProperties
32525 , defineProperty = Object.defineProperty, objPrototype = Object.prototype
32526 , NativeSymbol, SymbolPolyfill, HiddenSymbol, globalSymbols = create(null)
32527 , isNativeSafe;
32528
32529 if (typeof Symbol === 'function') {
32530 NativeSymbol = Symbol;
32531 try {
32532 String(NativeSymbol());
32533 isNativeSafe = true;
32534 } catch (ignore) {}
32535 }
32536
32537 var generateName = (function () {
32538 var created = create(null);
32539 return function (desc) {
32540 var postfix = 0, name, ie11BugWorkaround;
32541 while (created[desc + (postfix || '')]) ++postfix;
32542 desc += (postfix || '');
32543 created[desc] = true;
32544 name = '@@' + desc;
32545 defineProperty(objPrototype, name, d.gs(null, function (value) {
32546 // For IE11 issue see:
32547 // https://connect.microsoft.com/IE/feedbackdetail/view/1928508/
32548 // ie11-broken-getters-on-dom-objects
32549 // https://github.com/medikoo/es6-symbol/issues/12
32550 if (ie11BugWorkaround) return;
32551 ie11BugWorkaround = true;
32552 defineProperty(this, name, d(value));
32553 ie11BugWorkaround = false;
32554 }));
32555 return name;
32556 };
32557 }());
32558
32559 // Internal constructor (not one exposed) for creating Symbol instances.
32560 // This one is used to ensure that `someSymbol instanceof Symbol` always return false
32561 HiddenSymbol = function Symbol(description) {
32562 if (this instanceof HiddenSymbol) throw new TypeError('Symbol is not a constructor');
32563 return SymbolPolyfill(description);
32564 };
32565
32566 // Exposed `Symbol` constructor
32567 // (returns instances of HiddenSymbol)
32568 polyfill = SymbolPolyfill = function Symbol(description) {
32569 var symbol;
32570 if (this instanceof Symbol) throw new TypeError('Symbol is not a constructor');
32571 if (isNativeSafe) return NativeSymbol(description);
32572 symbol = create(HiddenSymbol.prototype);
32573 description = (description === undefined ? '' : String(description));
32574 return defineProperties(symbol, {
32575 __description__: d('', description),
32576 __name__: d('', generateName(description))
32577 });
32578 };
32579 defineProperties(SymbolPolyfill, {
32580 for: d(function (key) {
32581 if (globalSymbols[key]) return globalSymbols[key];
32582 return (globalSymbols[key] = SymbolPolyfill(String(key)));
32583 }),
32584 keyFor: d(function (s) {
32585 var key;
32586 validateSymbol(s);
32587 for (key in globalSymbols) if (globalSymbols[key] === s) return key;
32588 }),
32589
32590 // To ensure proper interoperability with other native functions (e.g. Array.from)
32591 // fallback to eventual native implementation of given symbol
32592 hasInstance: d('', (NativeSymbol && NativeSymbol.hasInstance) || SymbolPolyfill('hasInstance')),
32593 isConcatSpreadable: d('', (NativeSymbol && NativeSymbol.isConcatSpreadable) ||
32594 SymbolPolyfill('isConcatSpreadable')),
32595 iterator: d('', (NativeSymbol && NativeSymbol.iterator) || SymbolPolyfill('iterator')),
32596 match: d('', (NativeSymbol && NativeSymbol.match) || SymbolPolyfill('match')),
32597 replace: d('', (NativeSymbol && NativeSymbol.replace) || SymbolPolyfill('replace')),
32598 search: d('', (NativeSymbol && NativeSymbol.search) || SymbolPolyfill('search')),
32599 species: d('', (NativeSymbol && NativeSymbol.species) || SymbolPolyfill('species')),
32600 split: d('', (NativeSymbol && NativeSymbol.split) || SymbolPolyfill('split')),
32601 toPrimitive: d('', (NativeSymbol && NativeSymbol.toPrimitive) || SymbolPolyfill('toPrimitive')),
32602 toStringTag: d('', (NativeSymbol && NativeSymbol.toStringTag) || SymbolPolyfill('toStringTag')),
32603 unscopables: d('', (NativeSymbol && NativeSymbol.unscopables) || SymbolPolyfill('unscopables'))
32604 });
32605
32606 // Internal tweaks for real symbol producer
32607 defineProperties(HiddenSymbol.prototype, {
32608 constructor: d(SymbolPolyfill),
32609 toString: d('', function () { return this.__name__; })
32610 });
32611
32612 // Proper implementation of methods exposed on Symbol.prototype
32613 // They won't be accessible on produced symbol instances as they derive from HiddenSymbol.prototype
32614 defineProperties(SymbolPolyfill.prototype, {
32615 toString: d(function () { return 'Symbol (' + validateSymbol(this).__description__ + ')'; }),
32616 valueOf: d(function () { return validateSymbol(this); })
32617 });
32618 defineProperty(SymbolPolyfill.prototype, SymbolPolyfill.toPrimitive, d('', function () {
32619 var symbol = validateSymbol(this);
32620 if (typeof symbol === 'symbol') return symbol;
32621 return symbol.toString();
32622 }));
32623 defineProperty(SymbolPolyfill.prototype, SymbolPolyfill.toStringTag, d('c', 'Symbol'));
32624
32625 // Proper implementaton of toPrimitive and toStringTag for returned symbol instances
32626 defineProperty(HiddenSymbol.prototype, SymbolPolyfill.toStringTag,
32627 d('c', SymbolPolyfill.prototype[SymbolPolyfill.toStringTag]));
32628
32629 // Note: It's important to define `toPrimitive` as last one, as some implementations
32630 // implement `toPrimitive` natively without implementing `toStringTag` (or other specified symbols)
32631 // And that may invoke error in definition flow:
32632 // See: https://github.com/medikoo/es6-symbol/issues/13#issuecomment-164146149
32633 defineProperty(HiddenSymbol.prototype, SymbolPolyfill.toPrimitive,
32634 d('c', SymbolPolyfill.prototype[SymbolPolyfill.toPrimitive]));
32635 return polyfill;
32636 }
32637
32638 var es6Symbol;
32639 var hasRequiredEs6Symbol;
32640
32641 function requireEs6Symbol () {
32642 if (hasRequiredEs6Symbol) return es6Symbol;
32643 hasRequiredEs6Symbol = 1;
32644
32645 es6Symbol = requireIsImplemented()() ? Symbol : requirePolyfill();
32646 return es6Symbol;
32647 }
32648
32649 var isArguments;
32650 var hasRequiredIsArguments;
32651
32652 function requireIsArguments () {
32653 if (hasRequiredIsArguments) return isArguments;
32654 hasRequiredIsArguments = 1;
32655
32656 var objToString = Object.prototype.toString
32657 , id = objToString.call(
32658 (function () {
32659 return arguments;
32660 })()
32661 );
32662
32663 isArguments = function (value) {
32664 return objToString.call(value) === id;
32665 };
32666 return isArguments;
32667 }
32668
32669 var isFunction;
32670 var hasRequiredIsFunction;
32671
32672 function requireIsFunction () {
32673 if (hasRequiredIsFunction) return isFunction;
32674 hasRequiredIsFunction = 1;
32675
32676 var objToString = Object.prototype.toString, id = objToString.call(noop$4);
32677
32678 isFunction = function (value) {
32679 return typeof value === "function" && objToString.call(value) === id;
32680 };
32681 return isFunction;
32682 }
32683
32684 var isImplemented$1 = function () {
32685 var sign = Math.sign;
32686 if (typeof sign !== "function") return false;
32687 return (sign(10) === 1) && (sign(-20) === -1);
32688 };
32689
32690 var shim$2;
32691 var hasRequiredShim$2;
32692
32693 function requireShim$2 () {
32694 if (hasRequiredShim$2) return shim$2;
32695 hasRequiredShim$2 = 1;
32696
32697 shim$2 = function (value) {
32698 value = Number(value);
32699 if (isNaN(value) || (value === 0)) return value;
32700 return value > 0 ? 1 : -1;
32701 };
32702 return shim$2;
32703 }
32704
32705 var sign$1 = isImplemented$1()
32706 ? Math.sign
32707 : requireShim$2();
32708
32709 var sign = sign$1
32710
32711 , abs$1 = Math.abs, floor$1 = Math.floor;
32712
32713 var toInteger$1 = function (value) {
32714 if (isNaN(value)) return 0;
32715 value = Number(value);
32716 if ((value === 0) || !isFinite(value)) return value;
32717 return sign(value) * floor$1(abs$1(value));
32718 };
32719
32720 var toInteger = toInteger$1
32721
32722 , max = Math.max;
32723
32724 var toPosInteger = function (value) {
32725 return max(0, toInteger(value));
32726 };
32727
32728 var isString;
32729 var hasRequiredIsString;
32730
32731 function requireIsString () {
32732 if (hasRequiredIsString) return isString;
32733 hasRequiredIsString = 1;
32734
32735 var objToString = Object.prototype.toString, id = objToString.call("");
32736
32737 isString = function (value) {
32738 return (
32739 typeof value === "string" ||
32740 (value &&
32741 typeof value === "object" &&
32742 (value instanceof String || objToString.call(value) === id)) ||
32743 false
32744 );
32745 };
32746 return isString;
32747 }
32748
32749 var shim$1;
32750 var hasRequiredShim$1;
32751
32752 function requireShim$1 () {
32753 if (hasRequiredShim$1) return shim$1;
32754 hasRequiredShim$1 = 1;
32755
32756 var iteratorSymbol = requireEs6Symbol().iterator
32757 , isArguments = requireIsArguments()
32758 , isFunction = requireIsFunction()
32759 , toPosInt = toPosInteger
32760 , callable = validCallable
32761 , validValue$1 = validValue
32762 , isValue = isValue$3
32763 , isString = requireIsString()
32764 , isArray = Array.isArray
32765 , call = Function.prototype.call
32766 , desc = { configurable: true, enumerable: true, writable: true, value: null }
32767 , defineProperty = Object.defineProperty;
32768
32769 // eslint-disable-next-line complexity
32770 shim$1 = function (arrayLike /*, mapFn, thisArg*/) {
32771 var mapFn = arguments[1]
32772 , thisArg = arguments[2]
32773 , Context
32774 , i
32775 , j
32776 , arr
32777 , length
32778 , code
32779 , iterator
32780 , result
32781 , getIterator
32782 , value;
32783
32784 arrayLike = Object(validValue$1(arrayLike));
32785
32786 if (isValue(mapFn)) callable(mapFn);
32787 if (!this || this === Array || !isFunction(this)) {
32788 // Result: Plain array
32789 if (!mapFn) {
32790 if (isArguments(arrayLike)) {
32791 // Source: Arguments
32792 length = arrayLike.length;
32793 if (length !== 1) return Array.apply(null, arrayLike);
32794 arr = new Array(1);
32795 arr[0] = arrayLike[0];
32796 return arr;
32797 }
32798 if (isArray(arrayLike)) {
32799 // Source: Array
32800 arr = new Array(length = arrayLike.length);
32801 for (i = 0; i < length; ++i) arr[i] = arrayLike[i];
32802 return arr;
32803 }
32804 }
32805 arr = [];
32806 } else {
32807 // Result: Non plain array
32808 Context = this;
32809 }
32810
32811 if (!isArray(arrayLike)) {
32812 if ((getIterator = arrayLike[iteratorSymbol]) !== undefined) {
32813 // Source: Iterator
32814 iterator = callable(getIterator).call(arrayLike);
32815 if (Context) arr = new Context();
32816 result = iterator.next();
32817 i = 0;
32818 while (!result.done) {
32819 value = mapFn ? call.call(mapFn, thisArg, result.value, i) : result.value;
32820 if (Context) {
32821 desc.value = value;
32822 defineProperty(arr, i, desc);
32823 } else {
32824 arr[i] = value;
32825 }
32826 result = iterator.next();
32827 ++i;
32828 }
32829 length = i;
32830 } else if (isString(arrayLike)) {
32831 // Source: String
32832 length = arrayLike.length;
32833 if (Context) arr = new Context();
32834 for (i = 0, j = 0; i < length; ++i) {
32835 value = arrayLike[i];
32836 if (i + 1 < length) {
32837 code = value.charCodeAt(0);
32838 // eslint-disable-next-line max-depth
32839 if (code >= 0xd800 && code <= 0xdbff) value += arrayLike[++i];
32840 }
32841 value = mapFn ? call.call(mapFn, thisArg, value, j) : value;
32842 if (Context) {
32843 desc.value = value;
32844 defineProperty(arr, j, desc);
32845 } else {
32846 arr[j] = value;
32847 }
32848 ++j;
32849 }
32850 length = j;
32851 }
32852 }
32853 if (length === undefined) {
32854 // Source: array or array-like
32855 length = toPosInt(arrayLike.length);
32856 if (Context) arr = new Context(length);
32857 for (i = 0; i < length; ++i) {
32858 value = mapFn ? call.call(mapFn, thisArg, arrayLike[i], i) : arrayLike[i];
32859 if (Context) {
32860 desc.value = value;
32861 defineProperty(arr, i, desc);
32862 } else {
32863 arr[i] = value;
32864 }
32865 }
32866 }
32867 if (Context) {
32868 desc.value = null;
32869 arr.length = length;
32870 }
32871 return arr;
32872 };
32873 return shim$1;
32874 }
32875
32876 var from = isImplemented$3()
32877 ? Array.from
32878 : requireShim$1();
32879
32880 var isImplemented = function () {
32881 var numberIsNaN = Number.isNaN;
32882 if (typeof numberIsNaN !== "function") return false;
32883 return !numberIsNaN({}) && numberIsNaN(NaN) && !numberIsNaN(34);
32884 };
32885
32886 var shim;
32887 var hasRequiredShim;
32888
32889 function requireShim () {
32890 if (hasRequiredShim) return shim;
32891 hasRequiredShim = 1;
32892
32893 shim = function (value) {
32894 // eslint-disable-next-line no-self-compare
32895 return value !== value;
32896 };
32897 return shim;
32898 }
32899
32900 var isNan = isImplemented()
32901 ? Number.isNaN
32902 : requireShim();
32903
32904 var numberIsNaN = isNan
32905 , toPosInt = toPosInteger
32906 , value$1 = validValue
32907 , indexOf$1 = Array.prototype.indexOf
32908 , objHasOwnProperty = Object.prototype.hasOwnProperty
32909 , abs = Math.abs
32910 , floor = Math.floor;
32911
32912 var eIndexOf = function (searchElement /*, fromIndex*/) {
32913 var i, length, fromIndex, val;
32914 if (!numberIsNaN(searchElement)) return indexOf$1.apply(this, arguments);
32915
32916 length = toPosInt(value$1(this).length);
32917 fromIndex = arguments[1];
32918 if (isNaN(fromIndex)) fromIndex = 0;
32919 else if (fromIndex >= 0) fromIndex = floor(fromIndex);
32920 else fromIndex = toPosInt(this.length) - floor(abs(fromIndex));
32921
32922 for (i = fromIndex; i < length; ++i) {
32923 if (objHasOwnProperty.call(this, i)) {
32924 val = this[i];
32925 if (numberIsNaN(val)) return i; // Jslint: ignore
32926 }
32927 }
32928 return -1;
32929 };
32930
32931 var indexOf = eIndexOf
32932 , forEach = Array.prototype.forEach
32933 , splice = Array.prototype.splice;
32934
32935 // eslint-disable-next-line no-unused-vars
32936 var remove$1 = function (itemToRemove /*, …item*/) {
32937 forEach.call(
32938 arguments,
32939 function (item) {
32940 var index = indexOf.call(this, item);
32941 if (index !== -1) splice.call(this, index, 1);
32942 },
32943 this
32944 );
32945 };
32946
32947 var isValue = isValue$3;
32948
32949 var map = { function: true, object: true };
32950
32951 var isObject$1 = function (value) {
32952 return (isValue(value) && map[typeof value]) || false;
32953 };
32954
32955 var isObject = isObject$1;
32956
32957 var validObject = function (value) {
32958 if (!isObject(value)) throw new TypeError(value + " is not an Object");
32959 return value;
32960 };
32961
32962 var aFrom = from
32963 , remove = remove$1
32964 , value = validObject
32965 , d = dExports
32966 , emit = eventEmitterExports.methods.emit
32967
32968 , defineProperty = Object.defineProperty
32969 , hasOwnProperty$1 = Object.prototype.hasOwnProperty
32970 , getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
32971
32972 var pipe = function (e1, e2/*, name*/) {
32973 var pipes, pipe, desc, name;
32974
32975 (value(e1) && value(e2));
32976 name = arguments[2];
32977 if (name === undefined) name = 'emit';
32978
32979 pipe = {
32980 close: function () { remove.call(pipes, e2); }
32981 };
32982 if (hasOwnProperty$1.call(e1, '__eePipes__')) {
32983 (pipes = e1.__eePipes__).push(e2);
32984 return pipe;
32985 }
32986 defineProperty(e1, '__eePipes__', d('c', pipes = [e2]));
32987 desc = getOwnPropertyDescriptor(e1, name);
32988 if (!desc) {
32989 desc = d('c', undefined);
32990 } else {
32991 delete desc.get;
32992 delete desc.set;
32993 }
32994 desc.value = function () {
32995 var i, emitter, data = aFrom(pipes);
32996 emit.apply(this, arguments);
32997 for (i = 0; (emitter = data[i]); ++i) emit.apply(emitter, arguments);
32998 };
32999 defineProperty(e1, name, desc);
33000 return pipe;
33001 };
33002
33003 var pipe$1 = /*@__PURE__*/getDefaultExportFromCjs(pipe);
33004
33005 let registeredHandlers = [...pagedMediaHandlers, ...generatedContentHandlers, ...filters];
33006
33007 class Handlers {
33008 constructor(chunker, polisher, caller) {
33009
33010 registeredHandlers.forEach((Handler) => {
33011 let handler = new Handler(chunker, polisher, caller);
33012 pipe$1(handler, this);
33013 });
33014 }
33015 }
33016
33017 EventEmitter(Handlers.prototype);
33018
33019 function registerHandlers() {
33020 for (var i = 0; i < arguments.length; i++) {
33021 registeredHandlers.push(arguments[i]);
33022 }
33023 }
33024
33025 function initializeHandlers(chunker, polisher, caller) {
33026 let handlers = new Handlers(chunker, polisher, caller);
33027 return handlers;
33028 }
33029
33030 class Previewer {
33031 constructor(options) {
33032 // this.preview = this.getParams("preview") !== "false";
33033
33034 this.settings = options || {};
33035
33036 // Process styles
33037 this.polisher = new Polisher(false);
33038
33039 // Chunk contents
33040 this.chunker = new Chunker(undefined, undefined, this.settings);
33041
33042 // Hooks
33043 this.hooks = {};
33044 this.hooks.beforePreview = new Hook(this);
33045 this.hooks.afterPreview = new Hook(this);
33046
33047 // default size
33048 this.size = {
33049 width: {
33050 value: 8.5,
33051 unit: "in"
33052 },
33053 height: {
33054 value: 11,
33055 unit: "in"
33056 },
33057 format: undefined,
33058 orientation: undefined
33059 };
33060
33061 this.chunker.on("page", (page) => {
33062 this.emit("page", page);
33063 });
33064
33065 this.chunker.on("rendering", () => {
33066 this.emit("rendering", this.chunker);
33067 });
33068 }
33069
33070 initializeHandlers() {
33071 let handlers = initializeHandlers(this.chunker, this.polisher, this);
33072
33073 handlers.on("size", (size) => {
33074 this.size = size;
33075 this.emit("size", size);
33076 });
33077
33078 handlers.on("atpages", (pages) => {
33079 this.atpages = pages;
33080 this.emit("atpages", pages);
33081 });
33082
33083 return handlers;
33084 }
33085
33086 registerHandlers() {
33087 return registerHandlers.apply(registerHandlers, arguments);
33088 }
33089
33090 getParams(name) {
33091 let param;
33092 let url = new URL(window.location);
33093 let params = new URLSearchParams(url.search);
33094 for(var pair of params.entries()) {
33095 if(pair[0] === name) {
33096 param = pair[1];
33097 }
33098 }
33099
33100 return param;
33101 }
33102
33103 wrapContent() {
33104 // Wrap body in template tag
33105 let body = document.querySelector("body");
33106
33107 // Check if a template exists
33108 let template;
33109 template = body.querySelector(":scope > template[data-ref='pagedjs-content']");
33110
33111 if (!template) {
33112 // Otherwise create one
33113 template = document.createElement("template");
33114 template.dataset.ref = "pagedjs-content";
33115 template.innerHTML = body.innerHTML;
33116 body.innerHTML = "";
33117 body.appendChild(template);
33118 }
33119
33120 return template.content;
33121 }
33122
33123 removeStyles(doc=document) {
33124 // Get all stylesheets
33125 const stylesheets = Array.from(doc.querySelectorAll("link[rel='stylesheet']:not([data-pagedjs-ignore], [media~='screen'])"));
33126 // Get inline styles
33127 const inlineStyles = Array.from(doc.querySelectorAll("style:not([data-pagedjs-inserted-styles], [data-pagedjs-ignore], [media~='screen'])"));
33128 const elements = [...stylesheets, ...inlineStyles];
33129 return elements
33130 // preserve order
33131 .sort(function (element1, element2) {
33132 const position = element1.compareDocumentPosition(element2);
33133 if (position === Node.DOCUMENT_POSITION_PRECEDING) {
33134 return 1;
33135 } else if (position === Node.DOCUMENT_POSITION_FOLLOWING) {
33136 return -1;
33137 }
33138 return 0;
33139 })
33140 // extract the href
33141 .map((element) => {
33142 if (element.nodeName === "STYLE") {
33143 const obj = {};
33144 obj[window.location.href] = element.textContent;
33145 element.remove();
33146 return obj;
33147 }
33148 if (element.nodeName === "LINK") {
33149 element.remove();
33150 return element.href;
33151 }
33152 // ignore
33153 console.warn(`Unable to process: ${element}, ignoring.`);
33154 });
33155 }
33156
33157 async preview(content, stylesheets, renderTo) {
33158
33159 await this.hooks.beforePreview.trigger(content, renderTo);
33160
33161 if (!content) {
33162 content = this.wrapContent();
33163 }
33164
33165 if (!stylesheets) {
33166 stylesheets = this.removeStyles();
33167 }
33168
33169 this.polisher.setup();
33170
33171 this.handlers = this.initializeHandlers();
33172
33173 await this.polisher.add(...stylesheets);
33174
33175 let startTime = performance.now();
33176
33177 // Render flow
33178 let flow = await this.chunker.flow(content, renderTo);
33179
33180 let endTime = performance.now();
33181
33182 flow.performance = (endTime - startTime);
33183 flow.size = this.size;
33184
33185 this.emit("rendered", flow);
33186
33187 await this.hooks.afterPreview.trigger(flow.pages);
33188
33189 return flow;
33190 }
33191 }
33192
33193 EventEmitter(Previewer.prototype);
33194
33195 exports.Chunker = Chunker;
33196 exports.Handler = Handler;
33197 exports.Polisher = Polisher;
33198 exports.Previewer = Previewer;
33199 exports.initializeHandlers = initializeHandlers;
33200 exports.registerHandlers = registerHandlers;
33201 exports.registeredHandlers = registeredHandlers;
33202
33203}));