chroma-js-umd

A UMD build of chroma-js

This script should not be not be installed directly. It is a library for other scripts to include with the meta directive // @require https://update.greatest.deepsurf.us/scripts/526709/1536234/chroma-js-umd.js

  1. (function (global, factory) {
  2. typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
  3. typeof define === 'function' && define.amd ? define(['exports'], factory) :
  4. (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.chroma = {}));
  5. })(this, (function (exports) { 'use strict';
  6.  
  7. const { min: min$5, max: max$5 } = Math;
  8.  
  9. var limit$1 = (x, low = 0, high = 1) => {
  10. return min$5(max$5(low, x), high);
  11. };
  12.  
  13. var clip_rgb = (rgb) => {
  14. rgb._clipped = false;
  15. rgb._unclipped = rgb.slice(0);
  16. for (let i = 0; i <= 3; i++) {
  17. if (i < 3) {
  18. if (rgb[i] < 0 || rgb[i] > 255) rgb._clipped = true;
  19. rgb[i] = limit$1(rgb[i], 0, 255);
  20. } else if (i === 3) {
  21. rgb[i] = limit$1(rgb[i], 0, 1);
  22. }
  23. }
  24. return rgb;
  25. };
  26.  
  27. // ported from jQuery's $.type
  28. const classToType = {};
  29. for (let name of [
  30. 'Boolean',
  31. 'Number',
  32. 'String',
  33. 'Function',
  34. 'Array',
  35. 'Date',
  36. 'RegExp',
  37. 'Undefined',
  38. 'Null'
  39. ]) {
  40. classToType[`[object ${name}]`] = name.toLowerCase();
  41. }
  42. function type (obj) {
  43. return classToType[Object.prototype.toString.call(obj)] || 'object';
  44. }
  45.  
  46. var unpack = (args, keyOrder = null) => {
  47. // if called with more than 3 arguments, we return the arguments
  48. if (args.length >= 3) return Array.prototype.slice.call(args);
  49. // with less than 3 args we check if first arg is object
  50. // and use the keyOrder string to extract and sort properties
  51. if (type(args[0]) == 'object' && keyOrder) {
  52. return keyOrder
  53. .split('')
  54. .filter((k) => args[0][k] !== undefined)
  55. .map((k) => args[0][k]);
  56. }
  57. // otherwise we just return the first argument
  58. // (which we suppose is an array of args)
  59. return args[0].slice(0);
  60. };
  61.  
  62. var last = (args) => {
  63. if (args.length < 2) return null;
  64. const l = args.length - 1;
  65. if (type(args[l]) == 'string') return args[l].toLowerCase();
  66. return null;
  67. };
  68.  
  69. var _input = {
  70. format: {},
  71. autodetect: []
  72. };
  73.  
  74. let Color$3 = class Color {
  75. constructor(...args) {
  76. const me = this;
  77. if (
  78. type(args[0]) === 'object' &&
  79. args[0].constructor &&
  80. args[0].constructor === this.constructor
  81. ) {
  82. // the argument is already a Color instance
  83. return args[0];
  84. }
  85. // last argument could be the mode
  86. let mode = last(args);
  87. let autodetect = false;
  88. if (!mode) {
  89. autodetect = true;
  90.  
  91. if (!_input.sorted) {
  92. _input.autodetect = _input.autodetect.sort((a, b) => b.p - a.p);
  93. _input.sorted = true;
  94. }
  95.  
  96. // auto-detect format
  97. for (let chk of _input.autodetect) {
  98. mode = chk.test(...args);
  99. if (mode) break;
  100. }
  101. }
  102. if (_input.format[mode]) {
  103. const rgb = _input.format[mode].apply(
  104. null,
  105. autodetect ? args : args.slice(0, -1)
  106. );
  107. me._rgb = clip_rgb(rgb);
  108. } else {
  109. throw new Error('unknown format: ' + args);
  110. }
  111. // add alpha channel
  112. if (me._rgb.length === 3) me._rgb.push(1);
  113. }
  114. toString() {
  115. if (type(this.hex) == 'function') return this.hex();
  116. return `[${this._rgb.join(',')}]`;
  117. }
  118. };
  119.  
  120. // this gets updated automatically
  121. const version = '3.1.2';
  122.  
  123. const chroma$2 = (...args) => {
  124. return new Color$3(...args);
  125. };
  126.  
  127. chroma$2.version = version;
  128.  
  129. let Color$2 = class Color {
  130. constructor(...args) {
  131. const me = this;
  132. if (
  133. type(args[0]) === 'object' &&
  134. args[0].constructor &&
  135. args[0].constructor === this.constructor
  136. ) {
  137. // the argument is already a Color instance
  138. return args[0];
  139. }
  140. // last argument could be the mode
  141. let mode = last(args);
  142. let autodetect = false;
  143. if (!mode) {
  144. autodetect = true;
  145.  
  146. if (!_input.sorted) {
  147. _input.autodetect = _input.autodetect.sort((a, b) => b.p - a.p);
  148. _input.sorted = true;
  149. }
  150.  
  151. // auto-detect format
  152. for (let chk of _input.autodetect) {
  153. mode = chk.test(...args);
  154. if (mode) break;
  155. }
  156. }
  157. if (_input.format[mode]) {
  158. const rgb = _input.format[mode].apply(
  159. null,
  160. autodetect ? args : args.slice(0, -1)
  161. );
  162. me._rgb = clip_rgb(rgb);
  163. } else {
  164. throw new Error('unknown format: ' + args);
  165. }
  166. // add alpha channel
  167. if (me._rgb.length === 3) me._rgb.push(1);
  168. }
  169. toString() {
  170. if (type(this.hex) == 'function') return this.hex();
  171. return `[${this._rgb.join(',')}]`;
  172. }
  173. };
  174.  
  175. var input$1 = {
  176. format: {},
  177. autodetect: []
  178. };
  179.  
  180. const { PI: PI$3, min: min$4, max: max$4 } = Math;
  181.  
  182. const rnd2 = (a) => Math.round(a * 100) / 100;
  183. const rnd3 = (a) => Math.round(a * 100) / 100;
  184.  
  185. const TWOPI$1 = PI$3 * 2;
  186. const PITHIRD = PI$3 / 3;
  187. const DEG2RAD = PI$3 / 180;
  188. const RAD2DEG = 180 / PI$3;
  189.  
  190. /**
  191. * Reverse the first three elements of an array
  192. *
  193. * @param {any[]} arr
  194. * @returns {any[]}
  195. */
  196. function reverse3(arr) {
  197. return [...arr.slice(0, 3).reverse(), ...arr.slice(3)];
  198. }
  199.  
  200. /**
  201. X11 color names
  202.  
  203. http://www.w3.org/TR/css3-color/#svg-color
  204. */
  205.  
  206. const w3cx11$1 = {
  207. aliceblue: '#f0f8ff',
  208. antiquewhite: '#faebd7',
  209. aqua: '#00ffff',
  210. aquamarine: '#7fffd4',
  211. azure: '#f0ffff',
  212. beige: '#f5f5dc',
  213. bisque: '#ffe4c4',
  214. black: '#000000',
  215. blanchedalmond: '#ffebcd',
  216. blue: '#0000ff',
  217. blueviolet: '#8a2be2',
  218. brown: '#a52a2a',
  219. burlywood: '#deb887',
  220. cadetblue: '#5f9ea0',
  221. chartreuse: '#7fff00',
  222. chocolate: '#d2691e',
  223. coral: '#ff7f50',
  224. cornflowerblue: '#6495ed',
  225. cornsilk: '#fff8dc',
  226. crimson: '#dc143c',
  227. cyan: '#00ffff',
  228. darkblue: '#00008b',
  229. darkcyan: '#008b8b',
  230. darkgoldenrod: '#b8860b',
  231. darkgray: '#a9a9a9',
  232. darkgreen: '#006400',
  233. darkgrey: '#a9a9a9',
  234. darkkhaki: '#bdb76b',
  235. darkmagenta: '#8b008b',
  236. darkolivegreen: '#556b2f',
  237. darkorange: '#ff8c00',
  238. darkorchid: '#9932cc',
  239. darkred: '#8b0000',
  240. darksalmon: '#e9967a',
  241. darkseagreen: '#8fbc8f',
  242. darkslateblue: '#483d8b',
  243. darkslategray: '#2f4f4f',
  244. darkslategrey: '#2f4f4f',
  245. darkturquoise: '#00ced1',
  246. darkviolet: '#9400d3',
  247. deeppink: '#ff1493',
  248. deepskyblue: '#00bfff',
  249. dimgray: '#696969',
  250. dimgrey: '#696969',
  251. dodgerblue: '#1e90ff',
  252. firebrick: '#b22222',
  253. floralwhite: '#fffaf0',
  254. forestgreen: '#228b22',
  255. fuchsia: '#ff00ff',
  256. gainsboro: '#dcdcdc',
  257. ghostwhite: '#f8f8ff',
  258. gold: '#ffd700',
  259. goldenrod: '#daa520',
  260. gray: '#808080',
  261. green: '#008000',
  262. greenyellow: '#adff2f',
  263. grey: '#808080',
  264. honeydew: '#f0fff0',
  265. hotpink: '#ff69b4',
  266. indianred: '#cd5c5c',
  267. indigo: '#4b0082',
  268. ivory: '#fffff0',
  269. khaki: '#f0e68c',
  270. laserlemon: '#ffff54',
  271. lavender: '#e6e6fa',
  272. lavenderblush: '#fff0f5',
  273. lawngreen: '#7cfc00',
  274. lemonchiffon: '#fffacd',
  275. lightblue: '#add8e6',
  276. lightcoral: '#f08080',
  277. lightcyan: '#e0ffff',
  278. lightgoldenrod: '#fafad2',
  279. lightgoldenrodyellow: '#fafad2',
  280. lightgray: '#d3d3d3',
  281. lightgreen: '#90ee90',
  282. lightgrey: '#d3d3d3',
  283. lightpink: '#ffb6c1',
  284. lightsalmon: '#ffa07a',
  285. lightseagreen: '#20b2aa',
  286. lightskyblue: '#87cefa',
  287. lightslategray: '#778899',
  288. lightslategrey: '#778899',
  289. lightsteelblue: '#b0c4de',
  290. lightyellow: '#ffffe0',
  291. lime: '#00ff00',
  292. limegreen: '#32cd32',
  293. linen: '#faf0e6',
  294. magenta: '#ff00ff',
  295. maroon: '#800000',
  296. maroon2: '#7f0000',
  297. maroon3: '#b03060',
  298. mediumaquamarine: '#66cdaa',
  299. mediumblue: '#0000cd',
  300. mediumorchid: '#ba55d3',
  301. mediumpurple: '#9370db',
  302. mediumseagreen: '#3cb371',
  303. mediumslateblue: '#7b68ee',
  304. mediumspringgreen: '#00fa9a',
  305. mediumturquoise: '#48d1cc',
  306. mediumvioletred: '#c71585',
  307. midnightblue: '#191970',
  308. mintcream: '#f5fffa',
  309. mistyrose: '#ffe4e1',
  310. moccasin: '#ffe4b5',
  311. navajowhite: '#ffdead',
  312. navy: '#000080',
  313. oldlace: '#fdf5e6',
  314. olive: '#808000',
  315. olivedrab: '#6b8e23',
  316. orange: '#ffa500',
  317. orangered: '#ff4500',
  318. orchid: '#da70d6',
  319. palegoldenrod: '#eee8aa',
  320. palegreen: '#98fb98',
  321. paleturquoise: '#afeeee',
  322. palevioletred: '#db7093',
  323. papayawhip: '#ffefd5',
  324. peachpuff: '#ffdab9',
  325. peru: '#cd853f',
  326. pink: '#ffc0cb',
  327. plum: '#dda0dd',
  328. powderblue: '#b0e0e6',
  329. purple: '#800080',
  330. purple2: '#7f007f',
  331. purple3: '#a020f0',
  332. rebeccapurple: '#663399',
  333. red: '#ff0000',
  334. rosybrown: '#bc8f8f',
  335. royalblue: '#4169e1',
  336. saddlebrown: '#8b4513',
  337. salmon: '#fa8072',
  338. sandybrown: '#f4a460',
  339. seagreen: '#2e8b57',
  340. seashell: '#fff5ee',
  341. sienna: '#a0522d',
  342. silver: '#c0c0c0',
  343. skyblue: '#87ceeb',
  344. slateblue: '#6a5acd',
  345. slategray: '#708090',
  346. slategrey: '#708090',
  347. snow: '#fffafa',
  348. springgreen: '#00ff7f',
  349. steelblue: '#4682b4',
  350. tan: '#d2b48c',
  351. teal: '#008080',
  352. thistle: '#d8bfd8',
  353. tomato: '#ff6347',
  354. turquoise: '#40e0d0',
  355. violet: '#ee82ee',
  356. wheat: '#f5deb3',
  357. white: '#ffffff',
  358. whitesmoke: '#f5f5f5',
  359. yellow: '#ffff00',
  360. yellowgreen: '#9acd32'
  361. };
  362.  
  363. const RE_HEX$1 = /^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/;
  364. const RE_HEXA$1 = /^#?([A-Fa-f0-9]{8}|[A-Fa-f0-9]{4})$/;
  365.  
  366. const hex2rgb$1 = (hex) => {
  367. if (hex.match(RE_HEX$1)) {
  368. // remove optional leading #
  369. if (hex.length === 4 || hex.length === 7) {
  370. hex = hex.substr(1);
  371. }
  372. // expand short-notation to full six-digit
  373. if (hex.length === 3) {
  374. hex = hex.split('');
  375. hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
  376. }
  377. const u = parseInt(hex, 16);
  378. const r = u >> 16;
  379. const g = (u >> 8) & 0xff;
  380. const b = u & 0xff;
  381. return [r, g, b, 1];
  382. }
  383.  
  384. // match rgba hex format, eg #FF000077
  385. if (hex.match(RE_HEXA$1)) {
  386. if (hex.length === 5 || hex.length === 9) {
  387. // remove optional leading #
  388. hex = hex.substr(1);
  389. }
  390. // expand short-notation to full eight-digit
  391. if (hex.length === 4) {
  392. hex = hex.split('');
  393. hex =
  394. hex[0] +
  395. hex[0] +
  396. hex[1] +
  397. hex[1] +
  398. hex[2] +
  399. hex[2] +
  400. hex[3] +
  401. hex[3];
  402. }
  403. const u = parseInt(hex, 16);
  404. const r = (u >> 24) & 0xff;
  405. const g = (u >> 16) & 0xff;
  406. const b = (u >> 8) & 0xff;
  407. const a = Math.round(((u & 0xff) / 0xff) * 100) / 100;
  408. return [r, g, b, a];
  409. }
  410.  
  411. // we used to check for css colors here
  412. // if _input.css? and rgb = _input.css hex
  413. // return rgb
  414.  
  415. throw new Error(`unknown hex color: ${hex}`);
  416. };
  417.  
  418. const { round: round$8 } = Math;
  419.  
  420. const rgb2hex$1 = (...args) => {
  421. let [r, g, b, a] = unpack(args, 'rgba');
  422. let mode = last(args) || 'auto';
  423. if (a === undefined) a = 1;
  424. if (mode === 'auto') {
  425. mode = a < 1 ? 'rgba' : 'rgb';
  426. }
  427. r = round$8(r);
  428. g = round$8(g);
  429. b = round$8(b);
  430. const u = (r << 16) | (g << 8) | b;
  431. let str = '000000' + u.toString(16); //#.toUpperCase();
  432. str = str.substr(str.length - 6);
  433. let hxa = '0' + round$8(a * 255).toString(16);
  434. hxa = hxa.substr(hxa.length - 2);
  435. switch (mode.toLowerCase()) {
  436. case 'rgba':
  437. return `#${str}${hxa}`;
  438. case 'argb':
  439. return `#${hxa}${str}`;
  440. default:
  441. return `#${str}`;
  442. }
  443. };
  444.  
  445. Color$2.prototype.name = function () {
  446. const hex = rgb2hex$1(this._rgb, 'rgb');
  447. for (let n of Object.keys(w3cx11$1)) {
  448. if (w3cx11$1[n] === hex) return n.toLowerCase();
  449. }
  450. return hex;
  451. };
  452.  
  453. input$1.format.named = (name) => {
  454. name = name.toLowerCase();
  455. if (w3cx11$1[name]) return hex2rgb$1(w3cx11$1[name]);
  456. throw new Error('unknown color name: ' + name);
  457. };
  458.  
  459. input$1.autodetect.push({
  460. p: 5,
  461. test: (h, ...rest) => {
  462. if (!rest.length && type(h) === 'string' && w3cx11$1[h.toLowerCase()]) {
  463. return 'named';
  464. }
  465. }
  466. });
  467.  
  468. let Color$1 = class Color {
  469. constructor(...args) {
  470. const me = this;
  471. if (
  472. type(args[0]) === 'object' &&
  473. args[0].constructor &&
  474. args[0].constructor === this.constructor
  475. ) {
  476. // the argument is already a Color instance
  477. return args[0];
  478. }
  479. // last argument could be the mode
  480. let mode = last(args);
  481. let autodetect = false;
  482. if (!mode) {
  483. autodetect = true;
  484.  
  485. if (!_input.sorted) {
  486. _input.autodetect = _input.autodetect.sort((a, b) => b.p - a.p);
  487. _input.sorted = true;
  488. }
  489.  
  490. // auto-detect format
  491. for (let chk of _input.autodetect) {
  492. mode = chk.test(...args);
  493. if (mode) break;
  494. }
  495. }
  496. if (_input.format[mode]) {
  497. const rgb = _input.format[mode].apply(
  498. null,
  499. autodetect ? args : args.slice(0, -1)
  500. );
  501. me._rgb = clip_rgb(rgb);
  502. } else {
  503. throw new Error('unknown format: ' + args);
  504. }
  505. // add alpha channel
  506. if (me._rgb.length === 3) me._rgb.push(1);
  507. }
  508. toString() {
  509. if (type(this.hex) == 'function') return this.hex();
  510. return `[${this._rgb.join(',')}]`;
  511. }
  512. };
  513.  
  514. const { PI: PI$2} = Math;
  515.  
  516. const TWOPI = PI$2 * 2;
  517.  
  518. Color$1.prototype.alpha = function (a, mutate = false) {
  519. if (a !== undefined && type(a) === 'number') {
  520. if (mutate) {
  521. this._rgb[3] = a;
  522. return this;
  523. }
  524. return new Color$1([this._rgb[0], this._rgb[1], this._rgb[2], a], 'rgb');
  525. }
  526. return this._rgb[3];
  527. };
  528.  
  529. Color$1.prototype.clipped = function () {
  530. return this._rgb._clipped || false;
  531. };
  532.  
  533. const chroma$1 = (...args) => {
  534. return new Color$3(...args);
  535. };
  536.  
  537. chroma$1.version = version;
  538.  
  539. const labConstants$2 = {
  540. // D65 standard referent
  541. labWhitePoint: 'd65',
  542. Xn: 0.95047,
  543. Yn: 1,
  544. Zn: 1.08883,
  545.  
  546. kE: 216.0 / 24389.0,
  547. kKE: 8.0,
  548. kK: 24389.0 / 27.0,
  549.  
  550. RefWhiteRGB: {
  551. // sRGB
  552. X: 0.95047,
  553. Y: 1,
  554. Z: 1.08883
  555. },
  556.  
  557. MtxRGB2XYZ: {
  558. m00: 0.4124564390896922,
  559. m01: 0.21267285140562253,
  560. m02: 0.0193338955823293,
  561. m10: 0.357576077643909,
  562. m11: 0.715152155287818,
  563. m12: 0.11919202588130297,
  564. m20: 0.18043748326639894,
  565. m21: 0.07217499330655958,
  566. m22: 0.9503040785363679
  567. },
  568.  
  569. MtxXYZ2RGB: {
  570. m00: 3.2404541621141045,
  571. m01: -0.9692660305051868,
  572. m02: 0.055643430959114726,
  573. m10: -1.5371385127977166,
  574. m11: 1.8760108454466942,
  575. m12: -0.2040259135167538,
  576. m20: -0.498531409556016,
  577. m21: 0.041556017530349834,
  578. m22: 1.0572251882231791
  579. },
  580.  
  581. // used in rgb2xyz
  582. As: 0.9414285350000001,
  583. Bs: 1.040417467,
  584. Cs: 1.089532651,
  585.  
  586. MtxAdaptMa: {
  587. m00: 0.8951,
  588. m01: -0.7502,
  589. m02: 0.0389,
  590. m10: 0.2664,
  591. m11: 1.7135,
  592. m12: -0.0685,
  593. m20: -0.1614,
  594. m21: 0.0367,
  595. m22: 1.0296
  596. },
  597.  
  598. MtxAdaptMaI: {
  599. m00: 0.9869929054667123,
  600. m01: 0.43230526972339456,
  601. m02: -0.008528664575177328,
  602. m10: -0.14705425642099013,
  603. m11: 0.5183602715367776,
  604. m12: 0.04004282165408487,
  605. m20: 0.15996265166373125,
  606. m21: 0.0492912282128556,
  607. m22: 0.9684866957875502
  608. }
  609. };
  610.  
  611. // taken from https://de.mathworks.com/help/images/ref/whitepoint.html
  612. const ILLUMINANTS$1 = new Map([
  613. // ASTM E308-01
  614. ['a', [1.0985, 0.35585]],
  615. // Wyszecki & Stiles, p. 769
  616. ['b', [1.0985, 0.35585]],
  617. // C ASTM E308-01
  618. ['c', [0.98074, 1.18232]],
  619. // D50 (ASTM E308-01)
  620. ['d50', [0.96422, 0.82521]],
  621. // D55 (ASTM E308-01)
  622. ['d55', [0.95682, 0.92149]],
  623. // D65 (ASTM E308-01)
  624. ['d65', [0.95047, 1.08883]],
  625. // E (ASTM E308-01)
  626. ['e', [1, 1, 1]],
  627. // F2 (ASTM E308-01)
  628. ['f2', [0.99186, 0.67393]],
  629. // F7 (ASTM E308-01)
  630. ['f7', [0.95041, 1.08747]],
  631. // F11 (ASTM E308-01)
  632. ['f11', [1.00962, 0.6435]],
  633. ['icc', [0.96422, 0.82521]]
  634. ]);
  635.  
  636. function setLabWhitePoint$1(name) {
  637. const ill = ILLUMINANTS$1.get(String(name).toLowerCase());
  638. if (!ill) {
  639. throw new Error('unknown Lab illuminant ' + name);
  640. }
  641. labConstants$2.labWhitePoint = name;
  642. labConstants$2.Xn = ill[0];
  643. labConstants$2.Zn = ill[1];
  644. }
  645.  
  646. function getLabWhitePoint$1() {
  647. return labConstants$2.labWhitePoint;
  648. }
  649.  
  650. /*
  651. * L* [0..100]
  652. * a [-100..100]
  653. * b [-100..100]
  654. */
  655. const lab2rgb$1 = (...args) => {
  656. args = unpack(args, 'lab');
  657. const [L, a, b] = args;
  658. const [x, y, z] = lab2xyz$1(L, a, b);
  659. const [r, g, b_] = xyz2rgb$1(x, y, z);
  660. return [r, g, b_, args.length > 3 ? args[3] : 1];
  661. };
  662.  
  663. const lab2xyz$1 = (L, a, b) => {
  664. const { kE, kK, kKE, Xn, Yn, Zn } = labConstants$2;
  665.  
  666. const fy = (L + 16.0) / 116.0;
  667. const fx = 0.002 * a + fy;
  668. const fz = fy - 0.005 * b;
  669.  
  670. const fx3 = fx * fx * fx;
  671. const fz3 = fz * fz * fz;
  672.  
  673. const xr = fx3 > kE ? fx3 : (116.0 * fx - 16.0) / kK;
  674. const yr = L > kKE ? Math.pow((L + 16.0) / 116.0, 3.0) : L / kK;
  675. const zr = fz3 > kE ? fz3 : (116.0 * fz - 16.0) / kK;
  676.  
  677. const x = xr * Xn;
  678. const y = yr * Yn;
  679. const z = zr * Zn;
  680.  
  681. return [x, y, z];
  682. };
  683.  
  684. const compand$1 = (linear) => {
  685. /* sRGB */
  686. const sign = Math.sign(linear);
  687. linear = Math.abs(linear);
  688. return (
  689. (linear <= 0.0031308
  690. ? linear * 12.92
  691. : 1.055 * Math.pow(linear, 1.0 / 2.4) - 0.055) * sign
  692. );
  693. };
  694.  
  695. const xyz2rgb$1 = (x, y, z) => {
  696. const { MtxAdaptMa, MtxAdaptMaI, MtxXYZ2RGB, RefWhiteRGB, Xn, Yn, Zn } =
  697. labConstants$2;
  698.  
  699. const As = Xn * MtxAdaptMa.m00 + Yn * MtxAdaptMa.m10 + Zn * MtxAdaptMa.m20;
  700. const Bs = Xn * MtxAdaptMa.m01 + Yn * MtxAdaptMa.m11 + Zn * MtxAdaptMa.m21;
  701. const Cs = Xn * MtxAdaptMa.m02 + Yn * MtxAdaptMa.m12 + Zn * MtxAdaptMa.m22;
  702.  
  703. const Ad =
  704. RefWhiteRGB.X * MtxAdaptMa.m00 +
  705. RefWhiteRGB.Y * MtxAdaptMa.m10 +
  706. RefWhiteRGB.Z * MtxAdaptMa.m20;
  707. const Bd =
  708. RefWhiteRGB.X * MtxAdaptMa.m01 +
  709. RefWhiteRGB.Y * MtxAdaptMa.m11 +
  710. RefWhiteRGB.Z * MtxAdaptMa.m21;
  711. const Cd =
  712. RefWhiteRGB.X * MtxAdaptMa.m02 +
  713. RefWhiteRGB.Y * MtxAdaptMa.m12 +
  714. RefWhiteRGB.Z * MtxAdaptMa.m22;
  715.  
  716. const X1 =
  717. (x * MtxAdaptMa.m00 + y * MtxAdaptMa.m10 + z * MtxAdaptMa.m20) *
  718. (Ad / As);
  719. const Y1 =
  720. (x * MtxAdaptMa.m01 + y * MtxAdaptMa.m11 + z * MtxAdaptMa.m21) *
  721. (Bd / Bs);
  722. const Z1 =
  723. (x * MtxAdaptMa.m02 + y * MtxAdaptMa.m12 + z * MtxAdaptMa.m22) *
  724. (Cd / Cs);
  725.  
  726. const X2 =
  727. X1 * MtxAdaptMaI.m00 + Y1 * MtxAdaptMaI.m10 + Z1 * MtxAdaptMaI.m20;
  728. const Y2 =
  729. X1 * MtxAdaptMaI.m01 + Y1 * MtxAdaptMaI.m11 + Z1 * MtxAdaptMaI.m21;
  730. const Z2 =
  731. X1 * MtxAdaptMaI.m02 + Y1 * MtxAdaptMaI.m12 + Z1 * MtxAdaptMaI.m22;
  732.  
  733. const r = compand$1(
  734. X2 * MtxXYZ2RGB.m00 + Y2 * MtxXYZ2RGB.m10 + Z2 * MtxXYZ2RGB.m20
  735. );
  736. const g = compand$1(
  737. X2 * MtxXYZ2RGB.m01 + Y2 * MtxXYZ2RGB.m11 + Z2 * MtxXYZ2RGB.m21
  738. );
  739. const b = compand$1(
  740. X2 * MtxXYZ2RGB.m02 + Y2 * MtxXYZ2RGB.m12 + Z2 * MtxXYZ2RGB.m22
  741. );
  742.  
  743. return [r * 255, g * 255, b * 255];
  744. };
  745.  
  746. const rgb2lab$1 = (...args) => {
  747. const [r, g, b, ...rest] = unpack(args, 'rgb');
  748. const [x, y, z] = rgb2xyz$1(r, g, b);
  749. const [L, a, b_] = xyz2lab$1(x, y, z);
  750. return [L, a, b_, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
  751. };
  752.  
  753. function xyz2lab$1(x, y, z) {
  754. const { Xn, Yn, Zn, kE, kK } = labConstants$2;
  755. const xr = x / Xn;
  756. const yr = y / Yn;
  757. const zr = z / Zn;
  758.  
  759. const fx = xr > kE ? Math.pow(xr, 1.0 / 3.0) : (kK * xr + 16.0) / 116.0;
  760. const fy = yr > kE ? Math.pow(yr, 1.0 / 3.0) : (kK * yr + 16.0) / 116.0;
  761. const fz = zr > kE ? Math.pow(zr, 1.0 / 3.0) : (kK * zr + 16.0) / 116.0;
  762.  
  763. return [116.0 * fy - 16.0, 500.0 * (fx - fy), 200.0 * (fy - fz)];
  764. }
  765.  
  766. function gammaAdjustSRGB$1(companded) {
  767. const sign = Math.sign(companded);
  768. companded = Math.abs(companded);
  769. const linear =
  770. companded <= 0.04045
  771. ? companded / 12.92
  772. : Math.pow((companded + 0.055) / 1.055, 2.4);
  773. return linear * sign;
  774. }
  775.  
  776. const rgb2xyz$1 = (r, g, b) => {
  777. // normalize and gamma adjust
  778. r = gammaAdjustSRGB$1(r / 255);
  779. g = gammaAdjustSRGB$1(g / 255);
  780. b = gammaAdjustSRGB$1(b / 255);
  781.  
  782. const { MtxRGB2XYZ, MtxAdaptMa, MtxAdaptMaI, Xn, Yn, Zn, As, Bs, Cs } =
  783. labConstants$2;
  784.  
  785. let x = r * MtxRGB2XYZ.m00 + g * MtxRGB2XYZ.m10 + b * MtxRGB2XYZ.m20;
  786. let y = r * MtxRGB2XYZ.m01 + g * MtxRGB2XYZ.m11 + b * MtxRGB2XYZ.m21;
  787. let z = r * MtxRGB2XYZ.m02 + g * MtxRGB2XYZ.m12 + b * MtxRGB2XYZ.m22;
  788.  
  789. const Ad = Xn * MtxAdaptMa.m00 + Yn * MtxAdaptMa.m10 + Zn * MtxAdaptMa.m20;
  790. const Bd = Xn * MtxAdaptMa.m01 + Yn * MtxAdaptMa.m11 + Zn * MtxAdaptMa.m21;
  791. const Cd = Xn * MtxAdaptMa.m02 + Yn * MtxAdaptMa.m12 + Zn * MtxAdaptMa.m22;
  792.  
  793. let X = x * MtxAdaptMa.m00 + y * MtxAdaptMa.m10 + z * MtxAdaptMa.m20;
  794. let Y = x * MtxAdaptMa.m01 + y * MtxAdaptMa.m11 + z * MtxAdaptMa.m21;
  795. let Z = x * MtxAdaptMa.m02 + y * MtxAdaptMa.m12 + z * MtxAdaptMa.m22;
  796.  
  797. X *= Ad / As;
  798. Y *= Bd / Bs;
  799. Z *= Cd / Cs;
  800.  
  801. x = X * MtxAdaptMaI.m00 + Y * MtxAdaptMaI.m10 + Z * MtxAdaptMaI.m20;
  802. y = X * MtxAdaptMaI.m01 + Y * MtxAdaptMaI.m11 + Z * MtxAdaptMaI.m21;
  803. z = X * MtxAdaptMaI.m02 + Y * MtxAdaptMaI.m12 + Z * MtxAdaptMaI.m22;
  804.  
  805. return [x, y, z];
  806. };
  807.  
  808. Color$2.prototype.lab = function () {
  809. return rgb2lab$1(this._rgb);
  810. };
  811.  
  812. const lab$1 = (...args) => new Color$2(...args, 'lab');
  813. Object.assign(chroma$1, { lab: lab$1, getLabWhitePoint: getLabWhitePoint$1, setLabWhitePoint: setLabWhitePoint$1 });
  814.  
  815. input$1.format.lab = lab2rgb$1;
  816.  
  817. input$1.autodetect.push({
  818. p: 2,
  819. test: (...args) => {
  820. args = unpack(args, 'lab');
  821. if (type(args) === 'array' && args.length === 3) {
  822. return 'lab';
  823. }
  824. }
  825. });
  826.  
  827. const labConstants$1 = {
  828. // Corresponds roughly to RGB brighter/darker
  829. Kn: 18};
  830.  
  831. Color$1.prototype.darken = function (amount = 1) {
  832. const me = this;
  833. const lab = me.lab();
  834. lab[0] -= labConstants$1.Kn * amount;
  835. return new Color$1(lab, 'lab').alpha(me.alpha(), true);
  836. };
  837.  
  838. Color$1.prototype.brighten = function (amount = 1) {
  839. return this.darken(-amount);
  840. };
  841.  
  842. Color$1.prototype.darker = Color$1.prototype.darken;
  843. Color$1.prototype.brighter = Color$1.prototype.brighten;
  844.  
  845. Color$1.prototype.get = function (mc) {
  846. const [mode, channel] = mc.split('.');
  847. const src = this[mode]();
  848. if (channel) {
  849. const i = mode.indexOf(channel) - (mode.substr(0, 2) === 'ok' ? 2 : 0);
  850. if (i > -1) return src[i];
  851. throw new Error(`unknown channel ${channel} in mode ${mode}`);
  852. } else {
  853. return src;
  854. }
  855. };
  856.  
  857. const { pow: pow$8 } = Math;
  858.  
  859. const EPS$1 = 1e-7;
  860. const MAX_ITER$1 = 20;
  861.  
  862. Color$1.prototype.luminance = function (lum, mode = 'rgb') {
  863. if (lum !== undefined && type(lum) === 'number') {
  864. if (lum === 0) {
  865. // return pure black
  866. return new Color$1([0, 0, 0, this._rgb[3]], 'rgb');
  867. }
  868. if (lum === 1) {
  869. // return pure white
  870. return new Color$1([255, 255, 255, this._rgb[3]], 'rgb');
  871. }
  872. // compute new color using...
  873. let cur_lum = this.luminance();
  874. let max_iter = MAX_ITER$1;
  875.  
  876. const test = (low, high) => {
  877. const mid = low.interpolate(high, 0.5, mode);
  878. const lm = mid.luminance();
  879. if (Math.abs(lum - lm) < EPS$1 || !max_iter--) {
  880. // close enough
  881. return mid;
  882. }
  883. return lm > lum ? test(low, mid) : test(mid, high);
  884. };
  885.  
  886. const rgb = (
  887. cur_lum > lum
  888. ? test(new Color$1([0, 0, 0]), this)
  889. : test(this, new Color$1([255, 255, 255]))
  890. ).rgb();
  891. return new Color$1([...rgb, this._rgb[3]]);
  892. }
  893. return rgb2luminance$1(...this._rgb.slice(0, 3));
  894. };
  895.  
  896. const rgb2luminance$1 = (r, g, b) => {
  897. // relative luminance
  898. // see http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
  899. r = luminance_x$1(r);
  900. g = luminance_x$1(g);
  901. b = luminance_x$1(b);
  902. return 0.2126 * r + 0.7152 * g + 0.0722 * b;
  903. };
  904.  
  905. const luminance_x$1 = (x) => {
  906. x /= 255;
  907. return x <= 0.03928 ? x / 12.92 : pow$8((x + 0.055) / 1.055, 2.4);
  908. };
  909.  
  910. var interpolator = {};
  911.  
  912. var mix$1 = (col1, col2, f = 0.5, ...rest) => {
  913. let mode = rest[0] || 'lrgb';
  914. if (!interpolator[mode] && !rest.length) {
  915. // fall back to the first supported mode
  916. mode = Object.keys(interpolator)[0];
  917. }
  918. if (!interpolator[mode]) {
  919. throw new Error(`interpolation mode ${mode} is not defined`);
  920. }
  921. if (type(col1) !== 'object') col1 = new Color$1(col1);
  922. if (type(col2) !== 'object') col2 = new Color$1(col2);
  923. return interpolator[mode](col1, col2, f).alpha(
  924. col1.alpha() + f * (col2.alpha() - col1.alpha())
  925. );
  926. };
  927.  
  928. Color$1.prototype.mix = Color$1.prototype.interpolate = function (
  929. col2,
  930. f = 0.5,
  931. ...rest
  932. ) {
  933. return mix$1(this, col2, f, ...rest);
  934. };
  935.  
  936. Color$1.prototype.premultiply = function (mutate = false) {
  937. const rgb = this._rgb;
  938. const a = rgb[3];
  939. if (mutate) {
  940. this._rgb = [rgb[0] * a, rgb[1] * a, rgb[2] * a, a];
  941. return this;
  942. } else {
  943. return new Color$1([rgb[0] * a, rgb[1] * a, rgb[2] * a, a], 'rgb');
  944. }
  945. };
  946.  
  947. const { sin: sin$4, cos: cos$5 } = Math;
  948.  
  949. const lch2lab$1 = (...args) => {
  950. /*
  951. Convert from a qualitative parameter h and a quantitative parameter l to a 24-bit pixel.
  952. These formulas were invented by David Dalrymple to obtain maximum contrast without going
  953. out of gamut if the parameters are in the range 0-1.
  954.  
  955. A saturation multiplier was added by Gregor Aisch
  956. */
  957. let [l, c, h] = unpack(args, 'lch');
  958. if (isNaN(h)) h = 0;
  959. h = h * DEG2RAD;
  960. return [l, cos$5(h) * c, sin$4(h) * c];
  961. };
  962.  
  963. /*
  964. * L* [0..100]
  965. * a [-100..100]
  966. * b [-100..100]
  967. */
  968. const lab2rgb = (...args) => {
  969. args = unpack(args, 'lab');
  970. const [L, a, b] = args;
  971. const [x, y, z] = lab2xyz(L, a, b);
  972. const [r, g, b_] = xyz2rgb(x, y, z);
  973. return [r, g, b_, args.length > 3 ? args[3] : 1];
  974. };
  975.  
  976. const lab2xyz = (L, a, b) => {
  977. const { kE, kK, kKE, Xn, Yn, Zn } = labConstants$2;
  978.  
  979. const fy = (L + 16.0) / 116.0;
  980. const fx = 0.002 * a + fy;
  981. const fz = fy - 0.005 * b;
  982.  
  983. const fx3 = fx * fx * fx;
  984. const fz3 = fz * fz * fz;
  985.  
  986. const xr = fx3 > kE ? fx3 : (116.0 * fx - 16.0) / kK;
  987. const yr = L > kKE ? Math.pow((L + 16.0) / 116.0, 3.0) : L / kK;
  988. const zr = fz3 > kE ? fz3 : (116.0 * fz - 16.0) / kK;
  989.  
  990. const x = xr * Xn;
  991. const y = yr * Yn;
  992. const z = zr * Zn;
  993.  
  994. return [x, y, z];
  995. };
  996.  
  997. const compand = (linear) => {
  998. /* sRGB */
  999. const sign = Math.sign(linear);
  1000. linear = Math.abs(linear);
  1001. return (
  1002. (linear <= 0.0031308
  1003. ? linear * 12.92
  1004. : 1.055 * Math.pow(linear, 1.0 / 2.4) - 0.055) * sign
  1005. );
  1006. };
  1007.  
  1008. const xyz2rgb = (x, y, z) => {
  1009. const { MtxAdaptMa, MtxAdaptMaI, MtxXYZ2RGB, RefWhiteRGB, Xn, Yn, Zn } =
  1010. labConstants$2;
  1011.  
  1012. const As = Xn * MtxAdaptMa.m00 + Yn * MtxAdaptMa.m10 + Zn * MtxAdaptMa.m20;
  1013. const Bs = Xn * MtxAdaptMa.m01 + Yn * MtxAdaptMa.m11 + Zn * MtxAdaptMa.m21;
  1014. const Cs = Xn * MtxAdaptMa.m02 + Yn * MtxAdaptMa.m12 + Zn * MtxAdaptMa.m22;
  1015.  
  1016. const Ad =
  1017. RefWhiteRGB.X * MtxAdaptMa.m00 +
  1018. RefWhiteRGB.Y * MtxAdaptMa.m10 +
  1019. RefWhiteRGB.Z * MtxAdaptMa.m20;
  1020. const Bd =
  1021. RefWhiteRGB.X * MtxAdaptMa.m01 +
  1022. RefWhiteRGB.Y * MtxAdaptMa.m11 +
  1023. RefWhiteRGB.Z * MtxAdaptMa.m21;
  1024. const Cd =
  1025. RefWhiteRGB.X * MtxAdaptMa.m02 +
  1026. RefWhiteRGB.Y * MtxAdaptMa.m12 +
  1027. RefWhiteRGB.Z * MtxAdaptMa.m22;
  1028.  
  1029. const X1 =
  1030. (x * MtxAdaptMa.m00 + y * MtxAdaptMa.m10 + z * MtxAdaptMa.m20) *
  1031. (Ad / As);
  1032. const Y1 =
  1033. (x * MtxAdaptMa.m01 + y * MtxAdaptMa.m11 + z * MtxAdaptMa.m21) *
  1034. (Bd / Bs);
  1035. const Z1 =
  1036. (x * MtxAdaptMa.m02 + y * MtxAdaptMa.m12 + z * MtxAdaptMa.m22) *
  1037. (Cd / Cs);
  1038.  
  1039. const X2 =
  1040. X1 * MtxAdaptMaI.m00 + Y1 * MtxAdaptMaI.m10 + Z1 * MtxAdaptMaI.m20;
  1041. const Y2 =
  1042. X1 * MtxAdaptMaI.m01 + Y1 * MtxAdaptMaI.m11 + Z1 * MtxAdaptMaI.m21;
  1043. const Z2 =
  1044. X1 * MtxAdaptMaI.m02 + Y1 * MtxAdaptMaI.m12 + Z1 * MtxAdaptMaI.m22;
  1045.  
  1046. const r = compand(
  1047. X2 * MtxXYZ2RGB.m00 + Y2 * MtxXYZ2RGB.m10 + Z2 * MtxXYZ2RGB.m20
  1048. );
  1049. const g = compand(
  1050. X2 * MtxXYZ2RGB.m01 + Y2 * MtxXYZ2RGB.m11 + Z2 * MtxXYZ2RGB.m21
  1051. );
  1052. const b = compand(
  1053. X2 * MtxXYZ2RGB.m02 + Y2 * MtxXYZ2RGB.m12 + Z2 * MtxXYZ2RGB.m22
  1054. );
  1055.  
  1056. return [r * 255, g * 255, b * 255];
  1057. };
  1058.  
  1059. const lch2rgb$1 = (...args) => {
  1060. args = unpack(args, 'lch');
  1061. const [l, c, h] = args;
  1062. const [L, a, b_] = lch2lab$1(l, c, h);
  1063. const [r, g, b] = lab2rgb(L, a, b_);
  1064. return [r, g, b, args.length > 3 ? args[3] : 1];
  1065. };
  1066.  
  1067. const hcl2rgb = (...args) => {
  1068. const hcl = reverse3(unpack(args, 'hcl'));
  1069. return lch2rgb$1(...hcl);
  1070. };
  1071.  
  1072. const rgb2lab = (...args) => {
  1073. const [r, g, b, ...rest] = unpack(args, 'rgb');
  1074. const [x, y, z] = rgb2xyz(r, g, b);
  1075. const [L, a, b_] = xyz2lab(x, y, z);
  1076. return [L, a, b_, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
  1077. };
  1078.  
  1079. function xyz2lab(x, y, z) {
  1080. const { Xn, Yn, Zn, kE, kK } = labConstants$2;
  1081. const xr = x / Xn;
  1082. const yr = y / Yn;
  1083. const zr = z / Zn;
  1084.  
  1085. const fx = xr > kE ? Math.pow(xr, 1.0 / 3.0) : (kK * xr + 16.0) / 116.0;
  1086. const fy = yr > kE ? Math.pow(yr, 1.0 / 3.0) : (kK * yr + 16.0) / 116.0;
  1087. const fz = zr > kE ? Math.pow(zr, 1.0 / 3.0) : (kK * zr + 16.0) / 116.0;
  1088.  
  1089. return [116.0 * fy - 16.0, 500.0 * (fx - fy), 200.0 * (fy - fz)];
  1090. }
  1091.  
  1092. function gammaAdjustSRGB(companded) {
  1093. const sign = Math.sign(companded);
  1094. companded = Math.abs(companded);
  1095. const linear =
  1096. companded <= 0.04045
  1097. ? companded / 12.92
  1098. : Math.pow((companded + 0.055) / 1.055, 2.4);
  1099. return linear * sign;
  1100. }
  1101.  
  1102. const rgb2xyz = (r, g, b) => {
  1103. // normalize and gamma adjust
  1104. r = gammaAdjustSRGB(r / 255);
  1105. g = gammaAdjustSRGB(g / 255);
  1106. b = gammaAdjustSRGB(b / 255);
  1107.  
  1108. const { MtxRGB2XYZ, MtxAdaptMa, MtxAdaptMaI, Xn, Yn, Zn, As, Bs, Cs } =
  1109. labConstants$2;
  1110.  
  1111. let x = r * MtxRGB2XYZ.m00 + g * MtxRGB2XYZ.m10 + b * MtxRGB2XYZ.m20;
  1112. let y = r * MtxRGB2XYZ.m01 + g * MtxRGB2XYZ.m11 + b * MtxRGB2XYZ.m21;
  1113. let z = r * MtxRGB2XYZ.m02 + g * MtxRGB2XYZ.m12 + b * MtxRGB2XYZ.m22;
  1114.  
  1115. const Ad = Xn * MtxAdaptMa.m00 + Yn * MtxAdaptMa.m10 + Zn * MtxAdaptMa.m20;
  1116. const Bd = Xn * MtxAdaptMa.m01 + Yn * MtxAdaptMa.m11 + Zn * MtxAdaptMa.m21;
  1117. const Cd = Xn * MtxAdaptMa.m02 + Yn * MtxAdaptMa.m12 + Zn * MtxAdaptMa.m22;
  1118.  
  1119. let X = x * MtxAdaptMa.m00 + y * MtxAdaptMa.m10 + z * MtxAdaptMa.m20;
  1120. let Y = x * MtxAdaptMa.m01 + y * MtxAdaptMa.m11 + z * MtxAdaptMa.m21;
  1121. let Z = x * MtxAdaptMa.m02 + y * MtxAdaptMa.m12 + z * MtxAdaptMa.m22;
  1122.  
  1123. X *= Ad / As;
  1124. Y *= Bd / Bs;
  1125. Z *= Cd / Cs;
  1126.  
  1127. x = X * MtxAdaptMaI.m00 + Y * MtxAdaptMaI.m10 + Z * MtxAdaptMaI.m20;
  1128. y = X * MtxAdaptMaI.m01 + Y * MtxAdaptMaI.m11 + Z * MtxAdaptMaI.m21;
  1129. z = X * MtxAdaptMaI.m02 + Y * MtxAdaptMaI.m12 + Z * MtxAdaptMaI.m22;
  1130.  
  1131. return [x, y, z];
  1132. };
  1133.  
  1134. const { sqrt: sqrt$4, atan2: atan2$3, round: round$7 } = Math;
  1135.  
  1136. const lab2lch$1 = (...args) => {
  1137. const [l, a, b] = unpack(args, 'lab');
  1138. const c = sqrt$4(a * a + b * b);
  1139. let h = (atan2$3(b, a) * RAD2DEG + 360) % 360;
  1140. if (round$7(c * 10000) === 0) h = Number.NaN;
  1141. return [l, c, h];
  1142. };
  1143.  
  1144. const rgb2lch$1 = (...args) => {
  1145. const [r, g, b, ...rest] = unpack(args, 'rgb');
  1146. const [l, a, b_] = rgb2lab(r, g, b);
  1147. const [L, c, h] = lab2lch$1(l, a, b_);
  1148. return [L, c, h, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
  1149. };
  1150.  
  1151. Color$2.prototype.lch = function () {
  1152. return rgb2lch$1(this._rgb);
  1153. };
  1154. Color$2.prototype.hcl = function () {
  1155. return reverse3(rgb2lch$1(this._rgb));
  1156. };
  1157.  
  1158. const lch$1 = (...args) => new Color$2(...args, 'lch');
  1159. const hcl$1 = (...args) => new Color$2(...args, 'hcl');
  1160.  
  1161. Object.assign(chroma$1, { lch: lch$1, hcl: hcl$1 });
  1162.  
  1163. input$1.format.lch = lch2rgb$1;
  1164. input$1.format.hcl = hcl2rgb;
  1165. ['lch', 'hcl'].forEach((m) =>
  1166. input$1.autodetect.push({
  1167. p: 2,
  1168. test: (...args) => {
  1169. args = unpack(args, m);
  1170. if (type(args) === 'array' && args.length === 3) {
  1171. return m;
  1172. }
  1173. }
  1174. })
  1175. );
  1176.  
  1177. Color$1.prototype.saturate = function (amount = 1) {
  1178. const me = this;
  1179. const lch = me.lch();
  1180. lch[1] += labConstants$1.Kn * amount;
  1181. if (lch[1] < 0) lch[1] = 0;
  1182. return new Color$1(lch, 'lch').alpha(me.alpha(), true);
  1183. };
  1184.  
  1185. Color$1.prototype.desaturate = function (amount = 1) {
  1186. return this.saturate(-amount);
  1187. };
  1188.  
  1189. Color$1.prototype.set = function (mc, value, mutate = false) {
  1190. const [mode, channel] = mc.split('.');
  1191. const src = this[mode]();
  1192. if (channel) {
  1193. const i = mode.indexOf(channel) - (mode.substr(0, 2) === 'ok' ? 2 : 0);
  1194. if (i > -1) {
  1195. if (type(value) == 'string') {
  1196. switch (value.charAt(0)) {
  1197. case '+':
  1198. src[i] += +value;
  1199. break;
  1200. case '-':
  1201. src[i] += +value;
  1202. break;
  1203. case '*':
  1204. src[i] *= +value.substr(1);
  1205. break;
  1206. case '/':
  1207. src[i] /= +value.substr(1);
  1208. break;
  1209. default:
  1210. src[i] = +value;
  1211. }
  1212. } else if (type(value) === 'number') {
  1213. src[i] = value;
  1214. } else {
  1215. throw new Error(`unsupported value for Color.set`);
  1216. }
  1217. const out = new Color$1(src, mode);
  1218. if (mutate) {
  1219. this._rgb = out._rgb;
  1220. return this;
  1221. }
  1222. return out;
  1223. }
  1224. throw new Error(`unknown channel ${channel} in mode ${mode}`);
  1225. } else {
  1226. return src;
  1227. }
  1228. };
  1229.  
  1230. Color$1.prototype.tint = function (f = 0.5, ...rest) {
  1231. return mix$1(this, 'white', f, ...rest);
  1232. };
  1233.  
  1234. Color$1.prototype.shade = function (f = 0.5, ...rest) {
  1235. return mix$1(this, 'black', f, ...rest);
  1236. };
  1237.  
  1238. const num2rgb = (num) => {
  1239. if (type(num) == 'number' && num >= 0 && num <= 0xffffff) {
  1240. const r = num >> 16;
  1241. const g = (num >> 8) & 0xff;
  1242. const b = num & 0xff;
  1243. return [r, g, b, 1];
  1244. }
  1245. throw new Error('unknown num color: ' + num);
  1246. };
  1247.  
  1248. const rgb2num = (...args) => {
  1249. const [r, g, b] = unpack(args, 'rgb');
  1250. return (r << 16) + (g << 8) + b;
  1251. };
  1252.  
  1253. Color$2.prototype.num = function () {
  1254. return rgb2num(this._rgb);
  1255. };
  1256.  
  1257. const num$1 = (...args) => new Color$2(...args, 'num');
  1258.  
  1259. Object.assign(chroma$1, { num: num$1 });
  1260.  
  1261. input$1.format.num = num2rgb;
  1262.  
  1263. input$1.autodetect.push({
  1264. p: 5,
  1265. test: (...args) => {
  1266. if (
  1267. args.length === 1 &&
  1268. type(args[0]) === 'number' &&
  1269. args[0] >= 0 &&
  1270. args[0] <= 0xffffff
  1271. ) {
  1272. return 'num';
  1273. }
  1274. }
  1275. });
  1276.  
  1277. const { floor: floor$3 } = Math;
  1278.  
  1279. /*
  1280. * this is basically just HSV with some minor tweaks
  1281. *
  1282. * hue.. [0..360]
  1283. * chroma .. [0..1]
  1284. * grayness .. [0..1]
  1285. */
  1286.  
  1287. const hcg2rgb = (...args) => {
  1288. args = unpack(args, 'hcg');
  1289. let [h, c, _g] = args;
  1290. let r, g, b;
  1291. _g = _g * 255;
  1292. const _c = c * 255;
  1293. if (c === 0) {
  1294. r = g = b = _g;
  1295. } else {
  1296. if (h === 360) h = 0;
  1297. if (h > 360) h -= 360;
  1298. if (h < 0) h += 360;
  1299. h /= 60;
  1300. const i = floor$3(h);
  1301. const f = h - i;
  1302. const p = _g * (1 - c);
  1303. const q = p + _c * (1 - f);
  1304. const t = p + _c * f;
  1305. const v = p + _c;
  1306. switch (i) {
  1307. case 0:
  1308. [r, g, b] = [v, t, p];
  1309. break;
  1310. case 1:
  1311. [r, g, b] = [q, v, p];
  1312. break;
  1313. case 2:
  1314. [r, g, b] = [p, v, t];
  1315. break;
  1316. case 3:
  1317. [r, g, b] = [p, q, v];
  1318. break;
  1319. case 4:
  1320. [r, g, b] = [t, p, v];
  1321. break;
  1322. case 5:
  1323. [r, g, b] = [v, p, q];
  1324. break;
  1325. }
  1326. }
  1327. return [r, g, b, args.length > 3 ? args[3] : 1];
  1328. };
  1329.  
  1330. const rgb2hcg = (...args) => {
  1331. const [r, g, b] = unpack(args, 'rgb');
  1332. const minRgb = min$4(r, g, b);
  1333. const maxRgb = max$4(r, g, b);
  1334. const delta = maxRgb - minRgb;
  1335. const c = (delta * 100) / 255;
  1336. const _g = (minRgb / (255 - delta)) * 100;
  1337. let h;
  1338. if (delta === 0) {
  1339. h = Number.NaN;
  1340. } else {
  1341. if (r === maxRgb) h = (g - b) / delta;
  1342. if (g === maxRgb) h = 2 + (b - r) / delta;
  1343. if (b === maxRgb) h = 4 + (r - g) / delta;
  1344. h *= 60;
  1345. if (h < 0) h += 360;
  1346. }
  1347. return [h, c, _g];
  1348. };
  1349.  
  1350. Color$2.prototype.hcg = function () {
  1351. return rgb2hcg(this._rgb);
  1352. };
  1353.  
  1354. const hcg$1 = (...args) => new Color$2(...args, 'hcg');
  1355. chroma$1.hcg = hcg$1;
  1356.  
  1357. input$1.format.hcg = hcg2rgb;
  1358.  
  1359. input$1.autodetect.push({
  1360. p: 1,
  1361. test: (...args) => {
  1362. args = unpack(args, 'hcg');
  1363. if (type(args) === 'array' && args.length === 3) {
  1364. return 'hcg';
  1365. }
  1366. }
  1367. });
  1368.  
  1369. const { cos: cos$4 } = Math;
  1370.  
  1371. /*
  1372. * hue [0..360]
  1373. * saturation [0..1]
  1374. * intensity [0..1]
  1375. */
  1376. const hsi2rgb = (...args) => {
  1377. /*
  1378. borrowed from here:
  1379. http://hummer.stanford.edu/museinfo/doc/examples/humdrum/keyscape2/hsi2rgb.cpp
  1380. */
  1381. args = unpack(args, 'hsi');
  1382. let [h, s, i] = args;
  1383. let r, g, b;
  1384.  
  1385. if (isNaN(h)) h = 0;
  1386. if (isNaN(s)) s = 0;
  1387. // normalize hue
  1388. if (h > 360) h -= 360;
  1389. if (h < 0) h += 360;
  1390. h /= 360;
  1391. if (h < 1 / 3) {
  1392. b = (1 - s) / 3;
  1393. r = (1 + (s * cos$4(TWOPI$1 * h)) / cos$4(PITHIRD - TWOPI$1 * h)) / 3;
  1394. g = 1 - (b + r);
  1395. } else if (h < 2 / 3) {
  1396. h -= 1 / 3;
  1397. r = (1 - s) / 3;
  1398. g = (1 + (s * cos$4(TWOPI$1 * h)) / cos$4(PITHIRD - TWOPI$1 * h)) / 3;
  1399. b = 1 - (r + g);
  1400. } else {
  1401. h -= 2 / 3;
  1402. g = (1 - s) / 3;
  1403. b = (1 + (s * cos$4(TWOPI$1 * h)) / cos$4(PITHIRD - TWOPI$1 * h)) / 3;
  1404. r = 1 - (g + b);
  1405. }
  1406. r = limit$1(i * r * 3);
  1407. g = limit$1(i * g * 3);
  1408. b = limit$1(i * b * 3);
  1409. return [r * 255, g * 255, b * 255, args.length > 3 ? args[3] : 1];
  1410. };
  1411.  
  1412. const { min: min$3, sqrt: sqrt$3, acos } = Math;
  1413.  
  1414. const rgb2hsi = (...args) => {
  1415. /*
  1416. borrowed from here:
  1417. http://hummer.stanford.edu/museinfo/doc/examples/humdrum/keyscape2/rgb2hsi.cpp
  1418. */
  1419. let [r, g, b] = unpack(args, 'rgb');
  1420. r /= 255;
  1421. g /= 255;
  1422. b /= 255;
  1423. let h;
  1424. const min_ = min$3(r, g, b);
  1425. const i = (r + g + b) / 3;
  1426. const s = i > 0 ? 1 - min_ / i : 0;
  1427. if (s === 0) {
  1428. h = NaN;
  1429. } else {
  1430. h = (r - g + (r - b)) / 2;
  1431. h /= sqrt$3((r - g) * (r - g) + (r - b) * (g - b));
  1432. h = acos(h);
  1433. if (b > g) {
  1434. h = TWOPI$1 - h;
  1435. }
  1436. h /= TWOPI$1;
  1437. }
  1438. return [h * 360, s, i];
  1439. };
  1440.  
  1441. Color$2.prototype.hsi = function () {
  1442. return rgb2hsi(this._rgb);
  1443. };
  1444.  
  1445. const hsi$1 = (...args) => new Color$2(...args, 'hsi');
  1446. chroma$1.hsi = hsi$1;
  1447.  
  1448. input$1.format.hsi = hsi2rgb;
  1449.  
  1450. input$1.autodetect.push({
  1451. p: 2,
  1452. test: (...args) => {
  1453. args = unpack(args, 'hsi');
  1454. if (type(args) === 'array' && args.length === 3) {
  1455. return 'hsi';
  1456. }
  1457. }
  1458. });
  1459.  
  1460. const hsl2rgb$1 = (...args) => {
  1461. args = unpack(args, 'hsl');
  1462. const [h, s, l] = args;
  1463. let r, g, b;
  1464. if (s === 0) {
  1465. r = g = b = l * 255;
  1466. } else {
  1467. const t3 = [0, 0, 0];
  1468. const c = [0, 0, 0];
  1469. const t2 = l < 0.5 ? l * (1 + s) : l + s - l * s;
  1470. const t1 = 2 * l - t2;
  1471. const h_ = h / 360;
  1472. t3[0] = h_ + 1 / 3;
  1473. t3[1] = h_;
  1474. t3[2] = h_ - 1 / 3;
  1475. for (let i = 0; i < 3; i++) {
  1476. if (t3[i] < 0) t3[i] += 1;
  1477. if (t3[i] > 1) t3[i] -= 1;
  1478. if (6 * t3[i] < 1) c[i] = t1 + (t2 - t1) * 6 * t3[i];
  1479. else if (2 * t3[i] < 1) c[i] = t2;
  1480. else if (3 * t3[i] < 2) c[i] = t1 + (t2 - t1) * (2 / 3 - t3[i]) * 6;
  1481. else c[i] = t1;
  1482. }
  1483. [r, g, b] = [c[0] * 255, c[1] * 255, c[2] * 255];
  1484. }
  1485. if (args.length > 3) {
  1486. // keep alpha channel
  1487. return [r, g, b, args[3]];
  1488. }
  1489. return [r, g, b, 1];
  1490. };
  1491.  
  1492. /*
  1493. * supported arguments:
  1494. * - rgb2hsl(r,g,b)
  1495. * - rgb2hsl(r,g,b,a)
  1496. * - rgb2hsl([r,g,b])
  1497. * - rgb2hsl([r,g,b,a])
  1498. * - rgb2hsl({r,g,b,a})
  1499. */
  1500. const rgb2hsl$2 = (...args) => {
  1501. args = unpack(args, 'rgba');
  1502. let [r, g, b] = args;
  1503.  
  1504. r /= 255;
  1505. g /= 255;
  1506. b /= 255;
  1507.  
  1508. const minRgb = min$4(r, g, b);
  1509. const maxRgb = max$4(r, g, b);
  1510.  
  1511. const l = (maxRgb + minRgb) / 2;
  1512. let s, h;
  1513.  
  1514. if (maxRgb === minRgb) {
  1515. s = 0;
  1516. h = Number.NaN;
  1517. } else {
  1518. s =
  1519. l < 0.5
  1520. ? (maxRgb - minRgb) / (maxRgb + minRgb)
  1521. : (maxRgb - minRgb) / (2 - maxRgb - minRgb);
  1522. }
  1523.  
  1524. if (r == maxRgb) h = (g - b) / (maxRgb - minRgb);
  1525. else if (g == maxRgb) h = 2 + (b - r) / (maxRgb - minRgb);
  1526. else if (b == maxRgb) h = 4 + (r - g) / (maxRgb - minRgb);
  1527.  
  1528. h *= 60;
  1529. if (h < 0) h += 360;
  1530. if (args.length > 3 && args[3] !== undefined) return [h, s, l, args[3]];
  1531. return [h, s, l];
  1532. };
  1533.  
  1534. Color$2.prototype.hsl = function () {
  1535. return rgb2hsl$2(this._rgb);
  1536. };
  1537.  
  1538. const hsl$1 = (...args) => new Color$2(...args, 'hsl');
  1539. chroma$1.hsl = hsl$1;
  1540.  
  1541. input$1.format.hsl = hsl2rgb$1;
  1542.  
  1543. input$1.autodetect.push({
  1544. p: 2,
  1545. test: (...args) => {
  1546. args = unpack(args, 'hsl');
  1547. if (type(args) === 'array' && args.length === 3) {
  1548. return 'hsl';
  1549. }
  1550. }
  1551. });
  1552.  
  1553. const { floor: floor$2 } = Math;
  1554.  
  1555. const hsv2rgb = (...args) => {
  1556. args = unpack(args, 'hsv');
  1557. let [h, s, v] = args;
  1558. let r, g, b;
  1559. v *= 255;
  1560. if (s === 0) {
  1561. r = g = b = v;
  1562. } else {
  1563. if (h === 360) h = 0;
  1564. if (h > 360) h -= 360;
  1565. if (h < 0) h += 360;
  1566. h /= 60;
  1567.  
  1568. const i = floor$2(h);
  1569. const f = h - i;
  1570. const p = v * (1 - s);
  1571. const q = v * (1 - s * f);
  1572. const t = v * (1 - s * (1 - f));
  1573.  
  1574. switch (i) {
  1575. case 0:
  1576. [r, g, b] = [v, t, p];
  1577. break;
  1578. case 1:
  1579. [r, g, b] = [q, v, p];
  1580. break;
  1581. case 2:
  1582. [r, g, b] = [p, v, t];
  1583. break;
  1584. case 3:
  1585. [r, g, b] = [p, q, v];
  1586. break;
  1587. case 4:
  1588. [r, g, b] = [t, p, v];
  1589. break;
  1590. case 5:
  1591. [r, g, b] = [v, p, q];
  1592. break;
  1593. }
  1594. }
  1595. return [r, g, b, args.length > 3 ? args[3] : 1];
  1596. };
  1597.  
  1598. const { min: min$2, max: max$3 } = Math;
  1599.  
  1600. /*
  1601. * supported arguments:
  1602. * - rgb2hsv(r,g,b)
  1603. * - rgb2hsv([r,g,b])
  1604. * - rgb2hsv({r,g,b})
  1605. */
  1606. const rgb2hsl$1 = (...args) => {
  1607. args = unpack(args, 'rgb');
  1608. let [r, g, b] = args;
  1609. const min_ = min$2(r, g, b);
  1610. const max_ = max$3(r, g, b);
  1611. const delta = max_ - min_;
  1612. let h, s, v;
  1613. v = max_ / 255.0;
  1614. if (max_ === 0) {
  1615. h = Number.NaN;
  1616. s = 0;
  1617. } else {
  1618. s = delta / max_;
  1619. if (r === max_) h = (g - b) / delta;
  1620. if (g === max_) h = 2 + (b - r) / delta;
  1621. if (b === max_) h = 4 + (r - g) / delta;
  1622. h *= 60;
  1623. if (h < 0) h += 360;
  1624. }
  1625. return [h, s, v];
  1626. };
  1627.  
  1628. Color$2.prototype.hsv = function () {
  1629. return rgb2hsl$1(this._rgb);
  1630. };
  1631.  
  1632. const hsv$1 = (...args) => new Color$2(...args, 'hsv');
  1633. chroma$1.hsv = hsv$1;
  1634.  
  1635. input$1.format.hsv = hsv2rgb;
  1636.  
  1637. input$1.autodetect.push({
  1638. p: 2,
  1639. test: (...args) => {
  1640. args = unpack(args, 'hsv');
  1641. if (type(args) === 'array' && args.length === 3) {
  1642. return 'hsv';
  1643. }
  1644. }
  1645. });
  1646.  
  1647. // from https://www.w3.org/TR/css-color-4/multiply-matrices.js
  1648. function multiplyMatrices(A, B) {
  1649. let m = A.length;
  1650.  
  1651. if (!Array.isArray(A[0])) {
  1652. // A is vector, convert to [[a, b, c, ...]]
  1653. A = [A];
  1654. }
  1655.  
  1656. if (!Array.isArray(B[0])) {
  1657. // B is vector, convert to [[a], [b], [c], ...]]
  1658. B = B.map((x) => [x]);
  1659. }
  1660.  
  1661. let p = B[0].length;
  1662. let B_cols = B[0].map((_, i) => B.map((x) => x[i])); // transpose B
  1663. let product = A.map((row) =>
  1664. B_cols.map((col) => {
  1665. if (!Array.isArray(row)) {
  1666. return col.reduce((a, c) => a + c * row, 0);
  1667. }
  1668.  
  1669. return row.reduce((a, c, i) => a + c * (col[i] || 0), 0);
  1670. })
  1671. );
  1672.  
  1673. if (m === 1) {
  1674. product = product[0]; // Avoid [[a, b, c, ...]]
  1675. }
  1676.  
  1677. if (p === 1) {
  1678. return product.map((x) => x[0]); // Avoid [[a], [b], [c], ...]]
  1679. }
  1680.  
  1681. return product;
  1682. }
  1683.  
  1684. const oklab2rgb$1 = (...args) => {
  1685. args = unpack(args, 'lab');
  1686. const [L, a, b, ...rest] = args;
  1687. const [X, Y, Z] = OKLab_to_XYZ$1([L, a, b]);
  1688. const [r, g, b_] = xyz2rgb(X, Y, Z);
  1689. return [r, g, b_, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
  1690. };
  1691.  
  1692. // from https://www.w3.org/TR/css-color-4/#color-conversion-code
  1693. function OKLab_to_XYZ$1(OKLab) {
  1694. // Given OKLab, convert to XYZ relative to D65
  1695. var LMStoXYZ = [
  1696. [1.2268798758459243, -0.5578149944602171, 0.2813910456659647],
  1697. [-0.0405757452148008, 1.112286803280317, -0.0717110580655164],
  1698. [-0.0763729366746601, -0.4214933324022432, 1.5869240198367816]
  1699. ];
  1700. var OKLabtoLMS = [
  1701. [1.0, 0.3963377773761749, 0.2158037573099136],
  1702. [1.0, -0.1055613458156586, -0.0638541728258133],
  1703. [1.0, -0.0894841775298119, -1.2914855480194092]
  1704. ];
  1705.  
  1706. var LMSnl = multiplyMatrices(OKLabtoLMS, OKLab);
  1707. return multiplyMatrices(
  1708. LMStoXYZ,
  1709. LMSnl.map((c) => c ** 3)
  1710. );
  1711. }
  1712.  
  1713. const rgb2oklab$1 = (...args) => {
  1714. const [r, g, b, ...rest] = unpack(args, 'rgb');
  1715. const xyz = rgb2xyz(r, g, b);
  1716. const oklab = XYZ_to_OKLab$1(xyz);
  1717. return [...oklab, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
  1718. };
  1719.  
  1720. // from https://www.w3.org/TR/css-color-4/#color-conversion-code
  1721. function XYZ_to_OKLab$1(XYZ) {
  1722. // Given XYZ relative to D65, convert to OKLab
  1723. const XYZtoLMS = [
  1724. [0.819022437996703, 0.3619062600528904, -0.1288737815209879],
  1725. [0.0329836539323885, 0.9292868615863434, 0.0361446663506424],
  1726. [0.0481771893596242, 0.2642395317527308, 0.6335478284694309]
  1727. ];
  1728. const LMStoOKLab = [
  1729. [0.210454268309314, 0.7936177747023054, -0.0040720430116193],
  1730. [1.9779985324311684, -2.42859224204858, 0.450593709617411],
  1731. [0.0259040424655478, 0.7827717124575296, -0.8086757549230774]
  1732. ];
  1733.  
  1734. const LMS = multiplyMatrices(XYZtoLMS, XYZ);
  1735. // JavaScript Math.cbrt returns a sign-matched cube root
  1736. // beware if porting to other languages
  1737. // especially if tempted to use a general power function
  1738. return multiplyMatrices(
  1739. LMStoOKLab,
  1740. LMS.map((c) => Math.cbrt(c))
  1741. );
  1742. // L in range [0,1]. For use in CSS, multiply by 100 and add a percent
  1743. }
  1744.  
  1745. Color$2.prototype.oklab = function () {
  1746. return rgb2oklab$1(this._rgb);
  1747. };
  1748.  
  1749. const oklab$1 = (...args) => new Color$2(...args, 'oklab');
  1750. Object.assign(chroma$1, { oklab: oklab$1 });
  1751.  
  1752. input$1.format.oklab = oklab2rgb$1;
  1753.  
  1754. input$1.autodetect.push({
  1755. p: 2,
  1756. test: (...args) => {
  1757. args = unpack(args, 'oklab');
  1758. if (type(args) === 'array' && args.length === 3) {
  1759. return 'oklab';
  1760. }
  1761. }
  1762. });
  1763.  
  1764. const { pow: pow$7, sqrt: sqrt$2, PI: PI$1, cos: cos$3, sin: sin$3, atan2: atan2$2 } = Math;
  1765.  
  1766. var average = (colors, mode = 'lrgb', weights = null) => {
  1767. const l = colors.length;
  1768. if (!weights) weights = Array.from(new Array(l)).map(() => 1);
  1769. // normalize weights
  1770. const k =
  1771. l /
  1772. weights.reduce(function (a, b) {
  1773. return a + b;
  1774. });
  1775. weights.forEach((w, i) => {
  1776. weights[i] *= k;
  1777. });
  1778. // convert colors to Color objects
  1779. colors = colors.map((c) => new Color$1(c));
  1780. if (mode === 'lrgb') {
  1781. return _average_lrgb(colors, weights);
  1782. }
  1783. const first = colors.shift();
  1784. const xyz = first.get(mode);
  1785. const cnt = [];
  1786. let dx = 0;
  1787. let dy = 0;
  1788. // initial color
  1789. for (let i = 0; i < xyz.length; i++) {
  1790. xyz[i] = (xyz[i] || 0) * weights[0];
  1791. cnt.push(isNaN(xyz[i]) ? 0 : weights[0]);
  1792. if (mode.charAt(i) === 'h' && !isNaN(xyz[i])) {
  1793. const A = (xyz[i] / 180) * PI$1;
  1794. dx += cos$3(A) * weights[0];
  1795. dy += sin$3(A) * weights[0];
  1796. }
  1797. }
  1798.  
  1799. let alpha = first.alpha() * weights[0];
  1800. colors.forEach((c, ci) => {
  1801. const xyz2 = c.get(mode);
  1802. alpha += c.alpha() * weights[ci + 1];
  1803. for (let i = 0; i < xyz.length; i++) {
  1804. if (!isNaN(xyz2[i])) {
  1805. cnt[i] += weights[ci + 1];
  1806. if (mode.charAt(i) === 'h') {
  1807. const A = (xyz2[i] / 180) * PI$1;
  1808. dx += cos$3(A) * weights[ci + 1];
  1809. dy += sin$3(A) * weights[ci + 1];
  1810. } else {
  1811. xyz[i] += xyz2[i] * weights[ci + 1];
  1812. }
  1813. }
  1814. }
  1815. });
  1816.  
  1817. for (let i = 0; i < xyz.length; i++) {
  1818. if (mode.charAt(i) === 'h') {
  1819. let A = (atan2$2(dy / cnt[i], dx / cnt[i]) / PI$1) * 180;
  1820. while (A < 0) A += 360;
  1821. while (A >= 360) A -= 360;
  1822. xyz[i] = A;
  1823. } else {
  1824. xyz[i] = xyz[i] / cnt[i];
  1825. }
  1826. }
  1827. alpha /= l;
  1828. return new Color$1(xyz, mode).alpha(alpha > 0.99999 ? 1 : alpha, true);
  1829. };
  1830.  
  1831. const _average_lrgb = (colors, weights) => {
  1832. const l = colors.length;
  1833. const xyz = [0, 0, 0, 0];
  1834. for (let i = 0; i < colors.length; i++) {
  1835. const col = colors[i];
  1836. const f = weights[i] / l;
  1837. const rgb = col._rgb;
  1838. xyz[0] += pow$7(rgb[0], 2) * f;
  1839. xyz[1] += pow$7(rgb[1], 2) * f;
  1840. xyz[2] += pow$7(rgb[2], 2) * f;
  1841. xyz[3] += rgb[3] * f;
  1842. }
  1843. xyz[0] = sqrt$2(xyz[0]);
  1844. xyz[1] = sqrt$2(xyz[1]);
  1845. xyz[2] = sqrt$2(xyz[2]);
  1846. if (xyz[3] > 0.9999999) xyz[3] = 1;
  1847. return new Color$1(clip_rgb(xyz));
  1848. };
  1849.  
  1850. const chroma = (...args) => {
  1851. return new Color$3(...args);
  1852. };
  1853.  
  1854. chroma.version = version;
  1855.  
  1856. // minimal multi-purpose interface
  1857.  
  1858.  
  1859. const { pow: pow$6 } = Math;
  1860.  
  1861. function scale$2 (colors) {
  1862. // constructor
  1863. let _mode = 'rgb';
  1864. let _nacol = chroma('#ccc');
  1865. let _spread = 0;
  1866. // const _fixed = false;
  1867. let _domain = [0, 1];
  1868. let _pos = [];
  1869. let _padding = [0, 0];
  1870. let _classes = false;
  1871. let _colors = [];
  1872. let _out = false;
  1873. let _min = 0;
  1874. let _max = 1;
  1875. let _correctLightness = false;
  1876. let _colorCache = {};
  1877. let _useCache = true;
  1878. let _gamma = 1;
  1879.  
  1880. // private methods
  1881.  
  1882. const setColors = function (colors) {
  1883. colors = colors || ['#fff', '#000'];
  1884. if (
  1885. colors &&
  1886. type(colors) === 'string' &&
  1887. chroma.brewer &&
  1888. chroma.brewer[colors.toLowerCase()]
  1889. ) {
  1890. colors = chroma.brewer[colors.toLowerCase()];
  1891. }
  1892. if (type(colors) === 'array') {
  1893. // handle single color
  1894. if (colors.length === 1) {
  1895. colors = [colors[0], colors[0]];
  1896. }
  1897. // make a copy of the colors
  1898. colors = colors.slice(0);
  1899. // convert to chroma classes
  1900. for (let c = 0; c < colors.length; c++) {
  1901. colors[c] = chroma(colors[c]);
  1902. }
  1903. // auto-fill color position
  1904. _pos.length = 0;
  1905. for (let c = 0; c < colors.length; c++) {
  1906. _pos.push(c / (colors.length - 1));
  1907. }
  1908. }
  1909. resetCache();
  1910. return (_colors = colors);
  1911. };
  1912.  
  1913. const getClass = function (value) {
  1914. if (_classes != null) {
  1915. const n = _classes.length - 1;
  1916. let i = 0;
  1917. while (i < n && value >= _classes[i]) {
  1918. i++;
  1919. }
  1920. return i - 1;
  1921. }
  1922. return 0;
  1923. };
  1924.  
  1925. let tMapLightness = (t) => t;
  1926. let tMapDomain = (t) => t;
  1927.  
  1928. // const classifyValue = function(value) {
  1929. // let val = value;
  1930. // if (_classes.length > 2) {
  1931. // const n = _classes.length-1;
  1932. // const i = getClass(value);
  1933. // const minc = _classes[0] + ((_classes[1]-_classes[0]) * (0 + (_spread * 0.5))); // center of 1st class
  1934. // const maxc = _classes[n-1] + ((_classes[n]-_classes[n-1]) * (1 - (_spread * 0.5))); // center of last class
  1935. // val = _min + ((((_classes[i] + ((_classes[i+1] - _classes[i]) * 0.5)) - minc) / (maxc-minc)) * (_max - _min));
  1936. // }
  1937. // return val;
  1938. // };
  1939.  
  1940. const getColor = function (val, bypassMap) {
  1941. let col, t;
  1942. if (bypassMap == null) {
  1943. bypassMap = false;
  1944. }
  1945. if (isNaN(val) || val === null) {
  1946. return _nacol;
  1947. }
  1948. if (!bypassMap) {
  1949. if (_classes && _classes.length > 2) {
  1950. // find the class
  1951. const c = getClass(val);
  1952. t = c / (_classes.length - 2);
  1953. } else if (_max !== _min) {
  1954. // just interpolate between min/max
  1955. t = (val - _min) / (_max - _min);
  1956. } else {
  1957. t = 1;
  1958. }
  1959. } else {
  1960. t = val;
  1961. }
  1962.  
  1963. // domain map
  1964. t = tMapDomain(t);
  1965.  
  1966. if (!bypassMap) {
  1967. t = tMapLightness(t); // lightness correction
  1968. }
  1969.  
  1970. if (_gamma !== 1) {
  1971. t = pow$6(t, _gamma);
  1972. }
  1973.  
  1974. t = _padding[0] + t * (1 - _padding[0] - _padding[1]);
  1975.  
  1976. t = limit$1(t, 0, 1);
  1977.  
  1978. const k = Math.floor(t * 10000);
  1979.  
  1980. if (_useCache && _colorCache[k]) {
  1981. col = _colorCache[k];
  1982. } else {
  1983. if (type(_colors) === 'array') {
  1984. //for i in [0.._pos.length-1]
  1985. for (let i = 0; i < _pos.length; i++) {
  1986. const p = _pos[i];
  1987. if (t <= p) {
  1988. col = _colors[i];
  1989. break;
  1990. }
  1991. if (t >= p && i === _pos.length - 1) {
  1992. col = _colors[i];
  1993. break;
  1994. }
  1995. if (t > p && t < _pos[i + 1]) {
  1996. t = (t - p) / (_pos[i + 1] - p);
  1997. col = chroma.interpolate(
  1998. _colors[i],
  1999. _colors[i + 1],
  2000. t,
  2001. _mode
  2002. );
  2003. break;
  2004. }
  2005. }
  2006. } else if (type(_colors) === 'function') {
  2007. col = _colors(t);
  2008. }
  2009. if (_useCache) {
  2010. _colorCache[k] = col;
  2011. }
  2012. }
  2013. return col;
  2014. };
  2015.  
  2016. var resetCache = () => (_colorCache = {});
  2017.  
  2018. setColors(colors);
  2019.  
  2020. // public interface
  2021.  
  2022. const f = function (v) {
  2023. const c = chroma(getColor(v));
  2024. if (_out && c[_out]) {
  2025. return c[_out]();
  2026. } else {
  2027. return c;
  2028. }
  2029. };
  2030.  
  2031. f.classes = function (classes) {
  2032. if (classes != null) {
  2033. if (type(classes) === 'array') {
  2034. _classes = classes;
  2035. _domain = [classes[0], classes[classes.length - 1]];
  2036. } else {
  2037. const d = chroma.analyze(_domain);
  2038. if (classes === 0) {
  2039. _classes = [d.min, d.max];
  2040. } else {
  2041. _classes = chroma.limits(d, 'e', classes);
  2042. }
  2043. }
  2044. return f;
  2045. }
  2046. return _classes;
  2047. };
  2048.  
  2049. f.domain = function (domain) {
  2050. if (!arguments.length) {
  2051. return _domain;
  2052. }
  2053. _min = domain[0];
  2054. _max = domain[domain.length - 1];
  2055. _pos = [];
  2056. const k = _colors.length;
  2057. if (domain.length === k && _min !== _max) {
  2058. // update positions
  2059. for (let d of Array.from(domain)) {
  2060. _pos.push((d - _min) / (_max - _min));
  2061. }
  2062. } else {
  2063. for (let c = 0; c < k; c++) {
  2064. _pos.push(c / (k - 1));
  2065. }
  2066. if (domain.length > 2) {
  2067. // set domain map
  2068. const tOut = domain.map((d, i) => i / (domain.length - 1));
  2069. const tBreaks = domain.map((d) => (d - _min) / (_max - _min));
  2070. if (!tBreaks.every((val, i) => tOut[i] === val)) {
  2071. tMapDomain = (t) => {
  2072. if (t <= 0 || t >= 1) return t;
  2073. let i = 0;
  2074. while (t >= tBreaks[i + 1]) i++;
  2075. const f =
  2076. (t - tBreaks[i]) / (tBreaks[i + 1] - tBreaks[i]);
  2077. const out = tOut[i] + f * (tOut[i + 1] - tOut[i]);
  2078. return out;
  2079. };
  2080. }
  2081. }
  2082. }
  2083. _domain = [_min, _max];
  2084. return f;
  2085. };
  2086.  
  2087. f.mode = function (_m) {
  2088. if (!arguments.length) {
  2089. return _mode;
  2090. }
  2091. _mode = _m;
  2092. resetCache();
  2093. return f;
  2094. };
  2095.  
  2096. f.range = function (colors, _pos) {
  2097. setColors(colors);
  2098. return f;
  2099. };
  2100.  
  2101. f.out = function (_o) {
  2102. _out = _o;
  2103. return f;
  2104. };
  2105.  
  2106. f.spread = function (val) {
  2107. if (!arguments.length) {
  2108. return _spread;
  2109. }
  2110. _spread = val;
  2111. return f;
  2112. };
  2113.  
  2114. f.correctLightness = function (v) {
  2115. if (v == null) {
  2116. v = true;
  2117. }
  2118. _correctLightness = v;
  2119. resetCache();
  2120. if (_correctLightness) {
  2121. tMapLightness = function (t) {
  2122. const L0 = getColor(0, true).lab()[0];
  2123. const L1 = getColor(1, true).lab()[0];
  2124. const pol = L0 > L1;
  2125. let L_actual = getColor(t, true).lab()[0];
  2126. const L_ideal = L0 + (L1 - L0) * t;
  2127. let L_diff = L_actual - L_ideal;
  2128. let t0 = 0;
  2129. let t1 = 1;
  2130. let max_iter = 20;
  2131. while (Math.abs(L_diff) > 1e-2 && max_iter-- > 0) {
  2132. (function () {
  2133. if (pol) {
  2134. L_diff *= -1;
  2135. }
  2136. if (L_diff < 0) {
  2137. t0 = t;
  2138. t += (t1 - t) * 0.5;
  2139. } else {
  2140. t1 = t;
  2141. t += (t0 - t) * 0.5;
  2142. }
  2143. L_actual = getColor(t, true).lab()[0];
  2144. return (L_diff = L_actual - L_ideal);
  2145. })();
  2146. }
  2147. return t;
  2148. };
  2149. } else {
  2150. tMapLightness = (t) => t;
  2151. }
  2152. return f;
  2153. };
  2154.  
  2155. f.padding = function (p) {
  2156. if (p != null) {
  2157. if (type(p) === 'number') {
  2158. p = [p, p];
  2159. }
  2160. _padding = p;
  2161. return f;
  2162. } else {
  2163. return _padding;
  2164. }
  2165. };
  2166.  
  2167. f.colors = function (numColors, out) {
  2168. // If no arguments are given, return the original colors that were provided
  2169. if (arguments.length < 2) {
  2170. out = 'hex';
  2171. }
  2172. let result = [];
  2173.  
  2174. if (arguments.length === 0) {
  2175. result = _colors.slice(0);
  2176. } else if (numColors === 1) {
  2177. result = [f(0.5)];
  2178. } else if (numColors > 1) {
  2179. const dm = _domain[0];
  2180. const dd = _domain[1] - dm;
  2181. result = __range__$2(0, numColors).map((i) =>
  2182. f(dm + (i / (numColors - 1)) * dd)
  2183. );
  2184. } else {
  2185. // returns all colors based on the defined classes
  2186. colors = [];
  2187. let samples = [];
  2188. if (_classes && _classes.length > 2) {
  2189. for (
  2190. let i = 1, end = _classes.length, asc = 1 <= end;
  2191. asc ? i < end : i > end;
  2192. asc ? i++ : i--
  2193. ) {
  2194. samples.push((_classes[i - 1] + _classes[i]) * 0.5);
  2195. }
  2196. } else {
  2197. samples = _domain;
  2198. }
  2199. result = samples.map((v) => f(v));
  2200. }
  2201.  
  2202. if (chroma[out]) {
  2203. result = result.map((c) => c[out]());
  2204. }
  2205. return result;
  2206. };
  2207.  
  2208. f.cache = function (c) {
  2209. if (c != null) {
  2210. _useCache = c;
  2211. return f;
  2212. } else {
  2213. return _useCache;
  2214. }
  2215. };
  2216.  
  2217. f.gamma = function (g) {
  2218. if (g != null) {
  2219. _gamma = g;
  2220. return f;
  2221. } else {
  2222. return _gamma;
  2223. }
  2224. };
  2225.  
  2226. f.nodata = function (d) {
  2227. if (d != null) {
  2228. _nacol = chroma(d);
  2229. return f;
  2230. } else {
  2231. return _nacol;
  2232. }
  2233. };
  2234.  
  2235. return f;
  2236. }
  2237.  
  2238. function __range__$2(left, right, inclusive) {
  2239. let range = [];
  2240. let ascending = left < right;
  2241. let end = right ;
  2242. for (let i = left; ascending ? i < end : i > end; ascending ? i++ : i--) {
  2243. range.push(i);
  2244. }
  2245. return range;
  2246. }
  2247.  
  2248. //
  2249. // interpolates between a set of colors uzing a bezier spline
  2250. //
  2251.  
  2252.  
  2253. // nth row of the pascal triangle
  2254. const binom_row = function (n) {
  2255. let row = [1, 1];
  2256. for (let i = 1; i < n; i++) {
  2257. let newrow = [1];
  2258. for (let j = 1; j <= row.length; j++) {
  2259. newrow[j] = (row[j] || 0) + row[j - 1];
  2260. }
  2261. row = newrow;
  2262. }
  2263. return row;
  2264. };
  2265.  
  2266. const bezier = function (colors) {
  2267. let I, lab0, lab1, lab2;
  2268. colors = colors.map((c) => new Color$1(c));
  2269. if (colors.length === 2) {
  2270. // linear interpolation
  2271. [lab0, lab1] = colors.map((c) => c.lab());
  2272. I = function (t) {
  2273. const lab = [0, 1, 2].map((i) => lab0[i] + t * (lab1[i] - lab0[i]));
  2274. return new Color$1(lab, 'lab');
  2275. };
  2276. } else if (colors.length === 3) {
  2277. // quadratic bezier interpolation
  2278. [lab0, lab1, lab2] = colors.map((c) => c.lab());
  2279. I = function (t) {
  2280. const lab = [0, 1, 2].map(
  2281. (i) =>
  2282. (1 - t) * (1 - t) * lab0[i] +
  2283. 2 * (1 - t) * t * lab1[i] +
  2284. t * t * lab2[i]
  2285. );
  2286. return new Color$1(lab, 'lab');
  2287. };
  2288. } else if (colors.length === 4) {
  2289. // cubic bezier interpolation
  2290. let lab3;
  2291. [lab0, lab1, lab2, lab3] = colors.map((c) => c.lab());
  2292. I = function (t) {
  2293. const lab = [0, 1, 2].map(
  2294. (i) =>
  2295. (1 - t) * (1 - t) * (1 - t) * lab0[i] +
  2296. 3 * (1 - t) * (1 - t) * t * lab1[i] +
  2297. 3 * (1 - t) * t * t * lab2[i] +
  2298. t * t * t * lab3[i]
  2299. );
  2300. return new Color$1(lab, 'lab');
  2301. };
  2302. } else if (colors.length >= 5) {
  2303. // general case (degree n bezier)
  2304. let labs, row, n;
  2305. labs = colors.map((c) => c.lab());
  2306. n = colors.length - 1;
  2307. row = binom_row(n);
  2308. I = function (t) {
  2309. const u = 1 - t;
  2310. const lab = [0, 1, 2].map((i) =>
  2311. labs.reduce(
  2312. (sum, el, j) =>
  2313. sum + row[j] * u ** (n - j) * t ** j * el[i],
  2314. 0
  2315. )
  2316. );
  2317. return new Color$1(lab, 'lab');
  2318. };
  2319. } else {
  2320. throw new RangeError('No point in running bezier with only one color.');
  2321. }
  2322. return I;
  2323. };
  2324.  
  2325. var bezier$1 = (colors) => {
  2326. const f = bezier(colors);
  2327. f.scale = () => scale$2(f);
  2328. return f;
  2329. };
  2330.  
  2331. const { round: round$6 } = Math;
  2332.  
  2333. Color$2.prototype.rgb = function (rnd = true) {
  2334. if (rnd === false) return this._rgb.slice(0, 3);
  2335. return this._rgb.slice(0, 3).map(round$6);
  2336. };
  2337.  
  2338. Color$2.prototype.rgba = function (rnd = true) {
  2339. return this._rgb.slice(0, 4).map((v, i) => {
  2340. return i < 3 ? (rnd === false ? v : round$6(v)) : v;
  2341. });
  2342. };
  2343.  
  2344. const rgb$1 = (...args) => new Color$2(...args, 'rgb');
  2345. Object.assign(chroma$1, { rgb: rgb$1 });
  2346.  
  2347. input$1.format.rgb = (...args) => {
  2348. const rgba = unpack(args, 'rgba');
  2349. if (rgba[3] === undefined) rgba[3] = 1;
  2350. return rgba;
  2351. };
  2352.  
  2353. input$1.autodetect.push({
  2354. p: 3,
  2355. test: (...args) => {
  2356. args = unpack(args, 'rgba');
  2357. if (
  2358. type(args) === 'array' &&
  2359. (args.length === 3 ||
  2360. (args.length === 4 &&
  2361. type(args[3]) == 'number' &&
  2362. args[3] >= 0 &&
  2363. args[3] <= 1))
  2364. ) {
  2365. return 'rgb';
  2366. }
  2367. }
  2368. });
  2369.  
  2370. /*
  2371. * interpolates between a set of colors uzing a bezier spline
  2372. * blend mode formulas taken from https://web.archive.org/web/20180110014946/http://www.venture-ware.com/kevin/coding/lets-learn-math-photoshop-blend-modes/
  2373. */
  2374.  
  2375.  
  2376. const blend = (bottom, top, mode) => {
  2377. if (!blend[mode]) {
  2378. throw new Error('unknown blend mode ' + mode);
  2379. }
  2380. return blend[mode](bottom, top);
  2381. };
  2382.  
  2383. const blend_f = (f) => (bottom, top) => {
  2384. const c0 = chroma(top).rgb();
  2385. const c1 = chroma(bottom).rgb();
  2386. return chroma.rgb(f(c0, c1));
  2387. };
  2388.  
  2389. const each = (f) => (c0, c1) => {
  2390. const out = [];
  2391. out[0] = f(c0[0], c1[0]);
  2392. out[1] = f(c0[1], c1[1]);
  2393. out[2] = f(c0[2], c1[2]);
  2394. return out;
  2395. };
  2396.  
  2397. const normal = (a) => a;
  2398. const multiply = (a, b) => (a * b) / 255;
  2399. const darken = (a, b) => (a > b ? b : a);
  2400. const lighten = (a, b) => (a > b ? a : b);
  2401. const screen = (a, b) => 255 * (1 - (1 - a / 255) * (1 - b / 255));
  2402. const overlay = (a, b) =>
  2403. b < 128 ? (2 * a * b) / 255 : 255 * (1 - 2 * (1 - a / 255) * (1 - b / 255));
  2404. const burn = (a, b) => 255 * (1 - (1 - b / 255) / (a / 255));
  2405. const dodge = (a, b) => {
  2406. if (a === 255) return 255;
  2407. a = (255 * (b / 255)) / (1 - a / 255);
  2408. return a > 255 ? 255 : a;
  2409. };
  2410.  
  2411. // # add = (a,b) ->
  2412. // # if (a + b > 255) then 255 else a + b
  2413.  
  2414. blend.normal = blend_f(each(normal));
  2415. blend.multiply = blend_f(each(multiply));
  2416. blend.screen = blend_f(each(screen));
  2417. blend.overlay = blend_f(each(overlay));
  2418. blend.darken = blend_f(each(darken));
  2419. blend.lighten = blend_f(each(lighten));
  2420. blend.dodge = blend_f(each(dodge));
  2421. blend.burn = blend_f(each(burn));
  2422.  
  2423. // cubehelix interpolation
  2424. // based on D.A. Green "A colour scheme for the display of astronomical intensity images"
  2425. // http://astron-soc.in/bulletin/11June/289392011.pdf
  2426. const { pow: pow$5, sin: sin$2, cos: cos$2 } = Math;
  2427.  
  2428. function cubehelix (
  2429. start = 300,
  2430. rotations = -1.5,
  2431. hue = 1,
  2432. gamma = 1,
  2433. lightness = [0, 1]
  2434. ) {
  2435. let dh = 0,
  2436. dl;
  2437. if (type(lightness) === 'array') {
  2438. dl = lightness[1] - lightness[0];
  2439. } else {
  2440. dl = 0;
  2441. lightness = [lightness, lightness];
  2442. }
  2443. const f = function (fract) {
  2444. const a = TWOPI * ((start + 120) / 360 + rotations * fract);
  2445. const l = pow$5(lightness[0] + dl * fract, gamma);
  2446. const h = dh !== 0 ? hue[0] + fract * dh : hue;
  2447. const amp = (h * l * (1 - l)) / 2;
  2448. const cos_a = cos$2(a);
  2449. const sin_a = sin$2(a);
  2450. const r = l + amp * (-0.14861 * cos_a + 1.78277 * sin_a);
  2451. const g = l + amp * (-0.29227 * cos_a - 0.90649 * sin_a);
  2452. const b = l + amp * (1.97294 * cos_a);
  2453. return chroma(clip_rgb([r * 255, g * 255, b * 255, 1]));
  2454. };
  2455. f.start = function (s) {
  2456. if (s == null) {
  2457. return start;
  2458. }
  2459. start = s;
  2460. return f;
  2461. };
  2462. f.rotations = function (r) {
  2463. if (r == null) {
  2464. return rotations;
  2465. }
  2466. rotations = r;
  2467. return f;
  2468. };
  2469. f.gamma = function (g) {
  2470. if (g == null) {
  2471. return gamma;
  2472. }
  2473. gamma = g;
  2474. return f;
  2475. };
  2476. f.hue = function (h) {
  2477. if (h == null) {
  2478. return hue;
  2479. }
  2480. hue = h;
  2481. if (type(hue) === 'array') {
  2482. dh = hue[1] - hue[0];
  2483. if (dh === 0) {
  2484. hue = hue[1];
  2485. }
  2486. } else {
  2487. dh = 0;
  2488. }
  2489. return f;
  2490. };
  2491. f.lightness = function (h) {
  2492. if (h == null) {
  2493. return lightness;
  2494. }
  2495. if (type(h) === 'array') {
  2496. lightness = h;
  2497. dl = h[1] - h[0];
  2498. } else {
  2499. lightness = [h, h];
  2500. dl = 0;
  2501. }
  2502. return f;
  2503. };
  2504. f.scale = () => chroma.scale(f);
  2505. f.hue(hue);
  2506. return f;
  2507. }
  2508.  
  2509. var mix = (col1, col2, f = 0.5, ...rest) => {
  2510. let mode = rest[0] || 'lrgb';
  2511. if (!interpolator[mode] && !rest.length) {
  2512. // fall back to the first supported mode
  2513. mode = Object.keys(interpolator)[0];
  2514. }
  2515. if (!interpolator[mode]) {
  2516. throw new Error(`interpolation mode ${mode} is not defined`);
  2517. }
  2518. if (type(col1) !== 'object') col1 = new Color$1(col1);
  2519. if (type(col2) !== 'object') col2 = new Color$1(col2);
  2520. return interpolator[mode](col1, col2, f).alpha(
  2521. col1.alpha() + f * (col2.alpha() - col1.alpha())
  2522. );
  2523. };
  2524.  
  2525. const digits = '0123456789abcdef';
  2526.  
  2527. const { floor: floor$1, random } = Math;
  2528.  
  2529. var random$1 = () => {
  2530. let code = '#';
  2531. for (let i = 0; i < 6; i++) {
  2532. code += digits.charAt(floor$1(random() * 16));
  2533. }
  2534. return new Color$1(code, 'hex');
  2535. };
  2536.  
  2537. // minimal multi-purpose interface
  2538.  
  2539.  
  2540. const { pow: pow$4 } = Math;
  2541.  
  2542. function scale$1 (colors) {
  2543. // constructor
  2544. let _mode = 'rgb';
  2545. let _nacol = chroma('#ccc');
  2546. let _spread = 0;
  2547. // const _fixed = false;
  2548. let _domain = [0, 1];
  2549. let _pos = [];
  2550. let _padding = [0, 0];
  2551. let _classes = false;
  2552. let _colors = [];
  2553. let _out = false;
  2554. let _min = 0;
  2555. let _max = 1;
  2556. let _correctLightness = false;
  2557. let _colorCache = {};
  2558. let _useCache = true;
  2559. let _gamma = 1;
  2560.  
  2561. // private methods
  2562.  
  2563. const setColors = function (colors) {
  2564. colors = colors || ['#fff', '#000'];
  2565. if (
  2566. colors &&
  2567. type(colors) === 'string' &&
  2568. chroma.brewer &&
  2569. chroma.brewer[colors.toLowerCase()]
  2570. ) {
  2571. colors = chroma.brewer[colors.toLowerCase()];
  2572. }
  2573. if (type(colors) === 'array') {
  2574. // handle single color
  2575. if (colors.length === 1) {
  2576. colors = [colors[0], colors[0]];
  2577. }
  2578. // make a copy of the colors
  2579. colors = colors.slice(0);
  2580. // convert to chroma classes
  2581. for (let c = 0; c < colors.length; c++) {
  2582. colors[c] = chroma(colors[c]);
  2583. }
  2584. // auto-fill color position
  2585. _pos.length = 0;
  2586. for (let c = 0; c < colors.length; c++) {
  2587. _pos.push(c / (colors.length - 1));
  2588. }
  2589. }
  2590. resetCache();
  2591. return (_colors = colors);
  2592. };
  2593.  
  2594. const getClass = function (value) {
  2595. if (_classes != null) {
  2596. const n = _classes.length - 1;
  2597. let i = 0;
  2598. while (i < n && value >= _classes[i]) {
  2599. i++;
  2600. }
  2601. return i - 1;
  2602. }
  2603. return 0;
  2604. };
  2605.  
  2606. let tMapLightness = (t) => t;
  2607. let tMapDomain = (t) => t;
  2608.  
  2609. // const classifyValue = function(value) {
  2610. // let val = value;
  2611. // if (_classes.length > 2) {
  2612. // const n = _classes.length-1;
  2613. // const i = getClass(value);
  2614. // const minc = _classes[0] + ((_classes[1]-_classes[0]) * (0 + (_spread * 0.5))); // center of 1st class
  2615. // const maxc = _classes[n-1] + ((_classes[n]-_classes[n-1]) * (1 - (_spread * 0.5))); // center of last class
  2616. // val = _min + ((((_classes[i] + ((_classes[i+1] - _classes[i]) * 0.5)) - minc) / (maxc-minc)) * (_max - _min));
  2617. // }
  2618. // return val;
  2619. // };
  2620.  
  2621. const getColor = function (val, bypassMap) {
  2622. let col, t;
  2623. if (bypassMap == null) {
  2624. bypassMap = false;
  2625. }
  2626. if (isNaN(val) || val === null) {
  2627. return _nacol;
  2628. }
  2629. if (!bypassMap) {
  2630. if (_classes && _classes.length > 2) {
  2631. // find the class
  2632. const c = getClass(val);
  2633. t = c / (_classes.length - 2);
  2634. } else if (_max !== _min) {
  2635. // just interpolate between min/max
  2636. t = (val - _min) / (_max - _min);
  2637. } else {
  2638. t = 1;
  2639. }
  2640. } else {
  2641. t = val;
  2642. }
  2643.  
  2644. // domain map
  2645. t = tMapDomain(t);
  2646.  
  2647. if (!bypassMap) {
  2648. t = tMapLightness(t); // lightness correction
  2649. }
  2650.  
  2651. if (_gamma !== 1) {
  2652. t = pow$4(t, _gamma);
  2653. }
  2654.  
  2655. t = _padding[0] + t * (1 - _padding[0] - _padding[1]);
  2656.  
  2657. t = limit$1(t, 0, 1);
  2658.  
  2659. const k = Math.floor(t * 10000);
  2660.  
  2661. if (_useCache && _colorCache[k]) {
  2662. col = _colorCache[k];
  2663. } else {
  2664. if (type(_colors) === 'array') {
  2665. //for i in [0.._pos.length-1]
  2666. for (let i = 0; i < _pos.length; i++) {
  2667. const p = _pos[i];
  2668. if (t <= p) {
  2669. col = _colors[i];
  2670. break;
  2671. }
  2672. if (t >= p && i === _pos.length - 1) {
  2673. col = _colors[i];
  2674. break;
  2675. }
  2676. if (t > p && t < _pos[i + 1]) {
  2677. t = (t - p) / (_pos[i + 1] - p);
  2678. col = chroma.interpolate(
  2679. _colors[i],
  2680. _colors[i + 1],
  2681. t,
  2682. _mode
  2683. );
  2684. break;
  2685. }
  2686. }
  2687. } else if (type(_colors) === 'function') {
  2688. col = _colors(t);
  2689. }
  2690. if (_useCache) {
  2691. _colorCache[k] = col;
  2692. }
  2693. }
  2694. return col;
  2695. };
  2696.  
  2697. var resetCache = () => (_colorCache = {});
  2698.  
  2699. setColors(colors);
  2700.  
  2701. // public interface
  2702.  
  2703. const f = function (v) {
  2704. const c = chroma(getColor(v));
  2705. if (_out && c[_out]) {
  2706. return c[_out]();
  2707. } else {
  2708. return c;
  2709. }
  2710. };
  2711.  
  2712. f.classes = function (classes) {
  2713. if (classes != null) {
  2714. if (type(classes) === 'array') {
  2715. _classes = classes;
  2716. _domain = [classes[0], classes[classes.length - 1]];
  2717. } else {
  2718. const d = chroma.analyze(_domain);
  2719. if (classes === 0) {
  2720. _classes = [d.min, d.max];
  2721. } else {
  2722. _classes = chroma.limits(d, 'e', classes);
  2723. }
  2724. }
  2725. return f;
  2726. }
  2727. return _classes;
  2728. };
  2729.  
  2730. f.domain = function (domain) {
  2731. if (!arguments.length) {
  2732. return _domain;
  2733. }
  2734. _min = domain[0];
  2735. _max = domain[domain.length - 1];
  2736. _pos = [];
  2737. const k = _colors.length;
  2738. if (domain.length === k && _min !== _max) {
  2739. // update positions
  2740. for (let d of Array.from(domain)) {
  2741. _pos.push((d - _min) / (_max - _min));
  2742. }
  2743. } else {
  2744. for (let c = 0; c < k; c++) {
  2745. _pos.push(c / (k - 1));
  2746. }
  2747. if (domain.length > 2) {
  2748. // set domain map
  2749. const tOut = domain.map((d, i) => i / (domain.length - 1));
  2750. const tBreaks = domain.map((d) => (d - _min) / (_max - _min));
  2751. if (!tBreaks.every((val, i) => tOut[i] === val)) {
  2752. tMapDomain = (t) => {
  2753. if (t <= 0 || t >= 1) return t;
  2754. let i = 0;
  2755. while (t >= tBreaks[i + 1]) i++;
  2756. const f =
  2757. (t - tBreaks[i]) / (tBreaks[i + 1] - tBreaks[i]);
  2758. const out = tOut[i] + f * (tOut[i + 1] - tOut[i]);
  2759. return out;
  2760. };
  2761. }
  2762. }
  2763. }
  2764. _domain = [_min, _max];
  2765. return f;
  2766. };
  2767.  
  2768. f.mode = function (_m) {
  2769. if (!arguments.length) {
  2770. return _mode;
  2771. }
  2772. _mode = _m;
  2773. resetCache();
  2774. return f;
  2775. };
  2776.  
  2777. f.range = function (colors, _pos) {
  2778. setColors(colors);
  2779. return f;
  2780. };
  2781.  
  2782. f.out = function (_o) {
  2783. _out = _o;
  2784. return f;
  2785. };
  2786.  
  2787. f.spread = function (val) {
  2788. if (!arguments.length) {
  2789. return _spread;
  2790. }
  2791. _spread = val;
  2792. return f;
  2793. };
  2794.  
  2795. f.correctLightness = function (v) {
  2796. if (v == null) {
  2797. v = true;
  2798. }
  2799. _correctLightness = v;
  2800. resetCache();
  2801. if (_correctLightness) {
  2802. tMapLightness = function (t) {
  2803. const L0 = getColor(0, true).lab()[0];
  2804. const L1 = getColor(1, true).lab()[0];
  2805. const pol = L0 > L1;
  2806. let L_actual = getColor(t, true).lab()[0];
  2807. const L_ideal = L0 + (L1 - L0) * t;
  2808. let L_diff = L_actual - L_ideal;
  2809. let t0 = 0;
  2810. let t1 = 1;
  2811. let max_iter = 20;
  2812. while (Math.abs(L_diff) > 1e-2 && max_iter-- > 0) {
  2813. (function () {
  2814. if (pol) {
  2815. L_diff *= -1;
  2816. }
  2817. if (L_diff < 0) {
  2818. t0 = t;
  2819. t += (t1 - t) * 0.5;
  2820. } else {
  2821. t1 = t;
  2822. t += (t0 - t) * 0.5;
  2823. }
  2824. L_actual = getColor(t, true).lab()[0];
  2825. return (L_diff = L_actual - L_ideal);
  2826. })();
  2827. }
  2828. return t;
  2829. };
  2830. } else {
  2831. tMapLightness = (t) => t;
  2832. }
  2833. return f;
  2834. };
  2835.  
  2836. f.padding = function (p) {
  2837. if (p != null) {
  2838. if (type(p) === 'number') {
  2839. p = [p, p];
  2840. }
  2841. _padding = p;
  2842. return f;
  2843. } else {
  2844. return _padding;
  2845. }
  2846. };
  2847.  
  2848. f.colors = function (numColors, out) {
  2849. // If no arguments are given, return the original colors that were provided
  2850. if (arguments.length < 2) {
  2851. out = 'hex';
  2852. }
  2853. let result = [];
  2854.  
  2855. if (arguments.length === 0) {
  2856. result = _colors.slice(0);
  2857. } else if (numColors === 1) {
  2858. result = [f(0.5)];
  2859. } else if (numColors > 1) {
  2860. const dm = _domain[0];
  2861. const dd = _domain[1] - dm;
  2862. result = __range__$1(0, numColors).map((i) =>
  2863. f(dm + (i / (numColors - 1)) * dd)
  2864. );
  2865. } else {
  2866. // returns all colors based on the defined classes
  2867. colors = [];
  2868. let samples = [];
  2869. if (_classes && _classes.length > 2) {
  2870. for (
  2871. let i = 1, end = _classes.length, asc = 1 <= end;
  2872. asc ? i < end : i > end;
  2873. asc ? i++ : i--
  2874. ) {
  2875. samples.push((_classes[i - 1] + _classes[i]) * 0.5);
  2876. }
  2877. } else {
  2878. samples = _domain;
  2879. }
  2880. result = samples.map((v) => f(v));
  2881. }
  2882.  
  2883. if (chroma[out]) {
  2884. result = result.map((c) => c[out]());
  2885. }
  2886. return result;
  2887. };
  2888.  
  2889. f.cache = function (c) {
  2890. if (c != null) {
  2891. _useCache = c;
  2892. return f;
  2893. } else {
  2894. return _useCache;
  2895. }
  2896. };
  2897.  
  2898. f.gamma = function (g) {
  2899. if (g != null) {
  2900. _gamma = g;
  2901. return f;
  2902. } else {
  2903. return _gamma;
  2904. }
  2905. };
  2906.  
  2907. f.nodata = function (d) {
  2908. if (d != null) {
  2909. _nacol = chroma(d);
  2910. return f;
  2911. } else {
  2912. return _nacol;
  2913. }
  2914. };
  2915.  
  2916. return f;
  2917. }
  2918.  
  2919. function __range__$1(left, right, inclusive) {
  2920. let range = [];
  2921. let ascending = left < right;
  2922. let end = right ;
  2923. for (let i = left; ascending ? i < end : i > end; ascending ? i++ : i--) {
  2924. range.push(i);
  2925. }
  2926. return range;
  2927. }
  2928.  
  2929. const { log: log$1, pow: pow$3, floor, abs: abs$1 } = Math;
  2930.  
  2931. function analyze(data, key = null) {
  2932. const r = {
  2933. min: Number.MAX_VALUE,
  2934. max: Number.MAX_VALUE * -1,
  2935. sum: 0,
  2936. values: [],
  2937. count: 0
  2938. };
  2939. if (type(data) === 'object') {
  2940. data = Object.values(data);
  2941. }
  2942. data.forEach((val) => {
  2943. if (key && type(val) === 'object') val = val[key];
  2944. if (val !== undefined && val !== null && !isNaN(val)) {
  2945. r.values.push(val);
  2946. r.sum += val;
  2947. if (val < r.min) r.min = val;
  2948. if (val > r.max) r.max = val;
  2949. r.count += 1;
  2950. }
  2951. });
  2952.  
  2953. r.domain = [r.min, r.max];
  2954.  
  2955. r.limits = (mode, num) => limits(r, mode, num);
  2956.  
  2957. return r;
  2958. }
  2959.  
  2960. function limits(data, mode = 'equal', num = 7) {
  2961. if (type(data) == 'array') {
  2962. data = analyze(data);
  2963. }
  2964. const { min, max } = data;
  2965. const values = data.values.sort((a, b) => a - b);
  2966.  
  2967. if (num === 1) {
  2968. return [min, max];
  2969. }
  2970.  
  2971. const limits = [];
  2972.  
  2973. if (mode.substr(0, 1) === 'c') {
  2974. // continuous
  2975. limits.push(min);
  2976. limits.push(max);
  2977. }
  2978.  
  2979. if (mode.substr(0, 1) === 'e') {
  2980. // equal interval
  2981. limits.push(min);
  2982. for (let i = 1; i < num; i++) {
  2983. limits.push(min + (i / num) * (max - min));
  2984. }
  2985. limits.push(max);
  2986. } else if (mode.substr(0, 1) === 'l') {
  2987. // log scale
  2988. if (min <= 0) {
  2989. throw new Error(
  2990. 'Logarithmic scales are only possible for values > 0'
  2991. );
  2992. }
  2993. const min_log = Math.LOG10E * log$1(min);
  2994. const max_log = Math.LOG10E * log$1(max);
  2995. limits.push(min);
  2996. for (let i = 1; i < num; i++) {
  2997. limits.push(pow$3(10, min_log + (i / num) * (max_log - min_log)));
  2998. }
  2999. limits.push(max);
  3000. } else if (mode.substr(0, 1) === 'q') {
  3001. // quantile scale
  3002. limits.push(min);
  3003. for (let i = 1; i < num; i++) {
  3004. const p = ((values.length - 1) * i) / num;
  3005. const pb = floor(p);
  3006. if (pb === p) {
  3007. limits.push(values[pb]);
  3008. } else {
  3009. // p > pb
  3010. const pr = p - pb;
  3011. limits.push(values[pb] * (1 - pr) + values[pb + 1] * pr);
  3012. }
  3013. }
  3014. limits.push(max);
  3015. } else if (mode.substr(0, 1) === 'k') {
  3016. // k-means clustering
  3017. /*
  3018. implementation based on
  3019. http://code.google.com/p/figue/source/browse/trunk/figue.js#336
  3020. simplified for 1-d input values
  3021. */
  3022. let cluster;
  3023. const n = values.length;
  3024. const assignments = new Array(n);
  3025. const clusterSizes = new Array(num);
  3026. let repeat = true;
  3027. let nb_iters = 0;
  3028. let centroids = null;
  3029.  
  3030. // get seed values
  3031. centroids = [];
  3032. centroids.push(min);
  3033. for (let i = 1; i < num; i++) {
  3034. centroids.push(min + (i / num) * (max - min));
  3035. }
  3036. centroids.push(max);
  3037.  
  3038. while (repeat) {
  3039. // assignment step
  3040. for (let j = 0; j < num; j++) {
  3041. clusterSizes[j] = 0;
  3042. }
  3043. for (let i = 0; i < n; i++) {
  3044. const value = values[i];
  3045. let mindist = Number.MAX_VALUE;
  3046. let best;
  3047. for (let j = 0; j < num; j++) {
  3048. const dist = abs$1(centroids[j] - value);
  3049. if (dist < mindist) {
  3050. mindist = dist;
  3051. best = j;
  3052. }
  3053. clusterSizes[best]++;
  3054. assignments[i] = best;
  3055. }
  3056. }
  3057.  
  3058. // update centroids step
  3059. const newCentroids = new Array(num);
  3060. for (let j = 0; j < num; j++) {
  3061. newCentroids[j] = null;
  3062. }
  3063. for (let i = 0; i < n; i++) {
  3064. cluster = assignments[i];
  3065. if (newCentroids[cluster] === null) {
  3066. newCentroids[cluster] = values[i];
  3067. } else {
  3068. newCentroids[cluster] += values[i];
  3069. }
  3070. }
  3071. for (let j = 0; j < num; j++) {
  3072. newCentroids[j] *= 1 / clusterSizes[j];
  3073. }
  3074.  
  3075. // check convergence
  3076. repeat = false;
  3077. for (let j = 0; j < num; j++) {
  3078. if (newCentroids[j] !== centroids[j]) {
  3079. repeat = true;
  3080. break;
  3081. }
  3082. }
  3083.  
  3084. centroids = newCentroids;
  3085. nb_iters++;
  3086.  
  3087. if (nb_iters > 200) {
  3088. repeat = false;
  3089. }
  3090. }
  3091.  
  3092. // finished k-means clustering
  3093. // the next part is borrowed from gabrielflor.it
  3094. const kClusters = {};
  3095. for (let j = 0; j < num; j++) {
  3096. kClusters[j] = [];
  3097. }
  3098. for (let i = 0; i < n; i++) {
  3099. cluster = assignments[i];
  3100. kClusters[cluster].push(values[i]);
  3101. }
  3102. let tmpKMeansBreaks = [];
  3103. for (let j = 0; j < num; j++) {
  3104. tmpKMeansBreaks.push(kClusters[j][0]);
  3105. tmpKMeansBreaks.push(kClusters[j][kClusters[j].length - 1]);
  3106. }
  3107. tmpKMeansBreaks = tmpKMeansBreaks.sort((a, b) => a - b);
  3108. limits.push(tmpKMeansBreaks[0]);
  3109. for (let i = 1; i < tmpKMeansBreaks.length; i += 2) {
  3110. const v = tmpKMeansBreaks[i];
  3111. if (!isNaN(v) && limits.indexOf(v) === -1) {
  3112. limits.push(v);
  3113. }
  3114. }
  3115. }
  3116. return limits;
  3117. }
  3118.  
  3119. const { pow: pow$2 } = Math;
  3120.  
  3121. const EPS = 1e-7;
  3122. const MAX_ITER = 20;
  3123.  
  3124. Color$1.prototype.luminance = function (lum, mode = 'rgb') {
  3125. if (lum !== undefined && type(lum) === 'number') {
  3126. if (lum === 0) {
  3127. // return pure black
  3128. return new Color$1([0, 0, 0, this._rgb[3]], 'rgb');
  3129. }
  3130. if (lum === 1) {
  3131. // return pure white
  3132. return new Color$1([255, 255, 255, this._rgb[3]], 'rgb');
  3133. }
  3134. // compute new color using...
  3135. let cur_lum = this.luminance();
  3136. let max_iter = MAX_ITER;
  3137.  
  3138. const test = (low, high) => {
  3139. const mid = low.interpolate(high, 0.5, mode);
  3140. const lm = mid.luminance();
  3141. if (Math.abs(lum - lm) < EPS || !max_iter--) {
  3142. // close enough
  3143. return mid;
  3144. }
  3145. return lm > lum ? test(low, mid) : test(mid, high);
  3146. };
  3147.  
  3148. const rgb = (
  3149. cur_lum > lum
  3150. ? test(new Color$1([0, 0, 0]), this)
  3151. : test(this, new Color$1([255, 255, 255]))
  3152. ).rgb();
  3153. return new Color$1([...rgb, this._rgb[3]]);
  3154. }
  3155. return rgb2luminance(...this._rgb.slice(0, 3));
  3156. };
  3157.  
  3158. const rgb2luminance = (r, g, b) => {
  3159. // relative luminance
  3160. // see http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
  3161. r = luminance_x(r);
  3162. g = luminance_x(g);
  3163. b = luminance_x(b);
  3164. return 0.2126 * r + 0.7152 * g + 0.0722 * b;
  3165. };
  3166.  
  3167. const luminance_x = (x) => {
  3168. x /= 255;
  3169. return x <= 0.03928 ? x / 12.92 : pow$2((x + 0.055) / 1.055, 2.4);
  3170. };
  3171.  
  3172. var contrast = (a, b) => {
  3173. // WCAG contrast ratio
  3174. // see http://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef
  3175. a = new Color$1(a);
  3176. b = new Color$1(b);
  3177. const l1 = a.luminance();
  3178. const l2 = b.luminance();
  3179. return l1 > l2 ? (l1 + 0.05) / (l2 + 0.05) : (l2 + 0.05) / (l1 + 0.05);
  3180. };
  3181.  
  3182. /**
  3183. * @license
  3184. *
  3185. * The APCA contrast prediction algorithm is based of the formulas published
  3186. * in the APCA-1.0.98G specification by Myndex. The specification is available at:
  3187. * https://raw.githubusercontent.com/Myndex/apca-w3/master/images/APCAw3_0.1.17_APCA0.0.98G.svg
  3188. *
  3189. * Note that the APCA implementation is still beta, so please update to
  3190. * future versions of chroma.js when they become available.
  3191. *
  3192. * You can read more about the APCA Readability Criterion at
  3193. * https://readtech.org/ARC/
  3194. */
  3195.  
  3196. // constants
  3197. const W_offset = 0.027;
  3198. const P_in = 0.0005;
  3199. const P_out = 0.1;
  3200. const R_scale = 1.14;
  3201. const B_threshold = 0.022;
  3202. const B_exp = 1.414;
  3203.  
  3204. var contrastAPCA = (text, bg) => {
  3205. // parse input colors
  3206. text = new Color$1(text);
  3207. bg = new Color$1(bg);
  3208. // if text color has alpha, blend against background
  3209. if (text.alpha() < 1) {
  3210. text = mix$1(bg, text, text.alpha(), 'rgb');
  3211. }
  3212. const l_text = lum(...text.rgb());
  3213. const l_bg = lum(...bg.rgb());
  3214.  
  3215. // soft clamp black levels
  3216. const Y_text =
  3217. l_text >= B_threshold
  3218. ? l_text
  3219. : l_text + Math.pow(B_threshold - l_text, B_exp);
  3220. const Y_bg =
  3221. l_bg >= B_threshold ? l_bg : l_bg + Math.pow(B_threshold - l_bg, B_exp);
  3222.  
  3223. // normal polarity (dark text on light background)
  3224. const S_norm = Math.pow(Y_bg, 0.56) - Math.pow(Y_text, 0.57);
  3225. // reverse polarity (light text on dark background)
  3226. const S_rev = Math.pow(Y_bg, 0.65) - Math.pow(Y_text, 0.62);
  3227. // clamp noise then scale
  3228. const C =
  3229. Math.abs(Y_bg - Y_text) < P_in
  3230. ? 0
  3231. : Y_text < Y_bg
  3232. ? S_norm * R_scale
  3233. : S_rev * R_scale;
  3234. // clamp minimum contrast then offset
  3235. const S_apc = Math.abs(C) < P_out ? 0 : C > 0 ? C - W_offset : C + W_offset;
  3236. // scale to 100
  3237. return S_apc * 100;
  3238. };
  3239.  
  3240. function lum(r, g, b) {
  3241. return (
  3242. 0.2126729 * Math.pow(r / 255, 2.4) +
  3243. 0.7151522 * Math.pow(g / 255, 2.4) +
  3244. 0.072175 * Math.pow(b / 255, 2.4)
  3245. );
  3246. }
  3247.  
  3248. const { sqrt: sqrt$1, pow: pow$1, min: min$1, max: max$2, atan2: atan2$1, abs, cos: cos$1, sin: sin$1, exp, PI } = Math;
  3249.  
  3250. function deltaE (a, b, Kl = 1, Kc = 1, Kh = 1) {
  3251. // Delta E (CIE 2000)
  3252. // see http://www.brucelindbloom.com/index.html?Eqn_DeltaE_CIE2000.html
  3253. var rad2deg = function (rad) {
  3254. return (360 * rad) / (2 * PI);
  3255. };
  3256. var deg2rad = function (deg) {
  3257. return (2 * PI * deg) / 360;
  3258. };
  3259. a = new Color$1(a);
  3260. b = new Color$1(b);
  3261. const [L1, a1, b1] = Array.from(a.lab());
  3262. const [L2, a2, b2] = Array.from(b.lab());
  3263. const avgL = (L1 + L2) / 2;
  3264. const C1 = sqrt$1(pow$1(a1, 2) + pow$1(b1, 2));
  3265. const C2 = sqrt$1(pow$1(a2, 2) + pow$1(b2, 2));
  3266. const avgC = (C1 + C2) / 2;
  3267. const G = 0.5 * (1 - sqrt$1(pow$1(avgC, 7) / (pow$1(avgC, 7) + pow$1(25, 7))));
  3268. const a1p = a1 * (1 + G);
  3269. const a2p = a2 * (1 + G);
  3270. const C1p = sqrt$1(pow$1(a1p, 2) + pow$1(b1, 2));
  3271. const C2p = sqrt$1(pow$1(a2p, 2) + pow$1(b2, 2));
  3272. const avgCp = (C1p + C2p) / 2;
  3273. const arctan1 = rad2deg(atan2$1(b1, a1p));
  3274. const arctan2 = rad2deg(atan2$1(b2, a2p));
  3275. const h1p = arctan1 >= 0 ? arctan1 : arctan1 + 360;
  3276. const h2p = arctan2 >= 0 ? arctan2 : arctan2 + 360;
  3277. const avgHp =
  3278. abs(h1p - h2p) > 180 ? (h1p + h2p + 360) / 2 : (h1p + h2p) / 2;
  3279. const T =
  3280. 1 -
  3281. 0.17 * cos$1(deg2rad(avgHp - 30)) +
  3282. 0.24 * cos$1(deg2rad(2 * avgHp)) +
  3283. 0.32 * cos$1(deg2rad(3 * avgHp + 6)) -
  3284. 0.2 * cos$1(deg2rad(4 * avgHp - 63));
  3285. let deltaHp = h2p - h1p;
  3286. deltaHp =
  3287. abs(deltaHp) <= 180
  3288. ? deltaHp
  3289. : h2p <= h1p
  3290. ? deltaHp + 360
  3291. : deltaHp - 360;
  3292. deltaHp = 2 * sqrt$1(C1p * C2p) * sin$1(deg2rad(deltaHp) / 2);
  3293. const deltaL = L2 - L1;
  3294. const deltaCp = C2p - C1p;
  3295. const sl = 1 + (0.015 * pow$1(avgL - 50, 2)) / sqrt$1(20 + pow$1(avgL - 50, 2));
  3296. const sc = 1 + 0.045 * avgCp;
  3297. const sh = 1 + 0.015 * avgCp * T;
  3298. const deltaTheta = 30 * exp(-pow$1((avgHp - 275) / 25, 2));
  3299. const Rc = 2 * sqrt$1(pow$1(avgCp, 7) / (pow$1(avgCp, 7) + pow$1(25, 7)));
  3300. const Rt = -Rc * sin$1(2 * deg2rad(deltaTheta));
  3301. const result = sqrt$1(
  3302. pow$1(deltaL / (Kl * sl), 2) +
  3303. pow$1(deltaCp / (Kc * sc), 2) +
  3304. pow$1(deltaHp / (Kh * sh), 2) +
  3305. Rt * (deltaCp / (Kc * sc)) * (deltaHp / (Kh * sh))
  3306. );
  3307. return max$2(0, min$1(100, result));
  3308. }
  3309.  
  3310. // simple Euclidean distance
  3311. function distance (a, b, mode = 'lab') {
  3312. // Delta E (CIE 1976)
  3313. // see http://www.brucelindbloom.com/index.html?Equations.html
  3314. a = new Color$1(a);
  3315. b = new Color$1(b);
  3316. const l1 = a.get(mode);
  3317. const l2 = b.get(mode);
  3318. let sum_sq = 0;
  3319. for (let i in l1) {
  3320. const d = (l1[i] || 0) - (l2[i] || 0);
  3321. sum_sq += d * d;
  3322. }
  3323. return Math.sqrt(sum_sq);
  3324. }
  3325.  
  3326. var valid = (...args) => {
  3327. try {
  3328. new Color$1(...args);
  3329. return true;
  3330. // eslint-disable-next-line
  3331. } catch (e) {
  3332. return false;
  3333. }
  3334. };
  3335.  
  3336. var input = {
  3337. format: {},
  3338. autodetect: []
  3339. };
  3340.  
  3341. // minimal multi-purpose interface
  3342.  
  3343.  
  3344. const { pow } = Math;
  3345.  
  3346. function scale (colors) {
  3347. // constructor
  3348. let _mode = 'rgb';
  3349. let _nacol = chroma('#ccc');
  3350. let _spread = 0;
  3351. // const _fixed = false;
  3352. let _domain = [0, 1];
  3353. let _pos = [];
  3354. let _padding = [0, 0];
  3355. let _classes = false;
  3356. let _colors = [];
  3357. let _out = false;
  3358. let _min = 0;
  3359. let _max = 1;
  3360. let _correctLightness = false;
  3361. let _colorCache = {};
  3362. let _useCache = true;
  3363. let _gamma = 1;
  3364.  
  3365. // private methods
  3366.  
  3367. const setColors = function (colors) {
  3368. colors = colors || ['#fff', '#000'];
  3369. if (
  3370. colors &&
  3371. type(colors) === 'string' &&
  3372. chroma.brewer &&
  3373. chroma.brewer[colors.toLowerCase()]
  3374. ) {
  3375. colors = chroma.brewer[colors.toLowerCase()];
  3376. }
  3377. if (type(colors) === 'array') {
  3378. // handle single color
  3379. if (colors.length === 1) {
  3380. colors = [colors[0], colors[0]];
  3381. }
  3382. // make a copy of the colors
  3383. colors = colors.slice(0);
  3384. // convert to chroma classes
  3385. for (let c = 0; c < colors.length; c++) {
  3386. colors[c] = chroma(colors[c]);
  3387. }
  3388. // auto-fill color position
  3389. _pos.length = 0;
  3390. for (let c = 0; c < colors.length; c++) {
  3391. _pos.push(c / (colors.length - 1));
  3392. }
  3393. }
  3394. resetCache();
  3395. return (_colors = colors);
  3396. };
  3397.  
  3398. const getClass = function (value) {
  3399. if (_classes != null) {
  3400. const n = _classes.length - 1;
  3401. let i = 0;
  3402. while (i < n && value >= _classes[i]) {
  3403. i++;
  3404. }
  3405. return i - 1;
  3406. }
  3407. return 0;
  3408. };
  3409.  
  3410. let tMapLightness = (t) => t;
  3411. let tMapDomain = (t) => t;
  3412.  
  3413. // const classifyValue = function(value) {
  3414. // let val = value;
  3415. // if (_classes.length > 2) {
  3416. // const n = _classes.length-1;
  3417. // const i = getClass(value);
  3418. // const minc = _classes[0] + ((_classes[1]-_classes[0]) * (0 + (_spread * 0.5))); // center of 1st class
  3419. // const maxc = _classes[n-1] + ((_classes[n]-_classes[n-1]) * (1 - (_spread * 0.5))); // center of last class
  3420. // val = _min + ((((_classes[i] + ((_classes[i+1] - _classes[i]) * 0.5)) - minc) / (maxc-minc)) * (_max - _min));
  3421. // }
  3422. // return val;
  3423. // };
  3424.  
  3425. const getColor = function (val, bypassMap) {
  3426. let col, t;
  3427. if (bypassMap == null) {
  3428. bypassMap = false;
  3429. }
  3430. if (isNaN(val) || val === null) {
  3431. return _nacol;
  3432. }
  3433. if (!bypassMap) {
  3434. if (_classes && _classes.length > 2) {
  3435. // find the class
  3436. const c = getClass(val);
  3437. t = c / (_classes.length - 2);
  3438. } else if (_max !== _min) {
  3439. // just interpolate between min/max
  3440. t = (val - _min) / (_max - _min);
  3441. } else {
  3442. t = 1;
  3443. }
  3444. } else {
  3445. t = val;
  3446. }
  3447.  
  3448. // domain map
  3449. t = tMapDomain(t);
  3450.  
  3451. if (!bypassMap) {
  3452. t = tMapLightness(t); // lightness correction
  3453. }
  3454.  
  3455. if (_gamma !== 1) {
  3456. t = pow(t, _gamma);
  3457. }
  3458.  
  3459. t = _padding[0] + t * (1 - _padding[0] - _padding[1]);
  3460.  
  3461. t = limit$1(t, 0, 1);
  3462.  
  3463. const k = Math.floor(t * 10000);
  3464.  
  3465. if (_useCache && _colorCache[k]) {
  3466. col = _colorCache[k];
  3467. } else {
  3468. if (type(_colors) === 'array') {
  3469. //for i in [0.._pos.length-1]
  3470. for (let i = 0; i < _pos.length; i++) {
  3471. const p = _pos[i];
  3472. if (t <= p) {
  3473. col = _colors[i];
  3474. break;
  3475. }
  3476. if (t >= p && i === _pos.length - 1) {
  3477. col = _colors[i];
  3478. break;
  3479. }
  3480. if (t > p && t < _pos[i + 1]) {
  3481. t = (t - p) / (_pos[i + 1] - p);
  3482. col = chroma.interpolate(
  3483. _colors[i],
  3484. _colors[i + 1],
  3485. t,
  3486. _mode
  3487. );
  3488. break;
  3489. }
  3490. }
  3491. } else if (type(_colors) === 'function') {
  3492. col = _colors(t);
  3493. }
  3494. if (_useCache) {
  3495. _colorCache[k] = col;
  3496. }
  3497. }
  3498. return col;
  3499. };
  3500.  
  3501. var resetCache = () => (_colorCache = {});
  3502.  
  3503. setColors(colors);
  3504.  
  3505. // public interface
  3506.  
  3507. const f = function (v) {
  3508. const c = chroma(getColor(v));
  3509. if (_out && c[_out]) {
  3510. return c[_out]();
  3511. } else {
  3512. return c;
  3513. }
  3514. };
  3515.  
  3516. f.classes = function (classes) {
  3517. if (classes != null) {
  3518. if (type(classes) === 'array') {
  3519. _classes = classes;
  3520. _domain = [classes[0], classes[classes.length - 1]];
  3521. } else {
  3522. const d = chroma.analyze(_domain);
  3523. if (classes === 0) {
  3524. _classes = [d.min, d.max];
  3525. } else {
  3526. _classes = chroma.limits(d, 'e', classes);
  3527. }
  3528. }
  3529. return f;
  3530. }
  3531. return _classes;
  3532. };
  3533.  
  3534. f.domain = function (domain) {
  3535. if (!arguments.length) {
  3536. return _domain;
  3537. }
  3538. _min = domain[0];
  3539. _max = domain[domain.length - 1];
  3540. _pos = [];
  3541. const k = _colors.length;
  3542. if (domain.length === k && _min !== _max) {
  3543. // update positions
  3544. for (let d of Array.from(domain)) {
  3545. _pos.push((d - _min) / (_max - _min));
  3546. }
  3547. } else {
  3548. for (let c = 0; c < k; c++) {
  3549. _pos.push(c / (k - 1));
  3550. }
  3551. if (domain.length > 2) {
  3552. // set domain map
  3553. const tOut = domain.map((d, i) => i / (domain.length - 1));
  3554. const tBreaks = domain.map((d) => (d - _min) / (_max - _min));
  3555. if (!tBreaks.every((val, i) => tOut[i] === val)) {
  3556. tMapDomain = (t) => {
  3557. if (t <= 0 || t >= 1) return t;
  3558. let i = 0;
  3559. while (t >= tBreaks[i + 1]) i++;
  3560. const f =
  3561. (t - tBreaks[i]) / (tBreaks[i + 1] - tBreaks[i]);
  3562. const out = tOut[i] + f * (tOut[i + 1] - tOut[i]);
  3563. return out;
  3564. };
  3565. }
  3566. }
  3567. }
  3568. _domain = [_min, _max];
  3569. return f;
  3570. };
  3571.  
  3572. f.mode = function (_m) {
  3573. if (!arguments.length) {
  3574. return _mode;
  3575. }
  3576. _mode = _m;
  3577. resetCache();
  3578. return f;
  3579. };
  3580.  
  3581. f.range = function (colors, _pos) {
  3582. setColors(colors);
  3583. return f;
  3584. };
  3585.  
  3586. f.out = function (_o) {
  3587. _out = _o;
  3588. return f;
  3589. };
  3590.  
  3591. f.spread = function (val) {
  3592. if (!arguments.length) {
  3593. return _spread;
  3594. }
  3595. _spread = val;
  3596. return f;
  3597. };
  3598.  
  3599. f.correctLightness = function (v) {
  3600. if (v == null) {
  3601. v = true;
  3602. }
  3603. _correctLightness = v;
  3604. resetCache();
  3605. if (_correctLightness) {
  3606. tMapLightness = function (t) {
  3607. const L0 = getColor(0, true).lab()[0];
  3608. const L1 = getColor(1, true).lab()[0];
  3609. const pol = L0 > L1;
  3610. let L_actual = getColor(t, true).lab()[0];
  3611. const L_ideal = L0 + (L1 - L0) * t;
  3612. let L_diff = L_actual - L_ideal;
  3613. let t0 = 0;
  3614. let t1 = 1;
  3615. let max_iter = 20;
  3616. while (Math.abs(L_diff) > 1e-2 && max_iter-- > 0) {
  3617. (function () {
  3618. if (pol) {
  3619. L_diff *= -1;
  3620. }
  3621. if (L_diff < 0) {
  3622. t0 = t;
  3623. t += (t1 - t) * 0.5;
  3624. } else {
  3625. t1 = t;
  3626. t += (t0 - t) * 0.5;
  3627. }
  3628. L_actual = getColor(t, true).lab()[0];
  3629. return (L_diff = L_actual - L_ideal);
  3630. })();
  3631. }
  3632. return t;
  3633. };
  3634. } else {
  3635. tMapLightness = (t) => t;
  3636. }
  3637. return f;
  3638. };
  3639.  
  3640. f.padding = function (p) {
  3641. if (p != null) {
  3642. if (type(p) === 'number') {
  3643. p = [p, p];
  3644. }
  3645. _padding = p;
  3646. return f;
  3647. } else {
  3648. return _padding;
  3649. }
  3650. };
  3651.  
  3652. f.colors = function (numColors, out) {
  3653. // If no arguments are given, return the original colors that were provided
  3654. if (arguments.length < 2) {
  3655. out = 'hex';
  3656. }
  3657. let result = [];
  3658.  
  3659. if (arguments.length === 0) {
  3660. result = _colors.slice(0);
  3661. } else if (numColors === 1) {
  3662. result = [f(0.5)];
  3663. } else if (numColors > 1) {
  3664. const dm = _domain[0];
  3665. const dd = _domain[1] - dm;
  3666. result = __range__(0, numColors).map((i) =>
  3667. f(dm + (i / (numColors - 1)) * dd)
  3668. );
  3669. } else {
  3670. // returns all colors based on the defined classes
  3671. colors = [];
  3672. let samples = [];
  3673. if (_classes && _classes.length > 2) {
  3674. for (
  3675. let i = 1, end = _classes.length, asc = 1 <= end;
  3676. asc ? i < end : i > end;
  3677. asc ? i++ : i--
  3678. ) {
  3679. samples.push((_classes[i - 1] + _classes[i]) * 0.5);
  3680. }
  3681. } else {
  3682. samples = _domain;
  3683. }
  3684. result = samples.map((v) => f(v));
  3685. }
  3686.  
  3687. if (chroma[out]) {
  3688. result = result.map((c) => c[out]());
  3689. }
  3690. return result;
  3691. };
  3692.  
  3693. f.cache = function (c) {
  3694. if (c != null) {
  3695. _useCache = c;
  3696. return f;
  3697. } else {
  3698. return _useCache;
  3699. }
  3700. };
  3701.  
  3702. f.gamma = function (g) {
  3703. if (g != null) {
  3704. _gamma = g;
  3705. return f;
  3706. } else {
  3707. return _gamma;
  3708. }
  3709. };
  3710.  
  3711. f.nodata = function (d) {
  3712. if (d != null) {
  3713. _nacol = chroma(d);
  3714. return f;
  3715. } else {
  3716. return _nacol;
  3717. }
  3718. };
  3719.  
  3720. return f;
  3721. }
  3722.  
  3723. function __range__(left, right, inclusive) {
  3724. let range = [];
  3725. let ascending = left < right;
  3726. let end = right ;
  3727. for (let i = left; ascending ? i < end : i > end; ascending ? i++ : i--) {
  3728. range.push(i);
  3729. }
  3730. return range;
  3731. }
  3732.  
  3733. // some pre-defined color scales:
  3734.  
  3735. var scales = {
  3736. cool() {
  3737. return scale([chroma.hsl(180, 1, 0.9), chroma.hsl(250, 0.7, 0.4)]);
  3738. },
  3739. hot() {
  3740. return scale(['#000', '#f00', '#ff0', '#fff']).mode(
  3741. 'rgb'
  3742. );
  3743. }
  3744. };
  3745.  
  3746. /**
  3747. X11 color names
  3748.  
  3749. http://www.w3.org/TR/css3-color/#svg-color
  3750. */
  3751.  
  3752. const w3cx11 = {
  3753. aliceblue: '#f0f8ff',
  3754. antiquewhite: '#faebd7',
  3755. aqua: '#00ffff',
  3756. aquamarine: '#7fffd4',
  3757. azure: '#f0ffff',
  3758. beige: '#f5f5dc',
  3759. bisque: '#ffe4c4',
  3760. black: '#000000',
  3761. blanchedalmond: '#ffebcd',
  3762. blue: '#0000ff',
  3763. blueviolet: '#8a2be2',
  3764. brown: '#a52a2a',
  3765. burlywood: '#deb887',
  3766. cadetblue: '#5f9ea0',
  3767. chartreuse: '#7fff00',
  3768. chocolate: '#d2691e',
  3769. coral: '#ff7f50',
  3770. cornflowerblue: '#6495ed',
  3771. cornsilk: '#fff8dc',
  3772. crimson: '#dc143c',
  3773. cyan: '#00ffff',
  3774. darkblue: '#00008b',
  3775. darkcyan: '#008b8b',
  3776. darkgoldenrod: '#b8860b',
  3777. darkgray: '#a9a9a9',
  3778. darkgreen: '#006400',
  3779. darkgrey: '#a9a9a9',
  3780. darkkhaki: '#bdb76b',
  3781. darkmagenta: '#8b008b',
  3782. darkolivegreen: '#556b2f',
  3783. darkorange: '#ff8c00',
  3784. darkorchid: '#9932cc',
  3785. darkred: '#8b0000',
  3786. darksalmon: '#e9967a',
  3787. darkseagreen: '#8fbc8f',
  3788. darkslateblue: '#483d8b',
  3789. darkslategray: '#2f4f4f',
  3790. darkslategrey: '#2f4f4f',
  3791. darkturquoise: '#00ced1',
  3792. darkviolet: '#9400d3',
  3793. deeppink: '#ff1493',
  3794. deepskyblue: '#00bfff',
  3795. dimgray: '#696969',
  3796. dimgrey: '#696969',
  3797. dodgerblue: '#1e90ff',
  3798. firebrick: '#b22222',
  3799. floralwhite: '#fffaf0',
  3800. forestgreen: '#228b22',
  3801. fuchsia: '#ff00ff',
  3802. gainsboro: '#dcdcdc',
  3803. ghostwhite: '#f8f8ff',
  3804. gold: '#ffd700',
  3805. goldenrod: '#daa520',
  3806. gray: '#808080',
  3807. green: '#008000',
  3808. greenyellow: '#adff2f',
  3809. grey: '#808080',
  3810. honeydew: '#f0fff0',
  3811. hotpink: '#ff69b4',
  3812. indianred: '#cd5c5c',
  3813. indigo: '#4b0082',
  3814. ivory: '#fffff0',
  3815. khaki: '#f0e68c',
  3816. laserlemon: '#ffff54',
  3817. lavender: '#e6e6fa',
  3818. lavenderblush: '#fff0f5',
  3819. lawngreen: '#7cfc00',
  3820. lemonchiffon: '#fffacd',
  3821. lightblue: '#add8e6',
  3822. lightcoral: '#f08080',
  3823. lightcyan: '#e0ffff',
  3824. lightgoldenrod: '#fafad2',
  3825. lightgoldenrodyellow: '#fafad2',
  3826. lightgray: '#d3d3d3',
  3827. lightgreen: '#90ee90',
  3828. lightgrey: '#d3d3d3',
  3829. lightpink: '#ffb6c1',
  3830. lightsalmon: '#ffa07a',
  3831. lightseagreen: '#20b2aa',
  3832. lightskyblue: '#87cefa',
  3833. lightslategray: '#778899',
  3834. lightslategrey: '#778899',
  3835. lightsteelblue: '#b0c4de',
  3836. lightyellow: '#ffffe0',
  3837. lime: '#00ff00',
  3838. limegreen: '#32cd32',
  3839. linen: '#faf0e6',
  3840. magenta: '#ff00ff',
  3841. maroon: '#800000',
  3842. maroon2: '#7f0000',
  3843. maroon3: '#b03060',
  3844. mediumaquamarine: '#66cdaa',
  3845. mediumblue: '#0000cd',
  3846. mediumorchid: '#ba55d3',
  3847. mediumpurple: '#9370db',
  3848. mediumseagreen: '#3cb371',
  3849. mediumslateblue: '#7b68ee',
  3850. mediumspringgreen: '#00fa9a',
  3851. mediumturquoise: '#48d1cc',
  3852. mediumvioletred: '#c71585',
  3853. midnightblue: '#191970',
  3854. mintcream: '#f5fffa',
  3855. mistyrose: '#ffe4e1',
  3856. moccasin: '#ffe4b5',
  3857. navajowhite: '#ffdead',
  3858. navy: '#000080',
  3859. oldlace: '#fdf5e6',
  3860. olive: '#808000',
  3861. olivedrab: '#6b8e23',
  3862. orange: '#ffa500',
  3863. orangered: '#ff4500',
  3864. orchid: '#da70d6',
  3865. palegoldenrod: '#eee8aa',
  3866. palegreen: '#98fb98',
  3867. paleturquoise: '#afeeee',
  3868. palevioletred: '#db7093',
  3869. papayawhip: '#ffefd5',
  3870. peachpuff: '#ffdab9',
  3871. peru: '#cd853f',
  3872. pink: '#ffc0cb',
  3873. plum: '#dda0dd',
  3874. powderblue: '#b0e0e6',
  3875. purple: '#800080',
  3876. purple2: '#7f007f',
  3877. purple3: '#a020f0',
  3878. rebeccapurple: '#663399',
  3879. red: '#ff0000',
  3880. rosybrown: '#bc8f8f',
  3881. royalblue: '#4169e1',
  3882. saddlebrown: '#8b4513',
  3883. salmon: '#fa8072',
  3884. sandybrown: '#f4a460',
  3885. seagreen: '#2e8b57',
  3886. seashell: '#fff5ee',
  3887. sienna: '#a0522d',
  3888. silver: '#c0c0c0',
  3889. skyblue: '#87ceeb',
  3890. slateblue: '#6a5acd',
  3891. slategray: '#708090',
  3892. slategrey: '#708090',
  3893. snow: '#fffafa',
  3894. springgreen: '#00ff7f',
  3895. steelblue: '#4682b4',
  3896. tan: '#d2b48c',
  3897. teal: '#008080',
  3898. thistle: '#d8bfd8',
  3899. tomato: '#ff6347',
  3900. turquoise: '#40e0d0',
  3901. violet: '#ee82ee',
  3902. wheat: '#f5deb3',
  3903. white: '#ffffff',
  3904. whitesmoke: '#f5f5f5',
  3905. yellow: '#ffff00',
  3906. yellowgreen: '#9acd32'
  3907. };
  3908.  
  3909. /**
  3910. ColorBrewer colors for chroma.js
  3911.  
  3912. Copyright (c) 2002 Cynthia Brewer, Mark Harrower, and The
  3913. Pennsylvania State University.
  3914.  
  3915. Licensed under the Apache License, Version 2.0 (the "License");
  3916. you may not use this file except in compliance with the License.
  3917. You may obtain a copy of the License at
  3918. http://www.apache.org/licenses/LICENSE-2.0
  3919.  
  3920. Unless required by applicable law or agreed to in writing, software distributed
  3921. under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  3922. CONDITIONS OF ANY KIND, either express or implied. See the License for the
  3923. specific language governing permissions and limitations under the License.
  3924. */
  3925.  
  3926. const colorbrewer = {
  3927. // sequential
  3928. OrRd: ['#fff7ec', '#fee8c8', '#fdd49e', '#fdbb84', '#fc8d59', '#ef6548', '#d7301f', '#b30000', '#7f0000'],
  3929. PuBu: ['#fff7fb', '#ece7f2', '#d0d1e6', '#a6bddb', '#74a9cf', '#3690c0', '#0570b0', '#045a8d', '#023858'],
  3930. BuPu: ['#f7fcfd', '#e0ecf4', '#bfd3e6', '#9ebcda', '#8c96c6', '#8c6bb1', '#88419d', '#810f7c', '#4d004b'],
  3931. Oranges: ['#fff5eb', '#fee6ce', '#fdd0a2', '#fdae6b', '#fd8d3c', '#f16913', '#d94801', '#a63603', '#7f2704'],
  3932. BuGn: ['#f7fcfd', '#e5f5f9', '#ccece6', '#99d8c9', '#66c2a4', '#41ae76', '#238b45', '#006d2c', '#00441b'],
  3933. YlOrBr: ['#ffffe5', '#fff7bc', '#fee391', '#fec44f', '#fe9929', '#ec7014', '#cc4c02', '#993404', '#662506'],
  3934. YlGn: ['#ffffe5', '#f7fcb9', '#d9f0a3', '#addd8e', '#78c679', '#41ab5d', '#238443', '#006837', '#004529'],
  3935. Reds: ['#fff5f0', '#fee0d2', '#fcbba1', '#fc9272', '#fb6a4a', '#ef3b2c', '#cb181d', '#a50f15', '#67000d'],
  3936. RdPu: ['#fff7f3', '#fde0dd', '#fcc5c0', '#fa9fb5', '#f768a1', '#dd3497', '#ae017e', '#7a0177', '#49006a'],
  3937. Greens: ['#f7fcf5', '#e5f5e0', '#c7e9c0', '#a1d99b', '#74c476', '#41ab5d', '#238b45', '#006d2c', '#00441b'],
  3938. YlGnBu: ['#ffffd9', '#edf8b1', '#c7e9b4', '#7fcdbb', '#41b6c4', '#1d91c0', '#225ea8', '#253494', '#081d58'],
  3939. Purples: ['#fcfbfd', '#efedf5', '#dadaeb', '#bcbddc', '#9e9ac8', '#807dba', '#6a51a3', '#54278f', '#3f007d'],
  3940. GnBu: ['#f7fcf0', '#e0f3db', '#ccebc5', '#a8ddb5', '#7bccc4', '#4eb3d3', '#2b8cbe', '#0868ac', '#084081'],
  3941. Greys: ['#ffffff', '#f0f0f0', '#d9d9d9', '#bdbdbd', '#969696', '#737373', '#525252', '#252525', '#000000'],
  3942. YlOrRd: ['#ffffcc', '#ffeda0', '#fed976', '#feb24c', '#fd8d3c', '#fc4e2a', '#e31a1c', '#bd0026', '#800026'],
  3943. PuRd: ['#f7f4f9', '#e7e1ef', '#d4b9da', '#c994c7', '#df65b0', '#e7298a', '#ce1256', '#980043', '#67001f'],
  3944. Blues: ['#f7fbff', '#deebf7', '#c6dbef', '#9ecae1', '#6baed6', '#4292c6', '#2171b5', '#08519c', '#08306b'],
  3945. PuBuGn: ['#fff7fb', '#ece2f0', '#d0d1e6', '#a6bddb', '#67a9cf', '#3690c0', '#02818a', '#016c59', '#014636'],
  3946. Viridis: ['#440154', '#482777', '#3f4a8a', '#31678e', '#26838f', '#1f9d8a', '#6cce5a', '#b6de2b', '#fee825'],
  3947.  
  3948. // diverging
  3949. Spectral: ['#9e0142', '#d53e4f', '#f46d43', '#fdae61', '#fee08b', '#ffffbf', '#e6f598', '#abdda4', '#66c2a5', '#3288bd', '#5e4fa2'],
  3950. RdYlGn: ['#a50026', '#d73027', '#f46d43', '#fdae61', '#fee08b', '#ffffbf', '#d9ef8b', '#a6d96a', '#66bd63', '#1a9850', '#006837'],
  3951. RdBu: ['#67001f', '#b2182b', '#d6604d', '#f4a582', '#fddbc7', '#f7f7f7', '#d1e5f0', '#92c5de', '#4393c3', '#2166ac', '#053061'],
  3952. PiYG: ['#8e0152', '#c51b7d', '#de77ae', '#f1b6da', '#fde0ef', '#f7f7f7', '#e6f5d0', '#b8e186', '#7fbc41', '#4d9221', '#276419'],
  3953. PRGn: ['#40004b', '#762a83', '#9970ab', '#c2a5cf', '#e7d4e8', '#f7f7f7', '#d9f0d3', '#a6dba0', '#5aae61', '#1b7837', '#00441b'],
  3954. RdYlBu: ['#a50026', '#d73027', '#f46d43', '#fdae61', '#fee090', '#ffffbf', '#e0f3f8', '#abd9e9', '#74add1', '#4575b4', '#313695'],
  3955. BrBG: ['#543005', '#8c510a', '#bf812d', '#dfc27d', '#f6e8c3', '#f5f5f5', '#c7eae5', '#80cdc1', '#35978f', '#01665e', '#003c30'],
  3956. RdGy: ['#67001f', '#b2182b', '#d6604d', '#f4a582', '#fddbc7', '#ffffff', '#e0e0e0', '#bababa', '#878787', '#4d4d4d', '#1a1a1a'],
  3957. PuOr: ['#7f3b08', '#b35806', '#e08214', '#fdb863', '#fee0b6', '#f7f7f7', '#d8daeb', '#b2abd2', '#8073ac', '#542788', '#2d004b'],
  3958.  
  3959. // qualitative
  3960. Set2: ['#66c2a5', '#fc8d62', '#8da0cb', '#e78ac3', '#a6d854', '#ffd92f', '#e5c494', '#b3b3b3'],
  3961. Accent: ['#7fc97f', '#beaed4', '#fdc086', '#ffff99', '#386cb0', '#f0027f', '#bf5b17', '#666666'],
  3962. Set1: ['#e41a1c', '#377eb8', '#4daf4a', '#984ea3', '#ff7f00', '#ffff33', '#a65628', '#f781bf', '#999999'],
  3963. Set3: ['#8dd3c7', '#ffffb3', '#bebada', '#fb8072', '#80b1d3', '#fdb462', '#b3de69', '#fccde5', '#d9d9d9', '#bc80bd', '#ccebc5', '#ffed6f'],
  3964. Dark2: ['#1b9e77', '#d95f02', '#7570b3', '#e7298a', '#66a61e', '#e6ab02', '#a6761d', '#666666'],
  3965. Paired: ['#a6cee3', '#1f78b4', '#b2df8a', '#33a02c', '#fb9a99', '#e31a1c', '#fdbf6f', '#ff7f00', '#cab2d6', '#6a3d9a', '#ffff99', '#b15928'],
  3966. Pastel2: ['#b3e2cd', '#fdcdac', '#cbd5e8', '#f4cae4', '#e6f5c9', '#fff2ae', '#f1e2cc', '#cccccc'],
  3967. Pastel1: ['#fbb4ae', '#b3cde3', '#ccebc5', '#decbe4', '#fed9a6', '#ffffcc', '#e5d8bd', '#fddaec', '#f2f2f2']
  3968. };
  3969.  
  3970. const colorbrewerTypes = Object.keys(colorbrewer);
  3971. const typeMap = new Map(colorbrewerTypes.map((key) => [key.toLowerCase(), key]));
  3972.  
  3973. // use Proxy to allow case-insensitive access to palettes
  3974. const colorbrewerProxy =
  3975. typeof Proxy === 'function'
  3976. ? new Proxy(colorbrewer, {
  3977. get(target, prop) {
  3978. const lower = prop.toLowerCase();
  3979. if (typeMap.has(lower)) {
  3980. return target[typeMap.get(lower)];
  3981. }
  3982. },
  3983. getOwnPropertyNames() {
  3984. return Object.getOwnPropertyNames(colorbrewerTypes);
  3985. }
  3986. })
  3987. : colorbrewer;
  3988.  
  3989. class Color {
  3990. constructor(...args) {
  3991. const me = this;
  3992. if (
  3993. type(args[0]) === 'object' &&
  3994. args[0].constructor &&
  3995. args[0].constructor === this.constructor
  3996. ) {
  3997. // the argument is already a Color instance
  3998. return args[0];
  3999. }
  4000. // last argument could be the mode
  4001. let mode = last(args);
  4002. let autodetect = false;
  4003. if (!mode) {
  4004. autodetect = true;
  4005.  
  4006. if (!_input.sorted) {
  4007. _input.autodetect = _input.autodetect.sort((a, b) => b.p - a.p);
  4008. _input.sorted = true;
  4009. }
  4010.  
  4011. // auto-detect format
  4012. for (let chk of _input.autodetect) {
  4013. mode = chk.test(...args);
  4014. if (mode) break;
  4015. }
  4016. }
  4017. if (_input.format[mode]) {
  4018. const rgb = _input.format[mode].apply(
  4019. null,
  4020. autodetect ? args : args.slice(0, -1)
  4021. );
  4022. me._rgb = clip_rgb(rgb);
  4023. } else {
  4024. throw new Error('unknown format: ' + args);
  4025. }
  4026. // add alpha channel
  4027. if (me._rgb.length === 3) me._rgb.push(1);
  4028. }
  4029. toString() {
  4030. if (type(this.hex) == 'function') return this.hex();
  4031. return `[${this._rgb.join(',')}]`;
  4032. }
  4033. }
  4034.  
  4035. const cmyk2rgb = (...args) => {
  4036. args = unpack(args, 'cmyk');
  4037. const [c, m, y, k] = args;
  4038. const alpha = args.length > 4 ? args[4] : 1;
  4039. if (k === 1) return [0, 0, 0, alpha];
  4040. return [
  4041. c >= 1 ? 0 : 255 * (1 - c) * (1 - k), // r
  4042. m >= 1 ? 0 : 255 * (1 - m) * (1 - k), // g
  4043. y >= 1 ? 0 : 255 * (1 - y) * (1 - k), // b
  4044. alpha
  4045. ];
  4046. };
  4047.  
  4048. const { max: max$1 } = Math;
  4049.  
  4050. const rgb2cmyk = (...args) => {
  4051. let [r, g, b] = unpack(args, 'rgb');
  4052. r = r / 255;
  4053. g = g / 255;
  4054. b = b / 255;
  4055. const k = 1 - max$1(r, max$1(g, b));
  4056. const f = k < 1 ? 1 / (1 - k) : 0;
  4057. const c = (1 - r - k) * f;
  4058. const m = (1 - g - k) * f;
  4059. const y = (1 - b - k) * f;
  4060. return [c, m, y, k];
  4061. };
  4062.  
  4063. Color$2.prototype.cmyk = function () {
  4064. return rgb2cmyk(this._rgb);
  4065. };
  4066.  
  4067. const cmyk = (...args) => new Color$2(...args, 'cmyk');
  4068. Object.assign(chroma$1, { cmyk });
  4069.  
  4070. input$1.format.cmyk = cmyk2rgb;
  4071.  
  4072. input$1.autodetect.push({
  4073. p: 2,
  4074. test: (...args) => {
  4075. args = unpack(args, 'cmyk');
  4076. if (type(args) === 'array' && args.length === 4) {
  4077. return 'cmyk';
  4078. }
  4079. }
  4080. });
  4081.  
  4082. /*
  4083. * supported arguments:
  4084. * - hsl2css(h,s,l)
  4085. * - hsl2css(h,s,l,a)
  4086. * - hsl2css([h,s,l], mode)
  4087. * - hsl2css([h,s,l,a], mode)
  4088. * - hsl2css({h,s,l,a}, mode)
  4089. */
  4090. const hsl2css = (...args) => {
  4091. const hsla = unpack(args, 'hsla');
  4092. let mode = last(args) || 'lsa';
  4093. hsla[0] = rnd2(hsla[0] || 0) + 'deg';
  4094. hsla[1] = rnd2(hsla[1] * 100) + '%';
  4095. hsla[2] = rnd2(hsla[2] * 100) + '%';
  4096. if (mode === 'hsla' || (hsla.length > 3 && hsla[3] < 1)) {
  4097. hsla[3] = '/ ' + (hsla.length > 3 ? hsla[3] : 1);
  4098. mode = 'hsla';
  4099. } else {
  4100. hsla.length = 3;
  4101. }
  4102. return `${mode.substr(0, 3)}(${hsla.join(' ')})`;
  4103. };
  4104.  
  4105. /*
  4106. * supported arguments:
  4107. * - rgb2hsl(r,g,b)
  4108. * - rgb2hsl(r,g,b,a)
  4109. * - rgb2hsl([r,g,b])
  4110. * - rgb2hsl([r,g,b,a])
  4111. * - rgb2hsl({r,g,b,a})
  4112. */
  4113. const rgb2hsl = (...args) => {
  4114. args = unpack(args, 'rgba');
  4115. let [r, g, b] = args;
  4116.  
  4117. r /= 255;
  4118. g /= 255;
  4119. b /= 255;
  4120.  
  4121. const minRgb = min$4(r, g, b);
  4122. const maxRgb = max$4(r, g, b);
  4123.  
  4124. const l = (maxRgb + minRgb) / 2;
  4125. let s, h;
  4126.  
  4127. if (maxRgb === minRgb) {
  4128. s = 0;
  4129. h = Number.NaN;
  4130. } else {
  4131. s =
  4132. l < 0.5
  4133. ? (maxRgb - minRgb) / (maxRgb + minRgb)
  4134. : (maxRgb - minRgb) / (2 - maxRgb - minRgb);
  4135. }
  4136.  
  4137. if (r == maxRgb) h = (g - b) / (maxRgb - minRgb);
  4138. else if (g == maxRgb) h = 2 + (b - r) / (maxRgb - minRgb);
  4139. else if (b == maxRgb) h = 4 + (r - g) / (maxRgb - minRgb);
  4140.  
  4141. h *= 60;
  4142. if (h < 0) h += 360;
  4143. if (args.length > 3 && args[3] !== undefined) return [h, s, l, args[3]];
  4144. return [h, s, l];
  4145. };
  4146.  
  4147. /*
  4148. * supported arguments:
  4149. * - lab2css(l,a,b)
  4150. * - lab2css(l,a,b,alpha)
  4151. * - lab2css([l,a,b], mode)
  4152. * - lab2css([l,a,b,alpha], mode)
  4153. */
  4154. const lab2css = (...args) => {
  4155. const laba = unpack(args, 'lab');
  4156. let mode = last(args) || 'lab';
  4157. laba[0] = rnd2(laba[0]) + '%';
  4158. laba[1] = rnd2(laba[1]);
  4159. laba[2] = rnd2(laba[2]);
  4160. if (mode === 'laba' || (laba.length > 3 && laba[3] < 1)) {
  4161. laba[3] = '/ ' + (laba.length > 3 ? laba[3] : 1);
  4162. } else {
  4163. laba.length = 3;
  4164. }
  4165. return `lab(${laba.join(' ')})`;
  4166. };
  4167.  
  4168. /*
  4169. * supported arguments:
  4170. * - lab2css(l,a,b)
  4171. * - lab2css(l,a,b,alpha)
  4172. * - lab2css([l,a,b], mode)
  4173. * - lab2css([l,a,b,alpha], mode)
  4174. */
  4175. const lch2css = (...args) => {
  4176. const lcha = unpack(args, 'lch');
  4177. let mode = last(args) || 'lab';
  4178. lcha[0] = rnd2(lcha[0]) + '%';
  4179. lcha[1] = rnd2(lcha[1]);
  4180. lcha[2] = isNaN(lcha[2]) ? 'none' : rnd2(lcha[2]) + 'deg'; // add deg unit to hue
  4181. if (mode === 'lcha' || (lcha.length > 3 && lcha[3] < 1)) {
  4182. lcha[3] = '/ ' + (lcha.length > 3 ? lcha[3] : 1);
  4183. } else {
  4184. lcha.length = 3;
  4185. }
  4186. return `lch(${lcha.join(' ')})`;
  4187. };
  4188.  
  4189. const rgb2lch = (...args) => {
  4190. const [r, g, b, ...rest] = unpack(args, 'rgb');
  4191. const [l, a, b_] = rgb2lab(r, g, b);
  4192. const [L, c, h] = lab2lch$1(l, a, b_);
  4193. return [L, c, h, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
  4194. };
  4195.  
  4196. const rgb2oklab = (...args) => {
  4197. const [r, g, b, ...rest] = unpack(args, 'rgb');
  4198. const xyz = rgb2xyz(r, g, b);
  4199. const oklab = XYZ_to_OKLab(xyz);
  4200. return [...oklab, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
  4201. };
  4202.  
  4203. // from https://www.w3.org/TR/css-color-4/#color-conversion-code
  4204. function XYZ_to_OKLab(XYZ) {
  4205. // Given XYZ relative to D65, convert to OKLab
  4206. const XYZtoLMS = [
  4207. [0.819022437996703, 0.3619062600528904, -0.1288737815209879],
  4208. [0.0329836539323885, 0.9292868615863434, 0.0361446663506424],
  4209. [0.0481771893596242, 0.2642395317527308, 0.6335478284694309]
  4210. ];
  4211. const LMStoOKLab = [
  4212. [0.210454268309314, 0.7936177747023054, -0.0040720430116193],
  4213. [1.9779985324311684, -2.42859224204858, 0.450593709617411],
  4214. [0.0259040424655478, 0.7827717124575296, -0.8086757549230774]
  4215. ];
  4216.  
  4217. const LMS = multiplyMatrices(XYZtoLMS, XYZ);
  4218. // JavaScript Math.cbrt returns a sign-matched cube root
  4219. // beware if porting to other languages
  4220. // especially if tempted to use a general power function
  4221. return multiplyMatrices(
  4222. LMStoOKLab,
  4223. LMS.map((c) => Math.cbrt(c))
  4224. );
  4225. // L in range [0,1]. For use in CSS, multiply by 100 and add a percent
  4226. }
  4227.  
  4228. const oklab2css = (...args) => {
  4229. const laba = unpack(args, 'lab');
  4230. laba[0] = rnd2(laba[0] * 100) + '%';
  4231. laba[1] = rnd3(laba[1]);
  4232. laba[2] = rnd3(laba[2]);
  4233. if (laba.length > 3 && laba[3] < 1) {
  4234. laba[3] = '/ ' + (laba.length > 3 ? laba[3] : 1);
  4235. } else {
  4236. laba.length = 3;
  4237. }
  4238. return `oklab(${laba.join(' ')})`;
  4239. };
  4240.  
  4241. const { sqrt, atan2, round: round$5 } = Math;
  4242.  
  4243. const lab2lch = (...args) => {
  4244. const [l, a, b] = unpack(args, 'lab');
  4245. const c = sqrt(a * a + b * b);
  4246. let h = (atan2(b, a) * RAD2DEG + 360) % 360;
  4247. if (round$5(c * 10000) === 0) h = Number.NaN;
  4248. return [l, c, h];
  4249. };
  4250.  
  4251. const rgb2oklch$1 = (...args) => {
  4252. const [r, g, b, ...rest] = unpack(args, 'rgb');
  4253. const [l, a, b_] = rgb2oklab(r, g, b);
  4254. const [L, c, h] = lab2lch(l, a, b_);
  4255. return [L, c, h, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
  4256. };
  4257.  
  4258. const oklch2css = (...args) => {
  4259. const lcha = unpack(args, 'lch');
  4260. lcha[0] = rnd2(lcha[0] * 100) + '%';
  4261. lcha[1] = rnd3(lcha[1]);
  4262. lcha[2] = isNaN(lcha[2]) ? 'none' : rnd2(lcha[2]) + 'deg'; // add deg unit to hue
  4263. if (lcha.length > 3 && lcha[3] < 1) {
  4264. lcha[3] = '/ ' + (lcha.length > 3 ? lcha[3] : 1);
  4265. } else {
  4266. lcha.length = 3;
  4267. }
  4268. return `oklch(${lcha.join(' ')})`;
  4269. };
  4270.  
  4271. const labConstants = {
  4272. // D65 standard referent
  4273. labWhitePoint: 'd65',
  4274. Xn: 0.95047,
  4275. Zn: 1.08883};
  4276.  
  4277. // taken from https://de.mathworks.com/help/images/ref/whitepoint.html
  4278. const ILLUMINANTS = new Map([
  4279. // ASTM E308-01
  4280. ['a', [1.0985, 0.35585]],
  4281. // Wyszecki & Stiles, p. 769
  4282. ['b', [1.0985, 0.35585]],
  4283. // C ASTM E308-01
  4284. ['c', [0.98074, 1.18232]],
  4285. // D50 (ASTM E308-01)
  4286. ['d50', [0.96422, 0.82521]],
  4287. // D55 (ASTM E308-01)
  4288. ['d55', [0.95682, 0.92149]],
  4289. // D65 (ASTM E308-01)
  4290. ['d65', [0.95047, 1.08883]],
  4291. // E (ASTM E308-01)
  4292. ['e', [1, 1, 1]],
  4293. // F2 (ASTM E308-01)
  4294. ['f2', [0.99186, 0.67393]],
  4295. // F7 (ASTM E308-01)
  4296. ['f7', [0.95041, 1.08747]],
  4297. // F11 (ASTM E308-01)
  4298. ['f11', [1.00962, 0.6435]],
  4299. ['icc', [0.96422, 0.82521]]
  4300. ]);
  4301.  
  4302. function setLabWhitePoint(name) {
  4303. const ill = ILLUMINANTS.get(String(name).toLowerCase());
  4304. if (!ill) {
  4305. throw new Error('unknown Lab illuminant ' + name);
  4306. }
  4307. labConstants.labWhitePoint = name;
  4308. labConstants.Xn = ill[0];
  4309. labConstants.Zn = ill[1];
  4310. }
  4311.  
  4312. function getLabWhitePoint() {
  4313. return labConstants.labWhitePoint;
  4314. }
  4315.  
  4316. const { round: round$4 } = Math;
  4317.  
  4318. /*
  4319. * supported arguments:
  4320. * - rgb2css(r,g,b)
  4321. * - rgb2css(r,g,b,a)
  4322. * - rgb2css([r,g,b], mode)
  4323. * - rgb2css([r,g,b,a], mode)
  4324. * - rgb2css({r,g,b,a}, mode)
  4325. */
  4326. const rgb2css = (...args) => {
  4327. const rgba = unpack(args, 'rgba');
  4328. let mode = last(args) || 'rgb';
  4329. if (mode.substr(0, 3) === 'hsl') {
  4330. return hsl2css(rgb2hsl(rgba), mode);
  4331. }
  4332. if (mode.substr(0, 3) === 'lab') {
  4333. // change to D50 lab whitepoint since this is what W3C is using for CSS Lab colors
  4334. const prevWhitePoint = getLabWhitePoint();
  4335. setLabWhitePoint('d50');
  4336. const cssColor = lab2css(rgb2lab(rgba), mode);
  4337. setLabWhitePoint(prevWhitePoint);
  4338. return cssColor;
  4339. }
  4340. if (mode.substr(0, 3) === 'lch') {
  4341. // change to D50 lab whitepoint since this is what W3C is using for CSS Lab colors
  4342. const prevWhitePoint = getLabWhitePoint();
  4343. setLabWhitePoint('d50');
  4344. const cssColor = lch2css(rgb2lch(rgba), mode);
  4345. setLabWhitePoint(prevWhitePoint);
  4346. return cssColor;
  4347. }
  4348. if (mode.substr(0, 5) === 'oklab') {
  4349. return oklab2css(rgb2oklab(rgba));
  4350. }
  4351. if (mode.substr(0, 5) === 'oklch') {
  4352. return oklch2css(rgb2oklch$1(rgba));
  4353. }
  4354. rgba[0] = round$4(rgba[0]);
  4355. rgba[1] = round$4(rgba[1]);
  4356. rgba[2] = round$4(rgba[2]);
  4357. if (mode === 'rgba' || (rgba.length > 3 && rgba[3] < 1)) {
  4358. rgba[3] = '/ ' + (rgba.length > 3 ? rgba[3] : 1);
  4359. mode = 'rgba';
  4360. }
  4361. return `${mode.substr(0, 3)}(${rgba.slice(0, mode === 'rgb' ? 3 : 4).join(' ')})`;
  4362. };
  4363.  
  4364. const hsl2rgb = (...args) => {
  4365. args = unpack(args, 'hsl');
  4366. const [h, s, l] = args;
  4367. let r, g, b;
  4368. if (s === 0) {
  4369. r = g = b = l * 255;
  4370. } else {
  4371. const t3 = [0, 0, 0];
  4372. const c = [0, 0, 0];
  4373. const t2 = l < 0.5 ? l * (1 + s) : l + s - l * s;
  4374. const t1 = 2 * l - t2;
  4375. const h_ = h / 360;
  4376. t3[0] = h_ + 1 / 3;
  4377. t3[1] = h_;
  4378. t3[2] = h_ - 1 / 3;
  4379. for (let i = 0; i < 3; i++) {
  4380. if (t3[i] < 0) t3[i] += 1;
  4381. if (t3[i] > 1) t3[i] -= 1;
  4382. if (6 * t3[i] < 1) c[i] = t1 + (t2 - t1) * 6 * t3[i];
  4383. else if (2 * t3[i] < 1) c[i] = t2;
  4384. else if (3 * t3[i] < 2) c[i] = t1 + (t2 - t1) * (2 / 3 - t3[i]) * 6;
  4385. else c[i] = t1;
  4386. }
  4387. [r, g, b] = [c[0] * 255, c[1] * 255, c[2] * 255];
  4388. }
  4389. if (args.length > 3) {
  4390. // keep alpha channel
  4391. return [r, g, b, args[3]];
  4392. }
  4393. return [r, g, b, 1];
  4394. };
  4395.  
  4396. const lch2rgb = (...args) => {
  4397. args = unpack(args, 'lch');
  4398. const [l, c, h] = args;
  4399. const [L, a, b_] = lch2lab$1(l, c, h);
  4400. const [r, g, b] = lab2rgb(L, a, b_);
  4401. return [r, g, b, args.length > 3 ? args[3] : 1];
  4402. };
  4403.  
  4404. const oklab2rgb = (...args) => {
  4405. args = unpack(args, 'lab');
  4406. const [L, a, b, ...rest] = args;
  4407. const [X, Y, Z] = OKLab_to_XYZ([L, a, b]);
  4408. const [r, g, b_] = xyz2rgb(X, Y, Z);
  4409. return [r, g, b_, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
  4410. };
  4411.  
  4412. // from https://www.w3.org/TR/css-color-4/#color-conversion-code
  4413. function OKLab_to_XYZ(OKLab) {
  4414. // Given OKLab, convert to XYZ relative to D65
  4415. var LMStoXYZ = [
  4416. [1.2268798758459243, -0.5578149944602171, 0.2813910456659647],
  4417. [-0.0405757452148008, 1.112286803280317, -0.0717110580655164],
  4418. [-0.0763729366746601, -0.4214933324022432, 1.5869240198367816]
  4419. ];
  4420. var OKLabtoLMS = [
  4421. [1.0, 0.3963377773761749, 0.2158037573099136],
  4422. [1.0, -0.1055613458156586, -0.0638541728258133],
  4423. [1.0, -0.0894841775298119, -1.2914855480194092]
  4424. ];
  4425.  
  4426. var LMSnl = multiplyMatrices(OKLabtoLMS, OKLab);
  4427. return multiplyMatrices(
  4428. LMStoXYZ,
  4429. LMSnl.map((c) => c ** 3)
  4430. );
  4431. }
  4432.  
  4433. const { sin, cos } = Math;
  4434.  
  4435. const lch2lab = (...args) => {
  4436. /*
  4437. Convert from a qualitative parameter h and a quantitative parameter l to a 24-bit pixel.
  4438. These formulas were invented by David Dalrymple to obtain maximum contrast without going
  4439. out of gamut if the parameters are in the range 0-1.
  4440.  
  4441. A saturation multiplier was added by Gregor Aisch
  4442. */
  4443. let [l, c, h] = unpack(args, 'lch');
  4444. if (isNaN(h)) h = 0;
  4445. h = h * DEG2RAD;
  4446. return [l, cos(h) * c, sin(h) * c];
  4447. };
  4448.  
  4449. const oklch2rgb$1 = (...args) => {
  4450. args = unpack(args, 'lch');
  4451. const [l, c, h, ...rest] = args;
  4452. const [L, a, b_] = lch2lab(l, c, h);
  4453. const [r, g, b] = oklab2rgb(L, a, b_);
  4454. return [r, g, b, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
  4455. };
  4456.  
  4457. const { min, max } = Math;
  4458.  
  4459. var limit = (x, low = 0, high = 1) => {
  4460. return min(max(low, x), high);
  4461. };
  4462.  
  4463. const INT_OR_PCT = /((?:-?\d+)|(?:-?\d+(?:\.\d+)?)%|none)/.source;
  4464. const FLOAT_OR_PCT = /((?:-?(?:\d+(?:\.\d*)?|\.\d+)%?)|none)/.source;
  4465. const PCT = /((?:-?(?:\d+(?:\.\d*)?|\.\d+)%)|none)/.source;
  4466. const RE_S = /\s*/.source;
  4467. const SEP = /\s+/.source;
  4468. const COMMA = /\s*,\s*/.source;
  4469. const ANLGE = /((?:-?(?:\d+(?:\.\d*)?|\.\d+)(?:deg)?)|none)/.source;
  4470. const ALPHA = /\s*(?:\/\s*((?:[01]|[01]?\.\d+)|\d+(?:\.\d+)?%))?/.source;
  4471.  
  4472. // e.g. rgb(250 20 0), rgb(100% 50% 20%), rgb(100% 50% 20% / 0.5)
  4473. const RE_RGB = new RegExp(
  4474. '^rgba?\\(' +
  4475. RE_S +
  4476. [INT_OR_PCT, INT_OR_PCT, INT_OR_PCT].join(SEP) +
  4477. ALPHA +
  4478. '\\)$'
  4479. );
  4480. const RE_RGB_LEGACY = new RegExp(
  4481. '^rgb\\(' +
  4482. RE_S +
  4483. [INT_OR_PCT, INT_OR_PCT, INT_OR_PCT].join(COMMA) +
  4484. RE_S +
  4485. '\\)$'
  4486. );
  4487. const RE_RGBA_LEGACY = new RegExp(
  4488. '^rgba\\(' +
  4489. RE_S +
  4490. [INT_OR_PCT, INT_OR_PCT, INT_OR_PCT, FLOAT_OR_PCT].join(COMMA) +
  4491. RE_S +
  4492. '\\)$'
  4493. );
  4494.  
  4495. const RE_HSL = new RegExp(
  4496. '^hsla?\\(' + RE_S + [ANLGE, PCT, PCT].join(SEP) + ALPHA + '\\)$'
  4497. );
  4498. const RE_HSL_LEGACY = new RegExp(
  4499. '^hsl?\\(' + RE_S + [ANLGE, PCT, PCT].join(COMMA) + RE_S + '\\)$'
  4500. );
  4501. const RE_HSLA_LEGACY =
  4502. /^hsla\(\s*(-?\d+(?:\.\d+)?),\s*(-?\d+(?:\.\d+)?)%\s*,\s*(-?\d+(?:\.\d+)?)%\s*,\s*([01]|[01]?\.\d+)\)$/;
  4503.  
  4504. const RE_LAB = new RegExp(
  4505. '^lab\\(' +
  4506. RE_S +
  4507. [FLOAT_OR_PCT, FLOAT_OR_PCT, FLOAT_OR_PCT].join(SEP) +
  4508. ALPHA +
  4509. '\\)$'
  4510. );
  4511. const RE_LCH = new RegExp(
  4512. '^lch\\(' +
  4513. RE_S +
  4514. [FLOAT_OR_PCT, FLOAT_OR_PCT, ANLGE].join(SEP) +
  4515. ALPHA +
  4516. '\\)$'
  4517. );
  4518. const RE_OKLAB = new RegExp(
  4519. '^oklab\\(' +
  4520. RE_S +
  4521. [FLOAT_OR_PCT, FLOAT_OR_PCT, FLOAT_OR_PCT].join(SEP) +
  4522. ALPHA +
  4523. '\\)$'
  4524. );
  4525. const RE_OKLCH = new RegExp(
  4526. '^oklch\\(' +
  4527. RE_S +
  4528. [FLOAT_OR_PCT, FLOAT_OR_PCT, ANLGE].join(SEP) +
  4529. ALPHA +
  4530. '\\)$'
  4531. );
  4532.  
  4533. const { round: round$3 } = Math;
  4534.  
  4535. const roundRGB = (rgb) => {
  4536. return rgb.map((v, i) => (i <= 2 ? limit(round$3(v), 0, 255) : v));
  4537. };
  4538.  
  4539. const percentToAbsolute = (pct, min = 0, max = 100, signed = false) => {
  4540. if (typeof pct === 'string' && pct.endsWith('%')) {
  4541. pct = parseFloat(pct.substring(0, pct.length - 1)) / 100;
  4542. if (signed) {
  4543. // signed percentages are in the range -100% to 100%
  4544. pct = min + (pct + 1) * 0.5 * (max - min);
  4545. } else {
  4546. pct = min + pct * (max - min);
  4547. }
  4548. }
  4549. return +pct;
  4550. };
  4551.  
  4552. const noneToValue = (v, noneValue) => {
  4553. return v === 'none' ? noneValue : v;
  4554. };
  4555.  
  4556. const css2rgb = (css) => {
  4557. css = css.toLowerCase().trim();
  4558.  
  4559. if (css === 'transparent') {
  4560. return [0, 0, 0, 0];
  4561. }
  4562.  
  4563. let m;
  4564.  
  4565. if (input$1.format.named) {
  4566. try {
  4567. return input$1.format.named(css);
  4568. // eslint-disable-next-line
  4569. } catch (e) {}
  4570. }
  4571.  
  4572. // rgb(250 20 0) or rgb(250,20,0)
  4573. if ((m = css.match(RE_RGB)) || (m = css.match(RE_RGB_LEGACY))) {
  4574. let rgb = m.slice(1, 4);
  4575. for (let i = 0; i < 3; i++) {
  4576. rgb[i] = +percentToAbsolute(noneToValue(rgb[i], 0), 0, 255);
  4577. }
  4578. rgb = roundRGB(rgb);
  4579. const alpha = m[4] !== undefined ? +percentToAbsolute(m[4], 0, 1) : 1;
  4580. rgb[3] = alpha; // default alpha
  4581. return rgb;
  4582. }
  4583.  
  4584. // rgba(250,20,0,0.4)
  4585. if ((m = css.match(RE_RGBA_LEGACY))) {
  4586. const rgb = m.slice(1, 5);
  4587. for (let i = 0; i < 4; i++) {
  4588. rgb[i] = +percentToAbsolute(rgb[i], 0, 255);
  4589. }
  4590. return rgb;
  4591. }
  4592.  
  4593. // hsl(0,100%,50%)
  4594. if ((m = css.match(RE_HSL)) || (m = css.match(RE_HSL_LEGACY))) {
  4595. const hsl = m.slice(1, 4);
  4596. hsl[0] = +noneToValue(hsl[0].replace('deg', ''), 0);
  4597. hsl[1] = +percentToAbsolute(noneToValue(hsl[1], 0), 0, 100) * 0.01;
  4598. hsl[2] = +percentToAbsolute(noneToValue(hsl[2], 0), 0, 100) * 0.01;
  4599. const rgb = roundRGB(hsl2rgb(hsl));
  4600. const alpha = m[4] !== undefined ? +percentToAbsolute(m[4], 0, 1) : 1;
  4601. rgb[3] = alpha;
  4602. return rgb;
  4603. }
  4604.  
  4605. // hsla(0,100%,50%,0.5)
  4606. if ((m = css.match(RE_HSLA_LEGACY))) {
  4607. const hsl = m.slice(1, 4);
  4608. hsl[1] *= 0.01;
  4609. hsl[2] *= 0.01;
  4610. const rgb = hsl2rgb(hsl);
  4611. for (let i = 0; i < 3; i++) {
  4612. rgb[i] = round$3(rgb[i]);
  4613. }
  4614. rgb[3] = +m[4]; // default alpha = 1
  4615. return rgb;
  4616. }
  4617.  
  4618. if ((m = css.match(RE_LAB))) {
  4619. const lab = m.slice(1, 4);
  4620. lab[0] = percentToAbsolute(noneToValue(lab[0], 0), 0, 100);
  4621. lab[1] = percentToAbsolute(noneToValue(lab[1], 0), -125, 125, true);
  4622. lab[2] = percentToAbsolute(noneToValue(lab[2], 0), -125, 125, true);
  4623. // convert to D50 Lab whitepoint
  4624. const wp = getLabWhitePoint();
  4625. setLabWhitePoint('d50');
  4626. const rgb = roundRGB(lab2rgb(lab));
  4627. // convert back to original Lab whitepoint
  4628. setLabWhitePoint(wp);
  4629. const alpha = m[4] !== undefined ? +percentToAbsolute(m[4], 0, 1) : 1;
  4630. rgb[3] = alpha;
  4631. return rgb;
  4632. }
  4633.  
  4634. if ((m = css.match(RE_LCH))) {
  4635. const lch = m.slice(1, 4);
  4636. lch[0] = percentToAbsolute(lch[0], 0, 100);
  4637. lch[1] = percentToAbsolute(noneToValue(lch[1], 0), 0, 150, false);
  4638. lch[2] = +noneToValue(lch[2].replace('deg', ''), 0);
  4639. // convert to D50 Lab whitepoint
  4640. const wp = getLabWhitePoint();
  4641. setLabWhitePoint('d50');
  4642. const rgb = roundRGB(lch2rgb(lch));
  4643. // convert back to original Lab whitepoint
  4644. setLabWhitePoint(wp);
  4645. const alpha = m[4] !== undefined ? +percentToAbsolute(m[4], 0, 1) : 1;
  4646. rgb[3] = alpha;
  4647. return rgb;
  4648. }
  4649.  
  4650. if ((m = css.match(RE_OKLAB))) {
  4651. const oklab = m.slice(1, 4);
  4652. oklab[0] = percentToAbsolute(noneToValue(oklab[0], 0), 0, 1);
  4653. oklab[1] = percentToAbsolute(noneToValue(oklab[1], 0), -0.4, 0.4, true);
  4654. oklab[2] = percentToAbsolute(noneToValue(oklab[2], 0), -0.4, 0.4, true);
  4655. const rgb = roundRGB(oklab2rgb(oklab));
  4656. const alpha = m[4] !== undefined ? +percentToAbsolute(m[4], 0, 1) : 1;
  4657. rgb[3] = alpha;
  4658. return rgb;
  4659. }
  4660.  
  4661. if ((m = css.match(RE_OKLCH))) {
  4662. const oklch = m.slice(1, 4);
  4663. oklch[0] = percentToAbsolute(noneToValue(oklch[0], 0), 0, 1);
  4664. oklch[1] = percentToAbsolute(noneToValue(oklch[1], 0), 0, 0.4, false);
  4665. oklch[2] = +noneToValue(oklch[2].replace('deg', ''), 0);
  4666. const rgb = roundRGB(oklch2rgb$1(oklch));
  4667. const alpha = m[4] !== undefined ? +percentToAbsolute(m[4], 0, 1) : 1;
  4668. rgb[3] = alpha;
  4669. return rgb;
  4670. }
  4671. };
  4672.  
  4673. css2rgb.test = (s) => {
  4674. return (
  4675. // modern
  4676. RE_RGB.test(s) ||
  4677. RE_HSL.test(s) ||
  4678. RE_LAB.test(s) ||
  4679. RE_LCH.test(s) ||
  4680. RE_OKLAB.test(s) ||
  4681. RE_OKLCH.test(s) ||
  4682. // legacy
  4683. RE_RGB_LEGACY.test(s) ||
  4684. RE_RGBA_LEGACY.test(s) ||
  4685. RE_HSL_LEGACY.test(s) ||
  4686. RE_HSLA_LEGACY.test(s) ||
  4687. s === 'transparent'
  4688. );
  4689. };
  4690.  
  4691. Color$2.prototype.css = function (mode) {
  4692. return rgb2css(this._rgb, mode);
  4693. };
  4694.  
  4695. const css = (...args) => new Color$2(...args, 'css');
  4696. chroma$1.css = css;
  4697.  
  4698. input$1.format.css = css2rgb;
  4699.  
  4700. input$1.autodetect.push({
  4701. p: 5,
  4702. test: (h, ...rest) => {
  4703. if (!rest.length && type(h) === 'string' && css2rgb.test(h)) {
  4704. return 'css';
  4705. }
  4706. }
  4707. });
  4708.  
  4709. input$1.format.gl = (...args) => {
  4710. const rgb = unpack(args, 'rgba');
  4711. rgb[0] *= 255;
  4712. rgb[1] *= 255;
  4713. rgb[2] *= 255;
  4714. return rgb;
  4715. };
  4716.  
  4717. const gl = (...args) => new Color$2(...args, 'gl');
  4718. chroma$1.gl = gl;
  4719.  
  4720. Color$2.prototype.gl = function () {
  4721. const rgb = this._rgb;
  4722. return [rgb[0] / 255, rgb[1] / 255, rgb[2] / 255, rgb[3]];
  4723. };
  4724.  
  4725. Color$2.prototype.hcg = function () {
  4726. return rgb2hcg(this._rgb);
  4727. };
  4728.  
  4729. const hcg = (...args) => new Color$2(...args, 'hcg');
  4730. chroma$1.hcg = hcg;
  4731.  
  4732. input$1.format.hcg = hcg2rgb;
  4733.  
  4734. input$1.autodetect.push({
  4735. p: 1,
  4736. test: (...args) => {
  4737. args = unpack(args, 'hcg');
  4738. if (type(args) === 'array' && args.length === 3) {
  4739. return 'hcg';
  4740. }
  4741. }
  4742. });
  4743.  
  4744. const RE_HEX = /^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/;
  4745. const RE_HEXA = /^#?([A-Fa-f0-9]{8}|[A-Fa-f0-9]{4})$/;
  4746.  
  4747. const hex2rgb = (hex) => {
  4748. if (hex.match(RE_HEX)) {
  4749. // remove optional leading #
  4750. if (hex.length === 4 || hex.length === 7) {
  4751. hex = hex.substr(1);
  4752. }
  4753. // expand short-notation to full six-digit
  4754. if (hex.length === 3) {
  4755. hex = hex.split('');
  4756. hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
  4757. }
  4758. const u = parseInt(hex, 16);
  4759. const r = u >> 16;
  4760. const g = (u >> 8) & 0xff;
  4761. const b = u & 0xff;
  4762. return [r, g, b, 1];
  4763. }
  4764.  
  4765. // match rgba hex format, eg #FF000077
  4766. if (hex.match(RE_HEXA)) {
  4767. if (hex.length === 5 || hex.length === 9) {
  4768. // remove optional leading #
  4769. hex = hex.substr(1);
  4770. }
  4771. // expand short-notation to full eight-digit
  4772. if (hex.length === 4) {
  4773. hex = hex.split('');
  4774. hex =
  4775. hex[0] +
  4776. hex[0] +
  4777. hex[1] +
  4778. hex[1] +
  4779. hex[2] +
  4780. hex[2] +
  4781. hex[3] +
  4782. hex[3];
  4783. }
  4784. const u = parseInt(hex, 16);
  4785. const r = (u >> 24) & 0xff;
  4786. const g = (u >> 16) & 0xff;
  4787. const b = (u >> 8) & 0xff;
  4788. const a = Math.round(((u & 0xff) / 0xff) * 100) / 100;
  4789. return [r, g, b, a];
  4790. }
  4791.  
  4792. // we used to check for css colors here
  4793. // if _input.css? and rgb = _input.css hex
  4794. // return rgb
  4795.  
  4796. throw new Error(`unknown hex color: ${hex}`);
  4797. };
  4798.  
  4799. const { round: round$2 } = Math;
  4800.  
  4801. const rgb2hex = (...args) => {
  4802. let [r, g, b, a] = unpack(args, 'rgba');
  4803. let mode = last(args) || 'auto';
  4804. if (a === undefined) a = 1;
  4805. if (mode === 'auto') {
  4806. mode = a < 1 ? 'rgba' : 'rgb';
  4807. }
  4808. r = round$2(r);
  4809. g = round$2(g);
  4810. b = round$2(b);
  4811. const u = (r << 16) | (g << 8) | b;
  4812. let str = '000000' + u.toString(16); //#.toUpperCase();
  4813. str = str.substr(str.length - 6);
  4814. let hxa = '0' + round$2(a * 255).toString(16);
  4815. hxa = hxa.substr(hxa.length - 2);
  4816. switch (mode.toLowerCase()) {
  4817. case 'rgba':
  4818. return `#${str}${hxa}`;
  4819. case 'argb':
  4820. return `#${hxa}${str}`;
  4821. default:
  4822. return `#${str}`;
  4823. }
  4824. };
  4825.  
  4826. Color$2.prototype.hex = function (mode) {
  4827. return rgb2hex(this._rgb, mode);
  4828. };
  4829.  
  4830. const hex = (...args) => new Color$2(...args, 'hex');
  4831. chroma$1.hex = hex;
  4832.  
  4833. input$1.format.hex = hex2rgb;
  4834. input$1.autodetect.push({
  4835. p: 4,
  4836. test: (h, ...rest) => {
  4837. if (
  4838. !rest.length &&
  4839. type(h) === 'string' &&
  4840. [3, 4, 5, 6, 7, 8, 9].indexOf(h.length) >= 0
  4841. ) {
  4842. return 'hex';
  4843. }
  4844. }
  4845. });
  4846.  
  4847. Color$2.prototype.hsi = function () {
  4848. return rgb2hsi(this._rgb);
  4849. };
  4850.  
  4851. const hsi = (...args) => new Color$2(...args, 'hsi');
  4852. chroma$1.hsi = hsi;
  4853.  
  4854. input$1.format.hsi = hsi2rgb;
  4855.  
  4856. input$1.autodetect.push({
  4857. p: 2,
  4858. test: (...args) => {
  4859. args = unpack(args, 'hsi');
  4860. if (type(args) === 'array' && args.length === 3) {
  4861. return 'hsi';
  4862. }
  4863. }
  4864. });
  4865.  
  4866. Color$2.prototype.hsl = function () {
  4867. return rgb2hsl$2(this._rgb);
  4868. };
  4869.  
  4870. const hsl = (...args) => new Color$2(...args, 'hsl');
  4871. chroma$1.hsl = hsl;
  4872.  
  4873. input$1.format.hsl = hsl2rgb$1;
  4874.  
  4875. input$1.autodetect.push({
  4876. p: 2,
  4877. test: (...args) => {
  4878. args = unpack(args, 'hsl');
  4879. if (type(args) === 'array' && args.length === 3) {
  4880. return 'hsl';
  4881. }
  4882. }
  4883. });
  4884.  
  4885. Color$2.prototype.hsv = function () {
  4886. return rgb2hsl$1(this._rgb);
  4887. };
  4888.  
  4889. const hsv = (...args) => new Color$2(...args, 'hsv');
  4890. chroma$1.hsv = hsv;
  4891.  
  4892. input$1.format.hsv = hsv2rgb;
  4893.  
  4894. input$1.autodetect.push({
  4895. p: 2,
  4896. test: (...args) => {
  4897. args = unpack(args, 'hsv');
  4898. if (type(args) === 'array' && args.length === 3) {
  4899. return 'hsv';
  4900. }
  4901. }
  4902. });
  4903.  
  4904. Color$2.prototype.lab = function () {
  4905. return rgb2lab$1(this._rgb);
  4906. };
  4907.  
  4908. const lab = (...args) => new Color$2(...args, 'lab');
  4909. Object.assign(chroma$1, { lab, getLabWhitePoint: getLabWhitePoint$1, setLabWhitePoint: setLabWhitePoint$1 });
  4910.  
  4911. input$1.format.lab = lab2rgb$1;
  4912.  
  4913. input$1.autodetect.push({
  4914. p: 2,
  4915. test: (...args) => {
  4916. args = unpack(args, 'lab');
  4917. if (type(args) === 'array' && args.length === 3) {
  4918. return 'lab';
  4919. }
  4920. }
  4921. });
  4922.  
  4923. Color$2.prototype.lch = function () {
  4924. return rgb2lch$1(this._rgb);
  4925. };
  4926. Color$2.prototype.hcl = function () {
  4927. return reverse3(rgb2lch$1(this._rgb));
  4928. };
  4929.  
  4930. const lch = (...args) => new Color$2(...args, 'lch');
  4931. const hcl = (...args) => new Color$2(...args, 'hcl');
  4932.  
  4933. Object.assign(chroma$1, { lch, hcl });
  4934.  
  4935. input$1.format.lch = lch2rgb$1;
  4936. input$1.format.hcl = hcl2rgb;
  4937. ['lch', 'hcl'].forEach((m) =>
  4938. input$1.autodetect.push({
  4939. p: 2,
  4940. test: (...args) => {
  4941. args = unpack(args, m);
  4942. if (type(args) === 'array' && args.length === 3) {
  4943. return m;
  4944. }
  4945. }
  4946. })
  4947. );
  4948.  
  4949. Color$2.prototype.num = function () {
  4950. return rgb2num(this._rgb);
  4951. };
  4952.  
  4953. const num = (...args) => new Color$2(...args, 'num');
  4954.  
  4955. Object.assign(chroma$1, { num });
  4956.  
  4957. input$1.format.num = num2rgb;
  4958.  
  4959. input$1.autodetect.push({
  4960. p: 5,
  4961. test: (...args) => {
  4962. if (
  4963. args.length === 1 &&
  4964. type(args[0]) === 'number' &&
  4965. args[0] >= 0 &&
  4966. args[0] <= 0xffffff
  4967. ) {
  4968. return 'num';
  4969. }
  4970. }
  4971. });
  4972.  
  4973. const { round: round$1 } = Math;
  4974.  
  4975. Color$2.prototype.rgb = function (rnd = true) {
  4976. if (rnd === false) return this._rgb.slice(0, 3);
  4977. return this._rgb.slice(0, 3).map(round$1);
  4978. };
  4979.  
  4980. Color$2.prototype.rgba = function (rnd = true) {
  4981. return this._rgb.slice(0, 4).map((v, i) => {
  4982. return i < 3 ? (rnd === false ? v : round$1(v)) : v;
  4983. });
  4984. };
  4985.  
  4986. const rgb = (...args) => new Color$2(...args, 'rgb');
  4987. Object.assign(chroma$1, { rgb });
  4988.  
  4989. input$1.format.rgb = (...args) => {
  4990. const rgba = unpack(args, 'rgba');
  4991. if (rgba[3] === undefined) rgba[3] = 1;
  4992. return rgba;
  4993. };
  4994.  
  4995. input$1.autodetect.push({
  4996. p: 3,
  4997. test: (...args) => {
  4998. args = unpack(args, 'rgba');
  4999. if (
  5000. type(args) === 'array' &&
  5001. (args.length === 3 ||
  5002. (args.length === 4 &&
  5003. type(args[3]) == 'number' &&
  5004. args[3] >= 0 &&
  5005. args[3] <= 1))
  5006. ) {
  5007. return 'rgb';
  5008. }
  5009. }
  5010. });
  5011.  
  5012. /*
  5013. * Based on implementation by Neil Bartlett
  5014. * https://github.com/neilbartlett/color-temperature
  5015. */
  5016.  
  5017. const { log } = Math;
  5018.  
  5019. const temperature2rgb = (kelvin) => {
  5020. const temp = kelvin / 100;
  5021. let r, g, b;
  5022. if (temp < 66) {
  5023. r = 255;
  5024. g =
  5025. temp < 6
  5026. ? 0
  5027. : -155.25485562709179 -
  5028. 0.44596950469579133 * (g = temp - 2) +
  5029. 104.49216199393888 * log(g);
  5030. b =
  5031. temp < 20
  5032. ? 0
  5033. : -254.76935184120902 +
  5034. 0.8274096064007395 * (b = temp - 10) +
  5035. 115.67994401066147 * log(b);
  5036. } else {
  5037. r =
  5038. 351.97690566805693 +
  5039. 0.114206453784165 * (r = temp - 55) -
  5040. 40.25366309332127 * log(r);
  5041. g =
  5042. 325.4494125711974 +
  5043. 0.07943456536662342 * (g = temp - 50) -
  5044. 28.0852963507957 * log(g);
  5045. b = 255;
  5046. }
  5047. return [r, g, b, 1];
  5048. };
  5049.  
  5050. /*
  5051. * Based on implementation by Neil Bartlett
  5052. * https://github.com/neilbartlett/color-temperature
  5053. **/
  5054.  
  5055. const { round } = Math;
  5056.  
  5057. const rgb2temperature = (...args) => {
  5058. const rgb = unpack(args, 'rgb');
  5059. const r = rgb[0],
  5060. b = rgb[2];
  5061. let minTemp = 1000;
  5062. let maxTemp = 40000;
  5063. const eps = 0.4;
  5064. let temp;
  5065. while (maxTemp - minTemp > eps) {
  5066. temp = (maxTemp + minTemp) * 0.5;
  5067. const rgb = temperature2rgb(temp);
  5068. if (rgb[2] / rgb[0] >= b / r) {
  5069. maxTemp = temp;
  5070. } else {
  5071. minTemp = temp;
  5072. }
  5073. }
  5074. return round(temp);
  5075. };
  5076.  
  5077. Color$2.prototype.temp =
  5078. Color$2.prototype.kelvin =
  5079. Color$2.prototype.temperature =
  5080. function () {
  5081. return rgb2temperature(this._rgb);
  5082. };
  5083.  
  5084. const temp = (...args) => new Color$2(...args, 'temp');
  5085. Object.assign(chroma$1, { temp, kelvin: temp, temperature: temp });
  5086.  
  5087. input$1.format.temp =
  5088. input$1.format.kelvin =
  5089. input$1.format.temperature =
  5090. temperature2rgb;
  5091.  
  5092. Color$2.prototype.oklab = function () {
  5093. return rgb2oklab$1(this._rgb);
  5094. };
  5095.  
  5096. const oklab = (...args) => new Color$2(...args, 'oklab');
  5097. Object.assign(chroma$1, { oklab });
  5098.  
  5099. input$1.format.oklab = oklab2rgb$1;
  5100.  
  5101. input$1.autodetect.push({
  5102. p: 2,
  5103. test: (...args) => {
  5104. args = unpack(args, 'oklab');
  5105. if (type(args) === 'array' && args.length === 3) {
  5106. return 'oklab';
  5107. }
  5108. }
  5109. });
  5110.  
  5111. const oklch2rgb = (...args) => {
  5112. args = unpack(args, 'lch');
  5113. const [l, c, h, ...rest] = args;
  5114. const [L, a, b_] = lch2lab(l, c, h);
  5115. const [r, g, b] = oklab2rgb(L, a, b_);
  5116. return [r, g, b, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
  5117. };
  5118.  
  5119. const rgb2oklch = (...args) => {
  5120. const [r, g, b, ...rest] = unpack(args, 'rgb');
  5121. const [l, a, b_] = rgb2oklab(r, g, b);
  5122. const [L, c, h] = lab2lch(l, a, b_);
  5123. return [L, c, h, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
  5124. };
  5125.  
  5126. Color$2.prototype.oklch = function () {
  5127. return rgb2oklch(this._rgb);
  5128. };
  5129.  
  5130. const oklch = (...args) => new Color$2(...args, 'oklch');
  5131. Object.assign(chroma$1, { oklch });
  5132.  
  5133. input$1.format.oklch = oklch2rgb;
  5134.  
  5135. input$1.autodetect.push({
  5136. p: 2,
  5137. test: (...args) => {
  5138. args = unpack(args, 'oklch');
  5139. if (type(args) === 'array' && args.length === 3) {
  5140. return 'oklch';
  5141. }
  5142. }
  5143. });
  5144.  
  5145. // feel free to comment out anything to rollup
  5146. // a smaller chroma.js bundle
  5147.  
  5148. Object.assign(chroma$2, {
  5149. analyze,
  5150. average,
  5151. bezier: bezier$1,
  5152. blend,
  5153. brewer: colorbrewerProxy,
  5154. Color,
  5155. colors: w3cx11,
  5156. contrast,
  5157. contrastAPCA,
  5158. cubehelix,
  5159. deltaE,
  5160. distance,
  5161. input,
  5162. interpolate: mix,
  5163. limits,
  5164. mix,
  5165. random: random$1,
  5166. scale: scale$1,
  5167. scales,
  5168. valid
  5169. });
  5170.  
  5171. exports.Color = Color;
  5172. exports.analyze = analyze;
  5173. exports.average = average;
  5174. exports.bezier = bezier$1;
  5175. exports.blend = blend;
  5176. exports.brewer = colorbrewerProxy;
  5177. exports.cmyk = cmyk;
  5178. exports.colors = w3cx11;
  5179. exports.contrast = contrast;
  5180. exports.contrastAPCA = contrastAPCA;
  5181. exports.css = css;
  5182. exports.cubehelix = cubehelix;
  5183. exports.default = chroma$2;
  5184. exports.deltaE = deltaE;
  5185. exports.distance = distance;
  5186. exports.getLabWhitePoint = getLabWhitePoint$1;
  5187. exports.gl = gl;
  5188. exports.hcg = hcg;
  5189. exports.hcl = hcl;
  5190. exports.hex = hex;
  5191. exports.hsi = hsi;
  5192. exports.hsl = hsl;
  5193. exports.hsv = hsv;
  5194. exports.input = input;
  5195. exports.interpolate = mix;
  5196. exports.kelvin = temp;
  5197. exports.lab = lab;
  5198. exports.lch = lch;
  5199. exports.limits = limits;
  5200. exports.mix = mix;
  5201. exports.num = num;
  5202. exports.oklab = oklab;
  5203. exports.oklch = oklch;
  5204. exports.random = random$1;
  5205. exports.rgb = rgb;
  5206. exports.scale = scale$1;
  5207. exports.scales = scales;
  5208. exports.setLabWhitePoint = setLabWhitePoint$1;
  5209. exports.temp = temp;
  5210. exports.temperature = temp;
  5211. exports.valid = valid;
  5212. }));