@oscarpalmer/atoms 0.115.0 → 0.116.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 (87) hide show
  1. package/dist/atoms.full.js +1690 -2973
  2. package/dist/color/index.js +3 -3
  3. package/dist/color/misc/get.js +16 -2
  4. package/dist/color/misc/is.js +10 -1
  5. package/dist/color/misc/state.js +26 -24
  6. package/dist/color/space/hsl.js +19 -14
  7. package/dist/color/space/rgb.js +19 -19
  8. package/dist/function.js +9 -10
  9. package/dist/index.js +5 -4
  10. package/dist/internal/frame-rate.js +22 -0
  11. package/dist/internal/function.js +1 -20
  12. package/dist/value/diff.js +2 -3
  13. package/dist/value/merge.js +5 -5
  14. package/dist/value/smush.js +3 -3
  15. package/package.json +16 -15
  16. package/src/array/find.ts +1 -4
  17. package/src/array/flatten.ts +1 -3
  18. package/src/array/get.ts +1 -3
  19. package/src/array/group-by.ts +8 -21
  20. package/src/array/insert.ts +1 -5
  21. package/src/array/models.ts +3 -17
  22. package/src/array/sort.ts +13 -49
  23. package/src/array/splice.ts +3 -16
  24. package/src/array/to-map.ts +6 -14
  25. package/src/array/to-record.ts +9 -21
  26. package/src/array/to-set.ts +4 -4
  27. package/src/array/unique.ts +1 -3
  28. package/src/color/constants.ts +2 -9
  29. package/src/color/index.ts +3 -17
  30. package/src/color/instance.ts +2 -8
  31. package/src/color/misc/alpha.ts +1 -5
  32. package/src/color/misc/get.ts +21 -5
  33. package/src/color/misc/index.ts +1 -5
  34. package/src/color/misc/is.ts +15 -17
  35. package/src/color/misc/state.ts +33 -50
  36. package/src/color/models.ts +1 -8
  37. package/src/color/space/hex.ts +2 -6
  38. package/src/color/space/hsl.ts +22 -44
  39. package/src/color/space/rgb.ts +20 -39
  40. package/src/emitter.ts +3 -13
  41. package/src/function.ts +14 -30
  42. package/src/index.ts +4 -0
  43. package/src/internal/array/chunk.ts +1 -3
  44. package/src/internal/array/find.ts +7 -28
  45. package/src/internal/array/insert.ts +1 -7
  46. package/src/internal/frame-rate.ts +53 -0
  47. package/src/internal/function.ts +0 -50
  48. package/src/internal/is.ts +1 -3
  49. package/src/internal/math/aggregate.ts +2 -10
  50. package/src/internal/number.ts +3 -14
  51. package/src/internal/random.ts +2 -6
  52. package/src/internal/string.ts +1 -1
  53. package/src/internal/value/compare.ts +2 -8
  54. package/src/internal/value/equal.ts +29 -101
  55. package/src/internal/value/get.ts +9 -19
  56. package/src/internal/value/misc.ts +1 -4
  57. package/src/internal/value/set.ts +10 -9
  58. package/src/is.ts +5 -19
  59. package/src/math.ts +3 -11
  60. package/src/models.ts +93 -15
  61. package/src/query.ts +2 -10
  62. package/src/random.ts +4 -15
  63. package/src/sized.ts +3 -3
  64. package/src/string/case.ts +4 -11
  65. package/src/string/misc.ts +1 -5
  66. package/src/string/template.ts +1 -3
  67. package/src/value/clone.ts +4 -20
  68. package/src/value/diff.ts +4 -12
  69. package/src/value/merge.ts +11 -15
  70. package/src/value/smush.ts +13 -7
  71. package/src/value/unsmush.ts +18 -5
  72. package/types/array/group-by.d.ts +1 -2
  73. package/types/array/to-record.d.ts +1 -2
  74. package/types/color/index.d.ts +3 -3
  75. package/types/color/misc/get.d.ts +3 -0
  76. package/types/color/misc/is.d.ts +2 -0
  77. package/types/color/space/hsl.d.ts +1 -0
  78. package/types/color/space/rgb.d.ts +2 -1
  79. package/types/index.d.ts +2 -0
  80. package/types/internal/frame-rate.d.ts +5 -0
  81. package/types/internal/function.d.ts +0 -4
  82. package/types/internal/value/get.d.ts +3 -3
  83. package/types/internal/value/set.d.ts +3 -3
  84. package/types/is.d.ts +1 -1
  85. package/types/models.d.ts +33 -2
  86. package/types/value/smush.d.ts +3 -4
  87. package/types/value/unsmush.d.ts +9 -2
@@ -1,3307 +1,2024 @@
1
- /**
2
- * Chunk an array into smaller arrays
3
- * @param array Array to chunk
4
- * @param size Size of each chunk _(defaults to 5000)_
5
- * @returns Array of arrays
6
- */
1
+ function calculate() {
2
+ return new Promise((resolve) => {
3
+ const values = [];
4
+ let last;
5
+ function step(now) {
6
+ if (last != null) values.push(now - last);
7
+ last = now;
8
+ if (values.length >= CALCULATION_TOTAL) resolve(values.sort().slice(CALCULATION_TRIM_PART, -CALCULATION_TRIM_PART).reduce((first, second) => first + second, 0) / (values.length - CALCULATION_TRIM_TOTAL));
9
+ else requestAnimationFrame(step);
10
+ }
11
+ requestAnimationFrame(step);
12
+ });
13
+ }
14
+ const CALCULATION_TOTAL = 10;
15
+ const CALCULATION_TRIM_PART = 2;
16
+ const CALCULATION_TRIM_TOTAL = 4;
17
+ let FRAME_RATE_MS = 1e3 / 60;
18
+ calculate().then((value) => {
19
+ FRAME_RATE_MS = value;
20
+ });
21
+ var frame_rate_default = FRAME_RATE_MS;
7
22
  function chunk(array, size) {
8
- if (!Array.isArray(array)) {
9
- return [];
10
- }
11
- if (array.length === 0) {
12
- return [];
13
- }
14
- const { length } = array;
15
- const actualSize = typeof size === 'number' && size > 0 && size <= DEFAULT_SIZE
16
- ? size
17
- : DEFAULT_SIZE;
18
- if (length <= actualSize) {
19
- return [array];
20
- }
21
- const chunks = [];
22
- let index = 0;
23
- while (index < length) {
24
- chunks.push(array.slice(index, index + actualSize));
25
- index += actualSize;
26
- }
27
- return chunks;
28
- }
29
- //
30
- const DEFAULT_SIZE = 5_000;
31
-
23
+ if (!Array.isArray(array)) return [];
24
+ if (array.length === 0) return [];
25
+ const { length } = array;
26
+ const actualSize = typeof size === "number" && size > 0 && size <= DEFAULT_SIZE ? size : DEFAULT_SIZE;
27
+ if (length <= actualSize) return [array];
28
+ const chunks = [];
29
+ let index = 0;
30
+ while (index < length) {
31
+ chunks.push(array.slice(index, index + actualSize));
32
+ index += actualSize;
33
+ }
34
+ return chunks;
35
+ }
36
+ const DEFAULT_SIZE = 5e3;
32
37
  function compact(array, strict) {
33
- if (!Array.isArray(array)) {
34
- return [];
35
- }
36
- const { length } = array;
37
- const isStrict = strict ?? false;
38
- const compacted = [];
39
- for (let index = 0; index < length; index += 1) {
40
- const item = array[index];
41
- if ((isStrict && !!item) || (!isStrict && item != null)) {
42
- compacted.push(item);
43
- }
44
- }
45
- return compacted;
46
- }
47
-
48
- /**
49
- * Is the value an array or a record?
50
- * @param value Value to check
51
- * @returns `true` if the value is an array or a record, otherwise `false`
52
- */
38
+ if (!Array.isArray(array)) return [];
39
+ const { length } = array;
40
+ const isStrict = strict ?? false;
41
+ const compacted = [];
42
+ for (let index = 0; index < length; index += 1) {
43
+ const item = array[index];
44
+ if (isStrict && !!item || !isStrict && item != null) compacted.push(item);
45
+ }
46
+ return compacted;
47
+ }
53
48
  function isArrayOrPlainObject(value) {
54
- return Array.isArray(value) || isPlainObject(value);
49
+ return Array.isArray(value) || isPlainObject(value);
55
50
  }
56
- /**
57
- * Is the value a key?
58
- * @param value Value to check
59
- * @returns `true` if the value is a `Key` _(`number` or `string`)_, otherwise `false`
60
- */
61
51
  function isKey(value) {
62
- return typeof value === 'number' || typeof value === 'string';
52
+ return typeof value === "number" || typeof value === "string";
63
53
  }
64
- /**
65
- * Is the value a number?
66
- * @param value Value to check
67
- * @returns `true` if the value is a `number`, otherwise `false`
68
- */
69
54
  function isNumber(value) {
70
- return typeof value === 'number' && !Number.isNaN(value);
55
+ return typeof value === "number" && !Number.isNaN(value);
71
56
  }
72
- /**
73
- * Is the value a plain object?
74
- * @param value Value to check
75
- * @returns `true` if the value is a plain object, otherwise `false`
76
- */
77
57
  function isPlainObject(value) {
78
- if (value === null || typeof value !== 'object') {
79
- return false;
80
- }
81
- if (Symbol.toStringTag in value || Symbol.iterator in value) {
82
- return false;
83
- }
84
- const prototype = Object.getPrototypeOf(value);
85
- return (prototype === null ||
86
- prototype === Object.prototype ||
87
- Object.getPrototypeOf(prototype) === null);
88
- }
89
- /**
90
- * Is the value a typed array?
91
- * @param value Value to check
92
- * @returns `true` if the value is a typed array, otherwise `false`
93
- */
58
+ if (value === null || typeof value !== "object") return false;
59
+ if (Symbol.toStringTag in value || Symbol.iterator in value) return false;
60
+ const prototype = Object.getPrototypeOf(value);
61
+ return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
62
+ }
94
63
  function isTypedArray(value) {
95
- return TYPED_ARRAYS.has(value?.constructor);
64
+ return TYPED_ARRAYS.has(value?.constructor);
96
65
  }
97
- //
98
66
  const TYPED_ARRAYS = new Set([
99
- Int8Array,
100
- Uint8Array,
101
- Uint8ClampedArray,
102
- Int16Array,
103
- Uint16Array,
104
- Int32Array,
105
- Uint32Array,
106
- Float32Array,
107
- Float64Array,
108
- BigInt64Array,
109
- BigUint64Array,
67
+ Int8Array,
68
+ Uint8Array,
69
+ Uint8ClampedArray,
70
+ Int16Array,
71
+ Uint16Array,
72
+ Int32Array,
73
+ Uint32Array,
74
+ Float32Array,
75
+ Float64Array,
76
+ BigInt64Array,
77
+ BigUint64Array
110
78
  ]);
111
-
112
- /**
113
- * Get a random floating-point number
114
- * @param minimum Minimum value
115
- * @param maximum Maximum value
116
- * @returns Random floating-point number
117
- */
118
79
  function getRandomFloat(minimum, maximum) {
119
- let max = isNumber(maximum) && maximum <= Number.MAX_SAFE_INTEGER
120
- ? maximum
121
- : Number.MAX_SAFE_INTEGER;
122
- let min = isNumber(minimum) && minimum >= Number.MIN_SAFE_INTEGER
123
- ? minimum
124
- : Number.MIN_SAFE_INTEGER;
125
- if (min === max) {
126
- return min;
127
- }
128
- if (min > max) {
129
- [min, max] = [max, min];
130
- }
131
- return Math.random() * (max + 1 - min) + min;
132
- }
133
- /**
134
- * Get a random integer
135
- * @param minimum Minimum value
136
- * @param maximum Maximum value
137
- * @returns Random integer
138
- */
80
+ let max$1 = isNumber(maximum) && maximum <= Number.MAX_SAFE_INTEGER ? maximum : Number.MAX_SAFE_INTEGER;
81
+ let min$1 = isNumber(minimum) && minimum >= Number.MIN_SAFE_INTEGER ? minimum : Number.MIN_SAFE_INTEGER;
82
+ if (min$1 === max$1) return min$1;
83
+ if (min$1 > max$1) [min$1, max$1] = [max$1, min$1];
84
+ return Math.random() * (max$1 + 1 - min$1) + min$1;
85
+ }
139
86
  function getRandomInteger(minimum, maximum) {
140
- return Math.floor(getRandomFloat(minimum, maximum));
141
- }
142
-
143
- /**
144
- * Shuffle items in array
145
- * @param array Original array
146
- * @returns Shuffled array
147
- */
87
+ return Math.floor(getRandomFloat(minimum, maximum));
88
+ }
148
89
  function shuffle(array) {
149
- if (!Array.isArray(array)) {
150
- return [];
151
- }
152
- const shuffled = [...array];
153
- if (shuffled.length < 2) {
154
- return shuffled;
155
- }
156
- let index = Number(shuffled.length);
157
- while (--index >= 0) {
158
- const random = getRandomInteger(0, index);
159
- [shuffled[index], shuffled[random]] = [shuffled[random], shuffled[index]];
160
- }
161
- return shuffled;
162
- }
163
-
90
+ if (!Array.isArray(array)) return [];
91
+ const shuffled = [...array];
92
+ if (shuffled.length < 2) return shuffled;
93
+ let index = Number(shuffled.length);
94
+ while (--index >= 0) {
95
+ const random = getRandomInteger(0, index);
96
+ [shuffled[index], shuffled[random]] = [shuffled[random], shuffled[index]];
97
+ }
98
+ return shuffled;
99
+ }
164
100
  function getCallback$1(value) {
165
- switch (typeof value) {
166
- case 'function':
167
- return value;
168
- case 'number':
169
- case 'string':
170
- return typeof value === 'string' && value.includes('.')
171
- ? undefined
172
- : (obj) => obj[value];
173
- }
101
+ switch (typeof value) {
102
+ case "function": return value;
103
+ case "number":
104
+ case "string": return typeof value === "string" && value.includes(".") ? void 0 : (obj) => obj[value];
105
+ default: break;
106
+ }
174
107
  }
175
108
  function getCallbacks(bool, key, value) {
176
- if (typeof bool === 'function') {
177
- return { bool: bool };
178
- }
179
- return {
180
- keyed: getCallback$1(key),
181
- value: getCallback$1(value),
182
- };
183
- }
184
-
185
- //
109
+ if (typeof bool === "function") return { bool };
110
+ return {
111
+ keyed: getCallback$1(key),
112
+ value: getCallback$1(value)
113
+ };
114
+ }
186
115
  function findValue(type, array, parameters) {
187
- const findIndex = type === 'index';
188
- if (!Array.isArray(array) || array.length === 0) {
189
- return findIndex ? -1 : undefined;
190
- }
191
- const { bool, key, value } = getParameters(parameters);
192
- const callbacks = getCallbacks(bool, key);
193
- if (callbacks?.bool == null && callbacks?.keyed == null) {
194
- return findIndex
195
- ? array.indexOf(value)
196
- : array.find(item => item === value);
197
- }
198
- if (callbacks.bool != null) {
199
- const index = array.findIndex(callbacks.bool);
200
- return findIndex ? index : array[index];
201
- }
202
- return findValueInArray(array, callbacks.keyed, value, findIndex);
116
+ const findIndex = type === "index";
117
+ if (!Array.isArray(array) || array.length === 0) return findIndex ? -1 : void 0;
118
+ const { bool, key, value } = getParameters(parameters);
119
+ const callbacks = getCallbacks(bool, key);
120
+ if (callbacks?.bool == null && callbacks?.keyed == null) return findIndex ? array.indexOf(value) : array.find((item) => item === value);
121
+ if (callbacks.bool != null) {
122
+ const index = array.findIndex(callbacks.bool);
123
+ return findIndex ? index : array[index];
124
+ }
125
+ return findValueInArray(array, callbacks.keyed, value, findIndex);
203
126
  }
204
127
  function findValueInArray(array, callback, value, findIndex) {
205
- const { length } = array;
206
- for (let index = 0; index < length; index += 1) {
207
- const item = array[index];
208
- if (callback?.(item, index, array) === value) {
209
- return findIndex ? index : item;
210
- }
211
- }
212
- return findIndex ? -1 : undefined;
128
+ const { length } = array;
129
+ for (let index = 0; index < length; index += 1) {
130
+ const item = array[index];
131
+ if (callback?.(item, index, array) === value) return findIndex ? index : item;
132
+ }
133
+ return findIndex ? -1 : void 0;
213
134
  }
214
135
  function findValues(type, array, parameters) {
215
- if (!Array.isArray(array)) {
216
- return [];
217
- }
218
- if (array.length === 0) {
219
- return [];
220
- }
221
- const { length } = array;
222
- const { bool, key, value } = getParameters(parameters);
223
- const callbacks = getCallbacks(bool, key);
224
- if (type === 'unique' &&
225
- callbacks?.keyed == null &&
226
- length >= UNIQUE_THRESHOLD) {
227
- return [...new Set(array)];
228
- }
229
- if (callbacks?.bool != null) {
230
- return array.filter(callbacks.bool);
231
- }
232
- if (type === 'all' && key == null) {
233
- return array.filter(item => item === value);
234
- }
235
- const keys = new Set();
236
- const result = [];
237
- for (let index = 0; index < length; index += 1) {
238
- const item = array[index];
239
- const keyed = callbacks?.keyed?.(item, index, array) ?? item;
240
- if ((type === 'all' && Object.is(keyed, value)) ||
241
- (type === 'unique' && !keys.has(keyed))) {
242
- keys.add(keyed);
243
- result.push(item);
244
- }
245
- }
246
- keys.clear();
247
- return result;
136
+ if (!Array.isArray(array)) return [];
137
+ if (array.length === 0) return [];
138
+ const { length } = array;
139
+ const { bool, key, value } = getParameters(parameters);
140
+ const callbacks = getCallbacks(bool, key);
141
+ if (type === "unique" && callbacks?.keyed == null && length >= UNIQUE_THRESHOLD) return [...new Set(array)];
142
+ if (callbacks?.bool != null) return array.filter(callbacks.bool);
143
+ if (type === "all" && key == null) return array.filter((item) => item === value);
144
+ const keys = /* @__PURE__ */ new Set();
145
+ const result = [];
146
+ for (let index = 0; index < length; index += 1) {
147
+ const item = array[index];
148
+ const keyed = callbacks?.keyed?.(item, index, array) ?? item;
149
+ if (type === "all" && Object.is(keyed, value) || type === "unique" && !keys.has(keyed)) {
150
+ keys.add(keyed);
151
+ result.push(item);
152
+ }
153
+ }
154
+ keys.clear();
155
+ return result;
248
156
  }
249
157
  function getParameters(original) {
250
- const { length } = original;
251
- return {
252
- bool: length === 1 && typeof original[0] === 'function'
253
- ? original[0]
254
- : undefined,
255
- key: length === 2 ? original[0] : undefined,
256
- value: length === 1 && typeof original[0] !== 'function'
257
- ? original[0]
258
- : original[1],
259
- };
260
- }
261
- //
158
+ const { length } = original;
159
+ return {
160
+ bool: length === 1 && typeof original[0] === "function" ? original[0] : void 0,
161
+ key: length === 2 ? original[0] : void 0,
162
+ value: length === 1 && typeof original[0] !== "function" ? original[0] : original[1]
163
+ };
164
+ }
262
165
  const UNIQUE_THRESHOLD = 100;
263
-
264
166
  function exists(array, ...parameters) {
265
- if (parameters.length === 1 && typeof parameters[0] !== 'function') {
266
- return Array.isArray(array) ? array.includes(parameters[0]) : false;
267
- }
268
- return findValue('index', array, parameters) > -1;
167
+ if (parameters.length === 1 && typeof parameters[0] !== "function") return Array.isArray(array) ? array.includes(parameters[0]) : false;
168
+ return findValue("index", array, parameters) > -1;
269
169
  }
270
-
271
170
  function filter(array, ...parameters) {
272
- return findValues('all', array, parameters);
171
+ return findValues("all", array, parameters);
273
172
  }
274
-
275
173
  function find(array, ...parameters) {
276
- return findValue('value', array, parameters);
277
- }
278
-
279
- /**
280
- * Flatten an array _(using native `flat` and maximum depth)_
281
- * @param array Array to flatten
282
- * @returns Flattened array
283
- */
284
- function flatten$1(array) {
285
- return (Array.isArray(array) ? array.flat(Number.POSITIVE_INFINITY) : []);
286
- }
287
-
174
+ return findValue("value", array, parameters);
175
+ }
176
+ function flatten(array) {
177
+ return Array.isArray(array) ? array.flat(Number.POSITIVE_INFINITY) : [];
178
+ }
288
179
  function getArray(value, indiced) {
289
- if (Array.isArray(value)) {
290
- return value;
291
- }
292
- if (!isPlainObject(value)) {
293
- return [value];
294
- }
295
- if (indiced !== true) {
296
- return Object.values(value);
297
- }
298
- const keys = Object.keys(value);
299
- const { length } = keys;
300
- const array = [];
301
- for (let index = 0; index < length; index += 1) {
302
- const key = keys[index];
303
- if (!Number.isNaN(Number(key))) {
304
- array.push(value[key]);
305
- }
306
- }
307
- return array;
308
- }
309
-
180
+ if (Array.isArray(value)) return value;
181
+ if (!isPlainObject(value)) return [value];
182
+ if (indiced !== true) return Object.values(value);
183
+ const keys = Object.keys(value);
184
+ const { length } = keys;
185
+ const array = [];
186
+ for (let index = 0; index < length; index += 1) {
187
+ const key = keys[index];
188
+ if (!Number.isNaN(Number(key))) array.push(value[key]);
189
+ }
190
+ return array;
191
+ }
310
192
  function groupValues(array, key, value, arrays) {
311
- if (!Array.isArray(array) || array.length === 0) {
312
- return {};
313
- }
314
- const { length } = array;
315
- const callbacks = getCallbacks(undefined, key, value);
316
- const record = {};
317
- for (let index = 0; index < length; index += 1) {
318
- const item = array[index];
319
- const keyed = callbacks?.keyed?.(item, index, array) ?? index;
320
- const valued = callbacks?.value?.(item, index, array) ?? item;
321
- if (arrays) {
322
- const existing = record[keyed];
323
- if (existing == null) {
324
- record[keyed] = [valued];
325
- }
326
- else {
327
- existing.push(valued);
328
- }
329
- }
330
- else {
331
- record[keyed] = valued;
332
- }
333
- }
334
- return record;
335
- }
336
-
193
+ if (!Array.isArray(array) || array.length === 0) return {};
194
+ const { length } = array;
195
+ const callbacks = getCallbacks(void 0, key, value);
196
+ const record = {};
197
+ for (let index = 0; index < length; index += 1) {
198
+ const item = array[index];
199
+ const keyed = callbacks?.keyed?.(item, index, array) ?? index;
200
+ const valued = callbacks?.value?.(item, index, array) ?? item;
201
+ if (arrays) {
202
+ const existing = record[keyed];
203
+ if (existing == null) record[keyed] = [valued];
204
+ else existing.push(valued);
205
+ } else record[keyed] = valued;
206
+ }
207
+ return record;
208
+ }
337
209
  const groupBy = ((array, first, second) => groupValues(array, first, second, false));
338
210
  groupBy.arrays = ((array, first, second) => groupValues(array, first, second, true));
339
-
340
211
  function indexOf(array, ...parameters) {
341
- return findValue('index', array, parameters);
212
+ return findValue("index", array, parameters);
342
213
  }
343
-
344
- //
345
214
  function insertChunkedValues(type, array, items, start, deleteCount) {
346
- const actualDeleteCount = deleteCount < 0 ? 0 : deleteCount;
347
- const actualStart = Math.min(Math.max(0, start), array.length);
348
- const chunked = chunk(items);
349
- const lastIndex = chunked.length - 1;
350
- let index = Number(chunked.length);
351
- let returned;
352
- while (--index >= 0) {
353
- const result = array.splice(actualStart, index === lastIndex ? actualDeleteCount : 0, ...chunked[index]);
354
- if (returned == null) {
355
- returned = result;
356
- }
357
- else {
358
- returned.push(...result);
359
- }
360
- }
361
- if (type === 'insert') {
362
- return array;
363
- }
364
- return type === 'splice' ? returned : array.length;
215
+ const actualDeleteCount = deleteCount < 0 ? 0 : deleteCount;
216
+ const actualStart = Math.min(Math.max(0, start), array.length);
217
+ const chunked = chunk(items);
218
+ const lastIndex = chunked.length - 1;
219
+ let index = Number(chunked.length);
220
+ let returned;
221
+ while (--index >= 0) {
222
+ const result = array.splice(actualStart, index === lastIndex ? actualDeleteCount : 0, ...chunked[index]);
223
+ if (returned == null) returned = result;
224
+ else returned.push(...result);
225
+ }
226
+ if (type === "insert") return array;
227
+ return type === "splice" ? returned : array.length;
365
228
  }
