@oscarpalmer/atoms 0.190.0 → 0.192.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 (57) hide show
  1. package/dist/beacon.d.mts +6 -44
  2. package/dist/beacon.mjs +20 -67
  3. package/dist/color/constants.d.mts +82 -35
  4. package/dist/color/constants.mjs +106 -61
  5. package/dist/color/index.d.mts +3 -3
  6. package/dist/color/index.mjs +2 -2
  7. package/dist/color/instance.mjs +60 -35
  8. package/dist/color/misc/alpha.d.mts +1 -1
  9. package/dist/color/misc/alpha.mjs +12 -10
  10. package/dist/color/misc/format.d.mts +7 -0
  11. package/dist/color/misc/format.mjs +20 -0
  12. package/dist/color/misc/get.mjs +25 -25
  13. package/dist/color/misc/is.d.mts +0 -36
  14. package/dist/color/misc/is.mjs +22 -57
  15. package/dist/color/misc/state.d.mts +8 -6
  16. package/dist/color/misc/state.mjs +79 -88
  17. package/dist/color/models.d.mts +106 -6
  18. package/dist/color/space/hex.d.mts +3 -2
  19. package/dist/color/space/hex.mjs +22 -10
  20. package/dist/color/space/hsl.d.mts +3 -2
  21. package/dist/color/space/hsl.mjs +26 -14
  22. package/dist/color/space/hwb.d.mts +3 -2
  23. package/dist/color/space/hwb.mjs +20 -8
  24. package/dist/color/space/rgb.d.mts +3 -2
  25. package/dist/color/space/rgb.mjs +27 -15
  26. package/dist/herald.d.mts +2 -3
  27. package/dist/index.d.mts +139 -73
  28. package/dist/index.mjs +653 -477
  29. package/dist/internal/subscription.d.mts +52 -0
  30. package/dist/internal/subscription.mjs +127 -0
  31. package/dist/models.d.mts +5 -1
  32. package/package.json +4 -4
  33. package/src/beacon.ts +32 -117
  34. package/src/color/constants.ts +115 -66
  35. package/src/color/index.ts +26 -8
  36. package/src/color/instance.ts +113 -45
  37. package/src/color/misc/alpha.ts +18 -20
  38. package/src/color/misc/format.ts +29 -0
  39. package/src/color/misc/get.ts +31 -41
  40. package/src/color/misc/is.ts +31 -71
  41. package/src/color/misc/state.ts +165 -141
  42. package/src/color/models.ts +126 -5
  43. package/src/color/space/hex.ts +46 -18
  44. package/src/color/space/hsl.ts +44 -14
  45. package/src/color/space/hwb.ts +38 -8
  46. package/src/color/space/rgb.ts +48 -15
  47. package/src/herald.ts +1 -3
  48. package/src/index.ts +1 -0
  49. package/src/internal/subscription.ts +264 -0
  50. package/src/models.ts +5 -0
  51. package/src/string/fuzzy.ts +1 -1
  52. package/src/value/freeze.ts +2 -2
  53. package/src/value/shake.ts +1 -1
  54. package/src/value/transform.ts +1 -1
  55. package/dist/color/misc/index.d.mts +0 -7
  56. package/dist/color/misc/index.mjs +0 -15
  57. package/src/color/misc/index.ts +0 -29
package/dist/index.mjs CHANGED
@@ -2289,6 +2289,131 @@ const MESSAGE = "Herald requires an array of event names.";
2289
2289
  const NAME_EVENTS = "events";
2290
2290
  const NAME_HERALD = "herald";
2291
2291
  //#endregion
2292
+ //#region src/internal/subscription.ts
2293
+ function addSubscription(subscription, state) {
2294
+ const { key, subscriptions, value } = state.parameters;
2295
+ const { items, values } = subscriptions;
2296
+ if (key == null) {
2297
+ items.any.add(subscription);
2298
+ values.from.any.set(value, subscription);
2299
+ values.to.any.set(subscription, value);
2300
+ return;
2301
+ }
2302
+ if (items.keyed == null || values.from.keyed == null || values.to.keyed == null)
2303
+ // istanbul ignore next
2304
+ return;
2305
+ let keyedItems = items.keyed.get(key);
2306
+ if (keyedItems == null) {
2307
+ keyedItems = /* @__PURE__ */ new Set();
2308
+ items.keyed.set(key, keyedItems);
2309
+ }
2310
+ keyedItems.add(subscription);
2311
+ let keyedFrom = values.from.keyed.get(key);
2312
+ if (keyedFrom == null) {
2313
+ keyedFrom = /* @__PURE__ */ new Map();
2314
+ values.from.keyed.set(key, keyedFrom);
2315
+ }
2316
+ keyedFrom.set(value, subscription);
2317
+ let keyedTo = values.to.keyed.get(key);
2318
+ if (keyedTo == null) {
2319
+ keyedTo = /* @__PURE__ */ new Map();
2320
+ values.to.keyed.set(key, keyedTo);
2321
+ }
2322
+ keyedTo.set(subscription, value);
2323
+ }
2324
+ function clearSubscriptions(store) {
2325
+ for (const susbcription of store.values.to.any.keys()) susbcription.unsubscribe();
2326
+ if (store.values.to.keyed != null) for (const values of store.values.to.keyed.values()) for (const susbcription of values.keys()) susbcription.unsubscribe();
2327
+ }
2328
+ function getExistingSubscription(state) {
2329
+ const { parameters } = state;
2330
+ const { values } = parameters.subscriptions;
2331
+ return parameters.key == null ? values.from.any.get(parameters.value) : values.from.keyed?.get(parameters.key)?.get(parameters.value);
2332
+ }
2333
+ function getSubscription(parameters) {
2334
+ const state = {
2335
+ parameters,
2336
+ active: true
2337
+ };
2338
+ const existing = getExistingSubscription(state);
2339
+ if (existing != null) return existing;
2340
+ if (parameters.subscriptions.keys != null && parameters.key != null && !parameters.subscriptions.keys.has(parameters.key)) throw new Error();
2341
+ const instance = { unsubscribe: () => {
2342
+ removeSubscription(instance, state);
2343
+ } };
2344
+ Object.defineProperties(instance, {
2345
+ [PROPERTY]: {
2346
+ enumerable: false,
2347
+ value: true
2348
+ },
2349
+ [parameters.property.key]: {
2350
+ enumerable: false,
2351
+ value: parameters.property.value
2352
+ },
2353
+ active: {
2354
+ enumerable: true,
2355
+ get: () => (parameters.isActive?.() ?? true) && state.active
2356
+ }
2357
+ });
2358
+ addSubscription(instance, state);
2359
+ return Object.freeze(instance);
2360
+ }
2361
+ function getSubscriptions(keys) {
2362
+ return {
2363
+ keys,
2364
+ items: {
2365
+ any: /* @__PURE__ */ new Set(),
2366
+ keyed: keys == null ? void 0 : /* @__PURE__ */ new Map()
2367
+ },
2368
+ values: {
2369
+ from: {
2370
+ any: /* @__PURE__ */ new Map(),
2371
+ keyed: keys == null ? void 0 : /* @__PURE__ */ new Map()
2372
+ },
2373
+ to: {
2374
+ any: /* @__PURE__ */ new Map(),
2375
+ keyed: keys == null ? void 0 : /* @__PURE__ */ new Map()
2376
+ }
2377
+ }
2378
+ };
2379
+ }
2380
+ /**
2381
+ * Is the value a subscription?
2382
+ *
2383
+ * @param value Value to check
2384
+ * @returns `true` if the value is a subscription, otherwise `false`
2385
+ */
2386
+ function isSubscription(value) {
2387
+ return isPlainObject(value) && PROPERTY in value && value[PROPERTY] === true;
2388
+ }
2389
+ function removeFromStore(items, values, subscription, value, key) {
2390
+ items.delete(subscription);
2391
+ if (key == null) {
2392
+ values.from.any.delete(value);
2393
+ values.to.any.delete(subscription);
2394
+ } else {
2395
+ values.from.keyed?.get(key)?.delete(value);
2396
+ values.to.keyed?.get(key)?.delete(subscription);
2397
+ }
2398
+ }
2399
+ function removeSubscription(subscription, state) {
2400
+ if (!state.active) return;
2401
+ state.active = false;
2402
+ const { key, subscriptions, value } = state.parameters;
2403
+ const { items, values } = subscriptions;
2404
+ if (key == null) {
2405
+ removeFromStore(items.any, values, subscription, value);
2406
+ return;
2407
+ }
2408
+ const keyed = items.keyed?.get(key);
2409
+ if (items.keyed == null || keyed == null)
2410
+ // istanbul ignore next
2411
+ return;
2412
+ removeFromStore(keyed, values, subscription, value, key);
2413
+ if (keyed.size === 0) items.keyed.delete(key);
2414
+ }
2415
+ const PROPERTY = "$subscription";
2416
+ //#endregion
2292
2417
  //#region src/internal/value/equal.ts
