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