(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); }, 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); }, '%': 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(/%s/, args[i].value) .replace(/%[da]/, args[i].toCSS()); } str = str.replace(/%%/g, '%'); return new(tree.Quoted)('"' + str + '"', str); } }; 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'));