2293
2418
  /**
2294
2419
  * Deregister a equality comparison handler for a specific class
@@ -2633,125 +2758,6 @@ let memoizedLowerCase;
2633
2758
  let memoizedTitleCase;
2634
2759
  let memoizedUpperCase;
2635
2760
  //#endregion
2636
- //#region src/is.ts
2637
- /**
2638
- * Is the value empty, or only containing `null` or `undefined` values?
2639
- *
2640
- * @param value Value to check
2641
- * @returns `true` if the value is considered empty, otherwise `false`
2642
- */
2643
- function isEmpty(value) {
2644
- if (value == null) return true;
2645
- if (typeof value === "string") return value.length === 0;
2646
- const values = getArray(value);
2647
- const { length } = values;
2648
- for (let index = 0; index < length; index += 1) {
2649
- const item = values[index];
2650
- if (Array.isArray(item) ? item[1] != null : item != null) return false;
2651
- }
2652
- return true;
2653
- }
2654
- /**
2655
- * Is the value not empty, or holding non-empty values?
2656
- *
2657
- * @param value Value to check
2658
- * @returns `true` if the value is not considered empty, otherwise `false`
2659
- */
2660
- function isNonEmpty(value) {
2661
- return !isEmpty(value);
2662
- }
2663
- /**
2664
- * Is the value not `undefined` or `null`?
2665
- *
2666
- * @param value Value to check
2667
- * @returns `true` if the value is not `undefined` or `null`, otherwise `false`
2668
- */
2669
- function isNonNullable(value) {
2670
- return value != null;
2671
- }
2672
- /**
2673
- * Is the value not `undefined`, `null`, or stringified as an empty _(no whitespace)_ string?
2674
- *
2675
- * @param value Value to check
2676
- * @returns `true` if the value is not `undefined`, `null`, or matches an empty string, otherwise `false`
2677
- */
2678
- function isNonNullableOrEmpty(value) {
2679
- return value != null && getString(value) !== "";
2680
- }
2681
- /**
2682
- * Is the value not `undefined`, `null`, or stringified as a whitespace-only string?
2683
- *
2684
- * @param value Value to check
2685
- * @returns `true` if the value is not `undefined`, `null`, or matches a whitespace-only string, otherwise `false`
2686
- */
2687
- function isNonNullableOrWhitespace(value) {
2688
- return value != null && !EXPRESSION_WHITESPACE.test(getString(value));
2689
- }
2690
- /**
2691
- * Is the value not a number or a number-like string?
2692
- *
2693
- * @param value Value to check
2694
- * @returns `true` if the value is not a number or a number-like string, otherwise `false`
2695
- */
2696
- function isNonNumerical(value) {
2697
- return !isNumerical(value);
2698
- }
2699
- /**
2700
- * Is the value not an object _(or function)_?
2701
- *
2702
- * @param value Value to check
2703
- * @returns `true` if the value is not an object, otherwise `false`
2704
- */
2705
- function isNonObject(value) {
2706
- return !isObject(value);
2707
- }
2708
- /**
2709
- * Is the value `undefined` or `null`?
2710
- *
2711
- * @param value Value to check
2712
- * @returns `true` if the value is `undefined` or `null`, otherwise `false`
2713
- */
2714
- function isNullable(value) {
2715
- return value == null;
2716
- }
2717
- /**
2718
- * Is the value `undefined`, `null`, or stringified as an empty _(no whitespace)_ string?
2719
- *
2720
- * @param value Value to check
2721
- * @returns `true` if the value is nullable or matches an empty string, otherwise `false`
2722
- */
2723
- function isNullableOrEmpty(value) {
2724
- return value == null || getString(value) === "";
2725
- }
2726
- /**
2727
- * Is the value `undefined`, `null`, or stringified as a whitespace-only string?
2728
- *
2729
- * @param value Value to check
2730
- * @returns `true` if the value is nullable or matches a whitespace-only string, otherwise `false`
2731
- */
2732
- function isNullableOrWhitespace(value) {
2733
- return value == null || EXPRESSION_WHITESPACE.test(getString(value));
2734
- }
2735
- /**
2736
- * Is the value a number or a number-like string?
2737
- *
2738
- * @param value Value to check
2739
- * @returns `true` if the value is a number or a number-like string, otherwise `false`
2740
- */
2741
- function isNumerical(value) {
2742
- return isNumber(value) || typeof value === "string" && value.trim().length > 0 && !Number.isNaN(+value);
2743
- }
2744
- /**
2745
- * Is the value an object _(or function)_?
2746
- *
2747
- * @param value Value to check
2748
- * @returns `true` if the value matches, otherwise `false`
2749
- */
2750
- function isObject(value) {
2751
- return typeof value === "object" && value !== null || typeof value === "function";
2752
- }
2753
- const EXPRESSION_WHITESPACE = /^\s*$/;
2754
- //#endregion
2755
2761
  //#region src/string/match.ts
2756
2762
  /**
2757
2763
  * Check if a string ends with a specified substring
@@ -3820,11 +3826,11 @@ function beacon(value, options) {
3820
3826
  value,
3821
3827
  active: true,
3822
3828
  observable: void 0,
3823
- observers: /* @__PURE__ */ new Map(),
3824
- options: getBeaconOptions(options)
3829
+ options: getBeaconOptions(options),
3830
+ subscriptions: getSubscriptions()
3825
3831
  };
