UNPKG

859 kBJavaScriptView Raw
1/**
2 * @license Paged.js v0.1.43 | MIT | https://gitlab.pagedmedia.org/tools/pagedjs
3 */
4
5(function (global, factory) {
6 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
7 typeof define === 'function' && define.amd ? define(factory) :
8 (global = global || self, global.PagedPolyfill = factory());
9}(this, (function () { 'use strict';
10
11 function createCommonjsModule(fn, module) {
12 return module = { exports: {} }, fn(module, module.exports), module.exports;
13 }
14
15 function getCjsExportFromNamespace (n) {
16 return n && n['default'] || n;
17 }
18
19 var isImplemented = function () {
20 var assign = Object.assign, obj;
21 if (typeof assign !== "function") return false;
22 obj = { foo: "raz" };
23 assign(obj, { bar: "dwa" }, { trzy: "trzy" });
24 return (obj.foo + obj.bar + obj.trzy) === "razdwatrzy";
25 };
26
27 var isImplemented$1 = function () {
28 try {
29 Object.keys("primitive");
30 return true;
31 } catch (e) {
32 return false;
33 }
34 };
35
36 // eslint-disable-next-line no-empty-function
37 var noop = function () {};
38
39 var _undefined = noop(); // Support ES3 engines
40
41 var isValue = function (val) {
42 return (val !== _undefined) && (val !== null);
43 };
44
45 var keys = Object.keys;
46
47 var shim = function (object) {
48 return keys(isValue(object) ? Object(object) : object);
49 };
50
51 var keys$1 = isImplemented$1()
52 ? Object.keys
53 : shim;
54
55 var validValue = function (value) {
56 if (!isValue(value)) throw new TypeError("Cannot use null or undefined");
57 return value;
58 };
59
60 var max = Math.max;
61
62 var shim$1 = function (dest, src /*, …srcn*/) {
63 var error, i, length = max(arguments.length, 2), assign;
64 dest = Object(validValue(dest));
65 assign = function (key) {
66 try {
67 dest[key] = src[key];
68 } catch (e) {
69 if (!error) error = e;
70 }
71 };
72 for (i = 1; i < length; ++i) {
73 src = arguments[i];
74 keys$1(src).forEach(assign);
75 }
76 if (error !== undefined) throw error;
77 return dest;
78 };
79
80 var assign = isImplemented()
81 ? Object.assign
82 : shim$1;
83
84 var forEach = Array.prototype.forEach, create = Object.create;
85
86 var process = function (src, obj) {
87 var key;
88 for (key in src) obj[key] = src[key];
89 };
90
91 // eslint-disable-next-line no-unused-vars
92 var normalizeOptions = function (opts1 /*, …options*/) {
93 var result = create(null);
94 forEach.call(arguments, function (options) {
95 if (!isValue(options)) return;
96 process(Object(options), result);
97 });
98 return result;
99 };
100
101 // Deprecated
102
103 var isCallable = function (obj) {
104 return typeof obj === "function";
105 };
106
107 var str = "razdwatrzy";
108
109 var isImplemented$2 = function () {
110 if (typeof str.contains !== "function") return false;
111 return (str.contains("dwa") === true) && (str.contains("foo") === false);
112 };
113
114 var indexOf = String.prototype.indexOf;
115
116 var shim$2 = function (searchString/*, position*/) {
117 return indexOf.call(this, searchString, arguments[1]) > -1;
118 };
119
120 var contains = isImplemented$2()
121 ? String.prototype.contains
122 : shim$2;
123
124 var d_1 = createCommonjsModule(function (module) {
125
126 var d;
127
128 d = module.exports = function (dscr, value/*, options*/) {
129 var c, e, w, options, desc;
130 if ((arguments.length < 2) || (typeof dscr !== 'string')) {
131 options = value;
132 value = dscr;
133 dscr = null;
134 } else {
135 options = arguments[2];
136 }
137 if (dscr == null) {
138 c = w = true;
139 e = false;
140 } else {
141 c = contains.call(dscr, 'c');
142 e = contains.call(dscr, 'e');
143 w = contains.call(dscr, 'w');
144 }
145
146 desc = { value: value, configurable: c, enumerable: e, writable: w };
147 return !options ? desc : assign(normalizeOptions(options), desc);
148 };
149
150 d.gs = function (dscr, get, set/*, options*/) {
151 var c, e, options, desc;
152 if (typeof dscr !== 'string') {
153 options = set;
154 set = get;
155 get = dscr;
156 dscr = null;
157 } else {
158 options = arguments[3];
159 }
160 if (get == null) {
161 get = undefined;
162 } else if (!isCallable(get)) {
163 options = get;
164 get = set = undefined;
165 } else if (set == null) {
166 set = undefined;
167 } else if (!isCallable(set)) {
168 options = set;
169 set = undefined;
170 }
171 if (dscr == null) {
172 c = true;
173 e = false;
174 } else {
175 c = contains.call(dscr, 'c');
176 e = contains.call(dscr, 'e');
177 }
178
179 desc = { get: get, set: set, configurable: c, enumerable: e };
180 return !options ? desc : assign(normalizeOptions(options), desc);
181 };
182 });
183
184 var validCallable = function (fn) {
185 if (typeof fn !== "function") throw new TypeError(fn + " is not a function");
186 return fn;
187 };
188
189 var eventEmitter = createCommonjsModule(function (module, exports) {
190
191 var apply = Function.prototype.apply, call = Function.prototype.call
192 , create = Object.create, defineProperty = Object.defineProperty
193 , defineProperties = Object.defineProperties
194 , hasOwnProperty = Object.prototype.hasOwnProperty
195 , descriptor = { configurable: true, enumerable: false, writable: true }
196
197 , on, once, off, emit, methods, descriptors, base;
198
199 on = function (type, listener) {
200 var data;
201
202 validCallable(listener);
203
204 if (!hasOwnProperty.call(this, '__ee__')) {
205 data = descriptor.value = create(null);
206 defineProperty(this, '__ee__', descriptor);
207 descriptor.value = null;
208 } else {
209 data = this.__ee__;
210 }
211 if (!data[type]) data[type] = listener;
212 else if (typeof data[type] === 'object') data[type].push(listener);
213 else data[type] = [data[type], listener];
214
215 return this;
216 };
217
218 once = function (type, listener) {
219 var once, self;
220
221 validCallable(listener);
222 self = this;
223 on.call(this, type, once = function () {
224 off.call(self, type, once);
225 apply.call(listener, this, arguments);
226 });
227
228 once.__eeOnceListener__ = listener;
229 return this;
230 };
231
232 off = function (type, listener) {
233 var data, listeners, candidate, i;
234
235 validCallable(listener);
236
237 if (!hasOwnProperty.call(this, '__ee__')) return this;
238 data = this.__ee__;
239 if (!data[type]) return this;
240 listeners = data[type];
241
242 if (typeof listeners === 'object') {
243 for (i = 0; (candidate = listeners[i]); ++i) {
244 if ((candidate === listener) ||
245 (candidate.__eeOnceListener__ === listener)) {
246 if (listeners.length === 2) data[type] = listeners[i ? 0 : 1];
247 else listeners.splice(i, 1);
248 }
249 }
250 } else {
251 if ((listeners === listener) ||
252 (listeners.__eeOnceListener__ === listener)) {
253 delete data[type];
254 }
255 }
256
257 return this;
258 };
259
260 emit = function (type) {
261 var i, l, listener, listeners, args;
262
263 if (!hasOwnProperty.call(this, '__ee__')) return;
264 listeners = this.__ee__[type];
265 if (!listeners) return;
266
267 if (typeof listeners === 'object') {
268 l = arguments.length;
269 args = new Array(l - 1);
270 for (i = 1; i < l; ++i) args[i - 1] = arguments[i];
271
272 listeners = listeners.slice();
273 for (i = 0; (listener = listeners[i]); ++i) {
274 apply.call(listener, this, args);
275 }
276 } else {
277 switch (arguments.length) {
278 case 1:
279 call.call(listeners, this);
280 break;
281 case 2:
282 call.call(listeners, this, arguments[1]);
283 break;
284 case 3:
285 call.call(listeners, this, arguments[1], arguments[2]);
286 break;
287 default:
288 l = arguments.length;
289 args = new Array(l - 1);
290 for (i = 1; i < l; ++i) {
291 args[i - 1] = arguments[i];
292 }
293 apply.call(listeners, this, args);
294 }
295 }
296 };
297
298 methods = {
299 on: on,
300 once: once,
301 off: off,
302 emit: emit
303 };
304
305 descriptors = {
306 on: d_1(on),
307 once: d_1(once),
308 off: d_1(off),
309 emit: d_1(emit)
310 };
311
312 base = defineProperties({}, descriptors);
313
314 module.exports = exports = function (o) {
315 return (o == null) ? create(base) : defineProperties(Object(o), descriptors);
316 };
317 exports.methods = methods;
318 });
319 var eventEmitter_1 = eventEmitter.methods;
320
321 /**
322 * Hooks allow for injecting functions that must all complete in order before finishing
323 * They will execute in parallel but all must finish before continuing
324 * Functions may return a promise if they are asycn.
325 * From epubjs/src/utils/hooks
326 * @param {any} context scope of this
327 * @example this.content = new Hook(this);
328 */
329 class Hook {
330 constructor(context){
331 this.context = context || this;
332 this.hooks = [];
333 }
334
335 /**
336 * Adds a function to be run before a hook completes
337 * @example this.content.register(function(){...});
338 * @return {undefined} void
339 */
340 register(){
341 for(var i = 0; i < arguments.length; ++i) {
342 if (typeof arguments[i] === "function") {
343 this.hooks.push(arguments[i]);
344 } else {
345 // unpack array
346 for(var j = 0; j < arguments[i].length; ++j) {
347 this.hooks.push(arguments[i][j]);
348 }
349 }
350 }
351 }
352
353 /**
354 * Triggers a hook to run all functions
355 * @example this.content.trigger(args).then(function(){...});
356 * @return {Promise} results
357 */
358 trigger(){
359 var args = arguments;
360 var context = this.context;
361 var promises = [];
362
363 this.hooks.forEach(function(task) {
364 var executing = task.apply(context, args);
365
366 if(executing && typeof executing["then"] === "function") {
367 // Task is a function that returns a promise
368 promises.push(executing);
369 }
370 // Otherwise Task resolves immediately, add resolved promise with result
371 promises.push(new Promise((resolve, reject) => {
372 resolve(executing);
373 }));
374 });
375
376
377 return Promise.all(promises);
378 }
379
380 /**
381 * Triggers a hook to run all functions synchronously
382 * @example this.content.trigger(args).then(function(){...});
383 * @return {Array} results
384 */
385 triggerSync(){
386 var args = arguments;
387 var context = this.context;
388 var results = [];
389
390 this.hooks.forEach(function(task) {
391 var executing = task.apply(context, args);
392
393 results.push(executing);
394 });
395
396
397 return results;
398 }
399
400 // Adds a function to be run before a hook completes
401 list(){
402 return this.hooks;
403 }
404
405 clear(){
406 return this.hooks = [];
407 }
408 }
409
410 function getBoundingClientRect(element) {
411 if (!element) {
412 return;
413 }
414 let rect;
415 if (typeof element.getBoundingClientRect !== "undefined") {
416 rect = element.getBoundingClientRect();
417 } else {
418 let range = document.createRange();
419 range.selectNode(element);
420 rect = range.getBoundingClientRect();
421 }
422 return rect;
423 }
424
425 function getClientRects(element) {
426 if (!element) {
427 return;
428 }
429 let rect;
430 if (typeof element.getClientRects !== "undefined") {
431 rect = element.getClientRects();
432 } else {
433 let range = document.createRange();
434 range.selectNode(element);
435 rect = range.getClientRects();
436 }
437 return rect;
438 }
439
440 /**
441 * Generates a UUID
442 * based on: http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript
443 * @returns {string} uuid
444 */
445 function UUID() {
446 var d = new Date().getTime();
447 if (typeof performance !== "undefined" && typeof performance.now === "function") {
448 d += performance.now(); //use high-precision timer if available
449 }
450 return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
451 var r = (d + Math.random() * 16) % 16 | 0;
452 d = Math.floor(d / 16);
453 return (c === "x" ? r : (r & 0x3 | 0x8)).toString(16);
454 });
455 }
456
457 function attr(element, attributes) {
458 for (var i = 0; i < attributes.length; i++) {
459 if (element.hasAttribute(attributes[i])) {
460 return element.getAttribute(attributes[i]);
461 }
462 }
463 }
464
465 /* Based on by https://mths.be/cssescape v1.5.1 by @mathias | MIT license
466 * Allows # and .
467 */
468 function querySelectorEscape(value) {
469 if (arguments.length == 0) {
470 throw new TypeError("`CSS.escape` requires an argument.");
471 }
472 var string = String(value);
473
474 var length = string.length;
475 var index = -1;
476 var codeUnit;
477 var result = "";
478 var firstCodeUnit = string.charCodeAt(0);
479 while (++index < length) {
480 codeUnit = string.charCodeAt(index);
481
482
483
484 // Note: there’s no need to special-case astral symbols, surrogate
485 // pairs, or lone surrogates.
486
487 // If the character is NULL (U+0000), then the REPLACEMENT CHARACTER
488 // (U+FFFD).
489 if (codeUnit == 0x0000) {
490 result += "\uFFFD";
491 continue;
492 }
493
494 if (
495 // If the character is in the range [\1-\1F] (U+0001 to U+001F) or is
496 // U+007F, […]
497 (codeUnit >= 0x0001 && codeUnit <= 0x001F) || codeUnit == 0x007F ||
498 // If the character is the first character and is in the range [0-9]
499 // (U+0030 to U+0039), […]
500 (index == 0 && codeUnit >= 0x0030 && codeUnit <= 0x0039) ||
501 // If the character is the second character and is in the range [0-9]
502 // (U+0030 to U+0039) and the first character is a `-` (U+002D), […]
503 (
504 index == 1 &&
505 codeUnit >= 0x0030 && codeUnit <= 0x0039 &&
506 firstCodeUnit == 0x002D
507 )
508 ) {
509 // https://drafts.csswg.org/cssom/#escape-a-character-as-code-point
510 result += "\\" + codeUnit.toString(16) + " ";
511 continue;
512 }
513
514 if (
515 // If the character is the first character and is a `-` (U+002D), and
516 // there is no second character, […]
517 index == 0 &&
518 length == 1 &&
519 codeUnit == 0x002D
520 ) {
521 result += "\\" + string.charAt(index);
522 continue;
523 }
524
525 // support for period character in id
526 if (codeUnit == 0x002E) {
527 if (string.charAt(0) == "#") {
528 result += "\\.";
529 continue;
530 }
531 }
532
533
534 // If the character is not handled by one of the above rules and is
535 // greater than or equal to U+0080, is `-` (U+002D) or `_` (U+005F), or
536 // is in one of the ranges [0-9] (U+0030 to U+0039), [A-Z] (U+0041 to
537 // U+005A), or [a-z] (U+0061 to U+007A), […]
538 if (
539 codeUnit >= 0x0080 ||
540 codeUnit == 0x002D ||
541 codeUnit == 0x005F ||
542 codeUnit == 35 || // Allow #
543 codeUnit == 46 || // Allow .
544 codeUnit >= 0x0030 && codeUnit <= 0x0039 ||
545 codeUnit >= 0x0041 && codeUnit <= 0x005A ||
546 codeUnit >= 0x0061 && codeUnit <= 0x007A
547 ) {
548 // the character itself
549 result += string.charAt(index);
550 continue;
551 }
552
553 // Otherwise, the escaped character.
554 // https://drafts.csswg.org/cssom/#escape-a-character
555 result += "\\" + string.charAt(index);
556
557 }
558 return result;
559 }
560
561 /**
562 * Creates a new pending promise and provides methods to resolve or reject it.
563 * From: https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/Promise.jsm/Deferred#backwards_forwards_compatible
564 * @returns {object} defered
565 */
566 function defer() {
567 this.resolve = null;
568
569 this.reject = null;
570
571 this.id = UUID();
572
573 this.promise = new Promise((resolve, reject) => {
574 this.resolve = resolve;
575 this.reject = reject;
576 });
577 Object.freeze(this);
578 }
579
580 const requestIdleCallback = typeof window !== "undefined" && ("requestIdleCallback" in window ? window.requestIdleCallback : window.requestAnimationFrame);
581
582 function CSSValueToString(obj) {
583 return obj.value + (obj.unit || "");
584 }
585
586 function isElement(node) {
587 return node && node.nodeType === 1;
588 }
589
590 function isText(node) {
591 return node && node.nodeType === 3;
592 }
593
594 function *walk(start, limiter) {
595 let node = start;
596
597 while (node) {
598
599 yield node;
600
601 if (node.childNodes.length) {
602 node = node.firstChild;
603 } else if (node.nextSibling) {
604 if (limiter && node === limiter) {
605 node = undefined;
606 break;
607 }
608 node = node.nextSibling;
609 } else {
610 while (node) {
611 node = node.parentNode;
612 if (limiter && node === limiter) {
613 node = undefined;
614 break;
615 }
616 if (node && node.nextSibling) {
617 node = node.nextSibling;
618 break;
619 }
620
621 }
622 }
623 }
624 }
625
626 function nodeAfter(node, limiter) {
627 if (limiter && node === limiter) {
628 return;
629 }
630 let significantNode = nextSignificantNode(node);
631 if (significantNode) {
632 return significantNode;
633 }
634 if (node.parentNode) {
635 while ((node = node.parentNode)) {
636 if (limiter && node === limiter) {
637 return;
638 }
639 significantNode = nextSignificantNode(node);
640 if (significantNode) {
641 return significantNode;
642 }
643 }
644 }
645 }
646
647 function nodeBefore(node, limiter) {
648 if (limiter && node === limiter) {
649 return;
650 }
651 let significantNode = previousSignificantNode(node);
652 if (significantNode) {
653 return significantNode;
654 }
655 if (node.parentNode) {
656 while ((node = node.parentNode)) {
657 if (limiter && node === limiter) {
658 return;
659 }
660 significantNode = previousSignificantNode(node);
661 if (significantNode) {
662 return significantNode;
663 }
664 }
665 }
666 }
667
668 function elementAfter(node, limiter) {
669 let after = nodeAfter(node, limiter);
670
671 while (after && after.nodeType !== 1) {
672 after = nodeAfter(after, limiter);
673 }
674
675 return after;
676 }
677
678 function elementBefore(node, limiter) {
679 let before = nodeBefore(node, limiter);
680
681 while (before && before.nodeType !== 1) {
682 before = nodeBefore(before, limiter);
683 }
684
685 return before;
686 }
687
688 function displayedElementAfter(node, limiter) {
689 let after = elementAfter(node, limiter);
690
691 while (after && after.dataset.undisplayed) {
692 after = elementAfter(after);
693 }
694
695 return after;
696 }
697
698 function displayedElementBefore(node, limiter) {
699 let before = elementBefore(node, limiter);
700
701 while (before && before.dataset.undisplayed) {
702 before = elementBefore(before);
703 }
704
705 return before;
706 }
707
708 function rebuildAncestors(node) {
709 let parent, ancestor;
710 let ancestors = [];
711 let added = [];
712
713 let fragment = document.createDocumentFragment();
714
715 // Gather all ancestors
716 let element = node;
717 while(element.parentNode && element.parentNode.nodeType === 1) {
718 ancestors.unshift(element.parentNode);
719 element = element.parentNode;
720 }
721
722 for (var i = 0; i < ancestors.length; i++) {
723 ancestor = ancestors[i];
724 parent = ancestor.cloneNode(false);
725
726 parent.setAttribute("data-split-from", parent.getAttribute("data-ref"));
727 // ancestor.setAttribute("data-split-to", parent.getAttribute("data-ref"));
728
729 if (parent.hasAttribute("id")) {
730 let dataID = parent.getAttribute("id");
731 parent.setAttribute("data-id", dataID);
732 parent.removeAttribute("id");
733 }
734
735 // This is handled by css :not, but also tidied up here
736 if (parent.hasAttribute("data-break-before")) {
737 parent.removeAttribute("data-break-before");
738 }
739
740 if (parent.hasAttribute("data-previous-break-after")) {
741 parent.removeAttribute("data-previous-break-after");
742 }
743
744 if (added.length) {
745 let container = added[added.length-1];
746 container.appendChild(parent);
747 } else {
748 fragment.appendChild(parent);
749 }
750 added.push(parent);
751 }
752
753 added = undefined;
754 return fragment;
755 }
756
757 /*
758 export function split(bound, cutElement, breakAfter) {
759 let needsRemoval = [];
760 let index = indexOf(cutElement);
761
762 if (!breakAfter && index === 0) {
763 return;
764 }
765
766 if (breakAfter && index === (cutElement.parentNode.children.length - 1)) {
767 return;
768 }
769
770 // Create a fragment with rebuilt ancestors
771 let fragment = rebuildAncestors(cutElement);
772
773 // Clone cut
774 if (!breakAfter) {
775 let clone = cutElement.cloneNode(true);
776 let ref = cutElement.parentNode.getAttribute('data-ref');
777 let parent = fragment.querySelector("[data-ref='" + ref + "']");
778 parent.appendChild(clone);
779 needsRemoval.push(cutElement);
780 }
781
782 // Remove all after cut
783 let next = nodeAfter(cutElement, bound);
784 while (next) {
785 let clone = next.cloneNode(true);
786 let ref = next.parentNode.getAttribute('data-ref');
787 let parent = fragment.querySelector("[data-ref='" + ref + "']");
788 parent.appendChild(clone);
789 needsRemoval.push(next);
790 next = nodeAfter(next, bound);
791 }
792
793 // Remove originals
794 needsRemoval.forEach((node) => {
795 if (node) {
796 node.remove();
797 }
798 });
799
800 // Insert after bounds
801 bound.parentNode.insertBefore(fragment, bound.nextSibling);
802 return [bound, bound.nextSibling];
803 }
804 */
805
806 function needsBreakBefore(node) {
807 if( typeof node !== "undefined" &&
808 typeof node.dataset !== "undefined" &&
809 typeof node.dataset.breakBefore !== "undefined" &&
810 (node.dataset.breakBefore === "always" ||
811 node.dataset.breakBefore === "page" ||
812 node.dataset.breakBefore === "left" ||
813 node.dataset.breakBefore === "right" ||
814 node.dataset.breakBefore === "recto" ||
815 node.dataset.breakBefore === "verso")
816 ) {
817 return true;
818 }
819
820 return false;
821 }
822
823 function needsPreviousBreakAfter(node) {
824 if( typeof node !== "undefined" &&
825 typeof node.dataset !== "undefined" &&
826 typeof node.dataset.previousBreakAfter !== "undefined" &&
827 (node.dataset.previousBreakAfter === "always" ||
828 node.dataset.previousBreakAfter === "page" ||
829 node.dataset.previousBreakAfter === "left" ||
830 node.dataset.previousBreakAfter === "right" ||
831 node.dataset.previousBreakAfter === "recto" ||
832 node.dataset.previousBreakAfter === "verso")
833 ) {
834 return true;
835 }
836
837 return false;
838 }
839
840 function needsPageBreak(node, previousSignificantNode) {
841 if (typeof node === "undefined" || !previousSignificantNode || isIgnorable(node)) {
842 return false;
843 }
844 if (node.dataset && node.dataset.undisplayed) {
845 return false;
846 }
847 const previousSignificantNodePage = previousSignificantNode.dataset ? previousSignificantNode.dataset.page : undefined;
848 const currentNodePage = node.dataset ? node.dataset.page : undefined;
849 return currentNodePage !== previousSignificantNodePage;
850 }
851
852 function *words(node) {
853 let currentText = node.nodeValue;
854 let max = currentText.length;
855 let currentOffset = 0;
856 let currentLetter;
857
858 let range;
859
860 while(currentOffset < max) {
861 currentLetter = currentText[currentOffset];
862 if (/^[\S\u202F\u00A0]$/.test(currentLetter)) {
863 if (!range) {
864 range = document.createRange();
865 range.setStart(node, currentOffset);
866 }
867 } else {
868 if (range) {
869 range.setEnd(node, currentOffset);
870 yield range;
871 range = undefined;
872 }
873 }
874
875 currentOffset += 1;
876 }
877
878 if (range) {
879 range.setEnd(node, currentOffset);
880 yield range;
881 range = undefined;
882 }
883 }
884
885 function *letters(wordRange) {
886 let currentText = wordRange.startContainer;
887 let max = currentText.length;
888 let currentOffset = wordRange.startOffset;
889 // let currentLetter;
890
891 let range;
892
893 while(currentOffset < max) {
894 // currentLetter = currentText[currentOffset];
895 range = document.createRange();
896 range.setStart(currentText, currentOffset);
897 range.setEnd(currentText, currentOffset+1);
898
899 yield range;
900
901 currentOffset += 1;
902 }
903 }
904
905 function isContainer(node) {
906 let container;
907
908 if (typeof node.tagName === "undefined") {
909 return true;
910 }
911
912 if (node.style && node.style.display === "none") {
913 return false;
914 }
915
916 switch (node.tagName) {
917 // Inline
918 case "A":
919 case "ABBR":
920 case "ACRONYM":
921 case "B":
922 case "BDO":
923 case "BIG":
924 case "BR":
925 case "BUTTON":
926 case "CITE":
927 case "CODE":
928 case "DFN":
929 case "EM":
930 case "I":
931 case "IMG":
932 case "INPUT":
933 case "KBD":
934 case "LABEL":
935 case "MAP":
936 case "OBJECT":
937 case "Q":
938 case "SAMP":
939 case "SCRIPT":
940 case "SELECT":
941 case "SMALL":
942 case "SPAN":
943 case "STRONG":
944 case "SUB":
945 case "SUP":
946 case "TEXTAREA":
947 case "TIME":
948 case "TT":
949 case "VAR":
950 case "P":
951 case "H1":
952 case "H2":
953 case "H3":
954 case "H4":
955 case "H5":
956 case "H6":
957 case "FIGCAPTION":
958 case "BLOCKQUOTE":
959 case "PRE":
960 case "LI":
961 case "TR":
962 case "DT":
963 case "DD":
964 case "VIDEO":
965 case "CANVAS":
966 container = false;
967 break;
968 default:
969 container = true;
970 }
971
972 return container;
973 }
974
975 function cloneNode(n, deep=false) {
976 return n.cloneNode(deep);
977 }
978
979 function findElement(node, doc) {
980 const ref = node.getAttribute("data-ref");
981 return findRef(ref, doc);
982 }
983
984 function findRef(ref, doc) {
985 return doc.querySelector(`[data-ref='${ref}']`);
986 }
987
988 function validNode(node) {
989 if (isText(node)) {
990 return true;
991 }
992
993 if (isElement(node) && node.dataset.ref) {
994 return true;
995 }
996
997 return false;
998 }
999
1000 function prevValidNode(node) {
1001 while (!validNode(node)) {
1002 if (node.previousSibling) {
1003 node = node.previousSibling;
1004 } else {
1005 node = node.parentNode;
1006 }
1007
1008 if (!node) {
1009 break;
1010 }
1011 }
1012
1013 return node;
1014 }
1015
1016
1017 function indexOf$1(node) {
1018 let parent = node.parentNode;
1019 if (!parent) {
1020 return 0;
1021 }
1022 return Array.prototype.indexOf.call(parent.childNodes, node);
1023 }
1024
1025 function child(node, index) {
1026 return node.childNodes[index];
1027 }
1028
1029 function hasContent(node) {
1030 if (isElement(node)) {
1031 return true;
1032 } else if (isText(node) &&
1033 node.textContent.trim().length) {
1034 return true;
1035 }
1036 return false;
1037 }
1038
1039 function indexOfTextNode(node, parent) {
1040 if (!isText(node)) {
1041 return -1;
1042 }
1043 let nodeTextContent = node.textContent;
1044 let child;
1045 let index = -1;
1046 for (var i = 0; i < parent.childNodes.length; i++) {
1047 child = parent.childNodes[i];
1048 if (child.nodeType === 3) {
1049 let text = parent.childNodes[i].textContent;
1050 if (text.includes(nodeTextContent)) {
1051 index = i;
1052 break;
1053 }
1054 }
1055 }
1056
1057 return index;
1058 }
1059
1060
1061 /**
1062 * Throughout, whitespace is defined as one of the characters
1063 * "\t" TAB \u0009
1064 * "\n" LF \u000A
1065 * "\r" CR \u000D
1066 * " " SPC \u0020
1067 *
1068 * This does not use Javascript's "\s" because that includes non-breaking
1069 * spaces (and also some other characters).
1070 */
1071
1072 /**
1073 * Determine if a node should be ignored by the iterator functions.
1074 * taken from https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Whitespace#Whitespace_helper_functions
1075 *
1076 * @param {Node} node An object implementing the DOM1 |Node| interface.
1077 * @return {boolean} true if the node is:
1078 * 1) A |Text| node that is all whitespace
1079 * 2) A |Comment| node
1080 * and otherwise false.
1081 */
1082 function isIgnorable(node) {
1083 return (node.nodeType === 8) || // A comment node
1084 ((node.nodeType === 3) && isAllWhitespace(node)); // a text node, all whitespace
1085 }
1086
1087 /**
1088 * Determine whether a node's text content is entirely whitespace.
1089 *
1090 * @param {Node} node A node implementing the |CharacterData| interface (i.e., a |Text|, |Comment|, or |CDATASection| node
1091 * @return {boolean} true if all of the text content of |nod| is whitespace, otherwise false.
1092 */
1093 function isAllWhitespace(node) {
1094 return !(/[^\t\n\r ]/.test(node.textContent));
1095 }
1096
1097 /**
1098 * Version of |previousSibling| that skips nodes that are entirely
1099 * whitespace or comments. (Normally |previousSibling| is a property
1100 * of all DOM nodes that gives the sibling node, the node that is
1101 * a child of the same parent, that occurs immediately before the
1102 * reference node.)
1103 *
1104 * @param {ChildNode} sib The reference node.
1105 * @return {Node|null} Either:
1106 * 1) The closest previous sibling to |sib| that is not ignorable according to |is_ignorable|, or
1107 * 2) null if no such node exists.
1108 */
1109 function previousSignificantNode(sib) {
1110 while ((sib = sib.previousSibling)) {
1111 if (!isIgnorable(sib)) return sib;
1112 }
1113 return null;
1114 }
1115
1116 function breakInsideAvoidParentNode(node) {
1117 while ((node = node.parentNode)) {
1118 if (node && node.dataset && node.dataset.breakInside === "avoid") {
1119 return node;
1120 }
1121 }
1122 return null;
1123 }
1124
1125 /**
1126 * Find a parent with a given node name.
1127 * @param {Node} node - initial Node
1128 * @param {string} nodeName - node name (eg. "TD", "TABLE", "STRONG"...)
1129 * @param {Node} limiter - go up to the parent until there's no more parent or the current node is equals to the limiter
1130 * @returns {Node|undefined} - Either:
1131 * 1) The closest parent for a the given node name, or
1132 * 2) undefined if no such node exists.
1133 */
1134 function parentOf(node, nodeName, limiter) {
1135 if (limiter && node === limiter) {
1136 return;
1137 }
1138 if (node.parentNode) {
1139 while ((node = node.parentNode)) {
1140 if (limiter && node === limiter) {
1141 return;
1142 }
1143 if (node.nodeName === nodeName) {
1144 return node;
1145 }
1146 }
1147 }
1148 }
1149
1150 /**
1151 * Version of |nextSibling| that skips nodes that are entirely
1152 * whitespace or comments.
1153 *
1154 * @param {ChildNode} sib The reference node.
1155 * @return {Node|null} Either:
1156 * 1) The closest next sibling to |sib| that is not ignorable according to |is_ignorable|, or
1157 * 2) null if no such node exists.
1158 */
1159 function nextSignificantNode(sib) {
1160 while ((sib = sib.nextSibling)) {
1161 if (!isIgnorable(sib)) return sib;
1162 }
1163 return null;
1164 }
1165
1166 function filterTree(content, func, what) {
1167 const treeWalker = document.createTreeWalker(
1168 content || this.dom,
1169 what || NodeFilter.SHOW_ALL,
1170 func ? { acceptNode: func } : null,
1171 false
1172 );
1173
1174 let node;
1175 let current;
1176 node = treeWalker.nextNode();
1177 while(node) {
1178 current = node;
1179 node = treeWalker.nextNode();
1180 current.parentNode.removeChild(current);
1181 }
1182 }
1183
1184 /**
1185 * Layout
1186 * @class
1187 */
1188 class BreakToken {
1189
1190 constructor(node, offset) {
1191 this.node = node;
1192 this.offset = offset;
1193 }
1194
1195 equals(otherBreakToken) {
1196 if (!otherBreakToken) {
1197 return false;
1198 }
1199 if (this["node"] && otherBreakToken["node"] &&
1200 this["node"] !== otherBreakToken["node"]) {
1201 return false;
1202 }
1203 if (this["offset"] && otherBreakToken["offset"] &&
1204 this["offset"] !== otherBreakToken["offset"]) {
1205 return false;
1206 }
1207 return true;
1208 }
1209
1210 }
1211
1212 const MAX_CHARS_PER_BREAK = 1500;
1213
1214 /**
1215 * Layout
1216 * @class
1217 */
1218 class Layout {
1219
1220 constructor(element, hooks, options) {
1221 this.element = element;
1222
1223 this.bounds = this.element.getBoundingClientRect();
1224
1225 if (hooks) {
1226 this.hooks = hooks;
1227 } else {
1228 this.hooks = {};
1229 this.hooks.layout = new Hook();
1230 this.hooks.renderNode = new Hook();
1231 this.hooks.layoutNode = new Hook();
1232 this.hooks.beforeOverflow = new Hook();
1233 this.hooks.onOverflow = new Hook();
1234 this.hooks.onBreakToken = new Hook();
1235 }
1236
1237 this.settings = options || {};
1238
1239 this.maxChars = this.settings.maxChars || MAX_CHARS_PER_BREAK;
1240 this.forceRenderBreak = false;
1241 }
1242
1243 async renderTo(wrapper, source, breakToken, bounds = this.bounds) {
1244 let start = this.getStart(source, breakToken);
1245 let walker = walk(start, source);
1246
1247 let node;
1248 let prevNode;
1249 let done;
1250 let next;
1251
1252 let hasRenderedContent = false;
1253 let newBreakToken;
1254
1255 let length = 0;
1256
1257 let prevBreakToken = breakToken || new BreakToken(start);
1258
1259 while (!done && !newBreakToken) {
1260 next = walker.next();
1261 prevNode = node;
1262 node = next.value;
1263 done = next.done;
1264
1265 if (!node) {
1266 this.hooks && this.hooks.layout.trigger(wrapper, this);
1267
1268 let imgs = wrapper.querySelectorAll("img");
1269 if (imgs.length) {
1270 await this.waitForImages(imgs);
1271 }
1272
1273 newBreakToken = this.findBreakToken(wrapper, source, bounds, prevBreakToken);
1274
1275 if (newBreakToken && newBreakToken.equals(prevBreakToken)) {
1276 console.warn("Unable to layout item: ", prevNode);
1277 return undefined;
1278 }
1279 return newBreakToken;
1280 }
1281
1282 this.hooks && this.hooks.layoutNode.trigger(node);
1283
1284 // Check if the rendered element has a break set
1285 if (hasRenderedContent && this.shouldBreak(node)) {
1286 this.hooks && this.hooks.layout.trigger(wrapper, this);
1287
1288 let imgs = wrapper.querySelectorAll("img");
1289 if (imgs.length) {
1290 await this.waitForImages(imgs);
1291 }
1292
1293 newBreakToken = this.findBreakToken(wrapper, source, bounds, prevBreakToken);
1294
1295 if (!newBreakToken) {
1296 newBreakToken = this.breakAt(node);
1297 }
1298
1299 if (newBreakToken && newBreakToken.equals(prevBreakToken)) {
1300 console.warn("Unable to layout item: ", node);
1301 return undefined;
1302 }
1303
1304 length = 0;
1305
1306 break;
1307 }
1308
1309 // Should the Node be a shallow or deep clone
1310 let shallow = isContainer(node);
1311
1312 let rendered = this.append(node, wrapper, breakToken, shallow);
1313
1314 length += rendered.textContent.length;
1315
1316 // Check if layout has content yet
1317 if (!hasRenderedContent) {
1318 hasRenderedContent = hasContent(node);
1319 }
1320
1321 // Skip to the next node if a deep clone was rendered
1322 if (!shallow) {
1323 walker = walk(nodeAfter(node, source), source);
1324 }
1325
1326 if (this.forceRenderBreak) {
1327 this.hooks && this.hooks.layout.trigger(wrapper, this);
1328
1329 newBreakToken = this.findBreakToken(wrapper, source, bounds, prevBreakToken);
1330
1331 if (!newBreakToken) {
1332 newBreakToken = this.breakAt(node);
1333 }
1334
1335 length = 0;
1336 this.forceRenderBreak = false;
1337
1338 break;
1339 }
1340
1341 // Only check x characters
1342 if (length >= this.maxChars) {
1343
1344 this.hooks && this.hooks.layout.trigger(wrapper, this);
1345
1346 let imgs = wrapper.querySelectorAll("img");
1347 if (imgs.length) {
1348 await this.waitForImages(imgs);
1349 }
1350
1351 newBreakToken = this.findBreakToken(wrapper, source, bounds, prevBreakToken);
1352
1353 if (newBreakToken && newBreakToken.equals(prevBreakToken)) {
1354 console.warn("Unable to layout item: ", node);
1355 return undefined;
1356 }
1357
1358 if (newBreakToken) {
1359 length = 0;
1360 }
1361 }
1362
1363 }
1364
1365 return newBreakToken;
1366 }
1367
1368 breakAt(node, offset = 0) {
1369 let newBreakToken = new BreakToken(
1370 node,
1371 offset
1372 );
1373 let breakHooks = this.hooks.onBreakToken.triggerSync(newBreakToken, undefined, node, this);
1374 breakHooks.forEach((newToken) => {
1375 if (typeof newToken != "undefined") {
1376 newBreakToken = newToken;
1377 }
1378 });
1379
1380 return newBreakToken;
1381 }
1382
1383 shouldBreak(node) {
1384 let previousSibling = previousSignificantNode(node);
1385 let parentNode = node.parentNode;
1386 let parentBreakBefore = needsBreakBefore(node) && parentNode && !previousSibling && needsBreakBefore(parentNode);
1387 let doubleBreakBefore;
1388
1389 if (parentBreakBefore) {
1390 doubleBreakBefore = node.dataset.breakBefore === parentNode.dataset.breakBefore;
1391 }
1392
1393 return !doubleBreakBefore && needsBreakBefore(node) || needsPreviousBreakAfter(node) || needsPageBreak(node, previousSibling);
1394 }
1395
1396 forceBreak() {
1397 this.forceRenderBreak = true;
1398 }
1399
1400 getStart(source, breakToken) {
1401 let start;
1402 let node = breakToken && breakToken.node;
1403
1404 if (node) {
1405 start = node;
1406 } else {
1407 start = source.firstChild;
1408 }
1409
1410 return start;
1411 }
1412
1413 append(node, dest, breakToken, shallow = true, rebuild = true) {
1414
1415 let clone = cloneNode(node, !shallow);
1416
1417 if (node.parentNode && isElement(node.parentNode)) {
1418 let parent = findElement(node.parentNode, dest);
1419 // Rebuild chain
1420 if (parent) {
1421 parent.appendChild(clone);
1422 } else if (rebuild) {
1423 let fragment = rebuildAncestors(node);
1424 parent = findElement(node.parentNode, fragment);
1425 if (!parent) {
1426 dest.appendChild(clone);
1427 } else if (breakToken && isText(breakToken.node) && breakToken.offset > 0) {
1428 clone.textContent = clone.textContent.substring(breakToken.offset);
1429 parent.appendChild(clone);
1430 } else {
1431 parent.appendChild(clone);
1432 }
1433
1434 dest.appendChild(fragment);
1435 } else {
1436 dest.appendChild(clone);
1437 }
1438
1439
1440 } else {
1441 dest.appendChild(clone);
1442 }
1443
1444 let nodeHooks = this.hooks.renderNode.triggerSync(clone, node, this);
1445 nodeHooks.forEach((newNode) => {
1446 if (typeof newNode != "undefined") {
1447 clone = newNode;
1448 }
1449 });
1450
1451 return clone;
1452 }
1453
1454 async waitForImages(imgs) {
1455 let results = Array.from(imgs).map(async (img) => {
1456 return this.awaitImageLoaded(img);
1457 });
1458 await Promise.all(results);
1459 }
1460
1461 async awaitImageLoaded(image) {
1462 return new Promise(resolve => {
1463 if (image.complete !== true) {
1464 image.onload = function () {
1465 let {width, height} = window.getComputedStyle(image);
1466 resolve(width, height);
1467 };
1468 image.onerror = function (e) {
1469 let {width, height} = window.getComputedStyle(image);
1470 resolve(width, height, e);
1471 };
1472 } else {
1473 let {width, height} = window.getComputedStyle(image);
1474 resolve(width, height);
1475 }
1476 });
1477 }
1478
1479 avoidBreakInside(node, limiter) {
1480 let breakNode;
1481
1482 if (node === limiter) {
1483 return;
1484 }
1485
1486 while (node.parentNode) {
1487 node = node.parentNode;
1488
1489 if (node === limiter) {
1490 break;
1491 }
1492
1493 if (window.getComputedStyle(node)["break-inside"] === "avoid") {
1494 breakNode = node;
1495 break;
1496 }
1497
1498 }
1499 return breakNode;
1500 }
1501
1502 createBreakToken(overflow, rendered, source) {
1503 let container = overflow.startContainer;
1504 let offset = overflow.startOffset;
1505 let node, renderedNode, parent, index, temp;
1506
1507 if (isElement(container)) {
1508 temp = child(container, offset);
1509
1510 if (isElement(temp)) {
1511 renderedNode = findElement(temp, rendered);
1512
1513 if (!renderedNode) {
1514 // Find closest element with data-ref
1515 let prevNode = prevValidNode(temp);
1516 if (!isElement(prevNode)) {
1517 prevNode = prevNode.parentElement;
1518 }
1519 renderedNode = findElement(prevNode, rendered);
1520 // Check if temp is the last rendered node at its level.
1521 if (!temp.nextSibling) {
1522 // We need to ensure that the previous sibling of temp is fully rendered.
1523 const renderedNodeFromSource = findElement(renderedNode, source);
1524 const walker = document.createTreeWalker(renderedNodeFromSource, NodeFilter.SHOW_ELEMENT);
1525 const lastChildOfRenderedNodeFromSource = walker.lastChild();
1526 const lastChildOfRenderedNodeMatchingFromRendered = findElement(lastChildOfRenderedNodeFromSource, rendered);
1527 // Check if we found that the last child in source
1528 if (!lastChildOfRenderedNodeMatchingFromRendered) {
1529 // Pending content to be rendered before virtual break token
1530 return;
1531 }
1532 // Otherwise we will return a break token as per below
1533 }
1534 // renderedNode is actually the last unbroken box that does not overflow.
1535 // Break Token is therefore the next sibling of renderedNode within source node.
1536 node = findElement(renderedNode, source).nextSibling;
1537 offset = 0;
1538 } else {
1539 node = findElement(renderedNode, source);
1540 offset = 0;
1541 }
1542 } else {
1543 renderedNode = findElement(container, rendered);
1544
1545 if (!renderedNode) {
1546 renderedNode = findElement(prevValidNode(container), rendered);
1547 }
1548
1549 parent = findElement(renderedNode, source);
1550 index = indexOfTextNode(temp, parent);
1551 // No seperatation for the first textNode of an element
1552 if(index === 0) {
1553 node = parent;
1554 offset = 0;
1555 } else {
1556 node = child(parent, index);
1557 offset = 0;
1558 }
1559 }
1560 } else {
1561 renderedNode = findElement(container.parentNode, rendered);
1562
1563 if (!renderedNode) {
1564 renderedNode = findElement(prevValidNode(container.parentNode), rendered);
1565 }
1566
1567 parent = findElement(renderedNode, source);
1568 index = indexOfTextNode(container, parent);
1569
1570 if (index === -1) {
1571 return;
1572 }
1573
1574 node = child(parent, index);
1575
1576 offset += node.textContent.indexOf(container.textContent);
1577 }
1578
1579 if (!node) {
1580 return;
1581 }
1582
1583 return new BreakToken(
1584 node,
1585 offset
1586 );
1587
1588 }
1589
1590 findBreakToken(rendered, source, bounds = this.bounds, prevBreakToken, extract = true) {
1591 let overflow = this.findOverflow(rendered, bounds);
1592 let breakToken, breakLetter;
1593
1594 let overflowHooks = this.hooks.onOverflow.triggerSync(overflow, rendered, bounds, this);
1595 overflowHooks.forEach((newOverflow) => {
1596 if (typeof newOverflow != "undefined") {
1597 overflow = newOverflow;
1598 }
1599 });
1600
1601 if (overflow) {
1602 breakToken = this.createBreakToken(overflow, rendered, source);
1603 // breakToken is nullable
1604 let breakHooks = this.hooks.onBreakToken.triggerSync(breakToken, overflow, rendered, this);
1605 breakHooks.forEach((newToken) => {
1606 if (typeof newToken != "undefined") {
1607 breakToken = newToken;
1608 }
1609 });
1610
1611 // Stop removal if we are in a loop
1612 if (breakToken && breakToken.equals(prevBreakToken)) {
1613 return breakToken;
1614 }
1615
1616 if (breakToken && breakToken["node"] && breakToken["offset"] && breakToken["node"].textContent) {
1617 breakLetter = breakToken["node"].textContent.charAt(breakToken["offset"]);
1618 } else {
1619 breakLetter = undefined;
1620 }
1621
1622 if (breakToken && breakToken.node && extract) {
1623 this.removeOverflow(overflow, breakLetter);
1624 }
1625
1626 }
1627 return breakToken;
1628 }
1629
1630 hasOverflow(element, bounds = this.bounds) {
1631 let constrainingElement = element && element.parentNode; // this gets the element, instead of the wrapper for the width workaround
1632 let {width} = element.getBoundingClientRect();
1633 let scrollWidth = constrainingElement ? constrainingElement.scrollWidth : 0;
1634 return Math.max(Math.floor(width), scrollWidth) > Math.round(bounds.width);
1635 }
1636
1637 findOverflow(rendered, bounds = this.bounds) {
1638 if (!this.hasOverflow(rendered, bounds)) return;
1639
1640 let start = Math.round(bounds.left);
1641 let end = Math.round(bounds.right);
1642 let range;
1643
1644 let walker = walk(rendered.firstChild, rendered);
1645
1646 // Find Start
1647 let next, done, node, offset, skip, breakAvoid, prev, br;
1648 while (!done) {
1649 next = walker.next();
1650 done = next.done;
1651 node = next.value;
1652 skip = false;
1653 breakAvoid = false;
1654 prev = undefined;
1655 br = undefined;
1656
1657 if (node) {
1658 let pos = getBoundingClientRect(node);
1659 let left = Math.round(pos.left);
1660 let right = Math.floor(pos.right);
1661
1662 if (!range && left >= end) {
1663 // Check if it is a float
1664 let isFloat = false;
1665
1666 // Check if the node is inside a break-inside: avoid table cell
1667 const insideTableCell = parentOf(node, "TD", rendered);
1668 if (insideTableCell && window.getComputedStyle(insideTableCell)["break-inside"] === "avoid") {
1669 // breaking inside a table cell produces unexpected result, as a workaround, we forcibly avoid break inside in a cell.
1670 prev = insideTableCell;
1671 } else if (isElement(node)) {
1672 let styles = window.getComputedStyle(node);
1673 isFloat = styles.getPropertyValue("float") !== "none";
1674 skip = styles.getPropertyValue("break-inside") === "avoid";
1675 breakAvoid = node.dataset.breakBefore === "avoid" || node.dataset.previousBreakAfter === "avoid";
1676 prev = breakAvoid && nodeBefore(node, rendered);
1677 br = node.tagName === "BR" || node.tagName === "WBR";
1678 }
1679
1680 if (prev) {
1681 range = document.createRange();
1682 range.selectNode(prev);
1683 break;
1684 }
1685
1686 if (!br && !isFloat && isElement(node)) {
1687 range = document.createRange();
1688 range.selectNode(node);
1689 break;
1690 }
1691
1692 if (isText(node) && node.textContent.trim().length) {
1693 range = document.createRange();
1694 range.selectNode(node);
1695 break;
1696 }
1697
1698 }
1699
1700 if (!range && isText(node) &&
1701 node.textContent.trim().length &&
1702 !breakInsideAvoidParentNode(node.parentNode)) {
1703
1704 let rects = getClientRects(node);
1705 let rect;
1706 left = 0;
1707 for (var i = 0; i != rects.length; i++) {
1708 rect = rects[i];
1709 if (rect.width > 0 && (!left || rect.left > left)) {
1710 left = rect.left;
1711 }
1712 }
1713
1714 if (left >= end) {
1715 range = document.createRange();
1716 offset = this.textBreak(node, start, end);
1717 if (!offset) {
1718 range = undefined;
1719 } else {
1720 range.setStart(node, offset);
1721 }
1722 break;
1723 }
1724 }
1725
1726 // Skip children
1727 if (skip || right <= end) {
1728 next = nodeAfter(node, rendered);
1729 if (next) {
1730 walker = walk(next, rendered);
1731 }
1732
1733 }
1734
1735 }
1736 }
1737
1738 // Find End
1739 if (range) {
1740 range.setEndAfter(rendered.lastChild);
1741 return range;
1742 }
1743
1744 }
1745
1746 findEndToken(rendered, source, bounds = this.bounds) {
1747 if (rendered.childNodes.length === 0) {
1748 return;
1749 }
1750
1751 let lastChild = rendered.lastChild;
1752
1753 let lastNodeIndex;
1754 while (lastChild && lastChild.lastChild) {
1755 if (!validNode(lastChild)) {
1756 // Only get elements with refs
1757 lastChild = lastChild.previousSibling;
1758 } else if (!validNode(lastChild.lastChild)) {
1759 // Deal with invalid dom items
1760 lastChild = prevValidNode(lastChild.lastChild);
1761 break;
1762 } else {
1763 lastChild = lastChild.lastChild;
1764 }
1765 }
1766
1767 if (isText(lastChild)) {
1768
1769 if (lastChild.parentNode.dataset.ref) {
1770 lastNodeIndex = indexOf$1(lastChild);
1771 lastChild = lastChild.parentNode;
1772 } else {
1773 lastChild = lastChild.previousSibling;
1774 }
1775 }
1776
1777 let original = findElement(lastChild, source);
1778
1779 if (lastNodeIndex) {
1780 original = original.childNodes[lastNodeIndex];
1781 }
1782
1783 let after = nodeAfter(original);
1784
1785 return this.breakAt(after);
1786 }
1787
1788 textBreak(node, start, end) {
1789 let wordwalker = words(node);
1790 let left = 0;
1791 let right = 0;
1792 let word, next, done, pos;
1793 let offset;
1794 while (!done) {
1795 next = wordwalker.next();
1796 word = next.value;
1797 done = next.done;
1798
1799 if (!word) {
1800 break;
1801 }
1802
1803 pos = getBoundingClientRect(word);
1804
1805 left = Math.floor(pos.left);
1806 right = Math.floor(pos.right);
1807
1808 if (left >= end) {
1809 offset = word.startOffset;
1810 break;
1811 }
1812
1813 if (right > end) {
1814 let letterwalker = letters(word);
1815 let letter, nextLetter, doneLetter;
1816
1817 while (!doneLetter) {
1818 nextLetter = letterwalker.next();
1819 letter = nextLetter.value;
1820 doneLetter = nextLetter.done;
1821
1822 if (!letter) {
1823 break;
1824 }
1825
1826 pos = getBoundingClientRect(letter);
1827 left = Math.floor(pos.left);
1828
1829 if (left >= end) {
1830 offset = letter.startOffset;
1831 done = true;
1832
1833 break;
1834 }
1835 }
1836 }
1837
1838 }
1839
1840 return offset;
1841 }
1842
1843 removeOverflow(overflow, breakLetter) {
1844 let {startContainer} = overflow;
1845 let extracted = overflow.extractContents();
1846
1847 this.hyphenateAtBreak(startContainer, breakLetter);
1848
1849 return extracted;
1850 }
1851
1852 hyphenateAtBreak(startContainer, breakLetter) {
1853 if (isText(startContainer)) {
1854 let startText = startContainer.textContent;
1855 let prevLetter = startText[startText.length - 1];
1856
1857 // Add a hyphen if previous character is a letter or soft hyphen
1858 if (
1859 (breakLetter && /^\w|\u00AD$/.test(prevLetter) && /^\w|\u00AD$/.test(breakLetter)) ||
1860 (!breakLetter && /^\w|\u00AD$/.test(prevLetter))
1861 ) {
1862 startContainer.parentNode.classList.add("pagedjs_hyphen");
1863 startContainer.textContent += this.settings.hyphenGlyph || "\u2011";
1864 }
1865 }
1866 }
1867
1868 equalTokens(a, b) {
1869 if (!a || !b) {
1870 return false;
1871 }
1872 if (a["node"] && b["node"] && a["node"] !== b["node"]) {
1873 return false;
1874 }
1875 if (a["offset"] && b["offset"] && a["offset"] !== b["offset"]) {
1876 return false;
1877 }
1878 return true;
1879 }
1880 }
1881
1882 eventEmitter(Layout.prototype);
1883
1884 /**
1885 * Render a page
1886 * @class
1887 */
1888 class Page {
1889 constructor(pagesArea, pageTemplate, blank, hooks) {
1890 this.pagesArea = pagesArea;
1891 this.pageTemplate = pageTemplate;
1892 this.blank = blank;
1893
1894 this.width = undefined;
1895 this.height = undefined;
1896
1897 this.hooks = hooks;
1898
1899 // this.element = this.create(this.pageTemplate);
1900 }
1901
1902 create(template, after) {
1903 //let documentFragment = document.createRange().createContextualFragment( TEMPLATE );
1904 //let page = documentFragment.children[0];
1905 let clone = document.importNode(this.pageTemplate.content, true);
1906
1907 let page, index;
1908 if (after) {
1909 this.pagesArea.insertBefore(clone, after.nextElementSibling);
1910 index = Array.prototype.indexOf.call(this.pagesArea.children, after.nextElementSibling);
1911 page = this.pagesArea.children[index];
1912 } else {
1913 this.pagesArea.appendChild(clone);
1914 page = this.pagesArea.lastChild;
1915 }
1916
1917 let pagebox = page.querySelector(".pagedjs_pagebox");
1918 let area = page.querySelector(".pagedjs_page_content");
1919
1920
1921 let size = area.getBoundingClientRect();
1922
1923
1924 area.style.columnWidth = Math.round(size.width) + "px";
1925 area.style.columnGap = "calc(var(--pagedjs-margin-right) + var(--pagedjs-margin-left))";
1926 // area.style.overflow = "scroll";
1927
1928 this.width = Math.round(size.width);
1929 this.height = Math.round(size.height);
1930
1931 this.element = page;
1932 this.pagebox = pagebox;
1933 this.area = area;
1934
1935 return page;
1936 }
1937
1938 createWrapper() {
1939 let wrapper = document.createElement("div");
1940
1941 this.area.appendChild(wrapper);
1942
1943 this.wrapper = wrapper;
1944
1945 return wrapper;
1946 }
1947
1948 index(pgnum) {
1949 this.position = pgnum;
1950
1951 let page = this.element;
1952 // let pagebox = this.pagebox;
1953
1954 let index = pgnum + 1;
1955
1956 let id = `page-${index}`;
1957
1958 this.id = id;
1959
1960 // page.dataset.pageNumber = index;
1961
1962 page.dataset.pageNumber = index;
1963 page.setAttribute("id", id);
1964
1965 if (this.name) {
1966 page.classList.add("pagedjs_" + this.name + "_page");
1967 }
1968
1969 if (this.blank) {
1970 page.classList.add("pagedjs_blank_page");
1971 }
1972
1973 if (pgnum === 0) {
1974 page.classList.add("pagedjs_first_page");
1975 }
1976
1977 if (pgnum % 2 !== 1) {
1978 page.classList.remove("pagedjs_left_page");
1979 page.classList.add("pagedjs_right_page");
1980 } else {
1981 page.classList.remove("pagedjs_right_page");
1982 page.classList.add("pagedjs_left_page");
1983 }
1984 }
1985
1986 /*
1987 size(width, height) {
1988 if (width === this.width && height === this.height) {
1989 return;
1990 }
1991 this.width = width;
1992 this.height = height;
1993
1994 this.element.style.width = Math.round(width) + "px";
1995 this.element.style.height = Math.round(height) + "px";
1996 this.element.style.columnWidth = Math.round(width) + "px";
1997 }
1998 */
1999
2000 async layout(contents, breakToken, maxChars) {
2001
2002 this.clear();
2003
2004 this.startToken = breakToken;
2005
2006 this.layoutMethod = new Layout(this.area, this.hooks, maxChars);
2007
2008 let newBreakToken = await this.layoutMethod.renderTo(this.wrapper, contents, breakToken);
2009
2010 this.addListeners(contents);
2011
2012 this.endToken = newBreakToken;
2013
2014 return newBreakToken;
2015 }
2016
2017 async append(contents, breakToken) {
2018
2019 if (!this.layoutMethod) {
2020 return this.layout(contents, breakToken);
2021 }
2022
2023 let newBreakToken = await this.layoutMethod.renderTo(this.wrapper, contents, breakToken);
2024
2025 this.endToken = newBreakToken;
2026
2027 return newBreakToken;
2028 }
2029
2030 getByParent(ref, entries) {
2031 let e;
2032 for (var i = 0; i < entries.length; i++) {
2033 e = entries[i];
2034 if (e.dataset.ref === ref) {
2035 return e;
2036 }
2037 }
2038 }
2039
2040 onOverflow(func) {
2041 this._onOverflow = func;
2042 }
2043
2044 onUnderflow(func) {
2045 this._onUnderflow = func;
2046 }
2047
2048 clear() {
2049 this.removeListeners();
2050 this.wrapper && this.wrapper.remove();
2051 this.createWrapper();
2052 }
2053
2054 addListeners(contents) {
2055 if (typeof ResizeObserver !== "undefined") {
2056 this.addResizeObserver(contents);
2057 } else {
2058 this._checkOverflowAfterResize = this.checkOverflowAfterResize.bind(this, contents);
2059 this.element.addEventListener("overflow", this._checkOverflowAfterResize, false);
2060 this.element.addEventListener("underflow", this._checkOverflowAfterResize, false);
2061 }
2062 // TODO: fall back to mutation observer?
2063
2064 this._onScroll = function () {
2065 if (this.listening) {
2066 this.element.scrollLeft = 0;
2067 }
2068 }.bind(this);
2069
2070 // Keep scroll left from changing
2071 this.element.addEventListener("scroll", this._onScroll);
2072
2073 this.listening = true;
2074
2075 return true;
2076 }
2077
2078 removeListeners() {
2079 this.listening = false;
2080
2081 if (typeof ResizeObserver !== "undefined" && this.ro) {
2082 this.ro.disconnect();
2083 } else if (this.element) {
2084 this.element.removeEventListener("overflow", this._checkOverflowAfterResize, false);
2085 this.element.removeEventListener("underflow", this._checkOverflowAfterResize, false);
2086 }
2087
2088 this.element && this.element.removeEventListener("scroll", this._onScroll);
2089
2090 }
2091
2092 addResizeObserver(contents) {
2093 let wrapper = this.wrapper;
2094 let prevHeight = wrapper.getBoundingClientRect().height;
2095 this.ro = new ResizeObserver(entries => {
2096
2097 if (!this.listening) {
2098 return;
2099 }
2100 requestAnimationFrame(() => {
2101 for (let entry of entries) {
2102 const cr = entry.contentRect;
2103
2104 if (cr.height > prevHeight) {
2105 this.checkOverflowAfterResize(contents);
2106 prevHeight = wrapper.getBoundingClientRect().height;
2107 } else if (cr.height < prevHeight) { // TODO: calc line height && (prevHeight - cr.height) >= 22
2108 this.checkUnderflowAfterResize(contents);
2109 prevHeight = cr.height;
2110 }
2111 }
2112 });
2113 });
2114
2115 this.ro.observe(wrapper);
2116 }
2117
2118 checkOverflowAfterResize(contents) {
2119 if (!this.listening || !this.layoutMethod) {
2120 return;
2121 }
2122
2123 let newBreakToken = this.layoutMethod.findBreakToken(this.wrapper, contents, this.startToken);
2124
2125 if (newBreakToken) {
2126 this.endToken = newBreakToken;
2127 this._onOverflow && this._onOverflow(newBreakToken);
2128 }
2129 }
2130
2131 checkUnderflowAfterResize(contents) {
2132 if (!this.listening || !this.layoutMethod) {
2133 return;
2134 }
2135
2136 let endToken = this.layoutMethod.findEndToken(this.wrapper, contents);
2137
2138 if (endToken) {
2139 this._onUnderflow && this._onUnderflow(endToken);
2140 }
2141 }
2142
2143
2144 destroy() {
2145 this.removeListeners();
2146
2147 this.element.remove();
2148
2149 this.element = undefined;
2150 this.wrapper = undefined;
2151 }
2152 }
2153
2154 eventEmitter(Page.prototype);
2155
2156 /**
2157 * Render a flow of text offscreen
2158 * @class
2159 */
2160 class ContentParser {
2161
2162 constructor(content, cb) {
2163 if (content && content.nodeType) {
2164 // handle dom
2165 this.dom = this.add(content);
2166 } else if (typeof content === "string") {
2167 this.dom = this.parse(content);
2168 }
2169
2170 return this.dom;
2171 }
2172
2173 parse(markup, mime) {
2174 let range = document.createRange();
2175 let fragment = range.createContextualFragment(markup);
2176
2177 this.addRefs(fragment);
2178
2179 return fragment;
2180 }
2181
2182 add(contents) {
2183 // let fragment = document.createDocumentFragment();
2184 //
2185 // let children = [...contents.childNodes];
2186 // for (let child of children) {
2187 // let clone = child.cloneNode(true);
2188 // fragment.appendChild(clone);
2189 // }
2190
2191 this.addRefs(contents);
2192
2193 return contents;
2194 }
2195
2196 addRefs(content) {
2197 var treeWalker = document.createTreeWalker(
2198 content,
2199 NodeFilter.SHOW_ELEMENT,
2200 null,
2201 false
2202 );
2203
2204 let node = treeWalker.nextNode();
2205 while(node) {
2206
2207 if (!node.hasAttribute("data-ref")) {
2208 let uuid = UUID();
2209 node.setAttribute("data-ref", uuid);
2210 }
2211
2212 if (node.id) {
2213 node.setAttribute("data-id", node.id);
2214 }
2215
2216 // node.setAttribute("data-children", node.childNodes.length);
2217
2218 // node.setAttribute("data-text", node.textContent.trim().length);
2219 node = treeWalker.nextNode();
2220 }
2221 }
2222
2223 find(ref) {
2224 return this.refs[ref];
2225 }
2226
2227 destroy() {
2228 this.refs = undefined;
2229 this.dom = undefined;
2230 }
2231 }
2232
2233 /**
2234 * Queue for handling tasks one at a time
2235 * @class
2236 * @param {scope} context what this will resolve to in the tasks
2237 */
2238 class Queue {
2239 constructor(context){
2240 this._q = [];
2241 this.context = context;
2242 this.tick = requestAnimationFrame;
2243 this.running = false;
2244 this.paused = false;
2245 }
2246
2247 /**
2248 * Add an item to the queue
2249 * @return {Promise} enqueued
2250 */
2251 enqueue() {
2252 var deferred, promise;
2253 var queued;
2254 var task = [].shift.call(arguments);
2255 var args = arguments;
2256
2257 // Handle single args without context
2258 // if(args && !Array.isArray(args)) {
2259 // args = [args];
2260 // }
2261 if(!task) {
2262 throw new Error("No Task Provided");
2263 }
2264
2265 if(typeof task === "function"){
2266
2267 deferred = new defer();
2268 promise = deferred.promise;
2269
2270 queued = {
2271 "task" : task,
2272 "args" : args,
2273 //"context" : context,
2274 "deferred" : deferred,
2275 "promise" : promise
2276 };
2277
2278 } else {
2279 // Task is a promise
2280 queued = {
2281 "promise" : task
2282 };
2283
2284 }
2285
2286 this._q.push(queued);
2287
2288 // Wait to start queue flush
2289 if (this.paused == false && !this.running) {
2290 this.run();
2291 }
2292
2293 return queued.promise;
2294 }
2295
2296 /**
2297 * Run one item
2298 * @return {Promise} dequeued
2299 */
2300 dequeue(){
2301 var inwait, task, result;
2302
2303 if(this._q.length && !this.paused) {
2304 inwait = this._q.shift();
2305 task = inwait.task;
2306 if(task){
2307 // console.log(task)
2308
2309 result = task.apply(this.context, inwait.args);
2310
2311 if(result && typeof result["then"] === "function") {
2312 // Task is a function that returns a promise
2313 return result.then(function(){
2314 inwait.deferred.resolve.apply(this.context, arguments);
2315 }.bind(this), function() {
2316 inwait.deferred.reject.apply(this.context, arguments);
2317 }.bind(this));
2318 } else {
2319 // Task resolves immediately
2320 inwait.deferred.resolve.apply(this.context, result);
2321 return inwait.promise;
2322 }
2323
2324
2325
2326 } else if(inwait.promise) {
2327 // Task is a promise
2328 return inwait.promise;
2329 }
2330
2331 } else {
2332 inwait = new defer();
2333 inwait.deferred.resolve();
2334 return inwait.promise;
2335 }
2336
2337 }
2338
2339 // Run All Immediately
2340 dump(){
2341 while(this._q.length) {
2342 this.dequeue();
2343 }
2344 }
2345
2346 /**
2347 * Run all tasks sequentially, at convince
2348 * @return {Promise} all run
2349 */
2350 run(){
2351
2352 if(!this.running){
2353 this.running = true;
2354 this.defered = new defer();
2355 }
2356
2357 this.tick.call(window, () => {
2358
2359 if(this._q.length) {
2360
2361 this.dequeue()
2362 .then(function(){
2363 this.run();
2364 }.bind(this));
2365
2366 } else {
2367 this.defered.resolve();
2368 this.running = undefined;
2369 }
2370
2371 });
2372
2373 // Unpause
2374 if(this.paused == true) {
2375 this.paused = false;
2376 }
2377
2378 return this.defered.promise;
2379 }
2380
2381 /**
2382 * Flush all, as quickly as possible
2383 * @return {Promise} ran
2384 */
2385 flush(){
2386
2387 if(this.running){
2388 return this.running;
2389 }
2390
2391 if(this._q.length) {
2392 this.running = this.dequeue()
2393 .then(function(){
2394 this.running = undefined;
2395 return this.flush();
2396 }.bind(this));
2397
2398 return this.running;
2399 }
2400
2401 }
2402
2403 /**
2404 * Clear all items in wait
2405 * @return {void}
2406 */
2407 clear(){
2408 this._q = [];
2409 }
2410
2411 /**
2412 * Get the number of tasks in the queue
2413 * @return {number} tasks
2414 */
2415 length(){
2416 return this._q.length;
2417 }
2418
2419 /**
2420 * Pause a running queue
2421 * @return {void}
2422 */
2423 pause(){
2424 this.paused = true;
2425 }
2426
2427 /**
2428 * End the queue
2429 * @return {void}
2430 */
2431 stop(){
2432 this._q = [];
2433 this.running = false;
2434 this.paused = true;
2435 }
2436 }
2437
2438 const TEMPLATE = `
2439<div class="pagedjs_page">
2440 <div class="pagedjs_sheet">
2441 <div class="pagedjs_bleed pagedjs_bleed-top">
2442 <div class="pagedjs_marks-crop"></div>
2443 <div class="pagedjs_marks-middle">
2444 <div class="pagedjs_marks-cross"></div>
2445 </div>
2446 <div class="pagedjs_marks-crop"></div>
2447 </div>
2448 <div class="pagedjs_bleed pagedjs_bleed-bottom">
2449 <div class="pagedjs_marks-crop"></div>
2450 <div class="pagedjs_marks-middle">
2451 <div class="pagedjs_marks-cross"></div>
2452 </div> <div class="pagedjs_marks-crop"></div>
2453 </div>
2454 <div class="pagedjs_bleed pagedjs_bleed-left">
2455 <div class="pagedjs_marks-crop"></div>
2456 <div class="pagedjs_marks-middle">
2457 <div class="pagedjs_marks-cross"></div>
2458 </div> <div class="pagedjs_marks-crop"></div>
2459 </div>
2460 <div class="pagedjs_bleed pagedjs_bleed-right">
2461 <div class="pagedjs_marks-crop"></div>
2462 <div class="pagedjs_marks-middle">
2463 <div class="pagedjs_marks-cross"></div>
2464 </div>
2465 <div class="pagedjs_marks-crop"></div>
2466 </div>
2467 <div class="pagedjs_pagebox">
2468 <div class="pagedjs_margin-top-left-corner-holder">
2469 <div class="pagedjs_margin pagedjs_margin-top-left-corner"><div class="pagedjs_margin-content"></div></div>
2470 </div>
2471 <div class="pagedjs_margin-top">
2472 <div class="pagedjs_margin pagedjs_margin-top-left"><div class="pagedjs_margin-content"></div></div>
2473 <div class="pagedjs_margin pagedjs_margin-top-center"><div class="pagedjs_margin-content"></div></div>
2474 <div class="pagedjs_margin pagedjs_margin-top-right"><div class="pagedjs_margin-content"></div></div>
2475 </div>
2476 <div class="pagedjs_margin-top-right-corner-holder">
2477 <div class="pagedjs_margin pagedjs_margin-top-right-corner"><div class="pagedjs_margin-content"></div></div>
2478 </div>
2479 <div class="pagedjs_margin-right">
2480 <div class="pagedjs_margin pagedjs_margin-right-top"><div class="pagedjs_margin-content"></div></div>
2481 <div class="pagedjs_margin pagedjs_margin-right-middle"><div class="pagedjs_margin-content"></div></div>
2482 <div class="pagedjs_margin pagedjs_margin-right-bottom"><div class="pagedjs_margin-content"></div></div>
2483 </div>
2484 <div class="pagedjs_margin-left">
2485 <div class="pagedjs_margin pagedjs_margin-left-top"><div class="pagedjs_margin-content"></div></div>
2486 <div class="pagedjs_margin pagedjs_margin-left-middle"><div class="pagedjs_margin-content"></div></div>
2487 <div class="pagedjs_margin pagedjs_margin-left-bottom"><div class="pagedjs_margin-content"></div></div>
2488 </div>
2489 <div class="pagedjs_margin-bottom-left-corner-holder">
2490 <div class="pagedjs_margin pagedjs_margin-bottom-left-corner"><div class="pagedjs_margin-content"></div></div>
2491 </div>
2492 <div class="pagedjs_margin-bottom">
2493 <div class="pagedjs_margin pagedjs_margin-bottom-left"><div class="pagedjs_margin-content"></div></div>
2494 <div class="pagedjs_margin pagedjs_margin-bottom-center"><div class="pagedjs_margin-content"></div></div>
2495 <div class="pagedjs_margin pagedjs_margin-bottom-right"><div class="pagedjs_margin-content"></div></div>
2496 </div>
2497 <div class="pagedjs_margin-bottom-right-corner-holder">
2498 <div class="pagedjs_margin pagedjs_margin-bottom-right-corner"><div class="pagedjs_margin-content"></div></div>
2499 </div>
2500 <div class="pagedjs_area">
2501 <div class="pagedjs_page_content"></div>
2502 </div>
2503 </div>
2504 </div>
2505</div>`;
2506
2507 /**
2508 * Chop up text into flows
2509 * @class
2510 */
2511 class Chunker {
2512 constructor(content, renderTo, options) {
2513 // this.preview = preview;
2514
2515 this.settings = options || {};
2516
2517 this.hooks = {};
2518 this.hooks.beforeParsed = new Hook(this);
2519 this.hooks.filter = new Hook(this);
2520 this.hooks.afterParsed = new Hook(this);
2521 this.hooks.beforePageLayout = new Hook(this);
2522 this.hooks.layout = new Hook(this);
2523 this.hooks.renderNode = new Hook(this);
2524 this.hooks.layoutNode = new Hook(this);
2525 this.hooks.onOverflow = new Hook(this);
2526 this.hooks.onBreakToken = new Hook();
2527 this.hooks.afterPageLayout = new Hook(this);
2528 this.hooks.afterRendered = new Hook(this);
2529
2530 this.pages = [];
2531 this.total = 0;
2532
2533 this.q = new Queue(this);
2534 this.stopped = false;
2535 this.rendered = false;
2536
2537 this.content = content;
2538
2539 this.charsPerBreak = [];
2540 this.maxChars;
2541
2542 if (content) {
2543 this.flow(content, renderTo);
2544 }
2545 }
2546
2547 setup(renderTo) {
2548 this.pagesArea = document.createElement("div");
2549 this.pagesArea.classList.add("pagedjs_pages");
2550
2551 if (renderTo) {
2552 renderTo.appendChild(this.pagesArea);
2553 } else {
2554 document.querySelector("body").appendChild(this.pagesArea);
2555 }
2556
2557 this.pageTemplate = document.createElement("template");
2558 this.pageTemplate.innerHTML = TEMPLATE;
2559
2560 }
2561
2562 async flow(content, renderTo) {
2563 let parsed;
2564
2565 await this.hooks.beforeParsed.trigger(content, this);
2566
2567 parsed = new ContentParser(content);
2568
2569 this.hooks.filter.triggerSync(parsed);
2570
2571 this.source = parsed;
2572 this.breakToken = undefined;
2573
2574 if (this.pagesArea && this.pageTemplate) {
2575 this.q.clear();
2576 this.removePages();
2577 } else {
2578 this.setup(renderTo);
2579 }
2580
2581 this.emit("rendering", parsed);
2582
2583 await this.hooks.afterParsed.trigger(parsed, this);
2584
2585 await this.loadFonts();
2586
2587 let rendered = await this.render(parsed, this.breakToken);
2588 while (rendered.canceled) {
2589 this.start();
2590 rendered = await this.render(parsed, this.breakToken);
2591 }
2592
2593 this.rendered = true;
2594 this.pagesArea.style.setProperty("--pagedjs-page-count", this.total);
2595
2596 await this.hooks.afterRendered.trigger(this.pages, this);
2597
2598 this.emit("rendered", this.pages);
2599
2600
2601
2602 return this;
2603 }
2604
2605 // oversetPages() {
2606 // let overset = [];
2607 // for (let i = 0; i < this.pages.length; i++) {
2608 // let page = this.pages[i];
2609 // if (page.overset) {
2610 // overset.push(page);
2611 // // page.overset = false;
2612 // }
2613 // }
2614 // return overset;
2615 // }
2616 //
2617 // async handleOverset(parsed) {
2618 // let overset = this.oversetPages();
2619 // if (overset.length) {
2620 // console.log("overset", overset);
2621 // let index = this.pages.indexOf(overset[0]) + 1;
2622 // console.log("INDEX", index);
2623 //
2624 // // Remove pages
2625 // // this.removePages(index);
2626 //
2627 // // await this.render(parsed, overset[0].overset);
2628 //
2629 // // return this.handleOverset(parsed);
2630 // }
2631 // }
2632
2633 async render(parsed, startAt) {
2634 let renderer = this.layout(parsed, startAt, this.settings);
2635
2636 let done = false;
2637 let result;
2638 while (!done) {
2639 result = await this.q.enqueue(() => { return this.renderAsync(renderer); });
2640 done = result.done;
2641 }
2642
2643 return result;
2644 }
2645
2646 start() {
2647 this.rendered = false;
2648 this.stopped = false;
2649 }
2650
2651 stop() {
2652 this.stopped = true;
2653 // this.q.clear();
2654 }
2655
2656 renderOnIdle(renderer) {
2657 return new Promise(resolve => {
2658 requestIdleCallback(async () => {
2659 if (this.stopped) {
2660 return resolve({ done: true, canceled: true });
2661 }
2662 let result = await renderer.next();
2663 if (this.stopped) {
2664 resolve({ done: true, canceled: true });
2665 } else {
2666 resolve(result);
2667 }
2668 });
2669 });
2670 }
2671
2672 async renderAsync(renderer) {
2673 if (this.stopped) {
2674 return { done: true, canceled: true };
2675 }
2676 let result = await renderer.next();
2677 if (this.stopped) {
2678 return { done: true, canceled: true };
2679 } else {
2680 return result;
2681 }
2682 }
2683
2684 async handleBreaks(node) {
2685 let currentPage = this.total + 1;
2686 let currentPosition = currentPage % 2 === 0 ? "left" : "right";
2687 // TODO: Recto and Verso should reverse for rtl languages
2688 let currentSide = currentPage % 2 === 0 ? "verso" : "recto";
2689 let previousBreakAfter;
2690 let breakBefore;
2691 let page;
2692
2693 if (currentPage === 1) {
2694 return;
2695 }
2696
2697 if (node &&
2698 typeof node.dataset !== "undefined" &&
2699 typeof node.dataset.previousBreakAfter !== "undefined") {
2700 previousBreakAfter = node.dataset.previousBreakAfter;
2701 }
2702
2703 if (node &&
2704 typeof node.dataset !== "undefined" &&
2705 typeof node.dataset.breakBefore !== "undefined") {
2706 breakBefore = node.dataset.breakBefore;
2707 }
2708
2709 if( previousBreakAfter &&
2710 (previousBreakAfter === "left" || previousBreakAfter === "right") &&
2711 previousBreakAfter !== currentPosition) {
2712 page = this.addPage(true);
2713 } else if( previousBreakAfter &&
2714 (previousBreakAfter === "verso" || previousBreakAfter === "recto") &&
2715 previousBreakAfter !== currentSide) {
2716 page = this.addPage(true);
2717 } else if( breakBefore &&
2718 (breakBefore === "left" || breakBefore === "right") &&
2719 breakBefore !== currentPosition) {
2720 page = this.addPage(true);
2721 } else if( breakBefore &&
2722 (breakBefore === "verso" || breakBefore === "recto") &&
2723 breakBefore !== currentSide) {
2724 page = this.addPage(true);
2725 }
2726
2727 if (page) {
2728 await this.hooks.beforePageLayout.trigger(page, undefined, undefined, this);
2729 this.emit("page", page);
2730 // await this.hooks.layout.trigger(page.element, page, undefined, this);
2731 await this.hooks.afterPageLayout.trigger(page.element, page, undefined, this);
2732 this.emit("renderedPage", page);
2733 }
2734 }
2735
2736 async *layout(content, startAt) {
2737 let breakToken = startAt || false;
2738
2739 while (breakToken !== undefined && ( true)) {
2740
2741 if (breakToken && breakToken.node) {
2742 await this.handleBreaks(breakToken.node);
2743 } else {
2744 await this.handleBreaks(content.firstChild);
2745 }
2746
2747 let page = this.addPage();
2748
2749 await this.hooks.beforePageLayout.trigger(page, content, breakToken, this);
2750 this.emit("page", page);
2751
2752 // Layout content in the page, starting from the breakToken
2753 breakToken = await page.layout(content, breakToken, this.maxChars);
2754
2755 await this.hooks.afterPageLayout.trigger(page.element, page, breakToken, this);
2756 this.emit("renderedPage", page);
2757
2758 this.recoredCharLength(page.wrapper.textContent.length);
2759
2760 yield breakToken;
2761
2762 // Stop if we get undefined, showing we have reached the end of the content
2763 }
2764
2765
2766 }
2767
2768 recoredCharLength(length) {
2769 if (length === 0) {
2770 return;
2771 }
2772
2773 this.charsPerBreak.push(length);
2774
2775 // Keep the length of the last few breaks
2776 if (this.charsPerBreak.length > 4) {
2777 this.charsPerBreak.shift();
2778 }
2779
2780 this.maxChars = this.charsPerBreak.reduce((a, b) => a + b, 0) / (this.charsPerBreak.length);
2781 }
2782
2783 removePages(fromIndex=0) {
2784
2785 if (fromIndex >= this.pages.length) {
2786 return;
2787 }
2788
2789 // Remove pages
2790 for (let i = fromIndex; i < this.pages.length; i++) {
2791 this.pages[i].destroy();
2792 }
2793
2794 if (fromIndex > 0) {
2795 this.pages.splice(fromIndex);
2796 } else {
2797 this.pages = [];
2798 }
2799
2800 this.total = this.pages.length;
2801 }
2802
2803 addPage(blank) {
2804 let lastPage = this.pages[this.pages.length - 1];
2805 // Create a new page from the template
2806 let page = new Page(this.pagesArea, this.pageTemplate, blank, this.hooks);
2807
2808 this.pages.push(page);
2809
2810 // Create the pages
2811 page.create(undefined, lastPage && lastPage.element);
2812
2813 page.index(this.total);
2814
2815 if (!blank) {
2816 // Listen for page overflow
2817 page.onOverflow((overflowToken) => {
2818 console.warn("overflow on", page.id, overflowToken);
2819
2820 // Only reflow while rendering
2821 if (this.rendered) {
2822 return;
2823 }
2824
2825 let index = this.pages.indexOf(page) + 1;
2826
2827 // Stop the rendering
2828 this.stop();
2829
2830 // Set the breakToken to resume at
2831 this.breakToken = overflowToken;
2832
2833 // Remove pages
2834 this.removePages(index);
2835
2836 if (this.rendered === true) {
2837 this.rendered = false;
2838
2839 this.q.enqueue(async () => {
2840
2841 this.start();
2842
2843 await this.render(this.source, this.breakToken);
2844
2845 this.rendered = true;
2846
2847 });
2848 }
2849
2850
2851 });
2852
2853 page.onUnderflow((overflowToken) => {
2854 // console.log("underflow on", page.id, overflowToken);
2855
2856 // page.append(this.source, overflowToken);
2857
2858 });
2859 }
2860
2861 this.total = this.pages.length;
2862
2863 return page;
2864 }
2865 /*
2866 insertPage(index, blank) {
2867 let lastPage = this.pages[index];
2868 // Create a new page from the template
2869 let page = new Page(this.pagesArea, this.pageTemplate, blank, this.hooks);
2870
2871 let total = this.pages.splice(index, 0, page);
2872
2873 // Create the pages
2874 page.create(undefined, lastPage && lastPage.element);
2875
2876 page.index(index + 1);
2877
2878 for (let i = index + 2; i < this.pages.length; i++) {
2879 this.pages[i].index(i);
2880 }
2881
2882 if (!blank) {
2883 // Listen for page overflow
2884 page.onOverflow((overflowToken) => {
2885 if (total < this.pages.length) {
2886 this.pages[total].layout(this.source, overflowToken);
2887 } else {
2888 let newPage = this.addPage();
2889 newPage.layout(this.source, overflowToken);
2890 }
2891 });
2892
2893 page.onUnderflow(() => {
2894 // console.log("underflow on", page.id);
2895 });
2896 }
2897
2898 this.total += 1;
2899
2900 return page;
2901 }
2902 */
2903
2904
2905
2906 loadFonts() {
2907 let fontPromises = [];
2908 (document.fonts || []).forEach((fontFace) => {
2909 if (fontFace.status !== "loaded") {
2910 let fontLoaded = fontFace.load().then((r) => {
2911 return fontFace.family;
2912 }, (r) => {
2913 console.warn("Failed to preload font-family:", fontFace.family);
2914 return fontFace.family;
2915 });
2916 fontPromises.push(fontLoaded);
2917 }
2918 });
2919 return Promise.all(fontPromises).catch((err) => {
2920 console.warn(err);
2921 });
2922 }
2923
2924 destroy() {
2925 this.pagesArea.remove();
2926 this.pageTemplate.remove();
2927 }
2928
2929 }
2930
2931 eventEmitter(Chunker.prototype);
2932
2933 //
2934 // list
2935 // ┌──────┐
2936 // ┌──────────────┼─head │
2937 // │ │ tail─┼──────────────┐
2938 // │ └──────┘ │
2939 // ▼ ▼
2940 // item item item item
2941 // ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐
2942 // null ◀──┼─prev │◀───┼─prev │◀───┼─prev │◀───┼─prev │
2943 // │ next─┼───▶│ next─┼───▶│ next─┼───▶│ next─┼──▶ null
2944 // ├──────┤ ├──────┤ ├──────┤ ├──────┤
2945 // │ data │ │ data │ │ data │ │ data │
2946 // └──────┘ └──────┘ └──────┘ └──────┘
2947 //
2948
2949 function createItem(data) {
2950 return {
2951 prev: null,
2952 next: null,
2953 data: data
2954 };
2955 }
2956
2957 function allocateCursor(node, prev, next) {
2958 var cursor;
2959
2960 if (cursors !== null) {
2961 cursor = cursors;
2962 cursors = cursors.cursor;
2963 cursor.prev = prev;
2964 cursor.next = next;
2965 cursor.cursor = node.cursor;
2966 } else {
2967 cursor = {
2968 prev: prev,
2969 next: next,
2970 cursor: node.cursor
2971 };
2972 }
2973
2974 node.cursor = cursor;
2975
2976 return cursor;
2977 }
2978
2979 function releaseCursor(node) {
2980 var cursor = node.cursor;
2981
2982 node.cursor = cursor.cursor;
2983 cursor.prev = null;
2984 cursor.next = null;
2985 cursor.cursor = cursors;
2986 cursors = cursor;
2987 }
2988
2989 var cursors = null;
2990 var List = function() {
2991 this.cursor = null;
2992 this.head = null;
2993 this.tail = null;
2994 };
2995
2996 List.createItem = createItem;
2997 List.prototype.createItem = createItem;
2998
2999 List.prototype.updateCursors = function(prevOld, prevNew, nextOld, nextNew) {
3000 var cursor = this.cursor;
3001
3002 while (cursor !== null) {
3003 if (cursor.prev === prevOld) {
3004 cursor.prev = prevNew;
3005 }
3006
3007 if (cursor.next === nextOld) {
3008 cursor.next = nextNew;
3009 }
3010
3011 cursor = cursor.cursor;
3012 }
3013 };
3014
3015 List.prototype.getSize = function() {
3016 var size = 0;
3017 var cursor = this.head;
3018
3019 while (cursor) {
3020 size++;
3021 cursor = cursor.next;
3022 }
3023
3024 return size;
3025 };
3026
3027 List.prototype.fromArray = function(array) {
3028 var cursor = null;
3029
3030 this.head = null;
3031
3032 for (var i = 0; i < array.length; i++) {
3033 var item = createItem(array[i]);
3034
3035 if (cursor !== null) {
3036 cursor.next = item;
3037 } else {
3038 this.head = item;
3039 }
3040
3041 item.prev = cursor;
3042 cursor = item;
3043 }
3044
3045 this.tail = cursor;
3046
3047 return this;
3048 };
3049
3050 List.prototype.toArray = function() {
3051 var cursor = this.head;
3052 var result = [];
3053
3054 while (cursor) {
3055 result.push(cursor.data);
3056 cursor = cursor.next;
3057 }
3058
3059 return result;
3060 };
3061
3062 List.prototype.toJSON = List.prototype.toArray;
3063
3064 List.prototype.isEmpty = function() {
3065 return this.head === null;
3066 };
3067
3068 List.prototype.first = function() {
3069 return this.head && this.head.data;
3070 };
3071
3072 List.prototype.last = function() {
3073 return this.tail && this.tail.data;
3074 };
3075
3076 List.prototype.each = function(fn, context) {
3077 var item;
3078
3079 if (context === undefined) {
3080 context = this;
3081 }
3082
3083 // push cursor
3084 var cursor = allocateCursor(this, null, this.head);
3085
3086 while (cursor.next !== null) {
3087 item = cursor.next;
3088 cursor.next = item.next;
3089
3090 fn.call(context, item.data, item, this);
3091 }
3092
3093 // pop cursor
3094 releaseCursor(this);
3095 };
3096
3097 List.prototype.forEach = List.prototype.each;
3098
3099 List.prototype.eachRight = function(fn, context) {
3100 var item;
3101
3102 if (context === undefined) {
3103 context = this;
3104 }
3105
3106 // push cursor
3107 var cursor = allocateCursor(this, this.tail, null);
3108
3109 while (cursor.prev !== null) {
3110 item = cursor.prev;
3111 cursor.prev = item.prev;
3112
3113 fn.call(context, item.data, item, this);
3114 }
3115
3116 // pop cursor
3117 releaseCursor(this);
3118 };
3119
3120 List.prototype.forEachRight = List.prototype.eachRight;
3121
3122 List.prototype.nextUntil = function(start, fn, context) {
3123 if (start === null) {
3124 return;
3125 }
3126
3127 var item;
3128
3129 if (context === undefined) {
3130 context = this;
3131 }
3132
3133 // push cursor
3134 var cursor = allocateCursor(this, null, start);
3135
3136 while (cursor.next !== null) {
3137 item = cursor.next;
3138 cursor.next = item.next;
3139
3140 if (fn.call(context, item.data, item, this)) {
3141 break;
3142 }
3143 }
3144
3145 // pop cursor
3146 releaseCursor(this);
3147 };
3148
3149 List.prototype.prevUntil = function(start, fn, context) {
3150 if (start === null) {
3151 return;
3152 }
3153
3154 var item;
3155
3156 if (context === undefined) {
3157 context = this;
3158 }
3159
3160 // push cursor
3161 var cursor = allocateCursor(this, start, null);
3162
3163 while (cursor.prev !== null) {
3164 item = cursor.prev;
3165 cursor.prev = item.prev;
3166
3167 if (fn.call(context, item.data, item, this)) {
3168 break;
3169 }
3170 }
3171
3172 // pop cursor
3173 releaseCursor(this);
3174 };
3175
3176 List.prototype.some = function(fn, context) {
3177 var cursor = this.head;
3178
3179 if (context === undefined) {
3180 context = this;
3181 }
3182
3183 while (cursor !== null) {
3184 if (fn.call(context, cursor.data, cursor, this)) {
3185 return true;
3186 }
3187
3188 cursor = cursor.next;
3189 }
3190
3191 return false;
3192 };
3193
3194 List.prototype.map = function(fn, context) {
3195 var result = new List();
3196 var cursor = this.head;
3197
3198 if (context === undefined) {
3199 context = this;
3200 }
3201
3202 while (cursor !== null) {
3203 result.appendData(fn.call(context, cursor.data, cursor, this));
3204 cursor = cursor.next;
3205 }
3206
3207 return result;
3208 };
3209
3210 List.prototype.filter = function(fn, context) {
3211 var result = new List();
3212 var cursor = this.head;
3213
3214 if (context === undefined) {
3215 context = this;
3216 }
3217
3218 while (cursor !== null) {
3219 if (fn.call(context, cursor.data, cursor, this)) {
3220 result.appendData(cursor.data);
3221 }
3222 cursor = cursor.next;
3223 }
3224
3225 return result;
3226 };
3227
3228 List.prototype.clear = function() {
3229 this.head = null;
3230 this.tail = null;
3231 };
3232
3233 List.prototype.copy = function() {
3234 var result = new List();
3235 var cursor = this.head;
3236
3237 while (cursor !== null) {
3238 result.insert(createItem(cursor.data));
3239 cursor = cursor.next;
3240 }
3241
3242 return result;
3243 };
3244
3245 List.prototype.prepend = function(item) {
3246 // head
3247 // ^
3248 // item
3249 this.updateCursors(null, item, this.head, item);
3250
3251 // insert to the beginning of the list
3252 if (this.head !== null) {
3253 // new item <- first item
3254 this.head.prev = item;
3255
3256 // new item -> first item
3257 item.next = this.head;
3258 } else {
3259 // if list has no head, then it also has no tail
3260 // in this case tail points to the new item
3261 this.tail = item;
3262 }
3263
3264 // head always points to new item
3265 this.head = item;
3266
3267 return this;
3268 };
3269
3270 List.prototype.prependData = function(data) {
3271 return this.prepend(createItem(data));
3272 };
3273
3274 List.prototype.append = function(item) {
3275 return this.insert(item);
3276 };
3277
3278 List.prototype.appendData = function(data) {
3279 return this.insert(createItem(data));
3280 };
3281
3282 List.prototype.insert = function(item, before) {
3283 if (before !== undefined && before !== null) {
3284 // prev before
3285 // ^
3286 // item
3287 this.updateCursors(before.prev, item, before, item);
3288
3289 if (before.prev === null) {
3290 // insert to the beginning of list
3291 if (this.head !== before) {
3292 throw new Error('before doesn\'t belong to list');
3293 }
3294
3295 // since head points to before therefore list doesn't empty
3296 // no need to check tail
3297 this.head = item;
3298 before.prev = item;
3299 item.next = before;
3300
3301 this.updateCursors(null, item);
3302 } else {
3303
3304 // insert between two items
3305 before.prev.next = item;
3306 item.prev = before.prev;
3307
3308 before.prev = item;
3309 item.next = before;
3310 }
3311 } else {
3312 // tail
3313 // ^
3314 // item
3315 this.updateCursors(this.tail, item, null, item);
3316
3317 // insert to the ending of the list
3318 if (this.tail !== null) {
3319 // last item -> new item
3320 this.tail.next = item;
3321
3322 // last item <- new item
3323 item.prev = this.tail;
3324 } else {
3325 // if list has no tail, then it also has no head
3326 // in this case head points to new item
3327 this.head = item;
3328 }
3329
3330 // tail always points to new item
3331 this.tail = item;
3332 }
3333
3334 return this;
3335 };
3336
3337 List.prototype.insertData = function(data, before) {
3338 return this.insert(createItem(data), before);
3339 };
3340
3341 List.prototype.remove = function(item) {
3342 // item
3343 // ^
3344 // prev next
3345 this.updateCursors(item, item.prev, item, item.next);
3346
3347 if (item.prev !== null) {
3348 item.prev.next = item.next;
3349 } else {
3350 if (this.head !== item) {
3351 throw new Error('item doesn\'t belong to list');
3352 }
3353
3354 this.head = item.next;
3355 }
3356
3357 if (item.next !== null) {
3358 item.next.prev = item.prev;
3359 } else {
3360 if (this.tail !== item) {
3361 throw new Error('item doesn\'t belong to list');
3362 }
3363
3364 this.tail = item.prev;
3365 }
3366
3367 item.prev = null;
3368 item.next = null;
3369
3370 return item;
3371 };
3372
3373 List.prototype.push = function(data) {
3374 this.insert(createItem(data));
3375 };
3376
3377 List.prototype.pop = function() {
3378 if (this.tail !== null) {
3379 return this.remove(this.tail);
3380 }
3381 };
3382
3383 List.prototype.unshift = function(data) {
3384 this.prepend(createItem(data));
3385 };
3386
3387 List.prototype.shift = function() {
3388 if (this.head !== null) {
3389 return this.remove(this.head);
3390 }
3391 };
3392
3393 List.prototype.prependList = function(list) {
3394 return this.insertList(list, this.head);
3395 };
3396
3397 List.prototype.appendList = function(list) {
3398 return this.insertList(list);
3399 };
3400
3401 List.prototype.insertList = function(list, before) {
3402 // ignore empty lists
3403 if (list.head === null) {
3404 return this;
3405 }
3406
3407 if (before !== undefined && before !== null) {
3408 this.updateCursors(before.prev, list.tail, before, list.head);
3409
3410 // insert in the middle of dist list
3411 if (before.prev !== null) {
3412 // before.prev <-> list.head
3413 before.prev.next = list.head;
3414 list.head.prev = before.prev;
3415 } else {
3416 this.head = list.head;
3417 }
3418
3419 before.prev = list.tail;
3420 list.tail.next = before;
3421 } else {
3422 this.updateCursors(this.tail, list.tail, null, list.head);
3423
3424 // insert to end of the list
3425 if (this.tail !== null) {
3426 // if destination list has a tail, then it also has a head,
3427 // but head doesn't change
3428
3429 // dest tail -> source head
3430 this.tail.next = list.head;
3431
3432 // dest tail <- source head
3433 list.head.prev = this.tail;
3434 } else {
3435 // if list has no a tail, then it also has no a head
3436 // in this case points head to new item
3437 this.head = list.head;
3438 }
3439
3440 // tail always start point to new item
3441 this.tail = list.tail;
3442 }
3443
3444 list.head = null;
3445 list.tail = null;
3446
3447 return this;
3448 };
3449
3450 List.prototype.replace = function(oldItem, newItemOrList) {
3451 if ('head' in newItemOrList) {
3452 this.insertList(newItemOrList, oldItem);
3453 } else {
3454 this.insert(newItemOrList, oldItem);
3455 }
3456
3457 this.remove(oldItem);
3458 };
3459
3460 var List_1 = List;
3461
3462 var createCustomError = function createCustomError(name, message) {
3463 // use Object.create(), because some VMs prevent setting line/column otherwise
3464 // (iOS Safari 10 even throws an exception)
3465 var error = Object.create(SyntaxError.prototype);
3466 var errorStack = new Error();
3467
3468 error.name = name;
3469 error.message = message;
3470
3471 Object.defineProperty(error, 'stack', {
3472 get: function() {
3473 return (errorStack.stack || '').replace(/^(.+\n){1,3}/, name + ': ' + message + '\n');
3474 }
3475 });
3476
3477 return error;
3478 };
3479
3480 var MAX_LINE_LENGTH = 100;
3481 var OFFSET_CORRECTION = 60;
3482 var TAB_REPLACEMENT = ' ';
3483
3484 function sourceFragment(error, extraLines) {
3485 function processLines(start, end) {
3486 return lines.slice(start, end).map(function(line, idx) {
3487 var num = String(start + idx + 1);
3488
3489 while (num.length < maxNumLength) {
3490 num = ' ' + num;
3491 }
3492
3493 return num + ' |' + line;
3494 }).join('\n');
3495 }
3496
3497 var lines = error.source.split(/\r\n?|\n|\f/);
3498 var line = error.line;
3499 var column = error.column;
3500 var startLine = Math.max(1, line - extraLines) - 1;
3501 var endLine = Math.min(line + extraLines, lines.length + 1);
3502 var maxNumLength = Math.max(4, String(endLine).length) + 1;
3503 var cutLeft = 0;
3504
3505 // column correction according to replaced tab before column
3506 column += (TAB_REPLACEMENT.length - 1) * (lines[line - 1].substr(0, column - 1).match(/\t/g) || []).length;
3507
3508 if (column > MAX_LINE_LENGTH) {
3509 cutLeft = column - OFFSET_CORRECTION + 3;
3510 column = OFFSET_CORRECTION - 2;
3511 }
3512
3513 for (var i = startLine; i <= endLine; i++) {
3514 if (i >= 0 && i < lines.length) {
3515 lines[i] = lines[i].replace(/\t/g, TAB_REPLACEMENT);
3516 lines[i] =
3517 (cutLeft > 0 && lines[i].length > cutLeft ? '\u2026' : '') +
3518 lines[i].substr(cutLeft, MAX_LINE_LENGTH - 2) +
3519 (lines[i].length > cutLeft + MAX_LINE_LENGTH - 1 ? '\u2026' : '');
3520 }
3521 }
3522
3523 return [
3524 processLines(startLine, line),
3525 new Array(column + maxNumLength + 2).join('-') + '^',
3526 processLines(line, endLine)
3527 ].filter(Boolean).join('\n');
3528 }
3529
3530 var SyntaxError$1 = function(message, source, offset, line, column) {
3531 var error = createCustomError('SyntaxError', message);
3532
3533 error.source = source;
3534 error.offset = offset;
3535 error.line = line;
3536 error.column = column;
3537
3538 error.sourceFragment = function(extraLines) {
3539 return sourceFragment(error, isNaN(extraLines) ? 0 : extraLines);
3540 };
3541 Object.defineProperty(error, 'formattedMessage', {
3542 get: function() {
3543 return (
3544 'Parse error: ' + error.message + '\n' +
3545 sourceFragment(error, 2)
3546 );
3547 }
3548 });
3549
3550 // for backward capability
3551 error.parseError = {
3552 offset: offset,
3553 line: line,
3554 column: column
3555 };
3556
3557 return error;
3558 };
3559
3560 var _SyntaxError = SyntaxError$1;
3561
3562 // CSS Syntax Module Level 3
3563 // https://www.w3.org/TR/css-syntax-3/
3564 var TYPE = {
3565 EOF: 0, // <EOF-token>
3566 Ident: 1, // <ident-token>
3567 Function: 2, // <function-token>
3568 AtKeyword: 3, // <at-keyword-token>
3569 Hash: 4, // <hash-token>
3570 String: 5, // <string-token>
3571 BadString: 6, // <bad-string-token>
3572 Url: 7, // <url-token>
3573 BadUrl: 8, // <bad-url-token>
3574 Delim: 9, // <delim-token>
3575 Number: 10, // <number-token>
3576 Percentage: 11, // <percentage-token>
3577 Dimension: 12, // <dimension-token>
3578 WhiteSpace: 13, // <whitespace-token>
3579 CDO: 14, // <CDO-token>
3580 CDC: 15, // <CDC-token>
3581 Colon: 16, // <colon-token> :
3582 Semicolon: 17, // <semicolon-token> ;
3583 Comma: 18, // <comma-token> ,
3584 LeftSquareBracket: 19, // <[-token>
3585 RightSquareBracket: 20, // <]-token>
3586 LeftParenthesis: 21, // <(-token>
3587 RightParenthesis: 22, // <)-token>
3588 LeftCurlyBracket: 23, // <{-token>
3589 RightCurlyBracket: 24, // <}-token>
3590 Comment: 25
3591 };
3592
3593 var NAME = Object.keys(TYPE).reduce(function(result, key) {
3594 result[TYPE[key]] = key;
3595 return result;
3596 }, {});
3597
3598 var _const = {
3599 TYPE: TYPE,
3600 NAME: NAME
3601 };
3602
3603 var EOF = 0;
3604
3605 // https://drafts.csswg.org/css-syntax-3/
3606 // § 4.2. Definitions
3607
3608 // digit
3609 // A code point between U+0030 DIGIT ZERO (0) and U+0039 DIGIT NINE (9).
3610 function isDigit(code) {
3611 return code >= 0x0030 && code <= 0x0039;
3612 }
3613
3614 // hex digit
3615 // A digit, or a code point between U+0041 LATIN CAPITAL LETTER A (A) and U+0046 LATIN CAPITAL LETTER F (F),
3616 // or a code point between U+0061 LATIN SMALL LETTER A (a) and U+0066 LATIN SMALL LETTER F (f).
3617 function isHexDigit(code) {
3618 return (
3619 isDigit(code) || // 0 .. 9
3620 (code >= 0x0041 && code <= 0x0046) || // A .. F
3621 (code >= 0x0061 && code <= 0x0066) // a .. f
3622 );
3623 }
3624
3625 // uppercase letter
3626 // A code point between U+0041 LATIN CAPITAL LETTER A (A) and U+005A LATIN CAPITAL LETTER Z (Z).
3627 function isUppercaseLetter(code) {
3628 return code >= 0x0041 && code <= 0x005A;
3629 }
3630
3631 // lowercase letter
3632 // A code point between U+0061 LATIN SMALL LETTER A (a) and U+007A LATIN SMALL LETTER Z (z).
3633 function isLowercaseLetter(code) {
3634 return code >= 0x0061 && code <= 0x007A;
3635 }
3636
3637 // letter
3638 // An uppercase letter or a lowercase letter.
3639 function isLetter(code) {
3640 return isUppercaseLetter(code) || isLowercaseLetter(code);
3641 }
3642
3643 // non-ASCII code point
3644 // A code point with a value equal to or greater than U+0080 <control>.
3645 function isNonAscii(code) {
3646 return code >= 0x0080;
3647 }
3648
3649 // name-start code point
3650 // A letter, a non-ASCII code point, or U+005F LOW LINE (_).
3651 function isNameStart(code) {
3652 return isLetter(code) || isNonAscii(code) || code === 0x005F;
3653 }
3654
3655 // name code point
3656 // A name-start code point, a digit, or U+002D HYPHEN-MINUS (-).
3657 function isName(code) {
3658 return isNameStart(code) || isDigit(code) || code === 0x002D;
3659 }
3660
3661 // non-printable code point
3662 // A code point between U+0000 NULL and U+0008 BACKSPACE, or U+000B LINE TABULATION,
3663 // or a code point between U+000E SHIFT OUT and U+001F INFORMATION SEPARATOR ONE, or U+007F DELETE.
3664 function isNonPrintable(code) {
3665 return (
3666 (code >= 0x0000 && code <= 0x0008) ||
3667 (code === 0x000B) ||
3668 (code >= 0x000E && code <= 0x001F) ||
3669 (code === 0x007F)
3670 );
3671 }
3672
3673 // newline
3674 // U+000A LINE FEED. Note that U+000D CARRIAGE RETURN and U+000C FORM FEED are not included in this definition,
3675 // as they are converted to U+000A LINE FEED during preprocessing.
3676 // TODO: we doesn't do a preprocessing, so check a code point for U+000D CARRIAGE RETURN and U+000C FORM FEED
3677 function isNewline(code) {
3678 return code === 0x000A || code === 0x000D || code === 0x000C;
3679 }
3680
3681 // whitespace
3682 // A newline, U+0009 CHARACTER TABULATION, or U+0020 SPACE.
3683 function isWhiteSpace(code) {
3684 return isNewline(code) || code === 0x0020 || code === 0x0009;
3685 }
3686
3687 // § 4.3.8. Check if two code points are a valid escape
3688 function isValidEscape(first, second) {
3689 // If the first code point is not U+005C REVERSE SOLIDUS (\), return false.
3690 if (first !== 0x005C) {
3691 return false;
3692 }
3693
3694 // Otherwise, if the second code point is a newline or EOF, return false.
3695 if (isNewline(second) || second === EOF) {
3696 return false;
3697 }
3698
3699 // Otherwise, return true.
3700 return true;
3701 }
3702
3703 // § 4.3.9. Check if three code points would start an identifier
3704 function isIdentifierStart(first, second, third) {
3705 // Look at the first code point:
3706
3707 // U+002D HYPHEN-MINUS
3708 if (first === 0x002D) {
3709 // If the second code point is a name-start code point or a U+002D HYPHEN-MINUS,
3710 // or the second and third code points are a valid escape, return true. Otherwise, return false.
3711 return (
3712 isNameStart(second) ||
3713 second === 0x002D ||
3714 isValidEscape(second, third)
3715 );
3716 }
3717
3718 // name-start code point
3719 if (isNameStart(first)) {
3720 // Return true.
3721 return true;
3722 }
3723
3724 // U+005C REVERSE SOLIDUS (\)
3725 if (first === 0x005C) {
3726 // If the first and second code points are a valid escape, return true. Otherwise, return false.
3727 return isValidEscape(first, second);
3728 }
3729
3730 // anything else
3731 // Return false.
3732 return false;
3733 }
3734
3735 // § 4.3.10. Check if three code points would start a number
3736 function isNumberStart(first, second, third) {
3737 // Look at the first code point:
3738
3739 // U+002B PLUS SIGN (+)
3740 // U+002D HYPHEN-MINUS (-)
3741 if (first === 0x002B || first === 0x002D) {
3742 // If the second code point is a digit, return true.
3743 if (isDigit(second)) {
3744 return 2;
3745 }
3746
3747 // Otherwise, if the second code point is a U+002E FULL STOP (.)
3748 // and the third code point is a digit, return true.
3749 // Otherwise, return false.
3750 return second === 0x002E && isDigit(third) ? 3 : 0;
3751 }
3752
3753 // U+002E FULL STOP (.)
3754 if (first === 0x002E) {
3755 // If the second code point is a digit, return true. Otherwise, return false.
3756 return isDigit(second) ? 2 : 0;
3757 }
3758
3759 // digit
3760 if (isDigit(first)) {
3761 // Return true.
3762 return 1;
3763 }
3764
3765 // anything else
3766 // Return false.
3767 return 0;
3768 }
3769
3770 //
3771 // Misc
3772 //
3773
3774 // detect BOM (https://en.wikipedia.org/wiki/Byte_order_mark)
3775 function isBOM(code) {
3776 // UTF-16BE
3777 if (code === 0xFEFF) {
3778 return 1;
3779 }
3780
3781 // UTF-16LE
3782 if (code === 0xFFFE) {
3783 return 1;
3784 }
3785
3786 return 0;
3787 }
3788
3789 // Fast code category
3790 //
3791 // https://drafts.csswg.org/css-syntax/#tokenizer-definitions
3792 // > non-ASCII code point
3793 // > A code point with a value equal to or greater than U+0080 <control>
3794 // > name-start code point
3795 // > A letter, a non-ASCII code point, or U+005F LOW LINE (_).
3796 // > name code point
3797 // > A name-start code point, a digit, or U+002D HYPHEN-MINUS (-)
3798 // That means only ASCII code points has a special meaning and we define a maps for 0..127 codes only
3799 var CATEGORY = new Array(0x80);
3800 charCodeCategory.Eof = 0x80;
3801 charCodeCategory.WhiteSpace = 0x82;
3802 charCodeCategory.Digit = 0x83;
3803 charCodeCategory.NameStart = 0x84;
3804 charCodeCategory.NonPrintable = 0x85;
3805
3806 for (var i = 0; i < CATEGORY.length; i++) {
3807 switch (true) {
3808 case isWhiteSpace(i):
3809 CATEGORY[i] = charCodeCategory.WhiteSpace;
3810 break;
3811
3812 case isDigit(i):
3813 CATEGORY[i] = charCodeCategory.Digit;
3814 break;
3815
3816 case isNameStart(i):
3817 CATEGORY[i] = charCodeCategory.NameStart;
3818 break;
3819
3820 case isNonPrintable(i):
3821 CATEGORY[i] = charCodeCategory.NonPrintable;
3822 break;
3823
3824 default:
3825 CATEGORY[i] = i || charCodeCategory.Eof;
3826 }
3827 }
3828
3829 function charCodeCategory(code) {
3830 return code < 0x80 ? CATEGORY[code] : charCodeCategory.NameStart;
3831 }
3832 var charCodeDefinitions = {
3833 isDigit: isDigit,
3834 isHexDigit: isHexDigit,
3835 isUppercaseLetter: isUppercaseLetter,
3836 isLowercaseLetter: isLowercaseLetter,
3837 isLetter: isLetter,
3838 isNonAscii: isNonAscii,
3839 isNameStart: isNameStart,
3840 isName: isName,
3841 isNonPrintable: isNonPrintable,
3842 isNewline: isNewline,
3843 isWhiteSpace: isWhiteSpace,
3844 isValidEscape: isValidEscape,
3845 isIdentifierStart: isIdentifierStart,
3846 isNumberStart: isNumberStart,
3847
3848 isBOM: isBOM,
3849 charCodeCategory: charCodeCategory
3850 };
3851
3852 var isDigit$1 = charCodeDefinitions.isDigit;
3853 var isHexDigit$1 = charCodeDefinitions.isHexDigit;
3854 var isUppercaseLetter$1 = charCodeDefinitions.isUppercaseLetter;
3855 var isName$1 = charCodeDefinitions.isName;
3856 var isWhiteSpace$1 = charCodeDefinitions.isWhiteSpace;
3857 var isValidEscape$1 = charCodeDefinitions.isValidEscape;
3858
3859 function getCharCode(source, offset) {
3860 return offset < source.length ? source.charCodeAt(offset) : 0;
3861 }
3862
3863 function getNewlineLength(source, offset, code) {
3864 if (code === 13 /* \r */ && getCharCode(source, offset + 1) === 10 /* \n */) {
3865 return 2;
3866 }
3867
3868 return 1;
3869 }
3870
3871 function cmpChar(testStr, offset, referenceCode) {
3872 var code = testStr.charCodeAt(offset);
3873
3874 // code.toLowerCase() for A..Z
3875 if (isUppercaseLetter$1(code)) {
3876 code = code | 32;
3877 }
3878
3879 return code === referenceCode;
3880 }
3881
3882 function cmpStr(testStr, start, end, referenceStr) {
3883 if (end - start !== referenceStr.length) {
3884 return false;
3885 }
3886
3887 if (start < 0 || end > testStr.length) {
3888 return false;
3889 }
3890
3891 for (var i = start; i < end; i++) {
3892 var testCode = testStr.charCodeAt(i);
3893 var referenceCode = referenceStr.charCodeAt(i - start);
3894
3895 // testCode.toLowerCase() for A..Z
3896 if (isUppercaseLetter$1(testCode)) {
3897 testCode = testCode | 32;
3898 }
3899
3900 if (testCode !== referenceCode) {
3901 return false;
3902 }
3903 }
3904
3905 return true;
3906 }
3907
3908 function findWhiteSpaceStart(source, offset) {
3909 for (; offset >= 0; offset--) {
3910 if (!isWhiteSpace$1(source.charCodeAt(offset))) {
3911 break;
3912 }
3913 }
3914
3915 return offset + 1;
3916 }
3917
3918 function findWhiteSpaceEnd(source, offset) {
3919 for (; offset < source.length; offset++) {
3920 if (!isWhiteSpace$1(source.charCodeAt(offset))) {
3921 break;
3922 }
3923 }
3924
3925 return offset;
3926 }
3927
3928 function findDecimalNumberEnd(source, offset) {
3929 for (; offset < source.length; offset++) {
3930 if (!isDigit$1(source.charCodeAt(offset))) {
3931 break;
3932 }
3933 }
3934
3935 return offset;
3936 }
3937
3938 // § 4.3.7. Consume an escaped code point
3939 function consumeEscaped(source, offset) {
3940 // It assumes that the U+005C REVERSE SOLIDUS (\) has already been consumed and
3941 // that the next input code point has already been verified to be part of a valid escape.
3942 offset += 2;
3943
3944 // hex digit
3945 if (isHexDigit$1(getCharCode(source, offset - 1))) {
3946 // Consume as many hex digits as possible, but no more than 5.
3947 // Note that this means 1-6 hex digits have been consumed in total.
3948 for (var maxOffset = Math.min(source.length, offset + 5); offset < maxOffset; offset++) {
3949 if (!isHexDigit$1(getCharCode(source, offset))) {
3950 break;
3951 }
3952 }
3953
3954 // If the next input code point is whitespace, consume it as well.
3955 var code = getCharCode(source, offset);
3956 if (isWhiteSpace$1(code)) {
3957 offset += getNewlineLength(source, offset, code);
3958 }
3959 }
3960
3961 return offset;
3962 }
3963
3964 // §4.3.11. Consume a name
3965 // Note: This algorithm does not do the verification of the first few code points that are necessary
3966 // to ensure the returned code points would constitute an <ident-token>. If that is the intended use,
3967 // ensure that the stream starts with an identifier before calling this algorithm.
3968 function consumeName(source, offset) {
3969 // Let result initially be an empty string.
3970 // Repeatedly consume the next input code point from the stream:
3971 for (; offset < source.length; offset++) {
3972 var code = source.charCodeAt(offset);
3973
3974 // name code point
3975 if (isName$1(code)) {
3976 // Append the code point to result.
3977 continue;
3978 }
3979
3980 // the stream starts with a valid escape
3981 if (isValidEscape$1(code, getCharCode(source, offset + 1))) {
3982 // Consume an escaped code point. Append the returned code point to result.
3983 offset = consumeEscaped(source, offset) - 1;
3984 continue;
3985 }
3986
3987 // anything else
3988 // Reconsume the current input code point. Return result.
3989 break;
3990 }
3991
3992 return offset;
3993 }
3994
3995 // §4.3.12. Consume a number
3996 function consumeNumber(source, offset) {
3997 var code = source.charCodeAt(offset);
3998
3999 // 2. If the next input code point is U+002B PLUS SIGN (+) or U+002D HYPHEN-MINUS (-),
4000 // consume it and append it to repr.
4001 if (code === 0x002B || code === 0x002D) {
4002 code = source.charCodeAt(offset += 1);
4003 }
4004
4005 // 3. While the next input code point is a digit, consume it and append it to repr.
4006 if (isDigit$1(code)) {
4007 offset = findDecimalNumberEnd(source, offset + 1);
4008 code = source.charCodeAt(offset);
4009 }
4010
4011 // 4. If the next 2 input code points are U+002E FULL STOP (.) followed by a digit, then:
4012 if (code === 0x002E && isDigit$1(source.charCodeAt(offset + 1))) {
4013 // 4.1 Consume them.
4014 // 4.2 Append them to repr.
4015 code = source.charCodeAt(offset += 2);
4016
4017 // 4.3 Set type to "number".
4018 // TODO
4019
4020 // 4.4 While the next input code point is a digit, consume it and append it to repr.
4021
4022 offset = findDecimalNumberEnd(source, offset);
4023 }
4024
4025 // 5. If the next 2 or 3 input code points are U+0045 LATIN CAPITAL LETTER E (E)
4026 // or U+0065 LATIN SMALL LETTER E (e), ... , followed by a digit, then:
4027 if (cmpChar(source, offset, 101 /* e */)) {
4028 var sign = 0;
4029 code = source.charCodeAt(offset + 1);
4030
4031 // ... optionally followed by U+002D HYPHEN-MINUS (-) or U+002B PLUS SIGN (+) ...
4032 if (code === 0x002D || code === 0x002B) {
4033 sign = 1;
4034 code = source.charCodeAt(offset + 2);
4035 }
4036
4037 // ... followed by a digit
4038 if (isDigit$1(code)) {
4039 // 5.1 Consume them.
4040 // 5.2 Append them to repr.
4041
4042 // 5.3 Set type to "number".
4043 // TODO
4044
4045 // 5.4 While the next input code point is a digit, consume it and append it to repr.
4046 offset = findDecimalNumberEnd(source, offset + 1 + sign + 1);
4047 }
4048 }
4049
4050 return offset;
4051 }
4052
4053 // § 4.3.14. Consume the remnants of a bad url
4054 // ... its sole use is to consume enough of the input stream to reach a recovery point
4055 // where normal tokenizing can resume.
4056 function consumeBadUrlRemnants(source, offset) {
4057 // Repeatedly consume the next input code point from the stream:
4058 for (; offset < source.length; offset++) {
4059 var code = source.charCodeAt(offset);
4060
4061 // U+0029 RIGHT PARENTHESIS ())
4062 // EOF
4063 if (code === 0x0029) {
4064 // Return.
4065 offset++;
4066 break;
4067 }
4068
4069 if (isValidEscape$1(code, getCharCode(source, offset + 1))) {
4070 // Consume an escaped code point.
4071 // Note: This allows an escaped right parenthesis ("\)") to be encountered
4072 // without ending the <bad-url-token>. This is otherwise identical to
4073 // the "anything else" clause.
4074 offset = consumeEscaped(source, offset);
4075 }
4076 }
4077
4078 return offset;
4079 }
4080
4081 var utils = {
4082 consumeEscaped: consumeEscaped,
4083 consumeName: consumeName,
4084 consumeNumber: consumeNumber,
4085 consumeBadUrlRemnants: consumeBadUrlRemnants,
4086
4087 cmpChar: cmpChar,
4088 cmpStr: cmpStr,
4089
4090 getNewlineLength: getNewlineLength,
4091 findWhiteSpaceStart: findWhiteSpaceStart,
4092 findWhiteSpaceEnd: findWhiteSpaceEnd
4093 };
4094
4095 var TYPE$1 = _const.TYPE;
4096 var NAME$1 = _const.NAME;
4097
4098
4099 var cmpStr$1 = utils.cmpStr;
4100
4101 var EOF$1 = TYPE$1.EOF;
4102 var WHITESPACE = TYPE$1.WhiteSpace;
4103 var COMMENT = TYPE$1.Comment;
4104
4105 var OFFSET_MASK = 0x00FFFFFF;
4106 var TYPE_SHIFT = 24;
4107
4108 var TokenStream = function() {
4109 this.offsetAndType = null;
4110 this.balance = null;
4111
4112 this.reset();
4113 };
4114
4115 TokenStream.prototype = {
4116 reset: function() {
4117 this.eof = false;
4118 this.tokenIndex = -1;
4119 this.tokenType = 0;
4120 this.tokenStart = this.firstCharOffset;
4121 this.tokenEnd = this.firstCharOffset;
4122 },
4123
4124 lookupType: function(offset) {
4125 offset += this.tokenIndex;
4126
4127 if (offset < this.tokenCount) {
4128 return this.offsetAndType[offset] >> TYPE_SHIFT;
4129 }
4130
4131 return EOF$1;
4132 },
4133 lookupOffset: function(offset) {
4134 offset += this.tokenIndex;
4135
4136 if (offset < this.tokenCount) {
4137 return this.offsetAndType[offset - 1] & OFFSET_MASK;
4138 }
4139
4140 return this.source.length;
4141 },
4142 lookupValue: function(offset, referenceStr) {
4143 offset += this.tokenIndex;
4144
4145 if (offset < this.tokenCount) {
4146 return cmpStr$1(
4147 this.source,
4148 this.offsetAndType[offset - 1] & OFFSET_MASK,
4149 this.offsetAndType[offset] & OFFSET_MASK,
4150 referenceStr
4151 );
4152 }
4153
4154 return false;
4155 },
4156 getTokenStart: function(tokenIndex) {
4157 if (tokenIndex === this.tokenIndex) {
4158 return this.tokenStart;
4159 }
4160
4161 if (tokenIndex > 0) {
4162 return tokenIndex < this.tokenCount
4163 ? this.offsetAndType[tokenIndex - 1] & OFFSET_MASK
4164 : this.offsetAndType[this.tokenCount] & OFFSET_MASK;
4165 }
4166
4167 return this.firstCharOffset;
4168 },
4169
4170 // TODO: -> skipUntilBalanced
4171 getRawLength: function(startToken, mode) {
4172 var cursor = startToken;
4173 var balanceEnd;
4174 var offset = this.offsetAndType[Math.max(cursor - 1, 0)] & OFFSET_MASK;
4175 var type;
4176
4177 loop:
4178 for (; cursor < this.tokenCount; cursor++) {
4179 balanceEnd = this.balance[cursor];
4180
4181 // stop scanning on balance edge that points to offset before start token
4182 if (balanceEnd < startToken) {
4183 break loop;
4184 }
4185
4186 type = this.offsetAndType[cursor] >> TYPE_SHIFT;
4187
4188 // check token is stop type
4189 switch (mode(type, this.source, offset)) {
4190 case 1:
4191 break loop;
4192
4193 case 2:
4194 cursor++;
4195 break loop;
4196
4197 default:
4198 offset = this.offsetAndType[cursor] & OFFSET_MASK;
4199
4200 // fast forward to the end of balanced block
4201 if (this.balance[balanceEnd] === cursor) {
4202 cursor = balanceEnd;
4203 }
4204 }
4205 }
4206
4207 return cursor - this.tokenIndex;
4208 },
4209 isBalanceEdge: function(pos) {
4210 return this.balance[this.tokenIndex] < pos;
4211 },
4212 isDelim: function(code, offset) {
4213 if (offset) {
4214 return (
4215 this.lookupType(offset) === TYPE$1.Delim &&
4216 this.source.charCodeAt(this.lookupOffset(offset)) === code
4217 );
4218 }
4219
4220 return (
4221 this.tokenType === TYPE$1.Delim &&
4222 this.source.charCodeAt(this.tokenStart) === code
4223 );
4224 },
4225
4226 getTokenValue: function() {
4227 return this.source.substring(this.tokenStart, this.tokenEnd);
4228 },
4229 getTokenLength: function() {
4230 return this.tokenEnd - this.tokenStart;
4231 },
4232 substrToCursor: function(start) {
4233 return this.source.substring(start, this.tokenStart);
4234 },
4235
4236 skipWS: function() {
4237 for (var i = this.tokenIndex, skipTokenCount = 0; i < this.tokenCount; i++, skipTokenCount++) {
4238 if ((this.offsetAndType[i] >> TYPE_SHIFT) !== WHITESPACE) {
4239 break;
4240 }
4241 }
4242
4243 if (skipTokenCount > 0) {
4244 this.skip(skipTokenCount);
4245 }
4246 },
4247 skipSC: function() {
4248 while (this.tokenType === WHITESPACE || this.tokenType === COMMENT) {
4249 this.next();
4250 }
4251 },
4252 skip: function(tokenCount) {
4253 var next = this.tokenIndex + tokenCount;
4254
4255 if (next < this.tokenCount) {
4256 this.tokenIndex = next;
4257 this.tokenStart = this.offsetAndType[next - 1] & OFFSET_MASK;
4258 next = this.offsetAndType[next];
4259 this.tokenType = next >> TYPE_SHIFT;
4260 this.tokenEnd = next & OFFSET_MASK;
4261 } else {
4262 this.tokenIndex = this.tokenCount;
4263 this.next();
4264 }
4265 },
4266 next: function() {
4267 var next = this.tokenIndex + 1;
4268
4269 if (next < this.tokenCount) {
4270 this.tokenIndex = next;
4271 this.tokenStart = this.tokenEnd;
4272 next = this.offsetAndType[next];
4273 this.tokenType = next >> TYPE_SHIFT;
4274 this.tokenEnd = next & OFFSET_MASK;
4275 } else {
4276 this.tokenIndex = this.tokenCount;
4277 this.eof = true;
4278 this.tokenType = EOF$1;
4279 this.tokenStart = this.tokenEnd = this.source.length;
4280 }
4281 },
4282
4283 dump: function() {
4284 var offset = this.firstCharOffset;
4285
4286 return Array.prototype.slice.call(this.offsetAndType, 0, this.tokenCount).map(function(item, idx) {
4287 var start = offset;
4288 var end = item & OFFSET_MASK;
4289
4290 offset = end;
4291
4292 return {
4293 idx: idx,
4294 type: NAME$1[item >> TYPE_SHIFT],
4295 chunk: this.source.substring(start, end),
4296 balance: this.balance[idx]
4297 };
4298 }, this);
4299 }
4300 };
4301
4302 var TokenStream_1 = TokenStream;
4303
4304 function noop$1(value) {
4305 return value;
4306 }
4307
4308 function generateMultiplier(multiplier) {
4309 if (multiplier.min === 0 && multiplier.max === 0) {
4310 return '*';
4311 }
4312
4313 if (multiplier.min === 0 && multiplier.max === 1) {
4314 return '?';
4315 }
4316
4317 if (multiplier.min === 1 && multiplier.max === 0) {
4318 return multiplier.comma ? '#' : '+';
4319 }
4320
4321 if (multiplier.min === 1 && multiplier.max === 1) {
4322 return '';
4323 }
4324
4325 return (
4326 (multiplier.comma ? '#' : '') +
4327 (multiplier.min === multiplier.max
4328 ? '{' + multiplier.min + '}'
4329 : '{' + multiplier.min + ',' + (multiplier.max !== 0 ? multiplier.max : '') + '}'
4330 )
4331 );
4332 }
4333
4334 function generateTypeOpts(node) {
4335 switch (node.type) {
4336 case 'Range':
4337 return (
4338 ' [' +
4339 (node.min === null ? '-∞' : node.min) +
4340 ',' +
4341 (node.max === null ? '∞' : node.max) +
4342 ']'
4343 );
4344
4345 default:
4346 throw new Error('Unknown node type `' + node.type + '`');
4347 }
4348 }
4349
4350 function generateSequence(node, decorate, forceBraces, compact) {
4351 var combinator = node.combinator === ' ' || compact ? node.combinator : ' ' + node.combinator + ' ';
4352 var result = node.terms.map(function(term) {
4353 return generate(term, decorate, forceBraces, compact);
4354 }).join(combinator);
4355
4356 if (node.explicit || forceBraces) {
4357 result = (compact || result[0] === ',' ? '[' : '[ ') + result + (compact ? ']' : ' ]');
4358 }
4359
4360 return result;
4361 }
4362
4363 function generate(node, decorate, forceBraces, compact) {
4364 var result;
4365
4366 switch (node.type) {
4367 case 'Group':
4368 result =
4369 generateSequence(node, decorate, forceBraces, compact) +
4370 (node.disallowEmpty ? '!' : '');
4371 break;
4372
4373 case 'Multiplier':
4374 // return since node is a composition
4375 return (
4376 generate(node.term, decorate, forceBraces, compact) +
4377 decorate(generateMultiplier(node), node)
4378 );
4379
4380 case 'Type':
4381 result = '<' + node.name + (node.opts ? decorate(generateTypeOpts(node.opts), node.opts) : '') + '>';
4382 break;
4383
4384 case 'Property':
4385 result = '<\'' + node.name + '\'>';
4386 break;
4387
4388 case 'Keyword':
4389 result = node.name;
4390 break;
4391
4392 case 'AtKeyword':
4393 result = '@' + node.name;
4394 break;
4395
4396 case 'Function':
4397 result = node.name + '(';
4398 break;
4399
4400 case 'String':
4401 case 'Token':
4402 result = node.value;
4403 break;
4404
4405 case 'Comma':
4406 result = ',';
4407 break;
4408
4409 default:
4410 throw new Error('Unknown node type `' + node.type + '`');
4411 }
4412
4413 return decorate(result, node);
4414 }
4415
4416 var generate_1 = function(node, options) {
4417 var decorate = noop$1;
4418 var forceBraces = false;
4419 var compact = false;
4420
4421 if (typeof options === 'function') {
4422 decorate = options;
4423 } else if (options) {
4424 forceBraces = Boolean(options.forceBraces);
4425 compact = Boolean(options.compact);
4426 if (typeof options.decorate === 'function') {
4427 decorate = options.decorate;
4428 }
4429 }
4430
4431 return generate(node, decorate, forceBraces, compact);
4432 };
4433
4434 function fromMatchResult(matchResult) {
4435 var tokens = matchResult.tokens;
4436 var longestMatch = matchResult.longestMatch;
4437 var node = longestMatch < tokens.length ? tokens[longestMatch].node : null;
4438 var mismatchOffset = -1;
4439 var entries = 0;
4440 var css = '';
4441
4442 for (var i = 0; i < tokens.length; i++) {
4443 if (i === longestMatch) {
4444 mismatchOffset = css.length;
4445 }
4446
4447 if (node !== null && tokens[i].node === node) {
4448 if (i <= longestMatch) {
4449 entries++;
4450 } else {
4451 entries = 0;
4452 }
4453 }
4454
4455 css += tokens[i].value;
4456 }
4457
4458 return {
4459 node: node,
4460 css: css,
4461 mismatchOffset: mismatchOffset === -1 ? css.length : mismatchOffset,
4462 last: node === null || entries > 1
4463 };
4464 }
4465
4466 function getLocation(node, point) {
4467 var loc = node && node.loc && node.loc[point];
4468
4469 if (loc) {
4470 return {
4471 offset: loc.offset,
4472 line: loc.line,
4473 column: loc.column
4474 };
4475 }
4476
4477 return null;
4478 }
4479
4480 var SyntaxReferenceError = function(type, referenceName) {
4481 var error = createCustomError(
4482 'SyntaxReferenceError',
4483 type + (referenceName ? ' `' + referenceName + '`' : '')
4484 );
4485
4486 error.reference = referenceName;
4487
4488 return error;
4489 };
4490
4491 var MatchError = function(message, syntax, node, matchResult) {
4492 var error = createCustomError('SyntaxMatchError', message);
4493 var details = fromMatchResult(matchResult);
4494 var mismatchOffset = details.mismatchOffset || 0;
4495 var badNode = details.node || node;
4496 var end = getLocation(badNode, 'end');
4497 var start = details.last ? end : getLocation(badNode, 'start');
4498 var css = details.css;
4499
4500 error.rawMessage = message;
4501 error.syntax = syntax ? generate_1(syntax) : '<generic>';
4502 error.css = css;
4503 error.mismatchOffset = mismatchOffset;
4504 error.loc = {
4505 source: (badNode && badNode.loc && badNode.loc.source) || '<unknown>',
4506 start: start,
4507 end: end
4508 };
4509 error.line = start ? start.line : undefined;
4510 error.column = start ? start.column : undefined;
4511 error.offset = start ? start.offset : undefined;
4512 error.message = message + '\n' +
4513 ' syntax: ' + error.syntax + '\n' +
4514 ' value: ' + (error.css || '<empty string>') + '\n' +
4515 ' --------' + new Array(error.mismatchOffset + 1).join('-') + '^';
4516
4517 return error;
4518 };
4519
4520 var error = {
4521 SyntaxReferenceError: SyntaxReferenceError,
4522 MatchError: MatchError
4523 };
4524
4525 var hasOwnProperty = Object.prototype.hasOwnProperty;
4526 var keywords = Object.create(null);
4527 var properties = Object.create(null);
4528 var HYPHENMINUS = 45; // '-'.charCodeAt()
4529
4530 function isCustomProperty(str, offset) {
4531 offset = offset || 0;
4532
4533 return str.length - offset >= 2 &&
4534 str.charCodeAt(offset) === HYPHENMINUS &&
4535 str.charCodeAt(offset + 1) === HYPHENMINUS;
4536 }
4537
4538 function getVendorPrefix(str, offset) {
4539 offset = offset || 0;
4540
4541 // verdor prefix should be at least 3 chars length
4542 if (str.length - offset >= 3) {
4543 // vendor prefix starts with hyper minus following non-hyper minus
4544 if (str.charCodeAt(offset) === HYPHENMINUS &&
4545 str.charCodeAt(offset + 1) !== HYPHENMINUS) {
4546 // vendor prefix should contain a hyper minus at the ending
4547 var secondDashIndex = str.indexOf('-', offset + 2);
4548
4549 if (secondDashIndex !== -1) {
4550 return str.substring(offset, secondDashIndex + 1);
4551 }
4552 }
4553 }
4554
4555 return '';
4556 }
4557
4558 function getKeywordDescriptor(keyword) {
4559 if (hasOwnProperty.call(keywords, keyword)) {
4560 return keywords[keyword];
4561 }
4562
4563 var name = keyword.toLowerCase();
4564
4565 if (hasOwnProperty.call(keywords, name)) {
4566 return keywords[keyword] = keywords[name];
4567 }
4568
4569 var custom = isCustomProperty(name, 0);
4570 var vendor = !custom ? getVendorPrefix(name, 0) : '';
4571
4572 return keywords[keyword] = Object.freeze({
4573 basename: name.substr(vendor.length),
4574 name: name,
4575 vendor: vendor,
4576 prefix: vendor,
4577 custom: custom
4578 });
4579 }
4580
4581 function getPropertyDescriptor(property) {
4582 if (hasOwnProperty.call(properties, property)) {
4583 return properties[property];
4584 }
4585
4586 var name = property;
4587 var hack = property[0];
4588
4589 if (hack === '/') {
4590 hack = property[1] === '/' ? '//' : '/';
4591 } else if (hack !== '_' &&
4592 hack !== '*' &&
4593 hack !== '$' &&
4594 hack !== '#' &&
4595 hack !== '+' &&
4596 hack !== '&') {
4597 hack = '';
4598 }
4599
4600 var custom = isCustomProperty(name, hack.length);
4601
4602 // re-use result when possible (the same as for lower case)
4603 if (!custom) {
4604 name = name.toLowerCase();
4605 if (hasOwnProperty.call(properties, name)) {
4606 return properties[property] = properties[name];
4607 }
4608 }
4609
4610 var vendor = !custom ? getVendorPrefix(name, hack.length) : '';
4611 var prefix = name.substr(0, hack.length + vendor.length);
4612
4613 return properties[property] = Object.freeze({
4614 basename: name.substr(prefix.length),
4615 name: name.substr(hack.length),
4616 hack: hack,
4617 vendor: vendor,
4618 prefix: prefix,
4619 custom: custom
4620 });
4621 }
4622
4623 var names = {
4624 keyword: getKeywordDescriptor,
4625 property: getPropertyDescriptor,
4626 isCustomProperty: isCustomProperty,
4627 vendorPrefix: getVendorPrefix
4628 };
4629
4630 var MIN_SIZE = 16 * 1024;
4631 var SafeUint32Array = typeof Uint32Array !== 'undefined' ? Uint32Array : Array; // fallback on Array when TypedArray is not supported
4632
4633 var adoptBuffer = function adoptBuffer(buffer, size) {
4634 if (buffer === null || buffer.length < size) {
4635 return new SafeUint32Array(Math.max(size + 1024, MIN_SIZE));
4636 }
4637
4638 return buffer;
4639 };
4640
4641 var TYPE$2 = _const.TYPE;
4642
4643
4644 var isNewline$1 = charCodeDefinitions.isNewline;
4645 var isName$2 = charCodeDefinitions.isName;
4646 var isValidEscape$2 = charCodeDefinitions.isValidEscape;
4647 var isNumberStart$1 = charCodeDefinitions.isNumberStart;
4648 var isIdentifierStart$1 = charCodeDefinitions.isIdentifierStart;
4649 var charCodeCategory$1 = charCodeDefinitions.charCodeCategory;
4650 var isBOM$1 = charCodeDefinitions.isBOM;
4651
4652
4653 var cmpStr$2 = utils.cmpStr;
4654 var getNewlineLength$1 = utils.getNewlineLength;
4655 var findWhiteSpaceEnd$1 = utils.findWhiteSpaceEnd;
4656 var consumeEscaped$1 = utils.consumeEscaped;
4657 var consumeName$1 = utils.consumeName;
4658 var consumeNumber$1 = utils.consumeNumber;
4659 var consumeBadUrlRemnants$1 = utils.consumeBadUrlRemnants;
4660
4661 var OFFSET_MASK$1 = 0x00FFFFFF;
4662 var TYPE_SHIFT$1 = 24;
4663
4664 function tokenize(source, stream) {
4665 function getCharCode(offset) {
4666 return offset < sourceLength ? source.charCodeAt(offset) : 0;
4667 }
4668
4669 // § 4.3.3. Consume a numeric token
4670 function consumeNumericToken() {
4671 // Consume a number and let number be the result.
4672 offset = consumeNumber$1(source, offset);
4673
4674 // If the next 3 input code points would start an identifier, then:
4675 if (isIdentifierStart$1(getCharCode(offset), getCharCode(offset + 1), getCharCode(offset + 2))) {
4676 // Create a <dimension-token> with the same value and type flag as number, and a unit set initially to the empty string.
4677 // Consume a name. Set the <dimension-token>’s unit to the returned value.
4678 // Return the <dimension-token>.
4679 type = TYPE$2.Dimension;
4680 offset = consumeName$1(source, offset);
4681 return;
4682 }
4683
4684 // Otherwise, if the next input code point is U+0025 PERCENTAGE SIGN (%), consume it.
4685 if (getCharCode(offset) === 0x0025) {
4686 // Create a <percentage-token> with the same value as number, and return it.
4687 type = TYPE$2.Percentage;
4688 offset++;
4689 return;
4690 }
4691
4692 // Otherwise, create a <number-token> with the same value and type flag as number, and return it.
4693 type = TYPE$2.Number;
4694 }
4695
4696 // § 4.3.4. Consume an ident-like token
4697 function consumeIdentLikeToken() {
4698 const nameStartOffset = offset;
4699
4700 // Consume a name, and let string be the result.
4701 offset = consumeName$1(source, offset);
4702
4703 // If string’s value is an ASCII case-insensitive match for "url",
4704 // and the next input code point is U+0028 LEFT PARENTHESIS ((), consume it.
4705 if (cmpStr$2(source, nameStartOffset, offset, 'url') && getCharCode(offset) === 0x0028) {
4706 // While the next two input code points are whitespace, consume the next input code point.
4707 offset = findWhiteSpaceEnd$1(source, offset + 1);
4708
4709 // If the next one or two input code points are U+0022 QUOTATION MARK ("), U+0027 APOSTROPHE ('),
4710 // or whitespace followed by U+0022 QUOTATION MARK (") or U+0027 APOSTROPHE ('),
4711 // then create a <function-token> with its value set to string and return it.
4712 if (getCharCode(offset) === 0x0022 ||
4713 getCharCode(offset) === 0x0027) {
4714 type = TYPE$2.Function;
4715 offset = nameStartOffset + 4;
4716 return;
4717 }
4718
4719 // Otherwise, consume a url token, and return it.
4720 consumeUrlToken();
4721 return;
4722 }
4723
4724 // Otherwise, if the next input code point is U+0028 LEFT PARENTHESIS ((), consume it.
4725 // Create a <function-token> with its value set to string and return it.
4726 if (getCharCode(offset) === 0x0028) {
4727 type = TYPE$2.Function;
4728 offset++;
4729 return;
4730 }
4731
4732 // Otherwise, create an <ident-token> with its value set to string and return it.
4733 type = TYPE$2.Ident;
4734 }
4735
4736 // § 4.3.5. Consume a string token
4737 function consumeStringToken(endingCodePoint) {
4738 // This algorithm may be called with an ending code point, which denotes the code point
4739 // that ends the string. If an ending code point is not specified,
4740 // the current input code point is used.
4741 if (!endingCodePoint) {
4742 endingCodePoint = getCharCode(offset++);
4743 }
4744
4745 // Initially create a <string-token> with its value set to the empty string.
4746 type = TYPE$2.String;
4747
4748 // Repeatedly consume the next input code point from the stream:
4749 for (; offset < source.length; offset++) {
4750 var code = source.charCodeAt(offset);
4751
4752 switch (charCodeCategory$1(code)) {
4753 // ending code point
4754 case endingCodePoint:
4755 // Return the <string-token>.
4756 offset++;
4757 return;
4758
4759 // EOF
4760 case charCodeCategory$1.Eof:
4761 // This is a parse error. Return the <string-token>.
4762 return;
4763
4764 // newline
4765 case charCodeCategory$1.WhiteSpace:
4766 if (isNewline$1(code)) {
4767 // This is a parse error. Reconsume the current input code point,
4768 // create a <bad-string-token>, and return it.
4769 offset += getNewlineLength$1(source, offset, code);
4770 type = TYPE$2.BadString;
4771 return;
4772 }
4773 break;
4774
4775 // U+005C REVERSE SOLIDUS (\)
4776 case 0x005C:
4777 // If the next input code point is EOF, do nothing.
4778 if (offset === source.length - 1) {
4779 break;
4780 }
4781
4782 var nextCode = getCharCode(offset + 1);
4783
4784 // Otherwise, if the next input code point is a newline, consume it.
4785 if (isNewline$1(nextCode)) {
4786 offset += getNewlineLength$1(source, offset + 1, nextCode);
4787 } else if (isValidEscape$2(code, nextCode)) {
4788 // Otherwise, (the stream starts with a valid escape) consume
4789 // an escaped code point and append the returned code point to
4790 // the <string-token>’s value.
4791 offset = consumeEscaped$1(source, offset) - 1;
4792 }
4793 break;
4794
4795 // anything else
4796 // Append the current input code point to the <string-token>’s value.
4797 }
4798 }
4799 }
4800
4801 // § 4.3.6. Consume a url token
4802 // Note: This algorithm assumes that the initial "url(" has already been consumed.
4803 // This algorithm also assumes that it’s being called to consume an "unquoted" value, like url(foo).
4804 // A quoted value, like url("foo"), is parsed as a <function-token>. Consume an ident-like token
4805 // automatically handles this distinction; this algorithm shouldn’t be called directly otherwise.
4806 function consumeUrlToken() {
4807 // Initially create a <url-token> with its value set to the empty string.
4808 type = TYPE$2.Url;
4809
4810 // Consume as much whitespace as possible.
4811 offset = findWhiteSpaceEnd$1(source, offset);
4812
4813 // Repeatedly consume the next input code point from the stream:
4814 for (; offset < source.length; offset++) {
4815 var code = source.charCodeAt(offset);
4816
4817 switch (charCodeCategory$1(code)) {
4818 // U+0029 RIGHT PARENTHESIS ())
4819 case 0x0029:
4820 // Return the <url-token>.
4821 offset++;
4822 return;
4823
4824 // EOF
4825 case charCodeCategory$1.Eof:
4826 // This is a parse error. Return the <url-token>.
4827 return;
4828
4829 // whitespace
4830 case charCodeCategory$1.WhiteSpace:
4831 // Consume as much whitespace as possible.
4832 offset = findWhiteSpaceEnd$1(source, offset);
4833
4834 // If the next input code point is U+0029 RIGHT PARENTHESIS ()) or EOF,
4835 // consume it and return the <url-token>
4836 // (if EOF was encountered, this is a parse error);
4837 if (getCharCode(offset) === 0x0029 || offset >= source.length) {
4838 if (offset < source.length) {
4839 offset++;
4840 }
4841 return;
4842 }
4843
4844 // otherwise, consume the remnants of a bad url, create a <bad-url-token>,
4845 // and return it.
4846 offset = consumeBadUrlRemnants$1(source, offset);
4847 type = TYPE$2.BadUrl;
4848 return;
4849
4850 // U+0022 QUOTATION MARK (")
4851 // U+0027 APOSTROPHE (')
4852 // U+0028 LEFT PARENTHESIS (()
4853 // non-printable code point
4854 case 0x0022:
4855 case 0x0027:
4856 case 0x0028:
4857 case charCodeCategory$1.NonPrintable:
4858 // This is a parse error. Consume the remnants of a bad url,
4859 // create a <bad-url-token>, and return it.
4860 offset = consumeBadUrlRemnants$1(source, offset);
4861 type = TYPE$2.BadUrl;
4862 return;
4863
4864 // U+005C REVERSE SOLIDUS (\)
4865 case 0x005C:
4866 // If the stream starts with a valid escape, consume an escaped code point and
4867 // append the returned code point to the <url-token>’s value.
4868 if (isValidEscape$2(code, getCharCode(offset + 1))) {
4869 offset = consumeEscaped$1(source, offset) - 1;
4870 break;
4871 }
4872
4873 // Otherwise, this is a parse error. Consume the remnants of a bad url,
4874 // create a <bad-url-token>, and return it.
4875 offset = consumeBadUrlRemnants$1(source, offset);
4876 type = TYPE$2.BadUrl;
4877 return;
4878
4879 // anything else
4880 // Append the current input code point to the <url-token>’s value.
4881 }
4882 }
4883 }
4884
4885 if (!stream) {
4886 stream = new TokenStream_1();
4887 }
4888
4889 // ensure source is a string
4890 source = String(source || '');
4891
4892 var sourceLength = source.length;
4893 var offsetAndType = adoptBuffer(stream.offsetAndType, sourceLength + 1); // +1 because of eof-token
4894 var balance = adoptBuffer(stream.balance, sourceLength + 1);
4895 var tokenCount = 0;
4896 var start = isBOM$1(getCharCode(0));
4897 var offset = start;
4898 var balanceCloseType = 0;
4899 var balanceStart = 0;
4900 var balancePrev = 0;
4901
4902 // https://drafts.csswg.org/css-syntax-3/#consume-token
4903 // § 4.3.1. Consume a token
4904 while (offset < sourceLength) {
4905 var code = source.charCodeAt(offset);
4906 var type = 0;
4907
4908 balance[tokenCount] = sourceLength;
4909
4910 switch (charCodeCategory$1(code)) {
4911 // whitespace
4912 case charCodeCategory$1.WhiteSpace:
4913 // Consume as much whitespace as possible. Return a <whitespace-token>.
4914 type = TYPE$2.WhiteSpace;
4915 offset = findWhiteSpaceEnd$1(source, offset + 1);
4916 break;
4917
4918 // U+0022 QUOTATION MARK (")
4919 case 0x0022:
4920 // Consume a string token and return it.
4921 consumeStringToken();
4922 break;
4923
4924 // U+0023 NUMBER SIGN (#)
4925 case 0x0023:
4926 // If the next input code point is a name code point or the next two input code points are a valid escape, then:
4927 if (isName$2(getCharCode(offset + 1)) || isValidEscape$2(getCharCode(offset + 1), getCharCode(offset + 2))) {
4928 // Create a <hash-token>.
4929 type = TYPE$2.Hash;
4930
4931 // If the next 3 input code points would start an identifier, set the <hash-token>’s type flag to "id".
4932 // if (isIdentifierStart(getCharCode(offset + 1), getCharCode(offset + 2), getCharCode(offset + 3))) {
4933 // // TODO: set id flag
4934 // }
4935
4936 // Consume a name, and set the <hash-token>’s value to the returned string.
4937 offset = consumeName$1(source, offset + 1);
4938
4939 // Return the <hash-token>.
4940 } else {
4941 // Otherwise, return a <delim-token> with its value set to the current input code point.
4942 type = TYPE$2.Delim;
4943 offset++;
4944 }
4945
4946 break;
4947
4948 // U+0027 APOSTROPHE (')
4949 case 0x0027:
4950 // Consume a string token and return it.
4951 consumeStringToken();
4952 break;
4953
4954 // U+0028 LEFT PARENTHESIS (()
4955 case 0x0028:
4956 // Return a <(-token>.
4957 type = TYPE$2.LeftParenthesis;
4958 offset++;
4959 break;
4960
4961 // U+0029 RIGHT PARENTHESIS ())
4962 case 0x0029:
4963 // Return a <)-token>.
4964 type = TYPE$2.RightParenthesis;
4965 offset++;
4966 break;
4967
4968 // U+002B PLUS SIGN (+)
4969 case 0x002B:
4970 // If the input stream starts with a number, ...
4971 if (isNumberStart$1(code, getCharCode(offset + 1), getCharCode(offset + 2))) {
4972 // ... reconsume the current input code point, consume a numeric token, and return it.
4973 consumeNumericToken();
4974 } else {
4975 // Otherwise, return a <delim-token> with its value set to the current input code point.
4976 type = TYPE$2.Delim;
4977 offset++;
4978 }
4979 break;
4980
4981 // U+002C COMMA (,)
4982 case 0x002C:
4983 // Return a <comma-token>.
4984 type = TYPE$2.Comma;
4985 offset++;
4986 break;
4987
4988 // U+002D HYPHEN-MINUS (-)
4989 case 0x002D:
4990 // If the input stream starts with a number, reconsume the current input code point, consume a numeric token, and return it.
4991 if (isNumberStart$1(code, getCharCode(offset + 1), getCharCode(offset + 2))) {
4992 consumeNumericToken();
4993 } else {
4994 // 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>.
4995 if (getCharCode(offset + 1) === 0x002D &&
4996 getCharCode(offset + 2) === 0x003E) {
4997 type = TYPE$2.CDC;
4998 offset = offset + 3;
4999 } else {
5000 // Otherwise, if the input stream starts with an identifier, ...
5001 if (isIdentifierStart$1(code, getCharCode(offset + 1), getCharCode(offset + 2))) {
5002 // ... reconsume the current input code point, consume an ident-like token, and return it.
5003 consumeIdentLikeToken();
5004 } else {
5005 // Otherwise, return a <delim-token> with its value set to the current input code point.
5006 type = TYPE$2.Delim;
5007 offset++;
5008 }
5009 }
5010 }
5011 break;
5012
5013 // U+002E FULL STOP (.)
5014 case 0x002E:
5015 // If the input stream starts with a number, ...
5016 if (isNumberStart$1(code, getCharCode(offset + 1), getCharCode(offset + 2))) {
5017 // ... reconsume the current input code point, consume a numeric token, and return it.
5018 consumeNumericToken();
5019 } else {
5020 // Otherwise, return a <delim-token> with its value set to the current input code point.
5021 type = TYPE$2.Delim;
5022 offset++;
5023 }
5024
5025 break;
5026
5027 // U+002F SOLIDUS (/)
5028 case 0x002F:
5029 // If the next two input code point are U+002F SOLIDUS (/) followed by a U+002A ASTERISK (*),
5030 if (getCharCode(offset + 1) === 0x002A) {
5031 // ... consume them and all following code points up to and including the first U+002A ASTERISK (*)
5032 // followed by a U+002F SOLIDUS (/), or up to an EOF code point.
5033 type = TYPE$2.Comment;
5034 offset = source.indexOf('*/', offset + 2) + 2;
5035 if (offset === 1) {
5036 offset = source.length;
5037 }
5038 } else {
5039 type = TYPE$2.Delim;
5040 offset++;
5041 }
5042 break;
5043
5044 // U+003A COLON (:)
5045 case 0x003A:
5046 // Return a <colon-token>.
5047 type = TYPE$2.Colon;
5048 offset++;
5049 break;
5050
5051 // U+003B SEMICOLON (;)
5052 case 0x003B:
5053 // Return a <semicolon-token>.
5054 type = TYPE$2.Semicolon;
5055 offset++;
5056 break;
5057
5058 // U+003C LESS-THAN SIGN (<)
5059 case 0x003C:
5060 // If the next 3 input code points are U+0021 EXCLAMATION MARK U+002D HYPHEN-MINUS U+002D HYPHEN-MINUS (!--), ...
5061 if (getCharCode(offset + 1) === 0x0021 &&
5062 getCharCode(offset + 2) === 0x002D &&
5063 getCharCode(offset + 3) === 0x002D) {
5064 // ... consume them and return a <CDO-token>.
5065 type = TYPE$2.CDO;
5066 offset = offset + 4;
5067 } else {
5068 // Otherwise, return a <delim-token> with its value set to the current input code point.
5069 type = TYPE$2.Delim;
5070 offset++;
5071 }
5072
5073 break;
5074
5075 // U+0040 COMMERCIAL AT (@)
5076 case 0x0040:
5077 // If the next 3 input code points would start an identifier, ...
5078 if (isIdentifierStart$1(getCharCode(offset + 1), getCharCode(offset + 2), getCharCode(offset + 3))) {
5079 // ... consume a name, create an <at-keyword-token> with its value set to the returned value, and return it.
5080 type = TYPE$2.AtKeyword;
5081 offset = consumeName$1(source, offset + 1);
5082 } else {
5083 // Otherwise, return a <delim-token> with its value set to the current input code point.
5084 type = TYPE$2.Delim;
5085 offset++;
5086 }
5087
5088 break;
5089
5090 // U+005B LEFT SQUARE BRACKET ([)
5091 case 0x005B:
5092 // Return a <[-token>.
5093 type = TYPE$2.LeftSquareBracket;
5094 offset++;
5095 break;
5096
5097 // U+005C REVERSE SOLIDUS (\)
5098 case 0x005C:
5099 // If the input stream starts with a valid escape, ...
5100 if (isValidEscape$2(code, getCharCode(offset + 1))) {
5101 // ... reconsume the current input code point, consume an ident-like token, and return it.
5102 consumeIdentLikeToken();
5103 } else {
5104 // Otherwise, this is a parse error. Return a <delim-token> with its value set to the current input code point.
5105 type = TYPE$2.Delim;
5106 offset++;
5107 }
5108 break;
5109
5110 // U+005D RIGHT SQUARE BRACKET (])
5111 case 0x005D:
5112 // Return a <]-token>.
5113 type = TYPE$2.RightSquareBracket;
5114 offset++;
5115 break;
5116
5117 // U+007B LEFT CURLY BRACKET ({)
5118 case 0x007B:
5119 // Return a <{-token>.
5120 type = TYPE$2.LeftCurlyBracket;
5121 offset++;
5122 break;
5123
5124 // U+007D RIGHT CURLY BRACKET (})
5125 case 0x007D:
5126 // Return a <}-token>.
5127 type = TYPE$2.RightCurlyBracket;
5128 offset++;
5129 break;
5130
5131 // digit
5132 case charCodeCategory$1.Digit:
5133 // Reconsume the current input code point, consume a numeric token, and return it.
5134 consumeNumericToken();
5135 break;
5136
5137 // name-start code point
5138 case charCodeCategory$1.NameStart:
5139 // Reconsume the current input code point, consume an ident-like token, and return it.
5140 consumeIdentLikeToken();
5141 break;
5142
5143 // EOF
5144 case charCodeCategory$1.Eof:
5145 // Return an <EOF-token>.
5146 break;
5147
5148 // anything else
5149 default:
5150 // Return a <delim-token> with its value set to the current input code point.
5151 type = TYPE$2.Delim;
5152 offset++;
5153 }
5154
5155 switch (type) {
5156 case balanceCloseType:
5157 balancePrev = balanceStart & OFFSET_MASK$1;
5158 balanceStart = balance[balancePrev];
5159 balanceCloseType = balanceStart >> TYPE_SHIFT$1;
5160 balance[tokenCount] = balancePrev;
5161 balance[balancePrev++] = tokenCount;
5162 for (; balancePrev < tokenCount; balancePrev++) {
5163 if (balance[balancePrev] === sourceLength) {
5164 balance[balancePrev] = tokenCount;
5165 }
5166 }
5167 break;
5168
5169 case TYPE$2.LeftParenthesis:
5170 case TYPE$2.Function:
5171 balance[tokenCount] = balanceStart;
5172 balanceCloseType = TYPE$2.RightParenthesis;
5173 balanceStart = (balanceCloseType << TYPE_SHIFT$1) | tokenCount;
5174 break;
5175
5176 case TYPE$2.LeftSquareBracket:
5177 balance[tokenCount] = balanceStart;
5178 balanceCloseType = TYPE$2.RightSquareBracket;
5179 balanceStart = (balanceCloseType << TYPE_SHIFT$1) | tokenCount;
5180 break;
5181
5182 case TYPE$2.LeftCurlyBracket:
5183 balance[tokenCount] = balanceStart;
5184 balanceCloseType = TYPE$2.RightCurlyBracket;
5185 balanceStart = (balanceCloseType << TYPE_SHIFT$1) | tokenCount;
5186 break;
5187 }
5188
5189 offsetAndType[tokenCount++] = (type << TYPE_SHIFT$1) | offset;
5190 }
5191
5192 // finalize buffers
5193 offsetAndType[tokenCount] = (TYPE$2.EOF << TYPE_SHIFT$1) | offset; // <EOF-token>
5194 balance[tokenCount] = sourceLength;
5195 balance[sourceLength] = sourceLength; // prevents false positive balance match with any token
5196 while (balanceStart !== 0) {
5197 balancePrev = balanceStart & OFFSET_MASK$1;
5198 balanceStart = balance[balancePrev];
5199 balance[balancePrev] = sourceLength;
5200 }
5201
5202 // update stream
5203 stream.source = source;
5204 stream.firstCharOffset = start;
5205 stream.offsetAndType = offsetAndType;
5206 stream.tokenCount = tokenCount;
5207 stream.balance = balance;
5208 stream.reset();
5209 stream.next();
5210
5211 return stream;
5212 }
5213
5214 // extend tokenizer with constants
5215 Object.keys(_const).forEach(function(key) {
5216 tokenize[key] = _const[key];
5217 });
5218
5219 // extend tokenizer with static methods from utils
5220 Object.keys(charCodeDefinitions).forEach(function(key) {
5221 tokenize[key] = charCodeDefinitions[key];
5222 });
5223 Object.keys(utils).forEach(function(key) {
5224 tokenize[key] = utils[key];
5225 });
5226
5227 var tokenizer = tokenize;
5228
5229 var isDigit$2 = tokenizer.isDigit;
5230 var cmpChar$1 = tokenizer.cmpChar;
5231 var TYPE$3 = tokenizer.TYPE;
5232
5233 var DELIM = TYPE$3.Delim;
5234 var WHITESPACE$1 = TYPE$3.WhiteSpace;
5235 var COMMENT$1 = TYPE$3.Comment;
5236 var IDENT = TYPE$3.Ident;
5237 var NUMBER = TYPE$3.Number;
5238 var DIMENSION = TYPE$3.Dimension;
5239 var PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+)
5240 var HYPHENMINUS$1 = 0x002D; // U+002D HYPHEN-MINUS (-)
5241 var N = 0x006E; // U+006E LATIN SMALL LETTER N (n)
5242 var DISALLOW_SIGN = true;
5243 var ALLOW_SIGN = false;
5244
5245 function isDelim(token, code) {
5246 return token !== null && token.type === DELIM && token.value.charCodeAt(0) === code;
5247 }
5248
5249 function skipSC(token, offset, getNextToken) {
5250 while (token !== null && (token.type === WHITESPACE$1 || token.type === COMMENT$1)) {
5251 token = getNextToken(++offset);
5252 }
5253
5254 return offset;
5255 }
5256
5257 function checkInteger(token, valueOffset, disallowSign, offset) {
5258 if (!token) {
5259 return 0;
5260 }
5261
5262 var code = token.value.charCodeAt(valueOffset);
5263
5264 if (code === PLUSSIGN || code === HYPHENMINUS$1) {
5265 if (disallowSign) {
5266 // Number sign is not allowed
5267 return 0;
5268 }
5269 valueOffset++;
5270 }
5271
5272 for (; valueOffset < token.value.length; valueOffset++) {
5273 if (!isDigit$2(token.value.charCodeAt(valueOffset))) {
5274 // Integer is expected
5275 return 0;
5276 }
5277 }
5278
5279 return offset + 1;
5280 }
5281
5282 // ... <signed-integer>
5283 // ... ['+' | '-'] <signless-integer>
5284 function consumeB(token, offset_, getNextToken) {
5285 var sign = false;
5286 var offset = skipSC(token, offset_, getNextToken);
5287
5288 token = getNextToken(offset);
5289
5290 if (token === null) {
5291 return offset_;
5292 }
5293
5294 if (token.type !== NUMBER) {
5295 if (isDelim(token, PLUSSIGN) || isDelim(token, HYPHENMINUS$1)) {
5296 sign = true;
5297 offset = skipSC(getNextToken(++offset), offset, getNextToken);
5298 token = getNextToken(offset);
5299
5300 if (token === null && token.type !== NUMBER) {
5301 return 0;
5302 }
5303 } else {
5304 return offset_;
5305 }
5306 }
5307
5308 if (!sign) {
5309 var code = token.value.charCodeAt(0);
5310 if (code !== PLUSSIGN && code !== HYPHENMINUS$1) {
5311 // Number sign is expected
5312 return 0;
5313 }
5314 }
5315
5316 return checkInteger(token, sign ? 0 : 1, sign, offset);
5317 }
5318
5319 // An+B microsyntax https://www.w3.org/TR/css-syntax-3/#anb
5320 var genericAnPlusB = function anPlusB(token, getNextToken) {
5321 /* eslint-disable brace-style*/
5322 var offset = 0;
5323
5324 if (!token) {
5325 return 0;
5326 }
5327
5328 // <integer>
5329 if (token.type === NUMBER) {
5330 return checkInteger(token, 0, ALLOW_SIGN, offset); // b
5331 }
5332
5333 // -n
5334 // -n <signed-integer>
5335 // -n ['+' | '-'] <signless-integer>
5336 // -n- <signless-integer>
5337 // <dashndashdigit-ident>
5338 else if (token.type === IDENT && token.value.charCodeAt(0) === HYPHENMINUS$1) {
5339 // expect 1st char is N
5340 if (!cmpChar$1(token.value, 1, N)) {
5341 return 0;
5342 }
5343
5344 switch (token.value.length) {
5345 // -n
5346 // -n <signed-integer>
5347 // -n ['+' | '-'] <signless-integer>
5348 case 2:
5349 return consumeB(getNextToken(++offset), offset, getNextToken);
5350
5351 // -n- <signless-integer>
5352 case 3:
5353 if (token.value.charCodeAt(2) !== HYPHENMINUS$1) {
5354 return 0;
5355 }
5356
5357 offset = skipSC(getNextToken(++offset), offset, getNextToken);
5358 token = getNextToken(offset);
5359
5360 return checkInteger(token, 0, DISALLOW_SIGN, offset);
5361
5362 // <dashndashdigit-ident>
5363 default:
5364 if (token.value.charCodeAt(2) !== HYPHENMINUS$1) {
5365 return 0;
5366 }
5367
5368 return checkInteger(token, 3, DISALLOW_SIGN, offset);
5369 }
5370 }
5371
5372 // '+'? n
5373 // '+'? n <signed-integer>
5374 // '+'? n ['+' | '-'] <signless-integer>
5375 // '+'? n- <signless-integer>
5376 // '+'? <ndashdigit-ident>
5377 else if (token.type === IDENT || (isDelim(token, PLUSSIGN) && getNextToken(offset + 1).type === IDENT)) {
5378 // just ignore a plus
5379 if (token.type !== IDENT) {
5380 token = getNextToken(++offset);
5381 }
5382
5383 if (token === null || !cmpChar$1(token.value, 0, N)) {
5384 return 0;
5385 }
5386
5387 switch (token.value.length) {
5388 // '+'? n
5389 // '+'? n <signed-integer>
5390 // '+'? n ['+' | '-'] <signless-integer>
5391 case 1:
5392 return consumeB(getNextToken(++offset), offset, getNextToken);
5393
5394 // '+'? n- <signless-integer>
5395 case 2:
5396 if (token.value.charCodeAt(1) !== HYPHENMINUS$1) {
5397 return 0;
5398 }
5399
5400 offset = skipSC(getNextToken(++offset), offset, getNextToken);
5401 token = getNextToken(offset);
5402
5403 return checkInteger(token, 0, DISALLOW_SIGN, offset);
5404
5405 // '+'? <ndashdigit-ident>
5406 default:
5407 if (token.value.charCodeAt(1) !== HYPHENMINUS$1) {
5408 return 0;
5409 }
5410
5411 return checkInteger(token, 2, DISALLOW_SIGN, offset);
5412 }
5413 }
5414
5415 // <ndashdigit-dimension>
5416 // <ndash-dimension> <signless-integer>
5417 // <n-dimension>
5418 // <n-dimension> <signed-integer>
5419 // <n-dimension> ['+' | '-'] <signless-integer>
5420 else if (token.type === DIMENSION) {
5421 var code = token.value.charCodeAt(0);
5422 var sign = code === PLUSSIGN || code === HYPHENMINUS$1 ? 1 : 0;
5423
5424 for (var i = sign; i < token.value.length; i++) {
5425 if (!isDigit$2(token.value.charCodeAt(i))) {
5426 break;
5427 }
5428 }
5429
5430 if (i === sign) {
5431 // Integer is expected
5432 return 0;
5433 }
5434
5435 if (!cmpChar$1(token.value, i, N)) {
5436 return 0;
5437 }
5438
5439 // <n-dimension>
5440 // <n-dimension> <signed-integer>
5441 // <n-dimension> ['+' | '-'] <signless-integer>
5442 if (i + 1 === token.value.length) {
5443 return consumeB(getNextToken(++offset), offset, getNextToken);
5444 } else {
5445 if (token.value.charCodeAt(i + 1) !== HYPHENMINUS$1) {
5446 return 0;
5447 }
5448
5449 // <ndash-dimension> <signless-integer>
5450 if (i + 2 === token.value.length) {
5451 offset = skipSC(getNextToken(++offset), offset, getNextToken);
5452 token = getNextToken(offset);
5453
5454 return checkInteger(token, 0, DISALLOW_SIGN, offset);
5455 }
5456 // <ndashdigit-dimension>
5457 else {
5458 return checkInteger(token, i + 2, DISALLOW_SIGN, offset);
5459 }
5460 }
5461 }
5462
5463 return 0;
5464 };
5465
5466 var isHexDigit$2 = tokenizer.isHexDigit;
5467 var cmpChar$2 = tokenizer.cmpChar;
5468 var TYPE$4 = tokenizer.TYPE;
5469
5470 var IDENT$1 = TYPE$4.Ident;
5471 var DELIM$1 = TYPE$4.Delim;
5472 var NUMBER$1 = TYPE$4.Number;
5473 var DIMENSION$1 = TYPE$4.Dimension;
5474 var PLUSSIGN$1 = 0x002B; // U+002B PLUS SIGN (+)
5475 var HYPHENMINUS$2 = 0x002D; // U+002D HYPHEN-MINUS (-)
5476 var QUESTIONMARK = 0x003F; // U+003F QUESTION MARK (?)
5477 var U = 0x0075; // U+0075 LATIN SMALL LETTER U (u)
5478
5479 function isDelim$1(token, code) {
5480 return token !== null && token.type === DELIM$1 && token.value.charCodeAt(0) === code;
5481 }
5482
5483 function startsWith(token, code) {
5484 return token.value.charCodeAt(0) === code;
5485 }
5486
5487 function hexSequence(token, offset, allowDash) {
5488 for (var pos = offset, hexlen = 0; pos < token.value.length; pos++) {
5489 var code = token.value.charCodeAt(pos);
5490
5491 if (code === HYPHENMINUS$2 && allowDash && hexlen !== 0) {
5492 if (hexSequence(token, offset + hexlen + 1, false) > 0) {
5493 return 6; // dissallow following question marks
5494 }
5495
5496 return 0; // dash at the ending of a hex sequence is not allowed
5497 }
5498
5499 if (!isHexDigit$2(code)) {
5500 return 0; // not a hex digit
5501 }
5502
5503 if (++hexlen > 6) {
5504 return 0; // too many hex digits
5505 } }
5506
5507 return hexlen;
5508 }
5509
5510 function withQuestionMarkSequence(consumed, length, getNextToken) {
5511 if (!consumed) {
5512 return 0; // nothing consumed
5513 }
5514
5515 while (isDelim$1(getNextToken(length), QUESTIONMARK)) {
5516 if (++consumed > 6) {
5517 return 0; // too many question marks
5518 }
5519
5520 length++;
5521 }
5522
5523 return length;
5524 }
5525
5526 // https://drafts.csswg.org/css-syntax/#urange
5527 // Informally, the <urange> production has three forms:
5528 // U+0001
5529 // Defines a range consisting of a single code point, in this case the code point "1".
5530 // U+0001-00ff
5531 // Defines a range of codepoints between the first and the second value, in this case
5532 // the range between "1" and "ff" (255 in decimal) inclusive.
5533 // U+00??
5534 // Defines a range of codepoints where the "?" characters range over all hex digits,
5535 // in this case defining the same as the value U+0000-00ff.
5536 // In each form, a maximum of 6 digits is allowed for each hexadecimal number (if you treat "?" as a hexadecimal digit).
5537 //
5538 // <urange> =
5539 // u '+' <ident-token> '?'* |
5540 // u <dimension-token> '?'* |
5541 // u <number-token> '?'* |
5542 // u <number-token> <dimension-token> |
5543 // u <number-token> <number-token> |
5544 // u '+' '?'+
5545 var genericUrange = function urange(token, getNextToken) {
5546 var length = 0;
5547
5548 // should start with `u` or `U`
5549 if (token === null || token.type !== IDENT$1 || !cmpChar$2(token.value, 0, U)) {
5550 return 0;
5551 }
5552
5553 token = getNextToken(++length);
5554 if (token === null) {
5555 return 0;
5556 }
5557
5558 // u '+' <ident-token> '?'*
5559 // u '+' '?'+
5560 if (isDelim$1(token, PLUSSIGN$1)) {
5561 token = getNextToken(++length);
5562 if (token === null) {
5563 return 0;
5564 }
5565
5566 if (token.type === IDENT$1) {
5567 // u '+' <ident-token> '?'*
5568 return withQuestionMarkSequence(hexSequence(token, 0, true), ++length, getNextToken);
5569 }
5570
5571 if (isDelim$1(token, QUESTIONMARK)) {
5572 // u '+' '?'+
5573 return withQuestionMarkSequence(1, ++length, getNextToken);
5574 }
5575
5576 // Hex digit or question mark is expected
5577 return 0;
5578 }
5579
5580 // u <number-token> '?'*
5581 // u <number-token> <dimension-token>
5582 // u <number-token> <number-token>
5583 if (token.type === NUMBER$1) {
5584 if (!startsWith(token, PLUSSIGN$1)) {
5585 return 0;
5586 }
5587
5588 var consumedHexLength = hexSequence(token, 1, true);
5589 if (consumedHexLength === 0) {
5590 return 0;
5591 }
5592
5593 token = getNextToken(++length);
5594 if (token === null) {
5595 // u <number-token> <eof>
5596 return length;
5597 }
5598
5599 if (token.type === DIMENSION$1 || token.type === NUMBER$1) {
5600 // u <number-token> <dimension-token>
5601 // u <number-token> <number-token>
5602 if (!startsWith(token, HYPHENMINUS$2) || !hexSequence(token, 1, false)) {
5603 return 0;
5604 }
5605
5606 return length + 1;
5607 }
5608
5609 // u <number-token> '?'*
5610 return withQuestionMarkSequence(consumedHexLength, length, getNextToken);
5611 }
5612
5613 // u <dimension-token> '?'*
5614 if (token.type === DIMENSION$1) {
5615 if (!startsWith(token, PLUSSIGN$1)) {
5616 return 0;
5617 }
5618
5619 return withQuestionMarkSequence(hexSequence(token, 1, true), ++length, getNextToken);
5620 }
5621
5622 return 0;
5623 };
5624
5625 var isIdentifierStart$2 = tokenizer.isIdentifierStart;
5626 var isHexDigit$3 = tokenizer.isHexDigit;
5627 var isDigit$3 = tokenizer.isDigit;
5628 var cmpStr$3 = tokenizer.cmpStr;
5629 var consumeNumber$2 = tokenizer.consumeNumber;
5630 var TYPE$5 = tokenizer.TYPE;
5631
5632
5633
5634 var cssWideKeywords = ['unset', 'initial', 'inherit'];
5635 var calcFunctionNames = ['calc(', '-moz-calc(', '-webkit-calc('];
5636
5637 // https://www.w3.org/TR/css-values-3/#lengths
5638 var LENGTH = {
5639 // absolute length units
5640 'px': true,
5641 'mm': true,
5642 'cm': true,
5643 'in': true,
5644 'pt': true,
5645 'pc': true,
5646 'q': true,
5647
5648 // relative length units
5649 'em': true,
5650 'ex': true,
5651 'ch': true,
5652 'rem': true,
5653
5654 // viewport-percentage lengths
5655 'vh': true,
5656 'vw': true,
5657 'vmin': true,
5658 'vmax': true,
5659 'vm': true
5660 };
5661
5662 var ANGLE = {
5663 'deg': true,
5664 'grad': true,
5665 'rad': true,
5666 'turn': true
5667 };
5668
5669 var TIME = {
5670 's': true,
5671 'ms': true
5672 };
5673
5674 var FREQUENCY = {
5675 'hz': true,
5676 'khz': true
5677 };
5678
5679 // https://www.w3.org/TR/css-values-3/#resolution (https://drafts.csswg.org/css-values/#resolution)
5680 var RESOLUTION = {
5681 'dpi': true,
5682 'dpcm': true,
5683 'dppx': true,
5684 'x': true // https://github.com/w3c/csswg-drafts/issues/461
5685 };
5686
5687 // https://drafts.csswg.org/css-grid/#fr-unit
5688 var FLEX = {
5689 'fr': true
5690 };
5691
5692 // https://www.w3.org/TR/css3-speech/#mixing-props-voice-volume
5693 var DECIBEL = {
5694 'db': true
5695 };
5696
5697 // https://www.w3.org/TR/css3-speech/#voice-props-voice-pitch
5698 var SEMITONES = {
5699 'st': true
5700 };
5701
5702 // safe char code getter
5703 function charCode(str, index) {
5704 return index < str.length ? str.charCodeAt(index) : 0;
5705 }
5706
5707 function eqStr(actual, expected) {
5708 return cmpStr$3(actual, 0, actual.length, expected);
5709 }
5710
5711 function eqStrAny(actual, expected) {
5712 for (var i = 0; i < expected.length; i++) {
5713 if (eqStr(actual, expected[i])) {
5714 return true;
5715 }
5716 }
5717
5718 return false;
5719 }
5720
5721 // IE postfix hack, i.e. 123\0 or 123px\9
5722 function isPostfixIeHack(str, offset) {
5723 if (offset !== str.length - 2) {
5724 return false;
5725 }
5726
5727 return (
5728 str.charCodeAt(offset) === 0x005C && // U+005C REVERSE SOLIDUS (\)
5729 isDigit$3(str.charCodeAt(offset + 1))
5730 );
5731 }
5732
5733 function outOfRange(opts, value, numEnd) {
5734 if (opts && opts.type === 'Range') {
5735 var num = Number(
5736 numEnd !== undefined && numEnd !== value.length
5737 ? value.substr(0, numEnd)
5738 : value
5739 );
5740
5741 if (isNaN(num)) {
5742 return true;
5743 }
5744
5745 if (opts.min !== null && num < opts.min) {
5746 return true;
5747 }
5748
5749 if (opts.max !== null && num > opts.max) {
5750 return true;
5751 }
5752 }
5753
5754 return false;
5755 }
5756
5757 function consumeFunction(token, getNextToken) {
5758 var startIdx = token.index;
5759 var length = 0;
5760
5761 // balanced token consuming
5762 do {
5763 length++;
5764
5765 if (token.balance <= startIdx) {
5766 break;
5767 }
5768 } while (token = getNextToken(length));
5769
5770 return length;
5771 }
5772
5773 // TODO: implement
5774 // can be used wherever <length>, <frequency>, <angle>, <time>, <percentage>, <number>, or <integer> values are allowed
5775 // https://drafts.csswg.org/css-values/#calc-notation
5776 function calc(next) {
5777 return function(token, getNextToken, opts) {
5778 if (token === null) {
5779 return 0;
5780 }
5781
5782 if (token.type === TYPE$5.Function && eqStrAny(token.value, calcFunctionNames)) {
5783 return consumeFunction(token, getNextToken);
5784 }
5785
5786 return next(token, getNextToken, opts);
5787 };
5788 }
5789
5790 function tokenType(expectedTokenType) {
5791 return function(token) {
5792 if (token === null || token.type !== expectedTokenType) {
5793 return 0;
5794 }
5795
5796 return 1;
5797 };
5798 }
5799
5800 function func(name) {
5801 name = name + '(';
5802
5803 return function(token, getNextToken) {
5804 if (token !== null && eqStr(token.value, name)) {
5805 return consumeFunction(token, getNextToken);
5806 }
5807
5808 return 0;
5809 };
5810 }
5811
5812 // =========================
5813 // Complex types
5814 //
5815
5816 // https://drafts.csswg.org/css-values-4/#custom-idents
5817 // 4.2. Author-defined Identifiers: the <custom-ident> type
5818 // Some properties accept arbitrary author-defined identifiers as a component value.
5819 // This generic data type is denoted by <custom-ident>, and represents any valid CSS identifier
5820 // that would not be misinterpreted as a pre-defined keyword in that property’s value definition.
5821 //
5822 // See also: https://developer.mozilla.org/en-US/docs/Web/CSS/custom-ident
5823 function customIdent(token) {
5824 if (token === null || token.type !== TYPE$5.Ident) {
5825 return 0;
5826 }
5827
5828 var name = token.value.toLowerCase();
5829
5830 // The CSS-wide keywords are not valid <custom-ident>s
5831 if (eqStrAny(name, cssWideKeywords)) {
5832 return 0;
5833 }
5834
5835 // The default keyword is reserved and is also not a valid <custom-ident>
5836 if (eqStr(name, 'default')) {
5837 return 0;
5838 }
5839
5840 // TODO: ignore property specific keywords (as described https://developer.mozilla.org/en-US/docs/Web/CSS/custom-ident)
5841 // Specifications using <custom-ident> must specify clearly what other keywords
5842 // are excluded from <custom-ident>, if any—for example by saying that any pre-defined keywords
5843 // in that property’s value definition are excluded. Excluded keywords are excluded
5844 // in all ASCII case permutations.
5845
5846 return 1;
5847 }
5848
5849 // https://drafts.csswg.org/css-variables/#typedef-custom-property-name
5850 // A custom property is any property whose name starts with two dashes (U+002D HYPHEN-MINUS), like --foo.
5851 // The <custom-property-name> production corresponds to this: it’s defined as any valid identifier
5852 // that starts with two dashes, except -- itself, which is reserved for future use by CSS.
5853 // NOTE: Current implementation treat `--` as a valid name since most (all?) major browsers treat it as valid.
5854 function customPropertyName(token) {
5855 // ... defined as any valid identifier
5856 if (token === null || token.type !== TYPE$5.Ident) {
5857 return 0;
5858 }
5859
5860 // ... that starts with two dashes (U+002D HYPHEN-MINUS)
5861 if (charCode(token.value, 0) !== 0x002D || charCode(token.value, 1) !== 0x002D) {
5862 return 0;
5863 }
5864
5865 return 1;
5866 }
5867
5868 // https://drafts.csswg.org/css-color-4/#hex-notation
5869 // The syntax of a <hex-color> is a <hash-token> token whose value consists of 3, 4, 6, or 8 hexadecimal digits.
5870 // In other words, a hex color is written as a hash character, "#", followed by some number of digits 0-9 or
5871 // letters a-f (the case of the letters doesn’t matter - #00ff00 is identical to #00FF00).
5872 function hexColor(token) {
5873 if (token === null || token.type !== TYPE$5.Hash) {
5874 return 0;
5875 }
5876
5877 var length = token.value.length;
5878
5879 // valid values (length): #rgb (4), #rgba (5), #rrggbb (7), #rrggbbaa (9)
5880 if (length !== 4 && length !== 5 && length !== 7 && length !== 9) {
5881 return 0;
5882 }
5883
5884 for (var i = 1; i < length; i++) {
5885 if (!isHexDigit$3(token.value.charCodeAt(i))) {
5886 return 0;
5887 }
5888 }
5889
5890 return 1;
5891 }
5892
5893 function idSelector(token) {
5894 if (token === null || token.type !== TYPE$5.Hash) {
5895 return 0;
5896 }
5897
5898 if (!isIdentifierStart$2(charCode(token.value, 1), charCode(token.value, 2), charCode(token.value, 3))) {
5899 return 0;
5900 }
5901
5902 return 1;
5903 }
5904
5905 // https://drafts.csswg.org/css-syntax/#any-value
5906 // It represents the entirety of what a valid declaration can have as its value.
5907 function declarationValue(token, getNextToken) {
5908 if (!token) {
5909 return 0;
5910 }
5911
5912 var length = 0;
5913 var level = 0;
5914 var startIdx = token.index;
5915
5916 // The <declaration-value> production matches any sequence of one or more tokens,
5917 // so long as the sequence ...
5918 scan:
5919 do {
5920 switch (token.type) {
5921 // ... does not contain <bad-string-token>, <bad-url-token>,
5922 case TYPE$5.BadString:
5923 case TYPE$5.BadUrl:
5924 break scan;
5925
5926 // ... unmatched <)-token>, <]-token>, or <}-token>,
5927 case TYPE$5.RightCurlyBracket:
5928 case TYPE$5.RightParenthesis:
5929 case TYPE$5.RightSquareBracket:
5930 if (token.balance > token.index || token.balance < startIdx) {
5931 break scan;
5932 }
5933
5934 level--;
5935 break;
5936
5937 // ... or top-level <semicolon-token> tokens
5938 case TYPE$5.Semicolon:
5939 if (level === 0) {
5940 break scan;
5941 }
5942
5943 break;
5944
5945 // ... or <delim-token> tokens with a value of "!"
5946 case TYPE$5.Delim:
5947 if (token.value === '!' && level === 0) {
5948 break scan;
5949 }
5950
5951 break;
5952
5953 case TYPE$5.Function:
5954 case TYPE$5.LeftParenthesis:
5955 case TYPE$5.LeftSquareBracket:
5956 case TYPE$5.LeftCurlyBracket:
5957 level++;
5958 break;
5959 }
5960
5961 length++;
5962
5963 // until balance closing
5964 if (token.balance <= startIdx) {
5965 break;
5966 }
5967 } while (token = getNextToken(length));
5968
5969 return length;
5970 }
5971
5972 // https://drafts.csswg.org/css-syntax/#any-value
5973 // The <any-value> production is identical to <declaration-value>, but also
5974 // allows top-level <semicolon-token> tokens and <delim-token> tokens
5975 // with a value of "!". It represents the entirety of what valid CSS can be in any context.
5976 function anyValue(token, getNextToken) {
5977 if (!token) {
5978 return 0;
5979 }
5980
5981 var startIdx = token.index;
5982 var length = 0;
5983
5984 // The <any-value> production matches any sequence of one or more tokens,
5985 // so long as the sequence ...
5986 scan:
5987 do {
5988 switch (token.type) {
5989 // ... does not contain <bad-string-token>, <bad-url-token>,
5990 case TYPE$5.BadString:
5991 case TYPE$5.BadUrl:
5992 break scan;
5993
5994 // ... unmatched <)-token>, <]-token>, or <}-token>,
5995 case TYPE$5.RightCurlyBracket:
5996 case TYPE$5.RightParenthesis:
5997 case TYPE$5.RightSquareBracket:
5998 if (token.balance > token.index || token.balance < startIdx) {
5999 break scan;
6000 }
6001
6002 break;
6003 }
6004
6005 length++;
6006
6007 // until balance closing
6008 if (token.balance <= startIdx) {
6009 break;
6010 }
6011 } while (token = getNextToken(length));
6012
6013 return length;
6014 }
6015
6016 // =========================
6017 // Dimensions
6018 //
6019
6020 function dimension(type) {
6021 return function(token, getNextToken, opts) {
6022 if (token === null || token.type !== TYPE$5.Dimension) {
6023 return 0;
6024 }
6025
6026 var numberEnd = consumeNumber$2(token.value, 0);
6027
6028 // check unit
6029 if (type !== null) {
6030 // check for IE postfix hack, i.e. 123px\0 or 123px\9
6031 var reverseSolidusOffset = token.value.indexOf('\\', numberEnd);
6032 var unit = reverseSolidusOffset === -1 || !isPostfixIeHack(token.value, reverseSolidusOffset)
6033 ? token.value.substr(numberEnd)
6034 : token.value.substring(numberEnd, reverseSolidusOffset);
6035
6036 if (type.hasOwnProperty(unit.toLowerCase()) === false) {
6037 return 0;
6038 }
6039 }
6040
6041 // check range if specified
6042 if (outOfRange(opts, token.value, numberEnd)) {
6043 return 0;
6044 }
6045
6046 return 1;
6047 };
6048 }
6049
6050 // =========================
6051 // Percentage
6052 //
6053
6054 // §5.5. Percentages: the <percentage> type
6055 // https://drafts.csswg.org/css-values-4/#percentages
6056 function percentage(token, getNextToken, opts) {
6057 // ... corresponds to the <percentage-token> production
6058 if (token === null || token.type !== TYPE$5.Percentage) {
6059 return 0;
6060 }
6061
6062 // check range if specified
6063 if (outOfRange(opts, token.value, token.value.length - 1)) {
6064 return 0;
6065 }
6066
6067 return 1;
6068 }
6069
6070 // =========================
6071 // Numeric
6072 //
6073
6074 // https://drafts.csswg.org/css-values-4/#numbers
6075 // The value <zero> represents a literal number with the value 0. Expressions that merely
6076 // evaluate to a <number> with the value 0 (for example, calc(0)) do not match <zero>;
6077 // only literal <number-token>s do.
6078 function zero(next) {
6079 if (typeof next !== 'function') {
6080 next = function() {
6081 return 0;
6082 };
6083 }
6084
6085 return function(token, getNextToken, opts) {
6086 if (token !== null && token.type === TYPE$5.Number) {
6087 if (Number(token.value) === 0) {
6088 return 1;
6089 }
6090 }
6091
6092 return next(token, getNextToken, opts);
6093 };
6094 }
6095
6096 // § 5.3. Real Numbers: the <number> type
6097 // https://drafts.csswg.org/css-values-4/#numbers
6098 // Number values are denoted by <number>, and represent real numbers, possibly with a fractional component.
6099 // ... It corresponds to the <number-token> production
6100 function number(token, getNextToken, opts) {
6101 if (token === null) {
6102 return 0;
6103 }
6104
6105 var numberEnd = consumeNumber$2(token.value, 0);
6106 var isNumber = numberEnd === token.value.length;
6107 if (!isNumber && !isPostfixIeHack(token.value, numberEnd)) {
6108 return 0;
6109 }
6110
6111 // check range if specified
6112 if (outOfRange(opts, token.value, numberEnd)) {
6113 return 0;
6114 }
6115
6116 return 1;
6117 }
6118
6119 // §5.2. Integers: the <integer> type
6120 // https://drafts.csswg.org/css-values-4/#integers
6121 function integer(token, getNextToken, opts) {
6122 // ... corresponds to a subset of the <number-token> production
6123 if (token === null || token.type !== TYPE$5.Number) {
6124 return 0;
6125 }
6126
6127 // The first digit of an integer may be immediately preceded by `-` or `+` to indicate the integer’s sign.
6128 var i = token.value.charCodeAt(0) === 0x002B || // U+002B PLUS SIGN (+)
6129 token.value.charCodeAt(0) === 0x002D ? 1 : 0; // U+002D HYPHEN-MINUS (-)
6130
6131 // When written literally, an integer is one or more decimal digits 0 through 9 ...
6132 for (; i < token.value.length; i++) {
6133 if (!isDigit$3(token.value.charCodeAt(i))) {
6134 return 0;
6135 }
6136 }
6137
6138 // check range if specified
6139 if (outOfRange(opts, token.value, i)) {
6140 return 0;
6141 }
6142
6143 return 1;
6144 }
6145
6146 var generic = {
6147 // token types
6148 'ident-token': tokenType(TYPE$5.Ident),
6149 'function-token': tokenType(TYPE$5.Function),
6150 'at-keyword-token': tokenType(TYPE$5.AtKeyword),
6151 'hash-token': tokenType(TYPE$5.Hash),
6152 'string-token': tokenType(TYPE$5.String),
6153 'bad-string-token': tokenType(TYPE$5.BadString),
6154 'url-token': tokenType(TYPE$5.Url),
6155 'bad-url-token': tokenType(TYPE$5.BadUrl),
6156 'delim-token': tokenType(TYPE$5.Delim),
6157 'number-token': tokenType(TYPE$5.Number),
6158 'percentage-token': tokenType(TYPE$5.Percentage),
6159 'dimension-token': tokenType(TYPE$5.Dimension),
6160 'whitespace-token': tokenType(TYPE$5.WhiteSpace),
6161 'CDO-token': tokenType(TYPE$5.CDO),
6162 'CDC-token': tokenType(TYPE$5.CDC),
6163 'colon-token': tokenType(TYPE$5.Colon),
6164 'semicolon-token': tokenType(TYPE$5.Semicolon),
6165 'comma-token': tokenType(TYPE$5.Comma),
6166 '[-token': tokenType(TYPE$5.LeftSquareBracket),
6167 ']-token': tokenType(TYPE$5.RightSquareBracket),
6168 '(-token': tokenType(TYPE$5.LeftParenthesis),
6169 ')-token': tokenType(TYPE$5.RightParenthesis),
6170 '{-token': tokenType(TYPE$5.LeftCurlyBracket),
6171 '}-token': tokenType(TYPE$5.RightCurlyBracket),
6172
6173 // token type aliases
6174 'string': tokenType(TYPE$5.String),
6175 'ident': tokenType(TYPE$5.Ident),
6176
6177 // complex types
6178 'custom-ident': customIdent,
6179 'custom-property-name': customPropertyName,
6180 'hex-color': hexColor,
6181 'id-selector': idSelector, // element( <id-selector> )
6182 'an-plus-b': genericAnPlusB,
6183 'urange': genericUrange,
6184 'declaration-value': declarationValue,
6185 'any-value': anyValue,
6186
6187 // dimensions
6188 'dimension': calc(dimension(null)),
6189 'angle': calc(dimension(ANGLE)),
6190 'decibel': calc(dimension(DECIBEL)),
6191 'frequency': calc(dimension(FREQUENCY)),
6192 'flex': calc(dimension(FLEX)),
6193 'length': calc(zero(dimension(LENGTH))),
6194 'resolution': calc(dimension(RESOLUTION)),
6195 'semitones': calc(dimension(SEMITONES)),
6196 'time': calc(dimension(TIME)),
6197
6198 // percentage
6199 'percentage': calc(percentage),
6200
6201 // numeric
6202 'zero': zero(),
6203 'number': calc(number),
6204 'integer': calc(integer),
6205
6206 // old IE stuff
6207 '-ms-legacy-expression': func('expression')
6208 };
6209
6210 var _SyntaxError$1 = function SyntaxError(message, input, offset) {
6211 var error = createCustomError('SyntaxError', message);
6212
6213 error.input = input;
6214 error.offset = offset;
6215 error.rawMessage = message;
6216 error.message = error.rawMessage + '\n' +
6217 ' ' + error.input + '\n' +
6218 '--' + new Array((error.offset || error.input.length) + 1).join('-') + '^';
6219
6220 return error;
6221 };
6222
6223 var TAB = 9;
6224 var N$1 = 10;
6225 var F = 12;
6226 var R = 13;
6227 var SPACE = 32;
6228
6229 var Tokenizer = function(str) {
6230 this.str = str;
6231 this.pos = 0;
6232 };
6233
6234 Tokenizer.prototype = {
6235 charCodeAt: function(pos) {
6236 return pos < this.str.length ? this.str.charCodeAt(pos) : 0;
6237 },
6238 charCode: function() {
6239 return this.charCodeAt(this.pos);
6240 },
6241 nextCharCode: function() {
6242 return this.charCodeAt(this.pos + 1);
6243 },
6244 nextNonWsCode: function(pos) {
6245 return this.charCodeAt(this.findWsEnd(pos));
6246 },
6247 findWsEnd: function(pos) {
6248 for (; pos < this.str.length; pos++) {
6249 var code = this.str.charCodeAt(pos);
6250 if (code !== R && code !== N$1 && code !== F && code !== SPACE && code !== TAB) {
6251 break;
6252 }
6253 }
6254
6255 return pos;
6256 },
6257 substringToPos: function(end) {
6258 return this.str.substring(this.pos, this.pos = end);
6259 },
6260 eat: function(code) {
6261 if (this.charCode() !== code) {
6262 this.error('Expect `' + String.fromCharCode(code) + '`');
6263 }
6264
6265 this.pos++;
6266 },
6267 peek: function() {
6268 return this.pos < this.str.length ? this.str.charAt(this.pos++) : '';
6269 },
6270 error: function(message) {
6271 throw new _SyntaxError$1(message, this.str, this.pos);
6272 }
6273 };
6274
6275 var tokenizer$1 = Tokenizer;
6276
6277 var TAB$1 = 9;
6278 var N$2 = 10;
6279 var F$1 = 12;
6280 var R$1 = 13;
6281 var SPACE$1 = 32;
6282 var EXCLAMATIONMARK = 33; // !
6283 var NUMBERSIGN = 35; // #
6284 var AMPERSAND = 38; // &
6285 var APOSTROPHE = 39; // '
6286 var LEFTPARENTHESIS = 40; // (
6287 var RIGHTPARENTHESIS = 41; // )
6288 var ASTERISK = 42; // *
6289 var PLUSSIGN$2 = 43; // +
6290 var COMMA = 44; // ,
6291 var HYPERMINUS = 45; // -
6292 var LESSTHANSIGN = 60; // <
6293 var GREATERTHANSIGN = 62; // >
6294 var QUESTIONMARK$1 = 63; // ?
6295 var COMMERCIALAT = 64; // @
6296 var LEFTSQUAREBRACKET = 91; // [
6297 var RIGHTSQUAREBRACKET = 93; // ]
6298 var LEFTCURLYBRACKET = 123; // {
6299 var VERTICALLINE = 124; // |
6300 var RIGHTCURLYBRACKET = 125; // }
6301 var INFINITY = 8734; // ∞
6302 var NAME_CHAR = createCharMap(function(ch) {
6303 return /[a-zA-Z0-9\-]/.test(ch);
6304 });
6305 var COMBINATOR_PRECEDENCE = {
6306 ' ': 1,
6307 '&&': 2,
6308 '||': 3,
6309 '|': 4
6310 };
6311
6312 function createCharMap(fn) {
6313 var array = typeof Uint32Array === 'function' ? new Uint32Array(128) : new Array(128);
6314 for (var i = 0; i < 128; i++) {
6315 array[i] = fn(String.fromCharCode(i)) ? 1 : 0;
6316 }
6317 return array;
6318 }
6319
6320 function scanSpaces(tokenizer) {
6321 return tokenizer.substringToPos(
6322 tokenizer.findWsEnd(tokenizer.pos)
6323 );
6324 }
6325
6326 function scanWord(tokenizer) {
6327 var end = tokenizer.pos;
6328
6329 for (; end < tokenizer.str.length; end++) {
6330 var code = tokenizer.str.charCodeAt(end);
6331 if (code >= 128 || NAME_CHAR[code] === 0) {
6332 break;
6333 }
6334 }
6335
6336 if (tokenizer.pos === end) {
6337 tokenizer.error('Expect a keyword');
6338 }
6339
6340 return tokenizer.substringToPos(end);
6341 }
6342
6343 function scanNumber(tokenizer) {
6344 var end = tokenizer.pos;
6345
6346 for (; end < tokenizer.str.length; end++) {
6347 var code = tokenizer.str.charCodeAt(end);
6348 if (code < 48 || code > 57) {
6349 break;
6350 }
6351 }
6352
6353 if (tokenizer.pos === end) {
6354 tokenizer.error('Expect a number');
6355 }
6356
6357 return tokenizer.substringToPos(end);
6358 }
6359
6360 function scanString(tokenizer) {
6361 var end = tokenizer.str.indexOf('\'', tokenizer.pos + 1);
6362
6363 if (end === -1) {
6364 tokenizer.pos = tokenizer.str.length;
6365 tokenizer.error('Expect an apostrophe');
6366 }
6367
6368 return tokenizer.substringToPos(end + 1);
6369 }
6370
6371 function readMultiplierRange(tokenizer) {
6372 var min = null;
6373 var max = null;
6374
6375 tokenizer.eat(LEFTCURLYBRACKET);
6376
6377 min = scanNumber(tokenizer);
6378
6379 if (tokenizer.charCode() === COMMA) {
6380 tokenizer.pos++;
6381 if (tokenizer.charCode() !== RIGHTCURLYBRACKET) {
6382 max = scanNumber(tokenizer);
6383 }
6384 } else {
6385 max = min;
6386 }
6387
6388 tokenizer.eat(RIGHTCURLYBRACKET);
6389
6390 return {
6391 min: Number(min),
6392 max: max ? Number(max) : 0
6393 };
6394 }
6395
6396 function readMultiplier(tokenizer) {
6397 var range = null;
6398 var comma = false;
6399
6400 switch (tokenizer.charCode()) {
6401 case ASTERISK:
6402 tokenizer.pos++;
6403
6404 range = {
6405 min: 0,
6406 max: 0
6407 };
6408
6409 break;
6410
6411 case PLUSSIGN$2:
6412 tokenizer.pos++;
6413
6414 range = {
6415 min: 1,
6416 max: 0
6417 };
6418
6419 break;
6420
6421 case QUESTIONMARK$1:
6422 tokenizer.pos++;
6423
6424 range = {
6425 min: 0,
6426 max: 1
6427 };
6428
6429 break;
6430
6431 case NUMBERSIGN:
6432 tokenizer.pos++;
6433
6434 comma = true;
6435
6436 if (tokenizer.charCode() === LEFTCURLYBRACKET) {
6437 range = readMultiplierRange(tokenizer);
6438 } else {
6439 range = {
6440 min: 1,
6441 max: 0
6442 };
6443 }
6444
6445 break;
6446
6447 case LEFTCURLYBRACKET:
6448 range = readMultiplierRange(tokenizer);
6449 break;
6450
6451 default:
6452 return null;
6453 }
6454
6455 return {
6456 type: 'Multiplier',
6457 comma: comma,
6458 min: range.min,
6459 max: range.max,
6460 term: null
6461 };
6462 }
6463
6464 function maybeMultiplied(tokenizer, node) {
6465 var multiplier = readMultiplier(tokenizer);
6466
6467 if (multiplier !== null) {
6468 multiplier.term = node;
6469 return multiplier;
6470 }
6471
6472 return node;
6473 }
6474
6475 function maybeToken(tokenizer) {
6476 var ch = tokenizer.peek();
6477
6478 if (ch === '') {
6479 return null;
6480 }
6481
6482 return {
6483 type: 'Token',
6484 value: ch
6485 };
6486 }
6487
6488 function readProperty(tokenizer) {
6489 var name;
6490
6491 tokenizer.eat(LESSTHANSIGN);
6492 tokenizer.eat(APOSTROPHE);
6493
6494 name = scanWord(tokenizer);
6495
6496 tokenizer.eat(APOSTROPHE);
6497 tokenizer.eat(GREATERTHANSIGN);
6498
6499 return maybeMultiplied(tokenizer, {
6500 type: 'Property',
6501 name: name
6502 });
6503 }
6504
6505 // https://drafts.csswg.org/css-values-3/#numeric-ranges
6506 // 4.1. Range Restrictions and Range Definition Notation
6507 //
6508 // Range restrictions can be annotated in the numeric type notation using CSS bracketed
6509 // range notation—[min,max]—within the angle brackets, after the identifying keyword,
6510 // indicating a closed range between (and including) min and max.
6511 // For example, <integer [0, 10]> indicates an integer between 0 and 10, inclusive.
6512 function readTypeRange(tokenizer) {
6513 // use null for Infinity to make AST format JSON serializable/deserializable
6514 var min = null; // -Infinity
6515 var max = null; // Infinity
6516 var sign = 1;
6517
6518 tokenizer.eat(LEFTSQUAREBRACKET);
6519
6520 if (tokenizer.charCode() === HYPERMINUS) {
6521 tokenizer.peek();
6522 sign = -1;
6523 }
6524
6525 if (sign == -1 && tokenizer.charCode() === INFINITY) {
6526 tokenizer.peek();
6527 } else {
6528 min = sign * Number(scanNumber(tokenizer));
6529 }
6530
6531 scanSpaces(tokenizer);
6532 tokenizer.eat(COMMA);
6533 scanSpaces(tokenizer);
6534
6535 if (tokenizer.charCode() === INFINITY) {
6536 tokenizer.peek();
6537 } else {
6538 sign = 1;
6539
6540 if (tokenizer.charCode() === HYPERMINUS) {
6541 tokenizer.peek();
6542 sign = -1;
6543 }
6544
6545 max = sign * Number(scanNumber(tokenizer));
6546 }
6547
6548 tokenizer.eat(RIGHTSQUAREBRACKET);
6549
6550 // If no range is indicated, either by using the bracketed range notation
6551 // or in the property description, then [−∞,∞] is assumed.
6552 if (min === null && max === null) {
6553 return null;
6554 }
6555
6556 return {
6557 type: 'Range',
6558 min: min,
6559 max: max
6560 };
6561 }
6562
6563 function readType(tokenizer) {
6564 var name;
6565 var opts = null;
6566
6567 tokenizer.eat(LESSTHANSIGN);
6568 name = scanWord(tokenizer);
6569
6570 if (tokenizer.charCode() === LEFTPARENTHESIS &&
6571 tokenizer.nextCharCode() === RIGHTPARENTHESIS) {
6572 tokenizer.pos += 2;
6573 name += '()';
6574 }
6575
6576 if (tokenizer.charCodeAt(tokenizer.findWsEnd(tokenizer.pos)) === LEFTSQUAREBRACKET) {
6577 scanSpaces(tokenizer);
6578 opts = readTypeRange(tokenizer);
6579 }
6580
6581 tokenizer.eat(GREATERTHANSIGN);
6582
6583 return maybeMultiplied(tokenizer, {
6584 type: 'Type',
6585 name: name,
6586 opts: opts
6587 });
6588 }
6589
6590 function readKeywordOrFunction(tokenizer) {
6591 var name;
6592
6593 name = scanWord(tokenizer);
6594
6595 if (tokenizer.charCode() === LEFTPARENTHESIS) {
6596 tokenizer.pos++;
6597
6598 return {
6599 type: 'Function',
6600 name: name
6601 };
6602 }
6603
6604 return maybeMultiplied(tokenizer, {
6605 type: 'Keyword',
6606 name: name
6607 });
6608 }
6609
6610 function regroupTerms(terms, combinators) {
6611 function createGroup(terms, combinator) {
6612 return {
6613 type: 'Group',
6614 terms: terms,
6615 combinator: combinator,
6616 disallowEmpty: false,
6617 explicit: false
6618 };
6619 }
6620
6621 combinators = Object.keys(combinators).sort(function(a, b) {
6622 return COMBINATOR_PRECEDENCE[a] - COMBINATOR_PRECEDENCE[b];
6623 });
6624
6625 while (combinators.length > 0) {
6626 var combinator = combinators.shift();
6627 for (var i = 0, subgroupStart = 0; i < terms.length; i++) {
6628 var term = terms[i];
6629 if (term.type === 'Combinator') {
6630 if (term.value === combinator) {
6631 if (subgroupStart === -1) {
6632 subgroupStart = i - 1;
6633 }
6634 terms.splice(i, 1);
6635 i--;
6636 } else {
6637 if (subgroupStart !== -1 && i - subgroupStart > 1) {
6638 terms.splice(
6639 subgroupStart,
6640 i - subgroupStart,
6641 createGroup(terms.slice(subgroupStart, i), combinator)
6642 );
6643 i = subgroupStart + 1;
6644 }
6645 subgroupStart = -1;
6646 }
6647 }
6648 }
6649
6650 if (subgroupStart !== -1 && combinators.length) {
6651 terms.splice(
6652 subgroupStart,
6653 i - subgroupStart,
6654 createGroup(terms.slice(subgroupStart, i), combinator)
6655 );
6656 }
6657 }
6658
6659 return combinator;
6660 }
6661
6662 function readImplicitGroup(tokenizer) {
6663 var terms = [];
6664 var combinators = {};
6665 var token;
6666 var prevToken = null;
6667 var prevTokenPos = tokenizer.pos;
6668
6669 while (token = peek(tokenizer)) {
6670 if (token.type !== 'Spaces') {
6671 if (token.type === 'Combinator') {
6672 // check for combinator in group beginning and double combinator sequence
6673 if (prevToken === null || prevToken.type === 'Combinator') {
6674 tokenizer.pos = prevTokenPos;
6675 tokenizer.error('Unexpected combinator');
6676 }
6677
6678 combinators[token.value] = true;
6679 } else if (prevToken !== null && prevToken.type !== 'Combinator') {
6680 combinators[' '] = true; // a b
6681 terms.push({
6682 type: 'Combinator',
6683 value: ' '
6684 });
6685 }
6686
6687 terms.push(token);
6688 prevToken = token;
6689 prevTokenPos = tokenizer.pos;
6690 }
6691 }
6692
6693 // check for combinator in group ending
6694 if (prevToken !== null && prevToken.type === 'Combinator') {
6695 tokenizer.pos -= prevTokenPos;
6696 tokenizer.error('Unexpected combinator');
6697 }
6698
6699 return {
6700 type: 'Group',
6701 terms: terms,
6702 combinator: regroupTerms(terms, combinators) || ' ',
6703 disallowEmpty: false,
6704 explicit: false
6705 };
6706 }
6707
6708 function readGroup(tokenizer) {
6709 var result;
6710
6711 tokenizer.eat(LEFTSQUAREBRACKET);
6712 result = readImplicitGroup(tokenizer);
6713 tokenizer.eat(RIGHTSQUAREBRACKET);
6714
6715 result.explicit = true;
6716
6717 if (tokenizer.charCode() === EXCLAMATIONMARK) {
6718 tokenizer.pos++;
6719 result.disallowEmpty = true;
6720 }
6721
6722 return result;
6723 }
6724
6725 function peek(tokenizer) {
6726 var code = tokenizer.charCode();
6727
6728 if (code < 128 && NAME_CHAR[code] === 1) {
6729 return readKeywordOrFunction(tokenizer);
6730 }
6731
6732 switch (code) {
6733 case RIGHTSQUAREBRACKET:
6734 // don't eat, stop scan a group
6735 break;
6736
6737 case LEFTSQUAREBRACKET:
6738 return maybeMultiplied(tokenizer, readGroup(tokenizer));
6739
6740 case LESSTHANSIGN:
6741 return tokenizer.nextCharCode() === APOSTROPHE
6742 ? readProperty(tokenizer)
6743 : readType(tokenizer);
6744
6745 case VERTICALLINE:
6746 return {
6747 type: 'Combinator',
6748 value: tokenizer.substringToPos(
6749 tokenizer.nextCharCode() === VERTICALLINE
6750 ? tokenizer.pos + 2
6751 : tokenizer.pos + 1
6752 )
6753 };
6754
6755 case AMPERSAND:
6756 tokenizer.pos++;
6757 tokenizer.eat(AMPERSAND);
6758
6759 return {
6760 type: 'Combinator',
6761 value: '&&'
6762 };
6763
6764 case COMMA:
6765 tokenizer.pos++;
6766 return {
6767 type: 'Comma'
6768 };
6769
6770 case APOSTROPHE:
6771 return maybeMultiplied(tokenizer, {
6772 type: 'String',
6773 value: scanString(tokenizer)
6774 });
6775
6776 case SPACE$1:
6777 case TAB$1:
6778 case N$2:
6779 case R$1:
6780 case F$1:
6781 return {
6782 type: 'Spaces',
6783 value: scanSpaces(tokenizer)
6784 };
6785
6786 case COMMERCIALAT:
6787 code = tokenizer.nextCharCode();
6788
6789 if (code < 128 && NAME_CHAR[code] === 1) {
6790 tokenizer.pos++;
6791 return {
6792 type: 'AtKeyword',
6793 name: scanWord(tokenizer)
6794 };
6795 }
6796
6797 return maybeToken(tokenizer);
6798
6799 case ASTERISK:
6800 case PLUSSIGN$2:
6801 case QUESTIONMARK$1:
6802 case NUMBERSIGN:
6803 case EXCLAMATIONMARK:
6804 // prohibited tokens (used as a multiplier start)
6805 break;
6806
6807 case LEFTCURLYBRACKET:
6808 // LEFTCURLYBRACKET is allowed since mdn/data uses it w/o quoting
6809 // check next char isn't a number, because it's likely a disjoined multiplier
6810 code = tokenizer.nextCharCode();
6811
6812 if (code < 48 || code > 57) {
6813 return maybeToken(tokenizer);
6814 }
6815
6816 break;
6817
6818 default:
6819 return maybeToken(tokenizer);
6820 }
6821 }
6822
6823 function parse(source) {
6824 var tokenizer = new tokenizer$1(source);
6825 var result = readImplicitGroup(tokenizer);
6826
6827 if (tokenizer.pos !== source.length) {
6828 tokenizer.error('Unexpected input');
6829 }
6830
6831 // reduce redundant groups with single group term
6832 if (result.terms.length === 1 && result.terms[0].type === 'Group') {
6833 result = result.terms[0];
6834 }
6835
6836 return result;
6837 }
6838
6839 // warm up parse to elimitate code branches that never execute
6840 // fix soft deoptimizations (insufficient type feedback)
6841 parse('[a&&<b>#|<\'c\'>*||e() f{2} /,(% g#{1,2} h{2,})]!');
6842
6843 var parse_1 = parse;
6844
6845 var noop$2 = function() {};
6846
6847 function ensureFunction(value) {
6848 return typeof value === 'function' ? value : noop$2;
6849 }
6850
6851 var walk$1 = function(node, options, context) {
6852 function walk(node) {
6853 enter.call(context, node);
6854
6855 switch (node.type) {
6856 case 'Group':
6857 node.terms.forEach(walk);
6858 break;
6859
6860 case 'Multiplier':
6861 walk(node.term);
6862 break;
6863
6864 case 'Type':
6865 case 'Property':
6866 case 'Keyword':
6867 case 'AtKeyword':
6868 case 'Function':
6869 case 'String':
6870 case 'Token':
6871 case 'Comma':
6872 break;
6873
6874 default:
6875 throw new Error('Unknown type: ' + node.type);
6876 }
6877
6878 leave.call(context, node);
6879 }
6880
6881 var enter = noop$2;
6882 var leave = noop$2;
6883
6884 if (typeof options === 'function') {
6885 enter = options;
6886 } else if (options) {
6887 enter = ensureFunction(options.enter);
6888 leave = ensureFunction(options.leave);
6889 }
6890
6891 if (enter === noop$2 && leave === noop$2) {
6892 throw new Error('Neither `enter` nor `leave` walker handler is set or both aren\'t a function');
6893 }
6894
6895 walk(node);
6896 };
6897
6898 var tokenStream = new TokenStream_1();
6899 var astToTokens = {
6900 decorator: function(handlers) {
6901 var curNode = null;
6902 var prev = { len: 0, node: null };
6903 var nodes = [prev];
6904 var buffer = '';
6905
6906 return {
6907 children: handlers.children,
6908 node: function(node) {
6909 var tmp = curNode;
6910 curNode = node;
6911 handlers.node.call(this, node);
6912 curNode = tmp;
6913 },
6914 chunk: function(chunk) {
6915 buffer += chunk;
6916 if (prev.node !== curNode) {
6917 nodes.push({
6918 len: chunk.length,
6919 node: curNode
6920 });
6921 } else {
6922 prev.len += chunk.length;
6923 }
6924 },
6925 result: function() {
6926 return prepareTokens(buffer, nodes);
6927 }
6928 };
6929 }
6930 };
6931
6932 function prepareTokens(str, nodes) {
6933 var tokens = [];
6934 var nodesOffset = 0;
6935 var nodesIndex = 0;
6936 var currentNode = nodes ? nodes[nodesIndex].node : null;
6937
6938 tokenizer(str, tokenStream);
6939
6940 while (!tokenStream.eof) {
6941 if (nodes) {
6942 while (nodesIndex < nodes.length && nodesOffset + nodes[nodesIndex].len <= tokenStream.tokenStart) {
6943 nodesOffset += nodes[nodesIndex++].len;
6944 currentNode = nodes[nodesIndex].node;
6945 }
6946 }
6947
6948 tokens.push({
6949 type: tokenStream.tokenType,
6950 value: tokenStream.getTokenValue(),
6951 index: tokenStream.tokenIndex, // TODO: remove it, temporary solution
6952 balance: tokenStream.balance[tokenStream.tokenIndex], // TODO: remove it, temporary solution
6953 node: currentNode
6954 });
6955 tokenStream.next();
6956 // console.log({ ...tokens[tokens.length - 1], node: undefined });
6957 }
6958
6959 return tokens;
6960 }
6961
6962 var prepareTokens_1 = function(value, syntax) {
6963 if (typeof value === 'string') {
6964 return prepareTokens(value, null);
6965 }
6966
6967 return syntax.generate(value, astToTokens);
6968 };
6969
6970 var MATCH = { type: 'Match' };
6971 var MISMATCH = { type: 'Mismatch' };
6972 var DISALLOW_EMPTY = { type: 'DisallowEmpty' };
6973 var LEFTPARENTHESIS$1 = 40; // (
6974 var RIGHTPARENTHESIS$1 = 41; // )
6975
6976 function createCondition(match, thenBranch, elseBranch) {
6977 // reduce node count
6978 if (thenBranch === MATCH && elseBranch === MISMATCH) {
6979 return match;
6980 }
6981
6982 if (match === MATCH && thenBranch === MATCH && elseBranch === MATCH) {
6983 return match;
6984 }
6985
6986 if (match.type === 'If' && match.else === MISMATCH && thenBranch === MATCH) {
6987 thenBranch = match.then;
6988 match = match.match;
6989 }
6990
6991 return {
6992 type: 'If',
6993 match: match,
6994 then: thenBranch,
6995 else: elseBranch
6996 };
6997 }
6998
6999 function isFunctionType(name) {
7000 return (
7001 name.length > 2 &&
7002 name.charCodeAt(name.length - 2) === LEFTPARENTHESIS$1 &&
7003 name.charCodeAt(name.length - 1) === RIGHTPARENTHESIS$1
7004 );
7005 }
7006
7007 function isEnumCapatible(term) {
7008 return (
7009 term.type === 'Keyword' ||
7010 term.type === 'AtKeyword' ||
7011 term.type === 'Function' ||
7012 term.type === 'Type' && isFunctionType(term.name)
7013 );
7014 }
7015
7016 function buildGroupMatchGraph(combinator, terms, atLeastOneTermMatched) {
7017 switch (combinator) {
7018 case ' ':
7019 // Juxtaposing components means that all of them must occur, in the given order.
7020 //
7021 // a b c
7022 // =
7023 // match a
7024 // then match b
7025 // then match c
7026 // then MATCH
7027 // else MISMATCH
7028 // else MISMATCH
7029 // else MISMATCH
7030 var result = MATCH;
7031
7032 for (var i = terms.length - 1; i >= 0; i--) {
7033 var term = terms[i];
7034
7035 result = createCondition(
7036 term,
7037 result,
7038 MISMATCH
7039 );
7040 }
7041 return result;
7042
7043 case '|':
7044 // A bar (|) separates two or more alternatives: exactly one of them must occur.
7045 //
7046 // a | b | c
7047 // =
7048 // match a
7049 // then MATCH
7050 // else match b
7051 // then MATCH
7052 // else match c
7053 // then MATCH
7054 // else MISMATCH
7055
7056 var result = MISMATCH;
7057 var map = null;
7058
7059 for (var i = terms.length - 1; i >= 0; i--) {
7060 var term = terms[i];
7061
7062 // reduce sequence of keywords into a Enum
7063 if (isEnumCapatible(term)) {
7064 if (map === null && i > 0 && isEnumCapatible(terms[i - 1])) {
7065 map = Object.create(null);
7066 result = createCondition(
7067 {
7068 type: 'Enum',
7069 map: map
7070 },
7071 MATCH,
7072 result
7073 );
7074 }
7075
7076 if (map !== null) {
7077 var key = (isFunctionType(term.name) ? term.name.slice(0, -1) : term.name).toLowerCase();
7078 if (key in map === false) {
7079 map[key] = term;
7080 continue;
7081 }
7082 }
7083 }
7084
7085 map = null;
7086
7087 // create a new conditonal node
7088 result = createCondition(
7089 term,
7090 MATCH,
7091 result
7092 );
7093 }
7094 return result;
7095
7096 case '&&':
7097 // A double ampersand (&&) separates two or more components,
7098 // all of which must occur, in any order.
7099
7100 // Use MatchOnce for groups with a large number of terms,
7101 // since &&-groups produces at least N!-node trees
7102 if (terms.length > 5) {
7103 return {
7104 type: 'MatchOnce',
7105 terms: terms,
7106 all: true
7107 };
7108 }
7109
7110 // Use a combination tree for groups with small number of terms
7111 //
7112 // a && b && c
7113 // =
7114 // match a
7115 // then [b && c]
7116 // else match b
7117 // then [a && c]
7118 // else match c
7119 // then [a && b]
7120 // else MISMATCH
7121 //
7122 // a && b
7123 // =
7124 // match a
7125 // then match b
7126 // then MATCH
7127 // else MISMATCH
7128 // else match b
7129 // then match a
7130 // then MATCH
7131 // else MISMATCH
7132 // else MISMATCH
7133 var result = MISMATCH;
7134
7135 for (var i = terms.length - 1; i >= 0; i--) {
7136 var term = terms[i];
7137 var thenClause;
7138
7139 if (terms.length > 1) {
7140 thenClause = buildGroupMatchGraph(
7141 combinator,
7142 terms.filter(function(newGroupTerm) {
7143 return newGroupTerm !== term;
7144 }),
7145 false
7146 );
7147 } else {
7148 thenClause = MATCH;
7149 }
7150
7151 result = createCondition(
7152 term,
7153 thenClause,
7154 result
7155 );
7156 }
7157 return result;
7158
7159 case '||':
7160 // A double bar (||) separates two or more options:
7161 // one or more of them must occur, in any order.
7162
7163 // Use MatchOnce for groups with a large number of terms,
7164 // since ||-groups produces at least N!-node trees
7165 if (terms.length > 5) {
7166 return {
7167 type: 'MatchOnce',
7168 terms: terms,
7169 all: false
7170 };
7171 }
7172
7173 // Use a combination tree for groups with small number of terms
7174 //
7175 // a || b || c
7176 // =
7177 // match a
7178 // then [b || c]
7179 // else match b
7180 // then [a || c]
7181 // else match c
7182 // then [a || b]
7183 // else MISMATCH
7184 //
7185 // a || b
7186 // =
7187 // match a
7188 // then match b
7189 // then MATCH
7190 // else MATCH
7191 // else match b
7192 // then match a
7193 // then MATCH
7194 // else MATCH
7195 // else MISMATCH
7196 var result = atLeastOneTermMatched ? MATCH : MISMATCH;
7197
7198 for (var i = terms.length - 1; i >= 0; i--) {
7199 var term = terms[i];
7200 var thenClause;
7201
7202 if (terms.length > 1) {
7203 thenClause = buildGroupMatchGraph(
7204 combinator,
7205 terms.filter(function(newGroupTerm) {
7206 return newGroupTerm !== term;
7207 }),
7208 true
7209 );
7210 } else {
7211 thenClause = MATCH;
7212 }
7213
7214 result = createCondition(
7215 term,
7216 thenClause,
7217 result
7218 );
7219 }
7220 return result;
7221 }
7222 }
7223
7224 function buildMultiplierMatchGraph(node) {
7225 var result = MATCH;
7226 var matchTerm = buildMatchGraph(node.term);
7227
7228 if (node.max === 0) {
7229 // disable repeating of empty match to prevent infinite loop
7230 matchTerm = createCondition(
7231 matchTerm,
7232 DISALLOW_EMPTY,
7233 MISMATCH
7234 );
7235
7236 // an occurrence count is not limited, make a cycle;
7237 // to collect more terms on each following matching mismatch
7238 result = createCondition(
7239 matchTerm,
7240 null, // will be a loop
7241 MISMATCH
7242 );
7243
7244 result.then = createCondition(
7245 MATCH,
7246 MATCH,
7247 result // make a loop
7248 );
7249
7250 if (node.comma) {
7251 result.then.else = createCondition(
7252 { type: 'Comma', syntax: node },
7253 result,
7254 MISMATCH
7255 );
7256 }
7257 } else {
7258 // create a match node chain for [min .. max] interval with optional matches
7259 for (var i = node.min || 1; i <= node.max; i++) {
7260 if (node.comma && result !== MATCH) {
7261 result = createCondition(
7262 { type: 'Comma', syntax: node },
7263 result,
7264 MISMATCH
7265 );
7266 }
7267
7268 result = createCondition(
7269 matchTerm,
7270 createCondition(
7271 MATCH,
7272 MATCH,
7273 result
7274 ),
7275 MISMATCH
7276 );
7277 }
7278 }
7279
7280 if (node.min === 0) {
7281 // allow zero match
7282 result = createCondition(
7283 MATCH,
7284 MATCH,
7285 result
7286 );
7287 } else {
7288 // create a match node chain to collect [0 ... min - 1] required matches
7289 for (var i = 0; i < node.min - 1; i++) {
7290 if (node.comma && result !== MATCH) {
7291 result = createCondition(
7292 { type: 'Comma', syntax: node },
7293 result,
7294 MISMATCH
7295 );
7296 }
7297
7298 result = createCondition(
7299 matchTerm,
7300 result,
7301 MISMATCH
7302 );
7303 }
7304 }
7305
7306 return result;
7307 }
7308
7309 function buildMatchGraph(node) {
7310 if (typeof node === 'function') {
7311 return {
7312 type: 'Generic',
7313 fn: node
7314 };
7315 }
7316
7317 switch (node.type) {
7318 case 'Group':
7319 var result = buildGroupMatchGraph(
7320 node.combinator,
7321 node.terms.map(buildMatchGraph),
7322 false
7323 );
7324
7325 if (node.disallowEmpty) {
7326 result = createCondition(
7327 result,
7328 DISALLOW_EMPTY,
7329 MISMATCH
7330 );
7331 }
7332
7333 return result;
7334
7335 case 'Multiplier':
7336 return buildMultiplierMatchGraph(node);
7337
7338 case 'Type':
7339 case 'Property':
7340 return {
7341 type: node.type,
7342 name: node.name,
7343 syntax: node
7344 };
7345
7346 case 'Keyword':
7347 return {
7348 type: node.type,
7349 name: node.name.toLowerCase(),
7350 syntax: node
7351 };
7352
7353 case 'AtKeyword':
7354 return {
7355 type: node.type,
7356 name: '@' + node.name.toLowerCase(),
7357 syntax: node
7358 };
7359
7360 case 'Function':
7361 return {
7362 type: node.type,
7363 name: node.name.toLowerCase() + '(',
7364 syntax: node
7365 };
7366
7367 case 'String':
7368 // convert a one char length String to a Token
7369 if (node.value.length === 3) {
7370 return {
7371 type: 'Token',
7372 value: node.value.charAt(1),
7373 syntax: node
7374 };
7375 }
7376
7377 // otherwise use it as is
7378 return {
7379 type: node.type,
7380 value: node.value.substr(1, node.value.length - 2).replace(/\\'/g, '\''),
7381 syntax: node
7382 };
7383
7384 case 'Token':
7385 return {
7386 type: node.type,
7387 value: node.value,
7388 syntax: node
7389 };
7390
7391 case 'Comma':
7392 return {
7393 type: node.type,
7394 syntax: node
7395 };
7396
7397 default:
7398 throw new Error('Unknown node type:', node.type);
7399 }
7400 }
7401
7402 var matchGraph = {
7403 MATCH: MATCH,
7404 MISMATCH: MISMATCH,
7405 DISALLOW_EMPTY: DISALLOW_EMPTY,
7406 buildMatchGraph: function(syntaxTree, ref) {
7407 if (typeof syntaxTree === 'string') {
7408 syntaxTree = parse_1(syntaxTree);
7409 }
7410
7411 return {
7412 type: 'MatchGraph',
7413 match: buildMatchGraph(syntaxTree),
7414 syntax: ref || null,
7415 source: syntaxTree
7416 };
7417 }
7418 };
7419
7420 var hasOwnProperty$1 = Object.prototype.hasOwnProperty;
7421
7422 var MATCH$1 = matchGraph.MATCH;
7423 var MISMATCH$1 = matchGraph.MISMATCH;
7424 var DISALLOW_EMPTY$1 = matchGraph.DISALLOW_EMPTY;
7425 var TYPE$6 = _const.TYPE;
7426
7427 var STUB = 0;
7428 var TOKEN = 1;
7429 var OPEN_SYNTAX = 2;
7430 var CLOSE_SYNTAX = 3;
7431
7432 var EXIT_REASON_MATCH = 'Match';
7433 var EXIT_REASON_MISMATCH = 'Mismatch';
7434 var EXIT_REASON_ITERATION_LIMIT = 'Maximum iteration number exceeded (please fill an issue on https://github.com/csstree/csstree/issues)';
7435
7436 var ITERATION_LIMIT = 15000;
7437 var totalIterationCount = 0;
7438
7439 function reverseList(list) {
7440 var prev = null;
7441 var next = null;
7442 var item = list;
7443
7444 while (item !== null) {
7445 next = item.prev;
7446 item.prev = prev;
7447 prev = item;
7448 item = next;
7449 }
7450
7451 return prev;
7452 }
7453
7454 function areStringsEqualCaseInsensitive(testStr, referenceStr) {
7455 if (testStr.length !== referenceStr.length) {
7456 return false;
7457 }
7458
7459 for (var i = 0; i < testStr.length; i++) {
7460 var testCode = testStr.charCodeAt(i);
7461 var referenceCode = referenceStr.charCodeAt(i);
7462
7463 // testCode.toLowerCase() for U+0041 LATIN CAPITAL LETTER A (A) .. U+005A LATIN CAPITAL LETTER Z (Z).
7464 if (testCode >= 0x0041 && testCode <= 0x005A) {
7465 testCode = testCode | 32;
7466 }
7467
7468 if (testCode !== referenceCode) {
7469 return false;
7470 }
7471 }
7472
7473 return true;
7474 }
7475
7476 function isCommaContextStart(token) {
7477 if (token === null) {
7478 return true;
7479 }
7480
7481 return (
7482 token.type === TYPE$6.Comma ||
7483 token.type === TYPE$6.Function ||
7484 token.type === TYPE$6.LeftParenthesis ||
7485 token.type === TYPE$6.LeftSquareBracket ||
7486 token.type === TYPE$6.LeftCurlyBracket ||
7487 token.type === TYPE$6.Delim
7488 );
7489 }
7490
7491 function isCommaContextEnd(token) {
7492 if (token === null) {
7493 return true;
7494 }
7495
7496 return (
7497 token.type === TYPE$6.RightParenthesis ||
7498 token.type === TYPE$6.RightSquareBracket ||
7499 token.type === TYPE$6.RightCurlyBracket ||
7500 token.type === TYPE$6.Delim
7501 );
7502 }
7503
7504 function internalMatch(tokens, state, syntaxes) {
7505 function moveToNextToken() {
7506 do {
7507 tokenIndex++;
7508 token = tokenIndex < tokens.length ? tokens[tokenIndex] : null;
7509 } while (token !== null && (token.type === TYPE$6.WhiteSpace || token.type === TYPE$6.Comment));
7510 }
7511
7512 function getNextToken(offset) {
7513 var nextIndex = tokenIndex + offset;
7514
7515 return nextIndex < tokens.length ? tokens[nextIndex] : null;
7516 }
7517
7518 function stateSnapshotFromSyntax(nextState, prev) {
7519 return {
7520 nextState: nextState,
7521 matchStack: matchStack,
7522 syntaxStack: syntaxStack,
7523 thenStack: thenStack,
7524 tokenIndex: tokenIndex,
7525 prev: prev
7526 };
7527 }
7528
7529 function pushThenStack(nextState) {
7530 thenStack = {
7531 nextState: nextState,
7532 matchStack: matchStack,
7533 syntaxStack: syntaxStack,
7534 prev: thenStack
7535 };
7536 }
7537
7538 function pushElseStack(nextState) {
7539 elseStack = stateSnapshotFromSyntax(nextState, elseStack);
7540 }
7541
7542 function addTokenToMatch() {
7543 matchStack = {
7544 type: TOKEN,
7545 syntax: state.syntax,
7546 token: token,
7547 prev: matchStack
7548 };
7549
7550 moveToNextToken();
7551 syntaxStash = null;
7552
7553 if (tokenIndex > longestMatch) {
7554 longestMatch = tokenIndex;
7555 }
7556 }
7557
7558 function openSyntax() {
7559 syntaxStack = {
7560 syntax: state.syntax,
7561 opts: state.syntax.opts || (syntaxStack !== null && syntaxStack.opts) || null,
7562 prev: syntaxStack
7563 };
7564
7565 matchStack = {
7566 type: OPEN_SYNTAX,
7567 syntax: state.syntax,
7568 token: matchStack.token,
7569 prev: matchStack
7570 };
7571 }
7572
7573 function closeSyntax() {
7574 if (matchStack.type === OPEN_SYNTAX) {
7575 matchStack = matchStack.prev;
7576 } else {
7577 matchStack = {
7578 type: CLOSE_SYNTAX,
7579 syntax: syntaxStack.syntax,
7580 token: matchStack.token,
7581 prev: matchStack
7582 };
7583 }
7584
7585 syntaxStack = syntaxStack.prev;
7586 }
7587
7588 var syntaxStack = null;
7589 var thenStack = null;
7590 var elseStack = null;
7591
7592 // null – stashing allowed, nothing stashed
7593 // false – stashing disabled, nothing stashed
7594 // anithing else – fail stashable syntaxes, some syntax stashed
7595 var syntaxStash = null;
7596
7597 var iterationCount = 0; // count iterations and prevent infinite loop
7598 var exitReason = null;
7599
7600 var token = null;
7601 var tokenIndex = -1;
7602 var longestMatch = 0;
7603 var matchStack = {
7604 type: STUB,
7605 syntax: null,
7606 token: null,
7607 prev: null
7608 };
7609
7610 moveToNextToken();
7611
7612 while (exitReason === null && ++iterationCount < ITERATION_LIMIT) {
7613 // function mapList(list, fn) {
7614 // var result = [];
7615 // while (list) {
7616 // result.unshift(fn(list));
7617 // list = list.prev;
7618 // }
7619 // return result;
7620 // }
7621 // console.log('--\n',
7622 // '#' + iterationCount,
7623 // require('util').inspect({
7624 // 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),
7625 // token: token && token.value,
7626 // tokenIndex,
7627 // syntax: syntax.type + (syntax.id ? ' #' + syntax.id : '')
7628 // }, { depth: null })
7629 // );
7630 switch (state.type) {
7631 case 'Match':
7632 if (thenStack === null) {
7633 // turn to MISMATCH when some tokens left unmatched
7634 if (token !== null) {
7635 // doesn't mismatch if just one token left and it's an IE hack
7636 if (tokenIndex !== tokens.length - 1 || (token.value !== '\\0' && token.value !== '\\9')) {
7637 state = MISMATCH$1;
7638 break;
7639 }
7640 }
7641
7642 // break the main loop, return a result - MATCH
7643 exitReason = EXIT_REASON_MATCH;
7644 break;
7645 }
7646
7647 // go to next syntax (`then` branch)
7648 state = thenStack.nextState;
7649
7650 // check match is not empty
7651 if (state === DISALLOW_EMPTY$1) {
7652 if (thenStack.matchStack === matchStack) {
7653 state = MISMATCH$1;
7654 break;
7655 } else {
7656 state = MATCH$1;
7657 }
7658 }
7659
7660 // close syntax if needed
7661 while (thenStack.syntaxStack !== syntaxStack) {
7662 closeSyntax();
7663 }
7664
7665 // pop stack
7666 thenStack = thenStack.prev;
7667 break;
7668
7669 case 'Mismatch':
7670 // when some syntax is stashed
7671 if (syntaxStash !== null && syntaxStash !== false) {
7672 // there is no else branches or a branch reduce match stack
7673 if (elseStack === null || tokenIndex > elseStack.tokenIndex) {
7674 // restore state from the stash
7675 elseStack = syntaxStash;
7676 syntaxStash = false; // disable stashing
7677 }
7678 } else if (elseStack === null) {
7679 // no else branches -> break the main loop
7680 // return a result - MISMATCH
7681 exitReason = EXIT_REASON_MISMATCH;
7682 break;
7683 }
7684
7685 // go to next syntax (`else` branch)
7686 state = elseStack.nextState;
7687
7688 // restore all the rest stack states
7689 thenStack = elseStack.thenStack;
7690 syntaxStack = elseStack.syntaxStack;
7691 matchStack = elseStack.matchStack;
7692 tokenIndex = elseStack.tokenIndex;
7693 token = tokenIndex < tokens.length ? tokens[tokenIndex] : null;
7694
7695 // pop stack
7696 elseStack = elseStack.prev;
7697 break;
7698
7699 case 'MatchGraph':
7700 state = state.match;
7701 break;
7702
7703 case 'If':
7704 // IMPORTANT: else stack push must go first,
7705 // since it stores the state of thenStack before changes
7706 if (state.else !== MISMATCH$1) {
7707 pushElseStack(state.else);
7708 }
7709
7710 if (state.then !== MATCH$1) {
7711 pushThenStack(state.then);
7712 }
7713
7714 state = state.match;
7715 break;
7716
7717 case 'MatchOnce':
7718 state = {
7719 type: 'MatchOnceBuffer',
7720 syntax: state,
7721 index: 0,
7722 mask: 0
7723 };
7724 break;
7725
7726 case 'MatchOnceBuffer':
7727 var terms = state.syntax.terms;
7728
7729 if (state.index === terms.length) {
7730 // no matches at all or it's required all terms to be matched
7731 if (state.mask === 0 || state.syntax.all) {
7732 state = MISMATCH$1;
7733 break;
7734 }
7735
7736 // a partial match is ok
7737 state = MATCH$1;
7738 break;
7739 }
7740
7741 // all terms are matched
7742 if (state.mask === (1 << terms.length) - 1) {
7743 state = MATCH$1;
7744 break;
7745 }
7746
7747 for (; state.index < terms.length; state.index++) {
7748 var matchFlag = 1 << state.index;
7749
7750 if ((state.mask & matchFlag) === 0) {
7751 // IMPORTANT: else stack push must go first,
7752 // since it stores the state of thenStack before changes
7753 pushElseStack(state);
7754 pushThenStack({
7755 type: 'AddMatchOnce',
7756 syntax: state.syntax,
7757 mask: state.mask | matchFlag
7758 });
7759
7760 // match
7761 state = terms[state.index++];
7762 break;
7763 }
7764 }
7765 break;
7766
7767 case 'AddMatchOnce':
7768 state = {
7769 type: 'MatchOnceBuffer',
7770 syntax: state.syntax,
7771 index: 0,
7772 mask: state.mask
7773 };
7774 break;
7775
7776 case 'Enum':
7777 if (token !== null) {
7778 var name = token.value.toLowerCase();
7779
7780 // drop \0 and \9 hack from keyword name
7781 if (name.indexOf('\\') !== -1) {
7782 name = name.replace(/\\[09].*$/, '');
7783 }
7784
7785 if (hasOwnProperty$1.call(state.map, name)) {
7786 state = state.map[name];
7787 break;
7788 }
7789 }
7790
7791 state = MISMATCH$1;
7792 break;
7793
7794 case 'Generic':
7795 var opts = syntaxStack !== null ? syntaxStack.opts : null;
7796 var lastTokenIndex = tokenIndex + Math.floor(state.fn(token, getNextToken, opts));
7797
7798 if (!isNaN(lastTokenIndex) && lastTokenIndex > tokenIndex) {
7799 while (tokenIndex < lastTokenIndex) {
7800 addTokenToMatch();
7801 }
7802
7803 state = MATCH$1;
7804 } else {
7805 state = MISMATCH$1;
7806 }
7807
7808 break;
7809
7810 case 'Type':
7811 case 'Property':
7812 var syntaxDict = state.type === 'Type' ? 'types' : 'properties';
7813 var dictSyntax = hasOwnProperty$1.call(syntaxes, syntaxDict) ? syntaxes[syntaxDict][state.name] : null;
7814
7815 if (!dictSyntax || !dictSyntax.match) {
7816 throw new Error(
7817 'Bad syntax reference: ' +
7818 (state.type === 'Type'
7819 ? '<' + state.name + '>'
7820 : '<\'' + state.name + '\'>')
7821 );
7822 }
7823
7824 // stash a syntax for types with low priority
7825 if (syntaxStash !== false && token !== null && state.type === 'Type') {
7826 var lowPriorityMatching =
7827 // https://drafts.csswg.org/css-values-4/#custom-idents
7828 // When parsing positionally-ambiguous keywords in a property value, a <custom-ident> production
7829 // can only claim the keyword if no other unfulfilled production can claim it.
7830 (state.name === 'custom-ident' && token.type === TYPE$6.Ident) ||
7831
7832 // https://drafts.csswg.org/css-values-4/#lengths
7833 // ... if a `0` could be parsed as either a <number> or a <length> in a property (such as line-height),
7834 // it must parse as a <number>
7835 (state.name === 'length' && token.value === '0');
7836
7837 if (lowPriorityMatching) {
7838 if (syntaxStash === null) {
7839 syntaxStash = stateSnapshotFromSyntax(state, elseStack);
7840 }
7841
7842 state = MISMATCH$1;
7843 break;
7844 }
7845 }
7846
7847 openSyntax();
7848 state = dictSyntax.match;
7849 break;
7850
7851 case 'Keyword':
7852 var name = state.name;
7853
7854 if (token !== null) {
7855 var keywordName = token.value;
7856
7857 // drop \0 and \9 hack from keyword name
7858 if (keywordName.indexOf('\\') !== -1) {
7859 keywordName = keywordName.replace(/\\[09].*$/, '');
7860 }
7861
7862 if (areStringsEqualCaseInsensitive(keywordName, name)) {
7863 addTokenToMatch();
7864 state = MATCH$1;
7865 break;
7866 }
7867 }
7868
7869 state = MISMATCH$1;
7870 break;
7871
7872 case 'AtKeyword':
7873 case 'Function':
7874 if (token !== null && areStringsEqualCaseInsensitive(token.value, state.name)) {
7875 addTokenToMatch();
7876 state = MATCH$1;
7877 break;
7878 }
7879
7880 state = MISMATCH$1;
7881 break;
7882
7883 case 'Token':
7884 if (token !== null && token.value === state.value) {
7885 addTokenToMatch();
7886 state = MATCH$1;
7887 break;
7888 }
7889
7890 state = MISMATCH$1;
7891 break;
7892
7893 case 'Comma':
7894 if (token !== null && token.type === TYPE$6.Comma) {
7895 if (isCommaContextStart(matchStack.token)) {
7896 state = MISMATCH$1;
7897 } else {
7898 addTokenToMatch();
7899 state = isCommaContextEnd(token) ? MISMATCH$1 : MATCH$1;
7900 }
7901 } else {
7902 state = isCommaContextStart(matchStack.token) || isCommaContextEnd(token) ? MATCH$1 : MISMATCH$1;
7903 }
7904
7905 break;
7906
7907 case 'String':
7908 var string = '';
7909
7910 for (var lastTokenIndex = tokenIndex; lastTokenIndex < tokens.length && string.length < state.value.length; lastTokenIndex++) {
7911 string += tokens[lastTokenIndex].value;
7912 }
7913
7914 if (areStringsEqualCaseInsensitive(string, state.value)) {
7915 while (tokenIndex < lastTokenIndex) {
7916 addTokenToMatch();
7917 }
7918
7919 state = MATCH$1;
7920 } else {
7921 state = MISMATCH$1;
7922 }
7923
7924 break;
7925
7926 default:
7927 throw new Error('Unknown node type: ' + state.type);
7928 }
7929 }
7930
7931 totalIterationCount += iterationCount;
7932
7933 switch (exitReason) {
7934 case null:
7935 console.warn('[csstree-match] BREAK after ' + ITERATION_LIMIT + ' iterations');
7936 exitReason = EXIT_REASON_ITERATION_LIMIT;
7937 matchStack = null;
7938 break;
7939
7940 case EXIT_REASON_MATCH:
7941 while (syntaxStack !== null) {
7942 closeSyntax();
7943 }
7944 break;
7945
7946 default:
7947 matchStack = null;
7948 }
7949
7950 return {
7951 tokens: tokens,
7952 reason: exitReason,
7953 iterations: iterationCount,
7954 match: matchStack,
7955 longestMatch: longestMatch
7956 };
7957 }
7958
7959 function matchAsList(tokens, matchGraph, syntaxes) {
7960 var matchResult = internalMatch(tokens, matchGraph, syntaxes || {});
7961
7962 if (matchResult.match !== null) {
7963 var item = reverseList(matchResult.match).prev;
7964
7965 matchResult.match = [];
7966
7967 while (item !== null) {
7968 switch (item.type) {
7969 case STUB:
7970 break;
7971
7972 case OPEN_SYNTAX:
7973 case CLOSE_SYNTAX:
7974 matchResult.match.push({
7975 type: item.type,
7976 syntax: item.syntax
7977 });
7978 break;
7979
7980 default:
7981 matchResult.match.push({
7982 token: item.token.value,
7983 node: item.token.node
7984 });
7985 break;
7986 }
7987
7988 item = item.prev;
7989 }
7990 }
7991
7992 return matchResult;
7993 }
7994
7995 function matchAsTree(tokens, matchGraph, syntaxes) {
7996 var matchResult = internalMatch(tokens, matchGraph, syntaxes || {});
7997
7998 if (matchResult.match === null) {
7999 return matchResult;
8000 }
8001
8002 var item = matchResult.match;
8003 var host = matchResult.match = {
8004 syntax: matchGraph.syntax || null,
8005 match: []
8006 };
8007 var hostStack = [host];
8008
8009 // revert a list and start with 2nd item since 1st is a stub item
8010 item = reverseList(item).prev;
8011
8012 // build a tree
8013 while (item !== null) {
8014 switch (item.type) {
8015 case OPEN_SYNTAX:
8016 host.match.push(host = {
8017 syntax: item.syntax,
8018 match: []
8019 });
8020 hostStack.push(host);
8021 break;
8022
8023 case CLOSE_SYNTAX:
8024 hostStack.pop();
8025 host = hostStack[hostStack.length - 1];
8026 break;
8027
8028 default:
8029 host.match.push({
8030 syntax: item.syntax || null,
8031 token: item.token.value,
8032 node: item.token.node
8033 });
8034 }
8035
8036 item = item.prev;
8037 }
8038
8039 return matchResult;
8040 }
8041
8042 var match = {
8043 matchAsList: matchAsList,
8044 matchAsTree: matchAsTree,
8045 getTotalIterationCount: function() {
8046 return totalIterationCount;
8047 }
8048 };
8049
8050 function getTrace(node) {
8051 function shouldPutToTrace(syntax) {
8052 if (syntax === null) {
8053 return false;
8054 }
8055
8056 return (
8057 syntax.type === 'Type' ||
8058 syntax.type === 'Property' ||
8059 syntax.type === 'Keyword'
8060 );
8061 }
8062
8063 function hasMatch(matchNode) {
8064 if (Array.isArray(matchNode.match)) {
8065 // use for-loop for better perfomance
8066 for (var i = 0; i < matchNode.match.length; i++) {
8067 if (hasMatch(matchNode.match[i])) {
8068 if (shouldPutToTrace(matchNode.syntax)) {
8069 result.unshift(matchNode.syntax);
8070 }
8071
8072 return true;
8073 }
8074 }
8075 } else if (matchNode.node === node) {
8076 result = shouldPutToTrace(matchNode.syntax)
8077 ? [matchNode.syntax]
8078 : [];
8079
8080 return true;
8081 }
8082
8083 return false;
8084 }
8085
8086 var result = null;
8087
8088 if (this.matched !== null) {
8089 hasMatch(this.matched);
8090 }
8091
8092 return result;
8093 }
8094
8095 function testNode(match, node, fn) {
8096 var trace = getTrace.call(match, node);
8097
8098 if (trace === null) {
8099 return false;
8100 }
8101
8102 return trace.some(fn);
8103 }
8104
8105 function isType(node, type) {
8106 return testNode(this, node, function(matchNode) {
8107 return matchNode.type === 'Type' && matchNode.name === type;
8108 });
8109 }
8110
8111 function isProperty(node, property) {
8112 return testNode(this, node, function(matchNode) {
8113 return matchNode.type === 'Property' && matchNode.name === property;
8114 });
8115 }
8116
8117 function isKeyword(node) {
8118 return testNode(this, node, function(matchNode) {
8119 return matchNode.type === 'Keyword';
8120 });
8121 }
8122
8123 var trace = {
8124 getTrace: getTrace,
8125 isType: isType,
8126 isProperty: isProperty,
8127 isKeyword: isKeyword
8128 };
8129
8130 function getFirstMatchNode(matchNode) {
8131 if ('node' in matchNode) {
8132 return matchNode.node;
8133 }
8134
8135 return getFirstMatchNode(matchNode.match[0]);
8136 }
8137
8138 function getLastMatchNode(matchNode) {
8139 if ('node' in matchNode) {
8140 return matchNode.node;
8141 }
8142
8143 return getLastMatchNode(matchNode.match[matchNode.match.length - 1]);
8144 }
8145
8146 function matchFragments(lexer, ast, match, type, name) {
8147 function findFragments(matchNode) {
8148 if (matchNode.syntax !== null &&
8149 matchNode.syntax.type === type &&
8150 matchNode.syntax.name === name) {
8151 var start = getFirstMatchNode(matchNode);
8152 var end = getLastMatchNode(matchNode);
8153
8154 lexer.syntax.walk(ast, function(node, item, list) {
8155 if (node === start) {
8156 var nodes = new List_1();
8157
8158 do {
8159 nodes.appendData(item.data);
8160
8161 if (item.data === end) {
8162 break;
8163 }
8164
8165 item = item.next;
8166 } while (item !== null);
8167
8168 fragments.push({
8169 parent: list,
8170 nodes: nodes
8171 });
8172 }
8173 });
8174 }
8175
8176 if (Array.isArray(matchNode.match)) {
8177 matchNode.match.forEach(findFragments);
8178 }
8179 }
8180
8181 var fragments = [];
8182
8183 if (match.matched !== null) {
8184 findFragments(match.matched);
8185 }
8186
8187 return fragments;
8188 }
8189
8190 var search = {
8191 matchFragments: matchFragments
8192 };
8193
8194 var hasOwnProperty$2 = Object.prototype.hasOwnProperty;
8195
8196 function isValidNumber(value) {
8197 // Number.isInteger(value) && value >= 0
8198 return (
8199 typeof value === 'number' &&
8200 isFinite(value) &&
8201 Math.floor(value) === value &&
8202 value >= 0
8203 );
8204 }
8205
8206 function isValidLocation(loc) {
8207 return (
8208 Boolean(loc) &&
8209 isValidNumber(loc.offset) &&
8210 isValidNumber(loc.line) &&
8211 isValidNumber(loc.column)
8212 );
8213 }
8214
8215 function createNodeStructureChecker(type, fields) {
8216 return function checkNode(node, warn) {
8217 if (!node || node.constructor !== Object) {
8218 return warn(node, 'Type of node should be an Object');
8219 }
8220
8221 for (var key in node) {
8222 var valid = true;
8223
8224 if (hasOwnProperty$2.call(node, key) === false) {
8225 continue;
8226 }
8227
8228 if (key === 'type') {
8229 if (node.type !== type) {
8230 warn(node, 'Wrong node type `' + node.type + '`, expected `' + type + '`');
8231 }
8232 } else if (key === 'loc') {
8233 if (node.loc === null) {
8234 continue;
8235 } else if (node.loc && node.loc.constructor === Object) {
8236 if (typeof node.loc.source !== 'string') {
8237 key += '.source';
8238 } else if (!isValidLocation(node.loc.start)) {
8239 key += '.start';
8240 } else if (!isValidLocation(node.loc.end)) {
8241 key += '.end';
8242 } else {
8243 continue;
8244 }
8245 }
8246
8247 valid = false;
8248 } else if (fields.hasOwnProperty(key)) {
8249 for (var i = 0, valid = false; !valid && i < fields[key].length; i++) {
8250 var fieldType = fields[key][i];
8251
8252 switch (fieldType) {
8253 case String:
8254 valid = typeof node[key] === 'string';
8255 break;
8256
8257 case Boolean:
8258 valid = typeof node[key] === 'boolean';
8259 break;
8260
8261 case null:
8262 valid = node[key] === null;
8263 break;
8264
8265 default:
8266 if (typeof fieldType === 'string') {
8267 valid = node[key] && node[key].type === fieldType;
8268 } else if (Array.isArray(fieldType)) {
8269 valid = node[key] instanceof List_1;
8270 }
8271 }
8272 }
8273 } else {
8274 warn(node, 'Unknown field `' + key + '` for ' + type + ' node type');
8275 }
8276
8277 if (!valid) {
8278 warn(node, 'Bad value for `' + type + '.' + key + '`');
8279 }
8280 }
8281
8282 for (var key in fields) {
8283 if (hasOwnProperty$2.call(fields, key) &&
8284 hasOwnProperty$2.call(node, key) === false) {
8285 warn(node, 'Field `' + type + '.' + key + '` is missed');
8286 }
8287 }
8288 };
8289 }
8290
8291 function processStructure(name, nodeType) {
8292 var structure = nodeType.structure;
8293 var fields = {
8294 type: String,
8295 loc: true
8296 };
8297 var docs = {
8298 type: '"' + name + '"'
8299 };
8300
8301 for (var key in structure) {
8302 if (hasOwnProperty$2.call(structure, key) === false) {
8303 continue;
8304 }
8305
8306 var docsTypes = [];
8307 var fieldTypes = fields[key] = Array.isArray(structure[key])
8308 ? structure[key].slice()
8309 : [structure[key]];
8310
8311 for (var i = 0; i < fieldTypes.length; i++) {
8312 var fieldType = fieldTypes[i];
8313 if (fieldType === String || fieldType === Boolean) {
8314 docsTypes.push(fieldType.name);
8315 } else if (fieldType === null) {
8316 docsTypes.push('null');
8317 } else if (typeof fieldType === 'string') {
8318 docsTypes.push('<' + fieldType + '>');
8319 } else if (Array.isArray(fieldType)) {
8320 docsTypes.push('List'); // TODO: use type enum
8321 } else {
8322 throw new Error('Wrong value `' + fieldType + '` in `' + name + '.' + key + '` structure definition');
8323 }
8324 }
8325
8326 docs[key] = docsTypes.join(' | ');
8327 }
8328
8329 return {
8330 docs: docs,
8331 check: createNodeStructureChecker(name, fields)
8332 };
8333 }
8334
8335 var structure = {
8336 getStructureFromConfig: function(config) {
8337 var structure = {};
8338
8339 if (config.node) {
8340 for (var name in config.node) {
8341 if (hasOwnProperty$2.call(config.node, name)) {
8342 var nodeType = config.node[name];
8343
8344 if (nodeType.structure) {
8345 structure[name] = processStructure(name, nodeType);
8346 } else {
8347 throw new Error('Missed `structure` field in `' + name + '` node type definition');
8348 }
8349 }
8350 }
8351 }
8352
8353 return structure;
8354 }
8355 };
8356
8357 var SyntaxReferenceError$1 = error.SyntaxReferenceError;
8358 var MatchError$1 = error.MatchError;
8359
8360
8361
8362
8363
8364
8365 var buildMatchGraph$1 = matchGraph.buildMatchGraph;
8366 var matchAsTree$1 = match.matchAsTree;
8367
8368
8369 var getStructureFromConfig = structure.getStructureFromConfig;
8370 var cssWideKeywords$1 = buildMatchGraph$1('inherit | initial | unset');
8371 var cssWideKeywordsWithExpression = buildMatchGraph$1('inherit | initial | unset | <-ms-legacy-expression>');
8372
8373 function dumpMapSyntax(map, compact, syntaxAsAst) {
8374 var result = {};
8375
8376 for (var name in map) {
8377 if (map[name].syntax) {
8378 result[name] = syntaxAsAst
8379 ? map[name].syntax
8380 : generate_1(map[name].syntax, { compact: compact });
8381 }
8382 }
8383
8384 return result;
8385 }
8386
8387 function valueHasVar(tokens) {
8388 for (var i = 0; i < tokens.length; i++) {
8389 if (tokens[i].value.toLowerCase() === 'var(') {
8390 return true;
8391 }
8392 }
8393
8394 return false;
8395 }
8396
8397 function buildMatchResult(match, error, iterations) {
8398 return {
8399 matched: match,
8400 iterations: iterations,
8401 error: error,
8402 getTrace: trace.getTrace,
8403 isType: trace.isType,
8404 isProperty: trace.isProperty,
8405 isKeyword: trace.isKeyword
8406 };
8407 }
8408
8409 function matchSyntax(lexer, syntax, value, useCommon) {
8410 var tokens = prepareTokens_1(value, lexer.syntax);
8411 var result;
8412
8413 if (valueHasVar(tokens)) {
8414 return buildMatchResult(null, new Error('Matching for a tree with var() is not supported'));
8415 }
8416
8417 if (useCommon) {
8418 result = matchAsTree$1(tokens, lexer.valueCommonSyntax, lexer);
8419 }
8420
8421 if (!useCommon || !result.match) {
8422 result = matchAsTree$1(tokens, syntax.match, lexer);
8423 if (!result.match) {
8424 return buildMatchResult(
8425 null,
8426 new MatchError$1(result.reason, syntax.syntax, value, result),
8427 result.iterations
8428 );
8429 }
8430 }
8431
8432 return buildMatchResult(result.match, null, result.iterations);
8433 }
8434
8435 var Lexer = function(config, syntax, structure) {
8436 this.valueCommonSyntax = cssWideKeywords$1;
8437 this.syntax = syntax;
8438 this.generic = false;
8439 this.atrules = {};
8440 this.properties = {};
8441 this.types = {};
8442 this.structure = structure || getStructureFromConfig(config);
8443
8444 if (config) {
8445 if (config.types) {
8446 for (var name in config.types) {
8447 this.addType_(name, config.types[name]);
8448 }
8449 }
8450
8451 if (config.generic) {
8452 this.generic = true;
8453 for (var name in generic) {
8454 this.addType_(name, generic[name]);
8455 }
8456 }
8457
8458 if (config.atrules) {
8459 for (var name in config.atrules) {
8460 this.addAtrule_(name, config.atrules[name]);
8461 }
8462 }
8463
8464 if (config.properties) {
8465 for (var name in config.properties) {
8466 this.addProperty_(name, config.properties[name]);
8467 }
8468 }
8469 }
8470 };
8471
8472 Lexer.prototype = {
8473 structure: {},
8474 checkStructure: function(ast) {
8475 function collectWarning(node, message) {
8476 warns.push({
8477 node: node,
8478 message: message
8479 });
8480 }
8481
8482 var structure = this.structure;
8483 var warns = [];
8484
8485 this.syntax.walk(ast, function(node) {
8486 if (structure.hasOwnProperty(node.type)) {
8487 structure[node.type].check(node, collectWarning);
8488 } else {
8489 collectWarning(node, 'Unknown node type `' + node.type + '`');
8490 }
8491 });
8492
8493 return warns.length ? warns : false;
8494 },
8495
8496 createDescriptor: function(syntax, type, name) {
8497 var ref = {
8498 type: type,
8499 name: name
8500 };
8501 var descriptor = {
8502 type: type,
8503 name: name,
8504 syntax: null,
8505 match: null
8506 };
8507
8508 if (typeof syntax === 'function') {
8509 descriptor.match = buildMatchGraph$1(syntax, ref);
8510 } else {
8511 if (typeof syntax === 'string') {
8512 // lazy parsing on first access
8513 Object.defineProperty(descriptor, 'syntax', {
8514 get: function() {
8515 Object.defineProperty(descriptor, 'syntax', {
8516 value: parse_1(syntax)
8517 });
8518
8519 return descriptor.syntax;
8520 }
8521 });
8522 } else {
8523 descriptor.syntax = syntax;
8524 }
8525
8526 // lazy graph build on first access
8527 Object.defineProperty(descriptor, 'match', {
8528 get: function() {
8529 Object.defineProperty(descriptor, 'match', {
8530 value: buildMatchGraph$1(descriptor.syntax, ref)
8531 });
8532
8533 return descriptor.match;
8534 }
8535 });
8536 }
8537
8538 return descriptor;
8539 },
8540 addAtrule_: function(name, syntax) {
8541 this.atrules[name] = {
8542 prelude: syntax.prelude ? this.createDescriptor(syntax.prelude, 'AtrulePrelude', name) : null,
8543 descriptors: syntax.descriptors
8544 ? Object.keys(syntax.descriptors).reduce((res, name) => {
8545 res[name] = this.createDescriptor(syntax.descriptors[name], 'AtruleDescriptor', name);
8546 return res;
8547 }, {})
8548 : null
8549 };
8550 },
8551 addProperty_: function(name, syntax) {
8552 this.properties[name] = this.createDescriptor(syntax, 'Property', name);
8553 },
8554 addType_: function(name, syntax) {
8555 this.types[name] = this.createDescriptor(syntax, 'Type', name);
8556
8557 if (syntax === generic['-ms-legacy-expression']) {
8558 this.valueCommonSyntax = cssWideKeywordsWithExpression;
8559 }
8560 },
8561
8562 matchAtrulePrelude: function(atruleName, prelude) {
8563 var atrule = names.keyword(atruleName);
8564
8565 var atrulePreludeSyntax = atrule.vendor
8566 ? this.getAtrulePrelude(atrule.name) || this.getAtrulePrelude(atrule.basename)
8567 : this.getAtrulePrelude(atrule.name);
8568
8569 if (!atrulePreludeSyntax) {
8570 if (atrule.basename in this.atrules) {
8571 return buildMatchResult(null, new Error('At-rule `' + atruleName + '` should not contain a prelude'));
8572 }
8573
8574 return buildMatchResult(null, new SyntaxReferenceError$1('Unknown at-rule', atruleName));
8575 }
8576
8577 return matchSyntax(this, atrulePreludeSyntax, prelude, true);
8578 },
8579 matchAtruleDescriptor: function(atruleName, descriptorName, value) {
8580 var atrule = names.keyword(atruleName);
8581 var descriptor = names.keyword(descriptorName);
8582
8583 var atruleEntry = atrule.vendor
8584 ? this.atrules[atrule.name] || this.atrules[atrule.basename]
8585 : this.atrules[atrule.name];
8586
8587 if (!atruleEntry) {
8588 return buildMatchResult(null, new SyntaxReferenceError$1('Unknown at-rule', atruleName));
8589 }
8590
8591 if (!atruleEntry.descriptors) {
8592 return buildMatchResult(null, new Error('At-rule `' + atruleName + '` has no known descriptors'));
8593 }
8594
8595 var atruleDescriptorSyntax = descriptor.vendor
8596 ? atruleEntry.descriptors[descriptor.name] || atruleEntry.descriptors[descriptor.basename]
8597 : atruleEntry.descriptors[descriptor.name];
8598
8599 if (!atruleDescriptorSyntax) {
8600 return buildMatchResult(null, new SyntaxReferenceError$1('Unknown at-rule descriptor', descriptorName));
8601 }
8602
8603 return matchSyntax(this, atruleDescriptorSyntax, value, true);
8604 },
8605 matchDeclaration: function(node) {
8606 if (node.type !== 'Declaration') {
8607 return buildMatchResult(null, new Error('Not a Declaration node'));
8608 }
8609
8610 return this.matchProperty(node.property, node.value);
8611 },
8612 matchProperty: function(propertyName, value) {
8613 var property = names.property(propertyName);
8614
8615 // don't match syntax for a custom property
8616 if (property.custom) {
8617 return buildMatchResult(null, new Error('Lexer matching doesn\'t applicable for custom properties'));
8618 }
8619
8620 var propertySyntax = property.vendor
8621 ? this.getProperty(property.name) || this.getProperty(property.basename)
8622 : this.getProperty(property.name);
8623
8624 if (!propertySyntax) {
8625 return buildMatchResult(null, new SyntaxReferenceError$1('Unknown property', propertyName));
8626 }
8627
8628 return matchSyntax(this, propertySyntax, value, true);
8629 },
8630 matchType: function(typeName, value) {
8631 var typeSyntax = this.getType(typeName);
8632
8633 if (!typeSyntax) {
8634 return buildMatchResult(null, new SyntaxReferenceError$1('Unknown type', typeName));
8635 }
8636
8637 return matchSyntax(this, typeSyntax, value, false);
8638 },
8639 match: function(syntax, value) {
8640 if (typeof syntax !== 'string' && (!syntax || !syntax.type)) {
8641 return buildMatchResult(null, new SyntaxReferenceError$1('Bad syntax'));
8642 }
8643
8644 if (typeof syntax === 'string' || !syntax.match) {
8645 syntax = this.createDescriptor(syntax, 'Type', 'anonymous');
8646 }
8647
8648 return matchSyntax(this, syntax, value, false);
8649 },
8650
8651 findValueFragments: function(propertyName, value, type, name) {
8652 return search.matchFragments(this, value, this.matchProperty(propertyName, value), type, name);
8653 },
8654 findDeclarationValueFragments: function(declaration, type, name) {
8655 return search.matchFragments(this, declaration.value, this.matchDeclaration(declaration), type, name);
8656 },
8657 findAllFragments: function(ast, type, name) {
8658 var result = [];
8659
8660 this.syntax.walk(ast, {
8661 visit: 'Declaration',
8662 enter: function(declaration) {
8663 result.push.apply(result, this.findDeclarationValueFragments(declaration, type, name));
8664 }.bind(this)
8665 });
8666
8667 return result;
8668 },
8669
8670 getAtrulePrelude: function(atruleName) {
8671 return this.atrules.hasOwnProperty(atruleName) ? this.atrules[atruleName].prelude : null;
8672 },
8673 getAtruleDescriptor: function(atruleName, name) {
8674 return this.atrules.hasOwnProperty(atruleName) && this.atrules.declarators
8675 ? this.atrules[atruleName].declarators[name] || null
8676 : null;
8677 },
8678 getProperty: function(name) {
8679 return this.properties.hasOwnProperty(name) ? this.properties[name] : null;
8680 },
8681 getType: function(name) {
8682 return this.types.hasOwnProperty(name) ? this.types[name] : null;
8683 },
8684
8685 validate: function() {
8686 function validate(syntax, name, broken, descriptor) {
8687 if (broken.hasOwnProperty(name)) {
8688 return broken[name];
8689 }
8690
8691 broken[name] = false;
8692 if (descriptor.syntax !== null) {
8693 walk$1(descriptor.syntax, function(node) {
8694 if (node.type !== 'Type' && node.type !== 'Property') {
8695 return;
8696 }
8697
8698 var map = node.type === 'Type' ? syntax.types : syntax.properties;
8699 var brokenMap = node.type === 'Type' ? brokenTypes : brokenProperties;
8700
8701 if (!map.hasOwnProperty(node.name) || validate(syntax, node.name, brokenMap, map[node.name])) {
8702 broken[name] = true;
8703 }
8704 }, this);
8705 }
8706 }
8707
8708 var brokenTypes = {};
8709 var brokenProperties = {};
8710
8711 for (var key in this.types) {
8712 validate(this, key, brokenTypes, this.types[key]);
8713 }
8714
8715 for (var key in this.properties) {
8716 validate(this, key, brokenProperties, this.properties[key]);
8717 }
8718
8719 brokenTypes = Object.keys(brokenTypes).filter(function(name) {
8720 return brokenTypes[name];
8721 });
8722 brokenProperties = Object.keys(brokenProperties).filter(function(name) {
8723 return brokenProperties[name];
8724 });
8725
8726 if (brokenTypes.length || brokenProperties.length) {
8727 return {
8728 types: brokenTypes,
8729 properties: brokenProperties
8730 };
8731 }
8732
8733 return null;
8734 },
8735 dump: function(syntaxAsAst, pretty) {
8736 return {
8737 generic: this.generic,
8738 types: dumpMapSyntax(this.types, !pretty, syntaxAsAst),
8739 properties: dumpMapSyntax(this.properties, !pretty, syntaxAsAst)
8740 };
8741 },
8742 toString: function() {
8743 return JSON.stringify(this.dump());
8744 }
8745 };
8746
8747 var Lexer_1 = Lexer;
8748
8749 var definitionSyntax = {
8750 SyntaxError: _SyntaxError$1,
8751 parse: parse_1,
8752 generate: generate_1,
8753 walk: walk$1
8754 };
8755
8756 var isBOM$2 = tokenizer.isBOM;
8757
8758 var N$3 = 10;
8759 var F$2 = 12;
8760 var R$2 = 13;
8761
8762 function computeLinesAndColumns(host, source) {
8763 var sourceLength = source.length;
8764 var lines = adoptBuffer(host.lines, sourceLength); // +1
8765 var line = host.startLine;
8766 var columns = adoptBuffer(host.columns, sourceLength);
8767 var column = host.startColumn;
8768 var startOffset = source.length > 0 ? isBOM$2(source.charCodeAt(0)) : 0;
8769
8770 for (var i = startOffset; i < sourceLength; i++) { // -1
8771 var code = source.charCodeAt(i);
8772
8773 lines[i] = line;
8774 columns[i] = column++;
8775
8776 if (code === N$3 || code === R$2 || code === F$2) {
8777 if (code === R$2 && i + 1 < sourceLength && source.charCodeAt(i + 1) === N$3) {
8778 i++;
8779 lines[i] = line;
8780 columns[i] = column;
8781 }
8782
8783 line++;
8784 column = 1;
8785 }
8786 }
8787
8788 lines[i] = line;
8789 columns[i] = column;
8790
8791 host.lines = lines;
8792 host.columns = columns;
8793 }
8794
8795 var OffsetToLocation = function() {
8796 this.lines = null;
8797 this.columns = null;
8798 this.linesAndColumnsComputed = false;
8799 };
8800
8801 OffsetToLocation.prototype = {
8802 setSource: function(source, startOffset, startLine, startColumn) {
8803 this.source = source;
8804 this.startOffset = typeof startOffset === 'undefined' ? 0 : startOffset;
8805 this.startLine = typeof startLine === 'undefined' ? 1 : startLine;
8806 this.startColumn = typeof startColumn === 'undefined' ? 1 : startColumn;
8807 this.linesAndColumnsComputed = false;
8808 },
8809
8810 ensureLinesAndColumnsComputed: function() {
8811 if (!this.linesAndColumnsComputed) {
8812 computeLinesAndColumns(this, this.source);
8813 this.linesAndColumnsComputed = true;
8814 }
8815 },
8816 getLocation: function(offset, filename) {
8817 this.ensureLinesAndColumnsComputed();
8818
8819 return {
8820 source: filename,
8821 offset: this.startOffset + offset,
8822 line: this.lines[offset],
8823 column: this.columns[offset]
8824 };
8825 },
8826 getLocationRange: function(start, end, filename) {
8827 this.ensureLinesAndColumnsComputed();
8828
8829 return {
8830 source: filename,
8831 start: {
8832 offset: this.startOffset + start,
8833 line: this.lines[start],
8834 column: this.columns[start]
8835 },
8836 end: {
8837 offset: this.startOffset + end,
8838 line: this.lines[end],
8839 column: this.columns[end]
8840 }
8841 };
8842 }
8843 };
8844
8845 var OffsetToLocation_1 = OffsetToLocation;
8846
8847 var TYPE$7 = tokenizer.TYPE;
8848 var WHITESPACE$2 = TYPE$7.WhiteSpace;
8849 var COMMENT$2 = TYPE$7.Comment;
8850
8851 var sequence = function readSequence(recognizer) {
8852 var children = this.createList();
8853 var child = null;
8854 var context = {
8855 recognizer: recognizer,
8856 space: null,
8857 ignoreWS: false,
8858 ignoreWSAfter: false
8859 };
8860
8861 this.scanner.skipSC();
8862
8863 while (!this.scanner.eof) {
8864 switch (this.scanner.tokenType) {
8865 case COMMENT$2:
8866 this.scanner.next();
8867 continue;
8868
8869 case WHITESPACE$2:
8870 if (context.ignoreWS) {
8871 this.scanner.next();
8872 } else {
8873 context.space = this.WhiteSpace();
8874 }
8875 continue;
8876 }
8877
8878 child = recognizer.getNode.call(this, context);
8879
8880 if (child === undefined) {
8881 break;
8882 }
8883
8884 if (context.space !== null) {
8885 children.push(context.space);
8886 context.space = null;
8887 }
8888
8889 children.push(child);
8890
8891 if (context.ignoreWSAfter) {
8892 context.ignoreWSAfter = false;
8893 context.ignoreWS = true;
8894 } else {
8895 context.ignoreWS = false;
8896 }
8897 }
8898
8899 return children;
8900 };
8901
8902 var findWhiteSpaceStart$1 = utils.findWhiteSpaceStart;
8903
8904 var noop$3 = function() {};
8905
8906 var TYPE$8 = _const.TYPE;
8907 var NAME$2 = _const.NAME;
8908 var WHITESPACE$3 = TYPE$8.WhiteSpace;
8909 var IDENT$2 = TYPE$8.Ident;
8910 var FUNCTION = TYPE$8.Function;
8911 var URL$1 = TYPE$8.Url;
8912 var HASH = TYPE$8.Hash;
8913 var PERCENTAGE = TYPE$8.Percentage;
8914 var NUMBER$2 = TYPE$8.Number;
8915 var NUMBERSIGN$1 = 0x0023; // U+0023 NUMBER SIGN (#)
8916 var NULL = 0;
8917
8918 function createParseContext(name) {
8919 return function() {
8920 return this[name]();
8921 };
8922 }
8923
8924 function processConfig(config) {
8925 var parserConfig = {
8926 context: {},
8927 scope: {},
8928 atrule: {},
8929 pseudo: {}
8930 };
8931
8932 if (config.parseContext) {
8933 for (var name in config.parseContext) {
8934 switch (typeof config.parseContext[name]) {
8935 case 'function':
8936 parserConfig.context[name] = config.parseContext[name];
8937 break;
8938
8939 case 'string':
8940 parserConfig.context[name] = createParseContext(config.parseContext[name]);
8941 break;
8942 }
8943 }
8944 }
8945
8946 if (config.scope) {
8947 for (var name in config.scope) {
8948 parserConfig.scope[name] = config.scope[name];
8949 }
8950 }
8951
8952 if (config.atrule) {
8953 for (var name in config.atrule) {
8954 var atrule = config.atrule[name];
8955
8956 if (atrule.parse) {
8957 parserConfig.atrule[name] = atrule.parse;
8958 }
8959 }
8960 }
8961
8962 if (config.pseudo) {
8963 for (var name in config.pseudo) {
8964 var pseudo = config.pseudo[name];
8965
8966 if (pseudo.parse) {
8967 parserConfig.pseudo[name] = pseudo.parse;
8968 }
8969 }
8970 }
8971
8972 if (config.node) {
8973 for (var name in config.node) {
8974 parserConfig[name] = config.node[name].parse;
8975 }
8976 }
8977
8978 return parserConfig;
8979 }
8980
8981 var create$1 = function createParser(config) {
8982 var parser = {
8983 scanner: new TokenStream_1(),
8984 locationMap: new OffsetToLocation_1(),
8985
8986 filename: '<unknown>',
8987 needPositions: false,
8988 onParseError: noop$3,
8989 onParseErrorThrow: false,
8990 parseAtrulePrelude: true,
8991 parseRulePrelude: true,
8992 parseValue: true,
8993 parseCustomProperty: false,
8994
8995 readSequence: sequence,
8996
8997 createList: function() {
8998 return new List_1();
8999 },
9000 createSingleNodeList: function(node) {
9001 return new List_1().appendData(node);
9002 },
9003 getFirstListNode: function(list) {
9004 return list && list.first();
9005 },
9006 getLastListNode: function(list) {
9007 return list.last();
9008 },
9009
9010 parseWithFallback: function(consumer, fallback) {
9011 var startToken = this.scanner.tokenIndex;
9012
9013 try {
9014 return consumer.call(this);
9015 } catch (e) {
9016 if (this.onParseErrorThrow) {
9017 throw e;
9018 }
9019
9020 var fallbackNode = fallback.call(this, startToken);
9021
9022 this.onParseErrorThrow = true;
9023 this.onParseError(e, fallbackNode);
9024 this.onParseErrorThrow = false;
9025
9026 return fallbackNode;
9027 }
9028 },
9029
9030 lookupNonWSType: function(offset) {
9031 do {
9032 var type = this.scanner.lookupType(offset++);
9033 if (type !== WHITESPACE$3) {
9034 return type;
9035 }
9036 } while (type !== NULL);
9037
9038 return NULL;
9039 },
9040
9041 eat: function(tokenType) {
9042 if (this.scanner.tokenType !== tokenType) {
9043 var offset = this.scanner.tokenStart;
9044 var message = NAME$2[tokenType] + ' is expected';
9045
9046 // tweak message and offset
9047 switch (tokenType) {
9048 case IDENT$2:
9049 // when identifier is expected but there is a function or url
9050 if (this.scanner.tokenType === FUNCTION || this.scanner.tokenType === URL$1) {
9051 offset = this.scanner.tokenEnd - 1;
9052 message = 'Identifier is expected but function found';
9053 } else {
9054 message = 'Identifier is expected';
9055 }
9056 break;
9057
9058 case HASH:
9059 if (this.scanner.isDelim(NUMBERSIGN$1)) {
9060 this.scanner.next();
9061 offset++;
9062 message = 'Name is expected';
9063 }
9064 break;
9065
9066 case PERCENTAGE:
9067 if (this.scanner.tokenType === NUMBER$2) {
9068 offset = this.scanner.tokenEnd;
9069 message = 'Percent sign is expected';
9070 }
9071 break;
9072
9073 default:
9074 // when test type is part of another token show error for current position + 1
9075 // e.g. eat(HYPHENMINUS) will fail on "-foo", but pointing on "-" is odd
9076 if (this.scanner.source.charCodeAt(this.scanner.tokenStart) === tokenType) {
9077 offset = offset + 1;
9078 }
9079 }
9080
9081 this.error(message, offset);
9082 }
9083
9084 this.scanner.next();
9085 },
9086
9087 consume: function(tokenType) {
9088 var value = this.scanner.getTokenValue();
9089
9090 this.eat(tokenType);
9091
9092 return value;
9093 },
9094 consumeFunctionName: function() {
9095 var name = this.scanner.source.substring(this.scanner.tokenStart, this.scanner.tokenEnd - 1);
9096
9097 this.eat(FUNCTION);
9098
9099 return name;
9100 },
9101
9102 getLocation: function(start, end) {
9103 if (this.needPositions) {
9104 return this.locationMap.getLocationRange(
9105 start,
9106 end,
9107 this.filename
9108 );
9109 }
9110
9111 return null;
9112 },
9113 getLocationFromList: function(list) {
9114 if (this.needPositions) {
9115 var head = this.getFirstListNode(list);
9116 var tail = this.getLastListNode(list);
9117 return this.locationMap.getLocationRange(
9118 head !== null ? head.loc.start.offset - this.locationMap.startOffset : this.scanner.tokenStart,
9119 tail !== null ? tail.loc.end.offset - this.locationMap.startOffset : this.scanner.tokenStart,
9120 this.filename
9121 );
9122 }
9123
9124 return null;
9125 },
9126
9127 error: function(message, offset) {
9128 var location = typeof offset !== 'undefined' && offset < this.scanner.source.length
9129 ? this.locationMap.getLocation(offset)
9130 : this.scanner.eof
9131 ? this.locationMap.getLocation(findWhiteSpaceStart$1(this.scanner.source, this.scanner.source.length - 1))
9132 : this.locationMap.getLocation(this.scanner.tokenStart);
9133
9134 throw new _SyntaxError(
9135 message || 'Unexpected input',
9136 this.scanner.source,
9137 location.offset,
9138 location.line,
9139 location.column
9140 );
9141 }
9142 };
9143
9144 config = processConfig(config || {});
9145 for (var key in config) {
9146 parser[key] = config[key];
9147 }
9148
9149 return function(source, options) {
9150 options = options || {};
9151
9152 var context = options.context || 'default';
9153 var ast;
9154
9155 tokenizer(source, parser.scanner);
9156 parser.locationMap.setSource(
9157 source,
9158 options.offset,
9159 options.line,
9160 options.column
9161 );
9162
9163 parser.filename = options.filename || '<unknown>';
9164 parser.needPositions = Boolean(options.positions);
9165 parser.onParseError = typeof options.onParseError === 'function' ? options.onParseError : noop$3;
9166 parser.onParseErrorThrow = false;
9167 parser.parseAtrulePrelude = 'parseAtrulePrelude' in options ? Boolean(options.parseAtrulePrelude) : true;
9168 parser.parseRulePrelude = 'parseRulePrelude' in options ? Boolean(options.parseRulePrelude) : true;
9169 parser.parseValue = 'parseValue' in options ? Boolean(options.parseValue) : true;
9170 parser.parseCustomProperty = 'parseCustomProperty' in options ? Boolean(options.parseCustomProperty) : false;
9171
9172 if (!parser.context.hasOwnProperty(context)) {
9173 throw new Error('Unknown context `' + context + '`');
9174 }
9175
9176 ast = parser.context[context].call(parser, options);
9177
9178 if (!parser.scanner.eof) {
9179 parser.error();
9180 }
9181
9182 return ast;
9183 };
9184 };
9185
9186 /* -*- Mode: js; js-indent-level: 2; -*- */
9187 /*
9188 * Copyright 2011 Mozilla Foundation and contributors
9189 * Licensed under the New BSD license. See LICENSE or:
9190 * http://opensource.org/licenses/BSD-3-Clause
9191 */
9192
9193 var intToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split('');
9194
9195 /**
9196 * Encode an integer in the range of 0 to 63 to a single base 64 digit.
9197 */
9198 var encode = function (number) {
9199 if (0 <= number && number < intToCharMap.length) {
9200 return intToCharMap[number];
9201 }
9202 throw new TypeError("Must be between 0 and 63: " + number);
9203 };
9204
9205 /**
9206 * Decode a single base 64 character code digit to an integer. Returns -1 on
9207 * failure.
9208 */
9209 var decode = function (charCode) {
9210 var bigA = 65; // 'A'
9211 var bigZ = 90; // 'Z'
9212
9213 var littleA = 97; // 'a'
9214 var littleZ = 122; // 'z'
9215
9216 var zero = 48; // '0'
9217 var nine = 57; // '9'
9218
9219 var plus = 43; // '+'
9220 var slash = 47; // '/'
9221
9222 var littleOffset = 26;
9223 var numberOffset = 52;
9224
9225 // 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ
9226 if (bigA <= charCode && charCode <= bigZ) {
9227 return (charCode - bigA);
9228 }
9229
9230 // 26 - 51: abcdefghijklmnopqrstuvwxyz
9231 if (littleA <= charCode && charCode <= littleZ) {
9232 return (charCode - littleA + littleOffset);
9233 }
9234
9235 // 52 - 61: 0123456789
9236 if (zero <= charCode && charCode <= nine) {
9237 return (charCode - zero + numberOffset);
9238 }
9239
9240 // 62: +
9241 if (charCode == plus) {
9242 return 62;
9243 }
9244
9245 // 63: /
9246 if (charCode == slash) {
9247 return 63;
9248 }
9249
9250 // Invalid base64 digit.
9251 return -1;
9252 };
9253
9254 var base64 = {
9255 encode: encode,
9256 decode: decode
9257 };
9258
9259 /* -*- Mode: js; js-indent-level: 2; -*- */
9260 /*
9261 * Copyright 2011 Mozilla Foundation and contributors
9262 * Licensed under the New BSD license. See LICENSE or:
9263 * http://opensource.org/licenses/BSD-3-Clause
9264 *
9265 * Based on the Base 64 VLQ implementation in Closure Compiler:
9266 * https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java
9267 *
9268 * Copyright 2011 The Closure Compiler Authors. All rights reserved.
9269 * Redistribution and use in source and binary forms, with or without
9270 * modification, are permitted provided that the following conditions are
9271 * met:
9272 *
9273 * * Redistributions of source code must retain the above copyright
9274 * notice, this list of conditions and the following disclaimer.
9275 * * Redistributions in binary form must reproduce the above
9276 * copyright notice, this list of conditions and the following
9277 * disclaimer in the documentation and/or other materials provided
9278 * with the distribution.
9279 * * Neither the name of Google Inc. nor the names of its
9280 * contributors may be used to endorse or promote products derived
9281 * from this software without specific prior written permission.
9282 *
9283 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
9284 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
9285 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
9286 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
9287 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
9288 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9289 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
9290 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
9291 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
9292 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
9293 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
9294 */
9295
9296
9297
9298 // A single base 64 digit can contain 6 bits of data. For the base 64 variable
9299 // length quantities we use in the source map spec, the first bit is the sign,
9300 // the next four bits are the actual value, and the 6th bit is the
9301 // continuation bit. The continuation bit tells us whether there are more
9302 // digits in this value following this digit.
9303 //
9304 // Continuation
9305 // | Sign
9306 // | |
9307 // V V
9308 // 101011
9309
9310 var VLQ_BASE_SHIFT = 5;
9311
9312 // binary: 100000
9313 var VLQ_BASE = 1 << VLQ_BASE_SHIFT;
9314
9315 // binary: 011111
9316 var VLQ_BASE_MASK = VLQ_BASE - 1;
9317
9318 // binary: 100000
9319 var VLQ_CONTINUATION_BIT = VLQ_BASE;
9320
9321 /**
9322 * Converts from a two-complement value to a value where the sign bit is
9323 * placed in the least significant bit. For example, as decimals:
9324 * 1 becomes 2 (10 binary), -1 becomes 3 (11 binary)
9325 * 2 becomes 4 (100 binary), -2 becomes 5 (101 binary)
9326 */
9327 function toVLQSigned(aValue) {
9328 return aValue < 0
9329 ? ((-aValue) << 1) + 1
9330 : (aValue << 1) + 0;
9331 }
9332
9333 /**
9334 * Converts to a two-complement value from a value where the sign bit is
9335 * placed in the least significant bit. For example, as decimals:
9336 * 2 (10 binary) becomes 1, 3 (11 binary) becomes -1
9337 * 4 (100 binary) becomes 2, 5 (101 binary) becomes -2
9338 */
9339 function fromVLQSigned(aValue) {
9340 var isNegative = (aValue & 1) === 1;
9341 var shifted = aValue >> 1;
9342 return isNegative
9343 ? -shifted
9344 : shifted;
9345 }
9346
9347 /**
9348 * Returns the base 64 VLQ encoded value.
9349 */
9350 var encode$1 = function base64VLQ_encode(aValue) {
9351 var encoded = "";
9352 var digit;
9353
9354 var vlq = toVLQSigned(aValue);
9355
9356 do {
9357 digit = vlq & VLQ_BASE_MASK;
9358 vlq >>>= VLQ_BASE_SHIFT;
9359 if (vlq > 0) {
9360 // There are still more digits in this value, so we must make sure the
9361 // continuation bit is marked.
9362 digit |= VLQ_CONTINUATION_BIT;
9363 }
9364 encoded += base64.encode(digit);
9365 } while (vlq > 0);
9366
9367 return encoded;
9368 };
9369
9370 /**
9371 * Decodes the next base 64 VLQ value from the given string and returns the
9372 * value and the rest of the string via the out parameter.
9373 */
9374 var decode$1 = function base64VLQ_decode(aStr, aIndex, aOutParam) {
9375 var strLen = aStr.length;
9376 var result = 0;
9377 var shift = 0;
9378 var continuation, digit;
9379
9380 do {
9381 if (aIndex >= strLen) {
9382 throw new Error("Expected more digits in base 64 VLQ value.");
9383 }
9384
9385 digit = base64.decode(aStr.charCodeAt(aIndex++));
9386 if (digit === -1) {
9387 throw new Error("Invalid base64 digit: " + aStr.charAt(aIndex - 1));
9388 }
9389
9390 continuation = !!(digit & VLQ_CONTINUATION_BIT);
9391 digit &= VLQ_BASE_MASK;
9392 result = result + (digit << shift);
9393 shift += VLQ_BASE_SHIFT;
9394 } while (continuation);
9395
9396 aOutParam.value = fromVLQSigned(result);
9397 aOutParam.rest = aIndex;
9398 };
9399
9400 var base64Vlq = {
9401 encode: encode$1,
9402 decode: decode$1
9403 };
9404
9405 var util = createCommonjsModule(function (module, exports) {
9406 /* -*- Mode: js; js-indent-level: 2; -*- */
9407 /*
9408 * Copyright 2011 Mozilla Foundation and contributors
9409 * Licensed under the New BSD license. See LICENSE or:
9410 * http://opensource.org/licenses/BSD-3-Clause
9411 */
9412
9413 /**
9414 * This is a helper function for getting values from parameter/options
9415 * objects.
9416 *
9417 * @param args The object we are extracting values from
9418 * @param name The name of the property we are getting.
9419 * @param defaultValue An optional value to return if the property is missing
9420 * from the object. If this is not specified and the property is missing, an
9421 * error will be thrown.
9422 */
9423 function getArg(aArgs, aName, aDefaultValue) {
9424 if (aName in aArgs) {
9425 return aArgs[aName];
9426 } else if (arguments.length === 3) {
9427 return aDefaultValue;
9428 } else {
9429 throw new Error('"' + aName + '" is a required argument.');
9430 }
9431 }
9432 exports.getArg = getArg;
9433
9434 var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/;
9435 var dataUrlRegexp = /^data:.+\,.+$/;
9436
9437 function urlParse(aUrl) {
9438 var match = aUrl.match(urlRegexp);
9439 if (!match) {
9440 return null;
9441 }
9442 return {
9443 scheme: match[1],
9444 auth: match[2],
9445 host: match[3],
9446 port: match[4],
9447 path: match[5]
9448 };
9449 }
9450 exports.urlParse = urlParse;
9451
9452 function urlGenerate(aParsedUrl) {
9453 var url = '';
9454 if (aParsedUrl.scheme) {
9455 url += aParsedUrl.scheme + ':';
9456 }
9457 url += '//';
9458 if (aParsedUrl.auth) {
9459 url += aParsedUrl.auth + '@';
9460 }
9461 if (aParsedUrl.host) {
9462 url += aParsedUrl.host;
9463 }
9464 if (aParsedUrl.port) {
9465 url += ":" + aParsedUrl.port;
9466 }
9467 if (aParsedUrl.path) {
9468 url += aParsedUrl.path;
9469 }
9470 return url;
9471 }
9472 exports.urlGenerate = urlGenerate;
9473
9474 /**
9475 * Normalizes a path, or the path portion of a URL:
9476 *
9477 * - Replaces consecutive slashes with one slash.
9478 * - Removes unnecessary '.' parts.
9479 * - Removes unnecessary '<dir>/..' parts.
9480 *
9481 * Based on code in the Node.js 'path' core module.
9482 *
9483 * @param aPath The path or url to normalize.
9484 */
9485 function normalize(aPath) {
9486 var path = aPath;
9487 var url = urlParse(aPath);
9488 if (url) {
9489 if (!url.path) {
9490 return aPath;
9491 }
9492 path = url.path;
9493 }
9494 var isAbsolute = exports.isAbsolute(path);
9495
9496 var parts = path.split(/\/+/);
9497 for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {
9498 part = parts[i];
9499 if (part === '.') {
9500 parts.splice(i, 1);
9501 } else if (part === '..') {
9502 up++;
9503 } else if (up > 0) {
9504 if (part === '') {
9505 // The first part is blank if the path is absolute. Trying to go
9506 // above the root is a no-op. Therefore we can remove all '..' parts
9507 // directly after the root.
9508 parts.splice(i + 1, up);
9509 up = 0;
9510 } else {
9511 parts.splice(i, 2);
9512 up--;
9513 }
9514 }
9515 }
9516 path = parts.join('/');
9517
9518 if (path === '') {
9519 path = isAbsolute ? '/' : '.';
9520 }
9521
9522 if (url) {
9523 url.path = path;
9524 return urlGenerate(url);
9525 }
9526 return path;
9527 }
9528 exports.normalize = normalize;
9529
9530 /**
9531 * Joins two paths/URLs.
9532 *
9533 * @param aRoot The root path or URL.
9534 * @param aPath The path or URL to be joined with the root.
9535 *
9536 * - If aPath is a URL or a data URI, aPath is returned, unless aPath is a
9537 * scheme-relative URL: Then the scheme of aRoot, if any, is prepended
9538 * first.
9539 * - Otherwise aPath is a path. If aRoot is a URL, then its path portion
9540 * is updated with the result and aRoot is returned. Otherwise the result
9541 * is returned.
9542 * - If aPath is absolute, the result is aPath.
9543 * - Otherwise the two paths are joined with a slash.
9544 * - Joining for example 'http://' and 'www.example.com' is also supported.
9545 */
9546 function join(aRoot, aPath) {
9547 if (aRoot === "") {
9548 aRoot = ".";
9549 }
9550 if (aPath === "") {
9551 aPath = ".";
9552 }
9553 var aPathUrl = urlParse(aPath);
9554 var aRootUrl = urlParse(aRoot);
9555 if (aRootUrl) {
9556 aRoot = aRootUrl.path || '/';
9557 }
9558
9559 // `join(foo, '//www.example.org')`
9560 if (aPathUrl && !aPathUrl.scheme) {
9561 if (aRootUrl) {
9562 aPathUrl.scheme = aRootUrl.scheme;
9563 }
9564 return urlGenerate(aPathUrl);
9565 }
9566
9567 if (aPathUrl || aPath.match(dataUrlRegexp)) {
9568 return aPath;
9569 }
9570
9571 // `join('http://', 'www.example.com')`
9572 if (aRootUrl && !aRootUrl.host && !aRootUrl.path) {
9573 aRootUrl.host = aPath;
9574 return urlGenerate(aRootUrl);
9575 }
9576
9577 var joined = aPath.charAt(0) === '/'
9578 ? aPath
9579 : normalize(aRoot.replace(/\/+$/, '') + '/' + aPath);
9580
9581 if (aRootUrl) {
9582 aRootUrl.path = joined;
9583 return urlGenerate(aRootUrl);
9584 }
9585 return joined;
9586 }
9587 exports.join = join;
9588
9589 exports.isAbsolute = function (aPath) {
9590 return aPath.charAt(0) === '/' || urlRegexp.test(aPath);
9591 };
9592
9593 /**
9594 * Make a path relative to a URL or another path.
9595 *
9596 * @param aRoot The root path or URL.
9597 * @param aPath The path or URL to be made relative to aRoot.
9598 */
9599 function relative(aRoot, aPath) {
9600 if (aRoot === "") {
9601 aRoot = ".";
9602 }
9603
9604 aRoot = aRoot.replace(/\/$/, '');
9605
9606 // It is possible for the path to be above the root. In this case, simply
9607 // checking whether the root is a prefix of the path won't work. Instead, we
9608 // need to remove components from the root one by one, until either we find
9609 // a prefix that fits, or we run out of components to remove.
9610 var level = 0;
9611 while (aPath.indexOf(aRoot + '/') !== 0) {
9612 var index = aRoot.lastIndexOf("/");
9613 if (index < 0) {
9614 return aPath;
9615 }
9616
9617 // If the only part of the root that is left is the scheme (i.e. http://,
9618 // file:///, etc.), one or more slashes (/), or simply nothing at all, we
9619 // have exhausted all components, so the path is not relative to the root.
9620 aRoot = aRoot.slice(0, index);
9621 if (aRoot.match(/^([^\/]+:\/)?\/*$/)) {
9622 return aPath;
9623 }
9624
9625 ++level;
9626 }
9627
9628 // Make sure we add a "../" for each component we removed from the root.
9629 return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1);
9630 }
9631 exports.relative = relative;
9632
9633 var supportsNullProto = (function () {
9634 var obj = Object.create(null);
9635 return !('__proto__' in obj);
9636 }());
9637
9638 function identity (s) {
9639 return s;
9640 }
9641
9642 /**
9643 * Because behavior goes wacky when you set `__proto__` on objects, we
9644 * have to prefix all the strings in our set with an arbitrary character.
9645 *
9646 * See https://github.com/mozilla/source-map/pull/31 and
9647 * https://github.com/mozilla/source-map/issues/30
9648 *
9649 * @param String aStr
9650 */
9651 function toSetString(aStr) {
9652 if (isProtoString(aStr)) {
9653 return '$' + aStr;
9654 }
9655
9656 return aStr;
9657 }
9658 exports.toSetString = supportsNullProto ? identity : toSetString;
9659
9660 function fromSetString(aStr) {
9661 if (isProtoString(aStr)) {
9662 return aStr.slice(1);
9663 }
9664
9665 return aStr;
9666 }
9667 exports.fromSetString = supportsNullProto ? identity : fromSetString;
9668
9669 function isProtoString(s) {
9670 if (!s) {
9671 return false;
9672 }
9673
9674 var length = s.length;
9675
9676 if (length < 9 /* "__proto__".length */) {
9677 return false;
9678 }
9679
9680 if (s.charCodeAt(length - 1) !== 95 /* '_' */ ||
9681 s.charCodeAt(length - 2) !== 95 /* '_' */ ||
9682 s.charCodeAt(length - 3) !== 111 /* 'o' */ ||
9683 s.charCodeAt(length - 4) !== 116 /* 't' */ ||
9684 s.charCodeAt(length - 5) !== 111 /* 'o' */ ||
9685 s.charCodeAt(length - 6) !== 114 /* 'r' */ ||
9686 s.charCodeAt(length - 7) !== 112 /* 'p' */ ||
9687 s.charCodeAt(length - 8) !== 95 /* '_' */ ||
9688 s.charCodeAt(length - 9) !== 95 /* '_' */) {
9689 return false;
9690 }
9691
9692 for (var i = length - 10; i >= 0; i--) {
9693 if (s.charCodeAt(i) !== 36 /* '$' */) {
9694 return false;
9695 }
9696 }
9697
9698 return true;
9699 }
9700
9701 /**
9702 * Comparator between two mappings where the original positions are compared.
9703 *
9704 * Optionally pass in `true` as `onlyCompareGenerated` to consider two
9705 * mappings with the same original source/line/column, but different generated
9706 * line and column the same. Useful when searching for a mapping with a
9707 * stubbed out mapping.
9708 */
9709 function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {
9710 var cmp = strcmp(mappingA.source, mappingB.source);
9711 if (cmp !== 0) {
9712 return cmp;
9713 }
9714
9715 cmp = mappingA.originalLine - mappingB.originalLine;
9716 if (cmp !== 0) {
9717 return cmp;
9718 }
9719
9720 cmp = mappingA.originalColumn - mappingB.originalColumn;
9721 if (cmp !== 0 || onlyCompareOriginal) {
9722 return cmp;
9723 }
9724
9725 cmp = mappingA.generatedColumn - mappingB.generatedColumn;
9726 if (cmp !== 0) {
9727 return cmp;
9728 }
9729
9730 cmp = mappingA.generatedLine - mappingB.generatedLine;
9731 if (cmp !== 0) {
9732 return cmp;
9733 }
9734
9735 return strcmp(mappingA.name, mappingB.name);
9736 }
9737 exports.compareByOriginalPositions = compareByOriginalPositions;
9738
9739 /**
9740 * Comparator between two mappings with deflated source and name indices where
9741 * the generated positions are compared.
9742 *
9743 * Optionally pass in `true` as `onlyCompareGenerated` to consider two
9744 * mappings with the same generated line and column, but different
9745 * source/name/original line and column the same. Useful when searching for a
9746 * mapping with a stubbed out mapping.
9747 */
9748 function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) {
9749 var cmp = mappingA.generatedLine - mappingB.generatedLine;
9750 if (cmp !== 0) {
9751 return cmp;
9752 }
9753
9754 cmp = mappingA.generatedColumn - mappingB.generatedColumn;
9755 if (cmp !== 0 || onlyCompareGenerated) {
9756 return cmp;
9757 }
9758
9759 cmp = strcmp(mappingA.source, mappingB.source);
9760 if (cmp !== 0) {
9761 return cmp;
9762 }
9763
9764 cmp = mappingA.originalLine - mappingB.originalLine;
9765 if (cmp !== 0) {
9766 return cmp;
9767 }
9768
9769 cmp = mappingA.originalColumn - mappingB.originalColumn;
9770 if (cmp !== 0) {
9771 return cmp;
9772 }
9773
9774 return strcmp(mappingA.name, mappingB.name);
9775 }
9776 exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated;
9777
9778 function strcmp(aStr1, aStr2) {
9779 if (aStr1 === aStr2) {
9780 return 0;
9781 }
9782
9783 if (aStr1 === null) {
9784 return 1; // aStr2 !== null
9785 }
9786
9787 if (aStr2 === null) {
9788 return -1; // aStr1 !== null
9789 }
9790
9791 if (aStr1 > aStr2) {
9792 return 1;
9793 }
9794
9795 return -1;
9796 }
9797
9798 /**
9799 * Comparator between two mappings with inflated source and name strings where
9800 * the generated positions are compared.
9801 */
9802 function compareByGeneratedPositionsInflated(mappingA, mappingB) {
9803 var cmp = mappingA.generatedLine - mappingB.generatedLine;
9804 if (cmp !== 0) {
9805 return cmp;
9806 }
9807
9808 cmp = mappingA.generatedColumn - mappingB.generatedColumn;
9809 if (cmp !== 0) {
9810 return cmp;
9811 }
9812
9813 cmp = strcmp(mappingA.source, mappingB.source);
9814 if (cmp !== 0) {
9815 return cmp;
9816 }
9817
9818 cmp = mappingA.originalLine - mappingB.originalLine;
9819 if (cmp !== 0) {
9820 return cmp;
9821 }
9822
9823 cmp = mappingA.originalColumn - mappingB.originalColumn;
9824 if (cmp !== 0) {
9825 return cmp;
9826 }
9827
9828 return strcmp(mappingA.name, mappingB.name);
9829 }
9830 exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated;
9831
9832 /**
9833 * Strip any JSON XSSI avoidance prefix from the string (as documented
9834 * in the source maps specification), and then parse the string as
9835 * JSON.
9836 */
9837 function parseSourceMapInput(str) {
9838 return JSON.parse(str.replace(/^\)]}'[^\n]*\n/, ''));
9839 }
9840 exports.parseSourceMapInput = parseSourceMapInput;
9841
9842 /**
9843 * Compute the URL of a source given the the source root, the source's
9844 * URL, and the source map's URL.
9845 */
9846 function computeSourceURL(sourceRoot, sourceURL, sourceMapURL) {
9847 sourceURL = sourceURL || '';
9848
9849 if (sourceRoot) {
9850 // This follows what Chrome does.
9851 if (sourceRoot[sourceRoot.length - 1] !== '/' && sourceURL[0] !== '/') {
9852 sourceRoot += '/';
9853 }
9854 // The spec says:
9855 // Line 4: An optional source root, useful for relocating source
9856 // files on a server or removing repeated values in the
9857 // “sources” entry. This value is prepended to the individual
9858 // entries in the “source” field.
9859 sourceURL = sourceRoot + sourceURL;
9860 }
9861
9862 // Historically, SourceMapConsumer did not take the sourceMapURL as
9863 // a parameter. This mode is still somewhat supported, which is why
9864 // this code block is conditional. However, it's preferable to pass
9865 // the source map URL to SourceMapConsumer, so that this function
9866 // can implement the source URL resolution algorithm as outlined in
9867 // the spec. This block is basically the equivalent of:
9868 // new URL(sourceURL, sourceMapURL).toString()
9869 // ... except it avoids using URL, which wasn't available in the
9870 // older releases of node still supported by this library.
9871 //
9872 // The spec says:
9873 // If the sources are not absolute URLs after prepending of the
9874 // “sourceRoot”, the sources are resolved relative to the
9875 // SourceMap (like resolving script src in a html document).
9876 if (sourceMapURL) {
9877 var parsed = urlParse(sourceMapURL);
9878 if (!parsed) {
9879 throw new Error("sourceMapURL could not be parsed");
9880 }
9881 if (parsed.path) {
9882 // Strip the last path component, but keep the "/".
9883 var index = parsed.path.lastIndexOf('/');
9884 if (index >= 0) {
9885 parsed.path = parsed.path.substring(0, index + 1);
9886 }
9887 }
9888 sourceURL = join(urlGenerate(parsed), sourceURL);
9889 }
9890
9891 return normalize(sourceURL);
9892 }
9893 exports.computeSourceURL = computeSourceURL;
9894 });
9895 var util_1 = util.getArg;
9896 var util_2 = util.urlParse;
9897 var util_3 = util.urlGenerate;
9898 var util_4 = util.normalize;
9899 var util_5 = util.join;
9900 var util_6 = util.isAbsolute;
9901 var util_7 = util.relative;
9902 var util_8 = util.toSetString;
9903 var util_9 = util.fromSetString;
9904 var util_10 = util.compareByOriginalPositions;
9905 var util_11 = util.compareByGeneratedPositionsDeflated;
9906 var util_12 = util.compareByGeneratedPositionsInflated;
9907 var util_13 = util.parseSourceMapInput;
9908 var util_14 = util.computeSourceURL;
9909
9910 /* -*- Mode: js; js-indent-level: 2; -*- */
9911 /*
9912 * Copyright 2011 Mozilla Foundation and contributors
9913 * Licensed under the New BSD license. See LICENSE or:
9914 * http://opensource.org/licenses/BSD-3-Clause
9915 */
9916
9917
9918 var has = Object.prototype.hasOwnProperty;
9919 var hasNativeMap = typeof Map !== "undefined";
9920
9921 /**
9922 * A data structure which is a combination of an array and a set. Adding a new
9923 * member is O(1), testing for membership is O(1), and finding the index of an
9924 * element is O(1). Removing elements from the set is not supported. Only
9925 * strings are supported for membership.
9926 */
9927 function ArraySet() {
9928 this._array = [];
9929 this._set = hasNativeMap ? new Map() : Object.create(null);
9930 }
9931
9932 /**
9933 * Static method for creating ArraySet instances from an existing array.
9934 */
9935 ArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) {
9936 var set = new ArraySet();
9937 for (var i = 0, len = aArray.length; i < len; i++) {
9938 set.add(aArray[i], aAllowDuplicates);
9939 }
9940 return set;
9941 };
9942
9943 /**
9944 * Return how many unique items are in this ArraySet. If duplicates have been
9945 * added, than those do not count towards the size.
9946 *
9947 * @returns Number
9948 */
9949 ArraySet.prototype.size = function ArraySet_size() {
9950 return hasNativeMap ? this._set.size : Object.getOwnPropertyNames(this._set).length;
9951 };
9952
9953 /**
9954 * Add the given string to this set.
9955 *
9956 * @param String aStr
9957 */
9958 ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) {
9959 var sStr = hasNativeMap ? aStr : util.toSetString(aStr);
9960 var isDuplicate = hasNativeMap ? this.has(aStr) : has.call(this._set, sStr);
9961 var idx = this._array.length;
9962 if (!isDuplicate || aAllowDuplicates) {
9963 this._array.push(aStr);
9964 }
9965 if (!isDuplicate) {
9966 if (hasNativeMap) {
9967 this._set.set(aStr, idx);
9968 } else {
9969 this._set[sStr] = idx;
9970 }
9971 }
9972 };
9973
9974 /**
9975 * Is the given string a member of this set?
9976 *
9977 * @param String aStr
9978 */
9979 ArraySet.prototype.has = function ArraySet_has(aStr) {
9980 if (hasNativeMap) {
9981 return this._set.has(aStr);
9982 } else {
9983 var sStr = util.toSetString(aStr);
9984 return has.call(this._set, sStr);
9985 }
9986 };
9987
9988 /**
9989 * What is the index of the given string in the array?
9990 *
9991 * @param String aStr
9992 */
9993 ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) {
9994 if (hasNativeMap) {
9995 var idx = this._set.get(aStr);
9996 if (idx >= 0) {
9997 return idx;
9998 }
9999 } else {
10000 var sStr = util.toSetString(aStr);
10001 if (has.call(this._set, sStr)) {
10002 return this._set[sStr];
10003 }
10004 }
10005
10006 throw new Error('"' + aStr + '" is not in the set.');
10007 };
10008
10009 /**
10010 * What is the element at the given index?
10011 *
10012 * @param Number aIdx
10013 */
10014 ArraySet.prototype.at = function ArraySet_at(aIdx) {
10015 if (aIdx >= 0 && aIdx < this._array.length) {
10016 return this._array[aIdx];
10017 }
10018 throw new Error('No element indexed by ' + aIdx);
10019 };
10020
10021 /**
10022 * Returns the array representation of this set (which has the proper indices
10023 * indicated by indexOf). Note that this is a copy of the internal array used
10024 * for storing the members so that no one can mess with internal state.
10025 */
10026 ArraySet.prototype.toArray = function ArraySet_toArray() {
10027 return this._array.slice();
10028 };
10029
10030 var ArraySet_1 = ArraySet;
10031
10032 var arraySet = {
10033 ArraySet: ArraySet_1
10034 };
10035
10036 /* -*- Mode: js; js-indent-level: 2; -*- */
10037 /*
10038 * Copyright 2014 Mozilla Foundation and contributors
10039 * Licensed under the New BSD license. See LICENSE or:
10040 * http://opensource.org/licenses/BSD-3-Clause
10041 */
10042
10043
10044
10045 /**
10046 * Determine whether mappingB is after mappingA with respect to generated
10047 * position.
10048 */
10049 function generatedPositionAfter(mappingA, mappingB) {
10050 // Optimized for most common case
10051 var lineA = mappingA.generatedLine;
10052 var lineB = mappingB.generatedLine;
10053 var columnA = mappingA.generatedColumn;
10054 var columnB = mappingB.generatedColumn;
10055 return lineB > lineA || lineB == lineA && columnB >= columnA ||
10056 util.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0;
10057 }
10058
10059 /**
10060 * A data structure to provide a sorted view of accumulated mappings in a
10061 * performance conscious manner. It trades a neglibable overhead in general
10062 * case for a large speedup in case of mappings being added in order.
10063 */
10064 function MappingList() {
10065 this._array = [];
10066 this._sorted = true;
10067 // Serves as infimum
10068 this._last = {generatedLine: -1, generatedColumn: 0};
10069 }
10070
10071 /**
10072 * Iterate through internal items. This method takes the same arguments that
10073 * `Array.prototype.forEach` takes.
10074 *
10075 * NOTE: The order of the mappings is NOT guaranteed.
10076 */
10077 MappingList.prototype.unsortedForEach =
10078 function MappingList_forEach(aCallback, aThisArg) {
10079 this._array.forEach(aCallback, aThisArg);
10080 };
10081
10082 /**
10083 * Add the given source mapping.
10084 *
10085 * @param Object aMapping
10086 */
10087 MappingList.prototype.add = function MappingList_add(aMapping) {
10088 if (generatedPositionAfter(this._last, aMapping)) {
10089 this._last = aMapping;
10090 this._array.push(aMapping);
10091 } else {
10092 this._sorted = false;
10093 this._array.push(aMapping);
10094 }
10095 };
10096
10097 /**
10098 * Returns the flat, sorted array of mappings. The mappings are sorted by
10099 * generated position.
10100 *
10101 * WARNING: This method returns internal data without copying, for
10102 * performance. The return value must NOT be mutated, and should be treated as
10103 * an immutable borrow. If you want to take ownership, you must make your own
10104 * copy.
10105 */
10106 MappingList.prototype.toArray = function MappingList_toArray() {
10107 if (!this._sorted) {
10108 this._array.sort(util.compareByGeneratedPositionsInflated);
10109 this._sorted = true;
10110 }
10111 return this._array;
10112 };
10113
10114 var MappingList_1 = MappingList;
10115
10116 var mappingList = {
10117 MappingList: MappingList_1
10118 };
10119
10120 /* -*- Mode: js; js-indent-level: 2; -*- */
10121 /*
10122 * Copyright 2011 Mozilla Foundation and contributors
10123 * Licensed under the New BSD license. See LICENSE or:
10124 * http://opensource.org/licenses/BSD-3-Clause
10125 */
10126
10127
10128
10129 var ArraySet$1 = arraySet.ArraySet;
10130 var MappingList$1 = mappingList.MappingList;
10131
10132 /**
10133 * An instance of the SourceMapGenerator represents a source map which is
10134 * being built incrementally. You may pass an object with the following
10135 * properties:
10136 *
10137 * - file: The filename of the generated source.
10138 * - sourceRoot: A root for all relative URLs in this source map.
10139 */
10140 function SourceMapGenerator(aArgs) {
10141 if (!aArgs) {
10142 aArgs = {};
10143 }
10144 this._file = util.getArg(aArgs, 'file', null);
10145 this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null);
10146 this._skipValidation = util.getArg(aArgs, 'skipValidation', false);
10147 this._sources = new ArraySet$1();
10148 this._names = new ArraySet$1();
10149 this._mappings = new MappingList$1();
10150 this._sourcesContents = null;
10151 }
10152
10153 SourceMapGenerator.prototype._version = 3;
10154
10155 /**
10156 * Creates a new SourceMapGenerator based on a SourceMapConsumer
10157 *
10158 * @param aSourceMapConsumer The SourceMap.
10159 */
10160 SourceMapGenerator.fromSourceMap =
10161 function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) {
10162 var sourceRoot = aSourceMapConsumer.sourceRoot;
10163 var generator = new SourceMapGenerator({
10164 file: aSourceMapConsumer.file,
10165 sourceRoot: sourceRoot
10166 });
10167 aSourceMapConsumer.eachMapping(function (mapping) {
10168 var newMapping = {
10169 generated: {
10170 line: mapping.generatedLine,
10171 column: mapping.generatedColumn
10172 }
10173 };
10174
10175 if (mapping.source != null) {
10176 newMapping.source = mapping.source;
10177 if (sourceRoot != null) {
10178 newMapping.source = util.relative(sourceRoot, newMapping.source);
10179 }
10180
10181 newMapping.original = {
10182 line: mapping.originalLine,
10183 column: mapping.originalColumn
10184 };
10185
10186 if (mapping.name != null) {
10187 newMapping.name = mapping.name;
10188 }
10189 }
10190
10191 generator.addMapping(newMapping);
10192 });
10193 aSourceMapConsumer.sources.forEach(function (sourceFile) {
10194 var sourceRelative = sourceFile;
10195 if (sourceRoot !== null) {
10196 sourceRelative = util.relative(sourceRoot, sourceFile);
10197 }
10198
10199 if (!generator._sources.has(sourceRelative)) {
10200 generator._sources.add(sourceRelative);
10201 }
10202
10203 var content = aSourceMapConsumer.sourceContentFor(sourceFile);
10204 if (content != null) {
10205 generator.setSourceContent(sourceFile, content);
10206 }
10207 });
10208 return generator;
10209 };
10210
10211 /**
10212 * Add a single mapping from original source line and column to the generated
10213 * source's line and column for this source map being created. The mapping
10214 * object should have the following properties:
10215 *
10216 * - generated: An object with the generated line and column positions.
10217 * - original: An object with the original line and column positions.
10218 * - source: The original source file (relative to the sourceRoot).
10219 * - name: An optional original token name for this mapping.
10220 */
10221 SourceMapGenerator.prototype.addMapping =
10222 function SourceMapGenerator_addMapping(aArgs) {
10223 var generated = util.getArg(aArgs, 'generated');
10224 var original = util.getArg(aArgs, 'original', null);
10225 var source = util.getArg(aArgs, 'source', null);
10226 var name = util.getArg(aArgs, 'name', null);
10227
10228 if (!this._skipValidation) {
10229 this._validateMapping(generated, original, source, name);
10230 }
10231
10232 if (source != null) {
10233 source = String(source);
10234 if (!this._sources.has(source)) {
10235 this._sources.add(source);
10236 }
10237 }
10238
10239 if (name != null) {
10240 name = String(name);
10241 if (!this._names.has(name)) {
10242 this._names.add(name);
10243 }
10244 }
10245
10246 this._mappings.add({
10247 generatedLine: generated.line,
10248 generatedColumn: generated.column,
10249 originalLine: original != null && original.line,
10250 originalColumn: original != null && original.column,
10251 source: source,
10252 name: name
10253 });
10254 };
10255
10256 /**
10257 * Set the source content for a source file.
10258 */
10259 SourceMapGenerator.prototype.setSourceContent =
10260 function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) {
10261 var source = aSourceFile;
10262 if (this._sourceRoot != null) {
10263 source = util.relative(this._sourceRoot, source);
10264 }
10265
10266 if (aSourceContent != null) {
10267 // Add the source content to the _sourcesContents map.
10268 // Create a new _sourcesContents map if the property is null.
10269 if (!this._sourcesContents) {
10270 this._sourcesContents = Object.create(null);
10271 }
10272 this._sourcesContents[util.toSetString(source)] = aSourceContent;
10273 } else if (this._sourcesContents) {
10274 // Remove the source file from the _sourcesContents map.
10275 // If the _sourcesContents map is empty, set the property to null.
10276 delete this._sourcesContents[util.toSetString(source)];
10277 if (Object.keys(this._sourcesContents).length === 0) {
10278 this._sourcesContents = null;
10279 }
10280 }
10281 };
10282
10283 /**
10284 * Applies the mappings of a sub-source-map for a specific source file to the
10285 * source map being generated. Each mapping to the supplied source file is
10286 * rewritten using the supplied source map. Note: The resolution for the
10287 * resulting mappings is the minimium of this map and the supplied map.
10288 *
10289 * @param aSourceMapConsumer The source map to be applied.
10290 * @param aSourceFile Optional. The filename of the source file.
10291 * If omitted, SourceMapConsumer's file property will be used.
10292 * @param aSourceMapPath Optional. The dirname of the path to the source map
10293 * to be applied. If relative, it is relative to the SourceMapConsumer.
10294 * This parameter is needed when the two source maps aren't in the same
10295 * directory, and the source map to be applied contains relative source
10296 * paths. If so, those relative source paths need to be rewritten
10297 * relative to the SourceMapGenerator.
10298 */
10299 SourceMapGenerator.prototype.applySourceMap =
10300 function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) {
10301 var sourceFile = aSourceFile;
10302 // If aSourceFile is omitted, we will use the file property of the SourceMap
10303 if (aSourceFile == null) {
10304 if (aSourceMapConsumer.file == null) {
10305 throw new Error(
10306 'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' +
10307 'or the source map\'s "file" property. Both were omitted.'
10308 );
10309 }
10310 sourceFile = aSourceMapConsumer.file;
10311 }
10312 var sourceRoot = this._sourceRoot;
10313 // Make "sourceFile" relative if an absolute Url is passed.
10314 if (sourceRoot != null) {
10315 sourceFile = util.relative(sourceRoot, sourceFile);
10316 }
10317 // Applying the SourceMap can add and remove items from the sources and
10318 // the names array.
10319 var newSources = new ArraySet$1();
10320 var newNames = new ArraySet$1();
10321
10322 // Find mappings for the "sourceFile"
10323 this._mappings.unsortedForEach(function (mapping) {
10324 if (mapping.source === sourceFile && mapping.originalLine != null) {
10325 // Check if it can be mapped by the source map, then update the mapping.
10326 var original = aSourceMapConsumer.originalPositionFor({
10327 line: mapping.originalLine,
10328 column: mapping.originalColumn
10329 });
10330 if (original.source != null) {
10331 // Copy mapping
10332 mapping.source = original.source;
10333 if (aSourceMapPath != null) {
10334 mapping.source = util.join(aSourceMapPath, mapping.source);
10335 }
10336 if (sourceRoot != null) {
10337 mapping.source = util.relative(sourceRoot, mapping.source);
10338 }
10339 mapping.originalLine = original.line;
10340 mapping.originalColumn = original.column;
10341 if (original.name != null) {
10342 mapping.name = original.name;
10343 }
10344 }
10345 }
10346
10347 var source = mapping.source;
10348 if (source != null && !newSources.has(source)) {
10349 newSources.add(source);
10350 }
10351
10352 var name = mapping.name;
10353 if (name != null && !newNames.has(name)) {
10354 newNames.add(name);
10355 }
10356
10357 }, this);
10358 this._sources = newSources;
10359 this._names = newNames;
10360
10361 // Copy sourcesContents of applied map.
10362 aSourceMapConsumer.sources.forEach(function (sourceFile) {
10363 var content = aSourceMapConsumer.sourceContentFor(sourceFile);
10364 if (content != null) {
10365 if (aSourceMapPath != null) {
10366 sourceFile = util.join(aSourceMapPath, sourceFile);
10367 }
10368 if (sourceRoot != null) {
10369 sourceFile = util.relative(sourceRoot, sourceFile);
10370 }
10371 this.setSourceContent(sourceFile, content);
10372 }
10373 }, this);
10374 };
10375
10376 /**
10377 * A mapping can have one of the three levels of data:
10378 *
10379 * 1. Just the generated position.
10380 * 2. The Generated position, original position, and original source.
10381 * 3. Generated and original position, original source, as well as a name
10382 * token.
10383 *
10384 * To maintain consistency, we validate that any new mapping being added falls
10385 * in to one of these categories.
10386 */
10387 SourceMapGenerator.prototype._validateMapping =
10388 function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource,
10389 aName) {
10390 // When aOriginal is truthy but has empty values for .line and .column,
10391 // it is most likely a programmer error. In this case we throw a very
10392 // specific error message to try to guide them the right way.
10393 // For example: https://github.com/Polymer/polymer-bundler/pull/519
10394 if (aOriginal && typeof aOriginal.line !== 'number' && typeof aOriginal.column !== 'number') {
10395 throw new Error(
10396 'original.line and original.column are not numbers -- you probably meant to omit ' +
10397 'the original mapping entirely and only map the generated position. If so, pass ' +
10398 'null for the original mapping instead of an object with empty or null values.'
10399 );
10400 }
10401
10402 if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
10403 && aGenerated.line > 0 && aGenerated.column >= 0
10404 && !aOriginal && !aSource && !aName) {
10405 // Case 1.
10406 return;
10407 }
10408 else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
10409 && aOriginal && 'line' in aOriginal && 'column' in aOriginal
10410 && aGenerated.line > 0 && aGenerated.column >= 0
10411 && aOriginal.line > 0 && aOriginal.column >= 0
10412 && aSource) {
10413 // Cases 2 and 3.
10414 return;
10415 }
10416 else {
10417 throw new Error('Invalid mapping: ' + JSON.stringify({
10418 generated: aGenerated,
10419 source: aSource,
10420 original: aOriginal,
10421 name: aName
10422 }));
10423 }
10424 };
10425
10426 /**
10427 * Serialize the accumulated mappings in to the stream of base 64 VLQs
10428 * specified by the source map format.
10429 */
10430 SourceMapGenerator.prototype._serializeMappings =
10431 function SourceMapGenerator_serializeMappings() {
10432 var previousGeneratedColumn = 0;
10433 var previousGeneratedLine = 1;
10434 var previousOriginalColumn = 0;
10435 var previousOriginalLine = 0;
10436 var previousName = 0;
10437 var previousSource = 0;
10438 var result = '';
10439 var next;
10440 var mapping;
10441 var nameIdx;
10442 var sourceIdx;
10443
10444 var mappings = this._mappings.toArray();
10445 for (var i = 0, len = mappings.length; i < len; i++) {
10446 mapping = mappings[i];
10447 next = '';
10448
10449 if (mapping.generatedLine !== previousGeneratedLine) {
10450 previousGeneratedColumn = 0;
10451 while (mapping.generatedLine !== previousGeneratedLine) {
10452 next += ';';
10453 previousGeneratedLine++;
10454 }
10455 }
10456 else {
10457 if (i > 0) {
10458 if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) {
10459 continue;
10460 }
10461 next += ',';
10462 }
10463 }
10464
10465 next += base64Vlq.encode(mapping.generatedColumn
10466 - previousGeneratedColumn);
10467 previousGeneratedColumn = mapping.generatedColumn;
10468
10469 if (mapping.source != null) {
10470 sourceIdx = this._sources.indexOf(mapping.source);
10471 next += base64Vlq.encode(sourceIdx - previousSource);
10472 previousSource = sourceIdx;
10473
10474 // lines are stored 0-based in SourceMap spec version 3
10475 next += base64Vlq.encode(mapping.originalLine - 1
10476 - previousOriginalLine);
10477 previousOriginalLine = mapping.originalLine - 1;
10478
10479 next += base64Vlq.encode(mapping.originalColumn
10480 - previousOriginalColumn);
10481 previousOriginalColumn = mapping.originalColumn;
10482
10483 if (mapping.name != null) {
10484 nameIdx = this._names.indexOf(mapping.name);
10485 next += base64Vlq.encode(nameIdx - previousName);
10486 previousName = nameIdx;
10487 }
10488 }
10489
10490 result += next;
10491 }
10492
10493 return result;
10494 };
10495
10496 SourceMapGenerator.prototype._generateSourcesContent =
10497 function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) {
10498 return aSources.map(function (source) {
10499 if (!this._sourcesContents) {
10500 return null;
10501 }
10502 if (aSourceRoot != null) {
10503 source = util.relative(aSourceRoot, source);
10504 }
10505 var key = util.toSetString(source);
10506 return Object.prototype.hasOwnProperty.call(this._sourcesContents, key)
10507 ? this._sourcesContents[key]
10508 : null;
10509 }, this);
10510 };
10511
10512 /**
10513 * Externalize the source map.
10514 */
10515 SourceMapGenerator.prototype.toJSON =
10516 function SourceMapGenerator_toJSON() {
10517 var map = {
10518 version: this._version,
10519 sources: this._sources.toArray(),
10520 names: this._names.toArray(),
10521 mappings: this._serializeMappings()
10522 };
10523 if (this._file != null) {
10524 map.file = this._file;
10525 }
10526 if (this._sourceRoot != null) {
10527 map.sourceRoot = this._sourceRoot;
10528 }
10529 if (this._sourcesContents) {
10530 map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot);
10531 }
10532
10533 return map;
10534 };
10535
10536 /**
10537 * Render the source map being generated to a string.
10538 */
10539 SourceMapGenerator.prototype.toString =
10540 function SourceMapGenerator_toString() {
10541 return JSON.stringify(this.toJSON());
10542 };
10543
10544 var SourceMapGenerator_1 = SourceMapGenerator;
10545
10546 var sourceMapGenerator = {
10547 SourceMapGenerator: SourceMapGenerator_1
10548 };
10549
10550 var SourceMapGenerator$1 = sourceMapGenerator.SourceMapGenerator;
10551 var trackNodes = {
10552 Atrule: true,
10553 Selector: true,
10554 Declaration: true
10555 };
10556
10557 var sourceMap = function generateSourceMap(handlers) {
10558 var map = new SourceMapGenerator$1();
10559 var line = 1;
10560 var column = 0;
10561 var generated = {
10562 line: 1,
10563 column: 0
10564 };
10565 var original = {
10566 line: 0, // should be zero to add first mapping
10567 column: 0
10568 };
10569 var sourceMappingActive = false;
10570 var activatedGenerated = {
10571 line: 1,
10572 column: 0
10573 };
10574 var activatedMapping = {
10575 generated: activatedGenerated
10576 };
10577
10578 var handlersNode = handlers.node;
10579 handlers.node = function(node) {
10580 if (node.loc && node.loc.start && trackNodes.hasOwnProperty(node.type)) {
10581 var nodeLine = node.loc.start.line;
10582 var nodeColumn = node.loc.start.column - 1;
10583
10584 if (original.line !== nodeLine ||
10585 original.column !== nodeColumn) {
10586 original.line = nodeLine;
10587 original.column = nodeColumn;
10588
10589 generated.line = line;
10590 generated.column = column;
10591
10592 if (sourceMappingActive) {
10593 sourceMappingActive = false;
10594 if (generated.line !== activatedGenerated.line ||
10595 generated.column !== activatedGenerated.column) {
10596 map.addMapping(activatedMapping);
10597 }
10598 }
10599
10600 sourceMappingActive = true;
10601 map.addMapping({
10602 source: node.loc.source,
10603 original: original,
10604 generated: generated
10605 });
10606 }
10607 }
10608
10609 handlersNode.call(this, node);
10610
10611 if (sourceMappingActive && trackNodes.hasOwnProperty(node.type)) {
10612 activatedGenerated.line = line;
10613 activatedGenerated.column = column;
10614 }
10615 };
10616
10617 var handlersChunk = handlers.chunk;
10618 handlers.chunk = function(chunk) {
10619 for (var i = 0; i < chunk.length; i++) {
10620 if (chunk.charCodeAt(i) === 10) { // \n
10621 line++;
10622 column = 0;
10623 } else {
10624 column++;
10625 }
10626 }
10627
10628 handlersChunk(chunk);
10629 };
10630
10631 var handlersResult = handlers.result;
10632 handlers.result = function() {
10633 if (sourceMappingActive) {
10634 map.addMapping(activatedMapping);
10635 }
10636
10637 return {
10638 css: handlersResult(),
10639 map: map
10640 };
10641 };
10642
10643 return handlers;
10644 };
10645
10646 var hasOwnProperty$3 = Object.prototype.hasOwnProperty;
10647
10648 function processChildren(node, delimeter) {
10649 var list = node.children;
10650 var prev = null;
10651
10652 if (typeof delimeter !== 'function') {
10653 list.forEach(this.node, this);
10654 } else {
10655 list.forEach(function(node) {
10656 if (prev !== null) {
10657 delimeter.call(this, prev);
10658 }
10659
10660 this.node(node);
10661 prev = node;
10662 }, this);
10663 }
10664 }
10665
10666 var create$2 = function createGenerator(config) {
10667 function processNode(node) {
10668 if (hasOwnProperty$3.call(types, node.type)) {
10669 types[node.type].call(this, node);
10670 } else {
10671 throw new Error('Unknown node type: ' + node.type);
10672 }
10673 }
10674
10675 var types = {};
10676
10677 if (config.node) {
10678 for (var name in config.node) {
10679 types[name] = config.node[name].generate;
10680 }
10681 }
10682
10683 return function(node, options) {
10684 var buffer = '';
10685 var handlers = {
10686 children: processChildren,
10687 node: processNode,
10688 chunk: function(chunk) {
10689 buffer += chunk;
10690 },
10691 result: function() {
10692 return buffer;
10693 }
10694 };
10695
10696 if (options) {
10697 if (typeof options.decorator === 'function') {
10698 handlers = options.decorator(handlers);
10699 }
10700
10701 if (options.sourceMap) {
10702 handlers = sourceMap(handlers);
10703 }
10704 }
10705
10706 handlers.node(node);
10707
10708 return handlers.result();
10709 };
10710 };
10711
10712 var create$3 = function createConvertors(walk) {
10713 return {
10714 fromPlainObject: function(ast) {
10715 walk(ast, {
10716 enter: function(node) {
10717 if (node.children && node.children instanceof List_1 === false) {
10718 node.children = new List_1().fromArray(node.children);
10719 }
10720 }
10721 });
10722
10723 return ast;
10724 },
10725 toPlainObject: function(ast) {
10726 walk(ast, {
10727 leave: function(node) {
10728 if (node.children && node.children instanceof List_1) {
10729 node.children = node.children.toArray();
10730 }
10731 }
10732 });
10733
10734 return ast;
10735 }
10736 };
10737 };
10738
10739 var hasOwnProperty$4 = Object.prototype.hasOwnProperty;
10740 var noop$4 = function() {};
10741
10742 function ensureFunction$1(value) {
10743 return typeof value === 'function' ? value : noop$4;
10744 }
10745
10746 function invokeForType(fn, type) {
10747 return function(node, item, list) {
10748 if (node.type === type) {
10749 fn.call(this, node, item, list);
10750 }
10751 };
10752 }
10753
10754 function getWalkersFromStructure(name, nodeType) {
10755 var structure = nodeType.structure;
10756 var walkers = [];
10757
10758 for (var key in structure) {
10759 if (hasOwnProperty$4.call(structure, key) === false) {
10760 continue;
10761 }
10762
10763 var fieldTypes = structure[key];
10764 var walker = {
10765 name: key,
10766 type: false,
10767 nullable: false
10768 };
10769
10770 if (!Array.isArray(structure[key])) {
10771 fieldTypes = [structure[key]];
10772 }
10773
10774 for (var i = 0; i < fieldTypes.length; i++) {
10775 var fieldType = fieldTypes[i];
10776 if (fieldType === null) {
10777 walker.nullable = true;
10778 } else if (typeof fieldType === 'string') {
10779 walker.type = 'node';
10780 } else if (Array.isArray(fieldType)) {
10781 walker.type = 'list';
10782 }
10783 }
10784
10785 if (walker.type) {
10786 walkers.push(walker);
10787 }
10788 }
10789
10790 if (walkers.length) {
10791 return {
10792 context: nodeType.walkContext,
10793 fields: walkers
10794 };
10795 }
10796
10797 return null;
10798 }
10799
10800 function getTypesFromConfig(config) {
10801 var types = {};
10802
10803 for (var name in config.node) {
10804 if (hasOwnProperty$4.call(config.node, name)) {
10805 var nodeType = config.node[name];
10806
10807 if (!nodeType.structure) {
10808 throw new Error('Missed `structure` field in `' + name + '` node type definition');
10809 }
10810
10811 types[name] = getWalkersFromStructure(name, nodeType);
10812 }
10813 }
10814
10815 return types;
10816 }
10817
10818 function createTypeIterator(config, reverse) {
10819 var fields = config.fields.slice();
10820 var contextName = config.context;
10821 var useContext = typeof contextName === 'string';
10822
10823 if (reverse) {
10824 fields.reverse();
10825 }
10826
10827 return function(node, context, walk) {
10828 var prevContextValue;
10829
10830 if (useContext) {
10831 prevContextValue = context[contextName];
10832 context[contextName] = node;
10833 }
10834
10835 for (var i = 0; i < fields.length; i++) {
10836 var field = fields[i];
10837 var ref = node[field.name];
10838
10839 if (!field.nullable || ref) {
10840 if (field.type === 'list') {
10841 if (reverse) {
10842 ref.forEachRight(walk);
10843 } else {
10844 ref.forEach(walk);
10845 }
10846 } else {
10847 walk(ref);
10848 }
10849 }
10850 }
10851
10852 if (useContext) {
10853 context[contextName] = prevContextValue;
10854 }
10855 };
10856 }
10857
10858 function createFastTraveralMap(iterators) {
10859 return {
10860 Atrule: {
10861 StyleSheet: iterators.StyleSheet,
10862 Atrule: iterators.Atrule,
10863 Rule: iterators.Rule,
10864 Block: iterators.Block
10865 },
10866 Rule: {
10867 StyleSheet: iterators.StyleSheet,
10868 Atrule: iterators.Atrule,
10869 Rule: iterators.Rule,
10870 Block: iterators.Block
10871 },
10872 Declaration: {
10873 StyleSheet: iterators.StyleSheet,
10874 Atrule: iterators.Atrule,
10875 Rule: iterators.Rule,
10876 Block: iterators.Block,
10877 DeclarationList: iterators.DeclarationList
10878 }
10879 };
10880 }
10881
10882 var create$4 = function createWalker(config) {
10883 var types = getTypesFromConfig(config);
10884 var iteratorsNatural = {};
10885 var iteratorsReverse = {};
10886
10887 for (var name in types) {
10888 if (hasOwnProperty$4.call(types, name) && types[name] !== null) {
10889 iteratorsNatural[name] = createTypeIterator(types[name], false);
10890 iteratorsReverse[name] = createTypeIterator(types[name], true);
10891 }
10892 }
10893
10894 var fastTraversalIteratorsNatural = createFastTraveralMap(iteratorsNatural);
10895 var fastTraversalIteratorsReverse = createFastTraveralMap(iteratorsReverse);
10896
10897 var walk = function(root, options) {
10898 function walkNode(node, item, list) {
10899 enter.call(context, node, item, list);
10900
10901 if (iterators.hasOwnProperty(node.type)) {
10902 iterators[node.type](node, context, walkNode);
10903 }
10904
10905 leave.call(context, node, item, list);
10906 }
10907
10908 var enter = noop$4;
10909 var leave = noop$4;
10910 var iterators = iteratorsNatural;
10911 var context = {
10912 root: root,
10913 stylesheet: null,
10914 atrule: null,
10915 atrulePrelude: null,
10916 rule: null,
10917 selector: null,
10918 block: null,
10919 declaration: null,
10920 function: null
10921 };
10922
10923 if (typeof options === 'function') {
10924 enter = options;
10925 } else if (options) {
10926 enter = ensureFunction$1(options.enter);
10927 leave = ensureFunction$1(options.leave);
10928
10929 if (options.reverse) {
10930 iterators = iteratorsReverse;
10931 }
10932
10933 if (options.visit) {
10934 if (fastTraversalIteratorsNatural.hasOwnProperty(options.visit)) {
10935 iterators = options.reverse
10936 ? fastTraversalIteratorsReverse[options.visit]
10937 : fastTraversalIteratorsNatural[options.visit];
10938 } else if (!types.hasOwnProperty(options.visit)) {
10939 throw new Error('Bad value `' + options.visit + '` for `visit` option (should be: ' + Object.keys(types).join(', ') + ')');
10940 }
10941
10942 enter = invokeForType(enter, options.visit);
10943 leave = invokeForType(leave, options.visit);
10944 }
10945 }
10946
10947 if (enter === noop$4 && leave === noop$4) {
10948 throw new Error('Neither `enter` nor `leave` walker handler is set or both aren\'t a function');
10949 }
10950
10951 // swap handlers in reverse mode to invert visit order
10952 if (options.reverse) {
10953 var tmp = enter;
10954 enter = leave;
10955 leave = tmp;
10956 }
10957
10958 walkNode(root);
10959 };
10960
10961 walk.find = function(ast, fn) {
10962 var found = null;
10963
10964 walk(ast, function(node, item, list) {
10965 if (found === null && fn.call(this, node, item, list)) {
10966 found = node;
10967 }
10968 });
10969
10970 return found;
10971 };
10972
10973 walk.findLast = function(ast, fn) {
10974 var found = null;
10975
10976 walk(ast, {
10977 reverse: true,
10978 enter: function(node, item, list) {
10979 if (found === null && fn.call(this, node, item, list)) {
10980 found = node;
10981 }
10982 }
10983 });
10984
10985 return found;
10986 };
10987
10988 walk.findAll = function(ast, fn) {
10989 var found = [];
10990
10991 walk(ast, function(node, item, list) {
10992 if (fn.call(this, node, item, list)) {
10993 found.push(node);
10994 }
10995 });
10996
10997 return found;
10998 };
10999
11000 return walk;
11001 };
11002
11003 var clone = function clone(node) {
11004 var result = {};
11005
11006 for (var key in node) {
11007 var value = node[key];
11008
11009 if (value) {
11010 if (Array.isArray(value) || value instanceof List_1) {
11011 value = value.map(clone);
11012 } else if (value.constructor === Object) {
11013 value = clone(value);
11014 }
11015 }
11016
11017 result[key] = value;
11018 }
11019
11020 return result;
11021 };
11022
11023 var hasOwnProperty$5 = Object.prototype.hasOwnProperty;
11024 var shape = {
11025 generic: true,
11026 types: {},
11027 atrules: {},
11028 properties: {},
11029 parseContext: {},
11030 scope: {},
11031 atrule: ['parse'],
11032 pseudo: ['parse'],
11033 node: ['name', 'structure', 'parse', 'generate', 'walkContext']
11034 };
11035
11036 function isObject(value) {
11037 return value && value.constructor === Object;
11038 }
11039
11040 function copy(value) {
11041 if (isObject(value)) {
11042 return Object.assign({}, value);
11043 } else {
11044 return value;
11045 }
11046 }
11047 function extend(dest, src) {
11048 for (var key in src) {
11049 if (hasOwnProperty$5.call(src, key)) {
11050 if (isObject(dest[key])) {
11051 extend(dest[key], copy(src[key]));
11052 } else {
11053 dest[key] = copy(src[key]);
11054 }
11055 }
11056 }
11057 }
11058
11059 function mix(dest, src, shape) {
11060 for (var key in shape) {
11061 if (hasOwnProperty$5.call(shape, key) === false) {
11062 continue;
11063 }
11064
11065 if (shape[key] === true) {
11066 if (key in src) {
11067 if (hasOwnProperty$5.call(src, key)) {
11068 dest[key] = copy(src[key]);
11069 }
11070 }
11071 } else if (shape[key]) {
11072 if (isObject(shape[key])) {
11073 var res = {};
11074 extend(res, dest[key]);
11075 extend(res, src[key]);
11076 dest[key] = res;
11077 } else if (Array.isArray(shape[key])) {
11078 var res = {};
11079 var innerShape = shape[key].reduce(function(s, k) {
11080 s[k] = true;
11081 return s;
11082 }, {});
11083 for (var name in dest[key]) {
11084 if (hasOwnProperty$5.call(dest[key], name)) {
11085 res[name] = {};
11086 if (dest[key] && dest[key][name]) {
11087 mix(res[name], dest[key][name], innerShape);
11088 }
11089 }
11090 }
11091 for (var name in src[key]) {
11092 if (hasOwnProperty$5.call(src[key], name)) {
11093 if (!res[name]) {
11094 res[name] = {};
11095 }
11096 if (src[key] && src[key][name]) {
11097 mix(res[name], src[key][name], innerShape);
11098 }
11099 }
11100 }
11101 dest[key] = res;
11102 }
11103 }
11104 }
11105 return dest;
11106 }
11107
11108 var mix_1 = function(dest, src) {
11109 return mix(dest, src, shape);
11110 };
11111
11112 function createSyntax(config) {
11113 var parse = create$1(config);
11114 var walk = create$4(config);
11115 var generate = create$2(config);
11116 var convert = create$3(walk);
11117
11118 var syntax = {
11119 List: List_1,
11120 SyntaxError: _SyntaxError,
11121 TokenStream: TokenStream_1,
11122 Lexer: Lexer_1,
11123
11124 vendorPrefix: names.vendorPrefix,
11125 keyword: names.keyword,
11126 property: names.property,
11127 isCustomProperty: names.isCustomProperty,
11128
11129 definitionSyntax: definitionSyntax,
11130 lexer: null,
11131 createLexer: function(config) {
11132 return new Lexer_1(config, syntax, syntax.lexer.structure);
11133 },
11134
11135 tokenize: tokenizer,
11136 parse: parse,
11137 walk: walk,
11138 generate: generate,
11139
11140 find: walk.find,
11141 findLast: walk.findLast,
11142 findAll: walk.findAll,
11143
11144 clone: clone,
11145 fromPlainObject: convert.fromPlainObject,
11146 toPlainObject: convert.toPlainObject,
11147
11148 createSyntax: function(config) {
11149 return createSyntax(mix_1({}, config));
11150 },
11151 fork: function(extension) {
11152 var base = mix_1({}, config); // copy of config
11153 return createSyntax(
11154 typeof extension === 'function'
11155 ? extension(base, Object.assign)
11156 : mix_1(base, extension)
11157 );
11158 }
11159 };
11160
11161 syntax.lexer = new Lexer_1({
11162 generic: true,
11163 types: config.types,
11164 atrules: config.atrules,
11165 properties: config.properties,
11166 node: config.node
11167 }, syntax);
11168
11169 return syntax;
11170 }
11171 var create_1 = function(config) {
11172 return createSyntax(mix_1({}, config));
11173 };
11174
11175 var create$5 = {
11176 create: create_1
11177 };
11178
11179 var atRules = {
11180 "@charset": {
11181 syntax: "@charset \"<charset>\";",
11182 groups: [
11183 "CSS Charsets"
11184 ],
11185 status: "standard",
11186 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/@charset"
11187 },
11188 "@counter-style": {
11189 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}",
11190 interfaces: [
11191 "CSSCounterStyleRule"
11192 ],
11193 groups: [
11194 "CSS Counter Styles"
11195 ],
11196 descriptors: {
11197 "additive-symbols": {
11198 syntax: "[ <integer> && <symbol> ]#",
11199 media: "all",
11200 initial: "N/A",
11201 percentages: "no",
11202 computed: "asSpecified",
11203 order: "orderOfAppearance",
11204 status: "standard"
11205 },
11206 fallback: {
11207 syntax: "<counter-style-name>",
11208 media: "all",
11209 initial: "decimal",
11210 percentages: "no",
11211 computed: "asSpecified",
11212 order: "uniqueOrder",
11213 status: "standard"
11214 },
11215 negative: {
11216 syntax: "<symbol> <symbol>?",
11217 media: "all",
11218 initial: "\"-\" hyphen-minus",
11219 percentages: "no",
11220 computed: "asSpecified",
11221 order: "orderOfAppearance",
11222 status: "standard"
11223 },
11224 pad: {
11225 syntax: "<integer> && <symbol>",
11226 media: "all",
11227 initial: "0 \"\"",
11228 percentages: "no",
11229 computed: "asSpecified",
11230 order: "uniqueOrder",
11231 status: "standard"
11232 },
11233 prefix: {
11234 syntax: "<symbol>",
11235 media: "all",
11236 initial: "\"\"",
11237 percentages: "no",
11238 computed: "asSpecified",
11239 order: "uniqueOrder",
11240 status: "standard"
11241 },
11242 range: {
11243 syntax: "[ [ <integer> | infinite ]{2} ]# | auto",
11244 media: "all",
11245 initial: "auto",
11246 percentages: "no",
11247 computed: "asSpecified",
11248 order: "orderOfAppearance",
11249 status: "standard"
11250 },
11251 "speak-as": {
11252 syntax: "auto | bullets | numbers | words | spell-out | <counter-style-name>",
11253 media: "all",
11254 initial: "auto",
11255 percentages: "no",
11256 computed: "asSpecified",
11257 order: "uniqueOrder",
11258 status: "standard"
11259 },
11260 suffix: {
11261 syntax: "<symbol>",
11262 media: "all",
11263 initial: "\". \"",
11264 percentages: "no",
11265 computed: "asSpecified",
11266 order: "uniqueOrder",
11267 status: "standard"
11268 },
11269 symbols: {
11270 syntax: "<symbol>+",
11271 media: "all",
11272 initial: "N/A",
11273 percentages: "no",
11274 computed: "asSpecified",
11275 order: "orderOfAppearance",
11276 status: "standard"
11277 },
11278 system: {
11279 syntax: "cyclic | numeric | alphabetic | symbolic | additive | [ fixed <integer>? ] | [ extends <counter-style-name> ]",
11280 media: "all",
11281 initial: "symbolic",
11282 percentages: "no",
11283 computed: "asSpecified",
11284 order: "uniqueOrder",
11285 status: "standard"
11286 }
11287 },
11288 status: "standard",
11289 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/@counter-style"
11290 },
11291 "@document": {
11292 syntax: "@document [ <url> | url-prefix(<string>) | domain(<string>) | media-document(<string>) | regexp(<string>) ]# {\n <group-rule-body>\n}",
11293 interfaces: [
11294 "CSSGroupingRule",
11295 "CSSConditionRule"
11296 ],
11297 groups: [
11298 "CSS Conditional Rules"
11299 ],
11300 status: "nonstandard",
11301 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/@document"
11302 },
11303 "@font-face": {
11304 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}",
11305 interfaces: [
11306 "CSSFontFaceRule"
11307 ],
11308 groups: [
11309 "CSS Fonts"
11310 ],
11311 descriptors: {
11312 "font-display": {
11313 syntax: "[ auto | block | swap | fallback | optional ]",
11314 media: "visual",
11315 percentages: "no",
11316 initial: "auto",
11317 computed: "asSpecified",
11318 order: "uniqueOrder",
11319 status: "experimental"
11320 },
11321 "font-family": {
11322 syntax: "<family-name>",
11323 media: "all",
11324 initial: "n/a (required)",
11325 percentages: "no",
11326 computed: "asSpecified",
11327 order: "uniqueOrder",
11328 status: "standard"
11329 },
11330 "font-feature-settings": {
11331 syntax: "normal | <feature-tag-value>#",
11332 media: "all",
11333 initial: "normal",
11334 percentages: "no",
11335 computed: "asSpecified",
11336 order: "orderOfAppearance",
11337 status: "standard"
11338 },
11339 "font-variation-settings": {
11340 syntax: "normal | [ <string> <number> ]#",
11341 media: "all",
11342 initial: "normal",
11343 percentages: "no",
11344 computed: "asSpecified",
11345 order: "orderOfAppearance",
11346 status: "standard"
11347 },
11348 "font-stretch": {
11349 syntax: "<font-stretch-absolute>{1,2}",
11350 media: "all",
11351 initial: "normal",
11352 percentages: "no",
11353 computed: "asSpecified",
11354 order: "uniqueOrder",
11355 status: "standard"
11356 },
11357 "font-style": {
11358 syntax: "normal | italic | oblique <angle>{0,2}",
11359 media: "all",
11360 initial: "normal",
11361 percentages: "no",
11362 computed: "asSpecified",
11363 order: "uniqueOrder",
11364 status: "standard"
11365 },
11366 "font-weight": {
11367 syntax: "<font-weight-absolute>{1,2}",
11368 media: "all",
11369 initial: "normal",
11370 percentages: "no",
11371 computed: "asSpecified",
11372 order: "uniqueOrder",
11373 status: "standard"
11374 },
11375 "font-variant": {
11376 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 ]",
11377 media: "all",
11378 initial: "normal",
11379 percentages: "no",
11380 computed: "asSpecified",
11381 order: "orderOfAppearance",
11382 status: "standard"
11383 },
11384 src: {
11385 syntax: "[ <url> [ format( <string># ) ]? | local( <family-name> ) ]#",
11386 media: "all",
11387 initial: "n/a (required)",
11388 percentages: "no",
11389 computed: "asSpecified",
11390 order: "orderOfAppearance",
11391 status: "standard"
11392 },
11393 "unicode-range": {
11394 syntax: "<unicode-range>#",
11395 media: "all",
11396 initial: "U+0-10FFFF",
11397 percentages: "no",
11398 computed: "asSpecified",
11399 order: "orderOfAppearance",
11400 status: "standard"
11401 }
11402 },
11403 status: "standard",
11404 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/@font-face"
11405 },
11406 "@font-feature-values": {
11407 syntax: "@font-feature-values <family-name># {\n <feature-value-block-list>\n}",
11408 interfaces: [
11409 "CSSFontFeatureValuesRule"
11410 ],
11411 groups: [
11412 "CSS Fonts"
11413 ],
11414 status: "standard",
11415 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/@font-feature-values"
11416 },
11417 "@import": {
11418 syntax: "@import [ <string> | <url> ] [ <media-query-list> ]?;",
11419 groups: [
11420 "Media Queries"
11421 ],
11422 status: "standard",
11423 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/@import"
11424 },
11425 "@keyframes": {
11426 syntax: "@keyframes <keyframes-name> {\n <keyframe-block-list>\n}",
11427 interfaces: [
11428 "CSSKeyframeRule",
11429 "CSSKeyframesRule"
11430 ],
11431 groups: [
11432 "CSS Animations"
11433 ],
11434 status: "standard",
11435 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/@keyframes"
11436 },
11437 "@media": {
11438 syntax: "@media <media-query-list> {\n <group-rule-body>\n}",
11439 interfaces: [
11440 "CSSGroupingRule",
11441 "CSSConditionRule",
11442 "CSSMediaRule",
11443 "CSSCustomMediaRule"
11444 ],
11445 groups: [
11446 "CSS Conditional Rules",
11447 "Media Queries"
11448 ],
11449 status: "standard",
11450 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/@media"
11451 },
11452 "@namespace": {
11453 syntax: "@namespace <namespace-prefix>? [ <string> | <url> ];",
11454 groups: [
11455 "CSS Namespaces"
11456 ],
11457 status: "standard",
11458 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/@namespace"
11459 },
11460 "@page": {
11461 syntax: "@page <page-selector-list> {\n <page-body>\n}",
11462 interfaces: [
11463 "CSSPageRule"
11464 ],
11465 groups: [
11466 "CSS Pages"
11467 ],
11468 descriptors: {
11469 bleed: {
11470 syntax: "auto | <length>",
11471 media: [
11472 "visual",
11473 "paged"
11474 ],
11475 initial: "auto",
11476 percentages: "no",
11477 computed: "asSpecified",
11478 order: "uniqueOrder",
11479 status: "experimental"
11480 },
11481 marks: {
11482 syntax: "none | [ crop || cross ]",
11483 media: [
11484 "visual",
11485 "paged"
11486 ],
11487 initial: "none",
11488 percentages: "no",
11489 computed: "asSpecified",
11490 order: "orderOfAppearance",
11491 status: "experimental"
11492 }
11493 },
11494 status: "standard",
11495 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/@page"
11496 },
11497 "@supports": {
11498 syntax: "@supports <supports-condition> {\n <group-rule-body>\n}",
11499 interfaces: [
11500 "CSSGroupingRule",
11501 "CSSConditionRule",
11502 "CSSSupportsRule"
11503 ],
11504 groups: [
11505 "CSS Conditional Rules"
11506 ],
11507 status: "standard",
11508 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/@supports"
11509 },
11510 "@viewport": {
11511 syntax: "@viewport {\n <group-rule-body>\n}",
11512 interfaces: [
11513 "CSSViewportRule"
11514 ],
11515 groups: [
11516 "CSS Device Adaptation"
11517 ],
11518 descriptors: {
11519 height: {
11520 syntax: "<viewport-length>{1,2}",
11521 media: [
11522 "visual",
11523 "continuous"
11524 ],
11525 initial: [
11526 "min-height",
11527 "max-height"
11528 ],
11529 percentages: [
11530 "min-height",
11531 "max-height"
11532 ],
11533 computed: [
11534 "min-height",
11535 "max-height"
11536 ],
11537 order: "orderOfAppearance",
11538 status: "standard"
11539 },
11540 "max-height": {
11541 syntax: "<viewport-length>",
11542 media: [
11543 "visual",
11544 "continuous"
11545 ],
11546 initial: "auto",
11547 percentages: "referToHeightOfInitialViewport",
11548 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
11549 order: "uniqueOrder",
11550 status: "standard"
11551 },
11552 "max-width": {
11553 syntax: "<viewport-length>",
11554 media: [
11555 "visual",
11556 "continuous"
11557 ],
11558 initial: "auto",
11559 percentages: "referToWidthOfInitialViewport",
11560 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
11561 order: "uniqueOrder",
11562 status: "standard"
11563 },
11564 "max-zoom": {
11565 syntax: "auto | <number> | <percentage>",
11566 media: [
11567 "visual",
11568 "continuous"
11569 ],
11570 initial: "auto",
11571 percentages: "the zoom factor itself",
11572 computed: "autoNonNegativeOrPercentage",
11573 order: "uniqueOrder",
11574 status: "standard"
11575 },
11576 "min-height": {
11577 syntax: "<viewport-length>",
11578 media: [
11579 "visual",
11580 "continuous"
11581 ],
11582 initial: "auto",
11583 percentages: "referToHeightOfInitialViewport",
11584 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
11585 order: "uniqueOrder",
11586 status: "standard"
11587 },
11588 "min-width": {
11589 syntax: "<viewport-length>",
11590 media: [
11591 "visual",
11592 "continuous"
11593 ],
11594 initial: "auto",
11595 percentages: "referToWidthOfInitialViewport",
11596 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
11597 order: "uniqueOrder",
11598 status: "standard"
11599 },
11600 "min-zoom": {
11601 syntax: "auto | <number> | <percentage>",
11602 media: [
11603 "visual",
11604 "continuous"
11605 ],
11606 initial: "auto",
11607 percentages: "the zoom factor itself",
11608 computed: "autoNonNegativeOrPercentage",
11609 order: "uniqueOrder",
11610 status: "standard"
11611 },
11612 orientation: {
11613 syntax: "auto | portrait | landscape",
11614 media: [
11615 "visual",
11616 "continuous"
11617 ],
11618 initial: "auto",
11619 percentages: "referToSizeOfBoundingBox",
11620 computed: "asSpecified",
11621 order: "uniqueOrder",
11622 status: "standard"
11623 },
11624 "user-zoom": {
11625 syntax: "zoom | fixed",
11626 media: [
11627 "visual",
11628 "continuous"
11629 ],
11630 initial: "zoom",
11631 percentages: "referToSizeOfBoundingBox",
11632 computed: "asSpecified",
11633 order: "uniqueOrder",
11634 status: "standard"
11635 },
11636 width: {
11637 syntax: "<viewport-length>{1,2}",
11638 media: [
11639 "visual",
11640 "continuous"
11641 ],
11642 initial: [
11643 "min-width",
11644 "max-width"
11645 ],
11646 percentages: [
11647 "min-width",
11648 "max-width"
11649 ],
11650 computed: [
11651 "min-width",
11652 "max-width"
11653 ],
11654 order: "orderOfAppearance",
11655 status: "standard"
11656 },
11657 zoom: {
11658 syntax: "auto | <number> | <percentage>",
11659 media: [
11660 "visual",
11661 "continuous"
11662 ],
11663 initial: "auto",
11664 percentages: "the zoom factor itself",
11665 computed: "autoNonNegativeOrPercentage",
11666 order: "uniqueOrder",
11667 status: "standard"
11668 }
11669 },
11670 status: "standard",
11671 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/@viewport"
11672 }
11673 };
11674
11675 var atRules$1 = /*#__PURE__*/Object.freeze({
11676 __proto__: null,
11677 'default': atRules
11678 });
11679
11680 var all = {
11681 syntax: "initial | inherit | unset | revert",
11682 media: "noPracticalMedia",
11683 inherited: false,
11684 animationType: "eachOfShorthandPropertiesExceptUnicodeBiDiAndDirection",
11685 percentages: "no",
11686 groups: [
11687 "CSS Miscellaneous"
11688 ],
11689 initial: "noPracticalInitialValue",
11690 appliesto: "allElements",
11691 computed: "asSpecifiedAppliesToEachProperty",
11692 order: "uniqueOrder",
11693 status: "standard",
11694 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/all"
11695 };
11696 var animation = {
11697 syntax: "<single-animation>#",
11698 media: "visual",
11699 inherited: false,
11700 animationType: "discrete",
11701 percentages: "no",
11702 groups: [
11703 "CSS Animations"
11704 ],
11705 initial: [
11706 "animation-name",
11707 "animation-duration",
11708 "animation-timing-function",
11709 "animation-delay",
11710 "animation-iteration-count",
11711 "animation-direction",
11712 "animation-fill-mode",
11713 "animation-play-state"
11714 ],
11715 appliesto: "allElementsAndPseudos",
11716 computed: [
11717 "animation-name",
11718 "animation-duration",
11719 "animation-timing-function",
11720 "animation-delay",
11721 "animation-direction",
11722 "animation-iteration-count",
11723 "animation-fill-mode",
11724 "animation-play-state"
11725 ],
11726 order: "orderOfAppearance",
11727 status: "standard",
11728 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/animation"
11729 };
11730 var appearance = {
11731 syntax: "none | auto | button | textfield | <compat>",
11732 media: "all",
11733 inherited: false,
11734 animationType: "discrete",
11735 percentages: "no",
11736 groups: [
11737 "CSS Basic User Interface"
11738 ],
11739 initial: "auto",
11740 appliesto: "allElements",
11741 computed: "asSpecified",
11742 order: "perGrammar",
11743 status: "experimental",
11744 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-appearance"
11745 };
11746 var azimuth = {
11747 syntax: "<angle> | [ [ left-side | far-left | left | center-left | center | center-right | right | far-right | right-side ] || behind ] | leftwards | rightwards",
11748 media: "aural",
11749 inherited: true,
11750 animationType: "discrete",
11751 percentages: "no",
11752 groups: [
11753 "CSS Speech"
11754 ],
11755 initial: "center",
11756 appliesto: "allElements",
11757 computed: "normalizedAngle",
11758 order: "orderOfAppearance",
11759 status: "obsolete",
11760 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/azimuth"
11761 };
11762 var background = {
11763 syntax: "[ <bg-layer> , ]* <final-bg-layer>",
11764 media: "visual",
11765 inherited: false,
11766 animationType: [
11767 "background-color",
11768 "background-image",
11769 "background-clip",
11770 "background-position",
11771 "background-size",
11772 "background-repeat",
11773 "background-attachment"
11774 ],
11775 percentages: [
11776 "background-position",
11777 "background-size"
11778 ],
11779 groups: [
11780 "CSS Backgrounds and Borders"
11781 ],
11782 initial: [
11783 "background-image",
11784 "background-position",
11785 "background-size",
11786 "background-repeat",
11787 "background-origin",
11788 "background-clip",
11789 "background-attachment",
11790 "background-color"
11791 ],
11792 appliesto: "allElements",
11793 computed: [
11794 "background-image",
11795 "background-position",
11796 "background-size",
11797 "background-repeat",
11798 "background-origin",
11799 "background-clip",
11800 "background-attachment",
11801 "background-color"
11802 ],
11803 order: "orderOfAppearance",
11804 alsoAppliesTo: [
11805 "::first-letter",
11806 "::first-line",
11807 "::placeholder"
11808 ],
11809 status: "standard",
11810 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/background"
11811 };
11812 var border = {
11813 syntax: "<line-width> || <line-style> || <color>",
11814 media: "visual",
11815 inherited: false,
11816 animationType: [
11817 "border-color",
11818 "border-style",
11819 "border-width"
11820 ],
11821 percentages: "no",
11822 groups: [
11823 "CSS Backgrounds and Borders"
11824 ],
11825 initial: [
11826 "border-width",
11827 "border-style",
11828 "border-color"
11829 ],
11830 appliesto: "allElements",
11831 computed: [
11832 "border-width",
11833 "border-style",
11834 "border-color"
11835 ],
11836 order: "orderOfAppearance",
11837 alsoAppliesTo: [
11838 "::first-letter"
11839 ],
11840 status: "standard",
11841 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border"
11842 };
11843 var bottom = {
11844 syntax: "<length> | <percentage> | auto",
11845 media: "visual",
11846 inherited: false,
11847 animationType: "lpc",
11848 percentages: "referToContainingBlockHeight",
11849 groups: [
11850 "CSS Positioning"
11851 ],
11852 initial: "auto",
11853 appliesto: "positionedElements",
11854 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
11855 order: "uniqueOrder",
11856 status: "standard",
11857 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/bottom"
11858 };
11859 var clear = {
11860 syntax: "none | left | right | both | inline-start | inline-end",
11861 media: "visual",
11862 inherited: false,
11863 animationType: "discrete",
11864 percentages: "no",
11865 groups: [
11866 "CSS Positioning"
11867 ],
11868 initial: "none",
11869 appliesto: "blockLevelElements",
11870 computed: "asSpecified",
11871 order: "uniqueOrder",
11872 status: "standard",
11873 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/clear"
11874 };
11875 var clip = {
11876 syntax: "<shape> | auto",
11877 media: "visual",
11878 inherited: false,
11879 animationType: "rectangle",
11880 percentages: "no",
11881 groups: [
11882 "CSS Masking"
11883 ],
11884 initial: "auto",
11885 appliesto: "absolutelyPositionedElements",
11886 computed: "autoOrRectangle",
11887 order: "uniqueOrder",
11888 status: "standard",
11889 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/clip"
11890 };
11891 var color = {
11892 syntax: "<color>",
11893 media: "visual",
11894 inherited: true,
11895 animationType: "color",
11896 percentages: "no",
11897 groups: [
11898 "CSS Color"
11899 ],
11900 initial: "variesFromBrowserToBrowser",
11901 appliesto: "allElements",
11902 computed: "translucentValuesRGBAOtherwiseRGB",
11903 order: "uniqueOrder",
11904 alsoAppliesTo: [
11905 "::first-letter",
11906 "::first-line",
11907 "::placeholder"
11908 ],
11909 status: "standard",
11910 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/color"
11911 };
11912 var columns = {
11913 syntax: "<'column-width'> || <'column-count'>",
11914 media: "visual",
11915 inherited: false,
11916 animationType: [
11917 "column-width",
11918 "column-count"
11919 ],
11920 percentages: "no",
11921 groups: [
11922 "CSS Columns"
11923 ],
11924 initial: [
11925 "column-width",
11926 "column-count"
11927 ],
11928 appliesto: "blockContainersExceptTableWrappers",
11929 computed: [
11930 "column-width",
11931 "column-count"
11932 ],
11933 order: "perGrammar",
11934 status: "standard",
11935 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/columns"
11936 };
11937 var contain = {
11938 syntax: "none | strict | content | [ size || layout || style || paint ]",
11939 media: "all",
11940 inherited: false,
11941 animationType: "discrete",
11942 percentages: "no",
11943 groups: [
11944 "CSS Containment"
11945 ],
11946 initial: "none",
11947 appliesto: "allElements",
11948 computed: "asSpecified",
11949 order: "perGrammar",
11950 status: "experimental",
11951 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/contain"
11952 };
11953 var content = {
11954 syntax: "normal | none | [ <content-replacement> | <content-list> ] [/ <string> ]?",
11955 media: "all",
11956 inherited: false,
11957 animationType: "discrete",
11958 percentages: "no",
11959 groups: [
11960 "CSS Generated Content"
11961 ],
11962 initial: "normal",
11963 appliesto: "beforeAndAfterPseudos",
11964 computed: "normalOnElementsForPseudosNoneAbsoluteURIStringOrAsSpecified",
11965 order: "uniqueOrder",
11966 status: "standard",
11967 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/content"
11968 };
11969 var cursor = {
11970 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 ] ]",
11971 media: [
11972 "visual",
11973 "interactive"
11974 ],
11975 inherited: true,
11976 animationType: "discrete",
11977 percentages: "no",
11978 groups: [
11979 "CSS Basic User Interface"
11980 ],
11981 initial: "auto",
11982 appliesto: "allElements",
11983 computed: "asSpecifiedURLsAbsolute",
11984 order: "uniqueOrder",
11985 status: "standard",
11986 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/cursor"
11987 };
11988 var direction = {
11989 syntax: "ltr | rtl",
11990 media: "visual",
11991 inherited: true,
11992 animationType: "discrete",
11993 percentages: "no",
11994 groups: [
11995 "CSS Writing Modes"
11996 ],
11997 initial: "ltr",
11998 appliesto: "allElements",
11999 computed: "asSpecified",
12000 order: "uniqueOrder",
12001 status: "standard",
12002 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/direction"
12003 };
12004 var display = {
12005 syntax: "[ <display-outside> || <display-inside> ] | <display-listitem> | <display-internal> | <display-box> | <display-legacy>",
12006 media: "all",
12007 inherited: false,
12008 animationType: "discrete",
12009 percentages: "no",
12010 groups: [
12011 "CSS Display"
12012 ],
12013 initial: "inline",
12014 appliesto: "allElements",
12015 computed: "asSpecifiedExceptPositionedFloatingAndRootElementsKeywordMaybeDifferent",
12016 order: "uniqueOrder",
12017 status: "standard",
12018 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/display"
12019 };
12020 var filter = {
12021 syntax: "none | <filter-function-list>",
12022 media: "visual",
12023 inherited: false,
12024 animationType: "filterList",
12025 percentages: "no",
12026 groups: [
12027 "Filter Effects"
12028 ],
12029 initial: "none",
12030 appliesto: "allElementsSVGContainerElements",
12031 computed: "asSpecified",
12032 order: "uniqueOrder",
12033 status: "standard",
12034 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/filter"
12035 };
12036 var flex = {
12037 syntax: "none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]",
12038 media: "visual",
12039 inherited: false,
12040 animationType: [
12041 "flex-grow",
12042 "flex-shrink",
12043 "flex-basis"
12044 ],
12045 percentages: "no",
12046 groups: [
12047 "CSS Flexible Box Layout"
12048 ],
12049 initial: [
12050 "flex-grow",
12051 "flex-shrink",
12052 "flex-basis"
12053 ],
12054 appliesto: "flexItemsAndInFlowPseudos",
12055 computed: [
12056 "flex-grow",
12057 "flex-shrink",
12058 "flex-basis"
12059 ],
12060 order: "orderOfAppearance",
12061 status: "standard",
12062 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/flex"
12063 };
12064 var float = {
12065 syntax: "left | right | none | inline-start | inline-end",
12066 media: "visual",
12067 inherited: false,
12068 animationType: "discrete",
12069 percentages: "no",
12070 groups: [
12071 "CSS Positioning"
12072 ],
12073 initial: "none",
12074 appliesto: "allElementsNoEffectIfDisplayNone",
12075 computed: "asSpecified",
12076 order: "uniqueOrder",
12077 status: "standard",
12078 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/float"
12079 };
12080 var font = {
12081 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",
12082 media: "visual",
12083 inherited: true,
12084 animationType: [
12085 "font-style",
12086 "font-variant",
12087 "font-weight",
12088 "font-stretch",
12089 "font-size",
12090 "line-height",
12091 "font-family"
12092 ],
12093 percentages: [
12094 "font-size",
12095 "line-height"
12096 ],
12097 groups: [
12098 "CSS Fonts"
12099 ],
12100 initial: [
12101 "font-style",
12102 "font-variant",
12103 "font-weight",
12104 "font-stretch",
12105 "font-size",
12106 "line-height",
12107 "font-family"
12108 ],
12109 appliesto: "allElements",
12110 computed: [
12111 "font-style",
12112 "font-variant",
12113 "font-weight",
12114 "font-stretch",
12115 "font-size",
12116 "line-height",
12117 "font-family"
12118 ],
12119 order: "orderOfAppearance",
12120 alsoAppliesTo: [
12121 "::first-letter",
12122 "::first-line",
12123 "::placeholder"
12124 ],
12125 status: "standard",
12126 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font"
12127 };
12128 var gap = {
12129 syntax: "<'row-gap'> <'column-gap'>?",
12130 media: "visual",
12131 inherited: false,
12132 animationType: [
12133 "row-gap",
12134 "column-gap"
12135 ],
12136 percentages: "no",
12137 groups: [
12138 "CSS Box Alignment"
12139 ],
12140 initial: [
12141 "row-gap",
12142 "column-gap"
12143 ],
12144 appliesto: "gridContainers",
12145 computed: [
12146 "row-gap",
12147 "column-gap"
12148 ],
12149 order: "uniqueOrder",
12150 status: "standard",
12151 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/gap"
12152 };
12153 var grid = {
12154 syntax: "<'grid-template'> | <'grid-template-rows'> / [ auto-flow && dense? ] <'grid-auto-columns'>? | [ auto-flow && dense? ] <'grid-auto-rows'>? / <'grid-template-columns'>",
12155 media: "visual",
12156 inherited: false,
12157 animationType: "discrete",
12158 percentages: [
12159 "grid-template-rows",
12160 "grid-template-columns",
12161 "grid-auto-rows",
12162 "grid-auto-columns"
12163 ],
12164 groups: [
12165 "CSS Grid Layout"
12166 ],
12167 initial: [
12168 "grid-template-rows",
12169 "grid-template-columns",
12170 "grid-template-areas",
12171 "grid-auto-rows",
12172 "grid-auto-columns",
12173 "grid-auto-flow",
12174 "grid-column-gap",
12175 "grid-row-gap",
12176 "column-gap",
12177 "row-gap"
12178 ],
12179 appliesto: "gridContainers",
12180 computed: [
12181 "grid-template-rows",
12182 "grid-template-columns",
12183 "grid-template-areas",
12184 "grid-auto-rows",
12185 "grid-auto-columns",
12186 "grid-auto-flow",
12187 "grid-column-gap",
12188 "grid-row-gap",
12189 "column-gap",
12190 "row-gap"
12191 ],
12192 order: "uniqueOrder",
12193 status: "standard",
12194 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid"
12195 };
12196 var height = {
12197 syntax: "[ <length> | <percentage> ] && [ border-box | content-box ]? | available | min-content | max-content | fit-content | auto",
12198 media: "visual",
12199 inherited: false,
12200 animationType: "lpc",
12201 percentages: "regardingHeightOfGeneratedBoxContainingBlockPercentagesRelativeToContainingBlock",
12202 groups: [
12203 "CSS Box Model"
12204 ],
12205 initial: "auto",
12206 appliesto: "allElementsButNonReplacedAndTableColumns",
12207 computed: "percentageAutoOrAbsoluteLength",
12208 order: "uniqueOrder",
12209 status: "standard",
12210 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/height"
12211 };
12212 var hyphens = {
12213 syntax: "none | manual | auto",
12214 media: "visual",
12215 inherited: true,
12216 animationType: "discrete",
12217 percentages: "no",
12218 groups: [
12219 "CSS Text"
12220 ],
12221 initial: "manual",
12222 appliesto: "allElements",
12223 computed: "asSpecified",
12224 order: "uniqueOrder",
12225 status: "standard",
12226 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/hyphens"
12227 };
12228 var inset = {
12229 syntax: "<'top'>{1,4}",
12230 media: "visual",
12231 inherited: false,
12232 animationType: "lpc",
12233 percentages: "logicalHeightOfContainingBlock",
12234 groups: [
12235 "CSS Logical Properties"
12236 ],
12237 initial: "auto",
12238 appliesto: "positionedElements",
12239 computed: "sameAsBoxOffsets",
12240 order: "uniqueOrder",
12241 status: "standard",
12242 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/inset"
12243 };
12244 var isolation = {
12245 syntax: "auto | isolate",
12246 media: "visual",
12247 inherited: false,
12248 animationType: "discrete",
12249 percentages: "no",
12250 groups: [
12251 "Compositing and Blending"
12252 ],
12253 initial: "auto",
12254 appliesto: "allElementsSVGContainerGraphicsAndGraphicsReferencingElements",
12255 computed: "asSpecified",
12256 order: "uniqueOrder",
12257 status: "standard",
12258 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/isolation"
12259 };
12260 var left = {
12261 syntax: "<length> | <percentage> | auto",
12262 media: "visual",
12263 inherited: false,
12264 animationType: "lpc",
12265 percentages: "referToWidthOfContainingBlock",
12266 groups: [
12267 "CSS Positioning"
12268 ],
12269 initial: "auto",
12270 appliesto: "positionedElements",
12271 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
12272 order: "uniqueOrder",
12273 status: "standard",
12274 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/left"
12275 };
12276 var margin = {
12277 syntax: "[ <length> | <percentage> | auto ]{1,4}",
12278 media: "visual",
12279 inherited: false,
12280 animationType: "length",
12281 percentages: "referToWidthOfContainingBlock",
12282 groups: [
12283 "CSS Box Model"
12284 ],
12285 initial: [
12286 "margin-bottom",
12287 "margin-left",
12288 "margin-right",
12289 "margin-top"
12290 ],
12291 appliesto: "allElementsExceptTableDisplayTypes",
12292 computed: [
12293 "margin-bottom",
12294 "margin-left",
12295 "margin-right",
12296 "margin-top"
12297 ],
12298 order: "uniqueOrder",
12299 alsoAppliesTo: [
12300 "::first-letter"
12301 ],
12302 status: "standard",
12303 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/margin"
12304 };
12305 var mask = {
12306 syntax: "<mask-layer>#",
12307 media: "visual",
12308 inherited: false,
12309 animationType: [
12310 "mask-image",
12311 "mask-mode",
12312 "mask-repeat",
12313 "mask-position",
12314 "mask-clip",
12315 "mask-origin",
12316 "mask-size",
12317 "mask-composite"
12318 ],
12319 percentages: [
12320 "mask-position"
12321 ],
12322 groups: [
12323 "CSS Masking"
12324 ],
12325 initial: [
12326 "mask-image",
12327 "mask-mode",
12328 "mask-repeat",
12329 "mask-position",
12330 "mask-clip",
12331 "mask-origin",
12332 "mask-size",
12333 "mask-composite"
12334 ],
12335 appliesto: "allElementsSVGContainerElements",
12336 computed: [
12337 "mask-image",
12338 "mask-mode",
12339 "mask-repeat",
12340 "mask-position",
12341 "mask-clip",
12342 "mask-origin",
12343 "mask-size",
12344 "mask-composite"
12345 ],
12346 order: "perGrammar",
12347 stacking: true,
12348 status: "standard",
12349 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask"
12350 };
12351 var offset = {
12352 syntax: "[ <'offset-position'>? [ <'offset-path'> [ <'offset-distance'> || <'offset-rotate'> ]? ]? ]! [ / <'offset-anchor'> ]?",
12353 media: "visual",
12354 inherited: false,
12355 animationType: [
12356 "offset-position",
12357 "offset-path",
12358 "offset-distance",
12359 "offset-anchor",
12360 "offset-rotate"
12361 ],
12362 percentages: [
12363 "offset-position",
12364 "offset-distance",
12365 "offset-anchor"
12366 ],
12367 groups: [
12368 "CSS Motion Path"
12369 ],
12370 initial: [
12371 "offset-position",
12372 "offset-path",
12373 "offset-distance",
12374 "offset-anchor",
12375 "offset-rotate"
12376 ],
12377 appliesto: "transformableElements",
12378 computed: [
12379 "offset-position",
12380 "offset-path",
12381 "offset-distance",
12382 "offset-anchor",
12383 "offset-rotate"
12384 ],
12385 order: "perGrammar",
12386 stacking: true,
12387 status: "experimental",
12388 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/offset"
12389 };
12390 var opacity = {
12391 syntax: "<alpha-value>",
12392 media: "visual",
12393 inherited: false,
12394 animationType: "number",
12395 percentages: "no",
12396 groups: [
12397 "CSS Color"
12398 ],
12399 initial: "1.0",
12400 appliesto: "allElements",
12401 computed: "specifiedValueClipped0To1",
12402 order: "uniqueOrder",
12403 alsoAppliesTo: [
12404 "::placeholder"
12405 ],
12406 status: "standard",
12407 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/opacity"
12408 };
12409 var order = {
12410 syntax: "<integer>",
12411 media: "visual",
12412 inherited: false,
12413 animationType: "integer",
12414 percentages: "no",
12415 groups: [
12416 "CSS Flexible Box Layout"
12417 ],
12418 initial: "0",
12419 appliesto: "flexItemsAndAbsolutelyPositionedFlexContainerChildren",
12420 computed: "asSpecified",
12421 order: "uniqueOrder",
12422 status: "standard",
12423 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/order"
12424 };
12425 var orphans = {
12426 syntax: "<integer>",
12427 media: "visual",
12428 inherited: true,
12429 animationType: "discrete",
12430 percentages: "no",
12431 groups: [
12432 "CSS Fragmentation"
12433 ],
12434 initial: "2",
12435 appliesto: "blockContainerElements",
12436 computed: "asSpecified",
12437 order: "perGrammar",
12438 status: "standard",
12439 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/orphans"
12440 };
12441 var outline = {
12442 syntax: "[ <'outline-color'> || <'outline-style'> || <'outline-width'> ]",
12443 media: [
12444 "visual",
12445 "interactive"
12446 ],
12447 inherited: false,
12448 animationType: [
12449 "outline-color",
12450 "outline-width",
12451 "outline-style"
12452 ],
12453 percentages: "no",
12454 groups: [
12455 "CSS Basic User Interface"
12456 ],
12457 initial: [
12458 "outline-color",
12459 "outline-style",
12460 "outline-width"
12461 ],
12462 appliesto: "allElements",
12463 computed: [
12464 "outline-color",
12465 "outline-width",
12466 "outline-style"
12467 ],
12468 order: "orderOfAppearance",
12469 status: "standard",
12470 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/outline"
12471 };
12472 var overflow = {
12473 syntax: "[ visible | hidden | clip | scroll | auto ]{1,2}",
12474 media: "visual",
12475 inherited: false,
12476 animationType: "discrete",
12477 percentages: "no",
12478 groups: [
12479 "CSS Overflow"
12480 ],
12481 initial: "visible",
12482 appliesto: "blockContainersFlexContainersGridContainers",
12483 computed: "asSpecified",
12484 order: "uniqueOrder",
12485 status: "standard",
12486 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/overflow"
12487 };
12488 var padding = {
12489 syntax: "[ <length> | <percentage> ]{1,4}",
12490 media: "visual",
12491 inherited: false,
12492 animationType: "length",
12493 percentages: "referToWidthOfContainingBlock",
12494 groups: [
12495 "CSS Box Model"
12496 ],
12497 initial: [
12498 "padding-bottom",
12499 "padding-left",
12500 "padding-right",
12501 "padding-top"
12502 ],
12503 appliesto: "allElementsExceptInternalTableDisplayTypes",
12504 computed: [
12505 "padding-bottom",
12506 "padding-left",
12507 "padding-right",
12508 "padding-top"
12509 ],
12510 order: "uniqueOrder",
12511 alsoAppliesTo: [
12512 "::first-letter"
12513 ],
12514 status: "standard",
12515 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/padding"
12516 };
12517 var perspective = {
12518 syntax: "none | <length>",
12519 media: "visual",
12520 inherited: false,
12521 animationType: "length",
12522 percentages: "no",
12523 groups: [
12524 "CSS Transforms"
12525 ],
12526 initial: "none",
12527 appliesto: "transformableElements",
12528 computed: "absoluteLengthOrNone",
12529 order: "uniqueOrder",
12530 stacking: true,
12531 status: "standard",
12532 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/perspective"
12533 };
12534 var position = {
12535 syntax: "static | relative | absolute | sticky | fixed",
12536 media: "visual",
12537 inherited: false,
12538 animationType: "discrete",
12539 percentages: "no",
12540 groups: [
12541 "CSS Positioning"
12542 ],
12543 initial: "static",
12544 appliesto: "allElements",
12545 computed: "asSpecified",
12546 order: "uniqueOrder",
12547 stacking: true,
12548 status: "standard",
12549 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/position"
12550 };
12551 var quotes = {
12552 syntax: "none | auto | [ <string> <string> ]+",
12553 media: "visual",
12554 inherited: true,
12555 animationType: "discrete",
12556 percentages: "no",
12557 groups: [
12558 "CSS Generated Content"
12559 ],
12560 initial: "dependsOnUserAgent",
12561 appliesto: "allElements",
12562 computed: "asSpecified",
12563 order: "uniqueOrder",
12564 status: "standard",
12565 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/quotes"
12566 };
12567 var resize = {
12568 syntax: "none | both | horizontal | vertical | block | inline",
12569 media: "visual",
12570 inherited: false,
12571 animationType: "discrete",
12572 percentages: "no",
12573 groups: [
12574 "CSS Basic User Interface"
12575 ],
12576 initial: "none",
12577 appliesto: "elementsWithOverflowNotVisibleAndReplacedElements",
12578 computed: "asSpecified",
12579 order: "uniqueOrder",
12580 status: "standard",
12581 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/resize"
12582 };
12583 var right = {
12584 syntax: "<length> | <percentage> | auto",
12585 media: "visual",
12586 inherited: false,
12587 animationType: "lpc",
12588 percentages: "referToWidthOfContainingBlock",
12589 groups: [
12590 "CSS Positioning"
12591 ],
12592 initial: "auto",
12593 appliesto: "positionedElements",
12594 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
12595 order: "uniqueOrder",
12596 status: "standard",
12597 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/right"
12598 };
12599 var rotate = {
12600 syntax: "none | <angle> | [ x | y | z | <number>{3} ] && <angle>",
12601 media: "visual",
12602 inherited: false,
12603 animationType: "transform",
12604 percentages: "no",
12605 groups: [
12606 "CSS Transforms"
12607 ],
12608 initial: "none",
12609 appliesto: "transformableElements",
12610 computed: "asSpecified",
12611 order: "perGrammar",
12612 stacking: true,
12613 status: "standard",
12614 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/rotate"
12615 };
12616 var scale = {
12617 syntax: "none | <number>{1,3}",
12618 media: "visual",
12619 inherited: false,
12620 animationType: "transform",
12621 percentages: "no",
12622 groups: [
12623 "CSS Transforms"
12624 ],
12625 initial: "none",
12626 appliesto: "transformableElements",
12627 computed: "asSpecified",
12628 order: "perGrammar",
12629 stacking: true,
12630 status: "standard",
12631 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scale"
12632 };
12633 var top = {
12634 syntax: "<length> | <percentage> | auto",
12635 media: "visual",
12636 inherited: false,
12637 animationType: "lpc",
12638 percentages: "referToContainingBlockHeight",
12639 groups: [
12640 "CSS Positioning"
12641 ],
12642 initial: "auto",
12643 appliesto: "positionedElements",
12644 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
12645 order: "uniqueOrder",
12646 status: "standard",
12647 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/top"
12648 };
12649 var transform = {
12650 syntax: "none | <transform-list>",
12651 media: "visual",
12652 inherited: false,
12653 animationType: "transform",
12654 percentages: "referToSizeOfBoundingBox",
12655 groups: [
12656 "CSS Transforms"
12657 ],
12658 initial: "none",
12659 appliesto: "transformableElements",
12660 computed: "asSpecifiedRelativeToAbsoluteLengths",
12661 order: "uniqueOrder",
12662 stacking: true,
12663 status: "standard",
12664 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/transform"
12665 };
12666 var transition = {
12667 syntax: "<single-transition>#",
12668 media: "interactive",
12669 inherited: false,
12670 animationType: "discrete",
12671 percentages: "no",
12672 groups: [
12673 "CSS Transitions"
12674 ],
12675 initial: [
12676 "transition-delay",
12677 "transition-duration",
12678 "transition-property",
12679 "transition-timing-function"
12680 ],
12681 appliesto: "allElementsAndPseudos",
12682 computed: [
12683 "transition-delay",
12684 "transition-duration",
12685 "transition-property",
12686 "transition-timing-function"
12687 ],
12688 order: "orderOfAppearance",
12689 status: "standard",
12690 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/transition"
12691 };
12692 var translate = {
12693 syntax: "none | <length-percentage> [ <length-percentage> <length>? ]?",
12694 media: "visual",
12695 inherited: false,
12696 animationType: "transform",
12697 percentages: "referToSizeOfBoundingBox",
12698 groups: [
12699 "CSS Transforms"
12700 ],
12701 initial: "none",
12702 appliesto: "transformableElements",
12703 computed: "asSpecifiedRelativeToAbsoluteLengths",
12704 order: "perGrammar",
12705 stacking: true,
12706 status: "standard",
12707 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/translate"
12708 };
12709 var visibility = {
12710 syntax: "visible | hidden | collapse",
12711 media: "visual",
12712 inherited: true,
12713 animationType: "visibility",
12714 percentages: "no",
12715 groups: [
12716 "CSS Box Model"
12717 ],
12718 initial: "visible",
12719 appliesto: "allElements",
12720 computed: "asSpecified",
12721 order: "uniqueOrder",
12722 status: "standard",
12723 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/visibility"
12724 };
12725 var widows = {
12726 syntax: "<integer>",
12727 media: "visual",
12728 inherited: true,
12729 animationType: "discrete",
12730 percentages: "no",
12731 groups: [
12732 "CSS Fragmentation"
12733 ],
12734 initial: "2",
12735 appliesto: "blockContainerElements",
12736 computed: "asSpecified",
12737 order: "perGrammar",
12738 status: "standard",
12739 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/widows"
12740 };
12741 var width = {
12742 syntax: "[ <length> | <percentage> ] && [ border-box | content-box ]? | available | min-content | max-content | fit-content | auto",
12743 media: "visual",
12744 inherited: false,
12745 animationType: "lpc",
12746 percentages: "referToWidthOfContainingBlock",
12747 groups: [
12748 "CSS Box Model"
12749 ],
12750 initial: "auto",
12751 appliesto: "allElementsButNonReplacedAndTableRows",
12752 computed: "percentageAutoOrAbsoluteLength",
12753 order: "lengthOrPercentageBeforeKeywordIfBothPresent",
12754 status: "standard",
12755 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/width"
12756 };
12757 var zoom = {
12758 syntax: "normal | reset | <number> | <percentage>",
12759 media: "visual",
12760 inherited: false,
12761 animationType: "integer",
12762 percentages: "no",
12763 groups: [
12764 "Microsoft Extensions"
12765 ],
12766 initial: "normal",
12767 appliesto: "allElements",
12768 computed: "asSpecified",
12769 order: "uniqueOrder",
12770 status: "nonstandard",
12771 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/zoom"
12772 };
12773 var properties$1 = {
12774 "--*": {
12775 syntax: "<declaration-value>",
12776 media: "all",
12777 inherited: true,
12778 animationType: "discrete",
12779 percentages: "no",
12780 groups: [
12781 "CSS Variables"
12782 ],
12783 initial: "seeProse",
12784 appliesto: "allElements",
12785 computed: "asSpecifiedWithVarsSubstituted",
12786 order: "perGrammar",
12787 status: "experimental",
12788 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/--*"
12789 },
12790 "-ms-accelerator": {
12791 syntax: "false | true",
12792 media: "visual",
12793 inherited: false,
12794 animationType: "discrete",
12795 percentages: "no",
12796 groups: [
12797 "Microsoft Extensions"
12798 ],
12799 initial: "false",
12800 appliesto: "allElements",
12801 computed: "asSpecified",
12802 order: "uniqueOrder",
12803 status: "nonstandard",
12804 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-accelerator"
12805 },
12806 "-ms-block-progression": {
12807 syntax: "tb | rl | bt | lr",
12808 media: "visual",
12809 inherited: false,
12810 animationType: "discrete",
12811 percentages: "no",
12812 groups: [
12813 "Microsoft Extensions"
12814 ],
12815 initial: "tb",
12816 appliesto: "allElements",
12817 computed: "asSpecified",
12818 order: "uniqueOrder",
12819 status: "nonstandard",
12820 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-block-progression"
12821 },
12822 "-ms-content-zoom-chaining": {
12823 syntax: "none | chained",
12824 media: "interactive",
12825 inherited: false,
12826 animationType: "discrete",
12827 percentages: "no",
12828 groups: [
12829 "Microsoft Extensions"
12830 ],
12831 initial: "none",
12832 appliesto: "nonReplacedBlockAndInlineBlockElements",
12833 computed: "asSpecified",
12834 order: "uniqueOrder",
12835 status: "nonstandard",
12836 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-content-zoom-chaining"
12837 },
12838 "-ms-content-zooming": {
12839 syntax: "none | zoom",
12840 media: "interactive",
12841 inherited: false,
12842 animationType: "discrete",
12843 percentages: "no",
12844 groups: [
12845 "Microsoft Extensions"
12846 ],
12847 initial: "zoomForTheTopLevelNoneForTheRest",
12848 appliesto: "nonReplacedBlockAndInlineBlockElements",
12849 computed: "asSpecified",
12850 order: "uniqueOrder",
12851 status: "nonstandard",
12852 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-content-zooming"
12853 },
12854 "-ms-content-zoom-limit": {
12855 syntax: "<'-ms-content-zoom-limit-min'> <'-ms-content-zoom-limit-max'>",
12856 media: "interactive",
12857 inherited: false,
12858 animationType: "discrete",
12859 percentages: [
12860 "-ms-content-zoom-limit-max",
12861 "-ms-content-zoom-limit-min"
12862 ],
12863 groups: [
12864 "Microsoft Extensions"
12865 ],
12866 initial: [
12867 "-ms-content-zoom-limit-max",
12868 "-ms-content-zoom-limit-min"
12869 ],
12870 appliesto: "nonReplacedBlockAndInlineBlockElements",
12871 computed: [
12872 "-ms-content-zoom-limit-max",
12873 "-ms-content-zoom-limit-min"
12874 ],
12875 order: "uniqueOrder",
12876 status: "nonstandard",
12877 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-content-zoom-limit"
12878 },
12879 "-ms-content-zoom-limit-max": {
12880 syntax: "<percentage>",
12881 media: "interactive",
12882 inherited: false,
12883 animationType: "discrete",
12884 percentages: "maxZoomFactor",
12885 groups: [
12886 "Microsoft Extensions"
12887 ],
12888 initial: "400%",
12889 appliesto: "nonReplacedBlockAndInlineBlockElements",
12890 computed: "asSpecified",
12891 order: "uniqueOrder",
12892 status: "nonstandard",
12893 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-content-zoom-limit-max"
12894 },
12895 "-ms-content-zoom-limit-min": {
12896 syntax: "<percentage>",
12897 media: "interactive",
12898 inherited: false,
12899 animationType: "discrete",
12900 percentages: "minZoomFactor",
12901 groups: [
12902 "Microsoft Extensions"
12903 ],
12904 initial: "100%",
12905 appliesto: "nonReplacedBlockAndInlineBlockElements",
12906 computed: "asSpecified",
12907 order: "uniqueOrder",
12908 status: "nonstandard",
12909 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-content-zoom-limit-min"
12910 },
12911 "-ms-content-zoom-snap": {
12912 syntax: "<'-ms-content-zoom-snap-type'> || <'-ms-content-zoom-snap-points'>",
12913 media: "interactive",
12914 inherited: false,
12915 animationType: "discrete",
12916 percentages: "no",
12917 groups: [
12918 "Microsoft Extensions"
12919 ],
12920 initial: [
12921 "-ms-content-zoom-snap-type",
12922 "-ms-content-zoom-snap-points"
12923 ],
12924 appliesto: "nonReplacedBlockAndInlineBlockElements",
12925 computed: [
12926 "-ms-content-zoom-snap-type",
12927 "-ms-content-zoom-snap-points"
12928 ],
12929 order: "uniqueOrder",
12930 status: "nonstandard",
12931 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-content-zoom-snap"
12932 },
12933 "-ms-content-zoom-snap-points": {
12934 syntax: "snapInterval( <percentage>, <percentage> ) | snapList( <percentage># )",
12935 media: "interactive",
12936 inherited: false,
12937 animationType: "discrete",
12938 percentages: "no",
12939 groups: [
12940 "Microsoft Extensions"
12941 ],
12942 initial: "snapInterval(0%, 100%)",
12943 appliesto: "nonReplacedBlockAndInlineBlockElements",
12944 computed: "asSpecified",
12945 order: "uniqueOrder",
12946 status: "nonstandard",
12947 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-content-zoom-snap-points"
12948 },
12949 "-ms-content-zoom-snap-type": {
12950 syntax: "none | proximity | mandatory",
12951 media: "interactive",
12952 inherited: false,
12953 animationType: "discrete",
12954 percentages: "no",
12955 groups: [
12956 "Microsoft Extensions"
12957 ],
12958 initial: "none",
12959 appliesto: "nonReplacedBlockAndInlineBlockElements",
12960 computed: "asSpecified",
12961 order: "uniqueOrder",
12962 status: "nonstandard",
12963 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-content-zoom-snap-type"
12964 },
12965 "-ms-filter": {
12966 syntax: "<string>",
12967 media: "visual",
12968 inherited: false,
12969 animationType: "discrete",
12970 percentages: "no",
12971 groups: [
12972 "Microsoft Extensions"
12973 ],
12974 initial: "\"\"",
12975 appliesto: "allElements",
12976 computed: "asSpecified",
12977 order: "uniqueOrder",
12978 status: "nonstandard",
12979 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-filter"
12980 },
12981 "-ms-flow-from": {
12982 syntax: "[ none | <custom-ident> ]#",
12983 media: "visual",
12984 inherited: false,
12985 animationType: "discrete",
12986 percentages: "no",
12987 groups: [
12988 "Microsoft Extensions"
12989 ],
12990 initial: "none",
12991 appliesto: "nonReplacedElements",
12992 computed: "asSpecified",
12993 order: "uniqueOrder",
12994 status: "nonstandard",
12995 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-flow-from"
12996 },
12997 "-ms-flow-into": {
12998 syntax: "[ none | <custom-ident> ]#",
12999 media: "visual",
13000 inherited: false,
13001 animationType: "discrete",
13002 percentages: "no",
13003 groups: [
13004 "Microsoft Extensions"
13005 ],
13006 initial: "none",
13007 appliesto: "iframeElements",
13008 computed: "asSpecified",
13009 order: "uniqueOrder",
13010 status: "nonstandard",
13011 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-flow-into"
13012 },
13013 "-ms-high-contrast-adjust": {
13014 syntax: "auto | none",
13015 media: "visual",
13016 inherited: true,
13017 animationType: "discrete",
13018 percentages: "no",
13019 groups: [
13020 "Microsoft Extensions"
13021 ],
13022 initial: "auto",
13023 appliesto: "allElements",
13024 computed: "asSpecified",
13025 order: "uniqueOrder",
13026 status: "nonstandard",
13027 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-high-contrast-adjust"
13028 },
13029 "-ms-hyphenate-limit-chars": {
13030 syntax: "auto | <integer>{1,3}",
13031 media: "visual",
13032 inherited: true,
13033 animationType: "discrete",
13034 percentages: "no",
13035 groups: [
13036 "Microsoft Extensions"
13037 ],
13038 initial: "auto",
13039 appliesto: "allElements",
13040 computed: "asSpecified",
13041 order: "uniqueOrder",
13042 status: "nonstandard",
13043 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-hyphenate-limit-chars"
13044 },
13045 "-ms-hyphenate-limit-lines": {
13046 syntax: "no-limit | <integer>",
13047 media: "visual",
13048 inherited: true,
13049 animationType: "discrete",
13050 percentages: "no",
13051 groups: [
13052 "Microsoft Extensions"
13053 ],
13054 initial: "no-limit",
13055 appliesto: "blockContainerElements",
13056 computed: "asSpecified",
13057 order: "uniqueOrder",
13058 status: "nonstandard",
13059 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-hyphenate-limit-lines"
13060 },
13061 "-ms-hyphenate-limit-zone": {
13062 syntax: "<percentage> | <length>",
13063 media: "visual",
13064 inherited: true,
13065 animationType: "discrete",
13066 percentages: "referToLineBoxWidth",
13067 groups: [
13068 "Microsoft Extensions"
13069 ],
13070 initial: "0",
13071 appliesto: "blockContainerElements",
13072 computed: "asSpecified",
13073 order: "uniqueOrder",
13074 status: "nonstandard",
13075 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-hyphenate-limit-zone"
13076 },
13077 "-ms-ime-align": {
13078 syntax: "auto | after",
13079 media: "visual",
13080 inherited: false,
13081 animationType: "discrete",
13082 percentages: "no",
13083 groups: [
13084 "Microsoft Extensions"
13085 ],
13086 initial: "auto",
13087 appliesto: "allElements",
13088 computed: "asSpecified",
13089 order: "uniqueOrder",
13090 status: "nonstandard",
13091 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-ime-align"
13092 },
13093 "-ms-overflow-style": {
13094 syntax: "auto | none | scrollbar | -ms-autohiding-scrollbar",
13095 media: "interactive",
13096 inherited: true,
13097 animationType: "discrete",
13098 percentages: "no",
13099 groups: [
13100 "Microsoft Extensions"
13101 ],
13102 initial: "auto",
13103 appliesto: "nonReplacedBlockAndInlineBlockElements",
13104 computed: "asSpecified",
13105 order: "uniqueOrder",
13106 status: "nonstandard",
13107 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-overflow-style"
13108 },
13109 "-ms-scrollbar-3dlight-color": {
13110 syntax: "<color>",
13111 media: "visual",
13112 inherited: true,
13113 animationType: "discrete",
13114 percentages: "no",
13115 groups: [
13116 "Microsoft Extensions"
13117 ],
13118 initial: "dependsOnUserAgent",
13119 appliesto: "allElements",
13120 computed: "asSpecified",
13121 order: "uniqueOrder",
13122 status: "nonstandard",
13123 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scrollbar-3dlight-color"
13124 },
13125 "-ms-scrollbar-arrow-color": {
13126 syntax: "<color>",
13127 media: "visual",
13128 inherited: true,
13129 animationType: "discrete",
13130 percentages: "no",
13131 groups: [
13132 "Microsoft Extensions"
13133 ],
13134 initial: "ButtonText",
13135 appliesto: "allElements",
13136 computed: "asSpecified",
13137 order: "uniqueOrder",
13138 status: "nonstandard",
13139 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scrollbar-arrow-color"
13140 },
13141 "-ms-scrollbar-base-color": {
13142 syntax: "<color>",
13143 media: "visual",
13144 inherited: true,
13145 animationType: "discrete",
13146 percentages: "no",
13147 groups: [
13148 "Microsoft Extensions"
13149 ],
13150 initial: "dependsOnUserAgent",
13151 appliesto: "allElements",
13152 computed: "asSpecified",
13153 order: "uniqueOrder",
13154 status: "nonstandard",
13155 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scrollbar-base-color"
13156 },
13157 "-ms-scrollbar-darkshadow-color": {
13158 syntax: "<color>",
13159 media: "visual",
13160 inherited: true,
13161 animationType: "discrete",
13162 percentages: "no",
13163 groups: [
13164 "Microsoft Extensions"
13165 ],
13166 initial: "ThreeDDarkShadow",
13167 appliesto: "allElements",
13168 computed: "asSpecified",
13169 order: "uniqueOrder",
13170 status: "nonstandard",
13171 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scrollbar-darkshadow-color"
13172 },
13173 "-ms-scrollbar-face-color": {
13174 syntax: "<color>",
13175 media: "visual",
13176 inherited: true,
13177 animationType: "discrete",
13178 percentages: "no",
13179 groups: [
13180 "Microsoft Extensions"
13181 ],
13182 initial: "ThreeDFace",
13183 appliesto: "allElements",
13184 computed: "asSpecified",
13185 order: "uniqueOrder",
13186 status: "nonstandard",
13187 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scrollbar-face-color"
13188 },
13189 "-ms-scrollbar-highlight-color": {
13190 syntax: "<color>",
13191 media: "visual",
13192 inherited: true,
13193 animationType: "discrete",
13194 percentages: "no",
13195 groups: [
13196 "Microsoft Extensions"
13197 ],
13198 initial: "ThreeDHighlight",
13199 appliesto: "allElements",
13200 computed: "asSpecified",
13201 order: "uniqueOrder",
13202 status: "nonstandard",
13203 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scrollbar-highlight-color"
13204 },
13205 "-ms-scrollbar-shadow-color": {
13206 syntax: "<color>",
13207 media: "visual",
13208 inherited: true,
13209 animationType: "discrete",
13210 percentages: "no",
13211 groups: [
13212 "Microsoft Extensions"
13213 ],
13214 initial: "ThreeDDarkShadow",
13215 appliesto: "allElements",
13216 computed: "asSpecified",
13217 order: "uniqueOrder",
13218 status: "nonstandard",
13219 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scrollbar-shadow-color"
13220 },
13221 "-ms-scrollbar-track-color": {
13222 syntax: "<color>",
13223 media: "visual",
13224 inherited: true,
13225 animationType: "discrete",
13226 percentages: "no",
13227 groups: [
13228 "Microsoft Extensions"
13229 ],
13230 initial: "Scrollbar",
13231 appliesto: "allElements",
13232 computed: "asSpecified",
13233 order: "uniqueOrder",
13234 status: "nonstandard",
13235 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scrollbar-track-color"
13236 },
13237 "-ms-scroll-chaining": {
13238 syntax: "chained | none",
13239 media: "interactive",
13240 inherited: false,
13241 animationType: "discrete",
13242 percentages: "no",
13243 groups: [
13244 "Microsoft Extensions"
13245 ],
13246 initial: "chained",
13247 appliesto: "nonReplacedBlockAndInlineBlockElements",
13248 computed: "asSpecified",
13249 order: "uniqueOrder",
13250 status: "nonstandard",
13251 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scroll-chaining"
13252 },
13253 "-ms-scroll-limit": {
13254 syntax: "<'-ms-scroll-limit-x-min'> <'-ms-scroll-limit-y-min'> <'-ms-scroll-limit-x-max'> <'-ms-scroll-limit-y-max'>",
13255 media: "interactive",
13256 inherited: false,
13257 animationType: "discrete",
13258 percentages: "no",
13259 groups: [
13260 "Microsoft Extensions"
13261 ],
13262 initial: [
13263 "-ms-scroll-limit-x-min",
13264 "-ms-scroll-limit-y-min",
13265 "-ms-scroll-limit-x-max",
13266 "-ms-scroll-limit-y-max"
13267 ],
13268 appliesto: "nonReplacedBlockAndInlineBlockElements",
13269 computed: [
13270 "-ms-scroll-limit-x-min",
13271 "-ms-scroll-limit-y-min",
13272 "-ms-scroll-limit-x-max",
13273 "-ms-scroll-limit-y-max"
13274 ],
13275 order: "uniqueOrder",
13276 status: "nonstandard",
13277 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scroll-limit"
13278 },
13279 "-ms-scroll-limit-x-max": {
13280 syntax: "auto | <length>",
13281 media: "interactive",
13282 inherited: false,
13283 animationType: "discrete",
13284 percentages: "no",
13285 groups: [
13286 "Microsoft Extensions"
13287 ],
13288 initial: "auto",
13289 appliesto: "nonReplacedBlockAndInlineBlockElements",
13290 computed: "asSpecified",
13291 order: "uniqueOrder",
13292 status: "nonstandard",
13293 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scroll-limit-x-max"
13294 },
13295 "-ms-scroll-limit-x-min": {
13296 syntax: "<length>",
13297 media: "interactive",
13298 inherited: false,
13299 animationType: "discrete",
13300 percentages: "no",
13301 groups: [
13302 "Microsoft Extensions"
13303 ],
13304 initial: "0",
13305 appliesto: "nonReplacedBlockAndInlineBlockElements",
13306 computed: "asSpecified",
13307 order: "uniqueOrder",
13308 status: "nonstandard",
13309 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scroll-limit-x-min"
13310 },
13311 "-ms-scroll-limit-y-max": {
13312 syntax: "auto | <length>",
13313 media: "interactive",
13314 inherited: false,
13315 animationType: "discrete",
13316 percentages: "no",
13317 groups: [
13318 "Microsoft Extensions"
13319 ],
13320 initial: "auto",
13321 appliesto: "nonReplacedBlockAndInlineBlockElements",
13322 computed: "asSpecified",
13323 order: "uniqueOrder",
13324 status: "nonstandard",
13325 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scroll-limit-y-max"
13326 },
13327 "-ms-scroll-limit-y-min": {
13328 syntax: "<length>",
13329 media: "interactive",
13330 inherited: false,
13331 animationType: "discrete",
13332 percentages: "no",
13333 groups: [
13334 "Microsoft Extensions"
13335 ],
13336 initial: "0",
13337 appliesto: "nonReplacedBlockAndInlineBlockElements",
13338 computed: "asSpecified",
13339 order: "uniqueOrder",
13340 status: "nonstandard",
13341 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scroll-limit-y-min"
13342 },
13343 "-ms-scroll-rails": {
13344 syntax: "none | railed",
13345 media: "interactive",
13346 inherited: false,
13347 animationType: "discrete",
13348 percentages: "no",
13349 groups: [
13350 "Microsoft Extensions"
13351 ],
13352 initial: "railed",
13353 appliesto: "nonReplacedBlockAndInlineBlockElements",
13354 computed: "asSpecified",
13355 order: "uniqueOrder",
13356 status: "nonstandard",
13357 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scroll-rails"
13358 },
13359 "-ms-scroll-snap-points-x": {
13360 syntax: "snapInterval( <length-percentage>, <length-percentage> ) | snapList( <length-percentage># )",
13361 media: "interactive",
13362 inherited: false,
13363 animationType: "discrete",
13364 percentages: "no",
13365 groups: [
13366 "Microsoft Extensions"
13367 ],
13368 initial: "snapInterval(0px, 100%)",
13369 appliesto: "nonReplacedBlockAndInlineBlockElements",
13370 computed: "asSpecified",
13371 order: "uniqueOrder",
13372 status: "nonstandard",
13373 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scroll-snap-points-x"
13374 },
13375 "-ms-scroll-snap-points-y": {
13376 syntax: "snapInterval( <length-percentage>, <length-percentage> ) | snapList( <length-percentage># )",
13377 media: "interactive",
13378 inherited: false,
13379 animationType: "discrete",
13380 percentages: "no",
13381 groups: [
13382 "Microsoft Extensions"
13383 ],
13384 initial: "snapInterval(0px, 100%)",
13385 appliesto: "nonReplacedBlockAndInlineBlockElements",
13386 computed: "asSpecified",
13387 order: "uniqueOrder",
13388 status: "nonstandard",
13389 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scroll-snap-points-y"
13390 },
13391 "-ms-scroll-snap-type": {
13392 syntax: "none | proximity | mandatory",
13393 media: "interactive",
13394 inherited: false,
13395 animationType: "discrete",
13396 percentages: "no",
13397 groups: [
13398 "Microsoft Extensions"
13399 ],
13400 initial: "none",
13401 appliesto: "nonReplacedBlockAndInlineBlockElements",
13402 computed: "asSpecified",
13403 order: "uniqueOrder",
13404 status: "nonstandard",
13405 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scroll-snap-type"
13406 },
13407 "-ms-scroll-snap-x": {
13408 syntax: "<'-ms-scroll-snap-type'> <'-ms-scroll-snap-points-x'>",
13409 media: "interactive",
13410 inherited: false,
13411 animationType: "discrete",
13412 percentages: "no",
13413 groups: [
13414 "Microsoft Extensions"
13415 ],
13416 initial: [
13417 "-ms-scroll-snap-type",
13418 "-ms-scroll-snap-points-x"
13419 ],
13420 appliesto: "nonReplacedBlockAndInlineBlockElements",
13421 computed: [
13422 "-ms-scroll-snap-type",
13423 "-ms-scroll-snap-points-x"
13424 ],
13425 order: "uniqueOrder",
13426 status: "nonstandard",
13427 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scroll-snap-x"
13428 },
13429 "-ms-scroll-snap-y": {
13430 syntax: "<'-ms-scroll-snap-type'> <'-ms-scroll-snap-points-y'>",
13431 media: "interactive",
13432 inherited: false,
13433 animationType: "discrete",
13434 percentages: "no",
13435 groups: [
13436 "Microsoft Extensions"
13437 ],
13438 initial: [
13439 "-ms-scroll-snap-type",
13440 "-ms-scroll-snap-points-y"
13441 ],
13442 appliesto: "nonReplacedBlockAndInlineBlockElements",
13443 computed: [
13444 "-ms-scroll-snap-type",
13445 "-ms-scroll-snap-points-y"
13446 ],
13447 order: "uniqueOrder",
13448 status: "nonstandard",
13449 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scroll-snap-y"
13450 },
13451 "-ms-scroll-translation": {
13452 syntax: "none | vertical-to-horizontal",
13453 media: "interactive",
13454 inherited: true,
13455 animationType: "discrete",
13456 percentages: "no",
13457 groups: [
13458 "Microsoft Extensions"
13459 ],
13460 initial: "none",
13461 appliesto: "allElements",
13462 computed: "asSpecified",
13463 order: "uniqueOrder",
13464 status: "nonstandard",
13465 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scroll-translation"
13466 },
13467 "-ms-text-autospace": {
13468 syntax: "none | ideograph-alpha | ideograph-numeric | ideograph-parenthesis | ideograph-space",
13469 media: "visual",
13470 inherited: false,
13471 animationType: "discrete",
13472 percentages: "no",
13473 groups: [
13474 "Microsoft Extensions"
13475 ],
13476 initial: "none",
13477 appliesto: "allElements",
13478 computed: "asSpecified",
13479 order: "uniqueOrder",
13480 status: "nonstandard",
13481 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-text-autospace"
13482 },
13483 "-ms-touch-select": {
13484 syntax: "grippers | none",
13485 media: "interactive",
13486 inherited: true,
13487 animationType: "discrete",
13488 percentages: "no",
13489 groups: [
13490 "Microsoft Extensions"
13491 ],
13492 initial: "grippers",
13493 appliesto: "allElements",
13494 computed: "asSpecified",
13495 order: "uniqueOrder",
13496 status: "nonstandard",
13497 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-touch-select"
13498 },
13499 "-ms-user-select": {
13500 syntax: "none | element | text",
13501 media: "interactive",
13502 inherited: false,
13503 animationType: "discrete",
13504 percentages: "no",
13505 groups: [
13506 "Microsoft Extensions"
13507 ],
13508 initial: "text",
13509 appliesto: "nonReplacedElements",
13510 computed: "asSpecified",
13511 order: "uniqueOrder",
13512 status: "nonstandard",
13513 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-user-select"
13514 },
13515 "-ms-wrap-flow": {
13516 syntax: "auto | both | start | end | maximum | clear",
13517 media: "visual",
13518 inherited: false,
13519 animationType: "discrete",
13520 percentages: "no",
13521 groups: [
13522 "Microsoft Extensions"
13523 ],
13524 initial: "auto",
13525 appliesto: "blockLevelElements",
13526 computed: "asSpecified",
13527 order: "uniqueOrder",
13528 status: "nonstandard",
13529 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-wrap-flow"
13530 },
13531 "-ms-wrap-margin": {
13532 syntax: "<length>",
13533 media: "visual",
13534 inherited: false,
13535 animationType: "discrete",
13536 percentages: "no",
13537 groups: [
13538 "Microsoft Extensions"
13539 ],
13540 initial: "0",
13541 appliesto: "exclusionElements",
13542 computed: "asSpecified",
13543 order: "uniqueOrder",
13544 status: "nonstandard",
13545 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-wrap-margin"
13546 },
13547 "-ms-wrap-through": {
13548 syntax: "wrap | none",
13549 media: "visual",
13550 inherited: false,
13551 animationType: "discrete",
13552 percentages: "no",
13553 groups: [
13554 "Microsoft Extensions"
13555 ],
13556 initial: "wrap",
13557 appliesto: "blockLevelElements",
13558 computed: "asSpecified",
13559 order: "uniqueOrder",
13560 status: "nonstandard",
13561 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-wrap-through"
13562 },
13563 "-moz-appearance": {
13564 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",
13565 media: "visual",
13566 inherited: false,
13567 animationType: "discrete",
13568 percentages: "no",
13569 groups: [
13570 "Mozilla Extensions",
13571 "WebKit Extensions"
13572 ],
13573 initial: "noneButOverriddenInUserAgentCSS",
13574 appliesto: "allElements",
13575 computed: "asSpecified",
13576 order: "uniqueOrder",
13577 status: "nonstandard",
13578 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-appearance"
13579 },
13580 "-moz-binding": {
13581 syntax: "<url> | none",
13582 media: "visual",
13583 inherited: false,
13584 animationType: "discrete",
13585 percentages: "no",
13586 groups: [
13587 "Mozilla Extensions"
13588 ],
13589 initial: "none",
13590 appliesto: "allElementsExceptGeneratedContentOrPseudoElements",
13591 computed: "asSpecified",
13592 order: "uniqueOrder",
13593 status: "nonstandard",
13594 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-binding"
13595 },
13596 "-moz-border-bottom-colors": {
13597 syntax: "<color>+ | none",
13598 media: "visual",
13599 inherited: false,
13600 animationType: "discrete",
13601 percentages: "no",
13602 groups: [
13603 "Mozilla Extensions"
13604 ],
13605 initial: "none",
13606 appliesto: "allElements",
13607 computed: "asSpecified",
13608 order: "uniqueOrder",
13609 status: "nonstandard",
13610 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-border-bottom-colors"
13611 },
13612 "-moz-border-left-colors": {
13613 syntax: "<color>+ | none",
13614 media: "visual",
13615 inherited: false,
13616 animationType: "discrete",
13617 percentages: "no",
13618 groups: [
13619 "Mozilla Extensions"
13620 ],
13621 initial: "none",
13622 appliesto: "allElements",
13623 computed: "asSpecified",
13624 order: "uniqueOrder",
13625 status: "nonstandard",
13626 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-border-left-colors"
13627 },
13628 "-moz-border-right-colors": {
13629 syntax: "<color>+ | none",
13630 media: "visual",
13631 inherited: false,
13632 animationType: "discrete",
13633 percentages: "no",
13634 groups: [
13635 "Mozilla Extensions"
13636 ],
13637 initial: "none",
13638 appliesto: "allElements",
13639 computed: "asSpecified",
13640 order: "uniqueOrder",
13641 status: "nonstandard",
13642 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-border-right-colors"
13643 },
13644 "-moz-border-top-colors": {
13645 syntax: "<color>+ | none",
13646 media: "visual",
13647 inherited: false,
13648 animationType: "discrete",
13649 percentages: "no",
13650 groups: [
13651 "Mozilla Extensions"
13652 ],
13653 initial: "none",
13654 appliesto: "allElements",
13655 computed: "asSpecified",
13656 order: "uniqueOrder",
13657 status: "nonstandard",
13658 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-border-top-colors"
13659 },
13660 "-moz-context-properties": {
13661 syntax: "none | [ fill | fill-opacity | stroke | stroke-opacity ]#",
13662 media: "visual",
13663 inherited: true,
13664 animationType: "discrete",
13665 percentages: "no",
13666 groups: [
13667 "Mozilla Extensions"
13668 ],
13669 initial: "none",
13670 appliesto: "allElementsThatCanReferenceImages",
13671 computed: "asSpecified",
13672 order: "uniqueOrder",
13673 status: "nonstandard",
13674 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-context-properties"
13675 },
13676 "-moz-float-edge": {
13677 syntax: "border-box | content-box | margin-box | padding-box",
13678 media: "visual",
13679 inherited: false,
13680 animationType: "discrete",
13681 percentages: "no",
13682 groups: [
13683 "Mozilla Extensions"
13684 ],
13685 initial: "content-box",
13686 appliesto: "allElements",
13687 computed: "asSpecified",
13688 order: "uniqueOrder",
13689 status: "nonstandard",
13690 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-float-edge"
13691 },
13692 "-moz-force-broken-image-icon": {
13693 syntax: "<integer>",
13694 media: "visual",
13695 inherited: false,
13696 animationType: "discrete",
13697 percentages: "no",
13698 groups: [
13699 "Mozilla Extensions"
13700 ],
13701 initial: "0",
13702 appliesto: "images",
13703 computed: "asSpecified",
13704 order: "uniqueOrder",
13705 status: "nonstandard",
13706 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-force-broken-image-icon"
13707 },
13708 "-moz-image-region": {
13709 syntax: "<shape> | auto",
13710 media: "visual",
13711 inherited: true,
13712 animationType: "discrete",
13713 percentages: "no",
13714 groups: [
13715 "Mozilla Extensions"
13716 ],
13717 initial: "auto",
13718 appliesto: "xulImageElements",
13719 computed: "asSpecified",
13720 order: "uniqueOrder",
13721 status: "nonstandard",
13722 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-image-region"
13723 },
13724 "-moz-orient": {
13725 syntax: "inline | block | horizontal | vertical",
13726 media: "visual",
13727 inherited: false,
13728 animationType: "discrete",
13729 percentages: "no",
13730 groups: [
13731 "Mozilla Extensions"
13732 ],
13733 initial: "inline",
13734 appliesto: "anyElementEffectOnProgressAndMeter",
13735 computed: "asSpecified",
13736 order: "uniqueOrder",
13737 status: "nonstandard",
13738 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-orient"
13739 },
13740 "-moz-outline-radius": {
13741 syntax: "<outline-radius>{1,4} [ / <outline-radius>{1,4} ]?",
13742 media: "visual",
13743 inherited: false,
13744 animationType: [
13745 "-moz-outline-radius-topleft",
13746 "-moz-outline-radius-topright",
13747 "-moz-outline-radius-bottomright",
13748 "-moz-outline-radius-bottomleft"
13749 ],
13750 percentages: [
13751 "-moz-outline-radius-topleft",
13752 "-moz-outline-radius-topright",
13753 "-moz-outline-radius-bottomright",
13754 "-moz-outline-radius-bottomleft"
13755 ],
13756 groups: [
13757 "Mozilla Extensions"
13758 ],
13759 initial: [
13760 "-moz-outline-radius-topleft",
13761 "-moz-outline-radius-topright",
13762 "-moz-outline-radius-bottomright",
13763 "-moz-outline-radius-bottomleft"
13764 ],
13765 appliesto: "allElements",
13766 computed: [
13767 "-moz-outline-radius-topleft",
13768 "-moz-outline-radius-topright",
13769 "-moz-outline-radius-bottomright",
13770 "-moz-outline-radius-bottomleft"
13771 ],
13772 order: "uniqueOrder",
13773 status: "nonstandard",
13774 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-outline-radius"
13775 },
13776 "-moz-outline-radius-bottomleft": {
13777 syntax: "<outline-radius>",
13778 media: "visual",
13779 inherited: false,
13780 animationType: "lpc",
13781 percentages: "referToDimensionOfBorderBox",
13782 groups: [
13783 "Mozilla Extensions"
13784 ],
13785 initial: "0",
13786 appliesto: "allElements",
13787 computed: "asSpecified",
13788 order: "uniqueOrder",
13789 status: "nonstandard",
13790 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-outline-radius-bottomleft"
13791 },
13792 "-moz-outline-radius-bottomright": {
13793 syntax: "<outline-radius>",
13794 media: "visual",
13795 inherited: false,
13796 animationType: "lpc",
13797 percentages: "referToDimensionOfBorderBox",
13798 groups: [
13799 "Mozilla Extensions"
13800 ],
13801 initial: "0",
13802 appliesto: "allElements",
13803 computed: "asSpecified",
13804 order: "uniqueOrder",
13805 status: "nonstandard",
13806 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-outline-radius-bottomright"
13807 },
13808 "-moz-outline-radius-topleft": {
13809 syntax: "<outline-radius>",
13810 media: "visual",
13811 inherited: false,
13812 animationType: "lpc",
13813 percentages: "referToDimensionOfBorderBox",
13814 groups: [
13815 "Mozilla Extensions"
13816 ],
13817 initial: "0",
13818 appliesto: "allElements",
13819 computed: "asSpecified",
13820 order: "uniqueOrder",
13821 status: "nonstandard",
13822 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-outline-radius-topleft"
13823 },
13824 "-moz-outline-radius-topright": {
13825 syntax: "<outline-radius>",
13826 media: "visual",
13827 inherited: false,
13828 animationType: "lpc",
13829 percentages: "referToDimensionOfBorderBox",
13830 groups: [
13831 "Mozilla Extensions"
13832 ],
13833 initial: "0",
13834 appliesto: "allElements",
13835 computed: "asSpecified",
13836 order: "uniqueOrder",
13837 status: "nonstandard",
13838 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-outline-radius-topright"
13839 },
13840 "-moz-stack-sizing": {
13841 syntax: "ignore | stretch-to-fit",
13842 media: "visual",
13843 inherited: true,
13844 animationType: "discrete",
13845 percentages: "no",
13846 groups: [
13847 "Mozilla Extensions"
13848 ],
13849 initial: "stretch-to-fit",
13850 appliesto: "allElements",
13851 computed: "asSpecified",
13852 order: "uniqueOrder",
13853 status: "nonstandard",
13854 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-stack-sizing"
13855 },
13856 "-moz-text-blink": {
13857 syntax: "none | blink",
13858 media: "visual",
13859 inherited: false,
13860 animationType: "discrete",
13861 percentages: "no",
13862 groups: [
13863 "Mozilla Extensions"
13864 ],
13865 initial: "none",
13866 appliesto: "allElements",
13867 computed: "asSpecified",
13868 order: "uniqueOrder",
13869 status: "nonstandard",
13870 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-text-blink"
13871 },
13872 "-moz-user-focus": {
13873 syntax: "ignore | normal | select-after | select-before | select-menu | select-same | select-all | none",
13874 media: "interactive",
13875 inherited: false,
13876 animationType: "discrete",
13877 percentages: "no",
13878 groups: [
13879 "Mozilla Extensions"
13880 ],
13881 initial: "none",
13882 appliesto: "allElements",
13883 computed: "asSpecified",
13884 order: "uniqueOrder",
13885 status: "nonstandard",
13886 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-user-focus"
13887 },
13888 "-moz-user-input": {
13889 syntax: "auto | none | enabled | disabled",
13890 media: "visual",
13891 inherited: true,
13892 animationType: "discrete",
13893 percentages: "no",
13894 groups: [
13895 "Mozilla Extensions"
13896 ],
13897 initial: "auto",
13898 appliesto: "allElements",
13899 computed: "asSpecified",
13900 order: "uniqueOrder",
13901 status: "nonstandard",
13902 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-user-input"
13903 },
13904 "-moz-user-modify": {
13905 syntax: "read-only | read-write | write-only",
13906 media: "interactive",
13907 inherited: true,
13908 animationType: "discrete",
13909 percentages: "no",
13910 groups: [
13911 "Mozilla Extensions"
13912 ],
13913 initial: "read-only",
13914 appliesto: "allElements",
13915 computed: "asSpecified",
13916 order: "uniqueOrder",
13917 status: "nonstandard",
13918 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-user-modify"
13919 },
13920 "-moz-window-dragging": {
13921 syntax: "drag | no-drag",
13922 media: "visual",
13923 inherited: false,
13924 animationType: "discrete",
13925 percentages: "no",
13926 groups: [
13927 "Mozilla Extensions"
13928 ],
13929 initial: "drag",
13930 appliesto: "allElementsCreatingNativeWindows",
13931 computed: "asSpecified",
13932 order: "uniqueOrder",
13933 status: "nonstandard",
13934 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-window-dragging"
13935 },
13936 "-moz-window-shadow": {
13937 syntax: "default | menu | tooltip | sheet | none",
13938 media: "visual",
13939 inherited: false,
13940 animationType: "discrete",
13941 percentages: "no",
13942 groups: [
13943 "Mozilla Extensions"
13944 ],
13945 initial: "default",
13946 appliesto: "allElementsCreatingNativeWindows",
13947 computed: "asSpecified",
13948 order: "uniqueOrder",
13949 status: "nonstandard",
13950 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-window-shadow"
13951 },
13952 "-webkit-appearance": {
13953 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",
13954 media: "visual",
13955 inherited: false,
13956 animationType: "discrete",
13957 percentages: "no",
13958 groups: [
13959 "WebKit Extensions"
13960 ],
13961 initial: "noneButOverriddenInUserAgentCSS",
13962 appliesto: "allElements",
13963 computed: "asSpecified",
13964 order: "uniqueOrder",
13965 status: "nonstandard",
13966 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-appearance"
13967 },
13968 "-webkit-border-before": {
13969 syntax: "<'border-width'> || <'border-style'> || <'color'>",
13970 media: "visual",
13971 inherited: true,
13972 animationType: "discrete",
13973 percentages: [
13974 "-webkit-border-before-width"
13975 ],
13976 groups: [
13977 "WebKit Extensions"
13978 ],
13979 initial: [
13980 "border-width",
13981 "border-style",
13982 "color"
13983 ],
13984 appliesto: "allElements",
13985 computed: [
13986 "border-width",
13987 "border-style",
13988 "color"
13989 ],
13990 order: "uniqueOrder",
13991 status: "nonstandard",
13992 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-border-before"
13993 },
13994 "-webkit-border-before-color": {
13995 syntax: "<'color'>",
13996 media: "visual",
13997 inherited: true,
13998 animationType: "discrete",
13999 percentages: "no",
14000 groups: [
14001 "WebKit Extensions"
14002 ],
14003 initial: "currentcolor",
14004 appliesto: "allElements",
14005 computed: "computedColor",
14006 order: "uniqueOrder",
14007 status: "nonstandard"
14008 },
14009 "-webkit-border-before-style": {
14010 syntax: "<'border-style'>",
14011 media: "visual",
14012 inherited: true,
14013 animationType: "discrete",
14014 percentages: "no",
14015 groups: [
14016 "WebKit Extensions"
14017 ],
14018 initial: "none",
14019 appliesto: "allElements",
14020 computed: "asSpecified",
14021 order: "uniqueOrder",
14022 status: "nonstandard"
14023 },
14024 "-webkit-border-before-width": {
14025 syntax: "<'border-width'>",
14026 media: "visual",
14027 inherited: true,
14028 animationType: "discrete",
14029 percentages: "logicalWidthOfContainingBlock",
14030 groups: [
14031 "WebKit Extensions"
14032 ],
14033 initial: "medium",
14034 appliesto: "allElements",
14035 computed: "absoluteLengthZeroIfBorderStyleNoneOrHidden",
14036 order: "uniqueOrder",
14037 status: "nonstandard"
14038 },
14039 "-webkit-box-reflect": {
14040 syntax: "[ above | below | right | left ]? <length>? <image>?",
14041 media: "visual",
14042 inherited: false,
14043 animationType: "discrete",
14044 percentages: "no",
14045 groups: [
14046 "WebKit Extensions"
14047 ],
14048 initial: "none",
14049 appliesto: "allElements",
14050 computed: "asSpecified",
14051 order: "uniqueOrder",
14052 status: "nonstandard",
14053 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-box-reflect"
14054 },
14055 "-webkit-line-clamp": {
14056 syntax: "none | <integer>",
14057 media: "visual",
14058 inherited: false,
14059 animationType: "byComputedValueType",
14060 percentages: "no",
14061 groups: [
14062 "WebKit Extensions",
14063 "CSS Overflow"
14064 ],
14065 initial: "none",
14066 appliesto: "allElements",
14067 computed: "asSpecified",
14068 order: "uniqueOrder",
14069 status: "standard",
14070 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-line-clamp"
14071 },
14072 "-webkit-mask": {
14073 syntax: "[ <mask-reference> || <position> [ / <bg-size> ]? || <repeat-style> || [ <box> | border | padding | content | text ] || [ <box> | border | padding | content ] ]#",
14074 media: "visual",
14075 inherited: false,
14076 animationType: "discrete",
14077 percentages: "no",
14078 groups: [
14079 "WebKit Extensions"
14080 ],
14081 initial: [
14082 "-webkit-mask-image",
14083 "-webkit-mask-repeat",
14084 "-webkit-mask-attachment",
14085 "-webkit-mask-position",
14086 "-webkit-mask-origin",
14087 "-webkit-mask-clip"
14088 ],
14089 appliesto: "allElements",
14090 computed: [
14091 "-webkit-mask-image",
14092 "-webkit-mask-repeat",
14093 "-webkit-mask-attachment",
14094 "-webkit-mask-position",
14095 "-webkit-mask-origin",
14096 "-webkit-mask-clip"
14097 ],
14098 order: "uniqueOrder",
14099 status: "nonstandard",
14100 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask"
14101 },
14102 "-webkit-mask-attachment": {
14103 syntax: "<attachment>#",
14104 media: "visual",
14105 inherited: false,
14106 animationType: "discrete",
14107 percentages: "no",
14108 groups: [
14109 "WebKit Extensions"
14110 ],
14111 initial: "scroll",
14112 appliesto: "allElements",
14113 computed: "asSpecified",
14114 order: "orderOfAppearance",
14115 status: "nonstandard",
14116 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-mask-attachment"
14117 },
14118 "-webkit-mask-clip": {
14119 syntax: "[ <box> | border | padding | content | text ]#",
14120 media: "visual",
14121 inherited: false,
14122 animationType: "discrete",
14123 percentages: "no",
14124 groups: [
14125 "WebKit Extensions"
14126 ],
14127 initial: "border",
14128 appliesto: "allElements",
14129 computed: "asSpecified",
14130 order: "orderOfAppearance",
14131 status: "nonstandard",
14132 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-clip"
14133 },
14134 "-webkit-mask-composite": {
14135 syntax: "<composite-style>#",
14136 media: "visual",
14137 inherited: false,
14138 animationType: "discrete",
14139 percentages: "no",
14140 groups: [
14141 "WebKit Extensions"
14142 ],
14143 initial: "source-over",
14144 appliesto: "allElements",
14145 computed: "asSpecified",
14146 order: "orderOfAppearance",
14147 status: "nonstandard",
14148 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-mask-composite"
14149 },
14150 "-webkit-mask-image": {
14151 syntax: "<mask-reference>#",
14152 media: "visual",
14153 inherited: false,
14154 animationType: "discrete",
14155 percentages: "no",
14156 groups: [
14157 "WebKit Extensions"
14158 ],
14159 initial: "none",
14160 appliesto: "allElements",
14161 computed: "absoluteURIOrNone",
14162 order: "orderOfAppearance",
14163 status: "nonstandard",
14164 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-image"
14165 },
14166 "-webkit-mask-origin": {
14167 syntax: "[ <box> | border | padding | content ]#",
14168 media: "visual",
14169 inherited: false,
14170 animationType: "discrete",
14171 percentages: "no",
14172 groups: [
14173 "WebKit Extensions"
14174 ],
14175 initial: "padding",
14176 appliesto: "allElements",
14177 computed: "asSpecified",
14178 order: "orderOfAppearance",
14179 status: "nonstandard",
14180 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-origin"
14181 },
14182 "-webkit-mask-position": {
14183 syntax: "<position>#",
14184 media: "visual",
14185 inherited: false,
14186 animationType: "discrete",
14187 percentages: "referToSizeOfElement",
14188 groups: [
14189 "WebKit Extensions"
14190 ],
14191 initial: "0% 0%",
14192 appliesto: "allElements",
14193 computed: "absoluteLengthOrPercentage",
14194 order: "orderOfAppearance",
14195 status: "nonstandard",
14196 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-position"
14197 },
14198 "-webkit-mask-position-x": {
14199 syntax: "[ <length-percentage> | left | center | right ]#",
14200 media: "visual",
14201 inherited: false,
14202 animationType: "discrete",
14203 percentages: "referToSizeOfElement",
14204 groups: [
14205 "WebKit Extensions"
14206 ],
14207 initial: "0%",
14208 appliesto: "allElements",
14209 computed: "absoluteLengthOrPercentage",
14210 order: "orderOfAppearance",
14211 status: "nonstandard",
14212 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-mask-position-x"
14213 },
14214 "-webkit-mask-position-y": {
14215 syntax: "[ <length-percentage> | top | center | bottom ]#",
14216 media: "visual",
14217 inherited: false,
14218 animationType: "discrete",
14219 percentages: "referToSizeOfElement",
14220 groups: [
14221 "WebKit Extensions"
14222 ],
14223 initial: "0%",
14224 appliesto: "allElements",
14225 computed: "absoluteLengthOrPercentage",
14226 order: "orderOfAppearance",
14227 status: "nonstandard",
14228 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-mask-position-y"
14229 },
14230 "-webkit-mask-repeat": {
14231 syntax: "<repeat-style>#",
14232 media: "visual",
14233 inherited: false,
14234 animationType: "discrete",
14235 percentages: "no",
14236 groups: [
14237 "WebKit Extensions"
14238 ],
14239 initial: "repeat",
14240 appliesto: "allElements",
14241 computed: "asSpecified",
14242 order: "orderOfAppearance",
14243 status: "nonstandard",
14244 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-repeat"
14245 },
14246 "-webkit-mask-repeat-x": {
14247 syntax: "repeat | no-repeat | space | round",
14248 media: "visual",
14249 inherited: false,
14250 animationType: "discrete",
14251 percentages: "no",
14252 groups: [
14253 "WebKit Extensions"
14254 ],
14255 initial: "repeat",
14256 appliesto: "allElements",
14257 computed: "asSpecified",
14258 order: "orderOfAppearance",
14259 status: "nonstandard",
14260 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-mask-repeat-x"
14261 },
14262 "-webkit-mask-repeat-y": {
14263 syntax: "repeat | no-repeat | space | round",
14264 media: "visual",
14265 inherited: false,
14266 animationType: "discrete",
14267 percentages: "no",
14268 groups: [
14269 "WebKit Extensions"
14270 ],
14271 initial: "repeat",
14272 appliesto: "allElements",
14273 computed: "absoluteLengthOrPercentage",
14274 order: "orderOfAppearance",
14275 status: "nonstandard",
14276 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-mask-repeat-y"
14277 },
14278 "-webkit-mask-size": {
14279 syntax: "<bg-size>#",
14280 media: "visual",
14281 inherited: false,
14282 animationType: "discrete",
14283 percentages: "relativeToBackgroundPositioningArea",
14284 groups: [
14285 "WebKit Extensions"
14286 ],
14287 initial: "auto auto",
14288 appliesto: "allElements",
14289 computed: "asSpecified",
14290 order: "orderOfAppearance",
14291 status: "nonstandard",
14292 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-size"
14293 },
14294 "-webkit-overflow-scrolling": {
14295 syntax: "auto | touch",
14296 media: "visual",
14297 inherited: true,
14298 animationType: "discrete",
14299 percentages: "no",
14300 groups: [
14301 "WebKit Extensions"
14302 ],
14303 initial: "auto",
14304 appliesto: "scrollingBoxes",
14305 computed: "asSpecified",
14306 order: "orderOfAppearance",
14307 status: "nonstandard",
14308 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-overflow-scrolling"
14309 },
14310 "-webkit-tap-highlight-color": {
14311 syntax: "<color>",
14312 media: "visual",
14313 inherited: false,
14314 animationType: "discrete",
14315 percentages: "no",
14316 groups: [
14317 "WebKit Extensions"
14318 ],
14319 initial: "black",
14320 appliesto: "allElements",
14321 computed: "asSpecified",
14322 order: "uniqueOrder",
14323 status: "nonstandard",
14324 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-tap-highlight-color"
14325 },
14326 "-webkit-text-fill-color": {
14327 syntax: "<color>",
14328 media: "visual",
14329 inherited: true,
14330 animationType: "color",
14331 percentages: "no",
14332 groups: [
14333 "WebKit Extensions"
14334 ],
14335 initial: "currentcolor",
14336 appliesto: "allElements",
14337 computed: "computedColor",
14338 order: "uniqueOrder",
14339 status: "nonstandard",
14340 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-text-fill-color"
14341 },
14342 "-webkit-text-stroke": {
14343 syntax: "<length> || <color>",
14344 media: "visual",
14345 inherited: true,
14346 animationType: [
14347 "-webkit-text-stroke-width",
14348 "-webkit-text-stroke-color"
14349 ],
14350 percentages: "no",
14351 groups: [
14352 "WebKit Extensions"
14353 ],
14354 initial: [
14355 "-webkit-text-stroke-width",
14356 "-webkit-text-stroke-color"
14357 ],
14358 appliesto: "allElements",
14359 computed: [
14360 "-webkit-text-stroke-width",
14361 "-webkit-text-stroke-color"
14362 ],
14363 order: "canonicalOrder",
14364 status: "nonstandard",
14365 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-text-stroke"
14366 },
14367 "-webkit-text-stroke-color": {
14368 syntax: "<color>",
14369 media: "visual",
14370 inherited: true,
14371 animationType: "color",
14372 percentages: "no",
14373 groups: [
14374 "WebKit Extensions"
14375 ],
14376 initial: "currentcolor",
14377 appliesto: "allElements",
14378 computed: "computedColor",
14379 order: "uniqueOrder",
14380 status: "nonstandard",
14381 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-text-stroke-color"
14382 },
14383 "-webkit-text-stroke-width": {
14384 syntax: "<length>",
14385 media: "visual",
14386 inherited: true,
14387 animationType: "discrete",
14388 percentages: "no",
14389 groups: [
14390 "WebKit Extensions"
14391 ],
14392 initial: "0",
14393 appliesto: "allElements",
14394 computed: "absoluteLength",
14395 order: "uniqueOrder",
14396 status: "nonstandard",
14397 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-text-stroke-width"
14398 },
14399 "-webkit-touch-callout": {
14400 syntax: "default | none",
14401 media: "visual",
14402 inherited: true,
14403 animationType: "discrete",
14404 percentages: "no",
14405 groups: [
14406 "WebKit Extensions"
14407 ],
14408 initial: "default",
14409 appliesto: "allElements",
14410 computed: "asSpecified",
14411 order: "uniqueOrder",
14412 status: "nonstandard",
14413 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-touch-callout"
14414 },
14415 "-webkit-user-modify": {
14416 syntax: "read-only | read-write | read-write-plaintext-only",
14417 media: "interactive",
14418 inherited: true,
14419 animationType: "discrete",
14420 percentages: "no",
14421 groups: [
14422 "WebKit Extensions"
14423 ],
14424 initial: "read-only",
14425 appliesto: "allElements",
14426 computed: "asSpecified",
14427 order: "uniqueOrder",
14428 status: "nonstandard"
14429 },
14430 "align-content": {
14431 syntax: "normal | <baseline-position> | <content-distribution> | <overflow-position>? <content-position>",
14432 media: "visual",
14433 inherited: false,
14434 animationType: "discrete",
14435 percentages: "no",
14436 groups: [
14437 "CSS Box Alignment"
14438 ],
14439 initial: "normal",
14440 appliesto: "multilineFlexContainers",
14441 computed: "asSpecified",
14442 order: "uniqueOrder",
14443 status: "standard",
14444 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/align-content"
14445 },
14446 "align-items": {
14447 syntax: "normal | stretch | <baseline-position> | [ <overflow-position>? <self-position> ]",
14448 media: "visual",
14449 inherited: false,
14450 animationType: "discrete",
14451 percentages: "no",
14452 groups: [
14453 "CSS Box Alignment"
14454 ],
14455 initial: "normal",
14456 appliesto: "allElements",
14457 computed: "asSpecified",
14458 order: "uniqueOrder",
14459 status: "standard",
14460 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/align-items"
14461 },
14462 "align-self": {
14463 syntax: "auto | normal | stretch | <baseline-position> | <overflow-position>? <self-position>",
14464 media: "visual",
14465 inherited: false,
14466 animationType: "discrete",
14467 percentages: "no",
14468 groups: [
14469 "CSS Box Alignment"
14470 ],
14471 initial: "auto",
14472 appliesto: "flexItemsGridItemsAndAbsolutelyPositionedBoxes",
14473 computed: "autoOnAbsolutelyPositionedElementsValueOfAlignItemsOnParent",
14474 order: "uniqueOrder",
14475 status: "standard",
14476 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/align-self"
14477 },
14478 all: all,
14479 animation: animation,
14480 "animation-delay": {
14481 syntax: "<time>#",
14482 media: "visual",
14483 inherited: false,
14484 animationType: "discrete",
14485 percentages: "no",
14486 groups: [
14487 "CSS Animations"
14488 ],
14489 initial: "0s",
14490 appliesto: "allElementsAndPseudos",
14491 computed: "asSpecified",
14492 order: "uniqueOrder",
14493 status: "standard",
14494 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/animation-delay"
14495 },
14496 "animation-direction": {
14497 syntax: "<single-animation-direction>#",
14498 media: "visual",
14499 inherited: false,
14500 animationType: "discrete",
14501 percentages: "no",
14502 groups: [
14503 "CSS Animations"
14504 ],
14505 initial: "normal",
14506 appliesto: "allElementsAndPseudos",
14507 computed: "asSpecified",
14508 order: "uniqueOrder",
14509 status: "standard",
14510 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/animation-direction"
14511 },
14512 "animation-duration": {
14513 syntax: "<time>#",
14514 media: "visual",
14515 inherited: false,
14516 animationType: "discrete",
14517 percentages: "no",
14518 groups: [
14519 "CSS Animations"
14520 ],
14521 initial: "0s",
14522 appliesto: "allElementsAndPseudos",
14523 computed: "asSpecified",
14524 order: "uniqueOrder",
14525 status: "standard",
14526 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/animation-duration"
14527 },
14528 "animation-fill-mode": {
14529 syntax: "<single-animation-fill-mode>#",
14530 media: "visual",
14531 inherited: false,
14532 animationType: "discrete",
14533 percentages: "no",
14534 groups: [
14535 "CSS Animations"
14536 ],
14537 initial: "none",
14538 appliesto: "allElementsAndPseudos",
14539 computed: "asSpecified",
14540 order: "uniqueOrder",
14541 status: "standard",
14542 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/animation-fill-mode"
14543 },
14544 "animation-iteration-count": {
14545 syntax: "<single-animation-iteration-count>#",
14546 media: "visual",
14547 inherited: false,
14548 animationType: "discrete",
14549 percentages: "no",
14550 groups: [
14551 "CSS Animations"
14552 ],
14553 initial: "1",
14554 appliesto: "allElementsAndPseudos",
14555 computed: "asSpecified",
14556 order: "uniqueOrder",
14557 status: "standard",
14558 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/animation-iteration-count"
14559 },
14560 "animation-name": {
14561 syntax: "[ none | <keyframes-name> ]#",
14562 media: "visual",
14563 inherited: false,
14564 animationType: "discrete",
14565 percentages: "no",
14566 groups: [
14567 "CSS Animations"
14568 ],
14569 initial: "none",
14570 appliesto: "allElementsAndPseudos",
14571 computed: "asSpecified",
14572 order: "uniqueOrder",
14573 status: "standard",
14574 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/animation-name"
14575 },
14576 "animation-play-state": {
14577 syntax: "<single-animation-play-state>#",
14578 media: "visual",
14579 inherited: false,
14580 animationType: "discrete",
14581 percentages: "no",
14582 groups: [
14583 "CSS Animations"
14584 ],
14585 initial: "running",
14586 appliesto: "allElementsAndPseudos",
14587 computed: "asSpecified",
14588 order: "uniqueOrder",
14589 status: "standard",
14590 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/animation-play-state"
14591 },
14592 "animation-timing-function": {
14593 syntax: "<timing-function>#",
14594 media: "visual",
14595 inherited: false,
14596 animationType: "discrete",
14597 percentages: "no",
14598 groups: [
14599 "CSS Animations"
14600 ],
14601 initial: "ease",
14602 appliesto: "allElementsAndPseudos",
14603 computed: "asSpecified",
14604 order: "uniqueOrder",
14605 status: "standard",
14606 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/animation-timing-function"
14607 },
14608 appearance: appearance,
14609 "aspect-ratio": {
14610 syntax: "auto | <ratio>",
14611 media: "all",
14612 inherited: false,
14613 animationType: "discrete",
14614 percentages: "no",
14615 groups: [
14616 "CSS Basic User Interface"
14617 ],
14618 initial: "auto",
14619 appliesto: "allElementsExceptInlineBoxesAndInternalRubyOrTableBoxes",
14620 computed: "asSpecified",
14621 order: "perGrammar",
14622 status: "experimental",
14623 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/aspect-ratio"
14624 },
14625 azimuth: azimuth,
14626 "backdrop-filter": {
14627 syntax: "none | <filter-function-list>",
14628 media: "visual",
14629 inherited: false,
14630 animationType: "filterList",
14631 percentages: "no",
14632 groups: [
14633 "Filter Effects"
14634 ],
14635 initial: "none",
14636 appliesto: "allElementsSVGContainerElements",
14637 computed: "asSpecified",
14638 order: "uniqueOrder",
14639 status: "experimental",
14640 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/backdrop-filter"
14641 },
14642 "backface-visibility": {
14643 syntax: "visible | hidden",
14644 media: "visual",
14645 inherited: false,
14646 animationType: "discrete",
14647 percentages: "no",
14648 groups: [
14649 "CSS Transforms"
14650 ],
14651 initial: "visible",
14652 appliesto: "transformableElements",
14653 computed: "asSpecified",
14654 order: "uniqueOrder",
14655 status: "standard",
14656 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/backface-visibility"
14657 },
14658 background: background,
14659 "background-attachment": {
14660 syntax: "<attachment>#",
14661 media: "visual",
14662 inherited: false,
14663 animationType: "discrete",
14664 percentages: "no",
14665 groups: [
14666 "CSS Backgrounds and Borders"
14667 ],
14668 initial: "scroll",
14669 appliesto: "allElements",
14670 computed: "asSpecified",
14671 order: "uniqueOrder",
14672 alsoAppliesTo: [
14673 "::first-letter",
14674 "::first-line",
14675 "::placeholder"
14676 ],
14677 status: "standard",
14678 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/background-attachment"
14679 },
14680 "background-blend-mode": {
14681 syntax: "<blend-mode>#",
14682 media: "none",
14683 inherited: false,
14684 animationType: "discrete",
14685 percentages: "no",
14686 groups: [
14687 "Compositing and Blending"
14688 ],
14689 initial: "normal",
14690 appliesto: "allElementsSVGContainerGraphicsAndGraphicsReferencingElements",
14691 computed: "asSpecified",
14692 order: "uniqueOrder",
14693 alsoAppliesTo: [
14694 "::first-letter",
14695 "::first-line",
14696 "::placeholder"
14697 ],
14698 status: "standard",
14699 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/background-blend-mode"
14700 },
14701 "background-clip": {
14702 syntax: "<box>#",
14703 media: "visual",
14704 inherited: false,
14705 animationType: "discrete",
14706 percentages: "no",
14707 groups: [
14708 "CSS Backgrounds and Borders"
14709 ],
14710 initial: "border-box",
14711 appliesto: "allElements",
14712 computed: "asSpecified",
14713 order: "uniqueOrder",
14714 alsoAppliesTo: [
14715 "::first-letter",
14716 "::first-line",
14717 "::placeholder"
14718 ],
14719 status: "standard",
14720 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/background-clip"
14721 },
14722 "background-color": {
14723 syntax: "<color>",
14724 media: "visual",
14725 inherited: false,
14726 animationType: "color",
14727 percentages: "no",
14728 groups: [
14729 "CSS Backgrounds and Borders"
14730 ],
14731 initial: "transparent",
14732 appliesto: "allElements",
14733 computed: "computedColor",
14734 order: "uniqueOrder",
14735 alsoAppliesTo: [
14736 "::first-letter",
14737 "::first-line",
14738 "::placeholder"
14739 ],
14740 status: "standard",
14741 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/background-color"
14742 },
14743 "background-image": {
14744 syntax: "<bg-image>#",
14745 media: "visual",
14746 inherited: false,
14747 animationType: "discrete",
14748 percentages: "no",
14749 groups: [
14750 "CSS Backgrounds and Borders"
14751 ],
14752 initial: "none",
14753 appliesto: "allElements",
14754 computed: "asSpecifiedURLsAbsolute",
14755 order: "uniqueOrder",
14756 alsoAppliesTo: [
14757 "::first-letter",
14758 "::first-line",
14759 "::placeholder"
14760 ],
14761 status: "standard",
14762 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/background-image"
14763 },
14764 "background-origin": {
14765 syntax: "<box>#",
14766 media: "visual",
14767 inherited: false,
14768 animationType: "discrete",
14769 percentages: "no",
14770 groups: [
14771 "CSS Backgrounds and Borders"
14772 ],
14773 initial: "padding-box",
14774 appliesto: "allElements",
14775 computed: "asSpecified",
14776 order: "uniqueOrder",
14777 alsoAppliesTo: [
14778 "::first-letter",
14779 "::first-line",
14780 "::placeholder"
14781 ],
14782 status: "standard",
14783 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/background-origin"
14784 },
14785 "background-position": {
14786 syntax: "<bg-position>#",
14787 media: "visual",
14788 inherited: false,
14789 animationType: "repeatableListOfSimpleListOfLpc",
14790 percentages: "referToSizeOfBackgroundPositioningAreaMinusBackgroundImageSize",
14791 groups: [
14792 "CSS Backgrounds and Borders"
14793 ],
14794 initial: "0% 0%",
14795 appliesto: "allElements",
14796 computed: "listEachItemTwoKeywordsOriginOffsets",
14797 order: "uniqueOrder",
14798 alsoAppliesTo: [
14799 "::first-letter",
14800 "::first-line",
14801 "::placeholder"
14802 ],
14803 status: "standard",
14804 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/background-position"
14805 },
14806 "background-position-x": {
14807 syntax: "[ center | [ left | right | x-start | x-end ]? <length-percentage>? ]#",
14808 media: "visual",
14809 inherited: false,
14810 animationType: "discrete",
14811 percentages: "referToWidthOfBackgroundPositioningAreaMinusBackgroundImageHeight",
14812 groups: [
14813 "CSS Backgrounds and Borders"
14814 ],
14815 initial: "left",
14816 appliesto: "allElements",
14817 computed: "listEachItemConsistingOfAbsoluteLengthPercentageAndOrigin",
14818 order: "uniqueOrder",
14819 status: "experimental",
14820 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/background-position-x"
14821 },
14822 "background-position-y": {
14823 syntax: "[ center | [ top | bottom | y-start | y-end ]? <length-percentage>? ]#",
14824 media: "visual",
14825 inherited: false,
14826 animationType: "discrete",
14827 percentages: "referToHeightOfBackgroundPositioningAreaMinusBackgroundImageHeight",
14828 groups: [
14829 "CSS Backgrounds and Borders"
14830 ],
14831 initial: "top",
14832 appliesto: "allElements",
14833 computed: "listEachItemConsistingOfAbsoluteLengthPercentageAndOrigin",
14834 order: "uniqueOrder",
14835 status: "experimental",
14836 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/background-position-y"
14837 },
14838 "background-repeat": {
14839 syntax: "<repeat-style>#",
14840 media: "visual",
14841 inherited: false,
14842 animationType: "discrete",
14843 percentages: "no",
14844 groups: [
14845 "CSS Backgrounds and Borders"
14846 ],
14847 initial: "repeat",
14848 appliesto: "allElements",
14849 computed: "listEachItemHasTwoKeywordsOnePerDimension",
14850 order: "uniqueOrder",
14851 alsoAppliesTo: [
14852 "::first-letter",
14853 "::first-line",
14854 "::placeholder"
14855 ],
14856 status: "standard",
14857 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/background-repeat"
14858 },
14859 "background-size": {
14860 syntax: "<bg-size>#",
14861 media: "visual",
14862 inherited: false,
14863 animationType: "repeatableListOfSimpleListOfLpc",
14864 percentages: "relativeToBackgroundPositioningArea",
14865 groups: [
14866 "CSS Backgrounds and Borders"
14867 ],
14868 initial: "auto auto",
14869 appliesto: "allElements",
14870 computed: "asSpecifiedRelativeToAbsoluteLengths",
14871 order: "uniqueOrder",
14872 alsoAppliesTo: [
14873 "::first-letter",
14874 "::first-line",
14875 "::placeholder"
14876 ],
14877 status: "standard",
14878 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/background-size"
14879 },
14880 "block-overflow": {
14881 syntax: "clip | ellipsis | <string>",
14882 media: "visual",
14883 inherited: true,
14884 animationType: "discrete",
14885 percentages: "no",
14886 groups: [
14887 "CSS Overflow"
14888 ],
14889 initial: "clip",
14890 appliesto: "blockContainers",
14891 computed: "asSpecified",
14892 order: "perGrammar",
14893 status: "experimental"
14894 },
14895 "block-size": {
14896 syntax: "<'width'>",
14897 media: "visual",
14898 inherited: false,
14899 animationType: "discrete",
14900 percentages: "blockSizeOfContainingBlock",
14901 groups: [
14902 "CSS Logical Properties"
14903 ],
14904 initial: "auto",
14905 appliesto: "sameAsWidthAndHeight",
14906 computed: "sameAsWidthAndHeight",
14907 order: "uniqueOrder",
14908 status: "standard",
14909 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/block-size"
14910 },
14911 border: border,
14912 "border-block": {
14913 syntax: "<'border-top-width'> || <'border-top-style'> || <'color'>",
14914 media: "visual",
14915 inherited: false,
14916 animationType: "discrete",
14917 percentages: "no",
14918 groups: [
14919 "CSS Logical Properties"
14920 ],
14921 initial: [
14922 "border-top-width",
14923 "border-top-style",
14924 "border-top-color"
14925 ],
14926 appliesto: "allElements",
14927 computed: [
14928 "border-top-width",
14929 "border-top-style",
14930 "border-top-color"
14931 ],
14932 order: "uniqueOrder",
14933 status: "standard",
14934 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-block"
14935 },
14936 "border-block-color": {
14937 syntax: "<'border-top-color'>{1,2}",
14938 media: "visual",
14939 inherited: false,
14940 animationType: "discrete",
14941 percentages: "no",
14942 groups: [
14943 "CSS Logical Properties"
14944 ],
14945 initial: "currentcolor",
14946 appliesto: "allElements",
14947 computed: "computedColor",
14948 order: "uniqueOrder",
14949 status: "standard",
14950 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-block-color"
14951 },
14952 "border-block-style": {
14953 syntax: "<'border-top-style'>",
14954 media: "visual",
14955 inherited: false,
14956 animationType: "discrete",
14957 percentages: "no",
14958 groups: [
14959 "CSS Logical Properties"
14960 ],
14961 initial: "none",
14962 appliesto: "allElements",
14963 computed: "asSpecified",
14964 order: "uniqueOrder",
14965 status: "standard",
14966 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-block-style"
14967 },
14968 "border-block-width": {
14969 syntax: "<'border-top-width'>",
14970 media: "visual",
14971 inherited: false,
14972 animationType: "discrete",
14973 percentages: "logicalWidthOfContainingBlock",
14974 groups: [
14975 "CSS Logical Properties"
14976 ],
14977 initial: "medium",
14978 appliesto: "allElements",
14979 computed: "absoluteLengthZeroIfBorderStyleNoneOrHidden",
14980 order: "uniqueOrder",
14981 status: "standard",
14982 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-block-width"
14983 },
14984 "border-block-end": {
14985 syntax: "<'border-top-width'> || <'border-top-style'> || <'color'>",
14986 media: "visual",
14987 inherited: false,
14988 animationType: "discrete",
14989 percentages: "no",
14990 groups: [
14991 "CSS Logical Properties"
14992 ],
14993 initial: [
14994 "border-top-width",
14995 "border-top-style",
14996 "border-top-color"
14997 ],
14998 appliesto: "allElements",
14999 computed: [
15000 "border-top-width",
15001 "border-top-style",
15002 "border-top-color"
15003 ],
15004 order: "uniqueOrder",
15005 status: "standard",
15006 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-block-end"
15007 },
15008 "border-block-end-color": {
15009 syntax: "<'border-top-color'>",
15010 media: "visual",
15011 inherited: false,
15012 animationType: "discrete",
15013 percentages: "no",
15014 groups: [
15015 "CSS Logical Properties"
15016 ],
15017 initial: "currentcolor",
15018 appliesto: "allElements",
15019 computed: "computedColor",
15020 order: "uniqueOrder",
15021 status: "standard",
15022 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-block-end-color"
15023 },
15024 "border-block-end-style": {
15025 syntax: "<'border-top-style'>",
15026 media: "visual",
15027 inherited: false,
15028 animationType: "discrete",
15029 percentages: "no",
15030 groups: [
15031 "CSS Logical Properties"
15032 ],
15033 initial: "none",
15034 appliesto: "allElements",
15035 computed: "asSpecified",
15036 order: "uniqueOrder",
15037 status: "standard",
15038 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-block-end-style"
15039 },
15040 "border-block-end-width": {
15041 syntax: "<'border-top-width'>",
15042 media: "visual",
15043 inherited: false,
15044 animationType: "discrete",
15045 percentages: "logicalWidthOfContainingBlock",
15046 groups: [
15047 "CSS Logical Properties"
15048 ],
15049 initial: "medium",
15050 appliesto: "allElements",
15051 computed: "absoluteLengthZeroIfBorderStyleNoneOrHidden",
15052 order: "uniqueOrder",
15053 status: "standard",
15054 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-block-end-width"
15055 },
15056 "border-block-start": {
15057 syntax: "<'border-top-width'> || <'border-top-style'> || <'color'>",
15058 media: "visual",
15059 inherited: false,
15060 animationType: "discrete",
15061 percentages: "no",
15062 groups: [
15063 "CSS Logical Properties"
15064 ],
15065 initial: [
15066 "border-width",
15067 "border-style",
15068 "color"
15069 ],
15070 appliesto: "allElements",
15071 computed: [
15072 "border-width",
15073 "border-style",
15074 "border-block-start-color"
15075 ],
15076 order: "uniqueOrder",
15077 status: "standard",
15078 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-block-start"
15079 },
15080 "border-block-start-color": {
15081 syntax: "<'border-top-color'>",
15082 media: "visual",
15083 inherited: false,
15084 animationType: "discrete",
15085 percentages: "no",
15086 groups: [
15087 "CSS Logical Properties"
15088 ],
15089 initial: "currentcolor",
15090 appliesto: "allElements",
15091 computed: "computedColor",
15092 order: "uniqueOrder",
15093 status: "standard",
15094 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-block-start-color"
15095 },
15096 "border-block-start-style": {
15097 syntax: "<'border-top-style'>",
15098 media: "visual",
15099 inherited: false,
15100 animationType: "discrete",
15101 percentages: "no",
15102 groups: [
15103 "CSS Logical Properties"
15104 ],
15105 initial: "none",
15106 appliesto: "allElements",
15107 computed: "asSpecified",
15108 order: "uniqueOrder",
15109 status: "standard",
15110 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-block-start-style"
15111 },
15112 "border-block-start-width": {
15113 syntax: "<'border-top-width'>",
15114 media: "visual",
15115 inherited: false,
15116 animationType: "discrete",
15117 percentages: "logicalWidthOfContainingBlock",
15118 groups: [
15119 "CSS Logical Properties"
15120 ],
15121 initial: "medium",
15122 appliesto: "allElements",
15123 computed: "absoluteLengthZeroIfBorderStyleNoneOrHidden",
15124 order: "uniqueOrder",
15125 status: "standard",
15126 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-block-start-width"
15127 },
15128 "border-bottom": {
15129 syntax: "<line-width> || <line-style> || <color>",
15130 media: "visual",
15131 inherited: false,
15132 animationType: [
15133 "border-bottom-color",
15134 "border-bottom-style",
15135 "border-bottom-width"
15136 ],
15137 percentages: "no",
15138 groups: [
15139 "CSS Backgrounds and Borders"
15140 ],
15141 initial: [
15142 "border-bottom-width",
15143 "border-bottom-style",
15144 "border-bottom-color"
15145 ],
15146 appliesto: "allElements",
15147 computed: [
15148 "border-bottom-width",
15149 "border-bottom-style",
15150 "border-bottom-color"
15151 ],
15152 order: "orderOfAppearance",
15153 alsoAppliesTo: [
15154 "::first-letter"
15155 ],
15156 status: "standard",
15157 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-bottom"
15158 },
15159 "border-bottom-color": {
15160 syntax: "<'border-top-color'>",
15161 media: "visual",
15162 inherited: false,
15163 animationType: "color",
15164 percentages: "no",
15165 groups: [
15166 "CSS Backgrounds and Borders"
15167 ],
15168 initial: "currentcolor",
15169 appliesto: "allElements",
15170 computed: "computedColor",
15171 order: "uniqueOrder",
15172 alsoAppliesTo: [
15173 "::first-letter"
15174 ],
15175 status: "standard",
15176 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-bottom-color"
15177 },
15178 "border-bottom-left-radius": {
15179 syntax: "<length-percentage>{1,2}",
15180 media: "visual",
15181 inherited: false,
15182 animationType: "lpc",
15183 percentages: "referToDimensionOfBorderBox",
15184 groups: [
15185 "CSS Backgrounds and Borders"
15186 ],
15187 initial: "0",
15188 appliesto: "allElementsUAsNotRequiredWhenCollapse",
15189 computed: "twoAbsoluteLengthOrPercentages",
15190 order: "uniqueOrder",
15191 alsoAppliesTo: [
15192 "::first-letter"
15193 ],
15194 status: "standard",
15195 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-bottom-left-radius"
15196 },
15197 "border-bottom-right-radius": {
15198 syntax: "<length-percentage>{1,2}",
15199 media: "visual",
15200 inherited: false,
15201 animationType: "lpc",
15202 percentages: "referToDimensionOfBorderBox",
15203 groups: [
15204 "CSS Backgrounds and Borders"
15205 ],
15206 initial: "0",
15207 appliesto: "allElementsUAsNotRequiredWhenCollapse",
15208 computed: "twoAbsoluteLengthOrPercentages",
15209 order: "uniqueOrder",
15210 alsoAppliesTo: [
15211 "::first-letter"
15212 ],
15213 status: "standard",
15214 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-bottom-right-radius"
15215 },
15216 "border-bottom-style": {
15217 syntax: "<line-style>",
15218 media: "visual",
15219 inherited: false,
15220 animationType: "discrete",
15221 percentages: "no",
15222 groups: [
15223 "CSS Backgrounds and Borders"
15224 ],
15225 initial: "none",
15226 appliesto: "allElements",
15227 computed: "asSpecified",
15228 order: "uniqueOrder",
15229 alsoAppliesTo: [
15230 "::first-letter"
15231 ],
15232 status: "standard",
15233 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-bottom-style"
15234 },
15235 "border-bottom-width": {
15236 syntax: "<line-width>",
15237 media: "visual",
15238 inherited: false,
15239 animationType: "length",
15240 percentages: "no",
15241 groups: [
15242 "CSS Backgrounds and Borders"
15243 ],
15244 initial: "medium",
15245 appliesto: "allElements",
15246 computed: "absoluteLengthOr0IfBorderBottomStyleNoneOrHidden",
15247 order: "uniqueOrder",
15248 alsoAppliesTo: [
15249 "::first-letter"
15250 ],
15251 status: "standard",
15252 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-bottom-width"
15253 },
15254 "border-collapse": {
15255 syntax: "collapse | separate",
15256 media: "visual",
15257 inherited: true,
15258 animationType: "discrete",
15259 percentages: "no",
15260 groups: [
15261 "CSS Table"
15262 ],
15263 initial: "separate",
15264 appliesto: "tableElements",
15265 computed: "asSpecified",
15266 order: "uniqueOrder",
15267 status: "standard",
15268 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-collapse"
15269 },
15270 "border-color": {
15271 syntax: "<color>{1,4}",
15272 media: "visual",
15273 inherited: false,
15274 animationType: [
15275 "border-bottom-color",
15276 "border-left-color",
15277 "border-right-color",
15278 "border-top-color"
15279 ],
15280 percentages: "no",
15281 groups: [
15282 "CSS Backgrounds and Borders"
15283 ],
15284 initial: [
15285 "border-top-color",
15286 "border-right-color",
15287 "border-bottom-color",
15288 "border-left-color"
15289 ],
15290 appliesto: "allElements",
15291 computed: [
15292 "border-bottom-color",
15293 "border-left-color",
15294 "border-right-color",
15295 "border-top-color"
15296 ],
15297 order: "uniqueOrder",
15298 alsoAppliesTo: [
15299 "::first-letter"
15300 ],
15301 status: "standard",
15302 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-color"
15303 },
15304 "border-end-end-radius": {
15305 syntax: "<length-percentage>{1,2}",
15306 media: "visual",
15307 inherited: false,
15308 animationType: "lpc",
15309 percentages: "referToDimensionOfBorderBox",
15310 groups: [
15311 "CSS Logical Properties"
15312 ],
15313 initial: "0",
15314 appliesto: "allElementsUAsNotRequiredWhenCollapse",
15315 computed: "twoAbsoluteLengthOrPercentages",
15316 order: "uniqueOrder",
15317 alsoAppliesTo: [
15318 "::first-letter"
15319 ],
15320 status: "standard",
15321 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-end-end-radius"
15322 },
15323 "border-end-start-radius": {
15324 syntax: "<length-percentage>{1,2}",
15325 media: "visual",
15326 inherited: false,
15327 animationType: "lpc",
15328 percentages: "referToDimensionOfBorderBox",
15329 groups: [
15330 "CSS Logical Properties"
15331 ],
15332 initial: "0",
15333 appliesto: "allElementsUAsNotRequiredWhenCollapse",
15334 computed: "twoAbsoluteLengthOrPercentages",
15335 order: "uniqueOrder",
15336 alsoAppliesTo: [
15337 "::first-letter"
15338 ],
15339 status: "standard",
15340 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-end-start-radius"
15341 },
15342 "border-image": {
15343 syntax: "<'border-image-source'> || <'border-image-slice'> [ / <'border-image-width'> | / <'border-image-width'>? / <'border-image-outset'> ]? || <'border-image-repeat'>",
15344 media: "visual",
15345 inherited: false,
15346 animationType: "discrete",
15347 percentages: [
15348 "border-image-slice",
15349 "border-image-width"
15350 ],
15351 groups: [
15352 "CSS Backgrounds and Borders"
15353 ],
15354 initial: [
15355 "border-image-source",
15356 "border-image-slice",
15357 "border-image-width",
15358 "border-image-outset",
15359 "border-image-repeat"
15360 ],
15361 appliesto: "allElementsExceptTableElementsWhenCollapse",
15362 computed: [
15363 "border-image-outset",
15364 "border-image-repeat",
15365 "border-image-slice",
15366 "border-image-source",
15367 "border-image-width"
15368 ],
15369 order: "uniqueOrder",
15370 alsoAppliesTo: [
15371 "::first-letter"
15372 ],
15373 status: "standard",
15374 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-image"
15375 },
15376 "border-image-outset": {
15377 syntax: "[ <length> | <number> ]{1,4}",
15378 media: "visual",
15379 inherited: false,
15380 animationType: "byComputedValueType",
15381 percentages: "no",
15382 groups: [
15383 "CSS Backgrounds and Borders"
15384 ],
15385 initial: "0",
15386 appliesto: "allElementsExceptTableElementsWhenCollapse",
15387 computed: "asSpecifiedRelativeToAbsoluteLengths",
15388 order: "uniqueOrder",
15389 alsoAppliesTo: [
15390 "::first-letter"
15391 ],
15392 status: "standard",
15393 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-image-outset"
15394 },
15395 "border-image-repeat": {
15396 syntax: "[ stretch | repeat | round | space ]{1,2}",
15397 media: "visual",
15398 inherited: false,
15399 animationType: "discrete",
15400 percentages: "no",
15401 groups: [
15402 "CSS Backgrounds and Borders"
15403 ],
15404 initial: "stretch",
15405 appliesto: "allElementsExceptTableElementsWhenCollapse",
15406 computed: "asSpecified",
15407 order: "uniqueOrder",
15408 alsoAppliesTo: [
15409 "::first-letter"
15410 ],
15411 status: "standard",
15412 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-image-repeat"
15413 },
15414 "border-image-slice": {
15415 syntax: "<number-percentage>{1,4} && fill?",
15416 media: "visual",
15417 inherited: false,
15418 animationType: "byComputedValueType",
15419 percentages: "referToSizeOfBorderImage",
15420 groups: [
15421 "CSS Backgrounds and Borders"
15422 ],
15423 initial: "100%",
15424 appliesto: "allElementsExceptTableElementsWhenCollapse",
15425 computed: "oneToFourPercentagesOrAbsoluteLengthsPlusFill",
15426 order: "percentagesOrLengthsFollowedByFill",
15427 alsoAppliesTo: [
15428 "::first-letter"
15429 ],
15430 status: "standard",
15431 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-image-slice"
15432 },
15433 "border-image-source": {
15434 syntax: "none | <image>",
15435 media: "visual",
15436 inherited: false,
15437 animationType: "discrete",
15438 percentages: "no",
15439 groups: [
15440 "CSS Backgrounds and Borders"
15441 ],
15442 initial: "none",
15443 appliesto: "allElementsExceptTableElementsWhenCollapse",
15444 computed: "noneOrImageWithAbsoluteURI",
15445 order: "uniqueOrder",
15446 alsoAppliesTo: [
15447 "::first-letter"
15448 ],
15449 status: "standard",
15450 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-image-source"
15451 },
15452 "border-image-width": {
15453 syntax: "[ <length-percentage> | <number> | auto ]{1,4}",
15454 media: "visual",
15455 inherited: false,
15456 animationType: "byComputedValueType",
15457 percentages: "referToWidthOrHeightOfBorderImageArea",
15458 groups: [
15459 "CSS Backgrounds and Borders"
15460 ],
15461 initial: "1",
15462 appliesto: "allElementsExceptTableElementsWhenCollapse",
15463 computed: "asSpecifiedRelativeToAbsoluteLengths",
15464 order: "uniqueOrder",
15465 alsoAppliesTo: [
15466 "::first-letter"
15467 ],
15468 status: "standard",
15469 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-image-width"
15470 },
15471 "border-inline": {
15472 syntax: "<'border-top-width'> || <'border-top-style'> || <'color'>",
15473 media: "visual",
15474 inherited: false,
15475 animationType: "discrete",
15476 percentages: "no",
15477 groups: [
15478 "CSS Logical Properties"
15479 ],
15480 initial: [
15481 "border-top-width",
15482 "border-top-style",
15483 "border-top-color"
15484 ],
15485 appliesto: "allElements",
15486 computed: [
15487 "border-top-width",
15488 "border-top-style",
15489 "border-top-color"
15490 ],
15491 order: "uniqueOrder",
15492 status: "standard",
15493 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-inline"
15494 },
15495 "border-inline-end": {
15496 syntax: "<'border-top-width'> || <'border-top-style'> || <'color'>",
15497 media: "visual",
15498 inherited: false,
15499 animationType: "discrete",
15500 percentages: "no",
15501 groups: [
15502 "CSS Logical Properties"
15503 ],
15504 initial: [
15505 "border-width",
15506 "border-style",
15507 "color"
15508 ],
15509 appliesto: "allElements",
15510 computed: [
15511 "border-width",
15512 "border-style",
15513 "border-inline-end-color"
15514 ],
15515 order: "uniqueOrder",
15516 status: "standard",
15517 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-inline-end"
15518 },
15519 "border-inline-color": {
15520 syntax: "<'border-top-color'>{1,2}",
15521 media: "visual",
15522 inherited: false,
15523 animationType: "discrete",
15524 percentages: "no",
15525 groups: [
15526 "CSS Logical Properties"
15527 ],
15528 initial: "currentcolor",
15529 appliesto: "allElements",
15530 computed: "computedColor",
15531 order: "uniqueOrder",
15532 status: "standard",
15533 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-inline-color"
15534 },
15535 "border-inline-style": {
15536 syntax: "<'border-top-style'>",
15537 media: "visual",
15538 inherited: false,
15539 animationType: "discrete",
15540 percentages: "no",
15541 groups: [
15542 "CSS Logical Properties"
15543 ],
15544 initial: "none",
15545 appliesto: "allElements",
15546 computed: "asSpecified",
15547 order: "uniqueOrder",
15548 status: "standard",
15549 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-inline-style"
15550 },
15551 "border-inline-width": {
15552 syntax: "<'border-top-width'>",
15553 media: "visual",
15554 inherited: false,
15555 animationType: "discrete",
15556 percentages: "logicalWidthOfContainingBlock",
15557 groups: [
15558 "CSS Logical Properties"
15559 ],
15560 initial: "medium",
15561 appliesto: "allElements",
15562 computed: "absoluteLengthZeroIfBorderStyleNoneOrHidden",
15563 order: "uniqueOrder",
15564 status: "standard",
15565 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-inline-width"
15566 },
15567 "border-inline-end-color": {
15568 syntax: "<'border-top-color'>",
15569 media: "visual",
15570 inherited: false,
15571 animationType: "discrete",
15572 percentages: "no",
15573 groups: [
15574 "CSS Logical Properties"
15575 ],
15576 initial: "currentcolor",
15577 appliesto: "allElements",
15578 computed: "computedColor",
15579 order: "uniqueOrder",
15580 status: "standard",
15581 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-inline-end-color"
15582 },
15583 "border-inline-end-style": {
15584 syntax: "<'border-top-style'>",
15585 media: "visual",
15586 inherited: false,
15587 animationType: "discrete",
15588 percentages: "no",
15589 groups: [
15590 "CSS Logical Properties"
15591 ],
15592 initial: "none",
15593 appliesto: "allElements",
15594 computed: "asSpecified",
15595 order: "uniqueOrder",
15596 status: "standard",
15597 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-inline-end-style"
15598 },
15599 "border-inline-end-width": {
15600 syntax: "<'border-top-width'>",
15601 media: "visual",
15602 inherited: false,
15603 animationType: "discrete",
15604 percentages: "logicalWidthOfContainingBlock",
15605 groups: [
15606 "CSS Logical Properties"
15607 ],
15608 initial: "medium",
15609 appliesto: "allElements",
15610 computed: "absoluteLengthZeroIfBorderStyleNoneOrHidden",
15611 order: "uniqueOrder",
15612 status: "standard",
15613 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-inline-end-width"
15614 },
15615 "border-inline-start": {
15616 syntax: "<'border-top-width'> || <'border-top-style'> || <'color'>",
15617 media: "visual",
15618 inherited: false,
15619 animationType: "discrete",
15620 percentages: "no",
15621 groups: [
15622 "CSS Logical Properties"
15623 ],
15624 initial: [
15625 "border-width",
15626 "border-style",
15627 "color"
15628 ],
15629 appliesto: "allElements",
15630 computed: [
15631 "border-width",
15632 "border-style",
15633 "border-inline-start-color"
15634 ],
15635 order: "uniqueOrder",
15636 status: "standard",
15637 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-inline-start"
15638 },
15639 "border-inline-start-color": {
15640 syntax: "<'border-top-color'>",
15641 media: "visual",
15642 inherited: false,
15643 animationType: "discrete",
15644 percentages: "no",
15645 groups: [
15646 "CSS Logical Properties"
15647 ],
15648 initial: "currentcolor",
15649 appliesto: "allElements",
15650 computed: "computedColor",
15651 order: "uniqueOrder",
15652 status: "standard",
15653 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-inline-start-color"
15654 },
15655 "border-inline-start-style": {
15656 syntax: "<'border-top-style'>",
15657 media: "visual",
15658 inherited: false,
15659 animationType: "discrete",
15660 percentages: "no",
15661 groups: [
15662 "CSS Logical Properties"
15663 ],
15664 initial: "none",
15665 appliesto: "allElements",
15666 computed: "asSpecified",
15667 order: "uniqueOrder",
15668 status: "standard",
15669 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-inline-start-style"
15670 },
15671 "border-inline-start-width": {
15672 syntax: "<'border-top-width'>",
15673 media: "visual",
15674 inherited: false,
15675 animationType: "discrete",
15676 percentages: "logicalWidthOfContainingBlock",
15677 groups: [
15678 "CSS Logical Properties"
15679 ],
15680 initial: "medium",
15681 appliesto: "allElements",
15682 computed: "absoluteLengthZeroIfBorderStyleNoneOrHidden",
15683 order: "uniqueOrder",
15684 status: "standard",
15685 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-inline-start-width"
15686 },
15687 "border-left": {
15688 syntax: "<line-width> || <line-style> || <color>",
15689 media: "visual",
15690 inherited: false,
15691 animationType: [
15692 "border-left-color",
15693 "border-left-style",
15694 "border-left-width"
15695 ],
15696 percentages: "no",
15697 groups: [
15698 "CSS Backgrounds and Borders"
15699 ],
15700 initial: [
15701 "border-left-width",
15702 "border-left-style",
15703 "border-left-color"
15704 ],
15705 appliesto: "allElements",
15706 computed: [
15707 "border-left-width",
15708 "border-left-style",
15709 "border-left-color"
15710 ],
15711 order: "orderOfAppearance",
15712 alsoAppliesTo: [
15713 "::first-letter"
15714 ],
15715 status: "standard",
15716 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-left"
15717 },
15718 "border-left-color": {
15719 syntax: "<color>",
15720 media: "visual",
15721 inherited: false,
15722 animationType: "color",
15723 percentages: "no",
15724 groups: [
15725 "CSS Backgrounds and Borders"
15726 ],
15727 initial: "currentcolor",
15728 appliesto: "allElements",
15729 computed: "computedColor",
15730 order: "uniqueOrder",
15731 alsoAppliesTo: [
15732 "::first-letter"
15733 ],
15734 status: "standard",
15735 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-left-color"
15736 },
15737 "border-left-style": {
15738 syntax: "<line-style>",
15739 media: "visual",
15740 inherited: false,
15741 animationType: "discrete",
15742 percentages: "no",
15743 groups: [
15744 "CSS Backgrounds and Borders"
15745 ],
15746 initial: "none",
15747 appliesto: "allElements",
15748 computed: "asSpecified",
15749 order: "uniqueOrder",
15750 alsoAppliesTo: [
15751 "::first-letter"
15752 ],
15753 status: "standard",
15754 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-left-style"
15755 },
15756 "border-left-width": {
15757 syntax: "<line-width>",
15758 media: "visual",
15759 inherited: false,
15760 animationType: "length",
15761 percentages: "no",
15762 groups: [
15763 "CSS Backgrounds and Borders"
15764 ],
15765 initial: "medium",
15766 appliesto: "allElements",
15767 computed: "absoluteLengthOr0IfBorderLeftStyleNoneOrHidden",
15768 order: "uniqueOrder",
15769 alsoAppliesTo: [
15770 "::first-letter"
15771 ],
15772 status: "standard",
15773 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-left-width"
15774 },
15775 "border-radius": {
15776 syntax: "<length-percentage>{1,4} [ / <length-percentage>{1,4} ]?",
15777 media: "visual",
15778 inherited: false,
15779 animationType: [
15780 "border-top-left-radius",
15781 "border-top-right-radius",
15782 "border-bottom-right-radius",
15783 "border-bottom-left-radius"
15784 ],
15785 percentages: "referToDimensionOfBorderBox",
15786 groups: [
15787 "CSS Backgrounds and Borders"
15788 ],
15789 initial: [
15790 "border-top-left-radius",
15791 "border-top-right-radius",
15792 "border-bottom-right-radius",
15793 "border-bottom-left-radius"
15794 ],
15795 appliesto: "allElementsUAsNotRequiredWhenCollapse",
15796 computed: [
15797 "border-bottom-left-radius",
15798 "border-bottom-right-radius",
15799 "border-top-left-radius",
15800 "border-top-right-radius"
15801 ],
15802 order: "uniqueOrder",
15803 alsoAppliesTo: [
15804 "::first-letter"
15805 ],
15806 status: "standard",
15807 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-radius"
15808 },
15809 "border-right": {
15810 syntax: "<line-width> || <line-style> || <color>",
15811 media: "visual",
15812 inherited: false,
15813 animationType: [
15814 "border-right-color",
15815 "border-right-style",
15816 "border-right-width"
15817 ],
15818 percentages: "no",
15819 groups: [
15820 "CSS Backgrounds and Borders"
15821 ],
15822 initial: [
15823 "border-right-width",
15824 "border-right-style",
15825 "border-right-color"
15826 ],
15827 appliesto: "allElements",
15828 computed: [
15829 "border-right-width",
15830 "border-right-style",
15831 "border-right-color"
15832 ],
15833 order: "orderOfAppearance",
15834 alsoAppliesTo: [
15835 "::first-letter"
15836 ],
15837 status: "standard",
15838 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-right"
15839 },
15840 "border-right-color": {
15841 syntax: "<color>",
15842 media: "visual",
15843 inherited: false,
15844 animationType: "color",
15845 percentages: "no",
15846 groups: [
15847 "CSS Backgrounds and Borders"
15848 ],
15849 initial: "currentcolor",
15850 appliesto: "allElements",
15851 computed: "computedColor",
15852 order: "uniqueOrder",
15853 alsoAppliesTo: [
15854 "::first-letter"
15855 ],
15856 status: "standard",
15857 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-right-color"
15858 },
15859 "border-right-style": {
15860 syntax: "<line-style>",
15861 media: "visual",
15862 inherited: false,
15863 animationType: "discrete",
15864 percentages: "no",
15865 groups: [
15866 "CSS Backgrounds and Borders"
15867 ],
15868 initial: "none",
15869 appliesto: "allElements",
15870 computed: "asSpecified",
15871 order: "uniqueOrder",
15872 alsoAppliesTo: [
15873 "::first-letter"
15874 ],
15875 status: "standard",
15876 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-right-style"
15877 },
15878 "border-right-width": {
15879 syntax: "<line-width>",
15880 media: "visual",
15881 inherited: false,
15882 animationType: "length",
15883 percentages: "no",
15884 groups: [
15885 "CSS Backgrounds and Borders"
15886 ],
15887 initial: "medium",
15888 appliesto: "allElements",
15889 computed: "absoluteLengthOr0IfBorderRightStyleNoneOrHidden",
15890 order: "uniqueOrder",
15891 alsoAppliesTo: [
15892 "::first-letter"
15893 ],
15894 status: "standard",
15895 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-right-width"
15896 },
15897 "border-spacing": {
15898 syntax: "<length> <length>?",
15899 media: "visual",
15900 inherited: true,
15901 animationType: "discrete",
15902 percentages: "no",
15903 groups: [
15904 "CSS Table"
15905 ],
15906 initial: "0",
15907 appliesto: "tableElements",
15908 computed: "twoAbsoluteLengths",
15909 order: "uniqueOrder",
15910 status: "standard",
15911 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-spacing"
15912 },
15913 "border-start-end-radius": {
15914 syntax: "<length-percentage>{1,2}",
15915 media: "visual",
15916 inherited: false,
15917 animationType: "lpc",
15918 percentages: "referToDimensionOfBorderBox",
15919 groups: [
15920 "CSS Logical Properties"
15921 ],
15922 initial: "0",
15923 appliesto: "allElementsUAsNotRequiredWhenCollapse",
15924 computed: "twoAbsoluteLengthOrPercentages",
15925 order: "uniqueOrder",
15926 alsoAppliesTo: [
15927 "::first-letter"
15928 ],
15929 status: "standard",
15930 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-start-end-radius"
15931 },
15932 "border-start-start-radius": {
15933 syntax: "<length-percentage>{1,2}",
15934 media: "visual",
15935 inherited: false,
15936 animationType: "lpc",
15937 percentages: "referToDimensionOfBorderBox",
15938 groups: [
15939 "CSS Logical Properties"
15940 ],
15941 initial: "0",
15942 appliesto: "allElementsUAsNotRequiredWhenCollapse",
15943 computed: "twoAbsoluteLengthOrPercentages",
15944 order: "uniqueOrder",
15945 alsoAppliesTo: [
15946 "::first-letter"
15947 ],
15948 status: "standard",
15949 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-start-start-radius"
15950 },
15951 "border-style": {
15952 syntax: "<line-style>{1,4}",
15953 media: "visual",
15954 inherited: false,
15955 animationType: "discrete",
15956 percentages: "no",
15957 groups: [
15958 "CSS Backgrounds and Borders"
15959 ],
15960 initial: [
15961 "border-top-style",
15962 "border-right-style",
15963 "border-bottom-style",
15964 "border-left-style"
15965 ],
15966 appliesto: "allElements",
15967 computed: [
15968 "border-bottom-style",
15969 "border-left-style",
15970 "border-right-style",
15971 "border-top-style"
15972 ],
15973 order: "uniqueOrder",
15974 alsoAppliesTo: [
15975 "::first-letter"
15976 ],
15977 status: "standard",
15978 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-style"
15979 },
15980 "border-top": {
15981 syntax: "<line-width> || <line-style> || <color>",
15982 media: "visual",
15983 inherited: false,
15984 animationType: [
15985 "border-top-color",
15986 "border-top-style",
15987 "border-top-width"
15988 ],
15989 percentages: "no",
15990 groups: [
15991 "CSS Backgrounds and Borders"
15992 ],
15993 initial: [
15994 "border-top-width",
15995 "border-top-style",
15996 "border-top-color"
15997 ],
15998 appliesto: "allElements",
15999 computed: [
16000 "border-top-width",
16001 "border-top-style",
16002 "border-top-color"
16003 ],
16004 order: "orderOfAppearance",
16005 alsoAppliesTo: [
16006 "::first-letter"
16007 ],
16008 status: "standard",
16009 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-top"
16010 },
16011 "border-top-color": {
16012 syntax: "<color>",
16013 media: "visual",
16014 inherited: false,
16015 animationType: "color",
16016 percentages: "no",
16017 groups: [
16018 "CSS Backgrounds and Borders"
16019 ],
16020 initial: "currentcolor",
16021 appliesto: "allElements",
16022 computed: "computedColor",
16023 order: "uniqueOrder",
16024 alsoAppliesTo: [
16025 "::first-letter"
16026 ],
16027 status: "standard",
16028 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-top-color"
16029 },
16030 "border-top-left-radius": {
16031 syntax: "<length-percentage>{1,2}",
16032 media: "visual",
16033 inherited: false,
16034 animationType: "lpc",
16035 percentages: "referToDimensionOfBorderBox",
16036 groups: [
16037 "CSS Backgrounds and Borders"
16038 ],
16039 initial: "0",
16040 appliesto: "allElementsUAsNotRequiredWhenCollapse",
16041 computed: "twoAbsoluteLengthOrPercentages",
16042 order: "uniqueOrder",
16043 alsoAppliesTo: [
16044 "::first-letter"
16045 ],
16046 status: "standard",
16047 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-top-left-radius"
16048 },
16049 "border-top-right-radius": {
16050 syntax: "<length-percentage>{1,2}",
16051 media: "visual",
16052 inherited: false,
16053 animationType: "lpc",
16054 percentages: "referToDimensionOfBorderBox",
16055 groups: [
16056 "CSS Backgrounds and Borders"
16057 ],
16058 initial: "0",
16059 appliesto: "allElementsUAsNotRequiredWhenCollapse",
16060 computed: "twoAbsoluteLengthOrPercentages",
16061 order: "uniqueOrder",
16062 alsoAppliesTo: [
16063 "::first-letter"
16064 ],
16065 status: "standard",
16066 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-top-right-radius"
16067 },
16068 "border-top-style": {
16069 syntax: "<line-style>",
16070 media: "visual",
16071 inherited: false,
16072 animationType: "discrete",
16073 percentages: "no",
16074 groups: [
16075 "CSS Backgrounds and Borders"
16076 ],
16077 initial: "none",
16078 appliesto: "allElements",
16079 computed: "asSpecified",
16080 order: "uniqueOrder",
16081 alsoAppliesTo: [
16082 "::first-letter"
16083 ],
16084 status: "standard",
16085 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-top-style"
16086 },
16087 "border-top-width": {
16088 syntax: "<line-width>",
16089 media: "visual",
16090 inherited: false,
16091 animationType: "length",
16092 percentages: "no",
16093 groups: [
16094 "CSS Backgrounds and Borders"
16095 ],
16096 initial: "medium",
16097 appliesto: "allElements",
16098 computed: "absoluteLengthOr0IfBorderTopStyleNoneOrHidden",
16099 order: "uniqueOrder",
16100 alsoAppliesTo: [
16101 "::first-letter"
16102 ],
16103 status: "standard",
16104 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-top-width"
16105 },
16106 "border-width": {
16107 syntax: "<line-width>{1,4}",
16108 media: "visual",
16109 inherited: false,
16110 animationType: [
16111 "border-bottom-width",
16112 "border-left-width",
16113 "border-right-width",
16114 "border-top-width"
16115 ],
16116 percentages: "no",
16117 groups: [
16118 "CSS Backgrounds and Borders"
16119 ],
16120 initial: [
16121 "border-top-width",
16122 "border-right-width",
16123 "border-bottom-width",
16124 "border-left-width"
16125 ],
16126 appliesto: "allElements",
16127 computed: [
16128 "border-bottom-width",
16129 "border-left-width",
16130 "border-right-width",
16131 "border-top-width"
16132 ],
16133 order: "uniqueOrder",
16134 alsoAppliesTo: [
16135 "::first-letter"
16136 ],
16137 status: "standard",
16138 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-width"
16139 },
16140 bottom: bottom,
16141 "box-align": {
16142 syntax: "start | center | end | baseline | stretch",
16143 media: "visual",
16144 inherited: false,
16145 animationType: "discrete",
16146 percentages: "no",
16147 groups: [
16148 "Mozilla Extensions",
16149 "WebKit Extensions"
16150 ],
16151 initial: "stretch",
16152 appliesto: "elementsWithDisplayBoxOrInlineBox",
16153 computed: "asSpecified",
16154 order: "uniqueOrder",
16155 status: "nonstandard",
16156 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/box-align"
16157 },
16158 "box-decoration-break": {
16159 syntax: "slice | clone",
16160 media: "visual",
16161 inherited: false,
16162 animationType: "discrete",
16163 percentages: "no",
16164 groups: [
16165 "CSS Fragmentation"
16166 ],
16167 initial: "slice",
16168 appliesto: "allElements",
16169 computed: "asSpecified",
16170 order: "uniqueOrder",
16171 status: "standard",
16172 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/box-decoration-break"
16173 },
16174 "box-direction": {
16175 syntax: "normal | reverse | inherit",
16176 media: "visual",
16177 inherited: false,
16178 animationType: "discrete",
16179 percentages: "no",
16180 groups: [
16181 "Mozilla Extensions",
16182 "WebKit Extensions"
16183 ],
16184 initial: "normal",
16185 appliesto: "elementsWithDisplayBoxOrInlineBox",
16186 computed: "asSpecified",
16187 order: "uniqueOrder",
16188 status: "nonstandard",
16189 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/box-direction"
16190 },
16191 "box-flex": {
16192 syntax: "<number>",
16193 media: "visual",
16194 inherited: false,
16195 animationType: "discrete",
16196 percentages: "no",
16197 groups: [
16198 "Mozilla Extensions",
16199 "WebKit Extensions"
16200 ],
16201 initial: "0",
16202 appliesto: "directChildrenOfElementsWithDisplayMozBoxMozInlineBox",
16203 computed: "asSpecified",
16204 order: "uniqueOrder",
16205 status: "nonstandard",
16206 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/box-flex"
16207 },
16208 "box-flex-group": {
16209 syntax: "<integer>",
16210 media: "visual",
16211 inherited: false,
16212 animationType: "discrete",
16213 percentages: "no",
16214 groups: [
16215 "Mozilla Extensions",
16216 "WebKit Extensions"
16217 ],
16218 initial: "1",
16219 appliesto: "inFlowChildrenOfBoxElements",
16220 computed: "asSpecified",
16221 order: "uniqueOrder",
16222 status: "nonstandard",
16223 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/box-flex-group"
16224 },
16225 "box-lines": {
16226 syntax: "single | multiple",
16227 media: "visual",
16228 inherited: false,
16229 animationType: "discrete",
16230 percentages: "no",
16231 groups: [
16232 "Mozilla Extensions",
16233 "WebKit Extensions"
16234 ],
16235 initial: "single",
16236 appliesto: "boxElements",
16237 computed: "asSpecified",
16238 order: "uniqueOrder",
16239 status: "nonstandard",
16240 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/box-lines"
16241 },
16242 "box-ordinal-group": {
16243 syntax: "<integer>",
16244 media: "visual",
16245 inherited: false,
16246 animationType: "discrete",
16247 percentages: "no",
16248 groups: [
16249 "Mozilla Extensions",
16250 "WebKit Extensions"
16251 ],
16252 initial: "1",
16253 appliesto: "childrenOfBoxElements",
16254 computed: "asSpecified",
16255 order: "uniqueOrder",
16256 status: "nonstandard",
16257 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/box-ordinal-group"
16258 },
16259 "box-orient": {
16260 syntax: "horizontal | vertical | inline-axis | block-axis | inherit",
16261 media: "visual",
16262 inherited: false,
16263 animationType: "discrete",
16264 percentages: "no",
16265 groups: [
16266 "Mozilla Extensions",
16267 "WebKit Extensions"
16268 ],
16269 initial: "inlineAxisHorizontalInXUL",
16270 appliesto: "elementsWithDisplayBoxOrInlineBox",
16271 computed: "asSpecified",
16272 order: "uniqueOrder",
16273 status: "nonstandard",
16274 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/box-orient"
16275 },
16276 "box-pack": {
16277 syntax: "start | center | end | justify",
16278 media: "visual",
16279 inherited: false,
16280 animationType: "discrete",
16281 percentages: "no",
16282 groups: [
16283 "Mozilla Extensions",
16284 "WebKit Extensions"
16285 ],
16286 initial: "start",
16287 appliesto: "elementsWithDisplayMozBoxMozInlineBox",
16288 computed: "asSpecified",
16289 order: "uniqueOrder",
16290 status: "nonstandard",
16291 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/box-pack"
16292 },
16293 "box-shadow": {
16294 syntax: "none | <shadow>#",
16295 media: "visual",
16296 inherited: false,
16297 animationType: "shadowList",
16298 percentages: "no",
16299 groups: [
16300 "CSS Backgrounds and Borders"
16301 ],
16302 initial: "none",
16303 appliesto: "allElements",
16304 computed: "absoluteLengthsSpecifiedColorAsSpecified",
16305 order: "uniqueOrder",
16306 alsoAppliesTo: [
16307 "::first-letter"
16308 ],
16309 status: "standard",
16310 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/box-shadow"
16311 },
16312 "box-sizing": {
16313 syntax: "content-box | border-box",
16314 media: "visual",
16315 inherited: false,
16316 animationType: "discrete",
16317 percentages: "no",
16318 groups: [
16319 "CSS Basic User Interface"
16320 ],
16321 initial: "content-box",
16322 appliesto: "allElementsAcceptingWidthOrHeight",
16323 computed: "asSpecified",
16324 order: "uniqueOrder",
16325 status: "standard",
16326 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/box-sizing"
16327 },
16328 "break-after": {
16329 syntax: "auto | avoid | always | all | avoid-page | page | left | right | recto | verso | avoid-column | column | avoid-region | region",
16330 media: "visual",
16331 inherited: false,
16332 animationType: "discrete",
16333 percentages: "no",
16334 groups: [
16335 "CSS Fragmentation"
16336 ],
16337 initial: "auto",
16338 appliesto: "blockLevelElements",
16339 computed: "asSpecified",
16340 order: "uniqueOrder",
16341 status: "standard",
16342 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/break-after"
16343 },
16344 "break-before": {
16345 syntax: "auto | avoid | always | all | avoid-page | page | left | right | recto | verso | avoid-column | column | avoid-region | region",
16346 media: "visual",
16347 inherited: false,
16348 animationType: "discrete",
16349 percentages: "no",
16350 groups: [
16351 "CSS Fragmentation"
16352 ],
16353 initial: "auto",
16354 appliesto: "blockLevelElements",
16355 computed: "asSpecified",
16356 order: "uniqueOrder",
16357 status: "standard",
16358 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/break-before"
16359 },
16360 "break-inside": {
16361 syntax: "auto | avoid | avoid-page | avoid-column | avoid-region",
16362 media: "visual",
16363 inherited: false,
16364 animationType: "discrete",
16365 percentages: "no",
16366 groups: [
16367 "CSS Fragmentation"
16368 ],
16369 initial: "auto",
16370 appliesto: "blockLevelElements",
16371 computed: "asSpecified",
16372 order: "uniqueOrder",
16373 status: "standard",
16374 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/break-inside"
16375 },
16376 "caption-side": {
16377 syntax: "top | bottom | block-start | block-end | inline-start | inline-end",
16378 media: "visual",
16379 inherited: true,
16380 animationType: "discrete",
16381 percentages: "no",
16382 groups: [
16383 "CSS Table"
16384 ],
16385 initial: "top",
16386 appliesto: "tableCaptionElements",
16387 computed: "asSpecified",
16388 order: "uniqueOrder",
16389 status: "standard",
16390 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/caption-side"
16391 },
16392 "caret-color": {
16393 syntax: "auto | <color>",
16394 media: "interactive",
16395 inherited: true,
16396 animationType: "color",
16397 percentages: "no",
16398 groups: [
16399 "CSS Basic User Interface"
16400 ],
16401 initial: "auto",
16402 appliesto: "allElements",
16403 computed: "asAutoOrColor",
16404 order: "perGrammar",
16405 status: "standard",
16406 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/caret-color"
16407 },
16408 clear: clear,
16409 clip: clip,
16410 "clip-path": {
16411 syntax: "<clip-source> | [ <basic-shape> || <geometry-box> ] | none",
16412 media: "visual",
16413 inherited: false,
16414 animationType: "basicShapeOtherwiseNo",
16415 percentages: "referToReferenceBoxWhenSpecifiedOtherwiseBorderBox",
16416 groups: [
16417 "CSS Masking"
16418 ],
16419 initial: "none",
16420 appliesto: "allElementsSVGContainerElements",
16421 computed: "asSpecifiedURLsAbsolute",
16422 order: "uniqueOrder",
16423 status: "standard",
16424 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/clip-path"
16425 },
16426 color: color,
16427 "color-adjust": {
16428 syntax: "economy | exact",
16429 media: "visual",
16430 inherited: true,
16431 animationType: "discrete",
16432 percentages: "no",
16433 groups: [
16434 "CSS Color"
16435 ],
16436 initial: "economy",
16437 appliesto: "allElements",
16438 computed: "asSpecified",
16439 order: "perGrammar",
16440 status: "standard",
16441 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/color-adjust"
16442 },
16443 "column-count": {
16444 syntax: "<integer> | auto",
16445 media: "visual",
16446 inherited: false,
16447 animationType: "integer",
16448 percentages: "no",
16449 groups: [
16450 "CSS Columns"
16451 ],
16452 initial: "auto",
16453 appliesto: "blockContainersExceptTableWrappers",
16454 computed: "asSpecified",
16455 order: "perGrammar",
16456 status: "standard",
16457 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/column-count"
16458 },
16459 "column-fill": {
16460 syntax: "auto | balance | balance-all",
16461 media: "visualInContinuousMediaNoEffectInOverflowColumns",
16462 inherited: false,
16463 animationType: "discrete",
16464 percentages: "no",
16465 groups: [
16466 "CSS Columns"
16467 ],
16468 initial: "balance",
16469 appliesto: "multicolElements",
16470 computed: "asSpecified",
16471 order: "perGrammar",
16472 status: "standard",
16473 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/column-fill"
16474 },
16475 "column-gap": {
16476 syntax: "normal | <length-percentage>",
16477 media: "visual",
16478 inherited: false,
16479 animationType: "lpc",
16480 percentages: "referToDimensionOfContentArea",
16481 groups: [
16482 "CSS Box Alignment"
16483 ],
16484 initial: "normal",
16485 appliesto: "multiColumnElementsFlexContainersGridContainers",
16486 computed: "asSpecifiedWithLengthsAbsoluteAndNormalComputingToZeroExceptMultiColumn",
16487 order: "perGrammar",
16488 status: "standard",
16489 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/column-gap"
16490 },
16491 "column-rule": {
16492 syntax: "<'column-rule-width'> || <'column-rule-style'> || <'column-rule-color'>",
16493 media: "visual",
16494 inherited: false,
16495 animationType: [
16496 "column-rule-color",
16497 "column-rule-style",
16498 "column-rule-width"
16499 ],
16500 percentages: "no",
16501 groups: [
16502 "CSS Columns"
16503 ],
16504 initial: [
16505 "column-rule-width",
16506 "column-rule-style",
16507 "column-rule-color"
16508 ],
16509 appliesto: "multicolElements",
16510 computed: [
16511 "column-rule-color",
16512 "column-rule-style",
16513 "column-rule-width"
16514 ],
16515 order: "perGrammar",
16516 status: "standard",
16517 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/column-rule"
16518 },
16519 "column-rule-color": {
16520 syntax: "<color>",
16521 media: "visual",
16522 inherited: false,
16523 animationType: "color",
16524 percentages: "no",
16525 groups: [
16526 "CSS Columns"
16527 ],
16528 initial: "currentcolor",
16529 appliesto: "multicolElements",
16530 computed: "computedColor",
16531 order: "perGrammar",
16532 status: "standard",
16533 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/column-rule-color"
16534 },
16535 "column-rule-style": {
16536 syntax: "<'border-style'>",
16537 media: "visual",
16538 inherited: false,
16539 animationType: "discrete",
16540 percentages: "no",
16541 groups: [
16542 "CSS Columns"
16543 ],
16544 initial: "none",
16545 appliesto: "multicolElements",
16546 computed: "asSpecified",
16547 order: "perGrammar",
16548 status: "standard",
16549 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/column-rule-style"
16550 },
16551 "column-rule-width": {
16552 syntax: "<'border-width'>",
16553 media: "visual",
16554 inherited: false,
16555 animationType: "length",
16556 percentages: "no",
16557 groups: [
16558 "CSS Columns"
16559 ],
16560 initial: "medium",
16561 appliesto: "multicolElements",
16562 computed: "absoluteLength0IfColumnRuleStyleNoneOrHidden",
16563 order: "perGrammar",
16564 status: "standard",
16565 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/column-rule-width"
16566 },
16567 "column-span": {
16568 syntax: "none | all",
16569 media: "visual",
16570 inherited: false,
16571 animationType: "discrete",
16572 percentages: "no",
16573 groups: [
16574 "CSS Columns"
16575 ],
16576 initial: "none",
16577 appliesto: "inFlowBlockLevelElements",
16578 computed: "asSpecified",
16579 order: "perGrammar",
16580 status: "standard",
16581 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/column-span"
16582 },
16583 "column-width": {
16584 syntax: "<length> | auto",
16585 media: "visual",
16586 inherited: false,
16587 animationType: "length",
16588 percentages: "no",
16589 groups: [
16590 "CSS Columns"
16591 ],
16592 initial: "auto",
16593 appliesto: "blockContainersExceptTableWrappers",
16594 computed: "absoluteLengthZeroOrLarger",
16595 order: "perGrammar",
16596 status: "standard",
16597 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/column-width"
16598 },
16599 columns: columns,
16600 contain: contain,
16601 content: content,
16602 "counter-increment": {
16603 syntax: "[ <custom-ident> <integer>? ]+ | none",
16604 media: "all",
16605 inherited: false,
16606 animationType: "discrete",
16607 percentages: "no",
16608 groups: [
16609 "CSS Counter Styles"
16610 ],
16611 initial: "none",
16612 appliesto: "allElements",
16613 computed: "asSpecified",
16614 order: "uniqueOrder",
16615 status: "standard",
16616 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/counter-increment"
16617 },
16618 "counter-reset": {
16619 syntax: "[ <custom-ident> <integer>? ]+ | none",
16620 media: "all",
16621 inherited: false,
16622 animationType: "discrete",
16623 percentages: "no",
16624 groups: [
16625 "CSS Counter Styles"
16626 ],
16627 initial: "none",
16628 appliesto: "allElements",
16629 computed: "asSpecified",
16630 order: "uniqueOrder",
16631 status: "standard",
16632 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/counter-reset"
16633 },
16634 "counter-set": {
16635 syntax: "[ <custom-ident> <integer>? ]+ | none",
16636 media: "all",
16637 inherited: false,
16638 animationType: "discrete",
16639 percentages: "no",
16640 groups: [
16641 "CSS Counter Styles"
16642 ],
16643 initial: "none",
16644 appliesto: "allElements",
16645 computed: "asSpecified",
16646 order: "uniqueOrder",
16647 status: "standard",
16648 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/counter-set"
16649 },
16650 cursor: cursor,
16651 direction: direction,
16652 display: display,
16653 "empty-cells": {
16654 syntax: "show | hide",
16655 media: "visual",
16656 inherited: true,
16657 animationType: "discrete",
16658 percentages: "no",
16659 groups: [
16660 "CSS Table"
16661 ],
16662 initial: "show",
16663 appliesto: "tableCellElements",
16664 computed: "asSpecified",
16665 order: "uniqueOrder",
16666 status: "standard",
16667 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/empty-cells"
16668 },
16669 filter: filter,
16670 flex: flex,
16671 "flex-basis": {
16672 syntax: "content | <'width'>",
16673 media: "visual",
16674 inherited: false,
16675 animationType: "lpc",
16676 percentages: "referToFlexContainersInnerMainSize",
16677 groups: [
16678 "CSS Flexible Box Layout"
16679 ],
16680 initial: "auto",
16681 appliesto: "flexItemsAndInFlowPseudos",
16682 computed: "asSpecifiedRelativeToAbsoluteLengths",
16683 order: "lengthOrPercentageBeforeKeywordIfBothPresent",
16684 status: "standard",
16685 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/flex-basis"
16686 },
16687 "flex-direction": {
16688 syntax: "row | row-reverse | column | column-reverse",
16689 media: "visual",
16690 inherited: false,
16691 animationType: "discrete",
16692 percentages: "no",
16693 groups: [
16694 "CSS Flexible Box Layout"
16695 ],
16696 initial: "row",
16697 appliesto: "flexContainers",
16698 computed: "asSpecified",
16699 order: "uniqueOrder",
16700 status: "standard",
16701 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/flex-direction"
16702 },
16703 "flex-flow": {
16704 syntax: "<'flex-direction'> || <'flex-wrap'>",
16705 media: "visual",
16706 inherited: false,
16707 animationType: "discrete",
16708 percentages: "no",
16709 groups: [
16710 "CSS Flexible Box Layout"
16711 ],
16712 initial: [
16713 "flex-direction",
16714 "flex-wrap"
16715 ],
16716 appliesto: "flexContainers",
16717 computed: [
16718 "flex-direction",
16719 "flex-wrap"
16720 ],
16721 order: "orderOfAppearance",
16722 status: "standard",
16723 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/flex-flow"
16724 },
16725 "flex-grow": {
16726 syntax: "<number>",
16727 media: "visual",
16728 inherited: false,
16729 animationType: "number",
16730 percentages: "no",
16731 groups: [
16732 "CSS Flexible Box Layout"
16733 ],
16734 initial: "0",
16735 appliesto: "flexItemsAndInFlowPseudos",
16736 computed: "asSpecified",
16737 order: "uniqueOrder",
16738 status: "standard",
16739 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/flex-grow"
16740 },
16741 "flex-shrink": {
16742 syntax: "<number>",
16743 media: "visual",
16744 inherited: false,
16745 animationType: "number",
16746 percentages: "no",
16747 groups: [
16748 "CSS Flexible Box Layout"
16749 ],
16750 initial: "1",
16751 appliesto: "flexItemsAndInFlowPseudos",
16752 computed: "asSpecified",
16753 order: "uniqueOrder",
16754 status: "standard",
16755 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/flex-shrink"
16756 },
16757 "flex-wrap": {
16758 syntax: "nowrap | wrap | wrap-reverse",
16759 media: "visual",
16760 inherited: false,
16761 animationType: "discrete",
16762 percentages: "no",
16763 groups: [
16764 "CSS Flexible Box Layout"
16765 ],
16766 initial: "nowrap",
16767 appliesto: "flexContainers",
16768 computed: "asSpecified",
16769 order: "uniqueOrder",
16770 status: "standard",
16771 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/flex-wrap"
16772 },
16773 float: float,
16774 font: font,
16775 "font-family": {
16776 syntax: "[ <family-name> | <generic-family> ]#",
16777 media: "visual",
16778 inherited: true,
16779 animationType: "discrete",
16780 percentages: "no",
16781 groups: [
16782 "CSS Fonts"
16783 ],
16784 initial: "dependsOnUserAgent",
16785 appliesto: "allElements",
16786 computed: "asSpecified",
16787 order: "uniqueOrder",
16788 alsoAppliesTo: [
16789 "::first-letter",
16790 "::first-line",
16791 "::placeholder"
16792 ],
16793 status: "standard",
16794 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-family"
16795 },
16796 "font-feature-settings": {
16797 syntax: "normal | <feature-tag-value>#",
16798 media: "visual",
16799 inherited: true,
16800 animationType: "discrete",
16801 percentages: "no",
16802 groups: [
16803 "CSS Fonts"
16804 ],
16805 initial: "normal",
16806 appliesto: "allElements",
16807 computed: "asSpecified",
16808 order: "uniqueOrder",
16809 alsoAppliesTo: [
16810 "::first-letter",
16811 "::first-line",
16812 "::placeholder"
16813 ],
16814 status: "standard",
16815 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-feature-settings"
16816 },
16817 "font-kerning": {
16818 syntax: "auto | normal | none",
16819 media: "visual",
16820 inherited: true,
16821 animationType: "discrete",
16822 percentages: "no",
16823 groups: [
16824 "CSS Fonts"
16825 ],
16826 initial: "auto",
16827 appliesto: "allElements",
16828 computed: "asSpecified",
16829 order: "uniqueOrder",
16830 alsoAppliesTo: [
16831 "::first-letter",
16832 "::first-line",
16833 "::placeholder"
16834 ],
16835 status: "standard",
16836 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-kerning"
16837 },
16838 "font-language-override": {
16839 syntax: "normal | <string>",
16840 media: "visual",
16841 inherited: true,
16842 animationType: "discrete",
16843 percentages: "no",
16844 groups: [
16845 "CSS Fonts"
16846 ],
16847 initial: "normal",
16848 appliesto: "allElements",
16849 computed: "asSpecified",
16850 order: "uniqueOrder",
16851 alsoAppliesTo: [
16852 "::first-letter",
16853 "::first-line",
16854 "::placeholder"
16855 ],
16856 status: "standard",
16857 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-language-override"
16858 },
16859 "font-optical-sizing": {
16860 syntax: "auto | none",
16861 media: "visual",
16862 inherited: true,
16863 animationType: "discrete",
16864 percentages: "no",
16865 groups: [
16866 "CSS Fonts"
16867 ],
16868 initial: "auto",
16869 appliesto: "allElements",
16870 computed: "asSpecified",
16871 order: "perGrammar",
16872 alsoAppliesTo: [
16873 "::first-letter",
16874 "::first-line",
16875 "::placeholder"
16876 ],
16877 status: "standard",
16878 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-optical-sizing"
16879 },
16880 "font-variation-settings": {
16881 syntax: "normal | [ <string> <number> ]#",
16882 media: "visual",
16883 inherited: true,
16884 animationType: "transform",
16885 percentages: "no",
16886 groups: [
16887 "CSS Fonts"
16888 ],
16889 initial: "normal",
16890 appliesto: "allElements",
16891 computed: "asSpecified",
16892 order: "perGrammar",
16893 alsoAppliesTo: [
16894 "::first-letter",
16895 "::first-line",
16896 "::placeholder"
16897 ],
16898 status: "experimental",
16899 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-variation-settings"
16900 },
16901 "font-size": {
16902 syntax: "<absolute-size> | <relative-size> | <length-percentage>",
16903 media: "visual",
16904 inherited: true,
16905 animationType: "length",
16906 percentages: "referToParentElementsFontSize",
16907 groups: [
16908 "CSS Fonts"
16909 ],
16910 initial: "medium",
16911 appliesto: "allElements",
16912 computed: "asSpecifiedRelativeToAbsoluteLengths",
16913 order: "uniqueOrder",
16914 alsoAppliesTo: [
16915 "::first-letter",
16916 "::first-line",
16917 "::placeholder"
16918 ],
16919 status: "standard",
16920 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-size"
16921 },
16922 "font-size-adjust": {
16923 syntax: "none | <number>",
16924 media: "visual",
16925 inherited: true,
16926 animationType: "number",
16927 percentages: "no",
16928 groups: [
16929 "CSS Fonts"
16930 ],
16931 initial: "none",
16932 appliesto: "allElements",
16933 computed: "asSpecified",
16934 order: "uniqueOrder",
16935 alsoAppliesTo: [
16936 "::first-letter",
16937 "::first-line",
16938 "::placeholder"
16939 ],
16940 status: "standard",
16941 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-size-adjust"
16942 },
16943 "font-stretch": {
16944 syntax: "<font-stretch-absolute>",
16945 media: "visual",
16946 inherited: true,
16947 animationType: "fontStretch",
16948 percentages: "no",
16949 groups: [
16950 "CSS Fonts"
16951 ],
16952 initial: "normal",
16953 appliesto: "allElements",
16954 computed: "asSpecified",
16955 order: "uniqueOrder",
16956 alsoAppliesTo: [
16957 "::first-letter",
16958 "::first-line",
16959 "::placeholder"
16960 ],
16961 status: "standard",
16962 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-stretch"
16963 },
16964 "font-style": {
16965 syntax: "normal | italic | oblique <angle>?",
16966 media: "visual",
16967 inherited: true,
16968 animationType: "discrete",
16969 percentages: "no",
16970 groups: [
16971 "CSS Fonts"
16972 ],
16973 initial: "normal",
16974 appliesto: "allElements",
16975 computed: "asSpecified",
16976 order: "uniqueOrder",
16977 alsoAppliesTo: [
16978 "::first-letter",
16979 "::first-line",
16980 "::placeholder"
16981 ],
16982 status: "standard",
16983 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-style"
16984 },
16985 "font-synthesis": {
16986 syntax: "none | [ weight || style ]",
16987 media: "visual",
16988 inherited: true,
16989 animationType: "discrete",
16990 percentages: "no",
16991 groups: [
16992 "CSS Fonts"
16993 ],
16994 initial: "weight style",
16995 appliesto: "allElements",
16996 computed: "asSpecified",
16997 order: "orderOfAppearance",
16998 alsoAppliesTo: [
16999 "::first-letter",
17000 "::first-line",
17001 "::placeholder"
17002 ],
17003 status: "standard",
17004 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-synthesis"
17005 },
17006 "font-variant": {
17007 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 ]",
17008 media: "visual",
17009 inherited: true,
17010 animationType: "discrete",
17011 percentages: "no",
17012 groups: [
17013 "CSS Fonts"
17014 ],
17015 initial: "normal",
17016 appliesto: "allElements",
17017 computed: "asSpecified",
17018 order: "uniqueOrder",
17019 alsoAppliesTo: [
17020 "::first-letter",
17021 "::first-line",
17022 "::placeholder"
17023 ],
17024 status: "standard",
17025 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-variant"
17026 },
17027 "font-variant-alternates": {
17028 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> ) ]",
17029 media: "visual",
17030 inherited: true,
17031 animationType: "discrete",
17032 percentages: "no",
17033 groups: [
17034 "CSS Fonts"
17035 ],
17036 initial: "normal",
17037 appliesto: "allElements",
17038 computed: "asSpecified",
17039 order: "orderOfAppearance",
17040 alsoAppliesTo: [
17041 "::first-letter",
17042 "::first-line",
17043 "::placeholder"
17044 ],
17045 status: "standard",
17046 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-variant-alternates"
17047 },
17048 "font-variant-caps": {
17049 syntax: "normal | small-caps | all-small-caps | petite-caps | all-petite-caps | unicase | titling-caps",
17050 media: "visual",
17051 inherited: true,
17052 animationType: "discrete",
17053 percentages: "no",
17054 groups: [
17055 "CSS Fonts"
17056 ],
17057 initial: "normal",
17058 appliesto: "allElements",
17059 computed: "asSpecified",
17060 order: "uniqueOrder",
17061 alsoAppliesTo: [
17062 "::first-letter",
17063 "::first-line",
17064 "::placeholder"
17065 ],
17066 status: "standard",
17067 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-variant-caps"
17068 },
17069 "font-variant-east-asian": {
17070 syntax: "normal | [ <east-asian-variant-values> || <east-asian-width-values> || ruby ]",
17071 media: "visual",
17072 inherited: true,
17073 animationType: "discrete",
17074 percentages: "no",
17075 groups: [
17076 "CSS Fonts"
17077 ],
17078 initial: "normal",
17079 appliesto: "allElements",
17080 computed: "asSpecified",
17081 order: "orderOfAppearance",
17082 alsoAppliesTo: [
17083 "::first-letter",
17084 "::first-line",
17085 "::placeholder"
17086 ],
17087 status: "standard",
17088 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-variant-east-asian"
17089 },
17090 "font-variant-ligatures": {
17091 syntax: "normal | none | [ <common-lig-values> || <discretionary-lig-values> || <historical-lig-values> || <contextual-alt-values> ]",
17092 media: "visual",
17093 inherited: true,
17094 animationType: "discrete",
17095 percentages: "no",
17096 groups: [
17097 "CSS Fonts"
17098 ],
17099 initial: "normal",
17100 appliesto: "allElements",
17101 computed: "asSpecified",
17102 order: "orderOfAppearance",
17103 alsoAppliesTo: [
17104 "::first-letter",
17105 "::first-line",
17106 "::placeholder"
17107 ],
17108 status: "standard",
17109 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-variant-ligatures"
17110 },
17111 "font-variant-numeric": {
17112 syntax: "normal | [ <numeric-figure-values> || <numeric-spacing-values> || <numeric-fraction-values> || ordinal || slashed-zero ]",
17113 media: "visual",
17114 inherited: true,
17115 animationType: "discrete",
17116 percentages: "no",
17117 groups: [
17118 "CSS Fonts"
17119 ],
17120 initial: "normal",
17121 appliesto: "allElements",
17122 computed: "asSpecified",
17123 order: "orderOfAppearance",
17124 alsoAppliesTo: [
17125 "::first-letter",
17126 "::first-line",
17127 "::placeholder"
17128 ],
17129 status: "standard",
17130 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-variant-numeric"
17131 },
17132 "font-variant-position": {
17133 syntax: "normal | sub | super",
17134 media: "visual",
17135 inherited: true,
17136 animationType: "discrete",
17137 percentages: "no",
17138 groups: [
17139 "CSS Fonts"
17140 ],
17141 initial: "normal",
17142 appliesto: "allElements",
17143 computed: "asSpecified",
17144 order: "uniqueOrder",
17145 alsoAppliesTo: [
17146 "::first-letter",
17147 "::first-line",
17148 "::placeholder"
17149 ],
17150 status: "standard",
17151 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-variant-position"
17152 },
17153 "font-weight": {
17154 syntax: "<font-weight-absolute> | bolder | lighter",
17155 media: "visual",
17156 inherited: true,
17157 animationType: "fontWeight",
17158 percentages: "no",
17159 groups: [
17160 "CSS Fonts"
17161 ],
17162 initial: "normal",
17163 appliesto: "allElements",
17164 computed: "keywordOrNumericalValueBolderLighterTransformedToRealValue",
17165 order: "uniqueOrder",
17166 alsoAppliesTo: [
17167 "::first-letter",
17168 "::first-line",
17169 "::placeholder"
17170 ],
17171 status: "standard",
17172 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-weight"
17173 },
17174 gap: gap,
17175 grid: grid,
17176 "grid-area": {
17177 syntax: "<grid-line> [ / <grid-line> ]{0,3}",
17178 media: "visual",
17179 inherited: false,
17180 animationType: "discrete",
17181 percentages: "no",
17182 groups: [
17183 "CSS Grid Layout"
17184 ],
17185 initial: [
17186 "grid-row-start",
17187 "grid-column-start",
17188 "grid-row-end",
17189 "grid-column-end"
17190 ],
17191 appliesto: "gridItemsAndBoxesWithinGridContainer",
17192 computed: [
17193 "grid-row-start",
17194 "grid-column-start",
17195 "grid-row-end",
17196 "grid-column-end"
17197 ],
17198 order: "uniqueOrder",
17199 status: "standard",
17200 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-area"
17201 },
17202 "grid-auto-columns": {
17203 syntax: "<track-size>+",
17204 media: "visual",
17205 inherited: false,
17206 animationType: "discrete",
17207 percentages: "referToDimensionOfContentArea",
17208 groups: [
17209 "CSS Grid Layout"
17210 ],
17211 initial: "auto",
17212 appliesto: "gridContainers",
17213 computed: "percentageAsSpecifiedOrAbsoluteLength",
17214 order: "uniqueOrder",
17215 status: "standard",
17216 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-auto-columns"
17217 },
17218 "grid-auto-flow": {
17219 syntax: "[ row | column ] || dense",
17220 media: "visual",
17221 inherited: false,
17222 animationType: "discrete",
17223 percentages: "no",
17224 groups: [
17225 "CSS Grid Layout"
17226 ],
17227 initial: "row",
17228 appliesto: "gridContainers",
17229 computed: "asSpecified",
17230 order: "uniqueOrder",
17231 status: "standard",
17232 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-auto-flow"
17233 },
17234 "grid-auto-rows": {
17235 syntax: "<track-size>+",
17236 media: "visual",
17237 inherited: false,
17238 animationType: "discrete",
17239 percentages: "referToDimensionOfContentArea",
17240 groups: [
17241 "CSS Grid Layout"
17242 ],
17243 initial: "auto",
17244 appliesto: "gridContainers",
17245 computed: "percentageAsSpecifiedOrAbsoluteLength",
17246 order: "uniqueOrder",
17247 status: "standard",
17248 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-auto-rows"
17249 },
17250 "grid-column": {
17251 syntax: "<grid-line> [ / <grid-line> ]?",
17252 media: "visual",
17253 inherited: false,
17254 animationType: "discrete",
17255 percentages: "no",
17256 groups: [
17257 "CSS Grid Layout"
17258 ],
17259 initial: [
17260 "grid-column-start",
17261 "grid-column-end"
17262 ],
17263 appliesto: "gridItemsAndBoxesWithinGridContainer",
17264 computed: [
17265 "grid-column-start",
17266 "grid-column-end"
17267 ],
17268 order: "uniqueOrder",
17269 status: "standard",
17270 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-column"
17271 },
17272 "grid-column-end": {
17273 syntax: "<grid-line>",
17274 media: "visual",
17275 inherited: false,
17276 animationType: "discrete",
17277 percentages: "no",
17278 groups: [
17279 "CSS Grid Layout"
17280 ],
17281 initial: "auto",
17282 appliesto: "gridItemsAndBoxesWithinGridContainer",
17283 computed: "asSpecified",
17284 order: "uniqueOrder",
17285 status: "standard",
17286 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-column-end"
17287 },
17288 "grid-column-gap": {
17289 syntax: "<length-percentage>",
17290 media: "visual",
17291 inherited: false,
17292 animationType: "length",
17293 percentages: "referToDimensionOfContentArea",
17294 groups: [
17295 "CSS Grid Layout"
17296 ],
17297 initial: "0",
17298 appliesto: "gridContainers",
17299 computed: "percentageAsSpecifiedOrAbsoluteLength",
17300 order: "uniqueOrder",
17301 status: "obsolete",
17302 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/column-gap"
17303 },
17304 "grid-column-start": {
17305 syntax: "<grid-line>",
17306 media: "visual",
17307 inherited: false,
17308 animationType: "discrete",
17309 percentages: "no",
17310 groups: [
17311 "CSS Grid Layout"
17312 ],
17313 initial: "auto",
17314 appliesto: "gridItemsAndBoxesWithinGridContainer",
17315 computed: "asSpecified",
17316 order: "uniqueOrder",
17317 status: "standard",
17318 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-column-start"
17319 },
17320 "grid-gap": {
17321 syntax: "<'grid-row-gap'> <'grid-column-gap'>?",
17322 media: "visual",
17323 inherited: false,
17324 animationType: [
17325 "grid-row-gap",
17326 "grid-column-gap"
17327 ],
17328 percentages: "no",
17329 groups: [
17330 "CSS Grid Layout"
17331 ],
17332 initial: [
17333 "grid-row-gap",
17334 "grid-column-gap"
17335 ],
17336 appliesto: "gridContainers",
17337 computed: [
17338 "grid-row-gap",
17339 "grid-column-gap"
17340 ],
17341 order: "uniqueOrder",
17342 status: "obsolete",
17343 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/gap"
17344 },
17345 "grid-row": {
17346 syntax: "<grid-line> [ / <grid-line> ]?",
17347 media: "visual",
17348 inherited: false,
17349 animationType: "discrete",
17350 percentages: "no",
17351 groups: [
17352 "CSS Grid Layout"
17353 ],
17354 initial: [
17355 "grid-row-start",
17356 "grid-row-end"
17357 ],
17358 appliesto: "gridItemsAndBoxesWithinGridContainer",
17359 computed: [
17360 "grid-row-start",
17361 "grid-row-end"
17362 ],
17363 order: "uniqueOrder",
17364 status: "standard",
17365 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-row"
17366 },
17367 "grid-row-end": {
17368 syntax: "<grid-line>",
17369 media: "visual",
17370 inherited: false,
17371 animationType: "discrete",
17372 percentages: "no",
17373 groups: [
17374 "CSS Grid Layout"
17375 ],
17376 initial: "auto",
17377 appliesto: "gridItemsAndBoxesWithinGridContainer",
17378 computed: "asSpecified",
17379 order: "uniqueOrder",
17380 status: "standard",
17381 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-row-end"
17382 },
17383 "grid-row-gap": {
17384 syntax: "<length-percentage>",
17385 media: "visual",
17386 inherited: false,
17387 animationType: "length",
17388 percentages: "referToDimensionOfContentArea",
17389 groups: [
17390 "CSS Grid Layout"
17391 ],
17392 initial: "0",
17393 appliesto: "gridContainers",
17394 computed: "percentageAsSpecifiedOrAbsoluteLength",
17395 order: "uniqueOrder",
17396 status: "obsolete",
17397 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/row-gap"
17398 },
17399 "grid-row-start": {
17400 syntax: "<grid-line>",
17401 media: "visual",
17402 inherited: false,
17403 animationType: "discrete",
17404 percentages: "no",
17405 groups: [
17406 "CSS Grid Layout"
17407 ],
17408 initial: "auto",
17409 appliesto: "gridItemsAndBoxesWithinGridContainer",
17410 computed: "asSpecified",
17411 order: "uniqueOrder",
17412 status: "standard",
17413 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-row-start"
17414 },
17415 "grid-template": {
17416 syntax: "none | [ <'grid-template-rows'> / <'grid-template-columns'> ] | [ <line-names>? <string> <track-size>? <line-names>? ]+ [ / <explicit-track-list> ]?",
17417 media: "visual",
17418 inherited: false,
17419 animationType: "discrete",
17420 percentages: [
17421 "grid-template-columns",
17422 "grid-template-rows"
17423 ],
17424 groups: [
17425 "CSS Grid Layout"
17426 ],
17427 initial: [
17428 "grid-template-columns",
17429 "grid-template-rows",
17430 "grid-template-areas"
17431 ],
17432 appliesto: "gridContainers",
17433 computed: [
17434 "grid-template-columns",
17435 "grid-template-rows",
17436 "grid-template-areas"
17437 ],
17438 order: "uniqueOrder",
17439 status: "standard",
17440 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-template"
17441 },
17442 "grid-template-areas": {
17443 syntax: "none | <string>+",
17444 media: "visual",
17445 inherited: false,
17446 animationType: "discrete",
17447 percentages: "no",
17448 groups: [
17449 "CSS Grid Layout"
17450 ],
17451 initial: "none",
17452 appliesto: "gridContainers",
17453 computed: "asSpecified",
17454 order: "uniqueOrder",
17455 status: "standard",
17456 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-template-areas"
17457 },
17458 "grid-template-columns": {
17459 syntax: "none | <track-list> | <auto-track-list> | subgrid <line-name-list>?",
17460 media: "visual",
17461 inherited: false,
17462 animationType: "simpleListOfLpcDifferenceLpc",
17463 percentages: "referToDimensionOfContentArea",
17464 groups: [
17465 "CSS Grid Layout"
17466 ],
17467 initial: "none",
17468 appliesto: "gridContainers",
17469 computed: "asSpecifiedRelativeToAbsoluteLengths",
17470 order: "uniqueOrder",
17471 status: "standard",
17472 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-template-columns"
17473 },
17474 "grid-template-rows": {
17475 syntax: "none | <track-list> | <auto-track-list> | subgrid <line-name-list>?",
17476 media: "visual",
17477 inherited: false,
17478 animationType: "simpleListOfLpcDifferenceLpc",
17479 percentages: "referToDimensionOfContentArea",
17480 groups: [
17481 "CSS Grid Layout"
17482 ],
17483 initial: "none",
17484 appliesto: "gridContainers",
17485 computed: "asSpecifiedRelativeToAbsoluteLengths",
17486 order: "uniqueOrder",
17487 status: "standard",
17488 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-template-rows"
17489 },
17490 "hanging-punctuation": {
17491 syntax: "none | [ first || [ force-end | allow-end ] || last ]",
17492 media: "visual",
17493 inherited: true,
17494 animationType: "discrete",
17495 percentages: "no",
17496 groups: [
17497 "CSS Text"
17498 ],
17499 initial: "none",
17500 appliesto: "allElements",
17501 computed: "asSpecified",
17502 order: "uniqueOrder",
17503 status: "standard",
17504 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/hanging-punctuation"
17505 },
17506 height: height,
17507 hyphens: hyphens,
17508 "image-orientation": {
17509 syntax: "from-image | <angle> | [ <angle>? flip ]",
17510 media: "visual",
17511 inherited: true,
17512 animationType: "discrete",
17513 percentages: "no",
17514 groups: [
17515 "CSS Images"
17516 ],
17517 initial: "0deg",
17518 appliesto: "allElements",
17519 computed: "angleRoundedToNextQuarter",
17520 order: "uniqueOrder",
17521 status: "standard",
17522 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/image-orientation"
17523 },
17524 "image-rendering": {
17525 syntax: "auto | crisp-edges | pixelated",
17526 media: "visual",
17527 inherited: true,
17528 animationType: "discrete",
17529 percentages: "no",
17530 groups: [
17531 "CSS Images"
17532 ],
17533 initial: "auto",
17534 appliesto: "allElements",
17535 computed: "asSpecified",
17536 order: "uniqueOrder",
17537 status: "standard",
17538 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/image-rendering"
17539 },
17540 "image-resolution": {
17541 syntax: "[ from-image || <resolution> ] && snap?",
17542 media: "visual",
17543 inherited: true,
17544 animationType: "discrete",
17545 percentages: "no",
17546 groups: [
17547 "CSS Images"
17548 ],
17549 initial: "1dppx",
17550 appliesto: "allElements",
17551 computed: "asSpecifiedWithExceptionOfResolution",
17552 order: "uniqueOrder",
17553 status: "experimental"
17554 },
17555 "ime-mode": {
17556 syntax: "auto | normal | active | inactive | disabled",
17557 media: "interactive",
17558 inherited: false,
17559 animationType: "discrete",
17560 percentages: "no",
17561 groups: [
17562 "CSS Basic User Interface"
17563 ],
17564 initial: "auto",
17565 appliesto: "textFields",
17566 computed: "asSpecified",
17567 order: "uniqueOrder",
17568 status: "obsolete",
17569 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/ime-mode"
17570 },
17571 "initial-letter": {
17572 syntax: "normal | [ <number> <integer>? ]",
17573 media: "visual",
17574 inherited: false,
17575 animationType: "discrete",
17576 percentages: "no",
17577 groups: [
17578 "CSS Inline"
17579 ],
17580 initial: "normal",
17581 appliesto: "firstLetterPseudoElementsAndInlineLevelFirstChildren",
17582 computed: "asSpecified",
17583 order: "uniqueOrder",
17584 status: "experimental",
17585 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/initial-letter"
17586 },
17587 "initial-letter-align": {
17588 syntax: "[ auto | alphabetic | hanging | ideographic ]",
17589 media: "visual",
17590 inherited: false,
17591 animationType: "discrete",
17592 percentages: "no",
17593 groups: [
17594 "CSS Inline"
17595 ],
17596 initial: "auto",
17597 appliesto: "firstLetterPseudoElementsAndInlineLevelFirstChildren",
17598 computed: "asSpecified",
17599 order: "uniqueOrder",
17600 status: "experimental",
17601 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/initial-letter-align"
17602 },
17603 "inline-size": {
17604 syntax: "<'width'>",
17605 media: "visual",
17606 inherited: false,
17607 animationType: "discrete",
17608 percentages: "inlineSizeOfContainingBlock",
17609 groups: [
17610 "CSS Logical Properties"
17611 ],
17612 initial: "auto",
17613 appliesto: "sameAsWidthAndHeight",
17614 computed: "sameAsWidthAndHeight",
17615 order: "uniqueOrder",
17616 status: "standard",
17617 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/inline-size"
17618 },
17619 inset: inset,
17620 "inset-block": {
17621 syntax: "<'top'>{1,2}",
17622 media: "visual",
17623 inherited: false,
17624 animationType: "lpc",
17625 percentages: "logicalHeightOfContainingBlock",
17626 groups: [
17627 "CSS Logical Properties"
17628 ],
17629 initial: "auto",
17630 appliesto: "positionedElements",
17631 computed: "sameAsBoxOffsets",
17632 order: "uniqueOrder",
17633 status: "standard",
17634 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/inset-block"
17635 },
17636 "inset-block-end": {
17637 syntax: "<'top'>",
17638 media: "visual",
17639 inherited: false,
17640 animationType: "lpc",
17641 percentages: "logicalHeightOfContainingBlock",
17642 groups: [
17643 "CSS Logical Properties"
17644 ],
17645 initial: "auto",
17646 appliesto: "positionedElements",
17647 computed: "sameAsBoxOffsets",
17648 order: "uniqueOrder",
17649 status: "standard",
17650 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/inset-block-end"
17651 },
17652 "inset-block-start": {
17653 syntax: "<'top'>",
17654 media: "visual",
17655 inherited: false,
17656 animationType: "lpc",
17657 percentages: "logicalHeightOfContainingBlock",
17658 groups: [
17659 "CSS Logical Properties"
17660 ],
17661 initial: "auto",
17662 appliesto: "positionedElements",
17663 computed: "sameAsBoxOffsets",
17664 order: "uniqueOrder",
17665 status: "standard",
17666 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/inset-block-start"
17667 },
17668 "inset-inline": {
17669 syntax: "<'top'>{1,2}",
17670 media: "visual",
17671 inherited: false,
17672 animationType: "lpc",
17673 percentages: "logicalWidthOfContainingBlock",
17674 groups: [
17675 "CSS Logical Properties"
17676 ],
17677 initial: "auto",
17678 appliesto: "positionedElements",
17679 computed: "sameAsBoxOffsets",
17680 order: "uniqueOrder",
17681 status: "standard",
17682 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/inset-inline"
17683 },
17684 "inset-inline-end": {
17685 syntax: "<'top'>",
17686 media: "visual",
17687 inherited: false,
17688 animationType: "lpc",
17689 percentages: "logicalWidthOfContainingBlock",
17690 groups: [
17691 "CSS Logical Properties"
17692 ],
17693 initial: "auto",
17694 appliesto: "positionedElements",
17695 computed: "sameAsBoxOffsets",
17696 order: "uniqueOrder",
17697 status: "standard",
17698 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/inset-inline-end"
17699 },
17700 "inset-inline-start": {
17701 syntax: "<'top'>",
17702 media: "visual",
17703 inherited: false,
17704 animationType: "lpc",
17705 percentages: "logicalWidthOfContainingBlock",
17706 groups: [
17707 "CSS Logical Properties"
17708 ],
17709 initial: "auto",
17710 appliesto: "positionedElements",
17711 computed: "sameAsBoxOffsets",
17712 order: "uniqueOrder",
17713 status: "standard",
17714 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/inset-inline-start"
17715 },
17716 isolation: isolation,
17717 "justify-content": {
17718 syntax: "normal | <content-distribution> | <overflow-position>? [ <content-position> | left | right ]",
17719 media: "visual",
17720 inherited: false,
17721 animationType: "discrete",
17722 percentages: "no",
17723 groups: [
17724 "CSS Box Alignment"
17725 ],
17726 initial: "normal",
17727 appliesto: "flexContainers",
17728 computed: "asSpecified",
17729 order: "uniqueOrder",
17730 status: "standard",
17731 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/justify-content"
17732 },
17733 "justify-items": {
17734 syntax: "normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | legacy | legacy && [ left | right | center ]",
17735 media: "visual",
17736 inherited: false,
17737 animationType: "discrete",
17738 percentages: "no",
17739 groups: [
17740 "CSS Box Alignment"
17741 ],
17742 initial: "legacy",
17743 appliesto: "allElements",
17744 computed: "asSpecified",
17745 order: "perGrammar",
17746 status: "standard",
17747 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/justify-items"
17748 },
17749 "justify-self": {
17750 syntax: "auto | normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ]",
17751 media: "visual",
17752 inherited: false,
17753 animationType: "discrete",
17754 percentages: "no",
17755 groups: [
17756 "CSS Box Alignment"
17757 ],
17758 initial: "auto",
17759 appliesto: "blockLevelBoxesAndAbsolutelyPositionedBoxesAndGridItems",
17760 computed: "asSpecified",
17761 order: "uniqueOrder",
17762 status: "standard",
17763 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/justify-self"
17764 },
17765 left: left,
17766 "letter-spacing": {
17767 syntax: "normal | <length>",
17768 media: "visual",
17769 inherited: true,
17770 animationType: "length",
17771 percentages: "no",
17772 groups: [
17773 "CSS Text"
17774 ],
17775 initial: "normal",
17776 appliesto: "allElements",
17777 computed: "optimumValueOfAbsoluteLengthOrNormal",
17778 order: "uniqueOrder",
17779 alsoAppliesTo: [
17780 "::first-letter",
17781 "::first-line"
17782 ],
17783 status: "standard",
17784 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/letter-spacing"
17785 },
17786 "line-break": {
17787 syntax: "auto | loose | normal | strict | anywhere",
17788 media: "visual",
17789 inherited: false,
17790 animationType: "discrete",
17791 percentages: "no",
17792 groups: [
17793 "CSS Text"
17794 ],
17795 initial: "auto",
17796 appliesto: "allElements",
17797 computed: "asSpecified",
17798 order: "uniqueOrder",
17799 status: "standard",
17800 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/line-break"
17801 },
17802 "line-clamp": {
17803 syntax: "none | <integer>",
17804 media: "visual",
17805 inherited: false,
17806 animationType: "integer",
17807 percentages: "no",
17808 groups: [
17809 "CSS Overflow"
17810 ],
17811 initial: "none",
17812 appliesto: "blockContainersExceptMultiColumnContainers",
17813 computed: "asSpecified",
17814 order: "perGrammar",
17815 status: "experimental"
17816 },
17817 "line-height": {
17818 syntax: "normal | <number> | <length> | <percentage>",
17819 media: "visual",
17820 inherited: true,
17821 animationType: "numberOrLength",
17822 percentages: "referToElementFontSize",
17823 groups: [
17824 "CSS Fonts"
17825 ],
17826 initial: "normal",
17827 appliesto: "allElements",
17828 computed: "absoluteLengthOrAsSpecified",
17829 order: "uniqueOrder",
17830 alsoAppliesTo: [
17831 "::first-letter",
17832 "::first-line",
17833 "::placeholder"
17834 ],
17835 status: "standard",
17836 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/line-height"
17837 },
17838 "line-height-step": {
17839 syntax: "<length>",
17840 media: "visual",
17841 inherited: true,
17842 animationType: "discrete",
17843 percentages: "no",
17844 groups: [
17845 "CSS Fonts"
17846 ],
17847 initial: "0",
17848 appliesto: "blockContainers",
17849 computed: "absoluteLength",
17850 order: "perGrammar",
17851 status: "experimental",
17852 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/line-height-step"
17853 },
17854 "list-style": {
17855 syntax: "<'list-style-type'> || <'list-style-position'> || <'list-style-image'>",
17856 media: "visual",
17857 inherited: true,
17858 animationType: "discrete",
17859 percentages: "no",
17860 groups: [
17861 "CSS Lists and Counters"
17862 ],
17863 initial: [
17864 "list-style-type",
17865 "list-style-position",
17866 "list-style-image"
17867 ],
17868 appliesto: "listItems",
17869 computed: [
17870 "list-style-image",
17871 "list-style-position",
17872 "list-style-type"
17873 ],
17874 order: "orderOfAppearance",
17875 status: "standard",
17876 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/list-style"
17877 },
17878 "list-style-image": {
17879 syntax: "<url> | none",
17880 media: "visual",
17881 inherited: true,
17882 animationType: "discrete",
17883 percentages: "no",
17884 groups: [
17885 "CSS Lists and Counters"
17886 ],
17887 initial: "none",
17888 appliesto: "listItems",
17889 computed: "noneOrImageWithAbsoluteURI",
17890 order: "uniqueOrder",
17891 status: "standard",
17892 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/list-style-image"
17893 },
17894 "list-style-position": {
17895 syntax: "inside | outside",
17896 media: "visual",
17897 inherited: true,
17898 animationType: "discrete",
17899 percentages: "no",
17900 groups: [
17901 "CSS Lists and Counters"
17902 ],
17903 initial: "outside",
17904 appliesto: "listItems",
17905 computed: "asSpecified",
17906 order: "uniqueOrder",
17907 status: "standard",
17908 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/list-style-position"
17909 },
17910 "list-style-type": {
17911 syntax: "<counter-style> | <string> | none",
17912 media: "visual",
17913 inherited: true,
17914 animationType: "discrete",
17915 percentages: "no",
17916 groups: [
17917 "CSS Lists and Counters"
17918 ],
17919 initial: "disc",
17920 appliesto: "listItems",
17921 computed: "asSpecified",
17922 order: "uniqueOrder",
17923 status: "standard",
17924 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/list-style-type"
17925 },
17926 margin: margin,
17927 "margin-block": {
17928 syntax: "<'margin-left'>{1,2}",
17929 media: "visual",
17930 inherited: false,
17931 animationType: "discrete",
17932 percentages: "dependsOnLayoutModel",
17933 groups: [
17934 "CSS Logical Properties"
17935 ],
17936 initial: "0",
17937 appliesto: "sameAsMargin",
17938 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
17939 order: "uniqueOrder",
17940 status: "standard",
17941 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/margin-block"
17942 },
17943 "margin-block-end": {
17944 syntax: "<'margin-left'>",
17945 media: "visual",
17946 inherited: false,
17947 animationType: "discrete",
17948 percentages: "dependsOnLayoutModel",
17949 groups: [
17950 "CSS Logical Properties"
17951 ],
17952 initial: "0",
17953 appliesto: "sameAsMargin",
17954 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
17955 order: "uniqueOrder",
17956 status: "standard",
17957 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/margin-block-end"
17958 },
17959 "margin-block-start": {
17960 syntax: "<'margin-left'>",
17961 media: "visual",
17962 inherited: false,
17963 animationType: "discrete",
17964 percentages: "dependsOnLayoutModel",
17965 groups: [
17966 "CSS Logical Properties"
17967 ],
17968 initial: "0",
17969 appliesto: "sameAsMargin",
17970 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
17971 order: "uniqueOrder",
17972 status: "standard",
17973 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/margin-block-start"
17974 },
17975 "margin-bottom": {
17976 syntax: "<length> | <percentage> | auto",
17977 media: "visual",
17978 inherited: false,
17979 animationType: "length",
17980 percentages: "referToWidthOfContainingBlock",
17981 groups: [
17982 "CSS Box Model"
17983 ],
17984 initial: "0",
17985 appliesto: "allElementsExceptTableDisplayTypes",
17986 computed: "percentageAsSpecifiedOrAbsoluteLength",
17987 order: "uniqueOrder",
17988 alsoAppliesTo: [
17989 "::first-letter"
17990 ],
17991 status: "standard",
17992 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/margin-bottom"
17993 },
17994 "margin-inline": {
17995 syntax: "<'margin-left'>{1,2}",
17996 media: "visual",
17997 inherited: false,
17998 animationType: "discrete",
17999 percentages: "dependsOnLayoutModel",
18000 groups: [
18001 "CSS Logical Properties"
18002 ],
18003 initial: "0",
18004 appliesto: "sameAsMargin",
18005 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
18006 order: "uniqueOrder",
18007 status: "standard",
18008 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/margin-inline"
18009 },
18010 "margin-inline-end": {
18011 syntax: "<'margin-left'>",
18012 media: "visual",
18013 inherited: false,
18014 animationType: "discrete",
18015 percentages: "dependsOnLayoutModel",
18016 groups: [
18017 "CSS Logical Properties"
18018 ],
18019 initial: "0",
18020 appliesto: "sameAsMargin",
18021 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
18022 order: "uniqueOrder",
18023 status: "standard",
18024 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/margin-inline-end"
18025 },
18026 "margin-inline-start": {
18027 syntax: "<'margin-left'>",
18028 media: "visual",
18029 inherited: false,
18030 animationType: "discrete",
18031 percentages: "dependsOnLayoutModel",
18032 groups: [
18033 "CSS Logical Properties"
18034 ],
18035 initial: "0",
18036 appliesto: "sameAsMargin",
18037 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
18038 order: "uniqueOrder",
18039 status: "standard",
18040 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/margin-inline-start"
18041 },
18042 "margin-left": {
18043 syntax: "<length> | <percentage> | auto",
18044 media: "visual",
18045 inherited: false,
18046 animationType: "length",
18047 percentages: "referToWidthOfContainingBlock",
18048 groups: [
18049 "CSS Box Model"
18050 ],
18051 initial: "0",
18052 appliesto: "allElementsExceptTableDisplayTypes",
18053 computed: "percentageAsSpecifiedOrAbsoluteLength",
18054 order: "uniqueOrder",
18055 alsoAppliesTo: [
18056 "::first-letter"
18057 ],
18058 status: "standard",
18059 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/margin-left"
18060 },
18061 "margin-right": {
18062 syntax: "<length> | <percentage> | auto",
18063 media: "visual",
18064 inherited: false,
18065 animationType: "length",
18066 percentages: "referToWidthOfContainingBlock",
18067 groups: [
18068 "CSS Box Model"
18069 ],
18070 initial: "0",
18071 appliesto: "allElementsExceptTableDisplayTypes",
18072 computed: "percentageAsSpecifiedOrAbsoluteLength",
18073 order: "uniqueOrder",
18074 alsoAppliesTo: [
18075 "::first-letter"
18076 ],
18077 status: "standard",
18078 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/margin-right"
18079 },
18080 "margin-top": {
18081 syntax: "<length> | <percentage> | auto",
18082 media: "visual",
18083 inherited: false,
18084 animationType: "length",
18085 percentages: "referToWidthOfContainingBlock",
18086 groups: [
18087 "CSS Box Model"
18088 ],
18089 initial: "0",
18090 appliesto: "allElementsExceptTableDisplayTypes",
18091 computed: "percentageAsSpecifiedOrAbsoluteLength",
18092 order: "uniqueOrder",
18093 alsoAppliesTo: [
18094 "::first-letter"
18095 ],
18096 status: "standard",
18097 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/margin-top"
18098 },
18099 mask: mask,
18100 "mask-border": {
18101 syntax: "<'mask-border-source'> || <'mask-border-slice'> [ / <'mask-border-width'>? [ / <'mask-border-outset'> ]? ]? || <'mask-border-repeat'> || <'mask-border-mode'>",
18102 media: "visual",
18103 inherited: false,
18104 animationType: [
18105 "mask-border-mode",
18106 "mask-border-outset",
18107 "mask-border-repeat",
18108 "mask-border-slice",
18109 "mask-border-source",
18110 "mask-border-width"
18111 ],
18112 percentages: [
18113 "mask-border-slice",
18114 "mask-border-width"
18115 ],
18116 groups: [
18117 "CSS Masking"
18118 ],
18119 initial: [
18120 "mask-border-mode",
18121 "mask-border-outset",
18122 "mask-border-repeat",
18123 "mask-border-slice",
18124 "mask-border-source",
18125 "mask-border-width"
18126 ],
18127 appliesto: "allElementsSVGContainerElements",
18128 computed: [
18129 "mask-border-mode",
18130 "mask-border-outset",
18131 "mask-border-repeat",
18132 "mask-border-slice",
18133 "mask-border-source",
18134 "mask-border-width"
18135 ],
18136 order: "perGrammar",
18137 stacking: true,
18138 status: "experimental",
18139 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-border"
18140 },
18141 "mask-border-mode": {
18142 syntax: "luminance | alpha",
18143 media: "visual",
18144 inherited: false,
18145 animationType: "discrete",
18146 percentages: "no",
18147 groups: [
18148 "CSS Masking"
18149 ],
18150 initial: "alpha",
18151 appliesto: "allElementsSVGContainerElements",
18152 computed: "asSpecified",
18153 order: "perGrammar",
18154 status: "experimental",
18155 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-border-mode"
18156 },
18157 "mask-border-outset": {
18158 syntax: "[ <length> | <number> ]{1,4}",
18159 media: "visual",
18160 inherited: false,
18161 animationType: "discrete",
18162 percentages: "no",
18163 groups: [
18164 "CSS Masking"
18165 ],
18166 initial: "0",
18167 appliesto: "allElementsSVGContainerElements",
18168 computed: "asSpecifiedRelativeToAbsoluteLengths",
18169 order: "perGrammar",
18170 status: "experimental",
18171 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-border-outset"
18172 },
18173 "mask-border-repeat": {
18174 syntax: "[ stretch | repeat | round | space ]{1,2}",
18175 media: "visual",
18176 inherited: false,
18177 animationType: "discrete",
18178 percentages: "no",
18179 groups: [
18180 "CSS Masking"
18181 ],
18182 initial: "stretch",
18183 appliesto: "allElementsSVGContainerElements",
18184 computed: "asSpecified",
18185 order: "perGrammar",
18186 status: "experimental",
18187 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-border-repeat"
18188 },
18189 "mask-border-slice": {
18190 syntax: "<number-percentage>{1,4} fill?",
18191 media: "visual",
18192 inherited: false,
18193 animationType: "discrete",
18194 percentages: "referToSizeOfMaskBorderImage",
18195 groups: [
18196 "CSS Masking"
18197 ],
18198 initial: "0",
18199 appliesto: "allElementsSVGContainerElements",
18200 computed: "asSpecified",
18201 order: "perGrammar",
18202 status: "experimental",
18203 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-border-slice"
18204 },
18205 "mask-border-source": {
18206 syntax: "none | <image>",
18207 media: "visual",
18208 inherited: false,
18209 animationType: "discrete",
18210 percentages: "no",
18211 groups: [
18212 "CSS Masking"
18213 ],
18214 initial: "none",
18215 appliesto: "allElementsSVGContainerElements",
18216 computed: "asSpecifiedURLsAbsolute",
18217 order: "perGrammar",
18218 status: "experimental",
18219 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-border-source"
18220 },
18221 "mask-border-width": {
18222 syntax: "[ <length-percentage> | <number> | auto ]{1,4}",
18223 media: "visual",
18224 inherited: false,
18225 animationType: "discrete",
18226 percentages: "relativeToMaskBorderImageArea",
18227 groups: [
18228 "CSS Masking"
18229 ],
18230 initial: "auto",
18231 appliesto: "allElementsSVGContainerElements",
18232 computed: "asSpecifiedRelativeToAbsoluteLengths",
18233 order: "perGrammar",
18234 status: "experimental",
18235 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-border-width"
18236 },
18237 "mask-clip": {
18238 syntax: "[ <geometry-box> | no-clip ]#",
18239 media: "visual",
18240 inherited: false,
18241 animationType: "discrete",
18242 percentages: "no",
18243 groups: [
18244 "CSS Masking"
18245 ],
18246 initial: "border-box",
18247 appliesto: "allElementsSVGContainerElements",
18248 computed: "asSpecified",
18249 order: "perGrammar",
18250 status: "standard",
18251 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-clip"
18252 },
18253 "mask-composite": {
18254 syntax: "<compositing-operator>#",
18255 media: "visual",
18256 inherited: false,
18257 animationType: "discrete",
18258 percentages: "no",
18259 groups: [
18260 "CSS Masking"
18261 ],
18262 initial: "add",
18263 appliesto: "allElementsSVGContainerElements",
18264 computed: "asSpecified",
18265 order: "perGrammar",
18266 status: "standard",
18267 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-composite"
18268 },
18269 "mask-image": {
18270 syntax: "<mask-reference>#",
18271 media: "visual",
18272 inherited: false,
18273 animationType: "discrete",
18274 percentages: "no",
18275 groups: [
18276 "CSS Masking"
18277 ],
18278 initial: "none",
18279 appliesto: "allElementsSVGContainerElements",
18280 computed: "asSpecifiedURLsAbsolute",
18281 order: "perGrammar",
18282 status: "standard",
18283 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-image"
18284 },
18285 "mask-mode": {
18286 syntax: "<masking-mode>#",
18287 media: "visual",
18288 inherited: false,
18289 animationType: "discrete",
18290 percentages: "no",
18291 groups: [
18292 "CSS Masking"
18293 ],
18294 initial: "match-source",
18295 appliesto: "allElementsSVGContainerElements",
18296 computed: "asSpecified",
18297 order: "perGrammar",
18298 status: "standard",
18299 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-mode"
18300 },
18301 "mask-origin": {
18302 syntax: "<geometry-box>#",
18303 media: "visual",
18304 inherited: false,
18305 animationType: "discrete",
18306 percentages: "no",
18307 groups: [
18308 "CSS Masking"
18309 ],
18310 initial: "border-box",
18311 appliesto: "allElementsSVGContainerElements",
18312 computed: "asSpecified",
18313 order: "perGrammar",
18314 status: "standard",
18315 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-origin"
18316 },
18317 "mask-position": {
18318 syntax: "<position>#",
18319 media: "visual",
18320 inherited: false,
18321 animationType: "repeatableListOfSimpleListOfLpc",
18322 percentages: "referToSizeOfMaskPaintingArea",
18323 groups: [
18324 "CSS Masking"
18325 ],
18326 initial: "center",
18327 appliesto: "allElementsSVGContainerElements",
18328 computed: "consistsOfTwoKeywordsForOriginAndOffsets",
18329 order: "perGrammar",
18330 status: "standard",
18331 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-position"
18332 },
18333 "mask-repeat": {
18334 syntax: "<repeat-style>#",
18335 media: "visual",
18336 inherited: false,
18337 animationType: "discrete",
18338 percentages: "no",
18339 groups: [
18340 "CSS Masking"
18341 ],
18342 initial: "no-repeat",
18343 appliesto: "allElementsSVGContainerElements",
18344 computed: "consistsOfTwoDimensionKeywords",
18345 order: "perGrammar",
18346 status: "standard",
18347 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-repeat"
18348 },
18349 "mask-size": {
18350 syntax: "<bg-size>#",
18351 media: "visual",
18352 inherited: false,
18353 animationType: "repeatableListOfSimpleListOfLpc",
18354 percentages: "no",
18355 groups: [
18356 "CSS Masking"
18357 ],
18358 initial: "auto",
18359 appliesto: "allElementsSVGContainerElements",
18360 computed: "asSpecifiedRelativeToAbsoluteLengths",
18361 order: "perGrammar",
18362 status: "standard",
18363 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-size"
18364 },
18365 "mask-type": {
18366 syntax: "luminance | alpha",
18367 media: "visual",
18368 inherited: false,
18369 animationType: "discrete",
18370 percentages: "no",
18371 groups: [
18372 "CSS Masking"
18373 ],
18374 initial: "luminance",
18375 appliesto: "maskElements",
18376 computed: "asSpecified",
18377 order: "perGrammar",
18378 status: "standard",
18379 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-type"
18380 },
18381 "max-block-size": {
18382 syntax: "<'max-width'>",
18383 media: "visual",
18384 inherited: false,
18385 animationType: "discrete",
18386 percentages: "blockSizeOfContainingBlock",
18387 groups: [
18388 "CSS Logical Properties"
18389 ],
18390 initial: "0",
18391 appliesto: "sameAsWidthAndHeight",
18392 computed: "sameAsMaxWidthAndMaxHeight",
18393 order: "uniqueOrder",
18394 status: "experimental",
18395 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/max-block-size"
18396 },
18397 "max-height": {
18398 syntax: "<length> | <percentage> | none | max-content | min-content | fit-content | fill-available",
18399 media: "visual",
18400 inherited: false,
18401 animationType: "lpc",
18402 percentages: "regardingHeightOfGeneratedBoxContainingBlockPercentagesNone",
18403 groups: [
18404 "CSS Box Model"
18405 ],
18406 initial: "none",
18407 appliesto: "allElementsButNonReplacedAndTableColumns",
18408 computed: "percentageAsSpecifiedAbsoluteLengthOrNone",
18409 order: "uniqueOrder",
18410 status: "standard",
18411 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/max-height"
18412 },
18413 "max-inline-size": {
18414 syntax: "<'max-width'>",
18415 media: "visual",
18416 inherited: false,
18417 animationType: "discrete",
18418 percentages: "inlineSizeOfContainingBlock",
18419 groups: [
18420 "CSS Logical Properties"
18421 ],
18422 initial: "0",
18423 appliesto: "sameAsWidthAndHeight",
18424 computed: "sameAsMaxWidthAndMaxHeight",
18425 order: "uniqueOrder",
18426 status: "experimental",
18427 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/max-inline-size"
18428 },
18429 "max-lines": {
18430 syntax: "none | <integer>",
18431 media: "visual",
18432 inherited: false,
18433 animationType: "integer",
18434 percentages: "no",
18435 groups: [
18436 "CSS Overflow"
18437 ],
18438 initial: "none",
18439 appliesto: "blockContainersExceptMultiColumnContainers",
18440 computed: "asSpecified",
18441 order: "perGrammar",
18442 status: "experimental"
18443 },
18444 "max-width": {
18445 syntax: "<length> | <percentage> | none | max-content | min-content | fit-content | fill-available",
18446 media: "visual",
18447 inherited: false,
18448 animationType: "lpc",
18449 percentages: "referToWidthOfContainingBlock",
18450 groups: [
18451 "CSS Box Model"
18452 ],
18453 initial: "none",
18454 appliesto: "allElementsButNonReplacedAndTableRows",
18455 computed: "percentageAsSpecifiedAbsoluteLengthOrNone",
18456 order: "uniqueOrder",
18457 status: "standard",
18458 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/max-width"
18459 },
18460 "min-block-size": {
18461 syntax: "<'min-width'>",
18462 media: "visual",
18463 inherited: false,
18464 animationType: "discrete",
18465 percentages: "blockSizeOfContainingBlock",
18466 groups: [
18467 "CSS Logical Properties"
18468 ],
18469 initial: "0",
18470 appliesto: "sameAsWidthAndHeight",
18471 computed: "sameAsMinWidthAndMinHeight",
18472 order: "uniqueOrder",
18473 status: "standard",
18474 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/min-block-size"
18475 },
18476 "min-height": {
18477 syntax: "<length> | <percentage> | auto | max-content | min-content | fit-content | fill-available",
18478 media: "visual",
18479 inherited: false,
18480 animationType: "lpc",
18481 percentages: "regardingHeightOfGeneratedBoxContainingBlockPercentages0",
18482 groups: [
18483 "CSS Box Model"
18484 ],
18485 initial: "auto",
18486 appliesto: "allElementsButNonReplacedAndTableColumns",
18487 computed: "percentageAsSpecifiedOrAbsoluteLength",
18488 order: "uniqueOrder",
18489 status: "standard",
18490 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/min-height"
18491 },
18492 "min-inline-size": {
18493 syntax: "<'min-width'>",
18494 media: "visual",
18495 inherited: false,
18496 animationType: "discrete",
18497 percentages: "inlineSizeOfContainingBlock",
18498 groups: [
18499 "CSS Logical Properties"
18500 ],
18501 initial: "0",
18502 appliesto: "sameAsWidthAndHeight",
18503 computed: "sameAsMinWidthAndMinHeight",
18504 order: "uniqueOrder",
18505 status: "standard",
18506 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/min-inline-size"
18507 },
18508 "min-width": {
18509 syntax: "<length> | <percentage> | auto | max-content | min-content | fit-content | fill-available",
18510 media: "visual",
18511 inherited: false,
18512 animationType: "lpc",
18513 percentages: "referToWidthOfContainingBlock",
18514 groups: [
18515 "CSS Box Model"
18516 ],
18517 initial: "auto",
18518 appliesto: "allElementsButNonReplacedAndTableRows",
18519 computed: "percentageAsSpecifiedOrAbsoluteLength",
18520 order: "uniqueOrder",
18521 status: "standard",
18522 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/min-width"
18523 },
18524 "mix-blend-mode": {
18525 syntax: "<blend-mode>",
18526 media: "visual",
18527 inherited: false,
18528 animationType: "discrete",
18529 percentages: "no",
18530 groups: [
18531 "Compositing and Blending"
18532 ],
18533 initial: "normal",
18534 appliesto: "allElements",
18535 computed: "asSpecified",
18536 order: "uniqueOrder",
18537 stacking: true,
18538 status: "standard",
18539 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mix-blend-mode"
18540 },
18541 "object-fit": {
18542 syntax: "fill | contain | cover | none | scale-down",
18543 media: "visual",
18544 inherited: false,
18545 animationType: "discrete",
18546 percentages: "no",
18547 groups: [
18548 "CSS Images"
18549 ],
18550 initial: "fill",
18551 appliesto: "replacedElements",
18552 computed: "asSpecified",
18553 order: "uniqueOrder",
18554 status: "standard",
18555 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/object-fit"
18556 },
18557 "object-position": {
18558 syntax: "<position>",
18559 media: "visual",
18560 inherited: true,
18561 animationType: "repeatableListOfSimpleListOfLpc",
18562 percentages: "referToWidthAndHeightOfElement",
18563 groups: [
18564 "CSS Images"
18565 ],
18566 initial: "50% 50%",
18567 appliesto: "replacedElements",
18568 computed: "asSpecified",
18569 order: "uniqueOrder",
18570 status: "standard",
18571 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/object-position"
18572 },
18573 offset: offset,
18574 "offset-anchor": {
18575 syntax: "auto | <position>",
18576 media: "visual",
18577 inherited: false,
18578 animationType: "position",
18579 percentages: "relativeToWidthAndHeight",
18580 groups: [
18581 "CSS Motion Path"
18582 ],
18583 initial: "auto",
18584 appliesto: "transformableElements",
18585 computed: "forLengthAbsoluteValueOtherwisePercentage",
18586 order: "perGrammar",
18587 status: "experimental"
18588 },
18589 "offset-distance": {
18590 syntax: "<length-percentage>",
18591 media: "visual",
18592 inherited: false,
18593 animationType: "lpc",
18594 percentages: "referToTotalPathLength",
18595 groups: [
18596 "CSS Motion Path"
18597 ],
18598 initial: "0",
18599 appliesto: "transformableElements",
18600 computed: "forLengthAbsoluteValueOtherwisePercentage",
18601 order: "perGrammar",
18602 status: "experimental",
18603 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/offset-distance"
18604 },
18605 "offset-path": {
18606 syntax: "none | ray( [ <angle> && <size>? && contain? ] ) | <path()> | <url> | [ <basic-shape> || <geometry-box> ]",
18607 media: "visual",
18608 inherited: false,
18609 animationType: "angleOrBasicShapeOrPath",
18610 percentages: "no",
18611 groups: [
18612 "CSS Motion Path"
18613 ],
18614 initial: "none",
18615 appliesto: "transformableElements",
18616 computed: "asSpecified",
18617 order: "perGrammar",
18618 stacking: true,
18619 status: "experimental",
18620 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/offset-path"
18621 },
18622 "offset-position": {
18623 syntax: "auto | <position>",
18624 media: "visual",
18625 inherited: false,
18626 animationType: "position",
18627 percentages: "referToSizeOfContainingBlock",
18628 groups: [
18629 "CSS Motion Path"
18630 ],
18631 initial: "auto",
18632 appliesto: "transformableElements",
18633 computed: "forLengthAbsoluteValueOtherwisePercentage",
18634 order: "perGrammar",
18635 status: "experimental"
18636 },
18637 "offset-rotate": {
18638 syntax: "[ auto | reverse ] || <angle>",
18639 media: "visual",
18640 inherited: false,
18641 animationType: "angleOrBasicShapeOrPath",
18642 percentages: "no",
18643 groups: [
18644 "CSS Motion Path"
18645 ],
18646 initial: "auto",
18647 appliesto: "transformableElements",
18648 computed: "asSpecified",
18649 order: "perGrammar",
18650 status: "experimental",
18651 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/offset-rotate"
18652 },
18653 opacity: opacity,
18654 order: order,
18655 orphans: orphans,
18656 outline: outline,
18657 "outline-color": {
18658 syntax: "<color> | invert",
18659 media: [
18660 "visual",
18661 "interactive"
18662 ],
18663 inherited: false,
18664 animationType: "color",
18665 percentages: "no",
18666 groups: [
18667 "CSS Basic User Interface"
18668 ],
18669 initial: "invertOrCurrentColor",
18670 appliesto: "allElements",
18671 computed: "invertForTranslucentColorRGBAOtherwiseRGB",
18672 order: "uniqueOrder",
18673 status: "standard",
18674 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/outline-color"
18675 },
18676 "outline-offset": {
18677 syntax: "<length>",
18678 media: [
18679 "visual",
18680 "interactive"
18681 ],
18682 inherited: false,
18683 animationType: "length",
18684 percentages: "no",
18685 groups: [
18686 "CSS Basic User Interface"
18687 ],
18688 initial: "0",
18689 appliesto: "allElements",
18690 computed: "asSpecifiedRelativeToAbsoluteLengths",
18691 order: "uniqueOrder",
18692 status: "standard",
18693 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/outline-offset"
18694 },
18695 "outline-style": {
18696 syntax: "auto | <'border-style'>",
18697 media: [
18698 "visual",
18699 "interactive"
18700 ],
18701 inherited: false,
18702 animationType: "discrete",
18703 percentages: "no",
18704 groups: [
18705 "CSS Basic User Interface"
18706 ],
18707 initial: "none",
18708 appliesto: "allElements",
18709 computed: "asSpecified",
18710 order: "uniqueOrder",
18711 status: "standard",
18712 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/outline-style"
18713 },
18714 "outline-width": {
18715 syntax: "<line-width>",
18716 media: [
18717 "visual",
18718 "interactive"
18719 ],
18720 inherited: false,
18721 animationType: "length",
18722 percentages: "no",
18723 groups: [
18724 "CSS Basic User Interface"
18725 ],
18726 initial: "medium",
18727 appliesto: "allElements",
18728 computed: "absoluteLength0ForNone",
18729 order: "uniqueOrder",
18730 status: "standard",
18731 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/outline-width"
18732 },
18733 overflow: overflow,
18734 "overflow-anchor": {
18735 syntax: "auto | none",
18736 media: "visual",
18737 inherited: false,
18738 animationType: "discrete",
18739 percentages: "no",
18740 groups: [
18741 "CSS Scroll Anchoring"
18742 ],
18743 initial: "auto",
18744 appliesto: "allElements",
18745 computed: "asSpecified",
18746 order: "perGrammar",
18747 status: "experimental"
18748 },
18749 "overflow-block": {
18750 syntax: "visible | hidden | clip | scroll | auto",
18751 media: "visual",
18752 inherited: false,
18753 animationType: "discrete",
18754 percentages: "no",
18755 groups: [
18756 "CSS Overflow"
18757 ],
18758 initial: "auto",
18759 appliesto: "blockContainersFlexContainersGridContainers",
18760 computed: "asSpecified",
18761 order: "perGrammar",
18762 status: "experimental"
18763 },
18764 "overflow-clip-box": {
18765 syntax: "padding-box | content-box",
18766 media: "visual",
18767 inherited: false,
18768 animationType: "discrete",
18769 percentages: "no",
18770 groups: [
18771 "Mozilla Extensions"
18772 ],
18773 initial: "padding-box",
18774 appliesto: "allElements",
18775 computed: "asSpecified",
18776 order: "uniqueOrder",
18777 status: "nonstandard",
18778 mdn_url: "https://developer.mozilla.org/docs/Mozilla/CSS/overflow-clip-box"
18779 },
18780 "overflow-inline": {
18781 syntax: "visible | hidden | clip | scroll | auto",
18782 media: "visual",
18783 inherited: false,
18784 animationType: "discrete",
18785 percentages: "no",
18786 groups: [
18787 "CSS Overflow"
18788 ],
18789 initial: "auto",
18790 appliesto: "blockContainersFlexContainersGridContainers",
18791 computed: "asSpecified",
18792 order: "perGrammar",
18793 status: "experimental"
18794 },
18795 "overflow-wrap": {
18796 syntax: "normal | break-word | anywhere",
18797 media: "visual",
18798 inherited: true,
18799 animationType: "discrete",
18800 percentages: "no",
18801 groups: [
18802 "CSS Text"
18803 ],
18804 initial: "normal",
18805 appliesto: "nonReplacedInlineElements",
18806 computed: "asSpecified",
18807 order: "uniqueOrder",
18808 status: "standard",
18809 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/overflow-wrap"
18810 },
18811 "overflow-x": {
18812 syntax: "visible | hidden | clip | scroll | auto",
18813 media: "visual",
18814 inherited: false,
18815 animationType: "discrete",
18816 percentages: "no",
18817 groups: [
18818 "CSS Overflow"
18819 ],
18820 initial: "visible",
18821 appliesto: "blockContainersFlexContainersGridContainers",
18822 computed: "asSpecified",
18823 order: "uniqueOrder",
18824 status: "standard",
18825 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/overflow-x"
18826 },
18827 "overflow-y": {
18828 syntax: "visible | hidden | clip | scroll | auto",
18829 media: "visual",
18830 inherited: false,
18831 animationType: "discrete",
18832 percentages: "no",
18833 groups: [
18834 "CSS Overflow"
18835 ],
18836 initial: "visible",
18837 appliesto: "blockContainersFlexContainersGridContainers",
18838 computed: "asSpecified",
18839 order: "uniqueOrder",
18840 status: "standard",
18841 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/overflow-y"
18842 },
18843 "overscroll-behavior": {
18844 syntax: "[ contain | none | auto ]{1,2}",
18845 media: "visual",
18846 inherited: false,
18847 animationType: "discrete",
18848 percentages: "no",
18849 groups: [
18850 "CSS Box Model"
18851 ],
18852 initial: "auto",
18853 appliesto: "nonReplacedBlockAndInlineBlockElements",
18854 computed: "asSpecified",
18855 order: "uniqueOrder",
18856 status: "nonstandard",
18857 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/overscroll-behavior"
18858 },
18859 "overscroll-behavior-x": {
18860 syntax: "contain | none | auto",
18861 media: "visual",
18862 inherited: false,
18863 animationType: "discrete",
18864 percentages: "no",
18865 groups: [
18866 "CSS Box Model"
18867 ],
18868 initial: "auto",
18869 appliesto: "nonReplacedBlockAndInlineBlockElements",
18870 computed: "asSpecified",
18871 order: "uniqueOrder",
18872 status: "nonstandard",
18873 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/overscroll-behavior-x"
18874 },
18875 "overscroll-behavior-y": {
18876 syntax: "contain | none | auto",
18877 media: "visual",
18878 inherited: false,
18879 animationType: "discrete",
18880 percentages: "no",
18881 groups: [
18882 "CSS Box Model"
18883 ],
18884 initial: "auto",
18885 appliesto: "nonReplacedBlockAndInlineBlockElements",
18886 computed: "asSpecified",
18887 order: "uniqueOrder",
18888 status: "nonstandard",
18889 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/overscroll-behavior-y"
18890 },
18891 padding: padding,
18892 "padding-block": {
18893 syntax: "<'padding-left'>{1,2}",
18894 media: "visual",
18895 inherited: false,
18896 animationType: "discrete",
18897 percentages: "logicalWidthOfContainingBlock",
18898 groups: [
18899 "CSS Logical Properties"
18900 ],
18901 initial: "0",
18902 appliesto: "allElements",
18903 computed: "asLength",
18904 order: "uniqueOrder",
18905 status: "standard",
18906 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/padding-block"
18907 },
18908 "padding-block-end": {
18909 syntax: "<'padding-left'>",
18910 media: "visual",
18911 inherited: false,
18912 animationType: "discrete",
18913 percentages: "logicalWidthOfContainingBlock",
18914 groups: [
18915 "CSS Logical Properties"
18916 ],
18917 initial: "0",
18918 appliesto: "allElements",
18919 computed: "asLength",
18920 order: "uniqueOrder",
18921 status: "standard",
18922 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/padding-block-end"
18923 },
18924 "padding-block-start": {
18925 syntax: "<'padding-left'>",
18926 media: "visual",
18927 inherited: false,
18928 animationType: "discrete",
18929 percentages: "logicalWidthOfContainingBlock",
18930 groups: [
18931 "CSS Logical Properties"
18932 ],
18933 initial: "0",
18934 appliesto: "allElements",
18935 computed: "asLength",
18936 order: "uniqueOrder",
18937 status: "standard",
18938 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/padding-block-start"
18939 },
18940 "padding-bottom": {
18941 syntax: "<length> | <percentage>",
18942 media: "visual",
18943 inherited: false,
18944 animationType: "length",
18945 percentages: "referToWidthOfContainingBlock",
18946 groups: [
18947 "CSS Box Model"
18948 ],
18949 initial: "0",
18950 appliesto: "allElementsExceptInternalTableDisplayTypes",
18951 computed: "percentageAsSpecifiedOrAbsoluteLength",
18952 order: "uniqueOrder",
18953 alsoAppliesTo: [
18954 "::first-letter"
18955 ],
18956 status: "standard",
18957 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/padding-bottom"
18958 },
18959 "padding-inline": {
18960 syntax: "<'padding-left'>{1,2}",
18961 media: "visual",
18962 inherited: false,
18963 animationType: "discrete",
18964 percentages: "logicalWidthOfContainingBlock",
18965 groups: [
18966 "CSS Logical Properties"
18967 ],
18968 initial: "0",
18969 appliesto: "allElements",
18970 computed: "asLength",
18971 order: "uniqueOrder",
18972 status: "standard",
18973 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/padding-inline"
18974 },
18975 "padding-inline-end": {
18976 syntax: "<'padding-left'>",
18977 media: "visual",
18978 inherited: false,
18979 animationType: "discrete",
18980 percentages: "logicalWidthOfContainingBlock",
18981 groups: [
18982 "CSS Logical Properties"
18983 ],
18984 initial: "0",
18985 appliesto: "allElements",
18986 computed: "asLength",
18987 order: "uniqueOrder",
18988 status: "standard",
18989 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/padding-inline-end"
18990 },
18991 "padding-inline-start": {
18992 syntax: "<'padding-left'>",
18993 media: "visual",
18994 inherited: false,
18995 animationType: "discrete",
18996 percentages: "logicalWidthOfContainingBlock",
18997 groups: [
18998 "CSS Logical Properties"
18999 ],
19000 initial: "0",
19001 appliesto: "allElements",
19002 computed: "asLength",
19003 order: "uniqueOrder",
19004 status: "standard",
19005 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/padding-inline-start"
19006 },
19007 "padding-left": {
19008 syntax: "<length> | <percentage>",
19009 media: "visual",
19010 inherited: false,
19011 animationType: "length",
19012 percentages: "referToWidthOfContainingBlock",
19013 groups: [
19014 "CSS Box Model"
19015 ],
19016 initial: "0",
19017 appliesto: "allElementsExceptInternalTableDisplayTypes",
19018 computed: "percentageAsSpecifiedOrAbsoluteLength",
19019 order: "uniqueOrder",
19020 alsoAppliesTo: [
19021 "::first-letter"
19022 ],
19023 status: "standard",
19024 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/padding-left"
19025 },
19026 "padding-right": {
19027 syntax: "<length> | <percentage>",
19028 media: "visual",
19029 inherited: false,
19030 animationType: "length",
19031 percentages: "referToWidthOfContainingBlock",
19032 groups: [
19033 "CSS Box Model"
19034 ],
19035 initial: "0",
19036 appliesto: "allElementsExceptInternalTableDisplayTypes",
19037 computed: "percentageAsSpecifiedOrAbsoluteLength",
19038 order: "uniqueOrder",
19039 alsoAppliesTo: [
19040 "::first-letter"
19041 ],
19042 status: "standard",
19043 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/padding-right"
19044 },
19045 "padding-top": {
19046 syntax: "<length> | <percentage>",
19047 media: "visual",
19048 inherited: false,
19049 animationType: "length",
19050 percentages: "referToWidthOfContainingBlock",
19051 groups: [
19052 "CSS Box Model"
19053 ],
19054 initial: "0",
19055 appliesto: "allElementsExceptInternalTableDisplayTypes",
19056 computed: "percentageAsSpecifiedOrAbsoluteLength",
19057 order: "uniqueOrder",
19058 alsoAppliesTo: [
19059 "::first-letter"
19060 ],
19061 status: "standard",
19062 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/padding-top"
19063 },
19064 "page-break-after": {
19065 syntax: "auto | always | avoid | left | right | recto | verso",
19066 media: [
19067 "visual",
19068 "paged"
19069 ],
19070 inherited: false,
19071 animationType: "discrete",
19072 percentages: "no",
19073 groups: [
19074 "CSS Pages"
19075 ],
19076 initial: "auto",
19077 appliesto: "blockElementsInNormalFlow",
19078 computed: "asSpecified",
19079 order: "uniqueOrder",
19080 status: "standard",
19081 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/page-break-after"
19082 },
19083 "page-break-before": {
19084 syntax: "auto | always | avoid | left | right | recto | verso",
19085 media: [
19086 "visual",
19087 "paged"
19088 ],
19089 inherited: false,
19090 animationType: "discrete",
19091 percentages: "no",
19092 groups: [
19093 "CSS Pages"
19094 ],
19095 initial: "auto",
19096 appliesto: "blockElementsInNormalFlow",
19097 computed: "asSpecified",
19098 order: "uniqueOrder",
19099 status: "standard",
19100 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/page-break-before"
19101 },
19102 "page-break-inside": {
19103 syntax: "auto | avoid",
19104 media: [
19105 "visual",
19106 "paged"
19107 ],
19108 inherited: false,
19109 animationType: "discrete",
19110 percentages: "no",
19111 groups: [
19112 "CSS Pages"
19113 ],
19114 initial: "auto",
19115 appliesto: "blockElementsInNormalFlow",
19116 computed: "asSpecified",
19117 order: "uniqueOrder",
19118 status: "standard",
19119 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/page-break-inside"
19120 },
19121 "paint-order": {
19122 syntax: "normal | [ fill || stroke || markers ]",
19123 media: "visual",
19124 inherited: true,
19125 animationType: "discrete",
19126 percentages: "no",
19127 groups: [
19128 "CSS Text"
19129 ],
19130 initial: "normal",
19131 appliesto: "textElements",
19132 computed: "asSpecified",
19133 order: "uniqueOrder",
19134 status: "experimental",
19135 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/paint-order"
19136 },
19137 perspective: perspective,
19138 "perspective-origin": {
19139 syntax: "<position>",
19140 media: "visual",
19141 inherited: false,
19142 animationType: "simpleListOfLpc",
19143 percentages: "referToSizeOfBoundingBox",
19144 groups: [
19145 "CSS Transforms"
19146 ],
19147 initial: "50% 50%",
19148 appliesto: "transformableElements",
19149 computed: "forLengthAbsoluteValueOtherwisePercentage",
19150 order: "oneOrTwoValuesLengthAbsoluteKeywordsPercentages",
19151 status: "standard",
19152 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/perspective-origin"
19153 },
19154 "place-content": {
19155 syntax: "<'align-content'> <'justify-content'>?",
19156 media: "visual",
19157 inherited: false,
19158 animationType: "discrete",
19159 percentages: "no",
19160 groups: [
19161 "CSS Box Alignment"
19162 ],
19163 initial: "normal",
19164 appliesto: "multilineFlexContainers",
19165 computed: "asSpecified",
19166 order: "uniqueOrder",
19167 status: "standard",
19168 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/place-content"
19169 },
19170 "place-items": {
19171 syntax: "<'align-items'> <'justify-items'>?",
19172 media: "visual",
19173 inherited: false,
19174 animationType: "discrete",
19175 percentages: "no",
19176 groups: [
19177 "CSS Box Alignment"
19178 ],
19179 initial: [
19180 "align-items",
19181 "justify-items"
19182 ],
19183 appliesto: "allElements",
19184 computed: [
19185 "align-items",
19186 "justify-items"
19187 ],
19188 order: "uniqueOrder",
19189 status: "standard",
19190 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/place-items"
19191 },
19192 "place-self": {
19193 syntax: "<'align-self'> <'justify-self'>?",
19194 media: "visual",
19195 inherited: false,
19196 animationType: "discrete",
19197 percentages: "no",
19198 groups: [
19199 "CSS Box Alignment"
19200 ],
19201 initial: [
19202 "align-self",
19203 "justify-self"
19204 ],
19205 appliesto: "blockLevelBoxesAndAbsolutelyPositionedBoxesAndGridItems",
19206 computed: [
19207 "align-self",
19208 "justify-self"
19209 ],
19210 order: "uniqueOrder",
19211 status: "standard",
19212 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/place-self"
19213 },
19214 "pointer-events": {
19215 syntax: "auto | none | visiblePainted | visibleFill | visibleStroke | visible | painted | fill | stroke | all | inherit",
19216 media: "visual",
19217 inherited: true,
19218 animationType: "discrete",
19219 percentages: "no",
19220 groups: [
19221 "Pointer Events"
19222 ],
19223 initial: "auto",
19224 appliesto: "allElements",
19225 computed: "asSpecified",
19226 order: "uniqueOrder",
19227 status: "standard",
19228 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/pointer-events"
19229 },
19230 position: position,
19231 quotes: quotes,
19232 resize: resize,
19233 right: right,
19234 rotate: rotate,
19235 "row-gap": {
19236 syntax: "normal | <length-percentage>",
19237 media: "visual",
19238 inherited: false,
19239 animationType: "lpc",
19240 percentages: "referToDimensionOfContentArea",
19241 groups: [
19242 "CSS Box Alignment"
19243 ],
19244 initial: "normal",
19245 appliesto: "multiColumnElementsFlexContainersGridContainers",
19246 computed: "asSpecifiedWithLengthsAbsoluteAndNormalComputingToZeroExceptMultiColumn",
19247 order: "perGrammar",
19248 status: "standard",
19249 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/row-gap"
19250 },
19251 "ruby-align": {
19252 syntax: "start | center | space-between | space-around",
19253 media: "visual",
19254 inherited: true,
19255 animationType: "discrete",
19256 percentages: "no",
19257 groups: [
19258 "CSS Ruby"
19259 ],
19260 initial: "space-around",
19261 appliesto: "rubyBasesAnnotationsBaseAnnotationContainers",
19262 computed: "asSpecified",
19263 order: "uniqueOrder",
19264 status: "experimental",
19265 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/ruby-align"
19266 },
19267 "ruby-merge": {
19268 syntax: "separate | collapse | auto",
19269 media: "visual",
19270 inherited: true,
19271 animationType: "discrete",
19272 percentages: "no",
19273 groups: [
19274 "CSS Ruby"
19275 ],
19276 initial: "separate",
19277 appliesto: "rubyAnnotationsContainers",
19278 computed: "asSpecified",
19279 order: "uniqueOrder",
19280 status: "experimental"
19281 },
19282 "ruby-position": {
19283 syntax: "over | under | inter-character",
19284 media: "visual",
19285 inherited: true,
19286 animationType: "discrete",
19287 percentages: "no",
19288 groups: [
19289 "CSS Ruby"
19290 ],
19291 initial: "over",
19292 appliesto: "rubyAnnotationsContainers",
19293 computed: "asSpecified",
19294 order: "uniqueOrder",
19295 status: "experimental",
19296 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/ruby-position"
19297 },
19298 scale: scale,
19299 "scrollbar-color": {
19300 syntax: "auto | dark | light | <color>{2}",
19301 media: "visual",
19302 inherited: true,
19303 animationType: "color",
19304 percentages: "no",
19305 groups: [
19306 "CSS Scrollbars"
19307 ],
19308 initial: "auto",
19309 appliesto: "scrollingBoxes",
19310 computed: "asSpecified",
19311 order: "perGrammar",
19312 status: "standard",
19313 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scrollbar-color"
19314 },
19315 "scrollbar-width": {
19316 syntax: "auto | thin | none",
19317 media: "visual",
19318 inherited: false,
19319 animationType: "discrete",
19320 percentages: "no",
19321 groups: [
19322 "CSS Scrollbars"
19323 ],
19324 initial: "auto",
19325 appliesto: "scrollingBoxes",
19326 computed: "asSpecified",
19327 order: "perGrammar",
19328 status: "standard",
19329 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scrollbar-width"
19330 },
19331 "scroll-behavior": {
19332 syntax: "auto | smooth",
19333 media: "visual",
19334 inherited: false,
19335 animationType: "discrete",
19336 percentages: "no",
19337 groups: [
19338 "CSSOM View"
19339 ],
19340 initial: "auto",
19341 appliesto: "scrollingBoxes",
19342 computed: "asSpecified",
19343 order: "uniqueOrder",
19344 status: "standard",
19345 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-behavior"
19346 },
19347 "scroll-margin": {
19348 syntax: "<length>{1,4}",
19349 media: "visual",
19350 inherited: false,
19351 animationType: "byComputedValueType",
19352 percentages: "no",
19353 groups: [
19354 "CSS Scroll Snap"
19355 ],
19356 initial: "0",
19357 appliesto: "allElements",
19358 computed: "asSpecified",
19359 order: "perGrammar",
19360 status: "standard",
19361 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-margin"
19362 },
19363 "scroll-margin-block": {
19364 syntax: "<length>{1,2}",
19365 media: "visual",
19366 inherited: false,
19367 animationType: "byComputedValueType",
19368 percentages: "no",
19369 groups: [
19370 "CSS Scroll Snap"
19371 ],
19372 initial: "0",
19373 appliesto: "allElements",
19374 computed: "asSpecified",
19375 order: "perGrammar",
19376 status: "standard",
19377 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-margin-block"
19378 },
19379 "scroll-margin-block-start": {
19380 syntax: "<length>",
19381 media: "visual",
19382 inherited: false,
19383 animationType: "byComputedValueType",
19384 percentages: "no",
19385 groups: [
19386 "CSS Scroll Snap"
19387 ],
19388 initial: "0",
19389 appliesto: "allElements",
19390 computed: "asSpecified",
19391 order: "perGrammar",
19392 status: "standard",
19393 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-margin-block-start"
19394 },
19395 "scroll-margin-block-end": {
19396 syntax: "<length>",
19397 media: "visual",
19398 inherited: false,
19399 animationType: "byComputedValueType",
19400 percentages: "no",
19401 groups: [
19402 "CSS Scroll Snap"
19403 ],
19404 initial: "0",
19405 appliesto: "allElements",
19406 computed: "asSpecified",
19407 order: "perGrammar",
19408 status: "standard",
19409 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-margin-block-end"
19410 },
19411 "scroll-margin-bottom": {
19412 syntax: "<length>",
19413 media: "visual",
19414 inherited: false,
19415 animationType: "byComputedValueType",
19416 percentages: "no",
19417 groups: [
19418 "CSS Scroll Snap"
19419 ],
19420 initial: "0",
19421 appliesto: "allElements",
19422 computed: "asSpecified",
19423 order: "perGrammar",
19424 status: "standard",
19425 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-margin-bottom"
19426 },
19427 "scroll-margin-inline": {
19428 syntax: "<length>{1,2}",
19429 media: "visual",
19430 inherited: false,
19431 animationType: "byComputedValueType",
19432 percentages: "no",
19433 groups: [
19434 "CSS Scroll Snap"
19435 ],
19436 initial: "0",
19437 appliesto: "allElements",
19438 computed: "asSpecified",
19439 order: "perGrammar",
19440 status: "standard",
19441 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-margin-inline"
19442 },
19443 "scroll-margin-inline-start": {
19444 syntax: "<length>",
19445 media: "visual",
19446 inherited: false,
19447 animationType: "byComputedValueType",
19448 percentages: "no",
19449 groups: [
19450 "CSS Scroll Snap"
19451 ],
19452 initial: "0",
19453 appliesto: "allElements",
19454 computed: "asSpecified",
19455 order: "perGrammar",
19456 status: "standard",
19457 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-margin-inline-start"
19458 },
19459 "scroll-margin-inline-end": {
19460 syntax: "<length>",
19461 media: "visual",
19462 inherited: false,
19463 animationType: "byComputedValueType",
19464 percentages: "no",
19465 groups: [
19466 "CSS Scroll Snap"
19467 ],
19468 initial: "0",
19469 appliesto: "allElements",
19470 computed: "asSpecified",
19471 order: "perGrammar",
19472 status: "standard",
19473 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-margin-inline-end"
19474 },
19475 "scroll-margin-left": {
19476 syntax: "<length>",
19477 media: "visual",
19478 inherited: false,
19479 animationType: "byComputedValueType",
19480 percentages: "no",
19481 groups: [
19482 "CSS Scroll Snap"
19483 ],
19484 initial: "0",
19485 appliesto: "allElements",
19486 computed: "asSpecified",
19487 order: "perGrammar",
19488 status: "standard",
19489 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-margin-left"
19490 },
19491 "scroll-margin-right": {
19492 syntax: "<length>",
19493 media: "visual",
19494 inherited: false,
19495 animationType: "byComputedValueType",
19496 percentages: "no",
19497 groups: [
19498 "CSS Scroll Snap"
19499 ],
19500 initial: "0",
19501 appliesto: "allElements",
19502 computed: "asSpecified",
19503 order: "perGrammar",
19504 status: "standard",
19505 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-margin-right"
19506 },
19507 "scroll-margin-top": {
19508 syntax: "<length>",
19509 media: "visual",
19510 inherited: false,
19511 animationType: "byComputedValueType",
19512 percentages: "no",
19513 groups: [
19514 "CSS Scroll Snap"
19515 ],
19516 initial: "0",
19517 appliesto: "allElements",
19518 computed: "asSpecified",
19519 order: "perGrammar",
19520 status: "standard",
19521 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-margin-top"
19522 },
19523 "scroll-padding": {
19524 syntax: "[ auto | <length-percentage> ]{1,4}",
19525 media: "visual",
19526 inherited: false,
19527 animationType: "byComputedValueType",
19528 percentages: "relativeToTheScrollContainersScrollport",
19529 groups: [
19530 "CSS Scroll Snap"
19531 ],
19532 initial: "auto",
19533 appliesto: "scrollContainers",
19534 computed: "asSpecified",
19535 order: "perGrammar",
19536 status: "standard",
19537 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-padding"
19538 },
19539 "scroll-padding-block": {
19540 syntax: "[ auto | <length-percentage> ]{1,2}",
19541 media: "visual",
19542 inherited: false,
19543 animationType: "byComputedValueType",
19544 percentages: "relativeToTheScrollContainersScrollport",
19545 groups: [
19546 "CSS Scroll Snap"
19547 ],
19548 initial: "auto",
19549 appliesto: "scrollContainers",
19550 computed: "asSpecified",
19551 order: "perGrammar",
19552 status: "standard",
19553 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-padding-block"
19554 },
19555 "scroll-padding-block-start": {
19556 syntax: "auto | <length-percentage>",
19557 media: "visual",
19558 inherited: false,
19559 animationType: "byComputedValueType",
19560 percentages: "relativeToTheScrollContainersScrollport",
19561 groups: [
19562 "CSS Scroll Snap"
19563 ],
19564 initial: "auto",
19565 appliesto: "scrollContainers",
19566 computed: "asSpecified",
19567 order: "perGrammar",
19568 status: "standard",
19569 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-padding-block-start"
19570 },
19571 "scroll-padding-block-end": {
19572 syntax: "auto | <length-percentage>",
19573 media: "visual",
19574 inherited: false,
19575 animationType: "byComputedValueType",
19576 percentages: "relativeToTheScrollContainersScrollport",
19577 groups: [
19578 "CSS Scroll Snap"
19579 ],
19580 initial: "auto",
19581 appliesto: "scrollContainers",
19582 computed: "asSpecified",
19583 order: "perGrammar",
19584 status: "standard",
19585 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-padding-block-end"
19586 },
19587 "scroll-padding-bottom": {
19588 syntax: "auto | <length-percentage>",
19589 media: "visual",
19590 inherited: false,
19591 animationType: "byComputedValueType",
19592 percentages: "relativeToTheScrollContainersScrollport",
19593 groups: [
19594 "CSS Scroll Snap"
19595 ],
19596 initial: "auto",
19597 appliesto: "scrollContainers",
19598 computed: "asSpecified",
19599 order: "perGrammar",
19600 status: "standard",
19601 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-padding-bottom"
19602 },
19603 "scroll-padding-inline": {
19604 syntax: "[ auto | <length-percentage> ]{1,2}",
19605 media: "visual",
19606 inherited: false,
19607 animationType: "byComputedValueType",
19608 percentages: "relativeToTheScrollContainersScrollport",
19609 groups: [
19610 "CSS Scroll Snap"
19611 ],
19612 initial: "auto",
19613 appliesto: "scrollContainers",
19614 computed: "asSpecified",
19615 order: "perGrammar",
19616 status: "standard",
19617 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-padding-inline"
19618 },
19619 "scroll-padding-inline-start": {
19620 syntax: "auto | <length-percentage>",
19621 media: "visual",
19622 inherited: false,
19623 animationType: "byComputedValueType",
19624 percentages: "relativeToTheScrollContainersScrollport",
19625 groups: [
19626 "CSS Scroll Snap"
19627 ],
19628 initial: "auto",
19629 appliesto: "scrollContainers",
19630 computed: "asSpecified",
19631 order: "perGrammar",
19632 status: "standard",
19633 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-padding-inline-start"
19634 },
19635 "scroll-padding-inline-end": {
19636 syntax: "auto | <length-percentage>",
19637 media: "visual",
19638 inherited: false,
19639 animationType: "byComputedValueType",
19640 percentages: "relativeToTheScrollContainersScrollport",
19641 groups: [
19642 "CSS Scroll Snap"
19643 ],
19644 initial: "auto",
19645 appliesto: "scrollContainers",
19646 computed: "asSpecified",
19647 order: "perGrammar",
19648 status: "standard",
19649 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-padding-inline-end"
19650 },
19651 "scroll-padding-left": {
19652 syntax: "auto | <length-percentage>",
19653 media: "visual",
19654 inherited: false,
19655 animationType: "byComputedValueType",
19656 percentages: "relativeToTheScrollContainersScrollport",
19657 groups: [
19658 "CSS Scroll Snap"
19659 ],
19660 initial: "auto",
19661 appliesto: "scrollContainers",
19662 computed: "asSpecified",
19663 order: "perGrammar",
19664 status: "standard",
19665 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-padding-left"
19666 },
19667 "scroll-padding-right": {
19668 syntax: "auto | <length-percentage>",
19669 media: "visual",
19670 inherited: false,
19671 animationType: "byComputedValueType",
19672 percentages: "relativeToTheScrollContainersScrollport",
19673 groups: [
19674 "CSS Scroll Snap"
19675 ],
19676 initial: "auto",
19677 appliesto: "scrollContainers",
19678 computed: "asSpecified",
19679 order: "perGrammar",
19680 status: "standard",
19681 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-padding-right"
19682 },
19683 "scroll-padding-top": {
19684 syntax: "auto | <length-percentage>",
19685 media: "visual",
19686 inherited: false,
19687 animationType: "byComputedValueType",
19688 percentages: "relativeToTheScrollContainersScrollport",
19689 groups: [
19690 "CSS Scroll Snap"
19691 ],
19692 initial: "auto",
19693 appliesto: "scrollContainers",
19694 computed: "asSpecified",
19695 order: "perGrammar",
19696 status: "standard",
19697 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-padding-top"
19698 },
19699 "scroll-snap-align": {
19700 syntax: "[ none | start | end | center ]{1,2}",
19701 media: "visual",
19702 inherited: false,
19703 animationType: "discrete",
19704 percentages: "no",
19705 groups: [
19706 "CSS Scroll Snap"
19707 ],
19708 initial: "none",
19709 appliesto: "allElements",
19710 computed: "asSpecified",
19711 order: "perGrammar",
19712 status: "standard",
19713 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-snap-align"
19714 },
19715 "scroll-snap-coordinate": {
19716 syntax: "none | <position>#",
19717 media: "interactive",
19718 inherited: false,
19719 animationType: "position",
19720 percentages: "referToBorderBox",
19721 groups: [
19722 "CSS Scroll Snap"
19723 ],
19724 initial: "none",
19725 appliesto: "allElements",
19726 computed: "asSpecifiedRelativeToAbsoluteLengths",
19727 order: "uniqueOrder",
19728 status: "obsolete",
19729 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-snap-coordinate"
19730 },
19731 "scroll-snap-destination": {
19732 syntax: "<position>",
19733 media: "interactive",
19734 inherited: false,
19735 animationType: "position",
19736 percentages: "relativeToScrollContainerPaddingBoxAxis",
19737 groups: [
19738 "CSS Scroll Snap"
19739 ],
19740 initial: "0px 0px",
19741 appliesto: "scrollContainers",
19742 computed: "asSpecifiedRelativeToAbsoluteLengths",
19743 order: "uniqueOrder",
19744 status: "obsolete",
19745 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-snap-destination"
19746 },
19747 "scroll-snap-points-x": {
19748 syntax: "none | repeat( <length-percentage> )",
19749 media: "interactive",
19750 inherited: false,
19751 animationType: "discrete",
19752 percentages: "relativeToScrollContainerPaddingBoxAxis",
19753 groups: [
19754 "CSS Scroll Snap"
19755 ],
19756 initial: "none",
19757 appliesto: "scrollContainers",
19758 computed: "asSpecifiedRelativeToAbsoluteLengths",
19759 order: "uniqueOrder",
19760 status: "obsolete",
19761 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-snap-points-x"
19762 },
19763 "scroll-snap-points-y": {
19764 syntax: "none | repeat( <length-percentage> )",
19765 media: "interactive",
19766 inherited: false,
19767 animationType: "discrete",
19768 percentages: "relativeToScrollContainerPaddingBoxAxis",
19769 groups: [
19770 "CSS Scroll Snap"
19771 ],
19772 initial: "none",
19773 appliesto: "scrollContainers",
19774 computed: "asSpecifiedRelativeToAbsoluteLengths",
19775 order: "uniqueOrder",
19776 status: "obsolete",
19777 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-snap-points-y"
19778 },
19779 "scroll-snap-stop": {
19780 syntax: "normal | always",
19781 media: "visual",
19782 inherited: false,
19783 animationType: "discrete",
19784 percentages: "no",
19785 groups: [
19786 "CSS Scroll Snap"
19787 ],
19788 initial: "normal",
19789 appliesto: "allElements",
19790 computed: "asSpecified",
19791 order: "perGrammar",
19792 status: "standard",
19793 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-snap-stop"
19794 },
19795 "scroll-snap-type": {
19796 syntax: "none | [ x | y | block | inline | both ] [ mandatory | proximity ]?",
19797 media: "interactive",
19798 inherited: false,
19799 animationType: "discrete",
19800 percentages: "no",
19801 groups: [
19802 "CSS Scroll Snap"
19803 ],
19804 initial: "none",
19805 appliesto: "allElements",
19806 computed: "asSpecified",
19807 order: "uniqueOrder",
19808 status: "standard",
19809 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-snap-type"
19810 },
19811 "scroll-snap-type-x": {
19812 syntax: "none | mandatory | proximity",
19813 media: "interactive",
19814 inherited: false,
19815 animationType: "discrete",
19816 percentages: "no",
19817 groups: [
19818 "CSS Scroll Snap"
19819 ],
19820 initial: "none",
19821 appliesto: "scrollContainers",
19822 computed: "asSpecified",
19823 order: "uniqueOrder",
19824 status: "obsolete",
19825 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-snap-type-x"
19826 },
19827 "scroll-snap-type-y": {
19828 syntax: "none | mandatory | proximity",
19829 media: "interactive",
19830 inherited: false,
19831 animationType: "discrete",
19832 percentages: "no",
19833 groups: [
19834 "CSS Scroll Snap"
19835 ],
19836 initial: "none",
19837 appliesto: "scrollContainers",
19838 computed: "asSpecified",
19839 order: "uniqueOrder",
19840 status: "obsolete",
19841 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-snap-type-y"
19842 },
19843 "shape-image-threshold": {
19844 syntax: "<alpha-value>",
19845 media: "visual",
19846 inherited: false,
19847 animationType: "number",
19848 percentages: "no",
19849 groups: [
19850 "CSS Shapes"
19851 ],
19852 initial: "0.0",
19853 appliesto: "floats",
19854 computed: "specifiedValueNumberClipped0To1",
19855 order: "uniqueOrder",
19856 status: "standard",
19857 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/shape-image-threshold"
19858 },
19859 "shape-margin": {
19860 syntax: "<length-percentage>",
19861 media: "visual",
19862 inherited: false,
19863 animationType: "lpc",
19864 percentages: "referToWidthOfContainingBlock",
19865 groups: [
19866 "CSS Shapes"
19867 ],
19868 initial: "0",
19869 appliesto: "floats",
19870 computed: "asSpecifiedRelativeToAbsoluteLengths",
19871 order: "uniqueOrder",
19872 status: "standard",
19873 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/shape-margin"
19874 },
19875 "shape-outside": {
19876 syntax: "none | <shape-box> || <basic-shape> | <image>",
19877 media: "visual",
19878 inherited: false,
19879 animationType: "basicShapeOtherwiseNo",
19880 percentages: "no",
19881 groups: [
19882 "CSS Shapes"
19883 ],
19884 initial: "none",
19885 appliesto: "floats",
19886 computed: "asDefinedForBasicShapeWithAbsoluteURIOtherwiseAsSpecified",
19887 order: "uniqueOrder",
19888 status: "standard",
19889 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/shape-outside"
19890 },
19891 "tab-size": {
19892 syntax: "<integer> | <length>",
19893 media: "visual",
19894 inherited: true,
19895 animationType: "length",
19896 percentages: "no",
19897 groups: [
19898 "CSS Text"
19899 ],
19900 initial: "8",
19901 appliesto: "blockContainers",
19902 computed: "specifiedIntegerOrAbsoluteLength",
19903 order: "uniqueOrder",
19904 status: "standard",
19905 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/tab-size"
19906 },
19907 "table-layout": {
19908 syntax: "auto | fixed",
19909 media: "visual",
19910 inherited: false,
19911 animationType: "discrete",
19912 percentages: "no",
19913 groups: [
19914 "CSS Table"
19915 ],
19916 initial: "auto",
19917 appliesto: "tableElements",
19918 computed: "asSpecified",
19919 order: "uniqueOrder",
19920 status: "standard",
19921 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/table-layout"
19922 },
19923 "text-align": {
19924 syntax: "start | end | left | right | center | justify | match-parent",
19925 media: "visual",
19926 inherited: true,
19927 animationType: "discrete",
19928 percentages: "no",
19929 groups: [
19930 "CSS Text"
19931 ],
19932 initial: "startOrNamelessValueIfLTRRightIfRTL",
19933 appliesto: "blockContainers",
19934 computed: "asSpecifiedExceptMatchParent",
19935 order: "orderOfAppearance",
19936 alsoAppliesTo: [
19937 "::placeholder"
19938 ],
19939 status: "standard",
19940 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-align"
19941 },
19942 "text-align-last": {
19943 syntax: "auto | start | end | left | right | center | justify",
19944 media: "visual",
19945 inherited: true,
19946 animationType: "discrete",
19947 percentages: "no",
19948 groups: [
19949 "CSS Text"
19950 ],
19951 initial: "auto",
19952 appliesto: "blockContainers",
19953 computed: "asSpecified",
19954 order: "uniqueOrder",
19955 status: "standard",
19956 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-align-last"
19957 },
19958 "text-combine-upright": {
19959 syntax: "none | all | [ digits <integer>? ]",
19960 media: "visual",
19961 inherited: true,
19962 animationType: "discrete",
19963 percentages: "no",
19964 groups: [
19965 "CSS Writing Modes"
19966 ],
19967 initial: "none",
19968 appliesto: "nonReplacedInlineElements",
19969 computed: "keywordPlusIntegerIfDigits",
19970 order: "uniqueOrder",
19971 status: "standard",
19972 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-combine-upright"
19973 },
19974 "text-decoration": {
19975 syntax: "<'text-decoration-line'> || <'text-decoration-style'> || <'text-decoration-color'> || <'text-decoration-thickness'>",
19976 media: "visual",
19977 inherited: false,
19978 animationType: [
19979 "text-decoration-color",
19980 "text-decoration-style",
19981 "text-decoration-line",
19982 "text-decoration-thickness"
19983 ],
19984 percentages: "no",
19985 groups: [
19986 "CSS Text Decoration"
19987 ],
19988 initial: [
19989 "text-decoration-color",
19990 "text-decoration-style",
19991 "text-decoration-line"
19992 ],
19993 appliesto: "allElements",
19994 computed: [
19995 "text-decoration-line",
19996 "text-decoration-style",
19997 "text-decoration-color",
19998 "text-decoration-thickness"
19999 ],
20000 order: "orderOfAppearance",
20001 alsoAppliesTo: [
20002 "::first-letter",
20003 "::first-line",
20004 "::placeholder"
20005 ],
20006 status: "standard",
20007 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-decoration"
20008 },
20009 "text-decoration-color": {
20010 syntax: "<color>",
20011 media: "visual",
20012 inherited: false,
20013 animationType: "color",
20014 percentages: "no",
20015 groups: [
20016 "CSS Text Decoration"
20017 ],
20018 initial: "currentcolor",
20019 appliesto: "allElements",
20020 computed: "computedColor",
20021 order: "uniqueOrder",
20022 alsoAppliesTo: [
20023 "::first-letter",
20024 "::first-line",
20025 "::placeholder"
20026 ],
20027 status: "standard",
20028 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-decoration-color"
20029 },
20030 "text-decoration-line": {
20031 syntax: "none | [ underline || overline || line-through || blink ] | spelling-error | grammar-error",
20032 media: "visual",
20033 inherited: false,
20034 animationType: "discrete",
20035 percentages: "no",
20036 groups: [
20037 "CSS Text Decoration"
20038 ],
20039 initial: "none",
20040 appliesto: "allElements",
20041 computed: "asSpecified",
20042 order: "orderOfAppearance",
20043 alsoAppliesTo: [
20044 "::first-letter",
20045 "::first-line",
20046 "::placeholder"
20047 ],
20048 status: "standard",
20049 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-decoration-line"
20050 },
20051 "text-decoration-skip": {
20052 syntax: "none | [ objects || [ spaces | [ leading-spaces || trailing-spaces ] ] || edges || box-decoration ]",
20053 media: "visual",
20054 inherited: true,
20055 animationType: "discrete",
20056 percentages: "no",
20057 groups: [
20058 "CSS Text Decoration"
20059 ],
20060 initial: "objects",
20061 appliesto: "allElements",
20062 computed: "asSpecified",
20063 order: "orderOfAppearance",
20064 status: "experimental",
20065 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-decoration-skip"
20066 },
20067 "text-decoration-skip-ink": {
20068 syntax: "auto | none",
20069 media: "visual",
20070 inherited: true,
20071 animationType: "discrete",
20072 percentages: "no",
20073 groups: [
20074 "CSS Text Decoration"
20075 ],
20076 initial: "auto",
20077 appliesto: "allElements",
20078 computed: "asSpecified",
20079 order: "orderOfAppearance",
20080 status: "experimental",
20081 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-decoration-skip-ink"
20082 },
20083 "text-decoration-style": {
20084 syntax: "solid | double | dotted | dashed | wavy",
20085 media: "visual",
20086 inherited: false,
20087 animationType: "discrete",
20088 percentages: "no",
20089 groups: [
20090 "CSS Text Decoration"
20091 ],
20092 initial: "solid",
20093 appliesto: "allElements",
20094 computed: "asSpecified",
20095 order: "uniqueOrder",
20096 alsoAppliesTo: [
20097 "::first-letter",
20098 "::first-line",
20099 "::placeholder"
20100 ],
20101 status: "standard",
20102 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-decoration-style"
20103 },
20104 "text-decoration-thickness": {
20105 syntax: "auto | from-font | <length>",
20106 media: "visual",
20107 inherited: false,
20108 animationType: "byComputedValueType",
20109 percentages: "no",
20110 groups: [
20111 "CSS Text Decoration"
20112 ],
20113 initial: "auto",
20114 appliesto: "allElements",
20115 computed: "asSpecified",
20116 order: "uniqueOrder",
20117 alsoAppliesTo: [
20118 "::first-letter",
20119 "::first-line",
20120 "::placeholder"
20121 ],
20122 status: "standard",
20123 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-decoration-thickness"
20124 },
20125 "text-emphasis": {
20126 syntax: "<'text-emphasis-style'> || <'text-emphasis-color'>",
20127 media: "visual",
20128 inherited: false,
20129 animationType: [
20130 "text-emphasis-color",
20131 "text-emphasis-style"
20132 ],
20133 percentages: "no",
20134 groups: [
20135 "CSS Text Decoration"
20136 ],
20137 initial: [
20138 "text-emphasis-style",
20139 "text-emphasis-color"
20140 ],
20141 appliesto: "allElements",
20142 computed: [
20143 "text-emphasis-style",
20144 "text-emphasis-color"
20145 ],
20146 order: "orderOfAppearance",
20147 status: "standard",
20148 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-emphasis"
20149 },
20150 "text-emphasis-color": {
20151 syntax: "<color>",
20152 media: "visual",
20153 inherited: false,
20154 animationType: "color",
20155 percentages: "no",
20156 groups: [
20157 "CSS Text Decoration"
20158 ],
20159 initial: "currentcolor",
20160 appliesto: "allElements",
20161 computed: "computedColor",
20162 order: "uniqueOrder",
20163 status: "standard",
20164 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-emphasis-color"
20165 },
20166 "text-emphasis-position": {
20167 syntax: "[ over | under ] && [ right | left ]",
20168 media: "visual",
20169 inherited: false,
20170 animationType: "discrete",
20171 percentages: "no",
20172 groups: [
20173 "CSS Text Decoration"
20174 ],
20175 initial: "over right",
20176 appliesto: "allElements",
20177 computed: "asSpecified",
20178 order: "uniqueOrder",
20179 status: "standard",
20180 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-emphasis-position"
20181 },
20182 "text-emphasis-style": {
20183 syntax: "none | [ [ filled | open ] || [ dot | circle | double-circle | triangle | sesame ] ] | <string>",
20184 media: "visual",
20185 inherited: false,
20186 animationType: "discrete",
20187 percentages: "no",
20188 groups: [
20189 "CSS Text Decoration"
20190 ],
20191 initial: "none",
20192 appliesto: "allElements",
20193 computed: "asSpecified",
20194 order: "uniqueOrder",
20195 status: "standard",
20196 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-emphasis-style"
20197 },
20198 "text-indent": {
20199 syntax: "<length-percentage> && hanging? && each-line?",
20200 media: "visual",
20201 inherited: true,
20202 animationType: "lpc",
20203 percentages: "referToWidthOfContainingBlock",
20204 groups: [
20205 "CSS Text"
20206 ],
20207 initial: "0",
20208 appliesto: "blockContainers",
20209 computed: "percentageOrAbsoluteLengthPlusKeywords",
20210 order: "lengthOrPercentageBeforeKeywords",
20211 status: "standard",
20212 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-indent"
20213 },
20214 "text-justify": {
20215 syntax: "auto | inter-character | inter-word | none",
20216 media: "visual",
20217 inherited: true,
20218 animationType: "discrete",
20219 percentages: "no",
20220 groups: [
20221 "CSS Text"
20222 ],
20223 initial: "auto",
20224 appliesto: "inlineLevelAndTableCellElements",
20225 computed: "asSpecified",
20226 order: "uniqueOrder",
20227 status: "standard",
20228 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-justify"
20229 },
20230 "text-orientation": {
20231 syntax: "mixed | upright | sideways",
20232 media: "visual",
20233 inherited: true,
20234 animationType: "discrete",
20235 percentages: "no",
20236 groups: [
20237 "CSS Writing Modes"
20238 ],
20239 initial: "mixed",
20240 appliesto: "allElementsExceptTableRowGroupsRowsColumnGroupsAndColumns",
20241 computed: "asSpecified",
20242 order: "uniqueOrder",
20243 status: "standard",
20244 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-orientation"
20245 },
20246 "text-overflow": {
20247 syntax: "[ clip | ellipsis | <string> ]{1,2}",
20248 media: "visual",
20249 inherited: false,
20250 animationType: "discrete",
20251 percentages: "no",
20252 groups: [
20253 "CSS Basic User Interface"
20254 ],
20255 initial: "clip",
20256 appliesto: "blockContainerElements",
20257 computed: "asSpecified",
20258 order: "uniqueOrder",
20259 alsoAppliesTo: [
20260 "::placeholder"
20261 ],
20262 status: "standard",
20263 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-overflow"
20264 },
20265 "text-rendering": {
20266 syntax: "auto | optimizeSpeed | optimizeLegibility | geometricPrecision",
20267 media: "visual",
20268 inherited: true,
20269 animationType: "discrete",
20270 percentages: "no",
20271 groups: [
20272 "CSS Miscellaneous"
20273 ],
20274 initial: "auto",
20275 appliesto: "textElements",
20276 computed: "asSpecified",
20277 order: "uniqueOrder",
20278 status: "standard",
20279 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-rendering"
20280 },
20281 "text-shadow": {
20282 syntax: "none | <shadow-t>#",
20283 media: "visual",
20284 inherited: true,
20285 animationType: "shadowList",
20286 percentages: "no",
20287 groups: [
20288 "CSS Text Decoration"
20289 ],
20290 initial: "none",
20291 appliesto: "allElements",
20292 computed: "colorPlusThreeAbsoluteLengths",
20293 order: "uniqueOrder",
20294 alsoAppliesTo: [
20295 "::first-letter",
20296 "::first-line",
20297 "::placeholder"
20298 ],
20299 status: "standard",
20300 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-shadow"
20301 },
20302 "text-size-adjust": {
20303 syntax: "none | auto | <percentage>",
20304 media: "visual",
20305 inherited: true,
20306 animationType: "discrete",
20307 percentages: "referToSizeOfFont",
20308 groups: [
20309 "CSS Text"
20310 ],
20311 initial: "autoForSmartphoneBrowsersSupportingInflation",
20312 appliesto: "allElements",
20313 computed: "asSpecified",
20314 order: "uniqueOrder",
20315 status: "experimental",
20316 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-size-adjust"
20317 },
20318 "text-transform": {
20319 syntax: "none | capitalize | uppercase | lowercase | full-width | full-size-kana",
20320 media: "visual",
20321 inherited: true,
20322 animationType: "discrete",
20323 percentages: "no",
20324 groups: [
20325 "CSS Text"
20326 ],
20327 initial: "none",
20328 appliesto: "allElements",
20329 computed: "asSpecified",
20330 order: "uniqueOrder",
20331 alsoAppliesTo: [
20332 "::first-letter",
20333 "::first-line",
20334 "::placeholder"
20335 ],
20336 status: "standard",
20337 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-transform"
20338 },
20339 "text-underline-offset": {
20340 syntax: "auto | from-font | <length>",
20341 media: "visual",
20342 inherited: true,
20343 animationType: "byComputedValueType",
20344 percentages: "no",
20345 groups: [
20346 "CSS Text Decoration"
20347 ],
20348 initial: "auto",
20349 appliesto: "allElements",
20350 computed: "asSpecified",
20351 order: "uniqueOrder",
20352 alsoAppliesTo: [
20353 "::first-letter",
20354 "::first-line",
20355 "::placeholder"
20356 ],
20357 status: "standard",
20358 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-underline-offset"
20359 },
20360 "text-underline-position": {
20361 syntax: "auto | [ under || [ left | right ] ]",
20362 media: "visual",
20363 inherited: true,
20364 animationType: "discrete",
20365 percentages: "no",
20366 groups: [
20367 "CSS Text Decoration"
20368 ],
20369 initial: "auto",
20370 appliesto: "allElements",
20371 computed: "asSpecified",
20372 order: "orderOfAppearance",
20373 status: "standard",
20374 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-underline-position"
20375 },
20376 top: top,
20377 "touch-action": {
20378 syntax: "auto | none | [ [ pan-x | pan-left | pan-right ] || [ pan-y | pan-up | pan-down ] || pinch-zoom ] | manipulation",
20379 media: "visual",
20380 inherited: false,
20381 animationType: "discrete",
20382 percentages: "no",
20383 groups: [
20384 "Pointer Events"
20385 ],
20386 initial: "auto",
20387 appliesto: "allElementsExceptNonReplacedInlineElementsTableRowsColumnsRowColumnGroups",
20388 computed: "asSpecified",
20389 order: "uniqueOrder",
20390 status: "standard",
20391 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/touch-action"
20392 },
20393 transform: transform,
20394 "transform-box": {
20395 syntax: "border-box | fill-box | view-box",
20396 media: "visual",
20397 inherited: false,
20398 animationType: "discrete",
20399 percentages: "no",
20400 groups: [
20401 "CSS Transforms"
20402 ],
20403 initial: "border-box ",
20404 appliesto: "transformableElements",
20405 computed: "asSpecified",
20406 order: "uniqueOrder",
20407 status: "standard",
20408 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/transform-box"
20409 },
20410 "transform-origin": {
20411 syntax: "[ <length-percentage> | left | center | right | top | bottom ] | [ [ <length-percentage> | left | center | right ] && [ <length-percentage> | top | center | bottom ] ] <length>?",
20412 media: "visual",
20413 inherited: false,
20414 animationType: "simpleListOfLpc",
20415 percentages: "referToSizeOfBoundingBox",
20416 groups: [
20417 "CSS Transforms"
20418 ],
20419 initial: "50% 50% 0",
20420 appliesto: "transformableElements",
20421 computed: "forLengthAbsoluteValueOtherwisePercentage",
20422 order: "oneOrTwoValuesLengthAbsoluteKeywordsPercentages",
20423 status: "standard",
20424 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/transform-origin"
20425 },
20426 "transform-style": {
20427 syntax: "flat | preserve-3d",
20428 media: "visual",
20429 inherited: false,
20430 animationType: "discrete",
20431 percentages: "no",
20432 groups: [
20433 "CSS Transforms"
20434 ],
20435 initial: "flat",
20436 appliesto: "transformableElements",
20437 computed: "asSpecified",
20438 order: "uniqueOrder",
20439 stacking: true,
20440 status: "standard",
20441 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/transform-style"
20442 },
20443 transition: transition,
20444 "transition-delay": {
20445 syntax: "<time>#",
20446 media: "interactive",
20447 inherited: false,
20448 animationType: "discrete",
20449 percentages: "no",
20450 groups: [
20451 "CSS Transitions"
20452 ],
20453 initial: "0s",
20454 appliesto: "allElementsAndPseudos",
20455 computed: "asSpecified",
20456 order: "uniqueOrder",
20457 status: "standard",
20458 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/transition-delay"
20459 },
20460 "transition-duration": {
20461 syntax: "<time>#",
20462 media: "interactive",
20463 inherited: false,
20464 animationType: "discrete",
20465 percentages: "no",
20466 groups: [
20467 "CSS Transitions"
20468 ],
20469 initial: "0s",
20470 appliesto: "allElementsAndPseudos",
20471 computed: "asSpecified",
20472 order: "uniqueOrder",
20473 status: "standard",
20474 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/transition-duration"
20475 },
20476 "transition-property": {
20477 syntax: "none | <single-transition-property>#",
20478 media: "visual",
20479 inherited: false,
20480 animationType: "discrete",
20481 percentages: "no",
20482 groups: [
20483 "CSS Transitions"
20484 ],
20485 initial: "all",
20486 appliesto: "allElementsAndPseudos",
20487 computed: "asSpecified",
20488 order: "uniqueOrder",
20489 status: "standard",
20490 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/transition-property"
20491 },
20492 "transition-timing-function": {
20493 syntax: "<timing-function>#",
20494 media: "interactive",
20495 inherited: false,
20496 animationType: "discrete",
20497 percentages: "no",
20498 groups: [
20499 "CSS Transitions"
20500 ],
20501 initial: "ease",
20502 appliesto: "allElementsAndPseudos",
20503 computed: "asSpecified",
20504 order: "uniqueOrder",
20505 status: "standard",
20506 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/transition-timing-function"
20507 },
20508 translate: translate,
20509 "unicode-bidi": {
20510 syntax: "normal | embed | isolate | bidi-override | isolate-override | plaintext",
20511 media: "visual",
20512 inherited: false,
20513 animationType: "discrete",
20514 percentages: "no",
20515 groups: [
20516 "CSS Writing Modes"
20517 ],
20518 initial: "normal",
20519 appliesto: "allElementsSomeValuesNoEffectOnNonInlineElements",
20520 computed: "asSpecified",
20521 order: "uniqueOrder",
20522 status: "standard",
20523 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/unicode-bidi"
20524 },
20525 "user-select": {
20526 syntax: "auto | text | none | contain | all",
20527 media: "visual",
20528 inherited: false,
20529 animationType: "discrete",
20530 percentages: "no",
20531 groups: [
20532 "CSS Basic User Interface"
20533 ],
20534 initial: "auto",
20535 appliesto: "allElements",
20536 computed: "asSpecified",
20537 order: "uniqueOrder",
20538 status: "nonstandard",
20539 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/user-select"
20540 },
20541 "vertical-align": {
20542 syntax: "baseline | sub | super | text-top | text-bottom | middle | top | bottom | <percentage> | <length>",
20543 media: "visual",
20544 inherited: false,
20545 animationType: "length",
20546 percentages: "referToLineHeight",
20547 groups: [
20548 "CSS Table"
20549 ],
20550 initial: "baseline",
20551 appliesto: "inlineLevelAndTableCellElements",
20552 computed: "absoluteLengthOrKeyword",
20553 order: "uniqueOrder",
20554 alsoAppliesTo: [
20555 "::first-letter",
20556 "::first-line",
20557 "::placeholder"
20558 ],
20559 status: "standard",
20560 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/vertical-align"
20561 },
20562 visibility: visibility,
20563 "white-space": {
20564 syntax: "normal | pre | nowrap | pre-wrap | pre-line | break-spaces",
20565 media: "visual",
20566 inherited: true,
20567 animationType: "discrete",
20568 percentages: "no",
20569 groups: [
20570 "CSS Text"
20571 ],
20572 initial: "normal",
20573 appliesto: "allElements",
20574 computed: "asSpecified",
20575 order: "uniqueOrder",
20576 status: "standard",
20577 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/white-space"
20578 },
20579 widows: widows,
20580 width: width,
20581 "will-change": {
20582 syntax: "auto | <animateable-feature>#",
20583 media: "all",
20584 inherited: false,
20585 animationType: "discrete",
20586 percentages: "no",
20587 groups: [
20588 "CSS Will Change"
20589 ],
20590 initial: "auto",
20591 appliesto: "allElements",
20592 computed: "asSpecified",
20593 order: "uniqueOrder",
20594 status: "standard",
20595 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/will-change"
20596 },
20597 "word-break": {
20598 syntax: "normal | break-all | keep-all | break-word",
20599 media: "visual",
20600 inherited: true,
20601 animationType: "discrete",
20602 percentages: "no",
20603 groups: [
20604 "CSS Text"
20605 ],
20606 initial: "normal",
20607 appliesto: "allElements",
20608 computed: "asSpecified",
20609 order: "uniqueOrder",
20610 status: "standard",
20611 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/word-break"
20612 },
20613 "word-spacing": {
20614 syntax: "normal | <length-percentage>",
20615 media: "visual",
20616 inherited: true,
20617 animationType: "length",
20618 percentages: "referToWidthOfAffectedGlyph",
20619 groups: [
20620 "CSS Text"
20621 ],
20622 initial: "normal",
20623 appliesto: "allElements",
20624 computed: "optimumMinAndMaxValueOfAbsoluteLengthPercentageOrNormal",
20625 order: "uniqueOrder",
20626 alsoAppliesTo: [
20627 "::first-letter",
20628 "::first-line",
20629 "::placeholder"
20630 ],
20631 status: "standard",
20632 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/word-spacing"
20633 },
20634 "word-wrap": {
20635 syntax: "normal | break-word",
20636 media: "visual",
20637 inherited: true,
20638 animationType: "discrete",
20639 percentages: "no",
20640 groups: [
20641 "CSS Text"
20642 ],
20643 initial: "normal",
20644 appliesto: "nonReplacedInlineElements",
20645 computed: "asSpecified",
20646 order: "uniqueOrder",
20647 status: "standard",
20648 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/overflow-wrap"
20649 },
20650 "writing-mode": {
20651 syntax: "horizontal-tb | vertical-rl | vertical-lr | sideways-rl | sideways-lr",
20652 media: "visual",
20653 inherited: true,
20654 animationType: "discrete",
20655 percentages: "no",
20656 groups: [
20657 "CSS Writing Modes"
20658 ],
20659 initial: "horizontal-tb",
20660 appliesto: "allElementsExceptTableRowColumnGroupsTableRowsColumns",
20661 computed: "asSpecified",
20662 order: "uniqueOrder",
20663 status: "standard",
20664 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/writing-mode"
20665 },
20666 "z-index": {
20667 syntax: "auto | <integer>",
20668 media: "visual",
20669 inherited: false,
20670 animationType: "integer",
20671 percentages: "no",
20672 groups: [
20673 "CSS Positioning"
20674 ],
20675 initial: "auto",
20676 appliesto: "positionedElements",
20677 computed: "asSpecified",
20678 order: "uniqueOrder",
20679 stacking: true,
20680 status: "standard",
20681 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/z-index"
20682 },
20683 zoom: zoom
20684 };
20685
20686 var properties$2 = /*#__PURE__*/Object.freeze({
20687 __proto__: null,
20688 all: all,
20689 animation: animation,
20690 appearance: appearance,
20691 azimuth: azimuth,
20692 background: background,
20693 border: border,
20694 bottom: bottom,
20695 clear: clear,
20696 clip: clip,
20697 color: color,
20698 columns: columns,
20699 contain: contain,
20700 content: content,
20701 cursor: cursor,
20702 direction: direction,
20703 display: display,
20704 filter: filter,
20705 flex: flex,
20706 float: float,
20707 font: font,
20708 gap: gap,
20709 grid: grid,
20710 height: height,
20711 hyphens: hyphens,
20712 inset: inset,
20713 isolation: isolation,
20714 left: left,
20715 margin: margin,
20716 mask: mask,
20717 offset: offset,
20718 opacity: opacity,
20719 order: order,
20720 orphans: orphans,
20721 outline: outline,
20722 overflow: overflow,
20723 padding: padding,
20724 perspective: perspective,
20725 position: position,
20726 quotes: quotes,
20727 resize: resize,
20728 right: right,
20729 rotate: rotate,
20730 scale: scale,
20731 top: top,
20732 transform: transform,
20733 transition: transition,
20734 translate: translate,
20735 visibility: visibility,
20736 widows: widows,
20737 width: width,
20738 zoom: zoom,
20739 'default': properties$1
20740 });
20741
20742 var attachment = {
20743 syntax: "scroll | fixed | local"
20744 };
20745 var box = {
20746 syntax: "border-box | padding-box | content-box"
20747 };
20748 var color$1 = {
20749 syntax: "<rgb()> | <rgba()> | <hsl()> | <hsla()> | <hex-color> | <named-color> | currentcolor | <deprecated-system-color>"
20750 };
20751 var combinator = {
20752 syntax: "'>' | '+' | '~' | [ '||' ]"
20753 };
20754 var compat = {
20755 syntax: "searchfield | textarea | push-button | button-bevel | slider-horizontal | checkbox | radio | square-button | menulist | menulist-button | listbox | meter | progress-bar"
20756 };
20757 var gradient = {
20758 syntax: "<linear-gradient()> | <repeating-linear-gradient()> | <radial-gradient()> | <repeating-radial-gradient()> | <conic-gradient()>"
20759 };
20760 var hue = {
20761 syntax: "<number> | <angle>"
20762 };
20763 var image = {
20764 syntax: "<url> | <image()> | <image-set()> | <element()> | <paint()> | <cross-fade()> | <gradient>"
20765 };
20766 var nth = {
20767 syntax: "<an-plus-b> | even | odd"
20768 };
20769 var position$1 = {
20770 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> ] ]"
20771 };
20772 var quote = {
20773 syntax: "open-quote | close-quote | no-open-quote | no-close-quote"
20774 };
20775 var shadow = {
20776 syntax: "inset? && <length>{2,4} && <color>?"
20777 };
20778 var shape$1 = {
20779 syntax: "rect(<top>, <right>, <bottom>, <left>)"
20780 };
20781 var size = {
20782 syntax: "closest-side | farthest-side | closest-corner | farthest-corner | <length> | <length-percentage>{2}"
20783 };
20784 var symbol = {
20785 syntax: "<string> | <image> | <custom-ident>"
20786 };
20787 var target = {
20788 syntax: "<target-counter()> | <target-counters()> | <target-text()>"
20789 };
20790 var syntaxes = {
20791 "absolute-size": {
20792 syntax: "xx-small | x-small | small | medium | large | x-large | xx-large | xxx-large"
20793 },
20794 "alpha-value": {
20795 syntax: "<number> | <percentage>"
20796 },
20797 "angle-percentage": {
20798 syntax: "<angle> | <percentage>"
20799 },
20800 "angular-color-hint": {
20801 syntax: "<angle-percentage>"
20802 },
20803 "angular-color-stop": {
20804 syntax: "<color> && <color-stop-angle>?"
20805 },
20806 "angular-color-stop-list": {
20807 syntax: "[ <angular-color-stop> [, <angular-color-hint>]? ]# , <angular-color-stop>"
20808 },
20809 "animateable-feature": {
20810 syntax: "scroll-position | contents | <custom-ident>"
20811 },
20812 attachment: attachment,
20813 "attr()": {
20814 syntax: "attr( <attr-name> <type-or-unit>? [, <attr-fallback> ]? )"
20815 },
20816 "attr-matcher": {
20817 syntax: "[ '~' | '|' | '^' | '$' | '*' ]? '='"
20818 },
20819 "attr-modifier": {
20820 syntax: "i | s"
20821 },
20822 "attribute-selector": {
20823 syntax: "'[' <wq-name> ']' | '[' <wq-name> <attr-matcher> [ <string-token> | <ident-token> ] <attr-modifier>? ']'"
20824 },
20825 "auto-repeat": {
20826 syntax: "repeat( [ auto-fill | auto-fit ] , [ <line-names>? <fixed-size> ]+ <line-names>? )"
20827 },
20828 "auto-track-list": {
20829 syntax: "[ <line-names>? [ <fixed-size> | <fixed-repeat> ] ]* <line-names>? <auto-repeat>\n[ <line-names>? [ <fixed-size> | <fixed-repeat> ] ]* <line-names>?"
20830 },
20831 "baseline-position": {
20832 syntax: "[ first | last ]? baseline"
20833 },
20834 "basic-shape": {
20835 syntax: "<inset()> | <circle()> | <ellipse()> | <polygon()>"
20836 },
20837 "bg-image": {
20838 syntax: "none | <image>"
20839 },
20840 "bg-layer": {
20841 syntax: "<bg-image> || <bg-position> [ / <bg-size> ]? || <repeat-style> || <attachment> || <box> || <box>"
20842 },
20843 "bg-position": {
20844 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>? ] ]"
20845 },
20846 "bg-size": {
20847 syntax: "[ <length-percentage> | auto ]{1,2} | cover | contain"
20848 },
20849 "blur()": {
20850 syntax: "blur( <length> )"
20851 },
20852 "blend-mode": {
20853 syntax: "normal | multiply | screen | overlay | darken | lighten | color-dodge | color-burn | hard-light | soft-light | difference | exclusion | hue | saturation | color | luminosity"
20854 },
20855 box: box,
20856 "brightness()": {
20857 syntax: "brightness( <number-percentage> )"
20858 },
20859 "calc()": {
20860 syntax: "calc( <calc-sum> )"
20861 },
20862 "calc-sum": {
20863 syntax: "<calc-product> [ [ '+' | '-' ] <calc-product> ]*"
20864 },
20865 "calc-product": {
20866 syntax: "<calc-value> [ '*' <calc-value> | '/' <number> ]*"
20867 },
20868 "calc-value": {
20869 syntax: "<number> | <dimension> | <percentage> | ( <calc-sum> )"
20870 },
20871 "cf-final-image": {
20872 syntax: "<image> | <color>"
20873 },
20874 "cf-mixing-image": {
20875 syntax: "<percentage>? && <image>"
20876 },
20877 "circle()": {
20878 syntax: "circle( [ <shape-radius> ]? [ at <position> ]? )"
20879 },
20880 "clamp()": {
20881 syntax: "clamp( <calc-sum>#{3} )"
20882 },
20883 "class-selector": {
20884 syntax: "'.' <ident-token>"
20885 },
20886 "clip-source": {
20887 syntax: "<url>"
20888 },
20889 color: color$1,
20890 "color-stop": {
20891 syntax: "<color-stop-length> | <color-stop-angle>"
20892 },
20893 "color-stop-angle": {
20894 syntax: "<angle-percentage>{1,2}"
20895 },
20896 "color-stop-length": {
20897 syntax: "<length-percentage>{1,2}"
20898 },
20899 "color-stop-list": {
20900 syntax: "[ <linear-color-stop> [, <linear-color-hint>]? ]# , <linear-color-stop>"
20901 },
20902 combinator: combinator,
20903 "common-lig-values": {
20904 syntax: "[ common-ligatures | no-common-ligatures ]"
20905 },
20906 compat: compat,
20907 "composite-style": {
20908 syntax: "clear | copy | source-over | source-in | source-out | source-atop | destination-over | destination-in | destination-out | destination-atop | xor"
20909 },
20910 "compositing-operator": {
20911 syntax: "add | subtract | intersect | exclude"
20912 },
20913 "compound-selector": {
20914 syntax: "[ <type-selector>? <subclass-selector>* [ <pseudo-element-selector> <pseudo-class-selector>* ]* ]!"
20915 },
20916 "compound-selector-list": {
20917 syntax: "<compound-selector>#"
20918 },
20919 "complex-selector": {
20920 syntax: "<compound-selector> [ <combinator>? <compound-selector> ]*"
20921 },
20922 "complex-selector-list": {
20923 syntax: "<complex-selector>#"
20924 },
20925 "conic-gradient()": {
20926 syntax: "conic-gradient( [ from <angle> ]? [ at <position> ]?, <angular-color-stop-list> )"
20927 },
20928 "contextual-alt-values": {
20929 syntax: "[ contextual | no-contextual ]"
20930 },
20931 "content-distribution": {
20932 syntax: "space-between | space-around | space-evenly | stretch"
20933 },
20934 "content-list": {
20935 syntax: "[ <string> | contents | <image> | <quote> | <target> | <leader()> ]+"
20936 },
20937 "content-position": {
20938 syntax: "center | start | end | flex-start | flex-end"
20939 },
20940 "content-replacement": {
20941 syntax: "<image>"
20942 },
20943 "contrast()": {
20944 syntax: "contrast( [ <number-percentage> ] )"
20945 },
20946 "counter()": {
20947 syntax: "counter( <custom-ident>, <counter-style>? )"
20948 },
20949 "counter-style": {
20950 syntax: "<counter-style-name> | symbols()"
20951 },
20952 "counter-style-name": {
20953 syntax: "<custom-ident>"
20954 },
20955 "counters()": {
20956 syntax: "counters( <custom-ident>, <string>, <counter-style>? )"
20957 },
20958 "cross-fade()": {
20959 syntax: "cross-fade( <cf-mixing-image> , <cf-final-image>? )"
20960 },
20961 "cubic-bezier-timing-function": {
20962 syntax: "ease | ease-in | ease-out | ease-in-out | cubic-bezier(<number>, <number>, <number>, <number>)"
20963 },
20964 "deprecated-system-color": {
20965 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"
20966 },
20967 "discretionary-lig-values": {
20968 syntax: "[ discretionary-ligatures | no-discretionary-ligatures ]"
20969 },
20970 "display-box": {
20971 syntax: "contents | none"
20972 },
20973 "display-inside": {
20974 syntax: "flow | flow-root | table | flex | grid | ruby"
20975 },
20976 "display-internal": {
20977 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"
20978 },
20979 "display-legacy": {
20980 syntax: "inline-block | inline-list-item | inline-table | inline-flex | inline-grid"
20981 },
20982 "display-listitem": {
20983 syntax: "<display-outside>? && [ flow | flow-root ]? && list-item"
20984 },
20985 "display-outside": {
20986 syntax: "block | inline | run-in"
20987 },
20988 "drop-shadow()": {
20989 syntax: "drop-shadow( <length>{2,3} <color>? )"
20990 },
20991 "east-asian-variant-values": {
20992 syntax: "[ jis78 | jis83 | jis90 | jis04 | simplified | traditional ]"
20993 },
20994 "east-asian-width-values": {
20995 syntax: "[ full-width | proportional-width ]"
20996 },
20997 "element()": {
20998 syntax: "element( <id-selector> )"
20999 },
21000 "ellipse()": {
21001 syntax: "ellipse( [ <shape-radius>{2} ]? [ at <position> ]? )"
21002 },
21003 "ending-shape": {
21004 syntax: "circle | ellipse"
21005 },
21006 "env()": {
21007 syntax: "env( <custom-ident> , <declaration-value>? )"
21008 },
21009 "explicit-track-list": {
21010 syntax: "[ <line-names>? <track-size> ]+ <line-names>?"
21011 },
21012 "family-name": {
21013 syntax: "<string> | <custom-ident>+"
21014 },
21015 "feature-tag-value": {
21016 syntax: "<string> [ <integer> | on | off ]?"
21017 },
21018 "feature-type": {
21019 syntax: "@stylistic | @historical-forms | @styleset | @character-variant | @swash | @ornaments | @annotation"
21020 },
21021 "feature-value-block": {
21022 syntax: "<feature-type> '{' <feature-value-declaration-list> '}'"
21023 },
21024 "feature-value-block-list": {
21025 syntax: "<feature-value-block>+"
21026 },
21027 "feature-value-declaration": {
21028 syntax: "<custom-ident>: <integer>+;"
21029 },
21030 "feature-value-declaration-list": {
21031 syntax: "<feature-value-declaration>"
21032 },
21033 "feature-value-name": {
21034 syntax: "<custom-ident>"
21035 },
21036 "fill-rule": {
21037 syntax: "nonzero | evenodd"
21038 },
21039 "filter-function": {
21040 syntax: "<blur()> | <brightness()> | <contrast()> | <drop-shadow()> | <grayscale()> | <hue-rotate()> | <invert()> | <opacity()> | <saturate()> | <sepia()>"
21041 },
21042 "filter-function-list": {
21043 syntax: "[ <filter-function> | <url> ]+"
21044 },
21045 "final-bg-layer": {
21046 syntax: "<'background-color'> || <bg-image> || <bg-position> [ / <bg-size> ]? || <repeat-style> || <attachment> || <box> || <box>"
21047 },
21048 "fit-content()": {
21049 syntax: "fit-content( [ <length> | <percentage> ] )"
21050 },
21051 "fixed-breadth": {
21052 syntax: "<length-percentage>"
21053 },
21054 "fixed-repeat": {
21055 syntax: "repeat( [ <positive-integer> ] , [ <line-names>? <fixed-size> ]+ <line-names>? )"
21056 },
21057 "fixed-size": {
21058 syntax: "<fixed-breadth> | minmax( <fixed-breadth> , <track-breadth> ) | minmax( <inflexible-breadth> , <fixed-breadth> )"
21059 },
21060 "font-stretch-absolute": {
21061 syntax: "normal | ultra-condensed | extra-condensed | condensed | semi-condensed | semi-expanded | expanded | extra-expanded | ultra-expanded | <percentage>"
21062 },
21063 "font-variant-css21": {
21064 syntax: "[ normal | small-caps ]"
21065 },
21066 "font-weight-absolute": {
21067 syntax: "normal | bold | <number>"
21068 },
21069 "frequency-percentage": {
21070 syntax: "<frequency> | <percentage>"
21071 },
21072 "general-enclosed": {
21073 syntax: "[ <function-token> <any-value> ) ] | ( <ident> <any-value> )"
21074 },
21075 "generic-family": {
21076 syntax: "serif | sans-serif | cursive | fantasy | monospace"
21077 },
21078 "generic-name": {
21079 syntax: "serif | sans-serif | cursive | fantasy | monospace"
21080 },
21081 "geometry-box": {
21082 syntax: "<shape-box> | fill-box | stroke-box | view-box"
21083 },
21084 gradient: gradient,
21085 "grayscale()": {
21086 syntax: "grayscale( <number-percentage> )"
21087 },
21088 "grid-line": {
21089 syntax: "auto | <custom-ident> | [ <integer> && <custom-ident>? ] | [ span && [ <integer> || <custom-ident> ] ]"
21090 },
21091 "historical-lig-values": {
21092 syntax: "[ historical-ligatures | no-historical-ligatures ]"
21093 },
21094 "hsl()": {
21095 syntax: "hsl( <hue> <percentage> <percentage> [ / <alpha-value> ]? ) | hsl( <hue>, <percentage>, <percentage>, <alpha-value>? )"
21096 },
21097 "hsla()": {
21098 syntax: "hsla( <hue> <percentage> <percentage> [ / <alpha-value> ]? ) | hsla( <hue>, <percentage>, <percentage>, <alpha-value>? )"
21099 },
21100 hue: hue,
21101 "hue-rotate()": {
21102 syntax: "hue-rotate( <angle> )"
21103 },
21104 "id-selector": {
21105 syntax: "<hash-token>"
21106 },
21107 image: image,
21108 "image()": {
21109 syntax: "image( <image-tags>? [ <image-src>? , <color>? ]! )"
21110 },
21111 "image-set()": {
21112 syntax: "image-set( <image-set-option># )"
21113 },
21114 "image-set-option": {
21115 syntax: "[ <image> | <string> ] <resolution>"
21116 },
21117 "image-src": {
21118 syntax: "<url> | <string>"
21119 },
21120 "image-tags": {
21121 syntax: "ltr | rtl"
21122 },
21123 "inflexible-breadth": {
21124 syntax: "<length> | <percentage> | min-content | max-content | auto"
21125 },
21126 "inset()": {
21127 syntax: "inset( <length-percentage>{1,4} [ round <'border-radius'> ]? )"
21128 },
21129 "invert()": {
21130 syntax: "invert( <number-percentage> )"
21131 },
21132 "keyframes-name": {
21133 syntax: "<custom-ident> | <string>"
21134 },
21135 "keyframe-block": {
21136 syntax: "<keyframe-selector># {\n <declaration-list>\n}"
21137 },
21138 "keyframe-block-list": {
21139 syntax: "<keyframe-block>+"
21140 },
21141 "keyframe-selector": {
21142 syntax: "from | to | <percentage>"
21143 },
21144 "leader()": {
21145 syntax: "leader( <leader-type> )"
21146 },
21147 "leader-type": {
21148 syntax: "dotted | solid | space | <string>"
21149 },
21150 "length-percentage": {
21151 syntax: "<length> | <percentage>"
21152 },
21153 "line-names": {
21154 syntax: "'[' <custom-ident>* ']'"
21155 },
21156 "line-name-list": {
21157 syntax: "[ <line-names> | <name-repeat> ]+"
21158 },
21159 "line-style": {
21160 syntax: "none | hidden | dotted | dashed | solid | double | groove | ridge | inset | outset"
21161 },
21162 "line-width": {
21163 syntax: "<length> | thin | medium | thick"
21164 },
21165 "linear-color-hint": {
21166 syntax: "<length-percentage>"
21167 },
21168 "linear-color-stop": {
21169 syntax: "<color> <color-stop-length>?"
21170 },
21171 "linear-gradient()": {
21172 syntax: "linear-gradient( [ <angle> | to <side-or-corner> ]? , <color-stop-list> )"
21173 },
21174 "mask-layer": {
21175 syntax: "<mask-reference> || <position> [ / <bg-size> ]? || <repeat-style> || <geometry-box> || [ <geometry-box> | no-clip ] || <compositing-operator> || <masking-mode>"
21176 },
21177 "mask-position": {
21178 syntax: "[ <length-percentage> | left | center | right ] [ <length-percentage> | top | center | bottom ]?"
21179 },
21180 "mask-reference": {
21181 syntax: "none | <image> | <mask-source>"
21182 },
21183 "mask-source": {
21184 syntax: "<url>"
21185 },
21186 "masking-mode": {
21187 syntax: "alpha | luminance | match-source"
21188 },
21189 "matrix()": {
21190 syntax: "matrix( <number>#{6} )"
21191 },
21192 "matrix3d()": {
21193 syntax: "matrix3d( <number>#{16} )"
21194 },
21195 "max()": {
21196 syntax: "max( <calc-sum># )"
21197 },
21198 "media-and": {
21199 syntax: "<media-in-parens> [ and <media-in-parens> ]+"
21200 },
21201 "media-condition": {
21202 syntax: "<media-not> | <media-and> | <media-or> | <media-in-parens>"
21203 },
21204 "media-condition-without-or": {
21205 syntax: "<media-not> | <media-and> | <media-in-parens>"
21206 },
21207 "media-feature": {
21208 syntax: "( [ <mf-plain> | <mf-boolean> | <mf-range> ] )"
21209 },
21210 "media-in-parens": {
21211 syntax: "( <media-condition> ) | <media-feature> | <general-enclosed>"
21212 },
21213 "media-not": {
21214 syntax: "not <media-in-parens>"
21215 },
21216 "media-or": {
21217 syntax: "<media-in-parens> [ or <media-in-parens> ]+"
21218 },
21219 "media-query": {
21220 syntax: "<media-condition> | [ not | only ]? <media-type> [ and <media-condition-without-or> ]?"
21221 },
21222 "media-query-list": {
21223 syntax: "<media-query>#"
21224 },
21225 "media-type": {
21226 syntax: "<ident>"
21227 },
21228 "mf-boolean": {
21229 syntax: "<mf-name>"
21230 },
21231 "mf-name": {
21232 syntax: "<ident>"
21233 },
21234 "mf-plain": {
21235 syntax: "<mf-name> : <mf-value>"
21236 },
21237 "mf-range": {
21238 syntax: "<mf-name> [ '<' | '>' ]? '='? <mf-value>\n| <mf-value> [ '<' | '>' ]? '='? <mf-name>\n| <mf-value> '<' '='? <mf-name> '<' '='? <mf-value>\n| <mf-value> '>' '='? <mf-name> '>' '='? <mf-value>"
21239 },
21240 "mf-value": {
21241 syntax: "<number> | <dimension> | <ident> | <ratio>"
21242 },
21243 "min()": {
21244 syntax: "min( <calc-sum># )"
21245 },
21246 "minmax()": {
21247 syntax: "minmax( [ <length> | <percentage> | <flex> | min-content | max-content | auto ] , [ <length> | <percentage> | <flex> | min-content | max-content | auto ] )"
21248 },
21249 "named-color": {
21250 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"
21251 },
21252 "namespace-prefix": {
21253 syntax: "<ident>"
21254 },
21255 "ns-prefix": {
21256 syntax: "[ <ident-token> | '*' ]? '|'"
21257 },
21258 "number-percentage": {
21259 syntax: "<number> | <percentage>"
21260 },
21261 "numeric-figure-values": {
21262 syntax: "[ lining-nums | oldstyle-nums ]"
21263 },
21264 "numeric-fraction-values": {
21265 syntax: "[ diagonal-fractions | stacked-fractions ]"
21266 },
21267 "numeric-spacing-values": {
21268 syntax: "[ proportional-nums | tabular-nums ]"
21269 },
21270 nth: nth,
21271 "opacity()": {
21272 syntax: "opacity( [ <number-percentage> ] )"
21273 },
21274 "overflow-position": {
21275 syntax: "unsafe | safe"
21276 },
21277 "outline-radius": {
21278 syntax: "<length> | <percentage>"
21279 },
21280 "page-body": {
21281 syntax: "<declaration>? [ ; <page-body> ]? | <page-margin-box> <page-body>"
21282 },
21283 "page-margin-box": {
21284 syntax: "<page-margin-box-type> '{' <declaration-list> '}'"
21285 },
21286 "page-margin-box-type": {
21287 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"
21288 },
21289 "page-selector-list": {
21290 syntax: "[ <page-selector># ]?"
21291 },
21292 "page-selector": {
21293 syntax: "<pseudo-page>+ | <ident> <pseudo-page>*"
21294 },
21295 "paint()": {
21296 syntax: "paint( <ident>, <declaration-value>? )"
21297 },
21298 "perspective()": {
21299 syntax: "perspective( <length> )"
21300 },
21301 "polygon()": {
21302 syntax: "polygon( <fill-rule>? , [ <length-percentage> <length-percentage> ]# )"
21303 },
21304 position: position$1,
21305 "pseudo-class-selector": {
21306 syntax: "':' <ident-token> | ':' <function-token> <any-value> ')'"
21307 },
21308 "pseudo-element-selector": {
21309 syntax: "':' <pseudo-class-selector>"
21310 },
21311 "pseudo-page": {
21312 syntax: ": [ left | right | first | blank ]"
21313 },
21314 quote: quote,
21315 "radial-gradient()": {
21316 syntax: "radial-gradient( [ <ending-shape> || <size> ]? [ at <position> ]? , <color-stop-list> )"
21317 },
21318 "relative-selector": {
21319 syntax: "<combinator>? <complex-selector>"
21320 },
21321 "relative-selector-list": {
21322 syntax: "<relative-selector>#"
21323 },
21324 "relative-size": {
21325 syntax: "larger | smaller"
21326 },
21327 "repeat-style": {
21328 syntax: "repeat-x | repeat-y | [ repeat | space | round | no-repeat ]{1,2}"
21329 },
21330 "repeating-linear-gradient()": {
21331 syntax: "repeating-linear-gradient( [ <angle> | to <side-or-corner> ]? , <color-stop-list> )"
21332 },
21333 "repeating-radial-gradient()": {
21334 syntax: "repeating-radial-gradient( [ <ending-shape> || <size> ]? [ at <position> ]? , <color-stop-list> )"
21335 },
21336 "rgb()": {
21337 syntax: "rgb( <percentage>{3} [ / <alpha-value> ]? ) | rgb( <number>{3} [ / <alpha-value> ]? ) | rgb( <percentage>#{3} , <alpha-value>? ) | rgb( <number>#{3} , <alpha-value>? )"
21338 },
21339 "rgba()": {
21340 syntax: "rgba( <percentage>{3} [ / <alpha-value> ]? ) | rgba( <number>{3} [ / <alpha-value> ]? ) | rgba( <percentage>#{3} , <alpha-value>? ) | rgba( <number>#{3} , <alpha-value>? )"
21341 },
21342 "rotate()": {
21343 syntax: "rotate( [ <angle> | <zero> ] )"
21344 },
21345 "rotate3d()": {
21346 syntax: "rotate3d( <number> , <number> , <number> , [ <angle> | <zero> ] )"
21347 },
21348 "rotateX()": {
21349 syntax: "rotateX( [ <angle> | <zero> ] )"
21350 },
21351 "rotateY()": {
21352 syntax: "rotateY( [ <angle> | <zero> ] )"
21353 },
21354 "rotateZ()": {
21355 syntax: "rotateZ( [ <angle> | <zero> ] )"
21356 },
21357 "saturate()": {
21358 syntax: "saturate( <number-percentage> )"
21359 },
21360 "scale()": {
21361 syntax: "scale( <number> , <number>? )"
21362 },
21363 "scale3d()": {
21364 syntax: "scale3d( <number> , <number> , <number> )"
21365 },
21366 "scaleX()": {
21367 syntax: "scaleX( <number> )"
21368 },
21369 "scaleY()": {
21370 syntax: "scaleY( <number> )"
21371 },
21372 "scaleZ()": {
21373 syntax: "scaleZ( <number> )"
21374 },
21375 "self-position": {
21376 syntax: "center | start | end | self-start | self-end | flex-start | flex-end"
21377 },
21378 "shape-radius": {
21379 syntax: "<length-percentage> | closest-side | farthest-side"
21380 },
21381 "skew()": {
21382 syntax: "skew( [ <angle> | <zero> ] , [ <angle> | <zero> ]? )"
21383 },
21384 "skewX()": {
21385 syntax: "skewX( [ <angle> | <zero> ] )"
21386 },
21387 "skewY()": {
21388 syntax: "skewY( [ <angle> | <zero> ] )"
21389 },
21390 "sepia()": {
21391 syntax: "sepia( <number-percentage> )"
21392 },
21393 shadow: shadow,
21394 "shadow-t": {
21395 syntax: "[ <length>{2,3} && <color>? ]"
21396 },
21397 shape: shape$1,
21398 "shape-box": {
21399 syntax: "<box> | margin-box"
21400 },
21401 "side-or-corner": {
21402 syntax: "[ left | right ] || [ top | bottom ]"
21403 },
21404 "single-animation": {
21405 syntax: "<time> || <timing-function> || <time> || <single-animation-iteration-count> || <single-animation-direction> || <single-animation-fill-mode> || <single-animation-play-state> || [ none | <keyframes-name> ]"
21406 },
21407 "single-animation-direction": {
21408 syntax: "normal | reverse | alternate | alternate-reverse"
21409 },
21410 "single-animation-fill-mode": {
21411 syntax: "none | forwards | backwards | both"
21412 },
21413 "single-animation-iteration-count": {
21414 syntax: "infinite | <number>"
21415 },
21416 "single-animation-play-state": {
21417 syntax: "running | paused"
21418 },
21419 "single-transition": {
21420 syntax: "[ none | <single-transition-property> ] || <time> || <timing-function> || <time>"
21421 },
21422 "single-transition-property": {
21423 syntax: "all | <custom-ident>"
21424 },
21425 size: size,
21426 "step-position": {
21427 syntax: "jump-start | jump-end | jump-none | jump-both | start | end"
21428 },
21429 "step-timing-function": {
21430 syntax: "step-start | step-end | steps(<integer>[, <step-position>]?)"
21431 },
21432 "subclass-selector": {
21433 syntax: "<id-selector> | <class-selector> | <attribute-selector> | <pseudo-class-selector>"
21434 },
21435 "supports-condition": {
21436 syntax: "not <supports-in-parens> | <supports-in-parens> [ and <supports-in-parens> ]* | <supports-in-parens> [ or <supports-in-parens> ]*"
21437 },
21438 "supports-in-parens": {
21439 syntax: "( <supports-condition> ) | <supports-feature> | <general-enclosed>"
21440 },
21441 "supports-feature": {
21442 syntax: "<supports-decl> | <supports-selector-fn>"
21443 },
21444 "supports-decl": {
21445 syntax: "( <declaration> )"
21446 },
21447 "supports-selector-fn": {
21448 syntax: "selector( <complex-selector> )"
21449 },
21450 symbol: symbol,
21451 target: target,
21452 "target-counter()": {
21453 syntax: "target-counter( [ <string> | <url> ] , <custom-ident> , <counter-style>? )"
21454 },
21455 "target-counters()": {
21456 syntax: "target-counters( [ <string> | <url> ] , <custom-ident> , <string> , <counter-style>? )"
21457 },
21458 "target-text()": {
21459 syntax: "target-text( [ <string> | <url> ] , [ content | before | after | first-letter ]? )"
21460 },
21461 "time-percentage": {
21462 syntax: "<time> | <percentage>"
21463 },
21464 "timing-function": {
21465 syntax: "linear | <cubic-bezier-timing-function> | <step-timing-function>"
21466 },
21467 "track-breadth": {
21468 syntax: "<length-percentage> | <flex> | min-content | max-content | auto"
21469 },
21470 "track-list": {
21471 syntax: "[ <line-names>? [ <track-size> | <track-repeat> ] ]+ <line-names>?"
21472 },
21473 "track-repeat": {
21474 syntax: "repeat( [ <positive-integer> ] , [ <line-names>? <track-size> ]+ <line-names>? )"
21475 },
21476 "track-size": {
21477 syntax: "<track-breadth> | minmax( <inflexible-breadth> , <track-breadth> ) | fit-content( [ <length> | <percentage> ] )"
21478 },
21479 "transform-function": {
21480 syntax: "<matrix()> | <translate()> | <translateX()> | <translateY()> | <scale()> | <scaleX()> | <scaleY()> | <rotate()> | <skew()> | <skewX()> | <skewY()> | <matrix3d()> | <translate3d()> | <translateZ()> | <scale3d()> | <scaleZ()> | <rotate3d()> | <rotateX()> | <rotateY()> | <rotateZ()> | <perspective()>"
21481 },
21482 "transform-list": {
21483 syntax: "<transform-function>+"
21484 },
21485 "translate()": {
21486 syntax: "translate( <length-percentage> , <length-percentage>? )"
21487 },
21488 "translate3d()": {
21489 syntax: "translate3d( <length-percentage> , <length-percentage> , <length> )"
21490 },
21491 "translateX()": {
21492 syntax: "translateX( <length-percentage> )"
21493 },
21494 "translateY()": {
21495 syntax: "translateY( <length-percentage> )"
21496 },
21497 "translateZ()": {
21498 syntax: "translateZ( <length> )"
21499 },
21500 "type-or-unit": {
21501 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 | %"
21502 },
21503 "type-selector": {
21504 syntax: "<wq-name> | <ns-prefix>? '*'"
21505 },
21506 "var()": {
21507 syntax: "var( <custom-property-name> , <declaration-value>? )"
21508 },
21509 "viewport-length": {
21510 syntax: "auto | <length-percentage>"
21511 },
21512 "wq-name": {
21513 syntax: "<ns-prefix>? <ident-token>"
21514 }
21515 };
21516
21517 var syntaxes$1 = /*#__PURE__*/Object.freeze({
21518 __proto__: null,
21519 attachment: attachment,
21520 box: box,
21521 color: color$1,
21522 combinator: combinator,
21523 compat: compat,
21524 gradient: gradient,
21525 hue: hue,
21526 image: image,
21527 nth: nth,
21528 position: position$1,
21529 quote: quote,
21530 shadow: shadow,
21531 shape: shape$1,
21532 size: size,
21533 symbol: symbol,
21534 target: target,
21535 'default': syntaxes
21536 });
21537
21538 var properties$3 = {
21539 "-moz-background-clip": {
21540 comment: "deprecated syntax in old Firefox, https://developer.mozilla.org/en/docs/Web/CSS/background-clip",
21541 syntax: "padding | border"
21542 },
21543 "-moz-border-radius-bottomleft": {
21544 comment: "https://developer.mozilla.org/en-US/docs/Web/CSS/border-bottom-left-radius",
21545 syntax: "<'border-bottom-left-radius'>"
21546 },
21547 "-moz-border-radius-bottomright": {
21548 comment: "https://developer.mozilla.org/en-US/docs/Web/CSS/border-bottom-right-radius",
21549 syntax: "<'border-bottom-right-radius'>"
21550 },
21551 "-moz-border-radius-topleft": {
21552 comment: "https://developer.mozilla.org/en-US/docs/Web/CSS/border-top-left-radius",
21553 syntax: "<'border-top-left-radius'>"
21554 },
21555 "-moz-border-radius-topright": {
21556 comment: "https://developer.mozilla.org/en-US/docs/Web/CSS/border-bottom-right-radius",
21557 syntax: "<'border-bottom-right-radius'>"
21558 },
21559 "-moz-control-character-visibility": {
21560 comment: "firefox specific keywords, https://bugzilla.mozilla.org/show_bug.cgi?id=947588",
21561 syntax: "visible | hidden"
21562 },
21563 "-moz-osx-font-smoothing": {
21564 comment: "misssed old syntax https://developer.mozilla.org/en-US/docs/Web/CSS/font-smooth",
21565 syntax: "auto | grayscale"
21566 },
21567 "-moz-user-select": {
21568 comment: "https://developer.mozilla.org/en-US/docs/Web/CSS/user-select",
21569 syntax: "none | text | all | -moz-none"
21570 },
21571 "-ms-flex-align": {
21572 comment: "misssed old syntax implemented in IE, https://www.w3.org/TR/2012/WD-css3-flexbox-20120322/#flex-align",
21573 syntax: "start | end | center | baseline | stretch"
21574 },
21575 "-ms-flex-item-align": {
21576 comment: "misssed old syntax implemented in IE, https://www.w3.org/TR/2012/WD-css3-flexbox-20120322/#flex-align",
21577 syntax: "auto | start | end | center | baseline | stretch"
21578 },
21579 "-ms-flex-line-pack": {
21580 comment: "misssed old syntax implemented in IE, https://www.w3.org/TR/2012/WD-css3-flexbox-20120322/#flex-line-pack",
21581 syntax: "start | end | center | justify | distribute | stretch"
21582 },
21583 "-ms-flex-negative": {
21584 comment: "misssed old syntax implemented in IE; TODO: find references for comfirmation",
21585 syntax: "<'flex-shrink'>"
21586 },
21587 "-ms-flex-pack": {
21588 comment: "misssed old syntax implemented in IE, https://www.w3.org/TR/2012/WD-css3-flexbox-20120322/#flex-pack",
21589 syntax: "start | end | center | justify | distribute"
21590 },
21591 "-ms-flex-order": {
21592 comment: "misssed old syntax implemented in IE; https://msdn.microsoft.com/en-us/library/jj127303(v=vs.85).aspx",
21593 syntax: "<integer>"
21594 },
21595 "-ms-flex-positive": {
21596 comment: "misssed old syntax implemented in IE; TODO: find references for comfirmation",
21597 syntax: "<'flex-grow'>"
21598 },
21599 "-ms-flex-preferred-size": {
21600 comment: "misssed old syntax implemented in IE; TODO: find references for comfirmation",
21601 syntax: "<'flex-basis'>"
21602 },
21603 "-ms-interpolation-mode": {
21604 comment: "https://msdn.microsoft.com/en-us/library/ff521095(v=vs.85).aspx",
21605 syntax: "nearest-neighbor | bicubic"
21606 },
21607 "-ms-grid-column-align": {
21608 comment: "add this property first since it uses as fallback for flexbox, https://msdn.microsoft.com/en-us/library/windows/apps/hh466338.aspx",
21609 syntax: "start | end | center | stretch"
21610 },
21611 "-ms-grid-columns": {
21612 comment: "misssed old syntax implemented in IE; https://www.w3.org/TR/2012/WD-css3-grid-layout-20120322/#grid-columns",
21613 syntax: "<track-list-v0>"
21614 },
21615 "-ms-grid-row-align": {
21616 comment: "add this property first since it uses as fallback for flexbox, https://msdn.microsoft.com/en-us/library/windows/apps/hh466348.aspx",
21617 syntax: "start | end | center | stretch"
21618 },
21619 "-ms-grid-rows": {
21620 comment: "misssed old syntax implemented in IE; https://www.w3.org/TR/2012/WD-css3-grid-layout-20120322/#grid-rows",
21621 syntax: "<track-list-v0>"
21622 },
21623 "-ms-hyphenate-limit-last": {
21624 comment: "misssed old syntax implemented in IE; https://www.w3.org/TR/css-text-4/#hyphenate-line-limits",
21625 syntax: "none | always | column | page | spread"
21626 },
21627 "-webkit-appearance": {
21628 comment: "webkit specific keywords",
21629 references: [
21630 "http://css-infos.net/property/-webkit-appearance"
21631 ],
21632 syntax: "none | button | button-bevel | caps-lock-indicator | caret | checkbox | default-button | listbox | listitem | media-fullscreen-button | media-mute-button | media-play-button | media-seek-back-button | media-seek-forward-button | media-slider | media-sliderthumb | menulist | menulist-button | menulist-text | menulist-textfield | 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"
21633 },
21634 "-webkit-background-clip": {
21635 comment: "https://developer.mozilla.org/en/docs/Web/CSS/background-clip",
21636 syntax: "[ <box> | border | padding | content | text ]#"
21637 },
21638 "-webkit-column-break-after": {
21639 comment: "added, http://help.dottoro.com/lcrthhhv.php",
21640 syntax: "always | auto | avoid"
21641 },
21642 "-webkit-column-break-before": {
21643 comment: "added, http://help.dottoro.com/lcxquvkf.php",
21644 syntax: "always | auto | avoid"
21645 },
21646 "-webkit-column-break-inside": {
21647 comment: "added, http://help.dottoro.com/lclhnthl.php",
21648 syntax: "always | auto | avoid"
21649 },
21650 "-webkit-font-smoothing": {
21651 comment: "https://developer.mozilla.org/en-US/docs/Web/CSS/font-smooth",
21652 syntax: "auto | none | antialiased | subpixel-antialiased"
21653 },
21654 "-webkit-mask-box-image": {
21655 comment: "missed; https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-mask-box-image",
21656 syntax: "[ <url> | <gradient> | none ] [ <length-percentage>{4} <-webkit-mask-box-repeat>{2} ]?"
21657 },
21658 "-webkit-print-color-adjust": {
21659 comment: "missed",
21660 references: [
21661 "https://developer.mozilla.org/en/docs/Web/CSS/-webkit-print-color-adjust"
21662 ],
21663 syntax: "economy | exact"
21664 },
21665 "-webkit-text-security": {
21666 comment: "missed; http://help.dottoro.com/lcbkewgt.php",
21667 syntax: "none | circle | disc | square"
21668 },
21669 "-webkit-user-drag": {
21670 comment: "missed; http://help.dottoro.com/lcbixvwm.php",
21671 syntax: "none | element | auto"
21672 },
21673 "-webkit-user-select": {
21674 comment: "auto is supported by old webkit, https://developer.mozilla.org/en-US/docs/Web/CSS/user-select",
21675 syntax: "auto | none | text | all"
21676 },
21677 "alignment-baseline": {
21678 comment: "added SVG property",
21679 references: [
21680 "https://www.w3.org/TR/SVG/text.html#AlignmentBaselineProperty"
21681 ],
21682 syntax: "auto | baseline | before-edge | text-before-edge | middle | central | after-edge | text-after-edge | ideographic | alphabetic | hanging | mathematical"
21683 },
21684 "baseline-shift": {
21685 comment: "added SVG property",
21686 references: [
21687 "https://www.w3.org/TR/SVG/text.html#BaselineShiftProperty"
21688 ],
21689 syntax: "baseline | sub | super | <svg-length>"
21690 },
21691 behavior: {
21692 comment: "added old IE property https://msdn.microsoft.com/en-us/library/ms530723(v=vs.85).aspx",
21693 syntax: "<url>+"
21694 },
21695 "clip-rule": {
21696 comment: "added SVG property",
21697 references: [
21698 "https://www.w3.org/TR/SVG/masking.html#ClipRuleProperty"
21699 ],
21700 syntax: "nonzero | evenodd"
21701 },
21702 cue: {
21703 comment: "https://www.w3.org/TR/css3-speech/#property-index",
21704 syntax: "<'cue-before'> <'cue-after'>?"
21705 },
21706 "cue-after": {
21707 comment: "https://www.w3.org/TR/css3-speech/#property-index",
21708 syntax: "<url> <decibel>? | none"
21709 },
21710 "cue-before": {
21711 comment: "https://www.w3.org/TR/css3-speech/#property-index",
21712 syntax: "<url> <decibel>? | none"
21713 },
21714 cursor: {
21715 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",
21716 references: [
21717 "https://www.sitepoint.com/css3-cursor-styles/"
21718 ],
21719 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 ] ]"
21720 },
21721 display: {
21722 comment: "extended with -ms-flexbox",
21723 syntax: "block | contents | flex | flow | flow-root | grid | inline | inline-block | inline-flex | inline-grid | inline-list-item | inline-table | list-item | none | ruby | ruby-base | ruby-base-container | ruby-text | ruby-text-container | run-in | table | table-caption | table-cell | table-column | table-column-group | table-footer-group | table-header-group | table-row | table-row-group | -ms-flexbox | -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"
21724 },
21725 position: {
21726 comment: "extended with -webkit-sticky",
21727 syntax: "static | relative | absolute | sticky | fixed | -webkit-sticky"
21728 },
21729 "dominant-baseline": {
21730 comment: "added SVG property",
21731 references: [
21732 "https://www.w3.org/TR/SVG/text.html#DominantBaselineProperty"
21733 ],
21734 syntax: "auto | use-script | no-change | reset-size | ideographic | alphabetic | hanging | mathematical | central | middle | text-after-edge | text-before-edge"
21735 },
21736 "image-rendering": {
21737 comment: "extended with <-non-standard-image-rendering>, added SVG keywords optimizeSpeed and optimizeQuality",
21738 references: [
21739 "https://developer.mozilla.org/en/docs/Web/CSS/image-rendering",
21740 "https://www.w3.org/TR/SVG/painting.html#ImageRenderingProperty"
21741 ],
21742 syntax: "auto | crisp-edges | pixelated | optimizeSpeed | optimizeQuality | <-non-standard-image-rendering>"
21743 },
21744 fill: {
21745 comment: "added SVG property",
21746 references: [
21747 "https://www.w3.org/TR/SVG/painting.html#FillProperty"
21748 ],
21749 syntax: "<paint>"
21750 },
21751 "fill-opacity": {
21752 comment: "added SVG property",
21753 references: [
21754 "https://www.w3.org/TR/SVG/painting.html#FillProperty"
21755 ],
21756 syntax: "<number-zero-one>"
21757 },
21758 "fill-rule": {
21759 comment: "added SVG property",
21760 references: [
21761 "https://www.w3.org/TR/SVG/painting.html#FillProperty"
21762 ],
21763 syntax: "nonzero | evenodd"
21764 },
21765 filter: {
21766 comment: "extend with IE legacy syntaxes",
21767 syntax: "none | <filter-function-list> | <-ms-filter-function-list>"
21768 },
21769 "glyph-orientation-horizontal": {
21770 comment: "added SVG property",
21771 references: [
21772 "https://www.w3.org/TR/SVG/text.html#GlyphOrientationHorizontalProperty"
21773 ],
21774 syntax: "<angle>"
21775 },
21776 "glyph-orientation-vertical": {
21777 comment: "added SVG property",
21778 references: [
21779 "https://www.w3.org/TR/SVG/text.html#GlyphOrientationVerticalProperty"
21780 ],
21781 syntax: "<angle>"
21782 },
21783 kerning: {
21784 comment: "added SVG property",
21785 references: [
21786 "https://www.w3.org/TR/SVG/text.html#KerningProperty"
21787 ],
21788 syntax: "auto | <svg-length>"
21789 },
21790 "letter-spacing": {
21791 comment: "fix syntax <length> -> <length-percentage>",
21792 references: [
21793 "https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/letter-spacing"
21794 ],
21795 syntax: "normal | <length-percentage>"
21796 },
21797 marker: {
21798 comment: "added SVG property",
21799 references: [
21800 "https://www.w3.org/TR/SVG/painting.html#MarkerProperties"
21801 ],
21802 syntax: "none | <url>"
21803 },
21804 "marker-end": {
21805 comment: "added SVG property",
21806 references: [
21807 "https://www.w3.org/TR/SVG/painting.html#MarkerProperties"
21808 ],
21809 syntax: "none | <url>"
21810 },
21811 "marker-mid": {
21812 comment: "added SVG property",
21813 references: [
21814 "https://www.w3.org/TR/SVG/painting.html#MarkerProperties"
21815 ],
21816 syntax: "none | <url>"
21817 },
21818 "marker-start": {
21819 comment: "added SVG property",
21820 references: [
21821 "https://www.w3.org/TR/SVG/painting.html#MarkerProperties"
21822 ],
21823 syntax: "none | <url>"
21824 },
21825 "max-width": {
21826 comment: "extend by non-standard width keywords https://developer.mozilla.org/en-US/docs/Web/CSS/max-width",
21827 syntax: "<length> | <percentage> | none | max-content | min-content | fit-content | fill-available | <-non-standard-width>"
21828 },
21829 "min-width": {
21830 comment: "extend by non-standard width keywords https://developer.mozilla.org/en-US/docs/Web/CSS/width",
21831 syntax: "<length> | <percentage> | auto | max-content | min-content | fit-content | fill-available | <-non-standard-width>"
21832 },
21833 opacity: {
21834 comment: "strict to 0..1 <number> -> <number-zero-one>",
21835 syntax: "<number-zero-one>"
21836 },
21837 overflow: {
21838 comment: "extend by vendor keywords https://developer.mozilla.org/en-US/docs/Web/CSS/overflow",
21839 syntax: "[ visible | hidden | clip | scroll | auto ]{1,2} | <-non-standard-overflow>"
21840 },
21841 pause: {
21842 comment: "https://www.w3.org/TR/css3-speech/#property-index",
21843 syntax: "<'pause-before'> <'pause-after'>?"
21844 },
21845 "pause-after": {
21846 comment: "https://www.w3.org/TR/css3-speech/#property-index",
21847 syntax: "<time> | none | x-weak | weak | medium | strong | x-strong"
21848 },
21849 "pause-before": {
21850 comment: "https://www.w3.org/TR/css3-speech/#property-index",
21851 syntax: "<time> | none | x-weak | weak | medium | strong | x-strong"
21852 },
21853 rest: {
21854 comment: "https://www.w3.org/TR/css3-speech/#property-index",
21855 syntax: "<'rest-before'> <'rest-after'>?"
21856 },
21857 "rest-after": {
21858 comment: "https://www.w3.org/TR/css3-speech/#property-index",
21859 syntax: "<time> | none | x-weak | weak | medium | strong | x-strong"
21860 },
21861 "rest-before": {
21862 comment: "https://www.w3.org/TR/css3-speech/#property-index",
21863 syntax: "<time> | none | x-weak | weak | medium | strong | x-strong"
21864 },
21865 "shape-rendering": {
21866 comment: "added SVG property",
21867 references: [
21868 "https://www.w3.org/TR/SVG/painting.html#ShapeRenderingPropert"
21869 ],
21870 syntax: "auto | optimizeSpeed | crispEdges | geometricPrecision"
21871 },
21872 src: {
21873 comment: "added @font-face's src property https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/src",
21874 syntax: "[ <url> [ format( <string># ) ]? | local( <family-name> ) ]#"
21875 },
21876 speak: {
21877 comment: "https://www.w3.org/TR/css3-speech/#property-index",
21878 syntax: "auto | none | normal"
21879 },
21880 "speak-as": {
21881 comment: "https://www.w3.org/TR/css3-speech/#property-index",
21882 syntax: "normal | spell-out || digits || [ literal-punctuation | no-punctuation ]"
21883 },
21884 stroke: {
21885 comment: "added SVG property",
21886 references: [
21887 "https://www.w3.org/TR/SVG/painting.html#StrokeProperties"
21888 ],
21889 syntax: "<paint>"
21890 },
21891 "stroke-dasharray": {
21892 comment: "added SVG property; a list of comma and/or white space separated <length>s and <percentage>s",
21893 references: [
21894 "https://www.w3.org/TR/SVG/painting.html#StrokeProperties"
21895 ],
21896 syntax: "none | [ <svg-length>+ ]#"
21897 },
21898 "stroke-dashoffset": {
21899 comment: "added SVG property",
21900 references: [
21901 "https://www.w3.org/TR/SVG/painting.html#StrokeProperties"
21902 ],
21903 syntax: "<svg-length>"
21904 },
21905 "stroke-linecap": {
21906 comment: "added SVG property",
21907 references: [
21908 "https://www.w3.org/TR/SVG/painting.html#StrokeProperties"
21909 ],
21910 syntax: "butt | round | square"
21911 },
21912 "stroke-linejoin": {
21913 comment: "added SVG property",
21914 references: [
21915 "https://www.w3.org/TR/SVG/painting.html#StrokeProperties"
21916 ],
21917 syntax: "miter | round | bevel"
21918 },
21919 "stroke-miterlimit": {
21920 comment: "added SVG property (<miterlimit> = <number-one-or-greater>) ",
21921 references: [
21922 "https://www.w3.org/TR/SVG/painting.html#StrokeProperties"
21923 ],
21924 syntax: "<number-one-or-greater>"
21925 },
21926 "stroke-opacity": {
21927 comment: "added SVG property",
21928 references: [
21929 "https://www.w3.org/TR/SVG/painting.html#StrokeProperties"
21930 ],
21931 syntax: "<number-zero-one>"
21932 },
21933 "stroke-width": {
21934 comment: "added SVG property",
21935 references: [
21936 "https://www.w3.org/TR/SVG/painting.html#StrokeProperties"
21937 ],
21938 syntax: "<svg-length>"
21939 },
21940 "text-anchor": {
21941 comment: "added SVG property",
21942 references: [
21943 "https://www.w3.org/TR/SVG/text.html#TextAlignmentProperties"
21944 ],
21945 syntax: "start | middle | end"
21946 },
21947 "unicode-bidi": {
21948 comment: "added prefixed keywords https://developer.mozilla.org/en-US/docs/Web/CSS/unicode-bidi",
21949 syntax: "normal | embed | isolate | bidi-override | isolate-override | plaintext | -moz-isolate | -moz-isolate-override | -moz-plaintext | -webkit-isolate"
21950 },
21951 "unicode-range": {
21952 comment: "added missed property https://developer.mozilla.org/en-US/docs/Web/CSS/%40font-face/unicode-range",
21953 syntax: "<urange>#"
21954 },
21955 "voice-balance": {
21956 comment: "https://www.w3.org/TR/css3-speech/#property-index",
21957 syntax: "<number> | left | center | right | leftwards | rightwards"
21958 },
21959 "voice-duration": {
21960 comment: "https://www.w3.org/TR/css3-speech/#property-index",
21961 syntax: "auto | <time>"
21962 },
21963 "voice-family": {
21964 comment: "<name> -> <family-name>, https://www.w3.org/TR/css3-speech/#property-index",
21965 syntax: "[ [ <family-name> | <generic-voice> ] , ]* [ <family-name> | <generic-voice> ] | preserve"
21966 },
21967 "voice-pitch": {
21968 comment: "https://www.w3.org/TR/css3-speech/#property-index",
21969 syntax: "<frequency> && absolute | [ [ x-low | low | medium | high | x-high ] || [ <frequency> | <semitones> | <percentage> ] ]"
21970 },
21971 "voice-range": {
21972 comment: "https://www.w3.org/TR/css3-speech/#property-index",
21973 syntax: "<frequency> && absolute | [ [ x-low | low | medium | high | x-high ] || [ <frequency> | <semitones> | <percentage> ] ]"
21974 },
21975 "voice-rate": {
21976 comment: "https://www.w3.org/TR/css3-speech/#property-index",
21977 syntax: "[ normal | x-slow | slow | medium | fast | x-fast ] || <percentage>"
21978 },
21979 "voice-stress": {
21980 comment: "https://www.w3.org/TR/css3-speech/#property-index",
21981 syntax: "normal | strong | moderate | none | reduced"
21982 },
21983 "voice-volume": {
21984 comment: "https://www.w3.org/TR/css3-speech/#property-index",
21985 syntax: "silent | [ [ x-soft | soft | medium | loud | x-loud ] || <decibel> ]"
21986 },
21987 "writing-mode": {
21988 comment: "extend with SVG keywords",
21989 syntax: "horizontal-tb | vertical-rl | vertical-lr | sideways-rl | sideways-lr | <svg-writing-mode>"
21990 }
21991 };
21992 var syntaxes$2 = {
21993 "-legacy-gradient": {
21994 comment: "added collection of legacy gradient syntaxes",
21995 syntax: "<-webkit-gradient()> | <-legacy-linear-gradient> | <-legacy-repeating-linear-gradient> | <-legacy-radial-gradient> | <-legacy-repeating-radial-gradient>"
21996 },
21997 "-legacy-linear-gradient": {
21998 comment: "like standard syntax but w/o `to` keyword https://developer.mozilla.org/en-US/docs/Web/CSS/linear-gradient",
21999 syntax: "-moz-linear-gradient( <-legacy-linear-gradient-arguments> ) | -webkit-linear-gradient( <-legacy-linear-gradient-arguments> ) | -o-linear-gradient( <-legacy-linear-gradient-arguments> )"
22000 },
22001 "-legacy-repeating-linear-gradient": {
22002 comment: "like standard syntax but w/o `to` keyword https://developer.mozilla.org/en-US/docs/Web/CSS/linear-gradient",
22003 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> )"
22004 },
22005 "-legacy-linear-gradient-arguments": {
22006 comment: "like standard syntax but w/o `to` keyword https://developer.mozilla.org/en-US/docs/Web/CSS/linear-gradient",
22007 syntax: "[ <angle> | <side-or-corner> ]? , <color-stop-list>"
22008 },
22009 "-legacy-radial-gradient": {
22010 comment: "deprecated syntax that implemented by some browsers https://www.w3.org/TR/2011/WD-css3-images-20110908/#radial-gradients",
22011 syntax: "-moz-radial-gradient( <-legacy-radial-gradient-arguments> ) | -webkit-radial-gradient( <-legacy-radial-gradient-arguments> ) | -o-radial-gradient( <-legacy-radial-gradient-arguments> )"
22012 },
22013 "-legacy-repeating-radial-gradient": {
22014 comment: "deprecated syntax that implemented by some browsers https://www.w3.org/TR/2011/WD-css3-images-20110908/#radial-gradients",
22015 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> )"
22016 },
22017 "-legacy-radial-gradient-arguments": {
22018 comment: "deprecated syntax that implemented by some browsers https://www.w3.org/TR/2011/WD-css3-images-20110908/#radial-gradients",
22019 syntax: "[ <position> , ]? [ [ [ <-legacy-radial-gradient-shape> || <-legacy-radial-gradient-size> ] | [ <length> | <percentage> ]{2} ] , ]? <color-stop-list>"
22020 },
22021 "-legacy-radial-gradient-size": {
22022 comment: "before a standard it contains 2 extra keywords (`contain` and `cover`) https://www.w3.org/TR/2011/WD-css3-images-20110908/#ltsize",
22023 syntax: "closest-side | closest-corner | farthest-side | farthest-corner | contain | cover"
22024 },
22025 "-legacy-radial-gradient-shape": {
22026 comment: "define to double sure it doesn't extends in future https://www.w3.org/TR/2011/WD-css3-images-20110908/#ltshape",
22027 syntax: "circle | ellipse"
22028 },
22029 "-non-standard-font": {
22030 comment: "non standard fonts",
22031 references: [
22032 "https://webkit.org/blog/3709/using-the-system-font-in-web-content/"
22033 ],
22034 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"
22035 },
22036 "-non-standard-color": {
22037 comment: "non standard colors",
22038 references: [
22039 "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",
22040 "https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#Mozilla_Color_Preference_Extensions"
22041 ],
22042 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"
22043 },
22044 "-non-standard-image-rendering": {
22045 comment: "non-standard keywords http://phrogz.net/tmp/canvas_image_zoom.html",
22046 syntax: "optimize-contrast | -moz-crisp-edges | -o-crisp-edges | -webkit-optimize-contrast"
22047 },
22048 "-non-standard-overflow": {
22049 comment: "non-standard keywords https://developer.mozilla.org/en-US/docs/Web/CSS/overflow",
22050 syntax: "-moz-scrollbars-none | -moz-scrollbars-horizontal | -moz-scrollbars-vertical | -moz-hidden-unscrollable"
22051 },
22052 "-non-standard-width": {
22053 comment: "non-standard keywords https://developer.mozilla.org/en-US/docs/Web/CSS/width",
22054 syntax: "min-intrinsic | intrinsic | -moz-min-content | -moz-max-content | -webkit-min-content | -webkit-max-content"
22055 },
22056 "-webkit-gradient()": {
22057 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 )",
22058 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>]* )"
22059 },
22060 "-webkit-gradient-color-stop": {
22061 comment: "first Apple proposal gradient syntax https://webkit.org/blog/175/introducing-css-gradients/",
22062 syntax: "from( <color> ) | color-stop( [ <number-zero-one> | <percentage> ] , <color> ) | to( <color> )"
22063 },
22064 "-webkit-gradient-point": {
22065 comment: "first Apple proposal gradient syntax https://webkit.org/blog/175/introducing-css-gradients/",
22066 syntax: "[ left | center | right | <length-percentage> ] [ top | center | bottom | <length-percentage> ]"
22067 },
22068 "-webkit-gradient-radius": {
22069 comment: "first Apple proposal gradient syntax https://webkit.org/blog/175/introducing-css-gradients/",
22070 syntax: "<length> | <percentage>"
22071 },
22072 "-webkit-gradient-type": {
22073 comment: "first Apple proposal gradient syntax https://webkit.org/blog/175/introducing-css-gradients/",
22074 syntax: "linear | radial"
22075 },
22076 "-webkit-mask-box-repeat": {
22077 comment: "missed; https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-mask-box-image",
22078 syntax: "repeat | stretch | round"
22079 },
22080 "-webkit-mask-clip-style": {
22081 comment: "missed; there is no enough information about `-webkit-mask-clip` property, but looks like all those keywords are working",
22082 syntax: "border | border-box | padding | padding-box | content | content-box | text"
22083 },
22084 "-ms-filter-function-list": {
22085 comment: "https://developer.mozilla.org/en-US/docs/Web/CSS/-ms-filter",
22086 syntax: "<-ms-filter-function>+"
22087 },
22088 "-ms-filter-function": {
22089 comment: "https://developer.mozilla.org/en-US/docs/Web/CSS/-ms-filter",
22090 syntax: "<-ms-filter-function-progid> | <-ms-filter-function-legacy>"
22091 },
22092 "-ms-filter-function-progid": {
22093 comment: "https://developer.mozilla.org/en-US/docs/Web/CSS/-ms-filter",
22094 syntax: "'progid:' [ <ident-token> '.' ]* [ <ident-token> | <function-token> <any-value>? ) ]"
22095 },
22096 "-ms-filter-function-legacy": {
22097 comment: "https://developer.mozilla.org/en-US/docs/Web/CSS/-ms-filter",
22098 syntax: "<ident-token> | <function-token> <any-value>? )"
22099 },
22100 "-ms-filter": {
22101 syntax: "<string>"
22102 },
22103 age: {
22104 comment: "https://www.w3.org/TR/css3-speech/#voice-family",
22105 syntax: "child | young | old"
22106 },
22107 "attr-name": {
22108 syntax: "<wq-name>"
22109 },
22110 "attr-fallback": {
22111 syntax: "<any-value>"
22112 },
22113 "border-radius": {
22114 comment: "missed, https://drafts.csswg.org/css-backgrounds-3/#the-border-radius",
22115 syntax: "<length-percentage>{1,2}"
22116 },
22117 bottom: {
22118 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",
22119 syntax: "<length> | auto"
22120 },
22121 "content-list": {
22122 comment: "missed -> https://drafts.csswg.org/css-content/#typedef-content-list (document-url, <target> and leader() is omitted util stabilization)",
22123 syntax: "[ <string> | contents | <url> | <quote> | <attr()> | counter( <ident>, <'list-style-type'>? ) ]+"
22124 },
22125 "generic-voice": {
22126 comment: "https://www.w3.org/TR/css3-speech/#voice-family",
22127 syntax: "[ <age>? <gender> <integer>? ]"
22128 },
22129 gender: {
22130 comment: "https://www.w3.org/TR/css3-speech/#voice-family",
22131 syntax: "male | female | neutral"
22132 },
22133 "generic-family": {
22134 comment: "added -apple-system",
22135 references: [
22136 "https://webkit.org/blog/3709/using-the-system-font-in-web-content/"
22137 ],
22138 syntax: "serif | sans-serif | cursive | fantasy | monospace | -apple-system"
22139 },
22140 gradient: {
22141 comment: "added legacy syntaxes support",
22142 syntax: "<linear-gradient()> | <repeating-linear-gradient()> | <radial-gradient()> | <repeating-radial-gradient()> | <conic-gradient()> | <-legacy-gradient>"
22143 },
22144 left: {
22145 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",
22146 syntax: "<length> | auto"
22147 },
22148 "mask-image": {
22149 comment: "missed; https://drafts.fxtf.org/css-masking-1/#the-mask-image",
22150 syntax: "<mask-reference>#"
22151 },
22152 "name-repeat": {
22153 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",
22154 syntax: "repeat( [ <positive-integer> | auto-fill ], <line-names>+)"
22155 },
22156 "named-color": {
22157 comment: "added non standard color names",
22158 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 | <-non-standard-color>"
22159 },
22160 paint: {
22161 comment: "used by SVG https://www.w3.org/TR/SVG/painting.html#SpecifyingPaint",
22162 syntax: "none | <color> | <url> [ none | <color> ]? | context-fill | context-stroke"
22163 },
22164 "path()": {
22165 comment: "missed, `motion` property was renamed, but left it as is for now; path() syntax was get from last draft https://drafts.fxtf.org/motion-1/#funcdef-offset-path-path",
22166 syntax: "path( <string> )"
22167 },
22168 ratio: {
22169 comment: "missed, https://drafts.csswg.org/mediaqueries-4/#typedef-ratio",
22170 syntax: "<integer> / <integer>"
22171 },
22172 right: {
22173 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",
22174 syntax: "<length> | auto"
22175 },
22176 shape: {
22177 comment: "missed spaces in function body and add backwards compatible syntax",
22178 syntax: "rect( <top>, <right>, <bottom>, <left> ) | rect( <top> <right> <bottom> <left> )"
22179 },
22180 "svg-length": {
22181 comment: "All coordinates and lengths in SVG can be specified with or without a unit identifier",
22182 references: [
22183 "https://www.w3.org/TR/SVG11/coords.html#Units"
22184 ],
22185 syntax: "<percentage> | <length> | <number>"
22186 },
22187 "svg-writing-mode": {
22188 comment: "SVG specific keywords (deprecated for CSS)",
22189 references: [
22190 "https://developer.mozilla.org/en/docs/Web/CSS/writing-mode",
22191 "https://www.w3.org/TR/SVG/text.html#WritingModeProperty"
22192 ],
22193 syntax: "lr-tb | rl-tb | tb-rl | lr | rl | tb"
22194 },
22195 top: {
22196 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",
22197 syntax: "<length> | auto"
22198 },
22199 "track-group": {
22200 comment: "used by old grid-columns and grid-rows syntax v0",
22201 syntax: "'(' [ <string>* <track-minmax> <string>* ]+ ')' [ '[' <positive-integer> ']' ]? | <track-minmax>"
22202 },
22203 "track-list-v0": {
22204 comment: "used by old grid-columns and grid-rows syntax v0",
22205 syntax: "[ <string>* <track-group> <string>* ]+ | none"
22206 },
22207 "track-minmax": {
22208 comment: "used by old grid-columns and grid-rows syntax v0",
22209 syntax: "minmax( <track-breadth> , <track-breadth> ) | auto | <track-breadth> | fit-content"
22210 },
22211 x: {
22212 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",
22213 syntax: "<number>"
22214 },
22215 y: {
22216 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",
22217 syntax: "<number>"
22218 },
22219 declaration: {
22220 comment: "missed, restored by https://drafts.csswg.org/css-syntax",
22221 syntax: "<ident-token> : <declaration-value>? [ '!' important ]?"
22222 },
22223 "declaration-list": {
22224 comment: "missed, restored by https://drafts.csswg.org/css-syntax",
22225 syntax: "[ <declaration>? ';' ]* <declaration>?"
22226 },
22227 url: {
22228 comment: "https://drafts.csswg.org/css-values-4/#urls",
22229 syntax: "url( <string> <url-modifier>* ) | <url-token>"
22230 },
22231 "url-modifier": {
22232 comment: "https://drafts.csswg.org/css-values-4/#typedef-url-modifier",
22233 syntax: "<ident> | <function-token> <any-value> )"
22234 },
22235 "number-zero-one": {
22236 syntax: "<number [0,1]>"
22237 },
22238 "number-one-or-greater": {
22239 syntax: "<number [1,∞]>"
22240 },
22241 "positive-integer": {
22242 syntax: "<integer [0,∞]>"
22243 }
22244 };
22245 var patch = {
22246 properties: properties$3,
22247 syntaxes: syntaxes$2
22248 };
22249
22250 var patch$1 = /*#__PURE__*/Object.freeze({
22251 __proto__: null,
22252 properties: properties$3,
22253 syntaxes: syntaxes$2,
22254 'default': patch
22255 });
22256
22257 var mdnAtrules = getCjsExportFromNamespace(atRules$1);
22258
22259 var mdnProperties = getCjsExportFromNamespace(properties$2);
22260
22261 var mdnSyntaxes = getCjsExportFromNamespace(syntaxes$1);
22262
22263 var patch$2 = getCjsExportFromNamespace(patch$1);
22264
22265 function preprocessAtrules(dict) {
22266 var result = Object.create(null);
22267
22268 for (var atruleName in dict) {
22269 var atrule = dict[atruleName];
22270 var descriptors = null;
22271
22272 if (atrule.descriptors) {
22273 descriptors = Object.create(null);
22274
22275 for (var descriptor in atrule.descriptors) {
22276 descriptors[descriptor] = atrule.descriptors[descriptor].syntax;
22277 }
22278 }
22279
22280 result[atruleName.substr(1)] = {
22281 prelude: atrule.syntax.trim().match(/^@\S+\s+([^;\{]*)/)[1].trim() || null,
22282 descriptors
22283 };
22284 }
22285
22286 return result;
22287 }
22288
22289 function buildDictionary(dict, patchDict) {
22290 var result = {};
22291
22292 // copy all syntaxes for an original dict
22293 for (var key in dict) {
22294 result[key] = dict[key].syntax;
22295 }
22296
22297 // apply a patch
22298 for (var key in patchDict) {
22299 if (key in dict) {
22300 if (patchDict[key].syntax) {
22301 result[key] = patchDict[key].syntax;
22302 } else {
22303 delete result[key];
22304 }
22305 } else {
22306 if (patchDict[key].syntax) {
22307 result[key] = patchDict[key].syntax;
22308 }
22309 }
22310 }
22311
22312 return result;
22313 }
22314
22315 var data = {
22316 types: buildDictionary(mdnSyntaxes, patch$2.syntaxes),
22317 atrules: preprocessAtrules(mdnAtrules),
22318 properties: buildDictionary(mdnProperties, patch$2.properties)
22319 };
22320
22321 var cmpChar$3 = tokenizer.cmpChar;
22322 var isDigit$4 = tokenizer.isDigit;
22323 var TYPE$9 = tokenizer.TYPE;
22324
22325 var WHITESPACE$4 = TYPE$9.WhiteSpace;
22326 var COMMENT$3 = TYPE$9.Comment;
22327 var IDENT$3 = TYPE$9.Ident;
22328 var NUMBER$3 = TYPE$9.Number;
22329 var DIMENSION$2 = TYPE$9.Dimension;
22330 var PLUSSIGN$3 = 0x002B; // U+002B PLUS SIGN (+)
22331 var HYPHENMINUS$3 = 0x002D; // U+002D HYPHEN-MINUS (-)
22332 var N$4 = 0x006E; // U+006E LATIN SMALL LETTER N (n)
22333 var DISALLOW_SIGN$1 = true;
22334 var ALLOW_SIGN$1 = false;
22335
22336 function checkInteger$1(offset, disallowSign) {
22337 var pos = this.scanner.tokenStart + offset;
22338 var code = this.scanner.source.charCodeAt(pos);
22339
22340 if (code === PLUSSIGN$3 || code === HYPHENMINUS$3) {
22341 if (disallowSign) {
22342 this.error('Number sign is not allowed');
22343 }
22344 pos++;
22345 }
22346
22347 for (; pos < this.scanner.tokenEnd; pos++) {
22348 if (!isDigit$4(this.scanner.source.charCodeAt(pos))) {
22349 this.error('Integer is expected', pos);
22350 }
22351 }
22352 }
22353
22354 function checkTokenIsInteger(disallowSign) {
22355 return checkInteger$1.call(this, 0, disallowSign);
22356 }
22357
22358 function expectCharCode(offset, code) {
22359 if (!cmpChar$3(this.scanner.source, this.scanner.tokenStart + offset, code)) {
22360 var msg = '';
22361
22362 switch (code) {
22363 case N$4:
22364 msg = 'N is expected';
22365 break;
22366 case HYPHENMINUS$3:
22367 msg = 'HyphenMinus is expected';
22368 break;
22369 }
22370
22371 this.error(msg, this.scanner.tokenStart + offset);
22372 }
22373 }
22374
22375 // ... <signed-integer>
22376 // ... ['+' | '-'] <signless-integer>
22377 function consumeB$1() {
22378 var offset = 0;
22379 var sign = 0;
22380 var type = this.scanner.tokenType;
22381
22382 while (type === WHITESPACE$4 || type === COMMENT$3) {
22383 type = this.scanner.lookupType(++offset);
22384 }
22385
22386 if (type !== NUMBER$3) {
22387 if (this.scanner.isDelim(PLUSSIGN$3, offset) ||
22388 this.scanner.isDelim(HYPHENMINUS$3, offset)) {
22389 sign = this.scanner.isDelim(PLUSSIGN$3, offset) ? PLUSSIGN$3 : HYPHENMINUS$3;
22390
22391 do {
22392 type = this.scanner.lookupType(++offset);
22393 } while (type === WHITESPACE$4 || type === COMMENT$3);
22394
22395 if (type !== NUMBER$3) {
22396 this.scanner.skip(offset);
22397 checkTokenIsInteger.call(this, DISALLOW_SIGN$1);
22398 }
22399 } else {
22400 return null;
22401 }
22402 }
22403
22404 if (offset > 0) {
22405 this.scanner.skip(offset);
22406 }
22407
22408 if (sign === 0) {
22409 type = this.scanner.source.charCodeAt(this.scanner.tokenStart);
22410 if (type !== PLUSSIGN$3 && type !== HYPHENMINUS$3) {
22411 this.error('Number sign is expected');
22412 }
22413 }
22414
22415 checkTokenIsInteger.call(this, sign !== 0);
22416 return sign === HYPHENMINUS$3 ? '-' + this.consume(NUMBER$3) : this.consume(NUMBER$3);
22417 }
22418
22419 // An+B microsyntax https://www.w3.org/TR/css-syntax-3/#anb
22420 var AnPlusB = {
22421 name: 'AnPlusB',
22422 structure: {
22423 a: [String, null],
22424 b: [String, null]
22425 },
22426 parse: function() {
22427 /* eslint-disable brace-style*/
22428 var start = this.scanner.tokenStart;
22429 var a = null;
22430 var b = null;
22431
22432 // <integer>
22433 if (this.scanner.tokenType === NUMBER$3) {
22434 checkTokenIsInteger.call(this, ALLOW_SIGN$1);
22435 b = this.consume(NUMBER$3);
22436 }
22437
22438 // -n
22439 // -n <signed-integer>
22440 // -n ['+' | '-'] <signless-integer>
22441 // -n- <signless-integer>
22442 // <dashndashdigit-ident>
22443 else if (this.scanner.tokenType === IDENT$3 && cmpChar$3(this.scanner.source, this.scanner.tokenStart, HYPHENMINUS$3)) {
22444 a = '-1';
22445
22446 expectCharCode.call(this, 1, N$4);
22447
22448 switch (this.scanner.getTokenLength()) {
22449 // -n
22450 // -n <signed-integer>
22451 // -n ['+' | '-'] <signless-integer>
22452 case 2:
22453 this.scanner.next();
22454 b = consumeB$1.call(this);
22455 break;
22456
22457 // -n- <signless-integer>
22458 case 3:
22459 expectCharCode.call(this, 2, HYPHENMINUS$3);
22460
22461 this.scanner.next();
22462 this.scanner.skipSC();
22463
22464 checkTokenIsInteger.call(this, DISALLOW_SIGN$1);
22465
22466 b = '-' + this.consume(NUMBER$3);
22467 break;
22468
22469 // <dashndashdigit-ident>
22470 default:
22471 expectCharCode.call(this, 2, HYPHENMINUS$3);
22472 checkInteger$1.call(this, 3, DISALLOW_SIGN$1);
22473 this.scanner.next();
22474
22475 b = this.scanner.substrToCursor(start + 2);
22476 }
22477 }
22478
22479 // '+'? n
22480 // '+'? n <signed-integer>
22481 // '+'? n ['+' | '-'] <signless-integer>
22482 // '+'? n- <signless-integer>
22483 // '+'? <ndashdigit-ident>
22484 else if (this.scanner.tokenType === IDENT$3 || (this.scanner.isDelim(PLUSSIGN$3) && this.scanner.lookupType(1) === IDENT$3)) {
22485 var sign = 0;
22486 a = '1';
22487
22488 // just ignore a plus
22489 if (this.scanner.isDelim(PLUSSIGN$3)) {
22490 sign = 1;
22491 this.scanner.next();
22492 }
22493
22494 expectCharCode.call(this, 0, N$4);
22495
22496 switch (this.scanner.getTokenLength()) {
22497 // '+'? n
22498 // '+'? n <signed-integer>
22499 // '+'? n ['+' | '-'] <signless-integer>
22500 case 1:
22501 this.scanner.next();
22502 b = consumeB$1.call(this);
22503 break;
22504
22505 // '+'? n- <signless-integer>
22506 case 2:
22507 expectCharCode.call(this, 1, HYPHENMINUS$3);
22508
22509 this.scanner.next();
22510 this.scanner.skipSC();
22511
22512 checkTokenIsInteger.call(this, DISALLOW_SIGN$1);
22513
22514 b = '-' + this.consume(NUMBER$3);
22515 break;
22516
22517 // '+'? <ndashdigit-ident>
22518 default:
22519 expectCharCode.call(this, 1, HYPHENMINUS$3);
22520 checkInteger$1.call(this, 2, DISALLOW_SIGN$1);
22521 this.scanner.next();
22522
22523 b = this.scanner.substrToCursor(start + sign + 1);
22524 }
22525 }
22526
22527 // <ndashdigit-dimension>
22528 // <ndash-dimension> <signless-integer>
22529 // <n-dimension>
22530 // <n-dimension> <signed-integer>
22531 // <n-dimension> ['+' | '-'] <signless-integer>
22532 else if (this.scanner.tokenType === DIMENSION$2) {
22533 var code = this.scanner.source.charCodeAt(this.scanner.tokenStart);
22534 var sign = code === PLUSSIGN$3 || code === HYPHENMINUS$3;
22535
22536 for (var i = this.scanner.tokenStart + sign; i < this.scanner.tokenEnd; i++) {
22537 if (!isDigit$4(this.scanner.source.charCodeAt(i))) {
22538 break;
22539 }
22540 }
22541
22542 if (i === this.scanner.tokenStart + sign) {
22543 this.error('Integer is expected', this.scanner.tokenStart + sign);
22544 }
22545
22546 expectCharCode.call(this, i - this.scanner.tokenStart, N$4);
22547 a = this.scanner.source.substring(start, i);
22548
22549 // <n-dimension>
22550 // <n-dimension> <signed-integer>
22551 // <n-dimension> ['+' | '-'] <signless-integer>
22552 if (i + 1 === this.scanner.tokenEnd) {
22553 this.scanner.next();
22554 b = consumeB$1.call(this);
22555 } else {
22556 expectCharCode.call(this, i - this.scanner.tokenStart + 1, HYPHENMINUS$3);
22557
22558 // <ndash-dimension> <signless-integer>
22559 if (i + 2 === this.scanner.tokenEnd) {
22560 this.scanner.next();
22561 this.scanner.skipSC();
22562 checkTokenIsInteger.call(this, DISALLOW_SIGN$1);
22563 b = '-' + this.consume(NUMBER$3);
22564 }
22565 // <ndashdigit-dimension>
22566 else {
22567 checkInteger$1.call(this, i - this.scanner.tokenStart + 2, DISALLOW_SIGN$1);
22568 this.scanner.next();
22569 b = this.scanner.substrToCursor(i + 1);
22570 }
22571 }
22572 } else {
22573 this.error();
22574 }
22575
22576 if (a !== null && a.charCodeAt(0) === PLUSSIGN$3) {
22577 a = a.substr(1);
22578 }
22579
22580 if (b !== null && b.charCodeAt(0) === PLUSSIGN$3) {
22581 b = b.substr(1);
22582 }
22583
22584 return {
22585 type: 'AnPlusB',
22586 loc: this.getLocation(start, this.scanner.tokenStart),
22587 a: a,
22588 b: b
22589 };
22590 },
22591 generate: function(node) {
22592 var a = node.a !== null && node.a !== undefined;
22593 var b = node.b !== null && node.b !== undefined;
22594
22595 if (a) {
22596 this.chunk(
22597 node.a === '+1' ? '+n' : // eslint-disable-line operator-linebreak, indent
22598 node.a === '1' ? 'n' : // eslint-disable-line operator-linebreak, indent
22599 node.a === '-1' ? '-n' : // eslint-disable-line operator-linebreak, indent
22600 node.a + 'n' // eslint-disable-line operator-linebreak, indent
22601 );
22602
22603 if (b) {
22604 b = String(node.b);
22605 if (b.charAt(0) === '-' || b.charAt(0) === '+') {
22606 this.chunk(b.charAt(0));
22607 this.chunk(b.substr(1));
22608 } else {
22609 this.chunk('+');
22610 this.chunk(b);
22611 }
22612 }
22613 } else {
22614 this.chunk(String(node.b));
22615 }
22616 }
22617 };
22618
22619 var TYPE$a = tokenizer.TYPE;
22620
22621 var WhiteSpace = TYPE$a.WhiteSpace;
22622 var Semicolon = TYPE$a.Semicolon;
22623 var LeftCurlyBracket = TYPE$a.LeftCurlyBracket;
22624 var Delim = TYPE$a.Delim;
22625 var EXCLAMATIONMARK$1 = 0x0021; // U+0021 EXCLAMATION MARK (!)
22626
22627 function getOffsetExcludeWS() {
22628 if (this.scanner.tokenIndex > 0) {
22629 if (this.scanner.lookupType(-1) === WhiteSpace) {
22630 return this.scanner.tokenIndex > 1
22631 ? this.scanner.getTokenStart(this.scanner.tokenIndex - 1)
22632 : this.scanner.firstCharOffset;
22633 }
22634 }
22635
22636 return this.scanner.tokenStart;
22637 }
22638
22639 // 0, 0, false
22640 function balanceEnd() {
22641 return 0;
22642 }
22643
22644 // LEFTCURLYBRACKET, 0, false
22645 function leftCurlyBracket(tokenType) {
22646 return tokenType === LeftCurlyBracket ? 1 : 0;
22647 }
22648
22649 // LEFTCURLYBRACKET, SEMICOLON, false
22650 function leftCurlyBracketOrSemicolon(tokenType) {
22651 return tokenType === LeftCurlyBracket || tokenType === Semicolon ? 1 : 0;
22652 }
22653
22654 // EXCLAMATIONMARK, SEMICOLON, false
22655 function exclamationMarkOrSemicolon(tokenType, source, offset) {
22656 if (tokenType === Delim && source.charCodeAt(offset) === EXCLAMATIONMARK$1) {
22657 return 1;
22658 }
22659
22660 return tokenType === Semicolon ? 1 : 0;
22661 }
22662
22663 // 0, SEMICOLON, true
22664 function semicolonIncluded(tokenType) {
22665 return tokenType === Semicolon ? 2 : 0;
22666 }
22667
22668 var Raw = {
22669 name: 'Raw',
22670 structure: {
22671 value: String
22672 },
22673 parse: function(startToken, mode, excludeWhiteSpace) {
22674 var startOffset = this.scanner.getTokenStart(startToken);
22675 var endOffset;
22676
22677 this.scanner.skip(
22678 this.scanner.getRawLength(startToken, mode || balanceEnd)
22679 );
22680
22681 if (excludeWhiteSpace && this.scanner.tokenStart > startOffset) {
22682 endOffset = getOffsetExcludeWS.call(this);
22683 } else {
22684 endOffset = this.scanner.tokenStart;
22685 }
22686
22687 return {
22688 type: 'Raw',
22689 loc: this.getLocation(startOffset, endOffset),
22690 value: this.scanner.source.substring(startOffset, endOffset)
22691 };
22692 },
22693 generate: function(node) {
22694 this.chunk(node.value);
22695 },
22696
22697 mode: {
22698 default: balanceEnd,
22699 leftCurlyBracket: leftCurlyBracket,
22700 leftCurlyBracketOrSemicolon: leftCurlyBracketOrSemicolon,
22701 exclamationMarkOrSemicolon: exclamationMarkOrSemicolon,
22702 semicolonIncluded: semicolonIncluded
22703 }
22704 };
22705
22706 var TYPE$b = tokenizer.TYPE;
22707 var rawMode = Raw.mode;
22708
22709 var ATKEYWORD = TYPE$b.AtKeyword;
22710 var SEMICOLON = TYPE$b.Semicolon;
22711 var LEFTCURLYBRACKET$1 = TYPE$b.LeftCurlyBracket;
22712 var RIGHTCURLYBRACKET$1 = TYPE$b.RightCurlyBracket;
22713
22714 function consumeRaw(startToken) {
22715 return this.Raw(startToken, rawMode.leftCurlyBracketOrSemicolon, true);
22716 }
22717
22718 function isDeclarationBlockAtrule() {
22719 for (var offset = 1, type; type = this.scanner.lookupType(offset); offset++) {
22720 if (type === RIGHTCURLYBRACKET$1) {
22721 return true;
22722 }
22723
22724 if (type === LEFTCURLYBRACKET$1 ||
22725 type === ATKEYWORD) {
22726 return false;
22727 }
22728 }
22729
22730 return false;
22731 }
22732
22733 var Atrule = {
22734 name: 'Atrule',
22735 structure: {
22736 name: String,
22737 prelude: ['AtrulePrelude', 'Raw', null],
22738 block: ['Block', null]
22739 },
22740 parse: function() {
22741 var start = this.scanner.tokenStart;
22742 var name;
22743 var nameLowerCase;
22744 var prelude = null;
22745 var block = null;
22746
22747 this.eat(ATKEYWORD);
22748
22749 name = this.scanner.substrToCursor(start + 1);
22750 nameLowerCase = name.toLowerCase();
22751 this.scanner.skipSC();
22752
22753 // parse prelude
22754 if (this.scanner.eof === false &&
22755 this.scanner.tokenType !== LEFTCURLYBRACKET$1 &&
22756 this.scanner.tokenType !== SEMICOLON) {
22757 if (this.parseAtrulePrelude) {
22758 prelude = this.parseWithFallback(this.AtrulePrelude.bind(this, name), consumeRaw);
22759
22760 // turn empty AtrulePrelude into null
22761 if (prelude.type === 'AtrulePrelude' && prelude.children.head === null) {
22762 prelude = null;
22763 }
22764 } else {
22765 prelude = consumeRaw.call(this, this.scanner.tokenIndex);
22766 }
22767
22768 this.scanner.skipSC();
22769 }
22770
22771 switch (this.scanner.tokenType) {
22772 case SEMICOLON:
22773 this.scanner.next();
22774 break;
22775
22776 case LEFTCURLYBRACKET$1:
22777 if (this.atrule.hasOwnProperty(nameLowerCase) &&
22778 typeof this.atrule[nameLowerCase].block === 'function') {
22779 block = this.atrule[nameLowerCase].block.call(this);
22780 } else {
22781 // TODO: should consume block content as Raw?
22782 block = this.Block(isDeclarationBlockAtrule.call(this));
22783 }
22784
22785 break;
22786 }
22787
22788 return {
22789 type: 'Atrule',
22790 loc: this.getLocation(start, this.scanner.tokenStart),
22791 name: name,
22792 prelude: prelude,
22793 block: block
22794 };
22795 },
22796 generate: function(node) {
22797 this.chunk('@');
22798 this.chunk(node.name);
22799
22800 if (node.prelude !== null) {
22801 this.chunk(' ');
22802 this.node(node.prelude);
22803 }
22804
22805 if (node.block) {
22806 this.node(node.block);
22807 } else {
22808 this.chunk(';');
22809 }
22810 },
22811 walkContext: 'atrule'
22812 };
22813
22814 var TYPE$c = tokenizer.TYPE;
22815
22816 var SEMICOLON$1 = TYPE$c.Semicolon;
22817 var LEFTCURLYBRACKET$2 = TYPE$c.LeftCurlyBracket;
22818
22819 var AtrulePrelude = {
22820 name: 'AtrulePrelude',
22821 structure: {
22822 children: [[]]
22823 },
22824 parse: function(name) {
22825 var children = null;
22826
22827 if (name !== null) {
22828 name = name.toLowerCase();
22829 }
22830
22831 this.scanner.skipSC();
22832
22833 if (this.atrule.hasOwnProperty(name) &&
22834 typeof this.atrule[name].prelude === 'function') {
22835 // custom consumer
22836 children = this.atrule[name].prelude.call(this);
22837 } else {
22838 // default consumer
22839 children = this.readSequence(this.scope.AtrulePrelude);
22840 }
22841
22842 this.scanner.skipSC();
22843
22844 if (this.scanner.eof !== true &&
22845 this.scanner.tokenType !== LEFTCURLYBRACKET$2 &&
22846 this.scanner.tokenType !== SEMICOLON$1) {
22847 this.error('Semicolon or block is expected');
22848 }
22849
22850 if (children === null) {
22851 children = this.createList();
22852 }
22853
22854 return {
22855 type: 'AtrulePrelude',
22856 loc: this.getLocationFromList(children),
22857 children: children
22858 };
22859 },
22860 generate: function(node) {
22861 this.children(node);
22862 },
22863 walkContext: 'atrulePrelude'
22864 };
22865
22866 var TYPE$d = tokenizer.TYPE;
22867
22868 var IDENT$4 = TYPE$d.Ident;
22869 var STRING = TYPE$d.String;
22870 var COLON = TYPE$d.Colon;
22871 var LEFTSQUAREBRACKET$1 = TYPE$d.LeftSquareBracket;
22872 var RIGHTSQUAREBRACKET$1 = TYPE$d.RightSquareBracket;
22873 var DOLLARSIGN = 0x0024; // U+0024 DOLLAR SIGN ($)
22874 var ASTERISK$1 = 0x002A; // U+002A ASTERISK (*)
22875 var EQUALSSIGN = 0x003D; // U+003D EQUALS SIGN (=)
22876 var CIRCUMFLEXACCENT = 0x005E; // U+005E (^)
22877 var VERTICALLINE$1 = 0x007C; // U+007C VERTICAL LINE (|)
22878 var TILDE = 0x007E; // U+007E TILDE (~)
22879
22880 function getAttributeName() {
22881 if (this.scanner.eof) {
22882 this.error('Unexpected end of input');
22883 }
22884
22885 var start = this.scanner.tokenStart;
22886 var expectIdent = false;
22887 var checkColon = true;
22888
22889 if (this.scanner.isDelim(ASTERISK$1)) {
22890 expectIdent = true;
22891 checkColon = false;
22892 this.scanner.next();
22893 } else if (!this.scanner.isDelim(VERTICALLINE$1)) {
22894 this.eat(IDENT$4);
22895 }
22896
22897 if (this.scanner.isDelim(VERTICALLINE$1)) {
22898 if (this.scanner.source.charCodeAt(this.scanner.tokenStart + 1) !== EQUALSSIGN) {
22899 this.scanner.next();
22900 this.eat(IDENT$4);
22901 } else if (expectIdent) {
22902 this.error('Identifier is expected', this.scanner.tokenEnd);
22903 }
22904 } else if (expectIdent) {
22905 this.error('Vertical line is expected');
22906 }
22907
22908 if (checkColon && this.scanner.tokenType === COLON) {
22909 this.scanner.next();
22910 this.eat(IDENT$4);
22911 }
22912
22913 return {
22914 type: 'Identifier',
22915 loc: this.getLocation(start, this.scanner.tokenStart),
22916 name: this.scanner.substrToCursor(start)
22917 };
22918 }
22919
22920 function getOperator() {
22921 var start = this.scanner.tokenStart;
22922 var code = this.scanner.source.charCodeAt(start);
22923
22924 if (code !== EQUALSSIGN && // =
22925 code !== TILDE && // ~=
22926 code !== CIRCUMFLEXACCENT && // ^=
22927 code !== DOLLARSIGN && // $=
22928 code !== ASTERISK$1 && // *=
22929 code !== VERTICALLINE$1 // |=
22930 ) {
22931 this.error('Attribute selector (=, ~=, ^=, $=, *=, |=) is expected');
22932 }
22933
22934 this.scanner.next();
22935
22936 if (code !== EQUALSSIGN) {
22937 if (!this.scanner.isDelim(EQUALSSIGN)) {
22938 this.error('Equal sign is expected');
22939 }
22940
22941 this.scanner.next();
22942 }
22943
22944 return this.scanner.substrToCursor(start);
22945 }
22946
22947 // '[' <wq-name> ']'
22948 // '[' <wq-name> <attr-matcher> [ <string-token> | <ident-token> ] <attr-modifier>? ']'
22949 var AttributeSelector = {
22950 name: 'AttributeSelector',
22951 structure: {
22952 name: 'Identifier',
22953 matcher: [String, null],
22954 value: ['String', 'Identifier', null],
22955 flags: [String, null]
22956 },
22957 parse: function() {
22958 var start = this.scanner.tokenStart;
22959 var name;
22960 var matcher = null;
22961 var value = null;
22962 var flags = null;
22963
22964 this.eat(LEFTSQUAREBRACKET$1);
22965 this.scanner.skipSC();
22966
22967 name = getAttributeName.call(this);
22968 this.scanner.skipSC();
22969
22970 if (this.scanner.tokenType !== RIGHTSQUAREBRACKET$1) {
22971 // avoid case `[name i]`
22972 if (this.scanner.tokenType !== IDENT$4) {
22973 matcher = getOperator.call(this);
22974
22975 this.scanner.skipSC();
22976
22977 value = this.scanner.tokenType === STRING
22978 ? this.String()
22979 : this.Identifier();
22980
22981 this.scanner.skipSC();
22982 }
22983
22984 // attribute flags
22985 if (this.scanner.tokenType === IDENT$4) {
22986 flags = this.scanner.getTokenValue();
22987 this.scanner.next();
22988
22989 this.scanner.skipSC();
22990 }
22991 }
22992
22993 this.eat(RIGHTSQUAREBRACKET$1);
22994
22995 return {
22996 type: 'AttributeSelector',
22997 loc: this.getLocation(start, this.scanner.tokenStart),
22998 name: name,
22999 matcher: matcher,
23000 value: value,
23001 flags: flags
23002 };
23003 },
23004 generate: function(node) {
23005 var flagsPrefix = ' ';
23006
23007 this.chunk('[');
23008 this.node(node.name);
23009
23010 if (node.matcher !== null) {
23011 this.chunk(node.matcher);
23012
23013 if (node.value !== null) {
23014 this.node(node.value);
23015
23016 // space between string and flags is not required
23017 if (node.value.type === 'String') {
23018 flagsPrefix = '';
23019 }
23020 }
23021 }
23022
23023 if (node.flags !== null) {
23024 this.chunk(flagsPrefix);
23025 this.chunk(node.flags);
23026 }
23027
23028 this.chunk(']');
23029 }
23030 };
23031
23032 var TYPE$e = tokenizer.TYPE;
23033 var rawMode$1 = Raw.mode;
23034
23035 var WHITESPACE$5 = TYPE$e.WhiteSpace;
23036 var COMMENT$4 = TYPE$e.Comment;
23037 var SEMICOLON$2 = TYPE$e.Semicolon;
23038 var ATKEYWORD$1 = TYPE$e.AtKeyword;
23039 var LEFTCURLYBRACKET$3 = TYPE$e.LeftCurlyBracket;
23040 var RIGHTCURLYBRACKET$2 = TYPE$e.RightCurlyBracket;
23041
23042 function consumeRaw$1(startToken) {
23043 return this.Raw(startToken, null, true);
23044 }
23045 function consumeRule() {
23046 return this.parseWithFallback(this.Rule, consumeRaw$1);
23047 }
23048 function consumeRawDeclaration(startToken) {
23049 return this.Raw(startToken, rawMode$1.semicolonIncluded, true);
23050 }
23051 function consumeDeclaration() {
23052 if (this.scanner.tokenType === SEMICOLON$2) {
23053 return consumeRawDeclaration.call(this, this.scanner.tokenIndex);
23054 }
23055
23056 var node = this.parseWithFallback(this.Declaration, consumeRawDeclaration);
23057
23058 if (this.scanner.tokenType === SEMICOLON$2) {
23059 this.scanner.next();
23060 }
23061
23062 return node;
23063 }
23064
23065 var Block = {
23066 name: 'Block',
23067 structure: {
23068 children: [[
23069 'Atrule',
23070 'Rule',
23071 'Declaration'
23072 ]]
23073 },
23074 parse: function(isDeclaration) {
23075 var consumer = isDeclaration ? consumeDeclaration : consumeRule;
23076
23077 var start = this.scanner.tokenStart;
23078 var children = this.createList();
23079
23080 this.eat(LEFTCURLYBRACKET$3);
23081
23082 scan:
23083 while (!this.scanner.eof) {
23084 switch (this.scanner.tokenType) {
23085 case RIGHTCURLYBRACKET$2:
23086 break scan;
23087
23088 case WHITESPACE$5:
23089 case COMMENT$4:
23090 this.scanner.next();
23091 break;
23092
23093 case ATKEYWORD$1:
23094 children.push(this.parseWithFallback(this.Atrule, consumeRaw$1));
23095 break;
23096
23097 default:
23098 children.push(consumer.call(this));
23099 }
23100 }
23101
23102 if (!this.scanner.eof) {
23103 this.eat(RIGHTCURLYBRACKET$2);
23104 }
23105
23106 return {
23107 type: 'Block',
23108 loc: this.getLocation(start, this.scanner.tokenStart),
23109 children: children
23110 };
23111 },
23112 generate: function(node) {
23113 this.chunk('{');
23114 this.children(node, function(prev) {
23115 if (prev.type === 'Declaration') {
23116 this.chunk(';');
23117 }
23118 });
23119 this.chunk('}');
23120 },
23121 walkContext: 'block'
23122 };
23123
23124 var TYPE$f = tokenizer.TYPE;
23125
23126 var LEFTSQUAREBRACKET$2 = TYPE$f.LeftSquareBracket;
23127 var RIGHTSQUAREBRACKET$2 = TYPE$f.RightSquareBracket;
23128
23129 var Brackets = {
23130 name: 'Brackets',
23131 structure: {
23132 children: [[]]
23133 },
23134 parse: function(readSequence, recognizer) {
23135 var start = this.scanner.tokenStart;
23136 var children = null;
23137
23138 this.eat(LEFTSQUAREBRACKET$2);
23139
23140 children = readSequence.call(this, recognizer);
23141
23142 if (!this.scanner.eof) {
23143 this.eat(RIGHTSQUAREBRACKET$2);
23144 }
23145
23146 return {
23147 type: 'Brackets',
23148 loc: this.getLocation(start, this.scanner.tokenStart),
23149 children: children
23150 };
23151 },
23152 generate: function(node) {
23153 this.chunk('[');
23154 this.children(node);
23155 this.chunk(']');
23156 }
23157 };
23158
23159 var CDC = tokenizer.TYPE.CDC;
23160
23161 var CDC_1 = {
23162 name: 'CDC',
23163 structure: [],
23164 parse: function() {
23165 var start = this.scanner.tokenStart;
23166
23167 this.eat(CDC); // -->
23168
23169 return {
23170 type: 'CDC',
23171 loc: this.getLocation(start, this.scanner.tokenStart)
23172 };
23173 },
23174 generate: function() {
23175 this.chunk('-->');
23176 }
23177 };
23178
23179 var CDO = tokenizer.TYPE.CDO;
23180
23181 var CDO_1 = {
23182 name: 'CDO',
23183 structure: [],
23184 parse: function() {
23185 var start = this.scanner.tokenStart;
23186
23187 this.eat(CDO); // <!--
23188
23189 return {
23190 type: 'CDO',
23191 loc: this.getLocation(start, this.scanner.tokenStart)
23192 };
23193 },
23194 generate: function() {
23195 this.chunk('<!--');
23196 }
23197 };
23198
23199 var TYPE$g = tokenizer.TYPE;
23200
23201 var IDENT$5 = TYPE$g.Ident;
23202 var FULLSTOP = 0x002E; // U+002E FULL STOP (.)
23203
23204 // '.' ident
23205 var ClassSelector = {
23206 name: 'ClassSelector',
23207 structure: {
23208 name: String
23209 },
23210 parse: function() {
23211 if (!this.scanner.isDelim(FULLSTOP)) {
23212 this.error('Full stop is expected');
23213 }
23214
23215 this.scanner.next();
23216
23217 return {
23218 type: 'ClassSelector',
23219 loc: this.getLocation(this.scanner.tokenStart - 1, this.scanner.tokenEnd),
23220 name: this.consume(IDENT$5)
23221 };
23222 },
23223 generate: function(node) {
23224 this.chunk('.');
23225 this.chunk(node.name);
23226 }
23227 };
23228
23229 var TYPE$h = tokenizer.TYPE;
23230
23231 var IDENT$6 = TYPE$h.Ident;
23232 var PLUSSIGN$4 = 0x002B; // U+002B PLUS SIGN (+)
23233 var SOLIDUS = 0x002F; // U+002F SOLIDUS (/)
23234 var GREATERTHANSIGN$1 = 0x003E; // U+003E GREATER-THAN SIGN (>)
23235 var TILDE$1 = 0x007E; // U+007E TILDE (~)
23236
23237 // + | > | ~ | /deep/
23238 var Combinator = {
23239 name: 'Combinator',
23240 structure: {
23241 name: String
23242 },
23243 parse: function() {
23244 var start = this.scanner.tokenStart;
23245 var code = this.scanner.source.charCodeAt(this.scanner.tokenStart);
23246
23247 switch (code) {
23248 case GREATERTHANSIGN$1:
23249 case PLUSSIGN$4:
23250 case TILDE$1:
23251 this.scanner.next();
23252 break;
23253
23254 case SOLIDUS:
23255 this.scanner.next();
23256
23257 if (this.scanner.tokenType !== IDENT$6 || this.scanner.lookupValue(0, 'deep') === false) {
23258 this.error('Identifier `deep` is expected');
23259 }
23260
23261 this.scanner.next();
23262
23263 if (!this.scanner.isDelim(SOLIDUS)) {
23264 this.error('Solidus is expected');
23265 }
23266
23267 this.scanner.next();
23268 break;
23269
23270 default:
23271 this.error('Combinator is expected');
23272 }
23273
23274 return {
23275 type: 'Combinator',
23276 loc: this.getLocation(start, this.scanner.tokenStart),
23277 name: this.scanner.substrToCursor(start)
23278 };
23279 },
23280 generate: function(node) {
23281 this.chunk(node.name);
23282 }
23283 };
23284
23285 var TYPE$i = tokenizer.TYPE;
23286
23287 var COMMENT$5 = TYPE$i.Comment;
23288 var ASTERISK$2 = 0x002A; // U+002A ASTERISK (*)
23289 var SOLIDUS$1 = 0x002F; // U+002F SOLIDUS (/)
23290
23291 // '/*' .* '*/'
23292 var Comment = {
23293 name: 'Comment',
23294 structure: {
23295 value: String
23296 },
23297 parse: function() {
23298 var start = this.scanner.tokenStart;
23299 var end = this.scanner.tokenEnd;
23300
23301 this.eat(COMMENT$5);
23302
23303 if ((end - start + 2) >= 2 &&
23304 this.scanner.source.charCodeAt(end - 2) === ASTERISK$2 &&
23305 this.scanner.source.charCodeAt(end - 1) === SOLIDUS$1) {
23306 end -= 2;
23307 }
23308
23309 return {
23310 type: 'Comment',
23311 loc: this.getLocation(start, this.scanner.tokenStart),
23312 value: this.scanner.source.substring(start + 2, end)
23313 };
23314 },
23315 generate: function(node) {
23316 this.chunk('/*');
23317 this.chunk(node.value);
23318 this.chunk('*/');
23319 }
23320 };
23321
23322 var isCustomProperty$1 = names.isCustomProperty;
23323 var TYPE$j = tokenizer.TYPE;
23324 var rawMode$2 = Raw.mode;
23325
23326 var IDENT$7 = TYPE$j.Ident;
23327 var HASH$1 = TYPE$j.Hash;
23328 var COLON$1 = TYPE$j.Colon;
23329 var SEMICOLON$3 = TYPE$j.Semicolon;
23330 var DELIM$2 = TYPE$j.Delim;
23331 var EXCLAMATIONMARK$2 = 0x0021; // U+0021 EXCLAMATION MARK (!)
23332 var NUMBERSIGN$2 = 0x0023; // U+0023 NUMBER SIGN (#)
23333 var DOLLARSIGN$1 = 0x0024; // U+0024 DOLLAR SIGN ($)
23334 var AMPERSAND$1 = 0x0026; // U+0026 ANPERSAND (&)
23335 var ASTERISK$3 = 0x002A; // U+002A ASTERISK (*)
23336 var PLUSSIGN$5 = 0x002B; // U+002B PLUS SIGN (+)
23337 var SOLIDUS$2 = 0x002F; // U+002F SOLIDUS (/)
23338
23339 function consumeValueRaw(startToken) {
23340 return this.Raw(startToken, rawMode$2.exclamationMarkOrSemicolon, true);
23341 }
23342
23343 function consumeCustomPropertyRaw(startToken) {
23344 return this.Raw(startToken, rawMode$2.exclamationMarkOrSemicolon, false);
23345 }
23346
23347 function consumeValue() {
23348 var startValueToken = this.scanner.tokenIndex;
23349 var value = this.Value();
23350
23351 if (value.type !== 'Raw' &&
23352 this.scanner.eof === false &&
23353 this.scanner.tokenType !== SEMICOLON$3 &&
23354 this.scanner.isDelim(EXCLAMATIONMARK$2) === false &&
23355 this.scanner.isBalanceEdge(startValueToken) === false) {
23356 this.error();
23357 }
23358
23359 return value;
23360 }
23361
23362 var Declaration = {
23363 name: 'Declaration',
23364 structure: {
23365 important: [Boolean, String],
23366 property: String,
23367 value: ['Value', 'Raw']
23368 },
23369 parse: function() {
23370 var start = this.scanner.tokenStart;
23371 var startToken = this.scanner.tokenIndex;
23372 var property = readProperty$1.call(this);
23373 var customProperty = isCustomProperty$1(property);
23374 var parseValue = customProperty ? this.parseCustomProperty : this.parseValue;
23375 var consumeRaw = customProperty ? consumeCustomPropertyRaw : consumeValueRaw;
23376 var important = false;
23377 var value;
23378
23379 this.scanner.skipSC();
23380 this.eat(COLON$1);
23381
23382 if (!customProperty) {
23383 this.scanner.skipSC();
23384 }
23385
23386 if (parseValue) {
23387 value = this.parseWithFallback(consumeValue, consumeRaw);
23388 } else {
23389 value = consumeRaw.call(this, this.scanner.tokenIndex);
23390 }
23391
23392 if (this.scanner.isDelim(EXCLAMATIONMARK$2)) {
23393 important = getImportant.call(this);
23394 this.scanner.skipSC();
23395 }
23396
23397 // Do not include semicolon to range per spec
23398 // https://drafts.csswg.org/css-syntax/#declaration-diagram
23399
23400 if (this.scanner.eof === false &&
23401 this.scanner.tokenType !== SEMICOLON$3 &&
23402 this.scanner.isBalanceEdge(startToken) === false) {
23403 this.error();
23404 }
23405
23406 return {
23407 type: 'Declaration',
23408 loc: this.getLocation(start, this.scanner.tokenStart),
23409 important: important,
23410 property: property,
23411 value: value
23412 };
23413 },
23414 generate: function(node) {
23415 this.chunk(node.property);
23416 this.chunk(':');
23417 this.node(node.value);
23418
23419 if (node.important) {
23420 this.chunk(node.important === true ? '!important' : '!' + node.important);
23421 }
23422 },
23423 walkContext: 'declaration'
23424 };
23425
23426 function readProperty$1() {
23427 var start = this.scanner.tokenStart;
23428
23429 // hacks
23430 if (this.scanner.tokenType === DELIM$2) {
23431 switch (this.scanner.source.charCodeAt(this.scanner.tokenStart)) {
23432 case ASTERISK$3:
23433 case DOLLARSIGN$1:
23434 case PLUSSIGN$5:
23435 case NUMBERSIGN$2:
23436 case AMPERSAND$1:
23437 this.scanner.next();
23438 break;
23439
23440 // TODO: not sure we should support this hack
23441 case SOLIDUS$2:
23442 this.scanner.next();
23443 if (this.scanner.isDelim(SOLIDUS$2)) {
23444 this.scanner.next();
23445 }
23446 break;
23447 }
23448 }
23449
23450 if (this.scanner.tokenType === HASH$1) {
23451 this.eat(HASH$1);
23452 } else {
23453 this.eat(IDENT$7);
23454 }
23455
23456 return this.scanner.substrToCursor(start);
23457 }
23458
23459 // ! ws* important
23460 function getImportant() {
23461 this.eat(DELIM$2);
23462 this.scanner.skipSC();
23463
23464 var important = this.consume(IDENT$7);
23465
23466 // store original value in case it differ from `important`
23467 // for better original source restoring and hacks like `!ie` support
23468 return important === 'important' ? true : important;
23469 }
23470
23471 var TYPE$k = tokenizer.TYPE;
23472 var rawMode$3 = Raw.mode;
23473
23474 var WHITESPACE$6 = TYPE$k.WhiteSpace;
23475 var COMMENT$6 = TYPE$k.Comment;
23476 var SEMICOLON$4 = TYPE$k.Semicolon;
23477
23478 function consumeRaw$2(startToken) {
23479 return this.Raw(startToken, rawMode$3.semicolonIncluded, true);
23480 }
23481
23482 var DeclarationList = {
23483 name: 'DeclarationList',
23484 structure: {
23485 children: [[
23486 'Declaration'
23487 ]]
23488 },
23489 parse: function() {
23490 var children = this.createList();
23491
23492
23493 while (!this.scanner.eof) {
23494 switch (this.scanner.tokenType) {
23495 case WHITESPACE$6:
23496 case COMMENT$6:
23497 case SEMICOLON$4:
23498 this.scanner.next();
23499 break;
23500
23501 default:
23502 children.push(this.parseWithFallback(this.Declaration, consumeRaw$2));
23503 }
23504 }
23505
23506 return {
23507 type: 'DeclarationList',
23508 loc: this.getLocationFromList(children),
23509 children: children
23510 };
23511 },
23512 generate: function(node) {
23513 this.children(node, function(prev) {
23514 if (prev.type === 'Declaration') {
23515 this.chunk(';');
23516 }
23517 });
23518 }
23519 };
23520
23521 var consumeNumber$3 = utils.consumeNumber;
23522 var TYPE$l = tokenizer.TYPE;
23523
23524 var DIMENSION$3 = TYPE$l.Dimension;
23525
23526 var Dimension = {
23527 name: 'Dimension',
23528 structure: {
23529 value: String,
23530 unit: String
23531 },
23532 parse: function() {
23533 var start = this.scanner.tokenStart;
23534 var numberEnd = consumeNumber$3(this.scanner.source, start);
23535
23536 this.eat(DIMENSION$3);
23537
23538 return {
23539 type: 'Dimension',
23540 loc: this.getLocation(start, this.scanner.tokenStart),
23541 value: this.scanner.source.substring(start, numberEnd),
23542 unit: this.scanner.source.substring(numberEnd, this.scanner.tokenStart)
23543 };
23544 },
23545 generate: function(node) {
23546 this.chunk(node.value);
23547 this.chunk(node.unit);
23548 }
23549 };
23550
23551 var TYPE$m = tokenizer.TYPE;
23552
23553 var RIGHTPARENTHESIS$2 = TYPE$m.RightParenthesis;
23554
23555 // <function-token> <sequence> )
23556 var _Function = {
23557 name: 'Function',
23558 structure: {
23559 name: String,
23560 children: [[]]
23561 },
23562 parse: function(readSequence, recognizer) {
23563 var start = this.scanner.tokenStart;
23564 var name = this.consumeFunctionName();
23565 var nameLowerCase = name.toLowerCase();
23566 var children;
23567
23568 children = recognizer.hasOwnProperty(nameLowerCase)
23569 ? recognizer[nameLowerCase].call(this, recognizer)
23570 : readSequence.call(this, recognizer);
23571
23572 if (!this.scanner.eof) {
23573 this.eat(RIGHTPARENTHESIS$2);
23574 }
23575
23576 return {
23577 type: 'Function',
23578 loc: this.getLocation(start, this.scanner.tokenStart),
23579 name: name,
23580 children: children
23581 };
23582 },
23583 generate: function(node) {
23584 this.chunk(node.name);
23585 this.chunk('(');
23586 this.children(node);
23587 this.chunk(')');
23588 },
23589 walkContext: 'function'
23590 };
23591
23592 var TYPE$n = tokenizer.TYPE;
23593
23594 var HASH$2 = TYPE$n.Hash;
23595
23596 // '#' ident
23597 var HexColor = {
23598 name: 'HexColor',
23599 structure: {
23600 value: String
23601 },
23602 parse: function() {
23603 var start = this.scanner.tokenStart;
23604
23605 this.eat(HASH$2);
23606
23607 return {
23608 type: 'HexColor',
23609 loc: this.getLocation(start, this.scanner.tokenStart),
23610 value: this.scanner.substrToCursor(start + 1)
23611 };
23612 },
23613 generate: function(node) {
23614 this.chunk('#');
23615 this.chunk(node.value);
23616 }
23617 };
23618
23619 var TYPE$o = tokenizer.TYPE;
23620
23621 var IDENT$8 = TYPE$o.Ident;
23622
23623 var Identifier = {
23624 name: 'Identifier',
23625 structure: {
23626 name: String
23627 },
23628 parse: function() {
23629 return {
23630 type: 'Identifier',
23631 loc: this.getLocation(this.scanner.tokenStart, this.scanner.tokenEnd),
23632 name: this.consume(IDENT$8)
23633 };
23634 },
23635 generate: function(node) {
23636 this.chunk(node.name);
23637 }
23638 };
23639
23640 var TYPE$p = tokenizer.TYPE;
23641
23642 var HASH$3 = TYPE$p.Hash;
23643
23644 // <hash-token>
23645 var IdSelector = {
23646 name: 'IdSelector',
23647 structure: {
23648 name: String
23649 },
23650 parse: function() {
23651 var start = this.scanner.tokenStart;
23652
23653 // TODO: check value is an ident
23654 this.eat(HASH$3);
23655
23656 return {
23657 type: 'IdSelector',
23658 loc: this.getLocation(start, this.scanner.tokenStart),
23659 name: this.scanner.substrToCursor(start + 1)
23660 };
23661 },
23662 generate: function(node) {
23663 this.chunk('#');
23664 this.chunk(node.name);
23665 }
23666 };
23667
23668 var TYPE$q = tokenizer.TYPE;
23669
23670 var IDENT$9 = TYPE$q.Ident;
23671 var NUMBER$4 = TYPE$q.Number;
23672 var DIMENSION$4 = TYPE$q.Dimension;
23673 var LEFTPARENTHESIS$2 = TYPE$q.LeftParenthesis;
23674 var RIGHTPARENTHESIS$3 = TYPE$q.RightParenthesis;
23675 var COLON$2 = TYPE$q.Colon;
23676 var DELIM$3 = TYPE$q.Delim;
23677
23678 var MediaFeature = {
23679 name: 'MediaFeature',
23680 structure: {
23681 name: String,
23682 value: ['Identifier', 'Number', 'Dimension', 'Ratio', null]
23683 },
23684 parse: function() {
23685 var start = this.scanner.tokenStart;
23686 var name;
23687 var value = null;
23688
23689 this.eat(LEFTPARENTHESIS$2);
23690 this.scanner.skipSC();
23691
23692 name = this.consume(IDENT$9);
23693 this.scanner.skipSC();
23694
23695 if (this.scanner.tokenType !== RIGHTPARENTHESIS$3) {
23696 this.eat(COLON$2);
23697 this.scanner.skipSC();
23698
23699 switch (this.scanner.tokenType) {
23700 case NUMBER$4:
23701 if (this.lookupNonWSType(1) === DELIM$3) {
23702 value = this.Ratio();
23703 } else {
23704 value = this.Number();
23705 }
23706
23707 break;
23708
23709 case DIMENSION$4:
23710 value = this.Dimension();
23711 break;
23712
23713 case IDENT$9:
23714 value = this.Identifier();
23715
23716 break;
23717
23718 default:
23719 this.error('Number, dimension, ratio or identifier is expected');
23720 }
23721
23722 this.scanner.skipSC();
23723 }
23724
23725 this.eat(RIGHTPARENTHESIS$3);
23726
23727 return {
23728 type: 'MediaFeature',
23729 loc: this.getLocation(start, this.scanner.tokenStart),
23730 name: name,
23731 value: value
23732 };
23733 },
23734 generate: function(node) {
23735 this.chunk('(');
23736 this.chunk(node.name);
23737 if (node.value !== null) {
23738 this.chunk(':');
23739 this.node(node.value);
23740 }
23741 this.chunk(')');
23742 }
23743 };
23744
23745 var TYPE$r = tokenizer.TYPE;
23746
23747 var WHITESPACE$7 = TYPE$r.WhiteSpace;
23748 var COMMENT$7 = TYPE$r.Comment;
23749 var IDENT$a = TYPE$r.Ident;
23750 var LEFTPARENTHESIS$3 = TYPE$r.LeftParenthesis;
23751
23752 var MediaQuery = {
23753 name: 'MediaQuery',
23754 structure: {
23755 children: [[
23756 'Identifier',
23757 'MediaFeature',
23758 'WhiteSpace'
23759 ]]
23760 },
23761 parse: function() {
23762 this.scanner.skipSC();
23763
23764 var children = this.createList();
23765 var child = null;
23766 var space = null;
23767
23768 scan:
23769 while (!this.scanner.eof) {
23770 switch (this.scanner.tokenType) {
23771 case COMMENT$7:
23772 this.scanner.next();
23773 continue;
23774
23775 case WHITESPACE$7:
23776 space = this.WhiteSpace();
23777 continue;
23778
23779 case IDENT$a:
23780 child = this.Identifier();
23781 break;
23782
23783 case LEFTPARENTHESIS$3:
23784 child = this.MediaFeature();
23785 break;
23786
23787 default:
23788 break scan;
23789 }
23790
23791 if (space !== null) {
23792 children.push(space);
23793 space = null;
23794 }
23795
23796 children.push(child);
23797 }
23798
23799 if (child === null) {
23800 this.error('Identifier or parenthesis is expected');
23801 }
23802
23803 return {
23804 type: 'MediaQuery',
23805 loc: this.getLocationFromList(children),
23806 children: children
23807 };
23808 },
23809 generate: function(node) {
23810 this.children(node);
23811 }
23812 };
23813
23814 var COMMA$1 = tokenizer.TYPE.Comma;
23815
23816 var MediaQueryList = {
23817 name: 'MediaQueryList',
23818 structure: {
23819 children: [[
23820 'MediaQuery'
23821 ]]
23822 },
23823 parse: function(relative) {
23824 var children = this.createList();
23825
23826 this.scanner.skipSC();
23827
23828 while (!this.scanner.eof) {
23829 children.push(this.MediaQuery(relative));
23830
23831 if (this.scanner.tokenType !== COMMA$1) {
23832 break;
23833 }
23834
23835 this.scanner.next();
23836 }
23837
23838 return {
23839 type: 'MediaQueryList',
23840 loc: this.getLocationFromList(children),
23841 children: children
23842 };
23843 },
23844 generate: function(node) {
23845 this.children(node, function() {
23846 this.chunk(',');
23847 });
23848 }
23849 };
23850
23851 var Nth = {
23852 name: 'Nth',
23853 structure: {
23854 nth: ['AnPlusB', 'Identifier'],
23855 selector: ['SelectorList', null]
23856 },
23857 parse: function(allowOfClause) {
23858 this.scanner.skipSC();
23859
23860 var start = this.scanner.tokenStart;
23861 var end = start;
23862 var selector = null;
23863 var query;
23864
23865 if (this.scanner.lookupValue(0, 'odd') || this.scanner.lookupValue(0, 'even')) {
23866 query = this.Identifier();
23867 } else {
23868 query = this.AnPlusB();
23869 }
23870
23871 this.scanner.skipSC();
23872
23873 if (allowOfClause && this.scanner.lookupValue(0, 'of')) {
23874 this.scanner.next();
23875
23876 selector = this.SelectorList();
23877
23878 if (this.needPositions) {
23879 end = this.getLastListNode(selector.children).loc.end.offset;
23880 }
23881 } else {
23882 if (this.needPositions) {
23883 end = query.loc.end.offset;
23884 }
23885 }
23886
23887 return {
23888 type: 'Nth',
23889 loc: this.getLocation(start, end),
23890 nth: query,
23891 selector: selector
23892 };
23893 },
23894 generate: function(node) {
23895 this.node(node.nth);
23896 if (node.selector !== null) {
23897 this.chunk(' of ');
23898 this.node(node.selector);
23899 }
23900 }
23901 };
23902
23903 var NUMBER$5 = tokenizer.TYPE.Number;
23904
23905 var _Number = {
23906 name: 'Number',
23907 structure: {
23908 value: String
23909 },
23910 parse: function() {
23911 return {
23912 type: 'Number',
23913 loc: this.getLocation(this.scanner.tokenStart, this.scanner.tokenEnd),
23914 value: this.consume(NUMBER$5)
23915 };
23916 },
23917 generate: function(node) {
23918 this.chunk(node.value);
23919 }
23920 };
23921
23922 // '/' | '*' | ',' | ':' | '+' | '-'
23923 var Operator = {
23924 name: 'Operator',
23925 structure: {
23926 value: String
23927 },
23928 parse: function() {
23929 var start = this.scanner.tokenStart;
23930
23931 this.scanner.next();
23932
23933 return {
23934 type: 'Operator',
23935 loc: this.getLocation(start, this.scanner.tokenStart),
23936 value: this.scanner.substrToCursor(start)
23937 };
23938 },
23939 generate: function(node) {
23940 this.chunk(node.value);
23941 }
23942 };
23943
23944 var TYPE$s = tokenizer.TYPE;
23945
23946 var LEFTPARENTHESIS$4 = TYPE$s.LeftParenthesis;
23947 var RIGHTPARENTHESIS$4 = TYPE$s.RightParenthesis;
23948
23949 var Parentheses = {
23950 name: 'Parentheses',
23951 structure: {
23952 children: [[]]
23953 },
23954 parse: function(readSequence, recognizer) {
23955 var start = this.scanner.tokenStart;
23956 var children = null;
23957
23958 this.eat(LEFTPARENTHESIS$4);
23959
23960 children = readSequence.call(this, recognizer);
23961
23962 if (!this.scanner.eof) {
23963 this.eat(RIGHTPARENTHESIS$4);
23964 }
23965
23966 return {
23967 type: 'Parentheses',
23968 loc: this.getLocation(start, this.scanner.tokenStart),
23969 children: children
23970 };
23971 },
23972 generate: function(node) {
23973 this.chunk('(');
23974 this.children(node);
23975 this.chunk(')');
23976 }
23977 };
23978
23979 var consumeNumber$4 = utils.consumeNumber;
23980 var TYPE$t = tokenizer.TYPE;
23981
23982 var PERCENTAGE$1 = TYPE$t.Percentage;
23983
23984 var Percentage = {
23985 name: 'Percentage',
23986 structure: {
23987 value: String
23988 },
23989 parse: function() {
23990 var start = this.scanner.tokenStart;
23991 var numberEnd = consumeNumber$4(this.scanner.source, start);
23992
23993 this.eat(PERCENTAGE$1);
23994
23995 return {
23996 type: 'Percentage',
23997 loc: this.getLocation(start, this.scanner.tokenStart),
23998 value: this.scanner.source.substring(start, numberEnd)
23999 };
24000 },
24001 generate: function(node) {
24002 this.chunk(node.value);
24003 this.chunk('%');
24004 }
24005 };
24006
24007 var TYPE$u = tokenizer.TYPE;
24008
24009 var IDENT$b = TYPE$u.Ident;
24010 var FUNCTION$1 = TYPE$u.Function;
24011 var COLON$3 = TYPE$u.Colon;
24012 var RIGHTPARENTHESIS$5 = TYPE$u.RightParenthesis;
24013
24014 // : [ <ident> | <function-token> <any-value>? ) ]
24015 var PseudoClassSelector = {
24016 name: 'PseudoClassSelector',
24017 structure: {
24018 name: String,
24019 children: [['Raw'], null]
24020 },
24021 parse: function() {
24022 var start = this.scanner.tokenStart;
24023 var children = null;
24024 var name;
24025 var nameLowerCase;
24026
24027 this.eat(COLON$3);
24028
24029 if (this.scanner.tokenType === FUNCTION$1) {
24030 name = this.consumeFunctionName();
24031 nameLowerCase = name.toLowerCase();
24032
24033 if (this.pseudo.hasOwnProperty(nameLowerCase)) {
24034 this.scanner.skipSC();
24035 children = this.pseudo[nameLowerCase].call(this);
24036 this.scanner.skipSC();
24037 } else {
24038 children = this.createList();
24039 children.push(
24040 this.Raw(this.scanner.tokenIndex, null, false)
24041 );
24042 }
24043
24044 this.eat(RIGHTPARENTHESIS$5);
24045 } else {
24046 name = this.consume(IDENT$b);
24047 }
24048
24049 return {
24050 type: 'PseudoClassSelector',
24051 loc: this.getLocation(start, this.scanner.tokenStart),
24052 name: name,
24053 children: children
24054 };
24055 },
24056 generate: function(node) {
24057 this.chunk(':');
24058 this.chunk(node.name);
24059
24060 if (node.children !== null) {
24061 this.chunk('(');
24062 this.children(node);
24063 this.chunk(')');
24064 }
24065 },
24066 walkContext: 'function'
24067 };
24068
24069 var TYPE$v = tokenizer.TYPE;
24070
24071 var IDENT$c = TYPE$v.Ident;
24072 var FUNCTION$2 = TYPE$v.Function;
24073 var COLON$4 = TYPE$v.Colon;
24074 var RIGHTPARENTHESIS$6 = TYPE$v.RightParenthesis;
24075
24076 // :: [ <ident> | <function-token> <any-value>? ) ]
24077 var PseudoElementSelector = {
24078 name: 'PseudoElementSelector',
24079 structure: {
24080 name: String,
24081 children: [['Raw'], null]
24082 },
24083 parse: function() {
24084 var start = this.scanner.tokenStart;
24085 var children = null;
24086 var name;
24087 var nameLowerCase;
24088
24089 this.eat(COLON$4);
24090 this.eat(COLON$4);
24091
24092 if (this.scanner.tokenType === FUNCTION$2) {
24093 name = this.consumeFunctionName();
24094 nameLowerCase = name.toLowerCase();
24095
24096 if (this.pseudo.hasOwnProperty(nameLowerCase)) {
24097 this.scanner.skipSC();
24098 children = this.pseudo[nameLowerCase].call(this);
24099 this.scanner.skipSC();
24100 } else {
24101 children = this.createList();
24102 children.push(
24103 this.Raw(this.scanner.tokenIndex, null, false)
24104 );
24105 }
24106
24107 this.eat(RIGHTPARENTHESIS$6);
24108 } else {
24109 name = this.consume(IDENT$c);
24110 }
24111
24112 return {
24113 type: 'PseudoElementSelector',
24114 loc: this.getLocation(start, this.scanner.tokenStart),
24115 name: name,
24116 children: children
24117 };
24118 },
24119 generate: function(node) {
24120 this.chunk('::');
24121 this.chunk(node.name);
24122
24123 if (node.children !== null) {
24124 this.chunk('(');
24125 this.children(node);
24126 this.chunk(')');
24127 }
24128 },
24129 walkContext: 'function'
24130 };
24131
24132 var isDigit$5 = tokenizer.isDigit;
24133 var TYPE$w = tokenizer.TYPE;
24134
24135 var NUMBER$6 = TYPE$w.Number;
24136 var DELIM$4 = TYPE$w.Delim;
24137 var SOLIDUS$3 = 0x002F; // U+002F SOLIDUS (/)
24138 var FULLSTOP$1 = 0x002E; // U+002E FULL STOP (.)
24139
24140 // Terms of <ratio> should be a positive numbers (not zero or negative)
24141 // (see https://drafts.csswg.org/mediaqueries-3/#values)
24142 // However, -o-min-device-pixel-ratio takes fractional values as a ratio's term
24143 // and this is using by various sites. Therefore we relax checking on parse
24144 // to test a term is unsigned number without an exponent part.
24145 // Additional checking may be applied on lexer validation.
24146 function consumeNumber$5() {
24147 this.scanner.skipWS();
24148
24149 var value = this.consume(NUMBER$6);
24150
24151 for (var i = 0; i < value.length; i++) {
24152 var code = value.charCodeAt(i);
24153 if (!isDigit$5(code) && code !== FULLSTOP$1) {
24154 this.error('Unsigned number is expected', this.scanner.tokenStart - value.length + i);
24155 }
24156 }
24157
24158 if (Number(value) === 0) {
24159 this.error('Zero number is not allowed', this.scanner.tokenStart - value.length);
24160 }
24161
24162 return value;
24163 }
24164
24165 // <positive-integer> S* '/' S* <positive-integer>
24166 var Ratio = {
24167 name: 'Ratio',
24168 structure: {
24169 left: String,
24170 right: String
24171 },
24172 parse: function() {
24173 var start = this.scanner.tokenStart;
24174 var left = consumeNumber$5.call(this);
24175 var right;
24176
24177 this.scanner.skipWS();
24178
24179 if (!this.scanner.isDelim(SOLIDUS$3)) {
24180 this.error('Solidus is expected');
24181 }
24182 this.eat(DELIM$4);
24183 right = consumeNumber$5.call(this);
24184
24185 return {
24186 type: 'Ratio',
24187 loc: this.getLocation(start, this.scanner.tokenStart),
24188 left: left,
24189 right: right
24190 };
24191 },
24192 generate: function(node) {
24193 this.chunk(node.left);
24194 this.chunk('/');
24195 this.chunk(node.right);
24196 }
24197 };
24198
24199 var TYPE$x = tokenizer.TYPE;
24200 var rawMode$4 = Raw.mode;
24201
24202 var LEFTCURLYBRACKET$4 = TYPE$x.LeftCurlyBracket;
24203
24204 function consumeRaw$3(startToken) {
24205 return this.Raw(startToken, rawMode$4.leftCurlyBracket, true);
24206 }
24207
24208 function consumePrelude() {
24209 var prelude = this.SelectorList();
24210
24211 if (prelude.type !== 'Raw' &&
24212 this.scanner.eof === false &&
24213 this.scanner.tokenType !== LEFTCURLYBRACKET$4) {
24214 this.error();
24215 }
24216
24217 return prelude;
24218 }
24219
24220 var Rule = {
24221 name: 'Rule',
24222 structure: {
24223 prelude: ['SelectorList', 'Raw'],
24224 block: ['Block']
24225 },
24226 parse: function() {
24227 var startToken = this.scanner.tokenIndex;
24228 var startOffset = this.scanner.tokenStart;
24229 var prelude;
24230 var block;
24231
24232 if (this.parseRulePrelude) {
24233 prelude = this.parseWithFallback(consumePrelude, consumeRaw$3);
24234 } else {
24235 prelude = consumeRaw$3.call(this, startToken);
24236 }
24237
24238 block = this.Block(true);
24239
24240 return {
24241 type: 'Rule',
24242 loc: this.getLocation(startOffset, this.scanner.tokenStart),
24243 prelude: prelude,
24244 block: block
24245 };
24246 },
24247 generate: function(node) {
24248 this.node(node.prelude);
24249 this.node(node.block);
24250 },
24251 walkContext: 'rule'
24252 };
24253
24254 var Selector = {
24255 name: 'Selector',
24256 structure: {
24257 children: [[
24258 'TypeSelector',
24259 'IdSelector',
24260 'ClassSelector',
24261 'AttributeSelector',
24262 'PseudoClassSelector',
24263 'PseudoElementSelector',
24264 'Combinator',
24265 'WhiteSpace'
24266 ]]
24267 },
24268 parse: function() {
24269 var children = this.readSequence(this.scope.Selector);
24270
24271 // nothing were consumed
24272 if (this.getFirstListNode(children) === null) {
24273 this.error('Selector is expected');
24274 }
24275
24276 return {
24277 type: 'Selector',
24278 loc: this.getLocationFromList(children),
24279 children: children
24280 };
24281 },
24282 generate: function(node) {
24283 this.children(node);
24284 }
24285 };
24286
24287 var TYPE$y = tokenizer.TYPE;
24288
24289 var COMMA$2 = TYPE$y.Comma;
24290
24291 var SelectorList = {
24292 name: 'SelectorList',
24293 structure: {
24294 children: [[
24295 'Selector',
24296 'Raw'
24297 ]]
24298 },
24299 parse: function() {
24300 var children = this.createList();
24301
24302 while (!this.scanner.eof) {
24303 children.push(this.Selector());
24304
24305 if (this.scanner.tokenType === COMMA$2) {
24306 this.scanner.next();
24307 continue;
24308 }
24309
24310 break;
24311 }
24312
24313 return {
24314 type: 'SelectorList',
24315 loc: this.getLocationFromList(children),
24316 children: children
24317 };
24318 },
24319 generate: function(node) {
24320 this.children(node, function() {
24321 this.chunk(',');
24322 });
24323 },
24324 walkContext: 'selector'
24325 };
24326
24327 var STRING$1 = tokenizer.TYPE.String;
24328
24329 var _String = {
24330 name: 'String',
24331 structure: {
24332 value: String
24333 },
24334 parse: function() {
24335 return {
24336 type: 'String',
24337 loc: this.getLocation(this.scanner.tokenStart, this.scanner.tokenEnd),
24338 value: this.consume(STRING$1)
24339 };
24340 },
24341 generate: function(node) {
24342 this.chunk(node.value);
24343 }
24344 };
24345
24346 var TYPE$z = tokenizer.TYPE;
24347
24348 var WHITESPACE$8 = TYPE$z.WhiteSpace;
24349 var COMMENT$8 = TYPE$z.Comment;
24350 var ATKEYWORD$2 = TYPE$z.AtKeyword;
24351 var CDO$1 = TYPE$z.CDO;
24352 var CDC$1 = TYPE$z.CDC;
24353 var EXCLAMATIONMARK$3 = 0x0021; // U+0021 EXCLAMATION MARK (!)
24354
24355 function consumeRaw$4(startToken) {
24356 return this.Raw(startToken, null, false);
24357 }
24358
24359 var StyleSheet = {
24360 name: 'StyleSheet',
24361 structure: {
24362 children: [[
24363 'Comment',
24364 'CDO',
24365 'CDC',
24366 'Atrule',
24367 'Rule',
24368 'Raw'
24369 ]]
24370 },
24371 parse: function() {
24372 var start = this.scanner.tokenStart;
24373 var children = this.createList();
24374 var child;
24375
24376
24377 while (!this.scanner.eof) {
24378 switch (this.scanner.tokenType) {
24379 case WHITESPACE$8:
24380 this.scanner.next();
24381 continue;
24382
24383 case COMMENT$8:
24384 // ignore comments except exclamation comments (i.e. /*! .. */) on top level
24385 if (this.scanner.source.charCodeAt(this.scanner.tokenStart + 2) !== EXCLAMATIONMARK$3) {
24386 this.scanner.next();
24387 continue;
24388 }
24389
24390 child = this.Comment();
24391 break;
24392
24393 case CDO$1: // <!--
24394 child = this.CDO();
24395 break;
24396
24397 case CDC$1: // -->
24398 child = this.CDC();
24399 break;
24400
24401 // CSS Syntax Module Level 3
24402 // §2.2 Error handling
24403 // At the "top level" of a stylesheet, an <at-keyword-token> starts an at-rule.
24404 case ATKEYWORD$2:
24405 child = this.parseWithFallback(this.Atrule, consumeRaw$4);
24406 break;
24407
24408 // Anything else starts a qualified rule ...
24409 default:
24410 child = this.parseWithFallback(this.Rule, consumeRaw$4);
24411 }
24412
24413 children.push(child);
24414 }
24415
24416 return {
24417 type: 'StyleSheet',
24418 loc: this.getLocation(start, this.scanner.tokenStart),
24419 children: children
24420 };
24421 },
24422 generate: function(node) {
24423 this.children(node);
24424 },
24425 walkContext: 'stylesheet'
24426 };
24427
24428 var TYPE$A = tokenizer.TYPE;
24429
24430 var IDENT$d = TYPE$A.Ident;
24431 var ASTERISK$4 = 0x002A; // U+002A ASTERISK (*)
24432 var VERTICALLINE$2 = 0x007C; // U+007C VERTICAL LINE (|)
24433
24434 function eatIdentifierOrAsterisk() {
24435 if (this.scanner.tokenType !== IDENT$d &&
24436 this.scanner.isDelim(ASTERISK$4) === false) {
24437 this.error('Identifier or asterisk is expected');
24438 }
24439
24440 this.scanner.next();
24441 }
24442
24443 // ident
24444 // ident|ident
24445 // ident|*
24446 // *
24447 // *|ident
24448 // *|*
24449 // |ident
24450 // |*
24451 var TypeSelector = {
24452 name: 'TypeSelector',
24453 structure: {
24454 name: String
24455 },
24456 parse: function() {
24457 var start = this.scanner.tokenStart;
24458
24459 if (this.scanner.isDelim(VERTICALLINE$2)) {
24460 this.scanner.next();
24461 eatIdentifierOrAsterisk.call(this);
24462 } else {
24463 eatIdentifierOrAsterisk.call(this);
24464
24465 if (this.scanner.isDelim(VERTICALLINE$2)) {
24466 this.scanner.next();
24467 eatIdentifierOrAsterisk.call(this);
24468 }
24469 }
24470
24471 return {
24472 type: 'TypeSelector',
24473 loc: this.getLocation(start, this.scanner.tokenStart),
24474 name: this.scanner.substrToCursor(start)
24475 };
24476 },
24477 generate: function(node) {
24478 this.chunk(node.name);
24479 }
24480 };
24481
24482 var isHexDigit$4 = tokenizer.isHexDigit;
24483 var cmpChar$4 = tokenizer.cmpChar;
24484 var TYPE$B = tokenizer.TYPE;
24485 var NAME$3 = tokenizer.NAME;
24486
24487 var IDENT$e = TYPE$B.Ident;
24488 var NUMBER$7 = TYPE$B.Number;
24489 var DIMENSION$5 = TYPE$B.Dimension;
24490 var PLUSSIGN$6 = 0x002B; // U+002B PLUS SIGN (+)
24491 var HYPHENMINUS$4 = 0x002D; // U+002D HYPHEN-MINUS (-)
24492 var QUESTIONMARK$2 = 0x003F; // U+003F QUESTION MARK (?)
24493 var U$1 = 0x0075; // U+0075 LATIN SMALL LETTER U (u)
24494
24495 function eatHexSequence(offset, allowDash) {
24496 for (var pos = this.scanner.tokenStart + offset, len = 0; pos < this.scanner.tokenEnd; pos++) {
24497 var code = this.scanner.source.charCodeAt(pos);
24498
24499 if (code === HYPHENMINUS$4 && allowDash && len !== 0) {
24500 if (eatHexSequence.call(this, offset + len + 1, false) === 0) {
24501 this.error();
24502 }
24503
24504 return -1;
24505 }
24506
24507 if (!isHexDigit$4(code)) {
24508 this.error(
24509 allowDash && len !== 0
24510 ? 'HyphenMinus' + (len < 6 ? ' or hex digit' : '') + ' is expected'
24511 : (len < 6 ? 'Hex digit is expected' : 'Unexpected input'),
24512 pos
24513 );
24514 }
24515
24516 if (++len > 6) {
24517 this.error('Too many hex digits', pos);
24518 } }
24519
24520 this.scanner.next();
24521 return len;
24522 }
24523
24524 function eatQuestionMarkSequence(max) {
24525 var count = 0;
24526
24527 while (this.scanner.isDelim(QUESTIONMARK$2)) {
24528 if (++count > max) {
24529 this.error('Too many question marks');
24530 }
24531
24532 this.scanner.next();
24533 }
24534 }
24535
24536 function startsWith$1(code) {
24537 if (this.scanner.source.charCodeAt(this.scanner.tokenStart) !== code) {
24538 this.error(NAME$3[code] + ' is expected');
24539 }
24540 }
24541
24542 // https://drafts.csswg.org/css-syntax/#urange
24543 // Informally, the <urange> production has three forms:
24544 // U+0001
24545 // Defines a range consisting of a single code point, in this case the code point "1".
24546 // U+0001-00ff
24547 // Defines a range of codepoints between the first and the second value, in this case
24548 // the range between "1" and "ff" (255 in decimal) inclusive.
24549 // U+00??
24550 // Defines a range of codepoints where the "?" characters range over all hex digits,
24551 // in this case defining the same as the value U+0000-00ff.
24552 // In each form, a maximum of 6 digits is allowed for each hexadecimal number (if you treat "?" as a hexadecimal digit).
24553 //
24554 // <urange> =
24555 // u '+' <ident-token> '?'* |
24556 // u <dimension-token> '?'* |
24557 // u <number-token> '?'* |
24558 // u <number-token> <dimension-token> |
24559 // u <number-token> <number-token> |
24560 // u '+' '?'+
24561 function scanUnicodeRange() {
24562 var hexLength = 0;
24563
24564 // u '+' <ident-token> '?'*
24565 // u '+' '?'+
24566 if (this.scanner.isDelim(PLUSSIGN$6)) {
24567 this.scanner.next();
24568
24569 if (this.scanner.tokenType === IDENT$e) {
24570 hexLength = eatHexSequence.call(this, 0, true);
24571 if (hexLength > 0) {
24572 eatQuestionMarkSequence.call(this, 6 - hexLength);
24573 }
24574 return;
24575 }
24576
24577 if (this.scanner.isDelim(QUESTIONMARK$2)) {
24578 this.scanner.next();
24579 eatQuestionMarkSequence.call(this, 5);
24580 return;
24581 }
24582
24583 this.error('Hex digit or question mark is expected');
24584 return;
24585 }
24586
24587 // u <number-token> '?'*
24588 // u <number-token> <dimension-token>
24589 // u <number-token> <number-token>
24590 if (this.scanner.tokenType === NUMBER$7) {
24591 startsWith$1.call(this, PLUSSIGN$6);
24592 hexLength = eatHexSequence.call(this, 1, true);
24593
24594 if (this.scanner.isDelim(QUESTIONMARK$2)) {
24595 eatQuestionMarkSequence.call(this, 6 - hexLength);
24596 return;
24597 }
24598
24599 if (this.scanner.tokenType === DIMENSION$5 ||
24600 this.scanner.tokenType === NUMBER$7) {
24601 startsWith$1.call(this, HYPHENMINUS$4);
24602 eatHexSequence.call(this, 1, false);
24603 return;
24604 }
24605
24606 return;
24607 }
24608
24609 // u <dimension-token> '?'*
24610 if (this.scanner.tokenType === DIMENSION$5) {
24611 startsWith$1.call(this, PLUSSIGN$6);
24612 hexLength = eatHexSequence.call(this, 1, true);
24613
24614 if (hexLength > 0) {
24615 eatQuestionMarkSequence.call(this, 6 - hexLength);
24616 }
24617
24618 return;
24619 }
24620
24621 this.error();
24622 }
24623
24624 var UnicodeRange = {
24625 name: 'UnicodeRange',
24626 structure: {
24627 value: String
24628 },
24629 parse: function() {
24630 var start = this.scanner.tokenStart;
24631
24632 // U or u
24633 if (!cmpChar$4(this.scanner.source, start, U$1)) {
24634 this.error('U is expected');
24635 }
24636
24637 if (!cmpChar$4(this.scanner.source, start + 1, PLUSSIGN$6)) {
24638 this.error('Plus sign is expected');
24639 }
24640
24641 this.scanner.next();
24642 scanUnicodeRange.call(this);
24643
24644 return {
24645 type: 'UnicodeRange',
24646 loc: this.getLocation(start, this.scanner.tokenStart),
24647 value: this.scanner.substrToCursor(start)
24648 };
24649 },
24650 generate: function(node) {
24651 this.chunk(node.value);
24652 }
24653 };
24654
24655 var isWhiteSpace$2 = tokenizer.isWhiteSpace;
24656 var cmpStr$4 = tokenizer.cmpStr;
24657 var TYPE$C = tokenizer.TYPE;
24658
24659 var FUNCTION$3 = TYPE$C.Function;
24660 var URL$2 = TYPE$C.Url;
24661 var RIGHTPARENTHESIS$7 = TYPE$C.RightParenthesis;
24662
24663 // <url-token> | <function-token> <string> )
24664 var Url = {
24665 name: 'Url',
24666 structure: {
24667 value: ['String', 'Raw']
24668 },
24669 parse: function() {
24670 var start = this.scanner.tokenStart;
24671 var value;
24672
24673 switch (this.scanner.tokenType) {
24674 case URL$2:
24675 var rawStart = start + 4;
24676 var rawEnd = this.scanner.tokenEnd - 1;
24677
24678 while (rawStart < rawEnd && isWhiteSpace$2(this.scanner.source.charCodeAt(rawStart))) {
24679 rawStart++;
24680 }
24681
24682 while (rawStart < rawEnd && isWhiteSpace$2(this.scanner.source.charCodeAt(rawEnd - 1))) {
24683 rawEnd--;
24684 }
24685
24686 value = {
24687 type: 'Raw',
24688 loc: this.getLocation(rawStart, rawEnd),
24689 value: this.scanner.source.substring(rawStart, rawEnd)
24690 };
24691
24692 this.eat(URL$2);
24693 break;
24694
24695 case FUNCTION$3:
24696 if (!cmpStr$4(this.scanner.source, this.scanner.tokenStart, this.scanner.tokenEnd, 'url(')) {
24697 this.error('Function name must be `url`');
24698 }
24699
24700 this.eat(FUNCTION$3);
24701 this.scanner.skipSC();
24702 value = this.String();
24703 this.scanner.skipSC();
24704 this.eat(RIGHTPARENTHESIS$7);
24705 break;
24706
24707 default:
24708 this.error('Url or Function is expected');
24709 }
24710
24711 return {
24712 type: 'Url',
24713 loc: this.getLocation(start, this.scanner.tokenStart),
24714 value: value
24715 };
24716 },
24717 generate: function(node) {
24718 this.chunk('url');
24719 this.chunk('(');
24720 this.node(node.value);
24721 this.chunk(')');
24722 }
24723 };
24724
24725 var Value = {
24726 name: 'Value',
24727 structure: {
24728 children: [[]]
24729 },
24730 parse: function() {
24731 var start = this.scanner.tokenStart;
24732 var children = this.readSequence(this.scope.Value);
24733
24734 return {
24735 type: 'Value',
24736 loc: this.getLocation(start, this.scanner.tokenStart),
24737 children: children
24738 };
24739 },
24740 generate: function(node) {
24741 this.children(node);
24742 }
24743 };
24744
24745 var WHITESPACE$9 = tokenizer.TYPE.WhiteSpace;
24746 var SPACE$2 = Object.freeze({
24747 type: 'WhiteSpace',
24748 loc: null,
24749 value: ' '
24750 });
24751
24752 var WhiteSpace$1 = {
24753 name: 'WhiteSpace',
24754 structure: {
24755 value: String
24756 },
24757 parse: function() {
24758 this.eat(WHITESPACE$9);
24759 return SPACE$2;
24760
24761 // return {
24762 // type: 'WhiteSpace',
24763 // loc: this.getLocation(this.scanner.tokenStart, this.scanner.tokenEnd),
24764 // value: this.consume(WHITESPACE)
24765 // };
24766 },
24767 generate: function(node) {
24768 this.chunk(node.value);
24769 }
24770 };
24771
24772 var node = {
24773 AnPlusB: AnPlusB,
24774 Atrule: Atrule,
24775 AtrulePrelude: AtrulePrelude,
24776 AttributeSelector: AttributeSelector,
24777 Block: Block,
24778 Brackets: Brackets,
24779 CDC: CDC_1,
24780 CDO: CDO_1,
24781 ClassSelector: ClassSelector,
24782 Combinator: Combinator,
24783 Comment: Comment,
24784 Declaration: Declaration,
24785 DeclarationList: DeclarationList,
24786 Dimension: Dimension,
24787 Function: _Function,
24788 HexColor: HexColor,
24789 Identifier: Identifier,
24790 IdSelector: IdSelector,
24791 MediaFeature: MediaFeature,
24792 MediaQuery: MediaQuery,
24793 MediaQueryList: MediaQueryList,
24794 Nth: Nth,
24795 Number: _Number,
24796 Operator: Operator,
24797 Parentheses: Parentheses,
24798 Percentage: Percentage,
24799 PseudoClassSelector: PseudoClassSelector,
24800 PseudoElementSelector: PseudoElementSelector,
24801 Ratio: Ratio,
24802 Raw: Raw,
24803 Rule: Rule,
24804 Selector: Selector,
24805 SelectorList: SelectorList,
24806 String: _String,
24807 StyleSheet: StyleSheet,
24808 TypeSelector: TypeSelector,
24809 UnicodeRange: UnicodeRange,
24810 Url: Url,
24811 Value: Value,
24812 WhiteSpace: WhiteSpace$1
24813 };
24814
24815 var lexer = {
24816 generic: true,
24817 types: data.types,
24818 atrules: data.atrules,
24819 properties: data.properties,
24820 node: node
24821 };
24822
24823 var cmpChar$5 = tokenizer.cmpChar;
24824 var cmpStr$5 = tokenizer.cmpStr;
24825 var TYPE$D = tokenizer.TYPE;
24826
24827 var IDENT$f = TYPE$D.Ident;
24828 var STRING$2 = TYPE$D.String;
24829 var NUMBER$8 = TYPE$D.Number;
24830 var FUNCTION$4 = TYPE$D.Function;
24831 var URL$3 = TYPE$D.Url;
24832 var HASH$4 = TYPE$D.Hash;
24833 var DIMENSION$6 = TYPE$D.Dimension;
24834 var PERCENTAGE$2 = TYPE$D.Percentage;
24835 var LEFTPARENTHESIS$5 = TYPE$D.LeftParenthesis;
24836 var LEFTSQUAREBRACKET$3 = TYPE$D.LeftSquareBracket;
24837 var COMMA$3 = TYPE$D.Comma;
24838 var DELIM$5 = TYPE$D.Delim;
24839 var NUMBERSIGN$3 = 0x0023; // U+0023 NUMBER SIGN (#)
24840 var ASTERISK$5 = 0x002A; // U+002A ASTERISK (*)
24841 var PLUSSIGN$7 = 0x002B; // U+002B PLUS SIGN (+)
24842 var HYPHENMINUS$5 = 0x002D; // U+002D HYPHEN-MINUS (-)
24843 var SOLIDUS$4 = 0x002F; // U+002F SOLIDUS (/)
24844 var U$2 = 0x0075; // U+0075 LATIN SMALL LETTER U (u)
24845
24846 var _default = function defaultRecognizer(context) {
24847 switch (this.scanner.tokenType) {
24848 case HASH$4:
24849 return this.HexColor();
24850
24851 case COMMA$3:
24852 context.space = null;
24853 context.ignoreWSAfter = true;
24854 return this.Operator();
24855
24856 case LEFTPARENTHESIS$5:
24857 return this.Parentheses(this.readSequence, context.recognizer);
24858
24859 case LEFTSQUAREBRACKET$3:
24860 return this.Brackets(this.readSequence, context.recognizer);
24861
24862 case STRING$2:
24863 return this.String();
24864
24865 case DIMENSION$6:
24866 return this.Dimension();
24867
24868 case PERCENTAGE$2:
24869 return this.Percentage();
24870
24871 case NUMBER$8:
24872 return this.Number();
24873
24874 case FUNCTION$4:
24875 return cmpStr$5(this.scanner.source, this.scanner.tokenStart, this.scanner.tokenEnd, 'url(')
24876 ? this.Url()
24877 : this.Function(this.readSequence, context.recognizer);
24878
24879 case URL$3:
24880 return this.Url();
24881
24882 case IDENT$f:
24883 // check for unicode range, it should start with u+ or U+
24884 if (cmpChar$5(this.scanner.source, this.scanner.tokenStart, U$2) &&
24885 cmpChar$5(this.scanner.source, this.scanner.tokenStart + 1, PLUSSIGN$7)) {
24886 return this.UnicodeRange();
24887 } else {
24888 return this.Identifier();
24889 }
24890
24891 case DELIM$5:
24892 var code = this.scanner.source.charCodeAt(this.scanner.tokenStart);
24893
24894 if (code === SOLIDUS$4 ||
24895 code === ASTERISK$5 ||
24896 code === PLUSSIGN$7 ||
24897 code === HYPHENMINUS$5) {
24898 return this.Operator(); // TODO: replace with Delim
24899 }
24900
24901 // TODO: produce a node with Delim node type
24902
24903 if (code === NUMBERSIGN$3) {
24904 this.error('Hex or identifier is expected', this.scanner.tokenStart + 1);
24905 }
24906
24907 break;
24908 }
24909 };
24910
24911 var atrulePrelude = {
24912 getNode: _default
24913 };
24914
24915 var TYPE$E = tokenizer.TYPE;
24916
24917 var DELIM$6 = TYPE$E.Delim;
24918 var IDENT$g = TYPE$E.Ident;
24919 var DIMENSION$7 = TYPE$E.Dimension;
24920 var PERCENTAGE$3 = TYPE$E.Percentage;
24921 var NUMBER$9 = TYPE$E.Number;
24922 var HASH$5 = TYPE$E.Hash;
24923 var COLON$5 = TYPE$E.Colon;
24924 var LEFTSQUAREBRACKET$4 = TYPE$E.LeftSquareBracket;
24925 var NUMBERSIGN$4 = 0x0023; // U+0023 NUMBER SIGN (#)
24926 var ASTERISK$6 = 0x002A; // U+002A ASTERISK (*)
24927 var PLUSSIGN$8 = 0x002B; // U+002B PLUS SIGN (+)
24928 var SOLIDUS$5 = 0x002F; // U+002F SOLIDUS (/)
24929 var FULLSTOP$2 = 0x002E; // U+002E FULL STOP (.)
24930 var GREATERTHANSIGN$2 = 0x003E; // U+003E GREATER-THAN SIGN (>)
24931 var VERTICALLINE$3 = 0x007C; // U+007C VERTICAL LINE (|)
24932 var TILDE$2 = 0x007E; // U+007E TILDE (~)
24933
24934 function getNode(context) {
24935 switch (this.scanner.tokenType) {
24936 case LEFTSQUAREBRACKET$4:
24937 return this.AttributeSelector();
24938
24939 case HASH$5:
24940 return this.IdSelector();
24941
24942 case COLON$5:
24943 if (this.scanner.lookupType(1) === COLON$5) {
24944 return this.PseudoElementSelector();
24945 } else {
24946 return this.PseudoClassSelector();
24947 }
24948
24949 case IDENT$g:
24950 return this.TypeSelector();
24951
24952 case NUMBER$9:
24953 case PERCENTAGE$3:
24954 return this.Percentage();
24955
24956 case DIMENSION$7:
24957 // throws when .123ident
24958 if (this.scanner.source.charCodeAt(this.scanner.tokenStart) === FULLSTOP$2) {
24959 this.error('Identifier is expected', this.scanner.tokenStart + 1);
24960 }
24961 break;
24962
24963 case DELIM$6:
24964 var code = this.scanner.source.charCodeAt(this.scanner.tokenStart);
24965
24966 switch (code) {
24967 case PLUSSIGN$8:
24968 case GREATERTHANSIGN$2:
24969 case TILDE$2:
24970 context.space = null;
24971 context.ignoreWSAfter = true;
24972 return this.Combinator();
24973
24974 case SOLIDUS$5: // /deep/
24975 return this.Combinator();
24976
24977 case FULLSTOP$2:
24978 return this.ClassSelector();
24979
24980 case ASTERISK$6:
24981 case VERTICALLINE$3:
24982 return this.TypeSelector();
24983
24984 case NUMBERSIGN$4:
24985 return this.IdSelector();
24986 }
24987
24988 break;
24989 }
24990 }
24991 var selector = {
24992 getNode: getNode
24993 };
24994
24995 // https://drafts.csswg.org/css-images-4/#element-notation
24996 // https://developer.mozilla.org/en-US/docs/Web/CSS/element
24997 var element = function() {
24998 this.scanner.skipSC();
24999
25000 var children = this.createSingleNodeList(
25001 this.IdSelector()
25002 );
25003
25004 this.scanner.skipSC();
25005
25006 return children;
25007 };
25008
25009 // legacy IE function
25010 // expression( <any-value> )
25011 var expression = function() {
25012 return this.createSingleNodeList(
25013 this.Raw(this.scanner.tokenIndex, null, false)
25014 );
25015 };
25016
25017 var TYPE$F = tokenizer.TYPE;
25018 var rawMode$5 = Raw.mode;
25019
25020 var COMMA$4 = TYPE$F.Comma;
25021
25022 // var( <ident> , <value>? )
25023 var _var = function() {
25024 var children = this.createList();
25025
25026 this.scanner.skipSC();
25027
25028 // NOTE: Don't check more than a first argument is an ident, rest checks are for lexer
25029 children.push(this.Identifier());
25030
25031 this.scanner.skipSC();
25032
25033 if (this.scanner.tokenType === COMMA$4) {
25034 children.push(this.Operator());
25035 children.push(this.parseCustomProperty
25036 ? this.Value(null)
25037 : this.Raw(this.scanner.tokenIndex, rawMode$5.exclamationMarkOrSemicolon, false)
25038 );
25039 }
25040
25041 return children;
25042 };
25043
25044 var value = {
25045 getNode: _default,
25046 '-moz-element': element,
25047 'element': element,
25048 'expression': expression,
25049 'var': _var
25050 };
25051
25052 var scope = {
25053 AtrulePrelude: atrulePrelude,
25054 Selector: selector,
25055 Value: value
25056 };
25057
25058 var fontFace = {
25059 parse: {
25060 prelude: null,
25061 block: function() {
25062 return this.Block(true);
25063 }
25064 }
25065 };
25066
25067 var TYPE$G = tokenizer.TYPE;
25068
25069 var STRING$3 = TYPE$G.String;
25070 var IDENT$h = TYPE$G.Ident;
25071 var URL$4 = TYPE$G.Url;
25072 var FUNCTION$5 = TYPE$G.Function;
25073 var LEFTPARENTHESIS$6 = TYPE$G.LeftParenthesis;
25074
25075 var _import = {
25076 parse: {
25077 prelude: function() {
25078 var children = this.createList();
25079
25080 this.scanner.skipSC();
25081
25082 switch (this.scanner.tokenType) {
25083 case STRING$3:
25084 children.push(this.String());
25085 break;
25086
25087 case URL$4:
25088 case FUNCTION$5:
25089 children.push(this.Url());
25090 break;
25091
25092 default:
25093 this.error('String or url() is expected');
25094 }
25095
25096 if (this.lookupNonWSType(0) === IDENT$h ||
25097 this.lookupNonWSType(0) === LEFTPARENTHESIS$6) {
25098 children.push(this.WhiteSpace());
25099 children.push(this.MediaQueryList());
25100 }
25101
25102 return children;
25103 },
25104 block: null
25105 }
25106 };
25107
25108 var media = {
25109 parse: {
25110 prelude: function() {
25111 return this.createSingleNodeList(
25112 this.MediaQueryList()
25113 );
25114 },
25115 block: function() {
25116 return this.Block(false);
25117 }
25118 }
25119 };
25120
25121 var page = {
25122 parse: {
25123 prelude: function() {
25124 return this.createSingleNodeList(
25125 this.SelectorList()
25126 );
25127 },
25128 block: function() {
25129 return this.Block(true);
25130 }
25131 }
25132 };
25133
25134 var TYPE$H = tokenizer.TYPE;
25135
25136 var WHITESPACE$a = TYPE$H.WhiteSpace;
25137 var COMMENT$9 = TYPE$H.Comment;
25138 var IDENT$i = TYPE$H.Ident;
25139 var FUNCTION$6 = TYPE$H.Function;
25140 var COLON$6 = TYPE$H.Colon;
25141 var LEFTPARENTHESIS$7 = TYPE$H.LeftParenthesis;
25142
25143 function consumeRaw$5() {
25144 return this.createSingleNodeList(
25145 this.Raw(this.scanner.tokenIndex, null, false)
25146 );
25147 }
25148
25149 function parentheses() {
25150 this.scanner.skipSC();
25151
25152 if (this.scanner.tokenType === IDENT$i &&
25153 this.lookupNonWSType(1) === COLON$6) {
25154 return this.createSingleNodeList(
25155 this.Declaration()
25156 );
25157 }
25158
25159 return readSequence.call(this);
25160 }
25161
25162 function readSequence() {
25163 var children = this.createList();
25164 var space = null;
25165 var child;
25166
25167 this.scanner.skipSC();
25168
25169 scan:
25170 while (!this.scanner.eof) {
25171 switch (this.scanner.tokenType) {
25172 case WHITESPACE$a:
25173 space = this.WhiteSpace();
25174 continue;
25175
25176 case COMMENT$9:
25177 this.scanner.next();
25178 continue;
25179
25180 case FUNCTION$6:
25181 child = this.Function(consumeRaw$5, this.scope.AtrulePrelude);
25182 break;
25183
25184 case IDENT$i:
25185 child = this.Identifier();
25186 break;
25187
25188 case LEFTPARENTHESIS$7:
25189 child = this.Parentheses(parentheses, this.scope.AtrulePrelude);
25190 break;
25191
25192 default:
25193 break scan;
25194 }
25195
25196 if (space !== null) {
25197 children.push(space);
25198 space = null;
25199 }
25200
25201 children.push(child);
25202 }
25203
25204 return children;
25205 }
25206
25207 var supports = {
25208 parse: {
25209 prelude: function() {
25210 var children = readSequence.call(this);
25211
25212 if (this.getFirstListNode(children) === null) {
25213 this.error('Condition is expected');
25214 }
25215
25216 return children;
25217 },
25218 block: function() {
25219 return this.Block(false);
25220 }
25221 }
25222 };
25223
25224 var atrule = {
25225 'font-face': fontFace,
25226 'import': _import,
25227 'media': media,
25228 'page': page,
25229 'supports': supports
25230 };
25231
25232 var dir = {
25233 parse: function() {
25234 return this.createSingleNodeList(
25235 this.Identifier()
25236 );
25237 }
25238 };
25239
25240 var has$1 = {
25241 parse: function() {
25242 return this.createSingleNodeList(
25243 this.SelectorList()
25244 );
25245 }
25246 };
25247
25248 var lang = {
25249 parse: function() {
25250 return this.createSingleNodeList(
25251 this.Identifier()
25252 );
25253 }
25254 };
25255
25256 var selectorList = {
25257 parse: function selectorList() {
25258 return this.createSingleNodeList(
25259 this.SelectorList()
25260 );
25261 }
25262 };
25263
25264 var matches = selectorList;
25265
25266 var not = selectorList;
25267
25268 var ALLOW_OF_CLAUSE = true;
25269
25270 var nthWithOfClause = {
25271 parse: function nthWithOfClause() {
25272 return this.createSingleNodeList(
25273 this.Nth(ALLOW_OF_CLAUSE)
25274 );
25275 }
25276 };
25277
25278 var nthChild = nthWithOfClause;
25279
25280 var nthLastChild = nthWithOfClause;
25281
25282 var DISALLOW_OF_CLAUSE = false;
25283
25284 var nth$1 = {
25285 parse: function nth() {
25286 return this.createSingleNodeList(
25287 this.Nth(DISALLOW_OF_CLAUSE)
25288 );
25289 }
25290 };
25291
25292 var nthLastOfType = nth$1;
25293
25294 var nthOfType = nth$1;
25295
25296 var slotted = {
25297 parse: function compoundSelector() {
25298 return this.createSingleNodeList(
25299 this.Selector()
25300 );
25301 }
25302 };
25303
25304 var pseudo = {
25305 'dir': dir,
25306 'has': has$1,
25307 'lang': lang,
25308 'matches': matches,
25309 'not': not,
25310 'nth-child': nthChild,
25311 'nth-last-child': nthLastChild,
25312 'nth-last-of-type': nthLastOfType,
25313 'nth-of-type': nthOfType,
25314 'slotted': slotted
25315 };
25316
25317 var parser = {
25318 parseContext: {
25319 default: 'StyleSheet',
25320 stylesheet: 'StyleSheet',
25321 atrule: 'Atrule',
25322 atrulePrelude: function(options) {
25323 return this.AtrulePrelude(options.atrule ? String(options.atrule) : null);
25324 },
25325 mediaQueryList: 'MediaQueryList',
25326 mediaQuery: 'MediaQuery',
25327 rule: 'Rule',
25328 selectorList: 'SelectorList',
25329 selector: 'Selector',
25330 block: function() {
25331 return this.Block(true);
25332 },
25333 declarationList: 'DeclarationList',
25334 declaration: 'Declaration',
25335 value: 'Value'
25336 },
25337 scope: scope,
25338 atrule: atrule,
25339 pseudo: pseudo,
25340 node: node
25341 };
25342
25343 var walker = {
25344 node: node
25345 };
25346
25347 function merge() {
25348 var dest = {};
25349
25350 for (var i = 0; i < arguments.length; i++) {
25351 var src = arguments[i];
25352 for (var key in src) {
25353 dest[key] = src[key];
25354 }
25355 }
25356
25357 return dest;
25358 }
25359
25360 var syntax = create$5.create(
25361 merge(
25362 lexer,
25363 parser,
25364 walker
25365 )
25366 );
25367
25368 var lib = syntax;
25369
25370 class Sheet {
25371 constructor(url, hooks) {
25372
25373 if (hooks) {
25374 this.hooks = hooks;
25375 } else {
25376 this.hooks = {};
25377 this.hooks.onUrl = new Hook(this);
25378 this.hooks.onAtPage = new Hook(this);
25379 this.hooks.onAtMedia = new Hook(this);
25380 this.hooks.onRule = new Hook(this);
25381 this.hooks.onDeclaration = new Hook(this);
25382 this.hooks.onSelector = new Hook(this);
25383 this.hooks.onPseudoSelector = new Hook(this);
25384
25385 this.hooks.onContent = new Hook(this);
25386 this.hooks.onImport = new Hook(this);
25387
25388 this.hooks.beforeTreeParse = new Hook(this);
25389 this.hooks.beforeTreeWalk = new Hook(this);
25390 this.hooks.afterTreeWalk = new Hook(this);
25391 }
25392
25393 try {
25394 this.url = new URL(url, window.location.href);
25395 } catch (e) {
25396 this.url = new URL(window.location.href);
25397 }
25398 }
25399
25400
25401
25402 // parse
25403 async parse(text) {
25404 this.text = text;
25405
25406 await this.hooks.beforeTreeParse.trigger(this.text, this);
25407
25408 // send to csstree
25409 this.ast = lib.parse(this._text);
25410
25411 await this.hooks.beforeTreeWalk.trigger(this.ast);
25412
25413 // Replace urls
25414 this.replaceUrls(this.ast);
25415
25416 // Scope
25417 this.id = UUID();
25418 // this.addScope(this.ast, this.uuid);
25419
25420 // Replace IDs with data-id
25421 this.replaceIds(this.ast);
25422
25423 this.imported = [];
25424
25425 // Trigger Hooks
25426 this.urls(this.ast);
25427 this.rules(this.ast);
25428 this.atrules(this.ast);
25429
25430 await this.hooks.afterTreeWalk.trigger(this.ast, this);
25431
25432 // return ast
25433 return this.ast;
25434 }
25435
25436
25437
25438 insertRule(rule) {
25439 let inserted = this.ast.children.appendData(rule);
25440 inserted.forEach((item) => {
25441 this.declarations(item);
25442 });
25443 }
25444
25445 urls(ast) {
25446 lib.walk(ast, {
25447 visit: "Url",
25448 enter: (node, item, list) => {
25449 this.hooks.onUrl.trigger(node, item, list);
25450 }
25451 });
25452 }
25453
25454 atrules(ast) {
25455 lib.walk(ast, {
25456 visit: "Atrule",
25457 enter: (node, item, list) => {
25458 const basename = lib.keyword(node.name).basename;
25459
25460 if (basename === "page") {
25461 this.hooks.onAtPage.trigger(node, item, list);
25462 this.declarations(node, item, list);
25463 }
25464
25465 if (basename === "media") {
25466 this.hooks.onAtMedia.trigger(node, item, list);
25467 this.declarations(node, item, list);
25468 }
25469
25470 if (basename === "import") {
25471 this.hooks.onImport.trigger(node, item, list);
25472 this.imports(node, item, list);
25473 }
25474 }
25475 });
25476 }
25477
25478
25479 rules(ast) {
25480 lib.walk(ast, {
25481 visit: "Rule",
25482 enter: (ruleNode, ruleItem, rulelist) => {
25483 // console.log("rule", ruleNode);
25484
25485 this.hooks.onRule.trigger(ruleNode, ruleItem, rulelist);
25486 this.declarations(ruleNode, ruleItem, rulelist);
25487 this.onSelector(ruleNode, ruleItem, rulelist);
25488
25489 }
25490 });
25491 }
25492
25493 declarations(ruleNode, ruleItem, rulelist) {
25494 lib.walk(ruleNode, {
25495 visit: "Declaration",
25496 enter: (declarationNode, dItem, dList) => {
25497 // console.log(declarationNode);
25498
25499 this.hooks.onDeclaration.trigger(declarationNode, dItem, dList, {ruleNode, ruleItem, rulelist});
25500
25501 if (declarationNode.property === "content") {
25502 lib.walk(declarationNode, {
25503 visit: "Function",
25504 enter: (funcNode, fItem, fList) => {
25505 this.hooks.onContent.trigger(funcNode, fItem, fList, {declarationNode, dItem, dList}, {ruleNode, ruleItem, rulelist});
25506 }
25507 });
25508 }
25509
25510 }
25511 });
25512 }
25513
25514 // add pseudo elements to parser
25515 onSelector(ruleNode, ruleItem, rulelist) {
25516 lib.walk(ruleNode, {
25517 visit: "Selector",
25518 enter: (selectNode, selectItem, selectList) => {
25519 // console.log(selectNode);
25520 this.hooks.onSelector.trigger(selectNode, selectItem, selectList, {ruleNode, ruleItem, rulelist});
25521
25522 if (selectNode.children.forEach(node => {if (node.type === "PseudoElementSelector") {
25523 lib.walk(node, {
25524 visit: "PseudoElementSelector",
25525 enter: (pseudoNode, pItem, pList) => {
25526 this.hooks.onPseudoSelector.trigger(pseudoNode, pItem, pList, {selectNode, selectItem, selectList}, {ruleNode, ruleItem, rulelist});
25527 }
25528 });
25529 }}));
25530 // else {
25531 // console.log("dommage");
25532 // }
25533
25534 }
25535 });
25536 }
25537
25538 replaceUrls(ast) {
25539 lib.walk(ast, {
25540 visit: "Url",
25541 enter: (node, item, list) => {
25542 let content = node.value.value;
25543 if ((node.value.type === "Raw" && content.startsWith("data:")) || (node.value.type === "String" && (content.startsWith("\"data:") || content.startsWith("'data:")))) ; else {
25544 let href = content.replace(/["']/g, "");
25545 let url = new URL(href, this.url);
25546 node.value.value = url.toString();
25547 }
25548 }
25549 });
25550 }
25551
25552 addScope(ast, id) {
25553 // Get all selector lists
25554 // add an id
25555 lib.walk(ast, {
25556 visit: "Selector",
25557 enter: (node, item, list) => {
25558 let children = node.children;
25559 children.prepend(children.createItem({
25560 type: "WhiteSpace",
25561 value: " "
25562 }));
25563 children.prepend(children.createItem({
25564 type: "IdSelector",
25565 name: id,
25566 loc: null,
25567 children: null
25568 }));
25569 }
25570 });
25571 }
25572
25573 getNamedPageSelectors(ast) {
25574 let namedPageSelectors = {};
25575 lib.walk(ast, {
25576 visit: "Rule",
25577 enter: (node, item, list) => {
25578 lib.walk(node, {
25579 visit: "Declaration",
25580 enter: (declaration, dItem, dList) => {
25581 if (declaration.property === "page") {
25582 let value = declaration.value.children.first();
25583 let name = value.name;
25584 let selector = lib.generate(node.prelude);
25585 namedPageSelectors[name] = {
25586 name: name,
25587 selector: selector
25588 };
25589
25590 // dList.remove(dItem);
25591
25592 // Add in page break
25593 declaration.property = "break-before";
25594 value.type = "Identifier";
25595 value.name = "always";
25596
25597 }
25598 }
25599 });
25600 }
25601 });
25602 return namedPageSelectors;
25603 }
25604
25605 replaceIds(ast) {
25606 lib.walk(ast, {
25607 visit: "Rule",
25608 enter: (node, item, list) => {
25609
25610 lib.walk(node, {
25611 visit: "IdSelector",
25612 enter: (idNode, idItem, idList) => {
25613 let name = idNode.name;
25614 idNode.flags = null;
25615 idNode.matcher = "=";
25616 idNode.name = {type: "Identifier", loc: null, name: "data-id"};
25617 idNode.type = "AttributeSelector";
25618 idNode.value = {type: "String", loc: null, value: `"${name}"`};
25619 }
25620 });
25621 }
25622 });
25623 }
25624
25625 imports(node, item, list) {
25626 // console.log("import", node, item, list);
25627 let queries = [];
25628 lib.walk(node, {
25629 visit: "MediaQuery",
25630 enter: (mqNode, mqItem, mqList) => {
25631 lib.walk(mqNode, {
25632 visit: "Identifier",
25633 enter: (identNode, identItem, identList) => {
25634 queries.push(identNode.name);
25635 }
25636 });
25637 }
25638 });
25639
25640 // Just basic media query support for now
25641 let shouldNotApply = queries.some((query, index) => {
25642 let q = query;
25643 if (q === "not") {
25644 q = queries[index + 1];
25645 return !(q === "screen" || q === "speech");
25646 } else {
25647 return (q === "screen" || q === "speech");
25648 }
25649 });
25650
25651 if (shouldNotApply) {
25652 return;
25653 }
25654
25655 lib.walk(node, {
25656 visit: "String",
25657 enter: (urlNode, urlItem, urlList) => {
25658 let href = urlNode.value.replace(/["']/g, "");
25659 let url = new URL(href, this.url);
25660 let value = url.toString();
25661
25662 this.imported.push(value);
25663
25664 // Remove the original
25665 list.remove(item);
25666 }
25667 });
25668 }
25669
25670 set text(t) {
25671 this._text = t;
25672 }
25673
25674 get text() {
25675 return this._text;
25676 }
25677
25678 // generate string
25679 toString(ast) {
25680 return lib.generate(ast || this.ast);
25681 }
25682 }
25683
25684 var baseStyles = `
25685:root {
25686 --pagedjs-width: 8.5in;
25687 --pagedjs-height: 11in;
25688 --pagedjs-width-right: 8.5in;
25689 --pagedjs-height-right: 11in;
25690 --pagedjs-width-left: 8.5in;
25691 --pagedjs-height-left: 11in;
25692 --pagedjs-pagebox-width: 8.5in;
25693 --pagedjs-pagebox-height: 11in;
25694 --pagedjs-margin-top: 1in;
25695 --pagedjs-margin-right: 1in;
25696 --pagedjs-margin-bottom: 1in;
25697 --pagedjs-margin-left: 1in;
25698 --pagedjs-padding-top: 0mm;
25699 --pagedjs-padding-right: 0mm;
25700 --pagedjs-padding-bottom: 0mm;
25701 --pagedjs-padding-left: 0mm;
25702 --pagedjs-border-top: 0mm;
25703 --pagedjs-border-right: 0mm;
25704 --pagedjs-border-bottom: 0mm;
25705 --pagedjs-border-left: 0mm;
25706 --pagedjs-bleed-top: 0mm;
25707 --pagedjs-bleed-right: 0mm;
25708 --pagedjs-bleed-bottom: 0mm;
25709 --pagedjs-bleed-left: 0mm;
25710 --pagedjs-bleed-right-top: 0mm;
25711 --pagedjs-bleed-right-right: 0mm;
25712 --pagedjs-bleed-right-bottom: 0mm;
25713 --pagedjs-bleed-right-left: 0mm;
25714 --pagedjs-bleed-left-top: 0mm;
25715 --pagedjs-bleed-left-right: 0mm;
25716 --pagedjs-bleed-left-bottom: 0mm;
25717 --pagedjs-bleed-left-left: 0mm;
25718 --pagedjs-crop-color: black;
25719 --pagedjs-crop-offset: 2mm;
25720 --pagedjs-crop-stroke: 1px;
25721 --pagedjs-cross-size: 5mm;
25722 --pagedjs-mark-cross-display: none;
25723 --pagedjs-mark-crop-display: none;
25724 --pagedjs-page-count: 0;
25725 --pagedjs-page-counter-increment: 1;
25726}
25727
25728@page {
25729 size: letter;
25730 margin: 0;
25731}
25732
25733.pagedjs_sheet {
25734 box-sizing: border-box;
25735 width: var(--pagedjs-width);
25736 height: var(--pagedjs-height);
25737 overflow: hidden;
25738 position: relative;
25739 display: grid;
25740 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);
25741 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);
25742}
25743
25744.pagedjs_right_page .pagedjs_sheet {
25745 width: var(--pagedjs-width-right);
25746 height: var(--pagedjs-height-right);
25747 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);
25748 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);
25749}
25750
25751.pagedjs_left_page .pagedjs_sheet {
25752 width: var(--pagedjs-width-left);
25753 height: var(--pagedjs-height-left);
25754 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);
25755 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);
25756}
25757
25758.pagedjs_bleed {
25759 display: flex;
25760 align-items: center;
25761 justify-content: center;
25762 flex-wrap: nowrap;
25763 overflow: hidden;
25764}
25765
25766.pagedjs_bleed-top {
25767 grid-column: bleed-left / -1;
25768 grid-row: bleed-top;
25769 flex-direction: row;
25770}
25771
25772.pagedjs_bleed-bottom {
25773 grid-column: bleed-left / -1;
25774 grid-row: bleed-bottom;
25775 flex-direction: row;
25776}
25777
25778.pagedjs_bleed-left {
25779 grid-column: bleed-left;
25780 grid-row: bleed-top / -1;
25781 flex-direction: column;
25782}
25783
25784.pagedjs_bleed-right {
25785 grid-column: bleed-right;
25786 grid-row: bleed-top / -1;
25787 flex-direction: column;
25788}
25789
25790.pagedjs_marks-crop {
25791 display: var(--pagedjs-mark-crop-display);
25792 flex-grow: 0;
25793 flex-shrink: 0;
25794 z-index: 9999999999;
25795}
25796
25797.pagedjs_bleed-top .pagedjs_marks-crop:nth-child(1),
25798.pagedjs_bleed-bottom .pagedjs_marks-crop:nth-child(1) {
25799 width: calc(var(--pagedjs-bleed-left) - var(--pagedjs-crop-stroke));
25800 border-right: var(--pagedjs-crop-stroke) solid var(--pagedjs-crop-color);
25801}
25802
25803.pagedjs_right_page .pagedjs_bleed-top .pagedjs_marks-crop:nth-child(1),
25804.pagedjs_right_page .pagedjs_bleed-bottom .pagedjs_marks-crop:nth-child(1) {
25805 width: calc(var(--pagedjs-bleed-right-left) - var(--pagedjs-crop-stroke));
25806}
25807
25808.pagedjs_left_page .pagedjs_bleed-top .pagedjs_marks-crop:nth-child(1),
25809.pagedjs_left_page .pagedjs_bleed-bottom .pagedjs_marks-crop:nth-child(1) {
25810 width: calc(var(--pagedjs-bleed-left-left) - var(--pagedjs-crop-stroke));
25811}
25812
25813.pagedjs_bleed-top .pagedjs_marks-crop:nth-child(3),
25814.pagedjs_bleed-bottom .pagedjs_marks-crop:nth-child(3) {
25815 width: calc(var(--pagedjs-bleed-right) - var(--pagedjs-crop-stroke));
25816 border-left: var(--pagedjs-crop-stroke) solid var(--pagedjs-crop-color);
25817}
25818
25819.pagedjs_right_page .pagedjs_bleed-top .pagedjs_marks-crop:nth-child(3),
25820.pagedjs_right_page .pagedjs_bleed-bottom .pagedjs_marks-crop:nth-child(3) {
25821 width: calc(var(--pagedjs-bleed-right-right) - var(--pagedjs-crop-stroke));
25822}
25823
25824.pagedjs_left_page .pagedjs_bleed-top .pagedjs_marks-crop:nth-child(3),
25825.pagedjs_left_page .pagedjs_bleed-bottom .pagedjs_marks-crop:nth-child(3) {
25826 width: calc(var(--pagedjs-bleed-left-right) - var(--pagedjs-crop-stroke));
25827}
25828
25829.pagedjs_bleed-top .pagedjs_marks-crop {
25830 align-self: flex-start;
25831 height: calc(var(--pagedjs-bleed-top) - var(--pagedjs-crop-offset));
25832}
25833
25834.pagedjs_right_page .pagedjs_bleed-top .pagedjs_marks-crop {
25835 height: calc(var(--pagedjs-bleed-right-top) - var(--pagedjs-crop-offset));
25836}
25837
25838.pagedjs_left_page .pagedjs_bleed-top .pagedjs_marks-crop {
25839 height: calc(var(--pagedjs-bleed-left-top) - var(--pagedjs-crop-offset));
25840}
25841
25842.pagedjs_bleed-bottom .pagedjs_marks-crop {
25843 align-self: flex-end;
25844 height: calc(var(--pagedjs-bleed-bottom) - var(--pagedjs-crop-offset));
25845}
25846
25847.pagedjs_right_page .pagedjs_bleed-bottom .pagedjs_marks-crop {
25848 height: calc(var(--pagedjs-bleed-right-bottom) - var(--pagedjs-crop-offset));
25849}
25850
25851.pagedjs_left_page .pagedjs_bleed-bottom .pagedjs_marks-crop {
25852 height: calc(var(--pagedjs-bleed-left-bottom) - var(--pagedjs-crop-offset));
25853}
25854
25855.pagedjs_bleed-left .pagedjs_marks-crop:nth-child(1),
25856.pagedjs_bleed-right .pagedjs_marks-crop:nth-child(1) {
25857 height: calc(var(--pagedjs-bleed-top) - var(--pagedjs-crop-stroke));
25858 border-bottom: var(--pagedjs-crop-stroke) solid var(--pagedjs-crop-color);
25859}
25860
25861.pagedjs_right_page .pagedjs_bleed-left .pagedjs_marks-crop:nth-child(1),
25862.pagedjs_right_page .pagedjs_bleed-right .pagedjs_marks-crop:nth-child(1) {
25863 height: calc(var(--pagedjs-bleed-right-top) - var(--pagedjs-crop-stroke));
25864}
25865
25866.pagedjs_left_page .pagedjs_bleed-left .pagedjs_marks-crop:nth-child(1),
25867.pagedjs_left_page .pagedjs_bleed-right .pagedjs_marks-crop:nth-child(1) {
25868 height: calc(var(--pagedjs-bleed-left-top) - var(--pagedjs-crop-stroke));
25869}
25870
25871.pagedjs_bleed-left .pagedjs_marks-crop:nth-child(3),
25872.pagedjs_bleed-right .pagedjs_marks-crop:nth-child(3) {
25873 height: calc(var(--pagedjs-bleed-bottom) - var(--pagedjs-crop-stroke));
25874 border-top: var(--pagedjs-crop-stroke) solid var(--pagedjs-crop-color);
25875}
25876
25877.pagedjs_right_page .pagedjs_bleed-left .pagedjs_marks-crop:nth-child(3),
25878.pagedjs_right_page .pagedjs_bleed-right .pagedjs_marks-crop:nth-child(3) {
25879 height: calc(var(--pagedjs-bleed-right-bottom) - var(--pagedjs-crop-stroke));
25880}
25881
25882.pagedjs_left_page .pagedjs_bleed-left .pagedjs_marks-crop:nth-child(3),
25883.pagedjs_left_page .pagedjs_bleed-right .pagedjs_marks-crop:nth-child(3) {
25884 height: calc(var(--pagedjs-bleed-left-bottom) - var(--pagedjs-crop-stroke));
25885}
25886
25887.pagedjs_bleed-left .pagedjs_marks-crop {
25888 width: calc(var(--pagedjs-bleed-left) - var(--pagedjs-crop-offset));
25889 align-self: flex-start;
25890}
25891
25892.pagedjs_right_page .pagedjs_bleed-left .pagedjs_marks-crop {
25893 width: calc(var(--pagedjs-bleed-right-left) - var(--pagedjs-crop-offset));
25894}
25895
25896.pagedjs_left_page .pagedjs_bleed-left .pagedjs_marks-crop {
25897 width: calc(var(--pagedjs-bleed-left-left) - var(--pagedjs-crop-offset));
25898}
25899
25900.pagedjs_bleed-right .pagedjs_marks-crop {
25901 width: calc(var(--pagedjs-bleed-right) - var(--pagedjs-crop-offset));
25902 align-self: flex-end;
25903}
25904
25905.pagedjs_right_page .pagedjs_bleed-right .pagedjs_marks-crop {
25906 width: calc(var(--pagedjs-bleed-right-right) - var(--pagedjs-crop-offset));
25907}
25908
25909.pagedjs_left_page .pagedjs_bleed-right .pagedjs_marks-crop {
25910 width: calc(var(--pagedjs-bleed-left-right) - var(--pagedjs-crop-offset));
25911}
25912
25913.pagedjs_marks-middle {
25914 display: flex;
25915 flex-grow: 1;
25916 flex-shrink: 0;
25917 align-items: center;
25918 justify-content: center;
25919}
25920
25921.pagedjs_marks-cross {
25922 display: var(--pagedjs-mark-cross-display);
25923 background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iTGF5ZXJfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiIHdpZHRoPSIzMi41MzdweCIgaGVpZ2h0PSIzMi41MzdweCIgdmlld0JveD0iMC4xMDQgMC4xMDQgMzIuNTM3IDMyLjUzNyIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwLjEwNCAwLjEwNCAzMi41MzcgMzIuNTM3IiB4bWw6c3BhY2U9InByZXNlcnZlIj48cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IiNGRkZGRkYiIHN0cm9rZS13aWR0aD0iMy4zODkzIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIGQ9Ik0yOS45MzEsMTYuMzczYzAsNy40ODktNi4wNjgsMTMuNTYtMTMuNTU4LDEzLjU2Yy03LjQ4MywwLTEzLjU1Ny02LjA3Mi0xMy41NTctMTMuNTZjMC03LjQ4Niw2LjA3NC0xMy41NTQsMTMuNTU3LTEzLjU1NEMyMy44NjIsMi44MTksMjkuOTMxLDguODg3LDI5LjkzMSwxNi4zNzN6Ii8+PGxpbmUgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjRkZGRkZGIiBzdHJva2Utd2lkdGg9IjMuMzg5MyIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiB4MT0iMC4xMDQiIHkxPSIxNi4zNzMiIHgyPSIzMi42NDIiIHkyPSIxNi4zNzMiLz48bGluZSBmaWxsPSJub25lIiBzdHJva2U9IiNGRkZGRkYiIHN0cm9rZS13aWR0aD0iMy4zODkzIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHgxPSIxNi4zNzMiIHkxPSIwLjEwNCIgeDI9IjE2LjM3MyIgeTI9IjMyLjY0MiIvPjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iI0ZGRkZGRiIgc3Ryb2tlLXdpZHRoPSIzLjM4OTMiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgZD0iTTI0LjUwOCwxNi4zNzNjMCw0LjQ5Ni0zLjYzOCw4LjEzNS04LjEzNSw4LjEzNWMtNC40OTEsMC04LjEzNS0zLjYzOC04LjEzNS04LjEzNWMwLTQuNDg5LDMuNjQ0LTguMTM1LDguMTM1LTguMTM1QzIwLjg2OSw4LjIzOSwyNC41MDgsMTEuODg0LDI0LjUwOCwxNi4zNzN6Ii8+PHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwMDAwIiBzdHJva2Utd2lkdGg9IjAuNjc3OCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBkPSJNMjkuOTMxLDE2LjM3M2MwLDcuNDg5LTYuMDY4LDEzLjU2LTEzLjU1OCwxMy41NmMtNy40ODMsMC0xMy41NTctNi4wNzItMTMuNTU3LTEzLjU2YzAtNy40ODYsNi4wNzQtMTMuNTU0LDEzLjU1Ny0xMy41NTRDMjMuODYyLDIuODE5LDI5LjkzMSw4Ljg4NywyOS45MzEsMTYuMzczeiIvPjxsaW5lIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMDAwMCIgc3Ryb2tlLXdpZHRoPSIwLjY3NzgiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgeDE9IjAuMTA0IiB5MT0iMTYuMzczIiB4Mj0iMzIuNjQyIiB5Mj0iMTYuMzczIi8+PGxpbmUgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwMDAwIiBzdHJva2Utd2lkdGg9IjAuNjc3OCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiB4MT0iMTYuMzczIiB5MT0iMC4xMDQiIHgyPSIxNi4zNzMiIHkyPSIzMi42NDIiLz48cGF0aCBkPSJNMjQuNTA4LDE2LjM3M2MwLDQuNDk2LTMuNjM4LDguMTM1LTguMTM1LDguMTM1Yy00LjQ5MSwwLTguMTM1LTMuNjM4LTguMTM1LTguMTM1YzAtNC40ODksMy42NDQtOC4xMzUsOC4xMzUtOC4xMzVDMjAuODY5LDguMjM5LDI0LjUwOCwxMS44ODQsMjQuNTA4LDE2LjM3MyIvPjxsaW5lIGZpbGw9Im5vbmUiIHN0cm9rZT0iI0ZGRkZGRiIgc3Ryb2tlLXdpZHRoPSIwLjY3NzgiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgeDE9IjguMjM5IiB5MT0iMTYuMzczIiB4Mj0iMjQuNTA4IiB5Mj0iMTYuMzczIi8+PGxpbmUgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjRkZGRkZGIiBzdHJva2Utd2lkdGg9IjAuNjc3OCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiB4MT0iMTYuMzczIiB5MT0iOC4yMzkiIHgyPSIxNi4zNzMiIHkyPSIyNC41MDgiLz48L3N2Zz4=);
25924 background-repeat: no-repeat;
25925 background-position: 50% 50%;
25926 background-size: var(--pagedjs-cross-size);
25927
25928 z-index: 2147483647;
25929 width: var(--pagedjs-cross-size);
25930 height: var(--pagedjs-cross-size);
25931}
25932
25933.pagedjs_pagebox {
25934 box-sizing: border-box;
25935 width: var(--pagedjs-pagebox-width);
25936 height: var(--pagedjs-pagebox-height);
25937 position: relative;
25938 display: grid;
25939 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);
25940 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);
25941 grid-column: sheet-center;
25942 grid-row: sheet-middle;
25943}
25944
25945.pagedjs_pagebox * {
25946 box-sizing: border-box;
25947}
25948
25949.pagedjs_margin-top {
25950 width: calc(var(--pagedjs-pagebox-width) - var(--pagedjs-margin-left) - var(--pagedjs-margin-right));
25951 height: var(--pagedjs-margin-top);
25952 grid-column: center;
25953 grid-row: header;
25954 flex-wrap: nowrap;
25955 display: grid;
25956 grid-template-columns: repeat(3, 1fr);
25957 grid-template-rows: 100%;
25958}
25959
25960.pagedjs_margin-top-left-corner-holder {
25961 width: var(--pagedjs-margin-left);
25962 height: var(--pagedjs-margin-top);
25963 display: flex;
25964 grid-column: left;
25965 grid-row: header;
25966}
25967
25968.pagedjs_margin-top-right-corner-holder {
25969 width: var(--pagedjs-margin-right);
25970 height: var(--pagedjs-margin-top);
25971 display: flex;
25972 grid-column: right;
25973 grid-row: header;
25974}
25975
25976.pagedjs_margin-top-left-corner {
25977 width: var(--pagedjs-margin-left);
25978}
25979
25980.pagedjs_margin-top-right-corner {
25981 width: var(--pagedjs-margin-right);
25982}
25983
25984.pagedjs_margin-right {
25985 height: calc(var(--pagedjs-pagebox-height) - var(--pagedjs-margin-top) - var(--pagedjs-margin-bottom));
25986 width: var(--pagedjs-margin-right);
25987 right: 0;
25988 grid-column: right;
25989 grid-row: page;
25990 display: grid;
25991 grid-template-rows: repeat(3, 33.3333%);
25992 grid-template-columns: 100%;
25993}
25994
25995.pagedjs_margin-bottom {
25996 width: calc(var(--pagedjs-pagebox-width) - var(--pagedjs-margin-left) - var(--pagedjs-margin-right));
25997 height: var(--pagedjs-margin-bottom);
25998 grid-column: center;
25999 grid-row: footer;
26000 display: grid;
26001 grid-template-columns: repeat(3, 1fr);
26002 grid-template-rows: 100%;
26003}
26004
26005.pagedjs_margin-bottom-left-corner-holder {
26006 width: var(--pagedjs-margin-left);
26007 height: var(--pagedjs-margin-bottom);
26008 display: flex;
26009 grid-column: left;
26010 grid-row: footer;
26011}
26012
26013.pagedjs_margin-bottom-right-corner-holder {
26014 width: var(--pagedjs-margin-right);
26015 height: var(--pagedjs-margin-bottom);
26016 display: flex;
26017 grid-column: right;
26018 grid-row: footer;
26019}
26020
26021.pagedjs_margin-bottom-left-corner {
26022 width: var(--pagedjs-margin-left);
26023}
26024
26025.pagedjs_margin-bottom-right-corner {
26026 width: var(--pagedjs-margin-right);
26027}
26028
26029
26030
26031.pagedjs_margin-left {
26032 height: calc(var(--pagedjs-pagebox-height) - var(--pagedjs-margin-top) - var(--pagedjs-margin-bottom));
26033 width: var(--pagedjs-margin-left);
26034 grid-column: left;
26035 grid-row: page;
26036 display: grid;
26037 grid-template-rows: repeat(3, 33.33333%);
26038 grid-template-columns: 100%;
26039}
26040
26041.pagedjs_pages .pagedjs_pagebox .pagedjs_margin:not(.hasContent) {
26042 visibility: hidden;
26043}
26044
26045.pagedjs_pagebox > .pagedjs_area {
26046 grid-column: center;
26047 grid-row: page;
26048 width: 100%;
26049 height: 100%;
26050 padding: var(--pagedjs-padding-top) var(--pagedjs-padding-right) var(--pagedjs-padding-bottom) var(--pagedjs-padding-left);
26051 border-top: var(--pagedjs-border-top);
26052 border-right: var(--pagedjs-border-right);
26053 border-bottom: var(--pagedjs-border-bottom);
26054 border-left: var(--pagedjs-border-left);
26055}
26056
26057.pagedjs_pagebox > .pagedjs_area > .pagedjs_page_content {
26058 width: 100%;
26059 height: 100%;
26060 position: relative;
26061 column-fill: auto;
26062}
26063
26064.pagedjs_page {
26065 counter-increment: page var(--pagedjs-page-counter-increment);
26066 width: var(--pagedjs-width);
26067 height: var(--pagedjs-height);
26068}
26069
26070.pagedjs_page.pagedjs_right_page {
26071 width: var(--pagedjs-width-right);
26072 height: var(--pagedjs-height-right);
26073}
26074
26075.pagedjs_page.pagedjs_left_page {
26076 width: var(--pagedjs-width-left);
26077 height: var(--pagedjs-height-left);
26078}
26079
26080.pagedjs_pages {
26081 counter-reset: pages var(--pagedjs-page-count);
26082}
26083
26084.pagedjs_pagebox .pagedjs_margin-top-left-corner,
26085.pagedjs_pagebox .pagedjs_margin-top-right-corner,
26086.pagedjs_pagebox .pagedjs_margin-bottom-left-corner,
26087.pagedjs_pagebox .pagedjs_margin-bottom-right-corner,
26088.pagedjs_pagebox .pagedjs_margin-top-left,
26089.pagedjs_pagebox .pagedjs_margin-top-right,
26090.pagedjs_pagebox .pagedjs_margin-bottom-left,
26091.pagedjs_pagebox .pagedjs_margin-bottom-right,
26092.pagedjs_pagebox .pagedjs_margin-top-center,
26093.pagedjs_pagebox .pagedjs_margin-bottom-center,
26094.pagedjs_pagebox .pagedjs_margin-top-center,
26095.pagedjs_pagebox .pagedjs_margin-bottom-center,
26096.pagedjs_margin-right-middle,
26097.pagedjs_margin-left-middle {
26098 display: flex;
26099 align-items: center;
26100}
26101
26102.pagedjs_margin-right-top,
26103.pagedjs_margin-left-top {
26104 display: flex;
26105 align-items: flex-top;
26106}
26107
26108
26109.pagedjs_margin-right-bottom,
26110.pagedjs_margin-left-bottom {
26111 display: flex;
26112 align-items: flex-end;
26113}
26114
26115
26116
26117/*
26118.pagedjs_pagebox .pagedjs_margin-top-center,
26119.pagedjs_pagebox .pagedjs_margin-bottom-center {
26120 height: 100%;
26121 display: none;
26122 align-items: center;
26123 flex: 1 0 33%;
26124 margin: 0 auto;
26125}
26126
26127.pagedjs_pagebox .pagedjs_margin-top-left-corner,
26128.pagedjs_pagebox .pagedjs_margin-top-right-corner,
26129.pagedjs_pagebox .pagedjs_margin-bottom-right-corner,
26130.pagedjs_pagebox .pagedjs_margin-bottom-left-corner {
26131 display: none;
26132 align-items: center;
26133}
26134
26135.pagedjs_pagebox .pagedjs_margin-left-top,
26136.pagedjs_pagebox .pagedjs_margin-right-top {
26137 display: none;
26138 align-items: flex-start;
26139}
26140
26141.pagedjs_pagebox .pagedjs_margin-right-middle,
26142.pagedjs_pagebox .pagedjs_margin-left-middle {
26143 display: none;
26144 align-items: center;
26145}
26146
26147.pagedjs_pagebox .pagedjs_margin-left-bottom,
26148.pagedjs_pagebox .pagedjs_margin-right-bottom {
26149 display: none;
26150 align-items: flex-end;
26151}
26152*/
26153
26154.pagedjs_pagebox .pagedjs_margin-top-left,
26155.pagedjs_pagebox .pagedjs_margin-top-right-corner,
26156.pagedjs_pagebox .pagedjs_margin-bottom-left,
26157.pagedjs_pagebox .pagedjs_margin-bottom-right-corner { text-align: left; }
26158
26159.pagedjs_pagebox .pagedjs_margin-top-left-corner,
26160.pagedjs_pagebox .pagedjs_margin-top-right,
26161.pagedjs_pagebox .pagedjs_margin-bottom-left-corner,
26162.pagedjs_pagebox .pagedjs_margin-bottom-right { text-align: right; }
26163
26164.pagedjs_pagebox .pagedjs_margin-top-center,
26165.pagedjs_pagebox .pagedjs_margin-bottom-center,
26166.pagedjs_pagebox .pagedjs_margin-left-top,
26167.pagedjs_pagebox .pagedjs_margin-left-middle,
26168.pagedjs_pagebox .pagedjs_margin-left-bottom,
26169.pagedjs_pagebox .pagedjs_margin-right-top,
26170.pagedjs_pagebox .pagedjs_margin-right-middle,
26171.pagedjs_pagebox .pagedjs_margin-right-bottom { text-align: center; }
26172
26173.pagedjs_pages .pagedjs_margin .pagedjs_margin-content {
26174 width: 100%;
26175}
26176
26177.pagedjs_pages .pagedjs_margin-left .pagedjs_margin-content::after,
26178.pagedjs_pages .pagedjs_margin-top .pagedjs_margin-content::after,
26179.pagedjs_pages .pagedjs_margin-right .pagedjs_margin-content::after,
26180.pagedjs_pages .pagedjs_margin-bottom .pagedjs_margin-content::after {
26181 display: block;
26182}
26183
26184.pagedjs_pages > .pagedjs_page > .pagedjs_sheet > .pagedjs_pagebox > .pagedjs_area > div [data-split-to] {
26185 margin-bottom: unset;
26186 padding-bottom: unset;
26187}
26188
26189.pagedjs_pages > .pagedjs_page > .pagedjs_sheet > .pagedjs_pagebox > .pagedjs_area > div [data-split-from] {
26190 text-indent: unset;
26191 margin-top: unset;
26192 padding-top: unset;
26193 initial-letter: unset;
26194}
26195
26196.pagedjs_pages > .pagedjs_page > .pagedjs_sheet > .pagedjs_pagebox > .pagedjs_area > div [data-split-from] > *::first-letter,
26197.pagedjs_pages > .pagedjs_page > .pagedjs_sheet > .pagedjs_pagebox > .pagedjs_area > div [data-split-from]::first-letter {
26198 color: unset;
26199 font-size: unset;
26200 font-weight: unset;
26201 font-family: unset;
26202 color: unset;
26203 line-height: unset;
26204 float: unset;
26205 padding: unset;
26206 margin: unset;
26207}
26208
26209.pagedjs_pages > .pagedjs_page > .pagedjs_sheet > .pagedjs_pagebox > .pagedjs_area > div [data-split-to]:after,
26210.pagedjs_pages > .pagedjs_page > .pagedjs_sheet > .pagedjs_pagebox > .pagedjs_area > div [data-split-to]::after {
26211 content: unset;
26212}
26213
26214.pagedjs_pages > .pagedjs_page > .pagedjs_sheet > .pagedjs_pagebox > .pagedjs_area > div [data-split-from]:before,
26215.pagedjs_pages > .pagedjs_page > .pagedjs_sheet > .pagedjs_pagebox > .pagedjs_area > div [data-split-from]::before {
26216 content: unset;
26217}
26218
26219.pagedjs_pages > .pagedjs_page > .pagedjs_sheet > .pagedjs_pagebox > .pagedjs_area > div li[data-split-from]:first-of-type {
26220 list-style: none;
26221}
26222
26223/*
26224[data-page]:not([data-split-from]),
26225[data-break-before="page"]:not([data-split-from]),
26226[data-break-before="always"]:not([data-split-from]),
26227[data-break-before="left"]:not([data-split-from]),
26228[data-break-before="right"]:not([data-split-from]),
26229[data-break-before="recto"]:not([data-split-from]),
26230[data-break-before="verso"]:not([data-split-from])
26231{
26232 break-before: column;
26233}
26234
26235[data-page]:not([data-split-to]),
26236[data-break-after="page"]:not([data-split-to]),
26237[data-break-after="always"]:not([data-split-to]),
26238[data-break-after="left"]:not([data-split-to]),
26239[data-break-after="right"]:not([data-split-to]),
26240[data-break-after="recto"]:not([data-split-to]),
26241[data-break-after="verso"]:not([data-split-to])
26242{
26243 break-after: column;
26244}
26245*/
26246
26247.pagedjs_clear-after::after {
26248 content: none !important;
26249}
26250
26251[data-align-last-split-element='justify'] {
26252 text-align-last: justify;
26253}
26254
26255
26256@media print {
26257 html {
26258 width: 100%;
26259 height: 100%;
26260 }
26261 body {
26262 margin: 0;
26263 padding: 0;
26264 width: 100% !important;
26265 height: 100% !important;
26266 min-width: 100%;
26267 max-width: 100%;
26268 min-height: 100%;
26269 max-height: 100%;
26270 }
26271 .pagedjs_pages {
26272 width: auto;
26273 display: block !important;
26274 transform: none !important;
26275 height: 100% !important;
26276 min-height: 100%;
26277 max-height: 100%;
26278 overflow: visible;
26279 }
26280 .pagedjs_page {
26281 margin: 0;
26282 padding: 0;
26283 max-height: 100%;
26284 min-height: 100%;
26285 height: 100% !important;
26286 page-break-after: always;
26287 break-after: page;
26288 }
26289 .pagedjs_sheet {
26290 margin: 0;
26291 padding: 0;
26292 max-height: 100%;
26293 min-height: 100%;
26294 height: 100% !important;
26295 }
26296}
26297`;
26298
26299 async function request(url, options={}) {
26300 return new Promise(function(resolve, reject) {
26301 let request = new XMLHttpRequest();
26302
26303 request.open(options.method || "get", url, true);
26304
26305 for (let i in options.headers) {
26306 request.setRequestHeader(i, options.headers[i]);
26307 }
26308
26309 request.withCredentials = options.credentials === "include";
26310
26311 request.onload = () => {
26312 // Chrome returns a status code of 0 for local files
26313 const status = request.status === 0 && url.startsWith("file://") ? 200 : request.status;
26314 resolve(new Response(request.responseText, {status}));
26315 };
26316
26317 request.onerror = reject;
26318
26319 request.send(options.body || null);
26320 });
26321 }
26322
26323 class Polisher {
26324 constructor(setup) {
26325 this.sheets = [];
26326 this.inserted = [];
26327
26328 this.hooks = {};
26329 this.hooks.onUrl = new Hook(this);
26330 this.hooks.onAtPage = new Hook(this);
26331 this.hooks.onAtMedia = new Hook(this);
26332 this.hooks.onRule = new Hook(this);
26333 this.hooks.onDeclaration = new Hook(this);
26334 this.hooks.onContent = new Hook(this);
26335 this.hooks.onSelector = new Hook(this);
26336 this.hooks.onPseudoSelector = new Hook(this);
26337
26338 this.hooks.onImport = new Hook(this);
26339
26340 this.hooks.beforeTreeParse = new Hook(this);
26341 this.hooks.beforeTreeWalk = new Hook(this);
26342 this.hooks.afterTreeWalk = new Hook(this);
26343
26344 if (setup !== false) {
26345 this.setup();
26346 }
26347 }
26348
26349 setup() {
26350 this.base = this.insert(baseStyles);
26351 this.styleEl = document.createElement("style");
26352 document.head.appendChild(this.styleEl);
26353 this.styleSheet = this.styleEl.sheet;
26354 return this.styleSheet;
26355 }
26356
26357 async add() {
26358 let fetched = [];
26359 let urls = [];
26360
26361 for (var i = 0; i < arguments.length; i++) {
26362 let f;
26363
26364 if (typeof arguments[i] === "object") {
26365 for (let url in arguments[i]) {
26366 let obj = arguments[i];
26367 f = new Promise(function(resolve, reject) {
26368 urls.push(url);
26369 resolve(obj[url]);
26370 });
26371 }
26372 } else {
26373 urls.push(arguments[i]);
26374 f = request(arguments[i]).then((response) => {
26375 return response.text();
26376 });
26377 }
26378
26379
26380 fetched.push(f);
26381 }
26382
26383 return await Promise.all(fetched)
26384 .then(async (originals) => {
26385 let text = "";
26386 for (let index = 0; index < originals.length; index++) {
26387 text = await this.convertViaSheet(originals[index], urls[index]);
26388 this.insert(text);
26389 }
26390 return text;
26391 });
26392 }
26393
26394 async convertViaSheet(cssStr, href) {
26395 let sheet = new Sheet(href, this.hooks);
26396 await sheet.parse(cssStr);
26397
26398 // Insert the imported sheets first
26399 for (let url of sheet.imported) {
26400 let str = await request(url).then((response) => {
26401 return response.text();
26402 });
26403 let text = await this.convertViaSheet(str, url);
26404 this.insert(text);
26405 }
26406
26407 this.sheets.push(sheet);
26408
26409 if (typeof sheet.width !== "undefined") {
26410 this.width = sheet.width;
26411 }
26412 if (typeof sheet.height !== "undefined") {
26413 this.height = sheet.height;
26414 }
26415 if (typeof sheet.orientation !== "undefined") {
26416 this.orientation = sheet.orientation;
26417 }
26418 return sheet.toString();
26419 }
26420
26421 insert(text){
26422 let head = document.querySelector("head");
26423 let style = document.createElement("style");
26424 style.type = "text/css";
26425 style.setAttribute("data-pagedjs-inserted-styles", "true");
26426
26427 style.appendChild(document.createTextNode(text));
26428
26429 head.appendChild(style);
26430
26431 this.inserted.push(style);
26432 return style;
26433 }
26434
26435 destroy() {
26436 this.styleEl.remove();
26437 this.inserted.forEach((s) => {
26438 s.remove();
26439 });
26440 this.sheets = [];
26441 }
26442 }
26443
26444 class Handler {
26445 constructor(chunker, polisher, caller) {
26446 let hooks = Object.assign({}, chunker && chunker.hooks, polisher && polisher.hooks, caller && caller.hooks);
26447 this.chunker = chunker;
26448 this.polisher = polisher;
26449 this.caller = caller;
26450
26451 for (let name in hooks) {
26452 if (name in this) {
26453 let hook = hooks[name];
26454 hook.register(this[name].bind(this));
26455 }
26456 }
26457 }
26458 }
26459
26460 eventEmitter(Handler.prototype);
26461
26462 // https://www.w3.org/TR/css3-page/#page-size-prop
26463
26464 var pageSizes = {
26465 "A0": {
26466 width: {
26467 value: 841,
26468 unit: "mm"
26469 },
26470 height: {
26471 value: 1189,
26472 unit: "mm"
26473 }
26474 },
26475 "A1": {
26476 width: {
26477 value: 594,
26478 unit: "mm"
26479 },
26480 height: {
26481 value: 841,
26482 unit: "mm"
26483 }
26484 },
26485 "A2": {
26486 width: {
26487 value: 420,
26488 unit: "mm"
26489 },
26490 height: {
26491 value: 594,
26492 unit: "mm"
26493 }
26494 },
26495 "A3": {
26496 width: {
26497 value: 297,
26498 unit: "mm"
26499 },
26500 height: {
26501 value: 420,
26502 unit: "mm"
26503 }
26504 },
26505 "A4": {
26506 width: {
26507 value: 210,
26508 unit: "mm"
26509 },
26510 height: {
26511 value: 297,
26512 unit: "mm"
26513 }
26514 },
26515 "A5": {
26516 width: {
26517 value: 148,
26518 unit: "mm"
26519 },
26520 height: {
26521 value: 210,
26522 unit: "mm"
26523 }
26524 },
26525 "A6": {
26526 width: {
26527 value: 105,
26528 unit: "mm"
26529 },
26530 height: {
26531 value: 148,
26532 unit: "mm"
26533 }
26534 },
26535 "A7": {
26536 width: {
26537 value: 74,
26538 unit: "mm"
26539 },
26540 height: {
26541 value: 105,
26542 unit: "mm"
26543 }
26544 },
26545 "A8": {
26546 width: {
26547 value: 52,
26548 unit: "mm"
26549 },
26550 height: {
26551 value: 74,
26552 unit: "mm"
26553 }
26554 },
26555 "A9": {
26556 width: {
26557 value: 37,
26558 unit: "mm"
26559 },
26560 height: {
26561 value: 52,
26562 unit: "mm"
26563 }
26564 },
26565 "A10": {
26566 width: {
26567 value: 26,
26568 unit: "mm"
26569 },
26570 height: {
26571 value: 37,
26572 unit: "mm"
26573 }
26574 },
26575 "B4": {
26576 width: {
26577 value: 250,
26578 unit: "mm"
26579 },
26580 height: {
26581 value: 353,
26582 unit: "mm"
26583 }
26584 },
26585 "B5": {
26586 width: {
26587 value: 176,
26588 unit: "mm"
26589 },
26590 height: {
26591 value: 250,
26592 unit: "mm"
26593 }
26594 },
26595 "letter": {
26596 width: {
26597 value: 8.5,
26598 unit: "in"
26599 },
26600 height: {
26601 value: 11,
26602 unit: "in"
26603 }
26604 },
26605 "legal": {
26606 width: {
26607 value: 8.5,
26608 unit: "in"
26609 },
26610 height: {
26611 value: 14,
26612 unit: "in"
26613 }
26614 },
26615 "ledger": {
26616 width: {
26617 value: 11,
26618 unit: "in"
26619 },
26620 height: {
26621 value: 17,
26622 unit: "in"
26623 }
26624 }
26625 };
26626
26627 class AtPage extends Handler {
26628 constructor(chunker, polisher, caller) {
26629 super(chunker, polisher, caller);
26630
26631 this.pages = {};
26632
26633 this.width = undefined;
26634 this.height = undefined;
26635 this.orientation = undefined;
26636 this.marginalia = {};
26637 }
26638
26639 pageModel(selector) {
26640 return {
26641 selector: selector,
26642 name: undefined,
26643 psuedo: undefined,
26644 nth: undefined,
26645 marginalia: {},
26646 width: undefined,
26647 height: undefined,
26648 orientation: undefined,
26649 margin: {
26650 top: {},
26651 right: {},
26652 left: {},
26653 bottom: {}
26654 },
26655 padding: {
26656 top: {},
26657 right: {},
26658 left: {},
26659 bottom: {}
26660 },
26661 border: {
26662 top: {},
26663 right: {},
26664 left: {},
26665 bottom: {}
26666 },
26667 backgroundOrigin: undefined,
26668 block: {},
26669 marks: undefined
26670 };
26671 }
26672
26673 // Find and Remove @page rules
26674 onAtPage(node, item, list) {
26675 let page, marginalia;
26676 let selector = "";
26677 let named, psuedo, nth;
26678 let needsMerge = false;
26679
26680 if (node.prelude) {
26681 named = this.getTypeSelector(node);
26682 psuedo = this.getPsuedoSelector(node);
26683 nth = this.getNthSelector(node);
26684 selector = lib.generate(node.prelude);
26685 } else {
26686 selector = "*";
26687 }
26688
26689 if (selector in this.pages) {
26690 // this.pages[selector] = Object.assign(this.pages[selector], page);
26691 // console.log("after", selector, this.pages[selector]);
26692
26693 // this.pages[selector].added = false;
26694 page = this.pages[selector];
26695 marginalia = this.replaceMarginalia(node);
26696 needsMerge = true;
26697 } else {
26698 page = this.pageModel(selector);
26699 marginalia = this.replaceMarginalia(node);
26700 this.pages[selector] = page;
26701 }
26702
26703 page.name = named;
26704 page.psuedo = psuedo;
26705 page.nth = nth;
26706
26707 if (needsMerge) {
26708 page.marginalia = Object.assign(page.marginalia, marginalia);
26709 } else {
26710 page.marginalia = marginalia;
26711 }
26712
26713 let declarations = this.replaceDeclarations(node);
26714
26715 if (declarations.size) {
26716 page.size = declarations.size;
26717 page.width = declarations.size.width;
26718 page.height = declarations.size.height;
26719 page.orientation = declarations.size.orientation;
26720 page.format = declarations.size.format;
26721 }
26722
26723 if (declarations.bleed && declarations.bleed[0] != "auto") {
26724 switch (declarations.bleed.length) {
26725 case 4: // top right bottom left
26726 page.bleed = {
26727 top: declarations.bleed[0],
26728 right: declarations.bleed[1],
26729 bottom: declarations.bleed[2],
26730 left: declarations.bleed[3]
26731 };
26732 break;
26733 case 3: // top right bottom right
26734 page.bleed = {
26735 top: declarations.bleed[0],
26736 right: declarations.bleed[1],
26737 bottom: declarations.bleed[2],
26738 left: declarations.bleed[1]
26739 };
26740 break;
26741 case 2: // top right top right
26742 page.bleed = {
26743 top: declarations.bleed[0],
26744 right: declarations.bleed[1],
26745 bottom: declarations.bleed[0],
26746 left: declarations.bleed[1]
26747 };
26748 break;
26749 default:
26750 page.bleed = {
26751 top: declarations.bleed[0],
26752 right: declarations.bleed[0],
26753 bottom: declarations.bleed[0],
26754 left: declarations.bleed[0]
26755 };
26756 }
26757 }
26758
26759 if (declarations.marks) {
26760 if (!declarations.bleed || declarations.bleed && declarations.bleed[0] === "auto") {
26761 // Spec say 6pt, but needs more space for marks
26762 page.bleed = {
26763 top: { value: 6, unit: "mm" },
26764 right: { value: 6, unit: "mm" },
26765 bottom: { value: 6, unit: "mm" },
26766 left: { value: 6, unit: "mm" }
26767 };
26768 }
26769
26770 page.marks = declarations.marks;
26771 }
26772
26773 if (declarations.margin) {
26774 page.margin = declarations.margin;
26775 }
26776 if (declarations.padding) {
26777 page.padding = declarations.padding;
26778 }
26779
26780 if (declarations.border) {
26781 page.border = declarations.border;
26782 }
26783
26784 if (declarations.marks) {
26785 page.marks = declarations.marks;
26786 }
26787
26788 if (needsMerge) {
26789 page.block.children.appendList(node.block.children);
26790 } else {
26791 page.block = node.block;
26792 }
26793
26794 // Remove the rule
26795 list.remove(item);
26796 }
26797
26798 /* Handled in breaks */
26799 /*
26800 afterParsed(parsed) {
26801 for (let b in this.named) {
26802 // Find elements
26803 let elements = parsed.querySelectorAll(b);
26804 // Add break data
26805 for (var i = 0; i < elements.length; i++) {
26806 elements[i].setAttribute("data-page", this.named[b]);
26807 }
26808 }
26809 }
26810 */
26811
26812 afterTreeWalk(ast, sheet) {
26813 this.addPageClasses(this.pages, ast, sheet);
26814
26815 if ("*" in this.pages) {
26816 let width = this.pages["*"].width;
26817 let height = this.pages["*"].height;
26818 let format = this.pages["*"].format;
26819 let orientation = this.pages["*"].orientation;
26820 let bleed = this.pages["*"].bleed;
26821 let marks = this.pages["*"].marks;
26822 let bleedverso = undefined;
26823 let bleedrecto = undefined;
26824
26825 if (":left" in this.pages) {
26826 bleedverso = this.pages[":left"].bleed;
26827 }
26828
26829 if (":right" in this.pages) {
26830 bleedrecto = this.pages[":right"].bleed;
26831 }
26832
26833 if ((width && height) &&
26834 (this.width !== width || this.height !== height)) {
26835 this.width = width;
26836 this.height = height;
26837 this.format = format;
26838 this.orientation = orientation;
26839
26840 this.addRootVars(ast, width, height, orientation, bleed, bleedrecto, bleedverso, marks);
26841 this.addRootPage(ast, this.pages["*"].size, bleed, bleedrecto, bleedverso);
26842
26843 this.emit("size", { width, height, orientation, format, bleed });
26844 this.emit("atpages", this.pages);
26845 }
26846
26847 }
26848 }
26849
26850 getTypeSelector(ast) {
26851 // Find page name
26852 let name;
26853
26854 lib.walk(ast, {
26855 visit: "TypeSelector",
26856 enter: (node, item, list) => {
26857 name = node.name;
26858 }
26859 });
26860
26861 return name;
26862 }
26863
26864 getPsuedoSelector(ast) {
26865 // Find if it has :left & :right & :black & :first
26866 let name;
26867 lib.walk(ast, {
26868 visit: "PseudoClassSelector",
26869 enter: (node, item, list) => {
26870 if (node.name !== "nth") {
26871 name = node.name;
26872 }
26873 }
26874 });
26875
26876 return name;
26877 }
26878
26879 getNthSelector(ast) {
26880 // Find if it has :nth
26881 let nth;
26882 lib.walk(ast, {
26883 visit: "PseudoClassSelector",
26884 enter: (node, item, list) => {
26885 if (node.name === "nth" && node.children) {
26886 let raw = node.children.first();
26887 nth = raw.value;
26888 }
26889 }
26890 });
26891
26892 return nth;
26893 }
26894
26895 replaceMarginalia(ast) {
26896 let parsed = {};
26897
26898 lib.walk(ast.block, {
26899 visit: "Atrule",
26900 enter: (node, item, list) => {
26901 let name = node.name;
26902 if (name === "top") {
26903 name = "top-center";
26904 }
26905 if (name === "right") {
26906 name = "right-middle";
26907 }
26908 if (name === "left") {
26909 name = "left-middle";
26910 }
26911 if (name === "bottom") {
26912 name = "bottom-center";
26913 }
26914 parsed[name] = node.block;
26915 list.remove(item);
26916 }
26917 });
26918
26919 return parsed;
26920 }
26921
26922 replaceDeclarations(ast) {
26923 let parsed = {};
26924
26925 lib.walk(ast.block, {
26926 visit: "Declaration",
26927 enter: (declaration, dItem, dList) => {
26928 let prop = lib.property(declaration.property).name;
26929 // let value = declaration.value;
26930
26931 if (prop === "marks") {
26932 parsed.marks = [];
26933 lib.walk(declaration, {
26934 visit: "Identifier",
26935 enter: (ident) => {
26936 parsed.marks.push(ident.name);
26937 }
26938 });
26939 dList.remove(dItem);
26940 } else if (prop === "margin") {
26941 parsed.margin = this.getMargins(declaration);
26942 dList.remove(dItem);
26943
26944 } else if (prop.indexOf("margin-") === 0) {
26945 let m = prop.substring("margin-".length);
26946 if (!parsed.margin) {
26947 parsed.margin = {
26948 top: {},
26949 right: {},
26950 left: {},
26951 bottom: {}
26952 };
26953 }
26954 parsed.margin[m] = declaration.value.children.first();
26955 dList.remove(dItem);
26956
26957 } else if (prop === "padding") {
26958 parsed.padding = this.getPaddings(declaration.value);
26959 dList.remove(dItem);
26960
26961 } else if (prop.indexOf("padding-") === 0) {
26962 let p = prop.substring("padding-".length);
26963 if (!parsed.padding) {
26964 parsed.padding = {
26965 top: {},
26966 right: {},
26967 left: {},
26968 bottom: {}
26969 };
26970 }
26971 parsed.padding[p] = declaration.value.children.first();
26972 dList.remove(dItem);
26973 }
26974
26975 else if (prop === "border") {
26976 if (!parsed.border) {
26977 parsed.border = {
26978 top: {},
26979 right: {},
26980 left: {},
26981 bottom: {}
26982 };
26983 }
26984 parsed.border.top = lib.generate(declaration.value);
26985 parsed.border.right = lib.generate(declaration.value);
26986 parsed.border.left = lib.generate(declaration.value);
26987 parsed.border.bottom = lib.generate(declaration.value);
26988
26989 dList.remove(dItem);
26990
26991 }
26992
26993 else if (prop.indexOf("border-") === 0) {
26994 if (!parsed.border) {
26995 parsed.border = {
26996 top: {},
26997 right: {},
26998 left: {},
26999 bottom: {}
27000 };
27001 }
27002 let p = prop.substring("border-".length);
27003
27004 parsed.border[p] = lib.generate(declaration.value);
27005 dList.remove(dItem);
27006
27007 }
27008
27009 else if (prop === "size") {
27010 parsed.size = this.getSize(declaration);
27011 dList.remove(dItem);
27012 } else if (prop === "bleed") {
27013 parsed.bleed = [];
27014
27015 lib.walk(declaration, {
27016 enter: (subNode) => {
27017 switch (subNode.type) {
27018 case "String": // bleed: "auto"
27019 if (subNode.value.indexOf("auto") > -1) {
27020 parsed.bleed.push("auto");
27021 }
27022 break;
27023 case "Dimension": // bleed: 1in 2in, bleed: 20px ect.
27024 parsed.bleed.push({
27025 value: subNode.value,
27026 unit: subNode.unit
27027 });
27028 break;
27029 case "Number":
27030 parsed.bleed.push({
27031 value: subNode.value,
27032 unit: "px"
27033 });
27034 break;
27035 // ignore
27036 }
27037
27038 }
27039 });
27040
27041 dList.remove(dItem);
27042 }
27043
27044 }
27045 });
27046
27047 return parsed;
27048
27049 }
27050 getSize(declaration) {
27051 let width, height, orientation, format;
27052
27053 // Get size: Xmm Ymm
27054 lib.walk(declaration, {
27055 visit: "Dimension",
27056 enter: (node, item, list) => {
27057 let { value, unit } = node;
27058 if (typeof width === "undefined") {
27059 width = { value, unit };
27060 } else if (typeof height === "undefined") {
27061 height = { value, unit };
27062 }
27063 }
27064 });
27065
27066 // Get size: "A4"
27067 lib.walk(declaration, {
27068 visit: "String",
27069 enter: (node, item, list) => {
27070 let name = node.value.replace(/["|']/g, "");
27071 let s = pageSizes[name];
27072 if (s) {
27073 width = s.width;
27074 height = s.height;
27075 }
27076 }
27077 });
27078
27079 // Get Format or Landscape or Portrait
27080 lib.walk(declaration, {
27081 visit: "Identifier",
27082 enter: (node, item, list) => {
27083 let name = node.name;
27084 if (name === "landscape" || name === "portrait") {
27085 orientation = node.name;
27086 } else if (name !== "auto") {
27087 let s = pageSizes[name];
27088 if (s) {
27089 width = s.width;
27090 height = s.height;
27091 }
27092 format = name;
27093 }
27094 }
27095 });
27096
27097 return {
27098 width,
27099 height,
27100 orientation,
27101 format
27102 };
27103 }
27104
27105 getMargins(declaration) {
27106 let margins = [];
27107 let margin = {
27108 top: {},
27109 right: {},
27110 left: {},
27111 bottom: {}
27112 };
27113
27114 lib.walk(declaration, {
27115 enter: (node) => {
27116 switch (node.type) {
27117 case "Dimension": // margin: 1in 2in, margin: 20px, etc...
27118 margins.push(node);
27119 break;
27120 case "Number": // margin: 0
27121 margins.push({value: node.value, unit: "px"});
27122 break;
27123 // ignore
27124 }
27125 }
27126 });
27127
27128 if (margins.length === 1) {
27129 for (let m in margin) {
27130 margin[m] = margins[0];
27131 }
27132 } else if (margins.length === 2) {
27133 margin.top = margins[0];
27134 margin.right = margins[1];
27135 margin.bottom = margins[0];
27136 margin.left = margins[1];
27137 } else if (margins.length === 3) {
27138 margin.top = margins[0];
27139 margin.right = margins[1];
27140 margin.bottom = margins[2];
27141 margin.left = margins[1];
27142 } else if (margins.length === 4) {
27143 margin.top = margins[0];
27144 margin.right = margins[1];
27145 margin.bottom = margins[2];
27146 margin.left = margins[3];
27147 }
27148
27149 return margin;
27150 }
27151
27152 getPaddings(declaration) {
27153 let paddings = [];
27154 let padding = {
27155 top: {},
27156 right: {},
27157 left: {},
27158 bottom: {}
27159 };
27160
27161 lib.walk(declaration, {
27162 enter: (node) => {
27163 switch (node.type) {
27164 case "Dimension": // padding: 1in 2in, padding: 20px, etc...
27165 paddings.push(node);
27166 break;
27167 case "Number": // padding: 0
27168 paddings.push({value: node.value, unit: "px"});
27169 break;
27170 // ignore
27171 }
27172 }
27173 });
27174 if (paddings.length === 1) {
27175 for (let p in padding) {
27176 padding[p] = paddings[0];
27177 }
27178 } else if (paddings.length === 2) {
27179
27180 padding.top = paddings[0];
27181 padding.right = paddings[1];
27182 padding.bottom = paddings[0];
27183 padding.left = paddings[1];
27184 } else if (paddings.length === 3) {
27185
27186 padding.top = paddings[0];
27187 padding.right = paddings[1];
27188 padding.bottom = paddings[2];
27189 padding.left = paddings[1];
27190 } else if (paddings.length === 4) {
27191
27192 padding.top = paddings[0];
27193 padding.right = paddings[1];
27194 padding.bottom = paddings[2];
27195 padding.left = paddings[3];
27196 }
27197 return padding;
27198 }
27199
27200 // get values for the border on the @page to pass them to the element with the .pagedjs_area class
27201 getBorders(declaration) {
27202 let border = {
27203 top: {},
27204 right: {},
27205 left: {},
27206 bottom: {}
27207 };
27208
27209 if (declaration.prop == "border") {
27210 border.top = lib.generate(declaration.value);
27211 border.right = lib.generate(declaration.value);
27212 border.bottom = lib.generate(declaration.value);
27213 border.left = lib.generate(declaration.value);
27214
27215 }
27216 else if (declaration.prop == "border-top") {
27217 border.top = lib.generate(declaration.value);
27218 }
27219 else if (declaration.prop == "border-right") {
27220 border.right = lib.generate(declaration.value);
27221
27222 }
27223 else if (declaration.prop == "border-bottom") {
27224 border.bottom = lib.generate(declaration.value);
27225
27226 }
27227 else if (declaration.prop == "border-left") {
27228 border.left = lib.generate(declaration.value);
27229 }
27230
27231 return border;
27232 }
27233
27234
27235 addPageClasses(pages, ast, sheet) {
27236 // First add * page
27237 if ("*" in pages) {
27238 let p = this.createPage(pages["*"], ast.children, sheet);
27239 sheet.insertRule(p);
27240 }
27241 // Add :left & :right
27242 if (":left" in pages) {
27243 let left = this.createPage(pages[":left"], ast.children, sheet);
27244 sheet.insertRule(left);
27245 }
27246 if (":right" in pages) {
27247 let right = this.createPage(pages[":right"], ast.children, sheet);
27248 sheet.insertRule(right);
27249 }
27250 // Add :first & :blank
27251 if (":first" in pages) {
27252 let first = this.createPage(pages[":first"], ast.children, sheet);
27253 sheet.insertRule(first);
27254 }
27255 if (":blank" in pages) {
27256 let blank = this.createPage(pages[":blank"], ast.children, sheet);
27257 sheet.insertRule(blank);
27258 }
27259 // Add nth pages
27260 for (let pg in pages) {
27261 if (pages[pg].nth) {
27262 let nth = this.createPage(pages[pg], ast.children, sheet);
27263 sheet.insertRule(nth);
27264 }
27265 }
27266
27267 // Add named pages
27268 for (let pg in pages) {
27269 if (pages[pg].name) {
27270 let named = this.createPage(pages[pg], ast.children, sheet);
27271 sheet.insertRule(named);
27272 }
27273 }
27274
27275 }
27276
27277 createPage(page, ruleList, sheet) {
27278
27279 let selectors = this.selectorsForPage(page);
27280 let children = page.block.children.copy();
27281 let block = {
27282 type: "Block",
27283 loc: 0,
27284 children: children
27285 };
27286
27287
27288 let rule = this.createRule(selectors, block);
27289
27290 this.addMarginVars(page.margin, children, children.first());
27291 this.addPaddingVars(page.padding, children, children.first());
27292 this.addBorderVars(page.border, children, children.first());
27293
27294
27295 if (page.width) {
27296 this.addDimensions(page.width, page.height, page.orientation, children, children.first());
27297 }
27298
27299 if (page.marginalia) {
27300 this.addMarginaliaStyles(page, ruleList, rule, sheet);
27301 this.addMarginaliaContent(page, ruleList, rule, sheet);
27302 }
27303 return rule;
27304 }
27305
27306 addMarginVars(margin, list, item) {
27307 // variables for margins
27308 for (let m in margin) {
27309 if (typeof margin[m].value !== "undefined") {
27310 let value = margin[m].value + (margin[m].unit || "");
27311 let mVar = list.createItem({
27312 type: "Declaration",
27313 property: "--pagedjs-margin-" + m,
27314 value: {
27315 type: "Raw",
27316 value: value
27317 }
27318 });
27319 list.append(mVar, item);
27320
27321 }
27322 }
27323 }
27324
27325 addPaddingVars(padding, list, item) {
27326 // variables for padding
27327 for (let p in padding) {
27328
27329 if (typeof padding[p].value !== "undefined") {
27330 let value = padding[p].value + (padding[p].unit || "");
27331 let pVar = list.createItem({
27332 type: "Declaration",
27333 property: "--pagedjs-padding-" + p,
27334 value: {
27335 type: "Raw",
27336 value: value
27337 }
27338 });
27339
27340 list.append(pVar, item);
27341 }
27342
27343 }
27344 }
27345
27346 addBorderVars(border, list, item) {
27347 // variables for borders
27348 for (let b in border) {
27349 if (typeof border[b] !== "undefined") {
27350 let value = border[b];
27351 let bVar = list.createItem({
27352 type: "Declaration",
27353 property: "--pagedjs-border-" + b,
27354 value: {
27355 type: "Raw",
27356 value: value
27357 }
27358 });
27359 list.append(bVar, item);
27360 }
27361
27362 }
27363 }
27364
27365 addDimensions(width, height, orientation, list, item) {
27366 let widthString, heightString;
27367
27368 widthString = CSSValueToString(width);
27369 heightString = CSSValueToString(height);
27370
27371 if (orientation && orientation !== "portrait") {
27372 // reverse for orientation
27373 [widthString, heightString] = [heightString, widthString];
27374 }
27375
27376 // width variable
27377 let wVar = this.createVariable("--pagedjs-pagebox-width", widthString);
27378 list.appendData(wVar);
27379
27380 // height variable
27381 let hVar = this.createVariable("--pagedjs-pagebox-height", heightString);
27382 list.appendData(hVar);
27383
27384 // let w = this.createDimension("width", width);
27385 // let h = this.createDimension("height", height);
27386 // list.appendData(w);
27387 // list.appendData(h);
27388 }
27389
27390 addMarginaliaStyles(page, list, item, sheet) {
27391 for (let loc in page.marginalia) {
27392 let block = lib.clone(page.marginalia[loc]);
27393 let hasContent = false;
27394
27395 if (block.children.isEmpty()) {
27396 continue;
27397 }
27398
27399 lib.walk(block, {
27400 visit: "Declaration",
27401 enter: (node, item, list) => {
27402 if (node.property === "content") {
27403 if (node.value.children && node.value.children.first().name === "none") {
27404 hasContent = false;
27405 } else {
27406 hasContent = true;
27407 }
27408 list.remove(item);
27409 }
27410 if (node.property === "vertical-align") {
27411 lib.walk(node, {
27412 visit: "Identifier",
27413 enter: (identNode, identItem, identlist) => {
27414 let name = identNode.name;
27415 if (name === "top") {
27416 identNode.name = "flex-start";
27417 } else if (name === "middle") {
27418 identNode.name = "center";
27419 } else if (name === "bottom") {
27420 identNode.name = "flex-end";
27421 }
27422 }
27423 });
27424 node.property = "align-items";
27425 }
27426
27427 if (node.property === "width" &&
27428 (loc === "top-left" ||
27429 loc === "top-center" ||
27430 loc === "top-right" ||
27431 loc === "bottom-left" ||
27432 loc === "bottom-center" ||
27433 loc === "bottom-right")) {
27434 let c = lib.clone(node);
27435 c.property = "max-width";
27436 list.appendData(c);
27437 }
27438
27439 if (node.property === "height" &&
27440 (loc === "left-top" ||
27441 loc === "left-middle" ||
27442 loc === "left-bottom" ||
27443 loc === "right-top" ||
27444 loc === "right-middle" ||
27445 loc === "right-bottom")) {
27446 let c = lib.clone(node);
27447 c.property = "max-height";
27448 list.appendData(c);
27449 }
27450 }
27451 });
27452
27453 let marginSelectors = this.selectorsForPageMargin(page, loc);
27454 let marginRule = this.createRule(marginSelectors, block);
27455
27456 list.appendData(marginRule);
27457
27458 let sel = lib.generate({
27459 type: "Selector",
27460 children: marginSelectors
27461 });
27462
27463 this.marginalia[sel] = {
27464 page: page,
27465 selector: sel,
27466 block: page.marginalia[loc],
27467 hasContent: hasContent
27468 };
27469
27470 }
27471 }
27472
27473 addMarginaliaContent(page, list, item, sheet) {
27474 let displayNone;
27475 // Just content
27476 for (let loc in page.marginalia) {
27477 let content = lib.clone(page.marginalia[loc]);
27478 lib.walk(content, {
27479 visit: "Declaration",
27480 enter: (node, item, list) => {
27481 if (node.property !== "content") {
27482 list.remove(item);
27483 }
27484
27485 if (node.value.children && node.value.children.first().name === "none") {
27486 displayNone = true;
27487 }
27488 }
27489 });
27490
27491 if (content.children.isEmpty()) {
27492 continue;
27493 }
27494
27495 let displaySelectors = this.selectorsForPageMargin(page, loc);
27496 let displayDeclaration;
27497
27498 displaySelectors.insertData({
27499 type: "Combinator",
27500 name: ">"
27501 });
27502
27503 displaySelectors.insertData({
27504 type: "ClassSelector",
27505 name: "pagedjs_margin-content"
27506 });
27507
27508 displaySelectors.insertData({
27509 type: "Combinator",
27510 name: ">"
27511 });
27512
27513 displaySelectors.insertData({
27514 type: "TypeSelector",
27515 name: "*"
27516 });
27517
27518 if (displayNone) {
27519 displayDeclaration = this.createDeclaration("display", "none");
27520 } else {
27521 displayDeclaration = this.createDeclaration("display", "block");
27522 }
27523
27524 let displayRule = this.createRule(displaySelectors, [displayDeclaration]);
27525 sheet.insertRule(displayRule);
27526
27527 // insert content rule
27528 let contentSelectors = this.selectorsForPageMargin(page, loc);
27529
27530 contentSelectors.insertData({
27531 type: "Combinator",
27532 name: ">"
27533 });
27534
27535 contentSelectors.insertData({
27536 type: "ClassSelector",
27537 name: "pagedjs_margin-content"
27538 });
27539
27540 contentSelectors.insertData({
27541 type: "PseudoElementSelector",
27542 name: "after",
27543 children: null
27544 });
27545
27546 let contentRule = this.createRule(contentSelectors, content);
27547 sheet.insertRule(contentRule);
27548 }
27549 }
27550
27551 addRootVars(ast, width, height, orientation, bleed, bleedrecto, bleedverso, marks) {
27552 let rules = [];
27553 let selectors = new lib.List();
27554 selectors.insertData({
27555 type: "PseudoClassSelector",
27556 name: "root",
27557 children: null
27558 });
27559
27560 let widthString, heightString;
27561 let widthStringRight, heightStringRight;
27562 let widthStringLeft, heightStringLeft;
27563
27564 if (!bleed) {
27565 widthString = CSSValueToString(width);
27566 heightString = CSSValueToString(height);
27567 widthStringRight = CSSValueToString(width);
27568 heightStringRight = CSSValueToString(height);
27569 widthStringLeft = CSSValueToString(width);
27570 heightStringLeft = CSSValueToString(height);
27571 } else {
27572 widthString = `calc( ${CSSValueToString(width)} + ${CSSValueToString(bleed.left)} + ${CSSValueToString(bleed.right)} )`;
27573 heightString = `calc( ${CSSValueToString(height)} + ${CSSValueToString(bleed.top)} + ${CSSValueToString(bleed.bottom)} )`;
27574
27575 widthStringRight = `calc( ${CSSValueToString(width)} + ${CSSValueToString(bleed.left)} + ${CSSValueToString(bleed.right)} )`;
27576 heightStringRight = `calc( ${CSSValueToString(height)} + ${CSSValueToString(bleed.top)} + ${CSSValueToString(bleed.bottom)} )`;
27577
27578 widthStringLeft = `calc( ${CSSValueToString(width)} + ${CSSValueToString(bleed.left)} + ${CSSValueToString(bleed.right)} )`;
27579 heightStringLeft = `calc( ${CSSValueToString(height)} + ${CSSValueToString(bleed.top)} + ${CSSValueToString(bleed.bottom)} )`;
27580
27581 let bleedTop = this.createVariable("--pagedjs-bleed-top", CSSValueToString(bleed.top));
27582 let bleedRight = this.createVariable("--pagedjs-bleed-right", CSSValueToString(bleed.right));
27583 let bleedBottom = this.createVariable("--pagedjs-bleed-bottom", CSSValueToString(bleed.bottom));
27584 let bleedLeft = this.createVariable("--pagedjs-bleed-left", CSSValueToString(bleed.left));
27585
27586 let bleedTopRecto = this.createVariable("--pagedjs-bleed-right-top", CSSValueToString(bleed.top));
27587 let bleedRightRecto = this.createVariable("--pagedjs-bleed-right-right", CSSValueToString(bleed.right));
27588 let bleedBottomRecto = this.createVariable("--pagedjs-bleed-right-bottom", CSSValueToString(bleed.bottom));
27589 let bleedLeftRecto = this.createVariable("--pagedjs-bleed-right-left", CSSValueToString(bleed.left));
27590
27591 let bleedTopVerso = this.createVariable("--pagedjs-bleed-left-top", CSSValueToString(bleed.top));
27592 let bleedRightVerso = this.createVariable("--pagedjs-bleed-left-right", CSSValueToString(bleed.right));
27593 let bleedBottomVerso = this.createVariable("--pagedjs-bleed-left-bottom", CSSValueToString(bleed.bottom));
27594 let bleedLeftVerso = this.createVariable("--pagedjs-bleed-left-left", CSSValueToString(bleed.left));
27595
27596 if (bleedrecto) {
27597 bleedTopRecto = this.createVariable("--pagedjs-bleed-right-top", CSSValueToString(bleedrecto.top));
27598 bleedRightRecto = this.createVariable("--pagedjs-bleed-right-right", CSSValueToString(bleedrecto.right));
27599 bleedBottomRecto = this.createVariable("--pagedjs-bleed-right-bottom", CSSValueToString(bleedrecto.bottom));
27600 bleedLeftRecto = this.createVariable("--pagedjs-bleed-right-left", CSSValueToString(bleedrecto.left));
27601
27602 widthStringRight = `calc( ${CSSValueToString(width)} + ${CSSValueToString(bleedrecto.left)} + ${CSSValueToString(bleedrecto.right)} )`;
27603 heightStringRight = `calc( ${CSSValueToString(height)} + ${CSSValueToString(bleedrecto.top)} + ${CSSValueToString(bleedrecto.bottom)} )`;
27604 }
27605 if (bleedverso) {
27606 bleedTopVerso = this.createVariable("--pagedjs-bleed-left-top", CSSValueToString(bleedverso.top));
27607 bleedRightVerso = this.createVariable("--pagedjs-bleed-left-right", CSSValueToString(bleedverso.right));
27608 bleedBottomVerso = this.createVariable("--pagedjs-bleed-left-bottom", CSSValueToString(bleedverso.bottom));
27609 bleedLeftVerso = this.createVariable("--pagedjs-bleed-left-left", CSSValueToString(bleedverso.left));
27610
27611 widthStringLeft = `calc( ${CSSValueToString(width)} + ${CSSValueToString(bleedverso.left)} + ${CSSValueToString(bleedverso.right)} )`;
27612 heightStringLeft = `calc( ${CSSValueToString(height)} + ${CSSValueToString(bleedverso.top)} + ${CSSValueToString(bleedverso.bottom)} )`;
27613 }
27614
27615 let pageWidthVar = this.createVariable("--pagedjs-width", CSSValueToString(width));
27616 let pageHeightVar = this.createVariable("--pagedjs-height", CSSValueToString(height));
27617
27618 rules.push(
27619 bleedTop,
27620 bleedRight,
27621 bleedBottom,
27622 bleedLeft,
27623 bleedTopRecto,
27624 bleedRightRecto,
27625 bleedBottomRecto,
27626 bleedLeftRecto,
27627 bleedTopVerso,
27628 bleedRightVerso,
27629 bleedBottomVerso,
27630 bleedLeftVerso,
27631 pageWidthVar,
27632 pageHeightVar
27633 );
27634 }
27635
27636 if (marks) {
27637 marks.forEach((mark) => {
27638 let markDisplay = this.createVariable("--pagedjs-mark-" + mark + "-display", "block");
27639 rules.push(markDisplay);
27640 });
27641 }
27642
27643 // orientation variable
27644 if (orientation) {
27645 let oVar = this.createVariable("--pagedjs-orientation", orientation);
27646 rules.push(oVar);
27647
27648 if (orientation !== "portrait") {
27649 // reverse for orientation
27650 [widthString, heightString] = [heightString, widthString];
27651 [widthStringRight, heightStringRight] = [heightStringRight, widthStringRight];
27652 [widthStringLeft, heightStringLeft] = [heightStringLeft, widthStringLeft];
27653 }
27654 }
27655
27656 let wVar = this.createVariable("--pagedjs-width", widthString);
27657 let hVar = this.createVariable("--pagedjs-height", heightString);
27658
27659 let wVarR = this.createVariable("--pagedjs-width-right", widthStringRight);
27660 let hVarR = this.createVariable("--pagedjs-height-right", heightStringRight);
27661
27662 let wVarL = this.createVariable("--pagedjs-width-left", widthStringLeft);
27663 let hVarL = this.createVariable("--pagedjs-height-left", heightStringLeft);
27664
27665 rules.push(wVar, hVar, wVarR, hVarR, wVarL, hVarL);
27666
27667 let rule = this.createRule(selectors, rules);
27668
27669 ast.children.appendData(rule);
27670 }
27671
27672 /*
27673 @page {
27674 size: var(--pagedjs-width) var(--pagedjs-height);
27675 margin: 0;
27676 padding: 0;
27677 }
27678 */
27679 addRootPage(ast, size, bleed, bleedrecto, bleedverso) {
27680 let { width, height, orientation, format } = size;
27681 let children = new lib.List();
27682 let childrenLeft = new lib.List();
27683 let childrenRight = new lib.List();
27684 let dimensions = new lib.List();
27685 let dimensionsLeft = new lib.List();
27686 let dimensionsRight = new lib.List();
27687
27688 if (bleed) {
27689 let widthCalculations = new lib.List();
27690 let heightCalculations = new lib.List();
27691
27692 // width
27693 widthCalculations.appendData({
27694 type: "Dimension",
27695 unit: width.unit,
27696 value: width.value
27697 });
27698
27699 widthCalculations.appendData({
27700 type: "WhiteSpace",
27701 value: " "
27702 });
27703
27704 widthCalculations.appendData({
27705 type: "Operator",
27706 value: "+"
27707 });
27708
27709 widthCalculations.appendData({
27710 type: "WhiteSpace",
27711 value: " "
27712 });
27713
27714 widthCalculations.appendData({
27715 type: "Dimension",
27716 unit: bleed.left.unit,
27717 value: bleed.left.value
27718 });
27719
27720 widthCalculations.appendData({
27721 type: "WhiteSpace",
27722 value: " "
27723 });
27724
27725 widthCalculations.appendData({
27726 type: "Operator",
27727 value: "+"
27728 });
27729
27730 widthCalculations.appendData({
27731 type: "WhiteSpace",
27732 value: " "
27733 });
27734
27735 widthCalculations.appendData({
27736 type: "Dimension",
27737 unit: bleed.right.unit,
27738 value: bleed.right.value
27739 });
27740
27741 // height
27742 heightCalculations.appendData({
27743 type: "Dimension",
27744 unit: height.unit,
27745 value: height.value
27746 });
27747
27748 heightCalculations.appendData({
27749 type: "WhiteSpace",
27750 value: " "
27751 });
27752
27753 heightCalculations.appendData({
27754 type: "Operator",
27755 value: "+"
27756 });
27757
27758 heightCalculations.appendData({
27759 type: "WhiteSpace",
27760 value: " "
27761 });
27762
27763 heightCalculations.appendData({
27764 type: "Dimension",
27765 unit: bleed.top.unit,
27766 value: bleed.top.value
27767 });
27768
27769 heightCalculations.appendData({
27770 type: "WhiteSpace",
27771 value: " "
27772 });
27773
27774 heightCalculations.appendData({
27775 type: "Operator",
27776 value: "+"
27777 });
27778
27779 heightCalculations.appendData({
27780 type: "WhiteSpace",
27781 value: " "
27782 });
27783
27784 heightCalculations.appendData({
27785 type: "Dimension",
27786 unit: bleed.bottom.unit,
27787 value: bleed.bottom.value
27788 });
27789
27790 dimensions.appendData({
27791 type: "Function",
27792 name: "calc",
27793 children: widthCalculations
27794 });
27795
27796 dimensions.appendData({
27797 type: "WhiteSpace",
27798 value: " "
27799 });
27800
27801 dimensions.appendData({
27802 type: "Function",
27803 name: "calc",
27804 children: heightCalculations
27805 });
27806
27807 } else if (format) {
27808 dimensions.appendData({
27809 type: "Identifier",
27810 name: format
27811 });
27812
27813 if (orientation) {
27814 dimensions.appendData({
27815 type: "WhiteSpace",
27816 value: " "
27817 });
27818
27819 dimensions.appendData({
27820 type: "Identifier",
27821 name: orientation
27822 });
27823 }
27824 } else {
27825 dimensions.appendData({
27826 type: "Dimension",
27827 unit: width.unit,
27828 value: width.value
27829 });
27830
27831 dimensions.appendData({
27832 type: "WhiteSpace",
27833 value: " "
27834 });
27835
27836 dimensions.appendData({
27837 type: "Dimension",
27838 unit: height.unit,
27839 value: height.value
27840 });
27841 }
27842
27843 children.appendData({
27844 type: "Declaration",
27845 property: "size",
27846 loc: null,
27847 value: {
27848 type: "Value",
27849 children: dimensions
27850 }
27851 });
27852
27853 children.appendData({
27854 type: "Declaration",
27855 property: "margin",
27856 loc: null,
27857 value: {
27858 type: "Value",
27859 children: [{
27860 type: "Dimension",
27861 unit: "px",
27862 value: 0
27863 }]
27864 }
27865 });
27866
27867 children.appendData({
27868 type: "Declaration",
27869 property: "padding",
27870 loc: null,
27871 value: {
27872 type: "Value",
27873 children: [{
27874 type: "Dimension",
27875 unit: "px",
27876 value: 0
27877 }]
27878 }
27879 });
27880
27881 children.appendData({
27882 type: "Declaration",
27883 property: "padding",
27884 loc: null,
27885 value: {
27886 type: "Value",
27887 children: [{
27888 type: "Dimension",
27889 unit: "px",
27890 value: 0
27891 }]
27892 }
27893 });
27894
27895 let rule = ast.children.createItem({
27896 type: "Atrule",
27897 prelude: null,
27898 name: "page",
27899 block: {
27900 type: "Block",
27901 loc: null,
27902 children: children
27903 }
27904 });
27905
27906 ast.children.append(rule);
27907
27908 if (bleedverso) {
27909 let widthCalculationsLeft = new lib.List();
27910 let heightCalculationsLeft = new lib.List();
27911
27912 // width
27913 widthCalculationsLeft.appendData({
27914 type: "Dimension",
27915 unit: width.unit,
27916 value: width.value
27917 });
27918
27919 widthCalculationsLeft.appendData({
27920 type: "WhiteSpace",
27921 value: " "
27922 });
27923
27924 widthCalculationsLeft.appendData({
27925 type: "Operator",
27926 value: "+"
27927 });
27928
27929 widthCalculationsLeft.appendData({
27930 type: "WhiteSpace",
27931 value: " "
27932 });
27933
27934 widthCalculationsLeft.appendData({
27935 type: "Dimension",
27936 unit: bleedverso.left.unit,
27937 value: bleedverso.left.value
27938 });
27939
27940 widthCalculationsLeft.appendData({
27941 type: "WhiteSpace",
27942 value: " "
27943 });
27944
27945 widthCalculationsLeft.appendData({
27946 type: "Operator",
27947 value: "+"
27948 });
27949
27950 widthCalculationsLeft.appendData({
27951 type: "WhiteSpace",
27952 value: " "
27953 });
27954
27955 widthCalculationsLeft.appendData({
27956 type: "Dimension",
27957 unit: bleedverso.right.unit,
27958 value: bleedverso.right.value
27959 });
27960
27961 // height
27962 heightCalculationsLeft.appendData({
27963 type: "Dimension",
27964 unit: height.unit,
27965 value: height.value
27966 });
27967
27968 heightCalculationsLeft.appendData({
27969 type: "WhiteSpace",
27970 value: " "
27971 });
27972
27973 heightCalculationsLeft.appendData({
27974 type: "Operator",
27975 value: "+"
27976 });
27977
27978 heightCalculationsLeft.appendData({
27979 type: "WhiteSpace",
27980 value: " "
27981 });
27982
27983 heightCalculationsLeft.appendData({
27984 type: "Dimension",
27985 unit: bleedverso.top.unit,
27986 value: bleedverso.top.value
27987 });
27988
27989 heightCalculationsLeft.appendData({
27990 type: "WhiteSpace",
27991 value: " "
27992 });
27993
27994 heightCalculationsLeft.appendData({
27995 type: "Operator",
27996 value: "+"
27997 });
27998
27999 heightCalculationsLeft.appendData({
28000 type: "WhiteSpace",
28001 value: " "
28002 });
28003
28004 heightCalculationsLeft.appendData({
28005 type: "Dimension",
28006 unit: bleedverso.bottom.unit,
28007 value: bleedverso.bottom.value
28008 });
28009
28010 dimensionsLeft.appendData({
28011 type: "Function",
28012 name: "calc",
28013 children: widthCalculationsLeft
28014 });
28015
28016 dimensionsLeft.appendData({
28017 type: "WhiteSpace",
28018 value: " "
28019 });
28020
28021 dimensionsLeft.appendData({
28022 type: "Function",
28023 name: "calc",
28024 children: heightCalculationsLeft
28025 });
28026
28027 childrenLeft.appendData({
28028 type: "Declaration",
28029 property: "size",
28030 loc: null,
28031 value: {
28032 type: "Value",
28033 children: dimensionsLeft
28034 }
28035 });
28036
28037 let ruleLeft = ast.children.createItem({
28038 type: "Atrule",
28039 prelude: null,
28040 name: "page :left",
28041 block: {
28042 type: "Block",
28043 loc: null,
28044 children: childrenLeft
28045 }
28046 });
28047
28048 ast.children.append(ruleLeft);
28049
28050 }
28051
28052 if (bleedrecto) {
28053 let widthCalculationsRight = new lib.List();
28054 let heightCalculationsRight = new lib.List();
28055
28056 // width
28057 widthCalculationsRight.appendData({
28058 type: "Dimension",
28059 unit: width.unit,
28060 value: width.value
28061 });
28062
28063 widthCalculationsRight.appendData({
28064 type: "WhiteSpace",
28065 value: " "
28066 });
28067
28068 widthCalculationsRight.appendData({
28069 type: "Operator",
28070 value: "+"
28071 });
28072
28073 widthCalculationsRight.appendData({
28074 type: "WhiteSpace",
28075 value: " "
28076 });
28077
28078 widthCalculationsRight.appendData({
28079 type: "Dimension",
28080 unit: bleedrecto.left.unit,
28081 value: bleedrecto.left.value
28082 });
28083
28084 widthCalculationsRight.appendData({
28085 type: "WhiteSpace",
28086 value: " "
28087 });
28088
28089 widthCalculationsRight.appendData({
28090 type: "Operator",
28091 value: "+"
28092 });
28093
28094 widthCalculationsRight.appendData({
28095 type: "WhiteSpace",
28096 value: " "
28097 });
28098
28099 widthCalculationsRight.appendData({
28100 type: "Dimension",
28101 unit: bleedrecto.right.unit,
28102 value: bleedrecto.right.value
28103 });
28104
28105 // height
28106 heightCalculationsRight.appendData({
28107 type: "Dimension",
28108 unit: height.unit,
28109 value: height.value
28110 });
28111
28112 heightCalculationsRight.appendData({
28113 type: "WhiteSpace",
28114 value: " "
28115 });
28116
28117 heightCalculationsRight.appendData({
28118 type: "Operator",
28119 value: "+"
28120 });
28121
28122 heightCalculationsRight.appendData({
28123 type: "WhiteSpace",
28124 value: " "
28125 });
28126
28127 heightCalculationsRight.appendData({
28128 type: "Dimension",
28129 unit: bleedrecto.top.unit,
28130 value: bleedrecto.top.value
28131 });
28132
28133 heightCalculationsRight.appendData({
28134 type: "WhiteSpace",
28135 value: " "
28136 });
28137
28138 heightCalculationsRight.appendData({
28139 type: "Operator",
28140 value: "+"
28141 });
28142
28143 heightCalculationsRight.appendData({
28144 type: "WhiteSpace",
28145 value: " "
28146 });
28147
28148 heightCalculationsRight.appendData({
28149 type: "Dimension",
28150 unit: bleedrecto.bottom.unit,
28151 value: bleedrecto.bottom.value
28152 });
28153
28154 dimensionsRight.appendData({
28155 type: "Function",
28156 name: "calc",
28157 children: widthCalculationsRight
28158 });
28159
28160 dimensionsRight.appendData({
28161 type: "WhiteSpace",
28162 value: " "
28163 });
28164
28165 dimensionsRight.appendData({
28166 type: "Function",
28167 name: "calc",
28168 children: heightCalculationsRight
28169 });
28170
28171 childrenRight.appendData({
28172 type: "Declaration",
28173 property: "size",
28174 loc: null,
28175 value: {
28176 type: "Value",
28177 children: dimensionsRight
28178 }
28179 });
28180
28181 let ruleRight = ast.children.createItem({
28182 type: "Atrule",
28183 prelude: null,
28184 name: "page :right",
28185 block: {
28186 type: "Block",
28187 loc: null,
28188 children: childrenRight
28189 }
28190 });
28191
28192 ast.children.append(ruleRight);
28193
28194 }
28195 }
28196
28197 getNth(nth) {
28198 let n = nth.indexOf("n");
28199 let plus = nth.indexOf("+");
28200 let splitN = nth.split("n");
28201 let splitP = nth.split("+");
28202 let a = null;
28203 let b = null;
28204 if (n > -1) {
28205 a = splitN[0];
28206 if (plus > -1) {
28207 b = splitP[1];
28208 }
28209 } else {
28210 b = nth;
28211 }
28212
28213 return {
28214 type: "Nth",
28215 loc: null,
28216 selector: null,
28217 nth: {
28218 type: "AnPlusB",
28219 loc: null,
28220 a: a,
28221 b: b
28222 }
28223 };
28224 }
28225
28226 addPageAttributes(page, start, pages) {
28227 let named = start.dataset.page;
28228
28229 if (named) {
28230 page.name = named;
28231 page.element.classList.add("pagedjs_named_page");
28232 page.element.classList.add("pagedjs_" + named + "_page");
28233
28234 if (!start.dataset.splitFrom) {
28235 page.element.classList.add("pagedjs_" + named + "_first_page");
28236 }
28237 }
28238 }
28239
28240 getStartElement(content, breakToken) {
28241 let node = breakToken && breakToken.node;
28242
28243 if (!content && !breakToken) {
28244 return;
28245 }
28246
28247 // No break
28248 if (!node) {
28249 return content.children[0];
28250 }
28251
28252 // Top level element
28253 if (node.nodeType === 1 && node.parentNode.nodeType === 11) {
28254 return node;
28255 }
28256
28257 // Named page
28258 if (node.nodeType === 1 && node.dataset.page) {
28259 return node;
28260 }
28261
28262 // Get top level Named parent
28263 let fragment = rebuildAncestors(node);
28264 let pages = fragment.querySelectorAll("[data-page]");
28265
28266 if (pages.length) {
28267 return pages[pages.length - 1];
28268 } else {
28269 return fragment.children[0];
28270 }
28271 }
28272
28273 beforePageLayout(page, contents, breakToken, chunker) {
28274 let start = this.getStartElement(contents, breakToken);
28275 if (start) {
28276 this.addPageAttributes(page, start, chunker.pages);
28277 }
28278 // page.element.querySelector('.paged_area').style.color = red;
28279 }
28280
28281 afterPageLayout(fragment, page, breakToken, chunker) {
28282 for (let m in this.marginalia) {
28283 let margin = this.marginalia[m];
28284 let sels = m.split(" ");
28285
28286 let content;
28287 if (page.element.matches(sels[0]) && margin.hasContent) {
28288 content = page.element.querySelector(sels[1]);
28289 content.classList.add("hasContent");
28290 }
28291 }
28292
28293 // check center
28294 ["top", "bottom"].forEach((loc) => {
28295 let marginGroup = page.element.querySelector(".pagedjs_margin-" + loc);
28296 let center = page.element.querySelector(".pagedjs_margin-" + loc + "-center");
28297 let left = page.element.querySelector(".pagedjs_margin-" + loc + "-left");
28298 let right = page.element.querySelector(".pagedjs_margin-" + loc + "-right");
28299
28300 let centerContent = center.classList.contains("hasContent");
28301 let leftContent = left.classList.contains("hasContent");
28302 let rightContent = right.classList.contains("hasContent");
28303 let centerWidth, leftWidth, rightWidth;
28304
28305 if (leftContent) {
28306 leftWidth = window.getComputedStyle(left)["max-width"];
28307 }
28308
28309 if (rightContent) {
28310 rightWidth = window.getComputedStyle(right)["max-width"];
28311 }
28312
28313
28314 if (centerContent) {
28315 centerWidth = window.getComputedStyle(center)["max-width"];
28316
28317 if (centerWidth === "none" || centerWidth === "auto") {
28318 if (!leftContent && !rightContent) {
28319 marginGroup.style["grid-template-columns"] = "0 1fr 0";
28320 } else if (leftContent) {
28321 if (!rightContent) {
28322 if (leftWidth !== "none" && leftWidth !== "auto") {
28323 marginGroup.style["grid-template-columns"] = leftWidth + " 1fr " + leftWidth;
28324 } else {
28325 marginGroup.style["grid-template-columns"] = "auto auto 1fr";
28326 left.style["white-space"] = "nowrap";
28327 center.style["white-space"] = "nowrap";
28328 let leftOuterWidth = left.offsetWidth;
28329 let centerOuterWidth = center.offsetWidth;
28330 let outerwidths = leftOuterWidth + centerOuterWidth;
28331 let newcenterWidth = centerOuterWidth * 100 / outerwidths;
28332 marginGroup.style["grid-template-columns"] = "minmax(16.66%, 1fr) minmax(33%, " + newcenterWidth + "%) minmax(16.66%, 1fr)";
28333 left.style["white-space"] = "normal";
28334 center.style["white-space"] = "normal";
28335 }
28336 } else {
28337 if (leftWidth !== "none" && leftWidth !== "auto") {
28338 if (rightWidth !== "none" && rightWidth !== "auto") {
28339 marginGroup.style["grid-template-columns"] = leftWidth + " 1fr " + rightWidth;
28340 } else {
28341 marginGroup.style["grid-template-columns"] = leftWidth + " 1fr " + leftWidth;
28342 }
28343 } else {
28344 if (rightWidth !== "none" && rightWidth !== "auto") {
28345 marginGroup.style["grid-template-columns"] = rightWidth + " 1fr " + rightWidth;
28346 } else {
28347 marginGroup.style["grid-template-columns"] = "auto auto 1fr";
28348 left.style["white-space"] = "nowrap";
28349 center.style["white-space"] = "nowrap";
28350 right.style["white-space"] = "nowrap";
28351 let leftOuterWidth = left.offsetWidth;
28352 let centerOuterWidth = center.offsetWidth;
28353 let rightOuterWidth = right.offsetWidth;
28354 let outerwidths = leftOuterWidth + centerOuterWidth + rightOuterWidth;
28355 let newcenterWidth = centerOuterWidth * 100 / outerwidths;
28356 if (newcenterWidth > 40) {
28357 marginGroup.style["grid-template-columns"] = "minmax(16.66%, 1fr) minmax(33%, " + newcenterWidth + "%) minmax(16.66%, 1fr)";
28358 } else {
28359 marginGroup.style["grid-template-columns"] = "repeat(3, 1fr)";
28360 }
28361 left.style["white-space"] = "normal";
28362 center.style["white-space"] = "normal";
28363 right.style["white-space"] = "normal";
28364 }
28365 }
28366 }
28367 } else {
28368 if (rightWidth !== "none" && rightWidth !== "auto") {
28369 marginGroup.style["grid-template-columns"] = rightWidth + " 1fr " + rightWidth;
28370 } else {
28371 marginGroup.style["grid-template-columns"] = "auto auto 1fr";
28372 right.style["white-space"] = "nowrap";
28373 center.style["white-space"] = "nowrap";
28374 let rightOuterWidth = right.offsetWidth;
28375 let centerOuterWidth = center.offsetWidth;
28376 let outerwidths = rightOuterWidth + centerOuterWidth;
28377 let newcenterWidth = centerOuterWidth * 100 / outerwidths;
28378 marginGroup.style["grid-template-columns"] = "minmax(16.66%, 1fr) minmax(33%, " + newcenterWidth + "%) minmax(16.66%, 1fr)";
28379 right.style["white-space"] = "normal";
28380 center.style["white-space"] = "normal";
28381 }
28382 }
28383 } else if (centerWidth !== "none" && centerWidth !== "auto") {
28384 if (leftContent && leftWidth !== "none" && leftWidth !== "auto") {
28385 marginGroup.style["grid-template-columns"] = leftWidth + " " + centerWidth + " 1fr";
28386 } else if (rightContent && rightWidth !== "none" && rightWidth !== "auto") {
28387 marginGroup.style["grid-template-columns"] = "1fr " + centerWidth + " " + rightWidth;
28388 } else {
28389 marginGroup.style["grid-template-columns"] = "1fr " + centerWidth + " 1fr";
28390 }
28391
28392 }
28393
28394 } else {
28395 if (leftContent) {
28396 if (!rightContent) {
28397 marginGroup.style["grid-template-columns"] = "1fr 0 0";
28398 } else {
28399 if (leftWidth !== "none" && leftWidth !== "auto") {
28400 if (rightWidth !== "none" && rightWidth !== "auto") {
28401 marginGroup.style["grid-template-columns"] = leftWidth + " 1fr " + rightWidth;
28402 } else {
28403 marginGroup.style["grid-template-columns"] = leftWidth + " 0 1fr";
28404 }
28405 } else {
28406 if (rightWidth !== "none" && rightWidth !== "auto") {
28407 marginGroup.style["grid-template-columns"] = "1fr 0 " + rightWidth;
28408 } else {
28409 marginGroup.style["grid-template-columns"] = "auto 1fr auto";
28410 left.style["white-space"] = "nowrap";
28411 right.style["white-space"] = "nowrap";
28412 let leftOuterWidth = left.offsetWidth;
28413 let rightOuterWidth = right.offsetWidth;
28414 let outerwidths = leftOuterWidth + rightOuterWidth;
28415 let newLeftWidth = leftOuterWidth * 100 / outerwidths;
28416 marginGroup.style["grid-template-columns"] = "minmax(16.66%, " + newLeftWidth + "%) 0 1fr";
28417 left.style["white-space"] = "normal";
28418 right.style["white-space"] = "normal";
28419 }
28420 }
28421 }
28422 } else {
28423 if (rightWidth !== "none" && rightWidth !== "auto") {
28424 marginGroup.style["grid-template-columns"] = "1fr 0 " + rightWidth;
28425 } else {
28426 marginGroup.style["grid-template-columns"] = "0 0 1fr";
28427 }
28428 }
28429 }
28430 });
28431
28432 // check middle
28433 ["left", "right"].forEach((loc) => {
28434 let middle = page.element.querySelector(".pagedjs_margin-" + loc + "-middle.hasContent");
28435 let marginGroup = page.element.querySelector(".pagedjs_margin-" + loc);
28436 let top = page.element.querySelector(".pagedjs_margin-" + loc + "-top");
28437 let bottom = page.element.querySelector(".pagedjs_margin-" + loc + "-bottom");
28438 let topContent = top.classList.contains("hasContent");
28439 let bottomContent = bottom.classList.contains("hasContent");
28440 let middleHeight, topHeight, bottomHeight;
28441
28442 if (topContent) {
28443 topHeight = window.getComputedStyle(top)["max-height"];
28444 }
28445
28446 if (bottomContent) {
28447 bottomHeight = window.getComputedStyle(bottom)["max-height"];
28448 }
28449
28450 if (middle) {
28451 middleHeight = window.getComputedStyle(middle)["max-height"];
28452
28453 if (middleHeight === "none" || middleHeight === "auto") {
28454 if (!topContent && !bottomContent) {
28455 marginGroup.style["grid-template-rows"] = "0 1fr 0";
28456 } else if (topContent) {
28457 if (!bottomContent) {
28458 if (topHeight !== "none" && topHeight !== "auto") {
28459 marginGroup.style["grid-template-rows"] = topHeight + " calc(100% - " + topHeight + "*2) " + topHeight;
28460 }
28461 } else {
28462 if (topHeight !== "none" && topHeight !== "auto") {
28463 if (bottomHeight !== "none" && bottomHeight !== "auto") {
28464 marginGroup.style["grid-template-rows"] = topHeight + " calc(100% - " + topHeight + " - " + bottomHeight + ") " + bottomHeight;
28465 } else {
28466 marginGroup.style["grid-template-rows"] = topHeight + " calc(100% - " + topHeight + "*2) " + topHeight;
28467 }
28468 } else {
28469 if (bottomHeight !== "none" && bottomHeight !== "auto") {
28470 marginGroup.style["grid-template-rows"] = bottomHeight + " calc(100% - " + bottomHeight + "*2) " + bottomHeight;
28471 }
28472 }
28473 }
28474 } else {
28475 if (bottomHeight !== "none" && bottomHeight !== "auto") {
28476 marginGroup.style["grid-template-rows"] = bottomHeight + " calc(100% - " + bottomHeight + "*2) " + bottomHeight;
28477 }
28478 }
28479 } else {
28480 if (topContent && topHeight !== "none" && topHeight !== "auto") {
28481 marginGroup.style["grid-template-rows"] = topHeight + " " + middleHeight + " calc(100% - (" + topHeight + " + " + middleHeight + "))";
28482 } else if (bottomContent && bottomHeight !== "none" && bottomHeight !== "auto") {
28483 marginGroup.style["grid-template-rows"] = "1fr " + middleHeight + " " + bottomHeight;
28484 } else {
28485 marginGroup.style["grid-template-rows"] = "calc((100% - " + middleHeight + ")/2) " + middleHeight + " calc((100% - " + middleHeight + ")/2)";
28486 }
28487
28488 }
28489
28490 } else {
28491 if (topContent) {
28492 if (!bottomContent) {
28493 marginGroup.style["grid-template-rows"] = "1fr 0 0";
28494 } else {
28495 if (topHeight !== "none" && topHeight !== "auto") {
28496 if (bottomHeight !== "none" && bottomHeight !== "auto") {
28497 marginGroup.style["grid-template-rows"] = topHeight + " 1fr " + bottomHeight;
28498 } else {
28499 marginGroup.style["grid-template-rows"] = topHeight + " 0 1fr";
28500 }
28501 } else {
28502 if (bottomHeight !== "none" && bottomHeight !== "auto") {
28503 marginGroup.style["grid-template-rows"] = "1fr 0 " + bottomHeight;
28504 } else {
28505 marginGroup.style["grid-template-rows"] = "1fr 0 1fr";
28506 }
28507 }
28508 }
28509 } else {
28510 if (bottomHeight !== "none" && bottomHeight !== "auto") {
28511 marginGroup.style["grid-template-rows"] = "1fr 0 " + bottomHeight;
28512 } else {
28513 marginGroup.style["grid-template-rows"] = "0 0 1fr";
28514 }
28515 }
28516 }
28517
28518
28519
28520 });
28521
28522 }
28523
28524 // CSS Tree Helpers
28525
28526 selectorsForPage(page) {
28527 let nthlist;
28528 let nth;
28529
28530 let selectors = new lib.List();
28531
28532 selectors.insertData({
28533 type: "ClassSelector",
28534 name: "pagedjs_page"
28535 });
28536
28537 // Named page
28538 if (page.name) {
28539 selectors.insertData({
28540 type: "ClassSelector",
28541 name: "pagedjs_named_page"
28542 });
28543
28544 selectors.insertData({
28545 type: "ClassSelector",
28546 name: "pagedjs_" + page.name + "_page"
28547 });
28548 }
28549
28550 // PsuedoSelector
28551 if (page.psuedo && !(page.name && page.psuedo === "first")) {
28552 selectors.insertData({
28553 type: "ClassSelector",
28554 name: "pagedjs_" + page.psuedo + "_page"
28555 });
28556 }
28557
28558 if (page.name && page.psuedo === "first") {
28559 selectors.insertData({
28560 type: "ClassSelector",
28561 name: "pagedjs_" + page.name + "_" + page.psuedo + "_page"
28562 });
28563 }
28564
28565 // Nth
28566 if (page.nth) {
28567 nthlist = new lib.List();
28568 nth = this.getNth(page.nth);
28569
28570 nthlist.insertData(nth);
28571
28572 selectors.insertData({
28573 type: "PseudoClassSelector",
28574 name: "nth-of-type",
28575 children: nthlist
28576 });
28577 }
28578
28579 return selectors;
28580 }
28581
28582 selectorsForPageMargin(page, margin) {
28583 let selectors = this.selectorsForPage(page);
28584
28585 selectors.insertData({
28586 type: "Combinator",
28587 name: " "
28588 });
28589
28590 selectors.insertData({
28591 type: "ClassSelector",
28592 name: "pagedjs_margin-" + margin
28593 });
28594
28595 return selectors;
28596 }
28597
28598 createDeclaration(property, value, important) {
28599 let children = new lib.List();
28600
28601 children.insertData({
28602 type: "Identifier",
28603 loc: null,
28604 name: value
28605 });
28606
28607 return {
28608 type: "Declaration",
28609 loc: null,
28610 important: important,
28611 property: property,
28612 value: {
28613 type: "Value",
28614 loc: null,
28615 children: children
28616 }
28617 };
28618 }
28619
28620 createVariable(property, value) {
28621 return {
28622 type: "Declaration",
28623 loc: null,
28624 property: property,
28625 value: {
28626 type: "Raw",
28627 value: value
28628 }
28629 };
28630 }
28631
28632 createCalculatedDimension(property, items, important, operator = "+") {
28633 let children = new lib.List();
28634 let calculations = new lib.List();
28635
28636 items.forEach((item, index) => {
28637 calculations.appendData({
28638 type: "Dimension",
28639 unit: item.unit,
28640 value: item.value
28641 });
28642
28643 calculations.appendData({
28644 type: "WhiteSpace",
28645 value: " "
28646 });
28647
28648 if (index + 1 < items.length) {
28649 calculations.appendData({
28650 type: "Operator",
28651 value: operator
28652 });
28653
28654 calculations.appendData({
28655 type: "WhiteSpace",
28656 value: " "
28657 });
28658 }
28659 });
28660
28661 children.insertData({
28662 type: "Function",
28663 loc: null,
28664 name: "calc",
28665 children: calculations
28666 });
28667
28668 return {
28669 type: "Declaration",
28670 loc: null,
28671 important: important,
28672 property: property,
28673 value: {
28674 type: "Value",
28675 loc: null,
28676 children: children
28677 }
28678 };
28679 }
28680
28681 createDimension(property, cssValue, important) {
28682 let children = new lib.List();
28683
28684 children.insertData({
28685 type: "Dimension",
28686 loc: null,
28687 value: cssValue.value,
28688 unit: cssValue.unit
28689 });
28690
28691 return {
28692 type: "Declaration",
28693 loc: null,
28694 important: important,
28695 property: property,
28696 value: {
28697 type: "Value",
28698 loc: null,
28699 children: children
28700 }
28701 };
28702 }
28703
28704 createBlock(declarations) {
28705 let block = new lib.List();
28706
28707 declarations.forEach((declaration) => {
28708 block.insertData(declaration);
28709 });
28710
28711 return {
28712 type: "Block",
28713 loc: null,
28714 children: block
28715 };
28716 }
28717
28718 createRule(selectors, block) {
28719 let selectorList = new lib.List();
28720 selectorList.insertData({
28721 type: "Selector",
28722 children: selectors
28723 });
28724
28725 if (Array.isArray(block)) {
28726 block = this.createBlock(block);
28727 }
28728
28729 return {
28730 type: "Rule",
28731 prelude: {
28732 type: "SelectorList",
28733 children: selectorList
28734 },
28735 block: block
28736 };
28737 }
28738
28739 }
28740
28741 class Breaks extends Handler {
28742 constructor(chunker, polisher, caller) {
28743 super(chunker, polisher, caller);
28744
28745 this.breaks = {};
28746 }
28747
28748 onDeclaration(declaration, dItem, dList, rule) {
28749 let property = declaration.property;
28750
28751 if (property === "page") {
28752 let children = declaration.value.children.first();
28753 let value = children.name;
28754 let selector = lib.generate(rule.ruleNode.prelude);
28755 let name = value;
28756
28757 let breaker = {
28758 property: property,
28759 value: value,
28760 selector: selector,
28761 name: name
28762 };
28763
28764 selector.split(",").forEach((s) => {
28765 if (!this.breaks[s]) {
28766 this.breaks[s] = [breaker];
28767 } else {
28768 this.breaks[s].push(breaker);
28769 }
28770 });
28771
28772 dList.remove(dItem);
28773 }
28774
28775 if (property === "break-before" ||
28776 property === "break-after" ||
28777 property === "page-break-before" ||
28778 property === "page-break-after"
28779 ) {
28780 let child = declaration.value.children.first();
28781 let value = child.name;
28782 let selector = lib.generate(rule.ruleNode.prelude);
28783
28784 if (property === "page-break-before") {
28785 property = "break-before";
28786 } else if (property === "page-break-after") {
28787 property = "break-after";
28788 }
28789
28790 let breaker = {
28791 property: property,
28792 value: value,
28793 selector: selector
28794 };
28795
28796 selector.split(",").forEach((s) => {
28797 if (!this.breaks[s]) {
28798 this.breaks[s] = [breaker];
28799 } else {
28800 this.breaks[s].push(breaker);
28801 }
28802 });
28803
28804 // Remove from CSS -- handle right / left in module
28805 dList.remove(dItem);
28806 }
28807 }
28808
28809 afterParsed(parsed) {
28810 this.processBreaks(parsed, this.breaks);
28811 }
28812
28813 processBreaks(parsed, breaks) {
28814 for (let b in breaks) {
28815 // Find elements
28816 let elements = parsed.querySelectorAll(b);
28817 // Add break data
28818 for (var i = 0; i < elements.length; i++) {
28819 for (let prop of breaks[b]) {
28820
28821 if (prop.property === "break-after") {
28822 let nodeAfter = displayedElementAfter(elements[i], parsed);
28823
28824 elements[i].setAttribute("data-break-after", prop.value);
28825
28826 if (nodeAfter) {
28827 nodeAfter.setAttribute("data-previous-break-after", prop.value);
28828 }
28829 } else if (prop.property === "break-before") {
28830 let nodeBefore = displayedElementBefore(elements[i], parsed);
28831
28832 // Breaks are only allowed between siblings, not between a box and its container.
28833 // If we cannot find a node before we should not break!
28834 // https://drafts.csswg.org/css-break-3/#break-propagation
28835 if (nodeBefore) {
28836 if (prop.value === "page" && needsPageBreak(elements[i], nodeBefore)) {
28837 // we ignore this explicit page break because an implicit page break is already needed
28838 continue;
28839 }
28840 elements[i].setAttribute("data-break-before", prop.value);
28841 nodeBefore.setAttribute("data-next-break-before", prop.value);
28842 }
28843 } else if (prop.property === "page") {
28844 elements[i].setAttribute("data-page", prop.value);
28845
28846 let nodeAfter = displayedElementAfter(elements[i], parsed);
28847
28848 if (nodeAfter) {
28849 nodeAfter.setAttribute("data-after-page", prop.value);
28850 }
28851 } else {
28852 elements[i].setAttribute("data-" + prop.property, prop.value);
28853 }
28854 }
28855 }
28856 }
28857 }
28858
28859 mergeBreaks(pageBreaks, newBreaks) {
28860 for (let b in newBreaks) {
28861 if (b in pageBreaks) {
28862 pageBreaks[b] = pageBreaks[b].concat(newBreaks[b]);
28863 } else {
28864 pageBreaks[b] = newBreaks[b];
28865 }
28866 }
28867 return pageBreaks;
28868 }
28869
28870 addBreakAttributes(pageElement, page) {
28871 let before = pageElement.querySelector("[data-break-before]");
28872 let after = pageElement.querySelector("[data-break-after]");
28873 let previousBreakAfter = pageElement.querySelector("[data-previous-break-after]");
28874
28875 if (before) {
28876 if (before.dataset.splitFrom) {
28877 page.splitFrom = before.dataset.splitFrom;
28878 pageElement.setAttribute("data-split-from", before.dataset.splitFrom);
28879 } else if (before.dataset.breakBefore && before.dataset.breakBefore !== "avoid") {
28880 page.breakBefore = before.dataset.breakBefore;
28881 pageElement.setAttribute("data-break-before", before.dataset.breakBefore);
28882 }
28883 }
28884
28885 if (after && after.dataset) {
28886 if (after.dataset.splitTo) {
28887 page.splitTo = after.dataset.splitTo;
28888 pageElement.setAttribute("data-split-to", after.dataset.splitTo);
28889 } else if (after.dataset.breakAfter && after.dataset.breakAfter !== "avoid") {
28890 page.breakAfter = after.dataset.breakAfter;
28891 pageElement.setAttribute("data-break-after", after.dataset.breakAfter);
28892 }
28893 }
28894
28895 if (previousBreakAfter && previousBreakAfter.dataset) {
28896 if (previousBreakAfter.dataset.previousBreakAfter && previousBreakAfter.dataset.previousBreakAfter !== "avoid") {
28897 page.previousBreakAfter = previousBreakAfter.dataset.previousBreakAfter;
28898 }
28899 }
28900 }
28901
28902 afterPageLayout(pageElement, page) {
28903 this.addBreakAttributes(pageElement, page);
28904 }
28905 }
28906
28907 class PrintMedia extends Handler {
28908 constructor(chunker, polisher, caller) {
28909 super(chunker, polisher, caller);
28910 }
28911
28912 onAtMedia(node, item, list) {
28913 let media = this.getMediaName(node);
28914 let rules;
28915
28916 if (media === "print") {
28917 rules = node.block.children;
28918
28919 // Remove rules from the @media block
28920 node.block.children = new lib.List();
28921
28922 // Append rules to the end of main rules list
28923 list.appendList(rules);
28924 }
28925
28926 }
28927
28928 getMediaName(node) {
28929 let media = "";
28930
28931 if (typeof node.prelude === "undefined" ||
28932 node.prelude.type !== "AtrulePrelude" ) {
28933 return;
28934 }
28935
28936 lib.walk(node.prelude, {
28937 visit: "Identifier",
28938 enter: (identNode, iItem, iList) => {
28939 media = identNode.name;
28940 }
28941 });
28942 return media;
28943 }
28944
28945
28946 }
28947
28948 class Splits extends Handler {
28949 constructor(chunker, polisher, caller) {
28950 super(chunker, polisher, caller);
28951 }
28952
28953 afterPageLayout(pageElement, page, breakToken, chunker) {
28954 let splits = Array.from(pageElement.querySelectorAll("[data-split-from]"));
28955 let pages = pageElement.parentNode;
28956 let index = Array.prototype.indexOf.call(pages.children, pageElement);
28957 let prevPage;
28958
28959 if (index === 0) {
28960 return;
28961 }
28962
28963 prevPage = pages.children[index - 1];
28964
28965 let from; // Capture the last from element
28966 splits.forEach((split) => {
28967 let ref = split.dataset.ref;
28968 from = prevPage.querySelector("[data-ref='"+ ref +"']:not([data-split-to])");
28969
28970 if (from) {
28971 from.dataset.splitTo = ref;
28972
28973 if (!from.dataset.splitFrom) {
28974 from.dataset.splitOriginal = true;
28975 }
28976 }
28977 });
28978
28979 // Fix alignment on the deepest split element
28980 if (from) {
28981 this.handleAlignment(from);
28982 }
28983 }
28984
28985 handleAlignment(node) {
28986 let styles = window.getComputedStyle(node);
28987 let align = styles["text-align"];
28988 let alignLast = styles["text-align-last"];
28989 node.dataset.lastSplitElement = "true";
28990 if (align === "justify" && alignLast === "auto") {
28991 node.dataset.alignLastSplitElement = "justify";
28992 } else {
28993 node.dataset.alignLastSplitElement = alignLast;
28994 }
28995 }
28996
28997 }
28998
28999 class Counters extends Handler {
29000 constructor(chunker, polisher, caller) {
29001 super(chunker, polisher, caller);
29002
29003 this.styleSheet = polisher.styleSheet;
29004 this.counters = {};
29005 this.resetCountersMap = new Map();
29006 }
29007
29008 onDeclaration(declaration, dItem, dList, rule) {
29009 let property = declaration.property;
29010
29011 if (property === "counter-increment") {
29012 let inc = this.handleIncrement(declaration, rule);
29013 if (inc) {
29014 dList.remove(dItem);
29015 }
29016 } else if (property === "counter-reset") {
29017 let reset = this.handleReset(declaration, rule);
29018 if (reset) {
29019 dList.remove(dItem);
29020 }
29021 }
29022 }
29023
29024 onContent(funcNode, fItem, fList, declaration, rule) {
29025 if (funcNode.name === "counter") ;
29026 }
29027
29028 afterParsed(parsed) {
29029 this.processCounters(parsed, this.counters);
29030 this.scopeCounters(this.counters);
29031 }
29032
29033 addCounter(name) {
29034 if (name in this.counters) {
29035 return this.counters[name];
29036 }
29037
29038 this.counters[name] = {
29039 name: name,
29040 increments: {},
29041 resets: {}
29042 };
29043
29044 return this.counters[name];
29045 }
29046
29047 handleIncrement(declaration, rule) {
29048 const identifier = declaration.value.children.first();
29049 const number = declaration.value.children.getSize() > 1 ? declaration.value.children.last().value : 1;
29050 const name = identifier && identifier.name;
29051
29052 if (name === "page" || name.indexOf("target-counter-") === 0) {
29053 return;
29054 }
29055
29056 let selector = lib.generate(rule.ruleNode.prelude);
29057
29058 let counter;
29059 if (!(name in this.counters)) {
29060 counter = this.addCounter(name);
29061 } else {
29062 counter = this.counters[name];
29063 }
29064
29065 return counter.increments[selector] = {
29066 selector: selector,
29067 number
29068 };
29069 }
29070
29071 handleReset(declaration, rule) {
29072 let identifier = declaration.value.children.first();
29073 let number = declaration.value.children.getSize() > 1
29074 && declaration.value.children.last().value;
29075 let name = identifier && identifier.name;
29076 let selector = lib.generate(rule.ruleNode.prelude);
29077 let counter;
29078
29079 if (!(name in this.counters)) {
29080 counter = this.addCounter(name);
29081 } else {
29082 counter = this.counters[name];
29083 }
29084
29085 return counter.resets[selector] = {
29086 selector: selector,
29087 number: number || 0
29088 };
29089 }
29090
29091 processCounters(parsed, counters) {
29092 let counter;
29093 for (let c in counters) {
29094 counter = this.counters[c];
29095 this.processCounterIncrements(parsed, counter);
29096 this.processCounterResets(parsed, counter);
29097 if (c !== "page") {
29098 this.addCounterValues(parsed, counter);
29099 }
29100 }
29101 }
29102
29103 scopeCounters(counters) {
29104 let countersArray = [];
29105 for (let c in counters) {
29106 if(c !== "page") {
29107 countersArray.push(`${counters[c].name} 0`);
29108 }
29109 }
29110 // Add to pages to allow cross page scope
29111 this.insertRule(`.pagedjs_pages { counter-reset: ${countersArray.join(" ")} page 0 pages var(--pagedjs-page-count)}`);
29112 }
29113
29114 insertRule(rule) {
29115 this.styleSheet.insertRule(rule, this.styleSheet.cssRules.length);
29116 }
29117
29118 processCounterIncrements(parsed, counter) {
29119 let increment;
29120 for (let inc in counter.increments) {
29121 increment = counter.increments[inc];
29122 // Find elements for increments
29123 let incrementElements = parsed.querySelectorAll(increment.selector);
29124 // Add counter data
29125 for (let i = 0; i < incrementElements.length; i++) {
29126 incrementElements[i].setAttribute("data-counter-"+ counter.name +"-increment", increment.number);
29127 incrementElements[i].setAttribute("data-counter-increment", counter.name);
29128 }
29129 }
29130 }
29131
29132 processCounterResets(parsed, counter) {
29133 let reset;
29134 for (let r in counter.resets) {
29135 reset = counter.resets[r];
29136 // Find elements for resets
29137 let resetElements = parsed.querySelectorAll(reset.selector);
29138 // Add counter data
29139 for (var i = 0; i < resetElements.length; i++) {
29140 resetElements[i].setAttribute("data-counter-"+ counter.name +"-reset", reset.number);
29141 resetElements[i].setAttribute("data-counter-reset", counter.name);
29142 }
29143 }
29144 }
29145
29146 addCounterValues(parsed, counter) {
29147 const counterName = counter.name;
29148 const elements = parsed.querySelectorAll("[data-counter-"+ counterName +"-reset], [data-counter-"+ counterName +"-increment]");
29149
29150 let count = 0;
29151 let element;
29152 let increment, reset;
29153 let resetValue, incrementValue, resetDelta;
29154 let incrementArray;
29155
29156 for (let i = 0; i < elements.length; i++) {
29157 element = elements[i];
29158 resetDelta = 0;
29159 incrementArray = [];
29160
29161 if (element.hasAttribute("data-counter-"+ counterName +"-reset")) {
29162 reset = element.getAttribute("data-counter-"+ counterName +"-reset");
29163 resetValue = parseInt(reset);
29164
29165 // Use negative increment value inplace of reset
29166 resetDelta = resetValue - count;
29167 incrementArray.push(`${counterName} ${resetDelta}`);
29168
29169 count = resetValue;
29170 }
29171
29172 if (element.hasAttribute("data-counter-"+ counterName +"-increment")) {
29173
29174 increment = element.getAttribute("data-counter-"+ counterName +"-increment");
29175 incrementValue = parseInt(increment);
29176
29177 count += incrementValue;
29178
29179 element.setAttribute("data-counter-"+counterName+"-value", count);
29180
29181 incrementArray.push(`${counterName} ${incrementValue}`);
29182 }
29183
29184 if (incrementArray.length > 0) {
29185 this.incrementCounterForElement(element, incrementArray);
29186 }
29187
29188 }
29189 }
29190
29191 incrementCounterForElement(element, incrementArray) {
29192 if (!element || !incrementArray || incrementArray.length === 0) return;
29193
29194 const ref = element.dataset.ref;
29195 const prevIncrements = Array.from(this.styleSheet.cssRules).filter((rule) => {
29196 return rule.selectorText === `[data-ref="${element.dataset.ref}"]:not([data-split-from])`
29197 && rule.style[0] === "counter-increment";
29198 });
29199
29200 const increments = [];
29201 for (let styleRule of prevIncrements) {
29202 let values = styleRule.style.counterIncrement.split(" ");
29203 for (let i = 0; i < values.length; i+=2) {
29204 increments.push(values[i] + " " + values[i+1]);
29205 }
29206 }
29207
29208 Array.prototype.push.apply(increments, incrementArray);
29209
29210 this.insertRule(`[data-ref="${ref}"]:not([data-split-from]) { counter-increment: ${increments.join(" ")} }`);
29211 }
29212
29213 afterPageLayout(pageElement, page) {
29214 let pgreset = pageElement.querySelectorAll("[data-counter-page-reset]");
29215 pgreset.forEach((reset) => {
29216 const ref = reset.dataset && reset.dataset.ref;
29217 if (ref && this.resetCountersMap.has(ref)) ; else {
29218 if (ref) {
29219 this.resetCountersMap.set(ref, "");
29220 }
29221 let value = reset.dataset.counterPageReset;
29222 this.styleSheet.insertRule(`[data-page-number="${pageElement.dataset.pageNumber}"] { counter-increment: none; counter-reset: page ${value}; }`, this.styleSheet.cssRules.length);
29223 }
29224 });
29225 }
29226
29227 }
29228
29229 class Lists extends Handler {
29230 constructor(chunker, polisher, caller) {
29231 super(chunker, polisher, caller);
29232 }
29233 afterParsed(content) {
29234 const orderedLists = content.querySelectorAll("ol");
29235
29236 for (var list of orderedLists) {
29237 this.addDataNumbers(list);
29238 }
29239 }
29240
29241 afterPageLayout(pageElement, page, breakToken, chunker) {
29242 var orderedLists = pageElement.getElementsByTagName("ol");
29243 for (var list of orderedLists) {
29244 if (list.hasChildNodes()) {
29245 list.start = list.firstElementChild.dataset.itemNum;
29246 }
29247 else {
29248 list.parentNode.removeChild(list);
29249 }
29250 }
29251 }
29252
29253 addDataNumbers(list) {
29254 let start = 1;
29255 if (list.hasAttribute("start")) {
29256 start = parseInt(list.getAttribute("start"), 10);
29257 if (isNaN(start)) {
29258 start = 1;
29259 }
29260 }
29261 let items = list.children;
29262 for (var i = 0; i < items.length; i++) {
29263 items[i].setAttribute("data-item-num", i + start);
29264 }
29265 }
29266
29267 }
29268
29269 class PositionFixed extends Handler {
29270 constructor(chunker, polisher, caller) {
29271 super(chunker, polisher, caller);
29272 this.styleSheet = polisher.styleSheet;
29273 this.fixedElementsSelector = [];
29274 this.fixedElements = [];
29275 }
29276
29277 onDeclaration(declaration, dItem, dList, rule) {
29278 if (declaration.property === "position" && declaration.value.children.first().name === "fixed") {
29279 let selector = lib.generate(rule.ruleNode.prelude);
29280 this.fixedElementsSelector.push(selector);
29281 dList.remove(dItem);
29282 }
29283 }
29284
29285 afterParsed(fragment) {
29286 this.fixedElementsSelector.forEach(fixedEl => {
29287 fragment.querySelectorAll(`${fixedEl}`).forEach(el => {
29288 el.style.setProperty("position", "absolute");
29289 this.fixedElements.push(el);
29290 el.remove();
29291 });
29292 });
29293 }
29294
29295 afterPageLayout(pageElement, page, breakToken) {
29296 this.fixedElements.forEach(el => {
29297 const clone = el.cloneNode(true);
29298 pageElement.querySelector(".pagedjs_pagebox").insertAdjacentElement("afterbegin", clone);
29299 });
29300 }
29301 }
29302
29303 class PageCounterIncrement extends Handler {
29304 constructor(chunker, polisher, caller) {
29305 super(chunker, polisher, caller);
29306
29307 this.styleSheet = polisher.styleSheet;
29308 this.pageCounter = {
29309 name: "page",
29310 increments: {},
29311 resets: {}
29312 };
29313 }
29314
29315 onDeclaration(declaration, dItem, dList, rule) {
29316 const property = declaration.property;
29317
29318 if (property === "counter-increment") {
29319 let inc = this.handleIncrement(declaration, rule);
29320 if (inc) {
29321 dList.remove(dItem);
29322 }
29323 }
29324 }
29325
29326 afterParsed(_) {
29327 for (const inc in this.pageCounter.increments) {
29328 const increment = this.pageCounter.increments[inc];
29329 this.insertRule(`${increment.selector} { --pagedjs-page-counter-increment: ${increment.number} }`);
29330 }
29331 }
29332
29333 handleIncrement(declaration, rule) {
29334 const identifier = declaration.value.children.first();
29335 const number = declaration.value.children.getSize() > 1 ? declaration.value.children.last().value : 1;
29336 const name = identifier && identifier.name;
29337
29338 if (name.indexOf("target-counter-") === 0) {
29339 return;
29340 }
29341 // A counter named page is automatically created and incremented by 1 on every page of the document,
29342 // unless the counter-increment property in the page context explicitly specifies a different increment for the page counter.
29343 // https://www.w3.org/TR/css-page-3/#page-based-counters
29344 if (name !== "page") {
29345 return;
29346 }
29347 // the counter-increment property is not defined on the page context (i.e. @page rule), ignoring...
29348 if (rule.ruleNode.name === "page" && rule.ruleNode.type === "Atrule") {
29349 return;
29350 }
29351 const selector = lib.generate(rule.ruleNode.prelude);
29352 return this.pageCounter.increments[selector] = {
29353 selector: selector,
29354 number
29355 };
29356 }
29357
29358 insertRule(rule) {
29359 this.styleSheet.insertRule(rule, this.styleSheet.cssRules.length);
29360 }
29361 }
29362
29363 class NthOfType extends Handler {
29364 constructor(chunker, polisher, caller) {
29365 super(chunker, polisher, caller);
29366
29367 this.styleSheet = polisher.styleSheet;
29368 this.selectors = {};
29369 }
29370
29371 onRule(ruleNode, ruleItem, rulelist) {
29372 let selector = lib.generate(ruleNode.prelude);
29373 if (selector.match(/:(first|last|nth)-of-type/)) {
29374
29375 let declarations = lib.generate(ruleNode.block);
29376 declarations = declarations.replace(/[{}]/g,"");
29377
29378 let uuid = "nth-of-type-" + UUID();
29379
29380 selector.split(",").forEach((s) => {
29381 if (!this.selectors[s]) {
29382 this.selectors[s] = [uuid, declarations];
29383 } else {
29384 this.selectors[s][1] = `${this.selectors[s][1]};${declarations}` ;
29385 }
29386 });
29387
29388 rulelist.remove(ruleItem);
29389 }
29390 }
29391
29392 afterParsed(parsed) {
29393 this.processSelectors(parsed, this.selectors);
29394 }
29395
29396 processSelectors(parsed, selectors) {
29397 // add the new attributes to matching elements
29398 for (let s in selectors) {
29399 let elements = parsed.querySelectorAll(s);
29400
29401 for (var i = 0; i < elements.length; i++) {
29402 let dataNthOfType = elements[i].getAttribute("data-nth-of-type");
29403
29404 if (dataNthOfType && dataNthOfType != "") {
29405 dataNthOfType = `${dataNthOfType},${selectors[s][0]}`;
29406 elements[i].setAttribute("data-nth-of-type", dataNthOfType);
29407 } else {
29408 elements[i].setAttribute("data-nth-of-type", selectors[s][0]);
29409 }
29410 }
29411
29412 let rule = `*[data-nth-of-type*='${selectors[s][0]}'] { ${selectors[s][1]}; }`;
29413 this.styleSheet.insertRule(rule, this.styleSheet.cssRules.length);
29414 }
29415 }
29416 }
29417
29418 class Following extends Handler {
29419 constructor(chunker, polisher, caller) {
29420 super(chunker, polisher, caller);
29421
29422 this.styleSheet = polisher.styleSheet;
29423 this.selectors = {};
29424 }
29425
29426 onRule(ruleNode, ruleItem, rulelist) {
29427 let selector = lib.generate(ruleNode.prelude);
29428 if (selector.match(/\+/)) {
29429
29430 let declarations = lib.generate(ruleNode.block);
29431 declarations = declarations.replace(/[{}]/g,"");
29432
29433 let uuid = "following-" + UUID();
29434
29435 selector.split(",").forEach((s) => {
29436 if (!this.selectors[s]) {
29437 this.selectors[s] = [uuid, declarations];
29438 } else {
29439 this.selectors[s][1] = `${this.selectors[s][1]};${declarations}` ;
29440 }
29441 });
29442
29443 rulelist.remove(ruleItem);
29444 }
29445 }
29446
29447 afterParsed(parsed) {
29448 this.processSelectors(parsed, this.selectors);
29449 }
29450
29451 processSelectors(parsed, selectors) {
29452 // add the new attributes to matching elements
29453 for (let s in selectors) {
29454 let elements = parsed.querySelectorAll(s);
29455
29456 for (var i = 0; i < elements.length; i++) {
29457 let dataFollowing = elements[i].getAttribute("data-following");
29458
29459 if (dataFollowing && dataFollowing != "") {
29460 dataFollowing = `${dataFollowing},${selectors[s][0]}`;
29461 elements[i].setAttribute("data-following", dataFollowing);
29462 } else {
29463 elements[i].setAttribute("data-following", selectors[s][0]);
29464 }
29465 }
29466
29467 let rule = `*[data-following*='${selectors[s][0]}'] { ${selectors[s][1]}; }`;
29468 this.styleSheet.insertRule(rule, this.styleSheet.cssRules.length);
29469 }
29470 }
29471 }
29472
29473 var pagedMediaHandlers = [
29474 AtPage,
29475 Breaks,
29476 PrintMedia,
29477 Splits,
29478 Counters,
29479 Lists,
29480 PositionFixed,
29481 PageCounterIncrement,
29482 NthOfType,
29483 Following
29484 ];
29485
29486 class RunningHeaders extends Handler {
29487 constructor(chunker, polisher, caller) {
29488 super(chunker, polisher, caller);
29489
29490 this.runningSelectors = {};
29491 this.elements = {};
29492 }
29493
29494 onDeclaration(declaration, dItem, dList, rule) {
29495 if (declaration.property === "position") {
29496 let selector = lib.generate(rule.ruleNode.prelude);
29497 let identifier = declaration.value.children.first().name;
29498
29499 if (identifier === "running") {
29500 let value;
29501 lib.walk(declaration, {
29502 visit: "Function",
29503 enter: (node, item, list) => {
29504 value = node.children.first().name;
29505 }
29506 });
29507
29508 this.runningSelectors[value] = {
29509 identifier: identifier,
29510 value: value,
29511 selector: selector
29512 };
29513 }
29514 }
29515
29516 if (declaration.property === "content") {
29517
29518 lib.walk(declaration, {
29519 visit: "Function",
29520 enter: (funcNode, fItem, fList) => {
29521
29522 if (funcNode.name.indexOf("element") > -1) {
29523
29524 let selector = lib.generate(rule.ruleNode.prelude);
29525
29526 let func = funcNode.name;
29527
29528 let value = funcNode.children.first().name;
29529
29530 let args = [value];
29531
29532 // we only handle first for now
29533 let style = "first";
29534
29535 selector.split(",").forEach((s) => {
29536 // remove before / after
29537 s = s.replace(/::after|::before/, "");
29538
29539 this.elements[s] = {
29540 func: func,
29541 args: args,
29542 value: value,
29543 style: style ,
29544 selector: s,
29545 fullSelector: selector
29546 };
29547 });
29548 }
29549
29550 }
29551 });
29552 }
29553 }
29554
29555 afterParsed(fragment) {
29556 for (let name of Object.keys(this.runningSelectors)) {
29557 let set = this.runningSelectors[name];
29558 let selected = Array.from(fragment.querySelectorAll(set.selector));
29559
29560 if (set.identifier === "running") {
29561 for (let header of selected) {
29562 header.style.display = "none";
29563 }
29564 }
29565
29566 }
29567 }
29568
29569 afterPageLayout(fragment) {
29570 for (let name of Object.keys(this.runningSelectors)) {
29571 let set = this.runningSelectors[name];
29572 let selected = fragment.querySelector(set.selector);
29573 if (selected) {
29574 // let cssVar;
29575 if (set.identifier === "running") {
29576 // cssVar = selected.textContent.replace(/\\([\s\S])|(["|'])/g,"\\$1$2");
29577 // this.styleSheet.insertRule(`:root { --string-${name}: "${cssVar}"; }`, this.styleSheet.cssRules.length);
29578 // fragment.style.setProperty(`--string-${name}`, `"${cssVar}"`);
29579 set.first = selected;
29580 } else {
29581 console.warn(set.value + "needs css replacement");
29582 }
29583 }
29584 }
29585
29586 // move elements
29587 if (!this.orderedSelectors) {
29588 this.orderedSelectors = this.orderSelectors(this.elements);
29589 }
29590
29591 for (let selector of this.orderedSelectors) {
29592 if (selector) {
29593
29594 let el = this.elements[selector];
29595 let selected = fragment.querySelector(selector);
29596 if (selected) {
29597 let running = this.runningSelectors[el.args[0]];
29598 if (running && running.first) {
29599 selected.innerHTML = ""; // Clear node
29600 // selected.classList.add("pagedjs_clear-after"); // Clear ::after
29601 let clone = running.first.cloneNode(true);
29602 clone.style.display = null;
29603 selected.appendChild(clone);
29604 }
29605 }
29606 }
29607 }
29608 }
29609
29610 /**
29611 * Assign a weight to @page selector classes
29612 * 1) page
29613 * 2) left & right
29614 * 3) blank
29615 * 4) first & nth
29616 * 5) named page
29617 * 6) named left & right
29618 * 7) named first & nth
29619 * @param {string} [s] selector string
29620 * @return {int} weight
29621 */
29622 pageWeight(s) {
29623 let weight = 1;
29624 let selector = s.split(" ");
29625 let parts = selector.length && selector[0].split(".");
29626
29627 parts.shift(); // remove empty first part
29628
29629 switch (parts.length) {
29630 case 4:
29631 if (parts[3] === "pagedjs_first_page") {
29632 weight = 7;
29633 } else if (parts[3] === "pagedjs_left_page" || parts[3] === "pagedjs_right_page") {
29634 weight = 6;
29635 }
29636 break;
29637 case 3:
29638 if (parts[1] === "pagedjs_named_page") {
29639 if (parts[2].indexOf(":nth-of-type") > -1) {
29640 weight = 7;
29641 } else {
29642 weight = 5;
29643 }
29644 }
29645 break;
29646 case 2:
29647 if (parts[1] === "pagedjs_first_page") {
29648 weight = 4;
29649 } else if (parts[1] === "pagedjs_blank_page") {
29650 weight = 3;
29651 } else if (parts[1] === "pagedjs_left_page" || parts[1] === "pagedjs_right_page") {
29652 weight = 2;
29653 }
29654 break;
29655 default:
29656 if (parts[0].indexOf(":nth-of-type") > -1) {
29657 weight = 4;
29658 } else {
29659 weight = 1;
29660 }
29661 }
29662
29663 return weight;
29664 }
29665
29666 /**
29667 * Orders the selectors based on weight
29668 *
29669 * Does not try to deduplicate base on specifity of the selector
29670 * Previous matched selector will just be overwritten
29671 * @param {obj} [obj] selectors object
29672 * @return {Array} orderedSelectors
29673 */
29674 orderSelectors(obj) {
29675 let selectors = Object.keys(obj);
29676 let weighted = {
29677 1: [],
29678 2: [],
29679 3: [],
29680 4: [],
29681 5: [],
29682 6: [],
29683 7: []
29684 };
29685
29686 let orderedSelectors = [];
29687
29688 for (let s of selectors) {
29689 let w = this.pageWeight(s);
29690 weighted[w].unshift(s);
29691 }
29692
29693 for (var i = 1; i <= 7; i++) {
29694 orderedSelectors = orderedSelectors.concat(weighted[i]);
29695 }
29696
29697 return orderedSelectors;
29698 }
29699
29700 beforeTreeParse(text, sheet) {
29701 // element(x) is parsed as image element selector, so update element to element-ident
29702 sheet.text = text.replace(/element[\s]*\(([^|^#)]*)\)/g, "element-ident($1)");
29703 }
29704 }
29705
29706 function cleanPseudoContent(el, trim = "\"' ") {
29707 if(el == null) return;
29708 return el
29709 .replace(new RegExp(`^[${trim}]+`), "")
29710 .replace(new RegExp(`[${trim}]+$`), "")
29711 .replace(/["']/g, match => {
29712 return "\\" + match;
29713 })
29714 .replace(/[\n]/g, match => {
29715 return "\\00000A";
29716 });
29717 }
29718
29719 function cleanSelector(el) {
29720 if(el == null) return;
29721 return el
29722 .replace(new RegExp("::footnote-call", "g"), "")
29723 .replace(new RegExp("::footnote-marker", "g"), "");
29724 }
29725
29726 class StringSets extends Handler {
29727 constructor(chunker, polisher, caller) {
29728 super(chunker, polisher, caller);
29729
29730 this.stringSetSelectors = {};
29731 this.type;
29732 // pageLastString = last string variable defined on the page
29733 this.pageLastString;
29734
29735 }
29736
29737 onDeclaration(declaration, dItem, dList, rule) {
29738 if (declaration.property === "string-set") {
29739 let selector = lib.generate(rule.ruleNode.prelude);
29740
29741 let identifier = declaration.value.children.first().name;
29742
29743 let value;
29744 lib.walk(declaration, {
29745 visit: "Function",
29746 enter: (node, item, list) => {
29747 value = lib.generate(node);
29748 }
29749 });
29750
29751 this.stringSetSelectors[identifier] = {
29752 identifier,
29753 value,
29754 selector
29755 };
29756 }
29757 }
29758
29759 onContent(funcNode, fItem, fList, declaration, rule) {
29760
29761 if (funcNode.name === "string") {
29762 let identifier = funcNode.children && funcNode.children.first().name;
29763 this.type = funcNode.children.last().name;
29764 funcNode.name = "var";
29765 funcNode.children = new lib.List();
29766
29767
29768 if(this.type === "first" || this.type === "last" || this.type === "start" || this.type === "first-except"){
29769 funcNode.children.append(
29770 funcNode.children.createItem({
29771 type: "Identifier",
29772 loc: null,
29773 name: "--pagedjs-string-" + this.type + "-" + identifier
29774 })
29775 );
29776 }else {
29777 funcNode.children.append(
29778 funcNode.children.createItem({
29779 type: "Identifier",
29780 loc: null,
29781 name: "--pagedjs-string-first-" + identifier
29782 })
29783 );
29784 }
29785 }
29786 }
29787
29788 afterPageLayout(fragment) {
29789
29790
29791 if ( this.pageLastString === undefined )
29792 {
29793 this.pageLastString = {};
29794 }
29795
29796
29797 for (let name of Object.keys(this.stringSetSelectors)) {
29798
29799 let set = this.stringSetSelectors[name];
29800 let selected = fragment.querySelectorAll(set.selector);
29801
29802 // Get the last found string for the current identifier
29803 let stringPrevPage = ( name in this.pageLastString ) ? this.pageLastString[name] : "";
29804
29805 let varFirst, varLast, varStart, varFirstExcept;
29806
29807 if(selected.length == 0){
29808 // if there is no sel. on the page
29809 varFirst = stringPrevPage;
29810 varLast = stringPrevPage;
29811 varStart = stringPrevPage;
29812 varFirstExcept = stringPrevPage;
29813 }else {
29814
29815 selected.forEach((sel) => {
29816 // push each content into the array to define in the variable the first and the last element of the page.
29817 this.pageLastString[name] = selected[selected.length - 1].textContent;
29818
29819 });
29820
29821 /* FIRST */
29822
29823 varFirst = selected[0].textContent;
29824
29825
29826 /* LAST */
29827
29828 varLast = selected[selected.length - 1].textContent;
29829
29830
29831 /* START */
29832
29833 // Hack to find if the sel. is the first elem of the page / find a better way
29834 let selTop = selected[0].getBoundingClientRect().top;
29835 let pageContent = selected[0].closest(".pagedjs_page_content");
29836 let pageContentTop = pageContent.getBoundingClientRect().top;
29837
29838 if(selTop == pageContentTop){
29839 varStart = varFirst;
29840 }else {
29841 varStart = stringPrevPage;
29842 }
29843
29844 /* FIRST EXCEPT */
29845
29846 varFirstExcept = "";
29847
29848 }
29849
29850 fragment.style.setProperty(`--pagedjs-string-first-${name}`, `"${cleanPseudoContent(varFirst)}`);
29851 fragment.style.setProperty(`--pagedjs-string-last-${name}`, `"${cleanPseudoContent(varLast)}`);
29852 fragment.style.setProperty(`--pagedjs-string-start-${name}`, `"${cleanPseudoContent(varStart)}`);
29853 fragment.style.setProperty(`--pagedjs-string-first-except-${name}`, `"${cleanPseudoContent(varFirstExcept)}`);
29854
29855
29856 }
29857 }
29858
29859
29860 }
29861
29862 class TargetCounters extends Handler {
29863 constructor(chunker, polisher, caller) {
29864 super(chunker, polisher, caller);
29865
29866 this.styleSheet = polisher.styleSheet;
29867
29868 this.counterTargets = {};
29869 }
29870
29871 onContent(funcNode, fItem, fList, declaration, rule) {
29872 if (funcNode.name === "target-counter") {
29873 let selector = lib.generate(rule.ruleNode.prelude);
29874
29875 let first = funcNode.children.first();
29876 let func = first.name;
29877
29878 let value = lib.generate(funcNode);
29879
29880 let args = [];
29881
29882 first.children.forEach((child) => {
29883 if (child.type === "Identifier") {
29884
29885 args.push(child.name);
29886 }
29887 });
29888
29889 let counter;
29890 let style;
29891 let styleIdentifier;
29892
29893 funcNode.children.forEach((child) => {
29894 if (child.type === "Identifier") {
29895 if (!counter) {
29896 counter = child.name;
29897 } else if (!style) {
29898 styleIdentifier = lib.clone(child);
29899 style = child.name;
29900 }
29901 }
29902 });
29903
29904 let variable = "target-counter-" + UUID();
29905
29906 selector.split(",").forEach((s) => {
29907 this.counterTargets[s] = {
29908 func: func,
29909 args: args,
29910 value: value,
29911 counter: counter,
29912 style: style,
29913 selector: s,
29914 fullSelector: selector,
29915 variable: variable
29916 };
29917 });
29918
29919 // Replace with counter
29920 funcNode.name = "counter";
29921 funcNode.children = new lib.List();
29922 funcNode.children.appendData({
29923 type: "Identifier",
29924 loc: 0,
29925 name: variable
29926 });
29927
29928 if (styleIdentifier) {
29929 funcNode.children.appendData({type: "Operator", loc: null, value: ","});
29930 funcNode.children.appendData(styleIdentifier);
29931 }
29932 }
29933 }
29934
29935 afterPageLayout(fragment, page, breakToken, chunker) {
29936 Object.keys(this.counterTargets).forEach((name) => {
29937 let target = this.counterTargets[name];
29938 let split = target.selector.split("::");
29939 let query = split[0];
29940
29941 let queried = chunker.pagesArea.querySelectorAll(query + ":not([data-" + target.variable + "])");
29942
29943 queried.forEach((selected, index) => {
29944 // TODO: handle func other than attr
29945 if (target.func !== "attr") {
29946 return;
29947 }
29948 let val = attr(selected, target.args);
29949 let element = chunker.pagesArea.querySelector(querySelectorEscape(val));
29950
29951 if (element) {
29952 let selector = UUID();
29953 selected.setAttribute("data-" + target.variable, selector);
29954 // TODO: handle other counter types (by query)
29955 let pseudo = "";
29956 if (split.length > 1) {
29957 pseudo += "::" + split[1];
29958 }
29959 if (target.counter === "page") {
29960 let pages = chunker.pagesArea.querySelectorAll(".pagedjs_page");
29961 let pg = 0;
29962 for (let i = 0; i < pages.length; i++) {
29963 let styles = window.getComputedStyle(pages[i]);
29964 let reset = styles["counter-reset"].replace("page", "").trim();
29965 let increment = styles["counter-increment"].replace("page", "").trim();
29966
29967 if (reset !== "none") {
29968 pg = parseInt(reset);
29969 }
29970 if (increment !== "none") {
29971 pg += parseInt(increment);
29972 }
29973
29974 if (pages[i].contains(element)) {
29975 break;
29976 }
29977 }
29978
29979 this.styleSheet.insertRule(`[data-${target.variable}="${selector}"]${pseudo} { counter-reset: ${target.variable} ${pg}; }`, this.styleSheet.cssRules.length);
29980 } else {
29981 let value = element.getAttribute(`data-counter-${target.counter}-value`);
29982 if (value) {
29983 this.styleSheet.insertRule(`[data-${target.variable}="${selector}"]${pseudo} { counter-reset: ${target.variable} ${target.variable} ${parseInt(value)}; }`, this.styleSheet.cssRules.length);
29984 }
29985 }
29986 }
29987 });
29988 });
29989 }
29990 }
29991
29992 // import { nodeAfter } from "../../utils/dom";
29993
29994 class TargetText extends Handler {
29995 constructor(chunker, polisher, caller) {
29996 super(chunker, polisher, caller);
29997
29998 this.styleSheet = polisher.styleSheet;
29999 this.textTargets = {};
30000 this.beforeContent = "";
30001 this.afterContent = "";
30002 this.selector = {};
30003 }
30004
30005 onContent(funcNode, fItem, fList, declaration, rule) {
30006 if (funcNode.name === "target-text") {
30007 this.selector = lib.generate(rule.ruleNode.prelude);
30008 let first = funcNode.children.first();
30009 let last = funcNode.children.last();
30010 let func = first.name;
30011
30012 let value = lib.generate(funcNode);
30013
30014 let args = [];
30015
30016 first.children.forEach(child => {
30017 if (child.type === "Identifier") {
30018 args.push(child.name);
30019 }
30020 });
30021
30022 let style;
30023 if (last !== first) {
30024 style = last.name;
30025 }
30026
30027 let variable = "--pagedjs-" + UUID();
30028
30029 this.selector.split(",").forEach(s => {
30030 this.textTargets[s] = {
30031 func: func,
30032 args: args,
30033 value: value,
30034 style: style || "content",
30035 selector: s,
30036 fullSelector: this.selector,
30037 variable: variable
30038 };
30039 });
30040
30041 // Replace with variable
30042 funcNode.name = "var";
30043 funcNode.children = new lib.List();
30044 funcNode.children.appendData({
30045 type: "Identifier",
30046 loc: 0,
30047 name: variable
30048 });
30049 }
30050 }
30051
30052 // parse this on the ONCONTENT : get all before and after and replace the value with a variable
30053 onPseudoSelector(pseudoNode, pItem, pList, selector, rule) {
30054 // console.log(pseudoNode);
30055 // console.log(rule);
30056
30057 rule.ruleNode.block.children.forEach(properties => {
30058 if (pseudoNode.name === "before" && properties.property === "content") {
30059 // let beforeVariable = "--pagedjs-" + UUID();
30060
30061 let contenu = properties.value.children;
30062 contenu.forEach(prop => {
30063 if (prop.type === "String") {
30064 this.beforeContent = prop.value;
30065 }
30066 });
30067 } else if (pseudoNode.name === "after" && properties.property === "content") {
30068 properties.value.children.forEach(prop => {
30069 if (prop.type === "String") {
30070 this.afterContent = prop.value;
30071 }
30072 });
30073 }
30074 });
30075 }
30076
30077 afterParsed(fragment) {
30078 Object.keys(this.textTargets).forEach(name => {
30079 let target = this.textTargets[name];
30080 let split = target.selector.split("::");
30081 let query = split[0];
30082 let queried = fragment.querySelectorAll(query);
30083 let textContent;
30084 queried.forEach((selected, index) => {
30085 let val = attr(selected, target.args);
30086 let element = fragment.querySelector(querySelectorEscape(val));
30087 if (element) {
30088 // content & first-letter & before & after refactorized
30089 if (target.style) {
30090 this.selector = UUID();
30091 selected.setAttribute("data-target-text", this.selector);
30092
30093 let psuedo = "";
30094 if (split.length > 1) {
30095 psuedo += "::" + split[1];
30096 }
30097
30098 if (target.style === "before" || target.style === "after") {
30099 const pseudoType = `${target.style}Content`;
30100 textContent = cleanPseudoContent(this[pseudoType]);
30101 } else {
30102 textContent = cleanPseudoContent(element.textContent, " ");
30103 }
30104 textContent = target.style === "first-letter" ? textContent.charAt(0) : textContent;
30105 this.styleSheet.insertRule(`[data-target-text="${this.selector}"]${psuedo} { ${target.variable}: "${textContent}" }`);
30106 } else {
30107 console.warn("missed target", val);
30108 }
30109 }
30110 });
30111 });
30112 }
30113 }
30114
30115 var generatedContentHandlers = [
30116 RunningHeaders,
30117 StringSets,
30118 TargetCounters,
30119 TargetText
30120 ];
30121
30122 class WhiteSpaceFilter extends Handler {
30123 constructor(chunker, polisher, caller) {
30124 super(chunker, polisher, caller);
30125 }
30126
30127 filter(content) {
30128
30129 filterTree(content, (node) => {
30130 return this.filterEmpty(node);
30131 }, NodeFilter.SHOW_TEXT);
30132
30133 }
30134
30135 filterEmpty(node) {
30136 if (node.textContent.length > 1 && isIgnorable(node)) {
30137
30138 // Do not touch the content if text is pre-formatted
30139 let parent = node.parentNode;
30140 let pre = isElement(parent) && parent.closest("pre");
30141 if (pre) {
30142 return NodeFilter.FILTER_REJECT;
30143 }
30144
30145 const previousSibling = previousSignificantNode(node);
30146 const nextSibling = nextSignificantNode(node);
30147
30148 if (nextSibling === null && previousSibling === null) {
30149 // we should not remove a Node that does not have any siblings.
30150 node.textContent = " ";
30151 return NodeFilter.FILTER_REJECT;
30152 }
30153 if (nextSibling === null) {
30154 // we can safely remove this node
30155 return NodeFilter.FILTER_ACCEPT;
30156 }
30157 if (previousSibling === null) {
30158 // we can safely remove this node
30159 return NodeFilter.FILTER_ACCEPT;
30160 }
30161
30162 // replace the content with a single space
30163 node.textContent = " ";
30164
30165 // TODO: we also need to preserve sequences of white spaces when the parent has "white-space" rule:
30166 // pre
30167 // Sequences of white space are preserved. Lines are only broken at newline characters in the source and at <br> elements.
30168 //
30169 // pre-wrap
30170 // Sequences of white space are preserved. Lines are broken at newline characters, at <br>, and as necessary to fill line boxes.
30171 //
30172 // pre-line
30173 // Sequences of white space are collapsed. Lines are broken at newline characters, at <br>, and as necessary to fill line boxes.
30174 //
30175 // break-spaces
30176 // The behavior is identical to that of pre-wrap, except that:
30177 // - Any sequence of preserved white space always takes up space, including at the end of the line.
30178 // - A line breaking opportunity exists after every preserved white space character, including between white space characters.
30179 // - 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).
30180 //
30181 // See: https://developer.mozilla.org/en-US/docs/Web/CSS/white-space#Values
30182
30183 return NodeFilter.FILTER_REJECT;
30184 } else {
30185 return NodeFilter.FILTER_REJECT;
30186 }
30187 }
30188
30189 }
30190
30191 class CommentsFilter extends Handler {
30192 constructor(chunker, polisher, caller) {
30193 super(chunker, polisher, caller);
30194 }
30195
30196 filter(content) {
30197 filterTree(content, null, NodeFilter.SHOW_COMMENT);
30198 }
30199
30200 }
30201
30202 class ScriptsFilter extends Handler {
30203 constructor(chunker, polisher, caller) {
30204 super(chunker, polisher, caller);
30205 }
30206
30207 filter(content) {
30208 content.querySelectorAll("script").forEach( script => { script.remove(); });
30209 }
30210
30211 }
30212
30213 var clearCut = createCommonjsModule(function (module, exports) {
30214 /**
30215 * Originally ported from https://github.com/keeganstreet/specificity/blob/866bf7ab4e7f62a7179c15b13a95af4e1c7b1afa/specificity.js
30216 *
30217 * Calculates the specificity of CSS selectors
30218 * http://www.w3.org/TR/css3-selectors/#specificity
30219 *
30220 * Returns a selector integer value
30221 */
30222
30223 // The following regular expressions assume that selectors matching the preceding regular expressions have been removed
30224 var attributeRegex = /(\[[^\]]+\])/g;
30225 var idRegex = /(#[^\s\+>~\.\[:]+)/g;
30226 var classRegex = /(\.[^\s\+>~\.\[:]+)/g;
30227 var pseudoElementRegex = /(::[^\s\+>~\.\[:]+|:first-line|:first-letter|:before|:after)/g;
30228 var pseudoClassRegex = /(:[^\s\+>~\.\[:]+)/g;
30229 var elementRegex = /([^\s\+>~\.\[:]+)/g;
30230 var notRegex = /:not\(([^\)]*)\)/g;
30231 var ruleRegex = /\{[^]*/gm;
30232 var separatorRegex = /[\*\s\+>~]/g;
30233 var straysRegex = /[#\.]/g;
30234
30235 // Find matches for a regular expression in a string and push their details to parts
30236 // Type is "a" for IDs, "b" for classes, attributes and pseudo-classes and "c" for elements and pseudo-elements
30237 var findMatch = function(regex, type, types, selector) {
30238 var matches = selector.match(regex);
30239 if (matches) {
30240 for (var i = 0; i < matches.length; i++) {
30241 types[type]++;
30242 // Replace this simple selector with whitespace so it won't be counted in further simple selectors
30243 selector = selector.replace(matches[i], ' ');
30244 }
30245 }
30246
30247 return selector;
30248 };
30249
30250 // Calculate the specificity for a selector by dividing it into simple selectors and counting them
30251 var calculate = function(selector) {
30252 var commaIndex = selector.indexOf(',');
30253 if (commaIndex !== -1) {
30254 selector = selector.substring(0, commaIndex);
30255 }
30256
30257 var types = {
30258 a: 0,
30259 b: 0,
30260 c: 0
30261 };
30262
30263 // Remove the negation psuedo-class (:not) but leave its argument because specificity is calculated on its argument
30264 selector = selector.replace(notRegex, ' $1 ');
30265
30266 // Remove anything after a left brace in case a user has pasted in a rule, not just a selector
30267 selector = selector.replace(ruleRegex, ' ');
30268
30269 // Add attribute selectors to parts collection (type b)
30270 selector = findMatch(attributeRegex, 'b', types, selector);
30271
30272 // Add ID selectors to parts collection (type a)
30273 selector = findMatch(idRegex, 'a', types, selector);
30274
30275 // Add class selectors to parts collection (type b)
30276 selector = findMatch(classRegex, 'b', types, selector);
30277
30278 // Add pseudo-element selectors to parts collection (type c)
30279 selector = findMatch(pseudoElementRegex, 'c', types, selector);
30280
30281 // Add pseudo-class selectors to parts collection (type b)
30282 selector = findMatch(pseudoClassRegex, 'b', types, selector);
30283
30284 // Remove universal selector and separator characters
30285 selector = selector.replace(separatorRegex, ' ');
30286
30287 // Remove any stray dots or hashes which aren't attached to words
30288 // These may be present if the user is live-editing this selector
30289 selector = selector.replace(straysRegex, ' ');
30290
30291 // The only things left should be element selectors (type c)
30292 findMatch(elementRegex, 'c', types, selector);
30293
30294 return (types.a * 100) + (types.b * 10) + (types.c * 1);
30295 };
30296
30297 var specificityCache = {};
30298
30299 exports.calculateSpecificity = function(selector) {
30300 var specificity = specificityCache[selector];
30301 if (specificity === undefined) {
30302 specificity = calculate(selector);
30303 specificityCache[selector] = specificity;
30304 }
30305 return specificity;
30306 };
30307
30308 var validSelectorCache = {};
30309 var testSelectorElement = null;
30310
30311 exports.isSelectorValid = function(selector) {
30312 var valid = validSelectorCache[selector];
30313 if (valid === undefined) {
30314 if (testSelectorElement == null) {
30315 testSelectorElement = document.createElement('div');
30316 }
30317
30318 try {
30319 testSelectorElement.querySelector(selector);
30320 valid = true;
30321 } catch (error) {
30322 valid = false;
30323 }
30324 validSelectorCache[selector] = valid;
30325 }
30326 return valid;
30327 };
30328
30329 exports.validateSelector = function(selector) {
30330 if (!exports.isSelectorValid(selector)) {
30331 var error = new SyntaxError(selector + ' is not a valid selector');
30332 error.code = 'EBADSELECTOR';
30333 throw error;
30334 }
30335 };
30336 });
30337 var clearCut_1 = clearCut.calculateSpecificity;
30338 var clearCut_2 = clearCut.isSelectorValid;
30339 var clearCut_3 = clearCut.validateSelector;
30340
30341 class UndisplayedFilter extends Handler {
30342 constructor(chunker, polisher, caller) {
30343 super(chunker, polisher, caller);
30344 this.displayRules = {};
30345 }
30346
30347 onDeclaration(declaration, dItem, dList, rule) {
30348 if (declaration.property === "display") {
30349 let selector = lib.generate(rule.ruleNode.prelude);
30350 let value = declaration.value.children.first().name;
30351
30352 selector.split(",").forEach((s) => {
30353 this.displayRules[s] = {
30354 value: value,
30355 selector: s,
30356 specificity: clearCut_1(s),
30357 important: declaration.important
30358 };
30359 });
30360 }
30361 }
30362
30363 filter(content) {
30364 let { matches, selectors } = this.sortDisplayedSelectors(content, this.displayRules);
30365
30366 // Find matching elements that have display styles
30367 for (let i = 0; i < matches.length; i++) {
30368 let element = matches[i];
30369 let selector = selectors[i];
30370 let displayValue = selector[selector.length-1].value;
30371 if(this.removable(element) && displayValue === "none") {
30372 element.dataset.undisplayed = "undisplayed";
30373 }
30374 }
30375
30376 // Find elements that have inline styles
30377 let styledElements = content.querySelectorAll("[style]");
30378 for (let i = 0; i < styledElements.length; i++) {
30379 let element = styledElements[i];
30380 if (this.removable(element)) {
30381 element.dataset.undisplayed = "undisplayed";
30382 }
30383 }
30384 }
30385
30386 sorter(a, b) {
30387 if (a.important && !b.important) {
30388 return 1;
30389 }
30390
30391 if (b.important && !a.important) {
30392 return -1;
30393 }
30394
30395 return a.specificity - b.specificity;
30396 }
30397
30398 sortDisplayedSelectors(content, displayRules=[]) {
30399 let matches = [];
30400 let selectors = [];
30401 for (let d in displayRules) {
30402 let displayItem = displayRules[d];
30403 let selector = displayItem.selector;
30404 let query = [];
30405 try {
30406 try {
30407 query = content.querySelectorAll(selector);
30408 } catch (e) {
30409 query = content.querySelectorAll(cleanSelector(selector));
30410 }
30411 } catch (e) {
30412 query = [];
30413 }
30414 let elements = Array.from(query);
30415 for (let e of elements) {
30416 if (matches.includes(e)) {
30417 let index = matches.indexOf(e);
30418 selectors[index].push(displayItem);
30419 selectors[index] = selectors[index].sort(this.sorter);
30420 } else {
30421 matches.push(e);
30422 selectors.push([displayItem]);
30423 }
30424 }
30425 }
30426
30427 return { matches, selectors };
30428 }
30429
30430 removable(element) {
30431 if (element.style &&
30432 element.style.display !== "" &&
30433 element.style.display !== "none") {
30434 return false;
30435 }
30436
30437 return true;
30438 }
30439 }
30440
30441 var filters = [
30442 WhiteSpaceFilter,
30443 CommentsFilter,
30444 ScriptsFilter,
30445 UndisplayedFilter
30446 ];
30447
30448 var isImplemented$3 = function () {
30449 var from = Array.from, arr, result;
30450 if (typeof from !== "function") return false;
30451 arr = ["raz", "dwa"];
30452 result = from(arr);
30453 return Boolean(result && (result !== arr) && (result[1] === "dwa"));
30454 };
30455
30456 var validTypes = { object: true, symbol: true };
30457
30458 var isImplemented$4 = function () {
30459 var symbol;
30460 if (typeof Symbol !== 'function') return false;
30461 symbol = Symbol('test symbol');
30462 try { String(symbol); } catch (e) { return false; }
30463
30464 // Return 'true' also for polyfills
30465 if (!validTypes[typeof Symbol.iterator]) return false;
30466 if (!validTypes[typeof Symbol.toPrimitive]) return false;
30467 if (!validTypes[typeof Symbol.toStringTag]) return false;
30468
30469 return true;
30470 };
30471
30472 var isSymbol = function (x) {
30473 if (!x) return false;
30474 if (typeof x === 'symbol') return true;
30475 if (!x.constructor) return false;
30476 if (x.constructor.name !== 'Symbol') return false;
30477 return (x[x.constructor.toStringTag] === 'Symbol');
30478 };
30479
30480 var validateSymbol = function (value) {
30481 if (!isSymbol(value)) throw new TypeError(value + " is not a symbol");
30482 return value;
30483 };
30484
30485 var create$6 = Object.create, defineProperties = Object.defineProperties
30486 , defineProperty = Object.defineProperty, objPrototype = Object.prototype
30487 , NativeSymbol, SymbolPolyfill, HiddenSymbol, globalSymbols = create$6(null)
30488 , isNativeSafe;
30489
30490 if (typeof Symbol === 'function') {
30491 NativeSymbol = Symbol;
30492 try {
30493 String(NativeSymbol());
30494 isNativeSafe = true;
30495 } catch (ignore) {}
30496 }
30497
30498 var generateName = (function () {
30499 var created = create$6(null);
30500 return function (desc) {
30501 var postfix = 0, name, ie11BugWorkaround;
30502 while (created[desc + (postfix || '')]) ++postfix;
30503 desc += (postfix || '');
30504 created[desc] = true;
30505 name = '@@' + desc;
30506 defineProperty(objPrototype, name, d_1.gs(null, function (value) {
30507 // For IE11 issue see:
30508 // https://connect.microsoft.com/IE/feedbackdetail/view/1928508/
30509 // ie11-broken-getters-on-dom-objects
30510 // https://github.com/medikoo/es6-symbol/issues/12
30511 if (ie11BugWorkaround) return;
30512 ie11BugWorkaround = true;
30513 defineProperty(this, name, d_1(value));
30514 ie11BugWorkaround = false;
30515 }));
30516 return name;
30517 };
30518 }());
30519
30520 // Internal constructor (not one exposed) for creating Symbol instances.
30521 // This one is used to ensure that `someSymbol instanceof Symbol` always return false
30522 HiddenSymbol = function Symbol(description) {
30523 if (this instanceof HiddenSymbol) throw new TypeError('Symbol is not a constructor');
30524 return SymbolPolyfill(description);
30525 };
30526
30527 // Exposed `Symbol` constructor
30528 // (returns instances of HiddenSymbol)
30529 var polyfill = SymbolPolyfill = function Symbol(description) {
30530 var symbol;
30531 if (this instanceof Symbol) throw new TypeError('Symbol is not a constructor');
30532 if (isNativeSafe) return NativeSymbol(description);
30533 symbol = create$6(HiddenSymbol.prototype);
30534 description = (description === undefined ? '' : String(description));
30535 return defineProperties(symbol, {
30536 __description__: d_1('', description),
30537 __name__: d_1('', generateName(description))
30538 });
30539 };
30540 defineProperties(SymbolPolyfill, {
30541 for: d_1(function (key) {
30542 if (globalSymbols[key]) return globalSymbols[key];
30543 return (globalSymbols[key] = SymbolPolyfill(String(key)));
30544 }),
30545 keyFor: d_1(function (s) {
30546 var key;
30547 validateSymbol(s);
30548 for (key in globalSymbols) if (globalSymbols[key] === s) return key;
30549 }),
30550
30551 // To ensure proper interoperability with other native functions (e.g. Array.from)
30552 // fallback to eventual native implementation of given symbol
30553 hasInstance: d_1('', (NativeSymbol && NativeSymbol.hasInstance) || SymbolPolyfill('hasInstance')),
30554 isConcatSpreadable: d_1('', (NativeSymbol && NativeSymbol.isConcatSpreadable) ||
30555 SymbolPolyfill('isConcatSpreadable')),
30556 iterator: d_1('', (NativeSymbol && NativeSymbol.iterator) || SymbolPolyfill('iterator')),
30557 match: d_1('', (NativeSymbol && NativeSymbol.match) || SymbolPolyfill('match')),
30558 replace: d_1('', (NativeSymbol && NativeSymbol.replace) || SymbolPolyfill('replace')),
30559 search: d_1('', (NativeSymbol && NativeSymbol.search) || SymbolPolyfill('search')),
30560 species: d_1('', (NativeSymbol && NativeSymbol.species) || SymbolPolyfill('species')),
30561 split: d_1('', (NativeSymbol && NativeSymbol.split) || SymbolPolyfill('split')),
30562 toPrimitive: d_1('', (NativeSymbol && NativeSymbol.toPrimitive) || SymbolPolyfill('toPrimitive')),
30563 toStringTag: d_1('', (NativeSymbol && NativeSymbol.toStringTag) || SymbolPolyfill('toStringTag')),
30564 unscopables: d_1('', (NativeSymbol && NativeSymbol.unscopables) || SymbolPolyfill('unscopables'))
30565 });
30566
30567 // Internal tweaks for real symbol producer
30568 defineProperties(HiddenSymbol.prototype, {
30569 constructor: d_1(SymbolPolyfill),
30570 toString: d_1('', function () { return this.__name__; })
30571 });
30572
30573 // Proper implementation of methods exposed on Symbol.prototype
30574 // They won't be accessible on produced symbol instances as they derive from HiddenSymbol.prototype
30575 defineProperties(SymbolPolyfill.prototype, {
30576 toString: d_1(function () { return 'Symbol (' + validateSymbol(this).__description__ + ')'; }),
30577 valueOf: d_1(function () { return validateSymbol(this); })
30578 });
30579 defineProperty(SymbolPolyfill.prototype, SymbolPolyfill.toPrimitive, d_1('', function () {
30580 var symbol = validateSymbol(this);
30581 if (typeof symbol === 'symbol') return symbol;
30582 return symbol.toString();
30583 }));
30584 defineProperty(SymbolPolyfill.prototype, SymbolPolyfill.toStringTag, d_1('c', 'Symbol'));
30585
30586 // Proper implementaton of toPrimitive and toStringTag for returned symbol instances
30587 defineProperty(HiddenSymbol.prototype, SymbolPolyfill.toStringTag,
30588 d_1('c', SymbolPolyfill.prototype[SymbolPolyfill.toStringTag]));
30589
30590 // Note: It's important to define `toPrimitive` as last one, as some implementations
30591 // implement `toPrimitive` natively without implementing `toStringTag` (or other specified symbols)
30592 // And that may invoke error in definition flow:
30593 // See: https://github.com/medikoo/es6-symbol/issues/13#issuecomment-164146149
30594 defineProperty(HiddenSymbol.prototype, SymbolPolyfill.toPrimitive,
30595 d_1('c', SymbolPolyfill.prototype[SymbolPolyfill.toPrimitive]));
30596
30597 var es6Symbol = isImplemented$4() ? Symbol : polyfill;
30598
30599 var objToString = Object.prototype.toString
30600 , id = objToString.call(
30601 (function () {
30602 return arguments;
30603 })()
30604 );
30605
30606 var isArguments = function (value) {
30607 return objToString.call(value) === id;
30608 };
30609
30610 var objToString$1 = Object.prototype.toString, id$1 = objToString$1.call(noop);
30611
30612 var isFunction = function (value) {
30613 return typeof value === "function" && objToString$1.call(value) === id$1;
30614 };
30615
30616 var isImplemented$5 = function () {
30617 var sign = Math.sign;
30618 if (typeof sign !== "function") return false;
30619 return (sign(10) === 1) && (sign(-20) === -1);
30620 };
30621
30622 var shim$3 = function (value) {
30623 value = Number(value);
30624 if (isNaN(value) || (value === 0)) return value;
30625 return value > 0 ? 1 : -1;
30626 };
30627
30628 var sign = isImplemented$5()
30629 ? Math.sign
30630 : shim$3;
30631
30632 var abs = Math.abs, floor = Math.floor;
30633
30634 var toInteger = function (value) {
30635 if (isNaN(value)) return 0;
30636 value = Number(value);
30637 if ((value === 0) || !isFinite(value)) return value;
30638 return sign(value) * floor(abs(value));
30639 };
30640
30641 var max$1 = Math.max;
30642
30643 var toPosInteger = function (value) {
30644 return max$1(0, toInteger(value));
30645 };
30646
30647 var objToString$2 = Object.prototype.toString, id$2 = objToString$2.call("");
30648
30649 var isString = function (value) {
30650 return (
30651 typeof value === "string" ||
30652 (value &&
30653 typeof value === "object" &&
30654 (value instanceof String || objToString$2.call(value) === id$2)) ||
30655 false
30656 );
30657 };
30658
30659 var iteratorSymbol = es6Symbol.iterator
30660 , isArray = Array.isArray
30661 , call = Function.prototype.call
30662 , desc = { configurable: true, enumerable: true, writable: true, value: null }
30663 , defineProperty$1 = Object.defineProperty;
30664
30665 // eslint-disable-next-line complexity
30666 var shim$4 = function (arrayLike /*, mapFn, thisArg*/) {
30667 var mapFn = arguments[1]
30668 , thisArg = arguments[2]
30669 , Context
30670 , i
30671 , j
30672 , arr
30673 , length
30674 , code
30675 , iterator
30676 , result
30677 , getIterator
30678 , value;
30679
30680 arrayLike = Object(validValue(arrayLike));
30681
30682 if (isValue(mapFn)) validCallable(mapFn);
30683 if (!this || this === Array || !isFunction(this)) {
30684 // Result: Plain array
30685 if (!mapFn) {
30686 if (isArguments(arrayLike)) {
30687 // Source: Arguments
30688 length = arrayLike.length;
30689 if (length !== 1) return Array.apply(null, arrayLike);
30690 arr = new Array(1);
30691 arr[0] = arrayLike[0];
30692 return arr;
30693 }
30694 if (isArray(arrayLike)) {
30695 // Source: Array
30696 arr = new Array(length = arrayLike.length);
30697 for (i = 0; i < length; ++i) arr[i] = arrayLike[i];
30698 return arr;
30699 }
30700 }
30701 arr = [];
30702 } else {
30703 // Result: Non plain array
30704 Context = this;
30705 }
30706
30707 if (!isArray(arrayLike)) {
30708 if ((getIterator = arrayLike[iteratorSymbol]) !== undefined) {
30709 // Source: Iterator
30710 iterator = validCallable(getIterator).call(arrayLike);
30711 if (Context) arr = new Context();
30712 result = iterator.next();
30713 i = 0;
30714 while (!result.done) {
30715 value = mapFn ? call.call(mapFn, thisArg, result.value, i) : result.value;
30716 if (Context) {
30717 desc.value = value;
30718 defineProperty$1(arr, i, desc);
30719 } else {
30720 arr[i] = value;
30721 }
30722 result = iterator.next();
30723 ++i;
30724 }
30725 length = i;
30726 } else if (isString(arrayLike)) {
30727 // Source: String
30728 length = arrayLike.length;
30729 if (Context) arr = new Context();
30730 for (i = 0, j = 0; i < length; ++i) {
30731 value = arrayLike[i];
30732 if (i + 1 < length) {
30733 code = value.charCodeAt(0);
30734 // eslint-disable-next-line max-depth
30735 if (code >= 0xd800 && code <= 0xdbff) value += arrayLike[++i];
30736 }
30737 value = mapFn ? call.call(mapFn, thisArg, value, j) : value;
30738 if (Context) {
30739 desc.value = value;
30740 defineProperty$1(arr, j, desc);
30741 } else {
30742 arr[j] = value;
30743 }
30744 ++j;
30745 }
30746 length = j;
30747 }
30748 }
30749 if (length === undefined) {
30750 // Source: array or array-like
30751 length = toPosInteger(arrayLike.length);
30752 if (Context) arr = new Context(length);
30753 for (i = 0; i < length; ++i) {
30754 value = mapFn ? call.call(mapFn, thisArg, arrayLike[i], i) : arrayLike[i];
30755 if (Context) {
30756 desc.value = value;
30757 defineProperty$1(arr, i, desc);
30758 } else {
30759 arr[i] = value;
30760 }
30761 }
30762 }
30763 if (Context) {
30764 desc.value = null;
30765 arr.length = length;
30766 }
30767 return arr;
30768 };
30769
30770 var from_1 = isImplemented$3()
30771 ? Array.from
30772 : shim$4;
30773
30774 var isImplemented$6 = function () {
30775 var numberIsNaN = Number.isNaN;
30776 if (typeof numberIsNaN !== "function") return false;
30777 return !numberIsNaN({}) && numberIsNaN(NaN) && !numberIsNaN(34);
30778 };
30779
30780 var shim$5 = function (value) {
30781 // eslint-disable-next-line no-self-compare
30782 return value !== value;
30783 };
30784
30785 var isNan = isImplemented$6()
30786 ? Number.isNaN
30787 : shim$5;
30788
30789 var indexOf$2 = Array.prototype.indexOf
30790 , objHasOwnProperty = Object.prototype.hasOwnProperty
30791 , abs$1 = Math.abs
30792 , floor$1 = Math.floor;
30793
30794 var eIndexOf = function (searchElement /*, fromIndex*/) {
30795 var i, length, fromIndex, val;
30796 if (!isNan(searchElement)) return indexOf$2.apply(this, arguments);
30797
30798 length = toPosInteger(validValue(this).length);
30799 fromIndex = arguments[1];
30800 if (isNaN(fromIndex)) fromIndex = 0;
30801 else if (fromIndex >= 0) fromIndex = floor$1(fromIndex);
30802 else fromIndex = toPosInteger(this.length) - floor$1(abs$1(fromIndex));
30803
30804 for (i = fromIndex; i < length; ++i) {
30805 if (objHasOwnProperty.call(this, i)) {
30806 val = this[i];
30807 if (isNan(val)) return i; // Jslint: ignore
30808 }
30809 }
30810 return -1;
30811 };
30812
30813 var forEach$1 = Array.prototype.forEach
30814 , splice = Array.prototype.splice;
30815
30816 // eslint-disable-next-line no-unused-vars
30817 var remove = function (itemToRemove /*, …item*/) {
30818 forEach$1.call(
30819 arguments,
30820 function (item) {
30821 var index = eIndexOf.call(this, item);
30822 if (index !== -1) splice.call(this, index, 1);
30823 },
30824 this
30825 );
30826 };
30827
30828 var map = { function: true, object: true };
30829
30830 var isObject$1 = function (value) {
30831 return (isValue(value) && map[typeof value]) || false;
30832 };
30833
30834 var validObject = function (value) {
30835 if (!isObject$1(value)) throw new TypeError(value + " is not an Object");
30836 return value;
30837 };
30838
30839 var emit = eventEmitter.methods.emit
30840
30841 , defineProperty$2 = Object.defineProperty
30842 , hasOwnProperty$6 = Object.prototype.hasOwnProperty
30843 , getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
30844
30845 var pipe = function (e1, e2/*, name*/) {
30846 var pipes, pipe, desc, name;
30847
30848 (validObject(e1) && validObject(e2));
30849 name = arguments[2];
30850 if (name === undefined) name = 'emit';
30851
30852 pipe = {
30853 close: function () { remove.call(pipes, e2); }
30854 };
30855 if (hasOwnProperty$6.call(e1, '__eePipes__')) {
30856 (pipes = e1.__eePipes__).push(e2);
30857 return pipe;
30858 }
30859 defineProperty$2(e1, '__eePipes__', d_1('c', pipes = [e2]));
30860 desc = getOwnPropertyDescriptor(e1, name);
30861 if (!desc) {
30862 desc = d_1('c', undefined);
30863 } else {
30864 delete desc.get;
30865 delete desc.set;
30866 }
30867 desc.value = function () {
30868 var i, emitter, data = from_1(pipes);
30869 emit.apply(this, arguments);
30870 for (i = 0; (emitter = data[i]); ++i) emit.apply(emitter, arguments);
30871 };
30872 defineProperty$2(e1, name, desc);
30873 return pipe;
30874 };
30875
30876 let registeredHandlers = [...pagedMediaHandlers, ...generatedContentHandlers, ...filters];
30877
30878 class Handlers {
30879 constructor(chunker, polisher, caller) {
30880
30881 registeredHandlers.forEach((Handler) => {
30882 let handler = new Handler(chunker, polisher, caller);
30883 pipe(handler, this);
30884 });
30885 }
30886 }
30887
30888 eventEmitter(Handlers.prototype);
30889
30890 function registerHandlers() {
30891 for (var i = 0; i < arguments.length; i++) {
30892 registeredHandlers.push(arguments[i]);
30893 }
30894 }
30895
30896 function initializeHandlers(chunker, polisher, caller) {
30897 let handlers = new Handlers(chunker, polisher, caller);
30898 return handlers;
30899 }
30900
30901 class Previewer {
30902 constructor(options) {
30903 // this.preview = this.getParams("preview") !== "false";
30904
30905 this.settings = options || {};
30906
30907 // Process styles
30908 this.polisher = new Polisher(false);
30909
30910 // Chunk contents
30911 this.chunker = new Chunker(undefined, undefined, this.settings);
30912
30913 // Hooks
30914 this.hooks = {};
30915 this.hooks.beforePreview = new Hook(this);
30916 this.hooks.afterPreview = new Hook(this);
30917
30918 // default size
30919 this.size = {
30920 width: {
30921 value: 8.5,
30922 unit: "in"
30923 },
30924 height: {
30925 value: 11,
30926 unit: "in"
30927 },
30928 format: undefined,
30929 orientation: undefined
30930 };
30931
30932 this.chunker.on("page", (page) => {
30933 this.emit("page", page);
30934 });
30935
30936 this.chunker.on("rendering", () => {
30937 this.emit("rendering", this.chunker);
30938 });
30939 }
30940
30941 initializeHandlers() {
30942 let handlers = initializeHandlers(this.chunker, this.polisher, this);
30943
30944 handlers.on("size", (size) => {
30945 this.size = size;
30946 this.emit("size", size);
30947 });
30948
30949 handlers.on("atpages", (pages) => {
30950 this.atpages = pages;
30951 this.emit("atpages", pages);
30952 });
30953
30954 return handlers;
30955 }
30956
30957 registerHandlers() {
30958 return registerHandlers.apply(registerHandlers, arguments);
30959 }
30960
30961 getParams(name) {
30962 let param;
30963 let url = new URL(window.location);
30964 let params = new URLSearchParams(url.search);
30965 for(var pair of params.entries()) {
30966 if(pair[0] === name) {
30967 param = pair[1];
30968 }
30969 }
30970
30971 return param;
30972 }
30973
30974 wrapContent() {
30975 // Wrap body in template tag
30976 let body = document.querySelector("body");
30977
30978 // Check if a template exists
30979 let template;
30980 template = body.querySelector(":scope > template[data-ref='pagedjs-content']");
30981
30982 if (!template) {
30983 // Otherwise create one
30984 template = document.createElement("template");
30985 template.dataset.ref = "pagedjs-content";
30986 template.innerHTML = body.innerHTML;
30987 body.innerHTML = "";
30988 body.appendChild(template);
30989 }
30990
30991 return template.content;
30992 }
30993
30994 removeStyles(doc=document) {
30995 // Get all stylesheets
30996 let stylesheets = Array.from(doc.querySelectorAll("link[rel='stylesheet']"));
30997 let hrefs = stylesheets.map((sheet) => {
30998 sheet.remove();
30999 return sheet.href;
31000 });
31001
31002 // Get inline styles
31003 let inlineStyles = Array.from(doc.querySelectorAll("style:not([data-pagedjs-inserted-styles])"));
31004 inlineStyles.forEach((inlineStyle) => {
31005 let obj = {};
31006 obj[window.location.href] = inlineStyle.textContent;
31007 hrefs.push(obj);
31008 inlineStyle.remove();
31009 });
31010
31011 return hrefs;
31012 }
31013
31014 async preview(content, stylesheets, renderTo) {
31015
31016 await this.hooks.beforePreview.trigger(content, renderTo);
31017
31018 if (!content) {
31019 content = this.wrapContent();
31020 }
31021
31022 if (!stylesheets) {
31023 stylesheets = this.removeStyles();
31024 }
31025
31026 this.polisher.setup();
31027
31028 this.handlers = this.initializeHandlers();
31029
31030 await this.polisher.add(...stylesheets);
31031
31032 let startTime = performance.now();
31033
31034 // Render flow
31035 let flow = await this.chunker.flow(content, renderTo);
31036
31037 let endTime = performance.now();
31038
31039 flow.performance = (endTime - startTime);
31040 flow.size = this.size;
31041
31042 this.emit("rendered", flow);
31043
31044 await this.hooks.afterPreview.trigger(flow.pages);
31045
31046 return flow;
31047 }
31048 }
31049
31050 eventEmitter(Previewer.prototype);
31051
31052 var Paged = /*#__PURE__*/Object.freeze({
31053 __proto__: null,
31054 Chunker: Chunker,
31055 Polisher: Polisher,
31056 Previewer: Previewer,
31057 Handler: Handler,
31058 registerHandlers: registerHandlers,
31059 initializeHandlers: initializeHandlers
31060 });
31061
31062 window.Paged = Paged;
31063
31064 let ready = new Promise(function(resolve, reject){
31065 if (document.readyState === "interactive" || document.readyState === "complete") {
31066 resolve(document.readyState);
31067 return;
31068 }
31069
31070 document.onreadystatechange = function ($) {
31071 if (document.readyState === "interactive") {
31072 resolve(document.readyState);
31073 }
31074 };
31075 });
31076
31077 let config = window.PagedConfig || {
31078 auto: true,
31079 before: undefined,
31080 after: undefined,
31081 content: undefined,
31082 stylesheets: undefined,
31083 renderTo: undefined,
31084 settings: undefined
31085 };
31086
31087 let previewer = new Previewer(config.settings);
31088
31089 ready.then(async function () {
31090 let done;
31091 if (config.before) {
31092 await config.before();
31093 }
31094
31095 if(config.auto !== false) {
31096 done = await previewer.preview(config.content, config.stylesheets, config.renderTo);
31097 }
31098
31099
31100 if (config.after) {
31101 await config.after(done);
31102 }
31103 });
31104
31105 return previewer;
31106
31107})));