366
229
  function insertValues(type, array, items, start, deleteCount) {
367
- const splice = type === 'insert' || type === 'splice';
368
- if (!Array.isArray(array) || typeof start !== 'number') {
369
- return splice ? [] : 0;
370
- }
371
- if (!Array.isArray(items) || items.length === 0) {
372
- return splice ? [] : 0;
373
- }
374
- return insertChunkedValues(type, array, items, start, splice ? deleteCount : 0);
375
- }
376
-
230
+ const splice$1 = type === "insert" || type === "splice";
231
+ if (!Array.isArray(array) || typeof start !== "number") return splice$1 ? [] : 0;
232
+ if (!Array.isArray(items) || items.length === 0) return splice$1 ? [] : 0;
233
+ return insertChunkedValues(type, array, items, start, splice$1 ? deleteCount : 0);
234
+ }
377
235
  function insert(array, indexOrItems, items) {
378
- return insertValues('insert', array, items == null ? indexOrItems : items, typeof indexOrItems === 'number' ? indexOrItems : array?.length, 0);
379
- }
380
-
381
- // Uses chunking to avoid call stack size being exceeded
382
- /**
383
- * Push items into an array _(at the end)_
384
- * @param array Original array
385
- * @param pushed Pushed items
386
- * @returns New length of the array
387
- */
236
+ return insertValues("insert", array, items == null ? indexOrItems : items, typeof indexOrItems === "number" ? indexOrItems : array?.length, 0);
237
+ }
388
238
  function push(array, pushed) {
389
- return insertValues('push', array, pushed, array.length, 0);
239
+ return insertValues("push", array, pushed, array.length, 0);
390
240
  }
391
-
392
241
  function aggregate(type, array, key) {
393
- const length = Array.isArray(array) ? array.length : 0;
394
- if (length === 0) {
395
- return {
396
- count: 0,
397
- value: Number.NaN,
398
- };
399
- }
400
- const aggregator = aggregators[type];
401
- const isCallback = typeof key === 'function';
402
- let count = 0;
403
- let aggregated = Number.NaN;
404
- let notNumber = true;
405
- for (let index = 0; index < length; index += 1) {
406
- const item = array[index];
407
- const value = isCallback
408
- ? key(item, index, array)
409
- : (item[key] ?? item);
410
- if (typeof value === 'number' && !Number.isNaN(value)) {
411
- aggregated = aggregator(aggregated, value, notNumber);
412
- count += 1;
413
- notNumber = false;
414
- }
415
- }
416
- return {
417
- count,
418
- value: aggregated,
419
- };
242
+ const length = Array.isArray(array) ? array.length : 0;
243
+ if (length === 0) return {
244
+ count: 0,
245
+ value: NaN
246
+ };
247
+ const aggregator = aggregators[type];
248
+ const isCallback = typeof key === "function";
249
+ let count$1 = 0;
250
+ let aggregated = NaN;
251
+ let notNumber = true;
252
+ for (let index = 0; index < length; index += 1) {
253
+ const item = array[index];
254
+ const value = isCallback ? key(item, index, array) : item[key] ?? item;
255
+ if (typeof value === "number" && !Number.isNaN(value)) {
256
+ aggregated = aggregator(aggregated, value, notNumber);
257
+ count$1 += 1;
258
+ notNumber = false;
259
+ }
260
+ }
261
+ return {
262
+ count: count$1,
263
+ value: aggregated
264
+ };
420
265
  }
421
266
  function max(array, key) {
422
- return aggregate('max', array, key).value;
267
+ return aggregate("max", array, key).value;
423
268
  }
424
269
  function sum$1(current, value, notNumber) {
425
- return notNumber ? value : current + value;
270
+ return notNumber ? value : current + value;
426
271
  }
427
- //
428
272
  const aggregators = {
429
- sum: sum$1,
430
- average: sum$1,
431
- max: (current, value, notNumber) => notNumber || value > current ? value : current,
432
- min: (current, value, notNumber) => notNumber || value < current ? value : current,
273
+ sum: sum$1,
274
+ average: sum$1,
275
+ max: (current, value, notNumber) => notNumber || value > current ? value : current,
276
+ min: (current, value, notNumber) => notNumber || value < current ? value : current
433
277
  };
434
-
435
- /**
436
- * Get the string value from any value
437
- * @param value Original value
438
- * @returns String representation of the value
439
- */
440
278
  function getString(value) {
441
- if (typeof value === 'string') {
442
- return value;
443
- }
444
- if (value == null) {
445
- return '';
446
- }
447
- if (typeof value === 'function') {
448
- return getString(value());
449
- }
450
- if (typeof value !== 'object') {
451
- return String(value);
452
- }
453
- const asString = String(value.valueOf?.() ?? value);
454
- return asString.startsWith('[object ') ? JSON.stringify(value) : asString;
279
+ if (typeof value === "string") return value;
280
+ if (value == null) return "";
281
+ if (typeof value === "function") return getString(value());
282
+ if (typeof value !== "object") return String(value);
283
+ const asString = String(value.valueOf?.() ?? value);
284
+ return asString.startsWith("[object ") ? JSON.stringify(value) : asString;
455
285
  }
456
286
  function ignoreKey(key) {
457
- return EXPRESSION_IGNORED.test(key);
458
- }
459
- /**
460
- * Join an array of values into a string
461
- * @param value Array of values
462
- * @param delimiter Delimiter to use between values
463
- * @returns Joined string
464
- */
287
+ return EXPRESSION_IGNORED.test(key);
288
+ }
465
289
  function join(value, delimiter) {
466
- return compact(value)
467
- .map(getString)
468
- .join(typeof delimiter === 'string' ? delimiter : '');
290
+ return compact(value).map(getString).join(typeof delimiter === "string" ? delimiter : "");
469
291
  }
470
292
  function tryCallback(value, callback) {
471
- try {
472
- return callback(value);
473
- }
474
- catch {
475
- return value;
476
- }
293
+ try {
294
+ return callback(value);
295
+ } catch {
296
+ return value;
297
+ }
477
298
  }
478
299
  function tryDecode(value) {
479
- return tryCallback(value, decodeURIComponent);
300
+ return tryCallback(value, decodeURIComponent);
480
301
  }
481
302
  function tryEncode(value) {
482
- return tryCallback(value, encodeURIComponent);
303
+ return tryCallback(value, encodeURIComponent);
483
304
  }
484
- /**
485
- * Split a string into words _(and other readable parts)_
486
- * @param value Original string
487
- * @returns Array of words found in the string
488
- */
489
305
  function words(value) {
490
- return typeof value === 'string' ? (value.match(EXPRESSION_WORDS) ?? []) : [];
306
+ return typeof value === "string" ? value.match(EXPRESSION_WORDS) ?? [] : [];
491
307
  }
492
- //
493
308
  const EXPRESSION_IGNORED = /(^|\.)(__proto__|constructor|prototype)(\.|$)/i;
494
- // biome-ignore lint/suspicious/noControlCharactersInRegex: Lodash uses it, so it's fine ;-)
495
309
  const EXPRESSION_WORDS = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
496
-
497
- /**
498
- * Compare two values _(for sorting purposes)_
499
- * @param first First value
500
- * @param second Second value
501
- * @returns `0` if equal; `-1` first comes before second; `1` first comes after second
502
- */
503
310
  function compare(first, second) {
504
- if (Object.is(first, second)) {
505
- return 0;
506
- }
507
- if (first == null) {
508
- return -1;
509
- }
510
- if (second == null) {
511
- return 1;
512
- }
513
- const comparison = compareValue(first, second, false);
514
- if (comparison != null) {
515
- return comparison;
516
- }
517
- const firstParts = getParts$1(first);
518
- const secondParts = getParts$1(second);
519
- const length = max([firstParts.length, secondParts.length]);
520
- const lastIndex = length - 1;
521
- for (let index = 0; index < length; index += 1) {
522
- const firstPart = firstParts[index];
523
- const secondPart = secondParts[index];
524
- const comparison = compareValue(firstPart, secondPart, true);
525
- if (comparison === 0) {
526
- if (index === lastIndex) {
527
- break;
528
- }
529
- continue;
530
- }
531
- return comparison;
532
- }
533
- return 0;
311
+ if (Object.is(first, second)) return 0;
312
+ if (first == null) return -1;
313
+ if (second == null) return 1;
314
+ const comparison = compareValue(first, second, false);
315
+ if (comparison != null) return comparison;
316
+ const firstParts = getParts$1(first);
317
+ const secondParts = getParts$1(second);
318
+ const length = max([firstParts.length, secondParts.length]);
319
+ const lastIndex = length - 1;
320
+ for (let index = 0; index < length; index += 1) {
321
+ const firstPart = firstParts[index];
322
+ const secondPart = secondParts[index];
323
+ const comparison$1 = compareValue(firstPart, secondPart, true);
324
+ if (comparison$1 === 0) {
325
+ if (index === lastIndex) break;
326
+ continue;
327
+ }
328
+ return comparison$1;
329
+ }
330
+ return 0;
534
331
  }
535
332
  function compareNumbers(first, second) {
536
- const firstNumber = Number(first);
537
- const secondNumber = Number(second);
538
- if (firstNumber === secondNumber) {
539
- return 0;
540
- }
541
- return firstNumber > secondNumber ? 1 : -1;
333
+ const firstNumber = Number(first);
334
+ const secondNumber = Number(second);
335
+ if (firstNumber === secondNumber) return 0;
336
+ return firstNumber > secondNumber ? 1 : -1;
542
337
  }
543
338
  function compareSymbols(first, second) {
544
- return getString(first.description ?? first).localeCompare(getString(second.description ?? second));
339
+ return getString(first.description ?? first).localeCompare(getString(second.description ?? second));
545
340
  }
546
341
  function compareValue(first, second, compareStrings) {
547
- const firstType = typeof first;
548
- const secondType = typeof second;
549
- if (firstType === secondType && firstType in comparators) {
550
- return comparators[firstType](first, second);
551
- }
552
- if (first instanceof Date && second instanceof Date) {
553
- return compareNumbers(first.getTime(), second.getTime());
554
- }
555
- if (compareStrings) {
556
- return getString(first).localeCompare(getString(second));
557
- }
342
+ const firstType = typeof first;
343
+ if (firstType === typeof second && firstType in comparators) return comparators[firstType](first, second);
344
+ if (first instanceof Date && second instanceof Date) return compareNumbers(first.getTime(), second.getTime());
345
+ if (compareStrings) return getString(first).localeCompare(getString(second));
558
346
  }
559
347
  function getParts$1(value) {
560
- if (Array.isArray(value)) {
561
- return value;
562
- }
563
- return typeof value === 'object' ? [value] : words(getString(value));
348
+ if (Array.isArray(value)) return value;
349
+ return typeof value === "object" ? [value] : words(getString(value));
564
350
  }
565
- //
566
351
  const comparators = {
567
- bigint: compareNumbers,
568
- boolean: compareNumbers,
569
- number: compareNumbers,
570
- symbol: compareSymbols,
352
+ bigint: compareNumbers,
353
+ boolean: compareNumbers,
354
+ number: compareNumbers,
355
+ symbol: compareSymbols
571
356
  };
572
-
573
- /**
574
- * Is the array or object completely empty, or only containing `null` or `undefined` values?
575
- * @param value Array or object to check
576
- * @returns `true` if the value is considered empty, otherwise `false`
577
- */
578
357
  function isEmpty(value) {
579
- const values = Object.values(value);
580
- const { length } = values;
581
- for (let index = 0; index < length; index += 1) {
582
- if (values[index] != null) {
583
- return false;
584
- }
585
- }
586
- return true;
587
- }
588
- /**
589
- * Is the value `undefined` or `null`?
590
- * @param value Value to check
591
- * @returns `true` if the value is `undefined` or `null`, otherwise `false`
592
- */
358
+ const values = Object.values(value);
359
+ const { length } = values;
360
+ for (let index = 0; index < length; index += 1) if (values[index] != null) return false;
361
+ return true;
362
+ }
593
363
  function isNullable(value) {
594
- return value == null;
364
+ return value == null;
595
365
  }
596
- /**
597
- * Is the value `undefined`, `null`, or an empty _(no whitespace)_ string?
598
- * @param value Value to check
599
- * @returns `true` if the value is nullable or an empty string, otherwise `false`
600
- */
601
366
  function isNullableOrEmpty(value) {
602
- return value == null || getString(value) === '';
367
+ return value == null || getString(value) === "";
603
368
  }
604
- /**
605
- * Is the value `undefined`, `null`, or a whitespace-only string?
606
- * @param value Value to check
607
- * @returns `true` if the value is nullable or a whitespace-only string, otherwise `false`
608
- */
609
369
  function isNullableOrWhitespace(value) {
610
- return value == null || EXPRESSION_WHITESPACE.test(getString(value));
370
+ return value == null || EXPRESSION_WHITESPACE.test(getString(value));
611
371
  }
612
- /**
613
- * Is the value a number or a number-like string?
614
- * @param value Value to check
615
- * @returns `true` if the value is a number or a parseable string, otherwise `false`
616
- */
617
372
  function isNumerical(value) {
618
- return (isNumber(value) ||
619
- (typeof value === 'string' &&
620
- value.trim().length > 0 &&
621
- !Number.isNaN(+value)));
622
- }
623
- /**
624
- * Is the value an object _(or function)_?
625
- * @param value Value to check
626
- * @returns `true` if the value matches, otherwise `false`
627
- */
628
- function isObject$1(value) {
629
- return ((typeof value === 'object' && value !== null) || typeof value === 'function');
630
- }
631
- /**
632
- * - Is the value a primitive value?
633
- * @param value Value to check
634
- * @returns `true` if the value matches, otherwise `false`
635
- */
373
+ return isNumber(value) || typeof value === "string" && value.trim().length > 0 && !Number.isNaN(+value);
374
+ }
375
+ function isObject(value) {
376
+ return typeof value === "object" && value !== null || typeof value === "function";
377
+ }
636
378
  function isPrimitive(value) {
637
- return value == null || EXPRESSION_PRIMITIVE.test(typeof value);
379
+ return value == null || EXPRESSION_PRIMITIVE.test(typeof value);
638
380
  }
639
- //
640
381
  const EXPRESSION_PRIMITIVE = /^(bigint|boolean|number|string|symbol)$/;
641
382
  const EXPRESSION_WHITESPACE = /^\s*$/;
642
-
643
- //
644
- function getCallback(value, key, isObject) {
645
- if (key != null) {
646
- return;
647
- }
648
- if (isObject && typeof value.value === 'function') {
649
- return value.value;
650
- }
651
- return typeof value === 'function' ? value : undefined;
652
- }
653
- function getKey(value, isObject) {
654
- if (isObject && typeof value.key === 'string') {
655
- return value.key;
656
- }
657
- return typeof value === 'string' ? value : undefined;
658
- }
659
- function getModifier(value, modifier, isObject) {
660
- if (!isObject || typeof value.direction !== 'string') {
661
- return modifier;
662
- }
663
- if (value.direction === 'ascending') {
664
- return 1;
665
- }
666
- return value.direction === 'descending' ? -1 : modifier;
383
+ function getCallback(value, key, isObject$2) {
384
+ if (key != null) return;
385
+ if (isObject$2 && typeof value.value === "function") return value.value;
386
+ return typeof value === "function" ? value : void 0;
387
+ }
388
+ function getKey(value, isObject$2) {
389
+ if (isObject$2 && typeof value.key === "string") return value.key;
390
+ return typeof value === "string" ? value : void 0;
391
+ }
392
+ function getModifier(value, modifier, isObject$2) {
393
+ if (!isObject$2 || typeof value.direction !== "string") return modifier;
394
+ if (value.direction === "ascending") return 1;
395
+ return value.direction === "descending" ? -1 : modifier;
667
396
  }
668
397
  function getSorter(value, modifier) {
669
- const isObject = isPlainObject(value);
670
- const sorter = {
671
- identifier: '',
672
- modifier,
673
- };
674
- sorter.compare =
675
- isObject && typeof value.compare === 'function'
676
- ? value.compare
677
- : undefined;
678
- sorter.key = getKey(value, isObject);
679
- sorter.modifier = getModifier(value, modifier, isObject);
680
- sorter.callback = getCallback(value, sorter.key, isObject);
681
- if (sorter.key != null || sorter.callback != null) {
682
- sorter.identifier = `${sorter.key ?? sorter.callback}`;
683
- return sorter;
684
- }
398
+ const isObject$2 = isPlainObject(value);
399
+ const sorter = {
400
+ identifier: "",
401
+ modifier
402
+ };
403
+ sorter.compare = isObject$2 && typeof value.compare === "function" ? value.compare : void 0;
404
+ sorter.key = getKey(value, isObject$2);
405
+ sorter.modifier = getModifier(value, modifier, isObject$2);
406
+ sorter.callback = getCallback(value, sorter.key, isObject$2);
407
+ if (sorter.key != null || sorter.callback != null) {
408
+ sorter.identifier = `${sorter.key ?? sorter.callback}`;
409
+ return sorter;
410
+ }
685
411
  }
686
412
  function sort(array, first, second) {
687
- if (!Array.isArray(array)) {
688
- return [];
689
- }
690
- if (array.length < 2) {
691
- return array;
692
- }
693
- const direction = first === true || second === true ? 'desc' : 'asc';
694
- const modifier = direction === 'asc' ? 1 : -1;
695
- const sorters = (Array.isArray(first) ? first : [first])
696
- .map(item => getSorter(item, modifier))
697
- .filter(sorter => sorter != null)
698
- .filter((current, index, sorters) => sorters.findIndex(next => next.identifier === current.identifier) ===
699
- index);
700
- const { length } = sorters;
701
- if (length === 0) {
702
- return array.sort((first, second) => compare(first, second) * modifier);
703
- }
704
- if (length === 1) {
705
- const sorter = sorters[0];
706
- const { callback, key, modifier } = sorter;
707
- return array.sort((first, second) => {
708
- const firstValue = key == null ? callback?.(first) : first[key];
709
- const secondValue = key == null ? callback?.(second) : second[key];
710
- return ((sorter.compare?.(first, firstValue, second, secondValue) ??
711
- compare(firstValue, secondValue)) * modifier);
712
- });
713
- }
714
- return array.sort((first, second) => {
715
- for (let index = 0; index < length; index += 1) {
716
- const sorter = sorters[index];
717
- const { callback, key, modifier } = sorter;
718
- const firstValue = key == null ? callback?.(first) : first[key];
719
- const secondValue = key == null ? callback?.(second) : second[key];
720
- const compared = (sorter.compare?.(first, firstValue, second, secondValue) ??
721
- compare(firstValue, secondValue)) * modifier;
722
- if (compared !== 0) {
723
- return compared;
724
- }
725
- }
726
- return 0;
727
- });
728
- }
729
-
413
+ if (!Array.isArray(array)) return [];
414
+ if (array.length < 2) return array;
415
+ const modifier = (first === true || second === true ? "desc" : "asc") === "asc" ? 1 : -1;
416
+ const sorters = (Array.isArray(first) ? first : [first]).map((item) => getSorter(item, modifier)).filter((sorter) => sorter != null).filter((current, index, sorters$1) => sorters$1.findIndex((next) => next.identifier === current.identifier) === index);
417
+ const { length } = sorters;
418
+ if (length === 0) return array.sort((first$1, second$1) => compare(first$1, second$1) * modifier);
419
+ if (length === 1) {
420
+ const sorter = sorters[0];
421
+ const { callback, key, modifier: modifier$1 } = sorter;
422
+ return array.sort((first$1, second$1) => {
423
+ const firstValue = key == null ? callback?.(first$1) : first$1[key];
424
+ const secondValue = key == null ? callback?.(second$1) : second$1[key];
425
+ return (sorter.compare?.(first$1, firstValue, second$1, secondValue) ?? compare(firstValue, secondValue)) * modifier$1;
426
+ });
427
+ }
428
+ return array.sort((first$1, second$1) => {
429
+ for (let index = 0; index < length; index += 1) {
430
+ const sorter = sorters[index];
431
+ const { callback, key, modifier: modifier$1 } = sorter;
432
+ const firstValue = key == null ? callback?.(first$1) : first$1[key];
433
+ const secondValue = key == null ? callback?.(second$1) : second$1[key];
434
+ const compared = (sorter.compare?.(first$1, firstValue, second$1, secondValue) ?? compare(firstValue, secondValue)) * modifier$1;
435
+ if (compared !== 0) return compared;
436
+ }
437
+ return 0;
438
+ });
439
+ }
730
440
  function splice(array, start, deleteCountOrItems, items) {
731
- return insertValues('splice', array, typeof deleteCountOrItems === 'number' ? items : deleteCountOrItems, start, typeof deleteCountOrItems === 'number' ? deleteCountOrItems : 0);
441
+ return insertValues("splice", array, typeof deleteCountOrItems === "number" ? items : deleteCountOrItems, start, typeof deleteCountOrItems === "number" ? deleteCountOrItems : 0);
732
442
  }
733
-
734
443
  function getMapValues(array, first, second, arrays) {
735
- if (!Array.isArray(array)) {
736
- return new Map();
737
- }
738
- const { length } = array;
739
- const callbacks = getCallbacks(undefined, first, second);
740
- const map = new Map();
741
- for (let index = 0; index < length; index += 1) {
742
- const item = array[index];
743
- const key = callbacks?.keyed?.(item, index, array) ?? index;
744
- const value = callbacks?.value?.(item, index, array) ?? item;
745
- if (arrays) {
746
- const existing = map.get(key);
747
- if (existing == null) {
748
- map.set(key, [value]);
749
- }
750
- else {
751
- existing.push(value);
752
- }
753
- }
754
- else {
755
- map.set(key, value);
756
- }
757
- }
758
- return map;
444
+ if (!Array.isArray(array)) return /* @__PURE__ */ new Map();
445
+ const { length } = array;
446
+ const callbacks = getCallbacks(void 0, first, second);
447
+ const map = /* @__PURE__ */ new Map();
448
+ for (let index = 0; index < length; index += 1) {
449
+ const item = array[index];
450
+ const key = callbacks?.keyed?.(item, index, array) ?? index;
451
+ const value = callbacks?.value?.(item, index, array) ?? item;
452
+ if (arrays) {
453
+ const existing = map.get(key);
454
+ if (existing == null) map.set(key, [value]);
455
+ else existing.push(value);
456
+ } else map.set(key, value);
457
+ }
458
+ return map;
759
459
  }
760
460
  const toMap = ((array, first, second, arrays) => getMapValues(array, first, second, arrays));
761
461
  toMap.arrays = ((array, first, second) => getMapValues(array, first, second, true));
762
-
763
462
  const toRecord = ((array, first, second) => groupValues(array, first, second, false));
764
463
  toRecord.arrays = ((array, first, second) => groupValues(array, first, second, true));
765
-
766
464
  function toSet(array, value) {
767
- if (!Array.isArray(array)) {
768
- return new Set();
769
- }
770
- const callbacks = getCallbacks(undefined, undefined, value);
771
- if (callbacks?.value == null) {
772
- return new Set(array);
773
- }
774
- const { length } = array;
775
- const set = new Set();
776
- for (let index = 0; index < length; index += 1) {
777
- set.add(callbacks.value(array[index], index, array));
778
- }
779
- return set;
780
- }
781
-
465
+ if (!Array.isArray(array)) return /* @__PURE__ */ new Set();
466
+ const callbacks = getCallbacks(void 0, void 0, value);
467
+ if (callbacks?.value == null) return new Set(array);
468
+ const { length } = array;
469
+ const set = /* @__PURE__ */ new Set();
470
+ for (let index = 0; index < length; index += 1) set.add(callbacks.value(array[index], index, array));
471
+ return set;
472
+ }
782
473
  function unique(array, key) {
783
- if (!Array.isArray(array)) {
784
- return [];
785
- }
786
- return array.length > 1
787
- ? findValues('unique', array, [key, undefined])
788
- : array;
789
- }
790
-
791
- const ALPHA_FULL_HEX_SHORT = 'f';
474
+ if (!Array.isArray(array)) return [];
475
+ return array.length > 1 ? findValues("unique", array, [key, void 0]) : array;
476
+ }
477
+ const ALPHA_FULL_HEX_SHORT = "f";
792
478
  const ALPHA_FULL_HEX_LONG = `${ALPHA_FULL_HEX_SHORT}${ALPHA_FULL_HEX_SHORT}`;
793
479
  const ALPHA_FULL_VALUE = 1;
794
- const ALPHA_NONE_HEX = '00';
480
+ const ALPHA_NONE_HEX = "00";
795
481
  const ALPHA_NONE_VALUE = 0;
796
482
  const DEFAULT_ALPHA = {
797
- hex: ALPHA_FULL_HEX_LONG,
798
- value: ALPHA_FULL_VALUE,
483
+ hex: ALPHA_FULL_HEX_LONG,
484
+ value: ALPHA_FULL_VALUE
799
485
  };
800
486
  const DEFAULT_HSL = {
801
- hue: 0,
802
- lightness: 0,
803
- saturation: 0,
487
+ hue: 0,
488
+ lightness: 0,
489
+ saturation: 0
804
490
  };
805
491
  const DEFAULT_RGB = {
806
- blue: 0,
807
- green: 0,
808
- red: 0,
492
+ blue: 0,
493
+ green: 0,
494
+ red: 0
809
495
  };
810
496
  const EXPRESSION_HEX_LONG = /^#?([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})?$/i;
811
497
  const EXPRESSION_HEX_SHORT = /^#?([a-f0-9]{3,4})$/i;
812
498
  const EXPRESSION_PREFIX = /^#/;
813
- const HEX_BLACK = '000000';
814
- const HEX_WHITE = 'ffffff';
499
+ const HEX_BLACK = "000000";
500
+ const HEX_WHITE = "ffffff";
815
501
  const LENGTH_LONG = 6;
816
502
  const LENGTH_SHORT = 3;