3826
3832
  const instance = {
3827
- close: () => {
3833
+ deactivate: () => {
3828
3834
  finishBeacon(state, false);
3829
3835
  },
3830
3836
  emit: (value, finish) => {
@@ -3846,10 +3852,6 @@ function beacon(value, options) {
3846
3852
  enumerable: true,
3847
3853
  get: () => state.active
3848
3854
  },
3849
- closed: {
3850
- enumerable: true,
3851
- get: () => !state.active
3852
- },
3853
3855
  observable: {
3854
3856
  enumerable: true,
3855
3857
  get: () => {
@@ -3868,15 +3870,9 @@ function beacon(value, options) {
3868
3870
  function finishBeacon(state, emit) {
3869
3871
  if (!state.active) return;
3870
3872
  state.active = false;
3871
- const entries = [...state.observers.entries()];
3872
- const { length } = entries;
3873
- for (let index = 0; index < length; index += 1) {
3874
- const [subscription, observer] = entries[index];
3875
- if (emit) observer.complete?.();
3876
- subscription.close();
3877
- }
3878
- state.observable?.close();
3879
- state.observers.clear();
3873
+ for (const [, observer] of state.subscriptions.values.to.any) if (emit) observer.complete?.();
3874
+ clearSubscriptions(state.subscriptions);
3875
+ state.observable?.deactivate();
3880
3876
  state.observable = void 0;
3881
3877
  }
3882
3878
  function getBeaconOptions(input) {
@@ -3922,29 +3918,24 @@ function isBeaconInstance(name, value) {
3922
3918
  function isObservable(value) {
3923
3919
  return isBeaconInstance(NAME_OBSERVABLE, value);
3924
3920
  }
3925
- /**
3926
- * Is the value a subscription?
3927
- *
3928
- * @param value Value to check
3929
- * @returns `true` if the value is a subscription, otherwise `false`
3930
- */
3931
- function isSubscription(value) {
3932
- return isBeaconInstance(NAME_SUBSCRIPTION, value);
3933
- }
3934
3921
  function observe(beacon) {
3935
3922
  const state = {
3936
3923
  beacon,
3937
3924
  active: beacon.active
3938
3925
  };
3939
3926
  const instance = {
3940
- close: () => {
3927
+ deactivate: () => {
3941
3928
  state.active = false;
3942
3929
  },
3943
3930
  subscribe(first, second, third) {
3944
3931
  if (!beacon.active || !state.active) throw new Error(MESSAGE_OBSERVABLE);
3945
3932
  const observer = getObserver(first, second, third);
3946
- const subscription = subscribe(state);
3947
- beacon.observers.set(subscription, observer);
3933
+ const subscription = getSubscription({
3934
+ isActive: () => beacon.active && state.active,
3935
+ property: beaconSubscription,
3936
+ subscriptions: beacon.subscriptions,
3937
+ value: observer
3938
+ });
3948
3939
  observer.next?.(beacon.value);
3949
3940
  return subscription;
3950
3941
  }
@@ -3957,42 +3948,6 @@ function observe(beacon) {
3957
3948
  active: {
3958
3949
  enumerable: true,
3959
3950
  get: () => beacon.active && state.active
3960
- },
3961
- closed: {
3962
- enumerable: true,
3963
- get: () => !beacon.active || !state.active
3964
- }
3965
- });
3966
- return Object.freeze(instance);
3967
- }
3968
- function subscribe(observable) {
3969
- function unsubscribe() {
3970
- if (active) {
3971
- active = false;
3972
- observable.beacon.observers.delete(instance);
3973
- }
3974
- }
3975
- let active = true;
3976
- const instance = {
3977
- close: () => {
3978
- unsubscribe();
3979
- },
3980
- unsubscribe: () => {
3981
- unsubscribe();
3982
- }
3983
- };
3984
- Object.defineProperties(instance, {
3985
- [KEY_BEACON]: {
3986
- enumerable: false,
3987
- value: NAME_SUBSCRIPTION
3988
- },
3989
- active: {
3990
- enumerable: true,
3991
- get: () => observable.beacon.active && observable.active && active
3992
- },
3993
- closed: {
3994
- enumerable: true,
3995
- get: () => !observable.beacon.active || !observable.active || !active
3996
3951
  }
3997
3952
  });
3998
3953
  return Object.freeze(instance);
@@ -4003,7 +3958,7 @@ function update$1(type, state, value, finish) {
4003
3958
  if (state.options.equal(state.value, value)) return;
4004
3959
  state.value = value;
4005
3960
  }
4006
- for (const [, observer] of state.observers) observer[type]?.(value);
3961
+ for (const [, observer] of state.subscriptions.values.to.any) observer[type]?.(value);
4007
3962
  if (finish === true) finishBeacon(state, true);
4008
3963
  }
4009
3964
  const KEY_BEACON = "$beacon";
@@ -4011,23 +3966,119 @@ const MESSAGE_BEACON = "Cannot retrieve observable from a closed beacon";
4011
3966
  const MESSAGE_OBSERVABLE = "Cannot subscribe to a closed observable";
4012
3967
  const NAME_BEACON = "beacon";
4013
3968
  const NAME_OBSERVABLE = "observable";
4014
- const NAME_SUBSCRIPTION = "subscription";
4015
3969
  const TYPE_ERROR = "error";
4016
3970
  const TYPE_NEXT = "next";
3971
+ const beaconSubscription = {
3972
+ key: KEY_BEACON,
3973
+ value: "subscription"
3974
+ };
4017
3975
  //#endregion
4018
- //#region src/color/misc/index.ts
4019
- function formatHslColor(state, alpha) {
4020
- const { hue, lightness, saturation } = state.hsl;
4021
- return `hsl(${hue}deg ${saturation}% ${lightness}%${alpha ? ` / ${state.alpha.value}%` : ""})`;
4022
- }
4023
- function formatHwbColor(state, alpha) {
4024
- const { blackness, hue, whiteness } = state.hwb;
4025
- return `hwb(${hue}deg ${whiteness}% ${blackness}%${alpha ? ` / ${state.alpha.value}%` : ""})`;
4026
- }
4027
- function formatRgbColor(state, alpha) {
4028
- const { blue, green, red } = state.rgb;
4029
- return `rgb(${red} ${green} ${blue}${alpha ? ` / ${state.alpha.value}%` : ""})`;
4030
- }
3976
+ //#region src/color/constants.ts
3977
+ const COLOR_ALPHA = {
3978
+ fullHexShort: "f",
3979
+ fullHexLong: "ff",
3980
+ name: "alpha",
3981
+ noneHex: "00",
3982
+ noneValue: 0
3983
+ };
3984
+ const COLOR_DEFAULTS = {
3985
+ alpha: {
3986
+ hex: COLOR_ALPHA.fullHexLong,
3987
+ value: 100
3988
+ },
3989
+ hexBlack: "000000",
3990
+ hexWhite: "ffffff",
3991
+ hsl: {
3992
+ hue: 0,
3993
+ saturation: 0,
3994
+ lightness: 0
3995
+ },
3996
+ hwb: {
3997
+ hue: 0,
3998
+ whiteness: 0,
3999
+ blackness: 100
4000
+ },
4001
+ rgb: {
4002
+ blue: 0,
4003
+ green: 0,
4004
+ red: 0
4005
+ }
4006
+ };
4007
+ const COLOR_EXPRESSION = {
4008
+ alphaHex: /^([a-f0-9]{1,2})$/i,
4009
+ hexLong: /^#?([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})?$/i,
4010
+ hexShort: /^#?([a-f0-9]{3,4})$/i,
4011
+ prefix: /^#/
4012
+ };
4013
+ const COLOR_LENGTHS = {
4014
+ hexLong: 6,
4015
+ hexShort: 3
4016
+ };
4017
+ const COLOR_KEYS = {
4018
+ hsl: [
4019
+ "hue",
4020
+ "saturation",
4021
+ "lightness"
4022
+ ],
4023
+ hsla: [],
4024
+ hwb: [
4025
+ "hue",
4026
+ "whiteness",
4027
+ "blackness"
4028
+ ],
4029
+ hwba: [],
4030
+ rgb: [
4031
+ "red",
4032
+ "green",
4033
+ "blue"
4034
+ ],
4035
+ rgba: []
4036
+ };
4037
+ COLOR_KEYS.hsla = [...COLOR_KEYS.hsl, COLOR_ALPHA.name];
4038
+ COLOR_KEYS.hwba = [...COLOR_KEYS.hwb, COLOR_ALPHA.name];
4039
+ COLOR_KEYS.rgba = [...COLOR_KEYS.rgb, COLOR_ALPHA.name];
4040
+ const COLOR_MAX = {
4041
+ degree: 360,
4042
+ hex: 255,
4043
+ percent: 100
4044
+ };
4045
+ const COLOR_PROPERTY = {
4046
+ name: "$color",
4047
+ subscription: "subscription"
4048
+ };
4049
+ const COLOR_TYPE = {
4050
+ all: void 0,
4051
+ hex: "hex",
4052
+ hexa: "hexa",
4053
+ hsl: "hsl",
4054
+ hsla: "hsla",
4055
+ hwb: "hwb",
4056
+ hwba: "hwba",
4057
+ rgb: "rgb",
4058
+ rgba: "rgba"
4059
+ };
4060
+ COLOR_TYPE.all = /* @__PURE__ */ new Set([
4061
+ COLOR_ALPHA.name,
4062
+ COLOR_TYPE.hex,
4063
+ COLOR_TYPE.hexa,
4064
+ COLOR_TYPE.hsl,
4065
+ COLOR_TYPE.hsla,
4066
+ COLOR_TYPE.hwb,
4067
+ COLOR_TYPE.hwba,
4068
+ COLOR_TYPE.rgb,
4069
+ COLOR_TYPE.rgba
4070
+ ]);
4071
+ const COLOR_SRGB = {
4072
+ luminanceBlue: .0722,
4073
+ luminanceExponent: 2.4,
4074
+ luminanceGreen: .7152,
4075
+ luminanceMinimum: .03928,
4076
+ luminanceModifier: 1.055,
4077
+ luminanceMultiplier: 12.92,
4078
+ luminanceOffset: .055,
4079
+ luminanceRed: .2126,
4080
+ luminanceThreshold: .625
4081
+ };
4031
4082
  //#endregion
4032
4083
  //#region src/internal/math/misc.ts
4033
4084
  /**
@@ -4046,67 +4097,21 @@ function roundNumber(callback, value, decimals) {
4046
4097
  const mod = 10 ** decimals;
4047
4098
  return callback((value + Number.EPSILON) * mod) / mod;
4048
4099
  }
4049
- const ALPHA_FULL_HEX_LONG = `ff`;
4050
- const DEFAULT_ALPHA = {
4051
- hex: ALPHA_FULL_HEX_LONG,
4052
- value: 100
4053
- };
4054
- const DEFAULT_HSL = {
4055
- hue: 0,
4056
- saturation: 0,
4057
- lightness: 0
4058
- };
4059
- const DEFAULT_HWB = {
4060
- hue: 0,
4061
- whiteness: 0,
4062
- blackness: 100
4063
- };
4064
- const DEFAULT_RGB = {
4065
- blue: 0,
4066
- green: 0,
4067
- red: 0
4068
- };
4069
- const EXPRESSION_HEX_LONG = /^#?([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})?$/i;
4070
- const EXPRESSION_HEX_SHORT = /^#?([a-f0-9]{3,4})$/i;
4071
- const EXPRESSION_PREFIX = /^#/;
4072
- const HEX_BLACK = "000000";
4073
- const HEX_WHITE = "ffffff";
4074
- const KEYS_HSL = [
4075
- "hue",
4076
- "saturation",
4077
- "lightness"
4078
- ];
4079
- const KEYS_HSLA = [...KEYS_HSL, "alpha"];
4080
- const KEYS_HWB = [
4081
- "hue",
4082
- "whiteness",
4083
- "blackness"
4084
- ];
4085
- const KEYS_HWBA = [...KEYS_HWB, "alpha"];
4086
- const KEYS_RGB = [
4087
- "red",
4088
- "green",
4089
- "blue"
4090
- ];
4091
- const KEYS_RGBA = [...KEYS_RGB, "alpha"];
4092
- const SRGB_LUMINANCE_EXPONENT = 2.4;
4093
- const SRGB_LUMINANCE_MODIFIER = 1.055;
4094
- const SRGB_LUMINANCE_MULTIPLIER = 12.92;
4095
- const SRGB_LUMINANCE_OFFSET = .055;
4096
4100
  //#endregion
4097
4101
  //#region src/color/misc/alpha.ts
4098
- function getAlpha(value) {
4102
+ function getAlpha(value, hex) {
4099
4103
  if (typeof value === "number") return getAlphaFromValue(value);
4100
- if (typeof value === "string" && value !== ALPHA_FULL_HEX_LONG) return {
4104
+ if (typeof value !== "string" || value.toLowerCase() === COLOR_ALPHA.fullHexLong) return { ...COLOR_DEFAULTS.alpha };
4105
+ if (hex && COLOR_EXPRESSION.alphaHex.test(value)) return {
4101
4106
  hex: value,
4102
- value: Number.parseInt(value, 16) / 255
4107
+ value: Number.parseInt(value, 16) / COLOR_MAX.hex
4103
4108
  };
4104
- return { ...DEFAULT_ALPHA };
4109
+ return getAlphaFromValue(Number.parseFloat(value));
4105
4110
  }
4106
4111
  function getAlphaHexadecimal(value) {
4107
- if (value === 0) return "00";
4108
- if (value === 100) return ALPHA_FULL_HEX_LONG;
4109
- return round(value * 255).toString(16);
4112
+ if (value === COLOR_ALPHA.noneValue) return COLOR_ALPHA.noneHex;
4113
+ if (value === COLOR_MAX.percent) return COLOR_ALPHA.fullHexLong;
4114
+ return round(value / COLOR_MAX.percent * COLOR_MAX.hex).toString(16);
4110
4115
  }
4111
4116
  function getAlphaFromValue(value) {
4112
4117
  const alpha = getAlphaValue(value);
@@ -4116,8 +4121,8 @@ function getAlphaFromValue(value) {
4116
4121
  };
4117
4122
  }
4118
4123
  function getAlphaValue(original) {
4119
- if (Number.isNaN(original) || original >= 100) return 100;
4120
- return original <= 0 ? 0 : original;
4124
+ if (Number.isNaN(original)) return COLOR_MAX.percent;
4125
+ return clamp(original, COLOR_ALPHA.noneValue, COLOR_MAX.percent);
4121
4126
  }
4122
4127
  //#endregion
4123
4128
  //#region src/color/misc/get.ts
@@ -4125,19 +4130,19 @@ function getClampedValue(value, minimum, maximum, rounding) {
4125
4130
  return typeof value === "number" && !Number.isNaN(value) ? clamp(rounding ?? false ? round(value) : value, minimum, maximum) : minimum;
4126
4131
  }
4127
4132
  function getForegroundColor(value, hex) {
4128
- const { blue, green, red } = getColorState(value).rgb;
4133
+ const { blue, green, red } = getColorFromState(getColorState(value), COLOR_TYPE.rgb);
4129
4134
  const values = [
4130
- blue / 255,
4131
- green / 255,
4132
- red / 255
4135
+ blue / COLOR_MAX.hex,
4136
+ green / COLOR_MAX.hex,
4137
+ red / COLOR_MAX.hex
4133
4138
  ];
4134
4139
  const { length } = values;
4135
4140
  for (let index = 0; index < length; index += 1) {
4136
4141
  const color = values[index];
4137
- if (color <= .03928) values[index] /= SRGB_LUMINANCE_MULTIPLIER;
4138
- else values[index] = ((color + SRGB_LUMINANCE_OFFSET) / SRGB_LUMINANCE_MODIFIER) ** SRGB_LUMINANCE_EXPONENT;
4142
+ if (color <= COLOR_SRGB.luminanceMinimum) values[index] /= COLOR_SRGB.luminanceMultiplier;
4143
+ else values[index] = ((color + COLOR_SRGB.luminanceOffset) / COLOR_SRGB.luminanceModifier) ** COLOR_SRGB.luminanceExponent;
4139
4144
  }
4140
- const foreground = .2126 * values[2] + .7152 * values[1] + .0722 * values[0] > .625 ? HEX_BLACK : HEX_WHITE;
4145
+ const foreground = COLOR_SRGB.luminanceRed * values[2] + COLOR_SRGB.luminanceGreen * values[1] + COLOR_SRGB.luminanceBlue * values[0] > COLOR_SRGB.luminanceThreshold ? COLOR_DEFAULTS.hexBlack : COLOR_DEFAULTS.hexWhite;
4141
4146
  return hex === true ? foreground : color(foreground);
4142
4147
  }
4143
4148
  /**
@@ -4163,13 +4168,13 @@ function getHexaColor(value) {
4163
4168
  * @returns Hex color string
4164
4169
  */
4165
4170
  function getHexColor(value) {
4166
- return getColorState(value).hex;
4171
+ return getColorFromState(getColorState(value), COLOR_TYPE.hex);
4167
4172
  }
4168
4173
  function getHexValue(value) {
4169
- return getClampedValue(value, 0, 255, true);
4174
+ return getClampedValue(value, 0, COLOR_MAX.hex, true);
4170
4175
  }
4171
4176
  function getDegrees(value) {
4172
- return getClampedValue(value, 0, 360);
4177
+ return getClampedValue(value, 0, COLOR_MAX.degree);
4173
4178
  }
4174
4179
  /**
4175
4180
  * Get the _HSLA_ color from any kind of value
@@ -4181,10 +4186,10 @@ function getDegrees(value) {
4181
4186
  * @returns _HSLA_ color
4182
4187
  */
4183
4188
  function getHslaColor(value) {
4184
- const { alpha, hsl } = getColorState(value);
4189
+ const state = getColorState(value);
4185
4190
  return {
4186
- ...hsl,
4187
- alpha: alpha.value
4191
+ ...getColorFromState(state, COLOR_TYPE.hsl),
4192
+ alpha: state.alpha.value
4188
4193
  };
4189
4194
  }
4190
4195
  /**
@@ -4197,7 +4202,7 @@ function getHslaColor(value) {
4197
4202
  * @returns _HWB_ color
4198
4203
  */
4199
4204
  function getHwbColor(value) {
4200
- return getColorState(value).hwb;
4205
+ return getColorFromState(getColorState(value), COLOR_TYPE.hwb);
4201
4206
  }
4202
4207
  /**
4203
4208
  * Get the _HWBA_ color from any kind of value
@@ -4209,10 +4214,10 @@ function getHwbColor(value) {
4209
4214
  * @returns _HWBA_ color
4210
4215
  */
4211
4216
  function getHwbaColor(value) {
4212
- const { alpha, hwb } = getColorState(value);
4217
+ const state = getColorState(value);
4213
4218
  return {
4214
- ...hwb,
4215
- alpha: alpha.value
4219
+ ...getColorFromState(state, COLOR_TYPE.hwb),
4220
+ alpha: state.alpha.value
4216
4221
  };
4217
4222
  }
4218
4223
  /**
@@ -4225,10 +4230,10 @@ function getHwbaColor(value) {
4225
4230
  * @returns _HSL_ color
4226
4231
  */
4227
4232
  function getHslColor(value) {
4228
- return getColorState(value).hsl;
4233
+ return getColorFromState(getColorState(value), COLOR_TYPE.hsl);
4229
4234
  }
4230
4235
  function getPercentage(value) {
4231
- return getClampedValue(value, 0, 100);
4236
+ return getClampedValue(value, 0, COLOR_MAX.percent);
4232
4237
  }
4233
4238
  /**
4234
4239
  * Get the _RGBA_ color from any kind of value
@@ -4240,10 +4245,10 @@ function getPercentage(value) {
4240
4245
  * @returns _RGBA_ color
4241
4246
  */
4242
4247
  function getRgbaColor(value) {
4243
- const { alpha, rgb } = getColorState(value);
4248
+ const state = getColorState(value);
4244
4249
  return {
4245
- ...rgb,
4246
- alpha: alpha.value
4250
+ ...getColorFromState(state, COLOR_TYPE.rgb),
4251
+ alpha: state.alpha.value
4247
4252
  };
4248
4253
  }
4249
4254
  /**
@@ -4256,7 +4261,7 @@ function getRgbaColor(value) {
4256
4261
  * @returns _RGB_ color
4257
4262
  */
4258
4263
  function getRgbColor(value) {
4259
- return getColorState(value).rgb;
4264
+ return getColorFromState(getColorState(value), COLOR_TYPE.rgb);
4260
4265
  }
4261
4266
  //#endregion
4262
4267
  //#region src/color/misc/is.ts
@@ -4264,10 +4269,10 @@ function hasKeys(value, keys) {
4264
4269
  return typeof value === "object" && value !== null && keys.every((key) => key in value);
4265
4270
  }
4266
4271
  function isAlpha(value) {
4267
- return typeof value === "number" && between(value, 0, 100);
4272
+ return typeof value === "number" && between(value, COLOR_ALPHA.noneValue, COLOR_MAX.percent);
4268
4273
  }
4269
4274
  function isBytey(value) {
4270
- return typeof value === "number" && between(value, 0, 255);
4275
+ return typeof value === "number" && between(value, 0, COLOR_MAX.hex);
4271
4276
  }
4272
4277
  /**
4273
4278
  * Is the value a _Color_?
@@ -4276,7 +4281,7 @@ function isBytey(value) {
4276
4281
  * @returns `true` if the value is a _Color_, otherwise `false`
4277
4282
  */
4278
4283
  function isColor(value) {
4279
- return typeof value === "object" && value !== null && "$color" in value && value.$color === true;
4284
+ return isPlainObject(value) && COLOR_PROPERTY.name in value && value[COLOR_PROPERTY.name] === true;
4280
4285
  }
4281
4286
  function isColorValue(obj, properties) {
4282
4287
  if (typeof obj !== "object" || obj === null) return false;
@@ -4290,7 +4295,7 @@ function isColorValue(obj, properties) {
4290
4295
  return true;
4291
4296
  }
4292
4297
  function isDegree(value) {
4293
- return typeof value === "number" && between(value, 0, 360);
4298
+ return typeof value === "number" && between(value, 0, COLOR_MAX.degree);
4294
4299
  }
4295
4300
  /**
4296
4301
  * Is the value a hex color?
@@ -4310,10 +4315,10 @@ function isDegree(value) {
4310
4315
  */
4311
4316
  function isHexColor(value, alpha) {
4312
4317
  if (typeof value !== "string") return false;
4313
- if (!(EXPRESSION_HEX_SHORT.test(value) || EXPRESSION_HEX_LONG.test(value))) return false;
4318
+ if (!(COLOR_EXPRESSION.hexShort.test(value) || COLOR_EXPRESSION.hexLong.test(value))) return false;
4314
4319
  if (alpha === false) {
4315
- const unprefixed = value.replace(EXPRESSION_PREFIX, "");
4316
- return unprefixed.length === 3 || unprefixed.length === 6;
4320
+ const unprefixed = value.replace(COLOR_EXPRESSION.prefix, "");
4321
+ return unprefixed.length === COLOR_LENGTHS.hexShort || unprefixed.length === COLOR_LENGTHS.hexLong;
4317
4322
  }
4318
4323
  return true;
4319
4324
  }
@@ -4324,7 +4329,7 @@ function isHexColor(value, alpha) {
4324
4329
  * @returns `true` if the value is an _HSLA_ color, otherwise `false`
4325
4330
  */
4326
4331
  function isHslaColor(value) {
4327
- return isColorValue(value, KEYS_HSLA);
4332
+ return isColorValue(value, COLOR_KEYS.hsla);
4328
4333
  }
4329
4334
  /**
4330
4335
  * Is the value an _HSL_ color?
@@ -4333,16 +4338,10 @@ function isHslaColor(value) {
4333
4338
  * @returns `true` if the value is an _HSL_ color, otherwise `false`
4334
4339
  */
4335
4340
  function isHslColor(value) {
4336
- return isColorValue(value, KEYS_HSLA) || isColorValue(value, KEYS_HSL);
4341
+ return isColorValue(value, COLOR_KEYS.hsla) || isColorValue(value, COLOR_KEYS.hsl);
4337
4342
  }
4338
- /**
4339
- * Is the value like an _HSL_ color?
4340
- *
4341
- * @param value Value to check
4342
- * @returns `true` if the value is like an _HSL_ color, otherwise `false`
4343
- */
4344
4343
  function isHslLike(value) {
4345
- return hasKeys(value, KEYS_HSL);
4344
+ return hasKeys(value, COLOR_KEYS.hsl);
4346
4345
  }
4347
4346
  /**
4348
4347
  * Is the value an _HWBA_ color?
@@ -4351,16 +4350,7 @@ function isHslLike(value) {
4351
4350
  * @returns `true` if the value is an _HWBA_ color, otherwise `false`
4352
4351
  */
4353
4352
  function isHwbaColor(value) {
4354
- return isColorValue(value, KEYS_HWBA);
4355
- }
4356
- /**
4357
- * Is the value like an _HWBA_ color?
4358
- *
4359
- * @param value Value to check
4360
- * @returns `true` if the value is like an _HWBA_ color, otherwise `false`
4361
- */
4362
- function isHwbaLike(value) {
4363
- return hasKeys(value, KEYS_HWBA);
4353
+ return isColorValue(value, COLOR_KEYS.hwba);
4364
4354
  }
4365
4355
  /**
4366
4356
  * Is the value an _HWB_ color?
@@ -4369,16 +4359,10 @@ function isHwbaLike(value) {
4369
4359
  * @returns `true` if the value is an _HWB_ color, otherwise `false`
4370
4360
  */
4371
4361
  function isHwbColor(value) {
4372
- return isColorValue(value, KEYS_HWB) || isColorValue(value, KEYS_HWBA);
4362
+ return isColorValue(value, COLOR_KEYS.hwb) || isColorValue(value, COLOR_KEYS.hwba);
4373
4363
  }
4374
- /**
4375
- * Is the value like an _HWB_ color?
4376
- *
4377
- * @param value Value to check
4378
- * @returns `true` if the value is like an _HWB_ color, otherwise `false`
4379
- */
4380
4364
  function isHwbLike(value) {
4381
- return hasKeys(value, KEYS_HWB);
4365
+ return hasKeys(value, COLOR_KEYS.hwb);
4382
4366
  }
4383
4367
  /**
4384
4368
  * Is the value an _RGBA_ color?
@@ -4387,7 +4371,7 @@ function isHwbLike(value) {
4387
4371
  * @returns `true` if the value is an _RGBA_ color, otherwise `false`
4388
4372
  */
4389
4373
  function isRgbaColor(value) {
4390
- return isColorValue(value, KEYS_RGBA);
4374
+ return isColorValue(value, COLOR_KEYS.rgba);
4391
4375
  }
4392
4376
  /**
4393
4377
  * Is the value an _RGB_ color?
@@ -4396,19 +4380,13 @@ function isRgbaColor(value) {
4396
4380
  * @returns `true` if the value is an _RGB_ color, otherwise `false`
4397
4381
  */
4398
4382
  function isRgbColor(value) {
4399
- return isColorValue(value, KEYS_RGBA) || isColorValue(value, KEYS_RGB);
4383
+ return isColorValue(value, COLOR_KEYS.rgba) || isColorValue(value, COLOR_KEYS.rgb);
4400
4384
  }
4401
- /**
4402
- * Is the value like an _RGB_ color?
4403
- *
4404
- * @param value Value to check
4405
- * @returns `true` if the value is like an _RGB_ color, otherwise `false`
4406
- */
4407
4385
  function isRgbLike(value) {
4408
- return hasKeys(value, KEYS_RGB);
4386
+ return hasKeys(value, COLOR_KEYS.rgb);
4409
4387
  }
4410
4388
  function isPercentage(value) {
4411
- return typeof value === "number" && between(value, 0, 100);
4389
+ return typeof value === "number" && between(value, 0, COLOR_MAX.percent);
4412
4390
  }
4413
4391
  const validators = {
4414
4392
  alpha: isAlpha,
@@ -4433,11 +4411,11 @@ function convertRgbToHex(rgb, alpha) {
4433
4411
  return hexString.length === 1 ? `0${hexString}` : hexString;
4434
4412
  }))}`;
4435
4413
  let a = "";
4436
- if (typeof alpha === "boolean" && alpha) a = getAlpha(rgb.alpha).hex;
4414
+ if (typeof alpha === "boolean" && alpha) a = getAlpha(rgb.alpha, false).hex;
4437
4415
  return `${hex}${a}`;
4438
4416
  }
4439
4417
  function convertRgbToHsla(value) {
4440
- const values = getRgbValues(isRgbLike(value) ? getRgbValue(value) : { ...DEFAULT_RGB });
4418
+ const values = getRgbValues(isRgbLike(value) ? getRgbValue(value) : { ...COLOR_DEFAULTS.rgb });
4441
4419
  const { delta, max, min } = values;
4442
4420
  const lightness = (min + max) / 2;
4443
4421
  let hue = 0;
@@ -4449,13 +4427,13 @@ function convertRgbToHsla(value) {
4449
4427
  }
4450
4428
  return {
4451
4429
  hue,
4452
- saturation: saturation * 100,
4453
- lightness: lightness * 100,
4454
- alpha: getAlphaValue(value?.alpha ?? 100)
4430
+ saturation: saturation * COLOR_MAX.percent,
4431
+ lightness: lightness * COLOR_MAX.percent,
4432
+ alpha: getAlphaValue(value?.alpha ?? COLOR_MAX.percent)
4455
4433
  };
4456
4434
  }
4457
4435
  function convertRgbToHwba(value) {
4458
- const values = getRgbValues(isRgbLike(value) ? getRgbValue(value) : { ...DEFAULT_RGB });
4436
+ const values = getRgbValues(isRgbLike(value) ? getRgbValue(value) : { ...COLOR_DEFAULTS.rgb });
4459
4437
  const { delta, max, min } = values;
4460
4438
  let hue = 0;
4461
4439
  if (delta !== 0) {
@@ -4464,11 +4442,23 @@ function convertRgbToHwba(value) {
4464
4442
  }
4465
4443
  return {
4466
4444
  hue,
4467
- whiteness: min * 100,
4468
- blackness: (1 - max) * 100,
4469
- alpha: getAlphaValue(value?.alpha ?? 100)
4445
+ whiteness: min * COLOR_MAX.percent,
4446
+ blackness: (1 - max) * COLOR_MAX.percent,
4447
+ alpha: getAlphaValue(value?.alpha ?? COLOR_MAX.percent)
4470
4448
  };
4471
4449
  }
4450
+ function getColorFromRgb(state, type) {
4451
+ switch (type) {
4452
+ case COLOR_TYPE.hex:
4453
+ state.hex = rgbToHex(state.rgb);
4454
+ break;
4455
+ case COLOR_TYPE.hsl:
4456
+ state.hsl = rgbToHsl(state.rgb);
4457
+ break;
4458
+ case COLOR_TYPE.hwb: state.hwb = rgbToHwb(state.rgb);
4459
+ }
4460
+ return state[type];
4461
+ }
4472
4462
  function getRgbHue(values) {
4473
4463
  const { blue, delta, green, max, red } = values;
4474
4464
  switch (max) {
@@ -4485,9 +4475,9 @@ function getRgbValue(value) {
4485
4475
  };
4486
4476
  }
4487
4477
  function getRgbValues(rgb) {
4488
- const blue = rgb.blue / 255;
4489
- const green = rgb.green / 255;
4490
- const red = rgb.red / 255;
4478
+ const blue = rgb.blue / COLOR_MAX.hex;
4479
+ const green = rgb.green / COLOR_MAX.hex;
4480
+ const red = rgb.red / COLOR_MAX.hex;
4491
4481
  const max = Math.max(blue, green, red);
4492
4482
  const min = Math.min(blue, green, red);
4493
4483
  return {
@@ -4509,7 +4499,7 @@ function getRgbValues(rgb) {
4509
4499
  * @returns Hex color string
4510
4500
  */
4511
4501
  function rgbToHex(rgb, alpha) {
4512
- return convertRgbToHex(isRgbLike(rgb) ? getRgbValue(rgb) : { ...DEFAULT_RGB }, alpha ?? false);
4502
+ return convertRgbToHex(isRgbLike(rgb) ? getRgbValue(rgb) : { ...COLOR_DEFAULTS.rgb }, alpha ?? false);
4513
4503
  }
4514
4504
  /**
4515
4505
  * Convert an _RGB(A)_ color to an _HSL_ color
@@ -4577,17 +4567,29 @@ function rgbToHwba(rgb) {
4577
4567
  //#region src/color/space/hex.ts
4578
4568
  function convertHexToRgba(value) {
4579
4569
  const normalized = getNormalizedHex(value, true);
4580
- const pairs = EXPRESSION_HEX_LONG.exec(normalized);
4570
+ const pairs = COLOR_EXPRESSION.hexLong.exec(normalized);
4581
4571
  const values = [];
4582
4572
  const { length } = pairs;
4583
4573
  for (let index = 1; index < length; index += 1) values.push(Number.parseInt(pairs[index], 16));
4584
4574
  return {
4585
- alpha: getPercentage(values[3] / 255 * 100),
4575
+ alpha: getPercentage(values[3] / COLOR_MAX.hex * 100),
4586
4576
  blue: getHexValue(values[2]),
4587
4577
  green: getHexValue(values[1]),
4588
4578
  red: getHexValue(values[0])
4589
4579
  };
4590
4580
  }
4581
+ function getColorFromHex(state, type) {
4582
+ switch (type) {
4583
+ case COLOR_TYPE.hsl:
4584
+ state.hsl ??= hexToHsl(state.hex);
4585
+ break;
4586
+ case COLOR_TYPE.hwb:
4587
+ state.hwb ??= hexToHwb(state.hex);
4588
+ break;
4589
+ case COLOR_TYPE.rgb: state.rgb ??= hexToRgb(state.hex);
4590
+ }
4591
+ return state[type];
4592
+ }
4591
4593
  /**
4592
4594
  * Get the normalized hex color from a value
4593
4595
  *
@@ -4599,10 +4601,10 @@ function convertHexToRgba(value) {
4599
4601
  */
4600
4602
  function getNormalizedHex(value, alpha) {
4601
4603
  const includeAlpha = alpha ?? false;
4602
- if (!isHexColor(value)) return `${HEX_BLACK}${includeAlpha ? ALPHA_FULL_HEX_LONG : ""}`;
4603
- const normalized = value.replace(EXPRESSION_PREFIX, "");
4604
- if (normalized.length < 6) return join(`${normalized.slice(0, 3)}${includeAlpha ? normalized[3] ?? "f" : ""}`.split("").map((character) => character.repeat(2)));
4605
- return `${normalized.slice(0, 6)}${includeAlpha ? normalized.slice(6) || ALPHA_FULL_HEX_LONG : ""}`;
4604
+ if (!isHexColor(value)) return `${COLOR_DEFAULTS.hexBlack}${includeAlpha ? COLOR_ALPHA.fullHexLong : ""}`;
4605
+ const normalized = value.replace(COLOR_EXPRESSION.prefix, "");
4606
+ if (normalized.length < COLOR_LENGTHS.hexLong) return join(`${normalized.slice(0, COLOR_LENGTHS.hexShort)}${includeAlpha ? normalized[COLOR_LENGTHS.hexShort] ?? COLOR_ALPHA.fullHexShort : ""}`.split("").map((character) => character.repeat(2)));
4607
+ return `${normalized.slice(0, COLOR_LENGTHS.hexLong)}${includeAlpha ? normalized.slice(COLOR_LENGTHS.hexLong) || COLOR_ALPHA.fullHexLong : ""}`;
4606
4608
  }
4607
4609
  /**
4608
4610
  * Convert a hex color string to a _HSL_ color
@@ -4688,35 +4690,47 @@ function hexToRgba(value) {
4688
4690
  //#endregion
4689
4691
  //#region src/color/space/hsl.ts
4690
4692
  function convertHslToHwba(input) {
4691
- let { hue, lightness, saturation } = isHslLike(input) ? getHslValue(input) : { ...DEFAULT_HSL };
4692
- lightness /= 100;
4693
- saturation /= 100;
4693
+ let { hue, lightness, saturation } = isHslLike(input) ? getHslValue(input) : { ...COLOR_DEFAULTS.hsl };
4694
+ lightness /= COLOR_MAX.percent;
4695
+ saturation /= COLOR_MAX.percent;
4694
4696
  const value = lightness + saturation * Math.min(lightness, 1 - lightness);
4695
4697
  if (value === 0) saturation = 0;
4696
4698
  else saturation = 2 * (1 - lightness / value);
4697
4699
  const blackness = 1 - value;
4698
4700
  return {
4699
4701
  hue,
4700
- whiteness: (1 - saturation) * value * 100,
4701
- blackness: blackness * 100,
4702
- alpha: getAlphaValue(input?.alpha ?? 100)
4702
+ whiteness: (1 - saturation) * value * COLOR_MAX.percent,
4703
+ blackness: blackness * COLOR_MAX.percent,
4704
+ alpha: getAlphaValue(input?.alpha ?? COLOR_MAX.percent)
4703
4705
  };
4704
4706
  }
4705
4707
  function convertHslToRgba(input) {
4706
- const hsl = isHslLike(input) ? getHslValue(input) : { ...DEFAULT_HSL };
4707
- const hue = hsl.hue % 360;
4708
- const saturation = hsl.saturation / 100;
4709
- const lightness = hsl.lightness / 100;
4708
+ const hsl = isHslLike(input) ? getHslValue(input) : { ...COLOR_DEFAULTS.hsl };
4709
+ const hue = hsl.hue % COLOR_MAX.degree;
4710
+ const saturation = hsl.saturation / COLOR_MAX.percent;
4711
+ const lightness = hsl.lightness / COLOR_MAX.percent;
4710
4712
  return {
4711
- alpha: getAlphaValue(input?.alpha ?? 100),
4713
+ alpha: getAlphaValue(input?.alpha ?? COLOR_MAX.percent),
4712
4714
  blue: getHexValue(getHexyValue(hue, lightness, saturation, 4)),
4713
4715
  green: getHexValue(getHexyValue(hue, lightness, saturation, 8)),
4714
4716
  red: getHexValue(getHexyValue(hue, lightness, saturation, 0))
4715
4717
  };
4716
4718
  }
4719
+ function getColorFromHsl(state, type) {
4720
+ switch (type) {
4721
+ case COLOR_TYPE.hex:
4722
+ state.hex = hslToHex(state.hsl);
4723
+ break;
4724
+ case COLOR_TYPE.hwb:
4725
+ state.hwb = hslToHwb(state.hsl);
4726
+ break;
4727
+ case COLOR_TYPE.rgb: state.rgb = hslToRgb(state.hsl);
4728
+ }
4729
+ return state[type];
4730
+ }
4717
4731
  function getHexyValue(hue, lightness, saturation, value) {
4718
4732
  const part = (value + hue / 30) % 12;
4719
- return (lightness - saturation * Math.min(lightness, 1 - lightness) * Math.max(-1, Math.min(part - 3, 9 - part, 1))) * 255;
4733
+ return (lightness - saturation * Math.min(lightness, 1 - lightness) * Math.max(-1, Math.min(part - 3, 9 - part, 1))) * COLOR_MAX.hex;
4720
4734
  }
4721
4735
  function getHslValue(value) {
4722
4736
  return {
@@ -4798,9 +4812,9 @@ function hslToRgba(hsl) {
4798
4812
  //#endregion
4799
4813
  //#region src/color/space/hwb.ts
4800
4814
  function convertHwbToHsl(input) {
4801
- let { blackness, hue, whiteness } = isHwbLike(input) ? getHwbValue(input) : DEFAULT_HWB;
4802
- blackness /= 100;
4803
- whiteness /= 100;
4815
+ let { blackness, hue, whiteness } = isHwbLike(input) ? getHwbValue(input) : COLOR_DEFAULTS.hwb;
4816
+ blackness /= COLOR_MAX.percent;
4817
+ whiteness /= COLOR_MAX.percent;
4804
4818
  if (blackness + whiteness > 1) {
4805
4819
  const total = blackness + whiteness;
4806
4820
  blackness /= total;
@@ -4809,11 +4823,23 @@ function convertHwbToHsl(input) {
4809
4823
  const lightness = (1 - blackness + whiteness) / 2;
4810
4824
  return {
4811
4825
  hue,
4812
- saturation: getHwbSaturation(blackness, whiteness, lightness) * 100,
4813
- lightness: lightness * 100,
4814
- alpha: getAlphaValue(input?.alpha ?? 100)
4826
+ saturation: getHwbSaturation(blackness, whiteness, lightness) * COLOR_MAX.percent,
4827
+ lightness: lightness * COLOR_MAX.percent,
4828
+ alpha: getAlphaValue(input?.alpha ?? COLOR_MAX.percent)
4815
4829
  };
4816
4830
  }
4831
+ function getColorFromHwb(state, type) {
4832
+ switch (type) {
4833
+ case COLOR_TYPE.hex:
4834
+ state.hex = hwbToHex(state.hwb);
4835
+ break;
4836
+ case COLOR_TYPE.hsl:
4837
+ state.hsl = hwbToHsl(state.hwb);
4838
+ break;
4839
+ case COLOR_TYPE.rgb: state.rgb = hwbToRgb(state.hwb);
4840
+ }
4841
+ return state[type];
4842
+ }
4817
4843
  function getHwbSaturation(blackness, whiteness, lightness) {
4818
4844
  const hue = 1 - blackness - whiteness;
4819
4845
  if (hue <= 0) return 0;
@@ -4889,170 +4915,201 @@ function hwbToRgba(hwb) {
4889
4915
  }
4890
4916
  //#endregion
4891
4917
  //#region src/color/misc/state.ts
4918
+ function getColorFromState(state, type) {
4919
+ const { origin } = state;
4920
+ if (type === origin) return state[origin];
4921
+ return state[type] ?? getters[origin](state, type);
4922
+ }
4892
4923
  function getColorState(value) {
4893
4924
  if (typeof value === "string") return getColorStateForHex(value);
4894
- if (isColor(value)) return {
4895
- hex: value.hex,
4896
- hsl: value.hsl,
4897
- hwb: value.hwb,
4898
- rgb: value.rgb,
4899
- alpha: getAlpha(value.alpha)
4900
- };
4901
- const state = {};
4925
+ if (isColor(value)) {
4926
+ const { origin } = value;
4927
+ return {
4928
+ origin,
4929
+ [origin]: value[origin],
4930
+ alpha: getAlpha(value.alpha, false)
4931
+ };
4932
+ }
4902
4933
  if (typeof value === "object" && value !== null) {
4903
- state.alpha = getAlpha(value.alpha);
4904
- if (KEYS_HSL.every((key) => key in value)) return getColorStateForHsl(state, value);
4905
- if (KEYS_HWB.every((key) => key in value)) return getColorStateForHwb(state, value);
4906
- if (KEYS_RGB.every((key) => key in value)) return getColorStateForRgb(state, value);
4934
+ const state = {
4935
+ alpha: getAlpha(value.alpha, false),
4936
+ origin: void 0
4937
+ };
4938
+ if (COLOR_KEYS.hsl.every((key) => key in value)) {
4939
+ state.hsl = getHslValue(value);
4940
+ state.origin = COLOR_TYPE.hsl;
4941
+ } else if (COLOR_KEYS.hwb.every((key) => key in value)) {
4942
+ state.hwb = getHwbValue(value);
4943
+ state.origin = COLOR_TYPE.hwb;
4944
+ } else if (COLOR_KEYS.rgb.every((key) => key in value)) {
4945
+ state.rgb = getRgbValue(value);
4946
+ state.origin = COLOR_TYPE.rgb;
4947
+ }
4948
+ if (state.origin != null) return state;
4907
4949
  }
4908
- return getDefaultColorState(state);
4950
+ return getDefaultColorState();
4909
4951
  }
4910
4952
  function getColorStateForHex(value) {
4911
4953
  const normalized = getNormalizedHex(value, true);
4912
- const hex = normalized.slice(0, 6);
4913
- const hsl = hexToHsl(hex);
4914
4954
  return {
4915
- hex,
4916
- hsl,
4917
- alpha: getAlpha(normalized.slice(6)),
4918
- hwb: hslToHwb(hsl),
4919
- rgb: hslToRgb(hsl)
4955
+ hex: normalized.slice(0, COLOR_LENGTHS.hexLong),
4956
+ alpha: getAlpha(normalized.slice(COLOR_LENGTHS.hexLong), true),
4957
+ origin: COLOR_TYPE.hex
4920
4958
  };
4921
4959
  }
4922
- function getColorStateForHsl(state, value) {
4923
- state.hsl = getHslValue(value);
4924
- state.rgb = hslToRgb(state.hsl);
4925
- state.hex = hslToHex(state.hsl);
4926
- state.hwb = hslToHwb(state.hsl);
4927
- return state;
4928
- }
4929
- function getColorStateForHwb(state, value) {
4930
- state.hwb = getHwbValue(value);
4931
- state.hsl = hwbToHsl(state.hwb);
4932
- state.rgb = hwbToRgb(state.hwb);
4933
- state.hex = hwbToHex(state.hwb);
4934
- return state;
4935
- }
4936
- function getColorStateForRgb(state, value) {
4937
- state.rgb = getRgbValue(value);
4938
- state.hex = rgbToHex(state.rgb);
4939
- state.hsl = rgbToHsl(state.rgb);
4940
- state.hwb = rgbToHwb(state.rgb);
4941
- return state;
4942
- }
4943
- function getDefaultColorState(state) {
4944
- state.alpha = getAlpha(100);
4945
- state.hex = HEX_BLACK;
4946
- state.hsl = { ...DEFAULT_HSL };
4947
- state.hwb = { ...DEFAULT_HWB };
4948
- state.rgb = { ...DEFAULT_RGB };
4949
- return state;
4950
- }
4951
- function setHexColor(state, value, alpha) {
4960
+ function getDefaultColorState() {
4961
+ return {
4962
+ alpha: getAlpha(COLOR_MAX.percent, false),
4963
+ hex: COLOR_DEFAULTS.hexBlack,
4964
+ hsl: { ...COLOR_DEFAULTS.hsl },
4965
+ hwb: { ...COLOR_DEFAULTS.hwb },
4966
+ rgb: { ...COLOR_DEFAULTS.rgb },
4967
+ origin: COLOR_TYPE.hex
4968
+ };
4969
+ }
4970
+ function setColorValue(color, state, subscriptions, type, value, alpha) {
4971
+ state.hex = void 0;
4972
+ state.hsl = void 0;
4973
+ state.hwb = void 0;
4974
+ state.rgb = void 0;
4975
+ state.origin = type;
4976
+ state[type] = value;
4977
+ if (alpha != null) state.alpha = getAlpha(alpha, type === COLOR_TYPE.hex);
4978
+ for (const type of COLOR_TYPE.all) {
4979
+ const callbacks = subscriptions.values.to.keyed?.get(type);
4980
+ if (callbacks != null) for (const callback of callbacks.values()) callback(color[type]);
4981
+ }
4982
+ for (const callback of subscriptions.values.to.any.values()) callback(color);
4983
+ }
4984
+ function setHexColor(color, state, subscriptions, value, alpha) {
4952
4985
  if (!isHexColor(value) || !alpha && value === state.hex) return;
4953
4986
  const normalized = getNormalizedHex(value, true);
4954
- const hex = normalized.slice(0, 6);
4955
- const hsl = hexToHsl(hex);
4956
- state.hex = hex;
4957
- state.hsl = hsl;
4958
- state.rgb = hslToRgb(hsl);
4959
- state.hwb = hslToHwb(hsl);
4960
- if (alpha) state.alpha = getAlpha(normalized.slice(6));
4961
- }
4962
- function setHSLColor(state, value, alpha) {
4987
+ setColorValue(color, state, subscriptions, COLOR_TYPE.hex, normalized.slice(0, COLOR_LENGTHS.hexLong), alpha ? normalized.slice(COLOR_LENGTHS.hexLong) : void 0);
4988
+ }
4989
+ function setHSLColor(color, state, subscriptions, value, alpha) {
4963
4990
  if (!isHslLike(value)) return;
4964
- const hsl = {
4991
+ setColorValue(color, state, subscriptions, COLOR_TYPE.hsl, {
4965
4992
  hue: getDegrees(value.hue),
4966
4993
  saturation: getPercentage(value.saturation),
4967
4994
  lightness: getPercentage(value.lightness)
4968
- };
4969
- state.hsl = hsl;
4970
- state.hex = hslToHex(hsl);
4971
- state.hwb = hslToHwb(hsl);
4972
- state.rgb = hslToRgb(hsl);
4973
- if (alpha) state.alpha = getAlpha(value.alpha);
4995
+ }, alpha ? value.alpha : void 0);
4974
4996
  }
4975
- function setHWBColor(state, value, alpha) {
4997
+ function setHWBColor(color, state, subscriptions, value, alpha) {
4976
4998
  if (!isHwbLike(value)) return;
4977
- const hwb = {
4999
+ setColorValue(color, state, subscriptions, COLOR_TYPE.hwb, {
4978
5000
  hue: getDegrees(value.hue),
4979
5001
  whiteness: getPercentage(value.whiteness),
4980
5002
  blackness: getPercentage(value.blackness)
4981
- };
4982
- state.hwb = hwb;
4983
- state.hex = hwbToHex(hwb);
4984
- state.hsl = hwbToHsl(hwb);
4985
- state.rgb = hwbToRgb(hwb);
4986
- if (alpha) state.alpha = getAlpha(value.alpha);
5003
+ }, alpha ? value.alpha : void 0);
4987
5004
  }
4988
- function setRGBColor(state, value, alpha) {
5005
+ function setRGBColor(color, state, subscriptions, value, alpha) {
4989
5006
  if (!isRgbLike(value)) return;
4990
- const rgb = {
4991
- blue: getHexValue(value.blue),
5007
+ setColorValue(color, state, subscriptions, COLOR_TYPE.rgb, {
5008
+ red: getHexValue(value.red),
4992
5009
  green: getHexValue(value.green),
4993
- red: getHexValue(value.red)
4994
- };
4995
- const hsl = rgbToHsl(rgb);
4996
- state.hsl = hsl;
4997
- state.rgb = rgb;
4998
- state.hex = hslToHex(hsl);
4999
- state.hwb = hslToHwb(hsl);
5000
- if (alpha) state.alpha = getAlpha(value.alpha);
5010
+ blue: getHexValue(value.blue)
5011
+ }, alpha ? value.alpha : void 0);
5012
+ }
5013
+ const getters = {
5014
+ hex: getColorFromHex,
5015
+ hsl: getColorFromHsl,
5016
+ hwb: getColorFromHwb,
5017
+ rgb: getColorFromRgb
5018
+ };
5019
+ //#endregion
5020
+ //#region src/color/misc/format.ts
5021
+ function formatHslColor(state, alpha) {
5022
+ const { hue, lightness, saturation } = getColorFromState(state, COLOR_TYPE.hsl);
5023
+ return `hsl(${hue}deg ${saturation}% ${lightness}%${getSuffix(state, alpha)})`;
5024
+ }
5025
+ function formatHwbColor(state, alpha) {
5026
+ const { blackness, hue, whiteness } = getColorFromState(state, COLOR_TYPE.hwb);
5027
+ return `hwb(${hue}deg ${whiteness}% ${blackness}%${getSuffix(state, alpha)})`;
5028
+ }
5029
+ function formatRgbColor(state, alpha) {
5030
+ const { blue, green, red } = getColorFromState(state, COLOR_TYPE.rgb);
5031
+ return `rgb(${red} ${green} ${blue}${getSuffix(state, alpha)})`;
5032
+ }
5033
+ function getSuffix(state, alpha) {
5034
+ return alpha === true ? ` / ${state.alpha.value}%` : "";
5001
5035
  }
5002
5036
  //#endregion
5003
5037
  //#region src/color/instance.ts
5004
5038
  function color(value) {
5005
5039
  const state = getColorState(value);
5040
+ const subscriptions = getSubscriptions(COLOR_TYPE.all);
5006
5041
  const instance = {
5042
+ subscribe: (first, second) => subscribeToColor(subscriptions, first, second),
5007
5043
  toHexString: (alpha) => `#${alpha === true ? instance.hexa : instance.hex}`,
5008
- toHslString: (alpha) => formatHslColor(state, alpha === true),
5009
- toHwbString: (alpha) => formatHwbColor(state, alpha === true),
5010
- toRgbString: (alpha) => formatRgbColor(state, alpha === true),
5011
- toString: () => instance.toHexString()
5044
+ toHslString: (alpha) => formatHslColor(state, alpha),
5045
+ toHwbString: (alpha) => formatHwbColor(state, alpha),
5046
+ toRgbString: (alpha) => formatRgbColor(state, alpha),
5047
+ toString: () => instance.toHexString(),
5048
+ unsubscribe: () => clearSubscriptions(subscriptions)
5012
5049
  };
5013
5050
  Object.defineProperties(instance, {
5014
- $color: {
5051
+ [COLOR_PROPERTY.name]: {
5015
5052
  enumerable: false,
5016
- get: () => true
5053
+ value: true
5017
5054
  },
5018
5055
  alpha: {
5019
5056
  enumerable: true,
5020
5057
  get: () => state.alpha.value,
5021
- set: (value) => {
5022
- if (typeof value === "number" && !Number.isNaN(value)) state.alpha = getAlpha(value);
5023
- }
5058
+ set: (value) => setAlphaValue(state, value)
5059
+ },
5060
+ hex: getProperty(COLOR_TYPE.hex, instance, state, subscriptions, false),
5061
+ hexa: getProperty(COLOR_TYPE.hex, instance, state, subscriptions, true),
5062
+ hsl: getProperty(COLOR_TYPE.hsl, instance, state, subscriptions, false),
5063
+ hsla: getProperty(COLOR_TYPE.hsl, instance, state, subscriptions, true),
5064
+ hwb: getProperty(COLOR_TYPE.hwb, instance, state, subscriptions, false),
5065
+ hwba: getProperty(COLOR_TYPE.hwb, instance, state, subscriptions, true),
5066
+ origin: {
5067
+ enumerable: true,
5068
+ get: () => state.origin
5024
5069
  },
5025
- hex: getProperty("hex", state, false),
5026
- hexa: getProperty("hex", state, true),
5027
- hsl: getProperty("hsl", state, false),
5028
- hsla: getProperty("hsl", state, true),
5029
- hwb: getProperty("hwb", state, false),
5030
- hwba: getProperty("hwb", state, true),
5031
- rgb: getProperty("rgb", state, false),
5032
- rgba: getProperty("rgb", state, true)
5070
+ rgb: getProperty(COLOR_TYPE.rgb, instance, state, subscriptions, false),
5071
+ rgba: getProperty(COLOR_TYPE.rgb, instance, state, subscriptions, true)
5033
5072
  });
5034
5073
  return Object.freeze(instance);
5035
5074
  }
5036
- function getHex(state, alpha) {
5037
- return alpha ? `${state.hex}${state.alpha.hex}` : state.hex;
5038
- }
5039
- function getProperty(space, state, alpha) {
5040
- const setter = setters[space];
5075
+ function getProperty(space, color, state, subscriptions, alpha) {
5076
+ const setValue = setters[space];
5041
5077
  return {
5042
5078
  enumerable: true,
5043
- get: () => {
5044
- const value = state[space];
5045
- if (typeof value === "string") return getHex(state, alpha);
5046
- return alpha ? {
5047
- ...value,
5048
- alpha: state.alpha.value
5049
- } : { ...value };
5050
- },
5051
- set: (value) => {
5052
- setter(state, value, alpha);
5053
- }
5079
+ get: () => getValue$1(space, state, alpha),
5080
+ set: (value) => setValue(color, state, subscriptions, value, alpha)
5054
5081
  };
5055
5082
  }
5083
+ function getValue$1(space, state, alpha) {
5084
+ const value = getColorFromState(state, space);
5085
+ if (typeof value === "string") return alpha ? `${value}${state.alpha.hex}` : value;
5086
+ return alpha ? {
5087
+ ...value,
5088
+ alpha: state.alpha.value
5089
+ } : { ...value };
5090
+ }
5091
+ function setAlphaValue(state, value) {
5092
+ if (typeof value === "number" && !Number.isNaN(value)) state.alpha = getAlpha(value, false);
5093
+ }
5094
+ function subscribeToColor(subscriptions, first, second) {
5095
+ let key;
5096
+ let value;
5097
+ if (typeof first === "string") {
5098
+ key = first;
5099
+ value = second;
5100
+ } else if (typeof first === "function") value = first;
5101
+ if (typeof value !== "function") throw new Error();
5102
+ return getSubscription({
5103
+ key,
5104
+ subscriptions,
5105
+ value,
5106
+ property: colorSubscription
5107
+ });
5108
+ }
5109
+ const colorSubscription = {
5110
+ key: COLOR_PROPERTY.name,
5111
+ value: COLOR_PROPERTY.subscription
5112
+ };
5056
5113
  const setters = {
5057
5114
  hex: setHexColor,
5058
5115
  hsl: setHSLColor,
@@ -5074,6 +5131,125 @@ function getColor(value) {
5074
5131
  return isColor(value) ? value : color(value);
5075
5132
  }
5076
5133
  //#endregion
5134
+ //#region src/is.ts
5135
+ /**
5136
+ * Is the value empty, or only containing `null` or `undefined` values?
5137
+ *
5138
+ * @param value Value to check
5139
+ * @returns `true` if the value is considered empty, otherwise `false`
5140
+ */
5141
+ function isEmpty(value) {
5142
+ if (value == null) return true;
5143
+ if (typeof value === "string") return value.length === 0;
5144
+ const values = getArray(value);
5145
+ const { length } = values;
5146
+ for (let index = 0; index < length; index += 1) {
5147
+ const item = values[index];
5148
+ if (Array.isArray(item) ? item[1] != null : item != null) return false;
5149
+ }
5150
+ return true;
5151
+ }
5152
+ /**
5153
+ * Is the value not empty, or holding non-empty values?
5154
+ *
5155
+ * @param value Value to check
5156
+ * @returns `true` if the value is not considered empty, otherwise `false`
5157
+ */
5158
+ function isNonEmpty(value) {
5159
+ return !isEmpty(value);
5160
+ }
5161
+ /**
5162
+ * Is the value not `undefined` or `null`?
5163
+ *
5164
+ * @param value Value to check
5165
+ * @returns `true` if the value is not `undefined` or `null`, otherwise `false`
5166
+ */
5167
+ function isNonNullable(value) {
5168
+ return value != null;
5169
+ }
5170
+ /**
5171
+ * Is the value not `undefined`, `null`, or stringified as an empty _(no whitespace)_ string?
5172
+ *
5173
+ * @param value Value to check
5174
+ * @returns `true` if the value is not `undefined`, `null`, or matches an empty string, otherwise `false`
5175
+ */
5176
+ function isNonNullableOrEmpty(value) {
5177
+ return value != null && getString(value) !== "";
5178
+ }
5179
+ /**
5180
+ * Is the value not `undefined`, `null`, or stringified as a whitespace-only string?
5181
+ *
5182
+ * @param value Value to check
5183
+ * @returns `true` if the value is not `undefined`, `null`, or matches a whitespace-only string, otherwise `false`
5184
+ */
5185
+ function isNonNullableOrWhitespace(value) {
5186
+ return value != null && !EXPRESSION_WHITESPACE.test(getString(value));
5187
+ }
5188
+ /**
5189
+ * Is the value not a number or a number-like string?
5190
+ *
5191
+ * @param value Value to check
5192
+ * @returns `true` if the value is not a number or a number-like string, otherwise `false`
5193
+ */
5194
+ function isNonNumerical(value) {
5195
+ return !isNumerical(value);
5196
+ }
5197
+ /**
5198
+ * Is the value not an object _(or function)_?
5199
+ *
5200
+ * @param value Value to check
5201
+ * @returns `true` if the value is not an object, otherwise `false`
5202
+ */
5203
+ function isNonObject(value) {
5204
+ return !isObject(value);
5205
+ }
5206
+ /**
5207
+ * Is the value `undefined` or `null`?
5208
+ *
5209
+ * @param value Value to check
5210
+ * @returns `true` if the value is `undefined` or `null`, otherwise `false`
5211
+ */
5212
+ function isNullable(value) {
5213
+ return value == null;
5214
+ }
5215
+ /**
5216
+ * Is the value `undefined`, `null`, or stringified as an empty _(no whitespace)_ string?
5217
+ *
5218
+ * @param value Value to check
5219
+ * @returns `true` if the value is nullable or matches an empty string, otherwise `false`
5220
+ */
5221
+ function isNullableOrEmpty(value) {
5222
+ return value == null || getString(value) === "";
5223
+ }
5224
+ /**
5225
+ * Is the value `undefined`, `null`, or stringified as a whitespace-only string?
5226
+ *
5227
+ * @param value Value to check
5228
+ * @returns `true` if the value is nullable or matches a whitespace-only string, otherwise `false`
5229
+ */
5230
+ function isNullableOrWhitespace(value) {
5231
+ return value == null || EXPRESSION_WHITESPACE.test(getString(value));
5232
+ }
5233
+ /**
5234
+ * Is the value a number or a number-like string?
5235
+ *
5236
+ * @param value Value to check
5237
+ * @returns `true` if the value is a number or a number-like string, otherwise `false`
5238
+ */
5239
+ function isNumerical(value) {
5240
+ return isNumber(value) || typeof value === "string" && value.trim().length > 0 && !Number.isNaN(+value);
5241
+ }
5242
+ /**
5243
+ * Is the value an object _(or function)_?
5244
+ *
5245
+ * @param value Value to check
5246
+ * @returns `true` if the value matches, otherwise `false`
5247
+ */
5248
+ function isObject(value) {
5249
+ return typeof value === "object" && value !== null || typeof value === "function";
5250
+ }
5251
+ const EXPRESSION_WHITESPACE = /^\s*$/;
5252
+ //#endregion
5077
5253
  //#region src/logger.ts
5078
5254
  function isLogger(value) {
5079
5255
  return isLoggerInstance(NAME_LOGGER, value);
@@ -6114,4 +6290,4 @@ var SizedSet = class extends Set {
6114
6290
  }
6115
6291
  };
6116
6292
  //#endregion
6117
- export { CancelablePromise, Logger, PROMISE_ABORT_EVENT, PROMISE_ABORT_OPTIONS, PROMISE_ERROR_NAME, PROMISE_MESSAGE_EXPECTATION_ATTEMPT, PROMISE_MESSAGE_EXPECTATION_RESULT, PROMISE_MESSAGE_EXPECTATION_TIMED, PROMISE_MESSAGE_TIMEOUT, PROMISE_STRATEGY_ALL, PROMISE_STRATEGY_DEFAULT, PROMISE_TYPE_FULFILLED, PROMISE_TYPE_REJECTED, PromiseTimeoutError, QueueError, RetryError, SORT_DIRECTION_ASCENDING, SORT_DIRECTION_DESCENDING, SizedMap, SizedSet, assert, assertCondition, assertDefined, assertInstanceOf, assertIs, assertProperty, assign, asyncAttempt, asyncDebounce, asyncFlow, asyncMatchResult, asyncOnce, asyncPipe, asyncThrottle, attempt, attemptAsyncFlow, attemptAsyncPipe, attemptFlow, attemptPipe, attemptPromise, average, beacon, between, camelCase, cancelable, capitalize, ceil, chunk, clamp, clone, compact, compare, copy, count, debounce, deburr, dedent, delay, deregisterCloner, deregisterComparator, deregisterEqualizer, diff, difference, drop, endsWith, endsWithArray, equal, error, exclude, exists, filter, find, findLast, first, firstOrDefault, flatFreeze, flatten, floor, flow, freeze, fromQuery, toPromise as fromResult, toPromise, fuzzy, fuzzyMatch, getArray, getArrayComparison, getColor, getError, getForegroundColor, getHexColor, getHexaColor, getHslColor, getHslaColor, getHwbColor, getHwbaColor, getNormalizedHex, getNumber, getRandomBoolean, getRandomCharacters, getRandomColor, getRandomFloatingNumber as getRandomFloat, getRandomHex, getRandomInteger, getRandomItem, getRandomItems, getRgbColor, getRgbaColor, getSortedIndex, getString, getTimedPromise, getUuid, getValue, groupArraysBy, groupBy, handleResult, hasValue, hasValueResult, herald, hexToHsl, hexToHsla, hexToHwb, hexToHwba, hexToRgb, hexToRgba, hslToHex, hslToHwb, hslToHwba, hslToRgb, hslToRgba, hwbToHex, hwbToHsl, hwbToHsla, hwbToRgb, hwbToRgba, ignoreKey, inMap, inSet, includes, includesArray, indexOf, indexOfArray, initializeAssigner, initializeEqualizer, initializeMerger, initializeNormalizer, initializeSorter, initializeTemplater, initializeTransformer, insert, interpolate, intersection, isArrayOrPlainObject, isBeacon, isColor, isConstructor, isEmpty, isError, isEvents, isFrozen, isFulfilled, isHerald, isHexColor, isHslColor, isHslLike, isHslaColor, isHwbColor, isHwbLike, isHwbaColor, isHwbaLike, isInstanceOf, isKey, isKeyedQueue, isLogger, isNonArrayOrPlainObject, isNonConstructor, isNonEmpty, isNonInstanceOf, isNonKey, isNonNullable, isNonNullableOrEmpty, isNonNullableOrWhitespace, isNonNumber, isNonNumerical, isNonObject, isNonPlainObject, isNonPrimitive, isNonTypedArray, isNullable, isNullableOrEmpty, isNullableOrWhitespace, isNumber, isNumerical, isObject, isObservable, isOk, isPlainObject, isPrimitive, isQueue, isQueueInstance, isRejected, isResult, isRgbColor, isRgbLike, isRgbaColor, isSorted, isSubscription, isTimedLogger, isTypedArray, join, kebabCase, keyedQueue, last, lastIndexOf, lastOrDefault, lowerCase, matchResult, max, median, memoize, merge, min, move, moveIndices, moveToIndex, noop, normalize, ok, omit, once, parse, partition, pascalCase, pick, pipe, promises, push, queue, range, registerCloner, registerComparator, registerEqualizer, resultPromises, retry, reverse, rgbToHex, rgbToHsl, rgbToHsla, rgbToHwb, rgbToHwba, round, select, setValue, settlePromise, shake, shuffle, single, slice, smush, snakeCase, sort, splice, startsWith, startsWithArray, sum, swap, take, template, throttle, timed, times, titleCase, toMap, toMapArrays, toQuery, toRecord, toRecordArrays, toResult, toSet, toggle, transform, trim, truncate, tryDecode, tryEncode, union, unique, unsmush, unwrap, update, upperCase, words };
6293
+ export { CancelablePromise, Logger, PROMISE_ABORT_EVENT, PROMISE_ABORT_OPTIONS, PROMISE_ERROR_NAME, PROMISE_MESSAGE_EXPECTATION_ATTEMPT, PROMISE_MESSAGE_EXPECTATION_RESULT, PROMISE_MESSAGE_EXPECTATION_TIMED, PROMISE_MESSAGE_TIMEOUT, PROMISE_STRATEGY_ALL, PROMISE_STRATEGY_DEFAULT, PROMISE_TYPE_FULFILLED, PROMISE_TYPE_REJECTED, PromiseTimeoutError, QueueError, RetryError, SORT_DIRECTION_ASCENDING, SORT_DIRECTION_DESCENDING, SizedMap, SizedSet, assert, assertCondition, assertDefined, assertInstanceOf, assertIs, assertProperty, assign, asyncAttempt, asyncDebounce, asyncFlow, asyncMatchResult, asyncOnce, asyncPipe, asyncThrottle, attempt, attemptAsyncFlow, attemptAsyncPipe, attemptFlow, attemptPipe, attemptPromise, average, beacon, between, camelCase, cancelable, capitalize, ceil, chunk, clamp, clone, compact, compare, copy, count, debounce, deburr, dedent, delay, deregisterCloner, deregisterComparator, deregisterEqualizer, diff, difference, drop, endsWith, endsWithArray, equal, error, exclude, exists, filter, find, findLast, first, firstOrDefault, flatFreeze, flatten, floor, flow, freeze, fromQuery, toPromise as fromResult, toPromise, fuzzy, fuzzyMatch, getArray, getArrayComparison, getColor, getError, getForegroundColor, getHexColor, getHexaColor, getHslColor, getHslaColor, getHwbColor, getHwbaColor, getNormalizedHex, getNumber, getRandomBoolean, getRandomCharacters, getRandomColor, getRandomFloatingNumber as getRandomFloat, getRandomHex, getRandomInteger, getRandomItem, getRandomItems, getRgbColor, getRgbaColor, getSortedIndex, getString, getTimedPromise, getUuid, getValue, groupArraysBy, groupBy, handleResult, hasValue, hasValueResult, herald, hexToHsl, hexToHsla, hexToHwb, hexToHwba, hexToRgb, hexToRgba, hslToHex, hslToHwb, hslToHwba, hslToRgb, hslToRgba, hwbToHex, hwbToHsl, hwbToHsla, hwbToRgb, hwbToRgba, ignoreKey, inMap, inSet, includes, includesArray, indexOf, indexOfArray, initializeAssigner, initializeEqualizer, initializeMerger, initializeNormalizer, initializeSorter, initializeTemplater, initializeTransformer, insert, interpolate, intersection, isArrayOrPlainObject, isBeacon, isColor, isConstructor, isEmpty, isError, isEvents, isFrozen, isFulfilled, isHerald, isHexColor, isHslColor, isHslaColor, isHwbColor, isHwbaColor, isInstanceOf, isKey, isKeyedQueue, isLogger, isNonArrayOrPlainObject, isNonConstructor, isNonEmpty, isNonInstanceOf, isNonKey, isNonNullable, isNonNullableOrEmpty, isNonNullableOrWhitespace, isNonNumber, isNonNumerical, isNonObject, isNonPlainObject, isNonPrimitive, isNonTypedArray, isNullable, isNullableOrEmpty, isNullableOrWhitespace, isNumber, isNumerical, isObject, isObservable, isOk, isPlainObject, isPrimitive, isQueue, isQueueInstance, isRejected, isResult, isRgbColor, isRgbaColor, isSorted, isSubscription, isTimedLogger, isTypedArray, join, kebabCase, keyedQueue, last, lastIndexOf, lastOrDefault, lowerCase, matchResult, max, median, memoize, merge, min, move, moveIndices, moveToIndex, noop, normalize, ok, omit, once, parse, partition, pascalCase, pick, pipe, promises, push, queue, range, registerCloner, registerComparator, registerEqualizer, resultPromises, retry, reverse, rgbToHex, rgbToHsl, rgbToHsla, rgbToHwb, rgbToHwba, round, select, setValue, settlePromise, shake, shuffle, single, slice, smush, snakeCase, sort, splice, startsWith, startsWithArray, sum, swap, take, template, throttle, timed, times, titleCase, toMap, toMapArrays, toQuery, toRecord, toRecordArrays, toResult, toSet, toggle, transform, trim, truncate, tryDecode, tryEncode, union, unique, unsmush, unwrap, update, upperCase, words };