@decidables/detectable-elements 0.4.5 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2376,13 +2376,13 @@ function define (constructor, factory, prototype) {
2376
2376
  constructor.prototype = factory.prototype = prototype;
2377
2377
  prototype.constructor = constructor;
2378
2378
  }
2379
- function extend(parent, definition) {
2379
+ function extend$1(parent, definition) {
2380
2380
  var prototype = Object.create(parent.prototype);
2381
2381
  for (var key in definition) prototype[key] = definition[key];
2382
2382
  return prototype;
2383
2383
  }
2384
2384
 
2385
- function Color() {}
2385
+ function Color$1() {}
2386
2386
  var darker = 0.7;
2387
2387
  var brighter = 1 / darker;
2388
2388
  var reI = "\\s*([+-]?\\d+)\\s*",
@@ -2545,7 +2545,7 @@ var named = {
2545
2545
  yellow: 0xffff00,
2546
2546
  yellowgreen: 0x9acd32
2547
2547
  };
2548
- define(Color, color, {
2548
+ define(Color$1, color, {
2549
2549
  copy(channels) {
2550
2550
  return Object.assign(new this.constructor(), this, channels);
2551
2551
  },
@@ -2597,7 +2597,7 @@ function rgba(r, g, b, a) {
2597
2597
  return new Rgb(r, g, b, a);
2598
2598
  }
2599
2599
  function rgbConvert(o) {
2600
- if (!(o instanceof Color)) o = color(o);
2600
+ if (!(o instanceof Color$1)) o = color(o);
2601
2601
  if (!o) return new Rgb();
2602
2602
  o = o.rgb();
2603
2603
  return new Rgb(o.r, o.g, o.b, o.opacity);
@@ -2611,7 +2611,7 @@ function Rgb(r, g, b, opacity) {
2611
2611
  this.b = +b;
2612
2612
  this.opacity = +opacity;
2613
2613
  }
2614
- define(Rgb, rgb, extend(Color, {
2614
+ define(Rgb, rgb, extend$1(Color$1, {
2615
2615
  brighter(k) {
2616
2616
  k = k == null ? brighter : Math.pow(brighter, k);
2617
2617
  return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
@@ -2662,7 +2662,7 @@ function hsla(h, s, l, a) {
2662
2662
  }
2663
2663
  function hslConvert(o) {
2664
2664
  if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity);
2665
- if (!(o instanceof Color)) o = color(o);
2665
+ if (!(o instanceof Color$1)) o = color(o);
2666
2666
  if (!o) return new Hsl();
2667
2667
  if (o instanceof Hsl) return o;
2668
2668
  o = o.rgb();
@@ -2692,7 +2692,7 @@ function Hsl(h, s, l, opacity) {
2692
2692
  this.l = +l;
2693
2693
  this.opacity = +opacity;
2694
2694
  }
2695
- define(Hsl, hsl, extend(Color, {
2695
+ define(Hsl, hsl, extend$1(Color$1, {
2696
2696
  brighter(k) {
2697
2697
  k = k == null ? brighter : Math.pow(brighter, k);
2698
2698
  return new Hsl(this.h, this.s, this.l * k, this.opacity);
@@ -4793,8 +4793,8 @@ function clipRejoin (segments, compareIntersection, startInside, interpolate, st
4793
4793
  });
4794
4794
  if (!subject.length) return;
4795
4795
  clip.sort(compareIntersection);
4796
- link(subject);
4797
- link(clip);
4796
+ link$1(subject);
4797
+ link$1(clip);
4798
4798
  for (i = 0, n = clip.length; i < n; ++i) {
4799
4799
  clip[i].e = startInside = !startInside;
4800
4800
  }
@@ -4833,7 +4833,7 @@ function clipRejoin (segments, compareIntersection, startInside, interpolate, st
4833
4833
  stream.lineEnd();
4834
4834
  }
4835
4835
  }
4836
- function link(array) {
4836
+ function link$1(array) {
4837
4837
  if (!(n = array.length)) return;
4838
4838
  var n,
4839
4839
  i = 0,
@@ -6124,54 +6124,12 @@ class DecidablesElement extends i {
6124
6124
  const ambientS = rotate ? `${-ambientM.y}px ${ambientM.y / 2}px ${ambientM.b}px ${ambientM.s}px` : `${ambientM.y / 2}px ${ambientM.y}px ${ambientM.b}px ${ambientM.s}px`;
6125
6125
  return `${umbraS} ${umbraC}, ${penumbraS} ${penumbraC}, ${ambientS} ${ambientC}`;
6126
6126
  }
6127
- static get svgDefs() {
6128
- const shadows = DecidablesElement.shadows; /* eslint-disable-line prefer-destructuring */
6129
-
6130
- const filters = shadows.elevations.map(z => {
6131
- return `
6132
- <filter id=${`shadow-${z}`} filterUnits="userSpaceOnUse" x="-100%" y="-100%" width="200%" height="200%">
6133
- <feComponentTransfer in="SourceAlpha" result="solid">
6134
- <feFuncA type="table" tableValues="0 1 1"/>
6135
- </feComponentTransfer>
6136
- <feOffset in="solid" result="offU" dx=${shadows.mapUmbra[z].y / 2} dy=${shadows.mapUmbra[z].y} />
6137
- <feOffset in="solid" result="offP" dx=${shadows.mapPenumbra[z].y / 2} dy=${shadows.mapPenumbra[z].y} />
6138
- <feOffset in="solid" result="offA" dx=${shadows.mapAmbient[z].y / 2} dy=${shadows.mapAmbient[z].y} />
6139
- ${shadows.mapUmbra[z].s === 0 ? '' : `<feMorphology in="offU" result="spreadU" operator=${shadows.mapUmbra[z].s > 0 ? 'dilate' : 'erode'} radius=${Math.abs(shadows.mapUmbra[z].s)} />`}
6140
- ${shadows.mapPenumbra[z].s === 0 ? '' : `<feMorphology in="offP" result="spreadP" operator=${shadows.mapPenumbra[z].s > 0 ? 'dilate' : 'erode'} radius=${Math.abs(shadows.mapPenumbra[z].s)} />`}
6141
- ${shadows.mapAmbient[z].s === 0 ? '' : `<feMorphology in="offA" result="spreadA" operator=${shadows.mapAmbient[z].s > 0 ? 'dilate' : 'erode'} radius=${Math.abs(shadows.mapAmbient[z].s)} />`}
6142
- <feGaussianBlur in=${shadows.mapUmbra[z].s === 0 ? 'offU' : 'spreadU'} result="blurU" stdDeviation=${shadows.mapUmbra[z].b / 2} />
6143
- <feGaussianBlur in=${shadows.mapPenumbra[z].s === 0 ? 'offP' : 'spreadP'} result="blurP" stdDeviation=${shadows.mapPenumbra[z].b / 2} />
6144
- <feGaussianBlur in=${shadows.mapAmbient[z].s === 0 ? 'offA' : 'spreadA'} result="blurA" stdDeviation=${shadows.mapAmbient[z].b / 2} />
6145
- <feFlood in="SourceGraphic" result="opU" flood-color=${shadows.baselineColor} flood-opacity=${shadows.opacityUmbra + shadows.opacityBoost} />
6146
- <feFlood in="SourceGraphic" result="opP" flood-color=${shadows.baselineColor} flood-opacity=${shadows.opacityPenumbra + shadows.opacityBoost} />
6147
- <feFlood in="SourceGraphic" result="opA" flood-color=${shadows.baselineColor} flood-opacity=${shadows.opacityAmbient + shadows.opacityBoost} />
6148
- <feComposite in="opU" in2="blurU" result="shU" operator="in" />
6149
- <feComposite in="opP" in2="blurP" result="shP" operator="in" />
6150
- <feComposite in="opA" in2="blurA" result="shA" operator="in" />
6151
- <feMorphology in="solid" result="smaller" operator="erode" radius="1" />
6152
- <feComposite in="shU" in2="smaller" result="finalU" operator="out" />
6153
- <feComposite in="shP" in2="smaller" result="finalP" operator="out" />
6154
- <feComposite in="shA" in2="smaller" result="finalA" operator="out" />
6155
- <feMerge>
6156
- <feMergeNode in="finalU" />
6157
- <feMergeNode in="finalP" />
6158
- <feMergeNode in="finalA" />
6159
- <feMergeNode in="SourceGraphic" />
6160
- </feMerge>
6161
- </filter>`;
6162
- });
6163
- return `
6164
- <defs>
6165
- ${filters}
6166
- </defs>
6167
- `;
6168
- }
6169
6127
  static get svgFilters() {
6170
6128
  const shadows = DecidablesElement.shadows; /* eslint-disable-line prefer-destructuring */
6171
6129
 
6172
6130
  const filters = shadows.elevations.map(z => {
6173
6131
  return b`
6174
- <filter id=${`shadow-${z}`} x="-250%" y="-250%" width="600%" height="600%">
6132
+ <filter id=${`shadow-${z}`} filterUnits="userSpaceOnUse" x="-100%" y="-100%" width="200%" height="200%">
6175
6133
  <feComponentTransfer in="SourceAlpha" result="solid">
6176
6134
  <feFuncA type="table" tableValues="0 1 1"/>
6177
6135
  </feComponentTransfer>
@@ -6203,11 +6161,9 @@ class DecidablesElement extends i {
6203
6161
  </filter>`;
6204
6162
  });
6205
6163
  return b`
6206
- <svg class="defs">
6207
- <defs>
6208
- ${filters}
6209
- </defs>
6210
- </svg>
6164
+ <defs class="filtersUser">
6165
+ ${filters}
6166
+ </defs>
6211
6167
  `;
6212
6168
  }
6213
6169
  static get styles() {
@@ -13616,195 +13572,2649 @@ class RDKTask extends DecidablesMixinResizeable(DetectableElement) {
13616
13572
  }
13617
13573
  customElements.define('rdk-task', RDKTask);
13618
13574
 
13619
- /*
13620
- ROCSpace element
13621
- <roc-space>
13622
-
13623
- Attributes:
13624
- FAR; HR;
13625
- d'; C; zFAR; zHR
13626
-
13627
- draggable: yes/no
13628
-
13629
- scale: FAR/HR; zFAR/zHR; d'/C
13630
- grid: FAR/HR; zFAR/zHR; d'/C
13631
- isos: d'; C; FAR; HR
13575
+ function ownKeys(object, enumerableOnly) {
13576
+ var keys = Object.keys(object);
13577
+ if (Object.getOwnPropertySymbols) {
13578
+ var symbols = Object.getOwnPropertySymbols(object);
13579
+ if (enumerableOnly) {
13580
+ symbols = symbols.filter(function (sym) {
13581
+ return Object.getOwnPropertyDescriptor(object, sym).enumerable;
13582
+ });
13583
+ }
13584
+ keys.push.apply(keys, symbols);
13585
+ }
13586
+ return keys;
13587
+ }
13588
+ function _objectSpread2(target) {
13589
+ for (var i = 1; i < arguments.length; i++) {
13590
+ var source = arguments[i] != null ? arguments[i] : {};
13591
+ if (i % 2) {
13592
+ ownKeys(Object(source), true).forEach(function (key) {
13593
+ _defineProperty(target, key, source[key]);
13594
+ });
13595
+ } else if (Object.getOwnPropertyDescriptors) {
13596
+ Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
13597
+ } else {
13598
+ ownKeys(Object(source)).forEach(function (key) {
13599
+ Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
13600
+ });
13601
+ }
13602
+ }
13603
+ return target;
13604
+ }
13605
+ function _typeof(obj) {
13606
+ "@babel/helpers - typeof";
13632
13607
 
13633
- Styles:
13634
- ??
13635
- */
13636
- class ROCSpace extends DecidablesMixinResizeable(DetectableElement) {
13637
- static get properties() {
13638
- return {
13639
- contour: {
13640
- attribute: 'contour',
13641
- type: String,
13642
- reflect: true
13643
- },
13644
- point: {
13645
- attribute: 'point',
13646
- type: String,
13647
- reflect: true
13648
- },
13649
- isoD: {
13650
- attribute: 'iso-d',
13651
- type: String,
13652
- reflect: true
13653
- },
13654
- isoC: {
13655
- attribute: 'iso-c',
13656
- type: String,
13657
- reflect: true
13658
- },
13659
- zRoc: {
13660
- attribute: 'z-roc',
13661
- type: Boolean,
13662
- reflect: true
13663
- },
13664
- far: {
13665
- attribute: 'far',
13666
- type: Number,
13667
- reflect: true
13668
- },
13669
- hr: {
13670
- attribute: 'hr',
13671
- type: Number,
13672
- reflect: true
13673
- },
13674
- d: {
13675
- attribute: false,
13676
- type: Number,
13677
- reflect: false
13678
- },
13679
- c: {
13680
- attribute: false,
13681
- type: Number,
13682
- reflect: false
13683
- },
13684
- s: {
13685
- attribute: false,
13686
- type: Number,
13687
- reflect: false
13688
- }
13608
+ if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
13609
+ _typeof = function (obj) {
13610
+ return typeof obj;
13611
+ };
13612
+ } else {
13613
+ _typeof = function (obj) {
13614
+ return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
13689
13615
  };
13690
13616
  }
13691
- constructor() {
13692
- super();
13693
- this.firstUpdate = true;
13694
- this.drag = false;
13695
- this.sdt = false;
13696
- this.contours = ['sensitivity', 'bias', 'accuracy'];
13697
- this.contour = undefined;
13698
- this.points = ['all', 'first', 'rest', 'none'];
13699
- this.point = 'all';
13700
- this.isoDs = ['all', 'first', 'rest', 'none'];
13701
- this.isoD = 'first';
13702
- this.isoCs = ['all', 'first', 'rest', 'none'];
13703
- this.isoC = 'first';
13704
- this.zRoc = false;
13705
- this.far = 0.25;
13706
- this.hr = 0.75;
13707
- this.s = SDTMath.s.DEFAULT;
13708
- this.label = '';
13709
- this.locations = [{
13710
- name: 'default',
13711
- far: this.far,
13712
- hr: this.hr,
13713
- s: this.s,
13714
- label: ''
13715
- }];
13716
- this.pointArray = [];
13717
- this.isoDArray = [];
13718
- this.isoCArray = [];
13719
- this.alignState();
13720
- }
13721
- alignState() {
13722
- this.locations[0].hr = this.hr;
13723
- this.locations[0].far = this.far;
13724
- this.locations[0].s = this.s;
13725
- this.locations[0].label = this.label;
13726
- this.d = SDTMath.hrFar2D(this.hr, this.far, this.s);
13727
- this.c = SDTMath.hrFar2C(this.hr, this.far, this.s);
13728
- this.pointArray = [];
13729
- this.isoDArray = [];
13730
- this.isoCArray = [];
13731
- this.locations.forEach((item, index) => {
13732
- item.d = SDTMath.hrFar2D(item.hr, item.far, item.s);
13733
- item.c = SDTMath.hrFar2C(item.hr, item.far, item.s);
13734
- if (index === 0 && (this.point === 'first' || this.point === 'all')) {
13735
- this.pointArray.push(item);
13736
- } else if (index > 0 && (this.point === 'rest' || this.point === 'all')) {
13737
- this.pointArray.push(item);
13738
- }
13739
- if (index === 0 && (this.isoD === 'first' || this.isoD === 'all')) {
13740
- this.isoDArray.push(item);
13741
- } else if (index > 0 && (this.isoD === 'rest' || this.isoD === 'all')) {
13742
- this.isoDArray.push(item);
13743
- }
13744
- if (index === 0 && (this.isoC === 'first' || this.isoC === 'all')) {
13745
- this.isoCArray.push(item);
13746
- } else if (index > 0 && (this.isoC === 'rest' || this.isoC === 'all')) {
13747
- this.isoCArray.push(item);
13748
- }
13617
+ return _typeof(obj);
13618
+ }
13619
+ function _defineProperty(obj, key, value) {
13620
+ if (key in obj) {
13621
+ Object.defineProperty(obj, key, {
13622
+ value: value,
13623
+ enumerable: true,
13624
+ configurable: true,
13625
+ writable: true
13749
13626
  });
13627
+ } else {
13628
+ obj[key] = value;
13750
13629
  }
13751
- set(hr, far, name = 'default', label = '', s = 1) {
13752
- if (name === 'default') {
13753
- this.hr = hr;
13754
- this.far = far;
13755
- this.s = s;
13756
- this.label = label;
13630
+ return obj;
13631
+ }
13632
+ function _extends() {
13633
+ _extends = Object.assign || function (target) {
13634
+ for (var i = 1; i < arguments.length; i++) {
13635
+ var source = arguments[i];
13636
+ for (var key in source) {
13637
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
13638
+ target[key] = source[key];
13639
+ }
13640
+ }
13757
13641
  }
13758
- const location = this.locations.find(item => {
13759
- return item.name === name;
13760
- });
13761
- if (location === undefined) {
13762
- this.locations.push({
13763
- name: name,
13764
- far: far,
13765
- hr: hr,
13766
- s: s,
13767
- label: label
13768
- });
13769
- } else {
13770
- location.hr = hr;
13771
- location.far = far;
13772
- location.s = s;
13773
- location.label = label;
13642
+ return target;
13643
+ };
13644
+ return _extends.apply(this, arguments);
13645
+ }
13646
+ function _unsupportedIterableToArray(o, minLen) {
13647
+ if (!o) return;
13648
+ if (typeof o === "string") return _arrayLikeToArray(o, minLen);
13649
+ var n = Object.prototype.toString.call(o).slice(8, -1);
13650
+ if (n === "Object" && o.constructor) n = o.constructor.name;
13651
+ if (n === "Map" || n === "Set") return Array.from(o);
13652
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
13653
+ }
13654
+ function _arrayLikeToArray(arr, len) {
13655
+ if (len == null || len > arr.length) len = arr.length;
13656
+ for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
13657
+ return arr2;
13658
+ }
13659
+ function _createForOfIteratorHelper(o, allowArrayLike) {
13660
+ var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
13661
+ if (!it) {
13662
+ if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike) {
13663
+ if (it) o = it;
13664
+ var i = 0;
13665
+ var F = function () {};
13666
+ return {
13667
+ s: F,
13668
+ n: function () {
13669
+ if (i >= o.length) return {
13670
+ done: true
13671
+ };
13672
+ return {
13673
+ done: false,
13674
+ value: o[i++]
13675
+ };
13676
+ },
13677
+ e: function (e) {
13678
+ throw e;
13679
+ },
13680
+ f: F
13681
+ };
13774
13682
  }
13775
- this.requestUpdate();
13683
+ throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
13776
13684
  }
13777
- setWithSDT(d, c, name = 'default', label = '', s = 1) {
13778
- if (name === 'default') {
13779
- this.hr = SDTMath.dC2Hr(d, c, s);
13780
- this.far = SDTMath.dC2Far(d, c, s);
13781
- this.s = s;
13782
- this.label = label;
13685
+ var normalCompletion = true,
13686
+ didErr = false,
13687
+ err;
13688
+ return {
13689
+ s: function () {
13690
+ it = it.call(o);
13691
+ },
13692
+ n: function () {
13693
+ var step = it.next();
13694
+ normalCompletion = step.done;
13695
+ return step;
13696
+ },
13697
+ e: function (e) {
13698
+ didErr = true;
13699
+ err = e;
13700
+ },
13701
+ f: function () {
13702
+ try {
13703
+ if (!normalCompletion && it.return != null) it.return();
13704
+ } finally {
13705
+ if (didErr) throw err;
13706
+ }
13783
13707
  }
13784
- const location = this.locations.find(item => {
13785
- return item.name === name;
13786
- });
13787
- if (location === undefined) {
13788
- this.locations.push({
13789
- name: name,
13790
- far: SDTMath.dC2Far(d, c, s),
13791
- hr: SDTMath.dC2Hr(d, c, s),
13792
- s: s,
13793
- label: label
13794
- });
13708
+ };
13709
+ }
13710
+
13711
+ /**
13712
+ * de Casteljau's algorithm for drawing and splitting bezier curves.
13713
+ * Inspired by https://pomax.github.io/bezierinfo/
13714
+ *
13715
+ * @param {Number[][]} points Array of [x,y] points: [start, control1, control2, ..., end]
13716
+ * The original segment to split.
13717
+ * @param {Number} t Where to split the curve (value between [0, 1])
13718
+ * @return {Object} An object { left, right } where left is the segment from 0..t and
13719
+ * right is the segment from t..1.
13720
+ */
13721
+ function decasteljau(points, t) {
13722
+ var left = [];
13723
+ var right = [];
13724
+ function decasteljauRecurse(points, t) {
13725
+ if (points.length === 1) {
13726
+ left.push(points[0]);
13727
+ right.push(points[0]);
13795
13728
  } else {
13796
- location.hr = SDTMath.dC2Hr(d, c, s);
13797
- location.far = SDTMath.dC2Far(d, c, s);
13798
- location.s = s;
13799
- location.label = label;
13729
+ var newPoints = Array(points.length - 1);
13730
+ for (var i = 0; i < newPoints.length; i++) {
13731
+ if (i === 0) {
13732
+ left.push(points[0]);
13733
+ }
13734
+ if (i === newPoints.length - 1) {
13735
+ right.push(points[i + 1]);
13736
+ }
13737
+ newPoints[i] = [(1 - t) * points[i][0] + t * points[i + 1][0], (1 - t) * points[i][1] + t * points[i + 1][1]];
13738
+ }
13739
+ decasteljauRecurse(newPoints, t);
13800
13740
  }
13801
- this.sdt = true;
13802
- this.requestUpdate();
13803
13741
  }
13804
- static get styles() {
13805
- return [super.styles, i$3`
13806
- :host {
13807
- display: inline-block;
13742
+ if (points.length) {
13743
+ decasteljauRecurse(points, t);
13744
+ }
13745
+ return {
13746
+ left: left,
13747
+ right: right.reverse()
13748
+ };
13749
+ }
13750
+ /**
13751
+ * Convert segments represented as points back into a command object
13752
+ *
13753
+ * @param {Number[][]} points Array of [x,y] points: [start, control1, control2, ..., end]
13754
+ * Represents a segment
13755
+ * @return {Object} A command object representing the segment.
13756
+ */
13757
+
13758
+ function pointsToCommand(points) {
13759
+ var command = {};
13760
+ if (points.length === 4) {
13761
+ command.x2 = points[2][0];
13762
+ command.y2 = points[2][1];
13763
+ }
13764
+ if (points.length >= 3) {
13765
+ command.x1 = points[1][0];
13766
+ command.y1 = points[1][1];
13767
+ }
13768
+ command.x = points[points.length - 1][0];
13769
+ command.y = points[points.length - 1][1];
13770
+ if (points.length === 4) {
13771
+ // start, control1, control2, end
13772
+ command.type = 'C';
13773
+ } else if (points.length === 3) {
13774
+ // start, control, end
13775
+ command.type = 'Q';
13776
+ } else {
13777
+ // start, end
13778
+ command.type = 'L';
13779
+ }
13780
+ return command;
13781
+ }
13782
+ /**
13783
+ * Runs de Casteljau's algorithm enough times to produce the desired number of segments.
13784
+ *
13785
+ * @param {Number[][]} points Array of [x,y] points for de Casteljau (the initial segment to split)
13786
+ * @param {Number} segmentCount Number of segments to split the original into
13787
+ * @return {Number[][][]} Array of segments
13788
+ */
13789
+
13790
+ function splitCurveAsPoints(points, segmentCount) {
13791
+ segmentCount = segmentCount || 2;
13792
+ var segments = [];
13793
+ var remainingCurve = points;
13794
+ var tIncrement = 1 / segmentCount; // x-----x-----x-----x
13795
+ // t= 0.33 0.66 1
13796
+ // x-----o-----------x
13797
+ // r= 0.33
13798
+ // x-----o-----x
13799
+ // r= 0.5 (0.33 / (1 - 0.33)) === tIncrement / (1 - (tIncrement * (i - 1))
13800
+ // x-----x-----x-----x----x
13801
+ // t= 0.25 0.5 0.75 1
13802
+ // x-----o----------------x
13803
+ // r= 0.25
13804
+ // x-----o----------x
13805
+ // r= 0.33 (0.25 / (1 - 0.25))
13806
+ // x-----o----x
13807
+ // r= 0.5 (0.25 / (1 - 0.5))
13808
+
13809
+ for (var i = 0; i < segmentCount - 1; i++) {
13810
+ var tRelative = tIncrement / (1 - tIncrement * i);
13811
+ var split = decasteljau(remainingCurve, tRelative);
13812
+ segments.push(split.left);
13813
+ remainingCurve = split.right;
13814
+ } // last segment is just to the end from the last point
13815
+
13816
+ segments.push(remainingCurve);
13817
+ return segments;
13818
+ }
13819
+ /**
13820
+ * Convert command objects to arrays of points, run de Casteljau's algorithm on it
13821
+ * to split into to the desired number of segments.
13822
+ *
13823
+ * @param {Object} commandStart The start command object
13824
+ * @param {Object} commandEnd The end command object
13825
+ * @param {Number} segmentCount The number of segments to create
13826
+ * @return {Object[]} An array of commands representing the segments in sequence
13827
+ */
13828
+
13829
+ function splitCurve(commandStart, commandEnd, segmentCount) {
13830
+ var points = [[commandStart.x, commandStart.y]];
13831
+ if (commandEnd.x1 != null) {
13832
+ points.push([commandEnd.x1, commandEnd.y1]);
13833
+ }
13834
+ if (commandEnd.x2 != null) {
13835
+ points.push([commandEnd.x2, commandEnd.y2]);
13836
+ }
13837
+ points.push([commandEnd.x, commandEnd.y]);
13838
+ return splitCurveAsPoints(points, segmentCount).map(pointsToCommand);
13839
+ }
13840
+ var commandTokenRegex = /[MLCSTQAHVZmlcstqahv]|-?[\d.e+-]+/g;
13841
+ /**
13842
+ * List of params for each command type in a path `d` attribute
13843
+ */
13844
+
13845
+ var typeMap = {
13846
+ M: ['x', 'y'],
13847
+ L: ['x', 'y'],
13848
+ H: ['x'],
13849
+ V: ['y'],
13850
+ C: ['x1', 'y1', 'x2', 'y2', 'x', 'y'],
13851
+ S: ['x2', 'y2', 'x', 'y'],
13852
+ Q: ['x1', 'y1', 'x', 'y'],
13853
+ T: ['x', 'y'],
13854
+ A: ['rx', 'ry', 'xAxisRotation', 'largeArcFlag', 'sweepFlag', 'x', 'y'],
13855
+ Z: []
13856
+ }; // Add lower case entries too matching uppercase (e.g. 'm' == 'M')
13857
+
13858
+ Object.keys(typeMap).forEach(function (key) {
13859
+ typeMap[key.toLowerCase()] = typeMap[key];
13860
+ });
13861
+ function arrayOfLength(length, value) {
13862
+ var array = Array(length);
13863
+ for (var i = 0; i < length; i++) {
13864
+ array[i] = value;
13865
+ }
13866
+ return array;
13867
+ }
13868
+ /**
13869
+ * Converts a command object to a string to be used in a `d` attribute
13870
+ * @param {Object} command A command object
13871
+ * @return {String} The string for the `d` attribute
13872
+ */
13873
+
13874
+ function commandToString(command) {
13875
+ return "".concat(command.type).concat(typeMap[command.type].map(function (p) {
13876
+ return command[p];
13877
+ }).join(','));
13878
+ }
13879
+ /**
13880
+ * Converts command A to have the same type as command B.
13881
+ *
13882
+ * e.g., L0,5 -> C0,5,0,5,0,5
13883
+ *
13884
+ * Uses these rules:
13885
+ * x1 <- x
13886
+ * x2 <- x
13887
+ * y1 <- y
13888
+ * y2 <- y
13889
+ * rx <- 0
13890
+ * ry <- 0
13891
+ * xAxisRotation <- read from B
13892
+ * largeArcFlag <- read from B
13893
+ * sweepflag <- read from B
13894
+ *
13895
+ * @param {Object} aCommand Command object from path `d` attribute
13896
+ * @param {Object} bCommand Command object from path `d` attribute to match against
13897
+ * @return {Object} aCommand converted to type of bCommand
13898
+ */
13899
+
13900
+ function convertToSameType(aCommand, bCommand) {
13901
+ var conversionMap = {
13902
+ x1: 'x',
13903
+ y1: 'y',
13904
+ x2: 'x',
13905
+ y2: 'y'
13906
+ };
13907
+ var readFromBKeys = ['xAxisRotation', 'largeArcFlag', 'sweepFlag']; // convert (but ignore M types)
13908
+
13909
+ if (aCommand.type !== bCommand.type && bCommand.type.toUpperCase() !== 'M') {
13910
+ var aConverted = {};
13911
+ Object.keys(bCommand).forEach(function (bKey) {
13912
+ var bValue = bCommand[bKey]; // first read from the A command
13913
+
13914
+ var aValue = aCommand[bKey]; // if it is one of these values, read from B no matter what
13915
+
13916
+ if (aValue === undefined) {
13917
+ if (readFromBKeys.includes(bKey)) {
13918
+ aValue = bValue;
13919
+ } else {
13920
+ // if it wasn't in the A command, see if an equivalent was
13921
+ if (aValue === undefined && conversionMap[bKey]) {
13922
+ aValue = aCommand[conversionMap[bKey]];
13923
+ } // if it doesn't have a converted value, use 0
13924
+
13925
+ if (aValue === undefined) {
13926
+ aValue = 0;
13927
+ }
13928
+ }
13929
+ }
13930
+ aConverted[bKey] = aValue;
13931
+ }); // update the type to match B
13932
+
13933
+ aConverted.type = bCommand.type;
13934
+ aCommand = aConverted;
13935
+ }
13936
+ return aCommand;
13937
+ }
13938
+ /**
13939
+ * Interpolate between command objects commandStart and commandEnd segmentCount times.
13940
+ * If the types are L, Q, or C then the curves are split as per de Casteljau's algorithm.
13941
+ * Otherwise we just copy commandStart segmentCount - 1 times, finally ending with commandEnd.
13942
+ *
13943
+ * @param {Object} commandStart Command object at the beginning of the segment
13944
+ * @param {Object} commandEnd Command object at the end of the segment
13945
+ * @param {Number} segmentCount The number of segments to split this into. If only 1
13946
+ * Then [commandEnd] is returned.
13947
+ * @return {Object[]} Array of ~segmentCount command objects between commandStart and
13948
+ * commandEnd. (Can be segmentCount+1 objects if commandStart is type M).
13949
+ */
13950
+
13951
+ function splitSegment(commandStart, commandEnd, segmentCount) {
13952
+ var segments = []; // line, quadratic bezier, or cubic bezier
13953
+
13954
+ if (commandEnd.type === 'L' || commandEnd.type === 'Q' || commandEnd.type === 'C') {
13955
+ segments = segments.concat(splitCurve(commandStart, commandEnd, segmentCount)); // general case - just copy the same point
13956
+ } else {
13957
+ var copyCommand = _extends({}, commandStart); // convert M to L
13958
+
13959
+ if (copyCommand.type === 'M') {
13960
+ copyCommand.type = 'L';
13961
+ }
13962
+ segments = segments.concat(arrayOfLength(segmentCount - 1).map(function () {
13963
+ return copyCommand;
13964
+ }));
13965
+ segments.push(commandEnd);
13966
+ }
13967
+ return segments;
13968
+ }
13969
+ /**
13970
+ * Extends an array of commandsToExtend to the length of the referenceCommands by
13971
+ * splitting segments until the number of commands match. Ensures all the actual
13972
+ * points of commandsToExtend are in the extended array.
13973
+ *
13974
+ * @param {Object[]} commandsToExtend The command object array to extend
13975
+ * @param {Object[]} referenceCommands The command object array to match in length
13976
+ * @param {Function} excludeSegment a function that takes a start command object and
13977
+ * end command object and returns true if the segment should be excluded from splitting.
13978
+ * @return {Object[]} The extended commandsToExtend array
13979
+ */
13980
+
13981
+ function extend(commandsToExtend, referenceCommands, excludeSegment) {
13982
+ // compute insertion points:
13983
+ // number of segments in the path to extend
13984
+ var numSegmentsToExtend = commandsToExtend.length - 1; // number of segments in the reference path.
13985
+
13986
+ var numReferenceSegments = referenceCommands.length - 1; // this value is always between [0, 1].
13987
+
13988
+ var segmentRatio = numSegmentsToExtend / numReferenceSegments; // create a map, mapping segments in referenceCommands to how many points
13989
+ // should be added in that segment (should always be >= 1 since we need each
13990
+ // point itself).
13991
+ // 0 = segment 0-1, 1 = segment 1-2, n-1 = last vertex
13992
+
13993
+ var countPointsPerSegment = arrayOfLength(numReferenceSegments).reduce(function (accum, d, i) {
13994
+ var insertIndex = Math.floor(segmentRatio * i); // handle excluding segments
13995
+
13996
+ if (excludeSegment && insertIndex < commandsToExtend.length - 1 && excludeSegment(commandsToExtend[insertIndex], commandsToExtend[insertIndex + 1])) {
13997
+ // set the insertIndex to the segment that this point should be added to:
13998
+ // round the insertIndex essentially so we split half and half on
13999
+ // neighbouring segments. hence the segmentRatio * i < 0.5
14000
+ var addToPriorSegment = segmentRatio * i % 1 < 0.5; // only skip segment if we already have 1 point in it (can't entirely remove a segment)
14001
+
14002
+ if (accum[insertIndex]) {
14003
+ // TODO - Note this is a naive algorithm that should work for most d3-area use cases
14004
+ // but if two adjacent segments are supposed to be skipped, this will not perform as
14005
+ // expected. Could be updated to search for nearest segment to place the point in, but
14006
+ // will only do that if necessary.
14007
+ // add to the prior segment
14008
+ if (addToPriorSegment) {
14009
+ if (insertIndex > 0) {
14010
+ insertIndex -= 1; // not possible to add to previous so adding to next
14011
+ } else if (insertIndex < commandsToExtend.length - 1) {
14012
+ insertIndex += 1;
14013
+ } // add to next segment
14014
+ } else if (insertIndex < commandsToExtend.length - 1) {
14015
+ insertIndex += 1; // not possible to add to next so adding to previous
14016
+ } else if (insertIndex > 0) {
14017
+ insertIndex -= 1;
14018
+ }
14019
+ }
14020
+ }
14021
+ accum[insertIndex] = (accum[insertIndex] || 0) + 1;
14022
+ return accum;
14023
+ }, []); // extend each segment to have the correct number of points for a smooth interpolation
14024
+
14025
+ var extended = countPointsPerSegment.reduce(function (extended, segmentCount, i) {
14026
+ // if last command, just add `segmentCount` number of times
14027
+ if (i === commandsToExtend.length - 1) {
14028
+ var lastCommandCopies = arrayOfLength(segmentCount, _extends({}, commandsToExtend[commandsToExtend.length - 1])); // convert M to L
14029
+
14030
+ if (lastCommandCopies[0].type === 'M') {
14031
+ lastCommandCopies.forEach(function (d) {
14032
+ d.type = 'L';
14033
+ });
14034
+ }
14035
+ return extended.concat(lastCommandCopies);
14036
+ } // otherwise, split the segment segmentCount times.
14037
+
14038
+ return extended.concat(splitSegment(commandsToExtend[i], commandsToExtend[i + 1], segmentCount));
14039
+ }, []); // add in the very first point since splitSegment only adds in the ones after it
14040
+
14041
+ extended.unshift(commandsToExtend[0]);
14042
+ return extended;
14043
+ }
14044
+ /**
14045
+ * Takes a path `d` string and converts it into an array of command
14046
+ * objects. Drops the `Z` character.
14047
+ *
14048
+ * @param {String|null} d A path `d` string
14049
+ */
14050
+
14051
+ function pathCommandsFromString(d) {
14052
+ // split into valid tokens
14053
+ var tokens = (d || '').match(commandTokenRegex) || [];
14054
+ var commands = [];
14055
+ var commandArgs;
14056
+ var command; // iterate over each token, checking if we are at a new command
14057
+ // by presence in the typeMap
14058
+
14059
+ for (var i = 0; i < tokens.length; ++i) {
14060
+ commandArgs = typeMap[tokens[i]]; // new command found:
14061
+
14062
+ if (commandArgs) {
14063
+ command = {
14064
+ type: tokens[i]
14065
+ }; // add each of the expected args for this command:
14066
+
14067
+ for (var a = 0; a < commandArgs.length; ++a) {
14068
+ command[commandArgs[a]] = +tokens[i + a + 1];
14069
+ } // need to increment our token index appropriately since
14070
+ // we consumed token args
14071
+
14072
+ i += commandArgs.length;
14073
+ commands.push(command);
14074
+ }
14075
+ }
14076
+ return commands;
14077
+ }
14078
+ /**
14079
+ * Interpolate from A to B by extending A and B during interpolation to have
14080
+ * the same number of points. This allows for a smooth transition when they
14081
+ * have a different number of points.
14082
+ *
14083
+ * Ignores the `Z` command in paths unless both A and B end with it.
14084
+ *
14085
+ * This function works directly with arrays of command objects instead of with
14086
+ * path `d` strings (see interpolatePath for working with `d` strings).
14087
+ *
14088
+ * @param {Object[]} aCommandsInput Array of path commands
14089
+ * @param {Object[]} bCommandsInput Array of path commands
14090
+ * @param {(Function|Object)} interpolateOptions
14091
+ * @param {Function} interpolateOptions.excludeSegment a function that takes a start command object and
14092
+ * end command object and returns true if the segment should be excluded from splitting.
14093
+ * @param {Boolean} interpolateOptions.snapEndsToInput a boolean indicating whether end of input should
14094
+ * be sourced from input argument or computed.
14095
+ * @returns {Function} Interpolation function that maps t ([0, 1]) to an array of path commands.
14096
+ */
14097
+
14098
+ function interpolatePathCommands(aCommandsInput, bCommandsInput, interpolateOptions) {
14099
+ // make a copy so we don't mess with the input arrays
14100
+ var aCommands = aCommandsInput == null ? [] : aCommandsInput.slice();
14101
+ var bCommands = bCommandsInput == null ? [] : bCommandsInput.slice();
14102
+ var _ref = _typeof(interpolateOptions) === 'object' ? interpolateOptions : {
14103
+ excludeSegment: interpolateOptions,
14104
+ snapEndsToInput: true
14105
+ },
14106
+ excludeSegment = _ref.excludeSegment,
14107
+ snapEndsToInput = _ref.snapEndsToInput; // both input sets are empty, so we don't interpolate
14108
+
14109
+ if (!aCommands.length && !bCommands.length) {
14110
+ return function nullInterpolator() {
14111
+ return [];
14112
+ };
14113
+ } // do we add Z during interpolation? yes if both have it. (we'd expect both to have it or not)
14114
+
14115
+ var addZ = (aCommands.length === 0 || aCommands[aCommands.length - 1].type === 'Z') && (bCommands.length === 0 || bCommands[bCommands.length - 1].type === 'Z'); // we temporarily remove Z
14116
+
14117
+ if (aCommands.length > 0 && aCommands[aCommands.length - 1].type === 'Z') {
14118
+ aCommands.pop();
14119
+ }
14120
+ if (bCommands.length > 0 && bCommands[bCommands.length - 1].type === 'Z') {
14121
+ bCommands.pop();
14122
+ } // if A is empty, treat it as if it used to contain just the first point
14123
+ // of B. This makes it so the line extends out of from that first point.
14124
+
14125
+ if (!aCommands.length) {
14126
+ aCommands.push(bCommands[0]); // otherwise if B is empty, treat it as if it contains the first point
14127
+ // of A. This makes it so the line retracts into the first point.
14128
+ } else if (!bCommands.length) {
14129
+ bCommands.push(aCommands[0]);
14130
+ } // extend to match equal size
14131
+
14132
+ var numPointsToExtend = Math.abs(bCommands.length - aCommands.length);
14133
+ if (numPointsToExtend !== 0) {
14134
+ // B has more points than A, so add points to A before interpolating
14135
+ if (bCommands.length > aCommands.length) {
14136
+ aCommands = extend(aCommands, bCommands, excludeSegment); // else if A has more points than B, add more points to B
14137
+ } else if (bCommands.length < aCommands.length) {
14138
+ bCommands = extend(bCommands, aCommands, excludeSegment);
14139
+ }
14140
+ } // commands have same length now.
14141
+ // convert commands in A to the same type as those in B
14142
+
14143
+ aCommands = aCommands.map(function (aCommand, i) {
14144
+ return convertToSameType(aCommand, bCommands[i]);
14145
+ }); // create mutable interpolated command objects
14146
+
14147
+ var interpolatedCommands = aCommands.map(function (aCommand) {
14148
+ return _objectSpread2({}, aCommand);
14149
+ });
14150
+ if (addZ) {
14151
+ interpolatedCommands.push({
14152
+ type: 'Z'
14153
+ });
14154
+ aCommands.push({
14155
+ type: 'Z'
14156
+ }); // required for when returning at t == 0
14157
+ }
14158
+ return function pathCommandInterpolator(t) {
14159
+ // at 1 return the final value without the extensions used during interpolation
14160
+ if (t === 1 && snapEndsToInput) {
14161
+ return bCommandsInput == null ? [] : bCommandsInput;
14162
+ } // work with aCommands directly since interpolatedCommands are mutated
14163
+
14164
+ if (t === 0) {
14165
+ return aCommands;
14166
+ } // interpolate the commands using the mutable interpolated command objs
14167
+
14168
+ for (var i = 0; i < interpolatedCommands.length; ++i) {
14169
+ // if (interpolatedCommands[i].type === 'Z') continue;
14170
+ var aCommand = aCommands[i];
14171
+ var bCommand = bCommands[i];
14172
+ var interpolatedCommand = interpolatedCommands[i];
14173
+ var _iterator = _createForOfIteratorHelper(typeMap[interpolatedCommand.type]),
14174
+ _step;
14175
+ try {
14176
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
14177
+ var arg = _step.value;
14178
+ interpolatedCommand[arg] = (1 - t) * aCommand[arg] + t * bCommand[arg]; // do not use floats for flags (#27), round to integer
14179
+
14180
+ if (arg === 'largeArcFlag' || arg === 'sweepFlag') {
14181
+ interpolatedCommand[arg] = Math.round(interpolatedCommand[arg]);
14182
+ }
14183
+ }
14184
+ } catch (err) {
14185
+ _iterator.e(err);
14186
+ } finally {
14187
+ _iterator.f();
14188
+ }
14189
+ }
14190
+ return interpolatedCommands;
14191
+ };
14192
+ }
14193
+ /** @typedef InterpolateOptions */
14194
+
14195
+ /**
14196
+ * Interpolate from A to B by extending A and B during interpolation to have
14197
+ * the same number of points. This allows for a smooth transition when they
14198
+ * have a different number of points.
14199
+ *
14200
+ * Ignores the `Z` character in paths unless both A and B end with it.
14201
+ *
14202
+ * @param {String} a The `d` attribute for a path
14203
+ * @param {String} b The `d` attribute for a path
14204
+ * @param {((command1, command2) => boolean|{
14205
+ * excludeSegment?: (command1, command2) => boolean;
14206
+ * snapEndsToInput?: boolean
14207
+ * })} interpolateOptions The excludeSegment function or an options object
14208
+ * - interpolateOptions.excludeSegment a function that takes a start command object and
14209
+ * end command object and returns true if the segment should be excluded from splitting.
14210
+ * - interpolateOptions.snapEndsToInput a boolean indicating whether end of input should
14211
+ * be sourced from input argument or computed.
14212
+ * @returns {Function} Interpolation function that maps t ([0, 1]) to a path `d` string.
14213
+ */
14214
+
14215
+ function interpolatePath(a, b, interpolateOptions) {
14216
+ var aCommands = pathCommandsFromString(a);
14217
+ var bCommands = pathCommandsFromString(b);
14218
+ var _ref2 = _typeof(interpolateOptions) === 'object' ? interpolateOptions : {
14219
+ excludeSegment: interpolateOptions,
14220
+ snapEndsToInput: true
14221
+ },
14222
+ excludeSegment = _ref2.excludeSegment,
14223
+ snapEndsToInput = _ref2.snapEndsToInput;
14224
+ if (!aCommands.length && !bCommands.length) {
14225
+ return function nullInterpolator() {
14226
+ return '';
14227
+ };
14228
+ }
14229
+ var commandInterpolator = interpolatePathCommands(aCommands, bCommands, {
14230
+ excludeSegment: excludeSegment,
14231
+ snapEndsToInput: snapEndsToInput
14232
+ });
14233
+ return function pathStringInterpolator(t) {
14234
+ // at 1 return the final value without the extensions used during interpolation
14235
+ if (t === 1 && snapEndsToInput) {
14236
+ return b == null ? '' : b;
14237
+ }
14238
+ var interpolatedCommands = commandInterpolator(t); // convert to a string (fastest concat: https://jsperf.com/join-concat/150)
14239
+
14240
+ var interpolatedString = '';
14241
+ var _iterator2 = _createForOfIteratorHelper(interpolatedCommands),
14242
+ _step2;
14243
+ try {
14244
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
14245
+ var interpolatedCommand = _step2.value;
14246
+ interpolatedString += commandToString(interpolatedCommand);
14247
+ }
14248
+ } catch (err) {
14249
+ _iterator2.e(err);
14250
+ } finally {
14251
+ _iterator2.f();
14252
+ }
14253
+ return interpolatedString;
14254
+ };
14255
+ }
14256
+
14257
+ var cssKeywords = {
14258
+ aliceblue: [240, 248, 255],
14259
+ antiquewhite: [250, 235, 215],
14260
+ aqua: [0, 255, 255],
14261
+ aquamarine: [127, 255, 212],
14262
+ azure: [240, 255, 255],
14263
+ beige: [245, 245, 220],
14264
+ bisque: [255, 228, 196],
14265
+ black: [0, 0, 0],
14266
+ blanchedalmond: [255, 235, 205],
14267
+ blue: [0, 0, 255],
14268
+ blueviolet: [138, 43, 226],
14269
+ brown: [165, 42, 42],
14270
+ burlywood: [222, 184, 135],
14271
+ cadetblue: [95, 158, 160],
14272
+ chartreuse: [127, 255, 0],
14273
+ chocolate: [210, 105, 30],
14274
+ coral: [255, 127, 80],
14275
+ cornflowerblue: [100, 149, 237],
14276
+ cornsilk: [255, 248, 220],
14277
+ crimson: [220, 20, 60],
14278
+ cyan: [0, 255, 255],
14279
+ darkblue: [0, 0, 139],
14280
+ darkcyan: [0, 139, 139],
14281
+ darkgoldenrod: [184, 134, 11],
14282
+ darkgray: [169, 169, 169],
14283
+ darkgreen: [0, 100, 0],
14284
+ darkgrey: [169, 169, 169],
14285
+ darkkhaki: [189, 183, 107],
14286
+ darkmagenta: [139, 0, 139],
14287
+ darkolivegreen: [85, 107, 47],
14288
+ darkorange: [255, 140, 0],
14289
+ darkorchid: [153, 50, 204],
14290
+ darkred: [139, 0, 0],
14291
+ darksalmon: [233, 150, 122],
14292
+ darkseagreen: [143, 188, 143],
14293
+ darkslateblue: [72, 61, 139],
14294
+ darkslategray: [47, 79, 79],
14295
+ darkslategrey: [47, 79, 79],
14296
+ darkturquoise: [0, 206, 209],
14297
+ darkviolet: [148, 0, 211],
14298
+ deeppink: [255, 20, 147],
14299
+ deepskyblue: [0, 191, 255],
14300
+ dimgray: [105, 105, 105],
14301
+ dimgrey: [105, 105, 105],
14302
+ dodgerblue: [30, 144, 255],
14303
+ firebrick: [178, 34, 34],
14304
+ floralwhite: [255, 250, 240],
14305
+ forestgreen: [34, 139, 34],
14306
+ fuchsia: [255, 0, 255],
14307
+ gainsboro: [220, 220, 220],
14308
+ ghostwhite: [248, 248, 255],
14309
+ gold: [255, 215, 0],
14310
+ goldenrod: [218, 165, 32],
14311
+ gray: [128, 128, 128],
14312
+ green: [0, 128, 0],
14313
+ greenyellow: [173, 255, 47],
14314
+ grey: [128, 128, 128],
14315
+ honeydew: [240, 255, 240],
14316
+ hotpink: [255, 105, 180],
14317
+ indianred: [205, 92, 92],
14318
+ indigo: [75, 0, 130],
14319
+ ivory: [255, 255, 240],
14320
+ khaki: [240, 230, 140],
14321
+ lavender: [230, 230, 250],
14322
+ lavenderblush: [255, 240, 245],
14323
+ lawngreen: [124, 252, 0],
14324
+ lemonchiffon: [255, 250, 205],
14325
+ lightblue: [173, 216, 230],
14326
+ lightcoral: [240, 128, 128],
14327
+ lightcyan: [224, 255, 255],
14328
+ lightgoldenrodyellow: [250, 250, 210],
14329
+ lightgray: [211, 211, 211],
14330
+ lightgreen: [144, 238, 144],
14331
+ lightgrey: [211, 211, 211],
14332
+ lightpink: [255, 182, 193],
14333
+ lightsalmon: [255, 160, 122],
14334
+ lightseagreen: [32, 178, 170],
14335
+ lightskyblue: [135, 206, 250],
14336
+ lightslategray: [119, 136, 153],
14337
+ lightslategrey: [119, 136, 153],
14338
+ lightsteelblue: [176, 196, 222],
14339
+ lightyellow: [255, 255, 224],
14340
+ lime: [0, 255, 0],
14341
+ limegreen: [50, 205, 50],
14342
+ linen: [250, 240, 230],
14343
+ magenta: [255, 0, 255],
14344
+ maroon: [128, 0, 0],
14345
+ mediumaquamarine: [102, 205, 170],
14346
+ mediumblue: [0, 0, 205],
14347
+ mediumorchid: [186, 85, 211],
14348
+ mediumpurple: [147, 112, 219],
14349
+ mediumseagreen: [60, 179, 113],
14350
+ mediumslateblue: [123, 104, 238],
14351
+ mediumspringgreen: [0, 250, 154],
14352
+ mediumturquoise: [72, 209, 204],
14353
+ mediumvioletred: [199, 21, 133],
14354
+ midnightblue: [25, 25, 112],
14355
+ mintcream: [245, 255, 250],
14356
+ mistyrose: [255, 228, 225],
14357
+ moccasin: [255, 228, 181],
14358
+ navajowhite: [255, 222, 173],
14359
+ navy: [0, 0, 128],
14360
+ oldlace: [253, 245, 230],
14361
+ olive: [128, 128, 0],
14362
+ olivedrab: [107, 142, 35],
14363
+ orange: [255, 165, 0],
14364
+ orangered: [255, 69, 0],
14365
+ orchid: [218, 112, 214],
14366
+ palegoldenrod: [238, 232, 170],
14367
+ palegreen: [152, 251, 152],
14368
+ paleturquoise: [175, 238, 238],
14369
+ palevioletred: [219, 112, 147],
14370
+ papayawhip: [255, 239, 213],
14371
+ peachpuff: [255, 218, 185],
14372
+ peru: [205, 133, 63],
14373
+ pink: [255, 192, 203],
14374
+ plum: [221, 160, 221],
14375
+ powderblue: [176, 224, 230],
14376
+ purple: [128, 0, 128],
14377
+ rebeccapurple: [102, 51, 153],
14378
+ red: [255, 0, 0],
14379
+ rosybrown: [188, 143, 143],
14380
+ royalblue: [65, 105, 225],
14381
+ saddlebrown: [139, 69, 19],
14382
+ salmon: [250, 128, 114],
14383
+ sandybrown: [244, 164, 96],
14384
+ seagreen: [46, 139, 87],
14385
+ seashell: [255, 245, 238],
14386
+ sienna: [160, 82, 45],
14387
+ silver: [192, 192, 192],
14388
+ skyblue: [135, 206, 235],
14389
+ slateblue: [106, 90, 205],
14390
+ slategray: [112, 128, 144],
14391
+ slategrey: [112, 128, 144],
14392
+ snow: [255, 250, 250],
14393
+ springgreen: [0, 255, 127],
14394
+ steelblue: [70, 130, 180],
14395
+ tan: [210, 180, 140],
14396
+ teal: [0, 128, 128],
14397
+ thistle: [216, 191, 216],
14398
+ tomato: [255, 99, 71],
14399
+ turquoise: [64, 224, 208],
14400
+ violet: [238, 130, 238],
14401
+ wheat: [245, 222, 179],
14402
+ white: [255, 255, 255],
14403
+ whitesmoke: [245, 245, 245],
14404
+ yellow: [255, 255, 0],
14405
+ yellowgreen: [154, 205, 50]
14406
+ };
14407
+
14408
+ const reverseNames = Object.create(null);
14409
+
14410
+ // Create a list of reverse color names
14411
+ for (const name in cssKeywords) {
14412
+ if (Object.hasOwn(cssKeywords, name)) {
14413
+ reverseNames[cssKeywords[name]] = name;
14414
+ }
14415
+ }
14416
+ const cs = {
14417
+ to: {},
14418
+ get: {}
14419
+ };
14420
+ cs.get = function (string) {
14421
+ const prefix = string.slice(0, 3).toLowerCase();
14422
+ let value;
14423
+ let model;
14424
+ switch (prefix) {
14425
+ case 'hsl':
14426
+ {
14427
+ value = cs.get.hsl(string);
14428
+ model = 'hsl';
14429
+ break;
14430
+ }
14431
+ case 'hwb':
14432
+ {
14433
+ value = cs.get.hwb(string);
14434
+ model = 'hwb';
14435
+ break;
14436
+ }
14437
+ default:
14438
+ {
14439
+ value = cs.get.rgb(string);
14440
+ model = 'rgb';
14441
+ break;
14442
+ }
14443
+ }
14444
+ if (!value) {
14445
+ return null;
14446
+ }
14447
+ return {
14448
+ model,
14449
+ value
14450
+ };
14451
+ };
14452
+ cs.get.rgb = function (string) {
14453
+ if (!string) {
14454
+ return null;
14455
+ }
14456
+ const abbr = /^#([a-f\d]{3,4})$/i;
14457
+ const hex = /^#([a-f\d]{6})([a-f\d]{2})?$/i;
14458
+ const rgba = /^rgba?\(\s*([+-]?(?:\d*\.)?\d+(?:e\d+)?)(?=[\s,])\s*(?:,\s*)?([+-]?(?:\d*\.)?\d+(?:e\d+)?)(?=[\s,])\s*(?:,\s*)?([+-]?(?:\d*\.)?\d+(?:e\d+)?)\s*(?:[\s,|/]\s*([+-]?(?:\d*\.)?\d+(?:e\d+)?)(%?)\s*)?\)$/i;
14459
+ const per = /^rgba?\(\s*([+-]?[\d.]+)%\s*,?\s*([+-]?[\d.]+)%\s*,?\s*([+-]?[\d.]+)%\s*(?:[\s,|/]\s*([+-]?[\d.]+)(%?)\s*)?\)$/i;
14460
+ const keyword = /^(\w+)$/;
14461
+ let rgb = [0, 0, 0, 1];
14462
+ let match;
14463
+ let i;
14464
+ let hexAlpha;
14465
+ if (match = string.match(hex)) {
14466
+ hexAlpha = match[2];
14467
+ match = match[1];
14468
+ for (i = 0; i < 3; i++) {
14469
+ // https://jsperf.com/slice-vs-substr-vs-substring-methods-long-string/19
14470
+ const i2 = i * 2;
14471
+ rgb[i] = Number.parseInt(match.slice(i2, i2 + 2), 16);
14472
+ }
14473
+ if (hexAlpha) {
14474
+ rgb[3] = Number.parseInt(hexAlpha, 16) / 255;
14475
+ }
14476
+ } else if (match = string.match(abbr)) {
14477
+ match = match[1];
14478
+ hexAlpha = match[3];
14479
+ for (i = 0; i < 3; i++) {
14480
+ rgb[i] = Number.parseInt(match[i] + match[i], 16);
14481
+ }
14482
+ if (hexAlpha) {
14483
+ rgb[3] = Number.parseInt(hexAlpha + hexAlpha, 16) / 255;
14484
+ }
14485
+ } else if (match = string.match(rgba)) {
14486
+ for (i = 0; i < 3; i++) {
14487
+ rgb[i] = Number.parseFloat(match[i + 1]);
14488
+ }
14489
+ if (match[4]) {
14490
+ rgb[3] = match[5] ? Number.parseFloat(match[4]) * 0.01 : Number.parseFloat(match[4]);
14491
+ }
14492
+ } else if (match = string.match(per)) {
14493
+ for (i = 0; i < 3; i++) {
14494
+ rgb[i] = Math.round(Number.parseFloat(match[i + 1]) * 2.55);
14495
+ }
14496
+ if (match[4]) {
14497
+ rgb[3] = match[5] ? Number.parseFloat(match[4]) * 0.01 : Number.parseFloat(match[4]);
14498
+ }
14499
+ } else if (match = string.toLowerCase().match(keyword)) {
14500
+ if (match[1] === 'transparent') {
14501
+ return [0, 0, 0, 0];
14502
+ }
14503
+ if (!Object.hasOwn(cssKeywords, match[1])) {
14504
+ return null;
14505
+ }
14506
+
14507
+ // eslint-disable-next-line unicorn/prefer-spread
14508
+ rgb = cssKeywords[match[1]].slice();
14509
+ rgb[3] = 1;
14510
+ return rgb;
14511
+ } else {
14512
+ return null;
14513
+ }
14514
+ for (i = 0; i < 3; i++) {
14515
+ rgb[i] = clamp(rgb[i], 0, 255);
14516
+ }
14517
+ rgb[3] = clamp(rgb[3], 0, 1);
14518
+ return rgb;
14519
+ };
14520
+ cs.get.hsl = function (string) {
14521
+ if (!string) {
14522
+ return null;
14523
+ }
14524
+ const hsl = /^hsla?\(\s*([+-]?(?:\d{0,3}\.)?\d+)(?:deg)?\s*,?\s*([+-]?[\d.]+)%\s*,?\s*([+-]?[\d.]+)%\s*(?:[,|/]\s*([+-]?(?=\.\d|\d)(?:0|[1-9]\d*)?(?:\.\d*)?(?:e[+-]?\d+)?)\s*)?\)$/i;
14525
+ const match = string.match(hsl);
14526
+ if (match) {
14527
+ const alpha = Number.parseFloat(match[4]);
14528
+ const h = (Number.parseFloat(match[1]) % 360 + 360) % 360;
14529
+ const s = clamp(Number.parseFloat(match[2]), 0, 100);
14530
+ const l = clamp(Number.parseFloat(match[3]), 0, 100);
14531
+ const a = clamp(Number.isNaN(alpha) ? 1 : alpha, 0, 1);
14532
+ return [h, s, l, a];
14533
+ }
14534
+ return null;
14535
+ };
14536
+ cs.get.hwb = function (string) {
14537
+ if (!string) {
14538
+ return null;
14539
+ }
14540
+ const hwb = /^hwb\(\s*([+-]?\d{0,3}(?:\.\d+)?)(?:deg)?\s*[\s,]\s*([+-]?[\d.]+)%\s*[\s,]\s*([+-]?[\d.]+)%\s*(?:[\s,]\s*([+-]?(?=\.\d|\d)(?:0|[1-9]\d*)?(?:\.\d*)?(?:e[+-]?\d+)?)\s*)?\)$/i;
14541
+ const match = string.match(hwb);
14542
+ if (match) {
14543
+ const alpha = Number.parseFloat(match[4]);
14544
+ const h = (Number.parseFloat(match[1]) % 360 + 360) % 360;
14545
+ const w = clamp(Number.parseFloat(match[2]), 0, 100);
14546
+ const b = clamp(Number.parseFloat(match[3]), 0, 100);
14547
+ const a = clamp(Number.isNaN(alpha) ? 1 : alpha, 0, 1);
14548
+ return [h, w, b, a];
14549
+ }
14550
+ return null;
14551
+ };
14552
+ cs.to.hex = function (...rgba) {
14553
+ return '#' + hexDouble(rgba[0]) + hexDouble(rgba[1]) + hexDouble(rgba[2]) + (rgba[3] < 1 ? hexDouble(Math.round(rgba[3] * 255)) : '');
14554
+ };
14555
+ cs.to.rgb = function (...rgba) {
14556
+ return rgba.length < 4 || rgba[3] === 1 ? 'rgb(' + Math.round(rgba[0]) + ', ' + Math.round(rgba[1]) + ', ' + Math.round(rgba[2]) + ')' : 'rgba(' + Math.round(rgba[0]) + ', ' + Math.round(rgba[1]) + ', ' + Math.round(rgba[2]) + ', ' + rgba[3] + ')';
14557
+ };
14558
+ cs.to.rgb.percent = function (...rgba) {
14559
+ const r = Math.round(rgba[0] / 255 * 100);
14560
+ const g = Math.round(rgba[1] / 255 * 100);
14561
+ const b = Math.round(rgba[2] / 255 * 100);
14562
+ return rgba.length < 4 || rgba[3] === 1 ? 'rgb(' + r + '%, ' + g + '%, ' + b + '%)' : 'rgba(' + r + '%, ' + g + '%, ' + b + '%, ' + rgba[3] + ')';
14563
+ };
14564
+ cs.to.hsl = function (...hsla) {
14565
+ return hsla.length < 4 || hsla[3] === 1 ? 'hsl(' + hsla[0] + ', ' + hsla[1] + '%, ' + hsla[2] + '%)' : 'hsla(' + hsla[0] + ', ' + hsla[1] + '%, ' + hsla[2] + '%, ' + hsla[3] + ')';
14566
+ };
14567
+
14568
+ // Hwb is a bit different than rgb(a) & hsl(a) since there is no alpha specific syntax
14569
+ // (hwb have alpha optional & 1 is default value)
14570
+ cs.to.hwb = function (...hwba) {
14571
+ let a = '';
14572
+ if (hwba.length >= 4 && hwba[3] !== 1) {
14573
+ a = ', ' + hwba[3];
14574
+ }
14575
+ return 'hwb(' + hwba[0] + ', ' + hwba[1] + '%, ' + hwba[2] + '%' + a + ')';
14576
+ };
14577
+ cs.to.keyword = function (...rgb) {
14578
+ return reverseNames[rgb.slice(0, 3)];
14579
+ };
14580
+
14581
+ // Helpers
14582
+ function clamp(number_, min, max) {
14583
+ return Math.min(Math.max(min, number_), max);
14584
+ }
14585
+ function hexDouble(number_) {
14586
+ const string_ = Math.round(number_).toString(16).toUpperCase();
14587
+ return string_.length < 2 ? '0' + string_ : string_;
14588
+ }
14589
+
14590
+ /* MIT license */
14591
+ /* eslint-disable no-mixed-operators */
14592
+
14593
+ // NOTE: conversions should only return primitive values (i.e. arrays, or
14594
+ // values that give correct `typeof` results).
14595
+ // do not use box values types (i.e. Number(), String(), etc.)
14596
+
14597
+ const reverseKeywords = {};
14598
+ for (const key of Object.keys(cssKeywords)) {
14599
+ reverseKeywords[cssKeywords[key]] = key;
14600
+ }
14601
+ const convert$1 = {
14602
+ rgb: {
14603
+ channels: 3,
14604
+ labels: 'rgb'
14605
+ },
14606
+ hsl: {
14607
+ channels: 3,
14608
+ labels: 'hsl'
14609
+ },
14610
+ hsv: {
14611
+ channels: 3,
14612
+ labels: 'hsv'
14613
+ },
14614
+ hwb: {
14615
+ channels: 3,
14616
+ labels: 'hwb'
14617
+ },
14618
+ cmyk: {
14619
+ channels: 4,
14620
+ labels: 'cmyk'
14621
+ },
14622
+ xyz: {
14623
+ channels: 3,
14624
+ labels: 'xyz'
14625
+ },
14626
+ lab: {
14627
+ channels: 3,
14628
+ labels: 'lab'
14629
+ },
14630
+ oklab: {
14631
+ channels: 3,
14632
+ labels: ['okl', 'oka', 'okb']
14633
+ },
14634
+ lch: {
14635
+ channels: 3,
14636
+ labels: 'lch'
14637
+ },
14638
+ oklch: {
14639
+ channels: 3,
14640
+ labels: ['okl', 'okc', 'okh']
14641
+ },
14642
+ hex: {
14643
+ channels: 1,
14644
+ labels: ['hex']
14645
+ },
14646
+ keyword: {
14647
+ channels: 1,
14648
+ labels: ['keyword']
14649
+ },
14650
+ ansi16: {
14651
+ channels: 1,
14652
+ labels: ['ansi16']
14653
+ },
14654
+ ansi256: {
14655
+ channels: 1,
14656
+ labels: ['ansi256']
14657
+ },
14658
+ hcg: {
14659
+ channels: 3,
14660
+ labels: ['h', 'c', 'g']
14661
+ },
14662
+ apple: {
14663
+ channels: 3,
14664
+ labels: ['r16', 'g16', 'b16']
14665
+ },
14666
+ gray: {
14667
+ channels: 1,
14668
+ labels: ['gray']
14669
+ }
14670
+ };
14671
+
14672
+ // LAB f(t) constant
14673
+ const LAB_FT = (6 / 29) ** 3;
14674
+
14675
+ // SRGB non-linear transform functions
14676
+ function srgbNonlinearTransform(c) {
14677
+ const cc = c > 0.003_130_8 ? 1.055 * c ** (1 / 2.4) - 0.055 : c * 12.92;
14678
+ return Math.min(Math.max(0, cc), 1);
14679
+ }
14680
+ function srgbNonlinearTransformInv(c) {
14681
+ return c > 0.040_45 ? ((c + 0.055) / 1.055) ** 2.4 : c / 12.92;
14682
+ }
14683
+
14684
+ // Hide .channels and .labels properties
14685
+ for (const model of Object.keys(convert$1)) {
14686
+ if (!('channels' in convert$1[model])) {
14687
+ throw new Error('missing channels property: ' + model);
14688
+ }
14689
+ if (!('labels' in convert$1[model])) {
14690
+ throw new Error('missing channel labels property: ' + model);
14691
+ }
14692
+ if (convert$1[model].labels.length !== convert$1[model].channels) {
14693
+ throw new Error('channel and label counts mismatch: ' + model);
14694
+ }
14695
+ const {
14696
+ channels,
14697
+ labels
14698
+ } = convert$1[model];
14699
+ delete convert$1[model].channels;
14700
+ delete convert$1[model].labels;
14701
+ Object.defineProperty(convert$1[model], 'channels', {
14702
+ value: channels
14703
+ });
14704
+ Object.defineProperty(convert$1[model], 'labels', {
14705
+ value: labels
14706
+ });
14707
+ }
14708
+ convert$1.rgb.hsl = function (rgb) {
14709
+ const r = rgb[0] / 255;
14710
+ const g = rgb[1] / 255;
14711
+ const b = rgb[2] / 255;
14712
+ const min = Math.min(r, g, b);
14713
+ const max = Math.max(r, g, b);
14714
+ const delta = max - min;
14715
+ let h;
14716
+ let s;
14717
+ switch (max) {
14718
+ case min:
14719
+ {
14720
+ h = 0;
14721
+ break;
14722
+ }
14723
+ case r:
14724
+ {
14725
+ h = (g - b) / delta;
14726
+ break;
14727
+ }
14728
+ case g:
14729
+ {
14730
+ h = 2 + (b - r) / delta;
14731
+ break;
14732
+ }
14733
+ case b:
14734
+ {
14735
+ h = 4 + (r - g) / delta;
14736
+ break;
14737
+ }
14738
+ // No default
14739
+ }
14740
+ h = Math.min(h * 60, 360);
14741
+ if (h < 0) {
14742
+ h += 360;
14743
+ }
14744
+ const l = (min + max) / 2;
14745
+ if (max === min) {
14746
+ s = 0;
14747
+ } else if (l <= 0.5) {
14748
+ s = delta / (max + min);
14749
+ } else {
14750
+ s = delta / (2 - max - min);
14751
+ }
14752
+ return [h, s * 100, l * 100];
14753
+ };
14754
+ convert$1.rgb.hsv = function (rgb) {
14755
+ let rdif;
14756
+ let gdif;
14757
+ let bdif;
14758
+ let h;
14759
+ let s;
14760
+ const r = rgb[0] / 255;
14761
+ const g = rgb[1] / 255;
14762
+ const b = rgb[2] / 255;
14763
+ const v = Math.max(r, g, b);
14764
+ const diff = v - Math.min(r, g, b);
14765
+ const diffc = function (c) {
14766
+ return (v - c) / 6 / diff + 1 / 2;
14767
+ };
14768
+ if (diff === 0) {
14769
+ h = 0;
14770
+ s = 0;
14771
+ } else {
14772
+ s = diff / v;
14773
+ rdif = diffc(r);
14774
+ gdif = diffc(g);
14775
+ bdif = diffc(b);
14776
+ switch (v) {
14777
+ case r:
14778
+ {
14779
+ h = bdif - gdif;
14780
+ break;
14781
+ }
14782
+ case g:
14783
+ {
14784
+ h = 1 / 3 + rdif - bdif;
14785
+ break;
14786
+ }
14787
+ case b:
14788
+ {
14789
+ h = 2 / 3 + gdif - rdif;
14790
+ break;
14791
+ }
14792
+ // No default
14793
+ }
14794
+ if (h < 0) {
14795
+ h += 1;
14796
+ } else if (h > 1) {
14797
+ h -= 1;
14798
+ }
14799
+ }
14800
+ return [h * 360, s * 100, v * 100];
14801
+ };
14802
+ convert$1.rgb.hwb = function (rgb) {
14803
+ const r = rgb[0];
14804
+ const g = rgb[1];
14805
+ let b = rgb[2];
14806
+ const h = convert$1.rgb.hsl(rgb)[0];
14807
+ const w = 1 / 255 * Math.min(r, Math.min(g, b));
14808
+ b = 1 - 1 / 255 * Math.max(r, Math.max(g, b));
14809
+ return [h, w * 100, b * 100];
14810
+ };
14811
+ convert$1.rgb.oklab = function (rgb) {
14812
+ // Assume sRGB
14813
+ const r = srgbNonlinearTransformInv(rgb[0] / 255);
14814
+ const g = srgbNonlinearTransformInv(rgb[1] / 255);
14815
+ const b = srgbNonlinearTransformInv(rgb[2] / 255);
14816
+ const lp = Math.cbrt(0.412_221_470_8 * r + 0.536_332_536_3 * g + 0.051_445_992_9 * b);
14817
+ const mp = Math.cbrt(0.211_903_498_2 * r + 0.680_699_545_1 * g + 0.107_396_956_6 * b);
14818
+ const sp = Math.cbrt(0.088_302_461_9 * r + 0.281_718_837_6 * g + 0.629_978_700_5 * b);
14819
+ const l = 0.210_454_255_3 * lp + 0.793_617_785 * mp - 0.004_072_046_8 * sp;
14820
+ const aa = 1.977_998_495_1 * lp - 2.428_592_205 * mp + 0.450_593_709_9 * sp;
14821
+ const bb = 0.025_904_037_1 * lp + 0.782_771_766_2 * mp - 0.808_675_766 * sp;
14822
+ return [l * 100, aa * 100, bb * 100];
14823
+ };
14824
+ convert$1.rgb.cmyk = function (rgb) {
14825
+ const r = rgb[0] / 255;
14826
+ const g = rgb[1] / 255;
14827
+ const b = rgb[2] / 255;
14828
+ const k = Math.min(1 - r, 1 - g, 1 - b);
14829
+ const c = (1 - r - k) / (1 - k) || 0;
14830
+ const m = (1 - g - k) / (1 - k) || 0;
14831
+ const y = (1 - b - k) / (1 - k) || 0;
14832
+ return [c * 100, m * 100, y * 100, k * 100];
14833
+ };
14834
+ function comparativeDistance(x, y) {
14835
+ /*
14836
+ See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance
14837
+ */
14838
+ return (x[0] - y[0]) ** 2 + (x[1] - y[1]) ** 2 + (x[2] - y[2]) ** 2;
14839
+ }
14840
+ convert$1.rgb.keyword = function (rgb) {
14841
+ const reversed = reverseKeywords[rgb];
14842
+ if (reversed) {
14843
+ return reversed;
14844
+ }
14845
+ let currentClosestDistance = Number.POSITIVE_INFINITY;
14846
+ let currentClosestKeyword;
14847
+ for (const keyword of Object.keys(cssKeywords)) {
14848
+ const value = cssKeywords[keyword];
14849
+
14850
+ // Compute comparative distance
14851
+ const distance = comparativeDistance(rgb, value);
14852
+
14853
+ // Check if its less, if so set as closest
14854
+ if (distance < currentClosestDistance) {
14855
+ currentClosestDistance = distance;
14856
+ currentClosestKeyword = keyword;
14857
+ }
14858
+ }
14859
+ return currentClosestKeyword;
14860
+ };
14861
+ convert$1.keyword.rgb = function (keyword) {
14862
+ return [...cssKeywords[keyword]];
14863
+ };
14864
+ convert$1.rgb.xyz = function (rgb) {
14865
+ // Assume sRGB
14866
+ const r = srgbNonlinearTransformInv(rgb[0] / 255);
14867
+ const g = srgbNonlinearTransformInv(rgb[1] / 255);
14868
+ const b = srgbNonlinearTransformInv(rgb[2] / 255);
14869
+ const x = r * 0.412_456_4 + g * 0.357_576_1 + b * 0.180_437_5;
14870
+ const y = r * 0.212_672_9 + g * 0.715_152_2 + b * 0.072_175;
14871
+ const z = r * 0.019_333_9 + g * 0.119_192 + b * 0.950_304_1;
14872
+ return [x * 100, y * 100, z * 100];
14873
+ };
14874
+ convert$1.rgb.lab = function (rgb) {
14875
+ const xyz = convert$1.rgb.xyz(rgb);
14876
+ let x = xyz[0];
14877
+ let y = xyz[1];
14878
+ let z = xyz[2];
14879
+ x /= 95.047;
14880
+ y /= 100;
14881
+ z /= 108.883;
14882
+ x = x > LAB_FT ? x ** (1 / 3) : 7.787 * x + 16 / 116;
14883
+ y = y > LAB_FT ? y ** (1 / 3) : 7.787 * y + 16 / 116;
14884
+ z = z > LAB_FT ? z ** (1 / 3) : 7.787 * z + 16 / 116;
14885
+ const l = 116 * y - 16;
14886
+ const a = 500 * (x - y);
14887
+ const b = 200 * (y - z);
14888
+ return [l, a, b];
14889
+ };
14890
+ convert$1.hsl.rgb = function (hsl) {
14891
+ const h = hsl[0] / 360;
14892
+ const s = hsl[1] / 100;
14893
+ const l = hsl[2] / 100;
14894
+ let t3;
14895
+ let value;
14896
+ if (s === 0) {
14897
+ value = l * 255;
14898
+ return [value, value, value];
14899
+ }
14900
+ const t2 = l < 0.5 ? l * (1 + s) : l + s - l * s;
14901
+ const t1 = 2 * l - t2;
14902
+ const rgb = [0, 0, 0];
14903
+ for (let i = 0; i < 3; i++) {
14904
+ t3 = h + 1 / 3 * -(i - 1);
14905
+ if (t3 < 0) {
14906
+ t3++;
14907
+ }
14908
+ if (t3 > 1) {
14909
+ t3--;
14910
+ }
14911
+ if (6 * t3 < 1) {
14912
+ value = t1 + (t2 - t1) * 6 * t3;
14913
+ } else if (2 * t3 < 1) {
14914
+ value = t2;
14915
+ } else if (3 * t3 < 2) {
14916
+ value = t1 + (t2 - t1) * (2 / 3 - t3) * 6;
14917
+ } else {
14918
+ value = t1;
14919
+ }
14920
+ rgb[i] = value * 255;
14921
+ }
14922
+ return rgb;
14923
+ };
14924
+ convert$1.hsl.hsv = function (hsl) {
14925
+ const h = hsl[0];
14926
+ let s = hsl[1] / 100;
14927
+ let l = hsl[2] / 100;
14928
+ let smin = s;
14929
+ const lmin = Math.max(l, 0.01);
14930
+ l *= 2;
14931
+ s *= l <= 1 ? l : 2 - l;
14932
+ smin *= lmin <= 1 ? lmin : 2 - lmin;
14933
+ const v = (l + s) / 2;
14934
+ const sv = l === 0 ? 2 * smin / (lmin + smin) : 2 * s / (l + s);
14935
+ return [h, sv * 100, v * 100];
14936
+ };
14937
+ convert$1.hsv.rgb = function (hsv) {
14938
+ const h = hsv[0] / 60;
14939
+ const s = hsv[1] / 100;
14940
+ let v = hsv[2] / 100;
14941
+ const hi = Math.floor(h) % 6;
14942
+ const f = h - Math.floor(h);
14943
+ const p = 255 * v * (1 - s);
14944
+ const q = 255 * v * (1 - s * f);
14945
+ const t = 255 * v * (1 - s * (1 - f));
14946
+ v *= 255;
14947
+ switch (hi) {
14948
+ case 0:
14949
+ {
14950
+ return [v, t, p];
14951
+ }
14952
+ case 1:
14953
+ {
14954
+ return [q, v, p];
14955
+ }
14956
+ case 2:
14957
+ {
14958
+ return [p, v, t];
14959
+ }
14960
+ case 3:
14961
+ {
14962
+ return [p, q, v];
14963
+ }
14964
+ case 4:
14965
+ {
14966
+ return [t, p, v];
14967
+ }
14968
+ case 5:
14969
+ {
14970
+ return [v, p, q];
14971
+ }
14972
+ }
14973
+ };
14974
+ convert$1.hsv.hsl = function (hsv) {
14975
+ const h = hsv[0];
14976
+ const s = hsv[1] / 100;
14977
+ const v = hsv[2] / 100;
14978
+ const vmin = Math.max(v, 0.01);
14979
+ let sl;
14980
+ let l;
14981
+ l = (2 - s) * v;
14982
+ const lmin = (2 - s) * vmin;
14983
+ sl = s * vmin;
14984
+ sl /= lmin <= 1 ? lmin : 2 - lmin;
14985
+ sl = sl || 0;
14986
+ l /= 2;
14987
+ return [h, sl * 100, l * 100];
14988
+ };
14989
+
14990
+ // http://dev.w3.org/csswg/css-color/#hwb-to-rgb
14991
+ convert$1.hwb.rgb = function (hwb) {
14992
+ const h = hwb[0] / 360;
14993
+ let wh = hwb[1] / 100;
14994
+ let bl = hwb[2] / 100;
14995
+ const ratio = wh + bl;
14996
+ let f;
14997
+
14998
+ // Wh + bl cant be > 1
14999
+ if (ratio > 1) {
15000
+ wh /= ratio;
15001
+ bl /= ratio;
15002
+ }
15003
+ const i = Math.floor(6 * h);
15004
+ const v = 1 - bl;
15005
+ f = 6 * h - i;
15006
+
15007
+ // eslint-disable-next-line no-bitwise
15008
+ if ((i & 0x01) !== 0) {
15009
+ f = 1 - f;
15010
+ }
15011
+ const n = wh + f * (v - wh); // Linear interpolation
15012
+
15013
+ let r;
15014
+ let g;
15015
+ let b;
15016
+ /* eslint-disable max-statements-per-line,no-multi-spaces, default-case-last */
15017
+ switch (i) {
15018
+ default:
15019
+ case 6:
15020
+ case 0:
15021
+ {
15022
+ r = v;
15023
+ g = n;
15024
+ b = wh;
15025
+ break;
15026
+ }
15027
+ case 1:
15028
+ {
15029
+ r = n;
15030
+ g = v;
15031
+ b = wh;
15032
+ break;
15033
+ }
15034
+ case 2:
15035
+ {
15036
+ r = wh;
15037
+ g = v;
15038
+ b = n;
15039
+ break;
15040
+ }
15041
+ case 3:
15042
+ {
15043
+ r = wh;
15044
+ g = n;
15045
+ b = v;
15046
+ break;
15047
+ }
15048
+ case 4:
15049
+ {
15050
+ r = n;
15051
+ g = wh;
15052
+ b = v;
15053
+ break;
15054
+ }
15055
+ case 5:
15056
+ {
15057
+ r = v;
15058
+ g = wh;
15059
+ b = n;
15060
+ break;
15061
+ }
15062
+ }
15063
+ /* eslint-enable max-statements-per-line,no-multi-spaces, default-case-last */
15064
+
15065
+ return [r * 255, g * 255, b * 255];
15066
+ };
15067
+ convert$1.cmyk.rgb = function (cmyk) {
15068
+ const c = cmyk[0] / 100;
15069
+ const m = cmyk[1] / 100;
15070
+ const y = cmyk[2] / 100;
15071
+ const k = cmyk[3] / 100;
15072
+ const r = 1 - Math.min(1, c * (1 - k) + k);
15073
+ const g = 1 - Math.min(1, m * (1 - k) + k);
15074
+ const b = 1 - Math.min(1, y * (1 - k) + k);
15075
+ return [r * 255, g * 255, b * 255];
15076
+ };
15077
+ convert$1.xyz.rgb = function (xyz) {
15078
+ const x = xyz[0] / 100;
15079
+ const y = xyz[1] / 100;
15080
+ const z = xyz[2] / 100;
15081
+ let r;
15082
+ let g;
15083
+ let b;
15084
+ r = x * 3.240_454_2 + y * -1.5371385 + z * -0.4985314;
15085
+ g = x * -0.969266 + y * 1.876_010_8 + z * 0.041_556;
15086
+ b = x * 0.055_643_4 + y * -0.2040259 + z * 1.057_225_2;
15087
+
15088
+ // Assume sRGB
15089
+ r = srgbNonlinearTransform(r);
15090
+ g = srgbNonlinearTransform(g);
15091
+ b = srgbNonlinearTransform(b);
15092
+ return [r * 255, g * 255, b * 255];
15093
+ };
15094
+ convert$1.xyz.lab = function (xyz) {
15095
+ let x = xyz[0];
15096
+ let y = xyz[1];
15097
+ let z = xyz[2];
15098
+ x /= 95.047;
15099
+ y /= 100;
15100
+ z /= 108.883;
15101
+ x = x > LAB_FT ? x ** (1 / 3) : 7.787 * x + 16 / 116;
15102
+ y = y > LAB_FT ? y ** (1 / 3) : 7.787 * y + 16 / 116;
15103
+ z = z > LAB_FT ? z ** (1 / 3) : 7.787 * z + 16 / 116;
15104
+ const l = 116 * y - 16;
15105
+ const a = 500 * (x - y);
15106
+ const b = 200 * (y - z);
15107
+ return [l, a, b];
15108
+ };
15109
+ convert$1.xyz.oklab = function (xyz) {
15110
+ const x = xyz[0] / 100;
15111
+ const y = xyz[1] / 100;
15112
+ const z = xyz[2] / 100;
15113
+ const lp = Math.cbrt(0.818_933_010_1 * x + 0.361_866_742_4 * y - 0.128_859_713_7 * z);
15114
+ const mp = Math.cbrt(0.032_984_543_6 * x + 0.929_311_871_5 * y + 0.036_145_638_7 * z);
15115
+ const sp = Math.cbrt(0.048_200_301_8 * x + 0.264_366_269_1 * y + 0.633_851_707 * z);
15116
+ const l = 0.210_454_255_3 * lp + 0.793_617_785 * mp - 0.004_072_046_8 * sp;
15117
+ const a = 1.977_998_495_1 * lp - 2.428_592_205 * mp + 0.450_593_709_9 * sp;
15118
+ const b = 0.025_904_037_1 * lp + 0.782_771_766_2 * mp - 0.808_675_766 * sp;
15119
+ return [l * 100, a * 100, b * 100];
15120
+ };
15121
+ convert$1.oklab.oklch = function (oklab) {
15122
+ return convert$1.lab.lch(oklab);
15123
+ };
15124
+ convert$1.oklab.xyz = function (oklab) {
15125
+ const ll = oklab[0] / 100;
15126
+ const a = oklab[1] / 100;
15127
+ const b = oklab[2] / 100;
15128
+ const l = (0.999_999_998 * ll + 0.396_337_792 * a + 0.215_803_758 * b) ** 3;
15129
+ const m = (1.000_000_008 * ll - 0.105_561_342 * a - 0.063_854_175 * b) ** 3;
15130
+ const s = (1.000_000_055 * ll - 0.089_484_182 * a - 1.291_485_538 * b) ** 3;
15131
+ const x = 1.227_013_851 * l - 0.557_799_98 * m + 0.281_256_149 * s;
15132
+ const y = -0.040580178 * l + 1.112_256_87 * m - 0.071_676_679 * s;
15133
+ const z = -0.076381285 * l - 0.421_481_978 * m + 1.586_163_22 * s;
15134
+ return [x * 100, y * 100, z * 100];
15135
+ };
15136
+ convert$1.oklab.rgb = function (oklab) {
15137
+ const ll = oklab[0] / 100;
15138
+ const aa = oklab[1] / 100;
15139
+ const bb = oklab[2] / 100;
15140
+ const l = (ll + 0.396_337_777_4 * aa + 0.215_803_757_3 * bb) ** 3;
15141
+ const m = (ll - 0.105_561_345_8 * aa - 0.063_854_172_8 * bb) ** 3;
15142
+ const s = (ll - 0.089_484_177_5 * aa - 1.291_485_548 * bb) ** 3;
15143
+
15144
+ // Assume sRGB
15145
+ const r = srgbNonlinearTransform(4.076_741_662_1 * l - 3.307_711_591_3 * m + 0.230_969_929_2 * s);
15146
+ const g = srgbNonlinearTransform(-1.2684380046 * l + 2.609_757_401_1 * m - 0.341_319_396_5 * s);
15147
+ const b = srgbNonlinearTransform(-0.0041960863 * l - 0.703_418_614_7 * m + 1.707_614_701 * s);
15148
+ return [r * 255, g * 255, b * 255];
15149
+ };
15150
+ convert$1.oklch.oklab = function (oklch) {
15151
+ return convert$1.lch.lab(oklch);
15152
+ };
15153
+ convert$1.lab.xyz = function (lab) {
15154
+ const l = lab[0];
15155
+ const a = lab[1];
15156
+ const b = lab[2];
15157
+ let x;
15158
+ let y;
15159
+ let z;
15160
+ y = (l + 16) / 116;
15161
+ x = a / 500 + y;
15162
+ z = y - b / 200;
15163
+ const y2 = y ** 3;
15164
+ const x2 = x ** 3;
15165
+ const z2 = z ** 3;
15166
+ y = y2 > LAB_FT ? y2 : (y - 16 / 116) / 7.787;
15167
+ x = x2 > LAB_FT ? x2 : (x - 16 / 116) / 7.787;
15168
+ z = z2 > LAB_FT ? z2 : (z - 16 / 116) / 7.787;
15169
+
15170
+ // Illuminant D65 XYZ Tristrimulus Values
15171
+ // https://en.wikipedia.org/wiki/CIE_1931_color_space
15172
+ x *= 95.047;
15173
+ y *= 100;
15174
+ z *= 108.883;
15175
+ return [x, y, z];
15176
+ };
15177
+ convert$1.lab.lch = function (lab) {
15178
+ const l = lab[0];
15179
+ const a = lab[1];
15180
+ const b = lab[2];
15181
+ let h;
15182
+ const hr = Math.atan2(b, a);
15183
+ h = hr * 360 / 2 / Math.PI;
15184
+ if (h < 0) {
15185
+ h += 360;
15186
+ }
15187
+ const c = Math.sqrt(a * a + b * b);
15188
+ return [l, c, h];
15189
+ };
15190
+ convert$1.lch.lab = function (lch) {
15191
+ const l = lch[0];
15192
+ const c = lch[1];
15193
+ const h = lch[2];
15194
+ const hr = h / 360 * 2 * Math.PI;
15195
+ const a = c * Math.cos(hr);
15196
+ const b = c * Math.sin(hr);
15197
+ return [l, a, b];
15198
+ };
15199
+ convert$1.rgb.ansi16 = function (args, saturation = null) {
15200
+ const [r, g, b] = args;
15201
+ let value = saturation === null ? convert$1.rgb.hsv(args)[2] : saturation; // Hsv -> ansi16 optimization
15202
+
15203
+ value = Math.round(value / 50);
15204
+ if (value === 0) {
15205
+ return 30;
15206
+ }
15207
+ let ansi = 30
15208
+ /* eslint-disable no-bitwise */ + (Math.round(b / 255) << 2 | Math.round(g / 255) << 1 | Math.round(r / 255));
15209
+ /* eslint-enable no-bitwise */
15210
+
15211
+ if (value === 2) {
15212
+ ansi += 60;
15213
+ }
15214
+ return ansi;
15215
+ };
15216
+ convert$1.hsv.ansi16 = function (args) {
15217
+ // Optimization here; we already know the value and don't need to get
15218
+ // it converted for us.
15219
+ return convert$1.rgb.ansi16(convert$1.hsv.rgb(args), args[2]);
15220
+ };
15221
+ convert$1.rgb.ansi256 = function (args) {
15222
+ const r = args[0];
15223
+ const g = args[1];
15224
+ const b = args[2];
15225
+
15226
+ // We use the extended greyscale palette here, with the exception of
15227
+ // black and white. normal palette only has 4 greyscale shades.
15228
+ // eslint-disable-next-line no-bitwise
15229
+ if (r >> 4 === g >> 4 && g >> 4 === b >> 4) {
15230
+ if (r < 8) {
15231
+ return 16;
15232
+ }
15233
+ if (r > 248) {
15234
+ return 231;
15235
+ }
15236
+ return Math.round((r - 8) / 247 * 24) + 232;
15237
+ }
15238
+ const ansi = 16 + 36 * Math.round(r / 255 * 5) + 6 * Math.round(g / 255 * 5) + Math.round(b / 255 * 5);
15239
+ return ansi;
15240
+ };
15241
+ convert$1.ansi16.rgb = function (args) {
15242
+ args = args[0];
15243
+ let color = args % 10;
15244
+
15245
+ // Handle greyscale
15246
+ if (color === 0 || color === 7) {
15247
+ if (args > 50) {
15248
+ color += 3.5;
15249
+ }
15250
+ color = color / 10.5 * 255;
15251
+ return [color, color, color];
15252
+ }
15253
+ const mult = (Math.trunc(args > 50) + 1) * 0.5;
15254
+ /* eslint-disable no-bitwise */
15255
+ const r = (color & 1) * mult * 255;
15256
+ const g = (color >> 1 & 1) * mult * 255;
15257
+ const b = (color >> 2 & 1) * mult * 255;
15258
+ /* eslint-enable no-bitwise */
15259
+
15260
+ return [r, g, b];
15261
+ };
15262
+ convert$1.ansi256.rgb = function (args) {
15263
+ args = args[0];
15264
+
15265
+ // Handle greyscale
15266
+ if (args >= 232) {
15267
+ const c = (args - 232) * 10 + 8;
15268
+ return [c, c, c];
15269
+ }
15270
+ args -= 16;
15271
+ let rem;
15272
+ const r = Math.floor(args / 36) / 5 * 255;
15273
+ const g = Math.floor((rem = args % 36) / 6) / 5 * 255;
15274
+ const b = rem % 6 / 5 * 255;
15275
+ return [r, g, b];
15276
+ };
15277
+ convert$1.rgb.hex = function (args) {
15278
+ /* eslint-disable no-bitwise */
15279
+ const integer = ((Math.round(args[0]) & 0xFF) << 16) + ((Math.round(args[1]) & 0xFF) << 8) + (Math.round(args[2]) & 0xFF);
15280
+ /* eslint-enable no-bitwise */
15281
+
15282
+ const string = integer.toString(16).toUpperCase();
15283
+ return '000000'.slice(string.length) + string;
15284
+ };
15285
+ convert$1.hex.rgb = function (args) {
15286
+ const match = args.toString(16).match(/[a-f\d]{6}|[a-f\d]{3}/i);
15287
+ if (!match) {
15288
+ return [0, 0, 0];
15289
+ }
15290
+ let colorString = match[0];
15291
+ if (match[0].length === 3) {
15292
+ colorString = [...colorString].map(char => char + char).join('');
15293
+ }
15294
+ const integer = Number.parseInt(colorString, 16);
15295
+ /* eslint-disable no-bitwise */
15296
+ const r = integer >> 16 & 0xFF;
15297
+ const g = integer >> 8 & 0xFF;
15298
+ const b = integer & 0xFF;
15299
+ /* eslint-enable no-bitwise */
15300
+
15301
+ return [r, g, b];
15302
+ };
15303
+ convert$1.rgb.hcg = function (rgb) {
15304
+ const r = rgb[0] / 255;
15305
+ const g = rgb[1] / 255;
15306
+ const b = rgb[2] / 255;
15307
+ const max = Math.max(Math.max(r, g), b);
15308
+ const min = Math.min(Math.min(r, g), b);
15309
+ const chroma = max - min;
15310
+ let hue;
15311
+ const grayscale = chroma < 1 ? min / (1 - chroma) : 0;
15312
+ if (chroma <= 0) {
15313
+ hue = 0;
15314
+ } else if (max === r) {
15315
+ hue = (g - b) / chroma % 6;
15316
+ } else if (max === g) {
15317
+ hue = 2 + (b - r) / chroma;
15318
+ } else {
15319
+ hue = 4 + (r - g) / chroma;
15320
+ }
15321
+ hue /= 6;
15322
+ hue %= 1;
15323
+ return [hue * 360, chroma * 100, grayscale * 100];
15324
+ };
15325
+ convert$1.hsl.hcg = function (hsl) {
15326
+ const s = hsl[1] / 100;
15327
+ const l = hsl[2] / 100;
15328
+ const c = l < 0.5 ? 2 * s * l : 2 * s * (1 - l);
15329
+ let f = 0;
15330
+ if (c < 1) {
15331
+ f = (l - 0.5 * c) / (1 - c);
15332
+ }
15333
+ return [hsl[0], c * 100, f * 100];
15334
+ };
15335
+ convert$1.hsv.hcg = function (hsv) {
15336
+ const s = hsv[1] / 100;
15337
+ const v = hsv[2] / 100;
15338
+ const c = s * v;
15339
+ let f = 0;
15340
+ if (c < 1) {
15341
+ f = (v - c) / (1 - c);
15342
+ }
15343
+ return [hsv[0], c * 100, f * 100];
15344
+ };
15345
+ convert$1.hcg.rgb = function (hcg) {
15346
+ const h = hcg[0] / 360;
15347
+ const c = hcg[1] / 100;
15348
+ const g = hcg[2] / 100;
15349
+ if (c === 0) {
15350
+ return [g * 255, g * 255, g * 255];
15351
+ }
15352
+ const pure = [0, 0, 0];
15353
+ const hi = h % 1 * 6;
15354
+ const v = hi % 1;
15355
+ const w = 1 - v;
15356
+ let mg = 0;
15357
+
15358
+ /* eslint-disable max-statements-per-line */
15359
+ switch (Math.floor(hi)) {
15360
+ case 0:
15361
+ {
15362
+ pure[0] = 1;
15363
+ pure[1] = v;
15364
+ pure[2] = 0;
15365
+ break;
15366
+ }
15367
+ case 1:
15368
+ {
15369
+ pure[0] = w;
15370
+ pure[1] = 1;
15371
+ pure[2] = 0;
15372
+ break;
15373
+ }
15374
+ case 2:
15375
+ {
15376
+ pure[0] = 0;
15377
+ pure[1] = 1;
15378
+ pure[2] = v;
15379
+ break;
15380
+ }
15381
+ case 3:
15382
+ {
15383
+ pure[0] = 0;
15384
+ pure[1] = w;
15385
+ pure[2] = 1;
15386
+ break;
15387
+ }
15388
+ case 4:
15389
+ {
15390
+ pure[0] = v;
15391
+ pure[1] = 0;
15392
+ pure[2] = 1;
15393
+ break;
15394
+ }
15395
+ default:
15396
+ {
15397
+ pure[0] = 1;
15398
+ pure[1] = 0;
15399
+ pure[2] = w;
15400
+ }
15401
+ }
15402
+ /* eslint-enable max-statements-per-line */
15403
+
15404
+ mg = (1 - c) * g;
15405
+ return [(c * pure[0] + mg) * 255, (c * pure[1] + mg) * 255, (c * pure[2] + mg) * 255];
15406
+ };
15407
+ convert$1.hcg.hsv = function (hcg) {
15408
+ const c = hcg[1] / 100;
15409
+ const g = hcg[2] / 100;
15410
+ const v = c + g * (1 - c);
15411
+ let f = 0;
15412
+ if (v > 0) {
15413
+ f = c / v;
15414
+ }
15415
+ return [hcg[0], f * 100, v * 100];
15416
+ };
15417
+ convert$1.hcg.hsl = function (hcg) {
15418
+ const c = hcg[1] / 100;
15419
+ const g = hcg[2] / 100;
15420
+ const l = g * (1 - c) + 0.5 * c;
15421
+ let s = 0;
15422
+ if (l > 0 && l < 0.5) {
15423
+ s = c / (2 * l);
15424
+ } else if (l >= 0.5 && l < 1) {
15425
+ s = c / (2 * (1 - l));
15426
+ }
15427
+ return [hcg[0], s * 100, l * 100];
15428
+ };
15429
+ convert$1.hcg.hwb = function (hcg) {
15430
+ const c = hcg[1] / 100;
15431
+ const g = hcg[2] / 100;
15432
+ const v = c + g * (1 - c);
15433
+ return [hcg[0], (v - c) * 100, (1 - v) * 100];
15434
+ };
15435
+ convert$1.hwb.hcg = function (hwb) {
15436
+ const w = hwb[1] / 100;
15437
+ const b = hwb[2] / 100;
15438
+ const v = 1 - b;
15439
+ const c = v - w;
15440
+ let g = 0;
15441
+ if (c < 1) {
15442
+ g = (v - c) / (1 - c);
15443
+ }
15444
+ return [hwb[0], c * 100, g * 100];
15445
+ };
15446
+ convert$1.apple.rgb = function (apple) {
15447
+ return [apple[0] / 65_535 * 255, apple[1] / 65_535 * 255, apple[2] / 65_535 * 255];
15448
+ };
15449
+ convert$1.rgb.apple = function (rgb) {
15450
+ return [rgb[0] / 255 * 65_535, rgb[1] / 255 * 65_535, rgb[2] / 255 * 65_535];
15451
+ };
15452
+ convert$1.gray.rgb = function (args) {
15453
+ return [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255];
15454
+ };
15455
+ convert$1.gray.hsl = function (args) {
15456
+ return [0, 0, args[0]];
15457
+ };
15458
+ convert$1.gray.hsv = convert$1.gray.hsl;
15459
+ convert$1.gray.hwb = function (gray) {
15460
+ return [0, 100, gray[0]];
15461
+ };
15462
+ convert$1.gray.cmyk = function (gray) {
15463
+ return [0, 0, 0, gray[0]];
15464
+ };
15465
+ convert$1.gray.lab = function (gray) {
15466
+ return [gray[0], 0, 0];
15467
+ };
15468
+ convert$1.gray.hex = function (gray) {
15469
+ /* eslint-disable no-bitwise */
15470
+ const value = Math.round(gray[0] / 100 * 255) & 0xFF;
15471
+ const integer = (value << 16) + (value << 8) + value;
15472
+ /* eslint-enable no-bitwise */
15473
+
15474
+ const string = integer.toString(16).toUpperCase();
15475
+ return '000000'.slice(string.length) + string;
15476
+ };
15477
+ convert$1.rgb.gray = function (rgb) {
15478
+ const value = (rgb[0] + rgb[1] + rgb[2]) / 3;
15479
+ return [value / 255 * 100];
15480
+ };
15481
+
15482
+ /*
15483
+ This function routes a model to all other models.
15484
+
15485
+ all functions that are routed have a property `.conversion` attached
15486
+ to the returned synthetic function. This property is an array
15487
+ of strings, each with the steps in between the 'from' and 'to'
15488
+ color models (inclusive).
15489
+
15490
+ conversions that are not possible simply are not included.
15491
+ */
15492
+
15493
+ function buildGraph() {
15494
+ const graph = {};
15495
+ // https://jsperf.com/object-keys-vs-for-in-with-closure/3
15496
+ const models = Object.keys(convert$1);
15497
+ for (let {
15498
+ length
15499
+ } = models, i = 0; i < length; i++) {
15500
+ graph[models[i]] = {
15501
+ // http://jsperf.com/1-vs-infinity
15502
+ // micro-opt, but this is simple.
15503
+ distance: -1,
15504
+ parent: null
15505
+ };
15506
+ }
15507
+ return graph;
15508
+ }
15509
+
15510
+ // https://en.wikipedia.org/wiki/Breadth-first_search
15511
+ function deriveBFS(fromModel) {
15512
+ const graph = buildGraph();
15513
+ const queue = [fromModel]; // Unshift -> queue -> pop
15514
+
15515
+ graph[fromModel].distance = 0;
15516
+ while (queue.length > 0) {
15517
+ const current = queue.pop();
15518
+ const adjacents = Object.keys(convert$1[current]);
15519
+ for (let {
15520
+ length
15521
+ } = adjacents, i = 0; i < length; i++) {
15522
+ const adjacent = adjacents[i];
15523
+ const node = graph[adjacent];
15524
+ if (node.distance === -1) {
15525
+ node.distance = graph[current].distance + 1;
15526
+ node.parent = current;
15527
+ queue.unshift(adjacent);
15528
+ }
15529
+ }
15530
+ }
15531
+ return graph;
15532
+ }
15533
+ function link(from, to) {
15534
+ return function (args) {
15535
+ return to(from(args));
15536
+ };
15537
+ }
15538
+ function wrapConversion(toModel, graph) {
15539
+ const path = [graph[toModel].parent, toModel];
15540
+ let fn = convert$1[graph[toModel].parent][toModel];
15541
+ let cur = graph[toModel].parent;
15542
+ while (graph[cur].parent) {
15543
+ path.unshift(graph[cur].parent);
15544
+ fn = link(convert$1[graph[cur].parent][cur], fn);
15545
+ cur = graph[cur].parent;
15546
+ }
15547
+ fn.conversion = path;
15548
+ return fn;
15549
+ }
15550
+ function route(fromModel) {
15551
+ const graph = deriveBFS(fromModel);
15552
+ const conversion = {};
15553
+ const models = Object.keys(graph);
15554
+ for (let {
15555
+ length
15556
+ } = models, i = 0; i < length; i++) {
15557
+ const toModel = models[i];
15558
+ const node = graph[toModel];
15559
+ if (node.parent === null) {
15560
+ // No possible conversion, or this node is the source model.
15561
+ continue;
15562
+ }
15563
+ conversion[toModel] = wrapConversion(toModel, graph);
15564
+ }
15565
+ return conversion;
15566
+ }
15567
+
15568
+ const convert = {};
15569
+ const models = Object.keys(convert$1);
15570
+ function wrapRaw(fn) {
15571
+ const wrappedFn = function (...args) {
15572
+ const arg0 = args[0];
15573
+ if (arg0 === undefined || arg0 === null) {
15574
+ return arg0;
15575
+ }
15576
+ if (arg0.length > 1) {
15577
+ args = arg0;
15578
+ }
15579
+ return fn(args);
15580
+ };
15581
+
15582
+ // Preserve .conversion property if there is one
15583
+ if ('conversion' in fn) {
15584
+ wrappedFn.conversion = fn.conversion;
15585
+ }
15586
+ return wrappedFn;
15587
+ }
15588
+ function wrapRounded(fn) {
15589
+ const wrappedFn = function (...args) {
15590
+ const arg0 = args[0];
15591
+ if (arg0 === undefined || arg0 === null) {
15592
+ return arg0;
15593
+ }
15594
+ if (arg0.length > 1) {
15595
+ args = arg0;
15596
+ }
15597
+ const result = fn(args);
15598
+
15599
+ // We're assuming the result is an array here.
15600
+ // see notice in conversions.js; don't use box types
15601
+ // in conversion functions.
15602
+ if (typeof result === 'object') {
15603
+ for (let {
15604
+ length
15605
+ } = result, i = 0; i < length; i++) {
15606
+ result[i] = Math.round(result[i]);
15607
+ }
15608
+ }
15609
+ return result;
15610
+ };
15611
+
15612
+ // Preserve .conversion property if there is one
15613
+ if ('conversion' in fn) {
15614
+ wrappedFn.conversion = fn.conversion;
15615
+ }
15616
+ return wrappedFn;
15617
+ }
15618
+ for (const fromModel of models) {
15619
+ convert[fromModel] = {};
15620
+ Object.defineProperty(convert[fromModel], 'channels', {
15621
+ value: convert$1[fromModel].channels
15622
+ });
15623
+ Object.defineProperty(convert[fromModel], 'labels', {
15624
+ value: convert$1[fromModel].labels
15625
+ });
15626
+ const routes = route(fromModel);
15627
+ const routeModels = Object.keys(routes);
15628
+ for (const toModel of routeModels) {
15629
+ const fn = routes[toModel];
15630
+ convert[fromModel][toModel] = wrapRounded(fn);
15631
+ convert[fromModel][toModel].raw = wrapRaw(fn);
15632
+ }
15633
+ }
15634
+
15635
+ const skippedModels = [
15636
+ // To be honest, I don't really feel like keyword belongs in color convert, but eh.
15637
+ 'keyword',
15638
+ // Gray conflicts with some method names, and has its own method defined.
15639
+ 'gray',
15640
+ // Shouldn't really be in color-convert either...
15641
+ 'hex'];
15642
+ const hashedModelKeys = {};
15643
+ for (const model of Object.keys(convert)) {
15644
+ hashedModelKeys[[...convert[model].labels].sort().join('')] = model;
15645
+ }
15646
+ const limiters = {};
15647
+ function Color(object, model) {
15648
+ if (!(this instanceof Color)) {
15649
+ return new Color(object, model);
15650
+ }
15651
+ if (model && model in skippedModels) {
15652
+ model = null;
15653
+ }
15654
+ if (model && !(model in convert)) {
15655
+ throw new Error('Unknown model: ' + model);
15656
+ }
15657
+ let i;
15658
+ let channels;
15659
+ if (object == null) {
15660
+ // eslint-disable-line no-eq-null,eqeqeq
15661
+ this.model = 'rgb';
15662
+ this.color = [0, 0, 0];
15663
+ this.valpha = 1;
15664
+ } else if (object instanceof Color) {
15665
+ this.model = object.model;
15666
+ this.color = [...object.color];
15667
+ this.valpha = object.valpha;
15668
+ } else if (typeof object === 'string') {
15669
+ const result = cs.get(object);
15670
+ if (result === null) {
15671
+ throw new Error('Unable to parse color from string: ' + object);
15672
+ }
15673
+ this.model = result.model;
15674
+ channels = convert[this.model].channels;
15675
+ this.color = result.value.slice(0, channels);
15676
+ this.valpha = typeof result.value[channels] === 'number' ? result.value[channels] : 1;
15677
+ } else if (object.length > 0) {
15678
+ this.model = model || 'rgb';
15679
+ channels = convert[this.model].channels;
15680
+ const newArray = Array.prototype.slice.call(object, 0, channels);
15681
+ this.color = zeroArray(newArray, channels);
15682
+ this.valpha = typeof object[channels] === 'number' ? object[channels] : 1;
15683
+ } else if (typeof object === 'number') {
15684
+ // This is always RGB - can be converted later on.
15685
+ this.model = 'rgb';
15686
+ this.color = [object >> 16 & 0xFF, object >> 8 & 0xFF, object & 0xFF];
15687
+ this.valpha = 1;
15688
+ } else {
15689
+ this.valpha = 1;
15690
+ const keys = Object.keys(object);
15691
+ if ('alpha' in object) {
15692
+ keys.splice(keys.indexOf('alpha'), 1);
15693
+ this.valpha = typeof object.alpha === 'number' ? object.alpha : 0;
15694
+ }
15695
+ const hashedKeys = keys.sort().join('');
15696
+ if (!(hashedKeys in hashedModelKeys)) {
15697
+ throw new Error('Unable to parse color from object: ' + JSON.stringify(object));
15698
+ }
15699
+ this.model = hashedModelKeys[hashedKeys];
15700
+ const {
15701
+ labels
15702
+ } = convert[this.model];
15703
+ const color = [];
15704
+ for (i = 0; i < labels.length; i++) {
15705
+ color.push(object[labels[i]]);
15706
+ }
15707
+ this.color = zeroArray(color);
15708
+ }
15709
+
15710
+ // Perform limitations (clamping, etc.)
15711
+ if (limiters[this.model]) {
15712
+ channels = convert[this.model].channels;
15713
+ for (i = 0; i < channels; i++) {
15714
+ const limit = limiters[this.model][i];
15715
+ if (limit) {
15716
+ this.color[i] = limit(this.color[i]);
15717
+ }
15718
+ }
15719
+ }
15720
+ this.valpha = Math.max(0, Math.min(1, this.valpha));
15721
+ if (Object.freeze) {
15722
+ Object.freeze(this);
15723
+ }
15724
+ }
15725
+ Color.prototype = {
15726
+ toString() {
15727
+ return this.string();
15728
+ },
15729
+ toJSON() {
15730
+ return this[this.model]();
15731
+ },
15732
+ string(places) {
15733
+ let self = this.model in cs.to ? this : this.rgb();
15734
+ self = self.round(typeof places === 'number' ? places : 1);
15735
+ const arguments_ = self.valpha === 1 ? self.color : [...self.color, this.valpha];
15736
+ return cs.to[self.model](...arguments_);
15737
+ },
15738
+ percentString(places) {
15739
+ const self = this.rgb().round(typeof places === 'number' ? places : 1);
15740
+ const arguments_ = self.valpha === 1 ? self.color : [...self.color, this.valpha];
15741
+ return cs.to.rgb.percent(...arguments_);
15742
+ },
15743
+ array() {
15744
+ return this.valpha === 1 ? [...this.color] : [...this.color, this.valpha];
15745
+ },
15746
+ object() {
15747
+ const result = {};
15748
+ const {
15749
+ channels
15750
+ } = convert[this.model];
15751
+ const {
15752
+ labels
15753
+ } = convert[this.model];
15754
+ for (let i = 0; i < channels; i++) {
15755
+ result[labels[i]] = this.color[i];
15756
+ }
15757
+ if (this.valpha !== 1) {
15758
+ result.alpha = this.valpha;
15759
+ }
15760
+ return result;
15761
+ },
15762
+ unitArray() {
15763
+ const rgb = this.rgb().color;
15764
+ rgb[0] /= 255;
15765
+ rgb[1] /= 255;
15766
+ rgb[2] /= 255;
15767
+ if (this.valpha !== 1) {
15768
+ rgb.push(this.valpha);
15769
+ }
15770
+ return rgb;
15771
+ },
15772
+ unitObject() {
15773
+ const rgb = this.rgb().object();
15774
+ rgb.r /= 255;
15775
+ rgb.g /= 255;
15776
+ rgb.b /= 255;
15777
+ if (this.valpha !== 1) {
15778
+ rgb.alpha = this.valpha;
15779
+ }
15780
+ return rgb;
15781
+ },
15782
+ round(places) {
15783
+ places = Math.max(places || 0, 0);
15784
+ return new Color([...this.color.map(roundToPlace(places)), this.valpha], this.model);
15785
+ },
15786
+ alpha(value) {
15787
+ if (value !== undefined) {
15788
+ return new Color([...this.color, Math.max(0, Math.min(1, value))], this.model);
15789
+ }
15790
+ return this.valpha;
15791
+ },
15792
+ // Rgb
15793
+ red: getset('rgb', 0, maxfn(255)),
15794
+ green: getset('rgb', 1, maxfn(255)),
15795
+ blue: getset('rgb', 2, maxfn(255)),
15796
+ hue: getset(['hsl', 'hsv', 'hsl', 'hwb', 'hcg'], 0, value => (value % 360 + 360) % 360),
15797
+ saturationl: getset('hsl', 1, maxfn(100)),
15798
+ lightness: getset('hsl', 2, maxfn(100)),
15799
+ saturationv: getset('hsv', 1, maxfn(100)),
15800
+ value: getset('hsv', 2, maxfn(100)),
15801
+ chroma: getset('hcg', 1, maxfn(100)),
15802
+ gray: getset('hcg', 2, maxfn(100)),
15803
+ white: getset('hwb', 1, maxfn(100)),
15804
+ wblack: getset('hwb', 2, maxfn(100)),
15805
+ cyan: getset('cmyk', 0, maxfn(100)),
15806
+ magenta: getset('cmyk', 1, maxfn(100)),
15807
+ yellow: getset('cmyk', 2, maxfn(100)),
15808
+ black: getset('cmyk', 3, maxfn(100)),
15809
+ x: getset('xyz', 0, maxfn(95.047)),
15810
+ y: getset('xyz', 1, maxfn(100)),
15811
+ z: getset('xyz', 2, maxfn(108.833)),
15812
+ l: getset('lab', 0, maxfn(100)),
15813
+ a: getset('lab', 1),
15814
+ b: getset('lab', 2),
15815
+ keyword(value) {
15816
+ if (value !== undefined) {
15817
+ return new Color(value);
15818
+ }
15819
+ return convert[this.model].keyword(this.color);
15820
+ },
15821
+ hex(value) {
15822
+ if (value !== undefined) {
15823
+ return new Color(value);
15824
+ }
15825
+ return cs.to.hex(...this.rgb().round().color);
15826
+ },
15827
+ hexa(value) {
15828
+ if (value !== undefined) {
15829
+ return new Color(value);
15830
+ }
15831
+ const rgbArray = this.rgb().round().color;
15832
+ let alphaHex = Math.round(this.valpha * 255).toString(16).toUpperCase();
15833
+ if (alphaHex.length === 1) {
15834
+ alphaHex = '0' + alphaHex;
15835
+ }
15836
+ return cs.to.hex(...rgbArray) + alphaHex;
15837
+ },
15838
+ rgbNumber() {
15839
+ const rgb = this.rgb().color;
15840
+ return (rgb[0] & 0xFF) << 16 | (rgb[1] & 0xFF) << 8 | rgb[2] & 0xFF;
15841
+ },
15842
+ luminosity() {
15843
+ // http://www.w3.org/TR/WCAG20/#relativeluminancedef
15844
+ const rgb = this.rgb().color;
15845
+ const lum = [];
15846
+ for (const [i, element] of rgb.entries()) {
15847
+ const chan = element / 255;
15848
+ lum[i] = chan <= 0.04045 ? chan / 12.92 : ((chan + 0.055) / 1.055) ** 2.4;
15849
+ }
15850
+ return 0.2126 * lum[0] + 0.7152 * lum[1] + 0.0722 * lum[2];
15851
+ },
15852
+ contrast(color2) {
15853
+ // http://www.w3.org/TR/WCAG20/#contrast-ratiodef
15854
+ const lum1 = this.luminosity();
15855
+ const lum2 = color2.luminosity();
15856
+ if (lum1 > lum2) {
15857
+ return (lum1 + 0.05) / (lum2 + 0.05);
15858
+ }
15859
+ return (lum2 + 0.05) / (lum1 + 0.05);
15860
+ },
15861
+ level(color2) {
15862
+ // https://www.w3.org/TR/WCAG/#contrast-enhanced
15863
+ const contrastRatio = this.contrast(color2);
15864
+ if (contrastRatio >= 7) {
15865
+ return 'AAA';
15866
+ }
15867
+ return contrastRatio >= 4.5 ? 'AA' : '';
15868
+ },
15869
+ isDark() {
15870
+ // YIQ equation from http://24ways.org/2010/calculating-color-contrast
15871
+ const rgb = this.rgb().color;
15872
+ const yiq = (rgb[0] * 2126 + rgb[1] * 7152 + rgb[2] * 722) / 10000;
15873
+ return yiq < 128;
15874
+ },
15875
+ isLight() {
15876
+ return !this.isDark();
15877
+ },
15878
+ negate() {
15879
+ const rgb = this.rgb();
15880
+ for (let i = 0; i < 3; i++) {
15881
+ rgb.color[i] = 255 - rgb.color[i];
15882
+ }
15883
+ return rgb;
15884
+ },
15885
+ lighten(ratio) {
15886
+ const hsl = this.hsl();
15887
+ hsl.color[2] += hsl.color[2] * ratio;
15888
+ return hsl;
15889
+ },
15890
+ darken(ratio) {
15891
+ const hsl = this.hsl();
15892
+ hsl.color[2] -= hsl.color[2] * ratio;
15893
+ return hsl;
15894
+ },
15895
+ saturate(ratio) {
15896
+ const hsl = this.hsl();
15897
+ hsl.color[1] += hsl.color[1] * ratio;
15898
+ return hsl;
15899
+ },
15900
+ desaturate(ratio) {
15901
+ const hsl = this.hsl();
15902
+ hsl.color[1] -= hsl.color[1] * ratio;
15903
+ return hsl;
15904
+ },
15905
+ whiten(ratio) {
15906
+ const hwb = this.hwb();
15907
+ hwb.color[1] += hwb.color[1] * ratio;
15908
+ return hwb;
15909
+ },
15910
+ blacken(ratio) {
15911
+ const hwb = this.hwb();
15912
+ hwb.color[2] += hwb.color[2] * ratio;
15913
+ return hwb;
15914
+ },
15915
+ grayscale() {
15916
+ // http://en.wikipedia.org/wiki/Grayscale#Converting_colour_to_grayscale
15917
+ const rgb = this.rgb().color;
15918
+ const value = rgb[0] * 0.3 + rgb[1] * 0.59 + rgb[2] * 0.11;
15919
+ return Color.rgb(value, value, value);
15920
+ },
15921
+ fade(ratio) {
15922
+ return this.alpha(this.valpha - this.valpha * ratio);
15923
+ },
15924
+ opaquer(ratio) {
15925
+ return this.alpha(this.valpha + this.valpha * ratio);
15926
+ },
15927
+ rotate(degrees) {
15928
+ const hsl = this.hsl();
15929
+ let hue = hsl.color[0];
15930
+ hue = (hue + degrees) % 360;
15931
+ hue = hue < 0 ? 360 + hue : hue;
15932
+ hsl.color[0] = hue;
15933
+ return hsl;
15934
+ },
15935
+ mix(mixinColor, weight) {
15936
+ // Ported from sass implementation in C
15937
+ // https://github.com/sass/libsass/blob/0e6b4a2850092356aa3ece07c6b249f0221caced/functions.cpp#L209
15938
+ if (!mixinColor || !mixinColor.rgb) {
15939
+ throw new Error('Argument to "mix" was not a Color instance, but rather an instance of ' + typeof mixinColor);
15940
+ }
15941
+ const color1 = mixinColor.rgb();
15942
+ const color2 = this.rgb();
15943
+ const p = weight === undefined ? 0.5 : weight;
15944
+ const w = 2 * p - 1;
15945
+ const a = color1.alpha() - color2.alpha();
15946
+ const w1 = ((w * a === -1 ? w : (w + a) / (1 + w * a)) + 1) / 2;
15947
+ const w2 = 1 - w1;
15948
+ return Color.rgb(w1 * color1.red() + w2 * color2.red(), w1 * color1.green() + w2 * color2.green(), w1 * color1.blue() + w2 * color2.blue(), color1.alpha() * p + color2.alpha() * (1 - p));
15949
+ }
15950
+ };
15951
+
15952
+ // Model conversion methods and static constructors
15953
+ for (const model of Object.keys(convert)) {
15954
+ if (skippedModels.includes(model)) {
15955
+ continue;
15956
+ }
15957
+ const {
15958
+ channels
15959
+ } = convert[model];
15960
+
15961
+ // Conversion methods
15962
+ Color.prototype[model] = function (...arguments_) {
15963
+ if (this.model === model) {
15964
+ return new Color(this);
15965
+ }
15966
+ if (arguments_.length > 0) {
15967
+ return new Color(arguments_, model);
15968
+ }
15969
+ return new Color([...assertArray(convert[this.model][model].raw(this.color)), this.valpha], model);
15970
+ };
15971
+
15972
+ // 'static' construction methods
15973
+ Color[model] = function (...arguments_) {
15974
+ let color = arguments_[0];
15975
+ if (typeof color === 'number') {
15976
+ color = zeroArray(arguments_, channels);
15977
+ }
15978
+ return new Color(color, model);
15979
+ };
15980
+ }
15981
+ function roundTo(number, places) {
15982
+ return Number(number.toFixed(places));
15983
+ }
15984
+ function roundToPlace(places) {
15985
+ return function (number) {
15986
+ return roundTo(number, places);
15987
+ };
15988
+ }
15989
+ function getset(model, channel, modifier) {
15990
+ model = Array.isArray(model) ? model : [model];
15991
+ for (const m of model) {
15992
+ (limiters[m] ||= [])[channel] = modifier;
15993
+ }
15994
+ model = model[0];
15995
+ return function (value) {
15996
+ let result;
15997
+ if (value !== undefined) {
15998
+ if (modifier) {
15999
+ value = modifier(value);
16000
+ }
16001
+ result = this[model]();
16002
+ result.color[channel] = value;
16003
+ return result;
16004
+ }
16005
+ result = this[model]().color[channel];
16006
+ if (modifier) {
16007
+ result = modifier(result);
16008
+ }
16009
+ return result;
16010
+ };
16011
+ }
16012
+ function maxfn(max) {
16013
+ return function (v) {
16014
+ return Math.max(0, Math.min(max, v));
16015
+ };
16016
+ }
16017
+ function assertArray(value) {
16018
+ return Array.isArray(value) ? value : [value];
16019
+ }
16020
+ function zeroArray(array, length) {
16021
+ for (let i = 0; i < length; i++) {
16022
+ if (typeof array[i] !== 'number') {
16023
+ array[i] = 0;
16024
+ }
16025
+ }
16026
+ return array;
16027
+ }
16028
+
16029
+ /*
16030
+ ROCSpace element
16031
+ <roc-space>
16032
+
16033
+ Attributes:
16034
+ FAR; HR;
16035
+ d'; C; zFAR; zHR
16036
+
16037
+ draggable: yes/no
16038
+
16039
+ scale: FAR/HR; zFAR/zHR; d'/C
16040
+ grid: FAR/HR; zFAR/zHR; d'/C
16041
+ isos: d'; C; FAR; HR
16042
+
16043
+ Styles:
16044
+ ??
16045
+ */
16046
+ class ROCSpace extends DecidablesMixinResizeable(DetectableElement) {
16047
+ static get properties() {
16048
+ return {
16049
+ contour: {
16050
+ attribute: 'contour',
16051
+ type: String,
16052
+ reflect: true
16053
+ },
16054
+ point: {
16055
+ attribute: 'point',
16056
+ type: String,
16057
+ reflect: true
16058
+ },
16059
+ isoD: {
16060
+ attribute: 'iso-d',
16061
+ type: String,
16062
+ reflect: true
16063
+ },
16064
+ isoC: {
16065
+ attribute: 'iso-c',
16066
+ type: String,
16067
+ reflect: true
16068
+ },
16069
+ zRoc: {
16070
+ attribute: 'z-roc',
16071
+ type: Boolean,
16072
+ reflect: true
16073
+ },
16074
+ far: {
16075
+ attribute: 'far',
16076
+ type: Number,
16077
+ reflect: true
16078
+ },
16079
+ hr: {
16080
+ attribute: 'hr',
16081
+ type: Number,
16082
+ reflect: true
16083
+ },
16084
+ d: {
16085
+ attribute: false,
16086
+ type: Number,
16087
+ reflect: false
16088
+ },
16089
+ c: {
16090
+ attribute: false,
16091
+ type: Number,
16092
+ reflect: false
16093
+ },
16094
+ s: {
16095
+ attribute: false,
16096
+ type: Number,
16097
+ reflect: false
16098
+ }
16099
+ };
16100
+ }
16101
+ constructor() {
16102
+ super();
16103
+ this.firstUpdate = true;
16104
+ this.drag = false;
16105
+ this.sdt = false;
16106
+ this.contours = ['sensitivity', 'bias', 'accuracy'];
16107
+ this.contour = undefined;
16108
+ this.points = ['all', 'first', 'rest', 'none'];
16109
+ this.point = 'all';
16110
+ this.isoDs = ['all', 'first', 'rest', 'none'];
16111
+ this.isoD = 'first';
16112
+ this.isoCs = ['all', 'first', 'rest', 'none'];
16113
+ this.isoC = 'first';
16114
+ this.zRoc = false;
16115
+ this.far = 0.25;
16116
+ this.hr = 0.75;
16117
+ this.s = SDTMath.s.DEFAULT;
16118
+ this.label = '';
16119
+ this.locations = [{
16120
+ name: 'default',
16121
+ far: this.far,
16122
+ hr: this.hr,
16123
+ s: this.s,
16124
+ label: ''
16125
+ }];
16126
+ this.pointArray = [];
16127
+ this.isoDArray = [];
16128
+ this.isoCArray = [];
16129
+ this.alignState();
16130
+ }
16131
+ alignState() {
16132
+ this.locations[0].hr = this.hr;
16133
+ this.locations[0].far = this.far;
16134
+ this.locations[0].s = this.s;
16135
+ this.locations[0].label = this.label;
16136
+ this.d = SDTMath.hrFar2D(this.hr, this.far, this.s);
16137
+ this.c = SDTMath.hrFar2C(this.hr, this.far, this.s);
16138
+ this.pointArray = [];
16139
+ this.isoDArray = [];
16140
+ this.isoCArray = [];
16141
+ this.locations.forEach((item, index) => {
16142
+ item.d = SDTMath.hrFar2D(item.hr, item.far, item.s);
16143
+ item.c = SDTMath.hrFar2C(item.hr, item.far, item.s);
16144
+ if (index === 0 && (this.point === 'first' || this.point === 'all')) {
16145
+ this.pointArray.push(item);
16146
+ } else if (index > 0 && (this.point === 'rest' || this.point === 'all')) {
16147
+ this.pointArray.push(item);
16148
+ }
16149
+ if (index === 0 && (this.isoD === 'first' || this.isoD === 'all')) {
16150
+ this.isoDArray.push(item);
16151
+ } else if (index > 0 && (this.isoD === 'rest' || this.isoD === 'all')) {
16152
+ this.isoDArray.push(item);
16153
+ }
16154
+ if (index === 0 && (this.isoC === 'first' || this.isoC === 'all')) {
16155
+ this.isoCArray.push(item);
16156
+ } else if (index > 0 && (this.isoC === 'rest' || this.isoC === 'all')) {
16157
+ this.isoCArray.push(item);
16158
+ }
16159
+ });
16160
+ }
16161
+ set(hr, far, name = 'default', label = '', s = 1) {
16162
+ if (name === 'default') {
16163
+ this.hr = hr;
16164
+ this.far = far;
16165
+ this.s = s;
16166
+ this.label = label;
16167
+ }
16168
+ const location = this.locations.find(item => {
16169
+ return item.name === name;
16170
+ });
16171
+ if (location === undefined) {
16172
+ this.locations.push({
16173
+ name: name,
16174
+ far: far,
16175
+ hr: hr,
16176
+ s: s,
16177
+ label: label
16178
+ });
16179
+ } else {
16180
+ location.hr = hr;
16181
+ location.far = far;
16182
+ location.s = s;
16183
+ location.label = label;
16184
+ }
16185
+ this.requestUpdate();
16186
+ }
16187
+ setWithSDT(d, c, name = 'default', label = '', s = 1) {
16188
+ if (name === 'default') {
16189
+ this.hr = SDTMath.dC2Hr(d, c, s);
16190
+ this.far = SDTMath.dC2Far(d, c, s);
16191
+ this.s = s;
16192
+ this.label = label;
16193
+ }
16194
+ const location = this.locations.find(item => {
16195
+ return item.name === name;
16196
+ });
16197
+ if (location === undefined) {
16198
+ this.locations.push({
16199
+ name: name,
16200
+ far: SDTMath.dC2Far(d, c, s),
16201
+ hr: SDTMath.dC2Hr(d, c, s),
16202
+ s: s,
16203
+ label: label
16204
+ });
16205
+ } else {
16206
+ location.hr = SDTMath.dC2Hr(d, c, s);
16207
+ location.far = SDTMath.dC2Far(d, c, s);
16208
+ location.s = s;
16209
+ location.label = label;
16210
+ }
16211
+ this.sdt = true;
16212
+ this.requestUpdate();
16213
+ }
16214
+ static get styles() {
16215
+ return [super.styles, i$3`
16216
+ :host {
16217
+ display: inline-block;
13808
16218
 
13809
16219
  width: 20rem;
13810
16220
  height: 20rem;
@@ -13942,9 +16352,7 @@ class ROCSpace extends DecidablesMixinResizeable(DetectableElement) {
13942
16352
  }
13943
16353
  render() {
13944
16354
  /* eslint-disable-line class-methods-use-this */
13945
- return x$1`
13946
- ${DetectableElement.svgFilters}
13947
- `;
16355
+ return x$1``;
13948
16356
  }
13949
16357
  willUpdate() {
13950
16358
  this.alignState();
@@ -14034,7 +16442,10 @@ class ROCSpace extends DecidablesMixinResizeable(DetectableElement) {
14034
16442
  rem: this.rem
14035
16443
  }]);
14036
16444
  // ENTER
14037
- const svgEnter = svgUpdate.enter().append('svg').classed('main', true);
16445
+ const svgEnter = svgUpdate.enter().append('svg').classed('main', true).each((datum, index, nodes) => {
16446
+ // Filters for shadows
16447
+ B(DetectableElement.svgFilters, nodes[index]);
16448
+ });
14038
16449
  // MERGE
14039
16450
  const svgMerge = svgEnter.merge(svgUpdate).attr('viewBox', `0 0 ${elementSize} ${elementSize}`);
14040
16451
 
@@ -14081,7 +16492,7 @@ class ROCSpace extends DecidablesMixinResizeable(DetectableElement) {
14081
16492
  const contourColorStart = this.getComputedStyleValue(this.contour === 'bias' ? '---color-element-background' : this.contour === 'sensitivity' ? '---color-d' : this.contour === 'accuracy' ? '---color-acc-dark' : null);
14082
16493
  const contourColorEnd = this.getComputedStyleValue(this.contour === 'bias' ? '---color-c' : this.contour === 'sensitivity' ? '---color-element-background' : this.contour === 'accuracy' ? '---color-element-background' : null);
14083
16494
  const contourColor = linear().domain(extent(contourThresholds)).interpolate(() => {
14084
- return interpolateRgb(contourColorStart, contourColorEnd);
16495
+ return interpolateRgb(Color(contourColorStart).hex(), Color(contourColorEnd).hex());
14085
16496
  });
14086
16497
  // DATA-JOIN
14087
16498
  const contourPlotUpdate = underlayerMerge.selectAll('.plot-contour').data([this.contour]);
@@ -14097,10 +16508,17 @@ class ROCSpace extends DecidablesMixinResizeable(DetectableElement) {
14097
16508
  const contoursEnter = contoursUpdate.enter().append('path').classed('contour', true);
14098
16509
  // MERGE
14099
16510
  contoursEnter.merge(contoursUpdate).transition().duration(transitionDuration * 2) // Extra long transition!
14100
- .ease(cubicOut).attr('d', index(identity$1().scale(width / n))) // ????
14101
- .attr('fill', datum => {
16511
+ .ease(cubicOut)
16512
+ // .attr('d', d3.geoPath(d3.geoIdentity().scale(width / n))) // ????
16513
+ .attrTween('d', (datum, index$1, elements) => {
16514
+ const element = elements[index$1];
16515
+ const previous = select(element).attr('d');
16516
+ const current = index(identity$1().scale(width / n))(datum);
16517
+ return interpolatePath(previous, current);
16518
+ }).attr('fill', datum => {
14102
16519
  return contourColor(datum.value);
14103
16520
  });
16521
+
14104
16522
  // EXIT
14105
16523
  contoursUpdate.exit().remove();
14106
16524
 
@@ -14710,6 +17128,7 @@ class SDTModel extends DecidablesMixinResizeable(DetectableElement) {
14710
17128
  filter: url("#shadow-4");
14711
17129
 
14712
17130
  /* HACK: This gets Safari to correctly apply the filter! */
17131
+ /* https://github.com/emilbjorklund/svg-weirdness/issues/27 */
14713
17132
  transform: translateX(0);
14714
17133
  }
14715
17134
 
@@ -14899,9 +17318,7 @@ class SDTModel extends DecidablesMixinResizeable(DetectableElement) {
14899
17318
  }
14900
17319
  render() {
14901
17320
  /* eslint-disable-line class-methods-use-this */
14902
- return x$1`
14903
- ${DetectableElement.svgFilters}
14904
- `;
17321
+ return x$1``;
14905
17322
  }
14906
17323
  sendEvent() {
14907
17324
  this.dispatchEvent(new CustomEvent('sdt-model-change', {
@@ -15071,7 +17488,10 @@ class SDTModel extends DecidablesMixinResizeable(DetectableElement) {
15071
17488
  rem: this.rem
15072
17489
  }]);
15073
17490
  // ENTER
15074
- const svgEnter = svgUpdate.enter().append('svg').classed('main', true);
17491
+ const svgEnter = svgUpdate.enter().append('svg').classed('main', true).each((datum, index, nodes) => {
17492
+ // Filters for shadows
17493
+ B(DetectableElement.svgFilters, nodes[index]);
17494
+ });
15075
17495
  // MERGE
15076
17496
  const svgMerge = svgEnter.merge(svgUpdate).attr('viewBox', `0 0 ${elementWidth} ${elementHeight}`);
15077
17497