@baleada/logic 0.23.3 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/lib/index.cjs +2229 -1860
  2. package/lib/index.d.ts +934 -587
  3. package/lib/index.js +2158 -1828
  4. package/package.json +4 -3
package/lib/index.js CHANGED
@@ -1,24 +1,160 @@
1
1
  import BezierEasing from 'bezier-easing';
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';
4
- import { getStroke } from 'perfect-freehand';
5
- import polygonClipping from 'polygon-clipping';
6
- import ky from 'ky';
2
+ import { pipe, flatMap, unique, map, toArray, concat, filter, reduce, slice, sort, find, findIndex, at, some, includes, toLength, join, every, reverse as reverse$1, average } from 'lazy-collections';
3
+ import { sortKind, Searcher } from 'fast-fuzzy';
7
4
  import createDOMPurify from 'dompurify';
8
- import { Searcher } from 'fast-fuzzy';
5
+ import slugify from '@sindresorhus/slugify';
6
+ import arrayShuffle from 'array-shuffle';
9
7
  import { klona } from 'klona';
10
8
  import { dequal } from 'dequal';
11
- import slugify from '@sindresorhus/slugify';
9
+ import { merge } from 'dset/merge';
10
+ import { getStroke } from 'perfect-freehand';
11
+ import polygonClipping from 'polygon-clipping';
12
+ import ky from 'ky';
12
13
  import clsx from 'clsx';
13
14
 
