@fluixi/utils 1.0.0-alpha.53

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 (354) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +73 -0
  3. package/dist/index.cjs +1 -0
  4. package/dist/index.d.ts +2 -0
  5. package/dist/index.d.ts.map +1 -0
  6. package/dist/index.js +1 -0
  7. package/dist/index.mjs +1 -0
  8. package/dist/lib/array/advanced.cjs +1 -0
  9. package/dist/lib/array/advanced.d.ts +1116 -0
  10. package/dist/lib/array/advanced.d.ts.map +1 -0
  11. package/dist/lib/array/advanced.js +2429 -0
  12. package/dist/lib/array/advanced.mjs +1 -0
  13. package/dist/lib/array/array.cjs +1 -0
  14. package/dist/lib/array/array.d.ts +6 -0
  15. package/dist/lib/array/array.d.ts.map +1 -0
  16. package/dist/lib/array/array.js +31 -0
  17. package/dist/lib/array/array.mjs +1 -0
  18. package/dist/lib/array/index.cjs +1 -0
  19. package/dist/lib/array/index.d.ts +4 -0
  20. package/dist/lib/array/index.d.ts.map +1 -0
  21. package/dist/lib/array/index.js +3 -0
  22. package/dist/lib/array/index.mjs +1 -0
  23. package/dist/lib/array/utils.cjs +1 -0
  24. package/dist/lib/array/utils.d.ts +100 -0
  25. package/dist/lib/array/utils.d.ts.map +1 -0
  26. package/dist/lib/array/utils.js +165 -0
  27. package/dist/lib/array/utils.mjs +1 -0
  28. package/dist/lib/color/color.cjs +1 -0
  29. package/dist/lib/color/color.d.ts +366 -0
  30. package/dist/lib/color/color.d.ts.map +1 -0
  31. package/dist/lib/color/color.js +722 -0
  32. package/dist/lib/color/color.mjs +1 -0
  33. package/dist/lib/color/constants.cjs +1 -0
  34. package/dist/lib/color/constants.d.ts +361 -0
  35. package/dist/lib/color/constants.d.ts.map +1 -0
  36. package/dist/lib/color/constants.js +358 -0
  37. package/dist/lib/color/constants.mjs +1 -0
  38. package/dist/lib/color/conversions.cjs +1 -0
  39. package/dist/lib/color/conversions.d.ts +166 -0
  40. package/dist/lib/color/conversions.d.ts.map +1 -0
  41. package/dist/lib/color/conversions.js +766 -0
  42. package/dist/lib/color/conversions.mjs +1 -0
  43. package/dist/lib/color/helpers.cjs +1 -0
  44. package/dist/lib/color/helpers.d.ts +75 -0
  45. package/dist/lib/color/helpers.d.ts.map +1 -0
  46. package/dist/lib/color/helpers.js +419 -0
  47. package/dist/lib/color/helpers.mjs +1 -0
  48. package/dist/lib/color/index.cjs +1 -0
  49. package/dist/lib/color/index.d.ts +12 -0
  50. package/dist/lib/color/index.d.ts.map +1 -0
  51. package/dist/lib/color/index.js +15 -0
  52. package/dist/lib/color/index.mjs +1 -0
  53. package/dist/lib/color/types.cjs +1 -0
  54. package/dist/lib/color/types.d.ts +179 -0
  55. package/dist/lib/color/types.d.ts.map +1 -0
  56. package/dist/lib/color/types.js +1 -0
  57. package/dist/lib/color/types.mjs +0 -0
  58. package/dist/lib/color/utils.cjs +1 -0
  59. package/dist/lib/color/utils.d.ts +199 -0
  60. package/dist/lib/color/utils.d.ts.map +1 -0
  61. package/dist/lib/color/utils.js +858 -0
  62. package/dist/lib/color/utils.mjs +1 -0
  63. package/dist/lib/compare/comparators.cjs +1 -0
  64. package/dist/lib/compare/comparators.d.ts +65 -0
  65. package/dist/lib/compare/comparators.d.ts.map +1 -0
  66. package/dist/lib/compare/comparators.js +210 -0
  67. package/dist/lib/compare/comparators.mjs +1 -0
  68. package/dist/lib/compare/index.cjs +1 -0
  69. package/dist/lib/compare/index.d.ts +2 -0
  70. package/dist/lib/compare/index.d.ts.map +1 -0
  71. package/dist/lib/compare/index.js +1 -0
  72. package/dist/lib/compare/index.mjs +1 -0
  73. package/dist/lib/crypto/hash.cjs +1 -0
  74. package/dist/lib/crypto/hash.d.ts +6 -0
  75. package/dist/lib/crypto/hash.d.ts.map +1 -0
  76. package/dist/lib/crypto/hash.js +53 -0
  77. package/dist/lib/crypto/hash.mjs +1 -0
  78. package/dist/lib/crypto/index.cjs +1 -0
  79. package/dist/lib/crypto/index.d.ts +2 -0
  80. package/dist/lib/crypto/index.d.ts.map +1 -0
  81. package/dist/lib/crypto/index.js +1 -0
  82. package/dist/lib/crypto/index.mjs +1 -0
  83. package/dist/lib/dom/events.cjs +1 -0
  84. package/dist/lib/dom/events.d.ts +159 -0
  85. package/dist/lib/dom/events.d.ts.map +1 -0
  86. package/dist/lib/dom/events.js +50 -0
  87. package/dist/lib/dom/events.mjs +1 -0
  88. package/dist/lib/dom/index.cjs +1 -0
  89. package/dist/lib/dom/index.d.ts +3 -0
  90. package/dist/lib/dom/index.d.ts.map +1 -0
  91. package/dist/lib/dom/index.js +2 -0
  92. package/dist/lib/dom/index.mjs +1 -0
  93. package/dist/lib/dom/utils.cjs +1 -0
  94. package/dist/lib/dom/utils.d.ts +6 -0
  95. package/dist/lib/dom/utils.d.ts.map +1 -0
  96. package/dist/lib/dom/utils.js +37 -0
  97. package/dist/lib/dom/utils.mjs +1 -0
  98. package/dist/lib/functions/functions.cjs +1 -0
  99. package/dist/lib/functions/functions.d.ts +329 -0
  100. package/dist/lib/functions/functions.d.ts.map +1 -0
  101. package/dist/lib/functions/functions.js +585 -0
  102. package/dist/lib/functions/functions.mjs +1 -0
  103. package/dist/lib/functions/index.cjs +1 -0
  104. package/dist/lib/functions/index.d.ts +3 -0
  105. package/dist/lib/functions/index.d.ts.map +1 -0
  106. package/dist/lib/functions/index.js +1 -0
  107. package/dist/lib/functions/index.mjs +1 -0
  108. package/dist/lib/functions/types.cjs +1 -0
  109. package/dist/lib/functions/types.d.ts +2 -0
  110. package/dist/lib/functions/types.d.ts.map +1 -0
  111. package/dist/lib/functions/types.js +1 -0
  112. package/dist/lib/functions/types.mjs +0 -0
  113. package/dist/lib/helpers.cjs +1 -0
  114. package/dist/lib/helpers.d.ts +13 -0
  115. package/dist/lib/helpers.d.ts.map +1 -0
  116. package/dist/lib/helpers.js +66 -0
  117. package/dist/lib/helpers.mjs +1 -0
  118. package/dist/lib/index.cjs +1 -0
  119. package/dist/lib/index.d.ts +6 -0
  120. package/dist/lib/index.d.ts.map +1 -0
  121. package/dist/lib/index.js +8 -0
  122. package/dist/lib/index.mjs +1 -0
  123. package/dist/lib/maths/constants.cjs +1 -0
  124. package/dist/lib/maths/constants.d.ts +84 -0
  125. package/dist/lib/maths/constants.d.ts.map +1 -0
  126. package/dist/lib/maths/constants.js +79 -0
  127. package/dist/lib/maths/constants.mjs +1 -0
  128. package/dist/lib/maths/fn/advanced.cjs +1 -0
  129. package/dist/lib/maths/fn/advanced.d.ts +149 -0
  130. package/dist/lib/maths/fn/advanced.d.ts.map +1 -0
  131. package/dist/lib/maths/fn/advanced.js +264 -0
  132. package/dist/lib/maths/fn/advanced.mjs +1 -0
  133. package/dist/lib/maths/fn/basic.cjs +1 -0
  134. package/dist/lib/maths/fn/basic.d.ts +182 -0
  135. package/dist/lib/maths/fn/basic.d.ts.map +1 -0
  136. package/dist/lib/maths/fn/basic.js +343 -0
  137. package/dist/lib/maths/fn/basic.mjs +1 -0
  138. package/dist/lib/maths/fn/complex.cjs +1 -0
  139. package/dist/lib/maths/fn/complex.d.ts +153 -0
  140. package/dist/lib/maths/fn/complex.d.ts.map +1 -0
  141. package/dist/lib/maths/fn/complex.js +383 -0
  142. package/dist/lib/maths/fn/complex.mjs +1 -0
  143. package/dist/lib/maths/fn/index.cjs +1 -0
  144. package/dist/lib/maths/fn/index.d.ts +10 -0
  145. package/dist/lib/maths/fn/index.d.ts.map +1 -0
  146. package/dist/lib/maths/fn/index.js +9 -0
  147. package/dist/lib/maths/fn/index.mjs +1 -0
  148. package/dist/lib/maths/fn/trigo.cjs +1 -0
  149. package/dist/lib/maths/fn/trigo.d.ts +147 -0
  150. package/dist/lib/maths/fn/trigo.d.ts.map +1 -0
  151. package/dist/lib/maths/fn/trigo.js +227 -0
  152. package/dist/lib/maths/fn/trigo.mjs +1 -0
  153. package/dist/lib/maths/fn/vector.cjs +1 -0
  154. package/dist/lib/maths/fn/vector.d.ts +512 -0
  155. package/dist/lib/maths/fn/vector.d.ts.map +1 -0
  156. package/dist/lib/maths/fn/vector.js +1136 -0
  157. package/dist/lib/maths/fn/vector.mjs +1 -0
  158. package/dist/lib/maths/formatter.cjs +1 -0
  159. package/dist/lib/maths/formatter.d.ts +35 -0
  160. package/dist/lib/maths/formatter.d.ts.map +1 -0
  161. package/dist/lib/maths/formatter.js +56 -0
  162. package/dist/lib/maths/formatter.mjs +1 -0
  163. package/dist/lib/maths/guards.cjs +1 -0
  164. package/dist/lib/maths/guards.d.ts +166 -0
  165. package/dist/lib/maths/guards.d.ts.map +1 -0
  166. package/dist/lib/maths/guards.js +315 -0
  167. package/dist/lib/maths/guards.mjs +1 -0
  168. package/dist/lib/maths/index.cjs +1 -0
  169. package/dist/lib/maths/index.d.ts +24 -0
  170. package/dist/lib/maths/index.d.ts.map +1 -0
  171. package/dist/lib/maths/index.js +29 -0
  172. package/dist/lib/maths/index.mjs +1 -0
  173. package/dist/lib/maths/parser.cjs +1 -0
  174. package/dist/lib/maths/parser.d.ts +20 -0
  175. package/dist/lib/maths/parser.d.ts.map +1 -0
  176. package/dist/lib/maths/parser.js +78 -0
  177. package/dist/lib/maths/parser.mjs +1 -0
  178. package/dist/lib/maths/random.cjs +1 -0
  179. package/dist/lib/maths/random.d.ts +27 -0
  180. package/dist/lib/maths/random.d.ts.map +1 -0
  181. package/dist/lib/maths/random.js +49 -0
  182. package/dist/lib/maths/random.mjs +1 -0
  183. package/dist/lib/maths/types/advanced.cjs +1 -0
  184. package/dist/lib/maths/types/advanced.d.ts +357 -0
  185. package/dist/lib/maths/types/advanced.d.ts.map +1 -0
  186. package/dist/lib/maths/types/advanced.js +5 -0
  187. package/dist/lib/maths/types/advanced.mjs +0 -0
  188. package/dist/lib/maths/types/basic.cjs +1 -0
  189. package/dist/lib/maths/types/basic.d.ts +95 -0
  190. package/dist/lib/maths/types/basic.d.ts.map +1 -0
  191. package/dist/lib/maths/types/basic.js +5 -0
  192. package/dist/lib/maths/types/basic.mjs +0 -0
  193. package/dist/lib/maths/types/index.cjs +1 -0
  194. package/dist/lib/maths/types/index.d.ts +4 -0
  195. package/dist/lib/maths/types/index.d.ts.map +1 -0
  196. package/dist/lib/maths/types/index.js +3 -0
  197. package/dist/lib/maths/types/index.mjs +0 -0
  198. package/dist/lib/maths/types/negative.cjs +1 -0
  199. package/dist/lib/maths/types/negative.d.ts +51 -0
  200. package/dist/lib/maths/types/negative.d.ts.map +1 -0
  201. package/dist/lib/maths/types/negative.js +5 -0
  202. package/dist/lib/maths/types/negative.mjs +0 -0
  203. package/dist/lib/maths/types/operations.cjs +1 -0
  204. package/dist/lib/maths/types/operations.d.ts +188 -0
  205. package/dist/lib/maths/types/operations.d.ts.map +1 -0
  206. package/dist/lib/maths/types/operations.js +6 -0
  207. package/dist/lib/maths/types/operations.mjs +0 -0
  208. package/dist/lib/object/clone.cjs +1 -0
  209. package/dist/lib/object/clone.d.ts +46 -0
  210. package/dist/lib/object/clone.d.ts.map +1 -0
  211. package/dist/lib/object/clone.js +104 -0
  212. package/dist/lib/object/clone.mjs +1 -0
  213. package/dist/lib/object/diff.cjs +1 -0
  214. package/dist/lib/object/diff.d.ts +203 -0
  215. package/dist/lib/object/diff.d.ts.map +1 -0
  216. package/dist/lib/object/diff.js +805 -0
  217. package/dist/lib/object/diff.mjs +1 -0
  218. package/dist/lib/object/getter-setter.cjs +1 -0
  219. package/dist/lib/object/getter-setter.d.ts +361 -0
  220. package/dist/lib/object/getter-setter.d.ts.map +1 -0
  221. package/dist/lib/object/getter-setter.js +1771 -0
  222. package/dist/lib/object/getter-setter.mjs +1 -0
  223. package/dist/lib/object/index.cjs +6 -0
  224. package/dist/lib/object/index.d.ts +13 -0
  225. package/dist/lib/object/index.d.ts.map +1 -0
  226. package/dist/lib/object/index.js +12 -0
  227. package/dist/lib/object/index.mjs +6 -0
  228. package/dist/lib/object/merge.cjs +1 -0
  229. package/dist/lib/object/merge.d.ts +93 -0
  230. package/dist/lib/object/merge.d.ts.map +1 -0
  231. package/dist/lib/object/merge.js +474 -0
  232. package/dist/lib/object/merge.mjs +1 -0
  233. package/dist/lib/object/object.cjs +1 -0
  234. package/dist/lib/object/object.d.ts +128 -0
  235. package/dist/lib/object/object.d.ts.map +1 -0
  236. package/dist/lib/object/object.js +432 -0
  237. package/dist/lib/object/object.mjs +1 -0
  238. package/dist/lib/object/omit.cjs +1 -0
  239. package/dist/lib/object/omit.d.ts +351 -0
  240. package/dist/lib/object/omit.d.ts.map +1 -0
  241. package/dist/lib/object/omit.js +656 -0
  242. package/dist/lib/object/omit.mjs +1 -0
  243. package/dist/lib/object/reconcile.cjs +1 -0
  244. package/dist/lib/object/reconcile.d.ts +7 -0
  245. package/dist/lib/object/reconcile.d.ts.map +1 -0
  246. package/dist/lib/object/reconcile.js +122 -0
  247. package/dist/lib/object/reconcile.mjs +1 -0
  248. package/dist/lib/object/selector.cjs +1 -0
  249. package/dist/lib/object/selector.d.ts +50 -0
  250. package/dist/lib/object/selector.d.ts.map +1 -0
  251. package/dist/lib/object/selector.js +371 -0
  252. package/dist/lib/object/selector.mjs +1 -0
  253. package/dist/lib/object/sort.cjs +1 -0
  254. package/dist/lib/object/sort.d.ts +149 -0
  255. package/dist/lib/object/sort.d.ts.map +1 -0
  256. package/dist/lib/object/sort.js +298 -0
  257. package/dist/lib/object/sort.mjs +1 -0
  258. package/dist/lib/object/transform.cjs +1 -0
  259. package/dist/lib/object/transform.d.ts +620 -0
  260. package/dist/lib/object/transform.d.ts.map +1 -0
  261. package/dist/lib/object/transform.js +1058 -0
  262. package/dist/lib/object/transform.mjs +1 -0
  263. package/dist/lib/object/types.cjs +1 -0
  264. package/dist/lib/object/types.d.ts +250 -0
  265. package/dist/lib/object/types.d.ts.map +1 -0
  266. package/dist/lib/object/types.js +1 -0
  267. package/dist/lib/object/types.mjs +0 -0
  268. package/dist/lib/object/utils.cjs +6 -0
  269. package/dist/lib/object/utils.d.ts +165 -0
  270. package/dist/lib/object/utils.d.ts.map +1 -0
  271. package/dist/lib/object/utils.js +444 -0
  272. package/dist/lib/object/utils.mjs +6 -0
  273. package/dist/lib/primitive/boolean/boolean.cjs +1 -0
  274. package/dist/lib/primitive/boolean/boolean.d.ts +276 -0
  275. package/dist/lib/primitive/boolean/boolean.d.ts.map +1 -0
  276. package/dist/lib/primitive/boolean/boolean.js +615 -0
  277. package/dist/lib/primitive/boolean/boolean.mjs +1 -0
  278. package/dist/lib/primitive/boolean/index.cjs +1 -0
  279. package/dist/lib/primitive/boolean/index.d.ts +3 -0
  280. package/dist/lib/primitive/boolean/index.d.ts.map +1 -0
  281. package/dist/lib/primitive/boolean/index.js +2 -0
  282. package/dist/lib/primitive/boolean/index.mjs +1 -0
  283. package/dist/lib/primitive/boolean/types.cjs +1 -0
  284. package/dist/lib/primitive/boolean/types.d.ts +14 -0
  285. package/dist/lib/primitive/boolean/types.d.ts.map +1 -0
  286. package/dist/lib/primitive/boolean/types.js +1 -0
  287. package/dist/lib/primitive/boolean/types.mjs +0 -0
  288. package/dist/lib/primitive/date/date.cjs +1 -0
  289. package/dist/lib/primitive/date/date.d.ts +641 -0
  290. package/dist/lib/primitive/date/date.d.ts.map +1 -0
  291. package/dist/lib/primitive/date/date.js +1998 -0
  292. package/dist/lib/primitive/date/date.mjs +1 -0
  293. package/dist/lib/primitive/date/index.cjs +1 -0
  294. package/dist/lib/primitive/date/index.d.ts +3 -0
  295. package/dist/lib/primitive/date/index.d.ts.map +1 -0
  296. package/dist/lib/primitive/date/index.js +2 -0
  297. package/dist/lib/primitive/date/index.mjs +1 -0
  298. package/dist/lib/primitive/date/types.cjs +1 -0
  299. package/dist/lib/primitive/date/types.d.ts +205 -0
  300. package/dist/lib/primitive/date/types.d.ts.map +1 -0
  301. package/dist/lib/primitive/date/types.js +7 -0
  302. package/dist/lib/primitive/date/types.mjs +0 -0
  303. package/dist/lib/primitive/index.cjs +5 -0
  304. package/dist/lib/primitive/index.d.ts +5 -0
  305. package/dist/lib/primitive/index.d.ts.map +1 -0
  306. package/dist/lib/primitive/index.js +4 -0
  307. package/dist/lib/primitive/index.mjs +5 -0
  308. package/dist/lib/primitive/string/index.cjs +5 -0
  309. package/dist/lib/primitive/string/index.d.ts +3 -0
  310. package/dist/lib/primitive/string/index.d.ts.map +1 -0
  311. package/dist/lib/primitive/string/index.js +2 -0
  312. package/dist/lib/primitive/string/index.mjs +5 -0
  313. package/dist/lib/primitive/string/parser-2.cjs +8 -0
  314. package/dist/lib/primitive/string/parser-2.d.ts +17 -0
  315. package/dist/lib/primitive/string/parser-2.d.ts.map +1 -0
  316. package/dist/lib/primitive/string/parser-2.js +656 -0
  317. package/dist/lib/primitive/string/parser-2.mjs +8 -0
  318. package/dist/lib/primitive/string/parser.cjs +3 -0
  319. package/dist/lib/primitive/string/parser.d.ts +9 -0
  320. package/dist/lib/primitive/string/parser.d.ts.map +1 -0
  321. package/dist/lib/primitive/string/parser.js +775 -0
  322. package/dist/lib/primitive/string/parser.mjs +3 -0
  323. package/dist/lib/primitive/string/string.cjs +5 -0
  324. package/dist/lib/primitive/string/string.d.ts +535 -0
  325. package/dist/lib/primitive/string/string.d.ts.map +1 -0
  326. package/dist/lib/primitive/string/string.js +1301 -0
  327. package/dist/lib/primitive/string/string.mjs +5 -0
  328. package/dist/lib/primitive/string/types.cjs +1 -0
  329. package/dist/lib/primitive/string/types.d.ts +318 -0
  330. package/dist/lib/primitive/string/types.d.ts.map +1 -0
  331. package/dist/lib/primitive/string/types.js +5 -0
  332. package/dist/lib/primitive/string/types.mjs +0 -0
  333. package/dist/lib/primitive/types.cjs +1 -0
  334. package/dist/lib/primitive/types.d.ts +27 -0
  335. package/dist/lib/primitive/types.d.ts.map +1 -0
  336. package/dist/lib/primitive/types.js +1 -0
  337. package/dist/lib/primitive/types.mjs +0 -0
  338. package/dist/lib/url/index.cjs +1 -0
  339. package/dist/lib/url/index.d.ts +3 -0
  340. package/dist/lib/url/index.d.ts.map +1 -0
  341. package/dist/lib/url/index.js +2 -0
  342. package/dist/lib/url/index.mjs +1 -0
  343. package/dist/lib/url/parser.cjs +1 -0
  344. package/dist/lib/url/parser.d.ts +216 -0
  345. package/dist/lib/url/parser.d.ts.map +1 -0
  346. package/dist/lib/url/parser.js +488 -0
  347. package/dist/lib/url/parser.mjs +1 -0
  348. package/dist/lib/url/types.cjs +1 -0
  349. package/dist/lib/url/types.d.ts +18 -0
  350. package/dist/lib/url/types.d.ts.map +1 -0
  351. package/dist/lib/url/types.js +1 -0
  352. package/dist/lib/url/types.mjs +0 -0
  353. package/dist/tsconfig.lib.tsbuildinfo +1 -0
  354. package/package.json +150 -0
