>> 0;
- for (var i = 0; i < len; i++) {
- if (i in this) {
- block.call(thisObject, this[i], i, this);
- }
- }
- };
-}
-if (!Array.prototype.map) {
- Array.prototype.map = function(fun /*, thisp*/) {
- var len = this.length >>> 0;
- var res = new Array(len);
- var thisp = arguments[1];
-
- for (var i = 0; i < len; i++) {
- if (i in this) {
- res[i] = fun.call(thisp, this[i], i, this);
- }
- }
- return res;
- };
-}
-if (!Array.prototype.filter) {
- Array.prototype.filter = function (block /*, thisp */) {
- var values = [];
- var thisp = arguments[1];
- for (var i = 0; i < this.length; i++) {
- if (block.call(thisp, this[i])) {
- values.push(this[i]);
- }
- }
- return values;
- };
-}
-if (!Array.prototype.reduce) {
- Array.prototype.reduce = function(fun /*, initial*/) {
- var len = this.length >>> 0;
- var i = 0;
-
- // no value to return if no initial value and an empty array
- if (len === 0 && arguments.length === 1) throw new TypeError();
-
- if (arguments.length >= 2) {
- var rv = arguments[1];
- } else {
- do {
- if (i in this) {
- rv = this[i++];
- break;
- }
- // if array contains no values, no initial value to return
- if (++i >= len) throw new TypeError();
- } while (true);
- }
- for (; i < len; i++) {
- if (i in this) {
- rv = fun.call(null, rv, this[i], i, this);
- }
- }
- return rv;
- };
-}
-if (!Array.prototype.indexOf) {
- Array.prototype.indexOf = function (value /*, fromIndex */ ) {
- var length = this.length;
- var i = arguments[1] || 0;
-
- if (!length) return -1;
- if (i >= length) return -1;
- if (i < 0) i += length;
-
- for (; i < length; i++) {
- if (!Object.prototype.hasOwnProperty.call(this, i)) { continue }
- if (value === this[i]) return i;
- }
- return -1;
- };
-}
-
-//
-// Object
-//
-if (!Object.keys) {
- Object.keys = function (object) {
- var keys = [];
- for (var name in object) {
- if (Object.prototype.hasOwnProperty.call(object, name)) {
- keys.push(name);
- }
- }
- return keys;
- };
-}
-
-//
-// String
-//
-if (!String.prototype.trim) {
- String.prototype.trim = function () {
- return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
- };
-}
-var less, tree;
-
-if (typeof environment === "object" && ({}).toString.call(environment) === "[object Environment]") {
- // Rhino
- // Details on how to detect Rhino: https://github.com/ringo/ringojs/issues/88
- if (typeof(window) === 'undefined') { less = {} }
- else { less = window.less = {} }
- tree = less.tree = {};
- less.mode = 'rhino';
-} else if (typeof(window) === 'undefined') {
- // Node.js
- less = exports,
- tree = require('./tree');
- less.mode = 'node';
-} else {
- // Browser
- if (typeof(window.less) === 'undefined') { window.less = {} }
- less = window.less,
- tree = window.less.tree = {};
- less.mode = 'browser';
-}
-//
-// less.js - parser
-//
-// A relatively straight-forward predictive parser.
-// There is no tokenization/lexing stage, the input is parsed
-// in one sweep.
-//
-// To make the parser fast enough to run in the browser, several
-// optimization had to be made:
-//
-// - Matching and slicing on a huge input is often cause of slowdowns.
-// The solution is to chunkify the input into smaller strings.
-// The chunks are stored in the `chunks` var,
-// `j` holds the current chunk index, and `current` holds
-// the index of the current chunk in relation to `input`.
-// This gives us an almost 4x speed-up.
-//
-// - In many cases, we don't need to match individual tokens;
-// for example, if a value doesn't hold any variables, operations
-// or dynamic references, the parser can effectively 'skip' it,
-// treating it as a literal.
-// An example would be '1px solid #000' - which evaluates to itself,
-// we don't need to know what the individual components are.
-// The drawback, of course is that you don't get the benefits of
-// syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
-// and a smaller speed-up in the code-gen.
-//
-//
-// Token matching is done with the `$` function, which either takes
-// a terminal string or regexp, or a non-terminal function to call.
-// It also takes care of moving all the indices forwards.
-//
-//
-less.Parser = function Parser(env) {
- var input, // LeSS input string
- i, // current index in `input`
- j, // current chunk
- temp, // temporarily holds a chunk's state, for backtracking
- memo, // temporarily holds `i`, when backtracking
- furthest, // furthest index the parser has gone to
- chunks, // chunkified input
- current, // index of current chunk, in `input`
- parser;
-
- var that = this;
-
- // This function is called after all files
- // have been imported through `@import`.
- var finish = function () {};
-
- var imports = this.imports = {
- paths: env && env.paths || [], // Search paths, when importing
- queue: [], // Files which haven't been imported yet
- files: {}, // Holds the imported parse trees
- contents: {}, // Holds the imported file contents
- mime: env && env.mime, // MIME type of .less files
- error: null, // Error in parsing/evaluating an import
- push: function (path, callback) {
- var that = this;
- this.queue.push(path);
-
- //
- // Import a file asynchronously
- //
- less.Parser.importer(path, this.paths, function (e, root, contents) {
- that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
- that.files[path] = root; // Store the root
- that.contents[path] = contents;
-
- if (e && !that.error) { that.error = e }
- callback(e, root);
-
- if (that.queue.length === 0) { finish() } // Call `finish` if we're done importing
- }, env);
- }
- };
-
- function save() { temp = chunks[j], memo = i, current = i }
- function restore() { chunks[j] = temp, i = memo, current = i }
-
- function sync() {
- if (i > current) {
- chunks[j] = chunks[j].slice(i - current);
- current = i;
- }
- }
- //
- // Parse from a token, regexp or string, and move forward if match
- //
- function $(tok) {
- var match, args, length, c, index, endIndex, k, mem;
-
- //
- // Non-terminal
- //
- if (tok instanceof Function) {
- return tok.call(parser.parsers);
- //
- // Terminal
- //
- // Either match a single character in the input,
- // or match a regexp in the current chunk (chunk[j]).
- //
- } else if (typeof(tok) === 'string') {
- match = input.charAt(i) === tok ? tok : null;
- length = 1;
- sync ();
- } else {
- sync ();
-
- if (match = tok.exec(chunks[j])) {
- length = match[0].length;
- } else {
- return null;
- }
- }
-
- // The match is confirmed, add the match length to `i`,
- // and consume any extra white-space characters (' ' || '\n')
- // which come after that. The reason for this is that LeSS's
- // grammar is mostly white-space insensitive.
- //
- if (match) {
- mem = i += length;
- endIndex = i + chunks[j].length - length;
-
- while (i < endIndex) {
- c = input.charCodeAt(i);
- if (! (c === 32 || c === 10 || c === 9)) { break }
- i++;
- }
- chunks[j] = chunks[j].slice(length + (i - mem));
- current = i;
-
- if (chunks[j].length === 0 && j < chunks.length - 1) { j++ }
-
- if(typeof(match) === 'string') {
- return match;
- } else {
- return match.length === 1 ? match[0] : match;
- }
- }
- }
-
- function expect(arg, msg) {
- var result = $(arg);
- if (! result) {
- error(msg || (typeof(arg) === 'string' ? "expected '" + arg + "' got '" + input.charAt(i) + "'"
- : "unexpected token"));
- } else {
- return result;
- }
- }
-
- function error(msg, type) {
- throw { index: i, type: type || 'Syntax', message: msg };
- }
-
- // Same as $(), but don't change the state of the parser,
- // just return the match.
- function peek(tok) {
- if (typeof(tok) === 'string') {
- return input.charAt(i) === tok;
- } else {
- if (tok.test(chunks[j])) {
- return true;
- } else {
- return false;
- }
- }
- }
-
- function basename(pathname) {
- if (less.mode === 'node') {
- return require('path').basename(pathname);
- } else {
- return pathname.match(/[^\/]+$/)[0];
- }
- }
-
- function getInput(e, env) {
- if (e.filename && env.filename && (e.filename !== env.filename)) {
- return parser.imports.contents[basename(e.filename)];
- } else {
- return input;
- }
- }
-
- function getLocation(index, input) {
- for (var n = index, column = -1;
- n >= 0 && input.charAt(n) !== '\n';
- n--) { column++ }
-
- return { line: typeof(index) === 'number' ? (input.slice(0, index).match(/\n/g) || "").length : null,
- column: column };
- }
-
- function LessError(e, env) {
- var input = getInput(e, env),
- loc = getLocation(e.index, input),
- line = loc.line,
- col = loc.column,
- lines = input.split('\n');
-
- this.type = e.type || 'Syntax';
- this.message = e.message;
- this.filename = e.filename || env.filename;
- this.index = e.index;
- this.line = typeof(line) === 'number' ? line + 1 : null;
- this.callLine = e.call && (getLocation(e.call, input) + 1);
- this.callExtract = lines[getLocation(e.call, input)];
- this.stack = e.stack;
- this.column = col;
- this.extract = [
- lines[line - 1],
- lines[line],
- lines[line + 1]
- ];
- }
-
- this.env = env = env || {};
-
- // The optimization level dictates the thoroughness of the parser,
- // the lower the number, the less nodes it will create in the tree.
- // This could matter for debugging, or if you want to access
- // the individual nodes in the tree.
- this.optimization = ('optimization' in this.env) ? this.env.optimization : 1;
-
- this.env.filename = this.env.filename || null;
-
- //
- // The Parser
- //
- return parser = {
-
- imports: imports,
- //
- // Parse an input string into an abstract syntax tree,
- // call `callback` when done.
- //
- parse: function (str, callback) {
- var root, start, end, zone, line, lines, buff = [], c, error = null;
-
- i = j = current = furthest = 0;
- input = str.replace(/\r\n/g, '\n');
-
- // Split the input into chunks.
- chunks = (function (chunks) {
- var j = 0,
- skip = /[^"'`\{\}\/\(\)\\]+/g,
- comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
- string = /"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'|`((?:[^`\\\r\n]|\\.)*)`/g,
- level = 0,
- match,
- chunk = chunks[0],
- inParam;
-
- for (var i = 0, c, cc; i < input.length; i++) {
- skip.lastIndex = i;
- if (match = skip.exec(input)) {
- if (match.index === i) {
- i += match[0].length;
- chunk.push(match[0]);
- }
- }
- c = input.charAt(i);
- comment.lastIndex = string.lastIndex = i;
-
- if (match = string.exec(input)) {
- if (match.index === i) {
- i += match[0].length;
- chunk.push(match[0]);
- c = input.charAt(i);
- }
- }
-
- if (!inParam && c === '/') {
- cc = input.charAt(i + 1);
- if (cc === '/' || cc === '*') {
- if (match = comment.exec(input)) {
- if (match.index === i) {
- i += match[0].length;
- chunk.push(match[0]);
- c = input.charAt(i);
- }
- }
- }
- }
-
- switch (c) {
- case '{': if (! inParam) { level ++; chunk.push(c); break }
- case '}': if (! inParam) { level --; chunk.push(c); chunks[++j] = chunk = []; break }
- case '(': if (! inParam) { inParam = true; chunk.push(c); break }
- case ')': if ( inParam) { inParam = false; chunk.push(c); break }
- default: chunk.push(c);
- }
- }
- if (level > 0) {
- error = new(LessError)({
- index: i,
- type: 'Parse',
- message: "missing closing `}`",
- filename: env.filename
- }, env);
- }
-
- return chunks.map(function (c) { return c.join('') });;
- })([[]]);
-
- if (error) {
- return callback(error);
- }
-
- // Start with the primary rule.
- // The whole syntax tree is held under a Ruleset node,
- // with the `root` property set to true, so no `{}` are
- // output. The callback is called when the input is parsed.
- try {
- root = new(tree.Ruleset)([], $(this.parsers.primary));
- root.root = true;
- } catch (e) {
- return callback(new(LessError)(e, env));
- }
-
- root.toCSS = (function (evaluate) {
- var line, lines, column;
-
- return function (options, variables) {
- var frames = [], importError;
-
- options = options || {};
- //
- // Allows setting variables with a hash, so:
- //
- // `{ color: new(tree.Color)('#f01') }` will become:
- //
- // new(tree.Rule)('@color',
- // new(tree.Value)([
- // new(tree.Expression)([
- // new(tree.Color)('#f01')
- // ])
- // ])
- // )
- //
- if (typeof(variables) === 'object' && !Array.isArray(variables)) {
- variables = Object.keys(variables).map(function (k) {
- var value = variables[k];
-
- if (! (value instanceof tree.Value)) {
- if (! (value instanceof tree.Expression)) {
- value = new(tree.Expression)([value]);
- }
- value = new(tree.Value)([value]);
- }
- return new(tree.Rule)('@' + k, value, false, 0);
- });
- frames = [new(tree.Ruleset)(null, variables)];
- }
-
- try {
- var css = evaluate.call(this, { frames: frames })
- .toCSS([], { compress: options.compress || false });
- } catch (e) {
- throw new(LessError)(e, env);
- }
-
- if ((importError = parser.imports.error)) { // Check if there was an error during importing
- if (importError instanceof LessError) throw importError;
- else throw new(LessError)(importError, env);
- }
-
- if (options.yuicompress && less.mode === 'node') {
- return require('./cssmin').compressor.cssmin(css);
- } else if (options.compress) {
- return css.replace(/(\s)+/g, "$1");
- } else {
- return css;
- }
- };
- })(root.eval);
-
- // If `i` is smaller than the `input.length - 1`,
- // it means the parser wasn't able to parse the whole
- // string, so we've got a parsing error.
- //
- // We try to extract a \n delimited string,
- // showing the line where the parse error occured.
- // We split it up into two parts (the part which parsed,
- // and the part which didn't), so we can color them differently.
- if (i < input.length - 1) {
- i = furthest;
- lines = input.split('\n');
- line = (input.slice(0, i).match(/\n/g) || "").length + 1;
-
- for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }
-
- error = {
- type: "Parse",
- message: "Syntax Error on line " + line,
- index: i,
- filename: env.filename,
- line: line,
- column: column,
- extract: [
- lines[line - 2],
- lines[line - 1],
- lines[line]
- ]
- };
- }
-
- if (this.imports.queue.length > 0) {
- finish = function () { callback(error, root) };
- } else {
- callback(error, root);
- }
- },
-
- //
- // Here in, the parsing rules/functions
- //
- // The basic structure of the syntax tree generated is as follows:
- //
- // Ruleset -> Rule -> Value -> Expression -> Entity
- //
- // Here's some LESS code:
- //
- // .class {
- // color: #fff;
- // border: 1px solid #000;
- // width: @w + 4px;
- // > .child {...}
- // }
- //
- // And here's what the parse tree might look like:
- //
- // Ruleset (Selector '.class', [
- // Rule ("color", Value ([Expression [Color #fff]]))
- // Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
- // Rule ("width", Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
- // Ruleset (Selector [Element '>', '.child'], [...])
- // ])
- //
- // In general, most rules will try to parse a token with the `$()` function, and if the return
- // value is truly, will return a new node, of the relevant type. Sometimes, we need to check
- // first, before parsing, that's when we use `peek()`.
- //
- parsers: {
- //
- // The `primary` rule is the *entry* and *exit* point of the parser.
- // The rules here can appear at any level of the parse tree.
- //
- // The recursive nature of the grammar is an interplay between the `block`
- // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
- // as represented by this simplified grammar:
- //
- // primary → (ruleset | rule)+
- // ruleset → selector+ block
- // block → '{' primary '}'
- //
- // Only at one point is the primary rule not called from the
- // block rule: at the root level.
- //
- primary: function () {
- var node, root = [];
-
- while ((node = $(this.mixin.definition) || $(this.rule) || $(this.ruleset) ||
- $(this.mixin.call) || $(this.comment) || $(this.directive))
- || $(/^[\s\n]+/)) {
- node && root.push(node);
- }
- return root;
- },
-
- // We create a Comment node for CSS comments `/* */`,
- // but keep the LeSS comments `//` silent, by just skipping
- // over them.
- comment: function () {
- var comment;
-
- if (input.charAt(i) !== '/') return;
-
- if (input.charAt(i + 1) === '/') {
- return new(tree.Comment)($(/^\/\/.*/), true);
- } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) {
- return new(tree.Comment)(comment);
- }
- },
-
- //
- // Entities are tokens which can be found inside an Expression
- //
- entities: {
- //
- // A string, which supports escaping " and '
- //
- // "milky way" 'he\'s the one!'
- //
- quoted: function () {
- var str, j = i, e;
-
- if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
- if (input.charAt(j) !== '"' && input.charAt(j) !== "'") return;
-
- e && $('~');
-
- if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) {
- return new(tree.Quoted)(str[0], str[1] || str[2], e);
- }
- },
-
- //
- // A catch-all word, such as:
- //
- // black border-collapse
- //
- keyword: function () {
- var k;
-
- if (k = $(/^[_A-Za-z-][_A-Za-z0-9-]*/)) {
- if (tree.colors.hasOwnProperty(k)) {
- // detect named color
- return new(tree.Color)(tree.colors[k].slice(1));
- } else {
- return new(tree.Keyword)(k);
- }
- }
- },
-
- //
- // A function call
- //
- // rgb(255, 0, 255)
- //
- // We also try to catch IE's `alpha()`, but let the `alpha` parser
- // deal with the details.
- //
- // The arguments are parsed with the `entities.arguments` parser.
- //
- call: function () {
- var name, args, index = i;
-
- if (! (name = /^([\w-]+|%|progid:[\w\.]+)\(/.exec(chunks[j]))) return;
-
- name = name[1].toLowerCase();
-
- if (name === 'url') { return null }
- else { i += name.length }
-
- if (name === 'alpha') { return $(this.alpha) }
-
- $('('); // Parse the '(' and consume whitespace.
-
- args = $(this.entities.arguments);
-
- if (! $(')')) return;
-
- if (name) { return new(tree.Call)(name, args, index, env.filename) }
- },
- arguments: function () {
- var args = [], arg;
-
- while (arg = $(this.entities.assignment) || $(this.expression)) {
- args.push(arg);
- if (! $(',')) { break }
- }
- return args;
- },
- literal: function () {
- return $(this.entities.dimension) ||
- $(this.entities.color) ||
- $(this.entities.quoted);
- },
-
- // Assignments are argument entities for calls.
- // They are present in ie filter properties as shown below.
- //
- // filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* )
- //
-
- assignment: function () {
- var key, value;
- if ((key = $(/^\w+(?=\s?=)/i)) && $('=') && (value = $(this.entity))) {
- return new(tree.Assignment)(key, value);
- }
- },
-
- //
- // Parse url() tokens
- //
- // We use a specific rule for urls, because they don't really behave like
- // standard function calls. The difference is that the argument doesn't have
- // to be enclosed within a string, so it can't be parsed as an Expression.
- //
- url: function () {
- var value;
-
- if (input.charAt(i) !== 'u' || !$(/^url\(/)) return;
- value = $(this.entities.quoted) || $(this.entities.variable) ||
- $(this.entities.dataURI) || $(/^[-\w%@$\/.&=:;#+?~]+/) || "";
-
- expect(')');
-
- return new(tree.URL)((value.value || value.data || value instanceof tree.Variable)
- ? value : new(tree.Anonymous)(value), imports.paths);
- },
-
- dataURI: function () {
- var obj;
-
- if ($(/^data:/)) {
- obj = {};
- obj.mime = $(/^[^\/]+\/[^,;)]+/) || '';
- obj.charset = $(/^;\s*charset=[^,;)]+/) || '';
- obj.base64 = $(/^;\s*base64/) || '';
- obj.data = $(/^,\s*[^)]+/);
-
- if (obj.data) { return obj }
- }
- },
-
- //
- // A Variable entity, such as `@fink`, in
- //
- // width: @fink + 2px
- //
- // We use a different parser for variable definitions,
- // see `parsers.variable`.
- //
- variable: function () {
- var name, index = i;
-
- if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) {
- return new(tree.Variable)(name, index, env.filename);
- }
- },
-
- //
- // A Hexadecimal color
- //
- // #4F3C2F
- //
- // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
- //
- color: function () {
- var rgb;
-
- if (input.charAt(i) === '#' && (rgb = $(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/))) {
- return new(tree.Color)(rgb[1]);
- }
- },
-
- //
- // A Dimension, that is, a number and a unit
- //
- // 0.5em 95%
- //
- dimension: function () {
- var value, c = input.charCodeAt(i);
- if ((c > 57 || c < 45) || c === 47) return;
-
- if (value = $(/^(-?\d*\.?\d+)(px|%|em|rem|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/)) {
- return new(tree.Dimension)(value[1], value[2]);
- }
- },
-
- //
- // JavaScript code to be evaluated
- //
- // `window.location.href`
- //
- javascript: function () {
- var str, j = i, e;
-
- if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
- if (input.charAt(j) !== '`') { return }
-
- e && $('~');
-
- if (str = $(/^`([^`]*)`/)) {
- return new(tree.JavaScript)(str[1], i, e);
- }
- }
- },
-
- //
- // The variable part of a variable definition. Used in the `rule` parser
- //
- // @fink:
- //
- variable: function () {
- var name;
-
- if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1] }
- },
-
- //
- // A font size/line-height shorthand
- //
- // small/12px
- //
- // We need to peek first, or we'll match on keywords and dimensions
- //
- shorthand: function () {
- var a, b;
-
- if (! peek(/^[@\w.%-]+\/[@\w.-]+/)) return;
-
- if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
- return new(tree.Shorthand)(a, b);
- }
- },
-
- //
- // Mixins
- //
- mixin: {
- //
- // A Mixin call, with an optional argument list
- //
- // #mixins > .square(#fff);
- // .rounded(4px, black);
- // .button;
- //
- // The `while` loop is there because mixins can be
- // namespaced, but we only support the child and descendant
- // selector for now.
- //
- call: function () {
- var elements = [], e, c, args, index = i, s = input.charAt(i), important = false;
-
- if (s !== '.' && s !== '#') { return }
-
- while (e = $(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)) {
- elements.push(new(tree.Element)(c, e, i));
- c = $('>');
- }
- $('(') && (args = $(this.entities.arguments)) && $(')');
-
- if ($(this.important)) {
- important = true;
- }
-
- if (elements.length > 0 && ($(';') || peek('}'))) {
- return new(tree.mixin.Call)(elements, args, index, env.filename, important);
- }
- },
-
- //
- // A Mixin definition, with a list of parameters
- //
- // .rounded (@radius: 2px, @color) {
- // ...
- // }
- //
- // Until we have a finer grained state-machine, we have to
- // do a look-ahead, to make sure we don't have a mixin call.
- // See the `rule` function for more information.
- //
- // We start by matching `.rounded (`, and then proceed on to
- // the argument list, which has optional default values.
- // We store the parameters in `params`, with a `value` key,
- // if there is a value, such as in the case of `@radius`.
- //
- // Once we've got our params list, and a closing `)`, we parse
- // the `{...}` block.
- //
- definition: function () {
- var name, params = [], match, ruleset, param, value, cond;
- if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') ||
- peek(/^[^{]*(;|})/)) return;
-
- save();
-
- if (match = $(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)) {
- name = match[1];
-
- while (param = $(this.entities.variable) || $(this.entities.literal)
- || $(this.entities.keyword)) {
- // Variable
- if (param instanceof tree.Variable) {
- if ($(':')) {
- value = expect(this.expression, 'expected expression');
- params.push({ name: param.name, value: value });
- } else {
- params.push({ name: param.name });
- }
- } else {
- params.push({ value: param });
- }
- if (! $(',')) { break }
- }
- expect(')');
-
- if ($(/^when/)) { // Guard
- cond = expect(this.conditions, 'expected condition');
- }
-
- ruleset = $(this.block);
-
- if (ruleset) {
- return new(tree.mixin.Definition)(name, params, ruleset, cond);
- } else {
- restore();
- }
- }
- }
- },
-
- //
- // Entities are the smallest recognized token,
- // and can be found inside a rule's value.
- //
- entity: function () {
- return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) ||
- $(this.entities.call) || $(this.entities.keyword) || $(this.entities.javascript) ||
- $(this.comment);
- },
-
- //
- // A Rule terminator. Note that we use `peek()` to check for '}',
- // because the `block` rule will be expecting it, but we still need to make sure
- // it's there, if ';' was ommitted.
- //
- end: function () {
- return $(';') || peek('}');
- },
-
- //
- // IE's alpha function
- //
- // alpha(opacity=88)
- //
- alpha: function () {
- var value;
-
- if (! $(/^\(opacity=/i)) return;
- if (value = $(/^\d+/) || $(this.entities.variable)) {
- expect(')');
- return new(tree.Alpha)(value);
- }
- },
-
- //
- // A Selector Element
- //
- // div
- // + h1
- // #socks
- // input[type="text"]
- //
- // Elements are the building blocks for Selectors,
- // they are made out of a `Combinator` (see combinator rule),
- // and an element name, such as a tag a class, or `*`.
- //
- element: function () {
- var e, t, c, v;
-
- c = $(this.combinator);
- e = $(/^(?:\d+\.\d+|\d+)%/) || $(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/) ||
- $('*') || $(this.attribute) || $(/^\([^)@]+\)/);
-
- if (! e) {
- $('(') && (v = $(this.entities.variable)) && $(')') && (e = new(tree.Paren)(v));
- }
-
- if (e) { return new(tree.Element)(c, e, i) }
-
- if (c.value && c.value.charAt(0) === '&') {
- return new(tree.Element)(c, null, i);
- }
- },
-
- //
- // Combinators combine elements together, in a Selector.
- //
- // Because our parser isn't white-space sensitive, special care
- // has to be taken, when parsing the descendant combinator, ` `,
- // as it's an empty space. We have to check the previous character
- // in the input, to see if it's a ` ` character. More info on how
- // we deal with this in *combinator.js*.
- //
- combinator: function () {
- var match, c = input.charAt(i);
-
- if (c === '>' || c === '+' || c === '~') {
- i++;
- while (input.charAt(i) === ' ') { i++ }
- return new(tree.Combinator)(c);
- } else if (c === '&') {
- match = '&';
- i++;
- if(input.charAt(i) === ' ') {
- match = '& ';
- }
- while (input.charAt(i) === ' ') { i++ }
- return new(tree.Combinator)(match);
- } else if (c === ':' && input.charAt(i + 1) === ':') {
- i += 2;
- while (input.charAt(i) === ' ') { i++ }
- return new(tree.Combinator)('::');
- } else if (input.charAt(i - 1) === ' ') {
- return new(tree.Combinator)(" ");
- } else {
- return new(tree.Combinator)(null);
- }
- },
-
- //
- // A CSS Selector
- //
- // .class > div + h1
- // li a:hover
- //
- // Selectors are made out of one or more Elements, see above.
- //
- selector: function () {
- var sel, e, elements = [], c, match;
-
- while (e = $(this.element)) {
- c = input.charAt(i);
- elements.push(e)
- if (c === '{' || c === '}' || c === ';' || c === ',') { break }
- }
-
- if (elements.length > 0) { return new(tree.Selector)(elements) }
- },
- tag: function () {
- return $(/^[a-zA-Z][a-zA-Z-]*[0-9]?/) || $('*');
- },
- attribute: function () {
- var attr = '', key, val, op;
-
- if (! $('[')) return;
-
- if (key = $(/^[a-zA-Z-]+/) || $(this.entities.quoted)) {
- if ((op = $(/^[|~*$^]?=/)) &&
- (val = $(this.entities.quoted) || $(/^[\w-]+/))) {
- attr = [key, op, val.toCSS ? val.toCSS() : val].join('');
- } else { attr = key }
- }
-
- if (! $(']')) return;
-
- if (attr) { return "[" + attr + "]" }
- },
-
- //
- // The `block` rule is used by `ruleset` and `mixin.definition`.
- // It's a wrapper around the `primary` rule, with added `{}`.
- //
- block: function () {
- var content;
-
- if ($('{') && (content = $(this.primary)) && $('}')) {
- return content;
- }
- },
-
- //
- // div, .class, body > p {...}
- //
- ruleset: function () {
- var selectors = [], s, rules, match;
- save();
-
- while (s = $(this.selector)) {
- selectors.push(s);
- $(this.comment);
- if (! $(',')) { break }
- $(this.comment);
- }
-
- if (selectors.length > 0 && (rules = $(this.block))) {
- return new(tree.Ruleset)(selectors, rules);
- } else {
- // Backtrack
- furthest = i;
- restore();
- }
- },
- rule: function () {
- var name, value, c = input.charAt(i), important, match;
- save();
-
- if (c === '.' || c === '#' || c === '&') { return }
-
- if (name = $(this.variable) || $(this.property)) {
- if ((name.charAt(0) != '@') && (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j]))) {
- i += match[0].length - 1;
- value = new(tree.Anonymous)(match[1]);
- } else if (name === "font") {
- value = $(this.font);
- } else {
- value = $(this.value);
- }
- important = $(this.important);
-
- if (value && $(this.end)) {
- return new(tree.Rule)(name, value, important, memo);
- } else {
- furthest = i;
- restore();
- }
- }
- },
-
- //
- // An @import directive
- //
- // @import "lib";
- //
- // Depending on our environemnt, importing is done differently:
- // In the browser, it's an XHR request, in Node, it would be a
- // file-system operation. The function used for importing is
- // stored in `import`, which we pass to the Import constructor.
- //
- "import": function () {
- var path, features, index = i;
- if ($(/^@import\s+/) &&
- (path = $(this.entities.quoted) || $(this.entities.url))) {
- features = $(this.mediaFeatures);
- if ($(';')) {
- return new(tree.Import)(path, imports, features, index);
- }
- }
- },
-
- mediaFeature: function () {
- var nodes = [];
-
- do {
- if (e = $(this.entities.keyword)) {
- nodes.push(e);
- } else if ($('(')) {
- p = $(this.property);
- e = $(this.entity);
- if ($(')')) {
- if (p && e) {
- nodes.push(new(tree.Paren)(new(tree.Rule)(p, e, null, i, true)));
- } else if (e) {
- nodes.push(new(tree.Paren)(e));
- } else {
- return null;
- }
- } else { return null }
- }
- } while (e);
-
- if (nodes.length > 0) {
- return new(tree.Expression)(nodes);
- }
- },
-
- mediaFeatures: function () {
- var f, features = [];
- while (f = $(this.mediaFeature)) {
- features.push(f);
- if (! $(',')) { break }
- }
- return features.length > 0 ? features : null;
- },
-
- media: function () {
- var features;
-
- if ($(/^@media/)) {
- features = $(this.mediaFeatures);
-
- if (rules = $(this.block)) {
- return new(tree.Directive)('@media', rules, features);
- }
- }
- },
-
- //
- // A CSS Directive
- //
- // @charset "utf-8";
- //
- directive: function () {
- var name, value, rules, types, e, nodes;
-
- if (input.charAt(i) !== '@') return;
-
- if (value = $(this['import']) || $(this.media)) {
- return value;
- } else if (name = $(/^@page|@keyframes/) || $(/^@(?:-webkit-|-moz-|-o-|-ms-)[a-z0-9-]+/)) {
- types = ($(/^[^{]+/) || '').trim();
- if (rules = $(this.block)) {
- return new(tree.Directive)(name + " " + types, rules);
- }
- } else if (name = $(/^@[-a-z]+/)) {
- if (name === '@font-face') {
- if (rules = $(this.block)) {
- return new(tree.Directive)(name, rules);
- }
- } else if ((value = $(this.entity)) && $(';')) {
- return new(tree.Directive)(name, value);
- }
- }
- },
- font: function () {
- var value = [], expression = [], weight, shorthand, font, e;
-
- while (e = $(this.shorthand) || $(this.entity)) {
- expression.push(e);
- }
- value.push(new(tree.Expression)(expression));
-
- if ($(',')) {
- while (e = $(this.expression)) {
- value.push(e);
- if (! $(',')) { break }
- }
- }
- return new(tree.Value)(value);
- },
-
- //
- // A Value is a comma-delimited list of Expressions
- //
- // font-family: Baskerville, Georgia, serif;
- //
- // In a Rule, a Value represents everything after the `:`,
- // and before the `;`.
- //
- value: function () {
- var e, expressions = [], important;
-
- while (e = $(this.expression)) {
- expressions.push(e);
- if (! $(',')) { break }
- }
-
- if (expressions.length > 0) {
- return new(tree.Value)(expressions);
- }
- },
- important: function () {
- if (input.charAt(i) === '!') {
- return $(/^! *important/);
- }
- },
- sub: function () {
- var e;
-
- if ($('(') && (e = $(this.expression)) && $(')')) {
- return e;
- }
- },
- multiplication: function () {
- var m, a, op, operation;
- if (m = $(this.operand)) {
- while (!peek(/^\/\*/) && (op = ($('/') || $('*'))) && (a = $(this.operand))) {
- operation = new(tree.Operation)(op, [operation || m, a]);
- }
- return operation || m;
- }
- },
- addition: function () {
- var m, a, op, operation;
- if (m = $(this.multiplication)) {
- while ((op = $(/^[-+]\s+/) || (input.charAt(i - 1) != ' ' && ($('+') || $('-')))) &&
- (a = $(this.multiplication))) {
- operation = new(tree.Operation)(op, [operation || m, a]);
- }
- return operation || m;
- }
- },
- conditions: function () {
- var a, b, index = i, condition;
-
- if (a = $(this.condition)) {
- while ($(',') && (b = $(this.condition))) {
- condition = new(tree.Condition)('or', condition || a, b, index);
- }
- return condition || a;
- }
- },
- condition: function () {
- var a, b, c, op, index = i, negate = false;
-
- if ($(/^not/)) { negate = true }
- expect('(');
- if (a = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) {
- if (op = $(/^(?:>=|=<|[<=>])/)) {
- if (b = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) {
- c = new(tree.Condition)(op, a, b, index, negate);
- } else {
- error('expected expression');
- }
- } else {
- c = new(tree.Condition)('=', a, new(tree.Keyword)('true'), index, negate);
- }
- expect(')');
- return $(/^and/) ? new(tree.Condition)('and', c, $(this.condition)) : c;
- }
- },
-
- //
- // An operand is anything that can be part of an operation,
- // such as a Color, or a Variable
- //
- operand: function () {
- var negate, p = input.charAt(i + 1);
-
- if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $('-') }
- var o = $(this.sub) || $(this.entities.dimension) ||
- $(this.entities.color) || $(this.entities.variable) ||
- $(this.entities.call);
- return negate ? new(tree.Operation)('*', [new(tree.Dimension)(-1), o])
- : o;
- },
-
- //
- // Expressions either represent mathematical operations,
- // or white-space delimited Entities.
- //
- // 1px solid black
- // @var * 2
- //
- expression: function () {
- var e, delim, entities = [], d;
-
- while (e = $(this.addition) || $(this.entity)) {
- entities.push(e);
- }
- if (entities.length > 0) {
- return new(tree.Expression)(entities);
- }
- },
- property: function () {
- var name;
-
- if (name = $(/^(\*?-?[-a-z_0-9]+)\s*:/)) {
- return name[1];
- }
- }
- }
- };
-};
-
-if (less.mode === 'browser' || less.mode === 'rhino') {
- //
- // Used by `@import` directives
- //
- less.Parser.importer = function (path, paths, callback, env) {
- if (!/^([a-z]+:)?\//.test(path) && paths.length > 0) {
- path = paths[0] + path;
- }
- // We pass `true` as 3rd argument, to force the reload of the import.
- // This is so we can get the syntax tree as opposed to just the CSS output,
- // as we need this to evaluate the current stylesheet.
- loadStyleSheet({ href: path, title: path, type: env.mime }, function (e) {
- if (e && typeof(env.errback) === "function") {
- env.errback.call(null, path, paths, callback, env);
- } else {
- callback.apply(null, arguments);
- }
- }, true);
- };
-}
-
-(function (tree) {
-
-tree.functions = {
- rgb: function (r, g, b) {
- return this.rgba(r, g, b, 1.0);
- },
- rgba: function (r, g, b, a) {
- var rgb = [r, g, b].map(function (c) { return number(c) }),
- a = number(a);
- return new(tree.Color)(rgb, a);
- },
- hsl: function (h, s, l) {
- return this.hsla(h, s, l, 1.0);
- },
- hsla: function (h, s, l, a) {
- h = (number(h) % 360) / 360;
- s = number(s); l = number(l); a = number(a);
-
- var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
- var m1 = l * 2 - m2;
-
- return this.rgba(hue(h + 1/3) * 255,
- hue(h) * 255,
- hue(h - 1/3) * 255,
- a);
-
- function hue(h) {
- h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
- if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
- else if (h * 2 < 1) return m2;
- else if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
- else return m1;
- }
- },
- hue: function (color) {
- return new(tree.Dimension)(Math.round(color.toHSL().h));
- },
- saturation: function (color) {
- return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%');
- },
- lightness: function (color) {
- return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%');
- },
- alpha: function (color) {
- return new(tree.Dimension)(color.toHSL().a);
- },
- saturate: function (color, amount) {
- var hsl = color.toHSL();
-
- hsl.s += amount.value / 100;
- hsl.s = clamp(hsl.s);
- return hsla(hsl);
- },
- desaturate: function (color, amount) {
- var hsl = color.toHSL();
-
- hsl.s -= amount.value / 100;
- hsl.s = clamp(hsl.s);
- return hsla(hsl);
- },
- lighten: function (color, amount) {
- var hsl = color.toHSL();
-
- hsl.l += amount.value / 100;
- hsl.l = clamp(hsl.l);
- return hsla(hsl);
- },
- darken: function (color, amount) {
- var hsl = color.toHSL();
-
- hsl.l -= amount.value / 100;
- hsl.l = clamp(hsl.l);
- return hsla(hsl);
- },
- fadein: function (color, amount) {
- var hsl = color.toHSL();
-
- hsl.a += amount.value / 100;
- hsl.a = clamp(hsl.a);
- return hsla(hsl);
- },
- fadeout: function (color, amount) {
- var hsl = color.toHSL();
-
- hsl.a -= amount.value / 100;
- hsl.a = clamp(hsl.a);
- return hsla(hsl);
- },
- fade: function (color, amount) {
- var hsl = color.toHSL();
-
- hsl.a = amount.value / 100;
- hsl.a = clamp(hsl.a);
- return hsla(hsl);
- },
- spin: function (color, amount) {
- var hsl = color.toHSL();
- var hue = (hsl.h + amount.value) % 360;
-
- hsl.h = hue < 0 ? 360 + hue : hue;
-
- return hsla(hsl);
- },
- //
- // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
- // http://sass-lang.com
- //
- mix: function (color1, color2, weight) {
- var p = weight.value / 100.0;
- var w = p * 2 - 1;
- var a = color1.toHSL().a - color2.toHSL().a;
-
- var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
- var w2 = 1 - w1;
-
- var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
- color1.rgb[1] * w1 + color2.rgb[1] * w2,
- color1.rgb[2] * w1 + color2.rgb[2] * w2];
-
- var alpha = color1.alpha * p + color2.alpha * (1 - p);
-
- return new(tree.Color)(rgb, alpha);
- },
- greyscale: function (color) {
- return this.desaturate(color, new(tree.Dimension)(100));
- },
- e: function (str) {
- return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str);
- },
- escape: function (str) {
- return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29"));
- },
- '%': function (quoted /* arg, arg, ...*/) {
- var args = Array.prototype.slice.call(arguments, 1),
- str = quoted.value;
-
- for (var i = 0; i < args.length; i++) {
- str = str.replace(/%[sda]/i, function(token) {
- var value = token.match(/s/i) ? args[i].value : args[i].toCSS();
- return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
- });
- }
- str = str.replace(/%%/g, '%');
- return new(tree.Quoted)('"' + str + '"', str);
- },
- round: function (n) {
- return this._math('round', n);
- },
- ceil: function (n) {
- return this._math('ceil', n);
- },
- floor: function (n) {
- return this._math('floor', n);
- },
- _math: function (fn, n) {
- if (n instanceof tree.Dimension) {
- return new(tree.Dimension)(Math[fn](number(n)), n.unit);
- } else if (typeof(n) === 'number') {
- return Math[fn](n);
- } else {
- throw { type: "Argument", message: "argument must be a number" };
- }
- },
- argb: function (color) {
- return new(tree.Anonymous)(color.toARGB());
-
- },
- percentage: function (n) {
- return new(tree.Dimension)(n.value * 100, '%');
- },
- color: function (n) {
- if (n instanceof tree.Quoted) {
- return new(tree.Color)(n.value.slice(1));
- } else {
- throw { type: "Argument", message: "argument must be a string" };
- }
- },
- iscolor: function (n) {
- return this._isa(n, tree.Color);
- },
- isnumber: function (n) {
- return this._isa(n, tree.Dimension);
- },
- isstring: function (n) {
- return this._isa(n, tree.Quoted);
- },
- iskeyword: function (n) {
- return this._isa(n, tree.Keyword);
- },
- isurl: function (n) {
- return this._isa(n, tree.URL);
- },
- ispixel: function (n) {
- return (n instanceof tree.Dimension) && n.unit === 'px' ? tree.True : tree.False;
- },
- ispercentage: function (n) {
- return (n instanceof tree.Dimension) && n.unit === '%' ? tree.True : tree.False;
- },
- isem: function (n) {
- return (n instanceof tree.Dimension) && n.unit === 'em' ? tree.True : tree.False;
- },
- _isa: function (n, Type) {
- return (n instanceof Type) ? tree.True : tree.False;
- }
-};
-
-function hsla(hsla) {
- return tree.functions.hsla(hsla.h, hsla.s, hsla.l, hsla.a);
-}
-
-function number(n) {
- if (n instanceof tree.Dimension) {
- return parseFloat(n.unit == '%' ? n.value / 100 : n.value);
- } else if (typeof(n) === 'number') {
- return n;
- } else {
- throw {
- error: "RuntimeError",
- message: "color functions take numbers as parameters"
- };
- }
-}
-
-function clamp(val) {
- return Math.min(1, Math.max(0, val));
-}
-
-})(require('./tree'));
-(function (tree) {
- tree.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',
- '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'
- };
-})(require('./tree'));
-(function (tree) {
-
-tree.Alpha = function (val) {
- this.value = val;
-};
-tree.Alpha.prototype = {
- toCSS: function () {
- return "alpha(opacity=" +
- (this.value.toCSS ? this.value.toCSS() : this.value) + ")";
- },
- eval: function (env) {
- if (this.value.eval) { this.value = this.value.eval(env) }
- return this;
- }
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.Anonymous = function (string) {
- this.value = string.value || string;
-};
-tree.Anonymous.prototype = {
- toCSS: function () {
- return this.value;
- },
- eval: function () { return this }
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.Assignment = function (key, val) {
- this.key = key;
- this.value = val;
-};
-tree.Assignment.prototype = {
- toCSS: function () {
- return this.key + '=' + (this.value.toCSS ? this.value.toCSS() : this.value);
- },
- eval: function (env) {
- if (this.value.eval) { this.value = this.value.eval(env) }
- return this;
- }
-};
-
-})(require('../tree'));(function (tree) {
-
-//
-// A function call node.
-//
-tree.Call = function (name, args, index, filename) {
- this.name = name;
- this.args = args;
- this.index = index;
- this.filename = filename;
-};
-tree.Call.prototype = {
- //
- // When evaluating a function call,
- // we either find the function in `tree.functions` [1],
- // in which case we call it, passing the evaluated arguments,
- // or we simply print it out as it appeared originally [2].
- //
- // The *functions.js* file contains the built-in functions.
- //
- // The reason why we evaluate the arguments, is in the case where
- // we try to pass a variable to a function, like: `saturate(@color)`.
- // The function should receive the value, not the variable.
- //
- eval: function (env) {
- var args = this.args.map(function (a) { return a.eval(env) });
-
- if (this.name in tree.functions) { // 1.
- try {
- return tree.functions[this.name].apply(tree.functions, args);
- } catch (e) {
- throw { type: e.type || "Runtime",
- message: "error evaluating function `" + this.name + "`" +
- (e.message ? ': ' + e.message : ''),
- index: this.index, filename: this.filename };
- }
- } else { // 2.
- return new(tree.Anonymous)(this.name +
- "(" + args.map(function (a) { return a.toCSS() }).join(', ') + ")");
- }
- },
-
- toCSS: function (env) {
- return this.eval(env).toCSS();
- }
-};
-
-})(require('../tree'));
-(function (tree) {
-//
-// RGB Colors - #ff0014, #eee
-//
-tree.Color = function (rgb, a) {
- //
- // 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) {
- return parseInt(c, 16);
- });
- } else {
- this.rgb = rgb.split('').map(function (c) {
- return parseInt(c + c, 16);
- });
- }
- this.alpha = typeof(a) === 'number' ? a : 1;
-};
-tree.Color.prototype = {
- eval: function () { return this },
-
- //
- // If we have some transparency, the only way to represent it
- // is via `rgba`. Otherwise, we use the hex representation,
- // which has better compatibility with older browsers.
- // Values are capped between `0` and `255`, rounded and zero-padded.
- //
- toCSS: function () {
- if (this.alpha < 1.0) {
- return "rgba(" + this.rgb.map(function (c) {
- return Math.round(c);
- }).concat(this.alpha).join(', ') + ")";
- } else {
- return '#' + this.rgb.map(function (i) {
- i = Math.round(i);
- i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
- return i.length === 1 ? '0' + i : i;
- }).join('');
- }
- },
-
- //
- // 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 (op, other) {
- var result = [];
-
- if (! (other instanceof tree.Color)) {
- other = other.toColor();
- }
-
- for (var c = 0; c < 3; c++) {
- result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
- }
- return new(tree.Color)(result, this.alpha + other.alpha);
- },
-
- 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, s, l = (max + min) / 2, 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 };
- },
- toARGB: function () {
- var argb = [Math.round(this.alpha * 255)].concat(this.rgb);
- return '#' + argb.map(function (i) {
- i = Math.round(i);
- i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
- return i.length === 1 ? '0' + i : i;
- }).join('');
- }
-};
-
-
-})(require('../tree'));
-(function (tree) {
-
-tree.Comment = function (value, silent) {
- this.value = value;
- this.silent = !!silent;
-};
-tree.Comment.prototype = {
- toCSS: function (env) {
- return env.compress ? '' : this.value;
- },
- eval: function () { return this }
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.Condition = function (op, l, r, i, negate) {
- this.op = op.trim();
- this.lvalue = l;
- this.rvalue = r;
- this.index = i;
- this.negate = negate;
-};
-tree.Condition.prototype.eval = function (env) {
- var a = this.lvalue.eval(env),
- b = this.rvalue.eval(env);
-
- var i = this.index, result;
-
- var result = (function (op) {
- switch (op) {
- case 'and':
- return a && b;
- case 'or':
- return a || b;
- default:
- if (a.compare) {
- result = a.compare(b);
- } else if (b.compare) {
- result = b.compare(a);
- } else {
- throw { type: "Type",
- message: "Unable to perform comparison",
- index: i };
- }
- switch (result) {
- case -1: return op === '<' || op === '=<';
- case 0: return op === '=' || op === '>=' || op === '=<';
- case 1: return op === '>' || op === '>=';
- }
- }
- })(this.op);
- return this.negate ? !result : result;
-};
-
-})(require('../tree'));
-(function (tree) {
-
-//
-// A number with a unit
-//
-tree.Dimension = function (value, unit) {
- this.value = parseFloat(value);
- this.unit = unit || null;
-};
-
-tree.Dimension.prototype = {
- eval: function () { return this },
- toColor: function () {
- return new(tree.Color)([this.value, this.value, this.value]);
- },
- toCSS: function () {
- var css = this.value + this.unit;
- return css;
- },
-
- // In an operation between two Dimensions,
- // we default to the first Dimension's unit,
- // so `1px + 2em` will yield `3px`.
- // In the future, we could implement some unit
- // conversions such that `100cm + 10mm` would yield
- // `101cm`.
- operate: function (op, other) {
- return new(tree.Dimension)
- (tree.operate(op, this.value, other.value),
- this.unit || other.unit);
- },
-
- // TODO: Perform unit conversion before comparing
- compare: function (other) {
- if (other instanceof tree.Dimension) {
- if (other.value > this.value) {
- return -1;
- } else if (other.value < this.value) {
- return 1;
- } else {
- return 0;
- }
- } else {
- return -1;
- }
- }
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.Directive = function (name, value, features) {
- this.name = name;
- this.features = features && new(tree.Value)(features);
-
- if (Array.isArray(value)) {
- this.ruleset = new(tree.Ruleset)([], value);
- this.ruleset.allowImports = true;
- } else {
- this.value = value;
- }
-};
-tree.Directive.prototype = {
- toCSS: function (ctx, env) {
- var features = this.features ? ' ' + this.features.toCSS(env) : '';
-
- if (this.ruleset) {
- this.ruleset.root = true;
- return this.name + features + (env.compress ? '{' : ' {\n ') +
- this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n ') +
- (env.compress ? '}': '\n}\n');
- } else {
- return this.name + ' ' + this.value.toCSS() + ';\n';
- }
- },
- eval: function (env) {
- this.features = this.features && this.features.eval(env);
- env.frames.unshift(this);
- this.ruleset = this.ruleset && this.ruleset.eval(env);
- env.frames.shift();
- return this;
- },
- variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
- find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
- rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.Element = function (combinator, value, index) {
- this.combinator = combinator instanceof tree.Combinator ?
- combinator : new(tree.Combinator)(combinator);
-
- if (typeof(value) === 'string') {
- this.value = value.trim();
- } else if (value) {
- this.value = value;
- } else {
- this.value = "";
- }
- this.index = index;
-};
-tree.Element.prototype.eval = function (env) {
- return new(tree.Element)(this.combinator,
- this.value.eval ? this.value.eval(env) : this.value,
- this.index);
-};
-tree.Element.prototype.toCSS = function (env) {
- return this.combinator.toCSS(env || {}) + (this.value.toCSS ? this.value.toCSS(env) : this.value);
-};
-
-tree.Combinator = function (value) {
- if (value === ' ') {
- this.value = ' ';
- } else if (value === '& ') {
- this.value = '& ';
- } else {
- this.value = value ? value.trim() : "";
- }
-};
-tree.Combinator.prototype.toCSS = function (env) {
- return {
- '' : '',
- ' ' : ' ',
- '&' : '',
- '& ' : ' ',
- ':' : ' :',
- '::': '::',
- '+' : env.compress ? '+' : ' + ',
- '~' : env.compress ? '~' : ' ~ ',
- '>' : env.compress ? '>' : ' > '
- }[this.value];
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.Expression = function (value) { this.value = value };
-tree.Expression.prototype = {
- eval: function (env) {
- if (this.value.length > 1) {
- return new(tree.Expression)(this.value.map(function (e) {
- return e.eval(env);
- }));
- } else if (this.value.length === 1) {
- return this.value[0].eval(env);
- } else {
- return this;
- }
- },
- toCSS: function (env) {
- return this.value.map(function (e) {
- return e.toCSS ? e.toCSS(env) : '';
- }).join(' ');
- }
-};
-
-})(require('../tree'));
-(function (tree) {
-//
-// CSS @import node
-//
-// The general strategy here is that we don't want to wait
-// for the parsing to be completed, before we start importing
-// the file. That's because in the context of a browser,
-// most of the time will be spent waiting for the server to respond.
-//
-// On creation, we push the import path to our import queue, though
-// `import,push`, we also pass it a callback, which it'll call once
-// the file has been fetched, and parsed.
-//
-tree.Import = function (path, imports, features, index) {
- var that = this;
-
- this.index = index;
- this._path = path;
- this.features = features && new(tree.Value)(features);
-
- // The '.less' extension is optional
- if (path instanceof tree.Quoted) {
- this.path = /\.(le?|c)ss(\?.*)?$/.test(path.value) ? path.value : path.value + '.less';
- } else {
- this.path = path.value.value || path.value;
- }
-
- this.css = /css(\?.*)?$/.test(this.path);
-
- // Only pre-compile .less files
- if (! this.css) {
- imports.push(this.path, function (e, root) {
- if (e) { e.index = index }
- that.root = root || new(tree.Ruleset)([], []);
- });
- }
-};
-
-//
-// The actual import node doesn't return anything, when converted to CSS.
-// The reason is that it's used at the evaluation stage, so that the rules
-// it imports can be treated like any other rules.
-//
-// In `eval`, we make sure all Import nodes get evaluated, recursively, so
-// we end up with a flat structure, which can easily be imported in the parent
-// ruleset.
-//
-tree.Import.prototype = {
- toCSS: function (env) {
- var features = this.features ? ' ' + this.features.toCSS(env) : '';
-
- if (this.css) {
- return "@import " + this._path.toCSS() + features + ';\n';
- } else {
- return "";
- }
- },
- eval: function (env) {
- var ruleset, features = this.features && this.features.eval(env);
-
- if (this.css) {
- return this;
- } else {
- ruleset = new(tree.Ruleset)([], this.root.rules.slice(0));
-
- for (var i = 0; i < ruleset.rules.length; i++) {
- if (ruleset.rules[i] instanceof tree.Import) {
- Array.prototype
- .splice
- .apply(ruleset.rules,
- [i, 1].concat(ruleset.rules[i].eval(env)));
- }
- }
- return this.features ? new(tree.Directive)('@media', ruleset.rules, this.features.value) : ruleset.rules;
- }
- }
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.JavaScript = function (string, index, escaped) {
- this.escaped = escaped;
- this.expression = string;
- this.index = index;
-};
-tree.JavaScript.prototype = {
- eval: function (env) {
- var result,
- that = this,
- context = {};
-
- var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
- return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env));
- });
-
- try {
- expression = new(Function)('return (' + expression + ')');
- } catch (e) {
- throw { message: "JavaScript evaluation error: `" + expression + "`" ,
- index: this.index };
- }
-
- for (var k in env.frames[0].variables()) {
- context[k.slice(1)] = {
- value: env.frames[0].variables()[k].value,
- toJS: function () {
- return this.value.eval(env).toCSS();
- }
- };
- }
-
- try {
- result = expression.call(context);
- } catch (e) {
- throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
- index: this.index };
- }
- if (typeof(result) === 'string') {
- return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index);
- } else if (Array.isArray(result)) {
- return new(tree.Anonymous)(result.join(', '));
- } else {
- return new(tree.Anonymous)(result);
- }
- }
-};
-
-})(require('../tree'));
-
-(function (tree) {
-
-tree.Keyword = function (value) { this.value = value };
-tree.Keyword.prototype = {
- eval: function () { return this },
- toCSS: function () { return this.value },
- compare: function (other) {
- if (other instanceof tree.Keyword) {
- return other.value === this.value ? 0 : 1;
- } else {
- return -1;
- }
- }
-};
-
-tree.True = new(tree.Keyword)('true');
-tree.False = new(tree.Keyword)('false');
-
-})(require('../tree'));
-(function (tree) {
-
-tree.mixin = {};
-tree.mixin.Call = function (elements, args, index, filename, important) {
- this.selector = new(tree.Selector)(elements);
- this.arguments = args;
- this.index = index;
- this.filename = filename;
- this.important = important;
-};
-tree.mixin.Call.prototype = {
- eval: function (env) {
- var mixins, args, rules = [], match = false;
-
- for (var i = 0; i < env.frames.length; i++) {
- if ((mixins = env.frames[i].find(this.selector)).length > 0) {
- args = this.arguments && this.arguments.map(function (a) { return a.eval(env) });
- for (var m = 0; m < mixins.length; m++) {
- if (mixins[m].match(args, env)) {
- try {
- Array.prototype.push.apply(
- rules, mixins[m].eval(env, this.arguments, this.important).rules);
- match = true;
- } catch (e) {
- throw { message: e.message, index: e.index, filename: this.filename, stack: e.stack, call: this.index };
- }
- }
- }
- if (match) {
- return rules;
- } else {
- throw { type: 'Runtime',
- message: 'No matching definition was found for `' +
- this.selector.toCSS().trim() + '(' +
- this.arguments.map(function (a) {
- return a.toCSS();
- }).join(', ') + ")`",
- index: this.index, filename: this.filename };
- }
- }
- }
- throw { type: 'Name',
- message: this.selector.toCSS().trim() + " is undefined",
- index: this.index, filename: this.filename };
- }
-};
-
-tree.mixin.Definition = function (name, params, rules, condition) {
- this.name = name;
- this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
- this.params = params;
- this.condition = condition;
- this.arity = params.length;
- this.rules = rules;
- this._lookups = {};
- this.required = params.reduce(function (count, p) {
- if (!p.name || (p.name && !p.value)) { return count + 1 }
- else { return count }
- }, 0);
- this.parent = tree.Ruleset.prototype;
- this.frames = [];
-};
-tree.mixin.Definition.prototype = {
- toCSS: function () { return "" },
- variable: function (name) { return this.parent.variable.call(this, name) },
- variables: function () { return this.parent.variables.call(this) },
- find: function () { return this.parent.find.apply(this, arguments) },
- rulesets: function () { return this.parent.rulesets.apply(this) },
-
- evalParams: function (env, args) {
- var frame = new(tree.Ruleset)(null, []);
-
- for (var i = 0, val; i < this.params.length; i++) {
- if (this.params[i].name) {
- if (val = (args && args[i]) || this.params[i].value) {
- frame.rules.unshift(new(tree.Rule)(this.params[i].name, val.eval(env)));
- } else {
- throw { type: 'Runtime', message: "wrong number of arguments for " + this.name +
- ' (' + args.length + ' for ' + this.arity + ')' };
- }
- }
- }
- return frame;
- },
- eval: function (env, args, important) {
- var frame = this.evalParams(env, args), context, _arguments = [], rules;
-
- for (var i = 0; i < Math.max(this.params.length, args && args.length); i++) {
- _arguments.push(args[i] || this.params[i].value);
- }
- frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
-
- rules = important ?
- this.rules.map(function (r) {
- return new(tree.Rule)(r.name, r.value, '!important', r.index);
- }) : this.rules.slice(0);
-
- return new(tree.Ruleset)(null, rules).eval({
- frames: [this, frame].concat(this.frames, env.frames)
- });
- },
- match: function (args, env) {
- var argsLength = (args && args.length) || 0, len, frame;
-
- if (argsLength < this.required) { return false }
- if ((this.required > 0) && (argsLength > this.params.length)) { return false }
- if (this.condition && !this.condition.eval({
- frames: [this.evalParams(env, args)].concat(env.frames)
- })) { return false }
-
- len = Math.min(argsLength, this.arity);
-
- for (var i = 0; i < len; i++) {
- if (!this.params[i].name) {
- if (args[i].eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
- return false;
- }
- }
- }
- return true;
- }
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.Operation = function (op, operands) {
- this.op = op.trim();
- this.operands = operands;
-};
-tree.Operation.prototype.eval = function (env) {
- var a = this.operands[0].eval(env),
- b = this.operands[1].eval(env),
- temp;
-
- if (a instanceof tree.Dimension && b instanceof tree.Color) {
- if (this.op === '*' || this.op === '+') {
- temp = b, b = a, a = temp;
- } else {
- throw { name: "OperationError",
- message: "Can't substract or divide a color from a number" };
- }
- }
- return a.operate(this.op, b);
-};
-
-tree.operate = function (op, a, b) {
- switch (op) {
- case '+': return a + b;
- case '-': return a - b;
- case '*': return a * b;
- case '/': return a / b;
- }
-};
-
-})(require('../tree'));
-
-(function (tree) {
-
-tree.Paren = function (node) {
- this.value = node;
-};
-tree.Paren.prototype = {
- toCSS: function (env) {
- return '(' + this.value.toCSS(env) + ')';
- },
- eval: function (env) {
- return new(tree.Paren)(this.value.eval(env));
- }
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.Quoted = function (str, content, escaped, i) {
- this.escaped = escaped;
- this.value = content || '';
- this.quote = str.charAt(0);
- this.index = i;
-};
-tree.Quoted.prototype = {
- toCSS: function () {
- if (this.escaped) {
- return this.value;
- } else {
- return this.quote + this.value + this.quote;
- }
- },
- eval: function (env) {
- var that = this;
- var value = this.value.replace(/`([^`]+)`/g, function (_, exp) {
- return new(tree.JavaScript)(exp, that.index, true).eval(env).value;
- }).replace(/@\{([\w-]+)\}/g, function (_, name) {
- var v = new(tree.Variable)('@' + name, that.index).eval(env);
- return ('value' in v) ? v.value : v.toCSS();
- });
- return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index);
- }
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.Rule = function (name, value, important, index, inline) {
- this.name = name;
- this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
- this.important = important ? ' ' + important.trim() : '';
- this.index = index;
- this.inline = inline || false;
-
- if (name.charAt(0) === '@') {
- this.variable = true;
- } else { this.variable = false }
-};
-tree.Rule.prototype.toCSS = function (env) {
- if (this.variable) { return "" }
- else {
- return this.name + (env.compress ? ':' : ': ') +
- this.value.toCSS(env) +
- this.important + (this.inline ? "" : ";");
- }
-};
-
-tree.Rule.prototype.eval = function (context) {
- return new(tree.Rule)(this.name,
- this.value.eval(context),
- this.important,
- this.index, this.inline);
-};
-
-tree.Shorthand = function (a, b) {
- this.a = a;
- this.b = b;
-};
-
-tree.Shorthand.prototype = {
- toCSS: function (env) {
- return this.a.toCSS(env) + "/" + this.b.toCSS(env);
- },
- eval: function () { return this }
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.Ruleset = function (selectors, rules) {
- this.selectors = selectors;
- this.rules = rules;
- this._lookups = {};
-};
-tree.Ruleset.prototype = {
- eval: function (env) {
- var selectors = this.selectors && this.selectors.map(function (s) { return s.eval(env) });
- var ruleset = new(tree.Ruleset)(selectors, this.rules.slice(0));
-
- ruleset.root = this.root;
- ruleset.allowImports = this.allowImports;
-
- // push the current ruleset to the frames stack
- env.frames.unshift(ruleset);
-
- // Evaluate imports
- if (ruleset.root || ruleset.allowImports) {
- for (var i = 0; i < ruleset.rules.length; i++) {
- if (ruleset.rules[i] instanceof tree.Import) {
- Array.prototype.splice
- .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
- }
- }
- }
-
- // Store the frames around mixin definitions,
- // so they can be evaluated like closures when the time comes.
- for (var i = 0; i < ruleset.rules.length; i++) {
- if (ruleset.rules[i] instanceof tree.mixin.Definition) {
- ruleset.rules[i].frames = env.frames.slice(0);
- }
- }
-
- // Evaluate mixin calls.
- for (var i = 0; i < ruleset.rules.length; i++) {
- if (ruleset.rules[i] instanceof tree.mixin.Call) {
- Array.prototype.splice
- .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
- }
- }
-
- // Evaluate everything else
- for (var i = 0, rule; i < ruleset.rules.length; i++) {
- rule = ruleset.rules[i];
-
- if (! (rule instanceof tree.mixin.Definition)) {
- ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
- }
- }
-
- // Pop the stack
- env.frames.shift();
-
- return ruleset;
- },
- match: function (args) {
- return !args || args.length === 0;
- },
- variables: function () {
- if (this._variables) { return this._variables }
- else {
- return this._variables = this.rules.reduce(function (hash, r) {
- if (r instanceof tree.Rule && r.variable === true) {
- hash[r.name] = r;
- }
- return hash;
- }, {});
- }
- },
- variable: function (name) {
- return this.variables()[name];
- },
- rulesets: function () {
- if (this._rulesets) { return this._rulesets }
- else {
- return this._rulesets = this.rules.filter(function (r) {
- return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
- });
- }
- },
- find: function (selector, self) {
- self = self || this;
- var rules = [], rule, match,
- key = selector.toCSS();
-
- if (key in this._lookups) { return this._lookups[key] }
-
- this.rulesets().forEach(function (rule) {
- if (rule !== self) {
- for (var j = 0; j < rule.selectors.length; j++) {
- if (match = selector.match(rule.selectors[j])) {
- if (selector.elements.length > rule.selectors[j].elements.length) {
- Array.prototype.push.apply(rules, rule.find(
- new(tree.Selector)(selector.elements.slice(1)), self));
- } else {
- rules.push(rule);
- }
- break;
- }
- }
- }
- });
- return this._lookups[key] = rules;
- },
- //
- // Entry point for code generation
- //
- // `context` holds an array of arrays.
- //
- toCSS: function (context, env) {
- var css = [], // The CSS output
- rules = [], // node.Rule instances
- rulesets = [], // node.Ruleset instances
- paths = [], // Current selectors
- selector, // The fully rendered selector
- rule;
-
- if (! this.root) {
- if (context.length === 0) {
- paths = this.selectors.map(function (s) { return [s] });
- } else {
- this.joinSelectors(paths, context, this.selectors);
- }
- }
-
- // Compile rules and rulesets
- for (var i = 0; i < this.rules.length; i++) {
- rule = this.rules[i];
-
- if (rule.rules || (rule instanceof tree.Directive)) {
- rulesets.push(rule.toCSS(paths, env));
- } else if (rule instanceof tree.Comment) {
- if (!rule.silent) {
- if (this.root) {
- rulesets.push(rule.toCSS(env));
- } else {
- rules.push(rule.toCSS(env));
- }
- }
- } else {
- if (rule.toCSS && !rule.variable) {
- rules.push(rule.toCSS(env));
- } else if (rule.value && !rule.variable) {
- rules.push(rule.value.toString());
- }
- }
- }
-
- rulesets = rulesets.join('');
-
- // If this is the root node, we don't render
- // a selector, or {}.
- // Otherwise, only output if this ruleset has rules.
- if (this.root) {
- css.push(rules.join(env.compress ? '' : '\n'));
- } else {
- if (rules.length > 0) {
- selector = paths.map(function (p) {
- return p.map(function (s) {
- return s.toCSS(env);
- }).join('').trim();
- }).join( env.compress ? ',' : ',\n');
-
- css.push(selector,
- (env.compress ? '{' : ' {\n ') +
- rules.join(env.compress ? '' : '\n ') +
- (env.compress ? '}' : '\n}\n'));
- }
- }
- css.push(rulesets);
-
- return css.join('') + (env.compress ? '\n' : '');
- },
-
- joinSelectors: function (paths, context, selectors) {
- for (var s = 0; s < selectors.length; s++) {
- this.joinSelector(paths, context, selectors[s]);
- }
- },
-
- joinSelector: function (paths, context, selector) {
- var before = [], after = [], beforeElements = [],
- afterElements = [], hasParentSelector = false, el;
-
- for (var i = 0; i < selector.elements.length; i++) {
- el = selector.elements[i];
- if (el.combinator.value.charAt(0) === '&') {
- hasParentSelector = true;
- }
- if (hasParentSelector) afterElements.push(el);
- else beforeElements.push(el);
- }
-
- if (! hasParentSelector) {
- afterElements = beforeElements;
- beforeElements = [];
- }
-
- if (beforeElements.length > 0) {
- before.push(new(tree.Selector)(beforeElements));
- }
-
- if (afterElements.length > 0) {
- after.push(new(tree.Selector)(afterElements));
- }
-
- for (var c = 0; c < context.length; c++) {
- paths.push(before.concat(context[c]).concat(after));
- }
- }
-};
-})(require('../tree'));
-(function (tree) {
-
-tree.Selector = function (elements) {
- this.elements = elements;
- if (this.elements[0].combinator.value === "") {
- this.elements[0].combinator.value = ' ';
- }
-};
-tree.Selector.prototype.match = function (other) {
- var len = this.elements.length,
- olen = other.elements.length,
- max = Math.min(len, olen);
-
- if (len < olen) {
- return false;
- } else {
- for (var i = 0; i < max; i++) {
- if (this.elements[i].value !== other.elements[i].value) {
- return false;
- }
- }
- }
- return true;
-};
-tree.Selector.prototype.eval = function (env) {
- return new(tree.Selector)(this.elements.map(function (e) {
- return e.eval(env);
- }));
-};
-tree.Selector.prototype.toCSS = function (env) {
- if (this._css) { return this._css }
-
- return this._css = this.elements.map(function (e) {
- if (typeof(e) === 'string') {
- return ' ' + e.trim();
- } else {
- return e.toCSS(env);
- }
- }).join('');
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.URL = function (val, paths) {
- if (val.data) {
- this.attrs = val;
- } else {
- // Add the base path if the URL is relative and we are in the browser
- if (typeof(window) !== 'undefined' && !/^(?:https?:\/\/|file:\/\/|data:|\/)/.test(val.value) && paths.length > 0) {
- val.value = paths[0] + (val.value.charAt(0) === '/' ? val.value.slice(1) : val.value);
- }
- this.value = val;
- this.paths = paths;
- }
-};
-tree.URL.prototype = {
- toCSS: function () {
- return "url(" + (this.attrs ? 'data:' + this.attrs.mime + this.attrs.charset + this.attrs.base64 + this.attrs.data
- : this.value.toCSS()) + ")";
- },
- eval: function (ctx) {
- return this.attrs ? this : new(tree.URL)(this.value.eval(ctx), this.paths);
- }
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.Value = function (value) {
- this.value = value;
- this.is = 'value';
-};
-tree.Value.prototype = {
- eval: function (env) {
- if (this.value.length === 1) {
- return this.value[0].eval(env);
- } else {
- return new(tree.Value)(this.value.map(function (v) {
- return v.eval(env);
- }));
- }
- },
- toCSS: function (env) {
- return this.value.map(function (e) {
- return e.toCSS(env);
- }).join(env.compress ? ',' : ', ');
- }
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.Variable = function (name, index, file) { this.name = name, this.index = index, this.file = file };
-tree.Variable.prototype = {
- eval: function (env) {
- var variable, v, name = this.name;
-
- if (name.indexOf('@@') == 0) {
- name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
- }
-
- if (variable = tree.find(env.frames, function (frame) {
- if (v = frame.variable(name)) {
- return v.value.eval(env);
- }
- })) { return variable }
- else {
- throw { type: 'Name',
- message: "variable " + name + " is undefined",
- filename: this.file,
- index: this.index };
- }
- }
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.find = function (obj, fun) {
- for (var i = 0, r; i < obj.length; i++) {
- if (r = fun.call(obj, obj[i])) { return r }
- }
- return null;
-};
-tree.jsify = function (obj) {
- if (Array.isArray(obj.value) && (obj.value.length > 1)) {
- return '[' + obj.value.map(function (v) { return v.toCSS(false) }).join(', ') + ']';
- } else {
- return obj.toCSS(false);
- }
-};
-
-})(require('./tree'));
-//
-// browser.js - client-side engine
-//
-
-var isFileProtocol = (location.protocol === 'file:' ||
- location.protocol === 'chrome:' ||
- location.protocol === 'chrome-extension:' ||
- location.protocol === 'resource:');
-
-less.env = less.env || (location.hostname == '127.0.0.1' ||
- location.hostname == '0.0.0.0' ||
- location.hostname == 'localhost' ||
- location.port.length > 0 ||
- isFileProtocol ? 'development'
- : 'production');
-
-// 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.
-//
-less.async = false;
-
-// Interval between watch polls
-less.poll = less.poll || (isFileProtocol ? 1000 : 1500);
-
-//
-// Watch mode
-//
-less.watch = function () { return this.watchMode = true };
-less.unwatch = function () { return this.watchMode = false };
-
-if (less.env === 'development') {
- less.optimization = 0;
-
- if (/!watch/.test(location.hash)) {
- less.watch();
- }
- less.watchTimer = setInterval(function () {
- if (less.watchMode) {
- loadStyleSheets(function (e, root, _, sheet, env) {
- if (root) {
- createCSS(root.toCSS(), sheet, env.lastModified);
- }
- });
- }
- }, less.poll);
-} else {
- less.optimization = 3;
-}
-
-var cache;
-
-try {
- cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage;
-} catch (_) {
- cache = null;
-}
-
-//
-// Get all tags with the 'rel' attribute set to "stylesheet/less"
-//
-var links = document.getElementsByTagName('link');
-var typePattern = /^text\/(x-)?less$/;
-
-less.sheets = [];
-
-for (var i = 0; i < links.length; i++) {
- if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
- (links[i].type.match(typePattern)))) {
- less.sheets.push(links[i]);
- }
-}
-
-
-less.refresh = function (reload) {
- var startTime, endTime;
- startTime = endTime = new(Date);
-
- loadStyleSheets(function (e, root, _, sheet, env) {
- if (env.local) {
- log("loading " + sheet.href + " from cache.");
- } else {
- log("parsed " + sheet.href + " successfully.");
- createCSS(root.toCSS(), sheet, env.lastModified);
- }
- log("css for " + sheet.href + " generated in " + (new(Date) - endTime) + 'ms');
- (env.remaining === 0) && log("css generated in " + (new(Date) - startTime) + 'ms');
- endTime = new(Date);
- }, reload);
-
- loadStyles();
-};
-less.refreshStyles = loadStyles;
-
-less.refresh(less.env === 'development');
-
-function loadStyles() {
- var styles = document.getElementsByTagName('style');
- for (var i = 0; i < styles.length; i++) {
- if (styles[i].type.match(typePattern)) {
- new(less.Parser)().parse(styles[i].innerHTML || '', function (e, tree) {
- var css = tree.toCSS();
- var style = styles[i];
- style.type = 'text/css';
- if (style.styleSheet) {
- style.styleSheet.cssText = css;
- } else {
- style.innerHTML = css;
- }
- });
- }
- }
-}
-
-function loadStyleSheets(callback, reload) {
- for (var i = 0; i < less.sheets.length; i++) {
- loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1));
- }
-}
-
-function loadStyleSheet(sheet, callback, reload, remaining) {
- var url = window.location.href.replace(/[#?].*$/, '');
- var href = sheet.href.replace(/\?.*$/, '');
- var css = cache && cache.getItem(href);
- var timestamp = cache && cache.getItem(href + ':timestamp');
- var styles = { css: css, timestamp: timestamp };
-
- // Stylesheets in IE don't always return the full path
- if (! /^(https?|file):/.test(href)) {
- if (href.charAt(0) == "/") {
- href = window.location.protocol + "//" + window.location.host + href;
- } else {
- href = url.slice(0, url.lastIndexOf('/') + 1) + href;
- }
- }
- var filename = href.match(/([^\/]+)$/)[1];
-
- xhr(sheet.href, sheet.type, function (data, lastModified) {
- if (!reload && styles && lastModified &&
- (new(Date)(lastModified).valueOf() ===
- new(Date)(styles.timestamp).valueOf())) {
- // Use local copy
- createCSS(styles.css, sheet);
- callback(null, null, data, sheet, { local: true, remaining: remaining });
- } else {
- // Use remote copy (re-parse)
- try {
- new(less.Parser)({
- optimization: less.optimization,
- paths: [href.replace(/[\w\.-]+$/, '')],
- mime: sheet.type,
- filename: filename
- }).parse(data, function (e, root) {
- if (e) { return error(e, href) }
- try {
- callback(e, root, data, sheet, { local: false, lastModified: lastModified, remaining: remaining });
- removeNode(document.getElementById('less-error-message:' + extractId(href)));
- } catch (e) {
- error(e, href);
- }
- });
- } catch (e) {
- error(e, href);
- }
- }
- }, function (status, url) {
- throw new(Error)("Couldn't load " + url + " (" + status + ")");
- });
-}
-
-function extractId(href) {
- return href.replace(/^[a-z]+:\/\/?[^\/]+/, '' ) // Remove protocol & domain
- .replace(/^\//, '' ) // Remove root /
- .replace(/\?.*$/, '' ) // Remove query
- .replace(/\.[^\.\/]+$/, '' ) // Remove file extension
- .replace(/[^\.\w-]+/g, '-') // Replace illegal characters
- .replace(/\./g, ':'); // Replace dots with colons(for valid id)
-}
-
-function createCSS(styles, sheet, lastModified) {
- var css;
-
- // Strip the query-string
- var href = sheet.href ? sheet.href.replace(/\?.*$/, '') : '';
-
- // If there is no title set, use the filename, minus the extension
- var id = 'less:' + (sheet.title || extractId(href));
-
- // If the stylesheet doesn't exist, create a new node
- if ((css = document.getElementById(id)) === null) {
- css = document.createElement('style');
- css.type = 'text/css';
- css.media = sheet.media || 'screen';
- css.id = id;
- document.getElementsByTagName('head')[0].appendChild(css);
- }
-
- if (css.styleSheet) { // IE
- try {
- css.styleSheet.cssText = styles;
- } catch (e) {
- throw new(Error)("Couldn't reassign styleSheet.cssText.");
- }
- } else {
- (function (node) {
- if (css.childNodes.length > 0) {
- if (css.firstChild.nodeValue !== node.nodeValue) {
- css.replaceChild(node, css.firstChild);
- }
- } else {
- css.appendChild(node);
- }
- })(document.createTextNode(styles));
- }
-
- // Don't update the local store if the file wasn't modified
- if (lastModified && cache) {
- log('saving ' + href + ' to cache.');
- cache.setItem(href, styles);
- cache.setItem(href + ':timestamp', lastModified);
- }
-}
-
-function xhr(url, type, callback, errback) {
- var xhr = getXMLHttpRequest();
- var async = isFileProtocol ? false : less.async;
-
- if (typeof(xhr.overrideMimeType) === 'function') {
- xhr.overrideMimeType('text/css');
- }
- xhr.open('GET', url, async);
- xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
- xhr.send(null);
-
- if (isFileProtocol) {
- if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) {
- callback(xhr.responseText);
- } else {
- errback(xhr.status, url);
- }
- } else if (async) {
- xhr.onreadystatechange = function () {
- if (xhr.readyState == 4) {
- handleResponse(xhr, callback, errback);
- }
- };
- } else {
- handleResponse(xhr, callback, errback);
- }
-
- function handleResponse(xhr, callback, errback) {
- if (xhr.status >= 200 && xhr.status < 300) {
- callback(xhr.responseText,
- xhr.getResponseHeader("Last-Modified"));
- } else if (typeof(errback) === 'function') {
- errback(xhr.status, url);
- }
- }
-}
-
-function getXMLHttpRequest() {
- if (window.XMLHttpRequest) {
- return new(XMLHttpRequest);
- } else {
- try {
- return new(ActiveXObject)("MSXML2.XMLHTTP.3.0");
- } catch (e) {
- log("browser doesn't support AJAX.");
- return null;
- }
- }
-}
-
-function removeNode(node) {
- return node && node.parentNode.removeChild(node);
-}
-
-function log(str) {
- if (less.env == 'development' && typeof(console) !== "undefined") { console.log('less: ' + str) }
-}
-
-function error(e, href) {
- var id = 'less-error-message:' + extractId(href);
- var template = '{content}';
- var elem = document.createElement('div'), timer, content, error = [];
- var filename = e.filename || href;
-
- elem.id = id;
- elem.className = "less-error-message";
-
- content = '' + (e.message || 'There is an error in your .less file') +
- '
' + 'in ' + filename + " ";
-
- var errorline = function (e, i, classname) {
- if (e.extract[i]) {
- error.push(template.replace(/\{line\}/, parseInt(e.line) + (i - 1))
- .replace(/\{class\}/, classname)
- .replace(/\{content\}/, e.extract[i]));
- }
- };
-
- if (e.stack) {
- content += '
' + e.stack.split('\n').slice(1).join('
');
- } else if (e.extract) {
- errorline(e, 0, '');
- errorline(e, 1, 'line');
- errorline(e, 2, '');
- content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':
' +
- '';
- }
- elem.innerHTML = content;
-
- // CSS for error messages
- createCSS([
- '.less-error-message ul, .less-error-message li {',
- 'list-style-type: none;',
- 'margin-right: 15px;',
- 'padding: 4px 0;',
- 'margin: 0;',
- '}',
- '.less-error-message label {',
- 'font-size: 12px;',
- 'margin-right: 15px;',
- 'padding: 4px 0;',
- 'color: #cc7777;',
- '}',
- '.less-error-message pre {',
- 'color: #dd6666;',
- 'padding: 4px 0;',
- 'margin: 0;',
- 'display: inline-block;',
- '}',
- '.less-error-message pre.line {',
- 'color: #ff0000;',
- '}',
- '.less-error-message h3 {',
- 'font-size: 20px;',
- 'font-weight: bold;',
- 'padding: 15px 0 5px 0;',
- 'margin: 0;',
- '}',
- '.less-error-message a {',
- 'color: #10a',
- '}',
- '.less-error-message .error {',
- 'color: red;',
- 'font-weight: bold;',
- 'padding-bottom: 2px;',
- 'border-bottom: 1px dashed red;',
- '}'
- ].join('\n'), { title: 'error-message' });
-
- elem.style.cssText = [
- "font-family: Arial, sans-serif",
- "border: 1px solid #e00",
- "background-color: #eee",
- "border-radius: 5px",
- "-webkit-border-radius: 5px",
- "-moz-border-radius: 5px",
- "color: #e00",
- "padding: 15px",
- "margin-bottom: 15px"
- ].join(';');
-
- if (less.env == 'development') {
- timer = setInterval(function () {
- if (document.body) {
- if (document.getElementById(id)) {
- document.body.replaceChild(elem, document.getElementById(id));
- } else {
- document.body.insertBefore(elem, document.body.firstChild);
- }
- clearInterval(timer);
- }
- }, 10);
- }
-}
-
-})(window);
diff --git a/dist/less-1.2.2.min.js b/dist/less-1.2.2.min.js
deleted file mode 100644
index 55042ecb8..000000000
--- a/dist/less-1.2.2.min.js
+++ /dev/null
@@ -1,9 +0,0 @@
-//
-// LESS - Leaner CSS v1.2.2
-// http://lesscss.org
-//
-// Copyright (c) 2009-2011, Alexis Sellier
-// Licensed under the Apache 2.0 License.
-//
-(function(a,b){function c(b){return a.less[b.split("/")[1]]}function m(){var a=document.getElementsByTagName("style");for(var b=0;b0?d.firstChild.nodeValue!==a.nodeValue&&d.replaceChild(a,d.firstChild):d.appendChild(a)})(document.createTextNode(a));c&&h&&(v("saving "+e+" to cache."),h.setItem(e,a),h.setItem(e+":timestamp",c))}function s(a,b,c,e){function i(b,c,d){b.status>=200&&b.status<300?c(b.responseText,b.getResponseHeader("Last-Modified")):typeof d=="function"&&d(b.status,a)}var f=t(),h=g?!1:d.async;typeof f.overrideMimeType=="function"&&f.overrideMimeType("text/css"),f.open("GET",a,h),f.setRequestHeader("Accept",b||"text/x-less, text/css; q=0.9, */*; q=0.5"),f.send(null),g?f.status===0||f.status>=200&&f.status<300?c(f.responseText):e(f.status,a):h?f.onreadystatechange=function(){f.readyState==4&&i(f,c,e)}:i(f,c,e)}function t(){if(a.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(b){return v("browser doesn't support AJAX."),null}}function u(a){return a&&a.parentNode.removeChild(a)}function v(a){d.env=="development"&&typeof console!="undefined"&&console.log("less: "+a)}function w(a,b){var c="less-error-message:"+q(b),e='{content}',f=document.createElement("div"),g,h,i=[],j=a.filename||b;f.id=c,f.className="less-error-message",h=""+(a.message||"There is an error in your .less file")+"
"+'in '+j+" ";var k=function(a,b,c){a.extract[b]&&i.push(e.replace(/\{line\}/,parseInt(a.line)+(b-1)).replace(/\{class\}/,c).replace(/\{content\}/,a.extract[b]))};a.stack?h+="
"+a.stack.split("\n").slice(1).join("
"):a.extract&&(k(a,0,""),k(a,1,"line"),k(a,2,""),h+="on line "+a.line+", column "+(a.column+1)+":
"+""),f.innerHTML=h,r([".less-error-message ul, .less-error-message li {","list-style-type: none;","margin-right: 15px;","padding: 4px 0;","margin: 0;","}",".less-error-message label {","font-size: 12px;","margin-right: 15px;","padding: 4px 0;","color: #cc7777;","}",".less-error-message pre {","color: #dd6666;","padding: 4px 0;","margin: 0;","display: inline-block;","}",".less-error-message pre.line {","color: #ff0000;","}",".less-error-message h3 {","font-size: 20px;","font-weight: bold;","padding: 15px 0 5px 0;","margin: 0;","}",".less-error-message a {","color: #10a","}",".less-error-message .error {","color: red;","font-weight: bold;","padding-bottom: 2px;","border-bottom: 1px dashed red;","}"].join("\n"),{title:"error-message"}),f.style.cssText=["font-family: Arial, sans-serif","border: 1px solid #e00","background-color: #eee","border-radius: 5px","-webkit-border-radius: 5px","-moz-border-radius: 5px","color: #e00","padding: 15px","margin-bottom: 15px"].join(";"),d.env=="development"&&(g=setInterval(function(){document.body&&(document.getElementById(c)?document.body.replaceChild(f,document.getElementById(c)):document.body.insertBefore(f,document.body.firstChild),clearInterval(g))},10))}typeof define=="function"&&define.amd&&define("less",[],function(){return d}),Array.isArray||(Array.isArray=function(a){return Object.prototype.toString.call(a)==="[object Array]"||a instanceof Array}),Array.prototype.forEach||(Array.prototype.forEach=function(a,b){var c=this.length>>>0;for(var d=0;d>>0,c=new Array(b),d=arguments[1];for(var e=0;e>>0,c=0;if(b===0&&arguments.length===1)throw new TypeError;if(arguments.length>=2)var d=arguments[1];else do{if(c in this){d=this[c++];break}if(++c>=b)throw new TypeError}while(!0);for(;c=b)return-1;c<0&&(c+=b);for(;cn&&(m[i]=m[i].slice(h-n),n=h)}function w(a){var b,c,d,e,f,j,k,l;if(a instanceof Function)return a.call(o.parsers);if(typeof a=="string")b=g.charAt(h)===a?a:null,d=1,v();else{v();if(!(b=a.exec(m[i])))return null;d=b[0].length}if(b){l=h+=d,j=h+m[i].length-d;while(h=0&&b.charAt(c)!=="\n";c--)d++;return{line:typeof a=="number"?(b.slice(0,a).match(/\n/g)||"").length:null,column:d}}function D(a,b){var c=B(a,b),d=C(a.index,c),e=d.line,f=d.column,g=c.split("\n");this.type=a.type||"Syntax",this.message=a.message,this.filename=a.filename||b.filename,this.index=a.index,this.line=typeof e=="number"?e+1:null,this.callLine=a.call&&C(a.call,c)+1,this.callExtract=g[C(a.call,c)],this.stack=a.stack,this.column=f,this.extract=[g[e-1],g[e],g[e+1]]}var g,h,i,j,k,l,m,n,o,q=this,r=function(){},s=this.imports={paths:b&&b.paths||[],queue:[],files:{},contents:{},mime:b&&b.mime,error:null,push:function(a,c){var e=this;this.queue.push(a),d.Parser.importer(a,this.paths,function(b,d,f){e.queue.splice(e.queue.indexOf(a),1),e.files[a]=d,e.contents[a]=f,b&&!e.error&&(e.error=b),c(b,d),e.queue.length===0&&r()},b)}};return this.env=b=b||{},this.optimization="optimization"in this.env?this.env.optimization:1,this.env.filename=this.env.filename||null,o={imports:s,parse:function(a,e){var j,k,p,q,s,t,u=[],v,x=null;h=i=n=l=0,g=a.replace(/\r\n/g,"\n"),m=function(a){var c=0,d=/[^"'`\{\}\/\(\)\\]+/g,e=/\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,f=/"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'|`((?:[^`\\\r\n]|\\.)*)`/g,h=0,i,j=a[0],k;for(var l=0,m,n;l0&&(x=new D({index:l,type:"Parse",message:"missing closing `}`",filename:b.filename},b)),a.map(function(a){return a.join("")})}([[]]);if(x)return e(x);try{j=new f.Ruleset([],w(this.parsers.primary)),j.root=!0}catch(y){return e(new D(y,b))}j.toCSS=function(a){var e,g,h;return function(e,g){var h=[],i;e=e||{},typeof g=="object"&&!Array.isArray(g)&&(g=Object.keys(g).map(function(a){var b=g[a];return b instanceof f.Value||(b instanceof f.Expression||(b=new f.Expression([b])),b=new f.Value([b])),new f.Rule("@"+a,b,!1,0)}),h=[new f.Ruleset(null,g)]);try{var j=a.call(this,{frames:h}).toCSS([],{compress:e.compress||!1})}catch(k){throw new D(k,b)}if(i=o.imports.error)throw i instanceof D?i:new D(i,b);return e.yuicompress&&d.mode==="node"?c("./cssmin").compressor.cssmin(j):e.compress?j.replace(/(\s)+/g,"$1"):j}}(j.eval);if(h=0&&g.charAt(z)!=="\n";z--)A++;x={type:"Parse",message:"Syntax Error on line "+s,index:h,filename:b.filename,line:s,column:A,extract:[t[s-2],t[s-1],t[s]]}}this.imports.queue.length>0?r=function(){e(x,j)}:e(x,j)},parsers:{primary:function(){var a,b=[];while((a=w(this.mixin.definition)||w(this.rule)||w(this.ruleset)||w(this.mixin.call)||w(this.comment)||w(this.directive))||w(/^[\s\n]+/))a&&b.push(a);return b},comment:function(){var a;if(g.charAt(h)!=="/")return;if(g.charAt(h+1)==="/")return new f.Comment(w(/^\/\/.*/),!0);if(a=w(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/))return new f.Comment(a)},entities:{quoted:function(){var a,b=h,c;g.charAt(b)==="~"&&(b++,c=!0);if(g.charAt(b)!=='"'&&g.charAt(b)!=="'")return;c&&w("~");if(a=w(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/))return new f.Quoted(a[0],a[1]||a[2],c)},keyword:function(){var a;if(a=w(/^[_A-Za-z-][_A-Za-z0-9-]*/))return f.colors.hasOwnProperty(a)?new f.Color(f.colors[a].slice(1)):new f.Keyword(a)},call:function(){var a,c,d=h;if(!(a=/^([\w-]+|%|progid:[\w\.]+)\(/.exec(m[i])))return;a=a[1].toLowerCase();if(a==="url")return null;h+=a.length;if(a==="alpha")return w(this.alpha);w("("),c=w(this.entities.arguments);if(!w(")"))return;if(a)return new f.Call(a,c,d,b.filename)},arguments:function(){var a=[],b;while(b=w(this.entities.assignment)||w(this.expression)){a.push(b);if(!w(","))break}return a},literal:function(){return w(this.entities.dimension)||w(this.entities.color)||w(this.entities.quoted)},assignment:function(){var a,b;if((a=w(/^\w+(?=\s?=)/i))&&w("=")&&(b=w(this.entity)))return new f.Assignment(a,b)},url:function(){var a;if(g.charAt(h)!=="u"||!w(/^url\(/))return;return a=w(this.entities.quoted)||w(this.entities.variable)||w(this.entities.dataURI)||w(/^[-\w%@$\/.&=:;#+?~]+/)||"",x(")"),new f.URL(a.value||a.data||a instanceof f.Variable?a:new f.Anonymous(a),s.paths)},dataURI:function(){var a;if(w(/^data:/)){a={},a.mime=w(/^[^\/]+\/[^,;)]+/)||"",a.charset=w(/^;\s*charset=[^,;)]+/)||"",a.base64=w(/^;\s*base64/)||"",a.data=w(/^,\s*[^)]+/);if(a.data)return a}},variable:function(){var a,c=h;if(g.charAt(h)==="@"&&(a=w(/^@@?[\w-]+/)))return new f.Variable(a,c,b.filename)},color:function(){var a;if(g.charAt(h)==="#"&&(a=w(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/)))return new f.Color(a[1])},dimension:function(){var a,b=g.charCodeAt(h);if(b>57||b<45||b===47)return;if(a=w(/^(-?\d*\.?\d+)(px|%|em|rem|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/))return new f.Dimension(a[1],a[2])},javascript:function(){var a,b=h,c;g.charAt(b)==="~"&&(b++,c=!0);if(g.charAt(b)!=="`")return;c&&w("~");if(a=w(/^`([^`]*)`/))return new f.JavaScript(a[1],h,c)}},variable:function(){var a;if(g.charAt(h)==="@"&&(a=w(/^(@[\w-]+)\s*:/)))return a[1]},shorthand:function(){var a,b;if(!z(/^[@\w.%-]+\/[@\w.-]+/))return;if((a=w(this.entity))&&w("/")&&(b=w(this.entity)))return new f.Shorthand(a,b)},mixin:{call:function(){var a=[],c,d,e,i=h,j=g.charAt(h),k=!1;if(j!=="."&&j!=="#")return;while(c=w(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/))a.push(new f.Element(d,c,h)),d=w(">");w("(")&&(e=w(this.entities.arguments))&&w(")"),w(this.important)&&(k=!0);if(a.length>0&&(w(";")||z("}")))return new f.mixin.Call(a,e,i,b.filename,k)},definition:function(){var a,b=[],c,d,e,i,j;if(g.charAt(h)!=="."&&g.charAt(h)!=="#"||z(/^[^{]*(;|})/))return;t();if(c=w(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)){a=c[1];while(e=w(this.entities.variable)||w(this.entities.literal)||w(this.entities.keyword)){e instanceof f.Variable?w(":")?(i=x(this.expression,"expected expression"),b.push({name:e.name,value:i})):b.push({name:e.name}):b.push({value:e});if(!w(","))break}x(")"),w(/^when/)&&(j=x(this.conditions,"expected condition")),d=w(this.block);if(d)return new f.mixin.Definition(a,b,d,j);u()}}},entity:function(){return w(this.entities.literal)||w(this.entities.variable)||w(this.entities.url)||w(this.entities.call)||w(this.entities.keyword)||w(this.entities.javascript)||w(this.comment)},end:function(){return w(";")||z("}")},alpha:function(){var a;if(!w(/^\(opacity=/i))return;if(a=w(/^\d+/)||w(this.entities.variable))return x(")"),new f.Alpha(a)},element:function(){var a,b,c,d;c=w(this.combinator),a=w(/^(?:\d+\.\d+|\d+)%/)||w(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)||w("*")||w(this.attribute)||w(/^\([^)@]+\)/),a||w("(")&&(d=w(this.entities.variable))&&w(")")&&(a=new f.Paren(d));if(a)return new f.Element(c,a,h);if(c.value&&c.value.charAt(0)==="&")return new f.Element(c,null,h)},combinator:function(){var a,b=g.charAt(h);if(b===">"||b==="+"||b==="~"){h++;while(g.charAt(h)===" ")h++;return new f.Combinator(b)}if(b==="&"){a="&",h++,g.charAt(h)===" "&&(a="& ");while(g.charAt(h)===" ")h++;return new f.Combinator(a)}if(b===":"&&g.charAt(h+1)===":"){h+=2;while(g.charAt(h)===" ")h++;return new f.Combinator("::")}return g.charAt(h-1)===" "?new f.Combinator(" "):new f.Combinator(null)},selector:function(){var a,b,c=[],d,e;while(b=w(this.element)){d=g.charAt(h),c.push(b);if(d==="{"||d==="}"||d===";"||d===",")break}if(c.length>0)return new f.Selector(c)},tag:function(){return w(/^[a-zA-Z][a-zA-Z-]*[0-9]?/)||w("*")},attribute:function(){var a="",b,c,d;if(!w("["))return;if(b=w(/^[a-zA-Z-]+/)||w(this.entities.quoted))(d=w(/^[|~*$^]?=/))&&(c=w(this.entities.quoted)||w(/^[\w-]+/))?a=[b,d,c.toCSS?c.toCSS():c].join(""):a=b;if(!w("]"))return;if(a)return"["+a+"]"},block:function(){var a;if(w("{")&&(a=w(this.primary))&&w("}"))return a},ruleset:function(){var a=[],b,c,d;t();while(b=w(this.selector)){a.push(b),w(this.comment);if(!w(","))break;w(this.comment)}if(a.length>0&&(c=w(this.block)))return new f.Ruleset(a,c);l=h,u()},rule:function(){var a,b,c=g.charAt(h),d,e;t();if(c==="."||c==="#"||c==="&")return;if(a=w(this.variable)||w(this.property)){a.charAt(0)!="@"&&(e=/^([^@+\/'"*`(;{}-]*);/.exec(m[i]))?(h+=e[0].length-1,b=new f.Anonymous(e[1])):a==="font"?b=w(this.font):b=w(this.value),d=w(this.important);if(b&&w(this.end))return new f.Rule(a,b,d,k);l=h,u()}},"import":function(){var a,b,c=h;if(w(/^@import\s+/)&&(a=w(this.entities.quoted)||w(this.entities.url))){b=w(this.mediaFeatures);if(w(";"))return new f.Import(a,s,b,c)}},mediaFeature:function(){var a=[];do if(e=w(this.entities.keyword))a.push(e);else if(w("(")){p=w(this.property),e=w(this.entity);if(!w(")"))return null;if(p&&e)a.push(new f.Paren(new f.Rule(p,e,null,h,!0)));else{if(!e)return null;a.push(new f.Paren(e))}}while(e);if(a.length>0)return new f.Expression(a)},mediaFeatures:function(){var a,b=[];while(a=w(this.mediaFeature)){b.push(a);if(!w(","))break}return b.length>0?b:null},media:function(){var a;if(w(/^@media/)){a=w(this.mediaFeatures);if(rules=w(this.block))return new f.Directive("@media",rules,a)}},directive:function(){var a,b,c,d,e,i;if(g.charAt(h)!=="@")return;if(b=w(this["import"])||w(this.media))return b;if(a=w(/^@page|@keyframes/)||w(/^@(?:-webkit-|-moz-|-o-|-ms-)[a-z0-9-]+/)){d=(w(/^[^{]+/)||"").trim();if(c=w(this.block))return new f.Directive(a+" "+d,c)}else if(a=w(/^@[-a-z]+/))if(a==="@font-face"){if(c=w(this.block))return new f.Directive(a,c)}else if((b=w(this.entity))&&w(";"))return new f.Directive(a,b)},font:function(){var a=[],b=[],c,d,e,g;while(g=w(this.shorthand)||w(this.entity))b.push(g);a.push(new f.Expression(b));if(w(","))while(g=w(this.expression)){a.push(g);if(!w(","))break}return new f.Value(a)},value:function(){var a,b=[],c;while(a=w(this.expression)){b.push(a);if(!w(","))break}if(b.length>0)return new f.Value(b)},important:function(){if(g.charAt(h)==="!")return w(/^! *important/)},sub:function(){var a;if(w("(")&&(a=w(this.expression))&&w(")"))return a},multiplication:function(){var a,b,c,d;if(a=w(this.operand)){while(!z(/^\/\*/)&&(c=w("/")||w("*"))&&(b=w(this.operand)))d=new f.Operation(c,[d||a,b]);return d||a}},addition:function(){var a,b,c,d;if(a=w(this.multiplication)){while((c=w(/^[-+]\s+/)||g.charAt(h-1)!=" "&&(w("+")||w("-")))&&(b=w(this.multiplication)))d=new f.Operation(c,[d||a,b]);return d||a}},conditions:function(){var a,b,c=h,d;if(a=w(this.condition)){while(w(",")&&(b=w(this.condition)))d=new f.Condition("or",d||a,b,c);return d||a}},condition:function(){var a,b,c,d,e=h,g=!1;w(/^not/)&&(g=!0),x("(");if(a=w(this.addition)||w(this.entities.keyword)||w(this.entities.quoted))return(d=w(/^(?:>=|=<|[<=>])/))?(b=w(this.addition)||w(this.entities.keyword)||w(this.entities.quoted))?c=new f.Condition(d,a,b,e,g):y("expected expression"):c=new f.Condition("=",a,new f.Keyword("true"),e,g),x(")"),w(/^and/)?new f.Condition("and",c,w(this.condition)):c},operand:function(){var a,b=g.charAt(h+1);g.charAt(h)==="-"&&(b==="@"||b==="(")&&(a=w("-"));var c=w(this.sub)||w(this.entities.dimension)||w(this.entities.color)||w(this.entities.variable)||w(this.entities.call);return a?new f.Operation("*",[new f.Dimension(-1),c]):c},expression:function(){var a,b,c=[],d;while(a=w(this.addition)||w(this.entity))c.push(a);if(c.length>0)return new f.Expression(c)},property:function(){var a;if(a=w(/^(\*?-?[-a-z_0-9]+)\s*:/))return a[1]}}}};if(d.mode==="browser"||d.mode==="rhino")d.Parser.importer=function(a,b,c,d){!/^([a-z]+:)?\//.test(a)&&b.length>0&&(a=b[0]+a),o({href:a,title:a,type:d.mime},function(e){e&&typeof d.errback=="function"?d.errback.call(null,a,b,c,d):c.apply(null,arguments)},!0)};(function(a){function b(b){return a.functions.hsla(b.h,b.s,b.l,b.a)}function c(b){if(b instanceof a.Dimension)return parseFloat(b.unit=="%"?b.value/100:b.value);if(typeof b=="number")return b;throw{error:"RuntimeError",message:"color functions take numbers as parameters"}}function d(a){return Math.min(1,Math.max(0,a))}a.functions={rgb:function(a,b,c){return this.rgba(a,b,c,1)},rgba:function(b,d,e,f){var g=[b,d,e].map(function(a){return c(a)}),f=c(f);return new a.Color(g,f)},hsl:function(a,b,c){return this.hsla(a,b,c,1)},hsla:function(a,b,d,e){function h(a){return a=a<0?a+1:a>1?a-1:a,a*6<1?g+(f-g)*a*6:a*2<1?f:a*3<2?g+(f-g)*(2/3-a)*6:g}a=c(a)%360/360,b=c(b),d=c(d),e=c(e);var f=d<=.5?d*(b+1):d+b-d*b,g=d*2-f;return this.rgba(h(a+1/3)*255,h(a)*255,h(a-1/3)*255,e)},hue:function(b){return new a.Dimension(Math.round(b.toHSL().h))},saturation:function(b){return new a.Dimension(Math.round(b.toHSL().s*100),"%")},lightness:function(b){return new a.Dimension(Math.round(b.toHSL().l*100),"%")},alpha:function(b){return new a.Dimension(b.toHSL().a)},saturate:function(a,c){var e=a.toHSL();return e.s+=c.value/100,e.s=d(e.s),b(e)},desaturate:function(a,c){var e=a.toHSL();return e.s-=c.value/100,e.s=d(e.s),b(e)},lighten:function(a,c){var e=a.toHSL();return e.l+=c.value/100,e.l=d(e.l),b(e)},darken:function(a,c){var e=a.toHSL();return e.l-=c.value/100,e.l=d(e.l),b(e)},fadein:function(a,c){var e=a.toHSL();return e.a+=c.value/100,e.a=d(e.a),b(e)},fadeout:function(a,c){var e=a.toHSL();return e.a-=c.value/100,e.a=d(e.a),b(e)},fade:function(a,c){var e=a.toHSL();return e.a=c.value/100,e.a=d(e.a),b(e)},spin:function(a,c){var d=a.toHSL(),e=(d.h+c.value)%360;return d.h=e<0?360+e:e,b(d)},mix:function(b,c,d){var e=d.value/100,f=e*2-1,g=b.toHSL().a-c.toHSL().a,h=((f*g==-1?f:(f+g)/(1+f*g))+1)/2,i=1-h,j=[b.rgb[0]*h+c.rgb[0]*i,b.rgb[1]*h+c.rgb[1]*i,b.rgb[2]*h+c.rgb[2]*i],k=b.alpha*e+c.alpha*(1-e);return new a.Color(j,k)},greyscale:function(b){return this.desaturate(b,new a.Dimension(100))},e:function(b){return new a.Anonymous(b instanceof a.JavaScript?b.evaluated:b)},escape:function(b){return new a.Anonymous(encodeURI(b.value).replace(/=/g,"%3D").replace(/:/g,"%3A").replace(/#/g,"%23").replace(/;/g,"%3B").replace(/\(/g,"%28").replace(/\)/g,"%29"))},"%":function(b){var c=Array.prototype.slice.call(arguments,1),d=b.value;for(var e=0;e255?255:a<0?0:a).toString(16),a.length===1?"0"+a:a}).join("")},operate:function(b,c){var d=[];c instanceof a.Color||(c=c.toColor());for(var e=0;e<3;e++)d[e]=a.operate(b,this.rgb[e],c.rgb[e]);return new a.Color(d,this.alpha+c.alpha)},toHSL:function(){var a=this.rgb[0]/255,b=this.rgb[1]/255,c=this.rgb[2]/255,d=this.alpha,e=Math.max(a,b,c),f=Math.min(a,b,c),g,h,i=(e+f)/2,j=e-f;if(e===f)g=h=0;else{h=i>.5?j/(2-e-f):j/(e+f);switch(e){case a:g=(b-c)/j+(b255?255:a<0?0:a).toString(16),a.length===1?"0"+a:a}).join("")}}}(c("../tree")),function(a){a.Comment=function(a,b){this.value=a,this.silent=!!b},a.Comment.prototype={toCSS:function(a){return a.compress?"":this.value},eval:function(){return this}}}(c("../tree")),function(a){a.Condition=function(a,b,c,d,e){this.op=a.trim(),this.lvalue=b,this.rvalue=c,this.index=d,this.negate=e},a.Condition.prototype.eval=function(a){var b=this.lvalue.eval(a),c=this.rvalue.eval(a),d=this.index,e,e=function(a){switch(a){case"and":return b&&c;case"or":return b||c;default:if(b.compare)e=b.compare(c);else{if(!c.compare)throw{type:"Type",message:"Unable to perform comparison",index:d};e=c.compare(b)}switch(e){case-1:return a==="<"||a==="=<";case 0:return a==="="||a===">="||a==="=<";case 1:return a===">"||a===">="}}}(this.op);return this.negate?!e:e}}(c("../tree")),function(a){a.Dimension=function(a,b){this.value=parseFloat(a),this.unit=b||null},a.Dimension.prototype={eval:function(){return this},toColor:function(){return new a.Color([this.value,this.value,this.value])},toCSS:function(){var a=this.value+this.unit;return a},operate:function(b,c){return new a.Dimension(a.operate(b,this.value,c.value),this.unit||c.unit)},compare:function(b){return b instanceof a.Dimension?b.value>this.value?-1:b.value":a.compress?">":" > "}[this.value]}}(c("../tree")),function(a){a.Expression=function(a){this.value=a},a.Expression.prototype={eval:function(b){return this.value.length>1?new a.Expression(this.value.map(function(a){return a.eval(b)})):this.value.length===1?this.value[0].eval(b):this},toCSS:function(a){return this.value.map(function(b){return b.toCSS?b.toCSS(a):""}).join(" ")}}}(c("../tree")),function(a){a.Import=function(b,c,d,e){var f=this;this.index=e,this._path=b,this.features=d&&new a.Value(d),b instanceof a.Quoted?this.path=/\.(le?|c)ss(\?.*)?$/.test(b.value)?b.value:b.value+".less":this.path=b.value.value||b.value,this.css=/css(\?.*)?$/.test(this.path),this.css||c.push(this.path,function(b,c){b&&(b.index=e),f.root=c||new a.Ruleset([],[])})},a.Import.prototype={toCSS:function(a){var b=this.features?" "+this.features.toCSS(a):"";return this.css?"@import "+this._path.toCSS()+b+";\n":""},eval:function(b){var c,d=this.features&&this.features.eval(b);if(this.css)return this;c=new a.Ruleset([],this.root.rules.slice(0));for(var e=0;e0){c=this.arguments&&this.arguments.map(function(b){return b.eval(a)});for(var g=0;g0&&c>this.params.length)return!1;if(this.condition&&!this.condition.eval({frames:[this.evalParams(b,a)].concat(b.frames)}))return!1;d=Math.min(c,this.arity);for(var f=0;fe.selectors[g].elements.length?Array.prototype.push.apply(d,e.find(new a.Selector(b.elements.slice(1)),c)):d.push(e);break}}),this._lookups[g]=d)},toCSS:function(b,c){var d=[],e=[],f=[],g=[],h,i;this.root||(b.length===0?g=this.selectors.map(function(a){return[a]}):this.joinSelectors(g,b,this.selectors));for(var j=0;j0&&(h=g.map(function(a){return a.map(function(a){return a.toCSS(c)}).join("").trim()}).join(c.compress?",":",\n"),d.push(h,(c.compress?"{":" {\n ")+e.join(c.compress?"":"\n ")+(c.compress?"}":"\n}\n"))),d.push(f),d.join("")+(c.compress?"\n":"")},joinSelectors:function(a,b,c){for(var d=0;d0&&e.push(new a.Selector(g)),h.length>0&&f.push(new a.Selector(h));for(var l=0;l0&&(b.value=c[0]+(b.value.charAt(0)==="/"?b.value.slice(1):b.value)),this.value=b,this.paths=c)},b.URL.prototype={toCSS:function(){return"url("+(this.attrs?"data:"+this.attrs.mime+this.attrs.charset+this.attrs.base64+this.attrs.data:this.value.toCSS())+")"},eval:function(a){return this.attrs?this:new b.URL(this.value.eval(a),this.paths)}}}(c("../tree")),function(a){a.Value=function(a){this.value=a,this.is="value"},a.Value.prototype={eval:function(b){return this.value.length===1?this.value[0].eval(b):new a.Value(this.value.map(function(a){return a.eval(b)}))},toCSS:function(a){return this.value.map(function(b){return b.toCSS(a)}).join(a.compress?",":", ")}}}(c("../tree")),function(a){a.Variable=function(a,b,c){this.name=a,this.index=b,this.file=c},a.Variable.prototype={eval:function(b){var c,d,e=this.name;e.indexOf("@@")==0&&(e="@"+(new a.Variable(e.slice(1))).eval(b).value);if(c=a.find(b.frames,function(a){if(d=a.variable(e))return d.value.eval(b)}))return c;throw{type:"Name",message:"variable "+e+" is undefined",filename:this.file,index:this.index}}}}(c("../tree")),function(a){a.find=function(a,b){for(var c=0,d;c1?"["+a.value.map(function(a){return a.toCSS(!1)}).join(", ")+"]":a.toCSS(!1)}}(c("./tree"));var g=location.protocol==="file:"||location.protocol==="chrome:"||location.protocol==="chrome-extension:"||location.protocol==="resource:";d.env=d.env||(location.hostname=="127.0.0.1"||location.hostname=="0.0.0.0"||location.hostname=="localhost"||location.port.length>0||g?"development":"production"),d.async=!1,d.poll=d.poll||(g?1e3:1500),d.watch=function(){return this.watchMode=!0},d.unwatch=function(){return this.watchMode=!1},d.env==="development"?(d.optimization=0,/!watch/.test(location.hash)&&d.watch(),d.watchTimer=setInterval(function(){d.watchMode&&n(function(a,b,c,d,e){b&&r(b.toCSS(),d,e.lastModified)})},d.poll)):d.optimization=3;var h;try{h=typeof a.localStorage=="undefined"?null:a.localStorage}catch(i){h=null}var j=document.getElementsByTagName("link"),k=/^text\/(x-)?less$/;d.sheets=[];for(var l=0;l= 0; i--) {
+ if (_rules.indexOf(rules[i]) === -1) {
+ _rules.unshift(rules[i]);
+ }
+ }
+ rules = _rules;
css.push(selector,
(env.compress ? '{' : ' {\n ') +
diff --git a/dist/less-1.3.0.min.js b/dist/less-1.3.0.min.js
index 309bf550d..e69de29bb 100644
--- a/dist/less-1.3.0.min.js
+++ b/dist/less-1.3.0.min.js
@@ -1,9 +0,0 @@
-//
-// LESS - Leaner CSS v1.3.0
-// http://lesscss.org
-//
-// Copyright (c) 2009-2011, Alexis Sellier
-// Licensed under the Apache 2.0 License.
-//
-(function(a,b){function c(b){return a.less[b.split("/")[1]]}function l(){var a=document.getElementsByTagName("style");for(var b=0;b0?d.firstChild.nodeValue!==a.nodeValue&&d.replaceChild(a,d.firstChild):d.appendChild(a)})(document.createTextNode(a));c&&g&&(t("saving "+e+" to cache."),g.setItem(e,a),g.setItem(e+":timestamp",c))}function q(a,b,c,e){function i(b,c,d){b.status>=200&&b.status<300?c(b.responseText,b.getResponseHeader("Last-Modified")):typeof d=="function"&&d(b.status,a)}var g=r(),h=f?!1:d.async;typeof g.overrideMimeType=="function"&&g.overrideMimeType("text/css"),g.open("GET",a,h),g.setRequestHeader("Accept",b||"text/x-less, text/css; q=0.9, */*; q=0.5"),g.send(null),f?g.status===0||g.status>=200&&g.status<300?c(g.responseText):e(g.status,a):h?g.onreadystatechange=function(){g.readyState==4&&i(g,c,e)}:i(g,c,e)}function r(){if(a.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(b){return t("browser doesn't support AJAX."),null}}function s(a){return a&&a.parentNode.removeChild(a)}function t(a){d.env=="development"&&typeof console!="undefined"&&console.log("less: "+a)}function u(a,b){var c="less-error-message:"+o(b),e='{content}',f=document.createElement("div"),g,h,i=[],j=a.filename||b;f.id=c,f.className="less-error-message",h=""+(a.message||"There is an error in your .less file")+"
"+'in '+j+" ";var k=function(a,b,c){a.extract[b]&&i.push(e.replace(/\{line\}/,parseInt(a.line)+(b-1)).replace(/\{class\}/,c).replace(/\{content\}/,a.extract[b]))};a.stack?h+="
"+a.stack.split("\n").slice(1).join("
"):a.extract&&(k(a,0,""),k(a,1,"line"),k(a,2,""),h+="on line "+a.line+", column "+(a.column+1)+":
"+""),f.innerHTML=h,p([".less-error-message ul, .less-error-message li {","list-style-type: none;","margin-right: 15px;","padding: 4px 0;","margin: 0;","}",".less-error-message label {","font-size: 12px;","margin-right: 15px;","padding: 4px 0;","color: #cc7777;","}",".less-error-message pre {","color: #dd6666;","padding: 4px 0;","margin: 0;","display: inline-block;","}",".less-error-message pre.line {","color: #ff0000;","}",".less-error-message h3 {","font-size: 20px;","font-weight: bold;","padding: 15px 0 5px 0;","margin: 0;","}",".less-error-message a {","color: #10a","}",".less-error-message .error {","color: red;","font-weight: bold;","padding-bottom: 2px;","border-bottom: 1px dashed red;","}"].join("\n"),{title:"error-message"}),f.style.cssText=["font-family: Arial, sans-serif","border: 1px solid #e00","background-color: #eee","border-radius: 5px","-webkit-border-radius: 5px","-moz-border-radius: 5px","color: #e00","padding: 15px","margin-bottom: 15px"].join(";"),d.env=="development"&&(g=setInterval(function(){document.body&&(document.getElementById(c)?document.body.replaceChild(f,document.getElementById(c)):document.body.insertBefore(f,document.body.firstChild),clearInterval(g))},10))}typeof define=="function"&&define.amd&&define("less",[],function(){return d}),Array.isArray||(Array.isArray=function(a){return Object.prototype.toString.call(a)==="[object Array]"||a instanceof Array}),Array.prototype.forEach||(Array.prototype.forEach=function(a,b){var c=this.length>>>0;for(var d=0;d>>0,c=new Array(b),d=arguments[1];for(var e=0;e>>0,c=0;if(b===0&&arguments.length===1)throw new TypeError;if(arguments.length>=2)var d=arguments[1];else do{if(c in this){d=this[c++];break}if(++c>=b)throw new TypeError}while(!0);for(;c=b)return-1;c<0&&(c+=b);for(;cl&&(k[g]=k[g].slice(f-l),l=f)}function t(a){var c,d,e,h,i,j,n,o;if(a instanceof Function)return a.call(m.parsers);if(typeof a=="string")c=b.charAt(f)===a?a:null,e=1,s();else{s();if(c=a.exec(k[g]))e=c[0].length;else return null}if(c){o=f+=e,j=f+k[g].length-e;while(f=0&&b.charAt(c)!=="\n";c--)d++;return{line:typeof a=="number"?(b.slice(0,a).match(/\n/g)||"").length:null,column:d}}function A(a,b){var c=y(a,b),d=z(a.index,c),e=d.line,f=d.column,g=c.split("\n");this.type=a.type||"Syntax",this.message=a.message,this.filename=a.filename||b.filename,this.index=a.index,this.line=typeof e=="number"?e+1:null,this.callLine=a.call&&z(a.call,c).line+1,this.callExtract=g[z(a.call,c).line],this.stack=a.stack,this.column=f,this.extract=[g[e-1],g[e],g[e+1]]}var b,f,g,h,i,j,k,l,m,n=this,o=function(){},p=this.imports={paths:a&&a.paths||[],queue:[],files:{},contents:{},mime:a&&a.mime,error:null,push:function(b,c){var e=this;this.queue.push(b),d.Parser.importer(b,this.paths,function(a,d,f){e.queue.splice(e.queue.indexOf(b),1),e.files[b]=d,e.contents[b]=f,a&&!e.error&&(e.error=a),c(a,d),e.queue.length===0&&o()},a)}};return this.env=a=a||{},this.optimization="optimization"in this.env?this.env.optimization:1,this.env.filename=this.env.filename||null,m={imports:p,parse:function(h,i){var n,p,q,r,s,u,v=[],w,x=null;f=g=l=j=0,b=h.replace(/\r\n/g,"\n"),k=function(c){var d=0,e=/[^"'`\{\}\/\(\)\\]+/g,f=/\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,g=/"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'|`((?:[^`\\\r\n]|\\.)*)`/g,h=0,i,j=c[0],k;for(var l=0,m,n;l0&&(x=new A({index:l,type:"Parse",message:"missing closing `}`",filename:a.filename},a)),c.map(function(a){return a.join("")})}([[]]);if(x)return i(x);try{n=new e.Ruleset([],t(this.parsers.primary)),n.root=!0}catch(y){return i(new A(y,a))}n.toCSS=function(b){var f,g,h;return function(f,g){var h=[],i;f=f||{},typeof g=="object"&&!Array.isArray(g)&&(g=Object.keys(g).map(function(a){var b=g[a];return b instanceof e.Value||(b instanceof e.Expression||(b=new e.Expression([b])),b=new e.Value([b])),new e.Rule("@"+a,b,!1,0)}),h=[new e.Ruleset(null,g)]);try{var j=b.call(this,{frames:h}).toCSS([],{compress:f.compress||!1})}catch(k){throw new A(k,a)}if(i=m.imports.error)throw i instanceof A?i:new A(i,a);return f.yuicompress&&d.mode==="node"?c("./cssmin").compressor.cssmin(j):f.compress?j.replace(/(\s)+/g,"$1"):j}}(n.eval);if(f=0&&b.charAt(z)!=="\n";z--)B++;x={type:"Parse",message:"Syntax Error on line "+s,index:f,filename:a.filename,line:s,column:B,extract:[u[s-2],u[s-1],u[s]]}}this.imports.queue.length>0?o=function(){i(x,n)}:i(x,n)},parsers:{primary:function(){var a,b=[];while((a=t(this.mixin.definition)||t(this.rule)||t(this.ruleset)||t(this.mixin.call)||t(this.comment)||t(this.directive))||t(/^[\s\n]+/))a&&b.push(a);return b},comment:function(){var a;if(b.charAt(f)!=="/")return;if(b.charAt(f+1)==="/")return new e.Comment(t(/^\/\/.*/),!0);if(a=t(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/))return new e.Comment(a)},entities:{quoted:function(){var a,c=f,d;b.charAt(c)==="~"&&(c++,d=!0);if(b.charAt(c)!=='"'&&b.charAt(c)!=="'")return;d&&t("~");if(a=t(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/))return new e.Quoted(a[0],a[1]||a[2],d)},keyword:function(){var a;if(a=t(/^[_A-Za-z-][_A-Za-z0-9-]*/))return e.colors.hasOwnProperty(a)?new e.Color(e.colors[a].slice(1)):new e.Keyword(a)},call:function(){var b,c,d=f;if(!(b=/^([\w-]+|%|progid:[\w\.]+)\(/.exec(k[g])))return;b=b[1].toLowerCase();if(b==="url")return null;f+=b.length;if(b==="alpha")return t(this.alpha);t("("),c=t(this.entities.arguments);if(!t(")"))return;if(b)return new e.Call(b,c,d,a.filename)},arguments:function(){var a=[],b;while(b=t(this.entities.assignment)||t(this.expression)){a.push(b);if(!t(","))break}return a},literal:function(){return t(this.entities.dimension)||t(this.entities.color)||t(this.entities.quoted)},assignment:function(){var a,b;if((a=t(/^\w+(?=\s?=)/i))&&t("=")&&(b=t(this.entity)))return new e.Assignment(a,b)},url:function(){var a;if(b.charAt(f)!=="u"||!t(/^url\(/))return;return a=t(this.entities.quoted)||t(this.entities.variable)||t(this.entities.dataURI)||t(/^[-\w%@$\/.&=:;#+?~]+/)||"",u(")"),new e.URL(a.value||a.data||a instanceof e.Variable?a:new e.Anonymous(a),p.paths)},dataURI:function(){var a;if(t(/^data:/)){a={},a.mime=t(/^[^\/]+\/[^,;)]+/)||"",a.charset=t(/^;\s*charset=[^,;)]+/)||"",a.base64=t(/^;\s*base64/)||"",a.data=t(/^,\s*[^)]+/);if(a.data)return a}},variable:function(){var c,d=f;if(b.charAt(f)==="@"&&(c=t(/^@@?[\w-]+/)))return new e.Variable(c,d,a.filename)},color:function(){var a;if(b.charAt(f)==="#"&&(a=t(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/)))return new e.Color(a[1])},dimension:function(){var a,c=b.charCodeAt(f);if(c>57||c<45||c===47)return;if(a=t(/^(-?\d*\.?\d+)(px|%|em|rem|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/))return new e.Dimension(a[1],a[2])},javascript:function(){var a,c=f,d;b.charAt(c)==="~"&&(c++,d=!0);if(b.charAt(c)!=="`")return;d&&t("~");if(a=t(/^`([^`]*)`/))return new e.JavaScript(a[1],f,d)}},variable:function(){var a;if(b.charAt(f)==="@"&&(a=t(/^(@[\w-]+)\s*:/)))return a[1]},shorthand:function(){var a,b;if(!w(/^[@\w.%-]+\/[@\w.-]+/))return;if((a=t(this.entity))&&t("/")&&(b=t(this.entity)))return new e.Shorthand(a,b)},mixin:{call:function(){var c=[],d,g,h,i=f,j=b.charAt(f),k=!1;if(j!=="."&&j!=="#")return;while(d=t(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/))c.push(new e.Element(g,d,f)),g=t(">");t("(")&&(h=t(this.entities.arguments))&&t(")"),t(this.important)&&(k=!0);if(c.length>0&&(t(";")||w("}")))return new e.mixin.Call(c,h||[],i,a.filename,k)},definition:function(){var a,c=[],d,g,h,i,j,k=!1;if(b.charAt(f)!=="."&&b.charAt(f)!=="#"||w(/^[^{]*(;|})/))return;q();if(d=t(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)){a=d[1];do{if(b.charAt(f)==="."&&t(/^\.{3}/)){k=!0;break}if(!(h=t(this.entities.variable)||t(this.entities.literal)||t(this.entities.keyword)))break;if(h instanceof e.Variable)if(t(":"))i=u(this.expression,"expected expression"),c.push({name:h.name,value:i});else{if(t(/^\.{3}/)){c.push({name:h.name,variadic:!0}),k=!0;break}c.push({name:h.name})}else c.push({value:h})}while(t(","));u(")"),t(/^when/)&&(j=u(this.conditions,"expected condition")),g=t(this.block);if(g)return new e.mixin.Definition(a,c,g,j,k);r()}}},entity:function(){return t(this.entities.literal)||t(this.entities.variable)||t(this.entities.url)||t(this.entities.call)||t(this.entities.keyword)||t(this.entities.javascript)||t(this.comment)},end:function(){return t(";")||w("}")},alpha:function(){var a;if(!t(/^\(opacity=/i))return;if(a=t(/^\d+/)||t(this.entities.variable))return u(")"),new e.Alpha(a)},element:function(){var a,b,c,d;c=t(this.combinator),a=t(/^(?:\d+\.\d+|\d+)%/)||t(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)||t("*")||t(this.attribute)||t(/^\([^)@]+\)/),a||t("(")&&(d=t(this.entities.variable))&&t(")")&&(a=new e.Paren(d));if(a)return new e.Element(c,a,f);if(c.value&&c.value.charAt(0)==="&")return new e.Element(c,null,f)},combinator:function(){var a,c=b.charAt(f);if(c===">"||c==="+"||c==="~"){f++;while(b.charAt(f)===" ")f++;return new e.Combinator(c)}if(c==="&"){a="&",f++,b.charAt(f)===" "&&(a="& ");while(b.charAt(f)===" ")f++;return new e.Combinator(a)}return b.charAt(f-1)===" "?new e.Combinator(" "):new e.Combinator(null)},selector:function(){var a,c,d=[],g,h;if(t("("))return a=t(this.entity),u(")"),new e.Selector([new e.Element("",a,f)]);while(c=t(this.element)){g=b.charAt(f),d.push(c);if(g==="{"||g==="}"||g===";"||g===",")break}if(d.length>0)return new e.Selector(d)},tag:function(){return t(/^[a-zA-Z][a-zA-Z-]*[0-9]?/)||t("*")},attribute:function(){var a="",b,c,d;if(!t("["))return;if(b=t(/^[a-zA-Z-]+/)||t(this.entities.quoted))(d=t(/^[|~*$^]?=/))&&(c=t(this.entities.quoted)||t(/^[\w-]+/))?a=[b,d,c.toCSS?c.toCSS():c].join(""):a=b;if(!t("]"))return;if(a)return"["+a+"]"},block:function(){var a;if(t("{")&&(a=t(this.primary))&&t("}"))return a},ruleset:function(){var b=[],c,d,g;q();while(c=t(this.selector)){b.push(c),t(this.comment);if(!t(","))break;t(this.comment)}if(b.length>0&&(d=t(this.block)))return new e.Ruleset(b,d,a.strictImports);j=f,r()},rule:function(){var a,c,d=b.charAt(f),h,l;q();if(d==="."||d==="#"||d==="&")return;if(a=t(this.variable)||t(this.property)){a.charAt(0)!="@"&&(l=/^([^@+\/'"*`(;{}-]*);/.exec(k[g]))?(f+=l[0].length-1,c=new e.Anonymous(l[1])):a==="font"?c=t(this.font):c=t(this.value),h=t(this.important);if(c&&t(this.end))return new e.Rule(a,c,h,i);j=f,r()}},"import":function(){var a,b,c=f;if(t(/^@import\s+/)&&(a=t(this.entities.quoted)||t(this.entities.url))){b=t(this.mediaFeatures);if(t(";"))return new e.Import(a,p,b,c)}},mediaFeature:function(){var a,b,c=[];do if(a=t(this.entities.keyword))c.push(a);else if(t("(")){b=t(this.property),a=t(this.entity);if(!t(")"))return null;if(b&&a)c.push(new e.Paren(new e.Rule(b,a,null,f,!0)));else if(a)c.push(new e.Paren(a));else return null}while(a);if(c.length>0)return new e.Expression(c)},mediaFeatures:function(){var a,b=[];do if(a=t(this.mediaFeature)){b.push(a);if(!t(","))break}else if(a=t(this.entities.variable)){b.push(a);if(!t(","))break}while(a);return b.length>0?b:null},media:function(){var a,b;if(t(/^@media/)){a=t(this.mediaFeatures);if(b=t(this.block))return new e.Media(b,a)}},directive:function(){var a,c,d,g,h,i;if(b.charAt(f)!=="@")return;if(c=t(this["import"])||t(this.media))return c;if(a=t(/^@page|@keyframes/)||t(/^@(?:-webkit-|-moz-|-o-|-ms-)[a-z0-9-]+/)){g=(t(/^[^{]+/)||"").trim();if(d=t(this.block))return new e.Directive(a+" "+g,d)}else if(a=t(/^@[-a-z]+/))if(a==="@font-face"){if(d=t(this.block))return new e.Directive(a,d)}else if((c=t(this.entity))&&t(";"))return new e.Directive(a,c)},font:function(){var a=[],b=[],c,d,f,g;while(g=t(this.shorthand)||t(this.entity))b.push(g);a.push(new e.Expression(b));if(t(","))while(g=t(this.expression)){a.push(g);if(!t(","))break}return new e.Value(a)},value:function(){var a,b=[],c;while(a=t(this.expression)){b.push(a);if(!t(","))break}if(b.length>0)return new e.Value(b)},important:function(){if(b.charAt(f)==="!")return t(/^! *important/)},sub:function(){var a;if(t("(")&&(a=t(this.expression))&&t(")"))return a},multiplication:function(){var a,b,c,d;if(a=t(this.operand)){while(!w(/^\/\*/)&&(c=t("/")||t("*"))&&(b=t(this.operand)))d=new e.Operation(c,[d||a,b]);return d||a}},addition:function(){var a,c,d,g;if(a=t(this.multiplication)){while((d=t(/^[-+]\s+/)||b.charAt(f-1)!=" "&&(t("+")||t("-")))&&(c=t(this.multiplication)))g=new e.Operation(d,[g||a,c]);return g||a}},conditions:function(){var a,b,c=f,d;if(a=t(this.condition)){while(t(",")&&(b=t(this.condition)))d=new e.Condition("or",d||a,b,c);return d||a}},condition:function(){var a,b,c,d,g=f,h=!1;t(/^not/)&&(h=!0),u("(");if(a=t(this.addition)||t(this.entities.keyword)||t(this.entities.quoted))return(d=t(/^(?:>=|=<|[<=>])/))?(b=t(this.addition)||t(this.entities.keyword)||t(this.entities.quoted))?c=new e.Condition(d,a,b,g,h):v("expected expression"):c=new e.Condition("=",a,new e.Keyword("true"),g,h),u(")"),t(/^and/)?new e.Condition("and",c,t(this.condition)):c},operand:function(){var a,c=b.charAt(f+1);b.charAt(f)==="-"&&(c==="@"||c==="(")&&(a=t("-"));var d=t(this.sub)||t(this.entities.dimension)||t(this.entities.color)||t(this.entities.variable)||t(this.entities.call);return a?new e.Operation("*",[new e.Dimension(-1),d]):d},expression:function(){var a,b,c=[],d;while(a=t(this.addition)||t(this.entity))c.push(a);if(c.length>0)return new e.Expression(c)},property:function(){var a;if(a=t(/^(\*?-?[-a-z_0-9]+)\s*:/))return a[1]}}}};if(d.mode==="browser"||d.mode==="rhino")d.Parser.importer=function(a,b,c,d){!/^([a-z]+:)?\//.test(a)&&b.length>0&&(a=b[0]+a),n({href:a,title:a,type:d.mime},function(e){e&&typeof d.errback=="function"?d.errback.call(null,a,b,c,d):c.apply(null,arguments)},!0)};(function(a){function b(b){return a.functions.hsla(b.h,b.s,b.l,b.a)}function c(b){if(b instanceof a.Dimension)return parseFloat(b.unit=="%"?b.value/100:b.value);if(typeof b=="number")return b;throw{error:"RuntimeError",message:"color functions take numbers as parameters"}}function d(a){return Math.min(1,Math.max(0,a))}a.functions={rgb:function(a,b,c){return this.rgba(a,b,c,1)},rgba:function(b,d,e,f){var g=[b,d,e].map(function(a){return c(a)}),f=c(f);return new a.Color(g,f)},hsl:function(a,b,c){return this.hsla(a,b,c,1)},hsla:function(a,b,d,e){function h(a){return a=a<0?a+1:a>1?a-1:a,a*6<1?g+(f-g)*a*6:a*2<1?f:a*3<2?g+(f-g)*(2/3-a)*6:g}a=c(a)%360/360,b=c(b),d=c(d),e=c(e);var f=d<=.5?d*(b+1):d+b-d*b,g=d*2-f;return this.rgba(h(a+1/3)*255,h(a)*255,h(a-1/3)*255,e)},hue:function(b){return new a.Dimension(Math.round(b.toHSL().h))},saturation:function(b){return new a.Dimension(Math.round(b.toHSL().s*100),"%")},lightness:function(b){return new a.Dimension(Math.round(b.toHSL().l*100),"%")},alpha:function(b){return new a.Dimension(b.toHSL().a)},saturate:function(a,c){var e=a.toHSL();return e.s+=c.value/100,e.s=d(e.s),b(e)},desaturate:function(a,c){var e=a.toHSL();return e.s-=c.value/100,e.s=d(e.s),b(e)},lighten:function(a,c){var e=a.toHSL();return e.l+=c.value/100,e.l=d(e.l),b(e)},darken:function(a,c){var e=a.toHSL();return e.l-=c.value/100,e.l=d(e.l),b(e)},fadein:function(a,c){var e=a.toHSL();return e.a+=c.value/100,e.a=d(e.a),b(e)},fadeout:function(a,c){var e=a.toHSL();return e.a-=c.value/100,e.a=d(e.a),b(e)},fade:function(a,c){var e=a.toHSL();return e.a=c.value/100,e.a=d(e.a),b(e)},spin:function(a,c){var d=a.toHSL(),e=(d.h+c.value)%360;return d.h=e<0?360+e:e,b(d)},mix:function(b,c,d){var e=d.value/100,f=e*2-1,g=b.toHSL().a-c.toHSL().a,h=((f*g==-1?f:(f+g)/(1+f*g))+1)/2,i=1-h,j=[b.rgb[0]*h+c.rgb[0]*i,b.rgb[1]*h+c.rgb[1]*i,b.rgb[2]*h+c.rgb[2]*i],k=b.alpha*e+c.alpha*(1-e);return new a.Color(j,k)},greyscale:function(b){return this.desaturate(b,new a.Dimension(100))},e:function(b){return new a.Anonymous(b instanceof a.JavaScript?b.evaluated:b)},escape:function(b){return new a.Anonymous(encodeURI(b.value).replace(/=/g,"%3D").replace(/:/g,"%3A").replace(/#/g,"%23").replace(/;/g,"%3B").replace(/\(/g,"%28").replace(/\)/g,"%29"))},"%":function(b){var c=Array.prototype.slice.call(arguments,1),d=b.value;for(var e=0;e255?255:a<0?0:a).toString(16),a.length===1?"0"+a:a}).join("")},operate:function(b,c){var d=[];c instanceof a.Color||(c=c.toColor());for(var e=0;e<3;e++)d[e]=a.operate(b,this.rgb[e],c.rgb[e]);return new a.Color(d,this.alpha+c.alpha)},toHSL:function(){var a=this.rgb[0]/255,b=this.rgb[1]/255,c=this.rgb[2]/255,d=this.alpha,e=Math.max(a,b,c),f=Math.min(a,b,c),g,h,i=(e+f)/2,j=e-f;if(e===f)g=h=0;else{h=i>.5?j/(2-e-f):j/(e+f);switch(e){case a:g=(b-c)/j+(b255?255:a<0?0:a).toString(16),a.length===1?"0"+a:a}).join("")}}}(c("../tree")),function(a){a.Comment=function(a,b){this.value=a,this.silent=!!b},a.Comment.prototype={toCSS:function(a){return a.compress?"":this.value},eval:function(){return this}}}(c("../tree")),function(a){a.Condition=function(a,b,c,d,e){this.op=a.trim(),this.lvalue=b,this.rvalue=c,this.index=d,this.negate=e},a.Condition.prototype.eval=function(a){var b=this.lvalue.eval(a),c=this.rvalue.eval(a),d=this.index,e,e=function(a){switch(a){case"and":return b&&c;case"or":return b||c;default:if(b.compare)e=b.compare(c);else if(c.compare)e=c.compare(b);else throw{type:"Type",message:"Unable to perform comparison",index:d};switch(e){case-1:return a==="<"||a==="=<";case 0:return a==="="||a===">="||a==="=<";case 1:return a===">"||a===">="}}}(this.op);return this.negate?!e:e}}(c("../tree")),function(a){a.Dimension=function(a,b){this.value=parseFloat(a),this.unit=b||null},a.Dimension.prototype={eval:function(){return this},toColor:function(){return new a.Color([this.value,this.value,this.value])},toCSS:function(){var a=this.value+this.unit;return a},operate:function(b,c){return new a.Dimension(a.operate(b,this.value,c.value),this.unit||c.unit)},compare:function(b){return b instanceof a.Dimension?b.value>this.value?-1:b.value":a.compress?">":" > "}[this.value]}}(c("../tree")),function(a){a.Expression=function(a){this.value=a},a.Expression.prototype={eval:function(b){return this.value.length>1?new a.Expression(this.value.map(function(a){return a.eval(b)})):this.value.length===1?this.value[0].eval(b):this},toCSS:function(a){return this.value.map(function(b){return b.toCSS?b.toCSS(a):""}).join(" ")}}}(c("../tree")),function(a){a.Import=function(b,c,d,e){var f=this;this.index=e,this._path=b,this.features=d&&new a.Value(d),b instanceof a.Quoted?this.path=/\.(le?|c)ss(\?.*)?$/.test(b.value)?b.value:b.value+".less":this.path=b.value.value||b.value,this.css=/css(\?.*)?$/.test(this.path),this.css||c.push(this.path,function(b,c){b&&(b.index=e),f.root=c||new a.Ruleset([],[])})},a.Import.prototype={toCSS:function(a){var b=this.features?" "+this.features.toCSS(a):"";return this.css?"@import "+this._path.toCSS()+b+";\n":""},eval:function(b){var c,d=this.features&&this.features.eval(b);if(this.css)return this;c=new a.Ruleset([],this.root.rules.slice(0));for(var e=0;e1){var d=new a.Element("&",null,0),e=[new a.Selector([d])];c=new a.Ruleset(e,b.mediaBlocks),c.multiMedia=!0}return delete b.mediaBlocks,delete b.mediaPath,c},evalNested:function(b){var c,d,e=b.mediaPath.concat([this]);for(c=0;c0;c--)b.splice(c,0,new a.Anonymous("and"));return new a.Expression(b)})),new a.Ruleset([],[])},permute:function(a){if(a.length===0)return[];if(a.length===1)return a[0];var b=[],c=this.permute(a.slice(1));for(var d=0;d0){c=this.arguments&&this.arguments.map(function(b){return b.eval(a)});for(var g=0;gthis.params.length)return!1;if(this.required>0&&c>this.params.length)return!1}if(this.condition&&!this.condition.eval({frames:[this.evalParams(b,a)].concat(b.frames)}))return!1;d=Math.min(c,this.arity);for(var f=0;fe.selectors[g].elements.length?Array.prototype.push.apply(d,e.find(new a.Selector(b.elements.slice(1)),c)):d.push(e);break}}),this._lookups[g]=d)},toCSS:function(b,c){var d=[],e=[],f=[],g=[],h,i;this.root||(b.length===0?g=this.selectors.map(function(a){return[a]}):this.joinSelectors(g,b,this.selectors));for(var j=0;j0&&(h=g.map(function(a){return a.map(function(a){return a.toCSS(c)}).join("").trim()}).join(c.compress?",":",\n"),d.push(h,(c.compress?"{":" {\n ")+e.join(c.compress?"":"\n ")+(c.compress?"}":"\n}\n"))),d.push(f),d.join("")+(c.compress?"\n":"")},joinSelectors:function(a,b,c){for(var d=0;d0&&e.push(new a.Selector(g)),h.length>0&&f.push(new a.Selector(h));for(var l=0;l0&&(b.value=c[0]+(b.value.charAt(0)==="/"?b.value.slice(1):b.value)),this.value=b,this.paths=c)},b.URL.prototype={toCSS:function(){return"url("+(this.attrs?"data:"+this.attrs.mime+this.attrs.charset+this.attrs.base64+this.attrs.data:this.value.toCSS())+")"},eval:function(a){return this.attrs?this:new b.URL(this.value.eval(a),this.paths)}}}(c("../tree")),function(a){a.Value=function(a){this.value=a,this.is="value"},a.Value.prototype={eval:function(b){return this.value.length===1?this.value[0].eval(b):new a.Value(this.value.map(function(a){return a.eval(b)}))},toCSS:function(a){return this.value.map(function(b){return b.toCSS(a)}).join(a.compress?",":", ")}}}(c("../tree")),function(a){a.Variable=function(a,b,c){this.name=a,this.index=b,this.file=c},a.Variable.prototype={eval:function(b){var c,d,e=this.name;e.indexOf("@@")==0&&(e="@"+(new a.Variable(e.slice(1))).eval(b).value);if(c=a.find(b.frames,function(a){if(d=a.variable(e))return d.value.eval(b)}))return c;throw{type:"Name",message:"variable "+e+" is undefined",filename:this.file,index:this.index}}}}(c("../tree")),function(a){a.find=function(a,b){for(var c=0,d;c1?"["+a.value.map(function(a){return a.toCSS(!1)}).join(", ")+"]":a.toCSS(!1)}}(c("./tree"));var f=location.protocol==="file:"||location.protocol==="chrome:"||location.protocol==="chrome-extension:"||location.protocol==="resource:";d.env=d.env||(location.hostname=="127.0.0.1"||location.hostname=="0.0.0.0"||location.hostname=="localhost"||location.port.length>0||f?"development":"production"),d.async=!1,d.poll=d.poll||(f?1e3:1500),d.watch=function(){return this.watchMode=!0},d.unwatch=function(){return this.watchMode=!1},d.env==="development"?(d.optimization=0,/!watch/.test(location.hash)&&d.watch(),d.watchTimer=setInterval(function(){d.watchMode&&m(function(a,b,c,d,e){b&&p(b.toCSS(),d,e.lastModified)})},d.poll)):d.optimization=3;var g;try{g=typeof a.localStorage=="undefined"?null:a.localStorage}catch(h){g=null}var i=document.getElementsByTagName("link"),j=/^text\/(x-)?less$/;d.sheets=[];for(var k=0;k>> 0;
- for (var i = 0; i < len; i++) {
- if (i in this) {
- block.call(thisObject, this[i], i, this);
- }
- }
- };
-}
-if (!Array.prototype.map) {
- Array.prototype.map = function(fun /*, thisp*/) {
- var len = this.length >>> 0;
- var res = new Array(len);
- var thisp = arguments[1];
-
- for (var i = 0; i < len; i++) {
- if (i in this) {
- res[i] = fun.call(thisp, this[i], i, this);
- }
- }
- return res;
- };
-}
-if (!Array.prototype.filter) {
- Array.prototype.filter = function (block /*, thisp */) {
- var values = [];
- var thisp = arguments[1];
- for (var i = 0; i < this.length; i++) {
- if (block.call(thisp, this[i])) {
- values.push(this[i]);
- }
- }
- return values;
- };
-}
-if (!Array.prototype.reduce) {
- Array.prototype.reduce = function(fun /*, initial*/) {
- var len = this.length >>> 0;
- var i = 0;
-
- // no value to return if no initial value and an empty array
- if (len === 0 && arguments.length === 1) throw new TypeError();
-
- if (arguments.length >= 2) {
- var rv = arguments[1];
- } else {
- do {
- if (i in this) {
- rv = this[i++];
- break;
- }
- // if array contains no values, no initial value to return
- if (++i >= len) throw new TypeError();
- } while (true);
- }
- for (; i < len; i++) {
- if (i in this) {
- rv = fun.call(null, rv, this[i], i, this);
- }
- }
- return rv;
- };
-}
-if (!Array.prototype.indexOf) {
- Array.prototype.indexOf = function (value /*, fromIndex */ ) {
- var length = this.length;
- var i = arguments[1] || 0;
-
- if (!length) return -1;
- if (i >= length) return -1;
- if (i < 0) i += length;
-
- for (; i < length; i++) {
- if (!Object.prototype.hasOwnProperty.call(this, i)) { continue }
- if (value === this[i]) return i;
- }
- return -1;
- };
-}
-
-//
-// Object
-//
-if (!Object.keys) {
- Object.keys = function (object) {
- var keys = [];
- for (var name in object) {
- if (Object.prototype.hasOwnProperty.call(object, name)) {
- keys.push(name);
- }
- }
- return keys;
- };
-}
-
-//
-// String
-//
-if (!String.prototype.trim) {
- String.prototype.trim = function () {
- return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
- };
-}
-var less, tree;
-
-if (typeof(window) === 'undefined') {
- if (typeof(exports) === 'undefined') {
- // Rhino
- less = {};
- tree = less.tree = {};
- } else {
- // Node.js
- less = exports,
- tree = require('less/tree');
- }
-} else {
- // Browser
- if (typeof(window.less) === 'undefined') { window.less = {} }
- less = window.less,
- tree = window.less.tree = {};
-}
-//
-// less.js - parser
-//
-// A relatively straight-forward predictive parser.
-// There is no tokenization/lexing stage, the input is parsed
-// in one sweep.
-//
-// To make the parser fast enough to run in the browser, several
-// optimization had to be made:
-//
-// - Matching and slicing on a huge input is often cause of slowdowns.
-// The solution is to chunkify the input into smaller strings.
-// The chunks are stored in the `chunks` var,
-// `j` holds the current chunk index, and `current` holds
-// the index of the current chunk in relation to `input`.
-// This gives us an almost 4x speed-up.
-//
-// - In many cases, we don't need to match individual tokens;
-// for example, if a value doesn't hold any variables, operations
-// or dynamic references, the parser can effectively 'skip' it,
-// treating it as a literal.
-// An example would be '1px solid #000' - which evaluates to itself,
-// we don't need to know what the individual components are.
-// The drawback, of course is that you don't get the benefits of
-// syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
-// and a smaller speed-up in the code-gen.
-//
-//
-// Token matching is done with the `$` function, which either takes
-// a terminal string or regexp, or a non-terminal function to call.
-// It also takes care of moving all the indices forwards.
-//
-//
-less.Parser = function Parser(env) {
- var input, // LeSS input string
- i, // current index in `input`
- j, // current chunk
- temp, // temporarily holds a chunk's state, for backtracking
- memo, // temporarily holds `i`, when backtracking
- furthest, // furthest index the parser has gone to
- chunks, // chunkified input
- current, // index of current chunk, in `input`
- parser;
-
- var that = this;
-
- // This function is called after all files
- // have been imported through `@import`.
- var finish = function () {};
-
- var imports = this.imports = {
- paths: env && env.paths || [], // Search paths, when importing
- queue: [], // Files which haven't been imported yet
- files: {}, // Holds the imported parse trees
- mime: env && env.mime, // MIME type of .less files
- push: function (path, callback) {
- var that = this;
- this.queue.push(path);
-
- //
- // Import a file asynchronously
- //
- less.Parser.importer(path, this.paths, function (root) {
- that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
- that.files[path] = root; // Store the root
-
- callback(root);
-
- if (that.queue.length === 0) { finish() } // Call `finish` if we're done importing
- }, env);
- }
- };
-
- function save() { temp = chunks[j], memo = i, current = i }
- function restore() { chunks[j] = temp, i = memo, current = i }
-
- function sync() {
- if (i > current) {
- chunks[j] = chunks[j].slice(i - current);
- current = i;
- }
- }
- //
- // Parse from a token, regexp or string, and move forward if match
- //
- function $(tok) {
- var match, args, length, c, index, endIndex, k, mem;
-
- //
- // Non-terminal
- //
- if (tok instanceof Function) {
- return tok.call(parser.parsers);
- //
- // Terminal
- //
- // Either match a single character in the input,
- // or match a regexp in the current chunk (chunk[j]).
- //
- } else if (typeof(tok) === 'string') {
- match = input.charAt(i) === tok ? tok : null;
- length = 1;
- sync ();
- } else {
- sync ();
-
- if (match = tok.exec(chunks[j])) {
- length = match[0].length;
- } else {
- return null;
- }
- }
-
- // The match is confirmed, add the match length to `i`,
- // and consume any extra white-space characters (' ' || '\n')
- // which come after that. The reason for this is that LeSS's
- // grammar is mostly white-space insensitive.
- //
- if (match) {
- mem = i += length;
- endIndex = i + chunks[j].length - length;
-
- while (i < endIndex) {
- c = input.charCodeAt(i);
- if (! (c === 32 || c === 10 || c === 9)) { break }
- i++;
- }
- chunks[j] = chunks[j].slice(length + (i - mem));
- current = i;
-
- if (chunks[j].length === 0 && j < chunks.length - 1) { j++ }
-
- if(typeof(match) === 'string') {
- return match;
- } else {
- return match.length === 1 ? match[0] : match;
- }
- }
- }
-
- // Same as $(), but don't change the state of the parser,
- // just return the match.
- function peek(tok) {
- if (typeof(tok) === 'string') {
- return input.charAt(i) === tok;
- } else {
- if (tok.test(chunks[j])) {
- return true;
- } else {
- return false;
- }
- }
- }
-
- this.env = env = env || {};
-
- // The optimization level dictates the thoroughness of the parser,
- // the lower the number, the less nodes it will create in the tree.
- // This could matter for debugging, or if you want to access
- // the individual nodes in the tree.
- this.optimization = ('optimization' in this.env) ? this.env.optimization : 1;
-
- this.env.filename = this.env.filename || null;
-
- //
- // The Parser
- //
- return parser = {
-
- imports: imports,
- //
- // Parse an input string into an abstract syntax tree,
- // call `callback` when done.
- //
- parse: function (str, callback) {
- var root, start, end, zone, line, lines, buff = [], c, error = null;
-
- i = j = current = furthest = 0;
- chunks = [];
- input = str.replace(/\r\n/g, '\n');
-
- // Split the input into chunks.
- chunks = (function (chunks) {
- var j = 0,
- skip = /[^"'`\{\}\/\(\)]+/g,
- comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
- level = 0,
- match,
- chunk = chunks[0],
- inParam,
- inString;
-
- for (var i = 0, c, cc; i < input.length; i++) {
- skip.lastIndex = i;
- if (match = skip.exec(input)) {
- if (match.index === i) {
- i += match[0].length;
- chunk.push(match[0]);
- }
- }
- c = input.charAt(i);
- comment.lastIndex = i;
-
- if (!inString && !inParam && c === '/') {
- cc = input.charAt(i + 1);
- if (cc === '/' || cc === '*') {
- if (match = comment.exec(input)) {
- if (match.index === i) {
- i += match[0].length;
- chunk.push(match[0]);
- c = input.charAt(i);
- }
- }
- }
- }
-
- if (c === '{' && !inString && !inParam) { level ++;
- chunk.push(c);
- } else if (c === '}' && !inString && !inParam) { level --;
- chunk.push(c);
- chunks[++j] = chunk = [];
- } else if (c === '(' && !inString && !inParam) {
- chunk.push(c);
- inParam = true;
- } else if (c === ')' && !inString && inParam) {
- chunk.push(c);
- inParam = false;
- } else {
- if (c === '"' || c === "'" || c === '`') {
- if (! inString) {
- inString = c;
- } else {
- inString = inString === c ? false : inString;
- }
- }
- chunk.push(c);
- }
- }
- if (level > 0) {
- throw {
- type: 'Syntax',
- message: "Missing closing `}`",
- filename: env.filename
- };
- }
-
- return chunks.map(function (c) { return c.join('') });;
- })([[]]);
-
- // Start with the primary rule.
- // The whole syntax tree is held under a Ruleset node,
- // with the `root` property set to true, so no `{}` are
- // output. The callback is called when the input is parsed.
- root = new(tree.Ruleset)([], $(this.parsers.primary));
- root.root = true;
-
- root.toCSS = (function (evaluate) {
- var line, lines, column;
-
- return function (options, variables) {
- var frames = [];
-
- options = options || {};
- //
- // Allows setting variables with a hash, so:
- //
- // `{ color: new(tree.Color)('#f01') }` will become:
- //
- // new(tree.Rule)('@color',
- // new(tree.Value)([
- // new(tree.Expression)([
- // new(tree.Color)('#f01')
- // ])
- // ])
- // )
- //
- if (typeof(variables) === 'object' && !Array.isArray(variables)) {
- variables = Object.keys(variables).map(function (k) {
- var value = variables[k];
-
- if (! (value instanceof tree.Value)) {
- if (! (value instanceof tree.Expression)) {
- value = new(tree.Expression)([value]);
- }
- value = new(tree.Value)([value]);
- }
- return new(tree.Rule)('@' + k, value, false, 0);
- });
- frames = [new(tree.Ruleset)(null, variables)];
- }
-
- try {
- var css = evaluate.call(this, { frames: frames })
- .toCSS([], { compress: options.compress || false });
- } catch (e) {
- lines = input.split('\n');
- line = getLine(e.index);
-
- for (var n = e.index, column = -1;
- n >= 0 && input.charAt(n) !== '\n';
- n--) { column++ }
-
- throw {
- type: e.type,
- message: e.message,
- filename: env.filename,
- index: e.index,
- line: typeof(line) === 'number' ? line + 1 : null,
- callLine: e.call && (getLine(e.call) + 1),
- callExtract: lines[getLine(e.call)],
- stack: e.stack,
- column: column,
- extract: [
- lines[line - 1],
- lines[line],
- lines[line + 1]
- ]
- };
- }
- if (options.compress) {
- return css.replace(/(\s)+/g, "$1");
- } else {
- return css;
- }
-
- function getLine(index) {
- return index ? (input.slice(0, index).match(/\n/g) || "").length : null;
- }
- };
- })(root.eval);
-
- // If `i` is smaller than the `input.length - 1`,
- // it means the parser wasn't able to parse the whole
- // string, so we've got a parsing error.
- //
- // We try to extract a \n delimited string,
- // showing the line where the parse error occured.
- // We split it up into two parts (the part which parsed,
- // and the part which didn't), so we can color them differently.
- if (i < input.length - 1) {
- i = furthest;
- lines = input.split('\n');
- line = (input.slice(0, i).match(/\n/g) || "").length + 1;
-
- for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }
-
- error = {
- name: "ParseError",
- message: "Syntax Error on line " + line,
- index: i,
- filename: env.filename,
- line: line,
- column: column,
- extract: [
- lines[line - 2],
- lines[line - 1],
- lines[line]
- ]
- };
- }
-
- if (this.imports.queue.length > 0) {
- finish = function () { callback(error, root) };
- } else {
- callback(error, root);
- }
- },
-
- //
- // Here in, the parsing rules/functions
- //
- // The basic structure of the syntax tree generated is as follows:
- //
- // Ruleset -> Rule -> Value -> Expression -> Entity
- //
- // Here's some LESS code:
- //
- // .class {
- // color: #fff;
- // border: 1px solid #000;
- // width: @w + 4px;
- // > .child {...}
- // }
- //
- // And here's what the parse tree might look like:
- //
- // Ruleset (Selector '.class', [
- // Rule ("color", Value ([Expression [Color #fff]]))
- // Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
- // Rule ("width", Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
- // Ruleset (Selector [Element '>', '.child'], [...])
- // ])
- //
- // In general, most rules will try to parse a token with the `$()` function, and if the return
- // value is truly, will return a new node, of the relevant type. Sometimes, we need to check
- // first, before parsing, that's when we use `peek()`.
- //
- parsers: {
- //
- // The `primary` rule is the *entry* and *exit* point of the parser.
- // The rules here can appear at any level of the parse tree.
- //
- // The recursive nature of the grammar is an interplay between the `block`
- // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
- // as represented by this simplified grammar:
- //
- // primary → (ruleset | rule)+
- // ruleset → selector+ block
- // block → '{' primary '}'
- //
- // Only at one point is the primary rule not called from the
- // block rule: at the root level.
- //
- primary: function () {
- var node, root = [];
-
- while ((node = $(this.mixin.definition) || $(this.rule) || $(this.ruleset) ||
- $(this.mixin.call) || $(this.comment) || $(this.directive))
- || $(/^[\s\n]+/)) {
- node && root.push(node);
- }
- return root;
- },
-
- // We create a Comment node for CSS comments `/* */`,
- // but keep the LeSS comments `//` silent, by just skipping
- // over them.
- comment: function () {
- var comment;
-
- if (input.charAt(i) !== '/') return;
-
- if (input.charAt(i + 1) === '/') {
- return new(tree.Comment)($(/^\/\/.*/), true);
- } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) {
- return new(tree.Comment)(comment);
- }
- },
-
- //
- // Entities are tokens which can be found inside an Expression
- //
- entities: {
- //
- // A string, which supports escaping " and '
- //
- // "milky way" 'he\'s the one!'
- //
- quoted: function () {
- var str, j = i, e;
-
- if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
- if (input.charAt(j) !== '"' && input.charAt(j) !== "'") return;
-
- e && $('~');
-
- if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) {
- return new(tree.Quoted)(str[0], str[1] || str[2], e);
- }
- },
-
- //
- // A catch-all word, such as:
- //
- // black border-collapse
- //
- keyword: function () {
- var k;
- if (k = $(/^[A-Za-z-]+/)) { return new(tree.Keyword)(k) }
- },
-
- //
- // A function call
- //
- // rgb(255, 0, 255)
- //
- // We also try to catch IE's `alpha()`, but let the `alpha` parser
- // deal with the details.
- //
- // The arguments are parsed with the `entities.arguments` parser.
- //
- call: function () {
- var name, args, index = i;
-
- if (! (name = /^([\w-]+|%)\(/.exec(chunks[j]))) return;
-
- name = name[1].toLowerCase();
-
- if (name === 'url') { return null }
- else { i += name.length }
-
- if (name === 'alpha') { return $(this.alpha) }
-
- $('('); // Parse the '(' and consume whitespace.
-
- args = $(this.entities.arguments);
-
- if (! $(')')) return;
-
- if (name) { return new(tree.Call)(name, args, index) }
- },
- arguments: function () {
- var args = [], arg;
-
- while (arg = $(this.expression)) {
- args.push(arg);
- if (! $(',')) { break }
- }
- return args;
- },
- literal: function () {
- return $(this.entities.dimension) ||
- $(this.entities.color) ||
- $(this.entities.quoted);
- },
-
- //
- // Parse url() tokens
- //
- // We use a specific rule for urls, because they don't really behave like
- // standard function calls. The difference is that the argument doesn't have
- // to be enclosed within a string, so it can't be parsed as an Expression.
- //
- url: function () {
- var value;
-
- if (input.charAt(i) !== 'u' || !$(/^url\(/)) return;
- value = $(this.entities.quoted) || $(this.entities.variable) ||
- $(this.entities.dataURI) || $(/^[-\w%@$\/.&=:;#+?~]+/) || "";
- if (! $(')')) throw new(Error)("missing closing ) for url()");
-
- return new(tree.URL)((value.value || value.data || value instanceof tree.Variable)
- ? value : new(tree.Anonymous)(value), imports.paths);
- },
-
- dataURI: function () {
- var obj;
-
- if ($(/^data:/)) {
- obj = {};
- obj.mime = $(/^[^\/]+\/[^,;)]+/) || '';
- obj.charset = $(/^;\s*charset=[^,;)]+/) || '';
- obj.base64 = $(/^;\s*base64/) || '';
- obj.data = $(/^,\s*[^)]+/);
-
- if (obj.data) { return obj }
- }
- },
-
- //
- // A Variable entity, such as `@fink`, in
- //
- // width: @fink + 2px
- //
- // We use a different parser for variable definitions,
- // see `parsers.variable`.
- //
- variable: function () {
- var name, index = i;
-
- if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) {
- return new(tree.Variable)(name, index);
- }
- },
-
- //
- // A Hexadecimal color
- //
- // #4F3C2F
- //
- // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
- //
- color: function () {
- var rgb;
-
- if (input.charAt(i) === '#' && (rgb = $(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/))) {
- return new(tree.Color)(rgb[1]);
- }
- },
-
- //
- // A Dimension, that is, a number and a unit
- //
- // 0.5em 95%
- //
- dimension: function () {
- var value, c = input.charCodeAt(i);
- if ((c > 57 || c < 45) || c === 47) return;
-
- if (value = $(/^(-?\d*\.?\d+)(px|%|em|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/)) {
- return new(tree.Dimension)(value[1], value[2]);
- }
- },
-
- //
- // JavaScript code to be evaluated
- //
- // `window.location.href`
- //
- javascript: function () {
- var str, j = i, e;
-
- if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
- if (input.charAt(j) !== '`') { return }
-
- e && $('~');
-
- if (str = $(/^`([^`]*)`/)) {
- return new(tree.JavaScript)(str[1], i, e);
- }
- }
- },
-
- //
- // The variable part of a variable definition. Used in the `rule` parser
- //
- // @fink:
- //
- variable: function () {
- var name;
-
- if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1] }
- },
-
- //
- // A font size/line-height shorthand
- //
- // small/12px
- //
- // We need to peek first, or we'll match on keywords and dimensions
- //
- shorthand: function () {
- var a, b;
-
- if (! peek(/^[@\w.%-]+\/[@\w.-]+/)) return;
-
- if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
- return new(tree.Shorthand)(a, b);
- }
- },
-
- //
- // Mixins
- //
- mixin: {
- //
- // A Mixin call, with an optional argument list
- //
- // #mixins > .square(#fff);
- // .rounded(4px, black);
- // .button;
- //
- // The `while` loop is there because mixins can be
- // namespaced, but we only support the child and descendant
- // selector for now.
- //
- call: function () {
- var elements = [], e, c, args, index = i, s = input.charAt(i);
-
- if (s !== '.' && s !== '#') { return }
-
- while (e = $(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)) {
- elements.push(new(tree.Element)(c, e));
- c = $('>');
- }
- $('(') && (args = $(this.entities.arguments)) && $(')');
-
- if (elements.length > 0 && ($(';') || peek('}'))) {
- return new(tree.mixin.Call)(elements, args, index);
- }
- },
-
- //
- // A Mixin definition, with a list of parameters
- //
- // .rounded (@radius: 2px, @color) {
- // ...
- // }
- //
- // Until we have a finer grained state-machine, we have to
- // do a look-ahead, to make sure we don't have a mixin call.
- // See the `rule` function for more information.
- //
- // We start by matching `.rounded (`, and then proceed on to
- // the argument list, which has optional default values.
- // We store the parameters in `params`, with a `value` key,
- // if there is a value, such as in the case of `@radius`.
- //
- // Once we've got our params list, and a closing `)`, we parse
- // the `{...}` block.
- //
- definition: function () {
- var name, params = [], match, ruleset, param, value;
-
- if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') ||
- peek(/^[^{]*(;|})/)) return;
-
- if (match = $(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)) {
- name = match[1];
-
- while (param = $(this.entities.variable) || $(this.entities.literal)
- || $(this.entities.keyword)) {
- // Variable
- if (param instanceof tree.Variable) {
- if ($(':')) {
- if (value = $(this.expression)) {
- params.push({ name: param.name, value: value });
- } else {
- throw new(Error)("Expected value");
- }
- } else {
- params.push({ name: param.name });
- }
- } else {
- params.push({ value: param });
- }
- if (! $(',')) { break }
- }
- if (! $(')')) throw new(Error)("Expected )");
-
- ruleset = $(this.block);
-
- if (ruleset) {
- return new(tree.mixin.Definition)(name, params, ruleset);
- }
- }
- }
- },
-
- //
- // Entities are the smallest recognized token,
- // and can be found inside a rule's value.
- //
- entity: function () {
- return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) ||
- $(this.entities.call) || $(this.entities.keyword) || $(this.entities.javascript) ||
- $(this.comment);
- },
-
- //
- // A Rule terminator. Note that we use `peek()` to check for '}',
- // because the `block` rule will be expecting it, but we still need to make sure
- // it's there, if ';' was ommitted.
- //
- end: function () {
- return $(';') || peek('}');
- },
-
- //
- // IE's alpha function
- //
- // alpha(opacity=88)
- //
- alpha: function () {
- var value;
-
- if (! $(/^\(opacity=/i)) return;
- if (value = $(/^\d+/) || $(this.entities.variable)) {
- if (! $(')')) throw new(Error)("missing closing ) for alpha()");
- return new(tree.Alpha)(value);
- }
- },
-
- //
- // A Selector Element
- //
- // div
- // + h1
- // #socks
- // input[type="text"]
- //
- // Elements are the building blocks for Selectors,
- // they are made out of a `Combinator` (see combinator rule),
- // and an element name, such as a tag a class, or `*`.
- //
- element: function () {
- var e, t, c;
-
- c = $(this.combinator);
- e = $(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/) || $('*') || $(this.attribute) || $(/^\([^)@]+\)/);
-
- if (e) { return new(tree.Element)(c, e) }
-
- if (c.value && c.value[0] === '&') {
- return new(tree.Element)(c, null);
- }
- },
-
- //
- // Combinators combine elements together, in a Selector.
- //
- // Because our parser isn't white-space sensitive, special care
- // has to be taken, when parsing the descendant combinator, ` `,
- // as it's an empty space. We have to check the previous character
- // in the input, to see if it's a ` ` character. More info on how
- // we deal with this in *combinator.js*.
- //
- combinator: function () {
- var match, c = input.charAt(i);
-
- if (c === '>' || c === '+' || c === '~') {
- i++;
- while (input.charAt(i) === ' ') { i++ }
- return new(tree.Combinator)(c);
- } else if (c === '&') {
- match = '&';
- i++;
- if(input.charAt(i) === ' ') {
- match = '& ';
- }
- while (input.charAt(i) === ' ') { i++ }
- return new(tree.Combinator)(match);
- } else if (c === ':' && input.charAt(i + 1) === ':') {
- i += 2;
- while (input.charAt(i) === ' ') { i++ }
- return new(tree.Combinator)('::');
- } else if (input.charAt(i - 1) === ' ') {
- return new(tree.Combinator)(" ");
- } else {
- return new(tree.Combinator)(null);
- }
- },
-
- //
- // A CSS Selector
- //
- // .class > div + h1
- // li a:hover
- //
- // Selectors are made out of one or more Elements, see above.
- //
- selector: function () {
- var sel, e, elements = [], c, match;
-
- while (e = $(this.element)) {
- c = input.charAt(i);
- elements.push(e)
- if (c === '{' || c === '}' || c === ';' || c === ',') { break }
- }
-
- if (elements.length > 0) { return new(tree.Selector)(elements) }
- },
- tag: function () {
- return $(/^[a-zA-Z][a-zA-Z-]*[0-9]?/) || $('*');
- },
- attribute: function () {
- var attr = '', key, val, op;
-
- if (! $('[')) return;
-
- if (key = $(/^[a-zA-Z-]+/) || $(this.entities.quoted)) {
- if ((op = $(/^[|~*$^]?=/)) &&
- (val = $(this.entities.quoted) || $(/^[\w-]+/))) {
- attr = [key, op, val.toCSS ? val.toCSS() : val].join('');
- } else { attr = key }
- }
-
- if (! $(']')) return;
-
- if (attr) { return "[" + attr + "]" }
- },
-
- //
- // The `block` rule is used by `ruleset` and `mixin.definition`.
- // It's a wrapper around the `primary` rule, with added `{}`.
- //
- block: function () {
- var content;
-
- if ($('{') && (content = $(this.primary)) && $('}')) {
- return content;
- }
- },
-
- //
- // div, .class, body > p {...}
- //
- ruleset: function () {
- var selectors = [], s, rules, match;
- save();
-
- if (match = /^([.#: \w-]+)[\s\n]*\{/.exec(chunks[j])) {
- i += match[0].length - 1;
- selectors = [new(tree.Selector)([new(tree.Element)(null, match[1])])];
- } else {
- while (s = $(this.selector)) {
- selectors.push(s);
- $(this.comment);
- if (! $(',')) { break }
- $(this.comment);
- }
- }
-
- if (selectors.length > 0 && (rules = $(this.block))) {
- return new(tree.Ruleset)(selectors, rules);
- } else {
- // Backtrack
- furthest = i;
- restore();
- }
- },
- rule: function () {
- var name, value, c = input.charAt(i), important, match;
- save();
-
- if (c === '.' || c === '#' || c === '&') { return }
-
- if (name = $(this.variable) || $(this.property)) {
- if ((name.charAt(0) != '@') && (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j]))) {
- i += match[0].length - 1;
- value = new(tree.Anonymous)(match[1]);
- } else if (name === "font") {
- value = $(this.font);
- } else {
- value = $(this.value);
- }
- important = $(this.important);
-
- if (value && $(this.end)) {
- return new(tree.Rule)(name, value, important, memo);
- } else {
- furthest = i;
- restore();
- }
- }
- },
-
- //
- // An @import directive
- //
- // @import "lib";
- //
- // Depending on our environemnt, importing is done differently:
- // In the browser, it's an XHR request, in Node, it would be a
- // file-system operation. The function used for importing is
- // stored in `import`, which we pass to the Import constructor.
- //
- "import": function () {
- var path;
- if ($(/^@import\s+/) &&
- (path = $(this.entities.quoted) || $(this.entities.url)) &&
- $(';')) {
- return new(tree.Import)(path, imports);
- }
- },
-
- //
- // A CSS Directive
- //
- // @charset "utf-8";
- //
- directive: function () {
- var name, value, rules, types;
-
- if (input.charAt(i) !== '@') return;
-
- if (value = $(this['import'])) {
- return value;
- } else if (name = $(/^@media|@page|@-[-a-z]+/)) {
- types = ($(/^[^{]+/) || '').trim();
- if (rules = $(this.block)) {
- return new(tree.Directive)(name + " " + types, rules);
- }
- } else if (name = $(/^@[-a-z]+/)) {
- if (name === '@font-face') {
- if (rules = $(this.block)) {
- return new(tree.Directive)(name, rules);
- }
- } else if ((value = $(this.entity)) && $(';')) {
- return new(tree.Directive)(name, value);
- }
- }
- },
- font: function () {
- var value = [], expression = [], weight, shorthand, font, e;
-
- while (e = $(this.shorthand) || $(this.entity)) {
- expression.push(e);
- }
- value.push(new(tree.Expression)(expression));
-
- if ($(',')) {
- while (e = $(this.expression)) {
- value.push(e);
- if (! $(',')) { break }
- }
- }
- return new(tree.Value)(value);
- },
-
- //
- // A Value is a comma-delimited list of Expressions
- //
- // font-family: Baskerville, Georgia, serif;
- //
- // In a Rule, a Value represents everything after the `:`,
- // and before the `;`.
- //
- value: function () {
- var e, expressions = [], important;
-
- while (e = $(this.expression)) {
- expressions.push(e);
- if (! $(',')) { break }
- }
-
- if (expressions.length > 0) {
- return new(tree.Value)(expressions);
- }
- },
- important: function () {
- if (input.charAt(i) === '!') {
- return $(/^! *important/);
- }
- },
- sub: function () {
- var e;
-
- if ($('(') && (e = $(this.expression)) && $(')')) {
- return e;
- }
- },
- multiplication: function () {
- var m, a, op, operation;
- if (m = $(this.operand)) {
- while ((op = ($('/') || $('*'))) && (a = $(this.operand))) {
- operation = new(tree.Operation)(op, [operation || m, a]);
- }
- return operation || m;
- }
- },
- addition: function () {
- var m, a, op, operation;
- if (m = $(this.multiplication)) {
- while ((op = $(/^[-+]\s+/) || (input.charAt(i - 1) != ' ' && ($('+') || $('-')))) &&
- (a = $(this.multiplication))) {
- operation = new(tree.Operation)(op, [operation || m, a]);
- }
- return operation || m;
- }
- },
-
- //
- // An operand is anything that can be part of an operation,
- // such as a Color, or a Variable
- //
- operand: function () {
- var negate, p = input.charAt(i + 1);
-
- if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $('-') }
- var o = $(this.sub) || $(this.entities.dimension) ||
- $(this.entities.color) || $(this.entities.variable) ||
- $(this.entities.call);
- return negate ? new(tree.Operation)('*', [new(tree.Dimension)(-1), o])
- : o;
- },
-
- //
- // Expressions either represent mathematical operations,
- // or white-space delimited Entities.
- //
- // 1px solid black
- // @var * 2
- //
- expression: function () {
- var e, delim, entities = [], d;
-
- while (e = $(this.addition) || $(this.entity)) {
- entities.push(e);
- }
- if (entities.length > 0) {
- return new(tree.Expression)(entities);
- }
- },
- property: function () {
- var name;
-
- if (name = $(/^(\*?-?[-a-z_0-9]+)\s*:/)) {
- return name[1];
- }
- }
- }
- };
-};
-
-if (typeof(window) !== 'undefined' /* browser */ || typeof(exports) === 'undefined' /* rhino */) {
- //
- // Used by `@import` directives
- //
- less.Parser.importer = function (path, paths, callback, env) {
- if (path.charAt(0) !== '/' && paths.length > 0) {
- path = paths[0] + path;
- }
- // We pass `true` as 3rd argument, to force the reload of the import.
- // This is so we can get the syntax tree as opposed to just the CSS output,
- // as we need this to evaluate the current stylesheet.
- loadStyleSheet({ href: path, title: path, type: env.mime }, callback, true);
- };
-}
-
-(function (tree) {
-
-tree.functions = {
- rgb: function (r, g, b) {
- return this.rgba(r, g, b, 1.0);
- },
- rgba: function (r, g, b, a) {
- var rgb = [r, g, b].map(function (c) { return number(c) }),
- a = number(a);
- return new(tree.Color)(rgb, a);
- },
- hsl: function (h, s, l) {
- return this.hsla(h, s, l, 1.0);
- },
- hsla: function (h, s, l, a) {
- h = (number(h) % 360) / 360;
- s = number(s); l = number(l); a = number(a);
-
- var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
- var m1 = l * 2 - m2;
-
- return this.rgba(hue(h + 1/3) * 255,
- hue(h) * 255,
- hue(h - 1/3) * 255,
- a);
-
- function hue(h) {
- h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
- if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
- else if (h * 2 < 1) return m2;
- else if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
- else return m1;
- }
- },
- hue: function (color) {
- return new(tree.Dimension)(Math.round(color.toHSL().h));
- },
- saturation: function (color) {
- return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%');
- },
- lightness: function (color) {
- return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%');
- },
- alpha: function (color) {
- return new(tree.Dimension)(color.toHSL().a);
- },
- saturate: function (color, amount) {
- var hsl = color.toHSL();
-
- hsl.s += amount.value / 100;
- hsl.s = clamp(hsl.s);
- return hsla(hsl);
- },
- desaturate: function (color, amount) {
- var hsl = color.toHSL();
-
- hsl.s -= amount.value / 100;
- hsl.s = clamp(hsl.s);
- return hsla(hsl);
- },
- lighten: function (color, amount) {
- var hsl = color.toHSL();
-
- hsl.l += amount.value / 100;
- hsl.l = clamp(hsl.l);
- return hsla(hsl);
- },
- darken: function (color, amount) {
- var hsl = color.toHSL();
-
- hsl.l -= amount.value / 100;
- hsl.l = clamp(hsl.l);
- return hsla(hsl);
- },
- fadein: function (color, amount) {
- var hsl = color.toHSL();
-
- hsl.a += amount.value / 100;
- hsl.a = clamp(hsl.a);
- return hsla(hsl);
- },
- fadeout: function (color, amount) {
- var hsl = color.toHSL();
-
- hsl.a -= amount.value / 100;
- hsl.a = clamp(hsl.a);
- return hsla(hsl);
- },
- spin: function (color, amount) {
- var hsl = color.toHSL();
- var hue = (hsl.h + amount.value) % 360;
-
- hsl.h = hue < 0 ? 360 + hue : hue;
-
- return hsla(hsl);
- },
- //
- // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
- // http://sass-lang.com
- //
- mix: function (color1, color2, weight) {
- var p = weight.value / 100.0;
- var w = p * 2 - 1;
- var a = color1.toHSL().a - color2.toHSL().a;
-
- var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
- var w2 = 1 - w1;
-
- var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
- color1.rgb[1] * w1 + color2.rgb[1] * w2,
- color1.rgb[2] * w1 + color2.rgb[2] * w2];
-
- var alpha = color1.alpha * p + color2.alpha * (1 - p);
-
- return new(tree.Color)(rgb, alpha);
- },
- greyscale: function (color) {
- return this.desaturate(color, new(tree.Dimension)(100));
- },
- e: function (str) {
- return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str);
- },
- escape: function (str) {
- return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29"));
- },
- '%': function (quoted /* arg, arg, ...*/) {
- var args = Array.prototype.slice.call(arguments, 1),
- str = quoted.value;
-
- for (var i = 0; i < args.length; i++) {
- str = str.replace(/%[sda]/i, function(token) {
- var value = token.match(/s/i) ? args[i].value : args[i].toCSS();
- return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
- });
- }
- str = str.replace(/%%/g, '%');
- return new(tree.Quoted)('"' + str + '"', str);
- },
- round: function (n) {
- if (n instanceof tree.Dimension) {
- return new(tree.Dimension)(Math.round(number(n)), n.unit);
- } else if (typeof(n) === 'number') {
- return Math.round(n);
- } else {
- throw {
- error: "RuntimeError",
- message: "math functions take numbers as parameters"
- };
- }
- }
-};
-
-function hsla(hsla) {
- return tree.functions.hsla(hsla.h, hsla.s, hsla.l, hsla.a);
-}
-
-function number(n) {
- if (n instanceof tree.Dimension) {
- return parseFloat(n.unit == '%' ? n.value / 100 : n.value);
- } else if (typeof(n) === 'number') {
- return n;
- } else {
- throw {
- error: "RuntimeError",
- message: "color functions take numbers as parameters"
- };
- }
-}
-
-function clamp(val) {
- return Math.min(1, Math.max(0, val));
-}
-
-})(require('less/tree'));
-(function (tree) {
-
-tree.Alpha = function (val) {
- this.value = val;
-};
-tree.Alpha.prototype = {
- toCSS: function () {
- return "alpha(opacity=" +
- (this.value.toCSS ? this.value.toCSS() : this.value) + ")";
- },
- eval: function (env) {
- if (this.value.eval) { this.value = this.value.eval(env) }
- return this;
- }
-};
-
-})(require('less/tree'));
-(function (tree) {
-
-tree.Anonymous = function (string) {
- this.value = string.value || string;
-};
-tree.Anonymous.prototype = {
- toCSS: function () {
- return this.value;
- },
- eval: function () { return this }
-};
-
-})(require('less/tree'));
-(function (tree) {
-
-//
-// A function call node.
-//
-tree.Call = function (name, args, index) {
- this.name = name;
- this.args = args;
- this.index = index;
-};
-tree.Call.prototype = {
- //
- // When evaluating a function call,
- // we either find the function in `tree.functions` [1],
- // in which case we call it, passing the evaluated arguments,
- // or we simply print it out as it appeared originally [2].
- //
- // The *functions.js* file contains the built-in functions.
- //
- // The reason why we evaluate the arguments, is in the case where
- // we try to pass a variable to a function, like: `saturate(@color)`.
- // The function should receive the value, not the variable.
- //
- eval: function (env) {
- var args = this.args.map(function (a) { return a.eval(env) });
-
- if (this.name in tree.functions) { // 1.
- try {
- return tree.functions[this.name].apply(tree.functions, args);
- } catch (e) {
- throw { message: "error evaluating function `" + this.name + "`",
- index: this.index };
- }
- } else { // 2.
- return new(tree.Anonymous)(this.name +
- "(" + args.map(function (a) { return a.toCSS() }).join(', ') + ")");
- }
- },
-
- toCSS: function (env) {
- return this.eval(env).toCSS();
- }
-};
-
-})(require('less/tree'));
-(function (tree) {
-//
-// RGB Colors - #ff0014, #eee
-//
-tree.Color = function (rgb, a) {
- //
- // 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) {
- return parseInt(c, 16);
- });
- } else if (rgb.length == 8) {
- this.alpha = parseInt(rgb.substring(0,2), 16) / 255.0;
- this.rgb = rgb.substr(2).match(/.{2}/g).map(function (c) {
- return parseInt(c, 16);
- });
- } else {
- this.rgb = rgb.split('').map(function (c) {
- return parseInt(c + c, 16);
- });
- }
- this.alpha = typeof(a) === 'number' ? a : 1;
-};
-tree.Color.prototype = {
- eval: function () { return this },
-
- //
- // If we have some transparency, the only way to represent it
- // is via `rgba`. Otherwise, we use the hex representation,
- // which has better compatibility with older browsers.
- // Values are capped between `0` and `255`, rounded and zero-padded.
- //
- toCSS: function () {
- if (this.alpha < 1.0) {
- return "rgba(" + this.rgb.map(function (c) {
- return Math.round(c);
- }).concat(this.alpha).join(', ') + ")";
- } else {
- return '#' + this.rgb.map(function (i) {
- i = Math.round(i);
- i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
- return i.length === 1 ? '0' + i : i;
- }).join('');
- }
- },
-
- //
- // 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 (op, other) {
- var result = [];
-
- if (! (other instanceof tree.Color)) {
- other = other.toColor();
- }
-
- for (var c = 0; c < 3; c++) {
- result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
- }
- return new(tree.Color)(result, this.alpha + other.alpha);
- },
-
- 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, s, l = (max + min) / 2, 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 };
- }
-};
-
-
-})(require('less/tree'));
-(function (tree) {
-
-tree.Comment = function (value, silent) {
- this.value = value;
- this.silent = !!silent;
-};
-tree.Comment.prototype = {
- toCSS: function (env) {
- return env.compress ? '' : this.value;
- },
- eval: function () { return this }
-};
-
-})(require('less/tree'));
-(function (tree) {
-
-//
-// A number with a unit
-//
-tree.Dimension = function (value, unit) {
- this.value = parseFloat(value);
- this.unit = unit || null;
-};
-
-tree.Dimension.prototype = {
- eval: function () { return this },
- toColor: function () {
- return new(tree.Color)([this.value, this.value, this.value]);
- },
- toCSS: function () {
- var css = this.value + this.unit;
- return css;
- },
-
- // In an operation between two Dimensions,
- // we default to the first Dimension's unit,
- // so `1px + 2em` will yield `3px`.
- // In the future, we could implement some unit
- // conversions such that `100cm + 10mm` would yield
- // `101cm`.
- operate: function (op, other) {
- return new(tree.Dimension)
- (tree.operate(op, this.value, other.value),
- this.unit || other.unit);
- }
-};
-
-})(require('less/tree'));
-(function (tree) {
-
-tree.Directive = function (name, value) {
- this.name = name;
- if (Array.isArray(value)) {
- this.ruleset = new(tree.Ruleset)([], value);
- } else {
- this.value = value;
- }
-};
-tree.Directive.prototype = {
- toCSS: function (ctx, env) {
- if (this.ruleset) {
- this.ruleset.root = true;
- return this.name + (env.compress ? '{' : ' {\n ') +
- this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n ') +
- (env.compress ? '}': '\n}\n');
- } else {
- return this.name + ' ' + this.value.toCSS() + ';\n';
- }
- },
- eval: function (env) {
- env.frames.unshift(this);
- this.ruleset = this.ruleset && this.ruleset.eval(env);
- env.frames.shift();
- return this;
- },
- variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
- find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
- rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
-};
-
-})(require('less/tree'));
-(function (tree) {
-
-tree.Element = function (combinator, value) {
- this.combinator = combinator instanceof tree.Combinator ?
- combinator : new(tree.Combinator)(combinator);
- this.value = value ? value.trim() : "";
-};
-tree.Element.prototype.toCSS = function (env) {
- return this.combinator.toCSS(env || {}) + this.value;
-};
-
-tree.Combinator = function (value) {
- if (value === ' ') {
- this.value = ' ';
- } else if (value === '& ') {
- this.value = '& ';
- } else {
- this.value = value ? value.trim() : "";
- }
-};
-tree.Combinator.prototype.toCSS = function (env) {
- return {
- '' : '',
- ' ' : ' ',
- '&' : '',
- '& ' : ' ',
- ':' : ' :',
- '::': '::',
- '+' : env.compress ? '+' : ' + ',
- '~' : env.compress ? '~' : ' ~ ',
- '>' : env.compress ? '>' : ' > '
- }[this.value];
-};
-
-})(require('less/tree'));
-(function (tree) {
-
-tree.Expression = function (value) { this.value = value };
-tree.Expression.prototype = {
- eval: function (env) {
- if (this.value.length > 1) {
- return new(tree.Expression)(this.value.map(function (e) {
- return e.eval(env);
- }));
- } else if (this.value.length === 1) {
- return this.value[0].eval(env);
- } else {
- return this;
- }
- },
- toCSS: function (env) {
- return this.value.map(function (e) {
- return e.toCSS(env);
- }).join(' ');
- }
-};
-
-})(require('less/tree'));
-(function (tree) {
-//
-// CSS @import node
-//
-// The general strategy here is that we don't want to wait
-// for the parsing to be completed, before we start importing
-// the file. That's because in the context of a browser,
-// most of the time will be spent waiting for the server to respond.
-//
-// On creation, we push the import path to our import queue, though
-// `import,push`, we also pass it a callback, which it'll call once
-// the file has been fetched, and parsed.
-//
-tree.Import = function (path, imports) {
- var that = this;
-
- this._path = path;
-
- // The '.less' extension is optional
- if (path instanceof tree.Quoted) {
- this.path = /\.(le?|c)ss$/.test(path.value) ? path.value : path.value + '.less';
- } else {
- this.path = path.value.value || path.value;
- }
-
- this.css = /css$/.test(this.path);
-
- // Only pre-compile .less files
- if (! this.css) {
- imports.push(this.path, function (root) {
- if (! root) {
- throw new(Error)("Error parsing " + that.path);
- }
- that.root = root;
- });
- }
-};
-
-//
-// The actual import node doesn't return anything, when converted to CSS.
-// The reason is that it's used at the evaluation stage, so that the rules
-// it imports can be treated like any other rules.
-//
-// In `eval`, we make sure all Import nodes get evaluated, recursively, so
-// we end up with a flat structure, which can easily be imported in the parent
-// ruleset.
-//
-tree.Import.prototype = {
- toCSS: function () {
- if (this.css) {
- return "@import " + this._path.toCSS() + ';\n';
- } else {
- return "";
- }
- },
- eval: function (env) {
- var ruleset;
-
- if (this.css) {
- return this;
- } else {
- ruleset = new(tree.Ruleset)(null, this.root.rules.slice(0));
-
- for (var i = 0; i < ruleset.rules.length; i++) {
- if (ruleset.rules[i] instanceof tree.Import) {
- Array.prototype
- .splice
- .apply(ruleset.rules,
- [i, 1].concat(ruleset.rules[i].eval(env)));
- }
- }
- return ruleset.rules;
- }
- }
-};
-
-})(require('less/tree'));
-(function (tree) {
-
-tree.JavaScript = function (string, index, escaped) {
- this.escaped = escaped;
- this.expression = string;
- this.index = index;
-};
-tree.JavaScript.prototype = {
- eval: function (env) {
- var result,
- that = this,
- context = {};
-
- var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
- return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env));
- });
-
- try {
- expression = new(Function)('return (' + expression + ')');
- } catch (e) {
- throw { message: "JavaScript evaluation error: `" + expression + "`" ,
- index: this.index };
- }
-
- for (var k in env.frames[0].variables()) {
- context[k.slice(1)] = {
- value: env.frames[0].variables()[k].value,
- toJS: function () {
- return this.value.eval(env).toCSS();
- }
- };
- }
-
- try {
- result = expression.call(context);
- } catch (e) {
- throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
- index: this.index };
- }
- if (typeof(result) === 'string') {
- return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index);
- } else if (Array.isArray(result)) {
- return new(tree.Anonymous)(result.join(', '));
- } else {
- return new(tree.Anonymous)(result);
- }
- }
-};
-
-})(require('less/tree'));
-
-(function (tree) {
-
-tree.Keyword = function (value) { this.value = value };
-tree.Keyword.prototype = {
- eval: function () { return this },
- toCSS: function () { return this.value }
-};
-
-})(require('less/tree'));
-(function (tree) {
-
-tree.mixin = {};
-tree.mixin.Call = function (elements, args, index) {
- this.selector = new(tree.Selector)(elements);
- this.arguments = args;
- this.index = index;
-};
-tree.mixin.Call.prototype = {
- eval: function (env) {
- var mixins, args, rules = [], match = false;
-
- for (var i = 0; i < env.frames.length; i++) {
- if ((mixins = env.frames[i].find(this.selector)).length > 0) {
- args = this.arguments && this.arguments.map(function (a) { return a.eval(env) });
- for (var m = 0; m < mixins.length; m++) {
- if (mixins[m].match(args, env)) {
- try {
- Array.prototype.push.apply(
- rules, mixins[m].eval(env, this.arguments).rules);
- match = true;
- } catch (e) {
- throw { message: e.message, index: e.index, stack: e.stack, call: this.index };
- }
- }
- }
- if (match) {
- return rules;
- } else {
- throw { message: 'No matching definition was found for `' +
- this.selector.toCSS().trim() + '(' +
- this.arguments.map(function (a) {
- return a.toCSS();
- }).join(', ') + ")`",
- index: this.index };
- }
- }
- }
- throw { message: this.selector.toCSS().trim() + " is undefined",
- index: this.index };
- }
-};
-
-tree.mixin.Definition = function (name, params, rules) {
- this.name = name;
- this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
- this.params = params;
- this.arity = params.length;
- this.rules = rules;
- this._lookups = {};
- this.required = params.reduce(function (count, p) {
- if (!p.name || (p.name && !p.value)) { return count + 1 }
- else { return count }
- }, 0);
- this.parent = tree.Ruleset.prototype;
- this.frames = [];
-};
-tree.mixin.Definition.prototype = {
- toCSS: function () { return "" },
- variable: function (name) { return this.parent.variable.call(this, name) },
- variables: function () { return this.parent.variables.call(this) },
- find: function () { return this.parent.find.apply(this, arguments) },
- rulesets: function () { return this.parent.rulesets.apply(this) },
-
- eval: function (env, args) {
- var frame = new(tree.Ruleset)(null, []), context, _arguments = [];
-
- for (var i = 0, val; i < this.params.length; i++) {
- if (this.params[i].name) {
- if (val = (args && args[i]) || this.params[i].value) {
- frame.rules.unshift(new(tree.Rule)(this.params[i].name, val.eval(env)));
- } else {
- throw { message: "wrong number of arguments for " + this.name +
- ' (' + args.length + ' for ' + this.arity + ')' };
- }
- }
- }
- for (var i = 0; i < Math.max(this.params.length, args && args.length); i++) {
- _arguments.push(args[i] || this.params[i].value);
- }
- frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
-
- return new(tree.Ruleset)(null, this.rules.slice(0)).eval({
- frames: [this, frame].concat(this.frames, env.frames)
- });
- },
- match: function (args, env) {
- var argsLength = (args && args.length) || 0, len;
-
- if (argsLength < this.required) { return false }
- if ((this.required > 0) && (argsLength > this.params.length)) { return false }
-
- len = Math.min(argsLength, this.arity);
-
- for (var i = 0; i < len; i++) {
- if (!this.params[i].name) {
- if (args[i].eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
- return false;
- }
- }
- }
- return true;
- }
-};
-
-})(require('less/tree'));
-(function (tree) {
-
-tree.Operation = function (op, operands) {
- this.op = op.trim();
- this.operands = operands;
-};
-tree.Operation.prototype.eval = function (env) {
- var a = this.operands[0].eval(env),
- b = this.operands[1].eval(env),
- temp;
-
- if (a instanceof tree.Dimension && b instanceof tree.Color) {
- if (this.op === '*' || this.op === '+') {
- temp = b, b = a, a = temp;
- } else {
- throw { name: "OperationError",
- message: "Can't substract or divide a color from a number" };
- }
- }
- return a.operate(this.op, b);
-};
-
-tree.operate = function (op, a, b) {
- switch (op) {
- case '+': return a + b;
- case '-': return a - b;
- case '*': return a * b;
- case '/': return a / b;
- }
-};
-
-})(require('less/tree'));
-(function (tree) {
-
-tree.Quoted = function (str, content, escaped, i) {
- this.escaped = escaped;
- this.value = content || '';
- this.quote = str.charAt(0);
- this.index = i;
-};
-tree.Quoted.prototype = {
- toCSS: function () {
- if (this.escaped) {
- return this.value;
- } else {
- return this.quote + this.value + this.quote;
- }
- },
- eval: function (env) {
- var that = this;
- var value = this.value.replace(/`([^`]+)`/g, function (_, exp) {
- return new(tree.JavaScript)(exp, that.index, true).eval(env).value;
- }).replace(/@\{([\w-]+)\}/g, function (_, name) {
- var v = new(tree.Variable)('@' + name, that.index).eval(env);
- return v.value || v.toCSS();
- });
- return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index);
- }
-};
-
-})(require('less/tree'));
-(function (tree) {
-
-tree.Rule = function (name, value, important, index) {
- this.name = name;
- this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
- this.important = important ? ' ' + important.trim() : '';
- this.index = index;
-
- if (name.charAt(0) === '@') {
- this.variable = true;
- } else { this.variable = false }
-};
-tree.Rule.prototype.toCSS = function (env) {
- if (this.variable) { return "" }
- else {
- return this.name + (env.compress ? ':' : ': ') +
- this.value.toCSS(env) +
- this.important + ";";
- }
-};
-
-tree.Rule.prototype.eval = function (context) {
- return new(tree.Rule)(this.name, this.value.eval(context), this.important, this.index);
-};
-
-tree.Shorthand = function (a, b) {
- this.a = a;
- this.b = b;
-};
-
-tree.Shorthand.prototype = {
- toCSS: function (env) {
- return this.a.toCSS(env) + "/" + this.b.toCSS(env);
- },
- eval: function () { return this }
-};
-
-})(require('less/tree'));
-(function (tree) {
-
-tree.Ruleset = function (selectors, rules) {
- this.selectors = selectors;
- this.rules = rules;
- this._lookups = {};
-};
-tree.Ruleset.prototype = {
- eval: function (env) {
- var ruleset = new(tree.Ruleset)(this.selectors, this.rules.slice(0));
-
- ruleset.root = this.root;
-
- // push the current ruleset to the frames stack
- env.frames.unshift(ruleset);
-
- // Evaluate imports
- if (ruleset.root) {
- for (var i = 0; i < ruleset.rules.length; i++) {
- if (ruleset.rules[i] instanceof tree.Import) {
- Array.prototype.splice
- .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
- }
- }
- }
-
- // Store the frames around mixin definitions,
- // so they can be evaluated like closures when the time comes.
- for (var i = 0; i < ruleset.rules.length; i++) {
- if (ruleset.rules[i] instanceof tree.mixin.Definition) {
- ruleset.rules[i].frames = env.frames.slice(0);
- }
- }
-
- // Evaluate mixin calls.
- for (var i = 0; i < ruleset.rules.length; i++) {
- if (ruleset.rules[i] instanceof tree.mixin.Call) {
- Array.prototype.splice
- .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
- }
- }
-
- // Evaluate everything else
- for (var i = 0, rule; i < ruleset.rules.length; i++) {
- rule = ruleset.rules[i];
-
- if (! (rule instanceof tree.mixin.Definition)) {
- ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
- }
- }
-
- // Pop the stack
- env.frames.shift();
-
- return ruleset;
- },
- match: function (args) {
- return !args || args.length === 0;
- },
- variables: function () {
- if (this._variables) { return this._variables }
- else {
- return this._variables = this.rules.reduce(function (hash, r) {
- if (r instanceof tree.Rule && r.variable === true) {
- hash[r.name] = r;
- }
- return hash;
- }, {});
- }
- },
- variable: function (name) {
- return this.variables()[name];
- },
- rulesets: function () {
- if (this._rulesets) { return this._rulesets }
- else {
- return this._rulesets = this.rules.filter(function (r) {
- return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
- });
- }
- },
- find: function (selector, self) {
- self = self || this;
- var rules = [], rule, match,
- key = selector.toCSS();
-
- if (key in this._lookups) { return this._lookups[key] }
-
- this.rulesets().forEach(function (rule) {
- if (rule !== self) {
- for (var j = 0; j < rule.selectors.length; j++) {
- if (match = selector.match(rule.selectors[j])) {
- if (selector.elements.length > 1) {
- Array.prototype.push.apply(rules, rule.find(
- new(tree.Selector)(selector.elements.slice(1)), self));
- } else {
- rules.push(rule);
- }
- break;
- }
- }
- }
- });
- return this._lookups[key] = rules;
- },
- //
- // Entry point for code generation
- //
- // `context` holds an array of arrays.
- //
- toCSS: function (context, env) {
- var css = [], // The CSS output
- rules = [], // node.Rule instances
- rulesets = [], // node.Ruleset instances
- paths = [], // Current selectors
- selector, // The fully rendered selector
- rule;
-
- if (! this.root) {
- if (context.length === 0) {
- paths = this.selectors.map(function (s) { return [s] });
- } else {
- this.joinSelectors( paths, context, this.selectors );
- }
- }
-
- // Compile rules and rulesets
- for (var i = 0; i < this.rules.length; i++) {
- rule = this.rules[i];
-
- if (rule.rules || (rule instanceof tree.Directive)) {
- rulesets.push(rule.toCSS(paths, env));
- } else if (rule instanceof tree.Comment) {
- if (!rule.silent) {
- if (this.root) {
- rulesets.push(rule.toCSS(env));
- } else {
- rules.push(rule.toCSS(env));
- }
- }
- } else {
- if (rule.toCSS && !rule.variable) {
- rules.push(rule.toCSS(env));
- } else if (rule.value && !rule.variable) {
- rules.push(rule.value.toString());
- }
- }
- }
-
- rulesets = rulesets.join('');
-
- // If this is the root node, we don't render
- // a selector, or {}.
- // Otherwise, only output if this ruleset has rules.
- if (this.root) {
- css.push(rules.join(env.compress ? '' : '\n'));
- } else {
- if (rules.length > 0) {
- selector = paths.map(function (p) {
- return p.map(function (s) {
- return s.toCSS(env);
- }).join('').trim();
- }).join(env.compress ? ',' : (paths.length > 3 ? ',\n' : ', '));
- css.push(selector,
- (env.compress ? '{' : ' {\n ') +
- rules.join(env.compress ? '' : '\n ') +
- (env.compress ? '}' : '\n}\n'));
- }
- }
- css.push(rulesets);
-
- return css.join('') + (env.compress ? '\n' : '');
- },
-
- joinSelectors: function( paths, context, selectors ) {
- for (var s = 0; s < selectors.length; s++) {
- this.joinSelector(paths, context, selectors[s]);
- }
- },
-
- joinSelector: function( paths, context, selector ) {
- var before = [], after = [], beforeElements = [], afterElements = [], hasParentSelector = false, el;
-
- for (var i = 0; i < selector.elements.length; i++) {
- el = selector.elements[i];
- if (el.combinator.value[0] === '&') {
- hasParentSelector = true;
- }
- if(!hasParentSelector) {
- beforeElements.push(el);
- } else {
- afterElements.push(el);
- }
- }
-
- if(!hasParentSelector) {
- afterElements = beforeElements;
- beforeElements = [];
- }
-
- if(beforeElements.length > 0) {
- before.push(new (tree.Selector)(beforeElements));
- }
- if(afterElements.length > 0) {
- after.push(new (tree.Selector)(afterElements));
- }
-
- for (var c = 0; c < context.length; c++) {
- paths.push(before.concat(context[c]).concat(after));
- }
- }
-};
-})(require('less/tree'));
-(function (tree) {
-
-tree.Selector = function (elements) {
- this.elements = elements;
- if (this.elements[0].combinator.value === "") {
- this.elements[0].combinator.value = ' ';
- }
-};
-tree.Selector.prototype.match = function (other) {
- if (this.elements[0].value === other.elements[0].value) {
- return true;
- } else {
- return false;
- }
-};
-tree.Selector.prototype.toCSS = function (env) {
- if (this._css) { return this._css }
-
- return this._css = this.elements.map(function (e) {
- if (typeof(e) === 'string') {
- return ' ' + e.trim();
- } else {
- return e.toCSS(env);
- }
- }).join('');
-};
-
-})(require('less/tree'));
-(function (tree) {
-
-tree.URL = function (val, paths) {
- if (val.data) {
- this.attrs = val;
- } else {
- // Add the base path if the URL is relative and we are in the browser
- if (!/^(?:https?:\/|file:\/|data:\/)?\//.test(val.value) && paths.length > 0 && typeof(window) !== 'undefined') {
- val.value = paths[0] + (val.value.charAt(0) === '/' ? val.value.slice(1) : val.value);
- }
- this.value = val;
- this.paths = paths;
- }
-};
-tree.URL.prototype = {
- toCSS: function () {
- return "url(" + (this.attrs ? 'data:' + this.attrs.mime + this.attrs.charset + this.attrs.base64 + this.attrs.data
- : this.value.toCSS()) + ")";
- },
- eval: function (ctx) {
- return this.attrs ? this : new(tree.URL)(this.value.eval(ctx), this.paths);
- }
-};
-
-})(require('less/tree'));
-(function (tree) {
-
-tree.Value = function (value) {
- this.value = value;
- this.is = 'value';
-};
-tree.Value.prototype = {
- eval: function (env) {
- if (this.value.length === 1) {
- return this.value[0].eval(env);
- } else {
- return new(tree.Value)(this.value.map(function (v) {
- return v.eval(env);
- }));
- }
- },
- toCSS: function (env) {
- return this.value.map(function (e) {
- return e.toCSS(env);
- }).join(env.compress ? ',' : ', ');
- }
-};
-
-})(require('less/tree'));
-(function (tree) {
-
-tree.Variable = function (name, index) { this.name = name, this.index = index };
-tree.Variable.prototype = {
- eval: function (env) {
- var variable, v, name = this.name;
-
- if (name.indexOf('@@') == 0) {
- name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
- }
-
- if (variable = tree.find(env.frames, function (frame) {
- if (v = frame.variable(name)) {
- return v.value.eval(env);
- }
- })) { return variable }
- else {
- throw { message: "variable " + name + " is undefined",
- index: this.index };
- }
- }
-};
-
-})(require('less/tree'));
-require('less/tree').find = function (obj, fun) {
- for (var i = 0, r; i < obj.length; i++) {
- if (r = fun.call(obj, obj[i])) { return r }
- }
- return null;
-};
-require('less/tree').jsify = function (obj) {
- if (Array.isArray(obj.value) && (obj.value.length > 1)) {
- return '[' + obj.value.map(function (v) { return v.toCSS(false) }).join(', ') + ']';
- } else {
- return obj.toCSS(false);
- }
-};
-var name;
-
-function loadStyleSheet(sheet, callback, reload, remaining) {
- var sheetName = name.slice(0, name.lastIndexOf('/') + 1) + sheet.href;
- var input = readFile(sheetName);
- var parser = new less.Parser();
- parser.parse(input, function (e, root) {
- if (e) {
- print("Error: " + e);
- quit(1);
- }
- callback(root, sheet, { local: false, lastModified: 0, remaining: remaining });
- });
-
- // callback({}, sheet, { local: true, remaining: remaining });
-}
-
-function writeFile(filename, content) {
- var fstream = new java.io.FileWriter(filename);
- var out = new java.io.BufferedWriter(fstream);
- out.write(content);
- out.close();
-}
-
-// Command line integration via Rhino
-(function (args) {
- name = args[0];
- var output = args[1];
-
- if (!name) {
- print('No files present in the fileset; Check your pattern match in build.xml');
- quit(1);
- }
- path = name.split("/");path.pop();path=path.join("/")
-
- var input = readFile(name);
-
- if (!input) {
- print('lesscss: couldn\'t open file ' + name);
- quit(1);
- }
-
- var result;
- var parser = new less.Parser();
- parser.parse(input, function (e, root) {
- if (e) {
- quit(1);
- } else {
- result = root.toCSS();
- if (output) {
- writeFile(output, result);
- print("Written to " + output);
- } else {
- print(result);
- }
- quit(0);
- }
- });
- print("done");
-}(arguments));
diff --git a/dist/less-rhino-1.1.5.js b/dist/less-rhino-1.1.5.js
deleted file mode 100644
index e755f6310..000000000
--- a/dist/less-rhino-1.1.5.js
+++ /dev/null
@@ -1,2481 +0,0 @@
-//
-// Stub out `require` in rhino
-//
-function require(arg) {
- return less[arg.split('/')[1]];
-};
-
-
-// ecma-5.js
-//
-// -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
-// -- tlrobinson Tom Robinson
-// dantman Daniel Friesen
-
-//
-// Array
-//
-if (!Array.isArray) {
- Array.isArray = function(obj) {
- return Object.prototype.toString.call(obj) === "[object Array]" ||
- (obj instanceof Array);
- };
-}
-if (!Array.prototype.forEach) {
- Array.prototype.forEach = function(block, thisObject) {
- var len = this.length >>> 0;
- for (var i = 0; i < len; i++) {
- if (i in this) {
- block.call(thisObject, this[i], i, this);
- }
- }
- };
-}
-if (!Array.prototype.map) {
- Array.prototype.map = function(fun /*, thisp*/) {
- var len = this.length >>> 0;
- var res = new Array(len);
- var thisp = arguments[1];
-
- for (var i = 0; i < len; i++) {
- if (i in this) {
- res[i] = fun.call(thisp, this[i], i, this);
- }
- }
- return res;
- };
-}
-if (!Array.prototype.filter) {
- Array.prototype.filter = function (block /*, thisp */) {
- var values = [];
- var thisp = arguments[1];
- for (var i = 0; i < this.length; i++) {
- if (block.call(thisp, this[i])) {
- values.push(this[i]);
- }
- }
- return values;
- };
-}
-if (!Array.prototype.reduce) {
- Array.prototype.reduce = function(fun /*, initial*/) {
- var len = this.length >>> 0;
- var i = 0;
-
- // no value to return if no initial value and an empty array
- if (len === 0 && arguments.length === 1) throw new TypeError();
-
- if (arguments.length >= 2) {
- var rv = arguments[1];
- } else {
- do {
- if (i in this) {
- rv = this[i++];
- break;
- }
- // if array contains no values, no initial value to return
- if (++i >= len) throw new TypeError();
- } while (true);
- }
- for (; i < len; i++) {
- if (i in this) {
- rv = fun.call(null, rv, this[i], i, this);
- }
- }
- return rv;
- };
-}
-if (!Array.prototype.indexOf) {
- Array.prototype.indexOf = function (value /*, fromIndex */ ) {
- var length = this.length;
- var i = arguments[1] || 0;
-
- if (!length) return -1;
- if (i >= length) return -1;
- if (i < 0) i += length;
-
- for (; i < length; i++) {
- if (!Object.prototype.hasOwnProperty.call(this, i)) { continue }
- if (value === this[i]) return i;
- }
- return -1;
- };
-}
-
-//
-// Object
-//
-if (!Object.keys) {
- Object.keys = function (object) {
- var keys = [];
- for (var name in object) {
- if (Object.prototype.hasOwnProperty.call(object, name)) {
- keys.push(name);
- }
- }
- return keys;
- };
-}
-
-//
-// String
-//
-if (!String.prototype.trim) {
- String.prototype.trim = function () {
- return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
- };
-}
-var less, tree;
-
-if (typeof environment === "object" && ({}).toString.call(environment) === "[object Environment]") {
- // Rhino
- // Details on how to detect Rhino: https://github.com/ringo/ringojs/issues/88
- less = {};
- tree = less.tree = {};
- less.mode = 'rhino';
-} else if (typeof(window) === 'undefined') {
- // Node.js
- less = exports,
- tree = require('./tree');
- less.mode = 'rhino';
-} else {
- // Browser
- if (typeof(window.less) === 'undefined') { window.less = {} }
- less = window.less,
- tree = window.less.tree = {};
- less.mode = 'browser';
-}
-//
-// less.js - parser
-//
-// A relatively straight-forward predictive parser.
-// There is no tokenization/lexing stage, the input is parsed
-// in one sweep.
-//
-// To make the parser fast enough to run in the browser, several
-// optimization had to be made:
-//
-// - Matching and slicing on a huge input is often cause of slowdowns.
-// The solution is to chunkify the input into smaller strings.
-// The chunks are stored in the `chunks` var,
-// `j` holds the current chunk index, and `current` holds
-// the index of the current chunk in relation to `input`.
-// This gives us an almost 4x speed-up.
-//
-// - In many cases, we don't need to match individual tokens;
-// for example, if a value doesn't hold any variables, operations
-// or dynamic references, the parser can effectively 'skip' it,
-// treating it as a literal.
-// An example would be '1px solid #000' - which evaluates to itself,
-// we don't need to know what the individual components are.
-// The drawback, of course is that you don't get the benefits of
-// syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
-// and a smaller speed-up in the code-gen.
-//
-//
-// Token matching is done with the `$` function, which either takes
-// a terminal string or regexp, or a non-terminal function to call.
-// It also takes care of moving all the indices forwards.
-//
-//
-less.Parser = function Parser(env) {
- var input, // LeSS input string
- i, // current index in `input`
- j, // current chunk
- temp, // temporarily holds a chunk's state, for backtracking
- memo, // temporarily holds `i`, when backtracking
- furthest, // furthest index the parser has gone to
- chunks, // chunkified input
- current, // index of current chunk, in `input`
- parser;
-
- var that = this;
-
- // This function is called after all files
- // have been imported through `@import`.
- var finish = function () {};
-
- var imports = this.imports = {
- paths: env && env.paths || [], // Search paths, when importing
- queue: [], // Files which haven't been imported yet
- files: {}, // Holds the imported parse trees
- mime: env && env.mime, // MIME type of .less files
- push: function (path, callback) {
- var that = this;
- this.queue.push(path);
-
- //
- // Import a file asynchronously
- //
- less.Parser.importer(path, this.paths, function (root) {
- that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
- that.files[path] = root; // Store the root
-
- callback(root);
-
- if (that.queue.length === 0) { finish() } // Call `finish` if we're done importing
- }, env);
- }
- };
-
- function save() { temp = chunks[j], memo = i, current = i }
- function restore() { chunks[j] = temp, i = memo, current = i }
-
- function sync() {
- if (i > current) {
- chunks[j] = chunks[j].slice(i - current);
- current = i;
- }
- }
- //
- // Parse from a token, regexp or string, and move forward if match
- //
- function $(tok) {
- var match, args, length, c, index, endIndex, k, mem;
-
- //
- // Non-terminal
- //
- if (tok instanceof Function) {
- return tok.call(parser.parsers);
- //
- // Terminal
- //
- // Either match a single character in the input,
- // or match a regexp in the current chunk (chunk[j]).
- //
- } else if (typeof(tok) === 'string') {
- match = input.charAt(i) === tok ? tok : null;
- length = 1;
- sync ();
- } else {
- sync ();
-
- if (match = tok.exec(chunks[j])) {
- length = match[0].length;
- } else {
- return null;
- }
- }
-
- // The match is confirmed, add the match length to `i`,
- // and consume any extra white-space characters (' ' || '\n')
- // which come after that. The reason for this is that LeSS's
- // grammar is mostly white-space insensitive.
- //
- if (match) {
- mem = i += length;
- endIndex = i + chunks[j].length - length;
-
- while (i < endIndex) {
- c = input.charCodeAt(i);
- if (! (c === 32 || c === 10 || c === 9)) { break }
- i++;
- }
- chunks[j] = chunks[j].slice(length + (i - mem));
- current = i;
-
- if (chunks[j].length === 0 && j < chunks.length - 1) { j++ }
-
- if(typeof(match) === 'string') {
- return match;
- } else {
- return match.length === 1 ? match[0] : match;
- }
- }
- }
-
- // Same as $(), but don't change the state of the parser,
- // just return the match.
- function peek(tok) {
- if (typeof(tok) === 'string') {
- return input.charAt(i) === tok;
- } else {
- if (tok.test(chunks[j])) {
- return true;
- } else {
- return false;
- }
- }
- }
-
- this.env = env = env || {};
-
- // The optimization level dictates the thoroughness of the parser,
- // the lower the number, the less nodes it will create in the tree.
- // This could matter for debugging, or if you want to access
- // the individual nodes in the tree.
- this.optimization = ('optimization' in this.env) ? this.env.optimization : 1;
-
- this.env.filename = this.env.filename || null;
-
- //
- // The Parser
- //
- return parser = {
-
- imports: imports,
- //
- // Parse an input string into an abstract syntax tree,
- // call `callback` when done.
- //
- parse: function (str, callback) {
- var root, start, end, zone, line, lines, buff = [], c, error = null;
-
- i = j = current = furthest = 0;
- chunks = [];
- input = str.replace(/\r\n/g, '\n');
-
- // Split the input into chunks.
- chunks = (function (chunks) {
- var j = 0,
- skip = /[^"'`\{\}\/\(\)]+/g,
- comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
- level = 0,
- match,
- chunk = chunks[0],
- inParam,
- inString;
-
- for (var i = 0, c, cc; i < input.length; i++) {
- skip.lastIndex = i;
- if (match = skip.exec(input)) {
- if (match.index === i) {
- i += match[0].length;
- chunk.push(match[0]);
- }
- }
- c = input.charAt(i);
- comment.lastIndex = i;
-
- if (!inString && !inParam && c === '/') {
- cc = input.charAt(i + 1);
- if (cc === '/' || cc === '*') {
- if (match = comment.exec(input)) {
- if (match.index === i) {
- i += match[0].length;
- chunk.push(match[0]);
- c = input.charAt(i);
- }
- }
- }
- }
-
- if (c === '{' && !inString && !inParam) { level ++;
- chunk.push(c);
- } else if (c === '}' && !inString && !inParam) { level --;
- chunk.push(c);
- chunks[++j] = chunk = [];
- } else if (c === '(' && !inString && !inParam) {
- chunk.push(c);
- inParam = true;
- } else if (c === ')' && !inString && inParam) {
- chunk.push(c);
- inParam = false;
- } else {
- if (c === '"' || c === "'" || c === '`') {
- if (! inString) {
- inString = c;
- } else {
- inString = inString === c ? false : inString;
- }
- }
- chunk.push(c);
- }
- }
- if (level > 0) {
- throw {
- type: 'Syntax',
- message: "Missing closing `}`",
- filename: env.filename
- };
- }
-
- return chunks.map(function (c) { return c.join('') });;
- })([[]]);
-
- // Start with the primary rule.
- // The whole syntax tree is held under a Ruleset node,
- // with the `root` property set to true, so no `{}` are
- // output. The callback is called when the input is parsed.
- root = new(tree.Ruleset)([], $(this.parsers.primary));
- root.root = true;
-
- root.toCSS = (function (evaluate) {
- var line, lines, column;
-
- return function (options, variables) {
- var frames = [];
-
- options = options || {};
- //
- // Allows setting variables with a hash, so:
- //
- // `{ color: new(tree.Color)('#f01') }` will become:
- //
- // new(tree.Rule)('@color',
- // new(tree.Value)([
- // new(tree.Expression)([
- // new(tree.Color)('#f01')
- // ])
- // ])
- // )
- //
- if (typeof(variables) === 'object' && !Array.isArray(variables)) {
- variables = Object.keys(variables).map(function (k) {
- var value = variables[k];
-
- if (! (value instanceof tree.Value)) {
- if (! (value instanceof tree.Expression)) {
- value = new(tree.Expression)([value]);
- }
- value = new(tree.Value)([value]);
- }
- return new(tree.Rule)('@' + k, value, false, 0);
- });
- frames = [new(tree.Ruleset)(null, variables)];
- }
-
- try {
- var css = evaluate.call(this, { frames: frames })
- .toCSS([], { compress: options.compress || false });
- } catch (e) {
- lines = input.split('\n');
- line = getLine(e.index);
-
- for (var n = e.index, column = -1;
- n >= 0 && input.charAt(n) !== '\n';
- n--) { column++ }
-
- throw {
- type: e.type,
- message: e.message,
- filename: env.filename,
- index: e.index,
- line: typeof(line) === 'number' ? line + 1 : null,
- callLine: e.call && (getLine(e.call) + 1),
- callExtract: lines[getLine(e.call)],
- stack: e.stack,
- column: column,
- extract: [
- lines[line - 1],
- lines[line],
- lines[line + 1]
- ]
- };
- }
- if (options.compress) {
- return css.replace(/(\s)+/g, "$1");
- } else {
- return css;
- }
-
- function getLine(index) {
- return index ? (input.slice(0, index).match(/\n/g) || "").length : null;
- }
- };
- })(root.eval);
-
- // If `i` is smaller than the `input.length - 1`,
- // it means the parser wasn't able to parse the whole
- // string, so we've got a parsing error.
- //
- // We try to extract a \n delimited string,
- // showing the line where the parse error occured.
- // We split it up into two parts (the part which parsed,
- // and the part which didn't), so we can color them differently.
- if (i < input.length - 1) {
- i = furthest;
- lines = input.split('\n');
- line = (input.slice(0, i).match(/\n/g) || "").length + 1;
-
- for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }
-
- error = {
- name: "ParseError",
- message: "Syntax Error on line " + line,
- index: i,
- filename: env.filename,
- line: line,
- column: column,
- extract: [
- lines[line - 2],
- lines[line - 1],
- lines[line]
- ]
- };
- }
-
- if (this.imports.queue.length > 0) {
- finish = function () { callback(error, root) };
- } else {
- callback(error, root);
- }
- },
-
- //
- // Here in, the parsing rules/functions
- //
- // The basic structure of the syntax tree generated is as follows:
- //
- // Ruleset -> Rule -> Value -> Expression -> Entity
- //
- // Here's some LESS code:
- //
- // .class {
- // color: #fff;
- // border: 1px solid #000;
- // width: @w + 4px;
- // > .child {...}
- // }
- //
- // And here's what the parse tree might look like:
- //
- // Ruleset (Selector '.class', [
- // Rule ("color", Value ([Expression [Color #fff]]))
- // Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
- // Rule ("width", Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
- // Ruleset (Selector [Element '>', '.child'], [...])
- // ])
- //
- // In general, most rules will try to parse a token with the `$()` function, and if the return
- // value is truly, will return a new node, of the relevant type. Sometimes, we need to check
- // first, before parsing, that's when we use `peek()`.
- //
- parsers: {
- //
- // The `primary` rule is the *entry* and *exit* point of the parser.
- // The rules here can appear at any level of the parse tree.
- //
- // The recursive nature of the grammar is an interplay between the `block`
- // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
- // as represented by this simplified grammar:
- //
- // primary → (ruleset | rule)+
- // ruleset → selector+ block
- // block → '{' primary '}'
- //
- // Only at one point is the primary rule not called from the
- // block rule: at the root level.
- //
- primary: function () {
- var node, root = [];
-
- while ((node = $(this.mixin.definition) || $(this.rule) || $(this.ruleset) ||
- $(this.mixin.call) || $(this.comment) || $(this.directive))
- || $(/^[\s\n]+/)) {
- node && root.push(node);
- }
- return root;
- },
-
- // We create a Comment node for CSS comments `/* */`,
- // but keep the LeSS comments `//` silent, by just skipping
- // over them.
- comment: function () {
- var comment;
-
- if (input.charAt(i) !== '/') return;
-
- if (input.charAt(i + 1) === '/') {
- return new(tree.Comment)($(/^\/\/.*/), true);
- } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) {
- return new(tree.Comment)(comment);
- }
- },
-
- //
- // Entities are tokens which can be found inside an Expression
- //
- entities: {
- //
- // A string, which supports escaping " and '
- //
- // "milky way" 'he\'s the one!'
- //
- quoted: function () {
- var str, j = i, e;
-
- if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
- if (input.charAt(j) !== '"' && input.charAt(j) !== "'") return;
-
- e && $('~');
-
- if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) {
- return new(tree.Quoted)(str[0], str[1] || str[2], e);
- }
- },
-
- //
- // A catch-all word, such as:
- //
- // black border-collapse
- //
- keyword: function () {
- var k;
- if (k = $(/^[_A-Za-z-][_A-Za-z0-9-]*/)) { return new(tree.Keyword)(k) }
- },
-
- //
- // A function call
- //
- // rgb(255, 0, 255)
- //
- // We also try to catch IE's `alpha()`, but let the `alpha` parser
- // deal with the details.
- //
- // The arguments are parsed with the `entities.arguments` parser.
- //
- call: function () {
- var name, args, index = i;
-
- if (! (name = /^([\w-]+|%)\(/.exec(chunks[j]))) return;
-
- name = name[1].toLowerCase();
-
- if (name === 'url') { return null }
- else { i += name.length }
-
- if (name === 'alpha') { return $(this.alpha) }
-
- $('('); // Parse the '(' and consume whitespace.
-
- args = $(this.entities.arguments);
-
- if (! $(')')) return;
-
- if (name) { return new(tree.Call)(name, args, index) }
- },
- arguments: function () {
- var args = [], arg;
-
- while (arg = $(this.expression)) {
- args.push(arg);
- if (! $(',')) { break }
- }
- return args;
- },
- literal: function () {
- return $(this.entities.dimension) ||
- $(this.entities.color) ||
- $(this.entities.quoted);
- },
-
- //
- // Parse url() tokens
- //
- // We use a specific rule for urls, because they don't really behave like
- // standard function calls. The difference is that the argument doesn't have
- // to be enclosed within a string, so it can't be parsed as an Expression.
- //
- url: function () {
- var value;
-
- if (input.charAt(i) !== 'u' || !$(/^url\(/)) return;
- value = $(this.entities.quoted) || $(this.entities.variable) ||
- $(this.entities.dataURI) || $(/^[-\w%@$\/.&=:;#+?~]+/) || "";
- if (! $(')')) throw new(Error)("missing closing ) for url()");
-
- return new(tree.URL)((value.value || value.data || value instanceof tree.Variable)
- ? value : new(tree.Anonymous)(value), imports.paths);
- },
-
- dataURI: function () {
- var obj;
-
- if ($(/^data:/)) {
- obj = {};
- obj.mime = $(/^[^\/]+\/[^,;)]+/) || '';
- obj.charset = $(/^;\s*charset=[^,;)]+/) || '';
- obj.base64 = $(/^;\s*base64/) || '';
- obj.data = $(/^,\s*[^)]+/);
-
- if (obj.data) { return obj }
- }
- },
-
- //
- // A Variable entity, such as `@fink`, in
- //
- // width: @fink + 2px
- //
- // We use a different parser for variable definitions,
- // see `parsers.variable`.
- //
- variable: function () {
- var name, index = i;
-
- if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) {
- return new(tree.Variable)(name, index);
- }
- },
-
- //
- // A Hexadecimal color
- //
- // #4F3C2F
- //
- // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
- //
- color: function () {
- var rgb;
-
- if (input.charAt(i) === '#' && (rgb = $(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/))) {
- return new(tree.Color)(rgb[1]);
- }
- },
-
- //
- // A Dimension, that is, a number and a unit
- //
- // 0.5em 95%
- //
- dimension: function () {
- var value, c = input.charCodeAt(i);
- if ((c > 57 || c < 45) || c === 47) return;
-
- if (value = $(/^(-?\d*\.?\d+)(px|%|em|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/)) {
- return new(tree.Dimension)(value[1], value[2]);
- }
- },
-
- //
- // JavaScript code to be evaluated
- //
- // `window.location.href`
- //
- javascript: function () {
- var str, j = i, e;
-
- if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
- if (input.charAt(j) !== '`') { return }
-
- e && $('~');
-
- if (str = $(/^`([^`]*)`/)) {
- return new(tree.JavaScript)(str[1], i, e);
- }
- }
- },
-
- //
- // The variable part of a variable definition. Used in the `rule` parser
- //
- // @fink:
- //
- variable: function () {
- var name;
-
- if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1] }
- },
-
- //
- // A font size/line-height shorthand
- //
- // small/12px
- //
- // We need to peek first, or we'll match on keywords and dimensions
- //
- shorthand: function () {
- var a, b;
-
- if (! peek(/^[@\w.%-]+\/[@\w.-]+/)) return;
-
- if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
- return new(tree.Shorthand)(a, b);
- }
- },
-
- //
- // Mixins
- //
- mixin: {
- //
- // A Mixin call, with an optional argument list
- //
- // #mixins > .square(#fff);
- // .rounded(4px, black);
- // .button;
- //
- // The `while` loop is there because mixins can be
- // namespaced, but we only support the child and descendant
- // selector for now.
- //
- call: function () {
- var elements = [], e, c, args, index = i, s = input.charAt(i);
-
- if (s !== '.' && s !== '#') { return }
-
- while (e = $(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)) {
- elements.push(new(tree.Element)(c, e, i));
- c = $('>');
- }
- $('(') && (args = $(this.entities.arguments)) && $(')');
-
- if (elements.length > 0 && ($(';') || peek('}'))) {
- return new(tree.mixin.Call)(elements, args, index);
- }
- },
-
- //
- // A Mixin definition, with a list of parameters
- //
- // .rounded (@radius: 2px, @color) {
- // ...
- // }
- //
- // Until we have a finer grained state-machine, we have to
- // do a look-ahead, to make sure we don't have a mixin call.
- // See the `rule` function for more information.
- //
- // We start by matching `.rounded (`, and then proceed on to
- // the argument list, which has optional default values.
- // We store the parameters in `params`, with a `value` key,
- // if there is a value, such as in the case of `@radius`.
- //
- // Once we've got our params list, and a closing `)`, we parse
- // the `{...}` block.
- //
- definition: function () {
- var name, params = [], match, ruleset, param, value;
-
- if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') ||
- peek(/^[^{]*(;|})/)) return;
-
- if (match = $(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)) {
- name = match[1];
-
- while (param = $(this.entities.variable) || $(this.entities.literal)
- || $(this.entities.keyword)) {
- // Variable
- if (param instanceof tree.Variable) {
- if ($(':')) {
- if (value = $(this.expression)) {
- params.push({ name: param.name, value: value });
- } else {
- throw new(Error)("Expected value");
- }
- } else {
- params.push({ name: param.name });
- }
- } else {
- params.push({ value: param });
- }
- if (! $(',')) { break }
- }
- if (! $(')')) throw new(Error)("Expected )");
-
- ruleset = $(this.block);
-
- if (ruleset) {
- return new(tree.mixin.Definition)(name, params, ruleset);
- }
- }
- }
- },
-
- //
- // Entities are the smallest recognized token,
- // and can be found inside a rule's value.
- //
- entity: function () {
- return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) ||
- $(this.entities.call) || $(this.entities.keyword) || $(this.entities.javascript) ||
- $(this.comment);
- },
-
- //
- // A Rule terminator. Note that we use `peek()` to check for '}',
- // because the `block` rule will be expecting it, but we still need to make sure
- // it's there, if ';' was ommitted.
- //
- end: function () {
- return $(';') || peek('}');
- },
-
- //
- // IE's alpha function
- //
- // alpha(opacity=88)
- //
- alpha: function () {
- var value;
-
- if (! $(/^\(opacity=/i)) return;
- if (value = $(/^\d+/) || $(this.entities.variable)) {
- if (! $(')')) throw new(Error)("missing closing ) for alpha()");
- return new(tree.Alpha)(value);
- }
- },
-
- //
- // A Selector Element
- //
- // div
- // + h1
- // #socks
- // input[type="text"]
- //
- // Elements are the building blocks for Selectors,
- // they are made out of a `Combinator` (see combinator rule),
- // and an element name, such as a tag a class, or `*`.
- //
- element: function () {
- var e, t, c;
-
- c = $(this.combinator);
- e = $(/^(?:\d+\.\d+|\d+)%/) || $(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/) ||
- $('*') || $(this.attribute) || $(/^\([^)@]+\)/);
-
- if (e) { return new(tree.Element)(c, e, i) }
-
- if (c.value && c.value.charAt(0) === '&') {
- return new(tree.Element)(c, null, i);
- }
- },
-
- //
- // Combinators combine elements together, in a Selector.
- //
- // Because our parser isn't white-space sensitive, special care
- // has to be taken, when parsing the descendant combinator, ` `,
- // as it's an empty space. We have to check the previous character
- // in the input, to see if it's a ` ` character. More info on how
- // we deal with this in *combinator.js*.
- //
- combinator: function () {
- var match, c = input.charAt(i);
-
- if (c === '>' || c === '+' || c === '~') {
- i++;
- while (input.charAt(i) === ' ') { i++ }
- return new(tree.Combinator)(c);
- } else if (c === '&') {
- match = '&';
- i++;
- if(input.charAt(i) === ' ') {
- match = '& ';
- }
- while (input.charAt(i) === ' ') { i++ }
- return new(tree.Combinator)(match);
- } else if (c === ':' && input.charAt(i + 1) === ':') {
- i += 2;
- while (input.charAt(i) === ' ') { i++ }
- return new(tree.Combinator)('::');
- } else if (input.charAt(i - 1) === ' ') {
- return new(tree.Combinator)(" ");
- } else {
- return new(tree.Combinator)(null);
- }
- },
-
- //
- // A CSS Selector
- //
- // .class > div + h1
- // li a:hover
- //
- // Selectors are made out of one or more Elements, see above.
- //
- selector: function () {
- var sel, e, elements = [], c, match;
-
- while (e = $(this.element)) {
- c = input.charAt(i);
- elements.push(e)
- if (c === '{' || c === '}' || c === ';' || c === ',') { break }
- }
-
- if (elements.length > 0) { return new(tree.Selector)(elements) }
- },
- tag: function () {
- return $(/^[a-zA-Z][a-zA-Z-]*[0-9]?/) || $('*');
- },
- attribute: function () {
- var attr = '', key, val, op;
-
- if (! $('[')) return;
-
- if (key = $(/^[a-zA-Z-]+/) || $(this.entities.quoted)) {
- if ((op = $(/^[|~*$^]?=/)) &&
- (val = $(this.entities.quoted) || $(/^[\w-]+/))) {
- attr = [key, op, val.toCSS ? val.toCSS() : val].join('');
- } else { attr = key }
- }
-
- if (! $(']')) return;
-
- if (attr) { return "[" + attr + "]" }
- },
-
- //
- // The `block` rule is used by `ruleset` and `mixin.definition`.
- // It's a wrapper around the `primary` rule, with added `{}`.
- //
- block: function () {
- var content;
-
- if ($('{') && (content = $(this.primary)) && $('}')) {
- return content;
- }
- },
-
- //
- // div, .class, body > p {...}
- //
- ruleset: function () {
- var selectors = [], s, rules, match;
- save();
-
- while (s = $(this.selector)) {
- selectors.push(s);
- $(this.comment);
- if (! $(',')) { break }
- $(this.comment);
- }
-
- if (selectors.length > 0 && (rules = $(this.block))) {
- return new(tree.Ruleset)(selectors, rules);
- } else {
- // Backtrack
- furthest = i;
- restore();
- }
- },
- rule: function () {
- var name, value, c = input.charAt(i), important, match;
- save();
-
- if (c === '.' || c === '#' || c === '&') { return }
-
- if (name = $(this.variable) || $(this.property)) {
- if ((name.charAt(0) != '@') && (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j]))) {
- i += match[0].length - 1;
- value = new(tree.Anonymous)(match[1]);
- } else if (name === "font") {
- value = $(this.font);
- } else {
- value = $(this.value);
- }
- important = $(this.important);
-
- if (value && $(this.end)) {
- return new(tree.Rule)(name, value, important, memo);
- } else {
- furthest = i;
- restore();
- }
- }
- },
-
- //
- // An @import directive
- //
- // @import "lib";
- //
- // Depending on our environemnt, importing is done differently:
- // In the browser, it's an XHR request, in Node, it would be a
- // file-system operation. The function used for importing is
- // stored in `import`, which we pass to the Import constructor.
- //
- "import": function () {
- var path;
- if ($(/^@import\s+/) &&
- (path = $(this.entities.quoted) || $(this.entities.url)) &&
- $(';')) {
- return new(tree.Import)(path, imports);
- }
- },
-
- //
- // A CSS Directive
- //
- // @charset "utf-8";
- //
- directive: function () {
- var name, value, rules, types;
-
- if (input.charAt(i) !== '@') return;
-
- if (value = $(this['import'])) {
- return value;
- } else if (name = $(/^@media|@page/) || $(/^@(?:-webkit-|-moz-)?keyframes/)) {
- types = ($(/^[^{]+/) || '').trim();
- if (rules = $(this.block)) {
- return new(tree.Directive)(name + " " + types, rules);
- }
- } else if (name = $(/^@[-a-z]+/)) {
- if (name === '@font-face') {
- if (rules = $(this.block)) {
- return new(tree.Directive)(name, rules);
- }
- } else if ((value = $(this.entity)) && $(';')) {
- return new(tree.Directive)(name, value);
- }
- }
- },
- font: function () {
- var value = [], expression = [], weight, shorthand, font, e;
-
- while (e = $(this.shorthand) || $(this.entity)) {
- expression.push(e);
- }
- value.push(new(tree.Expression)(expression));
-
- if ($(',')) {
- while (e = $(this.expression)) {
- value.push(e);
- if (! $(',')) { break }
- }
- }
- return new(tree.Value)(value);
- },
-
- //
- // A Value is a comma-delimited list of Expressions
- //
- // font-family: Baskerville, Georgia, serif;
- //
- // In a Rule, a Value represents everything after the `:`,
- // and before the `;`.
- //
- value: function () {
- var e, expressions = [], important;
-
- while (e = $(this.expression)) {
- expressions.push(e);
- if (! $(',')) { break }
- }
-
- if (expressions.length > 0) {
- return new(tree.Value)(expressions);
- }
- },
- important: function () {
- if (input.charAt(i) === '!') {
- return $(/^! *important/);
- }
- },
- sub: function () {
- var e;
-
- if ($('(') && (e = $(this.expression)) && $(')')) {
- return e;
- }
- },
- multiplication: function () {
- var m, a, op, operation;
- if (m = $(this.operand)) {
- while ((op = ($('/') || $('*'))) && (a = $(this.operand))) {
- operation = new(tree.Operation)(op, [operation || m, a]);
- }
- return operation || m;
- }
- },
- addition: function () {
- var m, a, op, operation;
- if (m = $(this.multiplication)) {
- while ((op = $(/^[-+]\s+/) || (input.charAt(i - 1) != ' ' && ($('+') || $('-')))) &&
- (a = $(this.multiplication))) {
- operation = new(tree.Operation)(op, [operation || m, a]);
- }
- return operation || m;
- }
- },
-
- //
- // An operand is anything that can be part of an operation,
- // such as a Color, or a Variable
- //
- operand: function () {
- var negate, p = input.charAt(i + 1);
-
- if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $('-') }
- var o = $(this.sub) || $(this.entities.dimension) ||
- $(this.entities.color) || $(this.entities.variable) ||
- $(this.entities.call);
- return negate ? new(tree.Operation)('*', [new(tree.Dimension)(-1), o])
- : o;
- },
-
- //
- // Expressions either represent mathematical operations,
- // or white-space delimited Entities.
- //
- // 1px solid black
- // @var * 2
- //
- expression: function () {
- var e, delim, entities = [], d;
-
- while (e = $(this.addition) || $(this.entity)) {
- entities.push(e);
- }
- if (entities.length > 0) {
- return new(tree.Expression)(entities);
- }
- },
- property: function () {
- var name;
-
- if (name = $(/^(\*?-?[-a-z_0-9]+)\s*:/)) {
- return name[1];
- }
- }
- }
- };
-};
-
-if (less.mode === 'browser' || less.mode === 'rhino') {
- //
- // Used by `@import` directives
- //
- less.Parser.importer = function (path, paths, callback, env) {
- if (path.charAt(0) !== '/' && paths.length > 0) {
- path = paths[0] + path;
- }
- // We pass `true` as 3rd argument, to force the reload of the import.
- // This is so we can get the syntax tree as opposed to just the CSS output,
- // as we need this to evaluate the current stylesheet.
- loadStyleSheet({ href: path, title: path, type: env.mime }, callback, true);
- };
-}
-
-(function (tree) {
-
-tree.functions = {
- rgb: function (r, g, b) {
- return this.rgba(r, g, b, 1.0);
- },
- rgba: function (r, g, b, a) {
- var rgb = [r, g, b].map(function (c) { return number(c) }),
- a = number(a);
- return new(tree.Color)(rgb, a);
- },
- hsl: function (h, s, l) {
- return this.hsla(h, s, l, 1.0);
- },
- hsla: function (h, s, l, a) {
- h = (number(h) % 360) / 360;
- s = number(s); l = number(l); a = number(a);
-
- var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
- var m1 = l * 2 - m2;
-
- return this.rgba(hue(h + 1/3) * 255,
- hue(h) * 255,
- hue(h - 1/3) * 255,
- a);
-
- function hue(h) {
- h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
- if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
- else if (h * 2 < 1) return m2;
- else if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
- else return m1;
- }
- },
- hue: function (color) {
- return new(tree.Dimension)(Math.round(color.toHSL().h));
- },
- saturation: function (color) {
- return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%');
- },
- lightness: function (color) {
- return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%');
- },
- alpha: function (color) {
- return new(tree.Dimension)(color.toHSL().a);
- },
- saturate: function (color, amount) {
- var hsl = color.toHSL();
-
- hsl.s += amount.value / 100;
- hsl.s = clamp(hsl.s);
- return hsla(hsl);
- },
- desaturate: function (color, amount) {
- var hsl = color.toHSL();
-
- hsl.s -= amount.value / 100;
- hsl.s = clamp(hsl.s);
- return hsla(hsl);
- },
- lighten: function (color, amount) {
- var hsl = color.toHSL();
-
- hsl.l += amount.value / 100;
- hsl.l = clamp(hsl.l);
- return hsla(hsl);
- },
- darken: function (color, amount) {
- var hsl = color.toHSL();
-
- hsl.l -= amount.value / 100;
- hsl.l = clamp(hsl.l);
- return hsla(hsl);
- },
- fadein: function (color, amount) {
- var hsl = color.toHSL();
-
- hsl.a += amount.value / 100;
- hsl.a = clamp(hsl.a);
- return hsla(hsl);
- },
- fadeout: function (color, amount) {
- var hsl = color.toHSL();
-
- hsl.a -= amount.value / 100;
- hsl.a = clamp(hsl.a);
- return hsla(hsl);
- },
- fade: function (color, amount) {
- var hsl = color.toHSL();
-
- hsl.a = amount.value / 100;
- hsl.a = clamp(hsl.a);
- return hsla(hsl);
- },
- spin: function (color, amount) {
- var hsl = color.toHSL();
- var hue = (hsl.h + amount.value) % 360;
-
- hsl.h = hue < 0 ? 360 + hue : hue;
-
- return hsla(hsl);
- },
- //
- // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
- // http://sass-lang.com
- //
- mix: function (color1, color2, weight) {
- var p = weight.value / 100.0;
- var w = p * 2 - 1;
- var a = color1.toHSL().a - color2.toHSL().a;
-
- var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
- var w2 = 1 - w1;
-
- var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
- color1.rgb[1] * w1 + color2.rgb[1] * w2,
- color1.rgb[2] * w1 + color2.rgb[2] * w2];
-
- var alpha = color1.alpha * p + color2.alpha * (1 - p);
-
- return new(tree.Color)(rgb, alpha);
- },
- greyscale: function (color) {
- return this.desaturate(color, new(tree.Dimension)(100));
- },
- e: function (str) {
- return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str);
- },
- escape: function (str) {
- return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29"));
- },
- '%': function (quoted /* arg, arg, ...*/) {
- var args = Array.prototype.slice.call(arguments, 1),
- str = quoted.value;
-
- for (var i = 0; i < args.length; i++) {
- str = str.replace(/%[sda]/i, function(token) {
- var value = token.match(/s/i) ? args[i].value : args[i].toCSS();
- return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
- });
- }
- str = str.replace(/%%/g, '%');
- return new(tree.Quoted)('"' + str + '"', str);
- },
- round: function (n) {
- if (n instanceof tree.Dimension) {
- return new(tree.Dimension)(Math.round(number(n)), n.unit);
- } else if (typeof(n) === 'number') {
- return Math.round(n);
- } else {
- throw {
- error: "RuntimeError",
- message: "math functions take numbers as parameters"
- };
- }
- },
- argb: function (color) {
- return new(tree.Anonymous)(color.toARGB());
-
- }
-};
-
-function hsla(hsla) {
- return tree.functions.hsla(hsla.h, hsla.s, hsla.l, hsla.a);
-}
-
-function number(n) {
- if (n instanceof tree.Dimension) {
- return parseFloat(n.unit == '%' ? n.value / 100 : n.value);
- } else if (typeof(n) === 'number') {
- return n;
- } else {
- throw {
- error: "RuntimeError",
- message: "color functions take numbers as parameters"
- };
- }
-}
-
-function clamp(val) {
- return Math.min(1, Math.max(0, val));
-}
-
-})(require('./tree'));
-(function (tree) {
-
-tree.Alpha = function (val) {
- this.value = val;
-};
-tree.Alpha.prototype = {
- toCSS: function () {
- return "alpha(opacity=" +
- (this.value.toCSS ? this.value.toCSS() : this.value) + ")";
- },
- eval: function (env) {
- if (this.value.eval) { this.value = this.value.eval(env) }
- return this;
- }
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.Anonymous = function (string) {
- this.value = string.value || string;
-};
-tree.Anonymous.prototype = {
- toCSS: function () {
- return this.value;
- },
- eval: function () { return this }
-};
-
-})(require('../tree'));
-(function (tree) {
-
-//
-// A function call node.
-//
-tree.Call = function (name, args, index) {
- this.name = name;
- this.args = args;
- this.index = index;
-};
-tree.Call.prototype = {
- //
- // When evaluating a function call,
- // we either find the function in `tree.functions` [1],
- // in which case we call it, passing the evaluated arguments,
- // or we simply print it out as it appeared originally [2].
- //
- // The *functions.js* file contains the built-in functions.
- //
- // The reason why we evaluate the arguments, is in the case where
- // we try to pass a variable to a function, like: `saturate(@color)`.
- // The function should receive the value, not the variable.
- //
- eval: function (env) {
- var args = this.args.map(function (a) { return a.eval(env) });
-
- if (this.name in tree.functions) { // 1.
- try {
- return tree.functions[this.name].apply(tree.functions, args);
- } catch (e) {
- throw { message: "error evaluating function `" + this.name + "`",
- index: this.index };
- }
- } else { // 2.
- return new(tree.Anonymous)(this.name +
- "(" + args.map(function (a) { return a.toCSS() }).join(', ') + ")");
- }
- },
-
- toCSS: function (env) {
- return this.eval(env).toCSS();
- }
-};
-
-})(require('../tree'));
-(function (tree) {
-//
-// RGB Colors - #ff0014, #eee
-//
-tree.Color = function (rgb, a) {
- //
- // 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) {
- return parseInt(c, 16);
- });
- } else {
- this.rgb = rgb.split('').map(function (c) {
- return parseInt(c + c, 16);
- });
- }
- this.alpha = typeof(a) === 'number' ? a : 1;
-};
-tree.Color.prototype = {
- eval: function () { return this },
-
- //
- // If we have some transparency, the only way to represent it
- // is via `rgba`. Otherwise, we use the hex representation,
- // which has better compatibility with older browsers.
- // Values are capped between `0` and `255`, rounded and zero-padded.
- //
- toCSS: function () {
- if (this.alpha < 1.0) {
- return "rgba(" + this.rgb.map(function (c) {
- return Math.round(c);
- }).concat(this.alpha).join(', ') + ")";
- } else {
- return '#' + this.rgb.map(function (i) {
- i = Math.round(i);
- i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
- return i.length === 1 ? '0' + i : i;
- }).join('');
- }
- },
-
- //
- // 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 (op, other) {
- var result = [];
-
- if (! (other instanceof tree.Color)) {
- other = other.toColor();
- }
-
- for (var c = 0; c < 3; c++) {
- result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
- }
- return new(tree.Color)(result, this.alpha + other.alpha);
- },
-
- 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, s, l = (max + min) / 2, 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 };
- },
- toARGB: function () {
- var argb = [Math.round(this.alpha * 255)].concat(this.rgb);
- return '#' + argb.map(function (i) {
- i = Math.round(i);
- i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
- return i.length === 1 ? '0' + i : i;
- }).join('');
- }
-};
-
-
-})(require('../tree'));
-(function (tree) {
-
-tree.Comment = function (value, silent) {
- this.value = value;
- this.silent = !!silent;
-};
-tree.Comment.prototype = {
- toCSS: function (env) {
- return env.compress ? '' : this.value;
- },
- eval: function () { return this }
-};
-
-})(require('../tree'));
-(function (tree) {
-
-//
-// A number with a unit
-//
-tree.Dimension = function (value, unit) {
- this.value = parseFloat(value);
- this.unit = unit || null;
-};
-
-tree.Dimension.prototype = {
- eval: function () { return this },
- toColor: function () {
- return new(tree.Color)([this.value, this.value, this.value]);
- },
- toCSS: function () {
- var css = this.value + this.unit;
- return css;
- },
-
- // In an operation between two Dimensions,
- // we default to the first Dimension's unit,
- // so `1px + 2em` will yield `3px`.
- // In the future, we could implement some unit
- // conversions such that `100cm + 10mm` would yield
- // `101cm`.
- operate: function (op, other) {
- return new(tree.Dimension)
- (tree.operate(op, this.value, other.value),
- this.unit || other.unit);
- }
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.Directive = function (name, value) {
- this.name = name;
- if (Array.isArray(value)) {
- this.ruleset = new(tree.Ruleset)([], value);
- } else {
- this.value = value;
- }
-};
-tree.Directive.prototype = {
- toCSS: function (ctx, env) {
- if (this.ruleset) {
- this.ruleset.root = true;
- return this.name + (env.compress ? '{' : ' {\n ') +
- this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n ') +
- (env.compress ? '}': '\n}\n');
- } else {
- return this.name + ' ' + this.value.toCSS() + ';\n';
- }
- },
- eval: function (env) {
- env.frames.unshift(this);
- this.ruleset = this.ruleset && this.ruleset.eval(env);
- env.frames.shift();
- return this;
- },
- variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
- find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
- rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.Element = function (combinator, value, index) {
- this.combinator = combinator instanceof tree.Combinator ?
- combinator : new(tree.Combinator)(combinator);
- this.value = value ? value.trim() : "";
- this.index = index;
-};
-tree.Element.prototype.toCSS = function (env) {
- return this.combinator.toCSS(env || {}) + this.value;
-};
-
-tree.Combinator = function (value) {
- if (value === ' ') {
- this.value = ' ';
- } else if (value === '& ') {
- this.value = '& ';
- } else {
- this.value = value ? value.trim() : "";
- }
-};
-tree.Combinator.prototype.toCSS = function (env) {
- return {
- '' : '',
- ' ' : ' ',
- '&' : '',
- '& ' : ' ',
- ':' : ' :',
- '::': '::',
- '+' : env.compress ? '+' : ' + ',
- '~' : env.compress ? '~' : ' ~ ',
- '>' : env.compress ? '>' : ' > '
- }[this.value];
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.Expression = function (value) { this.value = value };
-tree.Expression.prototype = {
- eval: function (env) {
- if (this.value.length > 1) {
- return new(tree.Expression)(this.value.map(function (e) {
- return e.eval(env);
- }));
- } else if (this.value.length === 1) {
- return this.value[0].eval(env);
- } else {
- return this;
- }
- },
- toCSS: function (env) {
- return this.value.map(function (e) {
- return e.toCSS(env);
- }).join(' ');
- }
-};
-
-})(require('../tree'));
-(function (tree) {
-//
-// CSS @import node
-//
-// The general strategy here is that we don't want to wait
-// for the parsing to be completed, before we start importing
-// the file. That's because in the context of a browser,
-// most of the time will be spent waiting for the server to respond.
-//
-// On creation, we push the import path to our import queue, though
-// `import,push`, we also pass it a callback, which it'll call once
-// the file has been fetched, and parsed.
-//
-tree.Import = function (path, imports) {
- var that = this;
-
- this._path = path;
-
- // The '.less' extension is optional
- if (path instanceof tree.Quoted) {
- this.path = /\.(le?|c)ss(\?.*)?$/.test(path.value) ? path.value : path.value + '.less';
- } else {
- this.path = path.value.value || path.value;
- }
-
- this.css = /css(\?.*)?$/.test(this.path);
-
- // Only pre-compile .less files
- if (! this.css) {
- imports.push(this.path, function (root) {
- if (! root) {
- throw new(Error)("Error parsing " + that.path);
- }
- that.root = root;
- });
- }
-};
-
-//
-// The actual import node doesn't return anything, when converted to CSS.
-// The reason is that it's used at the evaluation stage, so that the rules
-// it imports can be treated like any other rules.
-//
-// In `eval`, we make sure all Import nodes get evaluated, recursively, so
-// we end up with a flat structure, which can easily be imported in the parent
-// ruleset.
-//
-tree.Import.prototype = {
- toCSS: function () {
- if (this.css) {
- return "@import " + this._path.toCSS() + ';\n';
- } else {
- return "";
- }
- },
- eval: function (env) {
- var ruleset;
-
- if (this.css) {
- return this;
- } else {
- ruleset = new(tree.Ruleset)(null, this.root.rules.slice(0));
-
- for (var i = 0; i < ruleset.rules.length; i++) {
- if (ruleset.rules[i] instanceof tree.Import) {
- Array.prototype
- .splice
- .apply(ruleset.rules,
- [i, 1].concat(ruleset.rules[i].eval(env)));
- }
- }
- return ruleset.rules;
- }
- }
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.JavaScript = function (string, index, escaped) {
- this.escaped = escaped;
- this.expression = string;
- this.index = index;
-};
-tree.JavaScript.prototype = {
- eval: function (env) {
- var result,
- that = this,
- context = {};
-
- var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
- return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env));
- });
-
- try {
- expression = new(Function)('return (' + expression + ')');
- } catch (e) {
- throw { message: "JavaScript evaluation error: `" + expression + "`" ,
- index: this.index };
- }
-
- for (var k in env.frames[0].variables()) {
- context[k.slice(1)] = {
- value: env.frames[0].variables()[k].value,
- toJS: function () {
- return this.value.eval(env).toCSS();
- }
- };
- }
-
- try {
- result = expression.call(context);
- } catch (e) {
- throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
- index: this.index };
- }
- if (typeof(result) === 'string') {
- return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index);
- } else if (Array.isArray(result)) {
- return new(tree.Anonymous)(result.join(', '));
- } else {
- return new(tree.Anonymous)(result);
- }
- }
-};
-
-})(require('../tree'));
-
-(function (tree) {
-
-tree.Keyword = function (value) { this.value = value };
-tree.Keyword.prototype = {
- eval: function () { return this },
- toCSS: function () { return this.value }
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.mixin = {};
-tree.mixin.Call = function (elements, args, index) {
- this.selector = new(tree.Selector)(elements);
- this.arguments = args;
- this.index = index;
-};
-tree.mixin.Call.prototype = {
- eval: function (env) {
- var mixins, args, rules = [], match = false;
-
- for (var i = 0; i < env.frames.length; i++) {
- if ((mixins = env.frames[i].find(this.selector)).length > 0) {
- args = this.arguments && this.arguments.map(function (a) { return a.eval(env) });
- for (var m = 0; m < mixins.length; m++) {
- if (mixins[m].match(args, env)) {
- try {
- Array.prototype.push.apply(
- rules, mixins[m].eval(env, this.arguments).rules);
- match = true;
- } catch (e) {
- throw { message: e.message, index: e.index, stack: e.stack, call: this.index };
- }
- }
- }
- if (match) {
- return rules;
- } else {
- throw { message: 'No matching definition was found for `' +
- this.selector.toCSS().trim() + '(' +
- this.arguments.map(function (a) {
- return a.toCSS();
- }).join(', ') + ")`",
- index: this.index };
- }
- }
- }
- throw { message: this.selector.toCSS().trim() + " is undefined",
- index: this.index };
- }
-};
-
-tree.mixin.Definition = function (name, params, rules) {
- this.name = name;
- this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
- this.params = params;
- this.arity = params.length;
- this.rules = rules;
- this._lookups = {};
- this.required = params.reduce(function (count, p) {
- if (!p.name || (p.name && !p.value)) { return count + 1 }
- else { return count }
- }, 0);
- this.parent = tree.Ruleset.prototype;
- this.frames = [];
-};
-tree.mixin.Definition.prototype = {
- toCSS: function () { return "" },
- variable: function (name) { return this.parent.variable.call(this, name) },
- variables: function () { return this.parent.variables.call(this) },
- find: function () { return this.parent.find.apply(this, arguments) },
- rulesets: function () { return this.parent.rulesets.apply(this) },
-
- eval: function (env, args) {
- var frame = new(tree.Ruleset)(null, []), context, _arguments = [];
-
- for (var i = 0, val; i < this.params.length; i++) {
- if (this.params[i].name) {
- if (val = (args && args[i]) || this.params[i].value) {
- frame.rules.unshift(new(tree.Rule)(this.params[i].name, val.eval(env)));
- } else {
- throw { message: "wrong number of arguments for " + this.name +
- ' (' + args.length + ' for ' + this.arity + ')' };
- }
- }
- }
- for (var i = 0; i < Math.max(this.params.length, args && args.length); i++) {
- _arguments.push(args[i] || this.params[i].value);
- }
- frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
-
- return new(tree.Ruleset)(null, this.rules.slice(0)).eval({
- frames: [this, frame].concat(this.frames, env.frames)
- });
- },
- match: function (args, env) {
- var argsLength = (args && args.length) || 0, len;
-
- if (argsLength < this.required) { return false }
- if ((this.required > 0) && (argsLength > this.params.length)) { return false }
-
- len = Math.min(argsLength, this.arity);
-
- for (var i = 0; i < len; i++) {
- if (!this.params[i].name) {
- if (args[i].eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
- return false;
- }
- }
- }
- return true;
- }
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.Operation = function (op, operands) {
- this.op = op.trim();
- this.operands = operands;
-};
-tree.Operation.prototype.eval = function (env) {
- var a = this.operands[0].eval(env),
- b = this.operands[1].eval(env),
- temp;
-
- if (a instanceof tree.Dimension && b instanceof tree.Color) {
- if (this.op === '*' || this.op === '+') {
- temp = b, b = a, a = temp;
- } else {
- throw { name: "OperationError",
- message: "Can't substract or divide a color from a number" };
- }
- }
- return a.operate(this.op, b);
-};
-
-tree.operate = function (op, a, b) {
- switch (op) {
- case '+': return a + b;
- case '-': return a - b;
- case '*': return a * b;
- case '/': return a / b;
- }
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.Quoted = function (str, content, escaped, i) {
- this.escaped = escaped;
- this.value = content || '';
- this.quote = str.charAt(0);
- this.index = i;
-};
-tree.Quoted.prototype = {
- toCSS: function () {
- if (this.escaped) {
- return this.value;
- } else {
- return this.quote + this.value + this.quote;
- }
- },
- eval: function (env) {
- var that = this;
- var value = this.value.replace(/`([^`]+)`/g, function (_, exp) {
- return new(tree.JavaScript)(exp, that.index, true).eval(env).value;
- }).replace(/@\{([\w-]+)\}/g, function (_, name) {
- var v = new(tree.Variable)('@' + name, that.index).eval(env);
- return v.value || v.toCSS();
- });
- return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index);
- }
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.Rule = function (name, value, important, index) {
- this.name = name;
- this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
- this.important = important ? ' ' + important.trim() : '';
- this.index = index;
-
- if (name.charAt(0) === '@') {
- this.variable = true;
- } else { this.variable = false }
-};
-tree.Rule.prototype.toCSS = function (env) {
- if (this.variable) { return "" }
- else {
- return this.name + (env.compress ? ':' : ': ') +
- this.value.toCSS(env) +
- this.important + ";";
- }
-};
-
-tree.Rule.prototype.eval = function (context) {
- return new(tree.Rule)(this.name, this.value.eval(context), this.important, this.index);
-};
-
-tree.Shorthand = function (a, b) {
- this.a = a;
- this.b = b;
-};
-
-tree.Shorthand.prototype = {
- toCSS: function (env) {
- return this.a.toCSS(env) + "/" + this.b.toCSS(env);
- },
- eval: function () { return this }
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.Ruleset = function (selectors, rules) {
- this.selectors = selectors;
- this.rules = rules;
- this._lookups = {};
-};
-tree.Ruleset.prototype = {
- eval: function (env) {
- var ruleset = new(tree.Ruleset)(this.selectors, this.rules.slice(0));
-
- ruleset.root = this.root;
-
- // push the current ruleset to the frames stack
- env.frames.unshift(ruleset);
-
- // Evaluate imports
- if (ruleset.root) {
- for (var i = 0; i < ruleset.rules.length; i++) {
- if (ruleset.rules[i] instanceof tree.Import) {
- Array.prototype.splice
- .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
- }
- }
- }
-
- // Store the frames around mixin definitions,
- // so they can be evaluated like closures when the time comes.
- for (var i = 0; i < ruleset.rules.length; i++) {
- if (ruleset.rules[i] instanceof tree.mixin.Definition) {
- ruleset.rules[i].frames = env.frames.slice(0);
- }
- }
-
- // Evaluate mixin calls.
- for (var i = 0; i < ruleset.rules.length; i++) {
- if (ruleset.rules[i] instanceof tree.mixin.Call) {
- Array.prototype.splice
- .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
- }
- }
-
- // Evaluate everything else
- for (var i = 0, rule; i < ruleset.rules.length; i++) {
- rule = ruleset.rules[i];
-
- if (! (rule instanceof tree.mixin.Definition)) {
- ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
- }
- }
-
- // Pop the stack
- env.frames.shift();
-
- return ruleset;
- },
- match: function (args) {
- return !args || args.length === 0;
- },
- variables: function () {
- if (this._variables) { return this._variables }
- else {
- return this._variables = this.rules.reduce(function (hash, r) {
- if (r instanceof tree.Rule && r.variable === true) {
- hash[r.name] = r;
- }
- return hash;
- }, {});
- }
- },
- variable: function (name) {
- return this.variables()[name];
- },
- rulesets: function () {
- if (this._rulesets) { return this._rulesets }
- else {
- return this._rulesets = this.rules.filter(function (r) {
- return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
- });
- }
- },
- find: function (selector, self) {
- self = self || this;
- var rules = [], rule, match,
- key = selector.toCSS();
-
- if (key in this._lookups) { return this._lookups[key] }
-
- this.rulesets().forEach(function (rule) {
- if (rule !== self) {
- for (var j = 0; j < rule.selectors.length; j++) {
- if (match = selector.match(rule.selectors[j])) {
- if (selector.elements.length > rule.selectors[j].elements.length) {
- Array.prototype.push.apply(rules, rule.find(
- new(tree.Selector)(selector.elements.slice(1)), self));
- } else {
- rules.push(rule);
- }
- break;
- }
- }
- }
- });
- return this._lookups[key] = rules;
- },
- //
- // Entry point for code generation
- //
- // `context` holds an array of arrays.
- //
- toCSS: function (context, env) {
- var css = [], // The CSS output
- rules = [], // node.Rule instances
- rulesets = [], // node.Ruleset instances
- paths = [], // Current selectors
- selector, // The fully rendered selector
- rule;
-
- if (! this.root) {
- if (context.length === 0) {
- paths = this.selectors.map(function (s) { return [s] });
- } else {
- this.joinSelectors( paths, context, this.selectors );
- }
- }
-
- // Compile rules and rulesets
- for (var i = 0; i < this.rules.length; i++) {
- rule = this.rules[i];
-
- if (rule.rules || (rule instanceof tree.Directive)) {
- rulesets.push(rule.toCSS(paths, env));
- } else if (rule instanceof tree.Comment) {
- if (!rule.silent) {
- if (this.root) {
- rulesets.push(rule.toCSS(env));
- } else {
- rules.push(rule.toCSS(env));
- }
- }
- } else {
- if (rule.toCSS && !rule.variable) {
- rules.push(rule.toCSS(env));
- } else if (rule.value && !rule.variable) {
- rules.push(rule.value.toString());
- }
- }
- }
-
- rulesets = rulesets.join('');
-
- // If this is the root node, we don't render
- // a selector, or {}.
- // Otherwise, only output if this ruleset has rules.
- if (this.root) {
- css.push(rules.join(env.compress ? '' : '\n'));
- } else {
- if (rules.length > 0) {
- selector = paths.map(function (p) {
- return p.map(function (s) {
- return s.toCSS(env);
- }).join('').trim();
- }).join(env.compress ? ',' : (paths.length > 3 ? ',\n' : ', '));
- css.push(selector,
- (env.compress ? '{' : ' {\n ') +
- rules.join(env.compress ? '' : '\n ') +
- (env.compress ? '}' : '\n}\n'));
- }
- }
- css.push(rulesets);
-
- return css.join('') + (env.compress ? '\n' : '');
- },
-
- joinSelectors: function (paths, context, selectors) {
- for (var s = 0; s < selectors.length; s++) {
- this.joinSelector(paths, context, selectors[s]);
- }
- },
-
- joinSelector: function (paths, context, selector) {
- var before = [], after = [], beforeElements = [],
- afterElements = [], hasParentSelector = false, el;
-
- for (var i = 0; i < selector.elements.length; i++) {
- el = selector.elements[i];
- if (el.combinator.value.charAt(0) === '&') {
- hasParentSelector = true;
- }
- if (hasParentSelector) afterElements.push(el);
- else beforeElements.push(el);
- }
-
- if (! hasParentSelector) {
- afterElements = beforeElements;
- beforeElements = [];
- }
-
- if (beforeElements.length > 0) {
- before.push(new(tree.Selector)(beforeElements));
- }
-
- if (afterElements.length > 0) {
- after.push(new(tree.Selector)(afterElements));
- }
-
- for (var c = 0; c < context.length; c++) {
- paths.push(before.concat(context[c]).concat(after));
- }
- }
-};
-})(require('../tree'));
-(function (tree) {
-
-tree.Selector = function (elements) {
- this.elements = elements;
- if (this.elements[0].combinator.value === "") {
- this.elements[0].combinator.value = ' ';
- }
-};
-tree.Selector.prototype.match = function (other) {
- var len = this.elements.length,
- olen = other.elements.length,
- max = Math.min(len, olen);
-
- if (len < olen) {
- return false;
- } else {
- for (var i = 0; i < max; i++) {
- if (this.elements[i].value !== other.elements[i].value) {
- return false;
- }
- }
- }
- return true;
-};
-tree.Selector.prototype.toCSS = function (env) {
- if (this._css) { return this._css }
-
- return this._css = this.elements.map(function (e) {
- if (typeof(e) === 'string') {
- return ' ' + e.trim();
- } else {
- return e.toCSS(env);
- }
- }).join('');
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.URL = function (val, paths) {
- if (val.data) {
- this.attrs = val;
- } else {
- // Add the base path if the URL is relative and we are in the browser
- if (!/^(?:https?:\/\/|file:\/\/|data:)?/.test(val.value) && paths.length > 0 && typeof(window) !== 'undefined') {
- val.value = paths[0] + (val.value.charAt(0) === '/' ? val.value.slice(1) : val.value);
- }
- this.value = val;
- this.paths = paths;
- }
-};
-tree.URL.prototype = {
- toCSS: function () {
- return "url(" + (this.attrs ? 'data:' + this.attrs.mime + this.attrs.charset + this.attrs.base64 + this.attrs.data
- : this.value.toCSS()) + ")";
- },
- eval: function (ctx) {
- return this.attrs ? this : new(tree.URL)(this.value.eval(ctx), this.paths);
- }
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.Value = function (value) {
- this.value = value;
- this.is = 'value';
-};
-tree.Value.prototype = {
- eval: function (env) {
- if (this.value.length === 1) {
- return this.value[0].eval(env);
- } else {
- return new(tree.Value)(this.value.map(function (v) {
- return v.eval(env);
- }));
- }
- },
- toCSS: function (env) {
- return this.value.map(function (e) {
- return e.toCSS(env);
- }).join(env.compress ? ',' : ', ');
- }
-};
-
-})(require('../tree'));
-(function (tree) {
-
-tree.Variable = function (name, index) { this.name = name, this.index = index };
-tree.Variable.prototype = {
- eval: function (env) {
- var variable, v, name = this.name;
-
- if (name.indexOf('@@') == 0) {
- name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
- }
-
- if (variable = tree.find(env.frames, function (frame) {
- if (v = frame.variable(name)) {
- return v.value.eval(env);
- }
- })) { return variable }
- else {
- throw { message: "variable " + name + " is undefined",
- index: this.index };
- }
- }
-};
-
-})(require('../tree'));
-require('./tree').find = function (obj, fun) {
- for (var i = 0, r; i < obj.length; i++) {
- if (r = fun.call(obj, obj[i])) { return r }
- }
- return null;
-};
-require('./tree').jsify = function (obj) {
- if (Array.isArray(obj.value) && (obj.value.length > 1)) {
- return '[' + obj.value.map(function (v) { return v.toCSS(false) }).join(', ') + ']';
- } else {
- return obj.toCSS(false);
- }
-};
-var name;
-
-function loadStyleSheet(sheet, callback, reload, remaining) {
- var sheetName = name.slice(0, name.lastIndexOf('/') + 1) + sheet.href;
- var input = readFile(sheetName);
- var parser = new less.Parser();
- parser.parse(input, function (e, root) {
- if (e) {
- print("Error: " + e);
- quit(1);
- }
- callback(root, sheet, { local: false, lastModified: 0, remaining: remaining });
- });
-
- // callback({}, sheet, { local: true, remaining: remaining });
-}
-
-function writeFile(filename, content) {
- var fstream = new java.io.FileWriter(filename);
- var out = new java.io.BufferedWriter(fstream);
- out.write(content);
- out.close();
-}
-
-// Command line integration via Rhino
-(function (args) {
- name = args[0];
- var output = args[1];
-
- if (!name) {
- print('No files present in the fileset; Check your pattern match in build.xml');
- quit(1);
- }
- path = name.split("/");path.pop();path=path.join("/")
-
- var input = readFile(name);
-
- if (!input) {
- print('lesscss: couldn\'t open file ' + name);
- quit(1);
- }
-
- var result;
- var parser = new less.Parser();
- parser.parse(input, function (e, root) {
- if (e) {
- quit(1);
- } else {
- result = root.toCSS();
- if (output) {
- writeFile(output, result);
- print("Written to " + output);
- } else {
- print(result);
- }
- quit(0);
- }
- });
- print("done");
-}(arguments));
diff --git a/lib/less/functions.js b/lib/less/functions.js
index 6eb34bac8..7706a16e9 100644
--- a/lib/less/functions.js
+++ b/lib/less/functions.js
@@ -121,6 +121,33 @@ tree.functions = {
return new(tree.Color)(rgb, alpha);
},
+ blend: function (mode, color1, color2, alpha) {
+ var rgb1 = [color1.rgb[0],
+ color1.rgb[1],
+ color1.rgb[2]];
+
+ var rgb2 = [color2.rgb[0],
+ color2.rgb[1],
+ color2.rgb[2]];
+
+ // Thanks to jswidget.com for sharing the blending algorithms used by many image processing programs.
+ // http://jswidget.com/blog/category/image-blending-algorithm/
+ //
+ var modes = {
+ multiply : function (color1, color2) {
+ return color2 * color1 / 255;
+ },
+ screen : function (color1, color2) {
+ return color2 + color1 - color2 * color1 / 255;
+ },
+ overlay : function (color1, color2) {
+ return (color1 < 128) ? (2 * color2 * color1 / 255) : (255 - 2 * (255 - color2) * (255 - color1) / 255);
+ }
+ }
+
+ return (Object.keys(modes).join().indexOf(mode.value) < 0) ? this.rgba(rgb2[0], rgb2[1], rgb2[2], alpha || 1.0) : this.rgba(modes[mode.value](rgb1[0],rgb2[0]), modes[mode.value](rgb1[1],rgb2[1]), modes[mode.value](rgb1[2],rgb2[2]), alpha || 1.0);
+
+ },
greyscale: function (color) {
return this.desaturate(color, new(tree.Dimension)(100));
},