/*! * Bootstrap Colorpicker * http://mjolnic.github.io/bootstrap-colorpicker/ * * Originally written by (c) 2012 Stefan Petre * Licensed under the Apache License v2.0 * http://www.apache.org/licenses/LICENSE-2.0.txt * * @todo Update DOCS */ (function ($) { // Color object const Color = function (val) { this.value = { h: 0, s: 0, b: 0, a: 1, }; this.origFormat = null; // original string format if (val) { if (val.toLowerCase !== undefined) { this.setColor(val); } else if (val.h !== undefined) { this.value = val; } } }; Color.prototype = { constructor: Color, _sanitizeNumber(val) { if (typeof val === 'number') { return val; } if (isNaN(val) || (val === null) || (val === '') || (val === undefined)) { return 1; } if (val.toLowerCase !== undefined) { return parseFloat(val); } return 1; }, // parse a string to HSB setColor(strVal) { strVal = strVal.toLowerCase(); this.value = this.stringToHSB(strVal) ||  { h: 0, s: 0, b: 0, a: 1, }; }, stringToHSB(strVal) { strVal = strVal.toLowerCase(); const that = this; let result = false; $.each(this.stringParsers, (i, parser) => { const match = parser.re.exec(strVal); const values = match && parser.parse.apply(that, [match]); const format = parser.format || 'rgba'; if (values) { if (format.match(/hsla?/)) { result = that.RGBtoHSB.apply(that, that.HSLtoRGB.apply(that, values)); } else { result = that.RGBtoHSB.apply(that, values); } that.origFormat = format; return false; } return true; }); return result; }, setHue(h) { this.value.h = 1 - h; }, setSaturation(s) { this.value.s = s; }, setBrightness(b) { this.value.b = 1 - b; }, setAlpha(a) { this.value.a = parseInt((1 - a) * 100, 10) / 100; }, toRGB(h, s, v, a) { h = h || this.value.h; s = s || this.value.s; v = v || this.value.b; a = a || this.value.a; let r; let g; let b; let i; let f; let p; let q; let t; if (h && s === undefined && v === undefined) { s = h.s, v = h.v, h = h.h; } i = Math.floor(h * 6); f = h * 6 - i; p = v * (1 - s); q = v * (1 - f * s); t = v * (1 - (1 - f) * s); switch (i % 6) { case 0: r = v, g = t, b = p; break; case 1: r = q, g = v, b = p; break; case 2: r = p, g = v, b = t; break; case 3: r = p, g = q, b = v; break; case 4: r = t, g = p, b = v; break; case 5: r = v, g = p, b = q; break; } return { r: Math.floor(r * 255), g: Math.floor(g * 255), b: Math.floor(b * 255), a, }; }, toHex(h, s, b, a) { const rgb = this.toRGB(h, s, b, a); return `#${((1 << 24) | (parseInt(rgb.r) << 16) | (parseInt(rgb.g) << 8) | parseInt(rgb.b)).toString(16).substr(1)}`; }, toHSL(h, s, b, a) { h = h || this.value.h; s = s || this.value.s; b = b || this.value.b; a = a || this.value.a; const H = h; let L = (2 - s) * b; let S = s * b; if (L > 0 && L <= 1) { S /= L; } else { S /= 2 - L; } L /= 2; if (S > 1) { S = 1; } return { h: isNaN(H) ? 0 : H, s: isNaN(S) ? 0 : S, l: isNaN(L) ? 0 : L, a: isNaN(a) ? 0 : a, }; }, RGBtoHSB(r, g, b, a) { r /= 255; g /= 255; b /= 255; let H; let S; let V; let C; V = Math.max(r, g, b); C = V - Math.min(r, g, b); H = (C === 0 ? null : V === r ? (g - b) / C : V === g ? (b - r) / C + 2 : (r - g) / C + 4 ); H = ((H + 360) % 6) * 60 / 360; S = C === 0 ? 0 : C / V; return { h: this._sanitizeNumber(H), s: S, b: V, a: this._sanitizeNumber(a), }; }, HueToRGB(p, q, h) { if (h < 0) { h += 1; } else if (h > 1) { h -= 1; } if ((h * 6) < 1) { return p + (q - p) * h * 6; } if ((h * 2) < 1) { return q; } if ((h * 3) < 2) { return p + (q - p) * ((2 / 3) - h) * 6; } return p; }, HSLtoRGB(h, s, l, a) { if (s < 0) { s = 0; } let q; if (l <= 0.5) { q = l * (1 + s); } else { q = l + s - (l * s); } const p = 2 * l - q; const tr = h + (1 / 3); const tg = h; const tb = h - (1 / 3); const r = Math.round(this.HueToRGB(p, q, tr) * 255); const g = Math.round(this.HueToRGB(p, q, tg) * 255); const b = Math.round(this.HueToRGB(p, q, tb) * 255); return [r, g, b, this._sanitizeNumber(a)]; }, toString(format) { format = format ||  'rgba'; switch (format) { case 'rgb': { var rgb = this.toRGB(); return `rgb(${rgb.r},${rgb.g},${rgb.b})`; } break; case 'rgba': { var rgb = this.toRGB(); return `rgba(${rgb.r},${rgb.g},${rgb.b},${rgb.a})`; } break; case 'hsl': { var hsl = this.toHSL(); return `hsl(${Math.round(hsl.h * 360)},${Math.round(hsl.s * 100)}%,${Math.round(hsl.l * 100)}%)`; } break; case 'hsla': { var hsl = this.toHSL(); return `hsla(${Math.round(hsl.h * 360)},${Math.round(hsl.s * 100)}%,${Math.round(hsl.l * 100)}%,${hsl.a})`; } break; case 'hex': { return this.toHex(); } break; default: { return false; } break; } }, // a set of RE's that can match strings and generate color tuples. // from John Resig color plugin // https://github.com/jquery/jquery-color/ stringParsers: [{ re: /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/, format: 'hex', parse(execResult) { return [ parseInt(execResult[1], 16), parseInt(execResult[2], 16), parseInt(execResult[3], 16), 1, ]; }, }, { re: /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/, format: 'hex', parse(execResult) { return [ parseInt(execResult[1] + execResult[1], 16), parseInt(execResult[2] + execResult[2], 16), parseInt(execResult[3] + execResult[3], 16), 1, ]; }, }, { re: /rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*?\)/, format: 'rgb', parse(execResult) { return [ execResult[1], execResult[2], execResult[3], 1, ]; }, }, { re: /rgb\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*?\)/, format: 'rgb', parse(execResult) { return [ 2.55 * execResult[1], 2.55 * execResult[2], 2.55 * execResult[3], 1, ]; }, }, { re: /rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/, format: 'rgba', parse(execResult) { return [ execResult[1], execResult[2], execResult[3], execResult[4], ]; }, }, { re: /rgba\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/, format: 'rgba', parse(execResult) { return [ 2.55 * execResult[1], 2.55 * execResult[2], 2.55 * execResult[3], execResult[4], ]; }, }, { re: /hsl\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*?\)/, format: 'hsl', parse(execResult) { return [ execResult[1] / 360, execResult[2] / 100, execResult[3] / 100, execResult[4], ]; }, }, { re: /hsla\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/, format: 'hsla', parse(execResult) { return [ execResult[1] / 360, execResult[2] / 100, execResult[3] / 100, execResult[4], ]; }, }, { // predefined color name re: /^([a-z]{3,})$/, format: 'alias', parse(execResult) { const hexval = this.colorNameToHex(execResult[0]) ||  '#000000'; const match = this.stringParsers[0].re.exec(hexval); const values = match && this.stringParsers[0].parse.apply(this, [match]); return values; }, }], colorNameToHex(name) { // 140 predefined colors from the HTML Colors spec const 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', darkgreen: '#006400', darkkhaki: '#bdb76b', darkmagenta: '#8b008b', darkolivegreen: '#556b2f', darkorange: '#ff8c00', darkorchid: '#9932cc', darkred: '#8b0000', darksalmon: '#e9967a', darkseagreen: '#8fbc8f', darkslateblue: '#483d8b', darkslategray: '#2f4f4f', darkturquoise: '#00ced1', darkviolet: '#9400d3', deeppink: '#ff1493', deepskyblue: '#00bfff', dimgray: '#696969', dodgerblue: '#1e90ff', firebrick: '#b22222', floralwhite: '#fffaf0', forestgreen: '#228b22', fuchsia: '#ff00ff', gainsboro: '#dcdcdc', ghostwhite: '#f8f8ff', gold: '#ffd700', goldenrod: '#daa520', gray: '#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', lightgrey: '#d3d3d3', lightgreen: '#90ee90', lightpink: '#ffb6c1', lightsalmon: '#ffa07a', lightseagreen: '#20b2aa', lightskyblue: '#87cefa', lightslategray: '#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', 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', }; if (typeof colors[name.toLowerCase()] !== 'undefined') { return colors[name.toLowerCase()]; } return false; }, }; const defaults = { horizontal: false, // horizontal mode layout ? inline: false, // forces to show the colorpicker as an inline element color: false, // forces a color format: false, // forces a format input: 'input', // children input selector container: false, // container selector component: '.add-on, .input-group-addon', // children component selector sliders: { saturation: { maxLeft: 100, maxTop: 100, callLeft: 'setSaturation', callTop: 'setBrightness', }, hue: { maxLeft: 0, maxTop: 100, callLeft: false, callTop: 'setHue', }, alpha: { maxLeft: 0, maxTop: 100, callLeft: false, callTop: 'setAlpha', }, }, slidersHorz: { saturation: { maxLeft: 100, maxTop: 100, callLeft: 'setSaturation', callTop: 'setBrightness', }, hue: { maxLeft: 100, maxTop: 0, callLeft: 'setHue', callTop: false, }, alpha: { maxLeft: 100, maxTop: 0, callLeft: 'setAlpha', callTop: false, }, }, template: '