less
Version:
Leaner CSS
1,308 lines (1,280 loc) • 502 kB
JavaScript
/**
* Less - Leaner CSS v4.2.2
* http://lesscss.org
*
* Copyright (c) 2009-2025, Alexis Sellier <self@cloudhead.net>
* Licensed under the Apache-2.0 License.
*
* @license Apache-2.0
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.less = factory());
})(this, (function () { 'use strict';
// Export a new default each time
function defaultOptions () {
return {
/* Inline Javascript - @plugin still allowed */
javascriptEnabled: false,
/* Outputs a makefile import dependency list to stdout. */
depends: false,
/* (DEPRECATED) Compress using less built-in compression.
* This does an okay job but does not utilise all the tricks of
* dedicated css compression. */
compress: false,
/* Runs the less parser and just reports errors without any output. */
lint: false,
/* Sets available include paths.
* If the file in an @import rule does not exist at that exact location,
* less will look for it at the location(s) passed to this option.
* You might use this for instance to specify a path to a library which
* you want to be referenced simply and relatively in the less files. */
paths: [],
/* color output in the terminal */
color: true,
/* The strictImports controls whether the compiler will allow an @import inside of either
* @media blocks or (a later addition) other selector blocks.
* See: https://github.com/less/less.js/issues/656 */
strictImports: false,
/* Allow Imports from Insecure HTTPS Hosts */
insecure: false,
/* Allows you to add a path to every generated import and url in your css.
* This does not affect less import statements that are processed, just ones
* that are left in the output css. */
rootpath: '',
/* By default URLs are kept as-is, so if you import a file in a sub-directory
* that references an image, exactly the same URL will be output in the css.
* This option allows you to re-write URL's in imported files so that the
* URL is always relative to the base imported file */
rewriteUrls: false,
/* How to process math
* 0 always - eagerly try to solve all operations
* 1 parens-division - require parens for division "/"
* 2 parens | strict - require parens for all operations
* 3 strict-legacy - legacy strict behavior (super-strict)
*/
math: 1,
/* Without this option, less attempts to guess at the output unit when it does maths. */
strictUnits: false,
/* Effectively the declaration is put at the top of your base Less file,
* meaning it can be used but it also can be overridden if this variable
* is defined in the file. */
globalVars: null,
/* As opposed to the global variable option, this puts the declaration at the
* end of your base file, meaning it will override anything defined in your Less file. */
modifyVars: null,
/* This option allows you to specify a argument to go on to every URL. */
urlArgs: ''
};
}
function extractId(href) {
return href.replace(/^[a-z-]+:\/+?[^/]+/, '') // Remove protocol & domain
.replace(/[?&]livereload=\w+/, '') // Remove LiveReload cachebuster
.replace(/^\//, '') // Remove root /
.replace(/\.[a-zA-Z]+$/, '') // Remove simple extension
.replace(/[^.\w-]+/g, '-') // Replace illegal characters
.replace(/\./g, ':'); // Replace dots with colons(for valid id)
}
function addDataAttr(options, tag) {
if (!tag) {
return;
} // in case of tag is null or undefined
for (var opt in tag.dataset) {
if (Object.prototype.hasOwnProperty.call(tag.dataset, opt)) {
if (opt === 'env' || opt === 'dumpLineNumbers' || opt === 'rootpath' || opt === 'errorReporting') {
options[opt] = tag.dataset[opt];
}
else {
try {
options[opt] = JSON.parse(tag.dataset[opt]);
}
catch (_) { }
}
}
}
}
var browser = {
createCSS: function (document, styles, sheet) {
// Strip the query-string
var href = sheet.href || '';
// If there is no title set, use the filename, minus the extension
var id = "less:".concat(sheet.title || extractId(href));
// If this has already been inserted into the DOM, we may need to replace it
var oldStyleNode = document.getElementById(id);
var keepOldStyleNode = false;
// Create a new stylesheet node for insertion or (if necessary) replacement
var styleNode = document.createElement('style');
styleNode.setAttribute('type', 'text/css');
if (sheet.media) {
styleNode.setAttribute('media', sheet.media);
}
styleNode.id = id;
if (!styleNode.styleSheet) {
styleNode.appendChild(document.createTextNode(styles));
// If new contents match contents of oldStyleNode, don't replace oldStyleNode
keepOldStyleNode = (oldStyleNode !== null && oldStyleNode.childNodes.length > 0 && styleNode.childNodes.length > 0 &&
oldStyleNode.firstChild.nodeValue === styleNode.firstChild.nodeValue);
}
var head = document.getElementsByTagName('head')[0];
// If there is no oldStyleNode, just append; otherwise, only append if we need
// to replace oldStyleNode with an updated stylesheet
if (oldStyleNode === null || keepOldStyleNode === false) {
var nextEl = sheet && sheet.nextSibling || null;
if (nextEl) {
nextEl.parentNode.insertBefore(styleNode, nextEl);
}
else {
head.appendChild(styleNode);
}
}
if (oldStyleNode && keepOldStyleNode === false) {
oldStyleNode.parentNode.removeChild(oldStyleNode);
}
// For IE.
// This needs to happen *after* the style element is added to the DOM, otherwise IE 7 and 8 may crash.
// See http://social.msdn.microsoft.com/Forums/en-US/7e081b65-878a-4c22-8e68-c10d39c2ed32/internet-explorer-crashes-appending-style-element-to-head
if (styleNode.styleSheet) {
try {
styleNode.styleSheet.cssText = styles;
}
catch (e) {
throw new Error('Couldn\'t reassign styleSheet.cssText.');
}
}
},
currentScript: function (window) {
var document = window.document;
return document.currentScript || (function () {
var scripts = document.getElementsByTagName('script');
return scripts[scripts.length - 1];
})();
}
};
var addDefaultOptions = (function (window, options) {
// use options from the current script tag data attribues
addDataAttr(options, browser.currentScript(window));
if (options.isFileProtocol === undefined) {
options.isFileProtocol = /^(file|(chrome|safari)(-extension)?|resource|qrc|app):/.test(window.location.protocol);
}
// Load styles asynchronously (default: false)
//
// This is set to `false` by default, so that the body
// doesn't start loading before the stylesheets are parsed.
// Setting this to `true` can result in flickering.
//
options.async = options.async || false;
options.fileAsync = options.fileAsync || false;
// Interval between watch polls
options.poll = options.poll || (options.isFileProtocol ? 1000 : 1500);
options.env = options.env || (window.location.hostname == '127.0.0.1' ||
window.location.hostname == '0.0.0.0' ||
window.location.hostname == 'localhost' ||
(window.location.port &&
window.location.port.length > 0) ||
options.isFileProtocol ? 'development'
: 'production');
var dumpLineNumbers = /!dumpLineNumbers:(comments|mediaquery|all)/.exec(window.location.hash);
if (dumpLineNumbers) {
options.dumpLineNumbers = dumpLineNumbers[1];
}
if (options.useFileCache === undefined) {
options.useFileCache = true;
}
if (options.onReady === undefined) {
options.onReady = true;
}
if (options.relativeUrls) {
options.rewriteUrls = 'all';
}
});
var logger$1 = {
error: function (msg) {
this._fireEvent('error', msg);
},
warn: function (msg) {
this._fireEvent('warn', msg);
},
info: function (msg) {
this._fireEvent('info', msg);
},
debug: function (msg) {
this._fireEvent('debug', msg);
},
addListener: function (listener) {
this._listeners.push(listener);
},
removeListener: function (listener) {
for (var i_1 = 0; i_1 < this._listeners.length; i_1++) {
if (this._listeners[i_1] === listener) {
this._listeners.splice(i_1, 1);
return;
}
}
},
_fireEvent: function (type, msg) {
for (var i_2 = 0; i_2 < this._listeners.length; i_2++) {
var logFunction = this._listeners[i_2][type];
if (logFunction) {
logFunction(msg);
}
}
},
_listeners: []
};
/**
* @todo Document why this abstraction exists, and the relationship between
* environment, file managers, and plugin manager
*/
var Environment = /** @class */ (function () {
function Environment(externalEnvironment, fileManagers) {
this.fileManagers = fileManagers || [];
externalEnvironment = externalEnvironment || {};
var optionalFunctions = ['encodeBase64', 'mimeLookup', 'charsetLookup', 'getSourceMapGenerator'];
var requiredFunctions = [];
var functions = requiredFunctions.concat(optionalFunctions);
for (var i_1 = 0; i_1 < functions.length; i_1++) {
var propName = functions[i_1];
var environmentFunc = externalEnvironment[propName];
if (environmentFunc) {
this[propName] = environmentFunc.bind(externalEnvironment);
}
else if (i_1 < requiredFunctions.length) {
this.warn("missing required function in environment - ".concat(propName));
}
}
}
Environment.prototype.getFileManager = function (filename, currentDirectory, options, environment, isSync) {
if (!filename) {
logger$1.warn('getFileManager called with no filename.. Please report this issue. continuing.');
}
if (currentDirectory === undefined) {
logger$1.warn('getFileManager called with null directory.. Please report this issue. continuing.');
}
var fileManagers = this.fileManagers;
if (options.pluginManager) {
fileManagers = [].concat(fileManagers).concat(options.pluginManager.getFileManagers());
}
for (var i_2 = fileManagers.length - 1; i_2 >= 0; i_2--) {
var fileManager = fileManagers[i_2];
if (fileManager[isSync ? 'supportsSync' : 'supports'](filename, currentDirectory, options, environment)) {
return fileManager;
}
}
return null;
};
Environment.prototype.addFileManager = function (fileManager) {
this.fileManagers.push(fileManager);
};
Environment.prototype.clearFileManagers = function () {
this.fileManagers = [];
};
return Environment;
}());
var colors = {
'aliceblue': '#f0f8ff',
'antiquewhite': '#faebd7',
'aqua': '#00ffff',
'aquamarine': '#7fffd4',
'azure': '#f0ffff',
'beige': '#f5f5dc',
'bisque': '#ffe4c4',
'black': '#000000',
'blanchedalmond': '#ffebcd',
'blue': '#0000ff',
'blueviolet': '#8a2be2',
'brown': '#a52a2a',
'burlywood': '#deb887',
'cadetblue': '#5f9ea0',
'chartreuse': '#7fff00',
'chocolate': '#d2691e',
'coral': '#ff7f50',
'cornflowerblue': '#6495ed',
'cornsilk': '#fff8dc',
'crimson': '#dc143c',
'cyan': '#00ffff',
'darkblue': '#00008b',
'darkcyan': '#008b8b',
'darkgoldenrod': '#b8860b',
'darkgray': '#a9a9a9',
'darkgrey': '#a9a9a9',
'darkgreen': '#006400',
'darkkhaki': '#bdb76b',
'darkmagenta': '#8b008b',
'darkolivegreen': '#556b2f',
'darkorange': '#ff8c00',
'darkorchid': '#9932cc',
'darkred': '#8b0000',
'darksalmon': '#e9967a',
'darkseagreen': '#8fbc8f',
'darkslateblue': '#483d8b',
'darkslategray': '#2f4f4f',
'darkslategrey': '#2f4f4f',
'darkturquoise': '#00ced1',
'darkviolet': '#9400d3',
'deeppink': '#ff1493',
'deepskyblue': '#00bfff',
'dimgray': '#696969',
'dimgrey': '#696969',
'dodgerblue': '#1e90ff',
'firebrick': '#b22222',
'floralwhite': '#fffaf0',
'forestgreen': '#228b22',
'fuchsia': '#ff00ff',
'gainsboro': '#dcdcdc',
'ghostwhite': '#f8f8ff',
'gold': '#ffd700',
'goldenrod': '#daa520',
'gray': '#808080',
'grey': '#808080',
'green': '#008000',
'greenyellow': '#adff2f',
'honeydew': '#f0fff0',
'hotpink': '#ff69b4',
'indianred': '#cd5c5c',
'indigo': '#4b0082',
'ivory': '#fffff0',
'khaki': '#f0e68c',
'lavender': '#e6e6fa',
'lavenderblush': '#fff0f5',
'lawngreen': '#7cfc00',
'lemonchiffon': '#fffacd',
'lightblue': '#add8e6',
'lightcoral': '#f08080',
'lightcyan': '#e0ffff',
'lightgoldenrodyellow': '#fafad2',
'lightgray': '#d3d3d3',
'lightgrey': '#d3d3d3',
'lightgreen': '#90ee90',
'lightpink': '#ffb6c1',
'lightsalmon': '#ffa07a',
'lightseagreen': '#20b2aa',
'lightskyblue': '#87cefa',
'lightslategray': '#778899',
'lightslategrey': '#778899',
'lightsteelblue': '#b0c4de',
'lightyellow': '#ffffe0',
'lime': '#00ff00',
'limegreen': '#32cd32',
'linen': '#faf0e6',
'magenta': '#ff00ff',
'maroon': '#800000',
'mediumaquamarine': '#66cdaa',
'mediumblue': '#0000cd',
'mediumorchid': '#ba55d3',
'mediumpurple': '#9370d8',
'mediumseagreen': '#3cb371',
'mediumslateblue': '#7b68ee',
'mediumspringgreen': '#00fa9a',
'mediumturquoise': '#48d1cc',
'mediumvioletred': '#c71585',
'midnightblue': '#191970',
'mintcream': '#f5fffa',
'mistyrose': '#ffe4e1',
'moccasin': '#ffe4b5',
'navajowhite': '#ffdead',
'navy': '#000080',
'oldlace': '#fdf5e6',
'olive': '#808000',
'olivedrab': '#6b8e23',
'orange': '#ffa500',
'orangered': '#ff4500',
'orchid': '#da70d6',
'palegoldenrod': '#eee8aa',
'palegreen': '#98fb98',
'paleturquoise': '#afeeee',
'palevioletred': '#d87093',
'papayawhip': '#ffefd5',
'peachpuff': '#ffdab9',
'peru': '#cd853f',
'pink': '#ffc0cb',
'plum': '#dda0dd',
'powderblue': '#b0e0e6',
'purple': '#800080',
'rebeccapurple': '#663399',
'red': '#ff0000',
'rosybrown': '#bc8f8f',
'royalblue': '#4169e1',
'saddlebrown': '#8b4513',
'salmon': '#fa8072',
'sandybrown': '#f4a460',
'seagreen': '#2e8b57',
'seashell': '#fff5ee',
'sienna': '#a0522d',
'silver': '#c0c0c0',
'skyblue': '#87ceeb',
'slateblue': '#6a5acd',
'slategray': '#708090',
'slategrey': '#708090',
'snow': '#fffafa',
'springgreen': '#00ff7f',
'steelblue': '#4682b4',
'tan': '#d2b48c',
'teal': '#008080',
'thistle': '#d8bfd8',
'tomato': '#ff6347',
'turquoise': '#40e0d0',
'violet': '#ee82ee',
'wheat': '#f5deb3',
'white': '#ffffff',
'whitesmoke': '#f5f5f5',
'yellow': '#ffff00',
'yellowgreen': '#9acd32'
};
var unitConversions = {
length: {
'm': 1,
'cm': 0.01,
'mm': 0.001,
'in': 0.0254,
'px': 0.0254 / 96,
'pt': 0.0254 / 72,
'pc': 0.0254 / 72 * 12
},
duration: {
's': 1,
'ms': 0.001
},
angle: {
'rad': 1 / (2 * Math.PI),
'deg': 1 / 360,
'grad': 1 / 400,
'turn': 1
}
};
var data = { colors: colors, unitConversions: unitConversions };
/**
* The reason why Node is a class and other nodes simply do not extend
* from Node (since we're transpiling) is due to this issue:
*
* @see https://github.com/less/less.js/issues/3434
*/
var Node = /** @class */ (function () {
function Node() {
this.parent = null;
this.visibilityBlocks = undefined;
this.nodeVisible = undefined;
this.rootNode = null;
this.parsed = null;
}
Object.defineProperty(Node.prototype, "currentFileInfo", {
get: function () {
return this.fileInfo();
},
enumerable: false,
configurable: true
});
Object.defineProperty(Node.prototype, "index", {
get: function () {
return this.getIndex();
},
enumerable: false,
configurable: true
});
Node.prototype.setParent = function (nodes, parent) {
function set(node) {
if (node && node instanceof Node) {
node.parent = parent;
}
}
if (Array.isArray(nodes)) {
nodes.forEach(set);
}
else {
set(nodes);
}
};
Node.prototype.getIndex = function () {
return this._index || (this.parent && this.parent.getIndex()) || 0;
};
Node.prototype.fileInfo = function () {
return this._fileInfo || (this.parent && this.parent.fileInfo()) || {};
};
Node.prototype.isRulesetLike = function () { return false; };
Node.prototype.toCSS = function (context) {
var strs = [];
this.genCSS(context, {
// remove when genCSS has JSDoc types
// eslint-disable-next-line no-unused-vars
add: function (chunk, fileInfo, index) {
strs.push(chunk);
},
isEmpty: function () {
return strs.length === 0;
}
});
return strs.join('');
};
Node.prototype.genCSS = function (context, output) {
output.add(this.value);
};
Node.prototype.accept = function (visitor) {
this.value = visitor.visit(this.value);
};
Node.prototype.eval = function () { return this; };
Node.prototype._operate = function (context, op, a, b) {
switch (op) {
case '+': return a + b;
case '-': return a - b;
case '*': return a * b;
case '/': return a / b;
}
};
Node.prototype.fround = function (context, value) {
var precision = context && context.numPrecision;
// add "epsilon" to ensure numbers like 1.000000005 (represented as 1.000000004999...) are properly rounded:
return (precision) ? Number((value + 2e-16).toFixed(precision)) : value;
};
Node.compare = function (a, b) {
/* returns:
-1: a < b
0: a = b
1: a > b
and *any* other value for a != b (e.g. undefined, NaN, -2 etc.) */
if ((a.compare) &&
// for "symmetric results" force toCSS-based comparison
// of Quoted or Anonymous if either value is one of those
!(b.type === 'Quoted' || b.type === 'Anonymous')) {
return a.compare(b);
}
else if (b.compare) {
return -b.compare(a);
}
else if (a.type !== b.type) {
return undefined;
}
a = a.value;
b = b.value;
if (!Array.isArray(a)) {
return a === b ? 0 : undefined;
}
if (a.length !== b.length) {
return undefined;
}
for (var i_1 = 0; i_1 < a.length; i_1++) {
if (Node.compare(a[i_1], b[i_1]) !== 0) {
return undefined;
}
}
return 0;
};
Node.numericCompare = function (a, b) {
return a < b ? -1
: a === b ? 0
: a > b ? 1 : undefined;
};
// Returns true if this node represents root of ast imported by reference
Node.prototype.blocksVisibility = function () {
if (this.visibilityBlocks === undefined) {
this.visibilityBlocks = 0;
}
return this.visibilityBlocks !== 0;
};
Node.prototype.addVisibilityBlock = function () {
if (this.visibilityBlocks === undefined) {
this.visibilityBlocks = 0;
}
this.visibilityBlocks = this.visibilityBlocks + 1;
};
Node.prototype.removeVisibilityBlock = function () {
if (this.visibilityBlocks === undefined) {
this.visibilityBlocks = 0;
}
this.visibilityBlocks = this.visibilityBlocks - 1;
};
// Turns on node visibility - if called node will be shown in output regardless
// of whether it comes from import by reference or not
Node.prototype.ensureVisibility = function () {
this.nodeVisible = true;
};
// Turns off node visibility - if called node will NOT be shown in output regardless
// of whether it comes from import by reference or not
Node.prototype.ensureInvisibility = function () {
this.nodeVisible = false;
};
// return values:
// false - the node must not be visible
// true - the node must be visible
// undefined or null - the node has the same visibility as its parent
Node.prototype.isVisible = function () {
return this.nodeVisible;
};
Node.prototype.visibilityInfo = function () {
return {
visibilityBlocks: this.visibilityBlocks,
nodeVisible: this.nodeVisible
};
};
Node.prototype.copyVisibilityInfo = function (info) {
if (!info) {
return;
}
this.visibilityBlocks = info.visibilityBlocks;
this.nodeVisible = info.nodeVisible;
};
return Node;
}());
//
// RGB Colors - #ff0014, #eee
//
var Color = function (rgb, a, originalForm) {
var self = this;
//
// The end goal here, is to parse the arguments
// into an integer triplet, such as `128, 255, 0`
//
// This facilitates operations and conversions.
//
if (Array.isArray(rgb)) {
this.rgb = rgb;
}
else if (rgb.length >= 6) {
this.rgb = [];
rgb.match(/.{2}/g).map(function (c, i) {
if (i < 3) {
self.rgb.push(parseInt(c, 16));
}
else {
self.alpha = (parseInt(c, 16)) / 255;
}
});
}
else {
this.rgb = [];
rgb.split('').map(function (c, i) {
if (i < 3) {
self.rgb.push(parseInt(c + c, 16));
}
else {
self.alpha = (parseInt(c + c, 16)) / 255;
}
});
}
this.alpha = this.alpha || (typeof a === 'number' ? a : 1);
if (typeof originalForm !== 'undefined') {
this.value = originalForm;
}
};
Color.prototype = Object.assign(new Node(), {
type: 'Color',
luma: function () {
var r = this.rgb[0] / 255, g = this.rgb[1] / 255, b = this.rgb[2] / 255;
r = (r <= 0.03928) ? r / 12.92 : Math.pow(((r + 0.055) / 1.055), 2.4);
g = (g <= 0.03928) ? g / 12.92 : Math.pow(((g + 0.055) / 1.055), 2.4);
b = (b <= 0.03928) ? b / 12.92 : Math.pow(((b + 0.055) / 1.055), 2.4);
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
},
genCSS: function (context, output) {
output.add(this.toCSS(context));
},
toCSS: function (context, doNotCompress) {
var compress = context && context.compress && !doNotCompress;
var color;
var alpha;
var colorFunction;
var args = [];
// `value` is set if this color was originally
// converted from a named color string so we need
// to respect this and try to output named color too.
alpha = this.fround(context, this.alpha);
if (this.value) {
if (this.value.indexOf('rgb') === 0) {
if (alpha < 1) {
colorFunction = 'rgba';
}
}
else if (this.value.indexOf('hsl') === 0) {
if (alpha < 1) {
colorFunction = 'hsla';
}
else {
colorFunction = 'hsl';
}
}
else {
return this.value;
}
}
else {
if (alpha < 1) {
colorFunction = 'rgba';
}
}
switch (colorFunction) {
case 'rgba':
args = this.rgb.map(function (c) {
return clamp$1(Math.round(c), 255);
}).concat(clamp$1(alpha, 1));
break;
case 'hsla':
args.push(clamp$1(alpha, 1));
// eslint-disable-next-line no-fallthrough
case 'hsl':
color = this.toHSL();
args = [
this.fround(context, color.h),
"".concat(this.fround(context, color.s * 100), "%"),
"".concat(this.fround(context, color.l * 100), "%")
].concat(args);
}
if (colorFunction) {
// Values are capped between `0` and `255`, rounded and zero-padded.
return "".concat(colorFunction, "(").concat(args.join(",".concat(compress ? '' : ' ')), ")");
}
color = this.toRGB();
if (compress) {
var splitcolor = color.split('');
// Convert color to short format
if (splitcolor[1] === splitcolor[2] && splitcolor[3] === splitcolor[4] && splitcolor[5] === splitcolor[6]) {
color = "#".concat(splitcolor[1]).concat(splitcolor[3]).concat(splitcolor[5]);
}
}
return color;
},
//
// Operations have to be done per-channel, if not,
// channels will spill onto each other. Once we have
// our result, in the form of an integer triplet,
// we create a new Color node to hold the result.
//
operate: function (context, op, other) {
var rgb = new Array(3);
var alpha = this.alpha * (1 - other.alpha) + other.alpha;
for (var c = 0; c < 3; c++) {
rgb[c] = this._operate(context, op, this.rgb[c], other.rgb[c]);
}
return new Color(rgb, alpha);
},
toRGB: function () {
return toHex(this.rgb);
},
toHSL: function () {
var r = this.rgb[0] / 255, g = this.rgb[1] / 255, b = this.rgb[2] / 255, a = this.alpha;
var max = Math.max(r, g, b), min = Math.min(r, g, b);
var h;
var s;
var l = (max + min) / 2;
var d = max - min;
if (max === min) {
h = s = 0;
}
else {
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch (max) {
case r:
h = (g - b) / d + (g < b ? 6 : 0);
break;
case g:
h = (b - r) / d + 2;
break;
case b:
h = (r - g) / d + 4;
break;
}
h /= 6;
}
return { h: h * 360, s: s, l: l, a: a };
},
// Adapted from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
toHSV: function () {
var r = this.rgb[0] / 255, g = this.rgb[1] / 255, b = this.rgb[2] / 255, a = this.alpha;
var max = Math.max(r, g, b), min = Math.min(r, g, b);
var h;
var s;
var v = max;
var d = max - min;
if (max === 0) {
s = 0;
}
else {
s = d / max;
}
if (max === min) {
h = 0;
}
else {
switch (max) {
case r:
h = (g - b) / d + (g < b ? 6 : 0);
break;
case g:
h = (b - r) / d + 2;
break;
case b:
h = (r - g) / d + 4;
break;
}
h /= 6;
}
return { h: h * 360, s: s, v: v, a: a };
},
toARGB: function () {
return toHex([this.alpha * 255].concat(this.rgb));
},
compare: function (x) {
return (x.rgb &&
x.rgb[0] === this.rgb[0] &&
x.rgb[1] === this.rgb[1] &&
x.rgb[2] === this.rgb[2] &&
x.alpha === this.alpha) ? 0 : undefined;
}
});
Color.fromKeyword = function (keyword) {
var c;
var key = keyword.toLowerCase();
// eslint-disable-next-line no-prototype-builtins
if (colors.hasOwnProperty(key)) {
c = new Color(colors[key].slice(1));
}
else if (key === 'transparent') {
c = new Color([0, 0, 0], 0);
}
if (c) {
c.value = keyword;
return c;
}
};
function clamp$1(v, max) {
return Math.min(Math.max(v, 0), max);
}
function toHex(v) {
return "#".concat(v.map(function (c) {
c = clamp$1(Math.round(c), 255);
return (c < 16 ? '0' : '') + c.toString(16);
}).join(''));
}
var Paren = function (node) {
this.value = node;
};
Paren.prototype = Object.assign(new Node(), {
type: 'Paren',
genCSS: function (context, output) {
output.add('(');
this.value.genCSS(context, output);
output.add(')');
},
eval: function (context) {
return new Paren(this.value.eval(context));
}
});
var _noSpaceCombinators = {
'': true,
' ': true,
'|': true
};
var Combinator = function (value) {
if (value === ' ') {
this.value = ' ';
this.emptyOrWhitespace = true;
}
else {
this.value = value ? value.trim() : '';
this.emptyOrWhitespace = this.value === '';
}
};
Combinator.prototype = Object.assign(new Node(), {
type: 'Combinator',
genCSS: function (context, output) {
var spaceOrEmpty = (context.compress || _noSpaceCombinators[this.value]) ? '' : ' ';
output.add(spaceOrEmpty + this.value + spaceOrEmpty);
}
});
var Element = function (combinator, value, isVariable, index, currentFileInfo, visibilityInfo) {
this.combinator = combinator instanceof Combinator ?
combinator : new Combinator(combinator);
if (typeof value === 'string') {
this.value = value.trim();
}
else if (value) {
this.value = value;
}
else {
this.value = '';
}
this.isVariable = isVariable;
this._index = index;
this._fileInfo = currentFileInfo;
this.copyVisibilityInfo(visibilityInfo);
this.setParent(this.combinator, this);
};
Element.prototype = Object.assign(new Node(), {
type: 'Element',
accept: function (visitor) {
var value = this.value;
this.combinator = visitor.visit(this.combinator);
if (typeof value === 'object') {
this.value = visitor.visit(value);
}
},
eval: function (context) {
return new Element(this.combinator, this.value.eval ? this.value.eval(context) : this.value, this.isVariable, this.getIndex(), this.fileInfo(), this.visibilityInfo());
},
clone: function () {
return new Element(this.combinator, this.value, this.isVariable, this.getIndex(), this.fileInfo(), this.visibilityInfo());
},
genCSS: function (context, output) {
output.add(this.toCSS(context), this.fileInfo(), this.getIndex());
},
toCSS: function (context) {
context = context || {};
var value = this.value;
var firstSelector = context.firstSelector;
if (value instanceof Paren) {
// selector in parens should not be affected by outer selector
// flags (breaks only interpolated selectors - see #1973)
context.firstSelector = true;
}
value = value.toCSS ? value.toCSS(context) : value;
context.firstSelector = firstSelector;
if (value === '' && this.combinator.value.charAt(0) === '&') {
return '';
}
else {
return this.combinator.toCSS(context) + value;
}
}
});
var Math$1 = {
ALWAYS: 0,
PARENS_DIVISION: 1,
PARENS: 2
// removed - STRICT_LEGACY: 3
};
var RewriteUrls = {
OFF: 0,
LOCAL: 1,
ALL: 2
};
/******************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
var __assign = function() {
__assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
function __spreadArray(to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
}
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
var e = new Error(message);
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
};
/**
* Returns the object type of the given payload
*
* @param {*} payload
* @returns {string}
*/
function getType(payload) {
return Object.prototype.toString.call(payload).slice(8, -1);
}
/**
* Returns whether the payload is a plain JavaScript object (excluding special classes or objects with other prototypes)
*
* @param {*} payload
* @returns {payload is PlainObject}
*/
function isPlainObject(payload) {
if (getType(payload) !== 'Object')
return false;
return payload.constructor === Object && Object.getPrototypeOf(payload) === Object.prototype;
}
/**
* Returns whether the payload is an array
*
* @param {any} payload
* @returns {payload is any[]}
*/
function isArray(payload) {
return getType(payload) === 'Array';
}
function assignProp(carry, key, newVal, originalObject, includeNonenumerable) {
var propType = {}.propertyIsEnumerable.call(originalObject, key)
? 'enumerable'
: 'nonenumerable';
if (propType === 'enumerable')
carry[key] = newVal;
if (includeNonenumerable && propType === 'nonenumerable') {
Object.defineProperty(carry, key, {
value: newVal,
enumerable: false,
writable: true,
configurable: true,
});
}
}
/**
* Copy (clone) an object and all its props recursively to get rid of any prop referenced of the original object. Arrays are also cloned, however objects inside arrays are still linked.
*
* @export
* @template T
* @param {T} target Target can be anything
* @param {Options} [options = {}] Options can be `props` or `nonenumerable`
* @returns {T} the target with replaced values
* @export
*/
function copy(target, options) {
if (options === void 0) { options = {}; }
if (isArray(target)) {
return target.map(function (item) { return copy(item, options); });
}
if (!isPlainObject(target)) {
return target;
}
var props = Object.getOwnPropertyNames(target);
var symbols = Object.getOwnPropertySymbols(target);
return __spreadArray(__spreadArray([], props, true), symbols, true).reduce(function (carry, key) {
if (isArray(options.props) && !options.props.includes(key)) {
return carry;
}
var val = target[key];
var newVal = copy(val, options);
assignProp(carry, key, newVal, target, options.nonenumerable);
return carry;
}, {});
}
/* jshint proto: true */
function getLocation(index, inputStream) {
var n = index + 1;
var line = null;
var column = -1;
while (--n >= 0 && inputStream.charAt(n) !== '\n') {
column++;
}
if (typeof index === 'number') {
line = (inputStream.slice(0, index).match(/\n/g) || '').length;
}
return {
line: line,
column: column
};
}
function copyArray(arr) {
var i;
var length = arr.length;
var copy = new Array(length);
for (i = 0; i < length; i++) {
copy[i] = arr[i];
}
return copy;
}
function clone(obj) {
var cloned = {};
for (var prop in obj) {
if (Object.prototype.hasOwnProperty.call(obj, prop)) {
cloned[prop] = obj[prop];
}
}
return cloned;
}
function defaults(obj1, obj2) {
var newObj = obj2 || {};
if (!obj2._defaults) {
newObj = {};
var defaults_1 = copy(obj1);
newObj._defaults = defaults_1;
var cloned = obj2 ? copy(obj2) : {};
Object.assign(newObj, defaults_1, cloned);
}
return newObj;
}
function copyOptions(obj1, obj2) {
if (obj2 && obj2._defaults) {
return obj2;
}
var opts = defaults(obj1, obj2);
if (opts.strictMath) {
opts.math = Math$1.PARENS;
}
// Back compat with changed relativeUrls option
if (opts.relativeUrls) {
opts.rewriteUrls = RewriteUrls.ALL;
}
if (typeof opts.math === 'string') {
switch (opts.math.toLowerCase()) {
case 'always':
opts.math = Math$1.ALWAYS;
break;
case 'parens-division':
opts.math = Math$1.PARENS_DIVISION;
break;
case 'strict':
case 'parens':
opts.math = Math$1.PARENS;
break;
default:
opts.math = Math$1.PARENS;
}
}
if (typeof opts.rewriteUrls === 'string') {
switch (opts.rewriteUrls.toLowerCase()) {
case 'off':
opts.rewriteUrls = RewriteUrls.OFF;
break;
case 'local':
opts.rewriteUrls = RewriteUrls.LOCAL;
break;
case 'all':
opts.rewriteUrls = RewriteUrls.ALL;
break;
}
}
return opts;
}
function merge(obj1, obj2) {
for (var prop in obj2) {
if (Object.prototype.hasOwnProperty.call(obj2, prop)) {
obj1[prop] = obj2[prop];
}
}
return obj1;
}
function flattenArray(arr, result) {
if (result === void 0) { result = []; }
for (var i_1 = 0, length_1 = arr.length; i_1 < length_1; i_1++) {
var value = arr[i_1];
if (Array.isArray(value)) {
flattenArray(value, result);
}
else {
if (value !== undefined) {
result.push(value);
}
}
}
return result;
}
function isNullOrUndefined(val) {
return val === null || val === undefined;
}
var utils = /*#__PURE__*/Object.freeze({
__proto__: null,
getLocation: getLocation,
copyArray: copyArray,
clone: clone,
defaults: defaults,
copyOptions: copyOptions,
merge: merge,
flattenArray: flattenArray,
isNullOrUndefined: isNullOrUndefined
});
var anonymousFunc = /(<anonymous>|Function):(\d+):(\d+)/;
/**
* This is a centralized class of any error that could be thrown internally (mostly by the parser).
* Besides standard .message it keeps some additional data like a path to the file where the error
* occurred along with line and column numbers.
*
* @class
* @extends Error
* @type {module.LessError}
*
* @prop {string} type
* @prop {string} filename
* @prop {number} index
* @prop {number} line
* @prop {number} column
* @prop {number} callLine
* @prop {number} callExtract
* @prop {string[]} extract
*
* @param {Object} e - An error object to wrap around or just a descriptive object
* @param {Object} fileContentMap - An object with file contents in 'contents' property (like importManager) @todo - move to fileManager?
* @param {string} [currentFilename]
*/
var LessError = function (e, fileContentMap, currentFilename) {
Error.call(this);
var filename = e.filename || currentFilename;
this.message = e.message;
this.stack = e.stack;
if (fileContentMap && filename) {
var input = fileContentMap.contents[filename];
var loc = getLocation(e.index, input);
var line = loc.line;
var col = loc.column;
var callLine = e.call && getLocation(e.call, input).line;
var lines = input ? input.split('\n') : '';
this.type = e.type || 'Syntax';
this.filename = filename;
this.index = e.index;
this.line = typeof line === 'number' ? line + 1 : null;
this.column = col;
if (!this.line && this.stack) {
var found = this.stack.match(anonymousFunc);
/**
* We have to figure out how this environment stringifies anonymous functions
* so we can correctly map plugin errors.
*
* Note, in Node 8, the output of anonymous funcs varied based on parameters
* being present or not, so we inject dummy params.
*/
var func = new Function('a', 'throw new Error()');
var lineAdjust = 0;
try {
func();
}
catch (e) {
var match = e.stack.match(anonymousFunc);
lineAdjust = 1 - parseInt(match[2]);
}
if (found) {
if (found[2]) {
this.line = parseInt(found[2]) + lineAdjust;
}
if (found[3]) {
this.column = parseInt(found[3]);
}
}
}
this.callLine = callLine + 1;
this.callExtract = lines[callLine];
this.extract = [
lines[this.line - 2],
lines[this.line - 1],
lines[this.line]
];
}
};
if (typeof Object.create === 'undefined') {
var F = function () { };
F.prototype = Error.prototype;
LessError.prototype = new F();
}
else {
LessError.prototype = Object.create(Error.prototype);
}
LessError.prototype.constructor = LessError;
/**
* An overridden version of the default Object.prototype.toString
* which uses additional information to create a helpful message.
*
* @param {Object} options
* @returns {string}
*/
LessError.prototype.toString = function (options) {
options = options || {};
var message = '';
var extract = this.extract || [];
var error = [];
var stylize = function (str) { return str; };
if (options.stylize) {