@baleada/logic 0.22.7 → 0.23.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/lib/index.cjs +2229 -508
  2. package/lib/index.d.ts +511 -73
  3. package/lib/index.js +2172 -500
  4. package/package.json +28 -16
package/lib/index.js CHANGED
@@ -1,50 +1,55 @@
1
- import { reduce, pipe, unique, toArray, slice, filter, map, concat, find, findIndex, join, some, every } from 'lazy-collections';
2
- import slugify from '@sindresorhus/slugify';
3
1
  import BezierEasing from 'bezier-easing';
4
2
  import { mix } from '@snigo.dev/color';
3
+ import { pipe, concat, toArray, filter, map, reduce, slice, sort, unique, find, findIndex, join, at, includes, some, every, flatMap, reverse as reverse$1 } from 'lazy-collections';
5
4
  import { getStroke } from 'perfect-freehand';
6
5
  import polygonClipping from 'polygon-clipping';
6
+ import ky from 'ky';
7
7
  import createDOMPurify from 'dompurify';
8
8
  import { Searcher } from 'fast-fuzzy';
9
+ import { klona } from 'klona';
10
+ import { dequal } from 'dequal';
11
+ import slugify from '@sindresorhus/slugify';
12
+ import clsx from 'clsx';
9
13
 
10
- function createReduceAsync(accumulate, initialValue) {
11
- return async (array) => {
12
- return await reduce(
13
- async (accumulatorPromise, item, index) => {
14
- const accumulator = await accumulatorPromise;
15
- return accumulate(accumulator, item, index);
16
- },
17
- Promise.resolve(initialValue)
18
- )(array);
14
+ function createClone() {
15
+ return (any) => {
16
+ return klona(any);
19
17
  };
20
18
  }
21
- function createReduce(accumulate, initialValue) {
22
- return (array) => reduce(accumulate, initialValue)(array);
19
+ function createEqual(compared) {
20
+ return (any) => dequal(any, compared);
23
21
  }
24
- function createForEachAsync(forEach) {
25
- return async (array) => {
26
- await createReduceAsync(async (_, item, index) => await forEach(item, index))(array);
27
- return array;
28
- };
22
+
23
+ function createConcat(...arrays) {
24
+ return (array) => pipe(
25
+ concat(array, ...arrays),
26
+ toArray()
27
+ )();
29
28
  }
30
- function createMapAsync(transform) {
31
- return async (array) => {
32
- return await createReduceAsync(
33
- async (resolvedMaps, item, index) => {
34
- const transformed = await transform(item, index);
35
- resolvedMaps.push(transformed);
36
- return resolvedMaps;
37
- },
38
- []
39
- )(array);
40
- };
29
+ function createFilter(predicate) {
30
+ return (array) => pipe(
31
+ filter(predicate),
32
+ toArray()
33
+ )(array);
41
34
  }
42
- function createFilterAsync(predicate) {
43
- return async (array) => {
44
- const transformedAsync = await createMapAsync(predicate)(array);
45
- return createFilter((_, index) => transformedAsync[index])(array);
35
+ function createInsert(item, index) {
36
+ return (array) => {
37
+ const withItems = createConcat(array, [item])([]);
38
+ return createReorder(
39
+ { start: array.length, itemCount: 1 },
40
+ index
41
+ )(withItems);
46
42
  };
47
43
  }
44
+ function createMap(transform) {
45
+ return (array) => pipe(
46
+ map(transform),
47
+ toArray()
48
+ )(array);
49
+ }
50
+ function createReduce(accumulate, initialValue) {
51
+ return (array) => reduce(accumulate, initialValue)(array);
52
+ }
48
53
  function createRemove(index) {
49
54
  return (array) => {
50
55
  return createConcat(
@@ -53,15 +58,6 @@ function createRemove(index) {
53
58
  )([]);
54
59
  };
55
60
  }
56
- function createInsert(item, index) {
57
- return (array) => {
58
- const withItems = createConcat(array, [item])([]);
59
- return createReorder(
60
- { start: array.length, itemCount: 1 },
61
- index
62
- )(withItems);
63
- };
64
- }
65
61
  function createReorder(from, to) {
66
62
  return (array) => {
67
63
  const [itemsToMoveStartIndex, itemsToMoveCount] = predicateObject(from) ? [from.start, from.itemCount] : [from, 1], insertIndex = to;
@@ -90,8 +86,34 @@ function createReorder(from, to) {
90
86
  return array;
91
87
  };
92
88
  }
93
- function predicateObject(value) {
94
- return typeof value === "object";
89
+ function createReplace(index, replacement) {
90
+ return createMap((item, i) => i === index ? replacement : item);
91
+ }
92
+ function createReverse() {
93
+ return (array) => {
94
+ const reversed = [];
95
+ for (let i = array.length - 1; i > -1; i--) {
96
+ reversed.push(array[i]);
97
+ }
98
+ return reversed;
99
+ };
100
+ }
101
+ function createSlice(from, to) {
102
+ const toSliced = to ? slice(from, to - 1) : slice(from);
103
+ return (array) => {
104
+ return from === to ? [] : pipe(
105
+ toSliced,
106
+ toArray()
107
+ )(array);
108
+ };
109
+ }
110
+ function createSort(compare) {
111
+ return (array) => {
112
+ return pipe(
113
+ sort(compare),
114
+ toArray()
115
+ )(array);
116
+ };
95
117
  }
96
118
  function createSwap(indices) {
97
119
  return (array) => {
@@ -113,16 +135,7 @@ function createSwap(indices) {
113
135
  reorderTo: (array2) => array2
114
136
  };
115
137
  })();
116
- return new Pipeable(array).pipe(reorderFrom, reorderTo);
117
- };
118
- }
119
- function createReplace(index, item) {
120
- return (array) => {
121
- return createConcat(
122
- createSlice(0, index)(array),
123
- [item],
124
- createSlice(index + 1)(array)
125
- )([]);
138
+ return pipe(reorderFrom, reorderTo)(array);
126
139
  };
127
140
  }
128
141
  function createUnique() {
@@ -131,277 +144,1990 @@ function createUnique() {
131
144
  toArray()
132
145
  )(array);
133
146
  }
134
- function createSlice(from, to) {
135
- return (array) => {
136
- return from === to ? [] : pipe(
137
- slice(from, to - 1),
138
- toArray()
147
+
148
+ function createFilterAsync(predicate) {
149
+ return async (array) => {
150
+ const transformedAsync = await createMapAsync(predicate)(array);
151
+ return createFilter((_, index) => transformedAsync[index])(array);
152
+ };
153
+ }
154
+ function createFindAsync(predicate) {
155
+ return async (array) => {
156
+ for (let i = 0; i < array.length; i++) {
157
+ const item = array[i], is = await predicate(item, i);
158
+ if (is)
159
+ return item;
160
+ }
161
+ };
162
+ }
163
+ function createFindIndexAsync(predicate) {
164
+ return async (array) => {
165
+ for (let i = 0; i < array.length; i++) {
166
+ const item = array[i], is = await predicate(item, i);
167
+ if (is)
168
+ return i;
169
+ }
170
+ };
171
+ }
172
+ function createForEachAsync(forEach) {
173
+ return async (array) => {
174
+ for (let i = 0; i < array.length; i++) {
175
+ const item = array[i];
176
+ await forEach(item, i);
177
+ }
178
+ return array;
179
+ };
180
+ }
181
+ function createMapAsync(transform) {
182
+ return async (array) => {
183
+ return await createReduceAsync(
184
+ async (resolvedMaps, item, index) => {
185
+ const transformed = await transform(item, index);
186
+ resolvedMaps.push(transformed);
187
+ return resolvedMaps;
188
+ },
189
+ []
139
190
  )(array);
140
191
  };
141
192
  }
142
- function createFilter(predicate) {
143
- return (array) => pipe(
144
- filter(predicate),
145
- toArray()
146
- )(array);
193
+ function createReduceAsync(accumulate, initialValue) {
194
+ return async (array) => {
195
+ return await reduce(
196
+ async (accumulatorPromise, item, index) => {
197
+ const accumulator = await accumulatorPromise;
198
+ return accumulate(accumulator, item, index);
199
+ },
200
+ Promise.resolve(initialValue)
201
+ )(array);
202
+ };
147
203
  }
148
- function createMap(transform) {
149
- return (array) => pipe(
150
- map(transform),
151
- toArray()
152
- )(array);
204
+
205
+ function createClip(required) {
206
+ return (string) => {
207
+ return string.replace(required, "");
208
+ };
153
209
  }
154
- function createConcat(...arrays) {
155
- return (array) => pipe(
156
- concat(array, ...arrays),
157
- toArray()
158
- )();
210
+ function createSlug(options) {
211
+ return (string) => {
212
+ return slugify(string, options);
213
+ };
159
214
  }
160
- function createReverse() {
161
- return (array) => {
162
- const reversed = [];
163
- for (let i = array.length - 1; i > -1; i--) {
164
- reversed.push(array[i]);
215
+
216
+ function createClamp(min, max) {
217
+ return (number) => {
218
+ const maxed = Math.max(number, min);
219
+ return Math.min(maxed, max);
220
+ };
221
+ }
222
+ function createDetermine(potentialities) {
223
+ const predicates = createMap(({ outcome, probability }, index) => {
224
+ const lowerBound = index === 0 ? 0 : pipe(
225
+ slice(0, index - 1),
226
+ reduce((lowerBound2, { probability: probability2 }) => lowerBound2 + probability2, 0)
227
+ )(potentialities), upperBound = lowerBound + probability;
228
+ return {
229
+ outcome,
230
+ predicate: (determinant) => determinant >= lowerBound && determinant < upperBound || determinant < 0 && index === 0 || index === predicates.length - 1
231
+ };
232
+ })(potentialities);
233
+ return (determinant) => find(({ predicate }) => predicate(determinant))(predicates).outcome;
234
+ }
235
+
236
+ function createEntries() {
237
+ return (object) => {
238
+ const entries = [];
239
+ for (const key in object) {
240
+ entries.push([key, object[key]]);
241
+ }
242
+ return entries;
243
+ };
244
+ }
245
+ function createKeys() {
246
+ return (object) => {
247
+ const keys = [];
248
+ for (const key in object) {
249
+ keys.push(key);
250
+ }
251
+ return keys;
252
+ };
253
+ }
254
+ function createEvery(predicate) {
255
+ return (object) => {
256
+ for (const key in object) {
257
+ if (!predicate(key, object[key])) {
258
+ return false;
259
+ }
260
+ }
261
+ return true;
262
+ };
263
+ }
264
+ function createSome(predicate) {
265
+ return (object) => {
266
+ for (const key in object) {
267
+ if (predicate(key, object[key]))
268
+ return true;
269
+ }
270
+ return false;
271
+ };
272
+ }
273
+
274
+ function createRename(from, to) {
275
+ return (map) => {
276
+ const keys = [...map.keys()], keyToRenameIndex = findIndex((k) => k === from)(keys), newKeys = createReplace(keyToRenameIndex, to)(keys), values = [...map.values()];
277
+ return createReduce((renamed, key, index) => renamed.set(key, values[index]), /* @__PURE__ */ new Map())(newKeys);
278
+ };
279
+ }
280
+
281
+ const defaultOptions$m = {
282
+ elementIsCandidate: false,
283
+ // Adapted from React Aria https://github.com/adobe/react-spectrum/blob/b6786da906973130a1746b2bee63215bba013ca4/packages/%40react-aria/focus/src/FocusScope.tsx#L256
284
+ tabbableSelector: join(':not([hidden]):not([tabindex="-1"]),')([
285
+ "input:not([disabled]):not([type=hidden])",
286
+ "select:not([disabled])",
287
+ "textarea:not([disabled])",
288
+ "button:not([disabled])",
289
+ "a[href]",
290
+ "area[href]",
291
+ "summary",
292
+ "iframe",
293
+ "object",
294
+ "embed",
295
+ "audio[controls]",
296
+ "video[controls]",
297
+ "[contenteditable]",
298
+ "[tabindex]:not([disabled])"
299
+ ])
300
+ };
301
+ function createFocusable(order, options = {}) {
302
+ const { elementIsCandidate, tabbableSelector } = { ...defaultOptions$m, ...options }, predicateFocusable = (element) => element.matches(tabbableSelector);
303
+ return (element) => {
304
+ if (elementIsCandidate && predicateFocusable(element))
305
+ return element;
306
+ switch (order) {
307
+ case "first":
308
+ for (let i = 0; i < element.children.length; i++) {
309
+ const focusable = createFocusable(order, { elementIsCandidate: true })(element.children[i]);
310
+ if (focusable)
311
+ return focusable;
312
+ }
313
+ break;
314
+ case "last":
315
+ for (let i = element.children.length - 1; i > -1; i--) {
316
+ const focusable = createFocusable(order, { elementIsCandidate: true })(element.children[i]);
317
+ if (focusable)
318
+ return focusable;
319
+ }
320
+ break;
321
+ }
322
+ };
323
+ }
324
+
325
+ function createToIndegree(graph) {
326
+ const toIncoming = createToIncoming(graph);
327
+ return (node) => pipe(
328
+ toIncoming,
329
+ toLength()
330
+ )(node);
331
+ }
332
+ function createToOutdegree(graph) {
333
+ const toOutgoing = createToOutgoing(graph);
334
+ return (node) => pipe(
335
+ toOutgoing,
336
+ toLength()
337
+ )(node);
338
+ }
339
+ function createToIncoming(graph) {
340
+ const { edges } = graph;
341
+ return function* (node) {
342
+ yield* filter(
343
+ ({ to }) => to === node
344
+ )(edges);
345
+ };
346
+ }
347
+ function createToOutgoing(graph) {
348
+ const { edges } = graph;
349
+ return function* (node) {
350
+ yield* filter(
351
+ ({ from }) => from === node
352
+ )(edges);
353
+ };
354
+ }
355
+ function createPredicateRoot(graph) {
356
+ const toIndegree = createToIndegree(graph);
357
+ return (node) => toIndegree(node) === 0;
358
+ }
359
+
360
+ function createFind(node) {
361
+ return (tree) => {
362
+ for (const treeNode of tree) {
363
+ if (treeNode.node === node)
364
+ return treeNode;
365
+ const found = createFind(node)(treeNode.children);
366
+ if (found)
367
+ return found;
368
+ }
369
+ };
370
+ }
371
+
372
+ function createToLayers$1(options = {}) {
373
+ const toSteps = createToSteps$2(options.createToSteps);
374
+ return function toLayers(directedAcyclic) {
375
+ const layers = [];
376
+ for (const { path } of toSteps(directedAcyclic)) {
377
+ const node = path.at(-1), depth = path.length - 1;
378
+ (layers[depth] || (layers[depth] = [])).push(node);
379
+ }
380
+ return layers;
381
+ };
382
+ }
383
+ function createToTree$2(options = {}) {
384
+ const toSteps = createToSteps$2(options.createToSteps);
385
+ return function toTree(directedAcyclic) {
386
+ const firstRoot = pipe(
387
+ createToRoots(),
388
+ at(0)
389
+ )(directedAcyclic), tree = [];
390
+ tree.push({
391
+ node: firstRoot,
392
+ children: []
393
+ });
394
+ for (const { path } of toSteps(directedAcyclic)) {
395
+ const node = path.at(-1), parent = path.at(-2);
396
+ if (parent) {
397
+ const parentTreeNode = createFind(parent)(tree);
398
+ if (parentTreeNode) {
399
+ parentTreeNode.children.push({
400
+ node,
401
+ children: []
402
+ });
403
+ }
404
+ }
405
+ }
406
+ return tree;
407
+ };
408
+ }
409
+ function createToCommonAncestors$2(directedAcyclic) {
410
+ const toNodeSteps = createToNodeSteps$2(directedAcyclic);
411
+ return function* (a, b) {
412
+ for (const { path: aPath } of toNodeSteps(a)) {
413
+ for (const { path: bPath } of toNodeSteps(b)) {
414
+ for (let aPathIndex = aPath.length - 1; aPathIndex >= 0; aPathIndex--) {
415
+ for (let bPathIndex = bPath.length - 1; bPathIndex >= 0; bPathIndex--) {
416
+ if (aPath[aPathIndex] === bPath[bPathIndex] && !includes(aPath[aPathIndex])([a, b])) {
417
+ yield {
418
+ node: aPath[aPathIndex],
419
+ distances: {
420
+ [a]: aPath.length - aPathIndex - 1,
421
+ [b]: bPath.length - bPathIndex - 1
422
+ }
423
+ };
424
+ }
425
+ }
426
+ }
427
+ }
428
+ }
429
+ };
430
+ }
431
+ function createPredicateAncestor$2(directedAcyclic) {
432
+ const toNodeSteps = createToNodeSteps$2(directedAcyclic);
433
+ return function(descendant, ancestor) {
434
+ return pipe(
435
+ toNodeSteps,
436
+ some(({ path }) => includes(ancestor)(path))
437
+ )(descendant);
438
+ };
439
+ }
440
+ function createToNodeSteps$2(directedAcyclic, options = {}) {
441
+ const toSteps = createToSteps$2(options.createToSteps);
442
+ return function* (node) {
443
+ yield* pipe(
444
+ toSteps,
445
+ filter(({ path }) => path.at(-1) === node)
446
+ )(directedAcyclic);
447
+ };
448
+ }
449
+ const defaultCreateToStepsOptions$1 = {
450
+ toUnsetMetadata: () => 0,
451
+ toMockMetadata: (node, totalConnectionsFollowed) => totalConnectionsFollowed,
452
+ kind: "directed acyclic"
453
+ };
454
+ function createToSteps$2(options = {}) {
455
+ const { toUnsetMetadata, toMockMetadata, root, kind } = { ...defaultCreateToStepsOptions$1, ...options };
456
+ return function* (directedAcyclic) {
457
+ const { nodes } = directedAcyclic, toOutdegree = createToOutdegree(directedAcyclic), toPath = createToPath$2(directedAcyclic), roots = pipe(
458
+ createToRoots({ kind }),
459
+ toArray()
460
+ )(directedAcyclic), state = {}, totalConnectionsFollowedByNode = {}, predicateExhausted = (node) => {
461
+ return totalConnectionsFollowedByNode[node] === toOutdegree(node);
462
+ };
463
+ for (const node of nodes) {
464
+ state[node] = {
465
+ status: "unset",
466
+ metadata: toUnsetMetadata(node)
467
+ };
468
+ }
469
+ let location = root || at(0)(roots);
470
+ const path = toPath(state);
471
+ yield { path, state: JSON.parse(JSON.stringify(state)) };
472
+ function* toStep() {
473
+ if (predicateExhausted(location)) {
474
+ if (includes(location)(roots))
475
+ return;
476
+ state[location].status = "unset";
477
+ state[location].metadata = toUnsetMetadata(location);
478
+ const path3 = toPath(state);
479
+ location = path3.at(-2);
480
+ yield* toStep();
481
+ return;
482
+ }
483
+ if (!(location in totalConnectionsFollowedByNode))
484
+ totalConnectionsFollowedByNode[location] = 0;
485
+ state[location].status = "set";
486
+ state[location].metadata = toMockMetadata(location, totalConnectionsFollowedByNode[location]);
487
+ const path2 = toPath(state);
488
+ yield { path: path2, state: JSON.parse(JSON.stringify(state)) };
489
+ totalConnectionsFollowedByNode[location]++;
490
+ const newLocation = path2.at(-1);
491
+ if (toOutdegree(newLocation) > 0)
492
+ location = newLocation;
493
+ yield* toStep();
494
+ }
495
+ yield* toStep();
496
+ };
497
+ }
498
+ function createToPath$2(directedAcyclic) {
499
+ const toOutdegree = createToOutdegree(directedAcyclic), toOutgoing = createToOutgoing(directedAcyclic), firstRoot = pipe(
500
+ createToRoots(),
501
+ at(0)
502
+ )(directedAcyclic);
503
+ return (state) => {
504
+ const path = [firstRoot], getLastOutdegree = () => toOutdegree(path.at(-1)), getLastStatus = () => state[path.at(-1)].status;
505
+ while (getLastOutdegree() > 0 && getLastStatus() === "set") {
506
+ const edge = pipe(
507
+ toOutgoing,
508
+ find(
509
+ ({ predicateTraversable }) => predicateTraversable(state)
510
+ )
511
+ )(path.at(-1));
512
+ path.push(edge.to);
513
+ }
514
+ return path;
515
+ };
516
+ }
517
+ function createToRoots(options = {}) {
518
+ return function* (directedAcyclic) {
519
+ const { nodes } = directedAcyclic;
520
+ for (const node of nodes) {
521
+ if (createPredicateRoot(directedAcyclic)(node))
522
+ yield node;
523
+ if (options.kind === "arborescence")
524
+ break;
525
+ }
526
+ };
527
+ }
528
+
529
+ function createToLayers(options = {}) {
530
+ const toSteps = createToSteps$1(options.createToSteps);
531
+ return async function toLayers(directedAcyclic) {
532
+ const layers = [];
533
+ for await (const { path } of toSteps(directedAcyclic)) {
534
+ const node = path.at(-1), depth = path.length - 1;
535
+ (layers[depth] || (layers[depth] = [])).push(node);
536
+ }
537
+ return layers;
538
+ };
539
+ }
540
+ function createToTree$1(options = {}) {
541
+ const toSteps = createToSteps$1(options.createToSteps);
542
+ return async function toTree(directedAcyclic) {
543
+ const firstRoot = pipe(
544
+ createToRoots(),
545
+ at(0)
546
+ )(directedAcyclic), tree = [];
547
+ tree.push({
548
+ node: firstRoot,
549
+ children: []
550
+ });
551
+ for await (const { path } of toSteps(directedAcyclic)) {
552
+ const node = path.at(-1), parent = path.at(-2);
553
+ if (parent) {
554
+ const parentTreeNode = createFind(parent)(tree);
555
+ if (parentTreeNode) {
556
+ parentTreeNode.children.push({
557
+ node,
558
+ children: []
559
+ });
560
+ }
561
+ }
562
+ }
563
+ return tree;
564
+ };
565
+ }
566
+ function createToCommonAncestors$1(directedAcyclic) {
567
+ const toNodeSteps = createToNodeSteps$1(directedAcyclic);
568
+ return async function* (a, b) {
569
+ for await (const { path: aPath } of toNodeSteps(a)) {
570
+ for await (const { path: bPath } of toNodeSteps(b)) {
571
+ for (let aPathIndex = aPath.length - 1; aPathIndex >= 0; aPathIndex--) {
572
+ for (let bPathIndex = bPath.length - 1; bPathIndex >= 0; bPathIndex--) {
573
+ if (aPath[aPathIndex] === bPath[bPathIndex] && !includes(aPath[aPathIndex])([a, b])) {
574
+ yield {
575
+ node: aPath[aPathIndex],
576
+ distances: {
577
+ [a]: aPath.length - aPathIndex - 1,
578
+ [b]: bPath.length - bPathIndex - 1
579
+ }
580
+ };
581
+ }
582
+ }
583
+ }
584
+ }
585
+ }
586
+ };
587
+ }
588
+ function createPredicateAncestor$1(directedAcyclic) {
589
+ const toNodeSteps = createToNodeSteps$1(directedAcyclic);
590
+ return async function(descendant, ancestor) {
591
+ return await pipe(
592
+ toNodeSteps,
593
+ some(({ path }) => includes(ancestor)(path))
594
+ )(descendant);
595
+ };
596
+ }
597
+ function createToNodeSteps$1(directedAcyclic, options = {}) {
598
+ const toSteps = createToSteps$1(options.createToSteps);
599
+ return async function* (node) {
600
+ yield* await pipe(
601
+ toSteps,
602
+ filter(({ path }) => path.at(-1) === node)
603
+ )(directedAcyclic);
604
+ };
605
+ }
606
+ function createToSteps$1(options = {}) {
607
+ const { toUnsetMetadata, toMockMetadata, root, kind } = { ...defaultCreateToStepsOptions$1, ...options };
608
+ return async function* (directedAcyclic) {
609
+ const { nodes } = directedAcyclic, toOutdegree = createToOutdegree(directedAcyclic), toPath = createToPath$1(directedAcyclic), roots = pipe(
610
+ createToRoots({ kind }),
611
+ toArray()
612
+ )(directedAcyclic), state = {}, totalConnectionsFollowedByNode = {}, predicateExhausted = (node) => {
613
+ return totalConnectionsFollowedByNode[node] === toOutdegree(node);
614
+ };
615
+ for (const node of nodes) {
616
+ state[node] = {
617
+ status: "unset",
618
+ metadata: toUnsetMetadata(node)
619
+ };
620
+ }
621
+ let location = root || at(0)(roots);
622
+ const path = await toPath(state);
623
+ yield { path, state: JSON.parse(JSON.stringify(state)) };
624
+ async function* toStep() {
625
+ if (predicateExhausted(location)) {
626
+ if (includes(location)(roots))
627
+ return;
628
+ state[location].status = "unset";
629
+ state[location].metadata = toUnsetMetadata(location);
630
+ const path3 = await toPath(state);
631
+ location = path3.at(-2);
632
+ yield* await toStep();
633
+ return;
634
+ }
635
+ if (!(location in totalConnectionsFollowedByNode))
636
+ totalConnectionsFollowedByNode[location] = 0;
637
+ state[location].status = "set";
638
+ state[location].metadata = toMockMetadata(location, totalConnectionsFollowedByNode[location]);
639
+ const path2 = await toPath(state);
640
+ yield { path: path2, state: JSON.parse(JSON.stringify(state)) };
641
+ totalConnectionsFollowedByNode[location]++;
642
+ const newLocation = path2.at(-1);
643
+ if (toOutdegree(newLocation) > 0)
644
+ location = newLocation;
645
+ yield* await toStep();
646
+ }
647
+ yield* await toStep();
648
+ };
649
+ }
650
+ function createToPath$1(directedAcyclic) {
651
+ const toOutdegree = createToOutdegree(directedAcyclic), toOutgoing = createToOutgoing(directedAcyclic), firstRoot = pipe(
652
+ createToRoots(),
653
+ at(0)
654
+ )(directedAcyclic);
655
+ return async (state) => {
656
+ const path = [firstRoot], getLastOutdegree = () => toOutdegree(path.at(-1)), getLastStatus = () => state[path.at(-1)].status;
657
+ while (getLastOutdegree() > 0 && getLastStatus() === "set") {
658
+ const edge = await pipe(
659
+ toOutgoing,
660
+ toArray(),
661
+ createFindAsync(
662
+ async ({ predicateTraversable }) => await predicateTraversable(state)
663
+ )
664
+ )(path.at(-1));
665
+ path.push(edge.to);
666
+ }
667
+ return path;
668
+ };
669
+ }
670
+
671
+ const defaultCreateToStepsOptions = {
672
+ priorityBranch: false,
673
+ kind: "directed acyclic"
674
+ };
675
+ function createToTree(options = {}) {
676
+ const withDefaults = {
677
+ ...options,
678
+ createToSteps: {
679
+ ...defaultCreateToStepsOptions,
680
+ ...options.createToSteps
681
+ }
682
+ };
683
+ return createToTree$2({
684
+ ...withDefaults,
685
+ createToSteps: toCreateDirectedAcyclicToStepsOptions(withDefaults.createToSteps)
686
+ });
687
+ }
688
+ function createToCommonAncestors(...params) {
689
+ return createToCommonAncestors$2(...params);
690
+ }
691
+ function createPredicateAncestor(...params) {
692
+ return createPredicateAncestor$2(...params);
693
+ }
694
+ function createToNodeSteps(decisionTree, options = {}) {
695
+ const withDefaults = {
696
+ ...options,
697
+ createToSteps: {
698
+ ...defaultCreateToStepsOptions,
699
+ ...options.createToSteps
700
+ }
701
+ };
702
+ return createToNodeSteps$2(
703
+ decisionTree,
704
+ {
705
+ ...withDefaults,
706
+ createToSteps: toCreateDirectedAcyclicToStepsOptions(withDefaults.createToSteps)
707
+ }
708
+ );
709
+ }
710
+ function createToSteps(options = {}) {
711
+ const withDefaults = {
712
+ ...defaultCreateToStepsOptions,
713
+ ...options
714
+ };
715
+ return createToSteps$2(
716
+ toCreateDirectedAcyclicToStepsOptions(withDefaults)
717
+ );
718
+ }
719
+ function createToPath(...params) {
720
+ return createToPath$2(...params);
721
+ }
722
+ function toCreateDirectedAcyclicToStepsOptions(options) {
723
+ return {
724
+ ...defaultCreateToStepsOptions,
725
+ ...options,
726
+ ...{
727
+ toUnsetMetadata: () => false,
728
+ toMockMetadata: (node, totalConnectionsFollowed) => options.priorityBranch ? !totalConnectionsFollowed : !!totalConnectionsFollowed
729
+ }
730
+ };
731
+ }
732
+
733
+ function createList() {
734
+ return (...classValues) => clsx(...classValues);
735
+ }
736
+
737
+ const defaultOptions$l = {
738
+ toId: (node) => node.id,
739
+ toChildren: (node) => node.children
740
+ };
741
+ function createToGraph(options = {}) {
742
+ const { toId, toChildren } = { ...defaultOptions$l, ...options };
743
+ return function* (tree) {
744
+ const root = tree[0], rootId = toId(root);
745
+ function* toPair(node, id) {
746
+ const children = toChildren(node) || [];
747
+ for (const child of children) {
748
+ const childId = toId(child);
749
+ yield {
750
+ node: childId,
751
+ edge: { from: id, to: childId }
752
+ };
753
+ yield* toPair(child, childId);
754
+ }
755
+ }
756
+ yield { node: rootId };
757
+ yield* toPair(root, rootId);
758
+ };
759
+ }
760
+
761
+ const defaultOptions$k = {
762
+ toKey: (alias) => fromAliasToKeyStatusKey(alias)
763
+ };
764
+ const createPredicateKeycomboMatch$1 = (keycombo, options = {}) => {
765
+ const { toKey } = { ...defaultOptions$k, ...options }, keys = pipe(
766
+ fromComboToAliases,
767
+ map(toKey)
768
+ )(keycombo);
769
+ return (event) => {
770
+ const { toValue, set } = createKeyStatuses();
771
+ set(fromEventToKeyStatusKey(event), "down");
772
+ for (const modifier of modifiers) {
773
+ if (event[`${modifier.toLowerCase()}Key`])
774
+ set({ key: modifier }, "down");
775
+ }
776
+ return every(pipe(
777
+ toValue,
778
+ predicateDown
779
+ ))(keys);
780
+ };
781
+ };
782
+
783
+ const defaultOptions$j = {
784
+ initial: [],
785
+ createPredicateKey: (query) => (candidate) => query === candidate
786
+ };
787
+ function createAssociativeArray(options = {}) {
788
+ const { initial, createPredicateKey } = { ...defaultOptions$j, ...options }, entries = [...initial];
789
+ const toValue = (key) => {
790
+ const predicateKey = createPredicateKey(key);
791
+ return find(
792
+ ([candidate]) => predicateKey(candidate)
793
+ )(entries)?.[1];
794
+ };
795
+ const set = (key, value) => {
796
+ const predicateKey = createPredicateKey(key), index = findIndex(
797
+ ([candidate]) => predicateKey(candidate)
798
+ )(entries);
799
+ if (index === -1) {
800
+ entries.push([key, value]);
801
+ return;
802
+ }
803
+ entries[index][1] = value;
804
+ };
805
+ const predicateHas = (key) => {
806
+ const predicateKey = createPredicateKey(key);
807
+ return findIndex(
808
+ ([candidate]) => predicateKey(candidate)
809
+ )(entries) !== -1;
810
+ };
811
+ const clear = () => {
812
+ entries.length = 0;
813
+ };
814
+ const del = (key) => {
815
+ const predicateKey = createPredicateKey(key), index = findIndex(
816
+ ([candidate]) => predicateKey(candidate)
817
+ )(entries);
818
+ if (index === -1) {
819
+ return false;
820
+ }
821
+ entries.splice(index, 1);
822
+ return true;
823
+ };
824
+ const toKeys = () => {
825
+ return createMap(([key]) => key)(entries);
826
+ };
827
+ const toValues = () => {
828
+ return createMap(([, value]) => value)(entries);
829
+ };
830
+ const toEntries = () => {
831
+ return entries;
832
+ };
833
+ return {
834
+ toValue,
835
+ set,
836
+ predicateHas,
837
+ clear,
838
+ delete: del,
839
+ toKeys,
840
+ toValues,
841
+ toEntries
842
+ // get: toValue,
843
+ // has: predicateHas,
844
+ // keys: toKeys,
845
+ // values: toValues,
846
+ };
847
+ }
848
+
849
+ const defaultOptions$i = {
850
+ minDuration: 0,
851
+ preventsDefaultUnlessDenied: true,
852
+ toKey: (alias) => fromAliasToKeyStatusKey(alias),
853
+ toAliases: (event) => fromEventToAliases(event)
854
+ };
855
+ function createKeypress(keycomboOrKeycombos, options = {}) {
856
+ const {
857
+ minDuration,
858
+ preventsDefaultUnlessDenied,
859
+ toKey,
860
+ toAliases,
861
+ onDown,
862
+ onUp,
863
+ onVisibilitychange
864
+ } = { ...defaultOptions$i, ...options }, {
865
+ matchPredicatesByKeycombo,
866
+ getDownCombos,
867
+ predicateValid,
868
+ cleanup,
869
+ statuses
870
+ } = createKeyState({
871
+ keycomboOrKeycombos,
872
+ unsupportedAliases: unsupportedAliases$2,
873
+ toKey,
874
+ toAliases,
875
+ getRequest: () => request
876
+ });
877
+ let request;
878
+ let localStatus;
879
+ const keydown = (event, api) => {
880
+ const { denied, getStatus } = api, key = fromEventToKeyStatusKey(event);
881
+ if (statuses.toValue(key) === "down") {
882
+ onDown?.(toHookApi(api));
883
+ return;
884
+ }
885
+ statuses.set(key, "down");
886
+ if (localStatus === "denied") {
887
+ denied();
888
+ onDown?.(toHookApi(api));
889
+ return;
890
+ }
891
+ const downCombos = getDownCombos();
892
+ if (
893
+ // NOT BUILDING VALID COMBO
894
+ !predicateValid(event) || downCombos.length > 1 && fromComboToAliasesLength(downCombos[0]) === fromComboToAliasesLength(downCombos[1])
895
+ ) {
896
+ denied();
897
+ localStatus = getStatus();
898
+ if (includes(event.key)(unsupportedKeys$2))
899
+ statuses.clear();
900
+ onDown?.(toHookApi(api));
901
+ return;
902
+ }
903
+ if (preventsDefaultUnlessDenied)
904
+ event.preventDefault();
905
+ const { getMetadata } = api, metadata = getMetadata();
906
+ metadata.pressed = downCombos[0];
907
+ localStatus = "recognizing";
908
+ cleanup();
909
+ storeKeyboardTimeMetadata({
910
+ event,
911
+ api,
912
+ getTimeMetadata: getMetadata,
913
+ getShouldStore: () => downCombos.length && getDownCombos()[0] === downCombos[0],
914
+ setRequest: (newRequest) => request = newRequest,
915
+ recognize
916
+ });
917
+ onDown?.(toHookApi(api));
918
+ };
919
+ const recognize = (event, api) => {
920
+ const { getMetadata, recognized } = api, metadata = getMetadata();
921
+ if (metadata.duration >= minDuration) {
922
+ recognized();
923
+ localStatus = "recognized";
924
+ return;
925
+ }
926
+ };
927
+ const keyup = (event, api) => {
928
+ const { denied } = api, key = fromEventToKeyStatusKey(event);
929
+ if (localStatus === "denied") {
930
+ denied();
931
+ if (includes(event.key)(unsupportedKeys$2))
932
+ statuses.clear();
933
+ else
934
+ statuses.delete(key);
935
+ if (!predicateSomeKeyDown(statuses))
936
+ localStatus = "recognizing";
937
+ onUp?.(toHookApi(api));
938
+ return;
939
+ }
940
+ statuses.delete(key);
941
+ const downCombos = getDownCombos(), matches = matchPredicatesByKeycombo[downCombos[0]]?.(statuses);
942
+ if (downCombos.length && matches) {
943
+ const { getMetadata } = api, metadata = getMetadata();
944
+ metadata.pressed = downCombos[0];
945
+ if (preventsDefaultUnlessDenied)
946
+ event.preventDefault();
947
+ localStatus = "recognizing";
948
+ onUp?.(toHookApi(api));
949
+ return;
950
+ }
951
+ denied();
952
+ cleanup();
953
+ onUp?.(toHookApi(api));
954
+ };
955
+ const visibilitychange = (event, api) => {
956
+ if (document.visibilityState === "hidden") {
957
+ statuses.clear();
958
+ localStatus = "recognizing";
959
+ cleanup();
960
+ }
961
+ onVisibilitychange?.(toHookApi(api));
962
+ };
963
+ return {
964
+ keydown,
965
+ keyup,
966
+ visibilitychange
967
+ };
968
+ }
969
+ const unsupportedAliases$2 = ["meta", "command", "cmd"];
970
+ const unsupportedKeys$2 = ["Meta"];
971
+
972
+ const defaultOptions$h = {
973
+ minDuration: 0,
974
+ preventsDefaultUnlessDenied: true,
975
+ toKey: (alias) => fromAliasToKeyStatusKey(alias),
976
+ toAliases: (event) => fromEventToAliases(event)
977
+ };
978
+ function createKeyrelease(keycomboOrKeycombos, options = {}) {
979
+ const {
980
+ minDuration,
981
+ preventsDefaultUnlessDenied,
982
+ toKey,
983
+ toAliases,
984
+ onDown,
985
+ onUp,
986
+ onVisibilitychange
987
+ } = { ...defaultOptions$h, ...options }, {
988
+ matchPredicatesByKeycombo,
989
+ getDownCombos,
990
+ predicateValid,
991
+ cleanup,
992
+ statuses
993
+ } = createKeyState({
994
+ keycomboOrKeycombos,
995
+ unsupportedAliases: unsupportedAliases$1,
996
+ toKey,
997
+ toAliases,
998
+ getRequest: () => request
999
+ });
1000
+ let request, localStatus;
1001
+ const keydown = (event, api) => {
1002
+ const { denied, getStatus } = api, key = fromEventToKeyStatusKey(event);
1003
+ if (statuses.toValue(key) === "down") {
1004
+ onDown?.(toHookApi(api));
1005
+ return;
1006
+ }
1007
+ statuses.set(key, "down");
1008
+ if (localStatus === "denied") {
1009
+ denied();
1010
+ onDown?.(toHookApi(api));
1011
+ return;
1012
+ }
1013
+ const downCombos = getDownCombos();
1014
+ if (
1015
+ // NOT BUILDING VALID COMBO
1016
+ !predicateValid(event) || downCombos.length > 1 && fromComboToAliasesLength(downCombos[0]) === fromComboToAliasesLength(downCombos[1])
1017
+ ) {
1018
+ denied();
1019
+ localStatus = getStatus();
1020
+ if (includes(event.key)(unsupportedKeys$1))
1021
+ statuses.clear();
1022
+ onDown?.(toHookApi(api));
1023
+ return;
1024
+ }
1025
+ if (preventsDefaultUnlessDenied)
1026
+ event.preventDefault();
1027
+ const { getMetadata } = api;
1028
+ localStatus = "recognizing";
1029
+ cleanup();
1030
+ storeKeyboardTimeMetadata({
1031
+ event,
1032
+ api,
1033
+ getTimeMetadata: getMetadata,
1034
+ getShouldStore: () => downCombos.length && getDownCombos()[0] === downCombos[0],
1035
+ setRequest: (newRequest) => request = newRequest
1036
+ });
1037
+ onDown?.(toHookApi(api));
1038
+ };
1039
+ const keyup = (event, api) => {
1040
+ const {
1041
+ getStatus,
1042
+ getMetadata,
1043
+ denied
1044
+ } = api, metadata = getMetadata(), key = fromEventToKeyStatusKey(event);
1045
+ if (["denied", "recognized"].includes(localStatus)) {
1046
+ if (localStatus === "denied")
1047
+ denied();
1048
+ if (includes(event.key)(unsupportedKeys$1))
1049
+ statuses.clear();
1050
+ else
1051
+ statuses.delete(key);
1052
+ if (!predicateSomeKeyDown(statuses))
1053
+ localStatus = "recognizing";
1054
+ onUp?.(toHookApi(api));
1055
+ return;
1056
+ }
1057
+ const downCombos = getDownCombos(), matches = matchPredicatesByKeycombo[downCombos[0]]?.(statuses);
1058
+ statuses.delete(key);
1059
+ if (!downCombos.length || !matches) {
1060
+ onUp?.(toHookApi(api));
1061
+ return;
1062
+ }
1063
+ recognize(event, api);
1064
+ const status = getStatus();
1065
+ if (status === "recognized") {
1066
+ localStatus = status;
1067
+ metadata.released = downCombos[0];
1068
+ }
1069
+ if (preventsDefaultUnlessDenied)
1070
+ event.preventDefault();
1071
+ onUp?.(toHookApi(api));
1072
+ };
1073
+ const recognize = (event, api) => {
1074
+ const { getMetadata, recognized, denied } = api, metadata = getMetadata();
1075
+ if (metadata.duration < minDuration) {
1076
+ denied();
1077
+ return;
1078
+ }
1079
+ recognized();
1080
+ };
1081
+ const visibilitychange = (event, api) => {
1082
+ if (document.visibilityState === "hidden") {
1083
+ statuses.clear();
1084
+ localStatus = "recognizing";
1085
+ cleanup();
1086
+ }
1087
+ onVisibilitychange?.(toHookApi(api));
1088
+ };
1089
+ return {
1090
+ keydown,
1091
+ keyup,
1092
+ visibilitychange
1093
+ };
1094
+ }
1095
+ const unsupportedAliases$1 = ["meta", "command", "cmd"];
1096
+ const unsupportedKeys$1 = ["Meta"];
1097
+
1098
+ const defaultOptions$g = {
1099
+ minDuration: 0,
1100
+ maxInterval: 5e3,
1101
+ // VS Code default
1102
+ preventsDefaultUnlessDenied: true,
1103
+ toKey: (alias) => fromAliasToKeyStatusKey(alias),
1104
+ toAliases: (event) => fromEventToAliases(event)
1105
+ };
1106
+ function createKeychord(keychord, options = {}) {
1107
+ const {
1108
+ minDuration,
1109
+ maxInterval,
1110
+ preventsDefaultUnlessDenied,
1111
+ toKey,
1112
+ toAliases,
1113
+ onDown,
1114
+ onUp,
1115
+ onVisibilitychange
1116
+ } = { ...defaultOptions$g, ...options }, narrowedKeychord = keychord.split(" "), keyStates = createMap((keycombo) => createKeyState({
1117
+ keycomboOrKeycombos: keycombo,
1118
+ unsupportedAliases,
1119
+ toKey,
1120
+ toAliases,
1121
+ getRequest: () => request
1122
+ }))(narrowedKeychord), localStatuses = createMap(
1123
+ () => "recognizing"
1124
+ )(keyStates);
1125
+ let request, playedIndex = 0;
1126
+ const keydown = (event, api) => {
1127
+ const { denied, getStatus } = api, key = fromEventToKeyStatusKey(event);
1128
+ if (keyStates[playedIndex].statuses.toValue(key) === "down") {
1129
+ onDown?.(toHookApi(api));
1130
+ return;
1131
+ }
1132
+ if (localStatuses[playedIndex] === "recognized") {
1133
+ playedIndex++;
1134
+ for (const [key2, status] of keyStates[playedIndex - 1].statuses.toEntries()) {
1135
+ keyStates[playedIndex].statuses.set(key2, status);
1136
+ }
1137
+ }
1138
+ keyStates[playedIndex].statuses.set(key, "down");
1139
+ if (localStatuses[playedIndex] === "denied") {
1140
+ denied();
1141
+ onDown?.(toHookApi(api));
1142
+ return;
1143
+ }
1144
+ const { getMetadata } = api, metadata = getMetadata(), downCombos = keyStates[playedIndex].getDownCombos();
1145
+ if (playedIndex === 0)
1146
+ metadata.played = [];
1147
+ if (
1148
+ // NOT BUILDING VALID COMBO
1149
+ !keyStates[playedIndex].predicateValid(event) || downCombos.length > 1 && fromComboToAliasesLength(downCombos[0]) === fromComboToAliasesLength(downCombos[1]) || playedIndex > 0 && event.timeStamp - metadata.played[playedIndex - 1].times.end > maxInterval
1150
+ ) {
1151
+ denied();
1152
+ localStatuses[playedIndex] = getStatus();
1153
+ if (includes(event.key)(unsupportedKeys)) {
1154
+ for (const { statuses } of keyStates)
1155
+ statuses.clear();
1156
+ }
1157
+ onDown?.(toHookApi(api));
1158
+ return;
1159
+ }
1160
+ if (preventsDefaultUnlessDenied)
1161
+ event.preventDefault();
1162
+ localStatuses[playedIndex] = "recognizing";
1163
+ keyStates[playedIndex].cleanup();
1164
+ storeKeyboardTimeMetadata({
1165
+ event,
1166
+ api,
1167
+ getTimeMetadata: () => {
1168
+ const metadata2 = getMetadata();
1169
+ return metadata2.played[playedIndex] || (metadata2.played[playedIndex] = {});
1170
+ },
1171
+ getShouldStore: () => downCombos.length && keyStates[playedIndex].getDownCombos()[0] === downCombos[0],
1172
+ setRequest: (newRequest) => request = newRequest
1173
+ });
1174
+ onDown?.(toHookApi(api));
1175
+ };
1176
+ const keyup = (event, api) => {
1177
+ const {
1178
+ getStatus,
1179
+ getMetadata,
1180
+ denied
1181
+ } = api, metadata = getMetadata(), key = fromEventToKeyStatusKey(event);
1182
+ if (["denied", "recognized"].includes(localStatuses[playedIndex])) {
1183
+ if (localStatuses[playedIndex] === "denied")
1184
+ denied();
1185
+ for (const { statuses } of keyStates) {
1186
+ if (includes(event.key)(unsupportedKeys))
1187
+ statuses.clear();
1188
+ else
1189
+ statuses.delete(key);
1190
+ }
1191
+ if (!predicateSomeKeyDown(keyStates[playedIndex].statuses)) {
1192
+ if (localStatuses[playedIndex] === "denied" || playedIndex === narrowedKeychord.length - 1 && localStatuses[playedIndex] === "recognized") {
1193
+ playedIndex = 0;
1194
+ for (let i = 0; i < localStatuses.length; i++)
1195
+ localStatuses[i] = "recognizing";
1196
+ for (const { statuses } of keyStates)
1197
+ statuses.clear();
1198
+ }
1199
+ }
1200
+ onUp?.(toHookApi(api));
1201
+ return;
1202
+ }
1203
+ const downCombos = keyStates[playedIndex].getDownCombos(), matches = keyStates[playedIndex].matchPredicatesByKeycombo[downCombos[0]]?.(keyStates[playedIndex].statuses);
1204
+ keyStates[playedIndex].statuses.delete(key);
1205
+ if (!downCombos.length || !matches) {
1206
+ onUp?.(toHookApi(api));
1207
+ return;
1208
+ }
1209
+ recognize(event, api);
1210
+ const status = getStatus();
1211
+ if (status === "recognizing" && localStatuses[playedIndex] === "recognized" || status === "recognized") {
1212
+ metadata.played[playedIndex] = {
1213
+ ...metadata.played[playedIndex],
1214
+ released: downCombos[0]
1215
+ };
1216
+ }
1217
+ if (preventsDefaultUnlessDenied)
1218
+ event.preventDefault();
1219
+ if (playedIndex === narrowedKeychord.length - 1 && !predicateSomeKeyDown(keyStates[playedIndex].statuses)) {
1220
+ playedIndex = 0;
1221
+ for (let i = 0; i < localStatuses.length; i++)
1222
+ localStatuses[i] = "recognizing";
1223
+ for (const { statuses } of keyStates)
1224
+ statuses.clear();
1225
+ }
1226
+ onUp?.(toHookApi(api));
1227
+ };
1228
+ const recognize = (event, api) => {
1229
+ const { getMetadata, recognized, denied } = api, metadata = getMetadata();
1230
+ if (metadata.played[playedIndex].duration < minDuration) {
1231
+ denied();
1232
+ return;
1233
+ }
1234
+ if (playedIndex === narrowedKeychord.length - 1) {
1235
+ recognized();
1236
+ localStatuses[playedIndex] = "recognized";
1237
+ return;
1238
+ }
1239
+ localStatuses[playedIndex] = "recognized";
1240
+ };
1241
+ const visibilitychange = (event, api) => {
1242
+ if (document.visibilityState === "hidden") {
1243
+ for (const { statuses } of keyStates)
1244
+ statuses.clear();
1245
+ localStatuses[playedIndex] = "recognizing";
1246
+ keyStates[playedIndex].cleanup();
1247
+ playedIndex = 0;
1248
+ }
1249
+ onVisibilitychange?.(toHookApi(api));
1250
+ };
1251
+ return {
1252
+ keydown,
1253
+ keyup,
1254
+ visibilitychange
1255
+ };
1256
+ }
1257
+ const unsupportedAliases = ["meta", "command", "cmd"];
1258
+ const unsupportedKeys = ["Meta"];
1259
+
1260
+ function createKonami(options = {}) {
1261
+ return createKeychord("up up down down left right left right b a enter", options);
1262
+ }
1263
+
1264
+ const defaultOptions$f = {
1265
+ minDuration: 0,
1266
+ minDistance: 0,
1267
+ getMousemoveTarget: (event) => event.target
1268
+ };
1269
+ function createMousepress(options = {}) {
1270
+ const {
1271
+ minDuration,
1272
+ minDistance,
1273
+ getMousemoveTarget,
1274
+ onDown,
1275
+ onLeave,
1276
+ onMove,
1277
+ onUp
1278
+ } = { ...defaultOptions$f, ...options }, cleanup = (event) => {
1279
+ window.cancelAnimationFrame(request);
1280
+ getMousemoveTarget(event).removeEventListener("mousemove", mousemoveEffect);
1281
+ };
1282
+ let request;
1283
+ let mousemoveEffect;
1284
+ let mouseStatus;
1285
+ const mousedown = (event, api) => {
1286
+ mouseStatus = "down";
1287
+ mousemoveEffect = (event2) => mousemove(event2, api);
1288
+ storePointerStartMetadata(event, api);
1289
+ storePointerMoveMetadata(event, api);
1290
+ storePointerTimeMetadata(
1291
+ event,
1292
+ api,
1293
+ () => mouseStatus === "down",
1294
+ (newRequest) => request = newRequest,
1295
+ recognize
1296
+ );
1297
+ getMousemoveTarget(event).addEventListener("mousemove", mousemoveEffect);
1298
+ onDown?.(toHookApi(api));
1299
+ };
1300
+ const mousemove = (event, api) => {
1301
+ storePointerMoveMetadata(event, api);
1302
+ recognize(event, api);
1303
+ onMove?.(toHookApi(api));
1304
+ };
1305
+ const recognize = (event, api) => {
1306
+ const { getMetadata, recognized } = api, metadata = getMetadata();
1307
+ if (metadata.duration >= minDuration && metadata.distance.straight.fromStart >= minDistance) {
1308
+ recognized();
1309
+ }
1310
+ };
1311
+ const mouseleave = (event, api) => {
1312
+ const { denied } = api;
1313
+ if (mouseStatus === "down") {
1314
+ denied();
1315
+ cleanup(event);
1316
+ mouseStatus = "leave";
1317
+ }
1318
+ onLeave?.(toHookApi(api));
1319
+ };
1320
+ const mouseup = (event, api) => {
1321
+ const { denied } = api;
1322
+ if (mouseStatus !== "down")
1323
+ return;
1324
+ denied();
1325
+ cleanup(event);
1326
+ mouseStatus = "up";
1327
+ onUp?.(toHookApi(api));
1328
+ };
1329
+ return {
1330
+ mousedown,
1331
+ mouseleave,
1332
+ mouseup
1333
+ };
1334
+ }
1335
+
1336
+ const defaultOptions$e = {
1337
+ minDuration: 0,
1338
+ minDistance: 0,
1339
+ minVelocity: 0,
1340
+ getMousemoveTarget: (event) => event.target
1341
+ };
1342
+ function createMouserelease(options = {}) {
1343
+ const {
1344
+ minDuration,
1345
+ minDistance,
1346
+ minVelocity,
1347
+ getMousemoveTarget,
1348
+ onDown,
1349
+ onLeave,
1350
+ onMove,
1351
+ onUp
1352
+ } = { ...defaultOptions$e, ...options }, cleanup = (event) => {
1353
+ window.cancelAnimationFrame(request);
1354
+ getMousemoveTarget(event).removeEventListener("mousemove", mousemoveEffect);
1355
+ };
1356
+ let request;
1357
+ let mousemoveEffect;
1358
+ let mouseStatus;
1359
+ const mousedown = (event, api) => {
1360
+ mouseStatus = "down";
1361
+ mousemoveEffect = (event2) => mousemove(event2, api);
1362
+ storePointerStartMetadata(event, api);
1363
+ storePointerMoveMetadata(event, api);
1364
+ storePointerTimeMetadata(
1365
+ event,
1366
+ api,
1367
+ () => mouseStatus === "down",
1368
+ (newRequest) => request = newRequest
1369
+ );
1370
+ getMousemoveTarget(event).addEventListener("mousemove", mousemoveEffect);
1371
+ onDown?.(toHookApi(api));
1372
+ };
1373
+ const mousemove = (event, api) => {
1374
+ storePointerMoveMetadata(event, api);
1375
+ onMove?.(toHookApi(api));
1376
+ };
1377
+ const mouseleave = (event, api) => {
1378
+ const { denied } = api;
1379
+ if (mouseStatus === "down") {
1380
+ denied();
1381
+ cleanup(event);
1382
+ mouseStatus = "leave";
1383
+ }
1384
+ onLeave?.(toHookApi(api));
1385
+ };
1386
+ const mouseup = (event, api) => {
1387
+ if (mouseStatus !== "down")
1388
+ return;
1389
+ storePointerMoveMetadata(event, api);
1390
+ cleanup(event);
1391
+ mouseStatus = "up";
1392
+ recognize(event, api);
1393
+ onUp?.(toHookApi(api));
1394
+ };
1395
+ const recognize = (event, api) => {
1396
+ const { getMetadata, recognized, denied } = api, metadata = getMetadata();
1397
+ if (metadata.duration >= minDuration && metadata.distance.straight.fromStart >= minDistance && metadata.velocity >= minVelocity) {
1398
+ recognized();
1399
+ } else {
1400
+ denied();
1401
+ }
1402
+ };
1403
+ return {
1404
+ mousedown,
1405
+ mouseleave,
1406
+ mouseup
1407
+ };
1408
+ }
1409
+
1410
+ const defaultOptions$d = {
1411
+ minDuration: 0,
1412
+ minDistance: 0
1413
+ };
1414
+ function createTouchpress(options = {}) {
1415
+ const {
1416
+ minDuration,
1417
+ minDistance,
1418
+ onStart,
1419
+ onCancel,
1420
+ onMove,
1421
+ onEnd
1422
+ } = { ...defaultOptions$d, ...options }, cleanup = () => {
1423
+ window.cancelAnimationFrame(request);
1424
+ };
1425
+ let request;
1426
+ let totalTouches = 0;
1427
+ const touchstart = (event, api) => {
1428
+ const { denied } = api;
1429
+ totalTouches++;
1430
+ if (totalTouches > 1) {
1431
+ cleanup();
1432
+ denied();
1433
+ onStart?.(toHookApi(api));
1434
+ return;
1435
+ }
1436
+ storePointerStartMetadata(event, api);
1437
+ storePointerMoveMetadata(event, api);
1438
+ storePointerTimeMetadata(
1439
+ event,
1440
+ api,
1441
+ () => totalTouches === 1,
1442
+ (newRequest) => request = newRequest,
1443
+ recognize
1444
+ );
1445
+ onStart?.(toHookApi(api));
1446
+ };
1447
+ const touchmove = (event, api) => {
1448
+ const { getStatus } = api;
1449
+ if (getStatus() !== "denied") {
1450
+ storePointerMoveMetadata(event, api);
1451
+ recognize(event, api);
1452
+ }
1453
+ onMove?.(toHookApi(api));
1454
+ };
1455
+ const recognize = (event, api) => {
1456
+ const { getMetadata, recognized } = api, metadata = getMetadata();
1457
+ if (metadata.duration >= minDuration && metadata.distance.straight.fromStart >= minDistance) {
1458
+ recognized();
1459
+ }
1460
+ };
1461
+ const touchcancel = (event, api) => {
1462
+ const { denied } = api;
1463
+ cleanup();
1464
+ denied();
1465
+ totalTouches--;
1466
+ onCancel?.(toHookApi(api));
1467
+ };
1468
+ const touchend = (event, api) => {
1469
+ const { denied } = api;
1470
+ cleanup();
1471
+ denied();
1472
+ totalTouches--;
1473
+ onEnd?.(toHookApi(api));
1474
+ };
1475
+ return {
1476
+ touchstart,
1477
+ touchmove,
1478
+ touchcancel,
1479
+ touchend
1480
+ };
1481
+ }
1482
+
1483
+ const defaultOptions$c = {
1484
+ minDuration: 0,
1485
+ minDistance: 0,
1486
+ minVelocity: 0
1487
+ };
1488
+ function createTouchrelease(options = {}) {
1489
+ const {
1490
+ minDuration,
1491
+ minDistance,
1492
+ minVelocity,
1493
+ onStart,
1494
+ onCancel,
1495
+ onMove,
1496
+ onEnd
1497
+ } = { ...defaultOptions$c, ...options }, cleanup = () => {
1498
+ window.cancelAnimationFrame(request);
1499
+ };
1500
+ let request;
1501
+ let totalTouches = 0;
1502
+ const touchstart = (event, api) => {
1503
+ const { denied } = api;
1504
+ totalTouches++;
1505
+ if (totalTouches > 1) {
1506
+ cleanup();
1507
+ denied();
1508
+ onStart?.(toHookApi(api));
1509
+ return;
1510
+ }
1511
+ storePointerStartMetadata(event, api);
1512
+ storePointerMoveMetadata(event, api);
1513
+ storePointerTimeMetadata(
1514
+ event,
1515
+ api,
1516
+ () => totalTouches === 1,
1517
+ (newRequest) => request = newRequest
1518
+ );
1519
+ onStart?.(toHookApi(api));
1520
+ };
1521
+ const touchmove = (event, api) => {
1522
+ const { getStatus } = api;
1523
+ if (getStatus() !== "denied")
1524
+ storePointerMoveMetadata(event, api);
1525
+ onMove?.(toHookApi(api));
1526
+ };
1527
+ const touchcancel = (event, api) => {
1528
+ const { denied } = api;
1529
+ cleanup();
1530
+ denied();
1531
+ totalTouches--;
1532
+ onCancel?.(toHookApi(api));
1533
+ };
1534
+ const touchend = (event, api) => {
1535
+ const { denied } = api;
1536
+ if (totalTouches !== 1) {
1537
+ cleanup();
1538
+ denied();
1539
+ onEnd?.(toHookApi(api));
1540
+ return;
1541
+ }
1542
+ storePointerMoveMetadata(event, api);
1543
+ cleanup();
1544
+ totalTouches--;
1545
+ recognize(event, api);
1546
+ onEnd?.(toHookApi(api));
1547
+ };
1548
+ const recognize = (event, api) => {
1549
+ const { getMetadata, recognized, denied } = api, metadata = getMetadata();
1550
+ if (metadata.duration >= minDuration && metadata.distance.straight.fromStart >= minDistance && metadata.velocity >= minVelocity) {
1551
+ recognized();
1552
+ } else {
1553
+ denied();
1554
+ }
1555
+ };
1556
+ return {
1557
+ touchstart,
1558
+ touchmove,
1559
+ touchcancel,
1560
+ touchend
1561
+ };
1562
+ }
1563
+
1564
+ const defaultOptions$b = {
1565
+ initial: []
1566
+ };
1567
+ function createKeyStatuses(options = {}) {
1568
+ return createAssociativeArray({
1569
+ ...defaultOptions$b,
1570
+ ...options,
1571
+ createPredicateKey: (query) => (key) => {
1572
+ for (const prop in query) {
1573
+ if (query[prop] !== key[prop]) {
1574
+ return false;
1575
+ }
1576
+ }
1577
+ return true;
1578
+ }
1579
+ });
1580
+ }
1581
+ function predicateDown(status) {
1582
+ return status === "down";
1583
+ }
1584
+ function predicateSomeKeyDown(statuses) {
1585
+ return includes("down")(statuses.toValues());
1586
+ }
1587
+
1588
+ function fromComboToAliases(combo) {
1589
+ const delimiter = "+";
1590
+ return pipe(
1591
+ unique(),
1592
+ map((name) => name === "" ? delimiter : name.toLowerCase()),
1593
+ toArray()
1594
+ )(combo.split(delimiter));
1595
+ }
1596
+
1597
+ function fromAliasToKeyStatusKey(alias) {
1598
+ if (alias in keysByAlias) {
1599
+ return { key: keysByAlias[alias] };
1600
+ }
1601
+ return {
1602
+ code: (() => {
1603
+ if (alias in codesByAlias)
1604
+ return codesByAlias[alias];
1605
+ if (letterRE.test(alias))
1606
+ return `Key${alias.toUpperCase()}`;
1607
+ if (digitRE.test(alias))
1608
+ return `Digit${alias}`;
1609
+ if (functionRE.test(alias))
1610
+ return alias.toUpperCase();
1611
+ return "unsupported";
1612
+ })()
1613
+ };
1614
+ }
1615
+ const digitRE = /^[0-9]$/;
1616
+ const letterRE = /^[a-zA-Z]$/;
1617
+ const functionRE = /^[fF][0-9]{1,2}$/;
1618
+ const codesByAlias = {
1619
+ "`": "Backquote",
1620
+ "~": "Backquote",
1621
+ "-": "Minus",
1622
+ _: "Minus",
1623
+ "=": "Equal",
1624
+ "+": "Equal",
1625
+ "[": "BracketLeft",
1626
+ "{": "BracketLeft",
1627
+ "]": "BracketRight",
1628
+ "}": "BracketRight",
1629
+ "\\": "Backslash",
1630
+ "|": "Backslash",
1631
+ ";": "Semicolon",
1632
+ ":": "Semicolon",
1633
+ "'": "Quote",
1634
+ '"': "Quote",
1635
+ ",": "Comma",
1636
+ "<": "Comma",
1637
+ ".": "Period",
1638
+ ">": "Period",
1639
+ "/": "Slash",
1640
+ "?": "Slash",
1641
+ "!": "Digit1",
1642
+ "@": "Digit2",
1643
+ "#": "Digit3",
1644
+ $: "Digit4",
1645
+ "%": "Digit5",
1646
+ "^": "Digit6",
1647
+ "&": "Digit7",
1648
+ "*": "Digit8",
1649
+ "(": "Digit9",
1650
+ ")": "Digit0",
1651
+ up: "ArrowUp",
1652
+ down: "ArrowDown",
1653
+ left: "ArrowLeft",
1654
+ right: "ArrowRight",
1655
+ enter: "Enter",
1656
+ space: "Space",
1657
+ tab: "Tab",
1658
+ esc: "Escape",
1659
+ backspace: "Backspace",
1660
+ delete: "Delete",
1661
+ home: "Home",
1662
+ end: "End",
1663
+ pagedown: "PageDown",
1664
+ pageup: "PageUp",
1665
+ capslock: "CapsLock",
1666
+ camera: "Camera"
1667
+ };
1668
+ const keysByAlias = {
1669
+ alt: "Alt",
1670
+ opt: "Alt",
1671
+ option: "Alt",
1672
+ ctrl: "Control",
1673
+ control: "Control",
1674
+ meta: "Meta",
1675
+ cmd: "Meta",
1676
+ command: "Meta",
1677
+ shift: "Shift"
1678
+ };
1679
+
1680
+ const defaultOptions$a = {
1681
+ toKey: (alias) => fromAliasToKeyStatusKey(alias)
1682
+ };
1683
+ const createPredicateKeycomboDown = (keycombo, options = {}) => {
1684
+ const { toKey } = { ...defaultOptions$a, ...options }, keys = pipe(
1685
+ fromComboToAliases,
1686
+ map(toKey)
1687
+ )(keycombo);
1688
+ return (statuses) => {
1689
+ const { toValue } = statuses;
1690
+ return every(pipe(
1691
+ toValue,
1692
+ predicateDown
1693
+ ))(keys);
1694
+ };
1695
+ };
1696
+
1697
+ function fromEventToAliases(event) {
1698
+ if (event.shiftKey && event.code in aliasesByShiftCode) {
1699
+ return [aliasesByShiftCode[event.code]];
1700
+ }
1701
+ if (event.key in aliasListsByModifier) {
1702
+ return aliasListsByModifier[event.key];
1703
+ }
1704
+ return event.code in aliasesByCode ? [aliasesByCode[event.code]] : [event.code.match(aliasCaptureRE)?.[1].toLowerCase() || "unsupported"];
1705
+ }
1706
+ const aliasCaptureRE = /^(?:Digit|Key)?(F[0-9]{1,2}|[0-9]|[A-Z])$/;
1707
+ const aliasesByCode = {
1708
+ Backquote: "`",
1709
+ Minus: "-",
1710
+ Equal: "=",
1711
+ BracketLeft: "[",
1712
+ BracketRight: "]",
1713
+ Backslash: "\\",
1714
+ Semicolon: ";",
1715
+ Quote: "'",
1716
+ Comma: ",",
1717
+ Period: ".",
1718
+ Slash: "/",
1719
+ ArrowUp: "up",
1720
+ ArrowDown: "down",
1721
+ ArrowLeft: "left",
1722
+ ArrowRight: "right",
1723
+ Enter: "enter",
1724
+ Space: "space",
1725
+ Tab: "tab",
1726
+ Escape: "esc",
1727
+ Backspace: "backspace",
1728
+ Delete: "delete",
1729
+ Home: "home",
1730
+ End: "end",
1731
+ PageDown: "pagedown",
1732
+ PageUp: "pageup",
1733
+ CapsLock: "capslock",
1734
+ Camera: "camera"
1735
+ };
1736
+ const aliasesByShiftCode = {
1737
+ Backquote: "~",
1738
+ Minus: "_",
1739
+ Equal: "+",
1740
+ BracketLeft: "{",
1741
+ BracketRight: "}",
1742
+ Backslash: "|",
1743
+ Semicolon: ":",
1744
+ Quote: '"',
1745
+ Comma: "<",
1746
+ Period: ">",
1747
+ Slash: "?",
1748
+ Digit1: "!",
1749
+ Digit2: "@",
1750
+ Digit3: "#",
1751
+ Digit4: "$",
1752
+ Digit5: "%",
1753
+ Digit6: "^",
1754
+ Digit7: "&",
1755
+ Digit8: "*",
1756
+ Digit9: "(",
1757
+ Digit0: ")"
1758
+ };
1759
+ const aliasListsByModifier = {
1760
+ Alt: ["alt", "option", "opt"],
1761
+ Control: ["control", "ctrl"],
1762
+ Meta: ["meta", "command", "cmd"],
1763
+ Shift: ["shift"]
1764
+ };
1765
+
1766
+ const defaultOptions$9 = {
1767
+ toKey: (alias) => fromAliasToKeyStatusKey(alias),
1768
+ toAliases: (event) => fromEventToAliases(event)
1769
+ };
1770
+ const createPredicateKeycomboMatch = (keycombo, options = {}) => {
1771
+ const { toKey, toAliases } = { ...defaultOptions$9, ...options }, aliases = fromComboToAliases(keycombo), keys = map(toKey)(aliases);
1772
+ return (statuses) => {
1773
+ const { toValue } = statuses;
1774
+ return every(pipe(
1775
+ toValue,
1776
+ predicateDown
1777
+ ))(keys) && every(
1778
+ ([key, value]) => value === "up" || some(
1779
+ (alias) => includes(alias)(aliases)
1780
+ )(toAliases(key))
1781
+ )(statuses.toEntries());
1782
+ };
1783
+ };
1784
+
1785
+ function createKeyState({
1786
+ keycomboOrKeycombos,
1787
+ unsupportedAliases,
1788
+ toKey,
1789
+ toAliases,
1790
+ getRequest
1791
+ }) {
1792
+ const narrowedKeycombos = createFilter(
1793
+ (keycombo) => !some(
1794
+ (alias) => includes(alias)(unsupportedAliases)
1795
+ )(fromComboToAliases(keycombo))
1796
+ )(Array.isArray(keycomboOrKeycombos) ? keycomboOrKeycombos : [keycomboOrKeycombos]), createPredicateKeycomboDownOptions = { toKey }, downPredicatesByKeycombo = (() => {
1797
+ const predicates = [];
1798
+ for (const keycombo of narrowedKeycombos) {
1799
+ predicates.push([
1800
+ keycombo,
1801
+ createPredicateKeycomboDown(
1802
+ keycombo,
1803
+ createPredicateKeycomboDownOptions
1804
+ )
1805
+ ]);
165
1806
  }
166
- return reversed;
1807
+ return predicates;
1808
+ })(), createPredicateKeycomboMatchOptions = { ...createPredicateKeycomboDownOptions, toAliases }, matchPredicatesByKeycombo = (() => {
1809
+ const predicates = {};
1810
+ for (const keycombo of narrowedKeycombos) {
1811
+ predicates[keycombo] = createPredicateKeycomboMatch(
1812
+ keycombo,
1813
+ createPredicateKeycomboMatchOptions
1814
+ );
1815
+ }
1816
+ return predicates;
1817
+ })(), validAliases = pipe(
1818
+ flatMap(fromComboToAliases),
1819
+ unique(),
1820
+ toArray()
1821
+ )(narrowedKeycombos), getDownCombos = () => pipe(
1822
+ filter(([, predicate]) => predicate(statuses)),
1823
+ map(([keycombo]) => [keycombo, fromComboToAliases(keycombo)]),
1824
+ sort(([, aliasesA], [, aliasesB]) => aliasesB.length - aliasesA.length),
1825
+ map(([keycombo]) => keycombo),
1826
+ toArray()
1827
+ )(downPredicatesByKeycombo), predicateValid = (event) => {
1828
+ const aliases = toAliases(event);
1829
+ return some(
1830
+ (validAlias) => includes(validAlias)(aliases)
1831
+ )(validAliases);
1832
+ }, cleanup = () => {
1833
+ window.cancelAnimationFrame(getRequest());
1834
+ }, statuses = createKeyStatuses();
1835
+ return {
1836
+ narrowedKeycombos,
1837
+ createPredicateKeycomboDownOptions,
1838
+ downPredicatesByKeycombo,
1839
+ createPredicateKeycomboMatchOptions,
1840
+ matchPredicatesByKeycombo,
1841
+ validAliases,
1842
+ getDownCombos,
1843
+ predicateValid,
1844
+ cleanup,
1845
+ statuses
167
1846
  };
168
1847
  }
169
- function createSort(compare) {
170
- return (array) => {
171
- return new Pipeable(array).pipe(
172
- createSlice(0),
173
- (sliced) => compare ? sliced.sort(compare) : sliced.sort()
174
- );
1848
+
1849
+ function toLength() {
1850
+ return function toLengthFn(data) {
1851
+ return [...data].length;
175
1852
  };
176
1853
  }
177
- function createSlug(options) {
178
- return (string) => {
179
- return slugify(string, options);
180
- };
1854
+
1855
+ const fromComboToAliasesLength = pipe(
1856
+ fromComboToAliases,
1857
+ toLength()
1858
+ );
1859
+
1860
+ function fromEventToKeyStatusKey({ key, code }) {
1861
+ return includes(key)(modifiers) ? { key } : { code };
181
1862
  }
182
- function createClip(required) {
183
- return (string) => {
184
- return string.replace(required, "");
185
- };
1863
+ const modifiers = ["Alt", "Control", "Meta", "Shift"];
1864
+
1865
+ function toDirection(angle, unit = "degrees") {
1866
+ return Object.keys(directions).find((direction) => directions[direction][unit](angle));
186
1867
  }
187
- function createClamp(min, max) {
188
- return (number) => {
189
- const maxed = Math.max(number, min);
190
- return Math.min(maxed, max);
1868
+ const directions = {
1869
+ up: {
1870
+ degrees: (degrees) => degrees >= 67.5 && degrees <= 112.5,
1871
+ radians: (radians) => radians >= 0.375 * Math.PI && radians <= 0.625 * Math.PI
1872
+ },
1873
+ upRight: {
1874
+ degrees: (degrees) => degrees >= 22.5 && degrees < 67.5,
1875
+ radians: (radians) => radians >= 0.125 * Math.PI && radians < 0.375 * Math.PI
1876
+ },
1877
+ right: {
1878
+ degrees: (degrees) => degrees > 337.5 && degrees <= 360 || degrees < 22.5 && degrees >= 0,
1879
+ radians: (radians) => radians > 1.875 * Math.PI && radians <= 2 * Math.PI || radians < 0.125 * Math.PI && radians >= 0
1880
+ },
1881
+ downRight: {
1882
+ degrees: (degrees) => degrees > 292.5 && degrees <= 337.5,
1883
+ radians: (radians) => radians > 1.625 * Math.PI && radians <= 1.875 * Math.PI
1884
+ },
1885
+ down: {
1886
+ degrees: (degrees) => degrees >= 247.5 && degrees <= 292.5,
1887
+ radians: (radians) => radians >= 1.375 * Math.PI && radians <= 1.625 * Math.PI
1888
+ },
1889
+ downLeft: {
1890
+ degrees: (degrees) => degrees >= 202.5 && degrees < 247.5,
1891
+ radians: (radians) => radians >= 1.125 * Math.PI && radians < 1.375 * Math.PI
1892
+ },
1893
+ left: {
1894
+ degrees: (degrees) => degrees > 157.5 && degrees < 202.5,
1895
+ radians: (radians) => radians > 0.875 * Math.PI && radians < 1.125 * Math.PI
1896
+ },
1897
+ upLeft: {
1898
+ degrees: (degrees) => degrees > 112.5 && degrees <= 157.5,
1899
+ radians: (radians) => radians > 0.625 * Math.PI && radians <= 0.875 * Math.PI
1900
+ }
1901
+ };
1902
+
1903
+ function toHookApi({
1904
+ getSequence,
1905
+ getStatus,
1906
+ getMetadata
1907
+ }) {
1908
+ return {
1909
+ sequence: getSequence(),
1910
+ status: getStatus(),
1911
+ metadata: getMetadata()
191
1912
  };
192
1913
  }
193
- function createDetermine(potentialities) {
194
- const predicates = createMap(({ outcome, probability }, index) => {
195
- const lowerBound = index === 0 ? 0 : pipe(
196
- slice(0, index - 1),
197
- reduce((lowerBound2, { probability: probability2 }) => lowerBound2 + probability2, 0)
198
- )(potentialities), upperBound = lowerBound + probability;
199
- return {
200
- outcome,
201
- predicate: (determinant) => determinant >= lowerBound && determinant < upperBound || determinant < 0 && index === 0 || index === predicates.length - 1
202
- };
203
- })(potentialities);
204
- return (determinant) => find(({ predicate }) => predicate(determinant))(predicates).outcome;
1914
+
1915
+ function toMousePoint(event) {
1916
+ return {
1917
+ x: event.clientX,
1918
+ y: event.clientY
1919
+ };
205
1920
  }
206
- function createRename(from, to) {
207
- return (map2) => {
208
- const keys = [...map2.keys()], keyToRenameIndex = findIndex((k) => k === from)(keys), newKeys = createReplace(keyToRenameIndex, to)(keys), values = [...map2.values()];
209
- return createReduce((renamed, key, index) => renamed.set(key, values[index]), /* @__PURE__ */ new Map())(newKeys);
1921
+ function toTouchMovePoint(event) {
1922
+ return {
1923
+ x: event.touches.item(0).clientX,
1924
+ y: event.touches.item(0).clientY
210
1925
  };
211
1926
  }
212
- function createToEntries() {
213
- return (object) => {
214
- const entries = [];
215
- for (const key in object) {
216
- entries.push([key, object[key]]);
217
- }
218
- return entries;
1927
+ function toTouchEndPoint(event) {
1928
+ return {
1929
+ x: event.changedTouches.item(0).clientX,
1930
+ y: event.changedTouches.item(0).clientY
219
1931
  };
220
1932
  }
221
- function createToKeys() {
222
- return (object) => {
223
- const keys = [];
224
- for (const key in object) {
225
- keys.push(key);
226
- }
227
- return keys;
1933
+
1934
+ function toPolarCoordinates({ xA, xB, yA, yB }) {
1935
+ const distance = Math.hypot(xB - xA, yB - yA), angle = Math.atan2(yA - yB, xB - xA), radians = angle >= 0 ? angle : 2 * Math.PI + angle, degrees = radians * 180 / Math.PI;
1936
+ return {
1937
+ distance,
1938
+ angle: { radians, degrees }
228
1939
  };
229
1940
  }
230
- function createToSome(predicate) {
231
- return (object) => {
232
- for (const key in object) {
233
- if (predicate(key, object[key])) {
234
- return true;
1941
+
1942
+ const initialMetadata$3 = {
1943
+ times: {
1944
+ start: 0,
1945
+ end: 0
1946
+ },
1947
+ duration: 0
1948
+ };
1949
+ function storeKeyboardTimeMetadata({
1950
+ event,
1951
+ api,
1952
+ getTimeMetadata,
1953
+ getShouldStore,
1954
+ setRequest,
1955
+ recognize
1956
+ }) {
1957
+ if (!getShouldStore())
1958
+ return;
1959
+ const { getStatus, onRecognized } = api, timeMetadata = getTimeMetadata();
1960
+ if (!timeMetadata.times)
1961
+ timeMetadata.times = createClone()(initialMetadata$3.times);
1962
+ timeMetadata.times.start = Math.round(event.timeStamp);
1963
+ timeMetadata.times.end = Math.round(event.timeStamp);
1964
+ const storeDuration = () => {
1965
+ const request = requestAnimationFrame((timestamp) => {
1966
+ if (!getShouldStore())
1967
+ return;
1968
+ timeMetadata.times.end = Math.round(timestamp);
1969
+ timeMetadata.duration = Math.max(0, timeMetadata.times.end - timeMetadata.times.start);
1970
+ if (recognize) {
1971
+ recognize(event, api);
1972
+ if (getStatus() === "recognized")
1973
+ onRecognized(event);
235
1974
  }
236
- }
237
- return false;
1975
+ storeDuration();
1976
+ });
1977
+ setRequest(request);
238
1978
  };
1979
+ storeDuration();
239
1980
  }
240
- function createToEvery(predicate) {
241
- return (object) => {
242
- for (const key in object) {
243
- if (!predicate(key, object[key])) {
244
- return false;
1981
+
1982
+ const initialMetadata$2 = {
1983
+ points: {
1984
+ start: { x: 0, y: 0 },
1985
+ end: { x: 0, y: 0 }
1986
+ }
1987
+ };
1988
+ function storePointerStartMetadata(event, api) {
1989
+ const { getMetadata } = api, metadata = getMetadata();
1990
+ const point = event instanceof MouseEvent ? toMousePoint(event) : toTouchMovePoint(event);
1991
+ if (!metadata.points)
1992
+ metadata.points = createClone()(initialMetadata$2.points);
1993
+ metadata.points.start = point;
1994
+ metadata.points.end = point;
1995
+ }
1996
+
1997
+ const initialMetadata$1 = {
1998
+ distance: {
1999
+ straight: {
2000
+ fromStart: 0,
2001
+ fromPrevious: 0
2002
+ },
2003
+ horizontal: {
2004
+ fromStart: 0,
2005
+ fromPrevious: 0
2006
+ },
2007
+ vertical: {
2008
+ fromStart: 0,
2009
+ fromPrevious: 0
2010
+ }
2011
+ },
2012
+ angle: {
2013
+ fromPrevious: { radians: 0, degrees: 0 },
2014
+ fromStart: { radians: 0, degrees: 0 }
2015
+ },
2016
+ direction: {
2017
+ fromPrevious: "up",
2018
+ fromStart: "up"
2019
+ }
2020
+ };
2021
+ function storePointerMoveMetadata(event, api) {
2022
+ const { getMetadata } = api, metadata = getMetadata();
2023
+ if (!metadata.distance) {
2024
+ metadata.distance = createClone()(initialMetadata$1.distance);
2025
+ metadata.angle = createClone()(initialMetadata$1.angle);
2026
+ metadata.direction = createClone()(initialMetadata$1.direction);
2027
+ }
2028
+ const { x: previousX, y: previousY } = metadata.points.end, { x: startX, y: startY } = metadata.points.start, { x: newX, y: newY } = (() => {
2029
+ if (event instanceof MouseEvent) {
2030
+ return toMousePoint(event);
2031
+ }
2032
+ if (event instanceof TouchEvent) {
2033
+ if (event.type === "touchmove") {
2034
+ return toTouchMovePoint(event);
245
2035
  }
2036
+ return toTouchEndPoint(event);
246
2037
  }
247
- return true;
2038
+ })(), { distance: distanceFromPrevious, angle: angleFromPrevious } = toPolarCoordinates({
2039
+ xA: previousX,
2040
+ xB: newX,
2041
+ yA: previousY,
2042
+ yB: newY
2043
+ }), { distance: distanceFromStart, angle: angleFromStart } = toPolarCoordinates({
2044
+ xA: startX,
2045
+ xB: newX,
2046
+ yA: startY,
2047
+ yB: newY
2048
+ });
2049
+ metadata.distance.straight.fromPrevious = distanceFromPrevious;
2050
+ metadata.distance.horizontal.fromPrevious = newX - previousX;
2051
+ metadata.distance.vertical.fromPrevious = newY - previousY;
2052
+ metadata.angle.fromPrevious = angleFromPrevious;
2053
+ metadata.direction.fromPrevious = toDirection(angleFromPrevious.degrees);
2054
+ metadata.distance.straight.fromStart = distanceFromStart;
2055
+ metadata.distance.horizontal.fromStart = newX - startX;
2056
+ metadata.distance.vertical.fromStart = newY - startY;
2057
+ metadata.angle.fromStart = angleFromStart;
2058
+ metadata.direction.fromStart = toDirection(angleFromStart.degrees);
2059
+ metadata.points.end = { x: newX, y: newY };
2060
+ }
2061
+
2062
+ const initialMetadata = {
2063
+ times: {
2064
+ start: 0,
2065
+ end: 0
2066
+ },
2067
+ duration: 0,
2068
+ velocity: 0
2069
+ };
2070
+ function storePointerTimeMetadata(event, api, getShouldStore, setRequest, recognize) {
2071
+ const { getMetadata, getStatus, onRecognized } = api, metadata = getMetadata();
2072
+ if (!metadata.times) {
2073
+ metadata.times = createClone()(initialMetadata.times);
2074
+ }
2075
+ metadata.times.start = Math.round(event.timeStamp);
2076
+ metadata.times.end = Math.round(event.timeStamp);
2077
+ let previousTime = metadata.times.start;
2078
+ const storeDuration = () => {
2079
+ const request = requestAnimationFrame((timestamp) => {
2080
+ if (getShouldStore()) {
2081
+ previousTime = metadata.times.end;
2082
+ metadata.times.end = Math.round(timestamp);
2083
+ metadata.duration = Math.max(0, metadata.times.end - metadata.times.start);
2084
+ const durationFromPrevious = Math.max(0, metadata.times.end - previousTime);
2085
+ metadata.velocity = metadata.distance.straight.fromPrevious / durationFromPrevious;
2086
+ recognize?.(event, api);
2087
+ if (getStatus() === "recognized")
2088
+ onRecognized(event);
2089
+ storeDuration();
2090
+ }
2091
+ });
2092
+ setRequest(request);
248
2093
  };
2094
+ storeDuration();
249
2095
  }
250
- function createMatchesKeycombo(keycombo) {
251
- return (event) => eventMatchesKeycombo(event, narrowKeycombo(keycombo));
2096
+
2097
+ function defineGraph(nodes, edges) {
2098
+ return { nodes, edges };
252
2099
  }
253
- function createMatchesMousecombo(mousecombo) {
254
- return (event) => eventMatchesMousecombo(event, narrowMousecombo(mousecombo));
2100
+ function defineGraphNodes(nodes) {
2101
+ return nodes;
255
2102
  }
256
- function createMatchesPointercombo(pointercombo) {
257
- return (event) => eventMatchesPointercombo(event, narrowPointercombo(pointercombo));
2103
+ function defineGraphEdges(edges) {
2104
+ return edges;
258
2105
  }
259
- function createToFocusable(order, elementIsCandidate) {
260
- return (element) => {
261
- if (elementIsCandidate && predicateFocusable(element))
262
- return element;
263
- switch (order) {
264
- case "first":
265
- for (let i = 0; i < element.children.length; i++) {
266
- const focusable = createToFocusable(order, true)(element.children[i]);
267
- if (focusable)
268
- return focusable;
269
- }
270
- break;
271
- case "last":
272
- for (let i = element.children.length - 1; i > -1; i--) {
273
- const focusable = createToFocusable(order, true)(element.children[i]);
274
- if (focusable)
275
- return focusable;
276
- }
277
- break;
278
- }
279
- };
2106
+ function defineGraphNode(node) {
2107
+ return node;
280
2108
  }
281
- class Pipeable {
282
- constructor(state) {
283
- this.state = state;
284
- }
285
- pipe(...fns) {
286
- return createReduce((piped, fn, index) => fn(piped, index), this.state)(fns);
287
- }
288
- async pipeAsync(...fns) {
289
- return await createReduceAsync(
290
- async (piped, fn, index) => await fn(piped, index),
291
- this.state
292
- )(fns);
293
- }
2109
+ function defineGraphEdge(from, to, predicateTraversable) {
2110
+ return { from, to, predicateTraversable };
294
2111
  }
295
-
296
- function toKey(name) {
297
- return name in keysByName ? keysByName[name] : name;
2112
+ function defineAsyncGraph(nodes, edges) {
2113
+ return { nodes, edges };
298
2114
  }
299
- const keysByName = {
300
- up: "ArrowUp",
301
- right: "ArrowRight",
302
- down: "ArrowDown",
303
- left: "ArrowLeft",
304
- enter: "Enter",
305
- backspace: "Backspace",
306
- tab: "Tab",
307
- space: " ",
308
- shift: "Shift",
309
- meta: "Meta",
310
- command: "Meta",
311
- cmd: "Meta",
312
- control: "Control",
313
- ctrl: "Control",
314
- alt: "Alt",
315
- opt: "Alt",
316
- option: "Alt",
317
- fn: "Fn",
318
- capslock: "CapsLock",
319
- end: "End",
320
- home: "Home",
321
- pagedown: "PageDown",
322
- pageup: "PageUp",
323
- esc: "Escape",
324
- camera: "Camera",
325
- delete: "Delete",
326
- f1: "F1",
327
- f2: "F2",
328
- f3: "F3",
329
- f4: "F4",
330
- f5: "F5",
331
- f6: "F6",
332
- f7: "F7",
333
- f8: "F8",
334
- f9: "F9",
335
- f10: "F10",
336
- f11: "F11",
337
- f12: "F12",
338
- f13: "F13",
339
- f14: "F14",
340
- f15: "F15",
341
- f16: "F16",
342
- f17: "F17",
343
- f18: "F18",
344
- f19: "F19",
345
- f20: "F20"
346
- };
347
- const toListenableKeycomboItems = createMap((name) => ({ name, type: fromComboItemNameToType(name) }));
348
- function narrowKeycombo(type) {
349
- return new Pipeable(type).pipe(
350
- toCombo,
351
- toListenableKeycomboItems
352
- );
2115
+ function defineAsyncGraphEdges(edges) {
2116
+ return edges;
353
2117
  }
354
- function narrowMousecombo(type) {
355
- return toCombo(type);
2118
+ function defineAsyncGraphEdge(from, to, predicateTraversable) {
2119
+ return { from, to, predicateTraversable };
356
2120
  }
357
- function narrowPointercombo(type) {
358
- return toCombo(type);
2121
+
2122
+ function defineAssociativeArrayEntries(entries) {
2123
+ return entries;
359
2124
  }
360
- const toUnique$1 = unique();
361
- const toComboItems = map((name) => name === "" ? delimiter : name);
362
- const delimiter = "+";
363
- function toCombo(type) {
364
- return pipe(
365
- toUnique$1,
366
- toComboItems,
367
- toArray()
368
- )(type.split(delimiter));
369
- }
370
- function fromComboItemNameToType(name) {
371
- return find((type) => predicatesByType[type](name))(listenableComboItemTypes) ?? "custom";
372
- }
373
- const listenableComboItemTypes = /* @__PURE__ */ new Set(["singleCharacter", "arrow", "other", "modifier", "click", "pointer"]);
374
- const predicatesByType = {
375
- singleCharacter: (name) => typeREs["singleCharacter"].test(name),
376
- arrow: (name) => typeREs["arrow"].test(name),
377
- other: (name) => typeREs["other"].test(name),
378
- modifier: (name) => typeREs["modifier"].test(name),
379
- click: (name) => typeREs["click"].test(name),
380
- pointer: (name) => typeREs["pointer"].test(name)
381
- };
382
- const typeREs = {
383
- singleCharacter: /^!?[a-zA-Z0-9,<.>/?;:'"[{\]}\\|`~!@#$%^&*()-_=+]$/,
384
- arrow: /^!?(arrow|vertical|horizontal|up|down|right|left)$/,
385
- other: /^!?(enter|backspace|space|tab|esc|home|end|pagedown|pageup|capslock|f[0-9]{1,2}|camera|delete)$/,
386
- modifier: /^!?(cmd|command|meta|shift|ctrl|control|alt|opt|option)$/,
387
- click: /^!?(rightclick|contextmenu|click|mousedown|mouseup|dblclick)$/,
388
- pointer: /^!?(pointerdown|pointerup|pointermove|pointerover|pointerout|pointerenter|pointerleave|pointercancel|gotpointercapture|lostpointercapture)$/
389
- };
390
- function toModifier(modifierOrAlias) {
391
- return modifierOrAlias in modifiersByAlias ? modifiersByAlias[modifierOrAlias] : modifierOrAlias;
392
- }
393
- const modifiersByAlias = {
394
- cmd: "meta",
395
- command: "meta",
396
- ctrl: "control",
397
- opt: "alt",
398
- option: "alt"
399
- };
2125
+
400
2126
  function createExceptAndOnlyEffect(type, effect, options) {
401
2127
  const { except = [], only = [] } = options;
402
2128
  if (type === "keydown" || type === "keyup") {
403
2129
  return (event) => {
404
- const { target } = event, [matchesOnly, matchesExcept] = target instanceof Element ? createMap((selectors) => some((selector) => target.matches(selector))(selectors))([only, except]) : [false, true];
2130
+ const { target } = event, [matchesOnly, matchesExcept] = target instanceof Element ? createMap((selectors) => some((selector) => target.matches(selector))(selectors))([only, except]) : [false, false];
405
2131
  if (matchesOnly) {
406
2132
  effect(event);
407
2133
  return;
@@ -414,7 +2140,7 @@ function createExceptAndOnlyEffect(type, effect, options) {
414
2140
  }
415
2141
  if (type === "click" || type === "dblclick" || type === "contextmenu" || type.startsWith("mouse")) {
416
2142
  return (event) => {
417
- const { target } = event, [matchesOnly, matchesExcept] = target instanceof Element ? createMap((selectors) => some((selector) => target.matches(selector))(selectors))([only, except]) : [false, true];
2143
+ const { target } = event, [matchesOnly, matchesExcept] = target instanceof Element ? createMap((selectors) => some((selector) => target.matches(selector))(selectors))([only, except]) : [false, false];
418
2144
  if (matchesOnly) {
419
2145
  effect(event);
420
2146
  return;
@@ -427,7 +2153,7 @@ function createExceptAndOnlyEffect(type, effect, options) {
427
2153
  }
428
2154
  if (type.startsWith("pointer")) {
429
2155
  return (event) => {
430
- const { target } = event, [matchesOnly, matchesExcept] = target instanceof Element ? createMap((selectors) => some((selector) => target.matches(selector))(selectors))([only, except]) : [false, true];
2156
+ const { target } = event, [matchesOnly, matchesExcept] = target instanceof Element ? createMap((selectors) => some((selector) => target.matches(selector))(selectors))([only, except]) : [false, false];
431
2157
  if (matchesOnly) {
432
2158
  effect(event);
433
2159
  return;
@@ -439,7 +2165,7 @@ function createExceptAndOnlyEffect(type, effect, options) {
439
2165
  };
440
2166
  }
441
2167
  return (event) => {
442
- const { target } = event, [matchesOnly, matchesExcept] = target instanceof Element ? createMap((selectors) => some((selector) => target.matches(selector))(selectors))([only, except]) : [false, true];
2168
+ const { target } = event, [matchesOnly, matchesExcept] = target instanceof Element ? createMap((selectors) => some((selector) => target.matches(selector))(selectors))([only, except]) : [false, false];
443
2169
  if (matchesOnly) {
444
2170
  effect(event, {});
445
2171
  return;
@@ -450,27 +2176,15 @@ function createExceptAndOnlyEffect(type, effect, options) {
450
2176
  }
451
2177
  };
452
2178
  }
453
- function predicateModified({ event, alias }) {
454
- return predicatesByModifier[alias]?.(event);
455
- }
456
- const predicatesByModifier = {
457
- shift: (event) => event.shiftKey,
458
- cmd: (event) => event.metaKey,
459
- command: (event) => event.metaKey,
460
- meta: (event) => event.metaKey,
461
- ctrl: (event) => event.ctrlKey,
462
- control: (event) => event.ctrlKey,
463
- alt: (event) => event.altKey,
464
- opt: (event) => event.altKey,
465
- option: (event) => event.altKey
466
- };
467
- function domIsAvailable() {
2179
+
2180
+ function getDomAvailability() {
468
2181
  try {
469
- return !!window;
2182
+ return !!window ? "available" : "unavailable";
470
2183
  } catch (error) {
471
- return false;
2184
+ return "unavailable";
472
2185
  }
473
2186
  }
2187
+
474
2188
  function predicateArray(value) {
475
2189
  return Array.isArray(value);
476
2190
  }
@@ -489,24 +2203,8 @@ function predicateNumber(value) {
489
2203
  function predicateString(value) {
490
2204
  return typeof value === "string";
491
2205
  }
492
- const tabbableSelector = join(':not([hidden]):not([tabindex="-1"]),')([
493
- "input:not([disabled]):not([type=hidden])",
494
- "select:not([disabled])",
495
- "textarea:not([disabled])",
496
- "button:not([disabled])",
497
- "a[href]",
498
- "area[href]",
499
- "summary",
500
- "iframe",
501
- "object",
502
- "embed",
503
- "audio[controls]",
504
- "video[controls]",
505
- "[contenteditable]",
506
- "[tabindex]:not([disabled])"
507
- ]);
508
- function predicateFocusable(element) {
509
- return element.matches(tabbableSelector);
2206
+ function predicateObject(value) {
2207
+ return typeof value === "object";
510
2208
  }
511
2209
 
512
2210
  class Recognizeable {
@@ -519,7 +2217,7 @@ class Recognizeable {
519
2217
  effects: {}
520
2218
  };
521
2219
  this.maxSequenceLength = options?.maxSequenceLength || defaultOptions.maxSequenceLength;
522
- this.effects = new Map(Object.entries(options?.effects || defaultOptions.effects));
2220
+ this.effects = options?.effects || defaultOptions.effects;
523
2221
  this.resetComputedMetadata();
524
2222
  this.setSequence(sequence);
525
2223
  this.effectApi = {
@@ -528,8 +2226,6 @@ class Recognizeable {
528
2226
  setMetadata: (metadata) => this.computedMetadata = metadata,
529
2227
  recognized: () => this.recognized(),
530
2228
  denied: () => this.denied(),
531
- recognizedUntilReady: () => this.recognizedUntilReady(),
532
- deniedUntilReady: () => this.deniedUntilReady(),
533
2229
  ready: () => this.ready()
534
2230
  };
535
2231
  this.ready();
@@ -544,12 +2240,6 @@ class Recognizeable {
544
2240
  denied() {
545
2241
  this.computedStatus = "denied";
546
2242
  }
547
- recognizedUntilReady() {
548
- this.computedStatus = "recognized until ready";
549
- }
550
- deniedUntilReady() {
551
- this.computedStatus = "denied until ready";
552
- }
553
2243
  computedStatus;
554
2244
  ready() {
555
2245
  this.computedStatus = "ready";
@@ -572,8 +2262,7 @@ class Recognizeable {
572
2262
  return this;
573
2263
  }
574
2264
  recognize(sequenceItem, { onRecognized } = {}) {
575
- if (!this.status.includes("until ready"))
576
- this.recognizing();
2265
+ this.recognizing();
577
2266
  const type = this.toType(sequenceItem), excess = predicateNumber(this.maxSequenceLength) ? Math.max(0, this.sequence.length - this.maxSequenceLength) : 0, newSequence = createConcat(
578
2267
  createSlice(excess)(this.sequence),
579
2268
  [sequenceItem]
@@ -581,11 +2270,10 @@ class Recognizeable {
581
2270
  this.effectApi.getSequence = () => newSequence;
582
2271
  this.effectApi.onRecognized = onRecognized || (() => {
583
2272
  });
584
- this.effects.get(type)?.(sequenceItem, { ...this.effectApi });
2273
+ this.effects[type]?.(sequenceItem, { ...this.effectApi });
585
2274
  switch (this.status) {
586
2275
  case "ready":
587
2276
  case "denied":
588
- case "denied until ready":
589
2277
  this.resetComputedMetadata();
590
2278
  this.setSequence([]);
591
2279
  break;
@@ -628,8 +2316,8 @@ class Listenable {
628
2316
  computedActive;
629
2317
  constructor(type, options) {
630
2318
  if (type === "recognizeable") {
631
- this.computedRecognizeable = new Recognizeable([], options?.recognizeable || {});
632
- this.recognizeableEffectsKeys = Object.keys(options?.recognizeable?.effects || {});
2319
+ this.computedRecognizeable = new Recognizeable([], options?.recognizeable);
2320
+ this.recognizeableEffectsKeys = Object.keys(options?.recognizeable?.effects);
633
2321
  }
634
2322
  this.computedActive = /* @__PURE__ */ new Set();
635
2323
  this.setType(type);
@@ -729,24 +2417,10 @@ class Listenable {
729
2417
  this.active.add({ target, id: [this.type, effect] });
730
2418
  }
731
2419
  recognizeableListen(effect, options) {
732
- let effectStatus = "ready";
733
2420
  const guardedEffect = (sequenceItem) => {
734
2421
  this.recognizeable.recognize(sequenceItem, { onRecognized: (sequenceItem2) => effect(sequenceItem2) });
735
- switch (this.recognizeable.status) {
736
- case "recognized until ready":
737
- if (effectStatus === "ready") {
738
- effect(sequenceItem);
739
- effectStatus = "performed";
740
- }
741
- break;
742
- case "recognized":
743
- effect(sequenceItem);
744
- effectStatus = "ready";
745
- break;
746
- default:
747
- effectStatus = "ready";
748
- break;
749
- }
2422
+ if (this.recognizeable.status === "recognized")
2423
+ effect(sequenceItem);
750
2424
  };
751
2425
  for (const type of this.recognizeableEffectsKeys) {
752
2426
  const listenable = new Listenable(type);
@@ -767,10 +2441,10 @@ class Listenable {
767
2441
  }
768
2442
  addEventListeners(eventListeners, options) {
769
2443
  const { target = document } = options;
770
- eventListeners.forEach((eventListener) => {
2444
+ for (const eventListener of eventListeners) {
771
2445
  target.addEventListener(eventListener[0], eventListener[1], eventListener[2]);
772
2446
  this.active.add({ target, id: eventListener });
773
- });
2447
+ }
774
2448
  }
775
2449
  listening() {
776
2450
  this.computedStatus = "listening";
@@ -882,109 +2556,22 @@ function toAddEventListenerParams(type, effect, options) {
882
2556
  const { addEventListener, useCapture } = options, exceptAndOnlyEffect = createExceptAndOnlyEffect(type, effect, options), effectOptions = [addEventListener || useCapture];
883
2557
  return { exceptAndOnlyEffect, effectOptions };
884
2558
  }
885
- function eventMatchesKeycombo(event, keycombo) {
886
- return every(({ name, type }, index) => {
887
- switch (type) {
888
- case "singleCharacter":
889
- if (name === "!")
890
- return event.key === "!";
891
- const keyToTest = event.altKey && fromComboItemNameToType(event.key) === "custom" ? fromCodeToSingleCharacter(event.code) : event.key.toLowerCase();
892
- return name.startsWith("!") ? keyToTest !== toKey(name.slice(1)).toLowerCase() : keyToTest === toKey(name).toLowerCase();
893
- case "other":
894
- if (name === "!") {
895
- return event.key === "!";
896
- }
897
- return name.startsWith("!") ? event.key.toLowerCase() !== toKey(name.slice(1)).toLowerCase() : event.key.toLowerCase() === toKey(name).toLowerCase();
898
- case "arrow":
899
- return predicatesByArrow.get(name)?.({ event, name }) ?? predicatesByArrow.get("default")({ event, name });
900
- case "modifier":
901
- if (index === keycombo.length - 1) {
902
- return name.startsWith("!") ? event.key.toLowerCase() !== toModifier(name.slice(1)).toLowerCase() : event.key.toLowerCase() === toModifier(name).toLowerCase();
903
- }
904
- return name.startsWith("!") ? !predicateModified({ event, alias: name.slice(1) }) : predicateModified({ event, alias: name });
905
- }
906
- })(keycombo);
907
- }
908
- function fromCodeToSingleCharacter(code) {
909
- for (const c in aliasesByCode) {
910
- if (c === code) {
911
- return aliasesByCode[c];
912
- }
913
- }
914
- for (const prefix of ["Key", "Digit"]) {
915
- const re = new RegExp(`^${prefix}`);
916
- if (re.test(code)) {
917
- return createClip(re)(code).toLowerCase();
918
- }
919
- }
920
- return code;
921
- }
922
- const aliasesByCode = {
923
- "Backquote": "`",
924
- "Minus": "-",
925
- "Equal": "=",
926
- "BracketLeft": "[",
927
- "BracketRight": "]",
928
- "Backslash": "\\",
929
- "Semicolon": ";",
930
- "Quote": "'",
931
- "Comma": ",",
932
- "Period": ".",
933
- "Slash": "/"
934
- };
935
- const predicatesByArrow = /* @__PURE__ */ new Map([
936
- [
937
- "arrow",
938
- ({ event }) => arrows.has(event.key.toLowerCase())
939
- ],
940
- [
941
- "!arrow",
942
- ({ event }) => !arrows.has(event.key.toLowerCase())
943
- ],
944
- [
945
- "vertical",
946
- ({ event }) => verticalArrows.has(event.key.toLowerCase())
947
- ],
948
- [
949
- "!vertical",
950
- ({ event }) => !verticalArrows.has(event.key.toLowerCase())
951
- ],
952
- [
953
- "horizontal",
954
- ({ event }) => horizontalArrows.has(event.key.toLowerCase())
955
- ],
956
- [
957
- "!horizontal",
958
- ({ event }) => !horizontalArrows.has(event.key.toLowerCase())
959
- ],
960
- [
961
- "default",
962
- ({ event, name }) => name.startsWith("!") ? event.key.toLowerCase() !== `arrow${name.toLowerCase()}` : event.key.toLowerCase() === `arrow${name.toLowerCase()}`
963
- ]
964
- ]);
965
- const arrows = /* @__PURE__ */ new Set(["arrowup", "arrowright", "arrowdown", "arrowleft"]);
966
- const verticalArrows = /* @__PURE__ */ new Set(["arrowup", "arrowdown"]);
967
- const horizontalArrows = /* @__PURE__ */ new Set(["arrowright", "arrowleft"]);
968
- function eventMatchesMousecombo(event, Mousecombo) {
969
- return every((name) => fromComboItemNameToType(name) === "click" || name.startsWith("!") && !predicateModified({ alias: name.slice(1), event }) || !name.startsWith("!") && predicateModified({ alias: name, event }))(Mousecombo);
970
- }
971
- function eventMatchesPointercombo(event, pointercombo) {
972
- return every((name) => fromComboItemNameToType(name) === "pointer" || name.startsWith("!") && !predicateModified({ alias: name.slice(1), event }) || !name.startsWith("!") && predicateModified({ alias: name, event }))(pointercombo);
973
- }
974
2559
  const observerAssertionsByType = {
975
2560
  intersect: (observer) => observer instanceof IntersectionObserver,
976
2561
  mutate: (observer) => observer instanceof MutationObserver,
977
2562
  resize: (observer) => observer instanceof ResizeObserver
978
2563
  };
979
2564
 
980
- const defaultOptions$7 = {
2565
+ const defaultOptions$8 = {
981
2566
  duration: 0,
2567
+ // delay not supported, because it can be effectd by delayable
982
2568
  timing: [
983
2569
  0,
984
2570
  0,
985
2571
  1,
986
2572
  1
987
2573
  ],
2574
+ // linear by default
988
2575
  iterations: 1,
989
2576
  alternates: false
990
2577
  };
@@ -1005,10 +2592,10 @@ class Animateable {
1005
2592
  getEaseables;
1006
2593
  getReversedEaseables;
1007
2594
  constructor(keyframes, options = {}) {
1008
- this.initialDuration = options?.duration || defaultOptions$7.duration;
1009
- this.controlPoints = fromTimingToControlPoints(options?.timing || defaultOptions$7.timing);
1010
- this.iterationLimit = options?.iterations || defaultOptions$7.iterations;
1011
- this.alternates = options?.alternates || defaultOptions$7.alternates;
2595
+ this.initialDuration = options?.duration || defaultOptions$8.duration;
2596
+ this.controlPoints = fromTimingToControlPoints(options?.timing || defaultOptions$8.timing);
2597
+ this.iterationLimit = options?.iterations || defaultOptions$8.iterations;
2598
+ this.alternates = options?.alternates || defaultOptions$8.alternates;
1012
2599
  this.reversedControlPoints = fromControlPointsToReversedControlPoints(this.controlPoints);
1013
2600
  this.toAnimationProgress = createToAnimationProgress(this.controlPoints);
1014
2601
  this.reversedToAnimationProgress = createToAnimationProgress(this.reversedControlPoints);
@@ -1084,10 +2671,11 @@ class Animateable {
1084
2671
  setKeyframes(keyframes) {
1085
2672
  this.stop();
1086
2673
  this.computedKeyframes = Array.from(keyframes).sort(({ progress: progressA }, { progress: progressB }) => progressA - progressB);
1087
- this.reversedKeyframes = new Pipeable(this.keyframes).pipe(
1088
- createReverse(),
1089
- createMap(({ progress, properties }) => ({ progress: 1 - progress, properties }))
1090
- );
2674
+ this.reversedKeyframes = pipe(
2675
+ reverse$1(),
2676
+ map(({ progress, properties }) => ({ progress: 1 - progress, properties })),
2677
+ toArray()
2678
+ )(this.keyframes);
1091
2679
  this.properties = toProperties(this.keyframes);
1092
2680
  this.easeables = this.getEaseables({ keyframes: this.keyframes, properties: this.properties });
1093
2681
  this.reversedEaseables = this.getReversedEaseables({ keyframes: this.reversedKeyframes, properties: this.properties });
@@ -1385,7 +2973,7 @@ class Animateable {
1385
2973
  break;
1386
2974
  case "reversing":
1387
2975
  this.computedIterations += 1;
1388
- if (this.iterations < this.iterationLimit || this.iterationLimit === true) {
2976
+ if (this.iterationLimit === true || this.iterations < this.iterationLimit) {
1389
2977
  this.createAnimate("reverse")(effect, options);
1390
2978
  } else {
1391
2979
  this.alternateCache.status = "ready";
@@ -1394,7 +2982,7 @@ class Animateable {
1394
2982
  }
1395
2983
  } else {
1396
2984
  this.computedIterations += 1;
1397
- if (this.iterations < this.iterationLimit || this.iterationLimit === true) {
2985
+ if (this.iterationLimit === true || this.iterations < this.iterationLimit) {
1398
2986
  this.createAnimate("play")(effect, options);
1399
2987
  }
1400
2988
  }
@@ -1410,7 +2998,7 @@ class Animateable {
1410
2998
  switch (this.alternateCache.status) {
1411
2999
  case "playing":
1412
3000
  this.computedIterations += 1;
1413
- if (this.iterations < this.iterationLimit || this.iterationLimit === true) {
3001
+ if (this.iterationLimit === true || this.iterations < this.iterationLimit) {
1414
3002
  this.createAnimate("play")(effect, options);
1415
3003
  } else {
1416
3004
  this.alternateCache.status = "ready";
@@ -1422,7 +3010,7 @@ class Animateable {
1422
3010
  }
1423
3011
  } else {
1424
3012
  this.computedIterations += 1;
1425
- if (this.iterations < this.iterationLimit) {
3013
+ if (this.iterationLimit === true || this.iterations < this.iterationLimit) {
1426
3014
  this.createAnimate("reverse")(effect, options);
1427
3015
  }
1428
3016
  }
@@ -1631,7 +3219,7 @@ function createGetEaseables(fromKeyframeToControlPoints) {
1631
3219
  (easeables, property) => {
1632
3220
  const propertyKeyframes = createFilter(({ properties: properties2 }) => properties2.hasOwnProperty(property))(keyframes), fromKeyframesToEaseables = createReduce(
1633
3221
  (propertyEaseables2, keyframe, index) => {
1634
- const previous = keyframe.properties[property], next = index === propertyKeyframes.length - 1 ? previous : propertyKeyframes[index + 1].properties[property], start = keyframe.progress, end = index === propertyKeyframes.length - 1 ? 2 : propertyKeyframes[index + 1].progress, hasCustomTiming = !!keyframe.timing, toAnimationProgress = index === propertyKeyframes.length - 1 ? (timeProgress) => 1 : createToAnimationProgress(fromKeyframeToControlPoints({ keyframe, index, propertyKeyframes }));
3222
+ const previous = keyframe.properties[property], next = index === propertyKeyframes.length - 1 ? previous : propertyKeyframes[index + 1].properties[property], start = keyframe.progress, end = index === propertyKeyframes.length - 1 ? 2 : propertyKeyframes[index + 1].progress, hasCustomTiming = !!keyframe.timing, toAnimationProgress = index === propertyKeyframes.length - 1 ? () => 1 : createToAnimationProgress(fromKeyframeToControlPoints({ keyframe, index, propertyKeyframes }));
1635
3223
  propertyEaseables2.push({
1636
3224
  property,
1637
3225
  value: { previous, next },
@@ -1646,7 +3234,7 @@ function createGetEaseables(fromKeyframeToControlPoints) {
1646
3234
  property,
1647
3235
  value: { previous: propertyEaseables[0].value.previous, next: propertyEaseables[0].value.previous },
1648
3236
  progress: { start: -1, end: propertyEaseables[0].progress.start },
1649
- toAnimationProgress: (timeProgress) => 1,
3237
+ toAnimationProgress: () => 1,
1650
3238
  hasCustomTiming: false
1651
3239
  };
1652
3240
  return createConcat(
@@ -1891,14 +3479,14 @@ const easingsNetInOutBack = [
1891
3479
  1.6
1892
3480
  ];
1893
3481
 
1894
- const defaultOptions$6 = {
3482
+ const defaultOptions$7 = {
1895
3483
  name: "baleada"
1896
3484
  };
1897
3485
  class Broadcastable {
1898
3486
  name;
1899
3487
  constructor(state, options = {}) {
1900
3488
  this.setState(state);
1901
- this.name = options.name ?? defaultOptions$6.name;
3489
+ this.name = options.name ?? defaultOptions$7.name;
1902
3490
  this.ready();
1903
3491
  }
1904
3492
  computedStatus;
@@ -1963,12 +3551,69 @@ function toMessageListenParams(instance, effect) {
1963
3551
  ];
1964
3552
  }
1965
3553
 
3554
+ const defaultOptions$6 = {
3555
+ locales: "en",
3556
+ collator: { sensitivity: "base" }
3557
+ };
3558
+ class Compareable {
3559
+ constructor(string, options = {}) {
3560
+ const locales = options.locales || defaultOptions$6.locales, collatorOptions = { ...defaultOptions$6.collator, ...options.collator }, key = locales + pipe(
3561
+ createEntries(),
3562
+ sort((a, b) => a[0] < b[0] ? -1 : 1),
3563
+ join()
3564
+ )(collatorOptions);
3565
+ this.computedCollator = cache[key] || (cache[key] = new Intl.Collator(locales, collatorOptions));
3566
+ this.setString(string);
3567
+ this.ready();
3568
+ }
3569
+ computedStatus;
3570
+ ready() {
3571
+ this.computedStatus = "ready";
3572
+ }
3573
+ get string() {
3574
+ return this.computedString;
3575
+ }
3576
+ set string(string) {
3577
+ this.setString(string);
3578
+ }
3579
+ get status() {
3580
+ return this.computedStatus;
3581
+ }
3582
+ computedCollator;
3583
+ get collator() {
3584
+ return this.computedCollator;
3585
+ }
3586
+ computedComparison;
3587
+ get comparison() {
3588
+ return this.computedComparison;
3589
+ }
3590
+ computedString;
3591
+ setString(string) {
3592
+ this.computedString = string;
3593
+ return this;
3594
+ }
3595
+ compare(compared) {
3596
+ this.comparing();
3597
+ this.computedComparison = this.computedCollator.compare(this.string, compared);
3598
+ this.compared();
3599
+ return this;
3600
+ }
3601
+ comparing() {
3602
+ this.computedStatus = "comparing";
3603
+ }
3604
+ compared() {
3605
+ this.computedStatus = "compared";
3606
+ }
3607
+ }
3608
+ const cache = {};
3609
+
1966
3610
  const defaultOptions$5 = {
1967
3611
  segment: {
1968
3612
  from: "start",
1969
3613
  to: "end"
1970
3614
  },
1971
3615
  divider: /\s/
3616
+ // Keep an eye out for use cases where a { before, after } object would be needed, or where multi-character dividers need to be used
1972
3617
  };
1973
3618
  const defaultCompleteOptions = {
1974
3619
  select: "completionEnd"
@@ -2051,6 +3696,7 @@ class Completeable {
2051
3696
  }
2052
3697
  return this;
2053
3698
  }
3699
+ // TODO: Support array of selections for multi cursor editing
2054
3700
  computedSelection;
2055
3701
  setSelection(selection) {
2056
3702
  this.computedSelection = selection;
@@ -2127,12 +3773,12 @@ function toPreviousMatch({ string, re, from }) {
2127
3773
  if (!re.test(string.slice(0, from)) || from === 0) {
2128
3774
  indexOf = -1;
2129
3775
  } else {
2130
- const reversedStringBeforeFrom = new Pipeable(string).pipe(
3776
+ const reversedStringBeforeFrom = pipe(
2131
3777
  (string2) => string2.slice(0, from),
2132
3778
  (sliced) => sliced.split(""),
2133
3779
  reverse,
2134
3780
  toString
2135
- ), toNextMatchIndex = toNextMatch({ string: reversedStringBeforeFrom, re, from: 0 });
3781
+ )(string), toNextMatchIndex = toNextMatch({ string: reversedStringBeforeFrom, re, from: 0 });
2136
3782
  indexOf = toNextMatchIndex === -1 ? -1 : reversedStringBeforeFrom.length - 1 - toNextMatchIndex;
2137
3783
  }
2138
3784
  return indexOf;
@@ -2503,11 +4149,12 @@ class Fetchable {
2503
4149
  computedText;
2504
4150
  constructor(resource, options = {}) {
2505
4151
  this.setResource(resource);
2506
- this.computedArrayBuffer = new Resolveable(async () => "arrayBuffer" in this.response ? await this.response.arrayBuffer() : await void 0);
2507
- this.computedBlob = new Resolveable(async () => "blob" in this.response ? await this.response.blob() : await void 0);
2508
- this.computedFormData = new Resolveable(async () => "formData" in this.response ? await this.response.formData() : await void 0);
2509
- this.computedJson = new Resolveable(async () => "json" in this.response ? await this.response.json() : await void 0);
2510
- this.computedText = new Resolveable(async () => "text" in this.response ? await this.response.text() : await void 0);
4152
+ this.computedKy = ky.create(narrowOptions(options.ky));
4153
+ this.computedArrayBuffer = new Resolveable(async () => "arrayBuffer" in this.response ? await this.response.arrayBuffer() : void 0);
4154
+ this.computedBlob = new Resolveable(async () => "blob" in this.response ? await this.response.blob() : void 0);
4155
+ this.computedFormData = new Resolveable(async () => "formData" in this.response ? await this.response.formData() : void 0);
4156
+ this.computedJson = new Resolveable(async () => "json" in this.response ? await this.response.json() : void 0);
4157
+ this.computedText = new Resolveable(async () => "text" in this.response ? await this.response.text() : void 0);
2511
4158
  this.ready();
2512
4159
  }
2513
4160
  computedStatus;
@@ -2520,6 +4167,10 @@ class Fetchable {
2520
4167
  set resource(resource) {
2521
4168
  this.setResource(resource);
2522
4169
  }
4170
+ computedKy;
4171
+ get ky() {
4172
+ return this.computedKy;
4173
+ }
2523
4174
  computedAbortController;
2524
4175
  get abortController() {
2525
4176
  if (!this.computedAbortController) {
@@ -2533,6 +4184,10 @@ class Fetchable {
2533
4184
  get response() {
2534
4185
  return this.computedResponse;
2535
4186
  }
4187
+ computedRetryCount = 0;
4188
+ get retryCount() {
4189
+ return this.computedRetryCount;
4190
+ }
2536
4191
  get error() {
2537
4192
  return this.computedError;
2538
4193
  }
@@ -2561,7 +4216,23 @@ class Fetchable {
2561
4216
  async fetch(options = {}) {
2562
4217
  this.fetching();
2563
4218
  try {
2564
- this.computedResponse = await fetch(this.resource, { signal: this.abortController.signal, ...narrowOptions(options) });
4219
+ this.computedResponse = await this.ky(
4220
+ this.resource,
4221
+ {
4222
+ ...options,
4223
+ signal: this.abortController.signal,
4224
+ hooks: {
4225
+ ...options.hooks,
4226
+ beforeRetry: [
4227
+ ...options.hooks?.beforeRetry || [],
4228
+ ({ retryCount }) => {
4229
+ this.retrying();
4230
+ this.computedRetryCount = retryCount;
4231
+ }
4232
+ ]
4233
+ }
4234
+ }
4235
+ );
2565
4236
  this.fetched();
2566
4237
  } catch (error) {
2567
4238
  this.computedError = error;
@@ -2575,6 +4246,9 @@ class Fetchable {
2575
4246
  fetching() {
2576
4247
  this.computedStatus = "fetching";
2577
4248
  }
4249
+ retrying() {
4250
+ this.computedStatus = "retrying";
4251
+ }
2578
4252
  fetched() {
2579
4253
  this.computedStatus = "fetched";
2580
4254
  }
@@ -2585,23 +4259,27 @@ class Fetchable {
2585
4259
  this.computedStatus = "errored";
2586
4260
  }
2587
4261
  async get(options = {}) {
2588
- await this.fetch({ signal: this.abortController.signal, ...narrowOptions(options), method: "get" });
4262
+ await this.fetch({ signal: this.abortController.signal, ...options, method: "get" });
2589
4263
  return this;
2590
4264
  }
2591
4265
  async patch(options = {}) {
2592
- await this.fetch({ signal: this.abortController.signal, ...narrowOptions(options), method: "patch" });
4266
+ await this.fetch({ signal: this.abortController.signal, ...options, method: "patch" });
2593
4267
  return this;
2594
4268
  }
2595
4269
  async post(options = {}) {
2596
- await this.fetch({ signal: this.abortController.signal, ...narrowOptions(options), method: "post" });
4270
+ await this.fetch({ signal: this.abortController.signal, ...options, method: "post" });
2597
4271
  return this;
2598
4272
  }
2599
4273
  async put(options = {}) {
2600
- await this.fetch({ signal: this.abortController.signal, ...narrowOptions(options), method: "put" });
4274
+ await this.fetch({ signal: this.abortController.signal, ...options, method: "put" });
2601
4275
  return this;
2602
4276
  }
2603
4277
  async delete(options = {}) {
2604
- await this.fetch({ signal: this.abortController.signal, ...narrowOptions(options), method: "delete" });
4278
+ await this.fetch({ signal: this.abortController.signal, ...options, method: "delete" });
4279
+ return this;
4280
+ }
4281
+ async head(options = {}) {
4282
+ await this.fetch({ signal: this.abortController.signal, ...options, method: "head" });
2605
4283
  return this;
2606
4284
  }
2607
4285
  abort() {
@@ -2610,16 +4288,9 @@ class Fetchable {
2610
4288
  }
2611
4289
  }
2612
4290
  function narrowOptions(options) {
2613
- return predicateFunction(options) ? options({ withJson }) : options;
2614
- }
2615
- function withJson(data) {
2616
- return {
2617
- body: JSON.stringify(data),
2618
- headers: {
2619
- "Accept": "application/json",
2620
- "Content-Type": "application/json"
2621
- }
2622
- };
4291
+ if (!options)
4292
+ return {};
4293
+ return predicateFunction(options) ? options({ stop: ky.stop }) : options;
2623
4294
  }
2624
4295
 
2625
4296
  class Fullscreenable {
@@ -2947,13 +4618,12 @@ class Pickable {
2947
4618
  }
2948
4619
  pick(indexOrIndices, options = {}) {
2949
4620
  const { replace, allowsDuplicates } = { ...defaultPickOptions, ...options };
2950
- this.computedPicks = new Pipeable(indexOrIndices).pipe(
4621
+ this.computedPicks = pipe(
2951
4622
  narrowIndices,
2952
4623
  this.toPossiblePicks,
2953
4624
  (possiblePicks) => {
2954
- if (replace === "all") {
4625
+ if (replace === "all")
2955
4626
  return allowsDuplicates ? possiblePicks : toUnique(possiblePicks);
2956
- }
2957
4627
  const maybeWithoutDuplicates = allowsDuplicates ? possiblePicks : createFilter(
2958
4628
  (possiblePick) => typeof find((pick) => pick === possiblePick)(this.picks || []) !== "number"
2959
4629
  )(possiblePicks);
@@ -2970,10 +4640,11 @@ class Pickable {
2970
4640
  if (maybeWithoutDuplicates.length > this.picks.length) {
2971
4641
  return createSlice(maybeWithoutDuplicates.length - this.picks.length)(maybeWithoutDuplicates);
2972
4642
  }
2973
- return new Pipeable(this.picks).pipe(
2974
- createSlice(maybeWithoutDuplicates.length),
2975
- createConcat(maybeWithoutDuplicates)
2976
- );
4643
+ return pipe(
4644
+ slice(maybeWithoutDuplicates.length),
4645
+ (array) => concat(array, maybeWithoutDuplicates),
4646
+ toArray()
4647
+ )(this.picks);
2977
4648
  case "lifo":
2978
4649
  if (maybeWithoutDuplicates.length === 0) {
2979
4650
  return this.picks;
@@ -2984,13 +4655,14 @@ class Pickable {
2984
4655
  if (maybeWithoutDuplicates.length > this.picks.length) {
2985
4656
  return createSlice(0, maybeWithoutDuplicates.length - this.picks.length + 1)(maybeWithoutDuplicates);
2986
4657
  }
2987
- return new Pipeable(this.picks).pipe(
2988
- createSlice(0, this.picks.length - maybeWithoutDuplicates.length),
2989
- createConcat(maybeWithoutDuplicates)
2990
- );
4658
+ return pipe(
4659
+ slice(0, this.picks.length - maybeWithoutDuplicates.length - 1),
4660
+ (array) => concat(array, maybeWithoutDuplicates),
4661
+ toArray()
4662
+ )(this.picks);
2991
4663
  }
2992
4664
  }
2993
- );
4665
+ )(indexOrIndices);
2994
4666
  this.computedFirst = Math.min(...this.picks);
2995
4667
  this.computedLast = Math.max(...this.picks);
2996
4668
  this.computedMultiple = toUnique(this.picks).length > 1;
@@ -3038,7 +4710,7 @@ class Sanitizeable {
3038
4710
  computedDompurify;
3039
4711
  computedStatus;
3040
4712
  ready() {
3041
- if (domIsAvailable()) {
4713
+ if (getDomAvailability() === "available") {
3042
4714
  this.computedDompurify = createDOMPurify();
3043
4715
  this.computedDompurify.setConfig(this.domPurifyConfig);
3044
4716
  }
@@ -3051,7 +4723,7 @@ class Sanitizeable {
3051
4723
  this.setHtml(html);
3052
4724
  }
3053
4725
  get dompurify() {
3054
- if (!this.computedDompurify && domIsAvailable()) {
4726
+ if (!this.computedDompurify && getDomAvailability() === "available") {
3055
4727
  this.computedDompurify = createDOMPurify();
3056
4728
  this.computedDompurify.setConfig(this.domPurifyConfig);
3057
4729
  }
@@ -3194,7 +4866,7 @@ class Storeable {
3194
4866
  computedStatus;
3195
4867
  ready() {
3196
4868
  this.computedStatus = "ready";
3197
- if (domIsAvailable()) {
4869
+ if (getDomAvailability() === "available") {
3198
4870
  if (predicateNull(this.storage.getItem(this.computedStatusKey))) {
3199
4871
  this.storeStatus();
3200
4872
  }
@@ -3207,7 +4879,7 @@ class Storeable {
3207
4879
  this.setKey(key);
3208
4880
  }
3209
4881
  get status() {
3210
- if (domIsAvailable()) {
4882
+ if (getDomAvailability() === "available") {
3211
4883
  const storedStatus = this.storage.getItem(this.computedStatusKey);
3212
4884
  if (this.computedStatus !== storedStatus && predicateString(storedStatus)) {
3213
4885
  this.computedStatus = storedStatus;
@@ -3295,4 +4967,4 @@ class Storeable {
3295
4967
  }
3296
4968
  }
3297
4969
 
3298
- export { Animateable, Broadcastable, Completeable, Copyable, Delayable, Drawable, Fetchable, Fullscreenable, Grantable, Listenable, Navigateable, Pickable, Pipeable, Recognizeable, Resolveable, Sanitizeable, Searchable, Shareable, Storeable, createClamp, createClip, createConcat, createDetermine, createFilter, createFilterAsync, createForEachAsync, createInsert, createMap, createMapAsync, createMatchesKeycombo, createMatchesMousecombo, createMatchesPointercombo, createReduce, createReduceAsync, createRemove, createRename, createReorder, createReplace, createReverse, createSlice, createSlug, createSort, createSwap, createToEntries, createToEvery, createToFocusable, createToKeys, createToSome, createUnique, easingsNetInBack, easingsNetInCirc, easingsNetInCubic, easingsNetInExpo, easingsNetInOutBack, easingsNetInOutCirc, easingsNetInOutCubic, easingsNetInOutExpo, easingsNetInOutQuad, easingsNetInOutQuint, easingsNetInOutSine, easingsNetInQuad, easingsNetInQuart, easingsNetInQuint, easingsNetInSine, easingsNetOutBack, easingsNetOutCirc, easingsNetOutCubic, easingsNetOutExpo, easingsNetOutQuad, easingsNetOutQuint, easingsNetOutSine, linear, materialAccelerated, materialDecelerated, materialStandard, toD, toFlattenedD, toMessageListenParams, verouEase, verouEaseIn, verouEaseInOut, verouEaseOut };
4970
+ export { Animateable, Broadcastable, Compareable, Completeable, Copyable, Delayable, Drawable, Fetchable, Fullscreenable, Grantable, Listenable, Navigateable, Pickable, Recognizeable, Resolveable, Sanitizeable, Searchable, Shareable, Storeable, createAssociativeArray, createPredicateAncestor$1 as createAsyncDirectedAcyclicPredicateAncestor, createToCommonAncestors$1 as createAsyncDirectedAcyclicToCommonAncestors, createToLayers as createAsyncDirectedAcyclicToLayers, createToNodeSteps$1 as createAsyncDirectedAcyclicToNodeSteps, createToPath$1 as createAsyncDirectedAcyclicToPath, createToSteps$1 as createAsyncDirectedAcyclicToSteps, createToTree$1 as createAsyncDirectedAcyclicToTree, createClamp, createClip, createClone, createConcat, createPredicateAncestor as createDecisionTreePredicateAncestor, createToCommonAncestors as createDecisionTreeToCommonAncestors, createToNodeSteps as createDecisionTreeToNodeSteps, createToPath as createDecisionTreeToPath, createToSteps as createDecisionTreeToSteps, createToTree as createDecisionTreeToTree, createDetermine, createPredicateAncestor$2 as createDirectedAcyclicPredicateAncestor, createToCommonAncestors$2 as createDirectedAcyclicToCommonAncestors, createToLayers$1 as createDirectedAcyclicToLayers, createToNodeSteps$2 as createDirectedAcyclicToNodeSteps, createToPath$2 as createDirectedAcyclicToPath, createToRoots as createDirectedAcyclicToRoots, createToSteps$2 as createDirectedAcyclicToSteps, createToTree$2 as createDirectedAcyclicToTree, createEntries, createEqual, createEvery, createFilter, createFilterAsync, createFindAsync, createFindIndexAsync, createFocusable, createForEachAsync, createInsert, createKeychord, createKeypress, createKeyrelease, createKeys, createKonami, createList, createMap, createMapAsync, createMousepress, createMouserelease, createPredicateKeycomboMatch$1 as createPredicateKeycomboMatch, createPredicateRoot, createReduce, createReduceAsync, createRemove, createRename, createReorder, createReplace, createReverse, createSlice, createSlug, createSome, createSort, createSwap, createToGraph, createToIncoming, createToIndegree, createToOutdegree, createToOutgoing, createTouchpress, createTouchrelease, createFind as createTreeFind, createUnique, defineAssociativeArrayEntries, defineAsyncGraph, defineAsyncGraphEdge, defineAsyncGraphEdges, defineGraph, defineGraphEdge, defineGraphEdges, defineGraphNode, defineGraphNodes, easingsNetInBack, easingsNetInCirc, easingsNetInCubic, easingsNetInExpo, easingsNetInOutBack, easingsNetInOutCirc, easingsNetInOutCubic, easingsNetInOutExpo, easingsNetInOutQuad, easingsNetInOutQuint, easingsNetInOutSine, easingsNetInQuad, easingsNetInQuart, easingsNetInQuint, easingsNetInSine, easingsNetOutBack, easingsNetOutCirc, easingsNetOutCubic, easingsNetOutExpo, easingsNetOutQuad, easingsNetOutQuint, easingsNetOutSine, linear, materialAccelerated, materialDecelerated, materialStandard, toD, toFlattenedD, toMessageListenParams, verouEase, verouEaseIn, verouEaseInOut, verouEaseOut };