@@ -0,0 +1,766 @@
1
+ /**
2
+ * @fileoverview Comprehensive color conversion utilities
3
+ * Supports conversions between: RGB, HSL, HSV, HWB, CMYK, LAB, LCH, OKLAB, OKLCH, XYZ
4
+ */
5
+ /**
6
+ * Constants for color conversions
7
+ */
8
+ const D65_WHITE = { x: 0.95047, y: 1.0, z: 1.08883 };
9
+ const EPSILON = 0.008856;
10
+ const KAPPA = 903.3;
11
+ /**
12
+ * Utility function to clamp values
13
+ */
14
+ function clamp(value, min, max) {
15
+ return Math.max(min, Math.min(max, value));
16
+ }
17
+ /**
18
+ * Round to specified precision
19
+ */
20
+ function roundToPrecision(value, precision = 2) {
21
+ const multiplier = Math.pow(10, precision);
22
+ return Math.round(value * multiplier) / multiplier;
23
+ }
24
+ // ============================================================================
25
+ // RGB CONVERSIONS
26
+ // ============================================================================
27
+ /**
28
+ * Convert RGB to HSL
29
+ */
30
+ export function rgbToHsl(rgb) {
31
+ const r = rgb.r / 255;
32
+ const g = rgb.g / 255;
33
+ const b = rgb.b / 255;
34
+ const max = Math.max(r, g, b);
35
+ const min = Math.min(r, g, b);
36
+ const delta = max - min;
37
+ let h = 0;
38
+ let s = 0;
39
+ const l = (max + min) / 2;
40
+ if (delta !== 0) {
41
+ s = l > 0.5 ? delta / (2 - max - min) : delta / (max + min);
42
+ switch (max) {
43
+ case r:
44
+ h = ((g - b) / delta + (g < b ? 6 : 0)) / 6;
45
+ break;
46
+ case g:
47
+ h = ((b - r) / delta + 2) / 6;
48
+ break;
49
+ case b:
50
+ h = ((r - g) / delta + 4) / 6;
51
+ break;
52
+ }
53
+ }
54
+ return {
55
+ h: h * 360,
56
+ s: s * 100,
57
+ l: l * 100,
58
+ a: rgb.a,
59
+ };
60
+ }
61
+ /**
62
+ * Convert RGB to HSV
63
+ */
64
+ export function rgbToHsv(rgb) {
65
+ const r = rgb.r / 255;
66
+ const g = rgb.g / 255;
67
+ const b = rgb.b / 255;
68
+ const max = Math.max(r, g, b);
69
+ const min = Math.min(r, g, b);
70
+ const delta = max - min;
71
+ let h = 0;
72
+ const s = max === 0 ? 0 : delta / max;
73
+ const v = max;
74
+ if (delta !== 0) {
75
+ switch (max) {
76
+ case r:
77
+ h = ((g - b) / delta + (g < b ? 6 : 0)) / 6;
78
+ break;
79
+ case g:
80
+ h = ((b - r) / delta + 2) / 6;
81
+ break;
82
+ case b:
83
+ h = ((r - g) / delta + 4) / 6;
84
+ break;
85
+ }
86
+ }
87
+ return {
88
+ h: h * 360,
89
+ s: s * 100,
90
+ v: v * 100,
91
+ a: rgb.a,
92
+ };
93
+ }
94
+ /**
95
+ * Convert RGB to HWB
96
+ */
97
+ export function rgbToHwb(rgb) {
98
+ const hsv = rgbToHsv(rgb);
99
+ const w = ((100 - hsv.s) * hsv.v) / 100;
100
+ const b = 100 - hsv.v;
101
+ return {
102
+ h: hsv.h,
103
+ w,
104
+ b,
105
+ a: rgb.a,
106
+ };
107
+ }
108
+ /**
109
+ * Convert RGB to CMYK
110
+ */
111
+ export function rgbToCmyk(rgb) {
112
+ const r = rgb.r / 255;
113
+ const g = rgb.g / 255;
114
+ const b = rgb.b / 255;
115
+ const k = 1 - Math.max(r, g, b);
116
+ const c = k === 1 ? 0 : (1 - r - k) / (1 - k);
117
+ const m = k === 1 ? 0 : (1 - g - k) / (1 - k);
118
+ const y = k === 1 ? 0 : (1 - b - k) / (1 - k);
119
+ return {
120
+ c: c * 100,
121
+ m: m * 100,
122
+ y: y * 100,
123
+ k: k * 100,
124
+ a: rgb.a,
125
+ };
126
+ }
127
+ /**
128
+ * Convert RGB to XYZ
129
+ */
130
+ export function rgbToXyz(rgb) {
131
+ let r = rgb.r / 255;
132
+ let g = rgb.g / 255;
133
+ let b = rgb.b / 255;
134
+ // Apply gamma correction
135
+ r = r > 0.04045 ? Math.pow((r + 0.055) / 1.055, 2.4) : r / 12.92;
136
+ g = g > 0.04045 ? Math.pow((g + 0.055) / 1.055, 2.4) : g / 12.92;
137
+ b = b > 0.04045 ? Math.pow((b + 0.055) / 1.055, 2.4) : b / 12.92;
138
+ // Convert to XYZ using sRGB matrix
139
+ const x = r * 0.4124564 + g * 0.3575761 + b * 0.1804375;
140
+ const y = r * 0.2126729 + g * 0.7151522 + b * 0.072175;
141
+ const z = r * 0.0193339 + g * 0.119192 + b * 0.9503041;
142
+ return {
143
+ x: x * 100,
144
+ y: y * 100,
145
+ z: z * 100,
146
+ alpha: rgb.a,
147
+ };
148
+ }
149
+ /**
150
+ * Convert RGB to LAB
151
+ */
152
+ export function rgbToLab(rgb) {
153
+ const xyz = rgbToXyz(rgb);
154
+ return xyzToLab(xyz);
155
+ }
156
+ /**
157
+ * Convert RGB to LCH
158
+ */
159
+ export function rgbToLch(rgb) {
160
+ const lab = rgbToLab(rgb);
161
+ return labToLch(lab);
162
+ }
163
+ /**
164
+ * Convert RGB to OKLAB
165
+ */
166
+ export function rgbToOklab(rgb) {
167
+ const r = rgb.r / 255;
168
+ const g = rgb.g / 255;
169
+ const b = rgb.b / 255;
170
+ // Linear RGB
171
+ const lr = r > 0.04045 ? Math.pow((r + 0.055) / 1.055, 2.4) : r / 12.92;
172
+ const lg = g > 0.04045 ? Math.pow((g + 0.055) / 1.055, 2.4) : g / 12.92;
173
+ const lb = b > 0.04045 ? Math.pow((b + 0.055) / 1.055, 2.4) : b / 12.92;
174
+ // Convert to LMS cone space
175
+ const l = 0.4122214708 * lr + 0.5363325363 * lg + 0.0514459929 * lb;
176
+ const m = 0.2119034982 * lr + 0.6806995451 * lg + 0.1073969566 * lb;
177
+ const s = 0.0883024619 * lr + 0.2817188376 * lg + 0.6299787005 * lb;
178
+ const l_ = Math.cbrt(l);
179
+ const m_ = Math.cbrt(m);
180
+ const s_ = Math.cbrt(s);
181
+ return {
182
+ l: 0.2104542553 * l_ + 0.793617785 * m_ - 0.0040720468 * s_,
183
+ a: 1.9779984951 * l_ - 2.428592205 * m_ + 0.4505937099 * s_,
184
+ b: 0.0259040371 * l_ + 0.7827717662 * m_ - 0.808675766 * s_,
185
+ alpha: rgb.a,
186
+ };
187
+ }
188
+ /**
189
+ * Convert RGB to OKLCH
190
+ */
191
+ export function rgbToOklch(rgb) {
192
+ const oklab = rgbToOklab(rgb);
193
+ return oklabToOklch(oklab);
194
+ }
195
+ // ============================================================================
196
+ // HSL CONVERSIONS
197
+ // ============================================================================
198
+ /**
199
+ * Convert HSL to RGB
200
+ */
201
+ export function hslToRgb(hsl) {
202
+ const h = hsl.h / 360;
203
+ const s = hsl.s / 100;
204
+ const l = hsl.l / 100;
205
+ let r, g, b;
206
+ if (s === 0) {
207
+ r = g = b = l;
208
+ }
209
+ else {
210
+ const hue2rgb = (p, q, t) => {
211
+ if (t < 0)
212
+ t += 1;
213
+ if (t > 1)
214
+ t -= 1;
215
+ if (t < 1 / 6)
216
+ return p + (q - p) * 6 * t;
217
+ if (t < 1 / 2)
218
+ return q;
219
+ if (t < 2 / 3)
220
+ return p + (q - p) * (2 / 3 - t) * 6;
221
+ return p;
222
+ };
223
+ const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
224
+ const p = 2 * l - q;
225
+ r = hue2rgb(p, q, h + 1 / 3);
226
+ g = hue2rgb(p, q, h);
227
+ b = hue2rgb(p, q, h - 1 / 3);
228
+ }
229
+ return {
230
+ r: Math.round(r * 255),
231
+ g: Math.round(g * 255),
232
+ b: Math.round(b * 255),
233
+ a: hsl.a,
234
+ };
235
+ }
236
+ /**
237
+ * Convert HSL to HSV
238
+ */
239
+ export function hslToHsv(hsl) {
240
+ const rgb = hslToRgb(hsl);
241
+ return rgbToHsv(rgb);
242
+ }
243
+ /**
244
+ * Convert HSL to HWB
245
+ */
246
+ export function hslToHwb(hsl) {
247
+ const rgb = hslToRgb(hsl);
248
+ return rgbToHwb(rgb);
249
+ }
250
+ // ============================================================================
251
+ // HSV CONVERSIONS
252
+ // ============================================================================
253
+ /**
254
+ * Convert HSV to RGB
255
+ */
256
+ export function hsvToRgb(hsv) {
257
+ const h = hsv.h / 360;
258
+ const s = hsv.s / 100;
259
+ const v = hsv.v / 100;
260
+ const i = Math.floor(h * 6);
261
+ const f = h * 6 - i;
262
+ const p = v * (1 - s);
263
+ const q = v * (1 - f * s);
264
+ const t = v * (1 - (1 - f) * s);
265
+ let r, g, b;
266
+ switch (i % 6) {
267
+ case 0:
268
+ r = v;
269
+ g = t;
270
+ b = p;
271
+ break;
272
+ case 1:
273
+ r = q;
274
+ g = v;
275
+ b = p;
276
+ break;
277
+ case 2:
278
+ r = p;
279
+ g = v;
280
+ b = t;
281
+ break;
282
+ case 3:
283
+ r = p;
284
+ g = q;
285
+ b = v;
286
+ break;
287
+ case 4:
288
+ r = t;
289
+ g = p;
290
+ b = v;
291
+ break;
292
+ case 5:
293
+ default:
294
+ r = v;
295
+ g = p;
296
+ b = q;
297
+ break;
298
+ }
299
+ return {
300
+ r: Math.round(r * 255),
301
+ g: Math.round(g * 255),
302
+ b: Math.round(b * 255),
303
+ a: hsv.a,
304
+ };
305
+ }
306
+ /**
307
+ * Convert HSV to HSL
308
+ */
309
+ export function hsvToHsl(hsv) {
310
+ const rgb = hsvToRgb(hsv);
311
+ return rgbToHsl(rgb);
312
+ }
313
+ /**
314
+ * Convert HSV to HWB
315
+ */
316
+ export function hsvToHwb(hsv) {
317
+ const w = ((100 - hsv.s) * hsv.v) / 100;
318
+ const b = 100 - hsv.v;
319
+ return {
320
+ h: hsv.h,
321
+ w,
322
+ b,
323
+ a: hsv.a,
324
+ };
325
+ }
326
+ // ============================================================================
327
+ // HWB CONVERSIONS
328
+ // ============================================================================
329
+ /**
330
+ * Convert HWB to RGB
331
+ */
332
+ export function hwbToRgb(hwb) {
333
+ const h = hwb.h;
334
+ let w = hwb.w / 100;
335
+ let b = hwb.b / 100;
336
+ const sum = w + b;
337
+ if (sum > 1) {
338
+ w /= sum;
339
+ b /= sum;
340
+ }
341
+ const v = 1 - b;
342
+ const s = v === 0 ? 0 : 1 - w / v;
343
+ return hsvToRgb({ h, s: s * 100, v: v * 100, a: hwb.a });
344
+ }
345
+ /**
346
+ * Convert HWB to HSL
347
+ */
348
+ export function hwbToHsl(hwb) {
349
+ const rgb = hwbToRgb(hwb);
350
+ return rgbToHsl(rgb);
351
+ }
352
+ /**
353
+ * Convert HWB to HSV
354
+ */
355
+ export function hwbToHsv(hwb) {
356
+ const rgb = hwbToRgb(hwb);
357
+ return rgbToHsv(rgb);
358
+ }
359
+ // ============================================================================
360
+ // CMYK CONVERSIONS
361
+ // ============================================================================
362
+ /**
363
+ * Convert CMYK to RGB
364
+ */
365
+ export function cmykToRgb(cmyk) {
366
+ const c = cmyk.c / 100;
367
+ const m = cmyk.m / 100;
368
+ const y = cmyk.y / 100;
369
+ const k = cmyk.k / 100;
370
+ const r = 255 * (1 - c) * (1 - k);
371
+ const g = 255 * (1 - m) * (1 - k);
372
+ const b = 255 * (1 - y) * (1 - k);
373
+ return {
374
+ r: Math.round(r),
375
+ g: Math.round(g),
376
+ b: Math.round(b),
377
+ a: cmyk.a,
378
+ };
379
+ }
380
+ /**
381
+ * Convert CMYK to HSL
382
+ */
383
+ export function cmykToHsl(cmyk) {
384
+ const rgb = cmykToRgb(cmyk);
385
+ return rgbToHsl(rgb);
386
+ }
387
+ /**
388
+ * Convert CMYK to HSV
389
+ */
390
+ export function cmykToHsv(cmyk) {
391
+ const rgb = cmykToRgb(cmyk);
392
+ return rgbToHsv(rgb);
393
+ }
394
+ // ============================================================================
395
+ // XYZ CONVERSIONS
396
+ // ============================================================================
397
+ /**
398
+ * Convert XYZ to RGB
399
+ */
400
+ export function xyzToRgb(xyz) {
401
+ const x = xyz.x / 100;
402
+ const y = xyz.y / 100;
403
+ const z = xyz.z / 100;
404
+ // Convert XYZ to linear RGB using sRGB matrix
405
+ let r = x * 3.2404542 + y * -1.5371385 + z * -0.4985314;
406
+ let g = x * -0.969266 + y * 1.8760108 + z * 0.041556;
407
+ let b = x * 0.0556434 + y * -0.2040259 + z * 1.0572252;
408
+ // Apply gamma correction
409
+ r = r > 0.0031308 ? 1.055 * Math.pow(r, 1 / 2.4) - 0.055 : 12.92 * r;
410
+ g = g > 0.0031308 ? 1.055 * Math.pow(g, 1 / 2.4) - 0.055 : 12.92 * g;
411
+ b = b > 0.0031308 ? 1.055 * Math.pow(b, 1 / 2.4) - 0.055 : 12.92 * b;
412
+ return {
413
+ r: Math.round(clamp(r * 255, 0, 255)),
414
+ g: Math.round(clamp(g * 255, 0, 255)),
415
+ b: Math.round(clamp(b * 255, 0, 255)),
416
+ a: xyz.alpha || 1,
417
+ };
418
+ }
419
+ /**
420
+ * Convert XYZ to LAB
421
+ */
422
+ export function xyzToLab(xyz) {
423
+ const xr = xyz.x / D65_WHITE.x / 100;
424
+ const yr = xyz.y / D65_WHITE.y / 100;
425
+ const zr = xyz.z / D65_WHITE.z / 100;
426
+ const fx = xr > EPSILON ? Math.cbrt(xr) : (KAPPA * xr + 16) / 116;
427
+ const fy = yr > EPSILON ? Math.cbrt(yr) : (KAPPA * yr + 16) / 116;
428
+ const fz = zr > EPSILON ? Math.cbrt(zr) : (KAPPA * zr + 16) / 116;
429
+ const l = 116 * fy - 16;
430
+ const a = 500 * (fx - fy);
431
+ const b = 200 * (fy - fz);
432
+ return {
433
+ l: clamp(l, 0, 100),
434
+ a,
435
+ b,
436
+ alpha: xyz.alpha,
437
+ };
438
+ }
439
+ // ============================================================================
440
+ // LAB CONVERSIONS
441
+ // ============================================================================
442
+ /**
443
+ * Convert LAB to XYZ
444
+ */
445
+ export function labToXyz(lab) {
446
+ const fy = (lab.l + 16) / 116;
447
+ const fx = lab.a / 500 + fy;
448
+ const fz = fy - lab.b / 200;
449
+ const xr = fx * fx * fx > EPSILON ? fx * fx * fx : (116 * fx - 16) / KAPPA;
450
+ const yr = lab.l > KAPPA * EPSILON ? Math.pow((lab.l + 16) / 116, 3) : lab.l / KAPPA;
451
+ const zr = fz * fz * fz > EPSILON ? fz * fz * fz : (116 * fz - 16) / KAPPA;
452
+ return {
453
+ x: xr * D65_WHITE.x * 100,
454
+ y: yr * D65_WHITE.y * 100,
455
+ z: zr * D65_WHITE.z * 100,
456
+ alpha: lab.alpha,
457
+ };
458
+ }
459
+ /**
460
+ * Convert LAB to RGB
461
+ */
462
+ export function labToRgb(lab) {
463
+ const xyz = labToXyz(lab);
464
+ return xyzToRgb(xyz);
465
+ }
466
+ /**
467
+ * Convert LAB to LCH
468
+ */
469
+ export function labToLch(lab) {
470
+ const c = Math.sqrt(lab.a * lab.a + lab.b * lab.b);
471
+ let h = (Math.atan2(lab.b, lab.a) * 180) / Math.PI;
472
+ if (h < 0) {
473
+ h += 360;
474
+ }
475
+ return {
476
+ l: lab.l,
477
+ c,
478
+ h,
479
+ alpha: lab.alpha,
480
+ };
481
+ }
482
+ // ============================================================================
483
+ // LCH CONVERSIONS
484
+ // ============================================================================
485
+ /**
486
+ * Convert LCH to LAB
487
+ */
488
+ export function lchToLab(lch) {
489
+ const h = (lch.h * Math.PI) / 180;
490
+ const a = lch.c * Math.cos(h);
491
+ const b = lch.c * Math.sin(h);
492
+ return {
493
+ l: lch.l,
494
+ a,
495
+ b,
496
+ alpha: lch.alpha,
497
+ };
498
+ }
499
+ /**
500
+ * Convert LCH to RGB
501
+ */
502
+ export function lchToRgb(lch) {
503
+ const lab = lchToLab(lch);
504
+ return labToRgb(lab);
505
+ }
506
+ /**
507
+ * Convert LCH to XYZ
508
+ */
509
+ export function lchToXyz(lch) {
510
+ const lab = lchToLab(lch);
511
+ return labToXyz(lab);
512
+ }
513
+ // ============================================================================
514
+ // OKLAB CONVERSIONS
515
+ // ============================================================================
516
+ /**
517
+ * Convert OKLAB to RGB
518
+ */
519
+ export function oklabToRgb(oklab) {
520
+ const l_ = oklab.l + 0.3963377774 * oklab.a + 0.2158037573 * oklab.b;
521
+ const m_ = oklab.l - 0.1055613458 * oklab.a - 0.0638541728 * oklab.b;
522
+ const s_ = oklab.l - 0.0894841775 * oklab.a - 1.291485548 * oklab.b;
523
+ const l = l_ * l_ * l_;
524
+ const m = m_ * m_ * m_;
525
+ const s = s_ * s_ * s_;
526
+ let lr = +4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s;
527
+ let lg = -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s;
528
+ let lb = -0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s;
529
+ // Apply gamma correction
530
+ lr = lr > 0.0031308 ? 1.055 * Math.pow(lr, 1 / 2.4) - 0.055 : 12.92 * lr;
531
+ lg = lg > 0.0031308 ? 1.055 * Math.pow(lg, 1 / 2.4) - 0.055 : 12.92 * lg;
532
+ lb = lb > 0.0031308 ? 1.055 * Math.pow(lb, 1 / 2.4) - 0.055 : 12.92 * lb;
533
+ return {
534
+ r: Math.round(clamp(lr * 255, 0, 255)),
535
+ g: Math.round(clamp(lg * 255, 0, 255)),
536
+ b: Math.round(clamp(lb * 255, 0, 255)),
537
+ a: oklab.alpha,
538
+ };
539
+ }
540
+ /**
541
+ * Convert OKLAB to OKLCH
542
+ */
543
+ export function oklabToOklch(oklab) {
544
+ const c = Math.sqrt(oklab.a * oklab.a + oklab.b * oklab.b);
545
+ let h = (Math.atan2(oklab.b, oklab.a) * 180) / Math.PI;
546
+ if (h < 0) {
547
+ h += 360;
548
+ }
549
+ return {
550
+ l: oklab.l,
551
+ c,
552
+ h,
553
+ alpha: oklab.alpha,
554
+ };
555
+ }
556
+ // ============================================================================
557
+ // OKLCH CONVERSIONS
558
+ // ============================================================================
559
+ /**
560
+ * Convert OKLCH to OKLAB
561
+ */
562
+ export function oklchToOklab(oklch) {
563
+ const h = (oklch.h * Math.PI) / 180;
564
+ const a = oklch.c * Math.cos(h);
565
+ const b = oklch.c * Math.sin(h);
566
+ return {
567
+ l: oklch.l,
568
+ a,
569
+ b,
570
+ alpha: oklch.alpha,
571
+ };
572
+ }
573
+ /**
574
+ * Convert OKLCH to RGB
575
+ */
576
+ export function oklchToRgb(oklch) {
577
+ const oklab = oklchToOklab(oklch);
578
+ return oklabToRgb(oklab);
579
+ }
580
+ // ============================================================================
581
+ // UNIVERSAL CONVERTER
582
+ // ============================================================================
583
+ /**
584
+ * Convert any color to RGB
585
+ */
586
+ export function anyToRgb(color) {
587
+ // Check which color space we have based on properties
588
+ if ('r' in color && 'g' in color && 'b' in color) {
589
+ return color;
590
+ }
591
+ if ('h' in color && 's' in color && 'l' in color) {
592
+ return hslToRgb(color);
593
+ }
594
+ if ('h' in color && 's' in color && 'v' in color) {
595
+ return hsvToRgb(color);
596
+ }
597
+ if ('h' in color && 'w' in color && 'b' in color) {
598
+ return hwbToRgb(color);
599
+ }
600
+ if ('c' in color && 'm' in color && 'y' in color && 'k' in color) {
601
+ return cmykToRgb(color);
602
+ }
603
+ if ('x' in color && 'y' in color && 'z' in color) {
604
+ return xyzToRgb(color);
605
+ }
606
+ if ('l' in color &&
607
+ 'a' in color &&
608
+ 'b' in color &&
609
+ !('c' in color) &&
610
+ !('h' in color)) {
611
+ return labToRgb(color);
612
+ }
613
+ if ('l' in color && 'c' in color && 'h' in color) {
614
+ // Could be LCH or OKLCH - we'll treat as LCH by default
615
+ // For better detection, check if values are in OKLCH range
616
+ const lchColor = color;
617
+ if (lchColor.l <= 1) {
618
+ // Likely OKLCH (0-1 range)
619
+ return oklchToRgb(color);
620
+ }
621
+ return lchToRgb(lchColor);
622
+ }
623
+ throw new Error('Unknown color format');
624
+ }
625
+ /**
626
+ * Generic conversion function
627
+ */
628
+ export function convertColor(color, targetFormat, options = {}) {
629
+ const { round = true, precision = 2, preserveAlpha = true } = options;
630
+ // First convert to RGB as intermediate format
631
+ const rgb = anyToRgb(color);
632
+ let result;
633
+ switch (targetFormat.toLowerCase()) {
634
+ case 'rgb':
635
+ result = rgb;
636
+ break;
637
+ case 'hsl':
638
+ result = rgbToHsl(rgb);
639
+ break;
640
+ case 'hsv':
641
+ result = rgbToHsv(rgb);
642
+ break;
643
+ case 'hwb':
644
+ result = rgbToHwb(rgb);
645
+ break;
646
+ case 'cmyk':
647
+ result = rgbToCmyk(rgb);
648
+ break;
649
+ case 'xyz':
650
+ result = rgbToXyz(rgb);
651
+ break;
652
+ case 'lab':
653
+ result = rgbToLab(rgb);
654
+ break;
655
+ case 'lch':
656
+ result = rgbToLch(rgb);
657
+ break;
658
+ case 'oklab':
659
+ result = rgbToOklab(rgb);
660
+ break;
661
+ case 'oklch':
662
+ result = rgbToOklch(rgb);
663
+ break;
664
+ default:
665
+ result = rgb;
666
+ }
667
+ // Apply rounding if requested
668
+ if (round && result) {
669
+ Object.keys(result).forEach((key) => {
670
+ if (typeof result[key] === 'number' && key !== 'a' && key !== 'alpha') {
671
+ result[key] = roundToPrecision(result[key], precision);
672
+ }
673
+ });
674
+ }
675
+ // Handle alpha channel
676
+ if (!preserveAlpha) {
677
+ delete result.a;
678
+ delete result.alpha;
679
+ }
680
+ return result;
681
+ }
682
+ /**
683
+ * Batch convert multiple colors
684
+ */
685
+ export function batchConvert(colors, targetFormat, options = {}) {
686
+ return colors.map((color) => convertColor(color, targetFormat, options));
687
+ }
688
+ /**
689
+ * Get conversion path between two formats
690
+ */
691
+ export function getConversionPath(from, to) {
692
+ // Direct conversions
693
+ const directConversions = {
694
+ rgb: ['hsl', 'hsv', 'hwb', 'cmyk', 'xyz', 'lab', 'lch', 'oklab', 'oklch'],
695
+ hsl: ['rgb', 'hsv', 'hwb'],
696
+ hsv: ['rgb', 'hsl', 'hwb'],
697
+ hwb: ['rgb', 'hsl', 'hsv'],
698
+ cmyk: ['rgb', 'hsl', 'hsv'],
699
+ xyz: ['rgb', 'lab'],
700
+ lab: ['rgb', 'xyz', 'lch'],
701
+ lch: ['rgb', 'lab', 'xyz'],
702
+ oklab: ['rgb', 'oklch'],
703
+ oklch: ['rgb', 'oklab'],
704
+ };
705
+ from = from.toLowerCase();
706
+ to = to.toLowerCase();
707
+ if (from === to) {
708
+ return [from];
709
+ }
710
+ // Check for direct conversion
711
+ if (directConversions[from]?.includes(to)) {
712
+ return [from, to];
713
+ }
714
+ // Use RGB as intermediate (most common case)
715
+ if (directConversions[from]?.includes('rgb') &&
716
+ directConversions['rgb']?.includes(to)) {
717
+ return [from, 'rgb', to];
718
+ }
719
+ // Use XYZ as intermediate for LAB/LCH conversions
720
+ if (['lab', 'lch'].includes(from) &&
721
+ ['lab', 'lch'].includes(to) &&
722
+ from !== to) {
723
+ return [from, 'xyz', to];
724
+ }
725
+ // Use OKLAB as intermediate for OKLCH
726
+ if (['oklab', 'oklch'].includes(from) &&
727
+ ['oklab', 'oklch'].includes(to) &&
728
+ from !== to) {
729
+ return [from, 'oklab', to];
730
+ }
731
+ // Complex path through RGB
732
+ if (directConversions[from] && directConversions['rgb']?.includes(to)) {
733
+ return [from, 'rgb', to];
734
+ }
735
+ return null;
736
+ }
737
+ /**
738
+ * Check if direct conversion exists between two formats
739
+ */
740
+ export function hasDirectConversion(from, to) {
741
+ const path = getConversionPath(from, to);
742
+ return path !== null && path.length <= 2;
743
+ }
744
+ /**
745
+ * Get all supported color formats
746
+ */
747
+ export function getSupportedFormats() {
748
+ return [
749
+ 'rgb',
750
+ 'hsl',
751
+ 'hsv',
752
+ 'hwb',
753
+ 'cmyk',
754
+ 'xyz',
755
+ 'lab',
756
+ 'lch',
757
+ 'oklab',
758
+ 'oklch',
759
+ ];
760
+ }
761
+ /**
762
+ * Validate color format
763
+ */
764
+ export function isValidFormat(format) {
765
+ return getSupportedFormats().includes(format.toLowerCase());
766
+ }