817
- const KEYS_HSL = ['hue', 'saturation', 'lightness'];
818
- const KEYS_HSLA = [...KEYS_HSL, 'alpha'];
819
- const KEYS_RGB = ['red', 'green', 'blue'];
820
- const KEYS_RGBA = [...KEYS_RGB, 'alpha'];
503
+ const KEYS_HSL = [
504
+ "hue",
505
+ "saturation",
506
+ "lightness"
507
+ ];
508
+ const KEYS_HSLA = [...KEYS_HSL, "alpha"];
509
+ const KEYS_RGB = [
510
+ "red",
511
+ "green",
512
+ "blue"
513
+ ];
514
+ const KEYS_RGBA = [...KEYS_RGB, "alpha"];
821
515
  const MAX_DEGREE = 360;
822
516
  const MAX_HEX = 255;
823
517
  const MAX_PERCENT = 100;
824
- //
825
- // https://www.w3.org/TR/WCAG20/#relativeluminancedef
826
- const SRGB_LUMINANCE_BLUE = 0.0722;
518
+ const SRGB_LUMINANCE_BLUE = .0722;
827
519
  const SRGB_LUMINANCE_EXPONENT = 2.4;
828
- const SRGB_LUMINANCE_GREEN = 0.7152;
829
- const SRGB_LUMINANCE_MINIMUM = 0.03928;
520
+ const SRGB_LUMINANCE_GREEN = .7152;
521
+ const SRGB_LUMINANCE_MINIMUM = .03928;
830
522
  const SRGB_LUMINANCE_MODIFIER = 1.055;
831
523
  const SRGB_LUMINANCE_MULTIPLIER = 12.92;
832
- const SRGB_LUMINANCE_OFFSET = 0.055;
833
- const SRGB_LUMINANCE_RED = 0.2126;
834
- const SRGB_LUMINANCE_THRESHOLD = 0.625;
835
-
524
+ const SRGB_LUMINANCE_OFFSET = .055;
525
+ const SRGB_LUMINANCE_RED = .2126;
526
+ const SRGB_LUMINANCE_THRESHOLD = .625;
836
527
  function formatColor(space, color, alpha) {
837
- const suffix = alpha ? ` / ${color.alpha}` : '';
838
- const value = color[space];
839
- return `${space}(${join(formattingKeys[space].map(key => value[key]), ' ')}${suffix})`;
528
+ const suffix = alpha ? ` / ${color.alpha}` : "";
529
+ const value = color[space];
530
+ return `${space}(${join(formattingKeys[space].map((key) => value[key]), " ")}${suffix})`;
840
531
  }
841
- //
842
532
  const formattingKeys = {
843
- hsl: KEYS_HSL,
844
- rgb: KEYS_RGB,
533
+ hsl: KEYS_HSL,
534
+ rgb: KEYS_RGB
845
535
  };
846
-
847
536
  function getAlpha(value) {
848
- if (typeof value === 'number') {
849
- return getAlphaFromValue(value);
850
- }
851
- if (typeof value === 'string' && value !== ALPHA_FULL_HEX_LONG) {
852
- return {
853
- hex: value,
854
- value: Number.parseInt(value, 16) / MAX_HEX,
855
- };
856
- }
857
- return { ...DEFAULT_ALPHA };
537
+ if (typeof value === "number") return getAlphaFromValue(value);
538
+ if (typeof value === "string" && value !== ALPHA_FULL_HEX_LONG) return {
539
+ hex: value,
540
+ value: Number.parseInt(value, 16) / MAX_HEX
541
+ };
542
+ return { ...DEFAULT_ALPHA };
858
543
  }
859
544
  function getAlphaHexadecimal(value) {
860
- if (value === ALPHA_NONE_VALUE) {
861
- return ALPHA_NONE_HEX;
862
- }
863
- if (value === ALPHA_FULL_VALUE) {
864
- return ALPHA_FULL_HEX_LONG;
865
- }
866
- return Math.round(value * MAX_HEX).toString(16);
545
+ if (value === ALPHA_NONE_VALUE) return ALPHA_NONE_HEX;
546
+ if (value === ALPHA_FULL_VALUE) return ALPHA_FULL_HEX_LONG;
547
+ return Math.round(value * MAX_HEX).toString(16);
867
548
  }
868
549
  function getAlphaFromValue(value) {
869
- const alpha = getAlphaValue(value);
870
- return {
871
- hex: getAlphaHexadecimal(alpha),
872
- value: alpha,
873
- };
550
+ const alpha = getAlphaValue(value);
551
+ return {
552
+ hex: getAlphaHexadecimal(alpha),
553
+ value: alpha
554
+ };
874
555
  }
875
556
  function getAlphaValue(original) {
876
- if (Number.isNaN(original) ||
877
- original >= MAX_PERCENT ||
878
- original === ALPHA_FULL_VALUE) {
879
- return ALPHA_FULL_VALUE;
880
- }
881
- if (original < ALPHA_NONE_VALUE) {
882
- return ALPHA_NONE_VALUE;
883
- }
884
- return original <= ALPHA_FULL_VALUE ? original : original / MAX_PERCENT;
885
- }
886
-
887
- /**
888
- * Is the number between a minimum and maximum value?
889
- * @param value Value to check
890
- * @param minimum Minimum value
891
- * @param maximum Maximum value
892
- * @returns `true` if the value is between the minimum and maximum, otherwise `false`
893
- */
557
+ if (Number.isNaN(original) || original >= MAX_PERCENT || original === ALPHA_FULL_VALUE) return ALPHA_FULL_VALUE;
558
+ if (original < ALPHA_NONE_VALUE) return ALPHA_NONE_VALUE;
559
+ return original <= ALPHA_FULL_VALUE ? original : original / MAX_PERCENT;
560
+ }
894
561
  function between(value, minimum, maximum) {
895
- if (![value, minimum, maximum].every(isNumber)) {
896
- return false;
897
- }
898
- if (minimum === maximum) {
899
- return value === minimum;
900
- }
901
- const max = maximum > minimum ? maximum : minimum;
902
- const min = maximum > minimum ? minimum : maximum;
903
- return value >= min && value <= max;
904
- }
905
- /**
906
- * Clamp a number between a minimum and maximum value
907
- * @param value Value to clamp
908
- * @param minimum Minimum value
909
- * @param maximum Maximum value
910
- * @param loop If `true`, the value will loop around when smaller than the minimum or larger than the maximum _(defaults to `false`)_
911
- * @returns Clamped value
912
- */
562
+ if (![
563
+ value,
564
+ minimum,
565
+ maximum
566
+ ].every(isNumber)) return false;
567
+ if (minimum === maximum) return value === minimum;
568
+ return value >= (maximum > minimum ? minimum : maximum) && value <= (maximum > minimum ? maximum : minimum);
569
+ }
913
570
  function clamp(value, minimum, maximum, loop) {
914
- if (![value, minimum, maximum].every(isNumber)) {
915
- return Number.NaN;
916
- }
917
- if (value < minimum) {
918
- return loop === true ? maximum : minimum;
919
- }
920
- const next = loop === true ? minimum : maximum;
921
- return value > maximum ? next : value;
922
- }
923
- /**
924
- * Get the number value from an unknown value _(based on Lodash)_
925
- * @param value Original value
926
- * @returns The value as a number, or `NaN` if the value is unable to be parsed
927
- */
571
+ if (![
572
+ value,
573
+ minimum,
574
+ maximum
575
+ ].every(isNumber)) return NaN;
576
+ if (value < minimum) return loop === true ? maximum : minimum;
577
+ return value > maximum ? loop === true ? minimum : maximum : value;
578
+ }
928
579
  function getNumber(value) {
929
- if (typeof value === 'number') {
930
- return value;
931
- }
932
- if (typeof value === 'bigint' || typeof value === 'boolean') {
933
- return Number(value);
934
- }
935
- if (value == null || typeof value === 'symbol') {
936
- return Number.NaN;
937
- }
938
- if (typeof value === 'function') {
939
- return getNumber(value());
940
- }
941
- let parsed = value.valueOf();
942
- if (typeof parsed === 'object') {
943
- parsed = parsed.toString();
944
- }
945
- if (typeof parsed !== 'string') {
946
- return getNumber(parsed);
947
- }
948
- const trimmed = parsed.trim();
949
- if (trimmed.length === 0) {
950
- return Number.NaN;
951
- }
952
- if (EXPRESSION_ZEROISH.test(parsed)) {
953
- return 0;
954
- }
955
- const isBinary = EXPRESSION_BINARY.test(trimmed);
956
- if (isBinary || EXPRESSION_OCTAL.test(trimmed)) {
957
- return Number.parseInt(trimmed.slice(2), isBinary ? 2 : OCTAL_VALUE);
958
- }
959
- return Number(EXPRESSION_HEX.test(trimmed)
960
- ? trimmed
961
- : trimmed.replace(EXPRESSION_UNDERSCORE, ''));
962
- }
963
- //
580
+ if (typeof value === "number") return value;
581
+ if (typeof value === "bigint" || typeof value === "boolean") return Number(value);
582
+ if (value == null || typeof value === "symbol") return NaN;
583
+ if (typeof value === "function") return getNumber(value());
584
+ let parsed = value.valueOf();
585
+ if (typeof parsed === "object") parsed = parsed.toString();
586
+ if (typeof parsed !== "string") return getNumber(parsed);
587
+ const trimmed = parsed.trim();
588
+ if (trimmed.length === 0) return NaN;
589
+ if (EXPRESSION_ZEROISH.test(parsed)) return 0;
590
+ const isBinary = EXPRESSION_BINARY.test(trimmed);
591
+ if (isBinary || EXPRESSION_OCTAL.test(trimmed)) return Number.parseInt(trimmed.slice(2), isBinary ? 2 : OCTAL_VALUE);
592
+ return Number(EXPRESSION_HEX.test(trimmed) ? trimmed : trimmed.replace(EXPRESSION_UNDERSCORE, ""));
593
+ }
964
594
  const EXPRESSION_BINARY = /^0b[01]+$/i;
965
595
  const EXPRESSION_HEX = /^0x[0-9a-f]+$/i;
966
596
  const EXPRESSION_OCTAL = /^0o[0-7]+$/i;
967
597
  const EXPRESSION_UNDERSCORE = /_/g;
968
598
  const EXPRESSION_ZEROISH = /^\s*0+\s*$/;
969
599
  const OCTAL_VALUE = 8;
970
-
600
+ function hasKeys(value, keys) {
601
+ return typeof value === "object" && value !== null && keys.every((key) => key in value);
602
+ }
971
603
  function isAlpha(value) {
972
- return (typeof value === 'number' &&
973
- between(value, ALPHA_NONE_VALUE, ALPHA_FULL_VALUE));
604
+ return typeof value === "number" && between(value, ALPHA_NONE_VALUE, ALPHA_FULL_VALUE);
974
605
  }
975
606
  function isBytey(value) {
976
- return typeof value === 'number' && between(value, 0, MAX_HEX);
607
+ return typeof value === "number" && between(value, 0, MAX_HEX);
977
608
  }
978
- /**
979
- * Is the value a Color?
980
- * @param value The value to check
981
- * @returns `true` if the value is a Color, otherwise `false`
982
- */
983
609
  function isColor(value) {
984
- return (typeof value === 'object' &&
985
- value !== null &&
986
- '$color' in value &&
987
- value.$color === true);
610
+ return typeof value === "object" && value !== null && "$color" in value && value.$color === true;
988
611
  }
989
612
  function isDegree(value) {
990
- return typeof value === 'number' && between(value, 0, MAX_DEGREE);
991
- }
992
- /**
993
- * Is the value a hex color?
994
- * @param value The value to check
995
- * @param alpha Allow alpha channel? _(defaults to `true`)_
996
- * @returns `true` if the value is a hex color, otherwise `false`
997
- */
613
+ return typeof value === "number" && between(value, 0, MAX_DEGREE);
614
+ }
998
615
  function isHexColor(value, alpha) {
999
- if (typeof value !== 'string') {
1000
- return false;
1001
- }
1002
- if (!(EXPRESSION_HEX_SHORT.test(value) || EXPRESSION_HEX_LONG.test(value))) {
1003
- return false;
1004
- }
1005
- if (alpha === false) {
1006
- return value.length === LENGTH_SHORT || value.length === LENGTH_LONG;
1007
- }
1008
- return true;
1009
- }
1010
- /**
1011
- * Is the value an HSLA color?
1012
- * @param value The value to check
1013
- * @returns `true` if the value is an HSLA color, otherwise `false`
1014
- */
616
+ if (typeof value !== "string") return false;
617
+ if (!(EXPRESSION_HEX_SHORT.test(value) || EXPRESSION_HEX_LONG.test(value))) return false;
618
+ if (alpha === false) return value.length === LENGTH_SHORT || value.length === LENGTH_LONG;
619
+ return true;
620
+ }
1015
621
  function isHslaColor(value) {
1016
- return isObject(value, KEYS_HSLA);
622
+ return isObject$1(value, KEYS_HSLA);
1017
623
  }
1018
- /**
1019
- * Is the value an HSL color?
1020
- * @param value The value to check
1021
- * @returns `true` if the value is an HSL color, otherwise `false`
1022
- */
1023
624
  function isHslColor(value) {
1024
- return isObject(value, KEYS_HSLA) || isObject(value, KEYS_HSL);
625
+ return isObject$1(value, KEYS_HSLA) || isObject$1(value, KEYS_HSL);
626
+ }
627
+ function isHslLike(value) {
628
+ return hasKeys(value, KEYS_HSL);
1025
629
  }
1026
- /**
1027
- * Is the value an RGBA color?
1028
- * @param value The value to check
1029
- * @returns `true` if the value is an RGBA color, otherwise `false`
1030
- */
1031
630
  function isRgbaColor(value) {
1032
- return isObject(value, KEYS_RGBA);
631
+ return isObject$1(value, KEYS_RGBA);
1033
632
  }
1034
- /**
1035
- * Is the value an RGB color?
1036
- * @param value The value to check
1037
- * @returns `true` if the value is an RGB color, otherwise `false`
1038
- */
1039
633
  function isRgbColor(value) {
1040
- return isObject(value, KEYS_RGBA) || isObject(value, KEYS_RGB);
1041
- }
1042
- function isObject(obj, properties) {
1043
- if (typeof obj !== 'object' || obj === null) {
1044
- return false;
1045
- }
1046
- const keys = Object.keys(obj);
1047
- const { length } = keys;
1048
- if (length !== properties.length) {
1049
- return false;
1050
- }
1051
- for (let index = 0; index < length; index += 1) {
1052
- const key = keys[index];
1053
- if (!(properties.includes(key) &&
1054
- validators[key](obj[key]))) {
1055
- return false;
1056
- }
1057
- }
1058
- return true;
634
+ return isObject$1(value, KEYS_RGBA) || isObject$1(value, KEYS_RGB);
635
+ }
636
+ function isRgbLike(value) {
637
+ return hasKeys(value, KEYS_RGB);
638
+ }
639
+ function isObject$1(obj, properties) {
640
+ if (typeof obj !== "object" || obj === null) return false;
641
+ const keys = Object.keys(obj);
642
+ const { length } = keys;
643
+ if (length !== properties.length) return false;
644
+ for (let index = 0; index < length; index += 1) {
645
+ const key = keys[index];
646
+ if (!(properties.includes(key) && validators[key](obj[key]))) return false;
647
+ }
648
+ return true;
1059
649
  }
1060
650
  function isPercentage(value) {
1061
- return typeof value === 'number' && between(value, 0, MAX_PERCENT);
651
+ return typeof value === "number" && between(value, 0, MAX_PERCENT);
1062
652
  }
1063
- //
1064
653
  const validators = {
1065
- alpha: isAlpha,
1066
- blue: isBytey,
1067
- green: isBytey,
1068
- hue: isDegree,
1069
- lightness: isPercentage,
1070
- saturation: isPercentage,
1071
- red: isBytey,
654
+ alpha: isAlpha,
655
+ blue: isBytey,
656
+ green: isBytey,
657
+ hue: isDegree,
658
+ lightness: isPercentage,
659
+ saturation: isPercentage,
660
+ red: isBytey
1072
661
  };
1073
-
662
+ function getForegroundColor(value) {
663
+ const { blue, green, red } = getState(value).rgb;
664
+ const values = [
665
+ blue / MAX_HEX,
666
+ green / MAX_HEX,
667
+ red / MAX_HEX
668
+ ];
669
+ for (let color of values) if (color <= SRGB_LUMINANCE_MINIMUM) color /= SRGB_LUMINANCE_MULTIPLIER;
670
+ else color = ((color + SRGB_LUMINANCE_OFFSET) / SRGB_LUMINANCE_MODIFIER) ** SRGB_LUMINANCE_EXPONENT;
671
+ return new Color(SRGB_LUMINANCE_RED * values[2] + SRGB_LUMINANCE_GREEN * values[1] + SRGB_LUMINANCE_BLUE * values[0] > SRGB_LUMINANCE_THRESHOLD ? HEX_BLACK : HEX_WHITE);
672
+ }
673
+ function getHexaColor(value) {
674
+ const { alpha, hex } = getState(value);
675
+ return `${hex}${alpha.hex}`;
676
+ }
677
+ function getHexColor(value) {
678
+ return getState(value).hex;
679
+ }
680
+ function getHexValue(value) {
681
+ return getValue$2(value, 0, MAX_HEX);
682
+ }
683
+ function getDegrees(value) {
684
+ return getValue$2(value, 0, MAX_DEGREE);
685
+ }
686
+ function getHslaColor(value) {
687
+ const { alpha, hsl } = getState(value);
688
+ return {
689
+ ...hsl,
690
+ alpha: alpha.value
691
+ };
692
+ }
693
+ function getHslColor(value) {
694
+ return getState(value).hsl;
695
+ }
696
+ function getPercentage(value) {
697
+ return getValue$2(value, 0, MAX_PERCENT);
698
+ }
699
+ function getRgbaColor(value) {
700
+ const { alpha, rgb } = getState(value);
701
+ return {
702
+ ...rgb,
703
+ alpha: alpha.value
704
+ };
705
+ }
706
+ function getRgbColor(value) {
707
+ return getState(value).rgb;
708
+ }
709
+ function getValue$2(value, minimum, maximum) {
710
+ return typeof value === "number" ? clamp(value, minimum, maximum) : minimum;
711
+ }
1074
712
  function convertRgbToHex(rgb, alpha) {
1075
- const hex = `${join([rgb.red, rgb.green, rgb.blue].map(color => {
1076
- const hex = color.toString(16);
1077
- return hex.length === 1 ? `0${hex}` : hex;
1078
- }))}`;
1079
- let a = '';
1080
- if (typeof alpha === 'boolean' && alpha) {
1081
- a = getAlpha(rgb.alpha).hex;
1082
- }
1083
- return `${hex}${a}`;
1084
- }
1085
- function convertRgbToHsla(rgb) {
1086
- const actual = isRgbColor(rgb) ? rgb : { ...DEFAULT_RGB };
1087
- const blue = actual.blue / MAX_HEX;
1088
- const green = actual.green / MAX_HEX;
1089
- const red = actual.red / MAX_HEX;
1090
- const max = Math.max(blue, green, red);
1091
- const min = Math.min(blue, green, red);
1092
- const delta = max - min;
1093
- const lightness = (min + max) / 2;
1094
- let hue = 0;
1095
- let saturation = 0;
1096
- if (delta !== 0) {
1097
- saturation =
1098
- lightness === 0 || lightness === 1
1099
- ? 0
1100
- : (max - lightness) / Math.min(lightness, 1 - lightness);
1101
- switch (max) {
1102
- case blue:
1103
- hue = (red - green) / delta + 4;
1104
- break;
1105
- case green:
1106
- hue = (blue - red) / delta + 2;
1107
- break;
1108
- case red:
1109
- hue = (green - blue) / delta + (green < blue ? 6 : 0);
1110
- break;
1111
- }
1112
- hue *= 60;
1113
- }
1114
- if (saturation < 0) {
1115
- hue += MAX_DEGREE / 2;
1116
- saturation = Math.abs(saturation);
1117
- }
1118
- if (hue >= MAX_DEGREE) {
1119
- hue -= MAX_DEGREE;
1120
- }
1121
- return {
1122
- alpha: getAlphaValue(rgb.alpha ?? ALPHA_FULL_VALUE),
1123
- hue: +hue.toFixed(2),
1124
- lightness: +(lightness * MAX_PERCENT).toFixed(2),
1125
- saturation: +(saturation * MAX_PERCENT).toFixed(2),
1126
- };
1127
- }
1128
- /**
1129
- * Convert an RGB(A) color to a hex color _(with optional alpha channel)_
1130
- * @param rgb RGB(A) color
1131
- * @param alpha Include alpha channel? _(defaults to `false`)_
1132
- * @returns Hex color
1133
- */
713
+ const hex = `${join([
714
+ rgb.red,
715
+ rgb.green,
716
+ rgb.blue
717
+ ].map((color) => {
718
+ const hex$1 = color.toString(16);
719
+ return hex$1.length === 1 ? `0${hex$1}` : hex$1;
720
+ }))}`;
721
+ let a = "";
722
+ if (typeof alpha === "boolean" && alpha) a = getAlpha(rgb.alpha).hex;
723
+ return `${hex}${a}`;
724
+ }
725
+ function convertRgbToHsla(value) {
726
+ const rgb = isRgbLike(value) ? getRgbValue(value) : { ...DEFAULT_RGB };
727
+ const blue = rgb.blue / MAX_HEX;
728
+ const green = rgb.green / MAX_HEX;
729
+ const red = rgb.red / MAX_HEX;
730
+ const max$1 = Math.max(blue, green, red);
731
+ const min$1 = Math.min(blue, green, red);
732
+ const delta = max$1 - min$1;
733
+ const lightness = (min$1 + max$1) / 2;
734
+ let hue = 0;
735
+ let saturation = 0;
736
+ if (delta !== 0) {
737
+ saturation = (max$1 - lightness) / Math.min(lightness, 1 - lightness);
738
+ switch (max$1) {
739
+ case blue:
740
+ hue = (red - green) / delta + 4;
741
+ break;
742
+ case green:
743
+ hue = (blue - red) / delta + 2;
744
+ break;
745
+ case red:
746
+ hue = (green - blue) / delta + (green < blue ? 6 : 0);
747
+ break;
748
+ }
749
+ hue *= 60;
750
+ }
751
+ return {
752
+ alpha: getAlphaValue(value.alpha ?? ALPHA_FULL_VALUE),
753
+ hue: +hue.toFixed(2),
754
+ lightness: +(lightness * MAX_PERCENT).toFixed(2),
755
+ saturation: +(saturation * MAX_PERCENT).toFixed(2)
756
+ };
757
+ }
758
+ function getRgbValue(value) {
759
+ return {
760
+ blue: getHexValue(value.blue),
761
+ green: getHexValue(value.green),
762
+ red: getHexValue(value.red)
763
+ };
764
+ }
1134
765
  function rgbToHex(rgb, alpha) {
1135
- return convertRgbToHex(isRgbColor(rgb) ? rgb : { ...DEFAULT_RGB }, alpha ?? false);
1136
- }
1137
- /**
1138
- * Convert an RGB(A) color to an HSL color
1139
- *
1140
- * Thanks, https://github.com/color-js/color.js/blob/main/src/spaces/hsl.js#L26
1141
- * @param rgb RGB(A) color
1142
- * @returns HSL color
1143
- */
766
+ return convertRgbToHex(isRgbLike(rgb) ? getRgbValue(rgb) : { ...DEFAULT_RGB }, alpha ?? false);
767
+ }
1144
768
  function rgbToHsl(rgb) {
1145
- const { hue, lightness, saturation } = convertRgbToHsla(rgb);
1146
- return {
1147
- hue,
1148
- lightness,
1149
- saturation,
1150
- };
1151
- }
1152
- /**
1153
- * Convert an RGB(A) color to an HSLA color
1154
- *
1155
- * Thanks, https://github.com/color-js/color.js/blob/main/src/spaces/hsl.js#L26
1156
- * @param rgb RGB(A) color
1157
- * @returns HSLA color
1158
- */
769
+ const { hue, lightness, saturation } = convertRgbToHsla(rgb);
770
+ return {
771
+ hue,
772
+ lightness,
773
+ saturation
774
+ };
775
+ }
1159
776
  function rgbToHsla(rgb) {
1160
- return convertRgbToHsla(rgb);
777
+ return convertRgbToHsla(rgb);
1161
778
  }