14
- function createClone() {
15
- return (any) => {
16
- return klona(any);
15
+ function createClip(content) {
16
+ return (string) => {
17
+ return string.replace(content, "");
17
18
  };
18
19
  }
19
- function createEqual(compared) {
20
- return (any) => dequal(any, compared);
20
+ function createSlug(options) {
21
+ return (string) => {
22
+ return slugify(string, options);
23
+ };
24
+ }
25
+ function createSanitize(options) {
26
+ const dompurify = createDOMPurify();
27
+ dompurify.setConfig(options);
28
+ return (string) => {
29
+ return dompurify.sanitize(string);
30
+ };
31
+ }
32
+ function createSplit(options) {
33
+ const { separator = "", limit } = options;
34
+ return (string) => {
35
+ return string.split(separator, limit);
36
+ };
37
+ }
38
+ function createNumber(options = {}) {
39
+ const { radix = 10 } = options;
40
+ return (string) => parseInt(string, radix);
41
+ }
42
+ function createResults(candidates, options = {}) {
43
+ const narrowedOptions = predicateFunction(options) ? options(sortKind) : options, searcher = new Searcher(candidates, narrowedOptions);
44
+ return (query) => searcher.search(query);
45
+ }
46
+
47
+ function fromShorthandAliasToLonghandAlias(shorthand) {
48
+ if (capitalLetterRE.test(shorthand))
49
+ return `shift+${shorthand.toLowerCase()}`;
50
+ if (shorthand in keycombosBySpecialCharacter)
51
+ return keycombosBySpecialCharacter[shorthand];
52
+ return shorthand;
53
+ }
54
+ const capitalLetterRE = /^[A-Z]$/;
55
+ const keycombosBySpecialCharacter = {
56
+ "~": "shift+`",
57
+ _: "shift+-",
58
+ "+": "shift+=",
59
+ "{": "shift+[",
60
+ "}": "shift+]",
61
+ "|": "shift+\\",
62
+ ":": "shift+;",
63
+ '"': "shift+'",
64
+ "<": "shift+,",
65
+ ">": "shift+.",
66
+ "?": "shift+/",
67
+ "!": "shift+1",
68
+ "@": "shift+2",
69
+ "#": "shift+3",
70
+ $: "shift+4",
71
+ "%": "shift+5",
72
+ "^": "shift+6",
73
+ "&": "shift+7",
74
+ "*": "shift+8",
75
+ "(": "shift+9",
76
+ ")": "shift+0"
77
+ };
78
+
79
+ function createAliases(options = {}) {
80
+ const { toLonghand = fromShorthandAliasToLonghandAlias } = options;
81
+ return (combo) => {
82
+ const separator = "+", splitByPlus = createSplit({ separator });
83
+ return pipe(
84
+ splitByPlus,
85
+ flatMap(
86
+ (alias) => pipe(
87
+ toLonghand,
88
+ splitByPlus
89
+ )(alias)
90
+ ),
91
+ // If the separator is used as a character in the type,
92
+ // two empty strings will be produced by the split.
93
+ // unique() combines those two into one, and also removes
94
+ // duplicates in longhand transformations.
95
+ unique(),
96
+ map((name) => name === "" ? separator : name.toLowerCase()),
97
+ toArray()
98
+ )(combo);
99
+ };
100
+ }
101
+
102
+ function fromAliasToCode(alias) {
103
+ if (alias in partialCodesByAlias)
104
+ return partialCodesByAlias[alias];
105
+ if (alias in keyStatusKeysByAlias)
106
+ return keyStatusKeysByAlias[alias];
107
+ if (letterRE.test(alias))
108
+ return `Key${alias.toUpperCase()}`;
109
+ if (digitRE.test(alias))
110
+ return `Digit${alias}`;
111
+ if (functionRE.test(alias))
112
+ return alias.toUpperCase();
113
+ return "unsupported";
21
114
  }
115
+ const digitRE = /^[0-9]$/;
116
+ const letterRE = /^[a-zA-Z]$/;
117
+ const functionRE = /^[fF][0-9]{1,2}$/;
118
+ const keyStatusKeysByAlias = {
119
+ "`": "Backquote",
120
+ "-": "Minus",
121
+ "=": "Equal",
122
+ "": "BracketLeft",
123
+ "]": "BracketRight",
124
+ "\\": "Backslash",
125
+ ";": "Semicolon",
126
+ "'": "Quote",
127
+ ",": "Comma",
128
+ ".": "Period",
129
+ "/": "Slash",
130
+ up: "ArrowUp",
131
+ down: "ArrowDown",
132
+ left: "ArrowLeft",
133
+ right: "ArrowRight",
134
+ enter: "Enter",
135
+ space: "Space",
136
+ tab: "Tab",
137
+ esc: "Escape",
138
+ backspace: "Backspace",
139
+ delete: "Delete",
140
+ home: "Home",
141
+ end: "End",
142
+ pagedown: "PageDown",
143
+ pageup: "PageUp",
144
+ capslock: "CapsLock",
145
+ camera: "Camera"
146
+ };
147
+ const partialCodesByAlias = {
148
+ alt: "Alt",
149
+ opt: "Alt",
150
+ option: "Alt",
151
+ ctrl: "Control",
152
+ control: "Control",
153
+ meta: "Meta",
154
+ cmd: "Meta",
155
+ command: "Meta",
156
+ shift: "Shift"
157
+ };
22
158
 
23
159
  function createConcat(...arrays) {
24
160
  return (array) => pipe(
@@ -99,6 +235,8 @@ function createReverse() {
99
235
  };
100
236
  }
101
237
  function createSlice(from, to) {
238
+ if (from < 0 || to && to < 0)
239
+ return (array) => array.slice(from, to);
102
240
  const toSliced = to ? slice(from, to - 1) : slice(from);
103
241
  return (array) => {
104
242
  return from === to ? [] : pipe(
@@ -107,6 +245,11 @@ function createSlice(from, to) {
107
245
  )(array);
108
246
  };
109
247
  }
248
+ function createShuffle() {
249
+ return (array) => {
250
+ return arrayShuffle(array);
251
+ };
252
+ }
110
253
  function createSort(compare) {
111
254
  return (array) => {
112
255
  return pipe(
@@ -115,19 +258,19 @@ function createSort(compare) {
115
258
  )(array);
116
259
  };
117
260
  }
118
- function createSwap(indices) {
261
+ function createSwap(item1Index, item2Index) {
119
262
  return (array) => {
120
- const { 0: from, 1: to } = indices, { reorderFrom, reorderTo } = (() => {
121
- if (from < to) {
263
+ const { reorderFrom, reorderTo } = (() => {
264
+ if (item1Index < item2Index) {
122
265
  return {
123
- reorderFrom: createReorder(from, to),
124
- reorderTo: createReorder(to - 1, from)
266
+ reorderFrom: createReorder(item1Index, item2Index),
267
+ reorderTo: createReorder(item2Index - 1, item1Index)
125
268
  };
126
269
  }
127
- if (from > to) {
270
+ if (item1Index > item2Index) {
128
271
  return {
129
- reorderFrom: createReorder(from, to),
130
- reorderTo: createReorder(to + 1, from)
272
+ reorderFrom: createReorder(item1Index, item2Index),
273
+ reorderTo: createReorder(item2Index + 1, item1Index)
131
274
  };
132
275
  }
133
276
  return {
@@ -145,6 +288,55 @@ function createUnique() {
145
288
  )(array);
146
289
  }
147
290
 
291
+ function createClone() {
292
+ return (any) => {
293
+ return klona(any);
294
+ };
295
+ }
296
+ function createDeepEqual(compared) {
297
+ return (any) => dequal(any, compared);
298
+ }
299
+ function createEqual(compared) {
300
+ return (any) => any === compared;
301
+ }
302
+
303
+ function createValue$2(key, options = {}) {
304
+ const { predicateKey = createEqual(key) } = options;
305
+ return (associativeArray) => {
306
+ return find(
307
+ ([candidate]) => predicateKey(candidate)
308
+ )(associativeArray)?.[1];
309
+ };
310
+ }
311
+ function createHas$1(key, options = {}) {
312
+ const { predicateKey = createEqual(key) } = options;
313
+ return (associativeArray) => {
314
+ return findIndex(
315
+ ([candidate]) => predicateKey(candidate)
316
+ )(associativeArray) !== -1;
317
+ };
318
+ }
319
+ function createKeys$1() {
320
+ return (associativeArray) => {
321
+ return createMap(([key]) => key)(associativeArray);
322
+ };
323
+ }
324
+ function createValues$1() {
325
+ return (associativeArray) => {
326
+ return createMap(([, value]) => value)(associativeArray);
327
+ };
328
+ }
329
+
330
+ function createForEachAsync(effect) {
331
+ return async (array) => {
332
+ for (let i = 0; i < array.length; i++) {
333
+ const item = array[i];
334
+ await effect(item, i);
335
+ }
336
+ return array;
337
+ };
338
+ }
339
+
148
340
  function createFilterAsync(predicate) {
149
341
  return async (array) => {
150
342
  const transformedAsync = await createMapAsync(predicate)(array);
@@ -169,15 +361,6 @@ function createFindIndexAsync(predicate) {
169
361
  }
170
362
  };
171
363
  }
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
364
  function createMapAsync(transform) {
182
365
  return async (array) => {
183
366
  return await createReduceAsync(
@@ -202,689 +385,495 @@ function createReduceAsync(accumulate, initialValue) {
202
385
  };
203
386
  }
204
387
 
205
- function createClip(required) {
206
- return (string) => {
207
- return string.replace(required, "");
208
- };
388
+ function createList() {
389
+ return (...classValues) => clsx(...classValues);
209
390
  }
210
- function createSlug(options) {
211
- return (string) => {
212
- return slugify(string, options);
391
+
392
+ const defaultCreateMixOptions = {
393
+ method: "oklch",
394
+ tag: "div",
395
+ getParent: () => document.body
396
+ };
397
+ function createMix(color2, options = {}) {
398
+ const { method, tag, getParent } = { ...defaultCreateMixOptions, ...options };
399
+ return (color1) => {
400
+ const element = document.createElement(tag), parent = getParent();
401
+ element.style.color = `color-mix(in ${method}, ${color1}, ${color2})`;
402
+ parent.appendChild(element);
403
+ const mixed = getComputedStyle(element).color;
404
+ parent.removeChild(element);
405
+ return mixed;
213
406
  };
214
407
  }
215
408
 
216
- function createClamp(min, max) {
217
- return (number) => {
218
- const maxed = Math.max(number, min);
219
- return Math.min(maxed, max);
220
- };
409
+ function createDepthPathConfig(directedAcyclic) {
410
+ const predicateTerminal = createTerminal(directedAcyclic), predicatePathable = (node) => !predicateTerminal(node), toTraversalCandidates = (path) => pipe(
411
+ at(-1),
412
+ createOutgoing(directedAcyclic)
413
+ )(path);
414
+ return { predicatePathable, toTraversalCandidates };
221
415
  }
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;
416
+
417
+ function createBreadthPathConfig(directedAcyclic) {
418
+ const predicateOnlyChild = createOnlyChild(directedAcyclic), predicatePathable = (node) => !predicateOnlyChild(node), toTraversalCandidates = (path) => pipe(
419
+ at(-2),
420
+ createOutgoing(directedAcyclic)
421
+ )(path);
422
+ return { predicatePathable, toTraversalCandidates };
234
423
  }
235
424
 
236
- function createEntries() {
237
- return (object) => {
238
- const entries = [];
239
- for (const key in object) {
240
- entries.push([key, object[key]]);
425
+ class Recognizeable {
426
+ maxSequenceLength;
427
+ effects;
428
+ effectApi;
429
+ constructor(sequence, options = {}) {
430
+ const defaultOptions = {
431
+ maxSequenceLength: true,
432
+ effects: {}
433
+ };
434
+ this.maxSequenceLength = options?.maxSequenceLength || defaultOptions.maxSequenceLength;
435
+ this.effects = options?.effects || defaultOptions.effects;
436
+ this.resetComputedMetadata();
437
+ this.setSequence(sequence);
438
+ this.effectApi = {
439
+ getStatus: () => this.status,
440
+ getMetadata: () => this.metadata,
441
+ setMetadata: (metadata) => this.computedMetadata = metadata,
442
+ recognized: () => this.recognized(),
443
+ denied: () => this.denied(),
444
+ ready: () => this.ready()
445
+ };
446
+ this.ready();
447
+ }
448
+ computedMetadata;
449
+ resetComputedMetadata() {
450
+ this.computedMetadata = {};
451
+ }
452
+ recognized() {
453
+ this.computedStatus = "recognized";
454
+ }
455
+ denied() {
456
+ this.computedStatus = "denied";
457
+ }
458
+ computedStatus;
459
+ ready() {
460
+ this.computedStatus = "ready";
461
+ }
462
+ get sequence() {
463
+ return this.computedSequence;
464
+ }
465
+ set sequence(sequence) {
466
+ this.setSequence(sequence);
467
+ }
468
+ get status() {
469
+ return this.computedStatus;
470
+ }
471
+ get metadata() {
472
+ return this.computedMetadata;
473
+ }
474
+ computedSequence;
475
+ setSequence(sequence) {
476
+ this.computedSequence = sequence;
477
+ return this;
478
+ }
479
+ recognize(sequenceItem, options = {}) {
480
+ this.recognizing();
481
+ const type = this.toType(sequenceItem), pushSequence = (sequenceItem2) => {
482
+ newSequence.push(sequenceItem2);
483
+ if (this.maxSequenceLength !== true && newSequence.length > this.maxSequenceLength) {
484
+ newSequence.shift();
485
+ }
486
+ }, newSequence = [];
487
+ for (const sequenceItem2 of this.sequence) {
488
+ pushSequence(sequenceItem2);
241
489
  }
242
- return entries;
243
- };
244
- }
245
- function createKeys() {
246
- return (object) => {
247
- const keys = [];
248
- for (const key in object) {
249
- keys.push(key);
490
+ pushSequence(sequenceItem);
491
+ this.effectApi.getSequence = () => newSequence;
492
+ this.effectApi.pushSequence = pushSequence;
493
+ this.effectApi.listenInjection = {
494
+ effect: options.listenInjection?.effect || (() => {
495
+ }),
496
+ optionsByType: options.listenInjection?.optionsByType || {}
497
+ };
498
+ this.effects[type]?.(sequenceItem, { ...this.effectApi });
499
+ switch (this.status) {
500
+ case "ready":
501
+ case "denied":
502
+ this.resetComputedMetadata();
503
+ this.setSequence([]);
504
+ break;
505
+ case "recognizing":
506
+ case "recognized":
507
+ this.setSequence(newSequence);
508
+ break;
250
509
  }
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;
510
+ return this;
511
+ }
512
+ recognizing() {
513
+ this.computedStatus = "recognizing";
514
+ }
515
+ toType(sequenceItem) {
516
+ if (predicateArray(sequenceItem)) {
517
+ if (sequenceItem[0] instanceof IntersectionObserverEntry) {
518
+ return "intersect";
519
+ }
520
+ if (sequenceItem[0] instanceof MutationRecord) {
521
+ return "mutate";
522
+ }
523
+ if (sequenceItem[0] instanceof ResizeObserverEntry) {
524
+ return "resize";
259
525
  }
526
+ } else {
527
+ if (sequenceItem instanceof MediaQueryListEvent) {
528
+ return sequenceItem.media;
529
+ }
530
+ if ("didTimeout" in sequenceItem) {
531
+ return "idle";
532
+ }
533
+ return sequenceItem.type;
260
534
  }
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
- };
535
+ }
279
536
  }
280
537
 
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
- }
538
+ class Listenable {
539
+ computedRecognizeable;
540
+ recognizeableEffectsKeys;
541
+ computedActive;
542
+ constructor(type, options) {
543
+ if (type === "recognizeable") {
544
+ this.computedRecognizeable = new Recognizeable([], options?.recognizeable);
545
+ this.recognizeableEffectsKeys = Object.keys(options?.recognizeable?.effects);
546
+ }
547
+ this.computedActive = /* @__PURE__ */ new Set();
548
+ this.setType(type);
549
+ this.ready();
550
+ }
551
+ computedStatus;
552
+ ready() {
553
+ this.computedStatus = "ready";
554
+ }
555
+ get type() {
556
+ return this.computedType;
557
+ }
558
+ set type(type) {
559
+ this.setType(type);
560
+ }
561
+ get status() {
562
+ return this.computedStatus;
563
+ }
564
+ get active() {
565
+ return this.computedActive;
566
+ }
567
+ get recognizeable() {
568
+ return this.computedRecognizeable;
569
+ }
570
+ computedType;
571
+ implementation;
572
+ setType(type) {
573
+ this.stop();
574
+ this.computedType = type;
575
+ this.implementation = toImplementation(type);
576
+ return this;
577
+ }
578
+ listen(effect, options = {}) {
579
+ switch (this.implementation) {
580
+ case "intersection":
581
+ this.intersectionListen(effect, options);
313
582
  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
- }
583
+ case "mutation":
584
+ this.mutationListen(effect, options);
320
585
  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")
586
+ case "resize":
587
+ this.resizeListen(effect, options);
588
+ break;
589
+ case "mediaquery":
590
+ this.mediaQueryListen(effect, options);
591
+ break;
592
+ case "idle":
593
+ this.idleListen(effect, options);
594
+ break;
595
+ case "message":
596
+ this.messageListen(effect, options);
597
+ break;
598
+ case "recognizeable":
599
+ this.recognizeableListen(effect, options);
600
+ break;
601
+ case "documentevent":
602
+ this.documentEventListen(effect, options);
603
+ break;
604
+ case "event":
605
+ this.eventListen(effect, options);
524
606
  break;
525
607
  }
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)
608
+ this.listening();
609
+ return this;
610
+ }
611
+ intersectionListen(effect, options) {
612
+ const { target, observer } = { ...this.getDefaultListenOptions(), ...options }, id = new IntersectionObserver(effect, observer);
613
+ id.observe(target);
614
+ this.active.add({ target, id });
615
+ }
616
+ mutationListen(effect, options) {
617
+ const { target, observe } = { ...this.getDefaultListenOptions(), ...options }, id = new MutationObserver(effect);
618
+ id.observe(target, observe);
619
+ this.active.add({ target, id });
620
+ }
621
+ resizeListen(effect, options) {
622
+ const { target, observe } = { ...this.getDefaultListenOptions(), ...options }, id = new ResizeObserver(effect);
623
+ id.observe(target, observe);
624
+ this.active.add({ target, id });
625
+ }
626
+ mediaQueryListen(effect, options) {
627
+ const target = window.matchMedia(this.type), { instantEffect } = { ...this.getDefaultListenOptions(), ...options };
628
+ instantEffect(target);
629
+ const withApi = (event) => effect(event);
630
+ target.addEventListener("change", withApi);
631
+ this.active.add({ target, id: ["change", withApi] });
632
+ }
633
+ idleListen(effect, options) {
634
+ const { requestIdleCallback } = { ...this.getDefaultListenOptions(), ...options }, id = window.requestIdleCallback((deadline) => effect(deadline), requestIdleCallback);
635
+ this.active.add({ target: window, id });
636
+ }
637
+ messageListen(effect, options) {
638
+ const { target = new BroadcastChannel("baleada") } = options;
639
+ target.addEventListener(this.type, (event) => effect(event));
640
+ this.active.add({ target, id: [this.type, effect] });
641
+ }
642
+ recognizeableListen(effect, options) {
643
+ const guardedEffect = (sequenceItem) => {
644
+ this.recognizeable.recognize(
645
+ sequenceItem,
646
+ { listenInjection: { effect, optionsByType } }
647
+ );
648
+ if (this.recognizeable.status === "recognized")
649
+ effect(sequenceItem);
650
+ }, optionsByType = {};
651
+ for (const type of this.recognizeableEffectsKeys) {
652
+ optionsByType[type] = {
653
+ ...this.getDefaultListenOptions(toImplementation(type)),
654
+ ...options
619
655
  };
620
656
  }
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);
657
+ for (const type of this.recognizeableEffectsKeys) {
658
+ const listenable = new Listenable(type);
659
+ listenable.listen(guardedEffect, options);
660
+ this.active.add({ id: listenable });
666
661
  }
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
662
+ }
663
+ documentEventListen(effect, options) {
664
+ const narrowedOptions = {
665
+ ...this.getDefaultListenOptions(),
666
+ target: document
667
+ };
668
+ this.eventListen(effect, narrowedOptions);
669
+ }
670
+ eventListen(effect, options) {
671
+ const { exceptAndOnlyEffect, effectOptions } = toAddEventListenerParams(this.type, effect, options), eventListeners = [[this.type, exceptAndOnlyEffect, ...effectOptions]];
672
+ this.addEventListeners(eventListeners, options);
673
+ }
674
+ addEventListeners(eventListeners, options) {
675
+ const { target } = { ...this.getDefaultListenOptions(), ...options };
676
+ for (const eventListener of eventListeners) {
677
+ target.addEventListener(eventListener[0], eventListener[1], eventListener[2]);
678
+ this.active.add({ target, id: eventListener });
681
679
  }
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
680
+ }
681
+ listening() {
682
+ this.computedStatus = "listening";
683
+ }
684
+ stop(options = {}) {
685
+ const { target } = options;
686
+ switch (this.status) {
687
+ case "ready":
688
+ case void 0:
689
+ break;
690
+ default:
691
+ const stoppables = [...this.active].filter((active) => !target || ("target" in active ? active.target === target : false)), shouldUpdateStatus = stoppables.length === this.active.size;
692
+ for (const stoppable of stoppables) {
693
+ stop(stoppable);
694
+ this.active.delete(stoppable);
695
+ }
696
+ if (shouldUpdateStatus) {
697
+ this.stopped();
698
+ }
699
+ break;
700
700
  }
701
- };
702
- return createToNodeSteps$2(
703
- decisionTree,
704
- {
705
- ...withDefaults,
706
- createToSteps: toCreateDirectedAcyclicToStepsOptions(withDefaults.createToSteps)
701
+ return this;
702
+ }
703
+ stopped() {
704
+ this.computedStatus = "stopped";
705
+ }
706
+ getDefaultListenOptions(implementation) {
707
+ switch (implementation || this.implementation) {
708
+ case "intersection":
709
+ return {
710
+ target: document.querySelector("html"),
711
+ observer: {}
712
+ };
713
+ case "mutation":
714
+ return {
715
+ target: document.querySelector("html"),
716
+ observe: {}
717
+ };
718
+ case "resize":
719
+ return {
720
+ target: document.querySelector("html"),
721
+ observe: {}
722
+ };
723
+ case "mediaquery":
724
+ return {
725
+ instantEffect: () => {
726
+ }
727
+ };
728
+ case "idle":
729
+ return {
730
+ requestIdleCallback: {}
731
+ };
732
+ case "message":
733
+ return {
734
+ target: new BroadcastChannel("baleada")
735
+ };
736
+ case "recognizeable":
737
+ return {};
738
+ case "documentevent":
739
+ return {};
740
+ case "event":
741
+ return { target: document };
707
742
  }
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);
743
+ }
721
744
  }
722
- function toCreateDirectedAcyclicToStepsOptions(options) {
723
- return {
724
- ...defaultCreateToStepsOptions,
725
- ...options,
726
- ...{
727
- toUnsetMetadata: () => false,
728
- toMockMetadata: (node, totalConnectionsFollowed) => options.priorityBranch ? !totalConnectionsFollowed : !!totalConnectionsFollowed
729
- }
730
- };
745
+ function stop(stoppable) {
746
+ if (stoppable.id instanceof Listenable) {
747
+ stoppable.id.stop();
748
+ return;
749
+ }
750
+ if (some((type) => observerAssertionsByType[type](stoppable.id))(["intersect", "mutate", "resize"])) {
751
+ const { id: id2 } = stoppable;
752
+ id2.disconnect();
753
+ return;
754
+ }
755
+ if ("target" in stoppable && stoppable.target instanceof MediaQueryList) {
756
+ const { target: target2, id: id2 } = stoppable;
757
+ target2.removeEventListener(id2[0], id2[1]);
758
+ return;
759
+ }
760
+ if (predicateNumber(stoppable.id)) {
761
+ const { target: target2, id: id2 } = stoppable;
762
+ target2.cancelIdleCallback(id2);
763
+ return;
764
+ }
765
+ if ("target" in stoppable && stoppable.target instanceof BroadcastChannel) {
766
+ const { target: target2, id: id2 } = stoppable;
767
+ target2.removeEventListener(id2[0], id2[1]);
768
+ return;
769
+ }
770
+ const { target, id } = stoppable;
771
+ target.removeEventListener(id[0], id[1], id[2]);
731
772
  }
732
-
733
- function createList() {
734
- return (...classValues) => clsx(...classValues);
773
+ function toImplementation(type) {
774
+ return find((implementation) => predicatesByImplementation.get(implementation)(type))(predicatesByImplementation.keys());
735
775
  }
736
-
737
- const defaultOptions$l = {
738
- toId: (node) => node.id,
739
- toChildren: (node) => node.children
776
+ const predicatesByImplementation = /* @__PURE__ */ new Map([
777
+ [
778
+ "recognizeable",
779
+ (type) => type === "recognizeable"
780
+ ],
781
+ [
782
+ "intersection",
783
+ (type) => type === "intersect"
784
+ ],
785
+ [
786
+ "mutation",
787
+ (type) => type === "mutate"
788
+ ],
789
+ [
790
+ "resize",
791
+ (type) => type === "resize"
792
+ ],
793
+ [
794
+ "mediaquery",
795
+ (type) => implementationREs.mediaquery.test(type)
796
+ ],
797
+ [
798
+ "idle",
799
+ (type) => type === "idle"
800
+ ],
801
+ [
802
+ "message",
803
+ (type) => type === "message" || type === "messageerror"
804
+ ],
805
+ [
806
+ "documentevent",
807
+ (type) => documentEvents.has(type)
808
+ ],
809
+ [
810
+ "event",
811
+ () => true
812
+ ]
813
+ ]);
814
+ const documentEvents = /* @__PURE__ */ new Set([
815
+ "fullscreenchange",
816
+ "fullscreenerror",
817
+ "pointerlockchange",
818
+ "pointerlockerror",
819
+ "readystatechange",
820
+ "visibilitychange"
821
+ ]);
822
+ const implementationREs = {
823
+ mediaquery: /^\(.+\)$/
740
824
  };
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
- };
825
+ function toAddEventListenerParams(type, effect, options) {
826
+ const { addEventListener, useCapture } = options, exceptAndOnlyEffect = createExceptAndOnlyEffect(type, effect, options), effectOptions = [addEventListener || useCapture];
827
+ return { exceptAndOnlyEffect, effectOptions };
759
828
  }
760
-
761
- const defaultOptions$k = {
762
- toKey: (alias) => fromAliasToKeyStatusKey(alias),
763
- toAliases: (event) => fromEventToAliases(event)
764
- };
765
- const createPredicateKeycomboMatch$1 = (keycombo, options = {}) => {
766
- const { toKey, toAliases } = { ...defaultOptions$k, ...options }, aliases = fromComboToAliases(keycombo), keys = map(toKey)(aliases);
767
- return (event) => {
768
- const { toValue, set, toEntries } = createKeyStatuses();
769
- set(fromEventToKeyStatusKey(event), "down");
770
- for (const modifier of modifiers) {
771
- if (event[`${modifier.toLowerCase()}Key`])
772
- set({ key: modifier }, "down");
773
- }
774
- return every(pipe(
775
- toValue,
776
- predicateDown
777
- ))(keys) && every(
778
- ([key]) => some(
779
- (alias) => includes(alias)(aliases)
780
- )(toAliases(key))
781
- )(toEntries());
782
- };
783
- };
784
-
785
- const defaultOptions$j = {
786
- initial: [],
787
- createPredicateKey: (query) => (candidate) => query === candidate
829
+ const observerAssertionsByType = {
830
+ intersect: (observer) => observer instanceof IntersectionObserver,
831
+ mutate: (observer) => observer instanceof MutationObserver,
832
+ resize: (observer) => observer instanceof ResizeObserver
788
833
  };
789
- function createAssociativeArray(options = {}) {
790
- const { initial, createPredicateKey } = { ...defaultOptions$j, ...options }, entries = [...initial];
791
- const toValue = (key) => {
792
- const predicateKey = createPredicateKey(key);
793
- return find(
794
- ([candidate]) => predicateKey(candidate)
795
- )(entries)?.[1];
796
- };
797
- const set = (key, value) => {
798
- const predicateKey = createPredicateKey(key), index = findIndex(
799
- ([candidate]) => predicateKey(candidate)
800
- )(entries);
801
- if (index === -1) {
802
- entries.push([key, value]);
803
- return;
804
- }
805
- entries[index][1] = value;
806
- };
807
- const predicateHas = (key) => {
808
- const predicateKey = createPredicateKey(key);
809
- return findIndex(
810
- ([candidate]) => predicateKey(candidate)
811
- )(entries) !== -1;
812
- };
813
- const clear = () => {
814
- entries.length = 0;
815
- };
816
- const del = (key) => {
817
- const predicateKey = createPredicateKey(key), index = findIndex(
818
- ([candidate]) => predicateKey(candidate)
819
- )(entries);
820
- if (index === -1) {
821
- return false;
822
- }
823
- entries.splice(index, 1);
824
- return true;
825
- };
826
- const toKeys = () => {
827
- return createMap(([key]) => key)(entries);
828
- };
829
- const toValues = () => {
830
- return createMap(([, value]) => value)(entries);
831
- };
832
- const toEntries = () => {
833
- return entries;
834
- };
835
- return {
836
- toValue,
837
- set,
838
- predicateHas,
839
- clear,
840
- delete: del,
841
- toKeys,
842
- toValues,
843
- toEntries
844
- // get: toValue,
845
- // has: predicateHas,
846
- // keys: toKeys,
847
- // values: toValues,
848
- };
849
- }
850
834
 
851
- const defaultOptions$i = {
835
+ const defaultOptions$k = {
852
836
  minDuration: 0,
853
837
  preventsDefaultUnlessDenied: true,
854
- toKey: (alias) => fromAliasToKeyStatusKey(alias),
855
- toAliases: (event) => fromEventToAliases(event)
838
+ toCode: (alias) => fromAliasToCode(alias),
839
+ toAliases: (code) => fromCodeToAliases(code)
856
840
  };
857
841
  function createKeypress(keycomboOrKeycombos, options = {}) {
858
842
  const {
859
843
  minDuration,
860
844
  preventsDefaultUnlessDenied,
861
- toKey,
845
+ toLonghand,
846
+ toCode,
862
847
  toAliases,
863
848
  onDown,
864
849
  onUp,
865
850
  onVisibilitychange
866
- } = { ...defaultOptions$i, ...options }, {
851
+ } = { ...defaultOptions$k, ...options }, {
867
852
  matchPredicatesByKeycombo,
868
853
  getDownCombos,
869
854
  predicateValid,
870
855
  cleanup,
871
- statuses
856
+ statuses,
857
+ toStatus,
858
+ setStatus,
859
+ clearStatuses,
860
+ deleteStatus
872
861
  } = createKeyState({
873
862
  keycomboOrKeycombos,
874
- unsupportedAliases: unsupportedAliases$2,
875
- toKey,
863
+ toLonghand,
864
+ toCode,
876
865
  toAliases,
877
866
  getRequest: () => request
878
- });
867
+ }), fromComboToAliasesLength = createAliasesLength({ toLonghand });
879
868
  let request;
880
869
  let localStatus;
881
870
  const keydown = (event, api) => {
882
- const { denied, getStatus } = api, key = fromEventToKeyStatusKey(event);
883
- if (statuses.toValue(key) === "down") {
871
+ const { denied, getStatus } = api, key = fromEventToKeyStatusCode(event);
872
+ if (toStatus(key) === "down") {
884
873
  onDown?.(toHookApi(api));
885
874
  return;
886
875
  }
887
- statuses.set(key, "down");
876
+ setStatus(key, "down");
888
877
  if (localStatus === "denied") {
889
878
  denied();
890
879
  onDown?.(toHookApi(api));
@@ -897,15 +886,15 @@ function createKeypress(keycomboOrKeycombos, options = {}) {
897
886
  ) {
898
887
  denied();
899
888
  localStatus = getStatus();
900
- if (includes(event.key)(unsupportedKeys$2))
901
- statuses.clear();
889
+ if (includes(event.key)(unsupportedKeys))
890
+ clearStatuses();
902
891
  onDown?.(toHookApi(api));
903
892
  return;
904
893
  }
905
894
  if (preventsDefaultUnlessDenied)
906
895
  event.preventDefault();
907
896
  const { getMetadata } = api, metadata = getMetadata();
908
- metadata.pressed = downCombos[0];
897
+ metadata.keycombo = downCombos[0];
909
898
  localStatus = "recognizing";
910
899
  cleanup();
911
900
  storeKeyboardTimeMetadata({
@@ -914,6 +903,7 @@ function createKeypress(keycomboOrKeycombos, options = {}) {
914
903
  getTimeMetadata: getMetadata,
915
904
  getShouldStore: () => downCombos.length && getDownCombos()[0] === downCombos[0],
916
905
  setRequest: (newRequest) => request = newRequest,
906
+ // @ts-expect-error
917
907
  recognize
918
908
  });
919
909
  onDown?.(toHookApi(api));
@@ -927,23 +917,23 @@ function createKeypress(keycomboOrKeycombos, options = {}) {
927
917
  }
928
918
  };
929
919
  const keyup = (event, api) => {
930
- const { denied } = api, key = fromEventToKeyStatusKey(event);
920
+ const { denied } = api, key = fromEventToKeyStatusCode(event);
931
921
  if (localStatus === "denied") {
932
922
  denied();
933
- if (includes(event.key)(unsupportedKeys$2))
934
- statuses.clear();
923
+ if (includes(event.key)(unsupportedKeys))
924
+ clearStatuses();
935
925
  else
936
- statuses.delete(key);
926
+ deleteStatus(key);
937
927
  if (!predicateSomeKeyDown(statuses))
938
928
  localStatus = "recognizing";
939
929
  onUp?.(toHookApi(api));
940
930
  return;
941
931
  }
942
- statuses.delete(key);
932
+ deleteStatus(key);
943
933
  const downCombos = getDownCombos(), matches = matchPredicatesByKeycombo[downCombos[0]]?.(statuses);
944
934
  if (downCombos.length && matches) {
945
935
  const { getMetadata } = api, metadata = getMetadata();
946
- metadata.pressed = downCombos[0];
936
+ metadata.keycombo = downCombos[0];
947
937
  if (preventsDefaultUnlessDenied)
948
938
  event.preventDefault();
949
939
  localStatus = "recognizing";
@@ -956,7 +946,7 @@ function createKeypress(keycomboOrKeycombos, options = {}) {
956
946
  };
957
947
  const visibilitychange = (event, api) => {
958
948
  if (document.visibilityState === "hidden") {
959
- statuses.clear();
949
+ clearStatuses();
960
950
  localStatus = "recognizing";
961
951
  cleanup();
962
952
  }
@@ -968,45 +958,63 @@ function createKeypress(keycomboOrKeycombos, options = {}) {
968
958
  visibilitychange
969
959
  };
970
960
  }
971
- const unsupportedAliases$2 = ["meta", "command", "cmd"];
972
- const unsupportedKeys$2 = ["Meta"];
961
+ class Keypress extends Listenable {
962
+ constructor(keycomboOrKeycombos, options) {
963
+ super(
964
+ "recognizeable",
965
+ {
966
+ recognizeable: {
967
+ effects: createKeypress(keycomboOrKeycombos, options)
968
+ }
969
+ }
970
+ );
971
+ }
972
+ get metadata() {
973
+ return this.recognizeable.metadata;
974
+ }
975
+ }
973
976
 
974
- const defaultOptions$h = {
977
+ const defaultOptions$j = {
975
978
  minDuration: 0,
976
979
  preventsDefaultUnlessDenied: true,
977
- toKey: (alias) => fromAliasToKeyStatusKey(alias),
978
- toAliases: (event) => fromEventToAliases(event)
980
+ toCode: (alias) => fromAliasToCode(alias),
981
+ toAliases: (code) => fromCodeToAliases(code)
979
982
  };
980
983
  function createKeyrelease(keycomboOrKeycombos, options = {}) {
981
984
  const {
982
985
  minDuration,
983
986
  preventsDefaultUnlessDenied,
984
- toKey,
987
+ toLonghand,
988
+ toCode,
985
989
  toAliases,
986
990
  onDown,
987
991
  onUp,
988
992
  onVisibilitychange
989
- } = { ...defaultOptions$h, ...options }, {
993
+ } = { ...defaultOptions$j, ...options }, {
990
994
  matchPredicatesByKeycombo,
991
995
  getDownCombos,
992
996
  predicateValid,
993
997
  cleanup,
994
- statuses
998
+ statuses,
999
+ toStatus,
1000
+ setStatus,
1001
+ clearStatuses,
1002
+ deleteStatus
995
1003
  } = createKeyState({
996
1004
  keycomboOrKeycombos,
997
- unsupportedAliases: unsupportedAliases$1,
998
- toKey,
1005
+ toLonghand,
1006
+ toCode,
999
1007
  toAliases,
1000
1008
  getRequest: () => request
1001
- });
1009
+ }), fromComboToAliasesLength = createAliasesLength({ toLonghand });
1002
1010
  let request, localStatus;
1003
1011
  const keydown = (event, api) => {
1004
- const { denied, getStatus } = api, key = fromEventToKeyStatusKey(event);
1005
- if (statuses.toValue(key) === "down") {
1012
+ const { denied, getStatus } = api, key = fromEventToKeyStatusCode(event);
1013
+ if (toStatus(key) === "down") {
1006
1014
  onDown?.(toHookApi(api));
1007
1015
  return;
1008
1016
  }
1009
- statuses.set(key, "down");
1017
+ setStatus(key, "down");
1010
1018
  if (localStatus === "denied") {
1011
1019
  denied();
1012
1020
  onDown?.(toHookApi(api));
@@ -1019,8 +1027,8 @@ function createKeyrelease(keycomboOrKeycombos, options = {}) {
1019
1027
  ) {
1020
1028
  denied();
1021
1029
  localStatus = getStatus();
1022
- if (includes(event.key)(unsupportedKeys$1))
1023
- statuses.clear();
1030
+ if (includes(event.key)(unsupportedKeys))
1031
+ clearStatuses();
1024
1032
  onDown?.(toHookApi(api));
1025
1033
  return;
1026
1034
  }
@@ -1043,21 +1051,21 @@ function createKeyrelease(keycomboOrKeycombos, options = {}) {
1043
1051
  getStatus,
1044
1052
  getMetadata,
1045
1053
  denied
1046
- } = api, metadata = getMetadata(), key = fromEventToKeyStatusKey(event);
1054
+ } = api, metadata = getMetadata(), key = fromEventToKeyStatusCode(event);
1047
1055
  if (["denied", "recognized"].includes(localStatus)) {
1048
1056
  if (localStatus === "denied")
1049
1057
  denied();
1050
- if (includes(event.key)(unsupportedKeys$1))
1051
- statuses.clear();
1058
+ if (includes(event.key)(unsupportedKeys))
1059
+ clearStatuses();
1052
1060
  else
1053
- statuses.delete(key);
1061
+ deleteStatus(key);
1054
1062
  if (!predicateSomeKeyDown(statuses))
1055
1063
  localStatus = "recognizing";
1056
1064
  onUp?.(toHookApi(api));
1057
1065
  return;
1058
1066
  }
1059
1067
  const downCombos = getDownCombos(), matches = matchPredicatesByKeycombo[downCombos[0]]?.(statuses);
1060
- statuses.delete(key);
1068
+ deleteStatus(key);
1061
1069
  if (!downCombos.length || !matches) {
1062
1070
  onUp?.(toHookApi(api));
1063
1071
  return;
@@ -1066,7 +1074,7 @@ function createKeyrelease(keycomboOrKeycombos, options = {}) {
1066
1074
  const status = getStatus();
1067
1075
  if (status === "recognized") {
1068
1076
  localStatus = status;
1069
- metadata.released = downCombos[0];
1077
+ metadata.keycombo = downCombos[0];
1070
1078
  }
1071
1079
  if (preventsDefaultUnlessDenied)
1072
1080
  event.preventDefault();
@@ -1082,7 +1090,7 @@ function createKeyrelease(keycomboOrKeycombos, options = {}) {
1082
1090
  };
1083
1091
  const visibilitychange = (event, api) => {
1084
1092
  if (document.visibilityState === "hidden") {
1085
- statuses.clear();
1093
+ clearStatuses();
1086
1094
  localStatus = "recognizing";
1087
1095
  cleanup();
1088
1096
  }
@@ -1094,50 +1102,64 @@ function createKeyrelease(keycomboOrKeycombos, options = {}) {
1094
1102
  visibilitychange
1095
1103
  };
1096
1104
  }
1097
- const unsupportedAliases$1 = ["meta", "command", "cmd"];
1098
- const unsupportedKeys$1 = ["Meta"];
1105
+ class Keyrelease extends Listenable {
1106
+ constructor(keycomboOrKeycombos, options) {
1107
+ super(
1108
+ "recognizeable",
1109
+ {
1110
+ recognizeable: {
1111
+ effects: createKeyrelease(keycomboOrKeycombos, options)
1112
+ }
1113
+ }
1114
+ );
1115
+ }
1116
+ get metadata() {
1117
+ return this.recognizeable.metadata;
1118
+ }
1119
+ }
1099
1120
 
1100
- const defaultOptions$g = {
1121
+ const defaultOptions$i = {
1101
1122
  minDuration: 0,
1102
1123
  maxInterval: 5e3,
1103
1124
  // VS Code default
1104
1125
  preventsDefaultUnlessDenied: true,
1105
- toKey: (alias) => fromAliasToKeyStatusKey(alias),
1106
- toAliases: (event) => fromEventToAliases(event)
1126
+ toCode: (alias) => fromAliasToCode(alias),
1127
+ toAliases: (code) => fromCodeToAliases(code)
1107
1128
  };
1108
- function createKeychord(keychord, options = {}) {
1129
+ function createKeychord(keycombos, options = {}) {
1109
1130
  const {
1110
1131
  minDuration,
1111
1132
  maxInterval,
1112
1133
  preventsDefaultUnlessDenied,
1113
- toKey,
1134
+ toLonghand,
1135
+ toCode,
1114
1136
  toAliases,
1115
1137
  onDown,
1116
1138
  onUp,
1117
1139
  onVisibilitychange
1118
- } = { ...defaultOptions$g, ...options }, narrowedKeychord = keychord.split(" "), keyStates = createMap((keycombo) => createKeyState({
1140
+ } = { ...defaultOptions$i, ...options }, narrowedKeycombos = keycombos.split(" "), keyStates = createMap((keycombo) => createKeyState({
1119
1141
  keycomboOrKeycombos: keycombo,
1120
- unsupportedAliases,
1121
- toKey,
1142
+ toLonghand,
1143
+ toCode,
1122
1144
  toAliases,
1123
1145
  getRequest: () => request
1124
- }))(narrowedKeychord), localStatuses = createMap(
1146
+ }))(narrowedKeycombos), localStatuses = createMap(
1125
1147
  () => "recognizing"
1126
- )(keyStates);
1148
+ )(keyStates), fromComboToAliasesLength = createAliasesLength({ toLonghand });
1127
1149
  let request, playedIndex = 0;
1128
1150
  const keydown = (event, api) => {
1129
- const { denied, getStatus } = api, key = fromEventToKeyStatusKey(event);
1130
- if (keyStates[playedIndex].statuses.toValue(key) === "down") {
1151
+ const { denied, getStatus } = api, key = fromEventToKeyStatusCode(event);
1152
+ if (keyStates[playedIndex].toStatus(key) === "down") {
1131
1153
  onDown?.(toHookApi(api));
1132
1154
  return;
1133
1155
  }
1134
1156
  if (localStatuses[playedIndex] === "recognized") {
1135
1157
  playedIndex++;
1136
- for (const [key2, status] of keyStates[playedIndex - 1].statuses.toEntries()) {
1137
- keyStates[playedIndex].statuses.set(key2, status);
1158
+ for (const [key2, status] of keyStates[playedIndex - 1].statuses) {
1159
+ keyStates[playedIndex].setStatus(key2, status);
1138
1160
  }
1139
1161
  }
1140
- keyStates[playedIndex].statuses.set(key, "down");
1162
+ keyStates[playedIndex].setStatus(key, "down");
1141
1163
  if (localStatuses[playedIndex] === "denied") {
1142
1164
  denied();
1143
1165
  onDown?.(toHookApi(api));
@@ -1153,8 +1175,8 @@ function createKeychord(keychord, options = {}) {
1153
1175
  denied();
1154
1176
  localStatuses[playedIndex] = getStatus();
1155
1177
  if (includes(event.key)(unsupportedKeys)) {
1156
- for (const { statuses } of keyStates)
1157
- statuses.clear();
1178
+ for (const { clearStatuses } of keyStates)
1179
+ clearStatuses();
1158
1180
  }
1159
1181
  onDown?.(toHookApi(api));
1160
1182
  return;
@@ -1180,30 +1202,30 @@ function createKeychord(keychord, options = {}) {
1180
1202
  getStatus,
1181
1203
  getMetadata,
1182
1204
  denied
1183
- } = api, metadata = getMetadata(), key = fromEventToKeyStatusKey(event);
1205
+ } = api, metadata = getMetadata(), key = fromEventToKeyStatusCode(event);
1184
1206
  if (["denied", "recognized"].includes(localStatuses[playedIndex])) {
1185
1207
  if (localStatuses[playedIndex] === "denied")
1186
1208
  denied();
1187
- for (const { statuses } of keyStates) {
1209
+ for (const { clearStatuses, deleteStatus } of keyStates) {
1188
1210
  if (includes(event.key)(unsupportedKeys))
1189
- statuses.clear();
1211
+ clearStatuses();
1190
1212
  else
1191
- statuses.delete(key);
1213
+ deleteStatus(key);
1192
1214
  }
1193
1215
  if (!predicateSomeKeyDown(keyStates[playedIndex].statuses)) {
1194
- if (localStatuses[playedIndex] === "denied" || playedIndex === narrowedKeychord.length - 1 && localStatuses[playedIndex] === "recognized") {
1216
+ if (localStatuses[playedIndex] === "denied" || playedIndex === narrowedKeycombos.length - 1 && localStatuses[playedIndex] === "recognized") {
1195
1217
  playedIndex = 0;
1196
1218
  for (let i = 0; i < localStatuses.length; i++)
1197
1219
  localStatuses[i] = "recognizing";
1198
- for (const { statuses } of keyStates)
1199
- statuses.clear();
1220
+ for (const { clearStatuses } of keyStates)
1221
+ clearStatuses();
1200
1222
  }
1201
1223
  }
1202
1224
  onUp?.(toHookApi(api));
1203
1225
  return;
1204
1226
  }
1205
1227
  const downCombos = keyStates[playedIndex].getDownCombos(), matches = keyStates[playedIndex].matchPredicatesByKeycombo[downCombos[0]]?.(keyStates[playedIndex].statuses);
1206
- keyStates[playedIndex].statuses.delete(key);
1228
+ keyStates[playedIndex].deleteStatus(key);
1207
1229
  if (!downCombos.length || !matches) {
1208
1230
  onUp?.(toHookApi(api));
1209
1231
  return;
@@ -1213,17 +1235,17 @@ function createKeychord(keychord, options = {}) {
1213
1235
  if (status === "recognizing" && localStatuses[playedIndex] === "recognized" || status === "recognized") {
1214
1236
  metadata.played[playedIndex] = {
1215
1237
  ...metadata.played[playedIndex],
1216
- released: downCombos[0]
1238
+ keycombo: downCombos[0]
1217
1239
  };
1218
1240
  }
1219
1241
  if (preventsDefaultUnlessDenied)
1220
1242
  event.preventDefault();
1221
- if (playedIndex === narrowedKeychord.length - 1 && !predicateSomeKeyDown(keyStates[playedIndex].statuses)) {
1243
+ if (playedIndex === narrowedKeycombos.length - 1 && !predicateSomeKeyDown(keyStates[playedIndex].statuses)) {
1222
1244
  playedIndex = 0;
1223
1245
  for (let i = 0; i < localStatuses.length; i++)
1224
1246
  localStatuses[i] = "recognizing";
1225
- for (const { statuses } of keyStates)
1226
- statuses.clear();
1247
+ for (const { clearStatuses } of keyStates)
1248
+ clearStatuses();
1227
1249
  }
1228
1250
  onUp?.(toHookApi(api));
1229
1251
  };
@@ -1233,7 +1255,7 @@ function createKeychord(keychord, options = {}) {
1233
1255
  denied();
1234
1256
  return;
1235
1257
  }
1236
- if (playedIndex === narrowedKeychord.length - 1) {
1258
+ if (playedIndex === narrowedKeycombos.length - 1) {
1237
1259
  recognized();
1238
1260
  localStatuses[playedIndex] = "recognized";
1239
1261
  return;
@@ -1242,8 +1264,8 @@ function createKeychord(keychord, options = {}) {
1242
1264
  };
1243
1265
  const visibilitychange = (event, api) => {
1244
1266
  if (document.visibilityState === "hidden") {
1245
- for (const { statuses } of keyStates)
1246
- statuses.clear();
1267
+ for (const { clearStatuses } of keyStates)
1268
+ clearStatuses();
1247
1269
  localStatuses[playedIndex] = "recognizing";
1248
1270
  keyStates[playedIndex].cleanup();
1249
1271
  playedIndex = 0;
@@ -1256,30 +1278,56 @@ function createKeychord(keychord, options = {}) {
1256
1278
  visibilitychange
1257
1279
  };
1258
1280
  }
1259
- const unsupportedAliases = ["meta", "command", "cmd"];
1260
- const unsupportedKeys = ["Meta"];
1281
+ class Keychord extends Listenable {
1282
+ constructor(keycombos, options) {
1283
+ super(
1284
+ "recognizeable",
1285
+ {
1286
+ recognizeable: {
1287
+ effects: createKeychord(keycombos, options)
1288
+ }
1289
+ }
1290
+ );
1291
+ }
1292
+ get metadata() {
1293
+ return this.recognizeable.metadata;
1294
+ }
1295
+ }
1261
1296
 
1262
1297
  function createKonami(options = {}) {
1263
1298
  return createKeychord("up up down down left right left right b a enter", options);
1264
1299
  }
1300
+ class Konami extends Listenable {
1301
+ constructor(options) {
1302
+ super(
1303
+ "recognizeable",
1304
+ {
1305
+ recognizeable: {
1306
+ effects: createKonami(options)
1307
+ }
1308
+ }
1309
+ );
1310
+ }
1311
+ get metadata() {
1312
+ return this.recognizeable.metadata;
1313
+ }
1314
+ }
1265
1315
 
1266
- const defaultOptions$f = {
1316
+ const defaultOptions$h = {
1267
1317
  minDuration: 0,
1268
- minDistance: 0,
1269
- getMousemoveTarget: (event) => event.target
1318
+ minDistance: 0
1270
1319
  };
1271
1320
  function createMousepress(options = {}) {
1272
1321
  const {
1273
1322
  minDuration,
1274
1323
  minDistance,
1275
- getMousemoveTarget,
1276
1324
  onDown,
1277
1325
  onLeave,
1278
1326
  onMove,
1279
1327
  onUp
1280
- } = { ...defaultOptions$f, ...options }, cleanup = (event) => {
1328
+ } = { ...defaultOptions$h, ...options }, cleanup = (target) => {
1281
1329
  window.cancelAnimationFrame(request);
1282
- getMousemoveTarget(event).removeEventListener("mousemove", mousemoveEffect);
1330
+ target.removeEventListener("mousemove", mousemoveEffect);
1283
1331
  };
1284
1332
  let request;
1285
1333
  let mousemoveEffect;
@@ -1294,9 +1342,11 @@ function createMousepress(options = {}) {
1294
1342
  api,
1295
1343
  () => mouseStatus === "down",
1296
1344
  (newRequest) => request = newRequest,
1345
+ // @ts-expect-error
1297
1346
  recognize
1298
1347
  );
1299
- getMousemoveTarget(event).addEventListener("mousemove", mousemoveEffect);
1348
+ const { listenInjection: { optionsByType: { mousedown: { target } } } } = api;
1349
+ target.addEventListener("mousemove", mousemoveEffect);
1300
1350
  onDown?.(toHookApi(api));
1301
1351
  };
1302
1352
  const mousemove = (event, api) => {
@@ -1313,20 +1363,20 @@ function createMousepress(options = {}) {
1313
1363
  }
1314
1364
  };
1315
1365
  const mouseleave = (event, api) => {
1316
- const { denied } = api;
1366
+ const { denied, listenInjection: { optionsByType: { mouseleave: { target } } } } = api;
1317
1367
  if (mouseStatus === "down") {
1318
1368
  denied();
1319
- cleanup(event);
1369
+ cleanup(target);
1320
1370
  mouseStatus = "leave";
1321
1371
  }
1322
1372
  onLeave?.(toHookApi(api));
1323
1373
  };
1324
1374
  const mouseup = (event, api) => {
1325
- const { denied } = api;
1375
+ const { denied, listenInjection: { optionsByType: { mouseup: { target } } } } = api;
1326
1376
  if (mouseStatus !== "down")
1327
1377
  return;
1328
1378
  denied();
1329
- cleanup(event);
1379
+ cleanup(target);
1330
1380
  mouseStatus = "up";
1331
1381
  onUp?.(toHookApi(api));
1332
1382
  };
@@ -1336,26 +1386,39 @@ function createMousepress(options = {}) {
1336
1386
  mouseup
1337
1387
  };
1338
1388
  }
1389
+ class Mousepress extends Listenable {
1390
+ constructor(options) {
1391
+ super(
1392
+ "recognizeable",
1393
+ {
1394
+ recognizeable: {
1395
+ effects: createMousepress(options)
1396
+ }
1397
+ }
1398
+ );
1399
+ }
1400
+ get metadata() {
1401
+ return this.recognizeable.metadata;
1402
+ }
1403
+ }
1339
1404
 
1340
- const defaultOptions$e = {
1405
+ const defaultOptions$g = {
1341
1406
  minDuration: 0,
1342
1407
  minDistance: 0,
1343
- minVelocity: 0,
1344
- getMousemoveTarget: (event) => event.target
1408
+ minVelocity: 0
1345
1409
  };
1346
1410
  function createMouserelease(options = {}) {
1347
1411
  const {
1348
1412
  minDuration,
1349
1413
  minDistance,
1350
1414
  minVelocity,
1351
- getMousemoveTarget,
1352
1415
  onDown,
1353
1416
  onLeave,
1354
1417
  onMove,
1355
1418
  onUp
1356
- } = { ...defaultOptions$e, ...options }, cleanup = (event) => {
1419
+ } = { ...defaultOptions$g, ...options }, cleanup = (target) => {
1357
1420
  window.cancelAnimationFrame(request);
1358
- getMousemoveTarget(event).removeEventListener("mousemove", mousemoveEffect);
1421
+ target.removeEventListener("mousemove", mousemoveEffect);
1359
1422
  };
1360
1423
  let request;
1361
1424
  let mousemoveEffect;
@@ -1371,7 +1434,8 @@ function createMouserelease(options = {}) {
1371
1434
  () => mouseStatus === "down",
1372
1435
  (newRequest) => request = newRequest
1373
1436
  );
1374
- getMousemoveTarget(event).addEventListener("mousemove", mousemoveEffect);
1437
+ const { listenInjection: { optionsByType: { mousedown: { target } } } } = api;
1438
+ target.addEventListener("mousemove", mousemoveEffect);
1375
1439
  onDown?.(toHookApi(api));
1376
1440
  };
1377
1441
  const mousemove = (event, api) => {
@@ -1379,10 +1443,10 @@ function createMouserelease(options = {}) {
1379
1443
  onMove?.(toHookApi(api));
1380
1444
  };
1381
1445
  const mouseleave = (event, api) => {
1382
- const { denied } = api;
1446
+ const { denied, listenInjection: { optionsByType: { mouseleave: { target } } } } = api;
1383
1447
  if (mouseStatus === "down") {
1384
1448
  denied();
1385
- cleanup(event);
1449
+ cleanup(target);
1386
1450
  mouseStatus = "leave";
1387
1451
  }
1388
1452
  onLeave?.(toHookApi(api));
@@ -1391,7 +1455,8 @@ function createMouserelease(options = {}) {
1391
1455
  if (mouseStatus !== "down")
1392
1456
  return;
1393
1457
  storePointerMoveMetadata(event, api);
1394
- cleanup(event);
1458
+ const { listenInjection: { optionsByType: { mouseup: { target } } } } = api;
1459
+ cleanup(target);
1395
1460
  mouseStatus = "up";
1396
1461
  recognize(event, api);
1397
1462
  onUp?.(toHookApi(api));
@@ -1410,8 +1475,23 @@ function createMouserelease(options = {}) {
1410
1475
  mouseup
1411
1476
  };
1412
1477
  }
1478
+ class Mouserelease extends Listenable {
1479
+ constructor(options) {
1480
+ super(
1481
+ "recognizeable",
1482
+ {
1483
+ recognizeable: {
1484
+ effects: createMouserelease(options)
1485
+ }
1486
+ }
1487
+ );
1488
+ }
1489
+ get metadata() {
1490
+ return this.recognizeable.metadata;
1491
+ }
1492
+ }
1413
1493
 
1414
- const defaultOptions$d = {
1494
+ const defaultOptions$f = {
1415
1495
  minDuration: 0,
1416
1496
  minDistance: 0
1417
1497
  };
@@ -1423,7 +1503,7 @@ function createTouchpress(options = {}) {
1423
1503
  onCancel,
1424
1504
  onMove,
1425
1505
  onEnd
1426
- } = { ...defaultOptions$d, ...options }, cleanup = () => {
1506
+ } = { ...defaultOptions$f, ...options }, cleanup = () => {
1427
1507
  window.cancelAnimationFrame(request);
1428
1508
  };
1429
1509
  let request;
@@ -1444,6 +1524,7 @@ function createTouchpress(options = {}) {
1444
1524
  api,
1445
1525
  () => totalTouches === 1,
1446
1526
  (newRequest) => request = newRequest,
1527
+ // @ts-expect-error
1447
1528
  recognize
1448
1529
  );
1449
1530
  onStart?.(toHookApi(api));
@@ -1483,8 +1564,23 @@ function createTouchpress(options = {}) {
1483
1564
  touchend
1484
1565
  };
1485
1566
  }
1567
+ class Touchpress extends Listenable {
1568
+ constructor(options) {
1569
+ super(
1570
+ "recognizeable",
1571
+ {
1572
+ recognizeable: {
1573
+ effects: createTouchpress(options)
1574
+ }
1575
+ }
1576
+ );
1577
+ }
1578
+ get metadata() {
1579
+ return this.recognizeable.metadata;
1580
+ }
1581
+ }
1486
1582
 
1487
- const defaultOptions$c = {
1583
+ const defaultOptions$e = {
1488
1584
  minDuration: 0,
1489
1585
  minDistance: 0,
1490
1586
  minVelocity: 0
@@ -1498,7 +1594,7 @@ function createTouchrelease(options = {}) {
1498
1594
  onCancel,
1499
1595
  onMove,
1500
1596
  onEnd
1501
- } = { ...defaultOptions$c, ...options }, cleanup = () => {
1597
+ } = { ...defaultOptions$e, ...options }, cleanup = () => {
1502
1598
  window.cancelAnimationFrame(request);
1503
1599
  };
1504
1600
  let request;
@@ -1564,1015 +1660,1340 @@ function createTouchrelease(options = {}) {
1564
1660
  touchend
1565
1661
  };
1566
1662
  }
1567
-
1568
- const defaultOptions$b = {
1569
- initial: []
1570
- };
1571
- function createKeyStatuses(options = {}) {
1572
- return createAssociativeArray({
1573
- ...defaultOptions$b,
1574
- ...options,
1575
- createPredicateKey: (query) => (key) => {
1576
- for (const prop in query) {
1577
- if (query[prop] !== key[prop]) {
1578
- return false;
1663
+ class Touchrelease extends Listenable {
1664
+ constructor(options) {
1665
+ super(
1666
+ "recognizeable",
1667
+ {
1668
+ recognizeable: {
1669
+ effects: createTouchrelease(options)
1579
1670
  }
1580
1671
  }
1581
- return true;
1582
- }
1583
- });
1672
+ );
1673
+ }
1674
+ get metadata() {
1675
+ return this.recognizeable.metadata;
1676
+ }
1584
1677
  }
1585
- function predicateDown(status) {
1586
- return status === "down";
1678
+
1679
+ function createRoot(graph) {
1680
+ const toIndegree = createIndegree(graph);
1681
+ return (node) => toIndegree(node) === 0;
1587
1682
  }
1588
- function predicateSomeKeyDown(statuses) {
1589
- return includes("down")(statuses.toValues());
1683
+ function createTerminal(graph) {
1684
+ const toOutdegree = createOutdegree(graph);
1685
+ return (node) => toOutdegree(node) === 0;
1590
1686
  }
1591
-
1592
- function fromComboToAliases(combo) {
1593
- const delimiter = "+";
1594
- return pipe(
1595
- unique(),
1596
- map((name) => name === "" ? delimiter : name.toLowerCase()),
1597
- toArray()
1598
- )(combo.split(delimiter));
1687
+ function createChildren(graph) {
1688
+ return function* (node) {
1689
+ const outgoing = createOutgoing(graph)(node);
1690
+ for (const edge of outgoing)
1691
+ yield edge.to;
1692
+ };
1599
1693
  }
1600
-
1601
- function fromAliasToKeyStatusKey(alias) {
1602
- if (alias in keysByAlias) {
1603
- return { key: keysByAlias[alias] };
1604
- }
1605
- return {
1606
- code: (() => {
1607
- if (alias in codesByAlias)
1608
- return codesByAlias[alias];
1609
- if (letterRE.test(alias))
1610
- return `Key${alias.toUpperCase()}`;
1611
- if (digitRE.test(alias))
1612
- return `Digit${alias}`;
1613
- if (functionRE.test(alias))
1614
- return alias.toUpperCase();
1615
- return "unsupported";
1616
- })()
1694
+ function createIndegree(graph) {
1695
+ const toIncoming = createIncoming(graph);
1696
+ return (node) => pipe(
1697
+ toIncoming,
1698
+ toLength()
1699
+ )(node);
1700
+ }
1701
+ function createOutdegree(graph) {
1702
+ const toOutgoing = createOutgoing(graph);
1703
+ return (node) => pipe(
1704
+ toOutgoing,
1705
+ toLength()
1706
+ )(node);
1707
+ }
1708
+ function createIncoming(graph) {
1709
+ const { edges } = graph;
1710
+ return function* (node) {
1711
+ yield* filter(
1712
+ ({ to }) => to === node
1713
+ )(edges);
1714
+ };
1715
+ }
1716
+ function createOutgoing(graph) {
1717
+ const { edges } = graph;
1718
+ return function* (node) {
1719
+ yield* filter(
1720
+ ({ from }) => from === node
1721
+ )(edges);
1722
+ };
1723
+ }
1724
+ function createOnlyChild(graph) {
1725
+ const toTotalSiblings = createTotalSiblings(graph);
1726
+ return (node) => toTotalSiblings(node) === 0;
1727
+ }
1728
+ function createTotalSiblings(graph) {
1729
+ const toSiblings = createSiblings(graph);
1730
+ return (node) => pipe(
1731
+ toSiblings,
1732
+ toLength()
1733
+ )(node);
1734
+ }
1735
+ function createSiblings(graph) {
1736
+ const { edges } = graph;
1737
+ return function* (node) {
1738
+ const parents = pipe(
1739
+ filter(
1740
+ ({ to }) => to === node
1741
+ ),
1742
+ map(
1743
+ ({ from }) => from
1744
+ )
1745
+ )(edges);
1746
+ for (const parent of parents) {
1747
+ yield* pipe(
1748
+ filter(
1749
+ ({ from, to }) => from === parent && to !== node
1750
+ ),
1751
+ map(
1752
+ ({ to }) => to
1753
+ )
1754
+ )(edges);
1755
+ }
1617
1756
  };
1618
1757
  }
1619
- const digitRE = /^[0-9]$/;
1620
- const letterRE = /^[a-zA-Z]$/;
1621
- const functionRE = /^[fF][0-9]{1,2}$/;
1622
- const codesByAlias = {
1623
- "`": "Backquote",
1624
- "~": "Backquote",
1625
- "-": "Minus",
1626
- _: "Minus",
1627
- "=": "Equal",
1628
- "+": "Equal",
1629
- "[": "BracketLeft",
1630
- "{": "BracketLeft",
1631
- "]": "BracketRight",
1632
- "}": "BracketRight",
1633
- "\\": "Backslash",
1634
- "|": "Backslash",
1635
- ";": "Semicolon",
1636
- ":": "Semicolon",
1637
- "'": "Quote",
1638
- '"': "Quote",
1639
- ",": "Comma",
1640
- "<": "Comma",
1641
- ".": "Period",
1642
- ">": "Period",
1643
- "/": "Slash",
1644
- "?": "Slash",
1645
- "!": "Digit1",
1646
- "@": "Digit2",
1647
- "#": "Digit3",
1648
- $: "Digit4",
1649
- "%": "Digit5",
1650
- "^": "Digit6",
1651
- "&": "Digit7",
1652
- "*": "Digit8",
1653
- "(": "Digit9",
1654
- ")": "Digit0",
1655
- up: "ArrowUp",
1656
- down: "ArrowDown",
1657
- left: "ArrowLeft",
1658
- right: "ArrowRight",
1659
- enter: "Enter",
1660
- space: "Space",
1661
- tab: "Tab",
1662
- esc: "Escape",
1663
- backspace: "Backspace",
1664
- delete: "Delete",
1665
- home: "Home",
1666
- end: "End",
1667
- pagedown: "PageDown",
1668
- pageup: "PageUp",
1669
- capslock: "CapsLock",
1670
- camera: "Camera"
1671
- };
1672
- const keysByAlias = {
1673
- alt: "Alt",
1674
- opt: "Alt",
1675
- option: "Alt",
1676
- ctrl: "Control",
1677
- control: "Control",
1678
- meta: "Meta",
1679
- cmd: "Meta",
1680
- command: "Meta",
1681
- shift: "Shift"
1682
- };
1683
1758
 
1684
- const defaultOptions$a = {
1685
- toKey: (alias) => fromAliasToKeyStatusKey(alias)
1686
- };
1687
- const createPredicateKeycomboDown = (keycombo, options = {}) => {
1688
- const { toKey } = { ...defaultOptions$a, ...options }, keys = pipe(
1689
- fromComboToAliases,
1690
- map(toKey)
1691
- )(keycombo);
1692
- return (statuses) => {
1693
- const { toValue } = statuses;
1694
- return every(pipe(
1695
- toValue,
1696
- predicateDown
1697
- ))(keys);
1759
+ function createFind(node) {
1760
+ return (tree) => {
1761
+ for (const treeNode of tree) {
1762
+ if (treeNode.node === node)
1763
+ return treeNode;
1764
+ const found = createFind(node)(treeNode.children);
1765
+ if (found)
1766
+ return found;
1767
+ }
1698
1768
  };
1699
- };
1769
+ }
1700
1770
 
1701
- function fromEventToAliases(event) {
1702
- if (event.shiftKey && event.code in aliasesByShiftCode) {
1703
- return [aliasesByShiftCode[event.code]];
1704
- }
1705
- if (event.key in aliasListsByModifier) {
1706
- return aliasListsByModifier[event.key];
1707
- }
1708
- return event.code in aliasesByCode ? [aliasesByCode[event.code]] : [event.code.match(aliasCaptureRE)?.[1].toLowerCase() || "unsupported"];
1771
+ function createPath$2(directedAcyclic, config) {
1772
+ const { predicatePathable, toTraversalCandidates } = config, firstRoot = pipe(
1773
+ createRoots(),
1774
+ at(0)
1775
+ )(directedAcyclic);
1776
+ return (state) => {
1777
+ const path = [firstRoot], getLastPathable = () => predicatePathable(path.at(-1)), getLastStatus = () => state[path.at(-1)].status;
1778
+ while (getLastPathable() && getLastStatus() === "set") {
1779
+ const edge = pipe(
1780
+ toTraversalCandidates,
1781
+ find(
1782
+ ({ predicateShouldTraverse }) => predicateShouldTraverse(state)
1783
+ )
1784
+ )(path);
1785
+ path.push(edge.to);
1786
+ }
1787
+ return path;
1788
+ };
1709
1789
  }
1710
- const aliasCaptureRE = /^(?:Digit|Key)?(F[0-9]{1,2}|[0-9]|[A-Z])$/;
1711
- const aliasesByCode = {
1712
- Backquote: "`",
1713
- Minus: "-",
1714
- Equal: "=",
1715
- BracketLeft: "[",
1716
- BracketRight: "]",
1717
- Backslash: "\\",
1718
- Semicolon: ";",
1719
- Quote: "'",
1720
- Comma: ",",
1721
- Period: ".",
1722
- Slash: "/",
1723
- ArrowUp: "up",
1724
- ArrowDown: "down",
1725
- ArrowLeft: "left",
1726
- ArrowRight: "right",
1727
- Enter: "enter",
1728
- Space: "space",
1729
- Tab: "tab",
1730
- Escape: "esc",
1731
- Backspace: "backspace",
1732
- Delete: "delete",
1733
- Home: "home",
1734
- End: "end",
1735
- PageDown: "pagedown",
1736
- PageUp: "pageup",
1737
- CapsLock: "capslock",
1738
- Camera: "camera"
1739
- };
1740
- const aliasesByShiftCode = {
1741
- Backquote: "~",
1742
- Minus: "_",
1743
- Equal: "+",
1744
- BracketLeft: "{",
1745
- BracketRight: "}",
1746
- Backslash: "|",
1747
- Semicolon: ":",
1748
- Quote: '"',
1749
- Comma: "<",
1750
- Period: ">",
1751
- Slash: "?",
1752
- Digit1: "!",
1753
- Digit2: "@",
1754
- Digit3: "#",
1755
- Digit4: "$",
1756
- Digit5: "%",
1757
- Digit6: "^",
1758
- Digit7: "&",
1759
- Digit8: "*",
1760
- Digit9: "(",
1761
- Digit0: ")"
1762
- };
1763
- const aliasListsByModifier = {
1764
- Alt: ["alt", "option", "opt"],
1765
- Control: ["control", "ctrl"],
1766
- Meta: ["meta", "command", "cmd"],
1767
- Shift: ["shift"]
1768
- };
1769
1790
 
1770
- const defaultOptions$9 = {
1771
- toKey: (alias) => fromAliasToKeyStatusKey(alias),
1772
- toAliases: (event) => fromEventToAliases(event)
1791
+ function createLayers$1(options = {}) {
1792
+ const toSteps = createDepthFirstSteps$2(options.createDepthFirstSteps);
1793
+ return function* toLayers(directedAcyclic) {
1794
+ const layers = [];
1795
+ for (const { path } of toSteps(directedAcyclic)) {
1796
+ const node = path.at(-1), depth = path.length - 1;
1797
+ if (!layers[depth] && depth > 0)
1798
+ yield layers[depth - 1];
1799
+ (layers[depth] || (layers[depth] = [])).push(node);
1800
+ }
1801
+ };
1802
+ }
1803
+ function createTree$2(options = {}) {
1804
+ const toSteps = createDepthFirstSteps$2(options.createDepthFirstSteps);
1805
+ return (directedAcyclic) => {
1806
+ const firstRoot = pipe(
1807
+ createRoots(),
1808
+ at(0)
1809
+ )(directedAcyclic), tree = [];
1810
+ tree.push({
1811
+ node: firstRoot,
1812
+ children: []
1813
+ });
1814
+ for (const { path } of toSteps(directedAcyclic)) {
1815
+ const node = path.at(-1), parent = path.at(-2);
1816
+ if (parent) {
1817
+ const parentTreeNode = createFind(parent)(tree);
1818
+ if (parentTreeNode) {
1819
+ parentTreeNode.children.push({
1820
+ node,
1821
+ children: []
1822
+ });
1823
+ }
1824
+ }
1825
+ }
1826
+ return tree;
1827
+ };
1828
+ }
1829
+ const defaultCreateDepthFirstStepsOptions = {
1830
+ getSetStateValue: ({ totalChildrenDiscovered }) => totalChildrenDiscovered
1773
1831
  };
1774
- const createPredicateKeycomboMatch = (keycombo, options = {}) => {
1775
- const { toKey, toAliases } = { ...defaultOptions$9, ...options }, aliases = fromComboToAliases(keycombo), keys = map(toKey)(aliases);
1776
- return (statuses) => {
1777
- const { toValue } = statuses;
1778
- return every(pipe(
1779
- toValue,
1780
- predicateDown
1781
- ))(keys) && every(
1782
- ([key, value]) => value === "up" || some(
1783
- (alias) => includes(alias)(aliases)
1784
- )(toAliases(key))
1785
- )(statuses.toEntries());
1832
+ function createDepthFirstSteps$2(options = {}) {
1833
+ return createSteps$1(
1834
+ createConfigureDepthFirstSteps(options),
1835
+ options
1836
+ );
1837
+ }
1838
+ function createConfigureDepthFirstSteps(options) {
1839
+ const { getSetStateValue: getSetStateValueOption } = {
1840
+ ...defaultCreateDepthFirstStepsOptions,
1841
+ ...options
1842
+ };
1843
+ return function(directedAcyclic) {
1844
+ const getSetStateValue = (node) => getSetStateValueOption({
1845
+ node,
1846
+ totalChildrenDiscovered: totalChildrenDiscoveredByNode[node]
1847
+ }), stepFromEffect = (node) => totalChildrenDiscoveredByNode[node]++, predicateSteppable = (node) => !predicateTerminal(node), predicateTerminal = createTerminal(directedAcyclic), predicateExhausted = (node) => totalChildrenDiscoveredByNode[node] === toTotalSiblings(node), toTotalSiblings = createOutdegree(directedAcyclic), totalChildrenDiscoveredByNode = createReduce(
1848
+ (totalChildrenDiscoveredByNode2, node) => {
1849
+ totalChildrenDiscoveredByNode2[node] = 0;
1850
+ return totalChildrenDiscoveredByNode2;
1851
+ },
1852
+ {}
1853
+ )(directedAcyclic.nodes);
1854
+ return {
1855
+ getSetStateValue,
1856
+ stepFromEffect,
1857
+ predicateSteppable,
1858
+ predicateExhausted,
1859
+ createPath: createDepthPathConfig(directedAcyclic)
1860
+ };
1786
1861
  };
1862
+ }
1863
+ const defaultCreateStepsOptions$1 = {
1864
+ kind: "directed acyclic"
1787
1865
  };
1788
-
1789
- function createKeyState({
1790
- keycomboOrKeycombos,
1791
- unsupportedAliases,
1792
- toKey,
1793
- toAliases,
1794
- getRequest
1795
- }) {
1796
- const narrowedKeycombos = createFilter(
1797
- (keycombo) => !some(
1798
- (alias) => includes(alias)(unsupportedAliases)
1799
- )(fromComboToAliases(keycombo))
1800
- )(Array.isArray(keycomboOrKeycombos) ? keycomboOrKeycombos : [keycomboOrKeycombos]), createPredicateKeycomboDownOptions = { toKey }, downPredicatesByKeycombo = (() => {
1801
- const predicates = [];
1802
- for (const keycombo of narrowedKeycombos) {
1803
- predicates.push([
1804
- keycombo,
1805
- createPredicateKeycomboDown(
1806
- keycombo,
1807
- createPredicateKeycomboDownOptions
1808
- )
1809
- ]);
1866
+ function createSteps$1(configure, options = {}) {
1867
+ return function* (directedAcyclic) {
1868
+ const {
1869
+ getSetStateValue,
1870
+ stepFromEffect,
1871
+ predicateSteppable,
1872
+ predicateExhausted,
1873
+ createPath: createPathConfig
1874
+ } = configure(directedAcyclic), { kind, root } = { ...defaultCreateStepsOptions$1, ...options }, { nodes } = directedAcyclic, toPath = createPath$2(directedAcyclic, createPathConfig), roots = pipe(
1875
+ createRoots({ kind }),
1876
+ toArray()
1877
+ )(directedAcyclic), state = {};
1878
+ for (const node of nodes) {
1879
+ state[node] = {
1880
+ status: "unset",
1881
+ value: void 0
1882
+ };
1810
1883
  }
1811
- return predicates;
1812
- })(), createPredicateKeycomboMatchOptions = { ...createPredicateKeycomboDownOptions, toAliases }, matchPredicatesByKeycombo = (() => {
1813
- const predicates = {};
1814
- for (const keycombo of narrowedKeycombos) {
1815
- predicates[keycombo] = createPredicateKeycomboMatch(
1816
- keycombo,
1817
- createPredicateKeycomboMatchOptions
1818
- );
1884
+ let location = root || at(0)(roots);
1885
+ const path = toPath(state);
1886
+ yield { path, state: JSON.parse(JSON.stringify(state)) };
1887
+ function* toStep() {
1888
+ if (predicateExhausted(location)) {
1889
+ if (includes(location)(roots))
1890
+ return;
1891
+ state[location].status = "unset";
1892
+ delete state[location].value;
1893
+ const path3 = toPath(state);
1894
+ location = path3.at(-2);
1895
+ yield* toStep();
1896
+ return;
1897
+ }
1898
+ state[location].status = "set";
1899
+ state[location].value = getSetStateValue(location);
1900
+ const path2 = toPath(state);
1901
+ yield { path: path2, state: JSON.parse(JSON.stringify(state)) };
1902
+ stepFromEffect(location);
1903
+ const newLocation = path2.at(-1);
1904
+ if (predicateSteppable(newLocation))
1905
+ location = newLocation;
1906
+ yield* toStep();
1819
1907
  }
1820
- return predicates;
1821
- })(), validAliases = pipe(
1822
- flatMap(fromComboToAliases),
1823
- unique(),
1824
- toArray()
1825
- )(narrowedKeycombos), getDownCombos = () => pipe(
1826
- filter(([, predicate]) => predicate(statuses)),
1827
- map(([keycombo]) => [keycombo, fromComboToAliases(keycombo)]),
1828
- sort(([, aliasesA], [, aliasesB]) => aliasesB.length - aliasesA.length),
1829
- map(([keycombo]) => keycombo),
1830
- toArray()
1831
- )(downPredicatesByKeycombo), predicateValid = (event) => {
1832
- const aliases = toAliases(event);
1833
- return some(
1834
- (validAlias) => includes(validAlias)(aliases)
1835
- )(validAliases);
1836
- }, cleanup = () => {
1837
- window.cancelAnimationFrame(getRequest());
1838
- }, statuses = createKeyStatuses();
1839
- return {
1840
- narrowedKeycombos,
1841
- createPredicateKeycomboDownOptions,
1842
- downPredicatesByKeycombo,
1843
- createPredicateKeycomboMatchOptions,
1844
- matchPredicatesByKeycombo,
1845
- validAliases,
1846
- getDownCombos,
1847
- predicateValid,
1848
- cleanup,
1849
- statuses
1908
+ yield* toStep();
1850
1909
  };
1851
1910
  }
1852
-
1853
- function toLength() {
1854
- return function toLengthFn(data) {
1855
- return [...data].length;
1911
+ function createRoots(options = {}) {
1912
+ return function* (directedAcyclic) {
1913
+ const { nodes } = directedAcyclic, predicateRoot = createRoot(directedAcyclic);
1914
+ for (const node of nodes) {
1915
+ if (predicateRoot(node))
1916
+ yield node;
1917
+ if (options.kind === "arborescence")
1918
+ break;
1919
+ }
1856
1920
  };
1857
1921
  }
1858
1922
 
1859
- const fromComboToAliasesLength = pipe(
1860
- fromComboToAliases,
1861
- toLength()
1862
- );
1923
+ function createCommonAncestors$2(directedAcyclic) {
1924
+ const toNodeDepthFirstSteps = createNodeDepthFirstSteps$2(directedAcyclic);
1925
+ return function* (a, b) {
1926
+ for (const { path: aPath } of toNodeDepthFirstSteps(a)) {
1927
+ for (const { path: bPath } of toNodeDepthFirstSteps(b)) {
1928
+ for (let aPathIndex = aPath.length - 1; aPathIndex >= 0; aPathIndex--) {
1929
+ for (let bPathIndex = bPath.length - 1; bPathIndex >= 0; bPathIndex--) {
1930
+ if (aPath[aPathIndex] === bPath[bPathIndex] && !includes(aPath[aPathIndex])([a, b])) {
1931
+ yield {
1932
+ node: aPath[aPathIndex],
1933
+ distances: {
1934
+ [a]: aPath.length - aPathIndex - 1,
1935
+ [b]: bPath.length - bPathIndex - 1
1936
+ }
1937
+ };
1938
+ }
1939
+ }
1940
+ }
1941
+ }
1942
+ }
1943
+ };
1944
+ }
1945
+ function createAncestor$2(directedAcyclic) {
1946
+ const toNodeDepthFirstSteps = createNodeDepthFirstSteps$2(directedAcyclic);
1947
+ return function(descendant, ancestor) {
1948
+ return pipe(
1949
+ toNodeDepthFirstSteps,
1950
+ some(({ path }) => includes(ancestor)(path))
1951
+ )(descendant);
1952
+ };
1953
+ }
1954
+ function createNodeDepthFirstSteps$2(directedAcyclic, options = {}) {
1955
+ const toSteps = createDepthFirstSteps$2(options.createDepthFirstSteps);
1956
+ return function* (node) {
1957
+ yield* pipe(
1958
+ toSteps,
1959
+ filter(({ path }) => path.at(-1) === node)
1960
+ )(directedAcyclic);
1961
+ };
1962
+ }
1863
1963
 
1864
- function fromEventToKeyStatusKey({ key, code }) {
1865
- return includes(key)(modifiers) ? { key } : { code };
1964
+ const defaultCreateStepsOptions = {
1965
+ priorityBranch: false,
1966
+ kind: "directed acyclic"
1967
+ };
1968
+ function createTree$1(options = {}) {
1969
+ const withDefaults = {
1970
+ ...options,
1971
+ createDepthFirstSteps: {
1972
+ ...defaultCreateStepsOptions,
1973
+ ...options.createDepthFirstSteps
1974
+ }
1975
+ };
1976
+ return createTree$2(withDefaults);
1977
+ }
1978
+ function createCommonAncestors$1(...params) {
1979
+ return createCommonAncestors$2(...params);
1980
+ }
1981
+ function createAncestor$1(...params) {
1982
+ return createAncestor$2(...params);
1983
+ }
1984
+ function createNodeDepthFirstSteps$1(decisionTree, options = {}) {
1985
+ const withDefaults = {
1986
+ ...options,
1987
+ createDepthFirstSteps: {
1988
+ ...defaultCreateStepsOptions,
1989
+ ...options.createDepthFirstSteps
1990
+ }
1991
+ };
1992
+ return createNodeDepthFirstSteps$2(
1993
+ decisionTree,
1994
+ withDefaults
1995
+ );
1996
+ }
1997
+ function createDepthFirstSteps$1(options) {
1998
+ const { priorityBranch } = { ...defaultCreateStepsOptions, ...options }, configureDepthFirstSteps = createConfigureDepthFirstSteps({
1999
+ getSetStateValue: ({ totalChildrenDiscovered }) => totalChildrenDiscovered === 0 ? priorityBranch : !priorityBranch
2000
+ });
2001
+ return createSteps$1(configureDepthFirstSteps, options);
2002
+ }
2003
+ function createPath$1(...params) {
2004
+ return createPath$2(...params);
1866
2005
  }
1867
- const modifiers = ["Alt", "Control", "Meta", "Shift"];
1868
2006
 
1869
- function toDirection(angle, unit = "degrees") {
1870
- return Object.keys(directions).find((direction) => directions[direction][unit](angle));
2007
+ function createPath(directedAcyclicAsync, config) {
2008
+ const { predicatePathable, toTraversalCandidates } = config, firstRoot = pipe(
2009
+ createRoots(),
2010
+ at(0)
2011
+ )(directedAcyclicAsync);
2012
+ return async (state) => {
2013
+ const path = [firstRoot], getLastPathable = () => predicatePathable(path.at(-1)), getLastStatus = () => state[path.at(-1)].status;
2014
+ while (getLastPathable() && getLastStatus() === "set") {
2015
+ const edge = await pipe(
2016
+ toTraversalCandidates,
2017
+ toArray(),
2018
+ createFindAsync(
2019
+ async ({ predicateShouldTraverse }) => await predicateShouldTraverse(state)
2020
+ )
2021
+ )(path);
2022
+ path.push(edge.to);
2023
+ }
2024
+ return path;
2025
+ };
1871
2026
  }
1872
- const directions = {
1873
- up: {
1874
- degrees: (degrees) => degrees >= 67.5 && degrees <= 112.5,
1875
- radians: (radians) => radians >= 0.375 * Math.PI && radians <= 0.625 * Math.PI
1876
- },
1877
- upRight: {
1878
- degrees: (degrees) => degrees >= 22.5 && degrees < 67.5,
1879
- radians: (radians) => radians >= 0.125 * Math.PI && radians < 0.375 * Math.PI
1880
- },
1881
- right: {
1882
- degrees: (degrees) => degrees > 337.5 && degrees <= 360 || degrees < 22.5 && degrees >= 0,
1883
- radians: (radians) => radians > 1.875 * Math.PI && radians <= 2 * Math.PI || radians < 0.125 * Math.PI && radians >= 0
1884
- },
1885
- downRight: {
1886
- degrees: (degrees) => degrees > 292.5 && degrees <= 337.5,
1887
- radians: (radians) => radians > 1.625 * Math.PI && radians <= 1.875 * Math.PI
1888
- },
1889
- down: {
1890
- degrees: (degrees) => degrees >= 247.5 && degrees <= 292.5,
1891
- radians: (radians) => radians >= 1.375 * Math.PI && radians <= 1.625 * Math.PI
1892
- },
1893
- downLeft: {
1894
- degrees: (degrees) => degrees >= 202.5 && degrees < 247.5,
1895
- radians: (radians) => radians >= 1.125 * Math.PI && radians < 1.375 * Math.PI
1896
- },
1897
- left: {
1898
- degrees: (degrees) => degrees > 157.5 && degrees < 202.5,
1899
- radians: (radians) => radians > 0.875 * Math.PI && radians < 1.125 * Math.PI
1900
- },
1901
- upLeft: {
1902
- degrees: (degrees) => degrees > 112.5 && degrees <= 157.5,
1903
- radians: (radians) => radians > 0.625 * Math.PI && radians <= 0.875 * Math.PI
1904
- }
1905
- };
1906
2027
 
1907
- function toHookApi({
1908
- getSequence,
1909
- getStatus,
1910
- getMetadata
1911
- }) {
1912
- return {
1913
- sequence: getSequence(),
1914
- status: getStatus(),
1915
- metadata: getMetadata()
2028
+ function createLayers(options = {}) {
2029
+ const toSteps = createDepthFirstSteps(options.createDepthFirstSteps);
2030
+ return async function toLayers(directedAcyclicAsync) {
2031
+ const layers = [];
2032
+ for await (const { path } of toSteps(directedAcyclicAsync)) {
2033
+ const node = path.at(-1), depth = path.length - 1;
2034
+ (layers[depth] || (layers[depth] = [])).push(node);
2035
+ }
2036
+ return layers;
2037
+ };
2038
+ }
2039
+ function createTree(options = {}) {
2040
+ const toSteps = createDepthFirstSteps(options.createDepthFirstSteps);
2041
+ return async function toTree(directedAcyclicAsync) {
2042
+ const firstRoot = pipe(
2043
+ createRoots(),
2044
+ at(0)
2045
+ )(directedAcyclicAsync), tree = [];
2046
+ tree.push({
2047
+ node: firstRoot,
2048
+ children: []
2049
+ });
2050
+ for await (const { path } of toSteps(directedAcyclicAsync)) {
2051
+ const node = path.at(-1), parent = path.at(-2);
2052
+ if (parent) {
2053
+ const parentTreeNode = createFind(parent)(tree);
2054
+ if (parentTreeNode) {
2055
+ parentTreeNode.children.push({
2056
+ node,
2057
+ children: []
2058
+ });
2059
+ }
2060
+ }
2061
+ }
2062
+ return tree;
2063
+ };
2064
+ }
2065
+ function createDepthFirstSteps(options = {}) {
2066
+ return createSteps(
2067
+ createConfigureDepthFirstSteps(options),
2068
+ options
2069
+ );
2070
+ }
2071
+ function createSteps(configure, options = {}) {
2072
+ return async function* (directedAcyclicAsync) {
2073
+ const {
2074
+ getSetStateValue,
2075
+ stepFromEffect,
2076
+ predicateSteppable,
2077
+ predicateExhausted,
2078
+ createPath: createPathConfig
2079
+ } = configure(directedAcyclicAsync), { kind, root } = { ...defaultCreateStepsOptions$1, ...options }, { nodes } = directedAcyclicAsync, toPath = createPath(directedAcyclicAsync, createPathConfig), roots = pipe(
2080
+ createRoots({ kind }),
2081
+ toArray()
2082
+ )(directedAcyclicAsync), state = {};
2083
+ for (const node of nodes) {
2084
+ state[node] = {
2085
+ status: "unset",
2086
+ value: void 0
2087
+ };
2088
+ }
2089
+ let location = root || at(0)(roots);
2090
+ const path = await toPath(state);
2091
+ yield { path, state: JSON.parse(JSON.stringify(state)) };
2092
+ async function* toStep() {
2093
+ if (predicateExhausted(location)) {
2094
+ if (includes(location)(roots))
2095
+ return;
2096
+ state[location].status = "unset";
2097
+ delete state[location].value;
2098
+ const path3 = await toPath(state);
2099
+ location = path3.at(-2);
2100
+ yield* await toStep();
2101
+ return;
2102
+ }
2103
+ state[location].status = "set";
2104
+ state[location].value = getSetStateValue(location);
2105
+ const path2 = await toPath(state);
2106
+ yield { path: path2, state: JSON.parse(JSON.stringify(state)) };
2107
+ stepFromEffect(location);
2108
+ const newLocation = path2.at(-1);
2109
+ if (predicateSteppable(newLocation))
2110
+ location = newLocation;
2111
+ yield* await toStep();
2112
+ }
2113
+ yield* await toStep();
1916
2114
  };
1917
2115
  }
1918
2116
 
1919
- function toMousePoint(event) {
1920
- return {
1921
- x: event.clientX,
1922
- y: event.clientY
2117
+ function createCommonAncestors(directedAcyclicAsync) {
2118
+ const toNodeDepthFirstSteps = createNodeDepthFirstSteps(directedAcyclicAsync);
2119
+ return async function* (a, b) {
2120
+ for await (const { path: aPath } of toNodeDepthFirstSteps(a)) {
2121
+ for await (const { path: bPath } of toNodeDepthFirstSteps(b)) {
2122
+ for (let aPathIndex = aPath.length - 1; aPathIndex >= 0; aPathIndex--) {
2123
+ for (let bPathIndex = bPath.length - 1; bPathIndex >= 0; bPathIndex--) {
2124
+ if (aPath[aPathIndex] === bPath[bPathIndex] && !includes(aPath[aPathIndex])([a, b])) {
2125
+ yield {
2126
+ node: aPath[aPathIndex],
2127
+ distances: {
2128
+ [a]: aPath.length - aPathIndex - 1,
2129
+ [b]: bPath.length - bPathIndex - 1
2130
+ }
2131
+ };
2132
+ }
2133
+ }
2134
+ }
2135
+ }
2136
+ }
1923
2137
  };
1924
2138
  }
1925
- function toTouchMovePoint(event) {
1926
- return {
1927
- x: event.touches.item(0).clientX,
1928
- y: event.touches.item(0).clientY
2139
+ function createAncestor(directedAcyclicAsync) {
2140
+ const toNodeDepthFirstSteps = createNodeDepthFirstSteps(directedAcyclicAsync);
2141
+ return async function(descendant, ancestor) {
2142
+ return await pipe(
2143
+ toNodeDepthFirstSteps,
2144
+ some(({ path }) => includes(ancestor)(path))
2145
+ )(descendant);
1929
2146
  };
1930
2147
  }
1931
- function toTouchEndPoint(event) {
1932
- return {
1933
- x: event.changedTouches.item(0).clientX,
1934
- y: event.changedTouches.item(0).clientY
2148
+ function createNodeDepthFirstSteps(directedAcyclicAsync, options = {}) {
2149
+ const toSteps = createDepthFirstSteps(options.createDepthFirstSteps);
2150
+ return async function* (node) {
2151
+ yield* await pipe(
2152
+ toSteps,
2153
+ filter(({ path }) => path.at(-1) === node)
2154
+ )(directedAcyclicAsync);
1935
2155
  };
1936
2156
  }
1937
2157
 
1938
- function toPolarCoordinates({ xA, xB, yA, yB }) {
1939
- 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;
1940
- return {
1941
- distance,
1942
- angle: { radians, degrees }
2158
+ const defaultOptions$d = {
2159
+ predicatesElement: false,
2160
+ // Adapted from React Aria https://github.com/adobe/react-spectrum/blob/b6786da906973130a1746b2bee63215bba013ca4/packages/%40react-aria/focus/src/FocusScope.tsx#L256
2161
+ tabbableSelector: join(':not([hidden]):not([tabindex="-1"]),')([
2162
+ "input:not([disabled]):not([type=hidden])",
2163
+ "select:not([disabled])",
2164
+ "textarea:not([disabled])",
2165
+ "button:not([disabled])",
2166
+ "a[href]",
2167
+ "area[href]",
2168
+ "summary",
2169
+ "iframe",
2170
+ "object",
2171
+ "embed",
2172
+ "audio[controls]",
2173
+ "video[controls]",
2174
+ "[contenteditable]",
2175
+ "[tabindex]:not([disabled])"
2176
+ ])
2177
+ };
2178
+ function createFocusable(order, options = {}) {
2179
+ const { predicatesElement, tabbableSelector } = { ...defaultOptions$d, ...options }, predicateFocusable = (element) => element.matches(tabbableSelector);
2180
+ return (element) => {
2181
+ if (predicatesElement && predicateFocusable(element))
2182
+ return element;
2183
+ switch (order) {
2184
+ case "first":
2185
+ for (let i = 0; i < element.children.length; i++) {
2186
+ const focusable = createFocusable(order, { predicatesElement: true })(element.children[i]);
2187
+ if (focusable)
2188
+ return focusable;
2189
+ }
2190
+ break;
2191
+ case "last":
2192
+ for (let i = element.children.length - 1; i > -1; i--) {
2193
+ const focusable = createFocusable(order, { predicatesElement: true })(element.children[i]);
2194
+ if (focusable)
2195
+ return focusable;
2196
+ }
2197
+ break;
2198
+ }
1943
2199
  };
1944
2200
  }
2201
+ function createComputedStyle(pseudoElement) {
2202
+ return (element) => getComputedStyle(element, pseudoElement);
2203
+ }
1945
2204
 
1946
- const initialMetadata$3 = {
1947
- times: {
1948
- start: 0,
1949
- end: 0
1950
- },
1951
- duration: 0
2205
+ const defaultOptions$c = {
2206
+ toCode: (alias) => fromAliasToCode(alias),
2207
+ toAliases: (descriptor) => fromKeyboardEventDescriptorToAliases(descriptor)
1952
2208
  };
1953
- function storeKeyboardTimeMetadata({
1954
- event,
1955
- api,
1956
- getTimeMetadata,
1957
- getShouldStore,
1958
- setRequest,
1959
- recognize
1960
- }) {
1961
- if (!getShouldStore())
1962
- return;
1963
- const { getStatus, onRecognized } = api, timeMetadata = getTimeMetadata();
1964
- if (!timeMetadata.times)
1965
- timeMetadata.times = createClone()(initialMetadata$3.times);
1966
- timeMetadata.times.start = Math.round(event.timeStamp);
1967
- timeMetadata.times.end = Math.round(event.timeStamp);
1968
- const storeDuration = () => {
1969
- const request = requestAnimationFrame((timestamp) => {
1970
- if (!getShouldStore())
1971
- return;
1972
- timeMetadata.times.end = Math.round(timestamp);
1973
- timeMetadata.duration = Math.max(0, timeMetadata.times.end - timeMetadata.times.start);
1974
- if (recognize) {
1975
- recognize(event, api);
1976
- if (getStatus() === "recognized")
1977
- onRecognized(event);
2209
+ const createKeycomboMatch$1 = (keycombo, options = {}) => {
2210
+ const { toLonghand, toCode, toAliases: fromDescriptorToAliases } = { ...defaultOptions$c, ...options }, fromComboToAliases = createAliases({ toLonghand }), aliases = fromComboToAliases(keycombo), codes = createMap(toCode)(aliases), implicitModifierAliases = (() => {
2211
+ const implicitModifierAliases2 = [];
2212
+ for (const code of codes) {
2213
+ const implicitModifier = find(
2214
+ (modifier) => code.includes(modifier)
2215
+ )(modifiers);
2216
+ if (implicitModifier)
2217
+ implicitModifierAliases2.push(implicitModifier.toLowerCase());
2218
+ }
2219
+ return implicitModifierAliases2;
2220
+ })();
2221
+ return (event) => {
2222
+ const statuses = [];
2223
+ createSet(fromEventToKeyStatusCode(event), "down")(statuses);
2224
+ for (const modifier of modifiers) {
2225
+ if (event[`${modifier.toLowerCase()}Key`])
2226
+ createSet(modifier, "down")(statuses);
2227
+ }
2228
+ const events = createMap(
2229
+ ([code]) => {
2230
+ const e = { code };
2231
+ for (const modifier of modifiers) {
2232
+ e[`${modifier.toLowerCase()}Key`] = event[`${modifier.toLowerCase()}Key`];
2233
+ }
2234
+ return e;
1978
2235
  }
1979
- storeDuration();
1980
- });
1981
- setRequest(request);
2236
+ )(statuses);
2237
+ return every(
2238
+ (code) => createValue(
2239
+ code,
2240
+ { predicateKey: createCode(code) }
2241
+ )(statuses) === "down"
2242
+ )(codes) && every(
2243
+ (e) => pipe(
2244
+ fromDescriptorToAliases,
2245
+ map(fromComboToAliases),
2246
+ some(
2247
+ (longhandAliases) => every(
2248
+ (longhandAlias) => includes(longhandAlias)(aliases) || includes(longhandAlias)(implicitModifierAliases)
2249
+ )(longhandAliases)
2250
+ )
2251
+ )(e)
2252
+ )(events);
1982
2253
  };
1983
- storeDuration();
1984
- }
1985
-
1986
- const initialMetadata$2 = {
1987
- points: {
1988
- start: { x: 0, y: 0 },
1989
- end: { x: 0, y: 0 }
1990
- }
1991
2254
  };
1992
- function storePointerStartMetadata(event, api) {
1993
- const { getMetadata } = api, metadata = getMetadata();
1994
- const point = event instanceof MouseEvent ? toMousePoint(event) : toTouchMovePoint(event);
1995
- if (!metadata.points)
1996
- metadata.points = createClone()(initialMetadata$2.points);
1997
- metadata.points.start = point;
1998
- metadata.points.end = point;
2255
+
2256
+ function createClamp(min, max) {
2257
+ return (number) => {
2258
+ const maxed = Math.max(number, min);
2259
+ return Math.min(maxed, max);
2260
+ };
2261
+ }
2262
+ function createDetermine(potentialities) {
2263
+ const predicates = createMap(
2264
+ ({ outcome, probability }, index) => {
2265
+ const lowerBound = index === 0 ? 0 : pipe(
2266
+ slice(0, index - 1),
2267
+ reduce(
2268
+ (lowerBound2, { probability: probability2 }) => lowerBound2 + probability2,
2269
+ 0
2270
+ )
2271
+ )(potentialities), upperBound = lowerBound + probability;
2272
+ return {
2273
+ outcome,
2274
+ predicate: (determinant) => determinant >= lowerBound && determinant < upperBound || determinant < 0 && index === 0 || index === predicates.length - 1
2275
+ };
2276
+ }
2277
+ )(potentialities);
2278
+ return (determinant) => find(
2279
+ ({ predicate }) => predicate(determinant)
2280
+ )(predicates).outcome;
2281
+ }
2282
+ function createGreater(threshold) {
2283
+ return (number) => number > threshold;
2284
+ }
2285
+ function createGreaterOrEqual(threshold) {
2286
+ return (number) => number >= threshold;
2287
+ }
2288
+ function createLessOrEqual(threshold) {
2289
+ return (number) => number <= threshold;
2290
+ }
2291
+ function createLess(threshold) {
2292
+ return (number) => number < threshold;
1999
2293
  }
2000
2294
 
2001
- const initialMetadata$1 = {
2002
- distance: {
2003
- straight: {
2004
- fromStart: 0,
2005
- fromPrevious: 0
2006
- },
2007
- horizontal: {
2008
- fromStart: 0,
2009
- fromPrevious: 0
2010
- },
2011
- vertical: {
2012
- fromStart: 0,
2013
- fromPrevious: 0
2295
+ function createValue$1(key) {
2296
+ return (object) => object[key];
2297
+ }
2298
+ function createHas(key) {
2299
+ return (object) => key in object;
2300
+ }
2301
+ function createKeys() {
2302
+ return (object) => {
2303
+ const keys = [];
2304
+ for (const key in object) {
2305
+ keys.push(key);
2014
2306
  }
2015
- },
2016
- angle: {
2017
- fromPrevious: { radians: 0, degrees: 0 },
2018
- fromStart: { radians: 0, degrees: 0 }
2019
- },
2020
- direction: {
2021
- fromPrevious: "up",
2022
- fromStart: "up"
2023
- }
2024
- };
2025
- function storePointerMoveMetadata(event, api) {
2026
- const { getMetadata } = api, metadata = getMetadata();
2027
- if (!metadata.distance) {
2028
- metadata.distance = createClone()(initialMetadata$1.distance);
2029
- metadata.angle = createClone()(initialMetadata$1.angle);
2030
- metadata.direction = createClone()(initialMetadata$1.direction);
2031
- }
2032
- const { x: previousX, y: previousY } = metadata.points.end, { x: startX, y: startY } = metadata.points.start, { x: newX, y: newY } = (() => {
2033
- if (event instanceof MouseEvent) {
2034
- return toMousePoint(event);
2307
+ return keys;
2308
+ };
2309
+ }
2310
+ function createEntries() {
2311
+ return (object) => {
2312
+ const entries = [];
2313
+ for (const key in object) {
2314
+ entries.push([key, object[key]]);
2035
2315
  }
2036
- if (event instanceof TouchEvent) {
2037
- if (event.type === "touchmove") {
2038
- return toTouchMovePoint(event);
2316
+ return entries;
2317
+ };
2318
+ }
2319
+ function createEvery(predicate) {
2320
+ return (object) => {
2321
+ for (const key in object) {
2322
+ if (!predicate(key, object[key])) {
2323
+ return false;
2039
2324
  }
2040
- return toTouchEndPoint(event);
2041
2325
  }
2042
- })(), { distance: distanceFromPrevious, angle: angleFromPrevious } = toPolarCoordinates({
2043
- xA: previousX,
2044
- xB: newX,
2045
- yA: previousY,
2046
- yB: newY
2047
- }), { distance: distanceFromStart, angle: angleFromStart } = toPolarCoordinates({
2048
- xA: startX,
2049
- xB: newX,
2050
- yA: startY,
2051
- yB: newY
2052
- });
2053
- metadata.distance.straight.fromPrevious = distanceFromPrevious;
2054
- metadata.distance.horizontal.fromPrevious = newX - previousX;
2055
- metadata.distance.vertical.fromPrevious = newY - previousY;
2056
- metadata.angle.fromPrevious = angleFromPrevious;
2057
- metadata.direction.fromPrevious = toDirection(angleFromPrevious.degrees);
2058
- metadata.distance.straight.fromStart = distanceFromStart;
2059
- metadata.distance.horizontal.fromStart = newX - startX;
2060
- metadata.distance.vertical.fromStart = newY - startY;
2061
- metadata.angle.fromStart = angleFromStart;
2062
- metadata.direction.fromStart = toDirection(angleFromStart.degrees);
2063
- metadata.points.end = { x: newX, y: newY };
2326
+ return true;
2327
+ };
2328
+ }
2329
+ function createSome(predicate) {
2330
+ return (object) => {
2331
+ for (const key in object) {
2332
+ if (predicate(key, object[key]))
2333
+ return true;
2334
+ }
2335
+ return false;
2336
+ };
2337
+ }
2338
+ function createDeepMerge(override) {
2339
+ return (object) => {
2340
+ const merged = createClone()(object);
2341
+ return merge(merged, override || {});
2342
+ };
2064
2343
  }
2065
2344
 
2066
- const initialMetadata = {
2067
- times: {
2068
- start: 0,
2069
- end: 0
2070
- },
2071
- duration: 0,
2072
- velocity: 0
2345
+ let totalGraphNodes = -1;
2346
+ const defaultOptions$b = {
2347
+ toId: () => `${totalGraphNodes++}`,
2348
+ toChildren: (node) => node.children
2073
2349
  };
2074
- function storePointerTimeMetadata(event, api, getShouldStore, setRequest, recognize) {
2075
- const { getSequence, getMetadata, getStatus, onRecognized } = api, metadata = getMetadata();
2076
- if (!metadata.times) {
2077
- metadata.times = createClone()(initialMetadata.times);
2078
- }
2079
- metadata.times.start = Math.round(event.timeStamp);
2080
- metadata.times.end = Math.round(event.timeStamp);
2081
- let previousTime = metadata.times.start;
2082
- const storeDuration = () => {
2083
- const request = requestAnimationFrame((timestamp) => {
2084
- if (getShouldStore()) {
2085
- previousTime = metadata.times.end;
2086
- metadata.times.end = Math.round(timestamp);
2087
- metadata.duration = Math.max(0, metadata.times.end - metadata.times.start);
2088
- const durationFromPrevious = Math.max(0, metadata.times.end - previousTime);
2089
- metadata.velocity = metadata.distance.straight.fromPrevious / durationFromPrevious;
2090
- const event2 = getSequence().at(-1);
2091
- recognize?.(event2, api);
2092
- if (getStatus() === "recognized")
2093
- onRecognized(event2);
2094
- storeDuration();
2350
+ function createGraph(options = {}) {
2351
+ const { toId, toChildren } = { ...defaultOptions$b, ...options };
2352
+ return function* (tree) {
2353
+ const root = tree[0], rootId = toId(root);
2354
+ function* toPair(node, id) {
2355
+ const children = toChildren(node) || [];
2356
+ for (const child of children) {
2357
+ const childId = toId(child);
2358
+ yield {
2359
+ node: childId,
2360
+ edge: { from: id, to: childId }
2361
+ };
2362
+ yield* toPair(child, childId);
2095
2363
  }
2096
- });
2097
- setRequest(request);
2364
+ }
2365
+ yield { node: rootId };
2366
+ yield* toPair(root, rootId);
2098
2367
  };
2099
- storeDuration();
2100
2368
  }
2101
2369
 
2102
- function defineGraph(nodes, edges) {
2103
- return { nodes, edges };
2370
+ function createSet$2(key, value, options = {}) {
2371
+ const { predicateKey = createEqual(key) } = options;
2372
+ return (associativeArray) => {
2373
+ const index = findIndex(
2374
+ ([candidate]) => predicateKey(candidate)
2375
+ )(associativeArray);
2376
+ if (index === -1) {
2377
+ associativeArray.push([key, value]);
2378
+ return;
2379
+ }
2380
+ associativeArray[index][1] = value;
2381
+ return associativeArray;
2382
+ };
2104
2383
  }
2105
- function defineGraphNodes(nodes) {
2106
- return nodes;
2384
+ function createClear$2() {
2385
+ return (associativeArray) => {
2386
+ associativeArray.length = 0;
2387
+ return associativeArray;
2388
+ };
2107
2389
  }
2108
- function defineGraphEdges(edges) {
2109
- return edges;
2390
+ function createDelete$2(key, options = {}) {
2391
+ const { predicateKey = createEqual(key) } = options;
2392
+ return (associativeArray) => {
2393
+ const index = findIndex(
2394
+ ([candidate]) => predicateKey(candidate)
2395
+ )(associativeArray);
2396
+ if (index === -1)
2397
+ return associativeArray;
2398
+ associativeArray.splice(index, 1);
2399
+ return associativeArray;
2400
+ };
2110
2401
  }
2111
- function defineGraphNode(node) {
2112
- return node;
2402
+
2403
+ function createSet$1(key, value) {
2404
+ return (object) => {
2405
+ object[key] = value;
2406
+ return object;
2407
+ };
2113
2408
  }
2114
- function defineGraphEdge(from, to, predicateTraversable) {
2115
- return { from, to, predicateTraversable };
2409
+ function createDelete$1(key) {
2410
+ return (object) => {
2411
+ delete object[key];
2412
+ return object;
2413
+ };
2116
2414
  }
2117
- function defineAsyncGraph(nodes, edges) {
2118
- return { nodes, edges };
2415
+ function createClear$1() {
2416
+ return (object) => {
2417
+ for (const key in object) {
2418
+ delete object[key];
2419
+ }
2420
+ return object;
2421
+ };
2119
2422
  }
2120
- function defineAsyncGraphEdges(edges) {
2121
- return edges;
2423
+
2424
+ function fromEventToKeyStatusCode({ code }) {
2425
+ const modifier = find(
2426
+ (modifier2) => code.includes(modifier2)
2427
+ )(modifiers);
2428
+ return modifier || code;
2429
+ }
2430
+ const modifiers = ["Alt", "Control", "Meta", "Shift"];
2431
+
2432
+ const createValue = createValue$2;
2433
+ function createSet(code, value) {
2434
+ return createSet$2(code, value);
2435
+ }
2436
+ const createClear = createClear$2;
2437
+ function createDelete(code) {
2438
+ return createDelete$2(code);
2439
+ }
2440
+ function createCode(query) {
2441
+ return function(candidate) {
2442
+ return query === candidate || includes(query)(modifiers) && candidate.includes(query) || includes(candidate)(modifiers) && query.includes(candidate);
2443
+ };
2444
+ }
2445
+ const createValues = createValues$1;
2446
+ function predicateSomeKeyDown(statuses) {
2447
+ return includes("down")(createValues()(statuses));
2122
2448
  }
2123
- function defineAsyncGraphEdge(from, to, predicateTraversable) {
2124
- return { from, to, predicateTraversable };
2449
+
2450
+ const defaultOptions$a = {
2451
+ toCode: (alias) => fromAliasToCode(alias)
2452
+ };
2453
+ const createKeycomboDown = (keycombo, options = {}) => {
2454
+ const { toLonghand, toCode } = { ...defaultOptions$a, ...options }, codes = pipe(
2455
+ createAliases({ toLonghand }),
2456
+ map(toCode)
2457
+ )(keycombo);
2458
+ return (statuses) => every(
2459
+ (code) => createValue(
2460
+ code,
2461
+ { predicateKey: createCode(code) }
2462
+ )(statuses) === "down"
2463
+ )(codes);
2464
+ };
2465
+
2466
+ function fromKeyboardEventDescriptorToAliases(event) {
2467
+ if (event.shiftKey && event.code in aliasesByShiftCode)
2468
+ return [aliasesByShiftCode[event.code]];
2469
+ const withoutModifierSide = toWithoutModifierSide(event.code);
2470
+ if (withoutModifierSide in aliasListsByModifier)
2471
+ return aliasListsByModifier[withoutModifierSide];
2472
+ return event.code in aliasesByCode ? [aliasesByCode[event.code]] : [event.code.match(aliasCaptureRE)?.[1].toLowerCase() || "unsupported"];
2125
2473
  }
2474
+ const toWithoutModifierSide = createClip(/(?:Left|Right)$/);
2475
+ const aliasCaptureRE = /^(?:Digit|Key)?(F[0-9]{1,2}|[0-9]|[A-Z])$/;
2476
+ const aliasesByCode = {
2477
+ Backquote: "`",
2478
+ Minus: "-",
2479
+ Equal: "=",
2480
+ BracketLeft: "[",
2481
+ BracketRight: "]",
2482
+ Backslash: "\\",
2483
+ Semicolon: ";",
2484
+ Quote: "'",
2485
+ Comma: ",",
2486
+ Period: ".",
2487
+ Slash: "/",
2488
+ ArrowUp: "up",
2489
+ ArrowDown: "down",
2490
+ ArrowLeft: "left",
2491
+ ArrowRight: "right",
2492
+ Enter: "enter",
2493
+ Space: "space",
2494
+ Tab: "tab",
2495
+ Escape: "esc",
2496
+ Backspace: "backspace",
2497
+ Delete: "delete",
2498
+ Home: "home",
2499
+ End: "end",
2500
+ PageDown: "pagedown",
2501
+ PageUp: "pageup",
2502
+ CapsLock: "capslock",
2503
+ Camera: "camera"
2504
+ };
2505
+ const aliasesByShiftCode = {
2506
+ Backquote: "~",
2507
+ Minus: "_",
2508
+ Equal: "+",
2509
+ BracketLeft: "{",
2510
+ BracketRight: "}",
2511
+ Backslash: "|",
2512
+ Semicolon: ":",
2513
+ Quote: '"',
2514
+ Comma: "<",
2515
+ Period: ">",
2516
+ Slash: "?",
2517
+ Digit1: "!",
2518
+ Digit2: "@",
2519
+ Digit3: "#",
2520
+ Digit4: "$",
2521
+ Digit5: "%",
2522
+ Digit6: "^",
2523
+ Digit7: "&",
2524
+ Digit8: "*",
2525
+ Digit9: "(",
2526
+ Digit0: ")"
2527
+ };
2528
+ const aliasListsByModifier = {
2529
+ Alt: ["alt", "option", "opt"],
2530
+ Control: ["control", "ctrl"],
2531
+ Meta: ["meta", "command", "cmd"],
2532
+ Shift: ["shift"]
2533
+ };
2126
2534
 
2127
- function defineAssociativeArrayEntries(entries) {
2128
- return entries;
2535
+ function fromCodeToAliases(code) {
2536
+ return fromKeyboardEventDescriptorToAliases({ code });
2129
2537
  }
2130
2538
 
2131
- function createExceptAndOnlyEffect(type, effect, options) {
2132
- const { except = [], only = [] } = options;
2133
- if (type === "keydown" || type === "keyup") {
2134
- return (event) => {
2135
- const { target } = event, [matchesOnly, matchesExcept] = target instanceof Element ? createMap((selectors) => some((selector) => target.matches(selector))(selectors))([only, except]) : [false, false];
2136
- if (matchesOnly) {
2137
- effect(event);
2138
- return;
2139
- }
2140
- if (only.length === 0 && !matchesExcept) {
2141
- effect(event);
2142
- return;
2143
- }
2144
- };
2145
- }
2146
- if (type === "click" || type === "dblclick" || type === "contextmenu" || type.startsWith("mouse")) {
2147
- return (event) => {
2148
- const { target } = event, [matchesOnly, matchesExcept] = target instanceof Element ? createMap((selectors) => some((selector) => target.matches(selector))(selectors))([only, except]) : [false, false];
2149
- if (matchesOnly) {
2150
- effect(event);
2151
- return;
2152
- }
2153
- if (only.length === 0 && !matchesExcept) {
2154
- effect(event);
2155
- return;
2156
- }
2157
- };
2158
- }
2159
- if (type.startsWith("pointer")) {
2160
- return (event) => {
2161
- const { target } = event, [matchesOnly, matchesExcept] = target instanceof Element ? createMap((selectors) => some((selector) => target.matches(selector))(selectors))([only, except]) : [false, false];
2162
- if (matchesOnly) {
2163
- effect(event);
2164
- return;
2165
- }
2166
- if (only.length === 0 && !matchesExcept) {
2167
- effect(event);
2168
- return;
2169
- }
2170
- };
2171
- }
2172
- return (event) => {
2173
- const { target } = event, [matchesOnly, matchesExcept] = target instanceof Element ? createMap((selectors) => some((selector) => target.matches(selector))(selectors))([only, except]) : [false, false];
2174
- if (matchesOnly) {
2175
- effect(event, {});
2176
- return;
2539
+ const defaultOptions$9 = {
2540
+ toCode: (alias) => fromAliasToCode(alias),
2541
+ toAliases: (code) => fromCodeToAliases(code)
2542
+ };
2543
+ const createKeycomboMatch = (keycombo, options = {}) => {
2544
+ const { toLonghand, toCode, toAliases } = { ...defaultOptions$9, ...options }, aliases = createAliases({ toLonghand })(keycombo), codes = map(toCode)(aliases);
2545
+ return (statuses) => every(
2546
+ (code) => createValue(
2547
+ code,
2548
+ { predicateKey: createCode(code) }
2549
+ )(statuses) === "down"
2550
+ )(codes) && every(
2551
+ ([code, value]) => value === "up" || pipe(
2552
+ toAliases,
2553
+ some((alias) => includes(alias)(aliases))
2554
+ )(code)
2555
+ )(statuses);
2556
+ };
2557
+
2558
+ function createKeyState({
2559
+ keycomboOrKeycombos,
2560
+ toLonghand,
2561
+ toCode,
2562
+ toAliases,
2563
+ getRequest
2564
+ }) {
2565
+ const fromComboToAliases = createAliases({ toLonghand }), narrowedKeycombos = createFilter(
2566
+ (keycombo) => !some(
2567
+ (alias) => includes(alias)(unsupportedAliases)
2568
+ )(fromComboToAliases(keycombo))
2569
+ )(Array.isArray(keycomboOrKeycombos) ? keycomboOrKeycombos : [keycomboOrKeycombos]), createKeycomboDownOptions = { toLonghand, toCode }, downPredicatesByKeycombo = (() => {
2570
+ const predicates = [];
2571
+ for (const keycombo of narrowedKeycombos) {
2572
+ predicates.push([
2573
+ keycombo,
2574
+ createKeycomboDown(
2575
+ keycombo,
2576
+ createKeycomboDownOptions
2577
+ )
2578
+ ]);
2177
2579
  }
2178
- if (only.length === 0 && !matchesExcept) {
2179
- effect(event, {});
2180
- return;
2580
+ return predicates;
2581
+ })(), createKeycomboMatchOptions = { ...createKeycomboDownOptions, toAliases }, matchPredicatesByKeycombo = (() => {
2582
+ const predicates = {};
2583
+ for (const keycombo of narrowedKeycombos) {
2584
+ predicates[keycombo] = createKeycomboMatch(
2585
+ keycombo,
2586
+ createKeycomboMatchOptions
2587
+ );
2181
2588
  }
2589
+ return predicates;
2590
+ })(), validAliases = pipe(
2591
+ flatMap(fromComboToAliases),
2592
+ unique(),
2593
+ toArray()
2594
+ )(narrowedKeycombos), getDownCombos = () => pipe(
2595
+ filter(([, predicate]) => predicate(statuses)),
2596
+ map(([keycombo]) => [keycombo, fromComboToAliases(keycombo)]),
2597
+ sort(([, aliasesA], [, aliasesB]) => aliasesB.length - aliasesA.length),
2598
+ map(([keycombo]) => keycombo),
2599
+ toArray()
2600
+ )(downPredicatesByKeycombo), predicateValid = (event) => {
2601
+ const aliases = toAliases(event.code);
2602
+ return some(
2603
+ (validAlias) => includes(validAlias)(aliases)
2604
+ )(validAliases);
2605
+ }, cleanup = () => {
2606
+ window.cancelAnimationFrame(getRequest());
2607
+ }, statuses = [], toStatus = (...params) => createValue(...params)(statuses), setStatus = (...params) => createSet(...params)(statuses), clearStatuses = (...params) => createClear(...params)(statuses), deleteStatus = (...params) => createDelete(...params)(statuses);
2608
+ return {
2609
+ narrowedKeycombos,
2610
+ createKeycomboDownOptions,
2611
+ downPredicatesByKeycombo,
2612
+ createKeycomboMatchOptions,
2613
+ matchPredicatesByKeycombo,
2614
+ validAliases,
2615
+ getDownCombos,
2616
+ predicateValid,
2617
+ cleanup,
2618
+ statuses,
2619
+ toStatus,
2620
+ setStatus,
2621
+ clearStatuses,
2622
+ deleteStatus
2182
2623
  };
2183
2624
  }
2625
+ const unsupportedAliases = ["meta", "command", "cmd"];
2626
+ const unsupportedKeys = ["Meta"];
2184
2627
 
2185
- function getDomAvailability() {
2186
- try {
2187
- return !!window ? "available" : "unavailable";
2188
- } catch (error) {
2189
- return "unavailable";
2190
- }
2628
+ function createAliasesLength(options) {
2629
+ return pipe(
2630
+ createAliases(options),
2631
+ toLength()
2632
+ );
2191
2633
  }
2192
2634
 
2193
- function predicateArray(value) {
2194
- return Array.isArray(value);
2195
- }
2196
- function predicateUndefined(value) {
2197
- return value === void 0;
2198
- }
2199
- function predicateFunction(value) {
2200
- return typeof value === "function";
2635
+ function toDirection(angle, unit = "degrees") {
2636
+ return Object.keys(directions).find((direction) => directions[direction][unit](angle));
2201
2637
  }
2202
- function predicateNull(value) {
2203
- return value === null;
2638
+ const directions = {
2639
+ up: {
2640
+ degrees: (degrees) => degrees >= 67.5 && degrees <= 112.5,
2641
+ radians: (radians) => radians >= 0.375 * Math.PI && radians <= 0.625 * Math.PI
2642
+ },
2643
+ upRight: {
2644
+ degrees: (degrees) => degrees >= 22.5 && degrees < 67.5,
2645
+ radians: (radians) => radians >= 0.125 * Math.PI && radians < 0.375 * Math.PI
2646
+ },
2647
+ right: {
2648
+ degrees: (degrees) => degrees > 337.5 && degrees <= 360 || degrees < 22.5 && degrees >= 0,
2649
+ radians: (radians) => radians > 1.875 * Math.PI && radians <= 2 * Math.PI || radians < 0.125 * Math.PI && radians >= 0
2650
+ },
2651
+ downRight: {
2652
+ degrees: (degrees) => degrees > 292.5 && degrees <= 337.5,
2653
+ radians: (radians) => radians > 1.625 * Math.PI && radians <= 1.875 * Math.PI
2654
+ },
2655
+ down: {
2656
+ degrees: (degrees) => degrees >= 247.5 && degrees <= 292.5,
2657
+ radians: (radians) => radians >= 1.375 * Math.PI && radians <= 1.625 * Math.PI
2658
+ },
2659
+ downLeft: {
2660
+ degrees: (degrees) => degrees >= 202.5 && degrees < 247.5,
2661
+ radians: (radians) => radians >= 1.125 * Math.PI && radians < 1.375 * Math.PI
2662
+ },
2663
+ left: {
2664
+ degrees: (degrees) => degrees > 157.5 && degrees < 202.5,
2665
+ radians: (radians) => radians > 0.875 * Math.PI && radians < 1.125 * Math.PI
2666
+ },
2667
+ upLeft: {
2668
+ degrees: (degrees) => degrees > 112.5 && degrees <= 157.5,
2669
+ radians: (radians) => radians > 0.625 * Math.PI && radians <= 0.875 * Math.PI
2670
+ }
2671
+ };
2672
+
2673
+ function toHookApi({
2674
+ getSequence,
2675
+ getStatus,
2676
+ getMetadata
2677
+ }) {
2678
+ return {
2679
+ sequence: getSequence(),
2680
+ status: getStatus(),
2681
+ metadata: getMetadata()
2682
+ };
2204
2683
  }
2205
- function predicateNumber(value) {
2206
- return typeof value === "number";
2684
+
2685
+ function toMousePoint(event) {
2686
+ return {
2687
+ x: event.clientX,
2688
+ y: event.clientY
2689
+ };
2207
2690
  }
2208
- function predicateString(value) {
2209
- return typeof value === "string";
2691
+ function toTouchMovePoint(event) {
2692
+ return {
2693
+ x: event.touches.item(0).clientX,
2694
+ y: event.touches.item(0).clientY
2695
+ };
2210
2696
  }
2211
- function predicateObject(value) {
2212
- return typeof value === "object";
2697
+ function toTouchEndPoint(event) {
2698
+ return {
2699
+ x: event.changedTouches.item(0).clientX,
2700
+ y: event.changedTouches.item(0).clientY
2701
+ };
2213
2702
  }
2214
2703
 
2215
- class Recognizeable {
2216
- maxSequenceLength;
2217
- effects;
2218
- effectApi;
2219
- constructor(sequence, options = {}) {
2220
- const defaultOptions = {
2221
- maxSequenceLength: true,
2222
- effects: {}
2223
- };
2224
- this.maxSequenceLength = options?.maxSequenceLength || defaultOptions.maxSequenceLength;
2225
- this.effects = options?.effects || defaultOptions.effects;
2226
- this.resetComputedMetadata();
2227
- this.setSequence(sequence);
2228
- this.effectApi = {
2229
- getStatus: () => this.status,
2230
- getMetadata: () => this.metadata,
2231
- setMetadata: (metadata) => this.computedMetadata = metadata,
2232
- recognized: () => this.recognized(),
2233
- denied: () => this.denied(),
2234
- ready: () => this.ready()
2235
- };
2236
- this.ready();
2237
- }
2238
- computedMetadata;
2239
- resetComputedMetadata() {
2240
- this.computedMetadata = {};
2241
- }
2242
- recognized() {
2243
- this.computedStatus = "recognized";
2244
- }
2245
- denied() {
2246
- this.computedStatus = "denied";
2247
- }
2248
- computedStatus;
2249
- ready() {
2250
- this.computedStatus = "ready";
2251
- }
2252
- get sequence() {
2253
- return this.computedSequence;
2254
- }
2255
- set sequence(sequence) {
2256
- this.setSequence(sequence);
2257
- }
2258
- get status() {
2259
- return this.computedStatus;
2260
- }
2261
- get metadata() {
2262
- return this.computedMetadata;
2263
- }
2264
- computedSequence;
2265
- setSequence(sequence) {
2266
- this.computedSequence = sequence;
2267
- return this;
2268
- }
2269
- recognize(sequenceItem, { onRecognized } = {}) {
2270
- this.recognizing();
2271
- const type = this.toType(sequenceItem), pushSequence = (sequenceItem2) => {
2272
- newSequence.push(sequenceItem2);
2273
- if (this.maxSequenceLength !== true && newSequence.length > this.maxSequenceLength) {
2274
- newSequence.shift();
2275
- }
2276
- }, newSequence = [];
2277
- for (const sequenceItem2 of this.sequence) {
2278
- pushSequence(sequenceItem2);
2279
- }
2280
- pushSequence(sequenceItem);
2281
- this.effectApi.getSequence = () => newSequence;
2282
- this.effectApi.pushSequence = pushSequence;
2283
- this.effectApi.onRecognized = onRecognized || (() => {
2284
- });
2285
- this.effects[type]?.(sequenceItem, { ...this.effectApi });
2286
- switch (this.status) {
2287
- case "ready":
2288
- case "denied":
2289
- this.resetComputedMetadata();
2290
- this.setSequence([]);
2291
- break;
2292
- case "recognizing":
2293
- case "recognized":
2294
- this.setSequence(newSequence);
2295
- break;
2296
- }
2297
- return this;
2298
- }
2299
- recognizing() {
2300
- this.computedStatus = "recognizing";
2301
- }
2302
- toType(sequenceItem) {
2303
- if (predicateArray(sequenceItem)) {
2304
- if (sequenceItem[0] instanceof IntersectionObserverEntry) {
2305
- return "intersect";
2306
- }
2307
- if (sequenceItem[0] instanceof MutationRecord) {
2308
- return "mutate";
2309
- }
2310
- if (sequenceItem[0] instanceof ResizeObserverEntry) {
2311
- return "resize";
2312
- }
2313
- } else {
2314
- if (sequenceItem instanceof MediaQueryListEvent) {
2315
- return sequenceItem.media;
2316
- }
2317
- if ("didTimeout" in sequenceItem) {
2318
- return "idle";
2319
- }
2320
- return sequenceItem.type;
2321
- }
2322
- }
2704
+ function toPolarCoordinates({ xA, xB, yA, yB }) {
2705
+ 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;
2706
+ return {
2707
+ distance,
2708
+ angle: { radians, degrees }
2709
+ };
2323
2710
  }
2324
2711
 
2325
- class Listenable {
2326
- computedRecognizeable;
2327
- recognizeableEffectsKeys;
2328
- computedActive;
2329
- constructor(type, options) {
2330
- if (type === "recognizeable") {
2331
- this.computedRecognizeable = new Recognizeable([], options?.recognizeable);
2332
- this.recognizeableEffectsKeys = Object.keys(options?.recognizeable?.effects);
2333
- }
2334
- this.computedActive = /* @__PURE__ */ new Set();
2335
- this.setType(type);
2336
- this.ready();
2337
- }
2338
- computedStatus;
2339
- ready() {
2340
- this.computedStatus = "ready";
2341
- }
2342
- get type() {
2343
- return this.computedType;
2344
- }
2345
- set type(type) {
2346
- this.setType(type);
2347
- }
2348
- get status() {
2349
- return this.computedStatus;
2350
- }
2351
- get active() {
2352
- return this.computedActive;
2353
- }
2354
- get recognizeable() {
2355
- return this.computedRecognizeable;
2356
- }
2357
- computedType;
2358
- implementation;
2359
- setType(type) {
2360
- this.stop();
2361
- this.computedType = type;
2362
- this.implementation = toImplementation(type);
2363
- return this;
2712
+ const initialMetadata$3 = {
2713
+ times: {
2714
+ start: 0,
2715
+ end: 0
2716
+ },
2717
+ duration: 0
2718
+ };
2719
+ function storeKeyboardTimeMetadata({
2720
+ event,
2721
+ api,
2722
+ getTimeMetadata,
2723
+ getShouldStore,
2724
+ setRequest,
2725
+ recognize
2726
+ }) {
2727
+ if (!getShouldStore())
2728
+ return;
2729
+ const { getStatus, listenInjection: { effect } } = api, timeMetadata = getTimeMetadata();
2730
+ if (!timeMetadata.times)
2731
+ timeMetadata.times = createClone()(initialMetadata$3.times);
2732
+ timeMetadata.times.start = Math.round(event.timeStamp);
2733
+ timeMetadata.times.end = Math.round(event.timeStamp);
2734
+ const storeDuration = () => {
2735
+ const request = requestAnimationFrame((timestamp) => {
2736
+ if (!getShouldStore())
2737
+ return;
2738
+ timeMetadata.times.end = Math.round(timestamp);
2739
+ timeMetadata.duration = Math.max(0, timeMetadata.times.end - timeMetadata.times.start);
2740
+ if (recognize) {
2741
+ recognize(event, api);
2742
+ if (getStatus() === "recognized")
2743
+ effect(event);
2744
+ }
2745
+ storeDuration();
2746
+ });
2747
+ setRequest(request);
2748
+ };
2749
+ storeDuration();
2750
+ }
2751
+
2752
+ const initialMetadata$2 = {
2753
+ points: {
2754
+ start: { x: 0, y: 0 },
2755
+ end: { x: 0, y: 0 }
2364
2756
  }
2365
- listen(effect, options = {}) {
2366
- switch (this.implementation) {
2367
- case "intersection":
2368
- this.intersectionListen(effect, options);
2369
- break;
2370
- case "mutation":
2371
- this.mutationListen(effect, options);
2372
- break;
2373
- case "resize":
2374
- this.resizeListen(effect, options);
2375
- break;
2376
- case "mediaquery":
2377
- this.mediaQueryListen(effect, options);
2378
- break;
2379
- case "idle":
2380
- this.idleListen(effect, options);
2381
- break;
2382
- case "message":
2383
- this.messageListen(effect, options);
2384
- break;
2385
- case "recognizeable":
2386
- this.recognizeableListen(effect, options);
2387
- break;
2388
- case "documentevent":
2389
- this.documentEventListen(effect, options);
2390
- break;
2391
- case "event":
2392
- this.eventListen(effect, options);
2393
- break;
2757
+ };
2758
+ function storePointerStartMetadata(event, api) {
2759
+ const { getMetadata } = api, metadata = getMetadata();
2760
+ const point = event instanceof MouseEvent ? toMousePoint(event) : toTouchMovePoint(event);
2761
+ if (!metadata.points)
2762
+ metadata.points = createClone()(initialMetadata$2.points);
2763
+ metadata.points.start = point;
2764
+ metadata.points.end = point;
2765
+ }
2766
+
2767
+ const initialMetadata$1 = {
2768
+ distance: {
2769
+ straight: {
2770
+ fromStart: 0,
2771
+ fromPrevious: 0
2772
+ },
2773
+ horizontal: {
2774
+ fromStart: 0,
2775
+ fromPrevious: 0
2776
+ },
2777
+ vertical: {
2778
+ fromStart: 0,
2779
+ fromPrevious: 0
2394
2780
  }
2395
- this.listening();
2396
- return this;
2397
- }
2398
- intersectionListen(effect, options) {
2399
- const { target = document.querySelector("html"), observer } = options, id = new IntersectionObserver(effect, observer);
2400
- id.observe(target);
2401
- this.active.add({ target, id });
2402
- }
2403
- mutationListen(effect, options) {
2404
- const { target = document.querySelector("html"), observe } = options, id = new MutationObserver(effect);
2405
- id.observe(target, observe);
2406
- this.active.add({ target, id });
2781
+ },
2782
+ angle: {
2783
+ fromPrevious: { radians: 0, degrees: 0 },
2784
+ fromStart: { radians: 0, degrees: 0 }
2785
+ },
2786
+ direction: {
2787
+ fromPrevious: "up",
2788
+ fromStart: "up"
2407
2789
  }
2408
- resizeListen(effect, options) {
2409
- const { target = document.querySelector("html"), observe } = options, id = new ResizeObserver(effect);
2410
- id.observe(target, observe);
2411
- this.active.add({ target, id });
2790
+ };
2791
+ function storePointerMoveMetadata(event, api) {
2792
+ const { getMetadata } = api, metadata = getMetadata();
2793
+ if (!metadata.distance) {
2794
+ metadata.distance = createClone()(initialMetadata$1.distance);
2795
+ metadata.angle = createClone()(initialMetadata$1.angle);
2796
+ metadata.direction = createClone()(initialMetadata$1.direction);
2412
2797
  }
2413
- mediaQueryListen(effect, options) {
2414
- const target = window.matchMedia(this.type);
2415
- if (predicateFunction(options.instantEffect)) {
2416
- options.instantEffect(target);
2798
+ const { x: previousX, y: previousY } = metadata.points.end, { x: startX, y: startY } = metadata.points.start, { x: newX, y: newY } = (() => {
2799
+ if (event instanceof MouseEvent) {
2800
+ return toMousePoint(event);
2417
2801
  }
2418
- const withApi = (event) => effect(event);
2419
- target.addEventListener("change", withApi);
2420
- this.active.add({ target, id: ["change", withApi] });
2421
- }
2422
- idleListen(effect, options) {
2423
- const { requestIdleCallback } = options, id = window.requestIdleCallback((deadline) => effect(deadline), requestIdleCallback);
2424
- this.active.add({ target: window, id });
2425
- }
2426
- messageListen(effect, options) {
2427
- const { target = new BroadcastChannel("baleada") } = options;
2428
- target.addEventListener(this.type, (event) => effect(event));
2429
- this.active.add({ target, id: [this.type, effect] });
2430
- }
2431
- recognizeableListen(effect, options) {
2432
- const guardedEffect = (sequenceItem) => {
2433
- this.recognizeable.recognize(sequenceItem, { onRecognized: (sequenceItem2) => effect(sequenceItem2) });
2434
- if (this.recognizeable.status === "recognized")
2435
- effect(sequenceItem);
2436
- };
2437
- for (const type of this.recognizeableEffectsKeys) {
2438
- const listenable = new Listenable(type);
2439
- listenable.listen(guardedEffect, options);
2440
- this.active.add({ id: listenable });
2802
+ if (event instanceof TouchEvent) {
2803
+ if (event.type === "touchmove") {
2804
+ return toTouchMovePoint(event);
2805
+ }
2806
+ return toTouchEndPoint(event);
2441
2807
  }
2808
+ })(), { distance: distanceFromPrevious, angle: angleFromPrevious } = toPolarCoordinates({
2809
+ xA: previousX,
2810
+ xB: newX,
2811
+ yA: previousY,
2812
+ yB: newY
2813
+ }), { distance: distanceFromStart, angle: angleFromStart } = toPolarCoordinates({
2814
+ xA: startX,
2815
+ xB: newX,
2816
+ yA: startY,
2817
+ yB: newY
2818
+ });
2819
+ metadata.distance.straight.fromPrevious = distanceFromPrevious;
2820
+ metadata.distance.horizontal.fromPrevious = newX - previousX;
2821
+ metadata.distance.vertical.fromPrevious = newY - previousY;
2822
+ metadata.angle.fromPrevious = angleFromPrevious;
2823
+ metadata.direction.fromPrevious = toDirection(angleFromPrevious.degrees);
2824
+ metadata.distance.straight.fromStart = distanceFromStart;
2825
+ metadata.distance.horizontal.fromStart = newX - startX;
2826
+ metadata.distance.vertical.fromStart = newY - startY;
2827
+ metadata.angle.fromStart = angleFromStart;
2828
+ metadata.direction.fromStart = toDirection(angleFromStart.degrees);
2829
+ metadata.points.end = { x: newX, y: newY };
2830
+ }
2831
+
2832
+ const initialMetadata = {
2833
+ times: {
2834
+ start: 0,
2835
+ end: 0
2836
+ },
2837
+ duration: 0,
2838
+ velocity: 0
2839
+ };
2840
+ function storePointerTimeMetadata(event, api, getShouldStore, setRequest, recognize) {
2841
+ const { getSequence, getMetadata, getStatus, listenInjection: { effect } } = api, metadata = getMetadata();
2842
+ if (!metadata.times) {
2843
+ metadata.times = createClone()(initialMetadata.times);
2442
2844
  }
2443
- documentEventListen(effect, options) {
2444
- const narrowedOptions = {
2445
- ...options,
2446
- target: document
2845
+ metadata.times.start = Math.round(event.timeStamp);
2846
+ metadata.times.end = Math.round(event.timeStamp);
2847
+ let previousTime = metadata.times.start;
2848
+ const storeDuration = () => {
2849
+ const request = requestAnimationFrame((timestamp) => {
2850
+ if (getShouldStore()) {
2851
+ previousTime = metadata.times.end;
2852
+ metadata.times.end = Math.round(timestamp);
2853
+ metadata.duration = Math.max(0, metadata.times.end - metadata.times.start);
2854
+ const durationFromPrevious = Math.max(0, metadata.times.end - previousTime);
2855
+ metadata.velocity = metadata.distance.straight.fromPrevious / durationFromPrevious;
2856
+ const event2 = getSequence().at(-1);
2857
+ recognize?.(event2, api);
2858
+ if (getStatus() === "recognized")
2859
+ effect(event2);
2860
+ storeDuration();
2861
+ }
2862
+ });
2863
+ setRequest(request);
2864
+ };
2865
+ storeDuration();
2866
+ }
2867
+
2868
+ function defineGraph(nodes, edges) {
2869
+ return { nodes, edges };
2870
+ }
2871
+ function defineGraphNodes(nodes) {
2872
+ return nodes;
2873
+ }
2874
+ function defineGraphEdges(edges) {
2875
+ return edges;
2876
+ }
2877
+ function defineGraphNode(node) {
2878
+ return node;
2879
+ }
2880
+ function defineGraphEdge(from, to, predicateShouldTraverse) {
2881
+ return { from, to, predicateShouldTraverse };
2882
+ }
2883
+ function defineGraphAsync(nodes, edges) {
2884
+ return { nodes, edges };
2885
+ }
2886
+ function defineGraphAsyncEdges(edges) {
2887
+ return edges;
2888
+ }
2889
+ function defineGraphAsyncEdge(from, to, predicateShouldTraverse) {
2890
+ return { from, to, predicateShouldTraverse };
2891
+ }
2892
+
2893
+ function defineAssociativeArray(associativeArray) {
2894
+ return associativeArray;
2895
+ }
2896
+
2897
+ function createExceptAndOnlyEffect(type, effect, options) {
2898
+ const { except = [], only = [] } = options;
2899
+ if (type === "keydown" || type === "keyup") {
2900
+ return (event) => {
2901
+ const { target } = event, [matchesOnly, matchesExcept] = target instanceof Element ? createMap((selectors) => some((selector) => target.matches(selector))(selectors))([only, except]) : [false, false];
2902
+ if (matchesOnly) {
2903
+ effect(event);
2904
+ return;
2905
+ }
2906
+ if (only.length === 0 && !matchesExcept) {
2907
+ effect(event);
2908
+ return;
2909
+ }
2447
2910
  };
2448
- this.eventListen(effect, narrowedOptions);
2449
- }
2450
- eventListen(effect, options) {
2451
- const { exceptAndOnlyEffect, effectOptions } = toAddEventListenerParams(this.type, effect, options), eventListeners = [[this.type, exceptAndOnlyEffect, ...effectOptions]];
2452
- this.addEventListeners(eventListeners, options);
2453
- }
2454
- addEventListeners(eventListeners, options) {
2455
- const { target = document } = options;
2456
- for (const eventListener of eventListeners) {
2457
- target.addEventListener(eventListener[0], eventListener[1], eventListener[2]);
2458
- this.active.add({ target, id: eventListener });
2459
- }
2460
2911
  }
2461
- listening() {
2462
- this.computedStatus = "listening";
2463
- }
2464
- stop(options = {}) {
2465
- const { target } = options;
2466
- switch (this.status) {
2467
- case "ready":
2468
- case void 0:
2469
- break;
2470
- default:
2471
- const stoppables = [...this.active].filter((active) => !target || ("target" in active ? active.target === target : false)), shouldUpdateStatus = stoppables.length === this.active.size;
2472
- for (const stoppable of stoppables) {
2473
- stop(stoppable);
2474
- this.active.delete(stoppable);
2475
- }
2476
- if (shouldUpdateStatus) {
2477
- this.stopped();
2478
- }
2479
- break;
2480
- }
2481
- return this;
2912
+ if (type === "click" || type === "dblclick" || type === "contextmenu" || type.startsWith("mouse")) {
2913
+ return (event) => {
2914
+ const { target } = event, [matchesOnly, matchesExcept] = target instanceof Element ? createMap((selectors) => some((selector) => target.matches(selector))(selectors))([only, except]) : [false, false];
2915
+ if (matchesOnly) {
2916
+ effect(event);
2917
+ return;
2918
+ }
2919
+ if (only.length === 0 && !matchesExcept) {
2920
+ effect(event);
2921
+ return;
2922
+ }
2923
+ };
2482
2924
  }
2483
- stopped() {
2484
- this.computedStatus = "stopped";
2925
+ if (type.startsWith("pointer")) {
2926
+ return (event) => {
2927
+ const { target } = event, [matchesOnly, matchesExcept] = target instanceof Element ? createMap((selectors) => some((selector) => target.matches(selector))(selectors))([only, except]) : [false, false];
2928
+ if (matchesOnly) {
2929
+ effect(event);
2930
+ return;
2931
+ }
2932
+ if (only.length === 0 && !matchesExcept) {
2933
+ effect(event);
2934
+ return;
2935
+ }
2936
+ };
2485
2937
  }
2938
+ return (event) => {
2939
+ const { target } = event, [matchesOnly, matchesExcept] = target instanceof Element ? createMap((selectors) => some((selector) => target.matches(selector))(selectors))([only, except]) : [false, false];
2940
+ if (matchesOnly) {
2941
+ effect(event, {});
2942
+ return;
2943
+ }
2944
+ if (only.length === 0 && !matchesExcept) {
2945
+ effect(event, {});
2946
+ return;
2947
+ }
2948
+ };
2486
2949
  }
2487
- function stop(stoppable) {
2488
- if (stoppable.id instanceof Listenable) {
2489
- stoppable.id.stop();
2490
- return;
2950
+
2951
+ function getDomAvailability() {
2952
+ try {
2953
+ return !!window ? "available" : "unavailable";
2954
+ } catch (error) {
2955
+ return "unavailable";
2491
2956
  }
2492
- if (some((type) => observerAssertionsByType[type](stoppable.id))(["intersect", "mutate", "resize"])) {
2493
- const { id: id2 } = stoppable;
2494
- id2.disconnect();
2495
- return;
2957
+ }
2958
+
2959
+ function predicateArray(value) {
2960
+ return Array.isArray(value);
2961
+ }
2962
+ function predicateUndefined(value) {
2963
+ return value === void 0;
2964
+ }
2965
+ function predicateFunction(value) {
2966
+ return typeof value === "function";
2967
+ }
2968
+ function predicateNull(value) {
2969
+ return value === null;
2970
+ }
2971
+ function predicateNumber(value) {
2972
+ return typeof value === "number";
2973
+ }
2974
+ function predicateString(value) {
2975
+ return typeof value === "string";
2976
+ }
2977
+ function predicateObject(value) {
2978
+ return typeof value === "object";
2979
+ }
2980
+
2981
+ function toInterpolated({ previous, next, progress }, options = {}) {
2982
+ if (predicateUndefined(previous)) {
2983
+ return next;
2496
2984
  }
2497
- if ("target" in stoppable && stoppable.target instanceof MediaQueryList) {
2498
- const { target: target2, id: id2 } = stoppable;
2499
- target2.removeEventListener(id2[0], id2[1]);
2500
- return;
2985
+ if (predicateNumber(previous) && predicateNumber(next)) {
2986
+ return (next - previous) * progress + previous;
2501
2987
  }
2502
- if (predicateNumber(stoppable.id)) {
2503
- const { target: target2, id: id2 } = stoppable;
2504
- target2.cancelIdleCallback(id2);
2505
- return;
2988
+ if (predicateString(previous) && predicateString(next)) {
2989
+ const { color: createMixOptions } = options;
2990
+ return createMix(`${next} ${progress * 100}%`, createMixOptions)(previous);
2506
2991
  }
2507
- if ("target" in stoppable && stoppable.target instanceof BroadcastChannel) {
2508
- const { target: target2, id: id2 } = stoppable;
2509
- target2.removeEventListener(id2[0], id2[1]);
2510
- return;
2992
+ if (predicateArray(previous) && predicateArray(next)) {
2993
+ const exactSliceEnd = (next.length - previous.length) * progress + previous.length, nextIsLonger = next.length > previous.length, sliceEnd = nextIsLonger ? Math.floor(exactSliceEnd) : Math.ceil(exactSliceEnd), sliceTarget = nextIsLonger ? next : previous;
2994
+ return createSlice(0, sliceEnd)(sliceTarget);
2511
2995
  }
2512
- const { target, id } = stoppable;
2513
- target.removeEventListener(id[0], id[1], id[2]);
2514
- }
2515
- function toImplementation(type) {
2516
- return find((implementation) => predicatesByImplementation.get(implementation)(type))(predicatesByImplementation.keys());
2517
- }
2518
- const predicatesByImplementation = /* @__PURE__ */ new Map([
2519
- [
2520
- "recognizeable",
2521
- (type) => type === "recognizeable"
2522
- ],
2523
- [
2524
- "intersection",
2525
- (type) => type === "intersect"
2526
- ],
2527
- [
2528
- "mutation",
2529
- (type) => type === "mutate"
2530
- ],
2531
- [
2532
- "resize",
2533
- (type) => type === "resize"
2534
- ],
2535
- [
2536
- "mediaquery",
2537
- (type) => implementationREs.mediaquery.test(type)
2538
- ],
2539
- [
2540
- "idle",
2541
- (type) => type === "idle"
2542
- ],
2543
- [
2544
- "message",
2545
- (type) => type === "message" || type === "messageerror"
2546
- ],
2547
- [
2548
- "documentevent",
2549
- (type) => documentEvents.has(type)
2550
- ],
2551
- [
2552
- "event",
2553
- () => true
2554
- ]
2555
- ]);
2556
- const documentEvents = /* @__PURE__ */ new Set([
2557
- "fullscreenchange",
2558
- "fullscreenerror",
2559
- "pointerlockchange",
2560
- "pointerlockerror",
2561
- "readystatechange",
2562
- "visibilitychange"
2563
- ]);
2564
- const implementationREs = {
2565
- mediaquery: /^\(.+\)$/
2566
- };
2567
- function toAddEventListenerParams(type, effect, options) {
2568
- const { addEventListener, useCapture } = options, exceptAndOnlyEffect = createExceptAndOnlyEffect(type, effect, options), effectOptions = [addEventListener || useCapture];
2569
- return { exceptAndOnlyEffect, effectOptions };
2570
2996
  }
2571
- const observerAssertionsByType = {
2572
- intersect: (observer) => observer instanceof IntersectionObserver,
2573
- mutate: (observer) => observer instanceof MutationObserver,
2574
- resize: (observer) => observer instanceof ResizeObserver
2575
- };
2576
2997
 
2577
2998
  const defaultOptions$8 = {
2578
2999
  duration: 0,
@@ -2587,6 +3008,14 @@ const defaultOptions$8 = {
2587
3008
  iterations: 1,
2588
3009
  alternates: false
2589
3010
  };
3011
+ const defaultAnimateOptions = {
3012
+ interpolate: {
3013
+ color: {
3014
+ method: "oklch",
3015
+ ...defaultCreateMixOptions
3016
+ }
3017
+ }
3018
+ };
2590
3019
  class Animateable {
2591
3020
  initialDuration;
2592
3021
  iterationLimit;
@@ -2609,8 +3038,8 @@ class Animateable {
2609
3038
  this.iterationLimit = options?.iterations || defaultOptions$8.iterations;
2610
3039
  this.alternates = options?.alternates || defaultOptions$8.alternates;
2611
3040
  this.reversedControlPoints = fromControlPointsToReversedControlPoints(this.controlPoints);
2612
- this.toAnimationProgress = createToAnimationProgress(this.controlPoints);
2613
- this.reversedToAnimationProgress = createToAnimationProgress(this.reversedControlPoints);
3041
+ this.toAnimationProgress = createAnimationProgress(this.controlPoints);
3042
+ this.reversedToAnimationProgress = createAnimationProgress(this.reversedControlPoints);
2614
3043
  this.playCache = {};
2615
3044
  this.reverseCache = {};
2616
3045
  this.pauseCache = {};
@@ -2860,7 +3289,7 @@ class Animateable {
2860
3289
  computedRequest;
2861
3290
  createAnimate(type) {
2862
3291
  return (effect, options = {}) => {
2863
- const { interpolate: interpolateOptions } = options;
3292
+ const { interpolate: interpolateOptions } = createDeepMerge(options)(defaultAnimateOptions);
2864
3293
  this.computedRequest = window.requestAnimationFrame((timestamp) => {
2865
3294
  this.setStartTimeAndStatus(type, timestamp);
2866
3295
  const timeElapsed = Math.min(timestamp - this.startTime - this.totalTimeInvisible, this.duration), timeRemaining = this.duration - timeElapsed, timeProgress = timeElapsed / this.duration, toAnimationProgress = this.getToAnimationProgress(type), animationProgress = toAnimationProgress(timeProgress);
@@ -3231,7 +3660,7 @@ function createGetEaseables(fromKeyframeToControlPoints) {
3231
3660
  (easeables, property) => {
3232
3661
  const propertyKeyframes = createFilter(({ properties: properties2 }) => properties2.hasOwnProperty(property))(keyframes), fromKeyframesToEaseables = createReduce(
3233
3662
  (propertyEaseables2, keyframe, index) => {
3234
- 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 }));
3663
+ 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 : createAnimationProgress(fromKeyframeToControlPoints({ keyframe, index, propertyKeyframes }));
3235
3664
  propertyEaseables2.push({
3236
3665
  property,
3237
3666
  value: { previous, next },
@@ -3284,32 +3713,10 @@ function fromControlPointsToReversedControlPoints(points) {
3284
3713
  { x: 1 - points[0].x, y: 1 - points[0].y }
3285
3714
  ];
3286
3715
  }
3287
- function createToAnimationProgress(points) {
3716
+ function createAnimationProgress(points) {
3288
3717
  const { 0: { x: point1x, y: point1y }, 1: { x: point2x, y: point2y } } = points;
3289
3718
  return BezierEasing(point1x, point1y, point2x, point2y);
3290
3719
  }
3291
- function toInterpolated({ previous, next, progress }, options = {}) {
3292
- if (predicateUndefined(previous)) {
3293
- return next;
3294
- }
3295
- if (predicateNumber(previous) && predicateNumber(next)) {
3296
- return (next - previous) * progress + previous;
3297
- }
3298
- if (predicateString(previous) && predicateString(next)) {
3299
- return mix(
3300
- options.colorModel,
3301
- {
3302
- start: previous,
3303
- end: next,
3304
- alpha: progress
3305
- }
3306
- ).toRgb().toRgbString();
3307
- }
3308
- if (predicateArray(previous) && predicateArray(next)) {
3309
- const exactSliceEnd = (next.length - previous.length) * progress + previous.length, nextIsLonger = next.length > previous.length, sliceEnd = nextIsLonger ? Math.floor(exactSliceEnd) : Math.ceil(exactSliceEnd), sliceTarget = nextIsLonger ? next : previous;
3310
- return createSlice(0, sliceEnd)(sliceTarget);
3311
- }
3312
- }
3313
3720
  const linear = [
3314
3721
  0,
3315
3722
  0,
@@ -3708,7 +4115,6 @@ class Completeable {
3708
4115
  }
3709
4116
  return this;
3710
4117
  }
3711
- // TODO: Support array of selections for multi cursor editing
3712
4118
  computedSelection;
3713
4119
  setSelection(selection) {
3714
4120
  this.computedSelection = selection;
@@ -4086,22 +4492,32 @@ class Drawable {
4086
4492
  }
4087
4493
  }
4088
4494
  function toD(stroke) {
4089
- return createReduce((d, [x0, y0], index) => {
4090
- const [x1, y1] = stroke[(index + 1) % stroke.length];
4091
- return `${d} ${x0} ${y0} ${(x0 + x1) / 2} ${(y0 + y1) / 2}`;
4092
- }, `M ${stroke[0][0]} ${stroke[0][1]} Q`)(stroke) + "Z";
4495
+ if (stroke.length < 4)
4496
+ return "";
4497
+ let a = stroke[0];
4498
+ let b = stroke[1];
4499
+ const c = stroke[2];
4500
+ let result = `M${a[0].toFixed(2)},${a[1].toFixed(2)} Q${b[0].toFixed(2)},${b[1].toFixed(2)} ${average()([b[0], c[0]]).toFixed(2)},${average()([b[1], c[1]]).toFixed(2)} T`;
4501
+ for (let i = 2; i < stroke.length - 1; i++) {
4502
+ a = stroke[i];
4503
+ b = stroke[i + 1];
4504
+ result += `${average()([a[0], b[0]]).toFixed(2)},${average()([a[1], b[1]]).toFixed(2)} `;
4505
+ }
4506
+ return `${result}Z`;
4093
4507
  }
4094
4508
  function toFlattenedD(stroke) {
4095
- if (stroke.length === 0) {
4509
+ if (stroke.length === 0)
4096
4510
  return "";
4511
+ const faces = polygonClipping.union([stroke]);
4512
+ const flattenedD = [];
4513
+ for (const face of faces) {
4514
+ for (const ring of face) {
4515
+ flattenedD.push(toD(ring));
4516
+ }
4097
4517
  }
4098
- const multiPolygon = polygonClipping.union([stroke]);
4099
- return createReduce((dFromMultiPolygon, polygon) => {
4100
- return dFromMultiPolygon + createReduce((dFromRing, points) => {
4101
- return dFromRing + toD(points);
4102
- }, "")(polygon);
4103
- }, "")(multiPolygon);
4518
+ return toSpaceSeparated(flattenedD);
4104
4519
  }
4520
+ const toSpaceSeparated = join(" ");
4105
4521
 
4106
4522
  class Resolveable {
4107
4523
  constructor(getPromise, options = {}) {
@@ -4124,20 +4540,23 @@ class Resolveable {
4124
4540
  get value() {
4125
4541
  return this.computedValue;
4126
4542
  }
4543
+ get error() {
4544
+ return this.computedError;
4545
+ }
4127
4546
  computedGetPromise;
4128
4547
  setGetPromise(getPromise) {
4129
4548
  this.computedGetPromise = getPromise;
4130
4549
  return this;
4131
4550
  }
4132
4551
  computedValue;
4133
- async resolve(...args) {
4552
+ computedError;
4553
+ async resolve() {
4134
4554
  this.resolving();
4135
4555
  try {
4136
- const promises = this.getPromise(...args);
4137
- this.computedValue = predicateArray(promises) ? await createMapAsync(async (promise) => await promise)(promises) : await promises;
4556
+ this.computedValue = await this.getPromise();
4138
4557
  this.resolved();
4139
4558
  } catch (error) {
4140
- this.computedValue = error;
4559
+ this.computedError = error;
4141
4560
  this.errored();
4142
4561
  }
4143
4562
  return this;
@@ -4179,27 +4598,26 @@ class Fetchable {
4179
4598
  set resource(resource) {
4180
4599
  this.setResource(resource);
4181
4600
  }
4601
+ get status() {
4602
+ return this.computedStatus;
4603
+ }
4182
4604
  computedKy;
4183
4605
  get ky() {
4184
4606
  return this.computedKy;
4185
4607
  }
4186
4608
  computedAbortController;
4187
4609
  get abortController() {
4188
- if (!this.computedAbortController) {
4610
+ if (!this.computedAbortController)
4189
4611
  this.computedAbortController = new AbortController();
4190
- }
4191
4612
  return this.computedAbortController;
4192
4613
  }
4193
- get status() {
4194
- return this.computedStatus;
4195
- }
4196
- get response() {
4197
- return this.computedResponse;
4198
- }
4199
4614
  computedRetryCount = 0;
4200
4615
  get retryCount() {
4201
4616
  return this.computedRetryCount;
4202
4617
  }
4618
+ get response() {
4619
+ return this.computedResponse;
4620
+ }
4203
4621
  get error() {
4204
4622
  return this.computedError;
4205
4623
  }
@@ -4271,27 +4689,27 @@ class Fetchable {
4271
4689
  this.computedStatus = "errored";
4272
4690
  }
4273
4691
  async get(options = {}) {
4274
- await this.fetch({ signal: this.abortController.signal, ...options, method: "get" });
4692
+ await this.fetch({ ...options, method: "get" });
4275
4693
  return this;
4276
4694
  }
4277
4695
  async patch(options = {}) {
4278
- await this.fetch({ signal: this.abortController.signal, ...options, method: "patch" });
4696
+ await this.fetch({ ...options, method: "patch" });
4279
4697
  return this;
4280
4698
  }
4281
4699
  async post(options = {}) {
4282
- await this.fetch({ signal: this.abortController.signal, ...options, method: "post" });
4700
+ await this.fetch({ ...options, method: "post" });
4283
4701
  return this;
4284
4702
  }
4285
4703
  async put(options = {}) {
4286
- await this.fetch({ signal: this.abortController.signal, ...options, method: "put" });
4704
+ await this.fetch({ ...options, method: "put" });
4287
4705
  return this;
4288
4706
  }
4289
4707
  async delete(options = {}) {
4290
- await this.fetch({ signal: this.abortController.signal, ...options, method: "delete" });
4708
+ await this.fetch({ ...options, method: "delete" });
4291
4709
  return this;
4292
4710
  }
4293
4711
  async head(options = {}) {
4294
- await this.fetch({ signal: this.abortController.signal, ...options, method: "head" });
4712
+ await this.fetch({ ...options, method: "head" });
4295
4713
  return this;
4296
4714
  }
4297
4715
  abort() {
@@ -4388,6 +4806,9 @@ class Grantable {
4388
4806
  get permission() {
4389
4807
  return this.computedPermission;
4390
4808
  }
4809
+ get error() {
4810
+ return this.computedError;
4811
+ }
4391
4812
  get status() {
4392
4813
  return this.computedStatus;
4393
4814
  }
@@ -4397,22 +4818,23 @@ class Grantable {
4397
4818
  return this;
4398
4819
  }
4399
4820
  computedPermission;
4400
- async query() {
4401
- this.querying();
4821
+ computedError;
4822
+ async grant() {
4823
+ this.granting();
4402
4824
  try {
4403
4825
  this.computedPermission = await navigator.permissions.query(this.descriptor);
4404
- this.queried();
4826
+ this.granted();
4405
4827
  } catch (error) {
4406
- this.computedPermission = error;
4828
+ this.computedError = error;
4407
4829
  this.errored();
4408
4830
  }
4409
4831
  return this;
4410
4832
  }
4411
- querying() {
4412
- this.computedStatus = "querying";
4833
+ granting() {
4834
+ this.computedStatus = "granting";
4413
4835
  }
4414
- queried() {
4415
- this.computedStatus = "queried";
4836
+ granted() {
4837
+ this.computedStatus = "granted";
4416
4838
  }
4417
4839
  errored() {
4418
4840
  this.computedStatus = "errored";
@@ -4608,9 +5030,6 @@ class Pickable {
4608
5030
  get newest() {
4609
5031
  return this.picks[this.picks.length - 1];
4610
5032
  }
4611
- get status() {
4612
- return this.computedStatus;
4613
- }
4614
5033
  get items() {
4615
5034
  return this.toItems(this.picks);
4616
5035
  }
@@ -4619,6 +5038,9 @@ class Pickable {
4619
5038
  get multiple() {
4620
5039
  return this.computedMultiple;
4621
5040
  }
5041
+ get status() {
5042
+ return this.computedStatus;
5043
+ }
4622
5044
  toPossiblePicks;
4623
5045
  setArray(array) {
4624
5046
  this.computedArray = array;
@@ -4712,112 +5134,20 @@ function narrowIndices(indexOrIndices) {
4712
5134
  }
4713
5135
  const toUnique = createUnique();
4714
5136
 
4715
- class Sanitizeable {
4716
- domPurifyConfig;
4717
- constructor(html, options) {
4718
- this.computedHtml = html;
4719
- this.domPurifyConfig = options;
4720
- this.ready();
4721
- }
4722
- computedDompurify;
4723
- computedStatus;
4724
- ready() {
4725
- if (getDomAvailability() === "available") {
4726
- this.computedDompurify = createDOMPurify();
4727
- this.computedDompurify.setConfig(this.domPurifyConfig);
4728
- }
4729
- this.computedStatus = "ready";
4730
- }
4731
- get html() {
4732
- return this.computedHtml;
4733
- }
4734
- set html(html) {
4735
- this.setHtml(html);
4736
- }
4737
- get dompurify() {
4738
- if (!this.computedDompurify && getDomAvailability() === "available") {
4739
- this.computedDompurify = createDOMPurify();
4740
- this.computedDompurify.setConfig(this.domPurifyConfig);
4741
- }
4742
- return this.computedDompurify;
4743
- }
4744
- get status() {
4745
- return this.computedStatus;
4746
- }
4747
- computedHtml;
4748
- setHtml(html) {
4749
- this.computedHtml = html;
4750
- return this;
4751
- }
4752
- sanitize() {
4753
- this.setHtml(this.dompurify.sanitize(this.html));
4754
- this.sanitized();
4755
- return this;
4756
- }
4757
- sanitized() {
4758
- this.computedStatus = "sanitized";
4759
- }
4760
- }
4761
-
4762
- class Searchable {
4763
- searcherOptions;
4764
- computedResults;
4765
- constructor(candidates, options = {}) {
4766
- this.searcherOptions = options;
4767
- this.setCandidates(candidates);
4768
- this.computedResults = [];
4769
- this.ready();
4770
- }
4771
- computedStatus;
4772
- ready() {
4773
- this.computedStatus = "ready";
4774
- }
4775
- computedCandidates;
4776
- get candidates() {
4777
- return this.computedCandidates;
4778
- }
4779
- set candidates(candidates) {
4780
- this.setCandidates(candidates);
4781
- }
4782
- get results() {
4783
- return this.computedResults;
4784
- }
4785
- get searcher() {
4786
- return this.computedSearcher;
4787
- }
4788
- get status() {
4789
- return this.computedStatus;
4790
- }
4791
- computedSearcher;
4792
- setCandidates(candidates) {
4793
- this.computedCandidates = Array.from(candidates);
4794
- this.computedSearcher = new Searcher(candidates, this.searcherOptions);
4795
- return this;
4796
- }
4797
- search(query, options) {
4798
- this.computedResults = this.searcher.search(query, options);
4799
- this.searched();
4800
- return this;
4801
- }
4802
- searched() {
4803
- this.computedStatus = "searched";
4804
- }
4805
- }
4806
-
4807
5137
  class Shareable {
4808
- constructor(state, options = {}) {
4809
- this.setState(state);
5138
+ constructor(shareData, options = {}) {
5139
+ this.setShareData(shareData);
4810
5140
  this.ready();
4811
5141
  }
4812
5142
  computedStatus;
4813
5143
  ready() {
4814
5144
  this.computedStatus = "ready";
4815
5145
  }
4816
- get state() {
5146
+ get shareData() {
4817
5147
  return this.computedState;
4818
5148
  }
4819
- set state(state) {
4820
- this.setState(state);
5149
+ set shareData(shareData) {
5150
+ this.setShareData(shareData);
4821
5151
  }
4822
5152
  get status() {
4823
5153
  return this.computedStatus;
@@ -4831,15 +5161,15 @@ class Shareable {
4831
5161
  return this.computedError;
4832
5162
  }
4833
5163
  computedState;
4834
- setState(state) {
4835
- this.computedState = state;
4836
- this.computedCan = new Resolveable(async () => await navigator.canShare(state));
5164
+ setShareData(shareData) {
5165
+ this.computedState = shareData;
5166
+ this.computedCan = new Resolveable(async () => await navigator.canShare(shareData));
4837
5167
  return this;
4838
5168
  }
4839
5169
  async share() {
4840
5170
  this.sharing();
4841
5171
  try {
4842
- await navigator.share(this.state);
5172
+ await navigator.share(this.shareData);
4843
5173
  this.shared();
4844
5174
  } catch (error) {
4845
5175
  this.computedError = error;
@@ -4979,4 +5309,4 @@ class Storeable {
4979
5309
  }
4980
5310
  }
4981
5311
 
4982
- 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 };
5312
+ export { Animateable, Broadcastable, Compareable, Completeable, Copyable, Delayable, Drawable, Fetchable, Fullscreenable, Grantable, Keychord, Keypress, Keyrelease, Konami, Listenable, Mousepress, Mouserelease, Navigateable, Pickable, Recognizeable, Resolveable, Shareable, Storeable, Touchpress, Touchrelease, createClear$2 as createAssociativeArrayClear, createDelete$2 as createAssociativeArrayDelete, createHas$1 as createAssociativeArrayHas, createKeys$1 as createAssociativeArrayKeys, createSet$2 as createAssociativeArraySet, createValue$2 as createAssociativeArrayValue, createValues$1 as createAssociativeArrayValues, createBreadthPathConfig, createChildren, createClamp, createClear$1 as createClear, createClip, createClone, createComputedStyle, createConcat, createAncestor$1 as createDecisionTreeAncestor, createCommonAncestors$1 as createDecisionTreeCommonAncestors, createNodeDepthFirstSteps$1 as createDecisionTreeNodeDepthFirstSteps, createPath$1 as createDecisionTreePath, createDepthFirstSteps$1 as createDecisionTreeSteps, createTree$1 as createDecisionTreeTree, createDeepEqual, createDeepMerge, createDelete$1 as createDelete, createDepthPathConfig, createDetermine, createAncestor$2 as createDirectedAcyclicAncestor, createAncestor as createDirectedAcyclicAsyncAncestor, createCommonAncestors as createDirectedAcyclicAsyncCommonAncestors, createDepthFirstSteps as createDirectedAcyclicAsyncDepthFirstSteps, createLayers as createDirectedAcyclicAsyncLayers, createNodeDepthFirstSteps as createDirectedAcyclicAsyncNodeDepthFirstSteps, createPath as createDirectedAcyclicAsyncPath, createTree as createDirectedAcyclicAsyncTree, createCommonAncestors$2 as createDirectedAcyclicCommonAncestors, createDepthFirstSteps$2 as createDirectedAcyclicDepthFirstSteps, createLayers$1 as createDirectedAcyclicLayers, createNodeDepthFirstSteps$2 as createDirectedAcyclicNodeDepthFirstSteps, createPath$2 as createDirectedAcyclicPath, createRoots as createDirectedAcyclicRoots, createTree$2 as createDirectedAcyclicTree, createEntries, createEqual, createEvery, createFilter, createFilterAsync, createFindAsync, createFindIndexAsync, createFocusable, createForEachAsync, createGraph, createGreater, createGreaterOrEqual, createHas, createIncoming, createIndegree, createInsert, createKeychord, createKeycomboMatch$1 as createKeycomboMatch, createKeypress, createKeyrelease, createKeys, createKonami, createLess, createLessOrEqual, createList, createMap, createMapAsync, createMix, createMousepress, createMouserelease, createNumber, createOnlyChild, createOutdegree, createOutgoing, createReduce, createReduceAsync, createRemove, createReorder, createReplace, createResults, createReverse, createRoot, createSanitize, createSet$1 as createSet, createShuffle, createSiblings, createSlice, createSlug, createSome, createSort, createSwap, createTerminal, createTotalSiblings, createTouchpress, createTouchrelease, createFind as createTreeFind, createUnique, createValue$1 as createValue, defineAssociativeArray, defineGraph, defineGraphAsync, defineGraphAsyncEdge, defineGraphAsyncEdges, 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, fromAliasToCode, fromCodeToAliases, fromKeyboardEventDescriptorToAliases, fromShorthandAliasToLonghandAlias, linear, materialAccelerated, materialDecelerated, materialStandard, toD, toFlattenedD, toMessageListenParams, verouEase, verouEaseIn, verouEaseInOut, verouEaseOut };