@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.
- package/dist/atoms.full.js +1690 -2973
- package/dist/color/index.js +3 -3
- package/dist/color/misc/get.js +16 -2
- package/dist/color/misc/is.js +10 -1
- package/dist/color/misc/state.js +26 -24
- package/dist/color/space/hsl.js +19 -14
- package/dist/color/space/rgb.js +19 -19
- package/dist/function.js +9 -10
- package/dist/index.js +5 -4
- package/dist/internal/frame-rate.js +22 -0
- package/dist/internal/function.js +1 -20
- package/dist/value/diff.js +2 -3
- package/dist/value/merge.js +5 -5
- package/dist/value/smush.js +3 -3
- package/package.json +16 -15
- package/src/array/find.ts +1 -4
- package/src/array/flatten.ts +1 -3
- package/src/array/get.ts +1 -3
- package/src/array/group-by.ts +8 -21
- package/src/array/insert.ts +1 -5
- package/src/array/models.ts +3 -17
- package/src/array/sort.ts +13 -49
- package/src/array/splice.ts +3 -16
- package/src/array/to-map.ts +6 -14
- package/src/array/to-record.ts +9 -21
- package/src/array/to-set.ts +4 -4
- package/src/array/unique.ts +1 -3
- package/src/color/constants.ts +2 -9
- package/src/color/index.ts +3 -17
- package/src/color/instance.ts +2 -8
- package/src/color/misc/alpha.ts +1 -5
- package/src/color/misc/get.ts +21 -5
- package/src/color/misc/index.ts +1 -5
- package/src/color/misc/is.ts +15 -17
- package/src/color/misc/state.ts +33 -50
- package/src/color/models.ts +1 -8
- package/src/color/space/hex.ts +2 -6
- package/src/color/space/hsl.ts +22 -44
- package/src/color/space/rgb.ts +20 -39
- package/src/emitter.ts +3 -13
- package/src/function.ts +14 -30
- package/src/index.ts +4 -0
- package/src/internal/array/chunk.ts +1 -3
- package/src/internal/array/find.ts +7 -28
- package/src/internal/array/insert.ts +1 -7
- package/src/internal/frame-rate.ts +53 -0
- package/src/internal/function.ts +0 -50
- package/src/internal/is.ts +1 -3
- package/src/internal/math/aggregate.ts +2 -10
- package/src/internal/number.ts +3 -14
- package/src/internal/random.ts +2 -6
- package/src/internal/string.ts +1 -1
- package/src/internal/value/compare.ts +2 -8
- package/src/internal/value/equal.ts +29 -101
- package/src/internal/value/get.ts +9 -19
- package/src/internal/value/misc.ts +1 -4
- package/src/internal/value/set.ts +10 -9
- package/src/is.ts +5 -19
- package/src/math.ts +3 -11
- package/src/models.ts +93 -15
- package/src/query.ts +2 -10
- package/src/random.ts +4 -15
- package/src/sized.ts +3 -3
- package/src/string/case.ts +4 -11
- package/src/string/misc.ts +1 -5
- package/src/string/template.ts +1 -3
- package/src/value/clone.ts +4 -20
- package/src/value/diff.ts +4 -12
- package/src/value/merge.ts +11 -15
- package/src/value/smush.ts +13 -7
- package/src/value/unsmush.ts +18 -5
- package/types/array/group-by.d.ts +1 -2
- package/types/array/to-record.d.ts +1 -2
- package/types/color/index.d.ts +3 -3
- package/types/color/misc/get.d.ts +3 -0
- package/types/color/misc/is.d.ts +2 -0
- package/types/color/space/hsl.d.ts +1 -0
- package/types/color/space/rgb.d.ts +2 -1
- package/types/index.d.ts +2 -0
- package/types/internal/frame-rate.d.ts +5 -0
- package/types/internal/function.d.ts +0 -4
- package/types/internal/value/get.d.ts +3 -3
- package/types/internal/value/set.d.ts +3 -3
- package/types/is.d.ts +1 -1
- package/types/models.d.ts +33 -2
- package/types/value/smush.d.ts +3 -4
- package/types/value/unsmush.d.ts +9 -2
package/dist/atoms.full.js
CHANGED
|
@@ -1,3307 +1,2024 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
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
|
-
|
|
64
|
+
return TYPED_ARRAYS.has(value?.constructor);
|
|
96
65
|
}
|
|
97
|
-
//
|
|
98
66
|
const TYPED_ARRAYS = new Set([
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
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
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
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
|
-
|
|
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
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
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
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
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
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
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
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
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
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
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
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
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
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
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
|
-
|
|
266
|
-
|
|
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
|
-
|
|
171
|
+
return findValues("all", array, parameters);
|
|
273
172
|
}
|
|
274
|
-
|
|
275
173
|
function find(array, ...parameters) {
|
|
276
|
-
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
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
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
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
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
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
|
-
|
|
212
|
+
return findValue("index", array, parameters);
|
|
342
213
|
}
|
|
343
|
-
|
|
344
|
-
//
|
|
345
214
|
function insertChunkedValues(type, array, items, start, deleteCount) {
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
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
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
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
|
-
|
|
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
|
-
|
|
239
|
+
return insertValues("push", array, pushed, array.length, 0);
|
|
390
240
|
}
|
|
391
|
-
|
|
392
241
|
function aggregate(type, array, key) {
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
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
|
-
|
|
267
|
+
return aggregate("max", array, key).value;
|
|
423
268
|
}
|
|
424
269
|
function sum$1(current, value, notNumber) {
|
|
425
|
-
|
|
270
|
+
return notNumber ? value : current + value;
|
|
426
271
|
}
|
|
427
|
-
//
|
|
428
272
|
const aggregators = {
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
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
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
}
|
|
293
|
+
try {
|
|
294
|
+
return callback(value);
|
|
295
|
+
} catch {
|
|
296
|
+
return value;
|
|
297
|
+
}
|
|
477
298
|
}
|
|
478
299
|
function tryDecode(value) {
|
|
479
|
-
|
|
300
|
+
return tryCallback(value, decodeURIComponent);
|
|
480
301
|
}
|
|
481
302
|
function tryEncode(value) {
|
|
482
|
-
|
|
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
|
-
|
|
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
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
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
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
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
|
-
|
|
339
|
+
return getString(first.description ?? first).localeCompare(getString(second.description ?? second));
|
|
545
340
|
}
|
|
546
341
|
function compareValue(first, second, compareStrings) {
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
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
|
-
|
|
561
|
-
|
|
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
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
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
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
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
|
-
|
|
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
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
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
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
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
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
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
|
-
|
|
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
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
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
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
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
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
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 =
|
|
480
|
+
const ALPHA_NONE_HEX = "00";
|
|
795
481
|
const ALPHA_NONE_VALUE = 0;
|
|
796
482
|
const DEFAULT_ALPHA = {
|
|
797
|
-
|
|
798
|
-
|
|
483
|
+
hex: ALPHA_FULL_HEX_LONG,
|
|
484
|
+
value: ALPHA_FULL_VALUE
|
|
799
485
|
};
|
|
800
486
|
const DEFAULT_HSL = {
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
487
|
+
hue: 0,
|
|
488
|
+
lightness: 0,
|
|
489
|
+
saturation: 0
|
|
804
490
|
};
|
|
805
491
|
const DEFAULT_RGB = {
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
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 =
|
|
814
|
-
const HEX_WHITE =
|
|
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 = [
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
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 =
|
|
829
|
-
const SRGB_LUMINANCE_MINIMUM =
|
|
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 =
|
|
833
|
-
const SRGB_LUMINANCE_RED =
|
|
834
|
-
const SRGB_LUMINANCE_THRESHOLD =
|
|
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
|
-
|
|
838
|
-
|
|
839
|
-
|
|
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
|
-
|
|
844
|
-
|
|
533
|
+
hsl: KEYS_HSL,
|
|
534
|
+
rgb: KEYS_RGB
|
|
845
535
|
};
|
|
846
|
-
|
|
847
536
|
function getAlpha(value) {
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
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
|
-
|
|
861
|
-
|
|
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
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
550
|
+
const alpha = getAlphaValue(value);
|
|
551
|
+
return {
|
|
552
|
+
hex: getAlphaHexadecimal(alpha),
|
|
553
|
+
value: alpha
|
|
554
|
+
};
|
|
874
555
|
}
|
|
875
556
|
function getAlphaValue(original) {
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
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
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
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
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
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
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1041
|
-
}
|
|
1042
|
-
function
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
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
|
-
|
|
651
|
+
return typeof value === "number" && between(value, 0, MAX_PERCENT);
|
|
1062
652
|
}
|
|
1063
|
-
//
|
|
1064
653
|
const validators = {
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
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
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
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
|
-
|
|
777
|
+
return convertRgbToHsla(rgb);
|
|
1161
778
|
}
|
|
1162
|
-
|
|
1163
779
|
function convertHexToRgba(value) {
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
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
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
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
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
*/
|
|
811
|
+
const { blue, green, red } = convertHexToRgba(value);
|
|
812
|
+
return {
|
|
813
|
+
blue,
|
|
814
|
+
green,
|
|
815
|
+
red
|
|
816
|
+
};
|
|
817
|
+
}
|
|
1228
818
|
function hexToRgba(value) {
|
|
1229
|
-
|
|
1230
|
-
}
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
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
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
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
|
-
|
|
856
|
+
return convertHslToRgba(hsl);
|
|
1279
857
|
}
|
|
1280
|
-
|
|
1281
858
|
function getState(value) {
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
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
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
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
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
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
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
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
|
-
|
|
1573
|
-
}
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
}
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
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
|
-
|
|
1087
|
+
return new Emitter(value);
|
|
1752
1088
|
}
|
|
1753
1089
|
function finishEmitter(state, emit) {
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
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
|
-
|
|
1104
|
+
return typeof value === "function" ? value : defaultValue;
|
|
1771
1105
|
}
|
|
1772
1106
|
function getObserver(first, second, third) {
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
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
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
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
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
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
|
-
|
|
2054
|
-
|
|
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
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
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
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
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
|
-
|
|
2203
|
-
|
|
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
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
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
|
-
|
|
2232
|
-
|
|
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
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
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
|
-
|
|
2252
|
-
|
|
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
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
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
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
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
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
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
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
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
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
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
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
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
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
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
|
-
|
|
1466
|
+
return TYPES.has(typeof value);
|
|
2387
1467
|
}
|
|
2388
1468
|
function setQueryValue(parameters, key, value) {
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
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
|
-
|
|
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([
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
*/
|
|
1480
|
+
const TYPES = new Set([
|
|
1481
|
+
"boolean",
|
|
1482
|
+
"number",
|
|
1483
|
+
"string"
|
|
1484
|
+
]);
|
|
2423
1485
|
function getRandomBoolean() {
|
|
2424
|
-
|
|
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
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2467
|
-
|
|
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
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2508
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2545
|
-
|
|
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
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
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
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
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
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
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
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
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 =
|
|
2637
|
-
|
|
1580
|
+
const TEMPLATE_UUID = "10000000-1000-4000-8000-100000000000";
|
|
2638
1581
|
function getValue(data, path, ignoreCase) {
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
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
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
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
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
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
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
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
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
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
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
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
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
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
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
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
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
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
|
-
|
|
1740
|
+
return cloneValue(value, 0, /* @__PURE__ */ new WeakMap());
|
|
2905
1741
|
}
|
|
2906
1742
|
function cloneArrayBuffer(value, depth, references) {
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
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
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
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
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
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
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
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
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
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
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
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
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
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
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
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
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
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
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
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
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
|
|
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
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
|
|
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
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
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
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
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
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
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
|
-
|
|
3170
|
-
|
|
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
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
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
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
}
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
|
|
3240
|
-
|
|
3241
|
-
|
|
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
|
-
|
|
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
|
-
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
|
|
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
|
-
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
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 };
|