1162
-
1163
779
  function convertHexToRgba(value) {
1164
- const normalized = getNormalizedHex(value, true);
1165
- const pairs = EXPRESSION_HEX_LONG.exec(normalized);
1166
- const values = [];
1167
- const { length } = pairs;
1168
- for (let index = 1; index < length; index += 1) {
1169
- values.push(Number.parseInt(pairs[index], 16));
1170
- }
1171
- return {
1172
- alpha: values[3] / MAX_HEX,
1173
- blue: values[2],
1174
- green: values[1],
1175
- red: values[0],
1176
- };
1177
- }
1178
- /**
1179
- * Get the normalized hex color from a value
1180
- * @param value Value to normalize
1181
- * @param alpha Include alpha channel? _(defaults to `false`)_
1182
- * @returns Normalized hex color, or `000000` if the value is unable to be normalized
1183
- */
780
+ const normalized = getNormalizedHex(value, true);
781
+ const pairs = EXPRESSION_HEX_LONG.exec(normalized);
782
+ const values = [];
783
+ const { length } = pairs;
784
+ for (let index = 1; index < length; index += 1) values.push(Number.parseInt(pairs[index], 16));
785
+ return {
786
+ alpha: values[3] / MAX_HEX,
787
+ blue: values[2],
788
+ green: values[1],
789
+ red: values[0]
790
+ };
791
+ }
1184
792
  function getNormalizedHex(value, alpha) {
1185
- const includeAlpha = alpha ?? false;
1186
- if (!isHexColor(value)) {
1187
- return `${HEX_BLACK}${includeAlpha ? ALPHA_FULL_HEX_LONG : ''}`;
1188
- }
1189
- const normalized = value.replace(EXPRESSION_PREFIX, '');
1190
- if (normalized.length < LENGTH_LONG) {
1191
- const hex = normalized.slice(0, LENGTH_SHORT);
1192
- const a = includeAlpha
1193
- ? (normalized[LENGTH_SHORT] ?? ALPHA_FULL_HEX_SHORT)
1194
- : '';
1195
- return join(`${hex}${a}`.split('').map(character => character.repeat(2)));
1196
- }
1197
- const hex = normalized.slice(0, LENGTH_LONG);
1198
- const a = includeAlpha
1199
- ? normalized.slice(LENGTH_LONG) || ALPHA_FULL_HEX_LONG
1200
- : '';
1201
- return `${hex}${a}`;
793
+ const includeAlpha = alpha ?? false;
794
+ if (!isHexColor(value)) return `${HEX_BLACK}${includeAlpha ? ALPHA_FULL_HEX_LONG : ""}`;
795
+ const normalized = value.replace(EXPRESSION_PREFIX, "");
796
+ if (normalized.length < LENGTH_LONG) return join(`${normalized.slice(0, LENGTH_SHORT)}${includeAlpha ? normalized[LENGTH_SHORT] ?? ALPHA_FULL_HEX_SHORT : ""}`.split("").map((character) => character.repeat(2)));
797
+ return `${normalized.slice(0, LENGTH_LONG)}${includeAlpha ? normalized.slice(LENGTH_LONG) || ALPHA_FULL_HEX_LONG : ""}`;
1202
798
  }
1203
799
  function hexToHsl(value) {
1204
- const { hue, lightness, saturation } = hexToHsla(value);
1205
- return {
1206
- hue,
1207
- lightness,
1208
- saturation,
1209
- };
800
+ const { hue, lightness, saturation } = hexToHsla(value);
801
+ return {
802
+ hue,
803
+ lightness,
804
+ saturation
805
+ };
1210
806
  }
1211
807
  function hexToHsla(value) {
1212
- return convertRgbToHsla(convertHexToRgba(value));
808
+ return convertRgbToHsla(convertHexToRgba(value));
1213
809
  }
1214
- /**
1215
- * Convert a hex color to an RGB color
1216
- * @param value Original value
1217
- * @returns RGB color
1218
- */
1219
810
  function hexToRgb(value) {
1220
- const { blue, green, red } = convertHexToRgba(value);
1221
- return { blue, green, red };
1222
- }
1223
- /**
1224
- * Convert a hex color to an RGBA color
1225
- * @param value Original value
1226
- * @returns RGBA color
1227
- */
811
+ const { blue, green, red } = convertHexToRgba(value);
812
+ return {
813
+ blue,
814
+ green,
815
+ red
816
+ };
817
+ }
1228
818
  function hexToRgba(value) {
1229
- return convertHexToRgba(value);
1230
- }
1231
-
1232
- function convertHslToRgba(hsl) {
1233
- const actual = isHslColor(hsl) ? hsl : { ...DEFAULT_HSL };
1234
- let hue = actual.hue % MAX_DEGREE;
1235
- if (hue < 0) {
1236
- hue += MAX_DEGREE;
1237
- }
1238
- const saturation = actual.saturation / MAX_PERCENT;
1239
- const lightness = actual.lightness / MAX_PERCENT;
1240
- return {
1241
- alpha: getAlphaValue(hsl.alpha ?? ALPHA_FULL_VALUE),
1242
- blue: clamp(Math.round(getHexyValue(hue, lightness, saturation, 4)), 0, MAX_HEX),
1243
- green: clamp(Math.round(getHexyValue(hue, lightness, saturation, 8)), 0, MAX_HEX),
1244
- red: clamp(Math.round(getHexyValue(hue, lightness, saturation, 0)), 0, MAX_HEX),
1245
- };
819
+ return convertHexToRgba(value);
820
+ }
821
+ function convertHslToRgba(value) {
822
+ const hsl = isHslLike(value) ? getHslValue(value) : { ...DEFAULT_HSL };
823
+ const hue = hsl.hue % MAX_DEGREE;
824
+ const saturation = hsl.saturation / MAX_PERCENT;
825
+ const lightness = hsl.lightness / MAX_PERCENT;
826
+ return {
827
+ alpha: getAlphaValue(value.alpha ?? ALPHA_FULL_VALUE),
828
+ blue: getHexValue(Math.round(getHexyValue(hue, lightness, saturation, 4))),
829
+ green: getHexValue(Math.round(getHexyValue(hue, lightness, saturation, 8))),
830
+ red: getHexValue(Math.round(getHexyValue(hue, lightness, saturation, 0)))
831
+ };
1246
832
  }
1247
833
  function getHexyValue(hue, lightness, saturation, value) {
1248
- const part = (value + hue / 30) % 12;
1249
- const mod = saturation * Math.min(lightness, 1 - lightness);
1250
- return ((lightness - mod * Math.max(-1, Math.min(part - 3, 9 - part, 1))) * MAX_HEX);
834
+ const part = (value + hue / 30) % 12;
835
+ return (lightness - saturation * Math.min(lightness, 1 - lightness) * Math.max(-1, Math.min(part - 3, 9 - part, 1))) * MAX_HEX;
836
+ }
837
+ function getHslValue(value) {
838
+ return {
839
+ hue: getDegrees(value.hue),
840
+ lightness: getPercentage(value.lightness),
841
+ saturation: getPercentage(value.saturation)
842
+ };
1251
843
  }
1252
844
  function hslToHex(hsl, alpha) {
1253
- return convertRgbToHex(convertHslToRgba(hsl), alpha ?? false);
1254
- }
1255
- /**
1256
- * Convert an HSL(A) color to an RGB color
1257
- *
1258
- * Thanks, https://github.com/color-js/color.js/blob/main/src/spaces/hsl.js#L61
1259
- * @param hsl HSL(A) color
1260
- * @returns RGB color
1261
- */
845
+ return convertRgbToHex(convertHslToRgba(hsl), alpha ?? false);
846
+ }
1262
847
  function hslToRgb(hsl) {
1263
- const { blue, green, red } = convertHslToRgba(hsl);
1264
- return {
1265
- blue,
1266
- green,
1267
- red,
1268
- };
1269
- }
1270
- /**
1271
- * Convert an HSL(A) color to an RGBA color
1272
- *
1273
- * Thanks, https://github.com/color-js/color.js/blob/main/src/spaces/hsl.js#L61
1274
- * @param hsl HSL(A) color
1275
- * @returns RGBA color
1276
- */
848
+ const { blue, green, red } = convertHslToRgba(hsl);
849
+ return {
850
+ blue,
851
+ green,
852
+ red
853
+ };
854
+ }
1277
855
  function hslToRgba(hsl) {
1278
- return convertHslToRgba(hsl);
856
+ return convertHslToRgba(hsl);
1279
857
  }
1280
-
1281
858
  function getState(value) {
1282
- if (typeof value === 'string') {
1283
- const normalized = getNormalizedHex(value, true);
1284
- const hex = normalized.slice(0, LENGTH_LONG);
1285
- const rgb = hexToRgb(hex);
1286
- return {
1287
- hex,
1288
- rgb,
1289
- alpha: getAlpha(normalized.slice(LENGTH_LONG)),
1290
- hsl: rgbToHsl(rgb),
1291
- };
1292
- }
1293
- if (isColor(value)) {
1294
- return {
1295
- hex: value.hex,
1296
- hsl: value.hsl,
1297
- rgb: value.rgb,
1298
- alpha: getAlpha(value.alpha),
1299
- };
1300
- }
1301
- const state = {};
1302
- if (typeof value === 'object' && value !== null) {
1303
- state.alpha = getAlpha(value.alpha);
1304
- if (isHslColor(value)) {
1305
- state.hsl = {
1306
- hue: clamp(value.hue, 0, MAX_DEGREE),
1307
- lightness: clamp(value.lightness, 0, MAX_PERCENT),
1308
- saturation: clamp(value.saturation, 0, MAX_PERCENT),
1309
- };
1310
- state.rgb = hslToRgb(state.hsl);
1311
- state.hex = rgbToHex(state.rgb);
1312
- return state;
1313
- }
1314
- if (isRgbColor(value)) {
1315
- state.rgb = {
1316
- blue: clamp(value.blue, 0, MAX_HEX),
1317
- green: clamp(value.green, 0, MAX_HEX),
1318
- red: clamp(value.red, 0, MAX_HEX),
1319
- };
1320
- state.hex = rgbToHex(state.rgb);
1321
- state.hsl = rgbToHsl(state.rgb);
1322
- return state;
1323
- }
1324
- }
1325
- state.alpha ??= getAlpha(ALPHA_FULL_VALUE);
1326
- state.hex ??= String(HEX_BLACK);
1327
- state.hsl ??= { ...DEFAULT_HSL };
1328
- state.rgb ??= { ...DEFAULT_RGB };
1329
- return state;
859
+ if (typeof value === "string") {
860
+ const normalized = getNormalizedHex(value, true);
861
+ const hex = normalized.slice(0, LENGTH_LONG);
862
+ const rgb = hexToRgb(hex);
863
+ return {
864
+ hex,
865
+ rgb,
866
+ alpha: getAlpha(normalized.slice(LENGTH_LONG)),
867
+ hsl: rgbToHsl(rgb)
868
+ };
869
+ }
870
+ if (isColor(value)) return {
871
+ hex: value.hex,
872
+ hsl: value.hsl,
873
+ rgb: value.rgb,
874
+ alpha: getAlpha(value.alpha)
875
+ };
876
+ const state = {};
877
+ if (typeof value === "object" && value !== null) {
878
+ state.alpha = getAlpha(value.alpha);
879
+ if (KEYS_HSL.every((key) => key in value)) {
880
+ state.hsl = getHslValue(value);
881
+ state.rgb = hslToRgb(state.hsl);
882
+ state.hex = rgbToHex(state.rgb);
883
+ return state;
884
+ }
885
+ if (KEYS_RGB.every((key) => key in value)) {
886
+ state.rgb = getRgbValue(value);
887
+ state.hex = rgbToHex(state.rgb);
888
+ state.hsl = rgbToHsl(state.rgb);
889
+ return state;
890
+ }
891
+ }
892
+ state.alpha ??= getAlpha(ALPHA_FULL_VALUE);
893
+ state.hex ??= String(HEX_BLACK);
894
+ state.hsl ??= { ...DEFAULT_HSL };
895
+ state.rgb ??= { ...DEFAULT_RGB };
896
+ return state;
1330
897
  }
1331
898
  function setHexColor(state, value, alpha) {
1332
- if (!isHexColor(value) || (!alpha && value === state.hex)) {
1333
- return;
1334
- }
1335
- const normalized = getNormalizedHex(value, true);
1336
- const hex = normalized.slice(0, LENGTH_LONG);
1337
- const rgb = hexToRgb(hex);
1338
- state.hex = hex;
1339
- state.hsl = rgbToHsl(rgb);
1340
- state.rgb = rgb;
1341
- if (alpha) {
1342
- state.alpha = getAlpha(normalized.slice(LENGTH_LONG));
1343
- }
899
+ if (!isHexColor(value) || !alpha && value === state.hex) return;
900
+ const normalized = getNormalizedHex(value, true);
901
+ const hex = normalized.slice(0, LENGTH_LONG);
902
+ const rgb = hexToRgb(hex);
903
+ state.hex = hex;
904
+ state.hsl = rgbToHsl(rgb);
905
+ state.rgb = rgb;
906
+ if (alpha) state.alpha = getAlpha(normalized.slice(LENGTH_LONG));
1344
907
  }
1345
908
  function setHSLColor(state, value, alpha) {
1346
- if (!isHslColor(value)) {
1347
- return;
1348
- }
1349
- const rgb = hslToRgb(value);
1350
- state.hex = rgbToHex(rgb);
1351
- state.hsl = value;
1352
- state.rgb = rgb;
1353
- if (alpha) {
1354
- state.alpha = getAlpha(value.alpha);
1355
- }
909
+ if (!isHslLike(value)) return;
910
+ const hsl = {
911
+ hue: getDegrees(value.hue),
912
+ lightness: getPercentage(value.lightness),
913
+ saturation: getPercentage(value.saturation)
914
+ };
915
+ const rgb = hslToRgb(hsl);
916
+ state.hex = rgbToHex(rgb);
917
+ state.hsl = hsl;
918
+ state.rgb = rgb;
919
+ if (alpha) state.alpha = getAlpha(value.alpha);
1356
920
  }
