@likec4/core 1.41.0 → 1.42.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.
Files changed (255) hide show
  1. package/builder/package.json +4 -0
  2. package/compute-view/package.json +4 -0
  3. package/compute-view/relationships/package.json +4 -0
  4. package/dist/builder/index.d.mts +13 -11
  5. package/dist/builder/index.mjs +111 -91
  6. package/dist/compute-view/index.d.mts +8 -7
  7. package/dist/compute-view/index.mjs +14 -11
  8. package/dist/compute-view/relationships-view/index.d.mts +9 -8
  9. package/dist/compute-view/relationships-view/index.mjs +6 -6
  10. package/dist/index.d.mts +7 -7
  11. package/dist/index.mjs +11 -11
  12. package/dist/model/connection/deployment/index.d.mts +11 -10
  13. package/dist/model/connection/deployment/index.mjs +2 -2
  14. package/dist/model/connection/index.d.mts +12 -11
  15. package/dist/model/connection/index.mjs +3 -3
  16. package/dist/model/connection/model/index.d.mts +11 -10
  17. package/dist/model/connection/model/index.mjs +2 -2
  18. package/dist/model/index.d.mts +14 -14
  19. package/dist/model/index.mjs +4 -5
  20. package/dist/shared/{core.Ae86Y3tB.mjs → core.01VTr9qu.mjs} +8 -26
  21. package/dist/shared/core.1vX5a9AY.mjs +86 -0
  22. package/dist/shared/{core.BVNaR17u.mjs → core.B7KhhkRY.mjs} +1 -1
  23. package/dist/shared/core.B85MJLTf.mjs +5 -0
  24. package/dist/shared/{core.DA5vzwZ9.mjs → core.BIqHjQiH.mjs} +56 -42
  25. package/dist/shared/core.BKlholso.mjs +3 -0
  26. package/dist/shared/core.BR4zXDH-.mjs +13 -0
  27. package/dist/shared/{core.CXy1NLUG.mjs → core.BYNkXQ8A.mjs} +21 -12
  28. package/dist/shared/{core.BuoXfSMj.mjs → core.BbE4y-yl.mjs} +1 -1
  29. package/dist/shared/core.BoYfZOBm.mjs +3 -0
  30. package/dist/shared/core.BsSXS-_R.mjs +7 -0
  31. package/dist/shared/{core.DJp8fgok.mjs → core.BzTakU3I.mjs} +14 -10
  32. package/dist/shared/{core.4u1dVmfX.mjs → core.C2TiyjI6.mjs} +2 -2
  33. package/dist/shared/{core.DLpidoWc.mjs → core.C3JowhaZ.mjs} +3 -3
  34. package/dist/shared/{core.CNGyqkJh.mjs → core.C4x8aaWa.mjs} +3 -1
  35. package/dist/shared/{core.BB6zA-UU.mjs → core.C8YY6Uub.mjs} +38 -9
  36. package/dist/shared/{core.Asc11Mjy.mjs → core.C8sl5Y8Z.mjs} +122 -58
  37. package/dist/shared/{core.BvMRMo7Z.mjs → core.CNgZvKb8.mjs} +3 -5198
  38. package/dist/shared/{core.CUG6vpyL.d.mts → core.CQngdcuj.d.mts} +85 -4
  39. package/dist/shared/{core.Be1n9a0i.mjs → core.C_Ni6yHl.mjs} +5 -4
  40. package/dist/shared/core.CbT8JVYL.mjs +5 -0
  41. package/dist/shared/core.CqAJJpK_.mjs +3 -0
  42. package/dist/shared/{core.BXsxn-hf.d.mts → core.D0PjZzIS.d.mts} +27 -15
  43. package/dist/shared/{core.DgesAwC8.d.mts → core.D5fzJWbF.d.mts} +2 -2
  44. package/dist/shared/{core.hfOE3RfK.d.mts → core.DACpKp35.d.mts} +5 -5
  45. package/dist/shared/core.DFi2dOTl.mjs +39548 -0
  46. package/dist/shared/{core.xSQO0XYD.d.mts → core.DIol3syK.d.mts} +2 -2
  47. package/dist/shared/{core.DlG1xWt2.mjs → core.DMMOWQqc.mjs} +3 -2
  48. package/dist/shared/core.DNbUPnve.mjs +3990 -0
  49. package/dist/shared/{core.CCD1ID81.mjs → core.DRJma0Ol.mjs} +4 -3
  50. package/dist/shared/{core.DgttqsJc.mjs → core.DRhg-gVU.mjs} +9 -9
  51. package/dist/shared/core.DSO_rTC2.mjs +5322 -0
  52. package/dist/shared/{core.FUPplpae.d.mts → core.D_vkffV4.d.mts} +4 -2
  53. package/dist/shared/core.DdMJk7nx.d.mts +476 -0
  54. package/dist/shared/{core.BhpgpOep.d.mts → core.Dgs6-nuz.d.mts} +2 -2
  55. package/dist/shared/{core.Be4Jy9Qx.mjs → core.FZ305VYd.mjs} +2 -2
  56. package/dist/shared/core.OHD4KXm9.mjs +5 -0
  57. package/dist/shared/{core.GTgsmXS_.mjs → core.QJD_fcrc.mjs} +2 -2
  58. package/dist/shared/core.RfnaEmgA.mjs +7 -0
  59. package/dist/shared/core.fHR_8Tnq.d.mts +450 -0
  60. package/dist/shared/{core.D0EgVMQK.mjs → core.lRvxPoao.mjs} +14 -12
  61. package/dist/shared/{core.CaT0SUUK.mjs → core.rCeaAqgW.mjs} +1 -84
  62. package/dist/shared/{core.zxTBF_PD.d.mts → core.s9uwOt60.d.mts} +4 -4
  63. package/dist/shared/core.yna0OdV5.d.mts +98 -0
  64. package/dist/styles/index.d.mts +106 -0
  65. package/dist/styles/index.mjs +1 -0
  66. package/dist/types/_aux.d.mts +2 -2
  67. package/dist/types/expression-model.d.mts +3 -4
  68. package/dist/types/expression.d.mts +3 -4
  69. package/dist/types/fqnRef.d.mts +2 -2
  70. package/dist/types/fqnRef.mjs +3 -3
  71. package/dist/types/index.d.mts +8 -8
  72. package/dist/types/index.mjs +150 -5
  73. package/dist/types/scalar.mjs +3 -2
  74. package/dist/utils/graphology/index.d.mts +1864 -0
  75. package/dist/utils/graphology/index.mjs +1 -0
  76. package/dist/utils/index.d.mts +11 -6
  77. package/dist/utils/index.mjs +21 -37
  78. package/dist/utils/iterable/index.d.mts +1 -1
  79. package/dist/utils/iterable/index.mjs +45 -7
  80. package/model/package.json +4 -0
  81. package/package.json +42 -24
  82. package/styles/package.json +4 -0
  83. package/types/package.json +4 -0
  84. package/utils/graphology/package.json +4 -0
  85. package/utils/package.json +4 -0
  86. package/dist/shared/core.6_Vp2iiN.mjs +0 -172
  87. package/dist/shared/core.CUw_2J9j.mjs +0 -47
  88. package/dist/shared/core.CzdwsPmY.d.mts +0 -69
  89. package/dist/shared/core.D-ZGWDDt.d.mts +0 -831
  90. package/dist/shared/core.DoM6aM9N.mjs +0 -7
  91. package/dist/shared/core.ILwny7BV.mjs +0 -38
  92. package/dist/theme/index.d.mts +0 -11
  93. package/dist/theme/index.mjs +0 -232
  94. package/src/builder/Builder.deployment.ts +0 -224
  95. package/src/builder/Builder.deploymentModel.ts +0 -449
  96. package/src/builder/Builder.element.ts +0 -241
  97. package/src/builder/Builder.model.ts +0 -494
  98. package/src/builder/Builder.ts +0 -946
  99. package/src/builder/Builder.view-common.ts +0 -273
  100. package/src/builder/Builder.view-deployment.ts +0 -135
  101. package/src/builder/Builder.view-element.ts +0 -202
  102. package/src/builder/Builder.views.ts +0 -399
  103. package/src/builder/Builder.with.ts +0 -156
  104. package/src/builder/_types.ts +0 -324
  105. package/src/builder/index.ts +0 -11
  106. package/src/compute-view/compute-view.ts +0 -80
  107. package/src/compute-view/deployment-view/_types.ts +0 -38
  108. package/src/compute-view/deployment-view/clean-connections.ts +0 -236
  109. package/src/compute-view/deployment-view/compute.ts +0 -94
  110. package/src/compute-view/deployment-view/memory/index.ts +0 -9
  111. package/src/compute-view/deployment-view/memory/memory.ts +0 -96
  112. package/src/compute-view/deployment-view/predicates/deploymentRefs-where.ts +0 -18
  113. package/src/compute-view/deployment-view/predicates/deploymentRefs.ts +0 -154
  114. package/src/compute-view/deployment-view/predicates/index.ts +0 -8
  115. package/src/compute-view/deployment-view/predicates/relation-direct.ts +0 -243
  116. package/src/compute-view/deployment-view/predicates/relation-in-out.ts +0 -70
  117. package/src/compute-view/deployment-view/predicates/relation-incoming.ts +0 -101
  118. package/src/compute-view/deployment-view/predicates/relation-outgoing.ts +0 -95
  119. package/src/compute-view/deployment-view/predicates/relation-where.ts +0 -18
  120. package/src/compute-view/deployment-view/predicates/utils.ts +0 -282
  121. package/src/compute-view/deployment-view/predicates/wildcard.ts +0 -41
  122. package/src/compute-view/deployment-view/stages/stage-exclude.ts +0 -5
  123. package/src/compute-view/deployment-view/stages/stage-final.ts +0 -245
  124. package/src/compute-view/deployment-view/stages/stage-include.ts +0 -95
  125. package/src/compute-view/deployment-view/utils.ts +0 -297
  126. package/src/compute-view/dynamic-view/compute.ts +0 -312
  127. package/src/compute-view/element-view/_types.ts +0 -47
  128. package/src/compute-view/element-view/clean-connections.ts +0 -117
  129. package/src/compute-view/element-view/compute.ts +0 -324
  130. package/src/compute-view/element-view/memory/NodeGroup.ts +0 -31
  131. package/src/compute-view/element-view/memory/index.ts +0 -10
  132. package/src/compute-view/element-view/memory/memory.ts +0 -178
  133. package/src/compute-view/element-view/memory/stage-exclude.ts +0 -59
  134. package/src/compute-view/element-view/memory/stage-final.ts +0 -129
  135. package/src/compute-view/element-view/memory/stage-include.ts +0 -130
  136. package/src/compute-view/element-view/predicates/_utils.ts +0 -91
  137. package/src/compute-view/element-view/predicates/element-expand.ts +0 -29
  138. package/src/compute-view/element-view/predicates/element-kind-tag.ts +0 -27
  139. package/src/compute-view/element-view/predicates/element-ref.ts +0 -24
  140. package/src/compute-view/element-view/predicates/relation-direct.ts +0 -321
  141. package/src/compute-view/element-view/predicates/relation-in-out.ts +0 -64
  142. package/src/compute-view/element-view/predicates/relation-in.ts +0 -115
  143. package/src/compute-view/element-view/predicates/relation-out.ts +0 -119
  144. package/src/compute-view/element-view/predicates/wildcard.ts +0 -88
  145. package/src/compute-view/element-view/utils.ts +0 -65
  146. package/src/compute-view/index.ts +0 -4
  147. package/src/compute-view/memory/AbstractMemory.ts +0 -45
  148. package/src/compute-view/memory/AbstractStageExclude.ts +0 -215
  149. package/src/compute-view/memory/AbstractStageInclude.ts +0 -200
  150. package/src/compute-view/memory/_types.ts +0 -148
  151. package/src/compute-view/memory/index.ts +0 -5
  152. package/src/compute-view/memory/ops.ts +0 -43
  153. package/src/compute-view/relationships-view/_types.ts +0 -16
  154. package/src/compute-view/relationships-view/compute.ts +0 -159
  155. package/src/compute-view/relationships-view/index.ts +0 -3
  156. package/src/compute-view/relationships-view/layout.ts +0 -358
  157. package/src/compute-view/relationships-view/utils.ts +0 -73
  158. package/src/compute-view/utils/ancestorsOfNode.ts +0 -19
  159. package/src/compute-view/utils/applyCustomElementProperties.ts +0 -107
  160. package/src/compute-view/utils/applyCustomRelationProperties.ts +0 -58
  161. package/src/compute-view/utils/applyViewRuleStyles.ts +0 -73
  162. package/src/compute-view/utils/buildComputedNodes.ts +0 -166
  163. package/src/compute-view/utils/buildElementNotations.ts +0 -64
  164. package/src/compute-view/utils/elementExpressionToPredicate.ts +0 -50
  165. package/src/compute-view/utils/link-nodes-with-edges.ts +0 -56
  166. package/src/compute-view/utils/merge-props-from-relationships.ts +0 -161
  167. package/src/compute-view/utils/relationExpressionToPredicates.ts +0 -55
  168. package/src/compute-view/utils/resolve-extended-views.ts +0 -85
  169. package/src/compute-view/utils/resolve-global-rules.ts +0 -88
  170. package/src/compute-view/utils/topological-sort.ts +0 -256
  171. package/src/compute-view/utils/view-hash.ts +0 -45
  172. package/src/compute-view/utils/with-readable-edges.ts +0 -40
  173. package/src/index.ts +0 -32
  174. package/src/model/DeploymentElementModel.ts +0 -712
  175. package/src/model/DeploymentModel.ts +0 -393
  176. package/src/model/ElementModel.ts +0 -316
  177. package/src/model/LikeC4Model.ts +0 -882
  178. package/src/model/RelationModel.ts +0 -152
  179. package/src/model/connection/Connection.ts +0 -72
  180. package/src/model/connection/deployment/DeploymentConnectionModel.ts +0 -185
  181. package/src/model/connection/deployment/find.ts +0 -120
  182. package/src/model/connection/deployment/index.ts +0 -8
  183. package/src/model/connection/index.ts +0 -22
  184. package/src/model/connection/model/ConnectionModel.ts +0 -158
  185. package/src/model/connection/model/find.ts +0 -117
  186. package/src/model/connection/model/index.ts +0 -8
  187. package/src/model/connection/ops.ts +0 -276
  188. package/src/model/guards.ts +0 -77
  189. package/src/model/index.ts +0 -72
  190. package/src/model/types.ts +0 -67
  191. package/src/model/utils.ts +0 -66
  192. package/src/model/view/EdgeModel.ts +0 -121
  193. package/src/model/view/LikeC4ViewModel.ts +0 -361
  194. package/src/model/view/LikeC4ViewsFolder.ts +0 -151
  195. package/src/model/view/NodeModel.ts +0 -247
  196. package/src/theme/element.ts +0 -61
  197. package/src/theme/index.ts +0 -127
  198. package/src/theme/relationships.ts +0 -54
  199. package/src/types/RichText.ts +0 -205
  200. package/src/types/_aux.ts +0 -317
  201. package/src/types/_common.ts +0 -102
  202. package/src/types/const.ts +0 -34
  203. package/src/types/expression-model.ts +0 -294
  204. package/src/types/expression.ts +0 -313
  205. package/src/types/fqnRef.ts +0 -91
  206. package/src/types/geometry.ts +0 -159
  207. package/src/types/global.ts +0 -21
  208. package/src/types/index.ts +0 -44
  209. package/src/types/model-data.ts +0 -77
  210. package/src/types/model-deployment.ts +0 -78
  211. package/src/types/model-dump.ts +0 -79
  212. package/src/types/model-logical.ts +0 -126
  213. package/src/types/model-spec.ts +0 -88
  214. package/src/types/operators.ts +0 -156
  215. package/src/types/project.ts +0 -14
  216. package/src/types/scalar.ts +0 -162
  217. package/src/types/styles.ts +0 -122
  218. package/src/types/view-changes.ts +0 -32
  219. package/src/types/view-common.ts +0 -157
  220. package/src/types/view-computed.ts +0 -126
  221. package/src/types/view-layouted.ts +0 -94
  222. package/src/types/view-parsed.deployment.ts +0 -39
  223. package/src/types/view-parsed.dynamic.ts +0 -89
  224. package/src/types/view-parsed.element.ts +0 -65
  225. package/src/types/view.ts +0 -113
  226. package/src/utils/common-head.ts +0 -22
  227. package/src/utils/compare-natural.ts +0 -60
  228. package/src/utils/const.ts +0 -1
  229. package/src/utils/fqn.ts +0 -302
  230. package/src/utils/getOrCreate.ts +0 -8
  231. package/src/utils/guards.ts +0 -9
  232. package/src/utils/index.ts +0 -68
  233. package/src/utils/invariant.ts +0 -29
  234. package/src/utils/iterable/_types.ts +0 -5
  235. package/src/utils/iterable/filter.ts +0 -55
  236. package/src/utils/iterable/find.ts +0 -38
  237. package/src/utils/iterable/first.ts +0 -48
  238. package/src/utils/iterable/flat.ts +0 -17
  239. package/src/utils/iterable/head.ts +0 -22
  240. package/src/utils/iterable/index.ts +0 -15
  241. package/src/utils/iterable/map.ts +0 -40
  242. package/src/utils/iterable/reduce.ts +0 -24
  243. package/src/utils/iterable/some.ts +0 -36
  244. package/src/utils/iterable/to.ts +0 -19
  245. package/src/utils/iterable/unique.ts +0 -23
  246. package/src/utils/markdown/index.ts +0 -2
  247. package/src/utils/markdown/to-html.ts +0 -32
  248. package/src/utils/markdown/to-text.ts +0 -14
  249. package/src/utils/memoize-prop.ts +0 -30
  250. package/src/utils/mnemonist.ts +0 -9
  251. package/src/utils/object-hash.ts +0 -14
  252. package/src/utils/promises.ts +0 -24
  253. package/src/utils/relations.ts +0 -36
  254. package/src/utils/set.ts +0 -83
  255. package/src/utils/string-hash.ts +0 -16