1357
921
  function setRGBColor(state, value, alpha) {
1358
- if (!isRgbColor(value)) {
1359
- return;
1360
- }
1361
- state.hex = rgbToHex(value);
1362
- state.hsl = rgbToHsl(value);
1363
- state.rgb = value;
1364
- if (alpha) {
1365
- state.alpha = getAlpha(value.alpha);
1366
- }
1367
- }
1368
-
1369
- class Color {
1370
- #state;
1371
- /**
1372
- * Get the alpha channel
1373
- */
1374
- get alpha() {
1375
- return this.#state.alpha.value;
1376
- }
1377
- /**
1378
- * Set the alpha channel
1379
- */
1380
- set alpha(value) {
1381
- if (typeof value === 'number' && !Number.isNaN(value)) {
1382
- this.#state.alpha = getAlpha(value);
1383
- }
1384
- }
1385
- /**
1386
- * Get the color as a hex color
1387
- */
1388
- get hex() {
1389
- return this.#state.hex;
1390
- }
1391
- /**
1392
- * Set colors from a hex color
1393
- */
1394
- set hex(value) {
1395
- setHexColor(this.#state, value, false);
1396
- }
1397
- /**
1398
- * Get the color as a hex color with an alpha channel
1399
- */
1400
- get hexa() {
1401
- return `${this.#state.hex}${this.#state.alpha.hex}`;
1402
- }
1403
- /**
1404
- * Set colors and alpha from a hex color with an alpha channel
1405
- */
1406
- set hexa(value) {
1407
- setHexColor(this.#state, value, true);
1408
- }
1409
- /**
1410
- * Get the color as an HSL color
1411
- */
1412
- get hsl() {
1413
- return this.#state.hsl;
1414
- }
1415
- /**
1416
- * Set colors from an HSL color
1417
- */
1418
- set hsl(value) {
1419
- setHSLColor(this.#state, value, false);
1420
- }
1421
- /**
1422
- * Get the color as an HSLA color
1423
- */
1424
- get hsla() {
1425
- return {
1426
- ...this.#state.hsl,
1427
- alpha: this.#state.alpha.value,
1428
- };
1429
- }
1430
- /**
1431
- * Set colors and alpha from an HSLA color
1432
- */
1433
- set hsla(value) {
1434
- setHSLColor(this.#state, value, true);
1435
- }
1436
- /**
1437
- * Get the color as an RGB color
1438
- */
1439
- get rgb() {
1440
- return this.#state.rgb;
1441
- }
1442
- /**
1443
- * Set colors from an RGB color
1444
- */
1445
- set rgb(value) {
1446
- setRGBColor(this.#state, value, false);
1447
- }
1448
- /**
1449
- * Get the color as an RGBA color
1450
- */
1451
- get rgba() {
1452
- return {
1453
- ...this.#state.rgb,
1454
- alpha: this.#state.alpha.value,
1455
- };
1456
- }
1457
- /**
1458
- * Set colors and alpha from an RGBA color
1459
- */
1460
- set rgba(value) {
1461
- setRGBColor(this.#state, value, true);
1462
- }
1463
- constructor(value) {
1464
- this.#state = getState(value);
1465
- Object.defineProperty(this, '$color', {
1466
- value: true,
1467
- });
1468
- }
1469
- toHexString(alpha) {
1470
- return `#${alpha === true ? this.hexa : this.hex}`;
1471
- }
1472
- toHslString(alpha) {
1473
- return formatColor('hsl', this, alpha === true);
1474
- }
1475
- toRgbString(alpha) {
1476
- return formatColor('rgb', this, alpha === true);
1477
- }
1478
- toString() {
1479
- return this.toHexString();
1480
- }
1481
- }
1482
-
1483
- /**
1484
- * Get a foreground color _(usually text)_ based on a background color's luminance
1485
- * @param value Original value
1486
- * @returns Foreground color
1487
- */
1488
- function getForegroundColor(value) {
1489
- const state = getState(value);
1490
- const { blue, green, red } = state.rgb;
1491
- const values = [blue / MAX_HEX, green / MAX_HEX, red / MAX_HEX];
1492
- for (let color of values) {
1493
- if (color <= SRGB_LUMINANCE_MINIMUM) {
1494
- color /= SRGB_LUMINANCE_MULTIPLIER;
1495
- }
1496
- else {
1497
- color =
1498
- ((color + SRGB_LUMINANCE_OFFSET) / SRGB_LUMINANCE_MODIFIER) **
1499
- SRGB_LUMINANCE_EXPONENT;
1500
- }
1501
- }
1502
- const luminance = SRGB_LUMINANCE_RED * values[2] +
1503
- SRGB_LUMINANCE_GREEN * values[1] +
1504
- SRGB_LUMINANCE_BLUE * values[0];
1505
- // Rudimentary and ureliable?; implement APCA for more reliable results?
1506
- return new Color(luminance > SRGB_LUMINANCE_THRESHOLD ? HEX_BLACK : HEX_WHITE);
1507
- }
1508
- /**
1509
- * Get the hex color _(with alpha channel)_ from any kind of value
1510
- * @param value Original value
1511
- * @returns Hex color
1512
- */
1513
- function getHexaColor(value) {
1514
- const { alpha, hex } = getState(value);
1515
- return `${hex}${alpha.hex}`;
1516
- }
1517
- /**
1518
- * Get the hex color from any kind of value
1519
- * @param value Original value
1520
- * @returns Hex color
1521
- */
1522
- function getHexColor(value) {
1523
- return getState(value).hex;
1524
- }
1525
- /**
1526
- * Get the HSLA color from any kind of value
1527
- * @param value Original value
1528
- * @returns HSLA color
1529
- */
1530
- function getHslaColor(value) {
1531
- const { alpha, hsl } = getState(value);
1532
- return {
1533
- ...hsl,
1534
- alpha: alpha.value,
1535
- };
1536
- }
1537
- /**
1538
- * Get the HSL color from any kind of value
1539
- * @param value Original value
1540
- * @returns HSL color
1541
- */
1542
- function getHslColor(value) {
1543
- return getState(value).hsl;
1544
- }
1545
- /**
1546
- * Get the RGBA color from any kind of value
1547
- * @param value Original value
1548
- * @returns RGBA color
1549
- */
1550
- function getRgbaColor(value) {
1551
- const { alpha, rgb } = getState(value);
1552
- return {
1553
- ...rgb,
1554
- alpha: alpha.value,
1555
- };
1556
- }
1557
- /**
1558
- * Get the RGB color from any kind of value
1559
- * @param value Original value
1560
- * @returns RGB color
1561
- */
1562
- function getRgbColor(value) {
1563
- return getState(value).rgb;
1564
- }
1565
-
1566
- /**
1567
- * Get a Color from any kind of value
1568
- * @param value Original value
1569
- * @returns Color instance
1570
- */
922
+ if (!isRgbLike(value)) return;
923
+ const rgb = {
924
+ blue: getHexValue(value.blue),
925
+ green: getHexValue(value.green),
926
+ red: getHexValue(value.red)
927
+ };
928
+ state.hex = rgbToHex(rgb);
929
+ state.hsl = rgbToHsl(rgb);
930
+ state.rgb = rgb;
931
+ if (alpha) state.alpha = getAlpha(value.alpha);
932
+ }
933
+ var Color = class {
934
+ #state;
935
+ get alpha() {
936
+ return this.#state.alpha.value;
937
+ }
938
+ set alpha(value) {
939
+ if (typeof value === "number" && !Number.isNaN(value)) this.#state.alpha = getAlpha(value);
940
+ }
941
+ get hex() {
942
+ return this.#state.hex;
943
+ }
944
+ set hex(value) {
945
+ setHexColor(this.#state, value, false);
946
+ }
947
+ get hexa() {
948
+ return `${this.#state.hex}${this.#state.alpha.hex}`;
949
+ }
950
+ set hexa(value) {
951
+ setHexColor(this.#state, value, true);
952
+ }
953
+ get hsl() {
954
+ return this.#state.hsl;
955
+ }
956
+ set hsl(value) {
957
+ setHSLColor(this.#state, value, false);
958
+ }
959
+ get hsla() {
960
+ return {
961
+ ...this.#state.hsl,
962
+ alpha: this.#state.alpha.value
963
+ };
964
+ }
965
+ set hsla(value) {
966
+ setHSLColor(this.#state, value, true);
967
+ }
968
+ get rgb() {
969
+ return this.#state.rgb;
970
+ }
971
+ set rgb(value) {
972
+ setRGBColor(this.#state, value, false);
973
+ }
974
+ get rgba() {
975
+ return {
976
+ ...this.#state.rgb,
977
+ alpha: this.#state.alpha.value
978
+ };
979
+ }
980
+ set rgba(value) {
981
+ setRGBColor(this.#state, value, true);
982
+ }
983
+ constructor(value) {
984
+ this.#state = getState(value);
985
+ Object.defineProperty(this, "$color", { value: true });
986
+ }
987
+ toHexString(alpha) {
988
+ return `#${alpha === true ? this.hexa : this.hex}`;
989
+ }
990
+ toHslString(alpha) {
991
+ return formatColor("hsl", this, alpha === true);
992
+ }
993
+ toRgbString(alpha) {
994
+ return formatColor("rgb", this, alpha === true);
995
+ }
996
+ toString() {
997
+ return this.toHexString();
998
+ }
999
+ };
1571
1000
  function getColor(value) {
1572
- return isColor(value) ? value : new Color(value);
1573
- }
1574
-
1575
- function calculate() {
1576
- return new Promise(resolve => {
1577
- const values = [];
1578
- let last;
1579
- function step(now) {
1580
- if (last != null) {
1581
- values.push(now - last);
1582
- }
1583
- last = now;
1584
- if (values.length >= CALCULATION_TOTAL) {
1585
- const median = values
1586
- .sort()
1587
- .slice(2, -2)
1588
- .reduce((first, second) => first + second, 0) /
1589
- (values.length - CALCULATION_TRIM);
1590
- resolve(median);
1591
- }
1592
- else {
1593
- requestAnimationFrame(step);
1594
- }
1595
- }
1596
- requestAnimationFrame(step);
1597
- });
1598
- }
1599
- /**
1600
- * A function that does nothing, which can be useful, I guess…
1601
- */
1602
- function noop() { }
1603
- //
1604
- const CALCULATION_TOTAL = 10;
1605
- const CALCULATION_TRIM = 4;
1606
- const DEFAULT_FPS = 60;
1607
- const MILLISECONDS_IN_SECOND = 1000;
1608
- /**
1609
- * A calculated average of the refresh rate of the display _(in milliseconds)_
1610
- */
1611
- let milliseconds = MILLISECONDS_IN_SECOND / DEFAULT_FPS;
1612
- calculate().then(value => {
1613
- milliseconds = value;
1614
- });
1615
-
1616
- class Emitter {
1617
- #state;
1618
- /**
1619
- * Is the emitter active?
1620
- */
1621
- get active() {
1622
- return this.#state.active;
1623
- }
1624
- /**
1625
- * The observable that can be subscribed to
1626
- */
1627
- get observable() {
1628
- return this.#state.observable;
1629
- }
1630
- /**
1631
- * The current value
1632
- */
1633
- get value() {
1634
- return this.#state.value;
1635
- }
1636
- constructor(value) {
1637
- const observers = new Map();
1638
- this.#state = {
1639
- observers,
1640
- value,
1641
- active: true,
1642
- observable: new Observable(this, observers),
1643
- };
1644
- }
1645
- /**
1646
- * Destroy the emitter
1647
- */
1648
- destroy() {
1649
- finishEmitter(this.#state, false);
1650
- }
1651
- /**
1652
- * Emit a new value
1653
- * @param value Value to set and emit
1654
- * @param finish Finish the emitter after emitting? _(defaults to `false`)_
1655
- */
1656
- emit(value, finish) {
1657
- this.#on('next', finish ?? false, value);
1658
- }
1659
- /**
1660
- * Emit an error
1661
- * @param error Error to emit
1662
- * @param finish Finish the emitter after emitting? _(defaults to `false`)_
1663
- */
1664
- error(error, finish) {
1665
- this.#on('error', finish ?? false, error);
1666
- }
1667
- /**
1668
- * Finish the emitter
1669
- */
1670
- finish() {
1671
- finishEmitter(this.#state, true);
1672
- }
1673
- #on(type, finish, value) {
1674
- if (this.#state.active) {
1675
- if (type === 'next') {
1676
- this.#state.value = value;
1677
- }
1678
- for (const [, observer] of this.#state.observers) {
1679
- observer[type]?.(value);
1680
- }
1681
- if (finish === true) {
1682
- finishEmitter(this.#state, true);
1683
- }
1684
- }
1685
- }
1686
- }
1687
- class Observable {
1688
- #state;
1689
- constructor(emitter, observers) {
1690
- this.#state = {
1691
- emitter,
1692
- observers,
1693
- closed: false,
1694
- };
1695
- }
1696
- /**
1697
- * Destroy the observable
1698
- */
1699
- destroy() {
1700
- this.#state.closed = true;
1701
- }
1702
- subscribe(first, second, third) {
1703
- if (this.#state.closed) {
1704
- throw new Error('Cannot subscribe to a destroyed observable');
1705
- }
1706
- const observer = getObserver(first, second, third);
1707
- const instance = new Subscription(this.#state);
1708
- this.#state.observers.set(instance, observer);
1709
- observer.next?.(this.#state.emitter.value);
1710
- return instance;
1711
- }
1712
- }
1713
- class Subscription {
1714
- #state;
1715
- constructor(state) {
1716
- this.#state = {
1717
- ...state,
1718
- closed: false,
1719
- };
1720
- }
1721
- /**
1722
- * Is the subscription closed?
1723
- */
1724
- get closed() {
1725
- return this.#state.closed || !this.#state.emitter.active;
1726
- }
1727
- /**
1728
- * Destroy the subscription
1729
- */
1730
- destroy() {
1731
- if (!this.#state.closed) {
1732
- this.unsubscribe();
1733
- }
1734
- }
1735
- /**
1736
- * Unsubscribe from its observable
1737
- */
1738
- unsubscribe() {
1739
- if (!this.#state.closed) {
1740
- this.#state.closed = true;
1741
- this.#state.observers.delete(this);
1742
- }
1743
- }
1744
- }
1745
- /**
1746
- * Create a new emitter
1747
- * @param value Initial value
1748
- * @returns Emitter instance
1749
- */
1001
+ return isColor(value) ? value : new Color(value);
1002
+ }
1003
+ function noop() {}
1004
+ var Emitter = class {
1005
+ #state;
1006
+ get active() {
1007
+ return this.#state.active;
1008
+ }
1009
+ get observable() {
1010
+ return this.#state.observable;
1011
+ }
1012
+ get value() {
1013
+ return this.#state.value;
1014
+ }
1015
+ constructor(value) {
1016
+ const observers = /* @__PURE__ */ new Map();
1017
+ this.#state = {
1018
+ observers,
1019
+ value,
1020
+ active: true,
1021
+ observable: new Observable(this, observers)
1022
+ };
1023
+ }
1024
+ destroy() {
1025
+ finishEmitter(this.#state, false);
1026
+ }
1027
+ emit(value, finish) {
1028
+ this.#on("next", finish ?? false, value);
1029
+ }
1030
+ error(error, finish) {
1031
+ this.#on("error", finish ?? false, error);
1032
+ }
1033
+ finish() {
1034
+ finishEmitter(this.#state, true);
1035
+ }
1036
+ #on(type, finish, value) {
1037
+ if (this.#state.active) {
1038
+ if (type === "next") this.#state.value = value;
1039
+ for (const [, observer] of this.#state.observers) observer[type]?.(value);
1040
+ if (finish === true) finishEmitter(this.#state, true);
1041
+ }
1042
+ }
1043
+ };
1044
+ var Observable = class {
1045
+ #state;
1046
+ constructor(emitter$1, observers) {
1047
+ this.#state = {
1048
+ emitter: emitter$1,
1049
+ observers,
1050
+ closed: false
1051
+ };
1052
+ }
1053
+ destroy() {
1054
+ this.#state.closed = true;
1055
+ }
1056
+ subscribe(first, second, third) {
1057
+ if (this.#state.closed) throw new Error("Cannot subscribe to a destroyed observable");
1058
+ const observer = getObserver(first, second, third);
1059
+ const instance = new Subscription(this.#state);
1060
+ this.#state.observers.set(instance, observer);
1061
+ observer.next?.(this.#state.emitter.value);
1062
+ return instance;
1063
+ }
1064
+ };
1065
+ var Subscription = class {
1066
+ #state;
1067
+ constructor(state) {
1068
+ this.#state = {
1069
+ ...state,
1070
+ closed: false
1071
+ };
1072
+ }
1073
+ get closed() {
1074
+ return this.#state.closed || !this.#state.emitter.active;
1075
+ }
1076
+ destroy() {
1077
+ if (!this.#state.closed) this.unsubscribe();
1078
+ }
1079
+ unsubscribe() {
1080
+ if (!this.#state.closed) {
1081
+ this.#state.closed = true;
1082
+ this.#state.observers.delete(this);
1083
+ }
1084
+ }
1085
+ };
1750
1086
  function emitter(value) {
1751
- return new Emitter(value);
1087
+ return new Emitter(value);
1752
1088
  }
1753
1089
  function finishEmitter(state, emit) {
1754
- if (state.active) {
1755
- state.active = false;
1756
- const entries = [...state.observers.entries()];
1757
- const { length } = entries;
1758
- for (let index = 0; index < length; index += 1) {
1759
- const [subscription, observer] = entries[index];
1760
- if (emit) {
1761
- observer.complete?.();
1762
- }
1763
- subscription.destroy();
1764
- }
1765
- state.observable?.destroy();
1766
- state.observers.clear();
1767
- }
1090
+ if (state.active) {
1091
+ state.active = false;
1092
+ const entries = [...state.observers.entries()];
1093
+ const { length } = entries;
1094
+ for (let index = 0; index < length; index += 1) {
1095
+ const [subscription, observer] = entries[index];
1096
+ if (emit) observer.complete?.();
1097
+ subscription.destroy();
1098
+ }
1099
+ state.observable?.destroy();
1100
+ state.observers.clear();
1101
+ }
1768
1102
  }
1769
1103
  function getFunction(value, defaultValue) {
1770
- return typeof value === 'function' ? value : defaultValue;
1104
+ return typeof value === "function" ? value : defaultValue;
1771
1105
  }
1772
1106
  function getObserver(first, second, third) {
1773
- let observer = {
1774
- next: noop,
1775
- };
1776
- if (typeof first === 'function') {
1777
- observer = {
1778
- error: getFunction(second, noop),
1779
- next: getFunction(first, noop),
1780
- complete: getFunction(third, noop),
1781
- };
1782
- }
1783
- else if (typeof first === 'object') {
1784
- observer.complete = getFunction(first?.complete, noop);
1785
- observer.error = getFunction(first?.error, noop);
1786
- observer.next = getFunction(first?.next, noop);
1787
- }
1788
- return observer;
1789
- }
1790
-
1791
- /**
1792
- * A Map with a maximum size
1793
- *
1794
- * Behaviour is similar to a _LRU_-cache, where the least recently used entries are removed
1795
- */
1796
- class SizedMap extends Map {
1797
- /**
1798
- * The maximum size of the Map
1799
- */
1800
- #maximumSize;
1801
- /**
1802
- * Is the Map full?
1803
- */
1804
- get full() {
1805
- return this.size >= this.#maximumSize;
1806
- }
1807
- get maximum() {
1808
- return this.#maximumSize;
1809
- }
1810
- constructor(first, second) {
1811
- const maximum = getMaximum(first, second);
1812
- super();
1813
- this.#maximumSize = maximum;
1814
- if (Array.isArray(first)) {
1815
- const { length } = first;
1816
- if (length <= maximum) {
1817
- for (let index = 0; index < length; index += 1) {
1818
- this.set(...first[index]);
1819
- }
1820
- }
1821
- else {
1822
- for (let index = 0; index < maximum; index += 1) {
1823
- this.set(...first[length - maximum + index]);
1824
- }
1825
- }
1826
- }
1827
- }
1828
- /**
1829
- * @inheritdoc
1830
- */
1831
- get(key) {
1832
- const value = super.get(key);
1833
- if (value !== undefined || this.has(key)) {
1834
- this.set(key, value);
1835
- }
1836
- return value;
1837
- }
1838
- /**
1839
- * @inheritdoc
1840
- */
1841
- set(key, value) {
1842
- if (this.has(key)) {
1843
- this.delete(key);
1844
- }
1845
- else if (this.size >= this.#maximumSize) {
1846
- this.delete(this.keys().next().value);
1847
- }
1848
- return super.set(key, value);
1849
- }
1850
- }
1851
- /**
1852
- * - A Set with a maximum size
1853
- * - Behaviour is similar to a _LRU_-cache, where the oldest values are removed
1854
- */
1855
- class SizedSet extends Set {
1856
- /**
1857
- * The maximum size of the Set
1858
- */
1859
- #maximumSize;
1860
- /**
1861
- * Is the Set full?
1862
- */
1863
- get full() {
1864
- return this.size >= this.#maximumSize;
1865
- }
1866
- get maximum() {
1867
- return this.#maximumSize;
1868
- }
1869
- constructor(first, second) {
1870
- const maximum = getMaximum(first, second);
1871
- super();
1872
- this.#maximumSize = maximum;
1873
- if (Array.isArray(first)) {
1874
- const { length } = first;
1875
- if (length <= maximum) {
1876
- for (let index = 0; index < length; index += 1) {
1877
- this.add(first[index]);
1878
- }
1879
- }
1880
- else {
1881
- for (let index = 0; index < maximum; index += 1) {
1882
- this.add(first[length - maximum + index]);
1883
- }
1884
- }
1885
- }
1886
- }
1887
- /**
1888
- * @inheritdoc
1889
- */
1890
- add(value) {
1891
- if (this.has(value)) {
1892
- this.delete(value);
1893
- }
1894
- else if (this.size >= this.#maximumSize) {
1895
- this.delete(this.values().next().value);
1896
- }
1897
- return super.add(value);
1898
- }
1899
- /**
1900
- * Get a value from the SizedSet, if it exists _(and move it to the end)_
1901
- * @param value Value to get from the SizedSet
1902
- * @param update Update the value's position in the SizedSet? _(defaults to `false`)_
1903
- * @returns The value if it exists, otherwise `undefined`
1904
- */
1905
- get(value, update) {
1906
- if (this.has(value)) {
1907
- if (update ?? false) {
1908
- this.delete(value);
1909
- this.add(value);
1910
- }
1911
- return value;
1912
- }
1913
- }
1914
- }
1107
+ let observer = { next: noop };
1108
+ if (typeof first === "function") observer = {
1109
+ error: getFunction(second, noop),
1110
+ next: getFunction(first, noop),
1111
+ complete: getFunction(third, noop)
1112
+ };
1113
+ else if (typeof first === "object") {
1114
+ observer.complete = getFunction(first?.complete, noop);
1115
+ observer.error = getFunction(first?.error, noop);
1116
+ observer.next = getFunction(first?.next, noop);
1117
+ }
1118
+ return observer;
1119
+ }
1120
+ var SizedMap = class extends Map {
1121
+ #maximumSize;
1122
+ get full() {
1123
+ return this.size >= this.#maximumSize;
1124
+ }
1125
+ get maximum() {
1126
+ return this.#maximumSize;
1127
+ }
1128
+ constructor(first, second) {
1129
+ const maximum = getMaximum(first, second);
1130
+ super();
1131
+ this.#maximumSize = maximum;
1132
+ if (Array.isArray(first)) {
1133
+ const { length } = first;
1134
+ if (length <= maximum) for (let index = 0; index < length; index += 1) this.set(...first[index]);
1135
+ else for (let index = 0; index < maximum; index += 1) this.set(...first[length - maximum + index]);
1136
+ }
1137
+ }
1138
+ get(key) {
1139
+ const value = super.get(key);
1140
+ if (value !== void 0 || this.has(key)) this.set(key, value);
1141
+ return value;
1142
+ }
1143
+ set(key, value) {
1144
+ if (this.has(key)) this.delete(key);
1145
+ else if (this.size >= this.#maximumSize) this.delete(this.keys().next().value);
1146
+ return super.set(key, value);
1147
+ }
1148
+ };
1149
+ var SizedSet = class extends Set {
1150
+ #maximumSize;
1151
+ get full() {
1152
+ return this.size >= this.#maximumSize;
1153
+ }
1154
+ get maximum() {
1155
+ return this.#maximumSize;
1156
+ }
1157
+ constructor(first, second) {
1158
+ const maximum = getMaximum(first, second);
1159
+ super();
1160
+ this.#maximumSize = maximum;
1161
+ if (Array.isArray(first)) {
1162
+ const { length } = first;
1163
+ if (length <= maximum) for (let index = 0; index < length; index += 1) this.add(first[index]);
1164
+ else for (let index = 0; index < maximum; index += 1) this.add(first[length - maximum + index]);
1165
+ }
1166
+ }
1167
+ add(value) {
1168
+ if (this.has(value)) this.delete(value);
1169
+ else if (this.size >= this.#maximumSize) this.delete(this.values().next().value);
1170
+ return super.add(value);
1171
+ }
1172
+ get(value, update) {
1173
+ if (this.has(value)) {
1174
+ if (update ?? false) {
1175
+ this.delete(value);
1176
+ this.add(value);
1177
+ }
1178
+ return value;
1179
+ }
1180
+ }
1181
+ };
1915
1182
  function getMaximum(first, second) {
1916
- let actual;
1917
- if (typeof first === 'number') {
1918
- actual = first;
1919
- }
1920
- else {
1921
- actual = typeof second === 'number' ? second : MAXIMUM_DEFAULT;
1922
- }
1923
- return clamp(actual, 1, MAXIMUM_ABSOLUTE);
1924
- }
1925
- //
1926
- const MAXIMUM_ABSOLUTE = 16_777_216;
1927
- const MAXIMUM_DEFAULT = 1_048_576;
1928
-
1929
- class Memoized {
1930
- #state;
1931
- /**
1932
- * Maximum cache size
1933
- */
1934
- get maximum() {
1935
- return this.#state.cache?.maximum ?? Number.NaN;
1936
- }
1937
- /**
1938
- * Current cache size
1939
- */
1940
- get size() {
1941
- return this.#state.cache?.size ?? Number.NaN;
1942
- }
1943
- constructor(callback, size) {
1944
- const cache = new SizedMap(size);
1945
- const getter = (...parameters) => {
1946
- const key = parameters.length === 1
1947
- ? parameters[0]
1948
- : join(parameters.map(getString), '_');
1949
- if (cache.has(key)) {
1950
- return cache.get(key);
1951
- }
1952
- const value = callback(...parameters);
1953
- cache.set(key, value);
1954
- return value;
1955
- };
1956
- this.#state = { cache, getter };
1957
- }
1958
- /**
1959
- * Clear the cache
1960
- */
1961
- clear() {
1962
- this.#state.cache?.clear();
1963
- }
1964
- /**
1965
- * Delete a result from the cache
1966
- * @param key Key to delete
1967
- * @returns `true` if the key existed and was removed, otherwise `false`
1968
- */
1969
- delete(key) {
1970
- return this.#state.cache?.delete(key) ?? false;
1971
- }
1972
- /**
1973
- * Destroy the instance _(clearing its cache and removing its callback)_
1974
- */
1975
- destroy() {
1976
- this.#state.cache?.clear();
1977
- this.#state.cache = undefined;
1978
- this.#state.getter = undefined;
1979
- }
1980
- /**
1981
- * Get a result from the cache
1982
- * @param key Key to get
1983
- * @returns The cached result or `undefined` if it does not exist
1984
- */
1985
- get(key) {
1986
- return this.#state.cache?.get(key);
1987
- }
1988
- /**
1989
- * Does the result exist?
1990
- * @param key Key to check
1991
- * @returns `true` if the result exists, otherwise `false`
1992
- */
1993
- has(key) {
1994
- return this.#state.cache?.has(key) ?? false;
1995
- }
1996
- /**
1997
- * Run the callback with the provided parameters
1998
- * @param parameters Parameters to pass to the callback
1999
- * @returns Cached or computed _(then cached)_ result
2000
- */
2001
- run(...parameters) {
2002
- if (this.#state.cache == null || this.#state.getter == null) {
2003
- /* istanbul ignore next */
2004
- throw new Error('The Memoized instance has been destroyed');
2005
- }
2006
- return this.#state.getter(...parameters);
2007
- }
2008
- }
2009
- /**
2010
- * Debounce a function, ensuring it is only called after `time` milliseconds have passed
2011
- *
2012
- * On subsequent calls, the timer is reset and will wait another `time` milliseconds _(and so on...)_
2013
- * @param callback Callback to debounce
2014
- * @param time Time in milliseconds to wait before calling the callback _(defaults to match frame rate)_
2015
- * @returns Debounced callback with a `cancel` method
2016
- */
1183
+ let actual;
1184
+ if (typeof first === "number") actual = first;
1185
+ else actual = typeof second === "number" ? second : MAXIMUM_DEFAULT;
1186
+ return clamp(actual, 1, MAXIMUM_ABSOLUTE);
1187
+ }
1188
+ const MAXIMUM_ABSOLUTE = 16777216;
1189
+ const MAXIMUM_DEFAULT = 1048576;
1190
+ var Memoized = class {
1191
+ #state;
1192
+ get maximum() {
1193
+ return this.#state.cache?.maximum ?? NaN;
1194
+ }
1195
+ get size() {
1196
+ return this.#state.cache?.size ?? NaN;
1197
+ }
1198
+ constructor(callback, size) {
1199
+ const cache = new SizedMap(size);
1200
+ const getter = (...parameters) => {
1201
+ const key = parameters.length === 1 ? parameters[0] : join(parameters.map(getString), "_");
1202
+ if (cache.has(key)) return cache.get(key);
1203
+ const value = callback(...parameters);
1204
+ cache.set(key, value);
1205
+ return value;
1206
+ };
1207
+ this.#state = {
1208
+ cache,
1209
+ getter
1210
+ };
1211
+ }
1212
+ clear() {
1213
+ this.#state.cache?.clear();
1214
+ }
1215
+ delete(key) {
1216
+ return this.#state.cache?.delete(key) ?? false;
1217
+ }
1218
+ destroy() {
1219
+ this.#state.cache?.clear();
1220
+ this.#state.cache = void 0;
1221
+ this.#state.getter = void 0;
1222
+ }
1223
+ get(key) {
1224
+ return this.#state.cache?.get(key);
1225
+ }
1226
+ has(key) {
1227
+ return this.#state.cache?.has(key) ?? false;
1228
+ }
1229
+ run(...parameters) {
1230
+ if (this.#state.cache == null || this.#state.getter == null) throw new Error("The Memoized instance has been destroyed");
1231
+ return this.#state.getter(...parameters);
1232
+ }
1233
+ };
2017
1234
  function debounce(callback, time) {
2018
- const interval = typeof time === 'number' && time >= milliseconds ? time : milliseconds;
2019
- function step(now, parameters) {
2020
- if (interval === milliseconds || now - start >= interval) {
2021
- callback(...parameters);
2022
- }
2023
- else {
2024
- frame = requestAnimationFrame(next => {
2025
- step(next, parameters);
2026
- });
2027
- }
2028
- }
2029
- let frame;
2030
- let start;
2031
- const debounced = (...parameters) => {
2032
- debounced.cancel();
2033
- frame = requestAnimationFrame(now => {
2034
- start = now - milliseconds;
2035
- step(now, parameters);
2036
- });
2037
- };
2038
- debounced.cancel = () => {
2039
- if (frame != null) {
2040
- cancelAnimationFrame(frame);
2041
- frame = undefined;
2042
- }
2043
- };
2044
- return debounced;
2045
- }
2046
- /**
2047
- * Memoize a function, caching and retrieving results based on the first parameter
2048
- * @param callback Callback to memoize
2049
- * @param cacheSize Size of the cache
2050
- * @returns Memoized instance
2051
- */
1235
+ const interval = typeof time === "number" && time >= frame_rate_default ? time : frame_rate_default;
1236
+ function step(now, parameters) {
1237
+ if (interval === frame_rate_default || now - start >= interval) callback(...parameters);
1238
+ else frame = requestAnimationFrame((next) => {
1239
+ step(next, parameters);
1240
+ });
1241
+ }
1242
+ let frame;
1243
+ let start;
1244
+ const debounced = (...parameters) => {
1245
+ debounced.cancel();
1246
+ frame = requestAnimationFrame((now) => {
1247
+ start = now - frame_rate_default;
1248
+ step(now, parameters);
1249
+ });
1250
+ };
1251
+ debounced.cancel = () => {
1252
+ if (frame != null) {
1253
+ cancelAnimationFrame(frame);
1254
+ frame = void 0;
1255
+ }
1256
+ };
1257
+ return debounced;
1258
+ }
2052
1259
  function memoize(callback, cacheSize) {
2053
- return new Memoized(callback, typeof cacheSize === 'number' && cacheSize > 0
2054
- ? cacheSize
2055
- : DEFAULT_CACHE_SIZE);
2056
- }
2057
- /**
2058
- * Throttle a function, ensuring it is only called once every `time` milliseconds
2059
- * @param callback Callback to throttle
2060
- * @param time Time in milliseconds to wait before calling the callback again _(defaults to match frame rate)_
2061
- * @returns Throttled callback with a `cancel` method
2062
- */
1260
+ return new Memoized(callback, typeof cacheSize === "number" && cacheSize > 0 ? cacheSize : DEFAULT_CACHE_SIZE);
1261
+ }
2063
1262
  function throttle(callback, time) {
2064
- const interval = typeof time === 'number' && time >= milliseconds ? time : milliseconds;
2065
- function step(now, parameters) {
2066
- if (interval === milliseconds || now - last >= interval) {
2067
- last = now;
2068
- callback(...parameters);
2069
- }
2070
- else {
2071
- frame = requestAnimationFrame(next => {
2072
- step(next, parameters);
2073
- });
2074
- }
2075
- }
2076
- let last;
2077
- let frame;
2078
- const throttler = (...parameters) => {
2079
- throttler.cancel();
2080
- frame = requestAnimationFrame(now => {
2081
- last ??= now - milliseconds;
2082
- step(now, parameters);
2083
- });
2084
- };
2085
- throttler.cancel = () => {
2086
- if (frame != null) {
2087
- cancelAnimationFrame(frame);
2088
- frame = undefined;
2089
- }
2090
- };
2091
- return throttler;
2092
- }
2093
- //
2094
- const DEFAULT_CACHE_SIZE = 65_536;
2095
-
1263
+ const interval = typeof time === "number" && time >= frame_rate_default ? time : frame_rate_default;
1264
+ function step(now, parameters) {
1265
+ if (interval === frame_rate_default || now - last >= interval) {
1266
+ last = now;
1267
+ callback(...parameters);
1268
+ } else frame = requestAnimationFrame((next) => {
1269
+ step(next, parameters);
1270
+ });
1271
+ }
1272
+ let last;
1273
+ let frame;
1274
+ const throttler = (...parameters) => {
1275
+ throttler.cancel();
1276
+ frame = requestAnimationFrame((now) => {
1277
+ last ??= now - frame_rate_default;
1278
+ step(now, parameters);
1279
+ });
1280
+ };
1281
+ throttler.cancel = () => {
1282
+ if (frame != null) {
1283
+ cancelAnimationFrame(frame);
1284
+ frame = void 0;
1285
+ }
1286
+ };
1287
+ return throttler;
1288
+ }
1289
+ const DEFAULT_CACHE_SIZE = 65536;
2096
1290
  let enabled = true;
2097
- class Logger {
2098
- /**
2099
- * Log any number of values at the "debug" log level
2100
- */
2101
- get debug() {
2102
- return enabled ? console.debug : noop;
2103
- }
2104
- /**
2105
- * Log the value and shows all its properties
2106
- */
2107
- get dir() {
2108
- return enabled ? console.dir : noop;
2109
- }
2110
- /**
2111
- * Is logging to the console enabled? _(defaults to `true`)_
2112
- */
2113
- get enabled() {
2114
- return enabled;
2115
- }
2116
- /**
2117
- * Enable or disable logging to the console
2118
- */
2119
- set enabled(value) {
2120
- enabled = typeof value === 'boolean' ? value : enabled;
2121
- }
2122
- /**
2123
- * Log any number of values at the "error" log level
2124
- */
2125
- get error() {
2126
- return enabled ? console.error : noop;
2127
- }
2128
- /**
2129
- * Log any number of values at the "info" log level
2130
- */
2131
- get info() {
2132
- return enabled ? console.info : noop;
2133
- }
2134
- /**
2135
- * Log any number of values at the "log" log level
2136
- */
2137
- get log() {
2138
- return enabled ? console.log : noop;
2139
- }
2140
- /**
2141
- * Log data as a table, with optional properties to use as columns
2142
- */
2143
- get table() {
2144
- return enabled ? console.table : noop;
2145
- }
2146
- /**
2147
- * Log any number of values together with a trace from where it was called
2148
- */
2149
- get trace() {
2150
- return enabled ? console.trace : noop;
2151
- }
2152
- /**
2153
- * Log any number of values at the "warn" log level
2154
- */
2155
- get warn() {
2156
- return enabled ? console.warn : noop;
2157
- }
2158
- /**
2159
- * Start a logged timer with a label
2160
- * @param label Label for the timer
2161
- * @returns Time instance
2162
- */
2163
- time(label) {
2164
- return new Time(label);
2165
- }
2166
- }
2167
- class Time {
2168
- #state;
2169
- constructor(label) {
2170
- this.#state = {
2171
- label,
2172
- started: enabled,
2173
- stopped: false,
2174
- };
2175
- if (this.#state.started) {
2176
- console.time(label);
2177
- }
2178
- }
2179
- /**
2180
- * Log the current duration of the timer _(ignored if logging is disabled)_
2181
- */
2182
- log() {
2183
- if (this.#state.started && !this.#state.stopped && enabled) {
2184
- console.timeLog(this.#state.label);
2185
- }
2186
- }
2187
- /**
2188
- * Stop the timer and logs the total duration
2189
- *
2190
- * _(Will always log the total duration, even if logging is disabled)_
2191
- */
2192
- stop() {
2193
- if (this.#state.started && !this.#state.stopped) {
2194
- this.#state.stopped = true;
2195
- console.timeEnd(this.#state.label);
2196
- }
2197
- }
2198
- }
1291
+ var Logger = class {
1292
+ get debug() {
1293
+ return enabled ? console.debug : noop;
1294
+ }
1295
+ get dir() {
1296
+ return enabled ? console.dir : noop;
1297
+ }
1298
+ get enabled() {
1299
+ return enabled;
1300
+ }
1301
+ set enabled(value) {
1302
+ enabled = typeof value === "boolean" ? value : enabled;
1303
+ }
1304
+ get error() {
1305
+ return enabled ? console.error : noop;
1306
+ }
1307
+ get info() {
1308
+ return enabled ? console.info : noop;
1309
+ }
1310
+ get log() {
1311
+ return enabled ? console.log : noop;
1312
+ }
1313
+ get table() {
1314
+ return enabled ? console.table : noop;
1315
+ }
1316
+ get trace() {
1317
+ return enabled ? console.trace : noop;
1318
+ }
1319
+ get warn() {
1320
+ return enabled ? console.warn : noop;
1321
+ }
1322
+ time(label) {
1323
+ return new Time(label);
1324
+ }
1325
+ };
1326
+ var Time = class {
1327
+ #state;
1328
+ constructor(label) {
1329
+ this.#state = {
1330
+ label,
1331
+ started: enabled,
1332
+ stopped: false
1333
+ };
1334
+ if (this.#state.started) console.time(label);
1335
+ }
1336
+ log() {
1337
+ if (this.#state.started && !this.#state.stopped && enabled) console.timeLog(this.#state.label);
1338
+ }
1339
+ stop() {
1340
+ if (this.#state.started && !this.#state.stopped) {
1341
+ this.#state.stopped = true;
1342
+ console.timeEnd(this.#state.label);
1343
+ }
1344
+ }
1345
+ };
2199
1346
  const logger = new Logger();
2200
-
2201
1347
  function average(array, key) {
2202
- const aggregated = aggregate('average', array, key);
2203
- return aggregated.count > 0
2204
- ? aggregated.value / aggregated.count
2205
- : Number.NaN;
1348
+ const aggregated = aggregate("average", array, key);
1349
+ return aggregated.count > 0 ? aggregated.value / aggregated.count : NaN;
2206
1350
  }
2207
1351
  function count(array, key, value) {
2208
- if (!Array.isArray(array)) {
2209
- return Number.NaN;
2210
- }
2211
- const { length } = array;
2212
- if (key == null) {
2213
- return length;
2214
- }
2215
- if (typeof key !== 'string' && typeof key !== 'function') {
2216
- return Number.NaN;
2217
- }
2218
- const callback = typeof key === 'function'
2219
- ? key
2220
- : (item) => item[key];
2221
- let count = 0;
2222
- for (let index = 0; index < length; index += 1) {
2223
- const item = array[index];
2224
- if (Object.is(callback(item, index, array), value)) {
2225
- count += 1;
2226
- }
2227
- }
2228
- return count;
1352
+ if (!Array.isArray(array)) return NaN;
1353
+ const { length } = array;
1354
+ if (key == null) return length;
1355
+ if (typeof key !== "string" && typeof key !== "function") return NaN;
1356
+ const callback = typeof key === "function" ? key : (item) => item[key];
1357
+ let count$1 = 0;
1358
+ for (let index = 0; index < length; index += 1) {
1359
+ const item = array[index];
1360
+ if (Object.is(callback(item, index, array), value)) count$1 += 1;
1361
+ }
1362
+ return count$1;
2229
1363
  }
2230
1364
  function min(array, key) {
2231
- const aggregated = aggregate('min', array, key);
2232
- return aggregated.count > 0 ? aggregated.value : Number.NaN;
2233
- }
2234
- /**
2235
- * Round a number
2236
- * @param value Number to round
2237
- * @param decimals Number of decimal places to round to _(defaults to `0`)_
2238
- * @returns Rounded number, or `NaN` if the value if unable to be rounded
2239
- */
1365
+ const aggregated = aggregate("min", array, key);
1366
+ return aggregated.count > 0 ? aggregated.value : NaN;
1367
+ }
2240
1368
  function round(value, decimals) {
2241
- if (typeof value !== 'number') {
2242
- return Number.NaN;
2243
- }
2244
- if (typeof decimals !== 'number' || decimals < 1) {
2245
- return Math.round(value);
2246
- }
2247
- const mod = 10 ** decimals;
2248
- return Math.round((value + Number.EPSILON) * mod) / mod;
1369
+ if (typeof value !== "number") return NaN;
1370
+ if (typeof decimals !== "number" || decimals < 1) return Math.round(value);
1371
+ const mod = 10 ** decimals;
1372
+ return Math.round((value + Number.EPSILON) * mod) / mod;
2249
1373
  }
2250
1374
  function sum(array, key) {
2251
- const aggregated = aggregate('sum', array, key);
2252
- return aggregated.count > 0 ? aggregated.value : Number.NaN;
1375
+ const aggregated = aggregate("sum", array, key);
1376
+ return aggregated.count > 0 ? aggregated.value : NaN;
2253
1377
  }
2254
-
2255
1378
  function findKey(needle, haystack) {
2256
- const keys = Object.keys(haystack);
2257
- const normalized = keys.map(key => key.toLowerCase());
2258
- const index = normalized.indexOf(needle.toLowerCase());
2259
- return index > -1 ? keys[index] : needle;
1379
+ const keys = Object.keys(haystack);
1380
+ const index = keys.map((key) => key.toLowerCase()).indexOf(needle.toLowerCase());
1381
+ return index > -1 ? keys[index] : needle;
2260
1382
  }
2261
1383
  function getPaths(path, lowercase) {
2262
- const normalized = lowercase ? path.toLowerCase() : path;
2263
- if (!EXPRESSION_NESTED.test(normalized)) {
2264
- return normalized;
2265
- }
2266
- return normalized
2267
- .replace(EXPRESSION_BRACKET, '.$1')
2268
- .replace(EXPRESSION_DOTS, '')
2269
- .split('.');
1384
+ const normalized = lowercase ? path.toLowerCase() : path;
1385
+ if (!EXPRESSION_NESTED.test(normalized)) return normalized;
1386
+ return normalized.replace(EXPRESSION_BRACKET, ".$1").replace(EXPRESSION_DOTS, "").split(".");
2270
1387
  }
2271
1388
  function handleValue(data, path, value, get, ignoreCase) {
2272
- if (typeof data === 'object' && data !== null && !ignoreKey(path)) {
2273
- const key = ignoreCase ? findKey(path, data) : path;
2274
- if (get) {
2275
- return data[key];
2276
- }
2277
- data[key] = value;
2278
- }
2279
- }
2280
- //
1389
+ if (typeof data === "object" && data !== null && !ignoreKey(path)) {
1390
+ const key = ignoreCase ? findKey(path, data) : path;
1391
+ if (get) return data[key];
1392
+ data[key] = value;
1393
+ }
1394
+ }
2281
1395
  const EXPRESSION_BRACKET = /\[(\w+)\]/g;
2282
1396
  const EXPRESSION_DOTS = /^\.|\.$/g;
2283
1397
  const EXPRESSION_NESTED = /\.|\[\w+\]/;
2284
-
2285
1398
  function setValue(data, path, value, ignoreCase) {
2286
- if (typeof data !== 'object' ||
2287
- data === null ||
2288
- typeof path !== 'string' ||
2289
- path.trim().length === 0) {
2290
- return data;
2291
- }
2292
- const shouldIgnoreCase = ignoreCase === true;
2293
- const paths = getPaths(path, shouldIgnoreCase);
2294
- if (typeof paths === 'string') {
2295
- handleValue(data, paths, value, false, shouldIgnoreCase);
2296
- return data;
2297
- }
2298
- const { length } = paths;
2299
- const lastIndex = length - 1;
2300
- let target = data;
2301
- for (let index = 0; index < length; index += 1) {
2302
- const path = paths[index];
2303
- if (index === lastIndex) {
2304
- handleValue(target, path, value, false, shouldIgnoreCase);
2305
- break;
2306
- }
2307
- let next = handleValue(target, path, null, true, shouldIgnoreCase);
2308
- if (typeof next !== 'object' || next === null) {
2309
- const nextPath = paths[index + 1];
2310
- if (EXPRESSION_INDEX.test(nextPath)) {
2311
- const length = Number.parseInt(nextPath, 10) + 1;
2312
- next = Array.from({ length }, () => undefined);
2313
- }
2314
- else {
2315
- next = {};
2316
- }
2317
- target[path] = next;
2318
- }
2319
- target = next;
2320
- }
2321
- return data;
2322
- }
2323
- //
1399
+ if (typeof data !== "object" || data === null || typeof path !== "string" || path.trim().length === 0) return data;
1400
+ const shouldIgnoreCase = ignoreCase === true;
1401
+ const paths = getPaths(path, shouldIgnoreCase);
1402
+ if (typeof paths === "string") {
1403
+ handleValue(data, paths, value, false, shouldIgnoreCase);
1404
+ return data;
1405
+ }
1406
+ const { length } = paths;
1407
+ const lastIndex = length - 1;
1408
+ let target = data;
1409
+ for (let index = 0; index < length; index += 1) {
1410
+ const path$1 = paths[index];
1411
+ if (index === lastIndex) {
1412
+ handleValue(target, path$1, value, false, shouldIgnoreCase);
1413
+ break;
1414
+ }
1415
+ let next = handleValue(target, path$1, null, true, shouldIgnoreCase);
1416
+ if (typeof next !== "object" || next === null) {
1417
+ const nextPath = paths[index + 1];
1418
+ if (EXPRESSION_INDEX.test(nextPath)) {
1419
+ const length$1 = Number.parseInt(nextPath, 10) + 1;
1420
+ next = Array.from({ length: length$1 }, () => void 0);
1421
+ } else next = {};
1422
+ target[path$1] = next;
1423
+ }
1424
+ target = next;
1425
+ }
1426
+ return data;
1427
+ }
2324
1428
  const EXPRESSION_INDEX = /^\d+$/;
2325
-
2326
- /**
2327
- * Convert a query string to a plain _(nested)_ object
2328
- * @param query Query string to convert
2329
- * @returns Plain object representation of the query string
2330
- */
2331
1429
  function fromQuery(query) {
2332
- if (typeof query !== 'string' || query.trim().length === 0) {
2333
- return {};
2334
- }
2335
- const parts = query.split('&');
2336
- const { length } = parts;
2337
- const parameters = {};
2338
- for (let index = 0; index < length; index += 1) {
2339
- const decoded = parts[index].split('=').map(tryDecode);
2340
- const key = decoded[0].replace(EXPRESSION_ARRAY_SUFFIX, '');
2341
- if (!ignoreKey(key)) {
2342
- setQueryValue(parameters, key, decoded[1]);
2343
- }
2344
- }
2345
- return parameters;
1430
+ if (typeof query !== "string" || query.trim().length === 0) return {};
1431
+ const parts = query.split("&");
1432
+ const { length } = parts;
1433
+ const parameters = {};
1434
+ for (let index = 0; index < length; index += 1) {
1435
+ const decoded = parts[index].split("=").map(tryDecode);
1436
+ const key = decoded[0].replace(EXPRESSION_ARRAY_SUFFIX, "");
1437
+ if (!ignoreKey(key)) setQueryValue(parameters, key, decoded[1]);
1438
+ }
1439
+ return parameters;
2346
1440
  }
2347
1441
  function getParts(value, fromArray, prefix) {
2348
- const keys = Object.keys(value);
2349
- const { length } = keys;
2350
- const parts = [];
2351
- for (let index = 0; index < length; index += 1) {
2352
- const key = keys[index];
2353
- const val = value[key];
2354
- const full = join([prefix, fromArray ? undefined : key], '.');
2355
- if (Array.isArray(val)) {
2356
- parts.push(...getParts(val, true, full));
2357
- }
2358
- else if (isPlainObject(val)) {
2359
- parts.push(...getParts(val, false, full));
2360
- }
2361
- else if (isDecodable(val)) {
2362
- parts.push(`${tryEncode(full)}=${tryEncode(val)}`);
2363
- }
2364
- else if (val instanceof Date) {
2365
- parts.push(`${tryEncode(full)}=${val.toJSON()}`);
2366
- }
2367
- }
2368
- return parts;
1442
+ const keys = Object.keys(value);
1443
+ const { length } = keys;
1444
+ const parts = [];
1445
+ for (let index = 0; index < length; index += 1) {
1446
+ const key = keys[index];
1447
+ const val = value[key];
1448
+ const full = join([prefix, fromArray ? void 0 : key], ".");
1449
+ if (Array.isArray(val)) parts.push(...getParts(val, true, full));
1450
+ else if (isPlainObject(val)) parts.push(...getParts(val, false, full));
1451
+ else if (isDecodable(val)) parts.push(`${tryEncode(full)}=${tryEncode(val)}`);
1452
+ else if (val instanceof Date) parts.push(`${tryEncode(full)}=${val.toJSON()}`);
1453
+ }
1454
+ return parts;
2369
1455
  }
2370
1456
  function getValue$1(value) {
2371
- if (EXPRESSION_BOOLEAN.test(value)) {
2372
- return value === 'true';
2373
- }
2374
- const asNumber = getNumber(value);
2375
- if (!Number.isNaN(asNumber)) {
2376
- return asNumber;
2377
- }
2378
- const parsed = Date.parse(value);
2379
- if (Number.isNaN(parsed)) {
2380
- return value;
2381
- }
2382
- const date = new Date(parsed);
2383
- return date.toJSON() === value ? date : value;
1457
+ if (EXPRESSION_BOOLEAN.test(value)) return value === "true";
1458
+ const asNumber = getNumber(value);
1459
+ if (!Number.isNaN(asNumber)) return asNumber;
1460
+ const parsed = Date.parse(value);
1461
+ if (Number.isNaN(parsed)) return value;
1462
+ const date = new Date(parsed);
1463
+ return date.toJSON() === value ? date : value;
2384
1464
  }
2385
1465
  function isDecodable(value) {
2386
- return TYPES.has(typeof value);
1466
+ return TYPES.has(typeof value);
2387
1467
  }
2388
1468
  function setQueryValue(parameters, key, value) {
2389
- if (key.includes('.')) {
2390
- setValue(parameters, key, getValue$1(value));
2391
- }
2392
- else {
2393
- if (key in parameters) {
2394
- if (!Array.isArray(parameters[key])) {
2395
- parameters[key] = [parameters[key]];
2396
- }
2397
- parameters[key].push(getValue$1(value));
2398
- }
2399
- else {
2400
- parameters[key] = getValue$1(value);
2401
- }
2402
- }
2403
- }
2404
- /**
2405
- * Convert a plain _(nested)_ object to a query string
2406
- * @param parameters Plain object to convert
2407
- * @returns Query string representation of the object
2408
- */
1469
+ if (key.includes(".")) setValue(parameters, key, getValue$1(value));
1470
+ else if (key in parameters) {
1471
+ if (!Array.isArray(parameters[key])) parameters[key] = [parameters[key]];
1472
+ parameters[key].push(getValue$1(value));
1473
+ } else parameters[key] = getValue$1(value);
1474
+ }
2409
1475
  function toQuery(parameters) {
2410
- return isPlainObject(parameters)
2411
- ? join(getParts(parameters, false).filter(part => part.length > 0), '&')
2412
- : '';
1476
+ return isPlainObject(parameters) ? join(getParts(parameters, false).filter((part) => part.length > 0), "&") : "";
2413
1477
  }
2414
- //
2415
1478
  const EXPRESSION_ARRAY_SUFFIX = /\[\]$/;
2416
1479
  const EXPRESSION_BOOLEAN = /^(false|true)$/;
2417
- const TYPES = new Set(['boolean', 'number', 'string']);
2418
-
2419
- /**
2420
- * Get a random boolean
2421
- * @return Random boolean
2422
- */
1480
+ const TYPES = new Set([
1481
+ "boolean",
1482
+ "number",
1483
+ "string"
1484
+ ]);
2423
1485
  function getRandomBoolean() {
2424
- return Math.random() > BOOLEAN_MODIFIER;
2425
- }
2426
- /**
2427
- * Get a random string of characters with a specified length
2428
- * @param length Length of random string
2429
- * @param selection String of characters to select from _(defaults to lowercase English alphabet)_
2430
- * @returns Random string of characters
2431
- */
1486
+ return Math.random() > BOOLEAN_MODIFIER;
1487
+ }
2432
1488
  function getRandomCharacters(length, selection) {
2433
- if (typeof length !== 'number' || length <= 0) {
2434
- return '';
2435
- }
2436
- const actual = typeof selection === 'string' && selection.length > 0
2437
- ? selection
2438
- : ALPHABET;
2439
- let result = '';
2440
- for (let index = 0; index < length; index += 1) {
2441
- result += actual.charAt(getRandomInteger(0, actual.length - 1));
2442
- }
2443
- return result;
2444
- }
2445
- /**
2446
- * Get a random hexadecimal color
2447
- * @param prefix Prefix the color with `#`? _(defaults to `false`)_
2448
- * @returns Random hexadecimal color string in the format `(#)RRGGBB`
2449
- */
1489
+ if (typeof length !== "number" || length <= 0) return "";
1490
+ const actual = typeof selection === "string" && selection.length > 0 ? selection : ALPHABET;
1491
+ let result = "";
1492
+ for (let index = 0; index < length; index += 1) result += actual.charAt(getRandomInteger(0, actual.length - 1));
1493
+ return result;
1494
+ }
2450
1495
  function getRandomColor(prefix) {
2451
- return `${prefix === true ? '#' : ''}${join(Array.from({ length: 6 }, getRandomHex))}`;
1496
+ return `${prefix === true ? "#" : ""}${join(Array.from({ length: 6 }, getRandomHex))}`;
2452
1497
  }
2453
- /**
2454
- * Get a random hexadecimal character
2455
- * @returns Random hexadecimal character from `0-9` and `A-F`
2456
- */
2457
1498
  function getRandomHex() {
2458
- return HEX_CHARACTERS[getRandomInteger(0, HEX_MAXIMUM)];
1499
+ return HEX_CHARACTERS[getRandomInteger(0, HEX_MAXIMUM)];
2459
1500
  }
2460
- /**
2461
- * Get a random item from an array
2462
- * @param array Array to get a random item from
2463
- * @returns Random item from the array, or `undefined` if unable to retrieve one
2464
- */
2465
1501
  function getRandomItem(array) {
2466
- if (!Array.isArray(array) || array.length === 0) {
2467
- return;
2468
- }
2469
- return array.length === 1
2470
- ? array[0]
2471
- : array[getRandomInteger(0, array.length - 1)];
1502
+ if (!Array.isArray(array) || array.length === 0) return;
1503
+ return array.length === 1 ? array[0] : array[getRandomInteger(0, array.length - 1)];
2472
1504
  }
2473
1505
  function getRandomItems(array, amount) {
2474
- if (!Array.isArray(array) || array.length === 0 || amount === 0) {
2475
- return [];
2476
- }
2477
- if (array.length < 2) {
2478
- return array;
2479
- }
2480
- if (amount === 1) {
2481
- return [array[getRandomInteger(0, array.length - 1)]];
2482
- }
2483
- return typeof amount !== 'number' || amount <= 0 || amount >= array.length
2484
- ? shuffle(array)
2485
- : shuffle(array).slice(0, amount);
2486
- }
2487
- //
2488
- const ALPHABET = 'abcdefghijklmnopqrstuvwxyz';
2489
- const BOOLEAN_MODIFIER = 0.5;
2490
- const HEX_CHARACTERS = '0123456789ABCDEF';
1506
+ if (!Array.isArray(array) || array.length === 0 || amount === 0) return [];
1507
+ if (array.length < 2) return array;
1508
+ if (amount === 1) return [array[getRandomInteger(0, array.length - 1)]];
1509
+ return typeof amount !== "number" || amount <= 0 || amount >= array.length ? shuffle(array) : shuffle(array).slice(0, amount);
1510
+ }
1511
+ const ALPHABET = "abcdefghijklmnopqrstuvwxyz";
1512
+ const BOOLEAN_MODIFIER = .5;
1513
+ const HEX_CHARACTERS = "0123456789ABCDEF";
2491
1514
  const HEX_MAXIMUM = 15;
2492
-
2493
- /**
2494
- * Convert a string to camel case _(thisIsCamelCase)_
2495
- * @param value String to convert to camel case
2496
- * @returns Camel-cased string
2497
- */
2498
1515
  function camelCase(value) {
2499
- return toCase(value, '', true, false);
1516
+ return toCase(value, "", true, false);
2500
1517
  }
2501
- /**
2502
- * Capitalize the first letter of a string _(and lowercase the rest)_
2503
- * @param value String to capitalize
2504
- * @returns Capitalized string
2505
- */
2506
1518
  function capitalize(value) {
2507
- if (typeof value !== 'string' || value.length === 0) {
2508
- return '';
2509
- }
2510
- return value.length === 1
2511
- ? value.toLocaleUpperCase()
2512
- : `${value.charAt(0).toLocaleUpperCase()}${value.slice(1).toLocaleLowerCase()}`;
2513
- }
2514
- /**
2515
- * Convert a string to kebab case _(this-is-kebab-case)_
2516
- * @param value String to convert to kebab case
2517
- * @returns Kebab-cased string
2518
- */
1519
+ if (typeof value !== "string" || value.length === 0) return "";
1520
+ return value.length === 1 ? value.toLocaleUpperCase() : `${value.charAt(0).toLocaleUpperCase()}${value.slice(1).toLocaleLowerCase()}`;
1521
+ }
2519
1522
  function kebabCase(value) {
2520
- return toCase(value, '-', false, false);
1523
+ return toCase(value, "-", false, false);
2521
1524
  }
2522
- /**
2523
- * Convert a string to pascal case _(ThisIsPascalCase)_
2524
- * @param value String to convert to pascal case
2525
- * @returns Pascal-cased string
2526
- */
2527
1525
  function pascalCase(value) {
2528
- return toCase(value, '', true, true);
1526
+ return toCase(value, "", true, true);
2529
1527
  }
2530
- /**
2531
- * Convert a string to snake case _(this_is_snake_case)_
2532
- * @param value String to convert to snake case
2533
- * @returns Snake-cased string
2534
- */
2535
1528
  function snakeCase(value) {
2536
- return toCase(value, '_', false, false);
1529
+ return toCase(value, "_", false, false);
2537
1530
  }
2538
- /**
2539
- * Convert a string to title case _(Capitalizing Every Word)_
2540
- * @param value String to convert to title case
2541
- * @returns Title-cased string
2542
- */
2543
1531
  function titleCase(value) {
2544
- if (typeof value !== 'string') {
2545
- return '';
2546
- }
2547
- return value.length < 1
2548
- ? capitalize(value)
2549
- : join(words(value).map(capitalize), ' ');
1532
+ if (typeof value !== "string") return "";
1533
+ return value.length < 1 ? capitalize(value) : join(words(value).map(capitalize), " ");
2550
1534
  }
2551
1535
  function toCase(value, delimiter, capitalizeAny, capitalizeFirst) {
2552
- if (typeof value !== 'string') {
2553
- return '';
2554
- }
2555
- if (value.length < 1) {
2556
- return value;
2557
- }
2558
- const parts = words(value);
2559
- const partsLength = parts.length;
2560
- const result = [];
2561
- for (let partIndex = 0; partIndex < partsLength; partIndex += 1) {
2562
- const part = parts[partIndex];
2563
- const acronymParts = part.replace(EXPRESSION_ACRONYM, (full, one, two, three) => three === 's' ? full : `${one}-${two}${three}`);
2564
- const camelCaseParts = acronymParts.replace(EXPRESSION_CAMEL_CASE, '$1-$2');
2565
- const items = camelCaseParts.split('-');
2566
- const itemsLength = items.length;
2567
- const partResult = [];
2568
- let itemCount = 0;
2569
- for (let itemIndex = 0; itemIndex < itemsLength; itemIndex += 1) {
2570
- const item = items[itemIndex];
2571
- if (item.length === 0) {
2572
- continue;
2573
- }
2574
- if (!capitalizeAny ||
2575
- (itemCount === 0 && partIndex === 0 && !capitalizeFirst)) {
2576
- partResult.push(item.toLocaleLowerCase());
2577
- }
2578
- else {
2579
- partResult.push(capitalize(item));
2580
- }
2581
- itemCount += 1;
2582
- }
2583
- result.push(join(partResult, delimiter));
2584
- }
2585
- return join(result, delimiter);
2586
- }
2587
- //
1536
+ if (typeof value !== "string") return "";
1537
+ if (value.length < 1) return value;
1538
+ const parts = words(value);
1539
+ const partsLength = parts.length;
1540
+ const result = [];
1541
+ for (let partIndex = 0; partIndex < partsLength; partIndex += 1) {
1542
+ const items = parts[partIndex].replace(EXPRESSION_ACRONYM, (full, one, two, three) => three === "s" ? full : `${one}-${two}${three}`).replace(EXPRESSION_CAMEL_CASE, "$1-$2").split("-");
1543
+ const itemsLength = items.length;
1544
+ const partResult = [];
1545
+ let itemCount = 0;
1546
+ for (let itemIndex = 0; itemIndex < itemsLength; itemIndex += 1) {
1547
+ const item = items[itemIndex];
1548
+ if (item.length === 0) continue;
1549
+ if (!capitalizeAny || itemCount === 0 && partIndex === 0 && !capitalizeFirst) partResult.push(item.toLocaleLowerCase());
1550
+ else partResult.push(capitalize(item));
1551
+ itemCount += 1;
1552
+ }
1553
+ result.push(join(partResult, delimiter));
1554
+ }
1555
+ return join(result, delimiter);
1556
+ }
2588
1557
  const EXPRESSION_CAMEL_CASE = /(\p{Ll})(\p{Lu})/gu;
2589
1558
  const EXPRESSION_ACRONYM = /(\p{Lu}*)(\p{Lu})(\p{Ll}+)/gu;
2590
-
2591
- /**
2592
- * Create a new UUID-string
2593
- * @returns UUID string
2594
- */
2595
1559
  function createUuid() {
2596
- return TEMPLATE_UUID.replace(EXPRESSION_UUID_PART, (substring) => {
2597
- const digit = Number.parseInt(substring, 10);
2598
- const random = crypto.getRandomValues(new Uint8Array(1))[0];
2599
- return (digit ^ (random & (15 >> (digit / 4)))).toString(16);
2600
- });
2601
- }
2602
- /**
2603
- * Parse a JSON string into its proper value _(or `undefined` if it fails)_
2604
- * @param value JSON string to parse
2605
- * @param reviver Reviver function to transform the parsed values
2606
- * @returns Parsed value or `undefined` if parsing fails
2607
- */
1560
+ return TEMPLATE_UUID.replace(EXPRESSION_UUID_PART, (substring) => {
1561
+ const digit = Number.parseInt(substring, 10);
1562
+ return (digit ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> digit / 4).toString(16);
1563
+ });
1564
+ }
2608
1565
  function parse(value, reviver) {
2609
- try {
2610
- return JSON.parse(value, reviver);
2611
- }
2612
- catch {
2613
- return undefined;
2614
- }
2615
- }
2616
- /**
2617
- * Truncate a string to a specified length, when possible
2618
- * @param value String to truncate
2619
- * @param length Maximum length of the string after truncation
2620
- * @param suffix Suffix to append to the truncated string
2621
- * @returns Truncated string
2622
- */
1566
+ try {
1567
+ return JSON.parse(value, reviver);
1568
+ } catch {
1569
+ return;
1570
+ }
1571
+ }
2623
1572
  function truncate(value, length, suffix) {
2624
- if (typeof value !== 'string' || typeof length !== 'number' || length <= 0) {
2625
- return '';
2626
- }
2627
- if (length >= value.length) {
2628
- return value;
2629
- }
2630
- const actualSuffix = typeof suffix === 'string' ? suffix : '';
2631
- const truncatedLength = length - actualSuffix.length;
2632
- return `${value.slice(0, truncatedLength)}${actualSuffix}`;
2633
- }
2634
- //
1573
+ if (typeof value !== "string" || typeof length !== "number" || length <= 0) return "";
1574
+ if (length >= value.length) return value;
1575
+ const actualSuffix = typeof suffix === "string" ? suffix : "";
1576
+ const truncatedLength = length - actualSuffix.length;
1577
+ return `${value.slice(0, truncatedLength)}${actualSuffix}`;
1578
+ }
2635
1579
  const EXPRESSION_UUID_PART = /[018]/g;
2636
- const TEMPLATE_UUID = '10000000-1000-4000-8000-100000000000';
2637
-
1580
+ const TEMPLATE_UUID = "10000000-1000-4000-8000-100000000000";
2638
1581
  function getValue(data, path, ignoreCase) {
2639
- if (typeof data !== 'object' ||
2640
- data === null ||
2641
- typeof path !== 'string' ||
2642
- path.trim().length === 0) {
2643
- return;
2644
- }
2645
- const shouldIgnoreCase = ignoreCase === true;
2646
- const paths = getPaths(path, shouldIgnoreCase);
2647
- if (typeof paths === 'string') {
2648
- return handleValue(data, paths, null, true, shouldIgnoreCase);
2649
- }
2650
- const { length } = paths;
2651
- let index = 0;
2652
- let value = data;
2653
- while (index < length && value != null) {
2654
- value = handleValue(value, paths[index++], null, true, shouldIgnoreCase);
2655
- }
2656
- return value;
2657
- }
2658
-
2659
- /**
2660
- * Render a string from a template with variables
2661
- * @param value Template string
2662
- * @param variables Variables to use
2663
- * @param options Templating options
2664
- * @returns Templated string
2665
- */
1582
+ if (typeof data !== "object" || data === null || typeof path !== "string" || path.trim().length === 0) return;
1583
+ const shouldIgnoreCase = ignoreCase === true;
1584
+ const paths = getPaths(path, shouldIgnoreCase);
1585
+ if (typeof paths === "string") return handleValue(data, paths, null, true, shouldIgnoreCase);
1586
+ const { length } = paths;
1587
+ let index = 0;
1588
+ let value = data;
1589
+ while (index < length && value != null) value = handleValue(value, paths[index++], null, true, shouldIgnoreCase);
1590
+ return value;
1591
+ }
2666
1592
  function template(value, variables, options) {
2667
- if (typeof value !== 'string') {
2668
- return '';
2669
- }
2670
- if (typeof variables !== 'object' || variables === null) {
2671
- return value;
2672
- }
2673
- const hasOptions = typeof options === 'object' && options != null;
2674
- const ignoreCase = hasOptions && options?.ignoreCase === true;
2675
- const pattern = hasOptions && options?.pattern instanceof RegExp
2676
- ? options.pattern
2677
- : EXPRESSION_VARIABLE;
2678
- const values = {};
2679
- return value.replace(pattern, (_, key) => {
2680
- if (values[key] != null) {
2681
- return values[key];
2682
- }
2683
- const value = getValue(variables, key, ignoreCase);
2684
- const nullish = value == null;
2685
- values[key] = nullish ? '' : getString(value);
2686
- return values[key];
2687
- });
2688
- }
2689
- //
1593
+ if (typeof value !== "string") return "";
1594
+ if (typeof variables !== "object" || variables === null) return value;
1595
+ const hasOptions = typeof options === "object" && options != null;
1596
+ const ignoreCase = hasOptions && options?.ignoreCase === true;
1597
+ const pattern = hasOptions && options?.pattern instanceof RegExp ? options.pattern : EXPRESSION_VARIABLE;
1598
+ const values = {};
1599
+ return value.replace(pattern, (_, key) => {
1600
+ if (values[key] != null) return values[key];
1601
+ const value$1 = getValue(variables, key, ignoreCase);
1602
+ values[key] = value$1 == null ? "" : getString(value$1);
1603
+ return values[key];
1604
+ });
1605
+ }
2690
1606
  const EXPRESSION_VARIABLE = /{{([\s\S]+?)}}/g;
2691
-
2692
1607
  function equal(first, second, options) {
2693
- return equalValue(first, second, getOptions$1(options));
1608
+ return equalValue(first, second, getOptions$1(options));
2694
1609
  }
2695
- // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: Extracting to smaller functions had unintended results for return-early statements, so leaving as-is for now
2696
1610
  function equalArray(first, second, options) {
2697
- const { length } = first;
2698
- if (length !== second.length) {
2699
- return false;
2700
- }
2701
- let offset = 0;
2702
- if (length >= ARRAY_THRESHOLD) {
2703
- offset = Math.round(length / ARRAY_PEEK_PERCENTAGE);
2704
- offset = offset > ARRAY_THRESHOLD ? ARRAY_THRESHOLD : offset;
2705
- for (let index = 0; index < offset; index += 1) {
2706
- if (!(equalValue(first[index], second[index], options) &&
2707
- equalValue(first[length - index - 1], second[length - index - 1], options))) {
2708
- return false;
2709
- }
2710
- }
2711
- }
2712
- const firstChunks = chunk(first.slice(offset, length - offset), ARRAY_THRESHOLD);
2713
- const secondChunks = chunk(second.slice(offset, length - offset), ARRAY_THRESHOLD);
2714
- const chunksLength = firstChunks.length;
2715
- for (let chunkIndex = 0; chunkIndex < chunksLength; chunkIndex += 1) {
2716
- const firstChunk = firstChunks[chunkIndex];
2717
- const secondChunk = secondChunks[chunkIndex];
2718
- const chunkLength = firstChunk.length;
2719
- for (let index = 0; index < chunkLength; index += 1) {
2720
- if (!equalValue(firstChunk[index], secondChunk[index], options)) {
2721
- return false;
2722
- }
2723
- }
2724
- }
2725
- return true;
1611
+ const { length } = first;
1612
+ if (length !== second.length) return false;
1613
+ let offset = 0;
1614
+ if (length >= ARRAY_THRESHOLD) {
1615
+ offset = Math.round(length / ARRAY_PEEK_PERCENTAGE);
1616
+ offset = offset > ARRAY_THRESHOLD ? ARRAY_THRESHOLD : offset;
1617
+ for (let index = 0; index < offset; index += 1) if (!(equalValue(first[index], second[index], options) && equalValue(first[length - index - 1], second[length - index - 1], options))) return false;
1618
+ }
1619
+ const firstChunks = chunk(first.slice(offset, length - offset), ARRAY_THRESHOLD);
1620
+ const secondChunks = chunk(second.slice(offset, length - offset), ARRAY_THRESHOLD);
1621
+ const chunksLength = firstChunks.length;
1622
+ for (let chunkIndex = 0; chunkIndex < chunksLength; chunkIndex += 1) {
1623
+ const firstChunk = firstChunks[chunkIndex];
1624
+ const secondChunk = secondChunks[chunkIndex];
1625
+ const chunkLength = firstChunk.length;
1626
+ for (let index = 0; index < chunkLength; index += 1) if (!equalValue(firstChunk[index], secondChunk[index], options)) return false;
1627
+ }
1628
+ return true;
2726
1629
  }
2727
1630
  function equalArrayBuffer(first, second, options) {
2728
- return first.byteLength === second.byteLength
2729
- ? equalArray(new Uint8Array(first), new Uint8Array(second), options)
2730
- : false;
1631
+ return first.byteLength === second.byteLength ? equalArray(new Uint8Array(first), new Uint8Array(second), options) : false;
2731
1632
  }
2732
1633
  function equalDataView(first, second, options) {
2733
- return first.byteOffset === second.byteOffset
2734
- ? equalArrayBuffer(first.buffer, second.buffer, options)
2735
- : false;
1634
+ return first.byteOffset === second.byteOffset ? equalArrayBuffer(first.buffer, second.buffer, options) : false;
2736
1635
  }
2737
1636
  function equalMap(first, second, options) {
2738
- const { size } = first;
2739
- if (size !== second.size) {
2740
- return false;
2741
- }
2742
- const firstKeys = [...first.keys()];
2743
- const secondKeys = [...second.keys()];
2744
- if (firstKeys.some(key => !secondKeys.includes(key))) {
2745
- return false;
2746
- }
2747
- for (let index = 0; index < size; index += 1) {
2748
- const key = firstKeys[index];
2749
- if (!equalValue(first.get(key), second.get(key), options)) {
2750
- return false;
2751
- }
2752
- }
2753
- return true;
1637
+ const { size } = first;
1638
+ if (size !== second.size) return false;
1639
+ const firstKeys = [...first.keys()];
1640
+ const secondKeys = [...second.keys()];
1641
+ if (firstKeys.some((key) => !secondKeys.includes(key))) return false;
1642
+ for (let index = 0; index < size; index += 1) {
1643
+ const key = firstKeys[index];
1644
+ if (!equalValue(first.get(key), second.get(key), options)) return false;
1645
+ }
1646
+ return true;
2754
1647
  }
2755
1648
  function equalObject(first, second, options) {
2756
- const firstKeys = [
2757
- ...Object.keys(first),
2758
- ...Object.getOwnPropertySymbols(first),
2759
- ].filter(key => filterKey(key, options));
2760
- const secondKeys = [
2761
- ...Object.keys(second),
2762
- ...Object.getOwnPropertySymbols(second),
2763
- ].filter(key => filterKey(key, options));
2764
- const { length } = firstKeys;
2765
- if (length !== secondKeys.length ||
2766
- firstKeys.some(key => !secondKeys.includes(key))) {
2767
- return false;
2768
- }
2769
- for (let index = 0; index < length; index += 1) {
2770
- const key = firstKeys[index];
2771
- if (!equalValue(first[key], second[key], options)) {
2772
- return false;
2773
- }
2774
- }
2775
- return true;
1649
+ const firstKeys = [...Object.keys(first), ...Object.getOwnPropertySymbols(first)].filter((key) => filterKey(key, options));
1650
+ const secondKeys = [...Object.keys(second), ...Object.getOwnPropertySymbols(second)].filter((key) => filterKey(key, options));
1651
+ const { length } = firstKeys;
1652
+ if (length !== secondKeys.length || firstKeys.some((key) => !secondKeys.includes(key))) return false;
1653
+ for (let index = 0; index < length; index += 1) {
1654
+ const key = firstKeys[index];
1655
+ if (!equalValue(first[key], second[key], options)) return false;
1656
+ }
1657
+ return true;
2776
1658
  }
2777
1659
  function equalProperties(first, second, properties, options) {
2778
- const { length } = properties;
2779
- for (let index = 0; index < length; index += 1) {
2780
- const property = properties[index];
2781
- if (!equalValue(first[property], second[property], options)) {
2782
- return false;
2783
- }
2784
- }
2785
- return true;
1660
+ const { length } = properties;
1661
+ for (let index = 0; index < length; index += 1) {
1662
+ const property = properties[index];
1663
+ if (!equalValue(first[property], second[property], options)) return false;
1664
+ }
1665
+ return true;
2786
1666
  }
2787
1667
  function equalSet(first, second, options) {
2788
- const { size } = first;
2789
- if (size !== second.size) {
2790
- return false;
2791
- }
2792
- const firstValues = [...first];
2793
- const secondValues = [...second];
2794
- for (let index = 0; index < size; index += 1) {
2795
- const firstValue = firstValues[index];
2796
- if (!secondValues.some(secondValue => equalValue(firstValue, secondValue, options))) {
2797
- return false;
2798
- }
2799
- }
2800
- return true;
1668
+ const { size } = first;
1669
+ if (size !== second.size) return false;
1670
+ const firstValues = [...first];
1671
+ const secondValues = [...second];
1672
+ for (let index = 0; index < size; index += 1) {
1673
+ const firstValue = firstValues[index];
1674
+ if (!secondValues.some((secondValue) => equalValue(firstValue, secondValue, options))) return false;
1675
+ }
1676
+ return true;
2801
1677
  }
2802
1678
  function equalTypedArray(first, second) {
2803
- if (first.constructor !== second.constructor) {
2804
- return false;
2805
- }
2806
- if (first.byteLength !== second.byteLength) {
2807
- return false;
2808
- }
2809
- const { length } = first;
2810
- for (let index = 0; index < length; index += 1) {
2811
- if (first[index] !== second[index]) {
2812
- return false;
2813
- }
2814
- }
2815
- return true;
1679
+ if (first.constructor !== second.constructor) return false;
1680
+ if (first.byteLength !== second.byteLength) return false;
1681
+ const { length } = first;
1682
+ for (let index = 0; index < length; index += 1) if (first[index] !== second[index]) return false;
1683
+ return true;
2816
1684
  }
2817
1685
  function equalValue(first, second, options) {
2818
- if (options.relaxedNullish === true && first == null && second == null) {
2819
- return true;
2820
- }
2821
- switch (true) {
2822
- case Object.is(first, second):
2823
- return true;
2824
- case first == null || second == null:
2825
- return first === second;
2826
- case typeof first !== typeof second:
2827
- return false;
2828
- case typeof first === 'string' && options.ignoreCase === true:
2829
- return Object.is(first.toLocaleLowerCase(), second.toLocaleLowerCase());
2830
- case first instanceof ArrayBuffer && second instanceof ArrayBuffer:
2831
- return equalArrayBuffer(first, second, options);
2832
- case first instanceof Date && second instanceof Date:
2833
- return Object.is(Number(first), Number(second));
2834
- case first instanceof DataView && second instanceof DataView:
2835
- return equalDataView(first, second, options);
2836
- case first instanceof Error && second instanceof Error:
2837
- return equalProperties(first, second, ['name', 'message'], options);
2838
- case first instanceof Map && second instanceof Map:
2839
- return equalMap(first, second, options);
2840
- case first instanceof RegExp && second instanceof RegExp:
2841
- return equalProperties(first, second, ['source', 'flags'], options);
2842
- case first instanceof Set && second instanceof Set:
2843
- return equalSet(first, second, options);
2844
- case Array.isArray(first) && Array.isArray(second):
2845
- return equalArray(first, second, options);
2846
- case isPlainObject(first) && isPlainObject(second):
2847
- return equalObject(first, second, options);
2848
- case isTypedArray(first) && isTypedArray(second):
2849
- return equalTypedArray(first, second);
2850
- default:
2851
- return Object.is(first, second);
2852
- }
1686
+ if (options.relaxedNullish === true && first == null && second == null) return true;
1687
+ switch (true) {
1688
+ case Object.is(first, second): return true;
1689
+ case first == null || second == null: return first === second;
1690
+ case typeof first !== typeof second: return false;
1691
+ case typeof first === "string" && options.ignoreCase === true: return Object.is(first.toLocaleLowerCase(), second.toLocaleLowerCase());
1692
+ case first instanceof ArrayBuffer && second instanceof ArrayBuffer: return equalArrayBuffer(first, second, options);
1693
+ case first instanceof Date && second instanceof Date: return Object.is(Number(first), Number(second));
1694
+ case first instanceof DataView && second instanceof DataView: return equalDataView(first, second, options);
1695
+ case first instanceof Error && second instanceof Error: return equalProperties(first, second, ["name", "message"], options);
1696
+ case first instanceof Map && second instanceof Map: return equalMap(first, second, options);
1697
+ case first instanceof RegExp && second instanceof RegExp: return equalProperties(first, second, ["source", "flags"], options);
1698
+ case first instanceof Set && second instanceof Set: return equalSet(first, second, options);
1699
+ case Array.isArray(first) && Array.isArray(second): return equalArray(first, second, options);
1700
+ case isPlainObject(first) && isPlainObject(second): return equalObject(first, second, options);
1701
+ case isTypedArray(first) && isTypedArray(second): return equalTypedArray(first, second);
1702
+ default: return Object.is(first, second);
1703
+ }
2853
1704
  }
2854
1705
  function filterKey(key, options) {
2855
- if (typeof key !== 'string') {
2856
- return true;
2857
- }
2858
- if (options.ignoreExpressions.enabled &&
2859
- options.ignoreExpressions.values.some(expression => expression.test(key))) {
2860
- return false;
2861
- }
2862
- if (options.ignoreKeys.enabled && options.ignoreKeys.values.has(key)) {
2863
- return false;
2864
- }
2865
- return true;
1706
+ if (typeof key !== "string") return true;
1707
+ if (options.ignoreExpressions.enabled && options.ignoreExpressions.values.some((expression) => expression.test(key))) return false;
1708
+ if (options.ignoreKeys.enabled && options.ignoreKeys.values.has(key)) return false;
1709
+ return true;
2866
1710
  }
2867
1711
  function getOptions$1(input) {
2868
- const options = {
2869
- ignoreCase: false,
2870
- ignoreExpressions: {
2871
- enabled: false,
2872
- values: [],
2873
- },
2874
- ignoreKeys: {
2875
- enabled: false,
2876
- values: new Set(),
2877
- },
2878
- relaxedNullish: false,
2879
- };
2880
- if (typeof input === 'boolean') {
2881
- options.ignoreCase = input;
2882
- return options;
2883
- }
2884
- if (!isPlainObject(input)) {
2885
- return options;
2886
- }
2887
- options.ignoreCase =
2888
- typeof input.ignoreCase === 'boolean' ? input.ignoreCase : false;
2889
- options.ignoreExpressions.values = (Array.isArray(input.ignoreKeys) ? input.ignoreKeys : [input.ignoreKeys]).filter(key => key instanceof RegExp);
2890
- options.ignoreKeys.values = new Set((Array.isArray(input.ignoreKeys)
2891
- ? input.ignoreKeys
2892
- : [input.ignoreKeys]).filter(key => typeof key === 'string'));
2893
- options.ignoreExpressions.enabled =
2894
- options.ignoreExpressions.values.length > 0;
2895
- options.ignoreKeys.enabled = options.ignoreKeys.values.size > 0;
2896
- options.relaxedNullish = input.relaxedNullish === true;
2897
- return options;
2898
- }
2899
- //
1712
+ const options = {
1713
+ ignoreCase: false,
1714
+ ignoreExpressions: {
1715
+ enabled: false,
1716
+ values: []
1717
+ },
1718
+ ignoreKeys: {
1719
+ enabled: false,
1720
+ values: /* @__PURE__ */ new Set()
1721
+ },
1722
+ relaxedNullish: false
1723
+ };
1724
+ if (typeof input === "boolean") {
1725
+ options.ignoreCase = input;
1726
+ return options;
1727
+ }
1728
+ if (!isPlainObject(input)) return options;
1729
+ options.ignoreCase = typeof input.ignoreCase === "boolean" ? input.ignoreCase : false;
1730
+ options.ignoreExpressions.values = (Array.isArray(input.ignoreKeys) ? input.ignoreKeys : [input.ignoreKeys]).filter((key) => key instanceof RegExp);
1731
+ options.ignoreKeys.values = new Set((Array.isArray(input.ignoreKeys) ? input.ignoreKeys : [input.ignoreKeys]).filter((key) => typeof key === "string"));
1732
+ options.ignoreExpressions.enabled = options.ignoreExpressions.values.length > 0;
1733
+ options.ignoreKeys.enabled = options.ignoreKeys.values.size > 0;
1734
+ options.relaxedNullish = input.relaxedNullish === true;
1735
+ return options;
1736
+ }
2900
1737
  const ARRAY_PEEK_PERCENTAGE = 10;
2901
1738
  const ARRAY_THRESHOLD = 100;
2902
-
2903
1739
  function clone(value) {
2904
- return cloneValue(value, 0, new WeakMap());
1740
+ return cloneValue(value, 0, /* @__PURE__ */ new WeakMap());
2905
1741
  }
2906
1742
  function cloneArrayBuffer(value, depth, references) {
2907
- if (typeof depth === 'number' && depth >= MAX_DEPTH$1) {
2908
- return value;
2909
- }
2910
- const cloned = new ArrayBuffer(value.byteLength);
2911
- new Uint8Array(cloned).set(new Uint8Array(value));
2912
- references?.set(value, cloned);
2913
- return cloned;
1743
+ if (typeof depth === "number" && depth >= MAX_DEPTH$1) return value;
1744
+ const cloned = new ArrayBuffer(value.byteLength);
1745
+ new Uint8Array(cloned).set(new Uint8Array(value));
1746
+ references?.set(value, cloned);
1747
+ return cloned;
2914
1748
  }
2915
1749
  function cloneDataView(value, depth, references) {
2916
- if (depth >= MAX_DEPTH$1) {
2917
- return value;
2918
- }
2919
- const buffer = cloneArrayBuffer(value.buffer);
2920
- const cloned = new DataView(buffer, value.byteOffset, value.byteLength);
2921
- references.set(value, cloned);
2922
- return cloned;
1750
+ if (depth >= MAX_DEPTH$1) return value;
1751
+ const buffer = cloneArrayBuffer(value.buffer);
1752
+ const cloned = new DataView(buffer, value.byteOffset, value.byteLength);
1753
+ references.set(value, cloned);
1754
+ return cloned;
2923
1755
  }