@@ -0,0 +1,3990 @@
1
+ import { t as t$2, a as t$3 } from './core.BsSXS-_R.mjs';
2
+ import { i as invariant } from './core.D4npX2q8.mjs';
3
+ import { m as memoizeProp } from './core.BR4zXDH-.mjs';
4
+
5
+ const { min: min$4, max: max$4 } = Math;
6
+
7
+ const limit = (x, low = 0, high = 1) => {
8
+ return min$4(max$4(low, x), high);
9
+ };
10
+
11
+ const clip_rgb = (rgb) => {
12
+ rgb._clipped = false;
13
+ rgb._unclipped = rgb.slice(0);
14
+ for (let i = 0; i <= 3; i++) {
15
+ if (i < 3) {
16
+ if (rgb[i] < 0 || rgb[i] > 255) rgb._clipped = true;
17
+ rgb[i] = limit(rgb[i], 0, 255);
18
+ } else if (i === 3) {
19
+ rgb[i] = limit(rgb[i], 0, 1);
20
+ }
21
+ }
22
+ return rgb;
23
+ };
24
+
25
+ // ported from jQuery's $.type
26
+ const classToType = {};
27
+ for (let name of [
28
+ 'Boolean',
29
+ 'Number',
30
+ 'String',
31
+ 'Function',
32
+ 'Array',
33
+ 'Date',
34
+ 'RegExp',
35
+ 'Undefined',
36
+ 'Null'
37
+ ]) {
38
+ classToType[`[object ${name}]`] = name.toLowerCase();
39
+ }
40
+ function type (obj) {
41
+ return classToType[Object.prototype.toString.call(obj)] || 'object';
42
+ }
43
+
44
+ const unpack = (args, keyOrder = null) => {
45
+ // if called with more than 3 arguments, we return the arguments
46
+ if (args.length >= 3) return Array.prototype.slice.call(args);
47
+ // with less than 3 args we check if first arg is object
48
+ // and use the keyOrder string to extract and sort properties
49
+ if (type(args[0]) == 'object' && keyOrder) {
50
+ return keyOrder
51
+ .split('')
52
+ .filter((k) => args[0][k] !== undefined)
53
+ .map((k) => args[0][k]);
54
+ }
55
+ // otherwise we just return the first argument
56
+ // (which we suppose is an array of args)
57
+ return args[0].slice(0);
58
+ };
59
+
60
+ const last = (args) => {
61
+ if (args.length < 2) return null;
62
+ const l = args.length - 1;
63
+ if (type(args[l]) == 'string') return args[l].toLowerCase();
64
+ return null;
65
+ };
66
+
67
+ const { PI: PI$2, min: min$3, max: max$3 } = Math;
68
+
69
+ const rnd2 = (a) => Math.round(a * 100) / 100;
70
+ const rnd3 = (a) => Math.round(a * 100) / 100;
71
+
72
+ const TWOPI = PI$2 * 2;
73
+ const PITHIRD = PI$2 / 3;
74
+ const DEG2RAD = PI$2 / 180;
75
+ const RAD2DEG = 180 / PI$2;
76
+
77
+ /**
78
+ * Reverse the first three elements of an array
79
+ *
80
+ * @param {any[]} arr
81
+ * @returns {any[]}
82
+ */
83
+ function reverse3(arr) {
84
+ return [...arr.slice(0, 3).reverse(), ...arr.slice(3)];
85
+ }
86
+
87
+ const input = {
88
+ format: {},
89
+ autodetect: []
90
+ };
91
+
92
+ class Color {
93
+ constructor(...args) {
94
+ const me = this;
95
+ if (
96
+ type(args[0]) === 'object' &&
97
+ args[0].constructor &&
98
+ args[0].constructor === this.constructor
99
+ ) {
100
+ // the argument is already a Color instance
101
+ return args[0];
102
+ }
103
+ // last argument could be the mode
104
+ let mode = last(args);
105
+ let autodetect = false;
106
+ if (!mode) {
107
+ autodetect = true;
108
+
109
+ if (!input.sorted) {
110
+ input.autodetect = input.autodetect.sort((a, b) => b.p - a.p);
111
+ input.sorted = true;
112
+ }
113
+
114
+ // auto-detect format
115
+ for (let chk of input.autodetect) {
116
+ mode = chk.test(...args);
117
+ if (mode) break;
118
+ }
119
+ }
120
+ if (input.format[mode]) {
121
+ const rgb = input.format[mode].apply(
122
+ null,
123
+ autodetect ? args : args.slice(0, -1)
124
+ );
125
+ me._rgb = clip_rgb(rgb);
126
+ } else {
127
+ throw new Error('unknown format: ' + args);
128
+ }
129
+ // add alpha channel
130
+ if (me._rgb.length === 3) me._rgb.push(1);
131
+ }
132
+ toString() {
133
+ if (type(this.hex) == 'function') return this.hex();
134
+ return `[${this._rgb.join(',')}]`;
135
+ }
136
+ }
137
+
138
+ // this gets updated automatically
139
+ const version = '3.1.2';
140
+
141
+ const chroma = (...args) => {
142
+ return new Color(...args);
143
+ };
144
+
145
+ chroma.version = version;
146
+
147
+ /**
148
+ X11 color names
149
+
150
+ http://www.w3.org/TR/css3-color/#svg-color
151
+ */
152
+
153
+ const w3cx11 = {
154
+ aliceblue: '#f0f8ff',
155
+ antiquewhite: '#faebd7',
156
+ aqua: '#00ffff',
157
+ aquamarine: '#7fffd4',
158
+ azure: '#f0ffff',
159
+ beige: '#f5f5dc',
160
+ bisque: '#ffe4c4',
161
+ black: '#000000',
162
+ blanchedalmond: '#ffebcd',
163
+ blue: '#0000ff',
164
+ blueviolet: '#8a2be2',
165
+ brown: '#a52a2a',
166
+ burlywood: '#deb887',
167
+ cadetblue: '#5f9ea0',
168
+ chartreuse: '#7fff00',
169
+ chocolate: '#d2691e',
170
+ coral: '#ff7f50',
171
+ cornflowerblue: '#6495ed',
172
+ cornsilk: '#fff8dc',
173
+ crimson: '#dc143c',
174
+ cyan: '#00ffff',
175
+ darkblue: '#00008b',
176
+ darkcyan: '#008b8b',
177
+ darkgoldenrod: '#b8860b',
178
+ darkgray: '#a9a9a9',
179
+ darkgreen: '#006400',
180
+ darkgrey: '#a9a9a9',
181
+ darkkhaki: '#bdb76b',
182
+ darkmagenta: '#8b008b',
183
+ darkolivegreen: '#556b2f',
184
+ darkorange: '#ff8c00',
185
+ darkorchid: '#9932cc',
186
+ darkred: '#8b0000',
187
+ darksalmon: '#e9967a',
188
+ darkseagreen: '#8fbc8f',
189
+ darkslateblue: '#483d8b',
190
+ darkslategray: '#2f4f4f',
191
+ darkslategrey: '#2f4f4f',
192
+ darkturquoise: '#00ced1',
193
+ darkviolet: '#9400d3',
194
+ deeppink: '#ff1493',
195
+ deepskyblue: '#00bfff',
196
+ dimgray: '#696969',
197
+ dimgrey: '#696969',
198
+ dodgerblue: '#1e90ff',
199
+ firebrick: '#b22222',
200
+ floralwhite: '#fffaf0',
201
+ forestgreen: '#228b22',
202
+ fuchsia: '#ff00ff',
203
+ gainsboro: '#dcdcdc',
204
+ ghostwhite: '#f8f8ff',
205
+ gold: '#ffd700',
206
+ goldenrod: '#daa520',
207
+ gray: '#808080',
208
+ green: '#008000',
209
+ greenyellow: '#adff2f',
210
+ grey: '#808080',
211
+ honeydew: '#f0fff0',
212
+ hotpink: '#ff69b4',
213
+ indianred: '#cd5c5c',
214
+ indigo: '#4b0082',
215
+ ivory: '#fffff0',
216
+ khaki: '#f0e68c',
217
+ laserlemon: '#ffff54',
218
+ lavender: '#e6e6fa',
219
+ lavenderblush: '#fff0f5',
220
+ lawngreen: '#7cfc00',
221
+ lemonchiffon: '#fffacd',
222
+ lightblue: '#add8e6',
223
+ lightcoral: '#f08080',
224
+ lightcyan: '#e0ffff',
225
+ lightgoldenrod: '#fafad2',
226
+ lightgoldenrodyellow: '#fafad2',
227
+ lightgray: '#d3d3d3',
228
+ lightgreen: '#90ee90',
229
+ lightgrey: '#d3d3d3',
230
+ lightpink: '#ffb6c1',
231
+ lightsalmon: '#ffa07a',
232
+ lightseagreen: '#20b2aa',
233
+ lightskyblue: '#87cefa',
234
+ lightslategray: '#778899',
235
+ lightslategrey: '#778899',
236
+ lightsteelblue: '#b0c4de',
237
+ lightyellow: '#ffffe0',
238
+ lime: '#00ff00',
239
+ limegreen: '#32cd32',
240
+ linen: '#faf0e6',
241
+ magenta: '#ff00ff',
242
+ maroon: '#800000',
243
+ maroon2: '#7f0000',
244
+ maroon3: '#b03060',
245
+ mediumaquamarine: '#66cdaa',
246
+ mediumblue: '#0000cd',
247
+ mediumorchid: '#ba55d3',
248
+ mediumpurple: '#9370db',
249
+ mediumseagreen: '#3cb371',
250
+ mediumslateblue: '#7b68ee',
251
+ mediumspringgreen: '#00fa9a',
252
+ mediumturquoise: '#48d1cc',
253
+ mediumvioletred: '#c71585',
254
+ midnightblue: '#191970',
255
+ mintcream: '#f5fffa',
256
+ mistyrose: '#ffe4e1',
257
+ moccasin: '#ffe4b5',
258
+ navajowhite: '#ffdead',
259
+ navy: '#000080',
260
+ oldlace: '#fdf5e6',
261
+ olive: '#808000',
262
+ olivedrab: '#6b8e23',
263
+ orange: '#ffa500',
264
+ orangered: '#ff4500',
265
+ orchid: '#da70d6',
266
+ palegoldenrod: '#eee8aa',
267
+ palegreen: '#98fb98',
268
+ paleturquoise: '#afeeee',
269
+ palevioletred: '#db7093',
270
+ papayawhip: '#ffefd5',
271
+ peachpuff: '#ffdab9',
272
+ peru: '#cd853f',
273
+ pink: '#ffc0cb',
274
+ plum: '#dda0dd',
275
+ powderblue: '#b0e0e6',
276
+ purple: '#800080',
277
+ purple2: '#7f007f',
278
+ purple3: '#a020f0',
279
+ rebeccapurple: '#663399',
280
+ red: '#ff0000',
281
+ rosybrown: '#bc8f8f',
282
+ royalblue: '#4169e1',
283
+ saddlebrown: '#8b4513',
284
+ salmon: '#fa8072',
285
+ sandybrown: '#f4a460',
286
+ seagreen: '#2e8b57',
287
+ seashell: '#fff5ee',
288
+ sienna: '#a0522d',
289
+ silver: '#c0c0c0',
290
+ skyblue: '#87ceeb',
291
+ slateblue: '#6a5acd',
292
+ slategray: '#708090',
293
+ slategrey: '#708090',
294
+ snow: '#fffafa',
295
+ springgreen: '#00ff7f',
296
+ steelblue: '#4682b4',
297
+ tan: '#d2b48c',
298
+ teal: '#008080',
299
+ thistle: '#d8bfd8',
300
+ tomato: '#ff6347',
301
+ turquoise: '#40e0d0',
302
+ violet: '#ee82ee',
303
+ wheat: '#f5deb3',
304
+ white: '#ffffff',
305
+ whitesmoke: '#f5f5f5',
306
+ yellow: '#ffff00',
307
+ yellowgreen: '#9acd32'
308
+ };
309
+
310
+ const RE_HEX = /^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/;
311
+ const RE_HEXA = /^#?([A-Fa-f0-9]{8}|[A-Fa-f0-9]{4})$/;
312
+
313
+ const hex2rgb = (hex) => {
314
+ if (hex.match(RE_HEX)) {
315
+ // remove optional leading #
316
+ if (hex.length === 4 || hex.length === 7) {
317
+ hex = hex.substr(1);
318
+ }
319
+ // expand short-notation to full six-digit
320
+ if (hex.length === 3) {
321
+ hex = hex.split('');
322
+ hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
323
+ }
324
+ const u = parseInt(hex, 16);
325
+ const r = u >> 16;
326
+ const g = (u >> 8) & 0xff;
327
+ const b = u & 0xff;
328
+ return [r, g, b, 1];
329
+ }
330
+
331
+ // match rgba hex format, eg #FF000077
332
+ if (hex.match(RE_HEXA)) {
333
+ if (hex.length === 5 || hex.length === 9) {
334
+ // remove optional leading #
335
+ hex = hex.substr(1);
336
+ }
337
+ // expand short-notation to full eight-digit
338
+ if (hex.length === 4) {
339
+ hex = hex.split('');
340
+ hex =
341
+ hex[0] +
342
+ hex[0] +
343
+ hex[1] +
344
+ hex[1] +
345
+ hex[2] +
346
+ hex[2] +
347
+ hex[3] +
348
+ hex[3];
349
+ }
350
+ const u = parseInt(hex, 16);
351
+ const r = (u >> 24) & 0xff;
352
+ const g = (u >> 16) & 0xff;
353
+ const b = (u >> 8) & 0xff;
354
+ const a = Math.round(((u & 0xff) / 0xff) * 100) / 100;
355
+ return [r, g, b, a];
356
+ }
357
+
358
+ // we used to check for css colors here
359
+ // if _input.css? and rgb = _input.css hex
360
+ // return rgb
361
+
362
+ throw new Error(`unknown hex color: ${hex}`);
363
+ };
364
+
365
+ const { round: round$5 } = Math;
366
+
367
+ const rgb2hex = (...args) => {
368
+ let [r, g, b, a] = unpack(args, 'rgba');
369
+ let mode = last(args) || 'auto';
370
+ if (a === undefined) a = 1;
371
+ if (mode === 'auto') {
372
+ mode = a < 1 ? 'rgba' : 'rgb';
373
+ }
374
+ r = round$5(r);
375
+ g = round$5(g);
376
+ b = round$5(b);
377
+ const u = (r << 16) | (g << 8) | b;
378
+ let str = '000000' + u.toString(16); //#.toUpperCase();
379
+ str = str.substr(str.length - 6);
380
+ let hxa = '0' + round$5(a * 255).toString(16);
381
+ hxa = hxa.substr(hxa.length - 2);
382
+ switch (mode.toLowerCase()) {
383
+ case 'rgba':
384
+ return `#${str}${hxa}`;
385
+ case 'argb':
386
+ return `#${hxa}${str}`;
387
+ default:
388
+ return `#${str}`;
389
+ }
390
+ };
391
+
392
+ Color.prototype.name = function () {
393
+ const hex = rgb2hex(this._rgb, 'rgb');
394
+ for (let n of Object.keys(w3cx11)) {
395
+ if (w3cx11[n] === hex) return n.toLowerCase();
396
+ }
397
+ return hex;
398
+ };
399
+
400
+ input.format.named = (name) => {
401
+ name = name.toLowerCase();
402
+ if (w3cx11[name]) return hex2rgb(w3cx11[name]);
403
+ throw new Error('unknown color name: ' + name);
404
+ };
405
+
406
+ input.autodetect.push({
407
+ p: 5,
408
+ test: (h, ...rest) => {
409
+ if (!rest.length && type(h) === 'string' && w3cx11[h.toLowerCase()]) {
410
+ return 'named';
411
+ }
412
+ }
413
+ });
414
+
415
+ Color.prototype.alpha = function (a, mutate = false) {
416
+ if (a !== undefined && type(a) === 'number') {
417
+ if (mutate) {
418
+ this._rgb[3] = a;
419
+ return this;
420
+ }
421
+ return new Color([this._rgb[0], this._rgb[1], this._rgb[2], a], 'rgb');
422
+ }
423
+ return this._rgb[3];
424
+ };
425
+
426
+ Color.prototype.clipped = function () {
427
+ return this._rgb._clipped || false;
428
+ };
429
+
430
+ const labConstants = {
431
+ // Corresponds roughly to RGB brighter/darker
432
+ Kn: 18,
433
+
434
+ // D65 standard referent
435
+ labWhitePoint: 'd65',
436
+ Xn: 0.95047,
437
+ Yn: 1,
438
+ Zn: 1.08883,
439
+
440
+ kE: 216.0 / 24389.0,
441
+ kKE: 8.0,
442
+ kK: 24389.0 / 27.0,
443
+
444
+ RefWhiteRGB: {
445
+ // sRGB
446
+ X: 0.95047,
447
+ Y: 1,
448
+ Z: 1.08883
449
+ },
450
+
451
+ MtxRGB2XYZ: {
452
+ m00: 0.4124564390896922,
453
+ m01: 0.21267285140562253,
454
+ m02: 0.0193338955823293,
455
+ m10: 0.357576077643909,
456
+ m11: 0.715152155287818,
457
+ m12: 0.11919202588130297,
458
+ m20: 0.18043748326639894,
459
+ m21: 0.07217499330655958,
460
+ m22: 0.9503040785363679
461
+ },
462
+
463
+ MtxXYZ2RGB: {
464
+ m00: 3.2404541621141045,
465
+ m01: -0.9692660305051868,
466
+ m02: 0.055643430959114726,
467
+ m10: -1.5371385127977166,
468
+ m11: 1.8760108454466942,
469
+ m12: -0.2040259135167538,
470
+ m20: -0.498531409556016,
471
+ m21: 0.041556017530349834,
472
+ m22: 1.0572251882231791
473
+ },
474
+
475
+ // used in rgb2xyz
476
+ As: 0.9414285350000001,
477
+ Bs: 1.040417467,
478
+ Cs: 1.089532651,
479
+
480
+ MtxAdaptMa: {
481
+ m00: 0.8951,
482
+ m01: -0.7502,
483
+ m02: 0.0389,
484
+ m10: 0.2664,
485
+ m11: 1.7135,
486
+ m12: -0.0685,
487
+ m20: -0.1614,
488
+ m21: 0.0367,
489
+ m22: 1.0296
490
+ },
491
+
492
+ MtxAdaptMaI: {
493
+ m00: 0.9869929054667123,
494
+ m01: 0.43230526972339456,
495
+ m02: -0.008528664575177328,
496
+ m10: -0.14705425642099013,
497
+ m11: 0.5183602715367776,
498
+ m12: 0.04004282165408487,
499
+ m20: 0.15996265166373125,
500
+ m21: 0.0492912282128556,
501
+ m22: 0.9684866957875502
502
+ }
503
+ };
504
+
505
+ // taken from https://de.mathworks.com/help/images/ref/whitepoint.html
506
+ const ILLUMINANTS = new Map([
507
+ // ASTM E308-01
508
+ ['a', [1.0985, 0.35585]],
509
+ // Wyszecki & Stiles, p. 769
510
+ ['b', [1.0985, 0.35585]],
511
+ // C ASTM E308-01
512
+ ['c', [0.98074, 1.18232]],
513
+ // D50 (ASTM E308-01)
514
+ ['d50', [0.96422, 0.82521]],
515
+ // D55 (ASTM E308-01)
516
+ ['d55', [0.95682, 0.92149]],
517
+ // D65 (ASTM E308-01)
518
+ ['d65', [0.95047, 1.08883]],
519
+ // E (ASTM E308-01)
520
+ ['e', [1, 1, 1]],
521
+ // F2 (ASTM E308-01)
522
+ ['f2', [0.99186, 0.67393]],
523
+ // F7 (ASTM E308-01)
524
+ ['f7', [0.95041, 1.08747]],
525
+ // F11 (ASTM E308-01)
526
+ ['f11', [1.00962, 0.6435]],
527
+ ['icc', [0.96422, 0.82521]]
528
+ ]);
529
+
530
+ function setLabWhitePoint(name) {
531
+ const ill = ILLUMINANTS.get(String(name).toLowerCase());
532
+ if (!ill) {
533
+ throw new Error('unknown Lab illuminant ' + name);
534
+ }
535
+ labConstants.labWhitePoint = name;
536
+ labConstants.Xn = ill[0];
537
+ labConstants.Zn = ill[1];
538
+ }
539
+
540
+ function getLabWhitePoint() {
541
+ return labConstants.labWhitePoint;
542
+ }
543
+
544
+ /*
545
+ * L* [0..100]
546
+ * a [-100..100]
547
+ * b [-100..100]
548
+ */
549
+ const lab2rgb = (...args) => {
550
+ args = unpack(args, 'lab');
551
+ const [L, a, b] = args;
552
+ const [x, y, z] = lab2xyz(L, a, b);
553
+ const [r, g, b_] = xyz2rgb(x, y, z);
554
+ return [r, g, b_, args.length > 3 ? args[3] : 1];
555
+ };
556
+
557
+ const lab2xyz = (L, a, b) => {
558
+ const { kE, kK, kKE, Xn, Yn, Zn } = labConstants;
559
+
560
+ const fy = (L + 16.0) / 116.0;
561
+ const fx = 0.002 * a + fy;
562
+ const fz = fy - 0.005 * b;
563
+
564
+ const fx3 = fx * fx * fx;
565
+ const fz3 = fz * fz * fz;
566
+
567
+ const xr = fx3 > kE ? fx3 : (116.0 * fx - 16.0) / kK;
568
+ const yr = L > kKE ? Math.pow((L + 16.0) / 116.0, 3.0) : L / kK;
569
+ const zr = fz3 > kE ? fz3 : (116.0 * fz - 16.0) / kK;
570
+
571
+ const x = xr * Xn;
572
+ const y = yr * Yn;
573
+ const z = zr * Zn;
574
+
575
+ return [x, y, z];
576
+ };
577
+
578
+ const compand = (linear) => {
579
+ /* sRGB */
580
+ const sign = Math.sign(linear);
581
+ linear = Math.abs(linear);
582
+ return (
583
+ (linear <= 0.0031308
584
+ ? linear * 12.92
585
+ : 1.055 * Math.pow(linear, 1.0 / 2.4) - 0.055) * sign
586
+ );
587
+ };
588
+
589
+ const xyz2rgb = (x, y, z) => {
590
+ const { MtxAdaptMa, MtxAdaptMaI, MtxXYZ2RGB, RefWhiteRGB, Xn, Yn, Zn } =
591
+ labConstants;
592
+
593
+ const As = Xn * MtxAdaptMa.m00 + Yn * MtxAdaptMa.m10 + Zn * MtxAdaptMa.m20;
594
+ const Bs = Xn * MtxAdaptMa.m01 + Yn * MtxAdaptMa.m11 + Zn * MtxAdaptMa.m21;
595
+ const Cs = Xn * MtxAdaptMa.m02 + Yn * MtxAdaptMa.m12 + Zn * MtxAdaptMa.m22;
596
+
597
+ const Ad =
598
+ RefWhiteRGB.X * MtxAdaptMa.m00 +
599
+ RefWhiteRGB.Y * MtxAdaptMa.m10 +
600
+ RefWhiteRGB.Z * MtxAdaptMa.m20;
601
+ const Bd =
602
+ RefWhiteRGB.X * MtxAdaptMa.m01 +
603
+ RefWhiteRGB.Y * MtxAdaptMa.m11 +
604
+ RefWhiteRGB.Z * MtxAdaptMa.m21;
605
+ const Cd =
606
+ RefWhiteRGB.X * MtxAdaptMa.m02 +
607
+ RefWhiteRGB.Y * MtxAdaptMa.m12 +
608
+ RefWhiteRGB.Z * MtxAdaptMa.m22;
609
+
610
+ const X1 =
611
+ (x * MtxAdaptMa.m00 + y * MtxAdaptMa.m10 + z * MtxAdaptMa.m20) *
612
+ (Ad / As);
613
+ const Y1 =
614
+ (x * MtxAdaptMa.m01 + y * MtxAdaptMa.m11 + z * MtxAdaptMa.m21) *
615
+ (Bd / Bs);
616
+ const Z1 =
617
+ (x * MtxAdaptMa.m02 + y * MtxAdaptMa.m12 + z * MtxAdaptMa.m22) *
618
+ (Cd / Cs);
619
+
620
+ const X2 =
621
+ X1 * MtxAdaptMaI.m00 + Y1 * MtxAdaptMaI.m10 + Z1 * MtxAdaptMaI.m20;
622
+ const Y2 =
623
+ X1 * MtxAdaptMaI.m01 + Y1 * MtxAdaptMaI.m11 + Z1 * MtxAdaptMaI.m21;
624
+ const Z2 =
625
+ X1 * MtxAdaptMaI.m02 + Y1 * MtxAdaptMaI.m12 + Z1 * MtxAdaptMaI.m22;
626
+
627
+ const r = compand(
628
+ X2 * MtxXYZ2RGB.m00 + Y2 * MtxXYZ2RGB.m10 + Z2 * MtxXYZ2RGB.m20
629
+ );
630
+ const g = compand(
631
+ X2 * MtxXYZ2RGB.m01 + Y2 * MtxXYZ2RGB.m11 + Z2 * MtxXYZ2RGB.m21
632
+ );
633
+ const b = compand(
634
+ X2 * MtxXYZ2RGB.m02 + Y2 * MtxXYZ2RGB.m12 + Z2 * MtxXYZ2RGB.m22
635
+ );
636
+
637
+ return [r * 255, g * 255, b * 255];
638
+ };
639
+
640
+ const rgb2lab = (...args) => {
641
+ const [r, g, b, ...rest] = unpack(args, 'rgb');
642
+ const [x, y, z] = rgb2xyz(r, g, b);
643
+ const [L, a, b_] = xyz2lab(x, y, z);
644
+ return [L, a, b_, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
645
+ };
646
+
647
+ function xyz2lab(x, y, z) {
648
+ const { Xn, Yn, Zn, kE, kK } = labConstants;
649
+ const xr = x / Xn;
650
+ const yr = y / Yn;
651
+ const zr = z / Zn;
652
+
653
+ const fx = xr > kE ? Math.pow(xr, 1.0 / 3.0) : (kK * xr + 16.0) / 116.0;
654
+ const fy = yr > kE ? Math.pow(yr, 1.0 / 3.0) : (kK * yr + 16.0) / 116.0;
655
+ const fz = zr > kE ? Math.pow(zr, 1.0 / 3.0) : (kK * zr + 16.0) / 116.0;
656
+
657
+ return [116.0 * fy - 16.0, 500.0 * (fx - fy), 200.0 * (fy - fz)];
658
+ }
659
+
660
+ function gammaAdjustSRGB(companded) {
661
+ const sign = Math.sign(companded);
662
+ companded = Math.abs(companded);
663
+ const linear =
664
+ companded <= 0.04045
665
+ ? companded / 12.92
666
+ : Math.pow((companded + 0.055) / 1.055, 2.4);
667
+ return linear * sign;
668
+ }
669
+
670
+ const rgb2xyz = (r, g, b) => {
671
+ // normalize and gamma adjust
672
+ r = gammaAdjustSRGB(r / 255);
673
+ g = gammaAdjustSRGB(g / 255);
674
+ b = gammaAdjustSRGB(b / 255);
675
+
676
+ const { MtxRGB2XYZ, MtxAdaptMa, MtxAdaptMaI, Xn, Yn, Zn, As, Bs, Cs } =
677
+ labConstants;
678
+
679
+ let x = r * MtxRGB2XYZ.m00 + g * MtxRGB2XYZ.m10 + b * MtxRGB2XYZ.m20;
680
+ let y = r * MtxRGB2XYZ.m01 + g * MtxRGB2XYZ.m11 + b * MtxRGB2XYZ.m21;
681
+ let z = r * MtxRGB2XYZ.m02 + g * MtxRGB2XYZ.m12 + b * MtxRGB2XYZ.m22;
682
+
683
+ const Ad = Xn * MtxAdaptMa.m00 + Yn * MtxAdaptMa.m10 + Zn * MtxAdaptMa.m20;
684
+ const Bd = Xn * MtxAdaptMa.m01 + Yn * MtxAdaptMa.m11 + Zn * MtxAdaptMa.m21;
685
+ const Cd = Xn * MtxAdaptMa.m02 + Yn * MtxAdaptMa.m12 + Zn * MtxAdaptMa.m22;
686
+
687
+ let X = x * MtxAdaptMa.m00 + y * MtxAdaptMa.m10 + z * MtxAdaptMa.m20;
688
+ let Y = x * MtxAdaptMa.m01 + y * MtxAdaptMa.m11 + z * MtxAdaptMa.m21;
689
+ let Z = x * MtxAdaptMa.m02 + y * MtxAdaptMa.m12 + z * MtxAdaptMa.m22;
690
+
691
+ X *= Ad / As;
692
+ Y *= Bd / Bs;
693
+ Z *= Cd / Cs;
694
+
695
+ x = X * MtxAdaptMaI.m00 + Y * MtxAdaptMaI.m10 + Z * MtxAdaptMaI.m20;
696
+ y = X * MtxAdaptMaI.m01 + Y * MtxAdaptMaI.m11 + Z * MtxAdaptMaI.m21;
697
+ z = X * MtxAdaptMaI.m02 + Y * MtxAdaptMaI.m12 + Z * MtxAdaptMaI.m22;
698
+
699
+ return [x, y, z];
700
+ };
701
+
702
+ Color.prototype.lab = function () {
703
+ return rgb2lab(this._rgb);
704
+ };
705
+
706
+ const lab$1 = (...args) => new Color(...args, 'lab');
707
+ Object.assign(chroma, { lab: lab$1, getLabWhitePoint, setLabWhitePoint });
708
+
709
+ input.format.lab = lab2rgb;
710
+
711
+ input.autodetect.push({
712
+ p: 2,
713
+ test: (...args) => {
714
+ args = unpack(args, 'lab');
715
+ if (type(args) === 'array' && args.length === 3) {
716
+ return 'lab';
717
+ }
718
+ }
719
+ });
720
+
721
+ Color.prototype.darken = function (amount = 1) {
722
+ const me = this;
723
+ const lab = me.lab();
724
+ lab[0] -= labConstants.Kn * amount;
725
+ return new Color(lab, 'lab').alpha(me.alpha(), true);
726
+ };
727
+
728
+ Color.prototype.brighten = function (amount = 1) {
729
+ return this.darken(-amount);
730
+ };
731
+
732
+ Color.prototype.darker = Color.prototype.darken;
733
+ Color.prototype.brighter = Color.prototype.brighten;
734
+
735
+ Color.prototype.get = function (mc) {
736
+ const [mode, channel] = mc.split('.');
737
+ const src = this[mode]();
738
+ if (channel) {
739
+ const i = mode.indexOf(channel) - (mode.substr(0, 2) === 'ok' ? 2 : 0);
740
+ if (i > -1) return src[i];
741
+ throw new Error(`unknown channel ${channel} in mode ${mode}`);
742
+ } else {
743
+ return src;
744
+ }
745
+ };
746
+
747
+ const { pow: pow$6 } = Math;
748
+
749
+ const EPS = 1e-7;
750
+ const MAX_ITER = 20;
751
+
752
+ Color.prototype.luminance = function (lum, mode = 'rgb') {
753
+ if (lum !== undefined && type(lum) === 'number') {
754
+ if (lum === 0) {
755
+ // return pure black
756
+ return new Color([0, 0, 0, this._rgb[3]], 'rgb');
757
+ }
758
+ if (lum === 1) {
759
+ // return pure white
760
+ return new Color([255, 255, 255, this._rgb[3]], 'rgb');
761
+ }
762
+ // compute new color using...
763
+ let cur_lum = this.luminance();
764
+ let max_iter = MAX_ITER;
765
+
766
+ const test = (low, high) => {
767
+ const mid = low.interpolate(high, 0.5, mode);
768
+ const lm = mid.luminance();
769
+ if (Math.abs(lum - lm) < EPS || !max_iter--) {
770
+ // close enough
771
+ return mid;
772
+ }
773
+ return lm > lum ? test(low, mid) : test(mid, high);
774
+ };
775
+
776
+ const rgb = (
777
+ cur_lum > lum
778
+ ? test(new Color([0, 0, 0]), this)
779
+ : test(this, new Color([255, 255, 255]))
780
+ ).rgb();
781
+ return new Color([...rgb, this._rgb[3]]);
782
+ }
783
+ return rgb2luminance(...this._rgb.slice(0, 3));
784
+ };
785
+
786
+ const rgb2luminance = (r, g, b) => {
787
+ // relative luminance
788
+ // see http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
789
+ r = luminance_x(r);
790
+ g = luminance_x(g);
791
+ b = luminance_x(b);
792
+ return 0.2126 * r + 0.7152 * g + 0.0722 * b;
793
+ };
794
+
795
+ const luminance_x = (x) => {
796
+ x /= 255;
797
+ return x <= 0.03928 ? x / 12.92 : pow$6((x + 0.055) / 1.055, 2.4);
798
+ };
799
+
800
+ const index = {};
801
+
802
+ const mix = (col1, col2, f = 0.5, ...rest) => {
803
+ let mode = rest[0] || 'lrgb';
804
+ if (!index[mode] && !rest.length) {
805
+ // fall back to the first supported mode
806
+ mode = Object.keys(index)[0];
807
+ }
808
+ if (!index[mode]) {
809
+ throw new Error(`interpolation mode ${mode} is not defined`);
810
+ }
811
+ if (type(col1) !== 'object') col1 = new Color(col1);
812
+ if (type(col2) !== 'object') col2 = new Color(col2);
813
+ return index[mode](col1, col2, f).alpha(
814
+ col1.alpha() + f * (col2.alpha() - col1.alpha())
815
+ );
816
+ };
817
+
818
+ Color.prototype.mix = Color.prototype.interpolate = function (
819
+ col2,
820
+ f = 0.5,
821
+ ...rest
822
+ ) {
823
+ return mix(this, col2, f, ...rest);
824
+ };
825
+
826
+ Color.prototype.premultiply = function (mutate = false) {
827
+ const rgb = this._rgb;
828
+ const a = rgb[3];
829
+ if (mutate) {
830
+ this._rgb = [rgb[0] * a, rgb[1] * a, rgb[2] * a, a];
831
+ return this;
832
+ } else {
833
+ return new Color([rgb[0] * a, rgb[1] * a, rgb[2] * a, a], 'rgb');
834
+ }
835
+ };
836
+
837
+ const { sin: sin$3, cos: cos$4 } = Math;
838
+
839
+ const lch2lab = (...args) => {
840
+ /*
841
+ Convert from a qualitative parameter h and a quantitative parameter l to a 24-bit pixel.
842
+ These formulas were invented by David Dalrymple to obtain maximum contrast without going
843
+ out of gamut if the parameters are in the range 0-1.
844
+
845
+ A saturation multiplier was added by Gregor Aisch
846
+ */
847
+ let [l, c, h] = unpack(args, 'lch');
848
+ if (isNaN(h)) h = 0;
849
+ h = h * DEG2RAD;
850
+ return [l, cos$4(h) * c, sin$3(h) * c];
851
+ };
852
+
853
+ const lch2rgb = (...args) => {
854
+ args = unpack(args, 'lch');
855
+ const [l, c, h] = args;
856
+ const [L, a, b_] = lch2lab(l, c, h);
857
+ const [r, g, b] = lab2rgb(L, a, b_);
858
+ return [r, g, b, args.length > 3 ? args[3] : 1];
859
+ };
860
+
861
+ const hcl2rgb = (...args) => {
862
+ const hcl = reverse3(unpack(args, 'hcl'));
863
+ return lch2rgb(...hcl);
864
+ };
865
+
866
+ const { sqrt: sqrt$4, atan2: atan2$2, round: round$4 } = Math;
867
+
868
+ const lab2lch = (...args) => {
869
+ const [l, a, b] = unpack(args, 'lab');
870
+ const c = sqrt$4(a * a + b * b);
871
+ let h = (atan2$2(b, a) * RAD2DEG + 360) % 360;
872
+ if (round$4(c * 10000) === 0) h = Number.NaN;
873
+ return [l, c, h];
874
+ };
875
+
876
+ const rgb2lch = (...args) => {
877
+ const [r, g, b, ...rest] = unpack(args, 'rgb');
878
+ const [l, a, b_] = rgb2lab(r, g, b);
879
+ const [L, c, h] = lab2lch(l, a, b_);
880
+ return [L, c, h, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
881
+ };
882
+
883
+ Color.prototype.lch = function () {
884
+ return rgb2lch(this._rgb);
885
+ };
886
+ Color.prototype.hcl = function () {
887
+ return reverse3(rgb2lch(this._rgb));
888
+ };
889
+
890
+ const lch$1 = (...args) => new Color(...args, 'lch');
891
+ const hcl = (...args) => new Color(...args, 'hcl');
892
+
893
+ Object.assign(chroma, { lch: lch$1, hcl });
894
+
895
+ input.format.lch = lch2rgb;
896
+ input.format.hcl = hcl2rgb;
897
+ ['lch', 'hcl'].forEach((m) =>
898
+ input.autodetect.push({
899
+ p: 2,
900
+ test: (...args) => {
901
+ args = unpack(args, m);
902
+ if (type(args) === 'array' && args.length === 3) {
903
+ return m;
904
+ }
905
+ }
906
+ })
907
+ );
908
+
909
+ Color.prototype.saturate = function (amount = 1) {
910
+ const me = this;
911
+ const lch = me.lch();
912
+ lch[1] += labConstants.Kn * amount;
913
+ if (lch[1] < 0) lch[1] = 0;
914
+ return new Color(lch, 'lch').alpha(me.alpha(), true);
915
+ };
916
+
917
+ Color.prototype.desaturate = function (amount = 1) {
918
+ return this.saturate(-amount);
919
+ };
920
+
921
+ Color.prototype.set = function (mc, value, mutate = false) {
922
+ const [mode, channel] = mc.split('.');
923
+ const src = this[mode]();
924
+ if (channel) {
925
+ const i = mode.indexOf(channel) - (mode.substr(0, 2) === 'ok' ? 2 : 0);
926
+ if (i > -1) {
927
+ if (type(value) == 'string') {
928
+ switch (value.charAt(0)) {
929
+ case '+':
930
+ src[i] += +value;
931
+ break;
932
+ case '-':
933
+ src[i] += +value;
934
+ break;
935
+ case '*':
936
+ src[i] *= +value.substr(1);
937
+ break;
938
+ case '/':
939
+ src[i] /= +value.substr(1);
940
+ break;
941
+ default:
942
+ src[i] = +value;
943
+ }
944
+ } else if (type(value) === 'number') {
945
+ src[i] = value;
946
+ } else {
947
+ throw new Error(`unsupported value for Color.set`);
948
+ }
949
+ const out = new Color(src, mode);
950
+ if (mutate) {
951
+ this._rgb = out._rgb;
952
+ return this;
953
+ }
954
+ return out;
955
+ }
956
+ throw new Error(`unknown channel ${channel} in mode ${mode}`);
957
+ } else {
958
+ return src;
959
+ }
960
+ };
961
+
962
+ Color.prototype.tint = function (f = 0.5, ...rest) {
963
+ return mix(this, 'white', f, ...rest);
964
+ };
965
+
966
+ Color.prototype.shade = function (f = 0.5, ...rest) {
967
+ return mix(this, 'black', f, ...rest);
968
+ };
969
+
970
+ const rgb$1 = (col1, col2, f) => {
971
+ const xyz0 = col1._rgb;
972
+ const xyz1 = col2._rgb;
973
+ return new Color(
974
+ xyz0[0] + f * (xyz1[0] - xyz0[0]),
975
+ xyz0[1] + f * (xyz1[1] - xyz0[1]),
976
+ xyz0[2] + f * (xyz1[2] - xyz0[2]),
977
+ 'rgb'
978
+ );
979
+ };
980
+
981
+ // register interpolator
982
+ index.rgb = rgb$1;
983
+
984
+ const { sqrt: sqrt$3, pow: pow$5 } = Math;
985
+
986
+ const lrgb = (col1, col2, f) => {
987
+ const [x1, y1, z1] = col1._rgb;
988
+ const [x2, y2, z2] = col2._rgb;
989
+ return new Color(
990
+ sqrt$3(pow$5(x1, 2) * (1 - f) + pow$5(x2, 2) * f),
991
+ sqrt$3(pow$5(y1, 2) * (1 - f) + pow$5(y2, 2) * f),
992
+ sqrt$3(pow$5(z1, 2) * (1 - f) + pow$5(z2, 2) * f),
993
+ 'rgb'
994
+ );
995
+ };
996
+
997
+ // register interpolator
998
+ index.lrgb = lrgb;
999
+
1000
+ const lab = (col1, col2, f) => {
1001
+ const xyz0 = col1.lab();
1002
+ const xyz1 = col2.lab();
1003
+ return new Color(
1004
+ xyz0[0] + f * (xyz1[0] - xyz0[0]),
1005
+ xyz0[1] + f * (xyz1[1] - xyz0[1]),
1006
+ xyz0[2] + f * (xyz1[2] - xyz0[2]),
1007
+ 'lab'
1008
+ );
1009
+ };
1010
+
1011
+ // register interpolator
1012
+ index.lab = lab;
1013
+
1014
+ const interpolate_hsx = (col1, col2, f, m) => {
1015
+ let xyz0, xyz1;
1016
+ if (m === 'hsl') {
1017
+ xyz0 = col1.hsl();
1018
+ xyz1 = col2.hsl();
1019
+ } else if (m === 'hsv') {
1020
+ xyz0 = col1.hsv();
1021
+ xyz1 = col2.hsv();
1022
+ } else if (m === 'hcg') {
1023
+ xyz0 = col1.hcg();
1024
+ xyz1 = col2.hcg();
1025
+ } else if (m === 'hsi') {
1026
+ xyz0 = col1.hsi();
1027
+ xyz1 = col2.hsi();
1028
+ } else if (m === 'lch' || m === 'hcl') {
1029
+ m = 'hcl';
1030
+ xyz0 = col1.hcl();
1031
+ xyz1 = col2.hcl();
1032
+ } else if (m === 'oklch') {
1033
+ xyz0 = col1.oklch().reverse();
1034
+ xyz1 = col2.oklch().reverse();
1035
+ }
1036
+
1037
+ let hue0, hue1, sat0, sat1, lbv0, lbv1;
1038
+ if (m.substr(0, 1) === 'h' || m === 'oklch') {
1039
+ [hue0, sat0, lbv0] = xyz0;
1040
+ [hue1, sat1, lbv1] = xyz1;
1041
+ }
1042
+
1043
+ let sat, hue, lbv, dh;
1044
+
1045
+ if (!isNaN(hue0) && !isNaN(hue1)) {
1046
+ // both colors have hue
1047
+ if (hue1 > hue0 && hue1 - hue0 > 180) {
1048
+ dh = hue1 - (hue0 + 360);
1049
+ } else if (hue1 < hue0 && hue0 - hue1 > 180) {
1050
+ dh = hue1 + 360 - hue0;
1051
+ } else {
1052
+ dh = hue1 - hue0;
1053
+ }
1054
+ hue = hue0 + f * dh;
1055
+ } else if (!isNaN(hue0)) {
1056
+ hue = hue0;
1057
+ if ((lbv1 == 1 || lbv1 == 0) && m != 'hsv') sat = sat0;
1058
+ } else if (!isNaN(hue1)) {
1059
+ hue = hue1;
1060
+ if ((lbv0 == 1 || lbv0 == 0) && m != 'hsv') sat = sat1;
1061
+ } else {
1062
+ hue = Number.NaN;
1063
+ }
1064
+
1065
+ if (sat === undefined) sat = sat0 + f * (sat1 - sat0);
1066
+ lbv = lbv0 + f * (lbv1 - lbv0);
1067
+ return m === 'oklch'
1068
+ ? new Color([lbv, sat, hue], m)
1069
+ : new Color([hue, sat, lbv], m);
1070
+ };
1071
+
1072
+ const lch = (col1, col2, f) => {
1073
+ return interpolate_hsx(col1, col2, f, 'lch');
1074
+ };
1075
+
1076
+ // register interpolator
1077
+ index.lch = lch;
1078
+ index.hcl = lch;
1079
+
1080
+ const num2rgb = (num) => {
1081
+ if (type(num) == 'number' && num >= 0 && num <= 0xffffff) {
1082
+ const r = num >> 16;
1083
+ const g = (num >> 8) & 0xff;
1084
+ const b = num & 0xff;
1085
+ return [r, g, b, 1];
1086
+ }
1087
+ throw new Error('unknown num color: ' + num);
1088
+ };
1089
+
1090
+ const rgb2num = (...args) => {
1091
+ const [r, g, b] = unpack(args, 'rgb');
1092
+ return (r << 16) + (g << 8) + b;
1093
+ };
1094
+
1095
+ Color.prototype.num = function () {
1096
+ return rgb2num(this._rgb);
1097
+ };
1098
+
1099
+ const num$1 = (...args) => new Color(...args, 'num');
1100
+
1101
+ Object.assign(chroma, { num: num$1 });
1102
+
1103
+ input.format.num = num2rgb;
1104
+
1105
+ input.autodetect.push({
1106
+ p: 5,
1107
+ test: (...args) => {
1108
+ if (
1109
+ args.length === 1 &&
1110
+ type(args[0]) === 'number' &&
1111
+ args[0] >= 0 &&
1112
+ args[0] <= 0xffffff
1113
+ ) {
1114
+ return 'num';
1115
+ }
1116
+ }
1117
+ });
1118
+
1119
+ const num = (col1, col2, f) => {
1120
+ const c1 = col1.num();
1121
+ const c2 = col2.num();
1122
+ return new Color(c1 + f * (c2 - c1), 'num');
1123
+ };
1124
+
1125
+ // register interpolator
1126
+ index.num = num;
1127
+
1128
+ const { floor: floor$3 } = Math;
1129
+
1130
+ /*
1131
+ * this is basically just HSV with some minor tweaks
1132
+ *
1133
+ * hue.. [0..360]
1134
+ * chroma .. [0..1]
1135
+ * grayness .. [0..1]
1136
+ */
1137
+
1138
+ const hcg2rgb = (...args) => {
1139
+ args = unpack(args, 'hcg');
1140
+ let [h, c, _g] = args;
1141
+ let r, g, b;
1142
+ _g = _g * 255;
1143
+ const _c = c * 255;
1144
+ if (c === 0) {
1145
+ r = g = b = _g;
1146
+ } else {
1147
+ if (h === 360) h = 0;
1148
+ if (h > 360) h -= 360;
1149
+ if (h < 0) h += 360;
1150
+ h /= 60;
1151
+ const i = floor$3(h);
1152
+ const f = h - i;
1153
+ const p = _g * (1 - c);
1154
+ const q = p + _c * (1 - f);
1155
+ const t = p + _c * f;
1156
+ const v = p + _c;
1157
+ switch (i) {
1158
+ case 0:
1159
+ [r, g, b] = [v, t, p];
1160
+ break;
1161
+ case 1:
1162
+ [r, g, b] = [q, v, p];
1163
+ break;
1164
+ case 2:
1165
+ [r, g, b] = [p, v, t];
1166
+ break;
1167
+ case 3:
1168
+ [r, g, b] = [p, q, v];
1169
+ break;
1170
+ case 4:
1171
+ [r, g, b] = [t, p, v];
1172
+ break;
1173
+ case 5:
1174
+ [r, g, b] = [v, p, q];
1175
+ break;
1176
+ }
1177
+ }
1178
+ return [r, g, b, args.length > 3 ? args[3] : 1];
1179
+ };
1180
+
1181
+ const rgb2hcg = (...args) => {
1182
+ const [r, g, b] = unpack(args, 'rgb');
1183
+ const minRgb = min$3(r, g, b);
1184
+ const maxRgb = max$3(r, g, b);
1185
+ const delta = maxRgb - minRgb;
1186
+ const c = (delta * 100) / 255;
1187
+ const _g = (minRgb / (255 - delta)) * 100;
1188
+ let h;
1189
+ if (delta === 0) {
1190
+ h = Number.NaN;
1191
+ } else {
1192
+ if (r === maxRgb) h = (g - b) / delta;
1193
+ if (g === maxRgb) h = 2 + (b - r) / delta;
1194
+ if (b === maxRgb) h = 4 + (r - g) / delta;
1195
+ h *= 60;
1196
+ if (h < 0) h += 360;
1197
+ }
1198
+ return [h, c, _g];
1199
+ };
1200
+
1201
+ Color.prototype.hcg = function () {
1202
+ return rgb2hcg(this._rgb);
1203
+ };
1204
+
1205
+ const hcg$1 = (...args) => new Color(...args, 'hcg');
1206
+ chroma.hcg = hcg$1;
1207
+
1208
+ input.format.hcg = hcg2rgb;
1209
+
1210
+ input.autodetect.push({
1211
+ p: 1,
1212
+ test: (...args) => {
1213
+ args = unpack(args, 'hcg');
1214
+ if (type(args) === 'array' && args.length === 3) {
1215
+ return 'hcg';
1216
+ }
1217
+ }
1218
+ });
1219
+
1220
+ const hcg = (col1, col2, f) => {
1221
+ return interpolate_hsx(col1, col2, f, 'hcg');
1222
+ };
1223
+
1224
+ // register interpolator
1225
+ index.hcg = hcg;
1226
+
1227
+ const { cos: cos$3 } = Math;
1228
+
1229
+ /*
1230
+ * hue [0..360]
1231
+ * saturation [0..1]
1232
+ * intensity [0..1]
1233
+ */
1234
+ const hsi2rgb = (...args) => {
1235
+ /*
1236
+ borrowed from here:
1237
+ http://hummer.stanford.edu/museinfo/doc/examples/humdrum/keyscape2/hsi2rgb.cpp
1238
+ */
1239
+ args = unpack(args, 'hsi');
1240
+ let [h, s, i] = args;
1241
+ let r, g, b;
1242
+
1243
+ if (isNaN(h)) h = 0;
1244
+ if (isNaN(s)) s = 0;
1245
+ // normalize hue
1246
+ if (h > 360) h -= 360;
1247
+ if (h < 0) h += 360;
1248
+ h /= 360;
1249
+ if (h < 1 / 3) {
1250
+ b = (1 - s) / 3;
1251
+ r = (1 + (s * cos$3(TWOPI * h)) / cos$3(PITHIRD - TWOPI * h)) / 3;
1252
+ g = 1 - (b + r);
1253
+ } else if (h < 2 / 3) {
1254
+ h -= 1 / 3;
1255
+ r = (1 - s) / 3;
1256
+ g = (1 + (s * cos$3(TWOPI * h)) / cos$3(PITHIRD - TWOPI * h)) / 3;
1257
+ b = 1 - (r + g);
1258
+ } else {
1259
+ h -= 2 / 3;
1260
+ g = (1 - s) / 3;
1261
+ b = (1 + (s * cos$3(TWOPI * h)) / cos$3(PITHIRD - TWOPI * h)) / 3;
1262
+ r = 1 - (g + b);
1263
+ }
1264
+ r = limit(i * r * 3);
1265
+ g = limit(i * g * 3);
1266
+ b = limit(i * b * 3);
1267
+ return [r * 255, g * 255, b * 255, args.length > 3 ? args[3] : 1];
1268
+ };
1269
+
1270
+ const { min: min$2, sqrt: sqrt$2, acos } = Math;
1271
+
1272
+ const rgb2hsi = (...args) => {
1273
+ /*
1274
+ borrowed from here:
1275
+ http://hummer.stanford.edu/museinfo/doc/examples/humdrum/keyscape2/rgb2hsi.cpp
1276
+ */
1277
+ let [r, g, b] = unpack(args, 'rgb');
1278
+ r /= 255;
1279
+ g /= 255;
1280
+ b /= 255;
1281
+ let h;
1282
+ const min_ = min$2(r, g, b);
1283
+ const i = (r + g + b) / 3;
1284
+ const s = i > 0 ? 1 - min_ / i : 0;
1285
+ if (s === 0) {
1286
+ h = NaN;
1287
+ } else {
1288
+ h = (r - g + (r - b)) / 2;
1289
+ h /= sqrt$2((r - g) * (r - g) + (r - b) * (g - b));
1290
+ h = acos(h);
1291
+ if (b > g) {
1292
+ h = TWOPI - h;
1293
+ }
1294
+ h /= TWOPI;
1295
+ }
1296
+ return [h * 360, s, i];
1297
+ };
1298
+
1299
+ Color.prototype.hsi = function () {
1300
+ return rgb2hsi(this._rgb);
1301
+ };
1302
+
1303
+ const hsi$1 = (...args) => new Color(...args, 'hsi');
1304
+ chroma.hsi = hsi$1;
1305
+
1306
+ input.format.hsi = hsi2rgb;
1307
+
1308
+ input.autodetect.push({
1309
+ p: 2,
1310
+ test: (...args) => {
1311
+ args = unpack(args, 'hsi');
1312
+ if (type(args) === 'array' && args.length === 3) {
1313
+ return 'hsi';
1314
+ }
1315
+ }
1316
+ });
1317
+
1318
+ const hsi = (col1, col2, f) => {
1319
+ return interpolate_hsx(col1, col2, f, 'hsi');
1320
+ };
1321
+
1322
+ // register interpolator
1323
+ index.hsi = hsi;
1324
+
1325
+ const hsl2rgb = (...args) => {
1326
+ args = unpack(args, 'hsl');
1327
+ const [h, s, l] = args;
1328
+ let r, g, b;
1329
+ if (s === 0) {
1330
+ r = g = b = l * 255;
1331
+ } else {
1332
+ const t3 = [0, 0, 0];
1333
+ const c = [0, 0, 0];
1334
+ const t2 = l < 0.5 ? l * (1 + s) : l + s - l * s;
1335
+ const t1 = 2 * l - t2;
1336
+ const h_ = h / 360;
1337
+ t3[0] = h_ + 1 / 3;
1338
+ t3[1] = h_;
1339
+ t3[2] = h_ - 1 / 3;
1340
+ for (let i = 0; i < 3; i++) {
1341
+ if (t3[i] < 0) t3[i] += 1;
1342
+ if (t3[i] > 1) t3[i] -= 1;
1343
+ if (6 * t3[i] < 1) c[i] = t1 + (t2 - t1) * 6 * t3[i];
1344
+ else if (2 * t3[i] < 1) c[i] = t2;
1345
+ else if (3 * t3[i] < 2) c[i] = t1 + (t2 - t1) * (2 / 3 - t3[i]) * 6;
1346
+ else c[i] = t1;
1347
+ }
1348
+ [r, g, b] = [c[0] * 255, c[1] * 255, c[2] * 255];
1349
+ }
1350
+ if (args.length > 3) {
1351
+ // keep alpha channel
1352
+ return [r, g, b, args[3]];
1353
+ }
1354
+ return [r, g, b, 1];
1355
+ };
1356
+
1357
+ /*
1358
+ * supported arguments:
1359
+ * - rgb2hsl(r,g,b)
1360
+ * - rgb2hsl(r,g,b,a)
1361
+ * - rgb2hsl([r,g,b])
1362
+ * - rgb2hsl([r,g,b,a])
1363
+ * - rgb2hsl({r,g,b,a})
1364
+ */
1365
+ const rgb2hsl$1 = (...args) => {
1366
+ args = unpack(args, 'rgba');
1367
+ let [r, g, b] = args;
1368
+
1369
+ r /= 255;
1370
+ g /= 255;
1371
+ b /= 255;
1372
+
1373
+ const minRgb = min$3(r, g, b);
1374
+ const maxRgb = max$3(r, g, b);
1375
+
1376
+ const l = (maxRgb + minRgb) / 2;
1377
+ let s, h;
1378
+
1379
+ if (maxRgb === minRgb) {
1380
+ s = 0;
1381
+ h = Number.NaN;
1382
+ } else {
1383
+ s =
1384
+ l < 0.5
1385
+ ? (maxRgb - minRgb) / (maxRgb + minRgb)
1386
+ : (maxRgb - minRgb) / (2 - maxRgb - minRgb);
1387
+ }
1388
+
1389
+ if (r == maxRgb) h = (g - b) / (maxRgb - minRgb);
1390
+ else if (g == maxRgb) h = 2 + (b - r) / (maxRgb - minRgb);
1391
+ else if (b == maxRgb) h = 4 + (r - g) / (maxRgb - minRgb);
1392
+
1393
+ h *= 60;
1394
+ if (h < 0) h += 360;
1395
+ if (args.length > 3 && args[3] !== undefined) return [h, s, l, args[3]];
1396
+ return [h, s, l];
1397
+ };
1398
+
1399
+ Color.prototype.hsl = function () {
1400
+ return rgb2hsl$1(this._rgb);
1401
+ };
1402
+
1403
+ const hsl$1 = (...args) => new Color(...args, 'hsl');
1404
+ chroma.hsl = hsl$1;
1405
+
1406
+ input.format.hsl = hsl2rgb;
1407
+
1408
+ input.autodetect.push({
1409
+ p: 2,
1410
+ test: (...args) => {
1411
+ args = unpack(args, 'hsl');
1412
+ if (type(args) === 'array' && args.length === 3) {
1413
+ return 'hsl';
1414
+ }
1415
+ }
1416
+ });
1417
+
1418
+ const hsl = (col1, col2, f) => {
1419
+ return interpolate_hsx(col1, col2, f, 'hsl');
1420
+ };
1421
+
1422
+ // register interpolator
1423
+ index.hsl = hsl;
1424
+
1425
+ const { floor: floor$2 } = Math;
1426
+
1427
+ const hsv2rgb = (...args) => {
1428
+ args = unpack(args, 'hsv');
1429
+ let [h, s, v] = args;
1430
+ let r, g, b;
1431
+ v *= 255;
1432
+ if (s === 0) {
1433
+ r = g = b = v;
1434
+ } else {
1435
+ if (h === 360) h = 0;
1436
+ if (h > 360) h -= 360;
1437
+ if (h < 0) h += 360;
1438
+ h /= 60;
1439
+
1440
+ const i = floor$2(h);
1441
+ const f = h - i;
1442
+ const p = v * (1 - s);
1443
+ const q = v * (1 - s * f);
1444
+ const t = v * (1 - s * (1 - f));
1445
+
1446
+ switch (i) {
1447
+ case 0:
1448
+ [r, g, b] = [v, t, p];
1449
+ break;
1450
+ case 1:
1451
+ [r, g, b] = [q, v, p];
1452
+ break;
1453
+ case 2:
1454
+ [r, g, b] = [p, v, t];
1455
+ break;
1456
+ case 3:
1457
+ [r, g, b] = [p, q, v];
1458
+ break;
1459
+ case 4:
1460
+ [r, g, b] = [t, p, v];
1461
+ break;
1462
+ case 5:
1463
+ [r, g, b] = [v, p, q];
1464
+ break;
1465
+ }
1466
+ }
1467
+ return [r, g, b, args.length > 3 ? args[3] : 1];
1468
+ };
1469
+
1470
+ const { min: min$1, max: max$2 } = Math;
1471
+
1472
+ /*
1473
+ * supported arguments:
1474
+ * - rgb2hsv(r,g,b)
1475
+ * - rgb2hsv([r,g,b])
1476
+ * - rgb2hsv({r,g,b})
1477
+ */
1478
+ const rgb2hsl = (...args) => {
1479
+ args = unpack(args, 'rgb');
1480
+ let [r, g, b] = args;
1481
+ const min_ = min$1(r, g, b);
1482
+ const max_ = max$2(r, g, b);
1483
+ const delta = max_ - min_;
1484
+ let h, s, v;
1485
+ v = max_ / 255.0;
1486
+ if (max_ === 0) {
1487
+ h = Number.NaN;
1488
+ s = 0;
1489
+ } else {
1490
+ s = delta / max_;
1491
+ if (r === max_) h = (g - b) / delta;
1492
+ if (g === max_) h = 2 + (b - r) / delta;
1493
+ if (b === max_) h = 4 + (r - g) / delta;
1494
+ h *= 60;
1495
+ if (h < 0) h += 360;
1496
+ }
1497
+ return [h, s, v];
1498
+ };
1499
+
1500
+ Color.prototype.hsv = function () {
1501
+ return rgb2hsl(this._rgb);
1502
+ };
1503
+
1504
+ const hsv$1 = (...args) => new Color(...args, 'hsv');
1505
+ chroma.hsv = hsv$1;
1506
+
1507
+ input.format.hsv = hsv2rgb;
1508
+
1509
+ input.autodetect.push({
1510
+ p: 2,
1511
+ test: (...args) => {
1512
+ args = unpack(args, 'hsv');
1513
+ if (type(args) === 'array' && args.length === 3) {
1514
+ return 'hsv';
1515
+ }
1516
+ }
1517
+ });
1518
+
1519
+ const hsv = (col1, col2, f) => {
1520
+ return interpolate_hsx(col1, col2, f, 'hsv');
1521
+ };
1522
+
1523
+ // register interpolator
1524
+ index.hsv = hsv;
1525
+
1526
+ // from https://www.w3.org/TR/css-color-4/multiply-matrices.js
1527
+ function multiplyMatrices(A, B) {
1528
+ let m = A.length;
1529
+
1530
+ if (!Array.isArray(A[0])) {
1531
+ // A is vector, convert to [[a, b, c, ...]]
1532
+ A = [A];
1533
+ }
1534
+
1535
+ if (!Array.isArray(B[0])) {
1536
+ // B is vector, convert to [[a], [b], [c], ...]]
1537
+ B = B.map((x) => [x]);
1538
+ }
1539
+
1540
+ let p = B[0].length;
1541
+ let B_cols = B[0].map((_, i) => B.map((x) => x[i])); // transpose B
1542
+ let product = A.map((row) =>
1543
+ B_cols.map((col) => {
1544
+ if (!Array.isArray(row)) {
1545
+ return col.reduce((a, c) => a + c * row, 0);
1546
+ }
1547
+
1548
+ return row.reduce((a, c, i) => a + c * (col[i] || 0), 0);
1549
+ })
1550
+ );
1551
+
1552
+ if (m === 1) {
1553
+ product = product[0]; // Avoid [[a, b, c, ...]]
1554
+ }
1555
+
1556
+ if (p === 1) {
1557
+ return product.map((x) => x[0]); // Avoid [[a], [b], [c], ...]]
1558
+ }
1559
+
1560
+ return product;
1561
+ }
1562
+
1563
+ const oklab2rgb = (...args) => {
1564
+ args = unpack(args, 'lab');
1565
+ const [L, a, b, ...rest] = args;
1566
+ const [X, Y, Z] = OKLab_to_XYZ([L, a, b]);
1567
+ const [r, g, b_] = xyz2rgb(X, Y, Z);
1568
+ return [r, g, b_, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
1569
+ };
1570
+
1571
+ // from https://www.w3.org/TR/css-color-4/#color-conversion-code
1572
+ function OKLab_to_XYZ(OKLab) {
1573
+ // Given OKLab, convert to XYZ relative to D65
1574
+ var LMStoXYZ = [
1575
+ [1.2268798758459243, -0.5578149944602171, 0.2813910456659647],
1576
+ [-0.0405757452148008, 1.112286803280317, -0.0717110580655164],
1577
+ [-0.0763729366746601, -0.4214933324022432, 1.5869240198367816]
1578
+ ];
1579
+ var OKLabtoLMS = [
1580
+ [1.0, 0.3963377773761749, 0.2158037573099136],
1581
+ [1.0, -0.1055613458156586, -0.0638541728258133],
1582
+ [1.0, -0.0894841775298119, -1.2914855480194092]
1583
+ ];
1584
+
1585
+ var LMSnl = multiplyMatrices(OKLabtoLMS, OKLab);
1586
+ return multiplyMatrices(
1587
+ LMStoXYZ,
1588
+ LMSnl.map((c) => c ** 3)
1589
+ );
1590
+ }
1591
+
1592
+ const rgb2oklab = (...args) => {
1593
+ const [r, g, b, ...rest] = unpack(args, 'rgb');
1594
+ const xyz = rgb2xyz(r, g, b);
1595
+ const oklab = XYZ_to_OKLab(xyz);
1596
+ return [...oklab, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
1597
+ };
1598
+
1599
+ // from https://www.w3.org/TR/css-color-4/#color-conversion-code
1600
+ function XYZ_to_OKLab(XYZ) {
1601
+ // Given XYZ relative to D65, convert to OKLab
1602
+ const XYZtoLMS = [
1603
+ [0.819022437996703, 0.3619062600528904, -0.1288737815209879],
1604
+ [0.0329836539323885, 0.9292868615863434, 0.0361446663506424],
1605
+ [0.0481771893596242, 0.2642395317527308, 0.6335478284694309]
1606
+ ];
1607
+ const LMStoOKLab = [
1608
+ [0.210454268309314, 0.7936177747023054, -0.0040720430116193],
1609
+ [1.9779985324311684, -2.42859224204858, 0.450593709617411],
1610
+ [0.0259040424655478, 0.7827717124575296, -0.8086757549230774]
1611
+ ];
1612
+
1613
+ const LMS = multiplyMatrices(XYZtoLMS, XYZ);
1614
+ // JavaScript Math.cbrt returns a sign-matched cube root
1615
+ // beware if porting to other languages
1616
+ // especially if tempted to use a general power function
1617
+ return multiplyMatrices(
1618
+ LMStoOKLab,
1619
+ LMS.map((c) => Math.cbrt(c))
1620
+ );
1621
+ // L in range [0,1]. For use in CSS, multiply by 100 and add a percent
1622
+ }
1623
+
1624
+ Color.prototype.oklab = function () {
1625
+ return rgb2oklab(this._rgb);
1626
+ };
1627
+
1628
+ const oklab$1 = (...args) => new Color(...args, 'oklab');
1629
+ Object.assign(chroma, { oklab: oklab$1 });
1630
+
1631
+ input.format.oklab = oklab2rgb;
1632
+
1633
+ input.autodetect.push({
1634
+ p: 2,
1635
+ test: (...args) => {
1636
+ args = unpack(args, 'oklab');
1637
+ if (type(args) === 'array' && args.length === 3) {
1638
+ return 'oklab';
1639
+ }
1640
+ }
1641
+ });
1642
+
1643
+ const oklab = (col1, col2, f) => {
1644
+ const xyz0 = col1.oklab();
1645
+ const xyz1 = col2.oklab();
1646
+ return new Color(
1647
+ xyz0[0] + f * (xyz1[0] - xyz0[0]),
1648
+ xyz0[1] + f * (xyz1[1] - xyz0[1]),
1649
+ xyz0[2] + f * (xyz1[2] - xyz0[2]),
1650
+ 'oklab'
1651
+ );
1652
+ };
1653
+
1654
+ // register interpolator
1655
+ index.oklab = oklab;
1656
+
1657
+ const oklch$1 = (col1, col2, f) => {
1658
+ return interpolate_hsx(col1, col2, f, 'oklch');
1659
+ };
1660
+
1661
+ // register interpolator
1662
+ index.oklch = oklch$1;
1663
+
1664
+ const { pow: pow$4, sqrt: sqrt$1, PI: PI$1, cos: cos$2, sin: sin$2, atan2: atan2$1 } = Math;
1665
+
1666
+ const average = (colors, mode = 'lrgb', weights = null) => {
1667
+ const l = colors.length;
1668
+ if (!weights) weights = Array.from(new Array(l)).map(() => 1);
1669
+ // normalize weights
1670
+ const k =
1671
+ l /
1672
+ weights.reduce(function (a, b) {
1673
+ return a + b;
1674
+ });
1675
+ weights.forEach((w, i) => {
1676
+ weights[i] *= k;
1677
+ });
1678
+ // convert colors to Color objects
1679
+ colors = colors.map((c) => new Color(c));
1680
+ if (mode === 'lrgb') {
1681
+ return _average_lrgb(colors, weights);
1682
+ }
1683
+ const first = colors.shift();
1684
+ const xyz = first.get(mode);
1685
+ const cnt = [];
1686
+ let dx = 0;
1687
+ let dy = 0;
1688
+ // initial color
1689
+ for (let i = 0; i < xyz.length; i++) {
1690
+ xyz[i] = (xyz[i] || 0) * weights[0];
1691
+ cnt.push(isNaN(xyz[i]) ? 0 : weights[0]);
1692
+ if (mode.charAt(i) === 'h' && !isNaN(xyz[i])) {
1693
+ const A = (xyz[i] / 180) * PI$1;
1694
+ dx += cos$2(A) * weights[0];
1695
+ dy += sin$2(A) * weights[0];
1696
+ }
1697
+ }
1698
+
1699
+ let alpha = first.alpha() * weights[0];
1700
+ colors.forEach((c, ci) => {
1701
+ const xyz2 = c.get(mode);
1702
+ alpha += c.alpha() * weights[ci + 1];
1703
+ for (let i = 0; i < xyz.length; i++) {
1704
+ if (!isNaN(xyz2[i])) {
1705
+ cnt[i] += weights[ci + 1];
1706
+ if (mode.charAt(i) === 'h') {
1707
+ const A = (xyz2[i] / 180) * PI$1;
1708
+ dx += cos$2(A) * weights[ci + 1];
1709
+ dy += sin$2(A) * weights[ci + 1];
1710
+ } else {
1711
+ xyz[i] += xyz2[i] * weights[ci + 1];
1712
+ }
1713
+ }
1714
+ }
1715
+ });
1716
+
1717
+ for (let i = 0; i < xyz.length; i++) {
1718
+ if (mode.charAt(i) === 'h') {
1719
+ let A = (atan2$1(dy / cnt[i], dx / cnt[i]) / PI$1) * 180;
1720
+ while (A < 0) A += 360;
1721
+ while (A >= 360) A -= 360;
1722
+ xyz[i] = A;
1723
+ } else {
1724
+ xyz[i] = xyz[i] / cnt[i];
1725
+ }
1726
+ }
1727
+ alpha /= l;
1728
+ return new Color(xyz, mode).alpha(alpha > 0.99999 ? 1 : alpha, true);
1729
+ };
1730
+
1731
+ const _average_lrgb = (colors, weights) => {
1732
+ const l = colors.length;
1733
+ const xyz = [0, 0, 0, 0];
1734
+ for (let i = 0; i < colors.length; i++) {
1735
+ const col = colors[i];
1736
+ const f = weights[i] / l;
1737
+ const rgb = col._rgb;
1738
+ xyz[0] += pow$4(rgb[0], 2) * f;
1739
+ xyz[1] += pow$4(rgb[1], 2) * f;
1740
+ xyz[2] += pow$4(rgb[2], 2) * f;
1741
+ xyz[3] += rgb[3] * f;
1742
+ }
1743
+ xyz[0] = sqrt$1(xyz[0]);
1744
+ xyz[1] = sqrt$1(xyz[1]);
1745
+ xyz[2] = sqrt$1(xyz[2]);
1746
+ if (xyz[3] > 0.9999999) xyz[3] = 1;
1747
+ return new Color(clip_rgb(xyz));
1748
+ };
1749
+
1750
+ // minimal multi-purpose interface
1751
+
1752
+
1753
+ const { pow: pow$3 } = Math;
1754
+
1755
+ function scale (colors) {
1756
+ // constructor
1757
+ let _mode = 'rgb';
1758
+ let _nacol = chroma('#ccc');
1759
+ let _spread = 0;
1760
+ // const _fixed = false;
1761
+ let _domain = [0, 1];
1762
+ let _pos = [];
1763
+ let _padding = [0, 0];
1764
+ let _classes = false;
1765
+ let _colors = [];
1766
+ let _out = false;
1767
+ let _min = 0;
1768
+ let _max = 1;
1769
+ let _correctLightness = false;
1770
+ let _colorCache = {};
1771
+ let _useCache = true;
1772
+ let _gamma = 1;
1773
+
1774
+ // private methods
1775
+
1776
+ const setColors = function (colors) {
1777
+ colors = colors || ['#fff', '#000'];
1778
+ if (
1779
+ colors &&
1780
+ type(colors) === 'string' &&
1781
+ chroma.brewer &&
1782
+ chroma.brewer[colors.toLowerCase()]
1783
+ ) {
1784
+ colors = chroma.brewer[colors.toLowerCase()];
1785
+ }
1786
+ if (type(colors) === 'array') {
1787
+ // handle single color
1788
+ if (colors.length === 1) {
1789
+ colors = [colors[0], colors[0]];
1790
+ }
1791
+ // make a copy of the colors
1792
+ colors = colors.slice(0);
1793
+ // convert to chroma classes
1794
+ for (let c = 0; c < colors.length; c++) {
1795
+ colors[c] = chroma(colors[c]);
1796
+ }
1797
+ // auto-fill color position
1798
+ _pos.length = 0;
1799
+ for (let c = 0; c < colors.length; c++) {
1800
+ _pos.push(c / (colors.length - 1));
1801
+ }
1802
+ }
1803
+ resetCache();
1804
+ return (_colors = colors);
1805
+ };
1806
+
1807
+ const getClass = function (value) {
1808
+ if (_classes != null) {
1809
+ const n = _classes.length - 1;
1810
+ let i = 0;
1811
+ while (i < n && value >= _classes[i]) {
1812
+ i++;
1813
+ }
1814
+ return i - 1;
1815
+ }
1816
+ return 0;
1817
+ };
1818
+
1819
+ let tMapLightness = (t) => t;
1820
+ let tMapDomain = (t) => t;
1821
+
1822
+ // const classifyValue = function(value) {
1823
+ // let val = value;
1824
+ // if (_classes.length > 2) {
1825
+ // const n = _classes.length-1;
1826
+ // const i = getClass(value);
1827
+ // const minc = _classes[0] + ((_classes[1]-_classes[0]) * (0 + (_spread * 0.5))); // center of 1st class
1828
+ // const maxc = _classes[n-1] + ((_classes[n]-_classes[n-1]) * (1 - (_spread * 0.5))); // center of last class
1829
+ // val = _min + ((((_classes[i] + ((_classes[i+1] - _classes[i]) * 0.5)) - minc) / (maxc-minc)) * (_max - _min));
1830
+ // }
1831
+ // return val;
1832
+ // };
1833
+
1834
+ const getColor = function (val, bypassMap) {
1835
+ let col, t;
1836
+ if (bypassMap == null) {
1837
+ bypassMap = false;
1838
+ }
1839
+ if (isNaN(val) || val === null) {
1840
+ return _nacol;
1841
+ }
1842
+ if (!bypassMap) {
1843
+ if (_classes && _classes.length > 2) {
1844
+ // find the class
1845
+ const c = getClass(val);
1846
+ t = c / (_classes.length - 2);
1847
+ } else if (_max !== _min) {
1848
+ // just interpolate between min/max
1849
+ t = (val - _min) / (_max - _min);
1850
+ } else {
1851
+ t = 1;
1852
+ }
1853
+ } else {
1854
+ t = val;
1855
+ }
1856
+
1857
+ // domain map
1858
+ t = tMapDomain(t);
1859
+
1860
+ if (!bypassMap) {
1861
+ t = tMapLightness(t); // lightness correction
1862
+ }
1863
+
1864
+ if (_gamma !== 1) {
1865
+ t = pow$3(t, _gamma);
1866
+ }
1867
+
1868
+ t = _padding[0] + t * (1 - _padding[0] - _padding[1]);
1869
+
1870
+ t = limit(t, 0, 1);
1871
+
1872
+ const k = Math.floor(t * 10000);
1873
+
1874
+ if (_useCache && _colorCache[k]) {
1875
+ col = _colorCache[k];
1876
+ } else {
1877
+ if (type(_colors) === 'array') {
1878
+ //for i in [0.._pos.length-1]
1879
+ for (let i = 0; i < _pos.length; i++) {
1880
+ const p = _pos[i];
1881
+ if (t <= p) {
1882
+ col = _colors[i];
1883
+ break;
1884
+ }
1885
+ if (t >= p && i === _pos.length - 1) {
1886
+ col = _colors[i];
1887
+ break;
1888
+ }
1889
+ if (t > p && t < _pos[i + 1]) {
1890
+ t = (t - p) / (_pos[i + 1] - p);
1891
+ col = chroma.interpolate(
1892
+ _colors[i],
1893
+ _colors[i + 1],
1894
+ t,
1895
+ _mode
1896
+ );
1897
+ break;
1898
+ }
1899
+ }
1900
+ } else if (type(_colors) === 'function') {
1901
+ col = _colors(t);
1902
+ }
1903
+ if (_useCache) {
1904
+ _colorCache[k] = col;
1905
+ }
1906
+ }
1907
+ return col;
1908
+ };
1909
+
1910
+ var resetCache = () => (_colorCache = {});
1911
+
1912
+ setColors(colors);
1913
+
1914
+ // public interface
1915
+
1916
+ const f = function (v) {
1917
+ const c = chroma(getColor(v));
1918
+ if (_out && c[_out]) {
1919
+ return c[_out]();
1920
+ } else {
1921
+ return c;
1922
+ }
1923
+ };
1924
+
1925
+ f.classes = function (classes) {
1926
+ if (classes != null) {
1927
+ if (type(classes) === 'array') {
1928
+ _classes = classes;
1929
+ _domain = [classes[0], classes[classes.length - 1]];
1930
+ } else {
1931
+ const d = chroma.analyze(_domain);
1932
+ if (classes === 0) {
1933
+ _classes = [d.min, d.max];
1934
+ } else {
1935
+ _classes = chroma.limits(d, 'e', classes);
1936
+ }
1937
+ }
1938
+ return f;
1939
+ }
1940
+ return _classes;
1941
+ };
1942
+
1943
+ f.domain = function (domain) {
1944
+ if (!arguments.length) {
1945
+ return _domain;
1946
+ }
1947
+ _min = domain[0];
1948
+ _max = domain[domain.length - 1];
1949
+ _pos = [];
1950
+ const k = _colors.length;
1951
+ if (domain.length === k && _min !== _max) {
1952
+ // update positions
1953
+ for (let d of Array.from(domain)) {
1954
+ _pos.push((d - _min) / (_max - _min));
1955
+ }
1956
+ } else {
1957
+ for (let c = 0; c < k; c++) {
1958
+ _pos.push(c / (k - 1));
1959
+ }
1960
+ if (domain.length > 2) {
1961
+ // set domain map
1962
+ const tOut = domain.map((d, i) => i / (domain.length - 1));
1963
+ const tBreaks = domain.map((d) => (d - _min) / (_max - _min));
1964
+ if (!tBreaks.every((val, i) => tOut[i] === val)) {
1965
+ tMapDomain = (t) => {
1966
+ if (t <= 0 || t >= 1) return t;
1967
+ let i = 0;
1968
+ while (t >= tBreaks[i + 1]) i++;
1969
+ const f =
1970
+ (t - tBreaks[i]) / (tBreaks[i + 1] - tBreaks[i]);
1971
+ const out = tOut[i] + f * (tOut[i + 1] - tOut[i]);
1972
+ return out;
1973
+ };
1974
+ }
1975
+ }
1976
+ }
1977
+ _domain = [_min, _max];
1978
+ return f;
1979
+ };
1980
+
1981
+ f.mode = function (_m) {
1982
+ if (!arguments.length) {
1983
+ return _mode;
1984
+ }
1985
+ _mode = _m;
1986
+ resetCache();
1987
+ return f;
1988
+ };
1989
+
1990
+ f.range = function (colors, _pos) {
1991
+ setColors(colors);
1992
+ return f;
1993
+ };
1994
+
1995
+ f.out = function (_o) {
1996
+ _out = _o;
1997
+ return f;
1998
+ };
1999
+
2000
+ f.spread = function (val) {
2001
+ if (!arguments.length) {
2002
+ return _spread;
2003
+ }
2004
+ _spread = val;
2005
+ return f;
2006
+ };
2007
+
2008
+ f.correctLightness = function (v) {
2009
+ if (v == null) {
2010
+ v = true;
2011
+ }
2012
+ _correctLightness = v;
2013
+ resetCache();
2014
+ if (_correctLightness) {
2015
+ tMapLightness = function (t) {
2016
+ const L0 = getColor(0, true).lab()[0];
2017
+ const L1 = getColor(1, true).lab()[0];
2018
+ const pol = L0 > L1;
2019
+ let L_actual = getColor(t, true).lab()[0];
2020
+ const L_ideal = L0 + (L1 - L0) * t;
2021
+ let L_diff = L_actual - L_ideal;
2022
+ let t0 = 0;
2023
+ let t1 = 1;
2024
+ let max_iter = 20;
2025
+ while (Math.abs(L_diff) > 1e-2 && max_iter-- > 0) {
2026
+ (function () {
2027
+ if (pol) {
2028
+ L_diff *= -1;
2029
+ }
2030
+ if (L_diff < 0) {
2031
+ t0 = t;
2032
+ t += (t1 - t) * 0.5;
2033
+ } else {
2034
+ t1 = t;
2035
+ t += (t0 - t) * 0.5;
2036
+ }
2037
+ L_actual = getColor(t, true).lab()[0];
2038
+ return (L_diff = L_actual - L_ideal);
2039
+ })();
2040
+ }
2041
+ return t;
2042
+ };
2043
+ } else {
2044
+ tMapLightness = (t) => t;
2045
+ }
2046
+ return f;
2047
+ };
2048
+
2049
+ f.padding = function (p) {
2050
+ if (p != null) {
2051
+ if (type(p) === 'number') {
2052
+ p = [p, p];
2053
+ }
2054
+ _padding = p;
2055
+ return f;
2056
+ } else {
2057
+ return _padding;
2058
+ }
2059
+ };
2060
+
2061
+ f.colors = function (numColors, out) {
2062
+ // If no arguments are given, return the original colors that were provided
2063
+ if (arguments.length < 2) {
2064
+ out = 'hex';
2065
+ }
2066
+ let result = [];
2067
+
2068
+ if (arguments.length === 0) {
2069
+ result = _colors.slice(0);
2070
+ } else if (numColors === 1) {
2071
+ result = [f(0.5)];
2072
+ } else if (numColors > 1) {
2073
+ const dm = _domain[0];
2074
+ const dd = _domain[1] - dm;
2075
+ result = __range__(0, numColors).map((i) =>
2076
+ f(dm + (i / (numColors - 1)) * dd)
2077
+ );
2078
+ } else {
2079
+ // returns all colors based on the defined classes
2080
+ colors = [];
2081
+ let samples = [];
2082
+ if (_classes && _classes.length > 2) {
2083
+ for (
2084
+ let i = 1, end = _classes.length, asc = 1 <= end;
2085
+ asc ? i < end : i > end;
2086
+ asc ? i++ : i--
2087
+ ) {
2088
+ samples.push((_classes[i - 1] + _classes[i]) * 0.5);
2089
+ }
2090
+ } else {
2091
+ samples = _domain;
2092
+ }
2093
+ result = samples.map((v) => f(v));
2094
+ }
2095
+
2096
+ if (chroma[out]) {
2097
+ result = result.map((c) => c[out]());
2098
+ }
2099
+ return result;
2100
+ };
2101
+
2102
+ f.cache = function (c) {
2103
+ if (c != null) {
2104
+ _useCache = c;
2105
+ return f;
2106
+ } else {
2107
+ return _useCache;
2108
+ }
2109
+ };
2110
+
2111
+ f.gamma = function (g) {
2112
+ if (g != null) {
2113
+ _gamma = g;
2114
+ return f;
2115
+ } else {
2116
+ return _gamma;
2117
+ }
2118
+ };
2119
+
2120
+ f.nodata = function (d) {
2121
+ if (d != null) {
2122
+ _nacol = chroma(d);
2123
+ return f;
2124
+ } else {
2125
+ return _nacol;
2126
+ }
2127
+ };
2128
+
2129
+ return f;
2130
+ }
2131
+
2132
+ function __range__(left, right, inclusive) {
2133
+ let range = [];
2134
+ let ascending = left < right;
2135
+ let end = right ;
2136
+ for (let i = left; ascending ? i < end : i > end; ascending ? i++ : i--) {
2137
+ range.push(i);
2138
+ }
2139
+ return range;
2140
+ }
2141
+
2142
+ //
2143
+ // interpolates between a set of colors uzing a bezier spline
2144
+ //
2145
+
2146
+
2147
+ // nth row of the pascal triangle
2148
+ const binom_row = function (n) {
2149
+ let row = [1, 1];
2150
+ for (let i = 1; i < n; i++) {
2151
+ let newrow = [1];
2152
+ for (let j = 1; j <= row.length; j++) {
2153
+ newrow[j] = (row[j] || 0) + row[j - 1];
2154
+ }
2155
+ row = newrow;
2156
+ }
2157
+ return row;
2158
+ };
2159
+
2160
+ const bezier = function (colors) {
2161
+ let I, lab0, lab1, lab2;
2162
+ colors = colors.map((c) => new Color(c));
2163
+ if (colors.length === 2) {
2164
+ // linear interpolation
2165
+ [lab0, lab1] = colors.map((c) => c.lab());
2166
+ I = function (t) {
2167
+ const lab = [0, 1, 2].map((i) => lab0[i] + t * (lab1[i] - lab0[i]));
2168
+ return new Color(lab, 'lab');
2169
+ };
2170
+ } else if (colors.length === 3) {
2171
+ // quadratic bezier interpolation
2172
+ [lab0, lab1, lab2] = colors.map((c) => c.lab());
2173
+ I = function (t) {
2174
+ const lab = [0, 1, 2].map(
2175
+ (i) =>
2176
+ (1 - t) * (1 - t) * lab0[i] +
2177
+ 2 * (1 - t) * t * lab1[i] +
2178
+ t * t * lab2[i]
2179
+ );
2180
+ return new Color(lab, 'lab');
2181
+ };
2182
+ } else if (colors.length === 4) {
2183
+ // cubic bezier interpolation
2184
+ let lab3;
2185
+ [lab0, lab1, lab2, lab3] = colors.map((c) => c.lab());
2186
+ I = function (t) {
2187
+ const lab = [0, 1, 2].map(
2188
+ (i) =>
2189
+ (1 - t) * (1 - t) * (1 - t) * lab0[i] +
2190
+ 3 * (1 - t) * (1 - t) * t * lab1[i] +
2191
+ 3 * (1 - t) * t * t * lab2[i] +
2192
+ t * t * t * lab3[i]
2193
+ );
2194
+ return new Color(lab, 'lab');
2195
+ };
2196
+ } else if (colors.length >= 5) {
2197
+ // general case (degree n bezier)
2198
+ let labs, row, n;
2199
+ labs = colors.map((c) => c.lab());
2200
+ n = colors.length - 1;
2201
+ row = binom_row(n);
2202
+ I = function (t) {
2203
+ const u = 1 - t;
2204
+ const lab = [0, 1, 2].map((i) =>
2205
+ labs.reduce(
2206
+ (sum, el, j) =>
2207
+ sum + row[j] * u ** (n - j) * t ** j * el[i],
2208
+ 0
2209
+ )
2210
+ );
2211
+ return new Color(lab, 'lab');
2212
+ };
2213
+ } else {
2214
+ throw new RangeError('No point in running bezier with only one color.');
2215
+ }
2216
+ return I;
2217
+ };
2218
+
2219
+ const bezier$1 = (colors) => {
2220
+ const f = bezier(colors);
2221
+ f.scale = () => scale(f);
2222
+ return f;
2223
+ };
2224
+
2225
+ const { round: round$3 } = Math;
2226
+
2227
+ Color.prototype.rgb = function (rnd = true) {
2228
+ if (rnd === false) return this._rgb.slice(0, 3);
2229
+ return this._rgb.slice(0, 3).map(round$3);
2230
+ };
2231
+
2232
+ Color.prototype.rgba = function (rnd = true) {
2233
+ return this._rgb.slice(0, 4).map((v, i) => {
2234
+ return i < 3 ? (rnd === false ? v : round$3(v)) : v;
2235
+ });
2236
+ };
2237
+
2238
+ const rgb = (...args) => new Color(...args, 'rgb');
2239
+ Object.assign(chroma, { rgb });
2240
+
2241
+ input.format.rgb = (...args) => {
2242
+ const rgba = unpack(args, 'rgba');
2243
+ if (rgba[3] === undefined) rgba[3] = 1;
2244
+ return rgba;
2245
+ };
2246
+
2247
+ input.autodetect.push({
2248
+ p: 3,
2249
+ test: (...args) => {
2250
+ args = unpack(args, 'rgba');
2251
+ if (
2252
+ type(args) === 'array' &&
2253
+ (args.length === 3 ||
2254
+ (args.length === 4 &&
2255
+ type(args[3]) == 'number' &&
2256
+ args[3] >= 0 &&
2257
+ args[3] <= 1))
2258
+ ) {
2259
+ return 'rgb';
2260
+ }
2261
+ }
2262
+ });
2263
+
2264
+ /*
2265
+ * interpolates between a set of colors uzing a bezier spline
2266
+ * blend mode formulas taken from https://web.archive.org/web/20180110014946/http://www.venture-ware.com/kevin/coding/lets-learn-math-photoshop-blend-modes/
2267
+ */
2268
+
2269
+
2270
+ const blend = (bottom, top, mode) => {
2271
+ if (!blend[mode]) {
2272
+ throw new Error('unknown blend mode ' + mode);
2273
+ }
2274
+ return blend[mode](bottom, top);
2275
+ };
2276
+
2277
+ const blend_f = (f) => (bottom, top) => {
2278
+ const c0 = chroma(top).rgb();
2279
+ const c1 = chroma(bottom).rgb();
2280
+ return chroma.rgb(f(c0, c1));
2281
+ };
2282
+
2283
+ const each = (f) => (c0, c1) => {
2284
+ const out = [];
2285
+ out[0] = f(c0[0], c1[0]);
2286
+ out[1] = f(c0[1], c1[1]);
2287
+ out[2] = f(c0[2], c1[2]);
2288
+ return out;
2289
+ };
2290
+
2291
+ const normal = (a) => a;
2292
+ const multiply = (a, b) => (a * b) / 255;
2293
+ const darken = (a, b) => (a > b ? b : a);
2294
+ const lighten = (a, b) => (a > b ? a : b);
2295
+ const screen = (a, b) => 255 * (1 - (1 - a / 255) * (1 - b / 255));
2296
+ const overlay = (a, b) =>
2297
+ b < 128 ? (2 * a * b) / 255 : 255 * (1 - 2 * (1 - a / 255) * (1 - b / 255));
2298
+ const burn = (a, b) => 255 * (1 - (1 - b / 255) / (a / 255));
2299
+ const dodge = (a, b) => {
2300
+ if (a === 255) return 255;
2301
+ a = (255 * (b / 255)) / (1 - a / 255);
2302
+ return a > 255 ? 255 : a;
2303
+ };
2304
+
2305
+ // # add = (a,b) ->
2306
+ // # if (a + b > 255) then 255 else a + b
2307
+
2308
+ blend.normal = blend_f(each(normal));
2309
+ blend.multiply = blend_f(each(multiply));
2310
+ blend.screen = blend_f(each(screen));
2311
+ blend.overlay = blend_f(each(overlay));
2312
+ blend.darken = blend_f(each(darken));
2313
+ blend.lighten = blend_f(each(lighten));
2314
+ blend.dodge = blend_f(each(dodge));
2315
+ blend.burn = blend_f(each(burn));
2316
+
2317
+ // cubehelix interpolation
2318
+ // based on D.A. Green "A colour scheme for the display of astronomical intensity images"
2319
+ // http://astron-soc.in/bulletin/11June/289392011.pdf
2320
+ const { pow: pow$2, sin: sin$1, cos: cos$1 } = Math;
2321
+
2322
+ function cubehelix (
2323
+ start = 300,
2324
+ rotations = -1.5,
2325
+ hue = 1,
2326
+ gamma = 1,
2327
+ lightness = [0, 1]
2328
+ ) {
2329
+ let dh = 0,
2330
+ dl;
2331
+ if (type(lightness) === 'array') {
2332
+ dl = lightness[1] - lightness[0];
2333
+ } else {
2334
+ dl = 0;
2335
+ lightness = [lightness, lightness];
2336
+ }
2337
+ const f = function (fract) {
2338
+ const a = TWOPI * ((start + 120) / 360 + rotations * fract);
2339
+ const l = pow$2(lightness[0] + dl * fract, gamma);
2340
+ const h = dh !== 0 ? hue[0] + fract * dh : hue;
2341
+ const amp = (h * l * (1 - l)) / 2;
2342
+ const cos_a = cos$1(a);
2343
+ const sin_a = sin$1(a);
2344
+ const r = l + amp * (-0.14861 * cos_a + 1.78277 * sin_a);
2345
+ const g = l + amp * (-0.29227 * cos_a - 0.90649 * sin_a);
2346
+ const b = l + amp * (1.97294 * cos_a);
2347
+ return chroma(clip_rgb([r * 255, g * 255, b * 255, 1]));
2348
+ };
2349
+ f.start = function (s) {
2350
+ if (s == null) {
2351
+ return start;
2352
+ }
2353
+ start = s;
2354
+ return f;
2355
+ };
2356
+ f.rotations = function (r) {
2357
+ if (r == null) {
2358
+ return rotations;
2359
+ }
2360
+ rotations = r;
2361
+ return f;
2362
+ };
2363
+ f.gamma = function (g) {
2364
+ if (g == null) {
2365
+ return gamma;
2366
+ }
2367
+ gamma = g;
2368
+ return f;
2369
+ };
2370
+ f.hue = function (h) {
2371
+ if (h == null) {
2372
+ return hue;
2373
+ }
2374
+ hue = h;
2375
+ if (type(hue) === 'array') {
2376
+ dh = hue[1] - hue[0];
2377
+ if (dh === 0) {
2378
+ hue = hue[1];
2379
+ }
2380
+ } else {
2381
+ dh = 0;
2382
+ }
2383
+ return f;
2384
+ };
2385
+ f.lightness = function (h) {
2386
+ if (h == null) {
2387
+ return lightness;
2388
+ }
2389
+ if (type(h) === 'array') {
2390
+ lightness = h;
2391
+ dl = h[1] - h[0];
2392
+ } else {
2393
+ lightness = [h, h];
2394
+ dl = 0;
2395
+ }
2396
+ return f;
2397
+ };
2398
+ f.scale = () => chroma.scale(f);
2399
+ f.hue(hue);
2400
+ return f;
2401
+ }
2402
+
2403
+ const digits = '0123456789abcdef';
2404
+
2405
+ const { floor: floor$1, random } = Math;
2406
+
2407
+ const random$1 = () => {
2408
+ let code = '#';
2409
+ for (let i = 0; i < 6; i++) {
2410
+ code += digits.charAt(floor$1(random() * 16));
2411
+ }
2412
+ return new Color(code, 'hex');
2413
+ };
2414
+
2415
+ const { log: log$1, pow: pow$1, floor, abs: abs$1 } = Math;
2416
+
2417
+ function analyze(data, key = null) {
2418
+ const r = {
2419
+ min: Number.MAX_VALUE,
2420
+ max: Number.MAX_VALUE * -1,
2421
+ sum: 0,
2422
+ values: [],
2423
+ count: 0
2424
+ };
2425
+ if (type(data) === 'object') {
2426
+ data = Object.values(data);
2427
+ }
2428
+ data.forEach((val) => {
2429
+ if (key && type(val) === 'object') val = val[key];
2430
+ if (val !== undefined && val !== null && !isNaN(val)) {
2431
+ r.values.push(val);
2432
+ r.sum += val;
2433
+ if (val < r.min) r.min = val;
2434
+ if (val > r.max) r.max = val;
2435
+ r.count += 1;
2436
+ }
2437
+ });
2438
+
2439
+ r.domain = [r.min, r.max];
2440
+
2441
+ r.limits = (mode, num) => limits(r, mode, num);
2442
+
2443
+ return r;
2444
+ }
2445
+
2446
+ function limits(data, mode = 'equal', num = 7) {
2447
+ if (type(data) == 'array') {
2448
+ data = analyze(data);
2449
+ }
2450
+ const { min, max } = data;
2451
+ const values = data.values.sort((a, b) => a - b);
2452
+
2453
+ if (num === 1) {
2454
+ return [min, max];
2455
+ }
2456
+
2457
+ const limits = [];
2458
+
2459
+ if (mode.substr(0, 1) === 'c') {
2460
+ // continuous
2461
+ limits.push(min);
2462
+ limits.push(max);
2463
+ }
2464
+
2465
+ if (mode.substr(0, 1) === 'e') {
2466
+ // equal interval
2467
+ limits.push(min);
2468
+ for (let i = 1; i < num; i++) {
2469
+ limits.push(min + (i / num) * (max - min));
2470
+ }
2471
+ limits.push(max);
2472
+ } else if (mode.substr(0, 1) === 'l') {
2473
+ // log scale
2474
+ if (min <= 0) {
2475
+ throw new Error(
2476
+ 'Logarithmic scales are only possible for values > 0'
2477
+ );
2478
+ }
2479
+ const min_log = Math.LOG10E * log$1(min);
2480
+ const max_log = Math.LOG10E * log$1(max);
2481
+ limits.push(min);
2482
+ for (let i = 1; i < num; i++) {
2483
+ limits.push(pow$1(10, min_log + (i / num) * (max_log - min_log)));
2484
+ }
2485
+ limits.push(max);
2486
+ } else if (mode.substr(0, 1) === 'q') {
2487
+ // quantile scale
2488
+ limits.push(min);
2489
+ for (let i = 1; i < num; i++) {
2490
+ const p = ((values.length - 1) * i) / num;
2491
+ const pb = floor(p);
2492
+ if (pb === p) {
2493
+ limits.push(values[pb]);
2494
+ } else {
2495
+ // p > pb
2496
+ const pr = p - pb;
2497
+ limits.push(values[pb] * (1 - pr) + values[pb + 1] * pr);
2498
+ }
2499
+ }
2500
+ limits.push(max);
2501
+ } else if (mode.substr(0, 1) === 'k') {
2502
+ // k-means clustering
2503
+ /*
2504
+ implementation based on
2505
+ http://code.google.com/p/figue/source/browse/trunk/figue.js#336
2506
+ simplified for 1-d input values
2507
+ */
2508
+ let cluster;
2509
+ const n = values.length;
2510
+ const assignments = new Array(n);
2511
+ const clusterSizes = new Array(num);
2512
+ let repeat = true;
2513
+ let nb_iters = 0;
2514
+ let centroids = null;
2515
+
2516
+ // get seed values
2517
+ centroids = [];
2518
+ centroids.push(min);
2519
+ for (let i = 1; i < num; i++) {
2520
+ centroids.push(min + (i / num) * (max - min));
2521
+ }
2522
+ centroids.push(max);
2523
+
2524
+ while (repeat) {
2525
+ // assignment step
2526
+ for (let j = 0; j < num; j++) {
2527
+ clusterSizes[j] = 0;
2528
+ }
2529
+ for (let i = 0; i < n; i++) {
2530
+ const value = values[i];
2531
+ let mindist = Number.MAX_VALUE;
2532
+ let best;
2533
+ for (let j = 0; j < num; j++) {
2534
+ const dist = abs$1(centroids[j] - value);
2535
+ if (dist < mindist) {
2536
+ mindist = dist;
2537
+ best = j;
2538
+ }
2539
+ clusterSizes[best]++;
2540
+ assignments[i] = best;
2541
+ }
2542
+ }
2543
+
2544
+ // update centroids step
2545
+ const newCentroids = new Array(num);
2546
+ for (let j = 0; j < num; j++) {
2547
+ newCentroids[j] = null;
2548
+ }
2549
+ for (let i = 0; i < n; i++) {
2550
+ cluster = assignments[i];
2551
+ if (newCentroids[cluster] === null) {
2552
+ newCentroids[cluster] = values[i];
2553
+ } else {
2554
+ newCentroids[cluster] += values[i];
2555
+ }
2556
+ }
2557
+ for (let j = 0; j < num; j++) {
2558
+ newCentroids[j] *= 1 / clusterSizes[j];
2559
+ }
2560
+
2561
+ // check convergence
2562
+ repeat = false;
2563
+ for (let j = 0; j < num; j++) {
2564
+ if (newCentroids[j] !== centroids[j]) {
2565
+ repeat = true;
2566
+ break;
2567
+ }
2568
+ }
2569
+
2570
+ centroids = newCentroids;
2571
+ nb_iters++;
2572
+
2573
+ if (nb_iters > 200) {
2574
+ repeat = false;
2575
+ }
2576
+ }
2577
+
2578
+ // finished k-means clustering
2579
+ // the next part is borrowed from gabrielflor.it
2580
+ const kClusters = {};
2581
+ for (let j = 0; j < num; j++) {
2582
+ kClusters[j] = [];
2583
+ }
2584
+ for (let i = 0; i < n; i++) {
2585
+ cluster = assignments[i];
2586
+ kClusters[cluster].push(values[i]);
2587
+ }
2588
+ let tmpKMeansBreaks = [];
2589
+ for (let j = 0; j < num; j++) {
2590
+ tmpKMeansBreaks.push(kClusters[j][0]);
2591
+ tmpKMeansBreaks.push(kClusters[j][kClusters[j].length - 1]);
2592
+ }
2593
+ tmpKMeansBreaks = tmpKMeansBreaks.sort((a, b) => a - b);
2594
+ limits.push(tmpKMeansBreaks[0]);
2595
+ for (let i = 1; i < tmpKMeansBreaks.length; i += 2) {
2596
+ const v = tmpKMeansBreaks[i];
2597
+ if (!isNaN(v) && limits.indexOf(v) === -1) {
2598
+ limits.push(v);
2599
+ }
2600
+ }
2601
+ }
2602
+ return limits;
2603
+ }
2604
+
2605
+ const contrast = (a, b) => {
2606
+ // WCAG contrast ratio
2607
+ // see http://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef
2608
+ a = new Color(a);
2609
+ b = new Color(b);
2610
+ const l1 = a.luminance();
2611
+ const l2 = b.luminance();
2612
+ return l1 > l2 ? (l1 + 0.05) / (l2 + 0.05) : (l2 + 0.05) / (l1 + 0.05);
2613
+ };
2614
+
2615
+ /**
2616
+ * @license
2617
+ *
2618
+ * The APCA contrast prediction algorithm is based of the formulas published
2619
+ * in the APCA-1.0.98G specification by Myndex. The specification is available at:
2620
+ * https://raw.githubusercontent.com/Myndex/apca-w3/master/images/APCAw3_0.1.17_APCA0.0.98G.svg
2621
+ *
2622
+ * Note that the APCA implementation is still beta, so please update to
2623
+ * future versions of chroma.js when they become available.
2624
+ *
2625
+ * You can read more about the APCA Readability Criterion at
2626
+ * https://readtech.org/ARC/
2627
+ */
2628
+
2629
+ // constants
2630
+ const W_offset = 0.027;
2631
+ const P_in = 0.0005;
2632
+ const P_out = 0.1;
2633
+ const R_scale = 1.14;
2634
+ const B_threshold = 0.022;
2635
+ const B_exp = 1.414;
2636
+
2637
+ const contrastAPCA = (text, bg) => {
2638
+ // parse input colors
2639
+ text = new Color(text);
2640
+ bg = new Color(bg);
2641
+ // if text color has alpha, blend against background
2642
+ if (text.alpha() < 1) {
2643
+ text = mix(bg, text, text.alpha(), 'rgb');
2644
+ }
2645
+ const l_text = lum(...text.rgb());
2646
+ const l_bg = lum(...bg.rgb());
2647
+
2648
+ // soft clamp black levels
2649
+ const Y_text =
2650
+ l_text >= B_threshold
2651
+ ? l_text
2652
+ : l_text + Math.pow(B_threshold - l_text, B_exp);
2653
+ const Y_bg =
2654
+ l_bg >= B_threshold ? l_bg : l_bg + Math.pow(B_threshold - l_bg, B_exp);
2655
+
2656
+ // normal polarity (dark text on light background)
2657
+ const S_norm = Math.pow(Y_bg, 0.56) - Math.pow(Y_text, 0.57);
2658
+ // reverse polarity (light text on dark background)
2659
+ const S_rev = Math.pow(Y_bg, 0.65) - Math.pow(Y_text, 0.62);
2660
+ // clamp noise then scale
2661
+ const C =
2662
+ Math.abs(Y_bg - Y_text) < P_in
2663
+ ? 0
2664
+ : Y_text < Y_bg
2665
+ ? S_norm * R_scale
2666
+ : S_rev * R_scale;
2667
+ // clamp minimum contrast then offset
2668
+ const S_apc = Math.abs(C) < P_out ? 0 : C > 0 ? C - W_offset : C + W_offset;
2669
+ // scale to 100
2670
+ return S_apc * 100;
2671
+ };
2672
+
2673
+ function lum(r, g, b) {
2674
+ return (
2675
+ 0.2126729 * Math.pow(r / 255, 2.4) +
2676
+ 0.7151522 * Math.pow(g / 255, 2.4) +
2677
+ 0.072175 * Math.pow(b / 255, 2.4)
2678
+ );
2679
+ }
2680
+
2681
+ const { sqrt, pow, min, max: max$1, atan2, abs, cos, sin, exp, PI } = Math;
2682
+
2683
+ function deltaE (a, b, Kl = 1, Kc = 1, Kh = 1) {
2684
+ // Delta E (CIE 2000)
2685
+ // see http://www.brucelindbloom.com/index.html?Eqn_DeltaE_CIE2000.html
2686
+ var rad2deg = function (rad) {
2687
+ return (360 * rad) / (2 * PI);
2688
+ };
2689
+ var deg2rad = function (deg) {
2690
+ return (2 * PI * deg) / 360;
2691
+ };
2692
+ a = new Color(a);
2693
+ b = new Color(b);
2694
+ const [L1, a1, b1] = Array.from(a.lab());
2695
+ const [L2, a2, b2] = Array.from(b.lab());
2696
+ const avgL = (L1 + L2) / 2;
2697
+ const C1 = sqrt(pow(a1, 2) + pow(b1, 2));
2698
+ const C2 = sqrt(pow(a2, 2) + pow(b2, 2));
2699
+ const avgC = (C1 + C2) / 2;
2700
+ const G = 0.5 * (1 - sqrt(pow(avgC, 7) / (pow(avgC, 7) + pow(25, 7))));
2701
+ const a1p = a1 * (1 + G);
2702
+ const a2p = a2 * (1 + G);
2703
+ const C1p = sqrt(pow(a1p, 2) + pow(b1, 2));
2704
+ const C2p = sqrt(pow(a2p, 2) + pow(b2, 2));
2705
+ const avgCp = (C1p + C2p) / 2;
2706
+ const arctan1 = rad2deg(atan2(b1, a1p));
2707
+ const arctan2 = rad2deg(atan2(b2, a2p));
2708
+ const h1p = arctan1 >= 0 ? arctan1 : arctan1 + 360;
2709
+ const h2p = arctan2 >= 0 ? arctan2 : arctan2 + 360;
2710
+ const avgHp =
2711
+ abs(h1p - h2p) > 180 ? (h1p + h2p + 360) / 2 : (h1p + h2p) / 2;
2712
+ const T =
2713
+ 1 -
2714
+ 0.17 * cos(deg2rad(avgHp - 30)) +
2715
+ 0.24 * cos(deg2rad(2 * avgHp)) +
2716
+ 0.32 * cos(deg2rad(3 * avgHp + 6)) -
2717
+ 0.2 * cos(deg2rad(4 * avgHp - 63));
2718
+ let deltaHp = h2p - h1p;
2719
+ deltaHp =
2720
+ abs(deltaHp) <= 180
2721
+ ? deltaHp
2722
+ : h2p <= h1p
2723
+ ? deltaHp + 360
2724
+ : deltaHp - 360;
2725
+ deltaHp = 2 * sqrt(C1p * C2p) * sin(deg2rad(deltaHp) / 2);
2726
+ const deltaL = L2 - L1;
2727
+ const deltaCp = C2p - C1p;
2728
+ const sl = 1 + (0.015 * pow(avgL - 50, 2)) / sqrt(20 + pow(avgL - 50, 2));
2729
+ const sc = 1 + 0.045 * avgCp;
2730
+ const sh = 1 + 0.015 * avgCp * T;
2731
+ const deltaTheta = 30 * exp(-pow((avgHp - 275) / 25, 2));
2732
+ const Rc = 2 * sqrt(pow(avgCp, 7) / (pow(avgCp, 7) + pow(25, 7)));
2733
+ const Rt = -Rc * sin(2 * deg2rad(deltaTheta));
2734
+ const result = sqrt(
2735
+ pow(deltaL / (Kl * sl), 2) +
2736
+ pow(deltaCp / (Kc * sc), 2) +
2737
+ pow(deltaHp / (Kh * sh), 2) +
2738
+ Rt * (deltaCp / (Kc * sc)) * (deltaHp / (Kh * sh))
2739
+ );
2740
+ return max$1(0, min(100, result));
2741
+ }
2742
+
2743
+ // simple Euclidean distance
2744
+ function distance (a, b, mode = 'lab') {
2745
+ // Delta E (CIE 1976)
2746
+ // see http://www.brucelindbloom.com/index.html?Equations.html
2747
+ a = new Color(a);
2748
+ b = new Color(b);
2749
+ const l1 = a.get(mode);
2750
+ const l2 = b.get(mode);
2751
+ let sum_sq = 0;
2752
+ for (let i in l1) {
2753
+ const d = (l1[i] || 0) - (l2[i] || 0);
2754
+ sum_sq += d * d;
2755
+ }
2756
+ return Math.sqrt(sum_sq);
2757
+ }
2758
+
2759
+ const valid = (...args) => {
2760
+ try {
2761
+ new Color(...args);
2762
+ return true;
2763
+ // eslint-disable-next-line
2764
+ } catch (e) {
2765
+ return false;
2766
+ }
2767
+ };
2768
+
2769
+ // some pre-defined color scales:
2770
+
2771
+ const scales = {
2772
+ cool() {
2773
+ return scale([chroma.hsl(180, 1, 0.9), chroma.hsl(250, 0.7, 0.4)]);
2774
+ },
2775
+ hot() {
2776
+ return scale(['#000', '#f00', '#ff0', '#fff']).mode(
2777
+ 'rgb'
2778
+ );
2779
+ }
2780
+ };
2781
+
2782
+ /**
2783
+ ColorBrewer colors for chroma.js
2784
+
2785
+ Copyright (c) 2002 Cynthia Brewer, Mark Harrower, and The
2786
+ Pennsylvania State University.
2787
+
2788
+ Licensed under the Apache License, Version 2.0 (the "License");
2789
+ you may not use this file except in compliance with the License.
2790
+ You may obtain a copy of the License at
2791
+ http://www.apache.org/licenses/LICENSE-2.0
2792
+
2793
+ Unless required by applicable law or agreed to in writing, software distributed
2794
+ under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
2795
+ CONDITIONS OF ANY KIND, either express or implied. See the License for the
2796
+ specific language governing permissions and limitations under the License.
2797
+ */
2798
+
2799
+ const colorbrewer = {
2800
+ // sequential
2801
+ OrRd: ['#fff7ec', '#fee8c8', '#fdd49e', '#fdbb84', '#fc8d59', '#ef6548', '#d7301f', '#b30000', '#7f0000'],
2802
+ PuBu: ['#fff7fb', '#ece7f2', '#d0d1e6', '#a6bddb', '#74a9cf', '#3690c0', '#0570b0', '#045a8d', '#023858'],
2803
+ BuPu: ['#f7fcfd', '#e0ecf4', '#bfd3e6', '#9ebcda', '#8c96c6', '#8c6bb1', '#88419d', '#810f7c', '#4d004b'],
2804
+ Oranges: ['#fff5eb', '#fee6ce', '#fdd0a2', '#fdae6b', '#fd8d3c', '#f16913', '#d94801', '#a63603', '#7f2704'],
2805
+ BuGn: ['#f7fcfd', '#e5f5f9', '#ccece6', '#99d8c9', '#66c2a4', '#41ae76', '#238b45', '#006d2c', '#00441b'],
2806
+ YlOrBr: ['#ffffe5', '#fff7bc', '#fee391', '#fec44f', '#fe9929', '#ec7014', '#cc4c02', '#993404', '#662506'],
2807
+ YlGn: ['#ffffe5', '#f7fcb9', '#d9f0a3', '#addd8e', '#78c679', '#41ab5d', '#238443', '#006837', '#004529'],
2808
+ Reds: ['#fff5f0', '#fee0d2', '#fcbba1', '#fc9272', '#fb6a4a', '#ef3b2c', '#cb181d', '#a50f15', '#67000d'],
2809
+ RdPu: ['#fff7f3', '#fde0dd', '#fcc5c0', '#fa9fb5', '#f768a1', '#dd3497', '#ae017e', '#7a0177', '#49006a'],
2810
+ Greens: ['#f7fcf5', '#e5f5e0', '#c7e9c0', '#a1d99b', '#74c476', '#41ab5d', '#238b45', '#006d2c', '#00441b'],
2811
+ YlGnBu: ['#ffffd9', '#edf8b1', '#c7e9b4', '#7fcdbb', '#41b6c4', '#1d91c0', '#225ea8', '#253494', '#081d58'],
2812
+ Purples: ['#fcfbfd', '#efedf5', '#dadaeb', '#bcbddc', '#9e9ac8', '#807dba', '#6a51a3', '#54278f', '#3f007d'],
2813
+ GnBu: ['#f7fcf0', '#e0f3db', '#ccebc5', '#a8ddb5', '#7bccc4', '#4eb3d3', '#2b8cbe', '#0868ac', '#084081'],
2814
+ Greys: ['#ffffff', '#f0f0f0', '#d9d9d9', '#bdbdbd', '#969696', '#737373', '#525252', '#252525', '#000000'],
2815
+ YlOrRd: ['#ffffcc', '#ffeda0', '#fed976', '#feb24c', '#fd8d3c', '#fc4e2a', '#e31a1c', '#bd0026', '#800026'],
2816
+ PuRd: ['#f7f4f9', '#e7e1ef', '#d4b9da', '#c994c7', '#df65b0', '#e7298a', '#ce1256', '#980043', '#67001f'],
2817
+ Blues: ['#f7fbff', '#deebf7', '#c6dbef', '#9ecae1', '#6baed6', '#4292c6', '#2171b5', '#08519c', '#08306b'],
2818
+ PuBuGn: ['#fff7fb', '#ece2f0', '#d0d1e6', '#a6bddb', '#67a9cf', '#3690c0', '#02818a', '#016c59', '#014636'],
2819
+ Viridis: ['#440154', '#482777', '#3f4a8a', '#31678e', '#26838f', '#1f9d8a', '#6cce5a', '#b6de2b', '#fee825'],
2820
+
2821
+ // diverging
2822
+ Spectral: ['#9e0142', '#d53e4f', '#f46d43', '#fdae61', '#fee08b', '#ffffbf', '#e6f598', '#abdda4', '#66c2a5', '#3288bd', '#5e4fa2'],
2823
+ RdYlGn: ['#a50026', '#d73027', '#f46d43', '#fdae61', '#fee08b', '#ffffbf', '#d9ef8b', '#a6d96a', '#66bd63', '#1a9850', '#006837'],
2824
+ RdBu: ['#67001f', '#b2182b', '#d6604d', '#f4a582', '#fddbc7', '#f7f7f7', '#d1e5f0', '#92c5de', '#4393c3', '#2166ac', '#053061'],
2825
+ PiYG: ['#8e0152', '#c51b7d', '#de77ae', '#f1b6da', '#fde0ef', '#f7f7f7', '#e6f5d0', '#b8e186', '#7fbc41', '#4d9221', '#276419'],
2826
+ PRGn: ['#40004b', '#762a83', '#9970ab', '#c2a5cf', '#e7d4e8', '#f7f7f7', '#d9f0d3', '#a6dba0', '#5aae61', '#1b7837', '#00441b'],
2827
+ RdYlBu: ['#a50026', '#d73027', '#f46d43', '#fdae61', '#fee090', '#ffffbf', '#e0f3f8', '#abd9e9', '#74add1', '#4575b4', '#313695'],
2828
+ BrBG: ['#543005', '#8c510a', '#bf812d', '#dfc27d', '#f6e8c3', '#f5f5f5', '#c7eae5', '#80cdc1', '#35978f', '#01665e', '#003c30'],
2829
+ RdGy: ['#67001f', '#b2182b', '#d6604d', '#f4a582', '#fddbc7', '#ffffff', '#e0e0e0', '#bababa', '#878787', '#4d4d4d', '#1a1a1a'],
2830
+ PuOr: ['#7f3b08', '#b35806', '#e08214', '#fdb863', '#fee0b6', '#f7f7f7', '#d8daeb', '#b2abd2', '#8073ac', '#542788', '#2d004b'],
2831
+
2832
+ // qualitative
2833
+ Set2: ['#66c2a5', '#fc8d62', '#8da0cb', '#e78ac3', '#a6d854', '#ffd92f', '#e5c494', '#b3b3b3'],
2834
+ Accent: ['#7fc97f', '#beaed4', '#fdc086', '#ffff99', '#386cb0', '#f0027f', '#bf5b17', '#666666'],
2835
+ Set1: ['#e41a1c', '#377eb8', '#4daf4a', '#984ea3', '#ff7f00', '#ffff33', '#a65628', '#f781bf', '#999999'],
2836
+ Set3: ['#8dd3c7', '#ffffb3', '#bebada', '#fb8072', '#80b1d3', '#fdb462', '#b3de69', '#fccde5', '#d9d9d9', '#bc80bd', '#ccebc5', '#ffed6f'],
2837
+ Dark2: ['#1b9e77', '#d95f02', '#7570b3', '#e7298a', '#66a61e', '#e6ab02', '#a6761d', '#666666'],
2838
+ Paired: ['#a6cee3', '#1f78b4', '#b2df8a', '#33a02c', '#fb9a99', '#e31a1c', '#fdbf6f', '#ff7f00', '#cab2d6', '#6a3d9a', '#ffff99', '#b15928'],
2839
+ Pastel2: ['#b3e2cd', '#fdcdac', '#cbd5e8', '#f4cae4', '#e6f5c9', '#fff2ae', '#f1e2cc', '#cccccc'],
2840
+ Pastel1: ['#fbb4ae', '#b3cde3', '#ccebc5', '#decbe4', '#fed9a6', '#ffffcc', '#e5d8bd', '#fddaec', '#f2f2f2']
2841
+ };
2842
+
2843
+ const colorbrewerTypes = Object.keys(colorbrewer);
2844
+ const typeMap = new Map(colorbrewerTypes.map((key) => [key.toLowerCase(), key]));
2845
+
2846
+ // use Proxy to allow case-insensitive access to palettes
2847
+ const colorbrewerProxy =
2848
+ typeof Proxy === 'function'
2849
+ ? new Proxy(colorbrewer, {
2850
+ get(target, prop) {
2851
+ const lower = prop.toLowerCase();
2852
+ if (typeMap.has(lower)) {
2853
+ return target[typeMap.get(lower)];
2854
+ }
2855
+ },
2856
+ getOwnPropertyNames() {
2857
+ return Object.getOwnPropertyNames(colorbrewerTypes);
2858
+ }
2859
+ })
2860
+ : colorbrewer;
2861
+
2862
+ const cmyk2rgb = (...args) => {
2863
+ args = unpack(args, 'cmyk');
2864
+ const [c, m, y, k] = args;
2865
+ const alpha = args.length > 4 ? args[4] : 1;
2866
+ if (k === 1) return [0, 0, 0, alpha];
2867
+ return [
2868
+ c >= 1 ? 0 : 255 * (1 - c) * (1 - k), // r
2869
+ m >= 1 ? 0 : 255 * (1 - m) * (1 - k), // g
2870
+ y >= 1 ? 0 : 255 * (1 - y) * (1 - k), // b
2871
+ alpha
2872
+ ];
2873
+ };
2874
+
2875
+ const { max } = Math;
2876
+
2877
+ const rgb2cmyk = (...args) => {
2878
+ let [r, g, b] = unpack(args, 'rgb');
2879
+ r = r / 255;
2880
+ g = g / 255;
2881
+ b = b / 255;
2882
+ const k = 1 - max(r, max(g, b));
2883
+ const f = k < 1 ? 1 / (1 - k) : 0;
2884
+ const c = (1 - r - k) * f;
2885
+ const m = (1 - g - k) * f;
2886
+ const y = (1 - b - k) * f;
2887
+ return [c, m, y, k];
2888
+ };
2889
+
2890
+ Color.prototype.cmyk = function () {
2891
+ return rgb2cmyk(this._rgb);
2892
+ };
2893
+
2894
+ const cmyk = (...args) => new Color(...args, 'cmyk');
2895
+ Object.assign(chroma, { cmyk });
2896
+
2897
+ input.format.cmyk = cmyk2rgb;
2898
+
2899
+ input.autodetect.push({
2900
+ p: 2,
2901
+ test: (...args) => {
2902
+ args = unpack(args, 'cmyk');
2903
+ if (type(args) === 'array' && args.length === 4) {
2904
+ return 'cmyk';
2905
+ }
2906
+ }
2907
+ });
2908
+
2909
+ /*
2910
+ * supported arguments:
2911
+ * - hsl2css(h,s,l)
2912
+ * - hsl2css(h,s,l,a)
2913
+ * - hsl2css([h,s,l], mode)
2914
+ * - hsl2css([h,s,l,a], mode)
2915
+ * - hsl2css({h,s,l,a}, mode)
2916
+ */
2917
+ const hsl2css = (...args) => {
2918
+ const hsla = unpack(args, 'hsla');
2919
+ let mode = last(args) || 'lsa';
2920
+ hsla[0] = rnd2(hsla[0] || 0) + 'deg';
2921
+ hsla[1] = rnd2(hsla[1] * 100) + '%';
2922
+ hsla[2] = rnd2(hsla[2] * 100) + '%';
2923
+ if (mode === 'hsla' || (hsla.length > 3 && hsla[3] < 1)) {
2924
+ hsla[3] = '/ ' + (hsla.length > 3 ? hsla[3] : 1);
2925
+ mode = 'hsla';
2926
+ } else {
2927
+ hsla.length = 3;
2928
+ }
2929
+ return `${mode.substr(0, 3)}(${hsla.join(' ')})`;
2930
+ };
2931
+
2932
+ /*
2933
+ * supported arguments:
2934
+ * - lab2css(l,a,b)
2935
+ * - lab2css(l,a,b,alpha)
2936
+ * - lab2css([l,a,b], mode)
2937
+ * - lab2css([l,a,b,alpha], mode)
2938
+ */
2939
+ const lab2css = (...args) => {
2940
+ const laba = unpack(args, 'lab');
2941
+ let mode = last(args) || 'lab';
2942
+ laba[0] = rnd2(laba[0]) + '%';
2943
+ laba[1] = rnd2(laba[1]);
2944
+ laba[2] = rnd2(laba[2]);
2945
+ if (mode === 'laba' || (laba.length > 3 && laba[3] < 1)) {
2946
+ laba[3] = '/ ' + (laba.length > 3 ? laba[3] : 1);
2947
+ } else {
2948
+ laba.length = 3;
2949
+ }
2950
+ return `lab(${laba.join(' ')})`;
2951
+ };
2952
+
2953
+ /*
2954
+ * supported arguments:
2955
+ * - lab2css(l,a,b)
2956
+ * - lab2css(l,a,b,alpha)
2957
+ * - lab2css([l,a,b], mode)
2958
+ * - lab2css([l,a,b,alpha], mode)
2959
+ */
2960
+ const lch2css = (...args) => {
2961
+ const lcha = unpack(args, 'lch');
2962
+ let mode = last(args) || 'lab';
2963
+ lcha[0] = rnd2(lcha[0]) + '%';
2964
+ lcha[1] = rnd2(lcha[1]);
2965
+ lcha[2] = isNaN(lcha[2]) ? 'none' : rnd2(lcha[2]) + 'deg'; // add deg unit to hue
2966
+ if (mode === 'lcha' || (lcha.length > 3 && lcha[3] < 1)) {
2967
+ lcha[3] = '/ ' + (lcha.length > 3 ? lcha[3] : 1);
2968
+ } else {
2969
+ lcha.length = 3;
2970
+ }
2971
+ return `lch(${lcha.join(' ')})`;
2972
+ };
2973
+
2974
+ const oklab2css = (...args) => {
2975
+ const laba = unpack(args, 'lab');
2976
+ laba[0] = rnd2(laba[0] * 100) + '%';
2977
+ laba[1] = rnd3(laba[1]);
2978
+ laba[2] = rnd3(laba[2]);
2979
+ if (laba.length > 3 && laba[3] < 1) {
2980
+ laba[3] = '/ ' + (laba.length > 3 ? laba[3] : 1);
2981
+ } else {
2982
+ laba.length = 3;
2983
+ }
2984
+ return `oklab(${laba.join(' ')})`;
2985
+ };
2986
+
2987
+ const rgb2oklch = (...args) => {
2988
+ const [r, g, b, ...rest] = unpack(args, 'rgb');
2989
+ const [l, a, b_] = rgb2oklab(r, g, b);
2990
+ const [L, c, h] = lab2lch(l, a, b_);
2991
+ return [L, c, h, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
2992
+ };
2993
+
2994
+ const oklch2css = (...args) => {
2995
+ const lcha = unpack(args, 'lch');
2996
+ lcha[0] = rnd2(lcha[0] * 100) + '%';
2997
+ lcha[1] = rnd3(lcha[1]);
2998
+ lcha[2] = isNaN(lcha[2]) ? 'none' : rnd2(lcha[2]) + 'deg'; // add deg unit to hue
2999
+ if (lcha.length > 3 && lcha[3] < 1) {
3000
+ lcha[3] = '/ ' + (lcha.length > 3 ? lcha[3] : 1);
3001
+ } else {
3002
+ lcha.length = 3;
3003
+ }
3004
+ return `oklch(${lcha.join(' ')})`;
3005
+ };
3006
+
3007
+ const { round: round$2 } = Math;
3008
+
3009
+ /*
3010
+ * supported arguments:
3011
+ * - rgb2css(r,g,b)
3012
+ * - rgb2css(r,g,b,a)
3013
+ * - rgb2css([r,g,b], mode)
3014
+ * - rgb2css([r,g,b,a], mode)
3015
+ * - rgb2css({r,g,b,a}, mode)
3016
+ */
3017
+ const rgb2css = (...args) => {
3018
+ const rgba = unpack(args, 'rgba');
3019
+ let mode = last(args) || 'rgb';
3020
+ if (mode.substr(0, 3) === 'hsl') {
3021
+ return hsl2css(rgb2hsl$1(rgba), mode);
3022
+ }
3023
+ if (mode.substr(0, 3) === 'lab') {
3024
+ // change to D50 lab whitepoint since this is what W3C is using for CSS Lab colors
3025
+ const prevWhitePoint = getLabWhitePoint();
3026
+ setLabWhitePoint('d50');
3027
+ const cssColor = lab2css(rgb2lab(rgba), mode);
3028
+ setLabWhitePoint(prevWhitePoint);
3029
+ return cssColor;
3030
+ }
3031
+ if (mode.substr(0, 3) === 'lch') {
3032
+ // change to D50 lab whitepoint since this is what W3C is using for CSS Lab colors
3033
+ const prevWhitePoint = getLabWhitePoint();
3034
+ setLabWhitePoint('d50');
3035
+ const cssColor = lch2css(rgb2lch(rgba), mode);
3036
+ setLabWhitePoint(prevWhitePoint);
3037
+ return cssColor;
3038
+ }
3039
+ if (mode.substr(0, 5) === 'oklab') {
3040
+ return oklab2css(rgb2oklab(rgba));
3041
+ }
3042
+ if (mode.substr(0, 5) === 'oklch') {
3043
+ return oklch2css(rgb2oklch(rgba));
3044
+ }
3045
+ rgba[0] = round$2(rgba[0]);
3046
+ rgba[1] = round$2(rgba[1]);
3047
+ rgba[2] = round$2(rgba[2]);
3048
+ if (mode === 'rgba' || (rgba.length > 3 && rgba[3] < 1)) {
3049
+ rgba[3] = '/ ' + (rgba.length > 3 ? rgba[3] : 1);
3050
+ mode = 'rgba';
3051
+ }
3052
+ return `${mode.substr(0, 3)}(${rgba.slice(0, mode === 'rgb' ? 3 : 4).join(' ')})`;
3053
+ };
3054
+
3055
+ const oklch2rgb = (...args) => {
3056
+ args = unpack(args, 'lch');
3057
+ const [l, c, h, ...rest] = args;
3058
+ const [L, a, b_] = lch2lab(l, c, h);
3059
+ const [r, g, b] = oklab2rgb(L, a, b_);
3060
+ return [r, g, b, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
3061
+ };
3062
+
3063
+ const INT_OR_PCT = /((?:-?\d+)|(?:-?\d+(?:\.\d+)?)%|none)/.source;
3064
+ const FLOAT_OR_PCT = /((?:-?(?:\d+(?:\.\d*)?|\.\d+)%?)|none)/.source;
3065
+ const PCT = /((?:-?(?:\d+(?:\.\d*)?|\.\d+)%)|none)/.source;
3066
+ const RE_S = /\s*/.source;
3067
+ const SEP = /\s+/.source;
3068
+ const COMMA = /\s*,\s*/.source;
3069
+ const ANLGE = /((?:-?(?:\d+(?:\.\d*)?|\.\d+)(?:deg)?)|none)/.source;
3070
+ const ALPHA = /\s*(?:\/\s*((?:[01]|[01]?\.\d+)|\d+(?:\.\d+)?%))?/.source;
3071
+
3072
+ // e.g. rgb(250 20 0), rgb(100% 50% 20%), rgb(100% 50% 20% / 0.5)
3073
+ const RE_RGB = new RegExp(
3074
+ '^rgba?\\(' +
3075
+ RE_S +
3076
+ [INT_OR_PCT, INT_OR_PCT, INT_OR_PCT].join(SEP) +
3077
+ ALPHA +
3078
+ '\\)$'
3079
+ );
3080
+ const RE_RGB_LEGACY = new RegExp(
3081
+ '^rgb\\(' +
3082
+ RE_S +
3083
+ [INT_OR_PCT, INT_OR_PCT, INT_OR_PCT].join(COMMA) +
3084
+ RE_S +
3085
+ '\\)$'
3086
+ );
3087
+ const RE_RGBA_LEGACY = new RegExp(
3088
+ '^rgba\\(' +
3089
+ RE_S +
3090
+ [INT_OR_PCT, INT_OR_PCT, INT_OR_PCT, FLOAT_OR_PCT].join(COMMA) +
3091
+ RE_S +
3092
+ '\\)$'
3093
+ );
3094
+
3095
+ const RE_HSL = new RegExp(
3096
+ '^hsla?\\(' + RE_S + [ANLGE, PCT, PCT].join(SEP) + ALPHA + '\\)$'
3097
+ );
3098
+ const RE_HSL_LEGACY = new RegExp(
3099
+ '^hsl?\\(' + RE_S + [ANLGE, PCT, PCT].join(COMMA) + RE_S + '\\)$'
3100
+ );
3101
+ const RE_HSLA_LEGACY =
3102
+ /^hsla\(\s*(-?\d+(?:\.\d+)?),\s*(-?\d+(?:\.\d+)?)%\s*,\s*(-?\d+(?:\.\d+)?)%\s*,\s*([01]|[01]?\.\d+)\)$/;
3103
+
3104
+ const RE_LAB = new RegExp(
3105
+ '^lab\\(' +
3106
+ RE_S +
3107
+ [FLOAT_OR_PCT, FLOAT_OR_PCT, FLOAT_OR_PCT].join(SEP) +
3108
+ ALPHA +
3109
+ '\\)$'
3110
+ );
3111
+ const RE_LCH = new RegExp(
3112
+ '^lch\\(' +
3113
+ RE_S +
3114
+ [FLOAT_OR_PCT, FLOAT_OR_PCT, ANLGE].join(SEP) +
3115
+ ALPHA +
3116
+ '\\)$'
3117
+ );
3118
+ const RE_OKLAB = new RegExp(
3119
+ '^oklab\\(' +
3120
+ RE_S +
3121
+ [FLOAT_OR_PCT, FLOAT_OR_PCT, FLOAT_OR_PCT].join(SEP) +
3122
+ ALPHA +
3123
+ '\\)$'
3124
+ );
3125
+ const RE_OKLCH = new RegExp(
3126
+ '^oklch\\(' +
3127
+ RE_S +
3128
+ [FLOAT_OR_PCT, FLOAT_OR_PCT, ANLGE].join(SEP) +
3129
+ ALPHA +
3130
+ '\\)$'
3131
+ );
3132
+
3133
+ const { round: round$1 } = Math;
3134
+
3135
+ const roundRGB = (rgb) => {
3136
+ return rgb.map((v, i) => (i <= 2 ? limit(round$1(v), 0, 255) : v));
3137
+ };
3138
+
3139
+ const percentToAbsolute = (pct, min = 0, max = 100, signed = false) => {
3140
+ if (typeof pct === 'string' && pct.endsWith('%')) {
3141
+ pct = parseFloat(pct.substring(0, pct.length - 1)) / 100;
3142
+ if (signed) {
3143
+ // signed percentages are in the range -100% to 100%
3144
+ pct = min + (pct + 1) * 0.5 * (max - min);
3145
+ } else {
3146
+ pct = min + pct * (max - min);
3147
+ }
3148
+ }
3149
+ return +pct;
3150
+ };
3151
+
3152
+ const noneToValue = (v, noneValue) => {
3153
+ return v === 'none' ? noneValue : v;
3154
+ };
3155
+
3156
+ const css2rgb = (css) => {
3157
+ css = css.toLowerCase().trim();
3158
+
3159
+ if (css === 'transparent') {
3160
+ return [0, 0, 0, 0];
3161
+ }
3162
+
3163
+ let m;
3164
+
3165
+ if (input.format.named) {
3166
+ try {
3167
+ return input.format.named(css);
3168
+ // eslint-disable-next-line
3169
+ } catch (e) {}
3170
+ }
3171
+
3172
+ // rgb(250 20 0) or rgb(250,20,0)
3173
+ if ((m = css.match(RE_RGB)) || (m = css.match(RE_RGB_LEGACY))) {
3174
+ let rgb = m.slice(1, 4);
3175
+ for (let i = 0; i < 3; i++) {
3176
+ rgb[i] = +percentToAbsolute(noneToValue(rgb[i], 0), 0, 255);
3177
+ }
3178
+ rgb = roundRGB(rgb);
3179
+ const alpha = m[4] !== undefined ? +percentToAbsolute(m[4], 0, 1) : 1;
3180
+ rgb[3] = alpha; // default alpha
3181
+ return rgb;
3182
+ }
3183
+
3184
+ // rgba(250,20,0,0.4)
3185
+ if ((m = css.match(RE_RGBA_LEGACY))) {
3186
+ const rgb = m.slice(1, 5);
3187
+ for (let i = 0; i < 4; i++) {
3188
+ rgb[i] = +percentToAbsolute(rgb[i], 0, 255);
3189
+ }
3190
+ return rgb;
3191
+ }
3192
+
3193
+ // hsl(0,100%,50%)
3194
+ if ((m = css.match(RE_HSL)) || (m = css.match(RE_HSL_LEGACY))) {
3195
+ const hsl = m.slice(1, 4);
3196
+ hsl[0] = +noneToValue(hsl[0].replace('deg', ''), 0);
3197
+ hsl[1] = +percentToAbsolute(noneToValue(hsl[1], 0), 0, 100) * 0.01;
3198
+ hsl[2] = +percentToAbsolute(noneToValue(hsl[2], 0), 0, 100) * 0.01;
3199
+ const rgb = roundRGB(hsl2rgb(hsl));
3200
+ const alpha = m[4] !== undefined ? +percentToAbsolute(m[4], 0, 1) : 1;
3201
+ rgb[3] = alpha;
3202
+ return rgb;
3203
+ }
3204
+
3205
+ // hsla(0,100%,50%,0.5)
3206
+ if ((m = css.match(RE_HSLA_LEGACY))) {
3207
+ const hsl = m.slice(1, 4);
3208
+ hsl[1] *= 0.01;
3209
+ hsl[2] *= 0.01;
3210
+ const rgb = hsl2rgb(hsl);
3211
+ for (let i = 0; i < 3; i++) {
3212
+ rgb[i] = round$1(rgb[i]);
3213
+ }
3214
+ rgb[3] = +m[4]; // default alpha = 1
3215
+ return rgb;
3216
+ }
3217
+
3218
+ if ((m = css.match(RE_LAB))) {
3219
+ const lab = m.slice(1, 4);
3220
+ lab[0] = percentToAbsolute(noneToValue(lab[0], 0), 0, 100);
3221
+ lab[1] = percentToAbsolute(noneToValue(lab[1], 0), -125, 125, true);
3222
+ lab[2] = percentToAbsolute(noneToValue(lab[2], 0), -125, 125, true);
3223
+ // convert to D50 Lab whitepoint
3224
+ const wp = getLabWhitePoint();
3225
+ setLabWhitePoint('d50');
3226
+ const rgb = roundRGB(lab2rgb(lab));
3227
+ // convert back to original Lab whitepoint
3228
+ setLabWhitePoint(wp);
3229
+ const alpha = m[4] !== undefined ? +percentToAbsolute(m[4], 0, 1) : 1;
3230
+ rgb[3] = alpha;
3231
+ return rgb;
3232
+ }
3233
+
3234
+ if ((m = css.match(RE_LCH))) {
3235
+ const lch = m.slice(1, 4);
3236
+ lch[0] = percentToAbsolute(lch[0], 0, 100);
3237
+ lch[1] = percentToAbsolute(noneToValue(lch[1], 0), 0, 150, false);
3238
+ lch[2] = +noneToValue(lch[2].replace('deg', ''), 0);
3239
+ // convert to D50 Lab whitepoint
3240
+ const wp = getLabWhitePoint();
3241
+ setLabWhitePoint('d50');
3242
+ const rgb = roundRGB(lch2rgb(lch));
3243
+ // convert back to original Lab whitepoint
3244
+ setLabWhitePoint(wp);
3245
+ const alpha = m[4] !== undefined ? +percentToAbsolute(m[4], 0, 1) : 1;
3246
+ rgb[3] = alpha;
3247
+ return rgb;
3248
+ }
3249
+
3250
+ if ((m = css.match(RE_OKLAB))) {
3251
+ const oklab = m.slice(1, 4);
3252
+ oklab[0] = percentToAbsolute(noneToValue(oklab[0], 0), 0, 1);
3253
+ oklab[1] = percentToAbsolute(noneToValue(oklab[1], 0), -0.4, 0.4, true);
3254
+ oklab[2] = percentToAbsolute(noneToValue(oklab[2], 0), -0.4, 0.4, true);
3255
+ const rgb = roundRGB(oklab2rgb(oklab));
3256
+ const alpha = m[4] !== undefined ? +percentToAbsolute(m[4], 0, 1) : 1;
3257
+ rgb[3] = alpha;
3258
+ return rgb;
3259
+ }
3260
+
3261
+ if ((m = css.match(RE_OKLCH))) {
3262
+ const oklch = m.slice(1, 4);
3263
+ oklch[0] = percentToAbsolute(noneToValue(oklch[0], 0), 0, 1);
3264
+ oklch[1] = percentToAbsolute(noneToValue(oklch[1], 0), 0, 0.4, false);
3265
+ oklch[2] = +noneToValue(oklch[2].replace('deg', ''), 0);
3266
+ const rgb = roundRGB(oklch2rgb(oklch));
3267
+ const alpha = m[4] !== undefined ? +percentToAbsolute(m[4], 0, 1) : 1;
3268
+ rgb[3] = alpha;
3269
+ return rgb;
3270
+ }
3271
+ };
3272
+
3273
+ css2rgb.test = (s) => {
3274
+ return (
3275
+ // modern
3276
+ RE_RGB.test(s) ||
3277
+ RE_HSL.test(s) ||
3278
+ RE_LAB.test(s) ||
3279
+ RE_LCH.test(s) ||
3280
+ RE_OKLAB.test(s) ||
3281
+ RE_OKLCH.test(s) ||
3282
+ // legacy
3283
+ RE_RGB_LEGACY.test(s) ||
3284
+ RE_RGBA_LEGACY.test(s) ||
3285
+ RE_HSL_LEGACY.test(s) ||
3286
+ RE_HSLA_LEGACY.test(s) ||
3287
+ s === 'transparent'
3288
+ );
3289
+ };
3290
+
3291
+ Color.prototype.css = function (mode) {
3292
+ return rgb2css(this._rgb, mode);
3293
+ };
3294
+
3295
+ const css = (...args) => new Color(...args, 'css');
3296
+ chroma.css = css;
3297
+
3298
+ input.format.css = css2rgb;
3299
+
3300
+ input.autodetect.push({
3301
+ p: 5,
3302
+ test: (h, ...rest) => {
3303
+ if (!rest.length && type(h) === 'string' && css2rgb.test(h)) {
3304
+ return 'css';
3305
+ }
3306
+ }
3307
+ });
3308
+
3309
+ input.format.gl = (...args) => {
3310
+ const rgb = unpack(args, 'rgba');
3311
+ rgb[0] *= 255;
3312
+ rgb[1] *= 255;
3313
+ rgb[2] *= 255;
3314
+ return rgb;
3315
+ };
3316
+
3317
+ const gl = (...args) => new Color(...args, 'gl');
3318
+ chroma.gl = gl;
3319
+
3320
+ Color.prototype.gl = function () {
3321
+ const rgb = this._rgb;
3322
+ return [rgb[0] / 255, rgb[1] / 255, rgb[2] / 255, rgb[3]];
3323
+ };
3324
+
3325
+ Color.prototype.hex = function (mode) {
3326
+ return rgb2hex(this._rgb, mode);
3327
+ };
3328
+
3329
+ const hex = (...args) => new Color(...args, 'hex');
3330
+ chroma.hex = hex;
3331
+
3332
+ input.format.hex = hex2rgb;
3333
+ input.autodetect.push({
3334
+ p: 4,
3335
+ test: (h, ...rest) => {
3336
+ if (
3337
+ !rest.length &&
3338
+ type(h) === 'string' &&
3339
+ [3, 4, 5, 6, 7, 8, 9].indexOf(h.length) >= 0
3340
+ ) {
3341
+ return 'hex';
3342
+ }
3343
+ }
3344
+ });
3345
+
3346
+ /*
3347
+ * Based on implementation by Neil Bartlett
3348
+ * https://github.com/neilbartlett/color-temperature
3349
+ */
3350
+
3351
+ const { log } = Math;
3352
+
3353
+ const temperature2rgb = (kelvin) => {
3354
+ const temp = kelvin / 100;
3355
+ let r, g, b;
3356
+ if (temp < 66) {
3357
+ r = 255;
3358
+ g =
3359
+ temp < 6
3360
+ ? 0
3361
+ : -155.25485562709179 -
3362
+ 0.44596950469579133 * (g = temp - 2) +
3363
+ 104.49216199393888 * log(g);
3364
+ b =
3365
+ temp < 20
3366
+ ? 0
3367
+ : -254.76935184120902 +
3368
+ 0.8274096064007395 * (b = temp - 10) +
3369
+ 115.67994401066147 * log(b);
3370
+ } else {
3371
+ r =
3372
+ 351.97690566805693 +
3373
+ 0.114206453784165 * (r = temp - 55) -
3374
+ 40.25366309332127 * log(r);
3375
+ g =
3376
+ 325.4494125711974 +
3377
+ 0.07943456536662342 * (g = temp - 50) -
3378
+ 28.0852963507957 * log(g);
3379
+ b = 255;
3380
+ }
3381
+ return [r, g, b, 1];
3382
+ };
3383
+
3384
+ /*
3385
+ * Based on implementation by Neil Bartlett
3386
+ * https://github.com/neilbartlett/color-temperature
3387
+ **/
3388
+
3389
+ const { round } = Math;
3390
+
3391
+ const rgb2temperature = (...args) => {
3392
+ const rgb = unpack(args, 'rgb');
3393
+ const r = rgb[0],
3394
+ b = rgb[2];
3395
+ let minTemp = 1000;
3396
+ let maxTemp = 40000;
3397
+ const eps = 0.4;
3398
+ let temp;
3399
+ while (maxTemp - minTemp > eps) {
3400
+ temp = (maxTemp + minTemp) * 0.5;
3401
+ const rgb = temperature2rgb(temp);
3402
+ if (rgb[2] / rgb[0] >= b / r) {
3403
+ maxTemp = temp;
3404
+ } else {
3405
+ minTemp = temp;
3406
+ }
3407
+ }
3408
+ return round(temp);
3409
+ };
3410
+
3411
+ Color.prototype.temp =
3412
+ Color.prototype.kelvin =
3413
+ Color.prototype.temperature =
3414
+ function () {
3415
+ return rgb2temperature(this._rgb);
3416
+ };
3417
+
3418
+ const temp = (...args) => new Color(...args, 'temp');
3419
+ Object.assign(chroma, { temp, kelvin: temp, temperature: temp });
3420
+
3421
+ input.format.temp =
3422
+ input.format.kelvin =
3423
+ input.format.temperature =
3424
+ temperature2rgb;
3425
+
3426
+ Color.prototype.oklch = function () {
3427
+ return rgb2oklch(this._rgb);
3428
+ };
3429
+
3430
+ const oklch = (...args) => new Color(...args, 'oklch');
3431
+ Object.assign(chroma, { oklch });
3432
+
3433
+ input.format.oklch = oklch2rgb;
3434
+
3435
+ input.autodetect.push({
3436
+ p: 2,
3437
+ test: (...args) => {
3438
+ args = unpack(args, 'oklch');
3439
+ if (type(args) === 'array' && args.length === 3) {
3440
+ return 'oklch';
3441
+ }
3442
+ }
3443
+ });
3444
+
3445
+ // feel free to comment out anything to rollup
3446
+ // a smaller chroma.js bundle
3447
+
3448
+ Object.assign(chroma, {
3449
+ analyze,
3450
+ average,
3451
+ bezier: bezier$1,
3452
+ blend,
3453
+ brewer: colorbrewerProxy,
3454
+ Color,
3455
+ colors: w3cx11,
3456
+ contrast,
3457
+ contrastAPCA,
3458
+ cubehelix,
3459
+ deltaE,
3460
+ distance,
3461
+ input,
3462
+ interpolate: mix,
3463
+ limits,
3464
+ mix,
3465
+ random: random$1,
3466
+ scale,
3467
+ scales,
3468
+ valid
3469
+ });
3470
+
3471
+ const LIGHTNESS_MAP = [0.96, 0.907, 0.805, 0.697, 0.605, 0.547, 0.518, 0.445, 0.395, 0.34];
3472
+ const SATURATION_MAP = [0.32, 0.16, 0.08, 0.04, 0, 0, 0.04, 0.08, 0.16, 0.32];
3473
+ function getClosestLightness(colorObject) {
3474
+ const lightnessGoal = colorObject.get("hsl.l");
3475
+ return LIGHTNESS_MAP.reduce(
3476
+ (prev, curr) => Math.abs(curr - lightnessGoal) < Math.abs(prev - lightnessGoal) ? curr : prev
3477
+ );
3478
+ }
3479
+ function generateColorsMap(color) {
3480
+ const colorObject = chroma(color);
3481
+ const closestLightness = getClosestLightness(colorObject);
3482
+ const baseColorIndex = LIGHTNESS_MAP.findIndex((l) => l === closestLightness);
3483
+ const colors = LIGHTNESS_MAP.map((l) => colorObject.set("hsl.l", l)).map((c) => chroma(c)).map((c, i) => {
3484
+ const saturationDelta = SATURATION_MAP[i] - SATURATION_MAP[baseColorIndex];
3485
+ return saturationDelta >= 0 ? c.saturate(saturationDelta) : c.desaturate(saturationDelta * -1);
3486
+ });
3487
+ colors[baseColorIndex] = chroma(color);
3488
+ return { baseColorIndex, colors };
3489
+ }
3490
+ function generateColors(color) {
3491
+ return generateColorsMap(color).colors.map((c) => c.hex());
3492
+ }
3493
+
3494
+ function t$1(...t){return t$2(n$1,t)}function n$1(e,t){let n={};for(let[r,i]of e.entries())n[i]=t(i,r,e);return n}
3495
+
3496
+ function t(...t){return t$2(n,t)}function n(e,t){if(e===t||Object.is(e,t))return true;if(typeof e!=`object`||typeof t!=`object`||e===null||t===null||Object.getPrototypeOf(e)!==Object.getPrototypeOf(t))return false;if(Array.isArray(e))return r(e,t);if(e instanceof Map)return i(e,t);if(e instanceof Set)return a(e,t);if(e instanceof Date)return e.getTime()===t.getTime();if(e instanceof RegExp)return e.toString()===t.toString();if(Object.keys(e).length!==Object.keys(t).length)return false;for(let[r,i]of Object.entries(e))if(!(r in t)||!n(i,t[r]))return false;return true}function r(e,t){if(e.length!==t.length)return false;for(let[r,i]of e.entries())if(!n(i,t[r]))return false;return true}function i(e,t){if(e.size!==t.size)return false;for(let[r,i]of e.entries())if(!t.has(r)||!n(i,t.get(r)))return false;return true}function a(e,t){if(e.size!==t.size)return false;let r=[...t];for(let t of e){let e=false;for(let[i,a]of r.entries())if(n(t,a)){e=true,r.splice(i,1);break}if(!e)return false}return true}
3497
+
3498
+ const blue$1 = {
3499
+ fill: "#3b82f6",
3500
+ stroke: "#2563eb",
3501
+ hiContrast: "#eff6ff",
3502
+ loContrast: "#bfdbfe"
3503
+ };
3504
+ const sky$1 = {
3505
+ fill: "#0284c7",
3506
+ stroke: "#0369a1",
3507
+ hiContrast: "#f0f9ff",
3508
+ loContrast: "#B6ECF7"
3509
+ };
3510
+ const slate$1 = {
3511
+ fill: "#64748b",
3512
+ stroke: "#475569",
3513
+ hiContrast: "#f8fafc",
3514
+ loContrast: "#cbd5e1"
3515
+ };
3516
+ const ElementColors = {
3517
+ primary: blue$1,
3518
+ blue: blue$1,
3519
+ secondary: sky$1,
3520
+ sky: sky$1,
3521
+ muted: slate$1,
3522
+ slate: slate$1,
3523
+ gray: {
3524
+ fill: "#737373",
3525
+ stroke: "#525252",
3526
+ hiContrast: "#fafafa",
3527
+ loContrast: "#d4d4d4"
3528
+ },
3529
+ red: {
3530
+ fill: "#AC4D39",
3531
+ stroke: "#853A2D",
3532
+ hiContrast: "#FBD3CB",
3533
+ loContrast: "#f5b2a3"
3534
+ },
3535
+ green: {
3536
+ fill: "#428a4f",
3537
+ stroke: "#2d5d39",
3538
+ hiContrast: "#f8fafc",
3539
+ loContrast: "#c2f0c2"
3540
+ },
3541
+ amber: {
3542
+ fill: "#A35829",
3543
+ stroke: "#7E451D",
3544
+ hiContrast: "#FFE0C2",
3545
+ loContrast: "#f9b27c"
3546
+ },
3547
+ indigo: {
3548
+ fill: "#6366f1",
3549
+ stroke: "#4f46e5",
3550
+ hiContrast: "#eef2ff",
3551
+ loContrast: "#c7d2fe"
3552
+ }
3553
+ };
3554
+
3555
+ const gray = {
3556
+ line: "#6E6E6E",
3557
+ labelBg: "#18191b",
3558
+ label: "#C6C6C6"
3559
+ };
3560
+ const slate = {
3561
+ line: "#64748b",
3562
+ // 500
3563
+ labelBg: "#0f172a",
3564
+ // 900
3565
+ label: "#cbd5e1"
3566
+ // 300
3567
+ };
3568
+ const blue = {
3569
+ line: "#3b82f6",
3570
+ // 500
3571
+ labelBg: "#172554",
3572
+ // 950
3573
+ label: "#60a5fa"
3574
+ // 400
3575
+ };
3576
+ const sky = {
3577
+ line: "#0ea5e9",
3578
+ // 500
3579
+ labelBg: "#082f49",
3580
+ // 950
3581
+ label: "#38bdf8"
3582
+ // 400
3583
+ };
3584
+ const RelationshipColors = {
3585
+ amber: {
3586
+ line: "#b45309",
3587
+ labelBg: "#78350f",
3588
+ label: "#FFE0C2"
3589
+ },
3590
+ blue,
3591
+ gray,
3592
+ green: {
3593
+ line: "#15803d",
3594
+ // 700
3595
+ labelBg: "#052e16",
3596
+ // 950
3597
+ label: "#22c55e"
3598
+ // 500
3599
+ },
3600
+ indigo: {
3601
+ line: "#6366f1",
3602
+ // 500
3603
+ labelBg: "#1e1b4b",
3604
+ // 950
3605
+ label: "#818cf8"
3606
+ // 400
3607
+ },
3608
+ muted: slate,
3609
+ primary: blue,
3610
+ red: {
3611
+ line: "#AC4D39",
3612
+ labelBg: "#b91c1c",
3613
+ label: "#f5b2a3"
3614
+ },
3615
+ secondary: sky,
3616
+ sky,
3617
+ slate
3618
+ };
3619
+
3620
+ const CONTRAST_MIN_WITH_FOREGROUND = 60;
3621
+ const CONTRAST_START_TONE_DIFFERENCE = 2;
3622
+ const CONTRAST_STEP_TONE_DIFFERENCE = 1;
3623
+ function computeColorValues(color) {
3624
+ invariant(chroma.valid(color), `Invalid color: ${color}`);
3625
+ const colors = generateColors(color);
3626
+ const fillColor = colors[6];
3627
+ const contrastedColors = getContrastedColorsAPCA(fillColor);
3628
+ return {
3629
+ elements: {
3630
+ fill: fillColor,
3631
+ stroke: colors[7],
3632
+ hiContrast: contrastedColors[0],
3633
+ loContrast: contrastedColors[1]
3634
+ },
3635
+ relationships: {
3636
+ line: colors[4],
3637
+ label: colors[3],
3638
+ labelBg: colors[9]
3639
+ }
3640
+ };
3641
+ }
3642
+ function getContrastedColorsAPCA(refColor) {
3643
+ const refColorChroma = chroma(refColor);
3644
+ let lightColorRgb = refColorChroma.brighten(CONTRAST_START_TONE_DIFFERENCE);
3645
+ let darkColorRgb = refColorChroma.darken(CONTRAST_START_TONE_DIFFERENCE);
3646
+ let previousLight;
3647
+ let previousDark;
3648
+ let contrastWithLight;
3649
+ let contrastWithDark;
3650
+ do {
3651
+ previousLight = lightColorRgb;
3652
+ previousDark = darkColorRgb;
3653
+ lightColorRgb = lightColorRgb.brighten(CONTRAST_STEP_TONE_DIFFERENCE);
3654
+ darkColorRgb = darkColorRgb.darken(CONTRAST_STEP_TONE_DIFFERENCE);
3655
+ contrastWithLight = chroma.contrastAPCA(refColorChroma, lightColorRgb);
3656
+ contrastWithDark = chroma.contrastAPCA(refColorChroma, darkColorRgb);
3657
+ } while (
3658
+ // Stop if one of the contrast is high enough or if we reach max value for each (aka when they are equal between two rounds)
3659
+ Math.abs(contrastWithLight) < CONTRAST_MIN_WITH_FOREGROUND && Math.abs(contrastWithDark) < CONTRAST_MIN_WITH_FOREGROUND && (!t(lightColorRgb, previousLight) || !t(darkColorRgb, previousDark))
3660
+ );
3661
+ if (Math.abs(contrastWithLight) > Math.abs(contrastWithDark)) {
3662
+ return [lightColorRgb.brighten(0.4).hex(), lightColorRgb.hex()];
3663
+ } else {
3664
+ return [darkColorRgb.darken(0.4).hex(), darkColorRgb.hex()];
3665
+ }
3666
+ }
3667
+
3668
+ const Sizes = ["xs", "sm", "md", "lg", "xl"];
3669
+ const BorderStyles = ["solid", "dashed", "dotted", "none"];
3670
+ const ElementShapes = [
3671
+ "rectangle",
3672
+ "person",
3673
+ "browser",
3674
+ "mobile",
3675
+ "cylinder",
3676
+ "storage",
3677
+ "queue"
3678
+ ];
3679
+ const RelationshipArrowTypes = [
3680
+ "none",
3681
+ "normal",
3682
+ "onormal",
3683
+ "dot",
3684
+ "odot",
3685
+ "diamond",
3686
+ "odiamond",
3687
+ "crow",
3688
+ "open",
3689
+ "vee"
3690
+ ];
3691
+ const ThemeColors = [
3692
+ "amber",
3693
+ "blue",
3694
+ "gray",
3695
+ "slate",
3696
+ "green",
3697
+ "indigo",
3698
+ "muted",
3699
+ "primary",
3700
+ "red",
3701
+ "secondary",
3702
+ "sky"
3703
+ ];
3704
+ function isThemeColor(color) {
3705
+ return ThemeColors.includes(color);
3706
+ }
3707
+ function isCustomColor(color) {
3708
+ return !isThemeColor(color);
3709
+ }
3710
+
3711
+ const defaultTheme = {
3712
+ colors: t$1(ThemeColors, (key) => ({
3713
+ elements: ElementColors[key],
3714
+ relationships: RelationshipColors[key]
3715
+ })),
3716
+ sizes: {
3717
+ xs: {
3718
+ width: 180,
3719
+ height: 100
3720
+ },
3721
+ sm: {
3722
+ width: 240,
3723
+ height: 135
3724
+ },
3725
+ md: {
3726
+ width: 320,
3727
+ height: 180
3728
+ },
3729
+ lg: {
3730
+ width: 420,
3731
+ height: 234
3732
+ },
3733
+ xl: {
3734
+ width: 520,
3735
+ height: 290
3736
+ }
3737
+ },
3738
+ spacing: {
3739
+ xs: 8,
3740
+ // 0.5rem
3741
+ sm: 10,
3742
+ // 0.625rem
3743
+ md: 16,
3744
+ // 1rem
3745
+ lg: 24,
3746
+ // 1.5rem = 16px + 8px
3747
+ xl: 32
3748
+ // 2rem
3749
+ },
3750
+ /**
3751
+ * Text sizes for titles
3752
+ * https://typescale.com/
3753
+ *
3754
+ * Scale: 1.2
3755
+ * Base: 16px
3756
+ */
3757
+ textSizes: {
3758
+ xs: 13.33,
3759
+ sm: 16,
3760
+ md: 19.2,
3761
+ lg: 23.04,
3762
+ xl: 27.65
3763
+ }
3764
+ };
3765
+
3766
+ function isPlainObject(value) {
3767
+ if (value === null || typeof value !== "object") {
3768
+ return false;
3769
+ }
3770
+ const prototype = Object.getPrototypeOf(value);
3771
+ if (prototype !== null && prototype !== Object.prototype && Object.getPrototypeOf(prototype) !== null) {
3772
+ return false;
3773
+ }
3774
+ if (Symbol.iterator in value) {
3775
+ return false;
3776
+ }
3777
+ if (Symbol.toStringTag in value) {
3778
+ return Object.prototype.toString.call(value) === "[object Module]";
3779
+ }
3780
+ return true;
3781
+ }
3782
+
3783
+ function _defu(baseObject, defaults, namespace = ".", merger) {
3784
+ if (!isPlainObject(defaults)) {
3785
+ return _defu(baseObject, {}, namespace, merger);
3786
+ }
3787
+ const object = Object.assign({}, defaults);
3788
+ for (const key in baseObject) {
3789
+ if (key === "__proto__" || key === "constructor") {
3790
+ continue;
3791
+ }
3792
+ const value = baseObject[key];
3793
+ if (value === null || value === void 0) {
3794
+ continue;
3795
+ }
3796
+ if (merger && merger(object, key, value, namespace)) {
3797
+ continue;
3798
+ }
3799
+ if (Array.isArray(value) && Array.isArray(object[key])) {
3800
+ object[key] = [...value, ...object[key]];
3801
+ } else if (isPlainObject(value) && isPlainObject(object[key])) {
3802
+ object[key] = _defu(
3803
+ value,
3804
+ object[key],
3805
+ (namespace ? `${namespace}.` : "") + key.toString(),
3806
+ merger
3807
+ );
3808
+ } else {
3809
+ object[key] = value;
3810
+ }
3811
+ }
3812
+ return object;
3813
+ }
3814
+ function createDefu(merger) {
3815
+ return (...arguments_) => (
3816
+ // eslint-disable-next-line unicorn/no-array-reduce
3817
+ arguments_.reduce((p, c) => _defu(p, c, "", merger), {})
3818
+ );
3819
+ }
3820
+ const defu = createDefu();
3821
+
3822
+ function ensureSizes({
3823
+ size,
3824
+ padding,
3825
+ textSize,
3826
+ ...rest
3827
+ }, defaultSize = defaultStyle.defaults.size) {
3828
+ size ??= defaultSize;
3829
+ textSize ??= size;
3830
+ padding ??= size;
3831
+ return {
3832
+ ...rest,
3833
+ size,
3834
+ padding,
3835
+ textSize
3836
+ };
3837
+ }
3838
+
3839
+ const styleDefaults = {
3840
+ color: "primary",
3841
+ size: "md",
3842
+ opacity: 15,
3843
+ shape: "rectangle",
3844
+ group: {
3845
+ opacity: 15,
3846
+ border: "dashed"
3847
+ },
3848
+ relationship: {
3849
+ color: "gray",
3850
+ line: "dashed",
3851
+ arrow: "normal"
3852
+ }
3853
+ };
3854
+
3855
+ const defaultStyle = {
3856
+ theme: defaultTheme,
3857
+ defaults: styleDefaults
3858
+ };
3859
+ class LikeC4Styles {
3860
+ constructor(config) {
3861
+ this.config = config;
3862
+ this.theme = config.theme;
3863
+ this.defaults = config.defaults;
3864
+ }
3865
+ theme;
3866
+ defaults;
3867
+ static DEFAULT = new LikeC4Styles(defaultStyle);
3868
+ static from(...configs) {
3869
+ if (t$3(configs, 1)) {
3870
+ return new LikeC4Styles(
3871
+ defu(...configs, defaultStyle)
3872
+ );
3873
+ }
3874
+ return this.DEFAULT;
3875
+ }
3876
+ /**
3877
+ * Default element colors
3878
+ */
3879
+ get elementColors() {
3880
+ return this.theme.colors[this.defaults.color].elements;
3881
+ }
3882
+ /**
3883
+ * Default relationship colors
3884
+ */
3885
+ get relationshipColors() {
3886
+ return this.theme.colors[this.defaults.relationship.color].relationships;
3887
+ }
3888
+ /**
3889
+ * Default group colors
3890
+ */
3891
+ get groupColors() {
3892
+ const color = this.defaults.group?.color;
3893
+ if (!color) {
3894
+ return this.elementColors;
3895
+ }
3896
+ return memoizeProp(this, "defaultGroup", () => ({
3897
+ ...this.elementColors,
3898
+ ...this.theme.colors[color].elements
3899
+ }));
3900
+ }
3901
+ isDefaultColor(color) {
3902
+ return color === this.defaults.color;
3903
+ }
3904
+ /**
3905
+ * Get color values
3906
+ *
3907
+ * @param color - The color to use
3908
+ * @default color From the defaults
3909
+ */
3910
+ colors(color) {
3911
+ color ??= this.defaults.color;
3912
+ if (this.isThemeColor(color)) {
3913
+ return this.theme.colors[color];
3914
+ }
3915
+ throw new Error(`Unknown color: ${color}`);
3916
+ }
3917
+ /**
3918
+ * Get font size in pixels
3919
+ *
3920
+ * @param textSize - The text size to use
3921
+ * @default textSize From the defaults
3922
+ */
3923
+ fontSize(textSize) {
3924
+ textSize ??= this.defaults.text ?? this.defaults.size;
3925
+ return this.theme.textSizes[textSize];
3926
+ }
3927
+ /**
3928
+ * Get padding in pixels
3929
+ *
3930
+ * @param paddingSize - The padding size to use
3931
+ * @default paddingSize From the defaults
3932
+ */
3933
+ padding(paddingSize) {
3934
+ paddingSize ??= this.defaults.padding ?? this.defaults.size;
3935
+ return this.theme.spacing[paddingSize];
3936
+ }
3937
+ isThemeColor(color) {
3938
+ return color in this.theme.colors;
3939
+ }
3940
+ /**
3941
+ * Calculate sizes and values based on the node styles
3942
+ *
3943
+ * @example
3944
+ * ```typescript
3945
+ * const { sizes, values } = styles.nodeSizes(node.style)
3946
+ *
3947
+ * // sizes
3948
+ * sizes.size // enum Size
3949
+ * sizes.padding // enum SpacingSize
3950
+ * sizes.textSize // enum TextSize
3951
+ *
3952
+ * // values
3953
+ * values.sizes // { width: number, height: number }
3954
+ * values.padding // number
3955
+ * values.textSize // number
3956
+ * ```
3957
+ */
3958
+ nodeSizes(nodestyles) {
3959
+ const sizes = ensureSizes(nodestyles, this.defaults.size);
3960
+ return {
3961
+ sizes,
3962
+ values: {
3963
+ sizes: this.theme.sizes[sizes.size],
3964
+ padding: this.padding(sizes.padding),
3965
+ textSize: this.fontSize(sizes.textSize)
3966
+ }
3967
+ };
3968
+ }
3969
+ /**
3970
+ * Compute ThemeColorValues from a given color
3971
+ * @param color - HEX, RGB, RGBA, etc.
3972
+ */
3973
+ computeFrom(color) {
3974
+ if (this.isThemeColor(color)) {
3975
+ return this.theme.colors[color];
3976
+ }
3977
+ if (!chroma.valid(color)) {
3978
+ throw new Error(`Invalid color value: "${color}"`);
3979
+ }
3980
+ return memoizeProp(this, `compute-${color}`, () => computeColorValues(color));
3981
+ }
3982
+ equals(other) {
3983
+ if (other === this) {
3984
+ return true;
3985
+ }
3986
+ return t(this.config, other.config);
3987
+ }
3988
+ }
3989
+
3990
+ export { BorderStyles as B, ElementShapes as E, LikeC4Styles as L, RelationshipArrowTypes as R, Sizes as S, ThemeColors as T, t as a, defaultTheme as b, computeColorValues as c, defu as d, ensureSizes as e, isCustomColor as f, isThemeColor as i, t$1 as t };