2924
1756
  function cloneMapOrSet(value, depth, references) {
2925
- if (depth >= MAX_DEPTH$1) {
2926
- return value;
2927
- }
2928
- const isMap = value instanceof Map;
2929
- const cloned = isMap ? new Map() : new Set();
2930
- const entries = [...value.entries()];
2931
- const { length } = entries;
2932
- for (let index = 0; index < length; index += 1) {
2933
- const entry = entries[index];
2934
- if (isMap) {
2935
- cloned.set(cloneValue(entry[0], depth + 1, references), cloneValue(entry[1], depth + 1, references));
2936
- }
2937
- else {
2938
- cloned.add(cloneValue(entry[0], depth + 1, references));
2939
- }
2940
- }
2941
- references.set(value, cloned);
2942
- return cloned;
1757
+ if (depth >= MAX_DEPTH$1) return value;
1758
+ const isMap = value instanceof Map;
1759
+ const cloned = isMap ? /* @__PURE__ */ new Map() : /* @__PURE__ */ new Set();
1760
+ const entries = [...value.entries()];
1761
+ const { length } = entries;
1762
+ for (let index = 0; index < length; index += 1) {
1763
+ const entry = entries[index];
1764
+ if (isMap) cloned.set(cloneValue(entry[0], depth + 1, references), cloneValue(entry[1], depth + 1, references));
1765
+ else cloned.add(cloneValue(entry[0], depth + 1, references));
1766
+ }
1767
+ references.set(value, cloned);
1768
+ return cloned;
2943
1769
  }
2944
1770
  function cloneNode(node, depth, references) {
2945
- if (depth >= MAX_DEPTH$1) {
2946
- return node;
2947
- }
2948
- const cloned = node.cloneNode(true);
2949
- references.set(node, cloned);
2950
- return cloned;
1771
+ if (depth >= MAX_DEPTH$1) return node;
1772
+ const cloned = node.cloneNode(true);
1773
+ references.set(node, cloned);
1774
+ return cloned;
2951
1775
  }
2952
1776
  function cloneObject(value, depth, references) {
2953
- if (depth >= MAX_DEPTH$1) {
2954
- return Array.isArray(value) ? [...value] : { ...value };
2955
- }
2956
- const cloned = (Array.isArray(value) ? [] : {});
2957
- const keys = [...Object.keys(value), ...Object.getOwnPropertySymbols(value)];
2958
- const { length } = keys;
2959
- for (let index = 0; index < length; index += 1) {
2960
- const key = keys[index];
2961
- cloned[key] = cloneValue(value[key], depth + 1, references);
2962
- }
2963
- references.set(value, cloned);
2964
- return cloned;
1777
+ if (depth >= MAX_DEPTH$1) return Array.isArray(value) ? [...value] : { ...value };
1778
+ const cloned = Array.isArray(value) ? [] : {};
1779
+ const keys = [...Object.keys(value), ...Object.getOwnPropertySymbols(value)];
1780
+ const { length } = keys;
1781
+ for (let index = 0; index < length; index += 1) {
1782
+ const key = keys[index];
1783
+ cloned[key] = cloneValue(value[key], depth + 1, references);
1784
+ }
1785
+ references.set(value, cloned);
1786
+ return cloned;
2965
1787
  }
2966
1788
  function cloneRegularExpression(value, depth, references) {
2967
- if (depth >= MAX_DEPTH$1) {
2968
- return value;
2969
- }
2970
- const cloned = new RegExp(value.source, value.flags);
2971
- cloned.lastIndex = value.lastIndex;
2972
- references.set(value, cloned);
2973
- return cloned;
1789
+ if (depth >= MAX_DEPTH$1) return value;
1790
+ const cloned = new RegExp(value.source, value.flags);
1791
+ cloned.lastIndex = value.lastIndex;
1792
+ references.set(value, cloned);
1793
+ return cloned;
2974
1794
  }
2975
1795
  function cloneTypedArray(value, depth, references) {
2976
- if (depth >= MAX_DEPTH$1) {
2977
- return value;
2978
- }
2979
- const cloned = new value.constructor(value);
2980
- references.set(value, cloned);
2981
- return cloned;
1796
+ if (depth >= MAX_DEPTH$1) return value;
1797
+ const cloned = new value.constructor(value);
1798
+ references.set(value, cloned);
1799
+ return cloned;
2982
1800
  }
2983
1801
  function cloneValue(value, depth, references) {
2984
- switch (true) {
2985
- case value == null:
2986
- return value;
2987
- case typeof value === 'bigint':
2988
- return BigInt(value);
2989
- case typeof value === 'boolean':
2990
- return Boolean(value);
2991
- case typeof value === 'function':
2992
- return;
2993
- case typeof value === 'number':
2994
- return Number(value);
2995
- case typeof value === 'string':
2996
- return String(value);
2997
- case typeof value === 'symbol':
2998
- return Symbol(value.description);
2999
- case references.has(value):
3000
- return references.get(value);
3001
- case value instanceof ArrayBuffer:
3002
- return cloneArrayBuffer(value, depth, references);
3003
- case value instanceof DataView:
3004
- return cloneDataView(value, depth, references);
3005
- case value instanceof RegExp:
3006
- return cloneRegularExpression(value, depth, references);
3007
- case value instanceof Map:
3008
- case value instanceof Set:
3009
- return cloneMapOrSet(value, depth, references);
3010
- case value instanceof Node:
3011
- return cloneNode(value, depth, references);
3012
- case isArrayOrPlainObject(value):
3013
- return cloneObject(value, depth, references);
3014
- case isTypedArray(value):
3015
- return cloneTypedArray(value, depth, references);
3016
- default:
3017
- return tryStructuredClone(value, depth, references);
3018
- }
1802
+ switch (true) {
1803
+ case value == null: return value;
1804
+ case typeof value === "bigint": return BigInt(value);
1805
+ case typeof value === "boolean": return Boolean(value);
1806
+ case typeof value === "function": return;
1807
+ case typeof value === "number": return Number(value);
1808
+ case typeof value === "string": return String(value);
1809
+ case typeof value === "symbol": return Symbol(value.description);
1810
+ case references.has(value): return references.get(value);
1811
+ case value instanceof ArrayBuffer: return cloneArrayBuffer(value, depth, references);
1812
+ case value instanceof DataView: return cloneDataView(value, depth, references);
1813
+ case value instanceof RegExp: return cloneRegularExpression(value, depth, references);
1814
+ case value instanceof Map:
1815
+ case value instanceof Set: return cloneMapOrSet(value, depth, references);
1816
+ case value instanceof Node: return cloneNode(value, depth, references);
1817
+ case isArrayOrPlainObject(value): return cloneObject(value, depth, references);
1818
+ case isTypedArray(value): return cloneTypedArray(value, depth, references);
1819
+ default: return tryStructuredClone(value, depth, references);
1820
+ }
3019
1821
  }
3020
1822
  function tryStructuredClone(value, depth, references) {
3021
- if (depth >= MAX_DEPTH$1) {
3022
- return value;
3023
- }
3024
- try {
3025
- const cloned = structuredClone(value);
3026
- references.set(value, cloned);
3027
- return cloned;
3028
- }
3029
- catch {
3030
- references.set(value, value);
3031
- return value;
3032
- }
3033
- }
3034
- //
1823
+ if (depth >= MAX_DEPTH$1) return value;
1824
+ try {
1825
+ const cloned = structuredClone(value);
1826
+ references.set(value, cloned);
1827
+ return cloned;
1828
+ } catch {
1829
+ references.set(value, value);
1830
+ return value;
1831
+ }
1832
+ }
3035
1833
  const MAX_DEPTH$1 = 100;
3036
-
3037
- //
3038
- /**
3039
- * Find the differences between two values
3040
- * @param first First value
3041
- * @param second Second value
3042
- * @param options Comparison options
3043
- * @returns Difference result
3044
- */
3045
1834
  function diff(first, second, options) {
3046
- const relaxedNullish = typeof options === 'object' && options?.relaxedNullish === true;
3047
- const result = {
3048
- original: {
3049
- from: first,
3050
- to: second,
3051
- },
3052
- type: 'partial',
3053
- values: {},
3054
- };
3055
- const same = (relaxedNullish && first == null && second == null) ||
3056
- Object.is(first, second);
3057
- const firstIsArrayOrObject = isArrayOrPlainObject(first);
3058
- const secondIsArrayOrObject = isArrayOrPlainObject(second);
3059
- if (same || !(firstIsArrayOrObject || secondIsArrayOrObject)) {
3060
- result.type = same ? 'none' : 'full';
3061
- return result;
3062
- }
3063
- if (firstIsArrayOrObject !== secondIsArrayOrObject) {
3064
- result.type = 'full';
3065
- return result;
3066
- }
3067
- const diffs = getDiffs(first, second, relaxedNullish);
3068
- const { length } = diffs;
3069
- if (length === 0) {
3070
- result.type = 'none';
3071
- }
3072
- for (let index = 0; index < length; index += 1) {
3073
- const diff = diffs[index];
3074
- result.values[diff.key] = { from: diff.from, to: diff.to };
3075
- }
3076
- return result;
1835
+ const relaxedNullish = typeof options === "object" && options?.relaxedNullish === true;
1836
+ const result = {
1837
+ original: {
1838
+ from: first,
1839
+ to: second
1840
+ },
1841
+ type: "partial",
1842
+ values: {}
1843
+ };
1844
+ const same = relaxedNullish && first == null && second == null || Object.is(first, second);
1845
+ const firstIsArrayOrObject = isArrayOrPlainObject(first);
1846
+ const secondIsArrayOrObject = isArrayOrPlainObject(second);
1847
+ if (same || !(firstIsArrayOrObject || secondIsArrayOrObject)) {
1848
+ result.type = same ? "none" : "full";
1849
+ return result;
1850
+ }
1851
+ if (firstIsArrayOrObject !== secondIsArrayOrObject) {
1852
+ result.type = "full";
1853
+ return result;
1854
+ }
1855
+ const diffs = getDiffs(first, second, relaxedNullish);
1856
+ const { length } = diffs;
1857
+ if (length === 0) result.type = "none";
1858
+ for (let index = 0; index < length; index += 1) {
1859
+ const diff$1 = diffs[index];
1860
+ result.values[diff$1.key] = {
1861
+ from: diff$1.from,
1862
+ to: diff$1.to
1863
+ };
1864
+ }
1865
+ return result;
3077
1866
  }
3078
1867
  function getChanges(changes, first, second, relaxedNullish, prefix) {
3079
- const checked = new Set();
3080
- for (let outerIndex = 0; outerIndex < 2; outerIndex += 1) {
3081
- const value = (outerIndex === 0 ? first : second) ?? {};
3082
- const keys = [
3083
- ...Object.keys(value),
3084
- ...Object.getOwnPropertySymbols(value),
3085
- ];
3086
- const { length } = keys;
3087
- for (let innerIndex = 0; innerIndex < length; innerIndex += 1) {
3088
- const key = keys[innerIndex];
3089
- if (checked.has(key)) {
3090
- continue;
3091
- }
3092
- checked.add(key);
3093
- setChanges({
3094
- changes,
3095
- key,
3096
- relaxedNullish,
3097
- prefix,
3098
- values: { first, second },
3099
- });
3100
- }
3101
- }
3102
- return changes;
1868
+ const checked = /* @__PURE__ */ new Set();
1869
+ for (let outerIndex = 0; outerIndex < 2; outerIndex += 1) {
1870
+ const value = (outerIndex === 0 ? first : second) ?? {};
1871
+ const keys = [...Object.keys(value), ...Object.getOwnPropertySymbols(value)];
1872
+ const { length } = keys;
1873
+ for (let innerIndex = 0; innerIndex < length; innerIndex += 1) {
1874
+ const key = keys[innerIndex];
1875
+ if (checked.has(key)) continue;
1876
+ checked.add(key);
1877
+ setChanges({
1878
+ changes,
1879
+ key,
1880
+ relaxedNullish,
1881
+ prefix,
1882
+ values: {
1883
+ first,
1884
+ second
1885
+ }
1886
+ });
1887
+ }
1888
+ }
1889
+ return changes;
3103
1890
  }
3104
1891
  function getDiffs(first, second, relaxedNullish, prefix) {
3105
- const changes = [];
3106
- if (Array.isArray(first) && Array.isArray(second)) {
3107
- const maximumLength = Math.max(first.length, second.length);
3108
- const minimumLength = Math.min(first.length, second.length);
3109
- for (let index = minimumLength; index < maximumLength; index += 1) {
3110
- const key = join([prefix, index], '.');
3111
- changes.push({
3112
- key,
3113
- from: index >= first.length ? undefined : first[index],
3114
- to: index >= first.length ? second[index] : undefined,
3115
- });
3116
- }
3117
- }
3118
- return getChanges(changes, first, second, relaxedNullish, prefix);
1892
+ const changes = [];
1893
+ if (Array.isArray(first) && Array.isArray(second)) {
1894
+ const maximumLength = Math.max(first.length, second.length);
1895
+ const minimumLength = Math.min(first.length, second.length);
1896
+ for (let index = minimumLength; index < maximumLength; index += 1) {
1897
+ const key = join([prefix, index], ".");
1898
+ changes.push({
1899
+ key,
1900
+ from: index >= first.length ? void 0 : first[index],
1901
+ to: index >= first.length ? second[index] : void 0
1902
+ });
1903
+ }
1904
+ }
1905
+ return getChanges(changes, first, second, relaxedNullish, prefix);
3119
1906
  }
3120
1907
  function setChanges(parameters) {
3121
- const { changes, key, prefix, relaxedNullish, values } = parameters;
3122
- const from = values.first?.[key];
3123
- const to = values.second?.[key];
3124
- if (equal(from, to, { relaxedNullish })) {
3125
- return;
3126
- }
3127
- const prefixed = join([prefix, key], '.');
3128
- const change = {
3129
- from,
3130
- to,
3131
- key: prefixed,
3132
- };
3133
- const nested = isArrayOrPlainObject(from) || isArrayOrPlainObject(to);
3134
- const diffs = nested ? getDiffs(from, to, relaxedNullish, prefixed) : [];
3135
- if (!nested || (nested && diffs.length > 0)) {
3136
- changes.push(change);
3137
- }
3138
- const diffsLength = diffs.length;
3139
- for (let diffIndex = 0; diffIndex < diffsLength; diffIndex += 1) {
3140
- changes.push(diffs[diffIndex]);
3141
- }
3142
- }
3143
-
1908
+ const { changes, key, prefix, relaxedNullish, values } = parameters;
1909
+ const from = values.first?.[key];
1910
+ const to = values.second?.[key];
1911
+ if (equal(from, to, { relaxedNullish })) return;
1912
+ const prefixed = join([prefix, key], ".");
1913
+ const change = {
1914
+ from,
1915
+ to,
1916
+ key: prefixed
1917
+ };
1918
+ const diffs = isArrayOrPlainObject(from) || isArrayOrPlainObject(to) ? getDiffs(from, to, relaxedNullish, prefixed) : [];
1919
+ changes.push(change);
1920
+ const diffsLength = diffs.length;
1921
+ for (let diffIndex = 0; diffIndex < diffsLength; diffIndex += 1) changes.push(diffs[diffIndex]);
1922
+ }
3144
1923
  function getOptions(options) {
3145
- const actual = {
3146
- replaceableObjects: undefined,
3147
- skipNullableInArrays: false,
3148
- };
3149
- if (typeof options !== 'object' || options == null) {
3150
- return actual;
3151
- }
3152
- actual.replaceableObjects = getReplaceableObjects(options.replaceableObjects);
3153
- actual.skipNullableInArrays = options.skipNullableInArrays === true;
3154
- return actual;
1924
+ const actual = {
1925
+ replaceableObjects: void 0,
1926
+ skipNullableInArrays: false
1927
+ };
1928
+ if (typeof options !== "object" || options == null) return actual;
1929
+ actual.replaceableObjects = getReplaceableObjects(options.replaceableObjects);
1930
+ actual.skipNullableInArrays = options.skipNullableInArrays === true;
1931
+ return actual;
3155
1932
  }
3156
1933
  function getReplaceableObjects(value) {
3157
- const items = (Array.isArray(value) ? value : [value]).filter(item => typeof item === 'string' || item instanceof RegExp);
3158
- if (items.length > 0) {
3159
- return (name) => items.some(item => typeof item === 'string' ? item === name : item.test(name));
3160
- }
3161
- }
3162
- /**
3163
- * Merge multiple arrays or objects into a single one
3164
- * @param values Values to merge
3165
- * @param options Merging options
3166
- * @returns Merged value
3167
- */
1934
+ const items = (Array.isArray(value) ? value : [value]).filter((item) => typeof item === "string" || item instanceof RegExp);
1935
+ if (items.length > 0) return (name) => items.some((item) => typeof item === "string" ? item === name : item.test(name));
1936
+ }
3168
1937
  function merge(values, options) {
3169
- if (!Array.isArray(values) || values.length === 0) {
3170
- return {};
3171
- }
3172
- return mergeValues(values, getOptions(options));
1938
+ if (!Array.isArray(values) || values.length === 0) return {};
1939
+ return mergeValues(values, getOptions(options), true);
3173
1940
  }
3174
1941
  function mergeObjects(values, options, prefix) {
3175
- const { length } = values;
3176
- const isArray = values.every(Array.isArray);
3177
- const result = (isArray ? [] : {});
3178
- for (let outerIndex = 0; outerIndex < length; outerIndex += 1) {
3179
- const item = values[outerIndex];
3180
- const keys = Object.keys(item);
3181
- const size = keys.length;
3182
- for (let innerIndex = 0; innerIndex < size; innerIndex += 1) {
3183
- const key = keys[innerIndex];
3184
- const full = join([prefix, key], '.');
3185
- const next = item[key];
3186
- const previous = result[key];
3187
- if (isArray && options.skipNullableInArrays && next == null) {
3188
- continue;
3189
- }
3190
- if (!(isArrayOrPlainObject(next) && isArrayOrPlainObject(previous)) ||
3191
- (options.replaceableObjects?.(full) ?? false)) {
3192
- result[key] = next;
3193
- }
3194
- else {
3195
- result[key] = mergeValues([previous, next], options, full);
3196
- }
3197
- }
3198
- }
3199
- return result;
3200
- }
3201
- function mergeValues(values, options, prefix) {
3202
- const actual = values.filter(isArrayOrPlainObject);
3203
- return actual.length > 1
3204
- ? mergeObjects(actual, options, prefix)
3205
- : (actual[0] ?? {});
3206
- }
3207
-
3208
- /**
3209
- * Create a new object with only the specified keys
3210
- * @param value Original object
3211
- * @param keys Keys to use
3212
- * @returns Partial object with only the specified keys
3213
- */
1942
+ const { length } = values;
1943
+ const isArray = values.every(Array.isArray);
1944
+ const result = isArray ? [] : {};
1945
+ for (let outerIndex = 0; outerIndex < length; outerIndex += 1) {
1946
+ const item = values[outerIndex];
1947
+ const keys = Object.keys(item);
1948
+ const size = keys.length;
1949
+ for (let innerIndex = 0; innerIndex < size; innerIndex += 1) {
1950
+ const key = keys[innerIndex];
1951
+ const full = join([prefix, key], ".");
1952
+ const next = item[key];
1953
+ const previous = result[key];
1954
+ if (isArray && options.skipNullableInArrays && next == null) continue;
1955
+ if (isArrayOrPlainObject(next) && isArrayOrPlainObject(previous) && !(options.replaceableObjects?.(full) ?? false)) result[key] = mergeValues([previous, next], options, false, full);
1956
+ else result[key] = next;
1957
+ }
1958
+ }
1959
+ return result;
1960
+ }
1961
+ function mergeValues(values, options, validate, prefix) {
1962
+ const actual = validate ? values.filter(isArrayOrPlainObject) : values;
1963
+ return actual.length > 1 ? mergeObjects(actual, options, prefix) : actual[0] ?? {};
1964
+ }
3214
1965
  function partial(value, keys) {
3215
- if (typeof value !== 'object' ||
3216
- value === null ||
3217
- Object.keys(value).length === 0 ||
3218
- !Array.isArray(keys) ||
3219
- keys.length === 0) {
3220
- return {};
3221
- }
3222
- const { length } = keys;
3223
- const result = {};
3224
- for (let index = 0; index < length; index += 1) {
3225
- const key = keys[index];
3226
- result[key] = value[key];
3227
- }
3228
- return result;
3229
- }
3230
-
3231
- function flatten(value, depth, smushed, prefix) {
3232
- if (depth >= MAX_DEPTH) {
3233
- return {};
3234
- }
3235
- if (smushed.has(value)) {
3236
- return smushed.get(value);
3237
- }
3238
- const keys = Object.keys(value);
3239
- const { length } = keys;
3240
- const flattened = {};
3241
- for (let index = 0; index < length; index += 1) {
3242
- const key = keys[index];
3243
- const val = value[key];
3244
- if (isArrayOrPlainObject(val)) {
3245
- Object.assign(flattened, {
3246
- [join([prefix, key], '.')]: Array.isArray(val) ? [...val] : { ...val },
3247
- ...flatten(val, depth + 1, smushed, join([prefix, key], '.')),
3248
- });
3249
- }
3250
- else {
3251
- flattened[join([prefix, key], '.')] = val;
3252
- }
3253
- }
3254
- smushed.set(value, flattened);
3255
- return flattened;
3256
- }
3257
- /**
3258
- * Smush an object into a flat object that uses dot notation keys
3259
- * @param value Object to smush
3260
- * @returns Smushed object with dot notation keys
3261
- */
1966
+ if (typeof value !== "object" || value === null || Object.keys(value).length === 0 || !Array.isArray(keys) || keys.length === 0) return {};
1967
+ const { length } = keys;
1968
+ const result = {};
1969
+ for (let index = 0; index < length; index += 1) {
1970
+ const key = keys[index];
1971
+ result[key] = value[key];
1972
+ }
1973
+ return result;
1974
+ }
1975
+ function flattenObject(value, depth, smushed, prefix) {
1976
+ if (depth >= MAX_DEPTH) return {};
1977
+ if (smushed.has(value)) return smushed.get(value);
1978
+ const keys = Object.keys(value);
1979
+ const { length } = keys;
1980
+ const flattened = {};
1981
+ for (let index = 0; index < length; index += 1) {
1982
+ const key = keys[index];
1983
+ const val = value[key];
1984
+ if (isArrayOrPlainObject(val)) Object.assign(flattened, {
1985
+ [join([prefix, key], ".")]: Array.isArray(val) ? [...val] : { ...val },
1986
+ ...flattenObject(val, depth + 1, smushed, join([prefix, key], "."))
1987
+ });
1988
+ else flattened[join([prefix, key], ".")] = val;
1989
+ }
1990
+ smushed.set(value, flattened);
1991
+ return flattened;
1992
+ }
3262
1993
  function smush(value) {
3263
- return typeof value === 'object' && value !== null
3264
- ? flatten(value, 0, new WeakMap())
3265
- : {};
1994
+ return typeof value === "object" && value !== null ? flattenObject(value, 0, /* @__PURE__ */ new WeakMap()) : {};
3266
1995
  }
3267
- //
3268
1996
  const MAX_DEPTH = 100;
3269
-
3270
1997
  function getKeys(value) {
3271
- const keys = Object.keys(value);
3272
- const { length } = keys;
3273
- const result = [];
3274
- for (let index = 0; index < length; index += 1) {
3275
- const key = keys[index];
3276
- result.push({
3277
- order: key.split('.').length,
3278
- value: key,
3279
- });
3280
- }
3281
- return result.sort((first, second) => first.order - second.order);
3282
- }
3283
- /**
3284
- * Unsmush a smushed object _(turning dot notation keys into nested keys)_
3285
- * @param value Object to unsmush
3286
- * @returns Unsmushed object with nested keys
3287
- */
1998
+ const keys = Object.keys(value);
1999
+ const { length } = keys;
2000
+ const result = [];
2001
+ for (let index = 0; index < length; index += 1) {
2002
+ const key = keys[index];
2003
+ result.push({
2004
+ order: key.split(".").length,
2005
+ value: key
2006
+ });
2007
+ }
2008
+ return result.sort((first, second) => first.order - second.order);
2009
+ }
3288
2010
  function unsmush(value) {
3289
- if (typeof value !== 'object' || value === null) {
3290
- return {};
3291
- }
3292
- const keys = getKeys(value);
3293
- const { length } = keys;
3294
- const unsmushed = {};
3295
- for (let index = 0; index < length; index += 1) {
3296
- const key = keys[index].value;
3297
- const val = value[key];
3298
- let next = val;
3299
- if (isArrayOrPlainObject(val)) {
3300
- next = Array.isArray(val) ? [...val] : { ...val };
3301
- }
3302
- setValue(unsmushed, key, next);
3303
- }
3304
- return unsmushed;
3305
- }
3306
-
3307
- export { SizedMap, SizedSet, average, between, camelCase, capitalize, chunk, clamp, clone, compact, compare, count, createUuid, debounce, diff, emitter, equal, exists, filter, find, flatten$1 as flatten, fromQuery, getArray, getColor, getForegroundColor, getHexColor, getHexaColor, getHslColor, getHslaColor, getNormalizedHex, getNumber, getRandomBoolean, getRandomCharacters, getRandomColor, getRandomFloat, getRandomHex, getRandomInteger, getRandomItem, getRandomItems, getRgbColor, getRgbaColor, getString, getValue, groupBy, hexToHsl, hexToHsla, hexToRgb, hexToRgba, hslToHex, hslToRgb, hslToRgba, indexOf, insert, isArrayOrPlainObject, isColor, isEmpty, isHexColor, isHslColor, isHslaColor, isKey, isNullable, isNullableOrEmpty, isNullableOrWhitespace, isNumber, isNumerical, isObject$1 as isObject, isPlainObject, isPrimitive, isRgbColor, isRgbaColor, isTypedArray, join, kebabCase, logger, max, memoize, merge, min, noop, parse, partial, pascalCase, push, rgbToHex, rgbToHsl, rgbToHsla, round, setValue, shuffle, smush, snakeCase, sort, splice, sum, template, throttle, titleCase, toMap, toQuery, toRecord, toSet, truncate, unique, unsmush, words };
2011
+ if (typeof value !== "object" || value === null) return {};
2012
+ const keys = getKeys(value);
2013
+ const { length } = keys;
2014
+ const unsmushed = {};
2015
+ for (let index = 0; index < length; index += 1) {
2016
+ const key = keys[index].value;
2017
+ const val = value[key];
2018
+ let next = val;
2019
+ if (isArrayOrPlainObject(val)) next = Array.isArray(val) ? [...val] : { ...val };
2020
+ setValue(unsmushed, key, next);
2021
+ }
2022
+ return unsmushed;
2023
+ }
2024
+ export { frame_rate_default as FRAME_RATE_MS, SizedMap, SizedSet, average, between, camelCase, capitalize, chunk, clamp, clone, compact, compare, count, createUuid, debounce, diff, emitter, equal, exists, filter, find, flatten, fromQuery, getArray, getColor, getForegroundColor, getHexColor, getHexaColor, getHslColor, getHslaColor, getNormalizedHex, getNumber, getRandomBoolean, getRandomCharacters, getRandomColor, getRandomFloat, getRandomHex, getRandomInteger, getRandomItem, getRandomItems, getRgbColor, getRgbaColor, getString, getValue, groupBy, hexToHsl, hexToHsla, hexToRgb, hexToRgba, hslToHex, hslToRgb, hslToRgba, indexOf, insert, isArrayOrPlainObject, isColor, isEmpty, isHexColor, isHslColor, isHslLike, isHslaColor, isKey, isNullable, isNullableOrEmpty, isNullableOrWhitespace, isNumber, isNumerical, isObject, isPlainObject, isPrimitive, isRgbColor, isRgbLike, isRgbaColor, isTypedArray, join, kebabCase, logger, max, memoize, merge, min, noop, parse, partial, pascalCase, push, rgbToHex, rgbToHsl, rgbToHsla, round, setValue, shuffle, smush, snakeCase, sort, splice, sum, template, throttle, titleCase, toMap, toQuery, toRecord, toSet, truncate, unique, unsmush, words };