@studiometa/js-toolkit 3.0.0-alpha.8 → 3.0.0-beta.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 (94) hide show
  1. package/Base/Base.js +2 -2
  2. package/Base/Base.js.map +2 -2
  3. package/Base/features.d.ts +1 -0
  4. package/Base/features.js +1 -0
  5. package/Base/features.js.map +2 -2
  6. package/Base/managers/ChildrenManager.d.ts +1 -1
  7. package/Base/managers/ChildrenManager.js +8 -1
  8. package/Base/managers/ChildrenManager.js.map +2 -2
  9. package/Base/managers/EventsManager.js +15 -17
  10. package/Base/managers/EventsManager.js.map +2 -2
  11. package/Base/managers/OptionsManager.d.ts +2 -2
  12. package/Base/managers/OptionsManager.js +8 -8
  13. package/Base/managers/OptionsManager.js.map +2 -2
  14. package/Base/managers/RefsManager.js +7 -5
  15. package/Base/managers/RefsManager.js.map +2 -2
  16. package/Base/utils.d.ts +4 -0
  17. package/Base/utils.js +7 -3
  18. package/Base/utils.js.map +2 -2
  19. package/decorators/withBreakpointObserver.js +14 -9
  20. package/decorators/withBreakpointObserver.js.map +2 -2
  21. package/decorators/withDrag.d.ts +1 -1
  22. package/decorators/withDrag.js.map +1 -1
  23. package/decorators/withRelativePointer.d.ts +1 -1
  24. package/decorators/withRelativePointer.js.map +1 -1
  25. package/decorators/withResponsiveOptions.d.ts +3 -1
  26. package/decorators/withResponsiveOptions.js +22 -2
  27. package/decorators/withResponsiveOptions.js.map +2 -2
  28. package/helpers/createApp.js +5 -1
  29. package/helpers/createApp.js.map +2 -2
  30. package/helpers/getDirectChildren.js +10 -5
  31. package/helpers/getDirectChildren.js.map +2 -2
  32. package/package.json +1 -1
  33. package/services/AbstractService.d.ts +98 -0
  34. package/services/AbstractService.js +115 -0
  35. package/services/AbstractService.js.map +7 -0
  36. package/services/DragService.d.ts +124 -0
  37. package/services/DragService.js +217 -0
  38. package/services/DragService.js.map +7 -0
  39. package/services/KeyService.d.ts +29 -0
  40. package/services/KeyService.js +48 -0
  41. package/services/KeyService.js.map +7 -0
  42. package/services/LoadService.d.ts +15 -0
  43. package/services/LoadService.js +19 -0
  44. package/services/LoadService.js.map +7 -0
  45. package/services/PointerService.d.ts +56 -0
  46. package/services/PointerService.js +129 -0
  47. package/services/PointerService.js.map +7 -0
  48. package/services/RafService.d.ts +19 -0
  49. package/services/RafService.js +45 -0
  50. package/services/RafService.js.map +7 -0
  51. package/services/ResizeService.d.ts +29 -0
  52. package/services/ResizeService.js +66 -0
  53. package/services/ResizeService.js.map +7 -0
  54. package/services/{scroll.d.ts → ScrollService.d.ts} +14 -3
  55. package/services/ScrollService.js +90 -0
  56. package/services/ScrollService.js.map +7 -0
  57. package/services/index.d.ts +8 -41
  58. package/services/index.js +8 -18
  59. package/services/index.js.map +3 -3
  60. package/services/utils.d.ts +14 -0
  61. package/services/utils.js +11 -0
  62. package/services/utils.js.map +7 -0
  63. package/tsconfig.build.tsbuildinfo +1 -0
  64. package/utils/index.d.ts +1 -0
  65. package/utils/index.js +1 -0
  66. package/utils/index.js.map +2 -2
  67. package/utils/loadElement.d.ts +42 -0
  68. package/utils/loadElement.js +33 -0
  69. package/utils/loadElement.js.map +7 -0
  70. package/utils/tween.js +1 -1
  71. package/utils/tween.js.map +2 -2
  72. package/services/drag.d.ts +0 -75
  73. package/services/drag.js +0 -199
  74. package/services/drag.js.map +0 -7
  75. package/services/key.d.ts +0 -21
  76. package/services/key.js +0 -65
  77. package/services/key.js.map +0 -7
  78. package/services/load.d.ts +0 -11
  79. package/services/load.js +0 -38
  80. package/services/load.js.map +0 -7
  81. package/services/pointer.d.ts +0 -32
  82. package/services/pointer.js +0 -123
  83. package/services/pointer.js.map +0 -7
  84. package/services/raf.d.ts +0 -9
  85. package/services/raf.js +0 -56
  86. package/services/raf.js.map +0 -7
  87. package/services/resize.d.ts +0 -15
  88. package/services/resize.js +0 -67
  89. package/services/resize.js.map +0 -7
  90. package/services/scroll.js +0 -105
  91. package/services/scroll.js.map +0 -7
  92. package/services/service.d.ts +0 -16
  93. package/services/service.js +0 -47
  94. package/services/service.js.map +0 -7
package/utils/index.js CHANGED
@@ -28,6 +28,7 @@ export * from "./dom/index.js";
28
28
  export * from "./wait.js";
29
29
  export * from "./random.js";
30
30
  export * from "./memo.js";
31
+ export * from "./loadElement.js";
31
32
  export {
32
33
  Queue,
33
34
  SmartQueue,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../packages/js-toolkit/utils/index.ts"],
4
- "sourcesContent": ["export { default as debounce } from './debounce.js';\nexport * from './trapFocus.js';\nexport { default as keyCodes } from './keyCodes.js';\nexport { default as memoize } from './memoize.js';\nexport { nextFrame } from './nextFrame.js';\nexport { nextTick } from './nextTick.js';\nexport { nextMicrotask } from './nextMicrotask.js';\nexport { default as throttle } from './throttle.js';\nexport { scrollTo } from './scrollTo.js';\nexport { default as getComponentResolver } from './getComponentResolver.js';\nexport * from './is.js';\nexport * from './has.js';\nexport * from './css/index.js';\nexport {\n objectToURLSearchParams,\n push as historyPush,\n replace as historyReplace,\n} from './history.js';\nexport * from './collide/index.js';\nexport * from './math/index.js';\nexport * from './string/index.js';\nexport * from './scheduler.js';\nexport * from './noop.js';\nexport { tween } from './tween.js';\nexport { Queue } from './Queue.js';\nexport { SmartQueue } from './SmartQueue.js';\nexport * from './dom/index.js';\nexport * from './wait.js';\nexport * from './random.js';\nexport * from './memo.js';\n"],
5
- "mappings": "AAAA,SAAoB,WAAXA,gBAA2B;AACpC,cAAc;AACd,SAAoB,WAAXA,gBAA2B;AACpC,SAAoB,WAAXA,gBAA0B;AACnC,SAAS,iBAAiB;AAC1B,SAAS,gBAAgB;AACzB,SAAS,qBAAqB;AAC9B,SAAoB,WAAXA,gBAA2B;AACpC,SAAS,gBAAgB;AACzB,SAAoB,WAAXA,gBAAuC;AAChD,cAAc;AACd,cAAc;AACd,cAAc;AACd;AAAA,EACE;AAAA,EACQ;AAAA,EACG;AAAA,OACN;AACP,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,SAAS,aAAa;AACtB,SAAS,aAAa;AACtB,SAAS,kBAAkB;AAC3B,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;",
4
+ "sourcesContent": ["export { default as debounce } from './debounce.js';\nexport * from './trapFocus.js';\nexport { default as keyCodes } from './keyCodes.js';\nexport { default as memoize } from './memoize.js';\nexport { nextFrame } from './nextFrame.js';\nexport { nextTick } from './nextTick.js';\nexport { nextMicrotask } from './nextMicrotask.js';\nexport { default as throttle } from './throttle.js';\nexport { scrollTo } from './scrollTo.js';\nexport { default as getComponentResolver } from './getComponentResolver.js';\nexport * from './is.js';\nexport * from './has.js';\nexport * from './css/index.js';\nexport {\n objectToURLSearchParams,\n push as historyPush,\n replace as historyReplace,\n} from './history.js';\nexport * from './collide/index.js';\nexport * from './math/index.js';\nexport * from './string/index.js';\nexport * from './scheduler.js';\nexport * from './noop.js';\nexport { tween } from './tween.js';\nexport { Queue } from './Queue.js';\nexport { SmartQueue } from './SmartQueue.js';\nexport * from './dom/index.js';\nexport * from './wait.js';\nexport * from './random.js';\nexport * from './memo.js';\nexport * from './loadElement.js';\n"],
5
+ "mappings": "AAAA,SAAoB,WAAXA,gBAA2B;AACpC,cAAc;AACd,SAAoB,WAAXA,gBAA2B;AACpC,SAAoB,WAAXA,gBAA0B;AACnC,SAAS,iBAAiB;AAC1B,SAAS,gBAAgB;AACzB,SAAS,qBAAqB;AAC9B,SAAoB,WAAXA,gBAA2B;AACpC,SAAS,gBAAgB;AACzB,SAAoB,WAAXA,gBAAuC;AAChD,cAAc;AACd,cAAc;AACd,cAAc;AACd;AAAA,EACE;AAAA,EACQ;AAAA,EACG;AAAA,OACN;AACP,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,SAAS,aAAa;AACtB,SAAS,aAAa;AACtB,SAAS,kBAAkB;AAC3B,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;",
6
6
  "names": ["default"]
7
7
  }
@@ -0,0 +1,42 @@
1
+ export type LoadableElements = {
2
+ embed: HTMLEmbedElement;
3
+ iframe: HTMLIFrameElement;
4
+ img: HTMLImageElement;
5
+ link: HTMLLinkElement;
6
+ script: HTMLScriptElement;
7
+ track: HTMLTrackElement;
8
+ };
9
+ export type LoadableElementsNames = keyof LoadableElements;
10
+ export type LoadElementsOptions = {
11
+ /**
12
+ * An HTML element where the created element will be appended.
13
+ */
14
+ appendTo?: HTMLElement;
15
+ };
16
+ export type LoadElementsReturnType<T extends LoadableElementsNames> = Promise<{
17
+ event: Event;
18
+ element: LoadableElements[T];
19
+ }>;
20
+ /**
21
+ * Load the given source for the given type of element.
22
+ * @todo manage memo
23
+ */
24
+ export declare function loadElement<T extends LoadableElementsNames>(src: string, type: T, { appendTo }?: LoadElementsOptions): LoadElementsReturnType<T>;
25
+ /**
26
+ * Load the given source as an `<img>` element.
27
+ */
28
+ export declare function loadImage(src: string, options?: LoadElementsOptions): LoadElementsReturnType<"img">;
29
+ /**
30
+ * Load the given source as an `<iframe>` element.
31
+ */
32
+ export declare function loadIframe(src: string, options?: LoadElementsOptions): LoadElementsReturnType<"iframe">;
33
+ /**
34
+ * Load the given source as a `<link>` element.
35
+ */
36
+ export declare function loadLink(src: string, options?: LoadElementsOptions): LoadElementsReturnType<"link">;
37
+ /**
38
+ * Load the given source as a `<script>` element. The generated element is
39
+ * appended to `document.head` by default, as a script element needs
40
+ * to be inserted in the DOM to load.
41
+ */
42
+ export declare function loadScript(src: string, options?: LoadElementsOptions): LoadElementsReturnType<"script">;
@@ -0,0 +1,33 @@
1
+ function loadElement(src, type, { appendTo = null } = {}) {
2
+ return new Promise((resolve, reject) => {
3
+ const eventOptions = { once: true };
4
+ const prop = type === "link" ? "href" : "src";
5
+ const element = document.createElement(type);
6
+ element.addEventListener("load", (event) => resolve({ event, element }), eventOptions);
7
+ element.addEventListener("error", (event) => reject({ event, element }), eventOptions);
8
+ element[prop] = src;
9
+ if (appendTo) {
10
+ appendTo.append(element);
11
+ }
12
+ });
13
+ }
14
+ function loadImage(src, options) {
15
+ return loadElement(src, "img", options);
16
+ }
17
+ function loadIframe(src, options) {
18
+ return loadElement(src, "iframe", options);
19
+ }
20
+ function loadLink(src, options) {
21
+ return loadElement(src, "link", options);
22
+ }
23
+ function loadScript(src, options) {
24
+ return loadElement(src, "script", { appendTo: document.head, ...options });
25
+ }
26
+ export {
27
+ loadElement,
28
+ loadIframe,
29
+ loadImage,
30
+ loadLink,
31
+ loadScript
32
+ };
33
+ //# sourceMappingURL=loadElement.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../packages/js-toolkit/utils/loadElement.ts"],
4
+ "sourcesContent": ["export type LoadableElements = {\n embed: HTMLEmbedElement;\n iframe: HTMLIFrameElement;\n img: HTMLImageElement;\n link: HTMLLinkElement;\n script: HTMLScriptElement;\n track: HTMLTrackElement;\n};\n\nexport type LoadableElementsNames = keyof LoadableElements;\n\nexport type LoadElementsOptions = {\n /**\n * An HTML element where the created element will be appended.\n */\n appendTo?: HTMLElement;\n};\n\nexport type LoadElementsReturnType<T extends LoadableElementsNames> = Promise<{\n event: Event;\n element: LoadableElements[T];\n}>;\n\n/**\n * Load the given source for the given type of element.\n * @todo manage memo\n */\nexport function loadElement<T extends LoadableElementsNames>(\n src: string,\n type: T,\n { appendTo = null }: LoadElementsOptions = {},\n): LoadElementsReturnType<T> {\n return new Promise((resolve, reject) => {\n const eventOptions = { once: true };\n const prop = type === 'link' ? 'href' : 'src';\n const element = document.createElement(type);\n element.addEventListener('load', (event) => resolve({ event, element }), eventOptions);\n element.addEventListener('error', (event) => reject({ event, element }), eventOptions);\n element[prop] = src;\n if (appendTo) {\n appendTo.append(element);\n }\n });\n}\n\n/**\n * Load the given source as an `<img>` element.\n */\nexport function loadImage(src: string, options?: LoadElementsOptions) {\n return loadElement(src, 'img', options);\n}\n\n/**\n * Load the given source as an `<iframe>` element.\n */\nexport function loadIframe(src: string, options?: LoadElementsOptions) {\n return loadElement(src, 'iframe', options);\n}\n\n/**\n * Load the given source as a `<link>` element.\n */\nexport function loadLink(src: string, options?: LoadElementsOptions) {\n return loadElement(src, 'link', options);\n}\n\n/**\n * Load the given source as a `<script>` element. The generated element is\n * appended to `document.head` by default, as a script element needs\n * to be inserted in the DOM to load.\n */\nexport function loadScript(src: string, options?: LoadElementsOptions) {\n return loadElement(src, 'script', { appendTo: document.head, ...options });\n}\n"],
5
+ "mappings": "AA2BO,SAAS,YACd,KACA,MACA,EAAE,WAAW,KAAK,IAAyB,CAAC,GACjB;AAC3B,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,eAAe,EAAE,MAAM,KAAK;AAClC,UAAM,OAAO,SAAS,SAAS,SAAS;AACxC,UAAM,UAAU,SAAS,cAAc,IAAI;AAC3C,YAAQ,iBAAiB,QAAQ,CAAC,UAAU,QAAQ,EAAE,OAAO,QAAQ,CAAC,GAAG,YAAY;AACrF,YAAQ,iBAAiB,SAAS,CAAC,UAAU,OAAO,EAAE,OAAO,QAAQ,CAAC,GAAG,YAAY;AACrF,YAAQ,IAAI,IAAI;AAChB,QAAI,UAAU;AACZ,eAAS,OAAO,OAAO;AAAA,IACzB;AAAA,EACF,CAAC;AACH;AAKO,SAAS,UAAU,KAAa,SAA+B;AACpE,SAAO,YAAY,KAAK,OAAO,OAAO;AACxC;AAKO,SAAS,WAAW,KAAa,SAA+B;AACrE,SAAO,YAAY,KAAK,UAAU,OAAO;AAC3C;AAKO,SAAS,SAAS,KAAa,SAA+B;AACnE,SAAO,YAAY,KAAK,QAAQ,OAAO;AACzC;AAOO,SAAS,WAAW,KAAa,SAA+B;AACrE,SAAO,YAAY,KAAK,UAAU,EAAE,UAAU,SAAS,MAAM,GAAG,QAAQ,CAAC;AAC3E;",
6
+ "names": []
7
+ }
package/utils/tween.js CHANGED
@@ -2,7 +2,7 @@ import { cubicBezier } from "@motionone/easing";
2
2
  import { lerp, map, clamp01, damp, inertiaFinalValue } from "./math/index.js";
3
3
  import { isDefined, isArray, isNumber } from "./is.js";
4
4
  import { noop, noopValue as linear } from "./noop.js";
5
- import useRaf from "../services/raf.js";
5
+ import { useRaf } from "../services/index.js";
6
6
  let id = 0;
7
7
  const DEFAULT_PROGRESS_PRECISION = 1e-4;
8
8
  function normalizeEase(ease) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../packages/js-toolkit/utils/tween.ts"],
4
- "sourcesContent": ["import { cubicBezier } from '@motionone/easing';\nimport { lerp, map, clamp01, damp, inertiaFinalValue } from './math/index.js';\nimport { isDefined, isArray, isNumber } from './is.js';\nimport { noop, noopValue as linear } from './noop.js';\nimport useRaf from '../services/raf.js';\nimport type { EasingFunction } from './math/createEases.js';\n\nlet id = 0;\nconst DEFAULT_PROGRESS_PRECISION = 0.0001;\n\nexport type BezierCurve = [number, number, number, number];\n\n/**\n * Controls for a tween.\n */\nexport interface Tween {\n /**\n * Start the tween from the beginning.\n */\n start: () => void;\n /**\n * Finish the tween and set its state to the end.\n */\n finish: () => void;\n /**\n * Pause the tween.\n */\n pause: () => void;\n /**\n * Start the tween from the current paused progress.\n */\n play: () => void;\n /**\n * Set and get the tween's progress.\n */\n progress: (progress?: number) => number;\n}\n\nexport interface TweenOptions {\n /**\n * The duration, in seconds.\n * Defaults to `1`.\n */\n duration?: number;\n /**\n * The delay, in seconds.\n * Defaults to `0`.\n */\n delay?: number;\n /**\n * The easing function or bezier curve to use.\n * Defaults to a linear easing function.\n */\n easing?: EasingFunction | BezierCurve;\n /**\n * The smooth factor. Setting this option to `true` or a `number` will disable the `duration` option.\n */\n smooth?: true | number;\n /**\n * The precision for when to consider the tween finished.\n * Defaults to `0.0001`.\n */\n precision?: number;\n /**\n * A callback executed on start.\n */\n onStart?: (progress: number) => void;\n /**\n * A callback executed each time the progress is updated.\n */\n onProgress?: (progress: number) => void;\n /**\n * A callback executed when the tween is finished.\n */\n onFinish?: (progress: number) => void;\n}\n\n/**\n * Normalize a easing function with default fallbacks.\n */\nexport function normalizeEase(ease: EasingFunction | BezierCurve): EasingFunction {\n if (!isDefined(ease)) {\n return linear;\n }\n\n if (isArray(ease)) {\n return cubicBezier(...ease);\n }\n\n return ease;\n}\n\n/**\n * Tween from 0 to 1.\n */\nexport function tween(callback: (progress: number) => unknown, options: TweenOptions = {}): Tween {\n const raf = useRaf();\n\n let progressValue = 0;\n let easedProgress = 0;\n\n const isSmooth = isDefined(options.smooth) && (isNumber(options.smooth) || options.smooth);\n const smoothFactor = isNumber(options.smooth) ? options.smooth : 0.1;\n const precision = options.precision ?? DEFAULT_PROGRESS_PRECISION;\n const ease = normalizeEase(options.easing);\n\n let delay = options.delay ?? 0;\n delay *= 1000;\n let duration = options.duration ?? 1;\n duration *= 1000;\n\n /* eslint-disable @typescript-eslint/no-use-before-define */\n let startTime = getStartTime();\n let endTime = getEndTime(startTime);\n /* eslint-enable @typescript-eslint/no-use-before-define */\n\n const key = `tw-${id}`;\n id += 1;\n\n const { onStart = noop, onProgress = noop, onFinish = noop } = options;\n let isRunning = false;\n\n /**\n * Pause the animation.\n */\n function pause() {\n isRunning = false;\n raf.remove(key);\n }\n\n /**\n * Set the progress value.\n */\n function progress(newProgress: number) {\n if (!isDefined(newProgress)) {\n return easedProgress;\n }\n\n progressValue = newProgress;\n easedProgress = isSmooth\n ? damp(progressValue, easedProgress, smoothFactor, precision)\n : ease(progressValue);\n\n // Stop when reaching precision\n if (Math.abs(1 - easedProgress) < precision) {\n progressValue = 1;\n easedProgress = 1;\n }\n\n callback(easedProgress);\n onProgress(easedProgress);\n\n if (easedProgress === 1) {\n pause();\n requestAnimationFrame(() => onFinish(easedProgress));\n }\n\n return easedProgress;\n }\n\n /**\n * Loop for rendering the animation.\n */\n function tick(props: { time: number }) {\n progress(clamp01(map(props.time, startTime, endTime, 0, 1)));\n }\n\n function getStartTime() {\n return performance.now() + delay;\n }\n\n function getEndTime(time: number) {\n return isSmooth ? inertiaFinalValue(time, 1) : time + duration;\n }\n\n /**\n * Play the animation.\n */\n function start() {\n onStart(0);\n startTime = getStartTime();\n endTime = getEndTime(startTime);\n progressValue = 0;\n easedProgress = 0;\n isRunning = true;\n\n raf.add(key, tick);\n }\n\n /**\n * Play a paused animation.\n */\n function play() {\n if (isRunning) {\n return;\n }\n\n startTime = getStartTime() - lerp(0, duration, progressValue);\n endTime = getEndTime(startTime);\n isRunning = true;\n\n raf.add(key, tick);\n }\n\n return {\n start,\n finish: () => progress(1),\n pause,\n play,\n progress,\n };\n}\n"],
5
- "mappings": "AAAA,SAAS,mBAAmB;AAC5B,SAAS,MAAM,KAAK,SAAS,MAAM,yBAAyB;AAC5D,SAAS,WAAW,SAAS,gBAAgB;AAC7C,SAAS,MAAM,aAAa,cAAc;AAC1C,OAAO,YAAY;AAGnB,IAAI,KAAK;AACT,MAAM,6BAA6B;AAwE5B,SAAS,cAAc,MAAoD;AAChF,MAAI,CAAC,UAAU,IAAI,GAAG;AACpB,WAAO;AAAA,EACT;AAEA,MAAI,QAAQ,IAAI,GAAG;AACjB,WAAO,YAAY,GAAG,IAAI;AAAA,EAC5B;AAEA,SAAO;AACT;AAKO,SAAS,MAAM,UAAyC,UAAwB,CAAC,GAAU;AAChG,QAAM,MAAM,OAAO;AAEnB,MAAI,gBAAgB;AACpB,MAAI,gBAAgB;AAEpB,QAAM,WAAW,UAAU,QAAQ,MAAM,MAAM,SAAS,QAAQ,MAAM,KAAK,QAAQ;AACnF,QAAM,eAAe,SAAS,QAAQ,MAAM,IAAI,QAAQ,SAAS;AACjE,QAAM,YAAY,QAAQ,aAAa;AACvC,QAAM,OAAO,cAAc,QAAQ,MAAM;AAEzC,MAAI,QAAQ,QAAQ,SAAS;AAC7B,WAAS;AACT,MAAI,WAAW,QAAQ,YAAY;AACnC,cAAY;AAGZ,MAAI,YAAY,aAAa;AAC7B,MAAI,UAAU,WAAW,SAAS;AAGlC,QAAM,MAAM,MAAM,EAAE;AACpB,QAAM;AAEN,QAAM,EAAE,UAAU,MAAM,aAAa,MAAM,WAAW,KAAK,IAAI;AAC/D,MAAI,YAAY;AAKhB,WAAS,QAAQ;AACf,gBAAY;AACZ,QAAI,OAAO,GAAG;AAAA,EAChB;AAKA,WAAS,SAAS,aAAqB;AACrC,QAAI,CAAC,UAAU,WAAW,GAAG;AAC3B,aAAO;AAAA,IACT;AAEA,oBAAgB;AAChB,oBAAgB,WACZ,KAAK,eAAe,eAAe,cAAc,SAAS,IAC1D,KAAK,aAAa;AAGtB,QAAI,KAAK,IAAI,IAAI,aAAa,IAAI,WAAW;AAC3C,sBAAgB;AAChB,sBAAgB;AAAA,IAClB;AAEA,aAAS,aAAa;AACtB,eAAW,aAAa;AAExB,QAAI,kBAAkB,GAAG;AACvB,YAAM;AACN,4BAAsB,MAAM,SAAS,aAAa,CAAC;AAAA,IACrD;AAEA,WAAO;AAAA,EACT;AAKA,WAAS,KAAK,OAAyB;AACrC,aAAS,QAAQ,IAAI,MAAM,MAAM,WAAW,SAAS,GAAG,CAAC,CAAC,CAAC;AAAA,EAC7D;AAEA,WAAS,eAAe;AACtB,WAAO,YAAY,IAAI,IAAI;AAAA,EAC7B;AAEA,WAAS,WAAW,MAAc;AAChC,WAAO,WAAW,kBAAkB,MAAM,CAAC,IAAI,OAAO;AAAA,EACxD;AAKA,WAAS,QAAQ;AACf,YAAQ,CAAC;AACT,gBAAY,aAAa;AACzB,cAAU,WAAW,SAAS;AAC9B,oBAAgB;AAChB,oBAAgB;AAChB,gBAAY;AAEZ,QAAI,IAAI,KAAK,IAAI;AAAA,EACnB;AAKA,WAAS,OAAO;AACd,QAAI,WAAW;AACb;AAAA,IACF;AAEA,gBAAY,aAAa,IAAI,KAAK,GAAG,UAAU,aAAa;AAC5D,cAAU,WAAW,SAAS;AAC9B,gBAAY;AAEZ,QAAI,IAAI,KAAK,IAAI;AAAA,EACnB;AAEA,SAAO;AAAA,IACL;AAAA,IACA,QAAQ,MAAM,SAAS,CAAC;AAAA,IACxB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["import { cubicBezier } from '@motionone/easing';\nimport { lerp, map, clamp01, damp, inertiaFinalValue } from './math/index.js';\nimport { isDefined, isArray, isNumber } from './is.js';\nimport { noop, noopValue as linear } from './noop.js';\nimport { useRaf } from '../services/index.js';\nimport type { EasingFunction } from './math/createEases.js';\n\nlet id = 0;\nconst DEFAULT_PROGRESS_PRECISION = 0.0001;\n\nexport type BezierCurve = [number, number, number, number];\n\n/**\n * Controls for a tween.\n */\nexport interface Tween {\n /**\n * Start the tween from the beginning.\n */\n start: () => void;\n /**\n * Finish the tween and set its state to the end.\n */\n finish: () => void;\n /**\n * Pause the tween.\n */\n pause: () => void;\n /**\n * Start the tween from the current paused progress.\n */\n play: () => void;\n /**\n * Set and get the tween's progress.\n */\n progress: (progress?: number) => number;\n}\n\nexport interface TweenOptions {\n /**\n * The duration, in seconds.\n * Defaults to `1`.\n */\n duration?: number;\n /**\n * The delay, in seconds.\n * Defaults to `0`.\n */\n delay?: number;\n /**\n * The easing function or bezier curve to use.\n * Defaults to a linear easing function.\n */\n easing?: EasingFunction | BezierCurve;\n /**\n * The smooth factor. Setting this option to `true` or a `number` will disable the `duration` option.\n */\n smooth?: true | number;\n /**\n * The precision for when to consider the tween finished.\n * Defaults to `0.0001`.\n */\n precision?: number;\n /**\n * A callback executed on start.\n */\n onStart?: (progress: number) => void;\n /**\n * A callback executed each time the progress is updated.\n */\n onProgress?: (progress: number) => void;\n /**\n * A callback executed when the tween is finished.\n */\n onFinish?: (progress: number) => void;\n}\n\n/**\n * Normalize a easing function with default fallbacks.\n */\nexport function normalizeEase(ease: EasingFunction | BezierCurve): EasingFunction {\n if (!isDefined(ease)) {\n return linear;\n }\n\n if (isArray(ease)) {\n return cubicBezier(...ease);\n }\n\n return ease;\n}\n\n/**\n * Tween from 0 to 1.\n */\nexport function tween(callback: (progress: number) => unknown, options: TweenOptions = {}): Tween {\n const raf = useRaf();\n\n let progressValue = 0;\n let easedProgress = 0;\n\n const isSmooth = isDefined(options.smooth) && (isNumber(options.smooth) || options.smooth);\n const smoothFactor = isNumber(options.smooth) ? options.smooth : 0.1;\n const precision = options.precision ?? DEFAULT_PROGRESS_PRECISION;\n const ease = normalizeEase(options.easing);\n\n let delay = options.delay ?? 0;\n delay *= 1000;\n let duration = options.duration ?? 1;\n duration *= 1000;\n\n /* eslint-disable @typescript-eslint/no-use-before-define */\n let startTime = getStartTime();\n let endTime = getEndTime(startTime);\n /* eslint-enable @typescript-eslint/no-use-before-define */\n\n const key = `tw-${id}`;\n id += 1;\n\n const { onStart = noop, onProgress = noop, onFinish = noop } = options;\n let isRunning = false;\n\n /**\n * Pause the animation.\n */\n function pause() {\n isRunning = false;\n raf.remove(key);\n }\n\n /**\n * Set the progress value.\n */\n function progress(newProgress: number) {\n if (!isDefined(newProgress)) {\n return easedProgress;\n }\n\n progressValue = newProgress;\n easedProgress = isSmooth\n ? damp(progressValue, easedProgress, smoothFactor, precision)\n : ease(progressValue);\n\n // Stop when reaching precision\n if (Math.abs(1 - easedProgress) < precision) {\n progressValue = 1;\n easedProgress = 1;\n }\n\n callback(easedProgress);\n onProgress(easedProgress);\n\n if (easedProgress === 1) {\n pause();\n requestAnimationFrame(() => onFinish(easedProgress));\n }\n\n return easedProgress;\n }\n\n /**\n * Loop for rendering the animation.\n */\n function tick(props: { time: number }) {\n progress(clamp01(map(props.time, startTime, endTime, 0, 1)));\n }\n\n function getStartTime() {\n return performance.now() + delay;\n }\n\n function getEndTime(time: number) {\n return isSmooth ? inertiaFinalValue(time, 1) : time + duration;\n }\n\n /**\n * Play the animation.\n */\n function start() {\n onStart(0);\n startTime = getStartTime();\n endTime = getEndTime(startTime);\n progressValue = 0;\n easedProgress = 0;\n isRunning = true;\n\n raf.add(key, tick);\n }\n\n /**\n * Play a paused animation.\n */\n function play() {\n if (isRunning) {\n return;\n }\n\n startTime = getStartTime() - lerp(0, duration, progressValue);\n endTime = getEndTime(startTime);\n isRunning = true;\n\n raf.add(key, tick);\n }\n\n return {\n start,\n finish: () => progress(1),\n pause,\n play,\n progress,\n };\n}\n"],
5
+ "mappings": "AAAA,SAAS,mBAAmB;AAC5B,SAAS,MAAM,KAAK,SAAS,MAAM,yBAAyB;AAC5D,SAAS,WAAW,SAAS,gBAAgB;AAC7C,SAAS,MAAM,aAAa,cAAc;AAC1C,SAAS,cAAc;AAGvB,IAAI,KAAK;AACT,MAAM,6BAA6B;AAwE5B,SAAS,cAAc,MAAoD;AAChF,MAAI,CAAC,UAAU,IAAI,GAAG;AACpB,WAAO;AAAA,EACT;AAEA,MAAI,QAAQ,IAAI,GAAG;AACjB,WAAO,YAAY,GAAG,IAAI;AAAA,EAC5B;AAEA,SAAO;AACT;AAKO,SAAS,MAAM,UAAyC,UAAwB,CAAC,GAAU;AAChG,QAAM,MAAM,OAAO;AAEnB,MAAI,gBAAgB;AACpB,MAAI,gBAAgB;AAEpB,QAAM,WAAW,UAAU,QAAQ,MAAM,MAAM,SAAS,QAAQ,MAAM,KAAK,QAAQ;AACnF,QAAM,eAAe,SAAS,QAAQ,MAAM,IAAI,QAAQ,SAAS;AACjE,QAAM,YAAY,QAAQ,aAAa;AACvC,QAAM,OAAO,cAAc,QAAQ,MAAM;AAEzC,MAAI,QAAQ,QAAQ,SAAS;AAC7B,WAAS;AACT,MAAI,WAAW,QAAQ,YAAY;AACnC,cAAY;AAGZ,MAAI,YAAY,aAAa;AAC7B,MAAI,UAAU,WAAW,SAAS;AAGlC,QAAM,MAAM,MAAM,EAAE;AACpB,QAAM;AAEN,QAAM,EAAE,UAAU,MAAM,aAAa,MAAM,WAAW,KAAK,IAAI;AAC/D,MAAI,YAAY;AAKhB,WAAS,QAAQ;AACf,gBAAY;AACZ,QAAI,OAAO,GAAG;AAAA,EAChB;AAKA,WAAS,SAAS,aAAqB;AACrC,QAAI,CAAC,UAAU,WAAW,GAAG;AAC3B,aAAO;AAAA,IACT;AAEA,oBAAgB;AAChB,oBAAgB,WACZ,KAAK,eAAe,eAAe,cAAc,SAAS,IAC1D,KAAK,aAAa;AAGtB,QAAI,KAAK,IAAI,IAAI,aAAa,IAAI,WAAW;AAC3C,sBAAgB;AAChB,sBAAgB;AAAA,IAClB;AAEA,aAAS,aAAa;AACtB,eAAW,aAAa;AAExB,QAAI,kBAAkB,GAAG;AACvB,YAAM;AACN,4BAAsB,MAAM,SAAS,aAAa,CAAC;AAAA,IACrD;AAEA,WAAO;AAAA,EACT;AAKA,WAAS,KAAK,OAAyB;AACrC,aAAS,QAAQ,IAAI,MAAM,MAAM,WAAW,SAAS,GAAG,CAAC,CAAC,CAAC;AAAA,EAC7D;AAEA,WAAS,eAAe;AACtB,WAAO,YAAY,IAAI,IAAI;AAAA,EAC7B;AAEA,WAAS,WAAW,MAAc;AAChC,WAAO,WAAW,kBAAkB,MAAM,CAAC,IAAI,OAAO;AAAA,EACxD;AAKA,WAAS,QAAQ;AACf,YAAQ,CAAC;AACT,gBAAY,aAAa;AACzB,cAAU,WAAW,SAAS;AAC9B,oBAAgB;AAChB,oBAAgB;AAChB,gBAAY;AAEZ,QAAI,IAAI,KAAK,IAAI;AAAA,EACnB;AAKA,WAAS,OAAO;AACd,QAAI,WAAW;AACb;AAAA,IACF;AAEA,gBAAY,aAAa,IAAI,KAAK,GAAG,UAAU,aAAa;AAC5D,cAAU,WAAW,SAAS;AAC9B,gBAAY;AAEZ,QAAI,IAAI,KAAK,IAAI;AAAA,EACnB;AAEA,SAAO;AAAA,IACL;AAAA,IACA,QAAQ,MAAM,SAAS,CAAC;AAAA,IACxB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;",
6
6
  "names": []
7
7
  }
@@ -1,75 +0,0 @@
1
- import type { ServiceInterface } from './index.js';
2
- export type DragService = ServiceInterface<DragServiceProps>;
3
- type DragLifecycle = 'start' | 'drag' | 'drop' | 'inertia' | 'stop';
4
- export interface DragServiceProps {
5
- /**
6
- * The current mode of the dragging logic.
7
- */
8
- mode: DragLifecycle;
9
- /**
10
- * The target element of the drag.
11
- */
12
- target: HTMLElement;
13
- /**
14
- * Whether the user is currently grabbing the targeted element or not.
15
- */
16
- isGrabbing: boolean;
17
- /**
18
- * Whether the drag currently has inertia or not.
19
- */
20
- hasInertia: boolean;
21
- /**
22
- * The current horizontal position in the viewport.
23
- */
24
- x: number;
25
- /**
26
- * The current vertical position in the viewport.
27
- */
28
- y: number;
29
- /**
30
- * The delta between the current position and the last.
31
- */
32
- delta: {
33
- x: number;
34
- y: number;
35
- };
36
- /**
37
- * The initial position where the dragging started.
38
- */
39
- origin: {
40
- x: number;
41
- y: number;
42
- };
43
- /**
44
- * The distance from the current position to the origin.
45
- */
46
- distance: {
47
- x: number;
48
- y: number;
49
- };
50
- /**
51
- * The final position that will be reached at the end of the inertia.
52
- */
53
- final: {
54
- x: number;
55
- y: number;
56
- };
57
- }
58
- export interface DragServiceOptions {
59
- dampFactor?: number;
60
- dragTreshold?: number;
61
- }
62
- /**
63
- * Use the drag service.
64
- *
65
- * ```js
66
- * import { useDrag } from '@studiometa/js-toolkit/services';
67
- * const { add, remove, props } = useDrag();
68
- * const draggableElement = document.querySelector('.draggable');
69
- * add(draggableElement, (props) => {}, { factor: 0.8 });
70
- * remove(draggableElement);
71
- * props(draggableElement);
72
- * ```
73
- */
74
- export default function useDrag(target: HTMLElement, options: DragServiceOptions): DragService;
75
- export {};
package/services/drag.js DELETED
@@ -1,199 +0,0 @@
1
- import { useService } from "./service.js";
2
- import useRaf from "./raf.js";
3
- import inertiaFinalValue from "../utils/math/inertiaFinalValue.js";
4
- import { isDefined } from "../utils/index.js";
5
- const MODES = {
6
- START: "start",
7
- DRAG: "drag",
8
- DROP: "drop",
9
- INERTIA: "inertia",
10
- STOP: "stop"
11
- };
12
- let count = 0;
13
- const targetEvents = ["pointerdown"];
14
- const windowEvents = ["pointerup", "touchend"];
15
- const passiveEventOptions = { passive: true };
16
- function getEventPosition(event) {
17
- const eventOrTouch = isDefined(event.touches) ? event.touches[0] : event;
18
- return {
19
- x: eventOrTouch.clientX,
20
- y: eventOrTouch.clientY
21
- };
22
- }
23
- function createDragService(target, { dampFactor = 0.85, dragTreshold = 10 } = {}) {
24
- count += 1;
25
- const id = `drag-${count}`;
26
- let previousEvent;
27
- function shouldPreventClick() {
28
- return Math.abs(props.distance.x) > dragTreshold || Math.abs(props.distance.y) > dragTreshold;
29
- }
30
- function start(x, y) {
31
- if (props.isGrabbing) {
32
- return;
33
- }
34
- props.x = x;
35
- props.y = y;
36
- props.origin.x = x;
37
- props.origin.y = y;
38
- props.delta.x = 0;
39
- props.delta.y = 0;
40
- props.distance.x = 0;
41
- props.distance.y = 0;
42
- props.final.x = x;
43
- props.final.y = y;
44
- props.mode = MODES.START;
45
- props.isGrabbing = true;
46
- trigger(props);
47
- document.addEventListener("touchmove", handleEvent, passiveEventOptions);
48
- document.addEventListener("mousemove", handleEvent, passiveEventOptions);
49
- }
50
- function drop() {
51
- document.removeEventListener("touchmove", handleEvent);
52
- document.removeEventListener("mousemove", handleEvent);
53
- props.isGrabbing = false;
54
- props.mode = MODES.DROP;
55
- props.hasInertia = true;
56
- props.final.x = inertiaFinalValue(props.x, props.delta.x, dampFactor);
57
- props.final.y = inertiaFinalValue(props.y, props.delta.y, dampFactor);
58
- trigger(props);
59
- setTimeout(() => {
60
- const raf = useRaf();
61
- raf.remove(id);
62
- raf.add(id, rafHandler);
63
- }, 0);
64
- }
65
- function stop() {
66
- useRaf().remove(id);
67
- props.isGrabbing = false;
68
- props.hasInertia = false;
69
- props.mode = MODES.STOP;
70
- trigger(props);
71
- }
72
- function rafHandler() {
73
- if (!props.isGrabbing) {
74
- props.x += props.delta.x;
75
- props.y += props.delta.y;
76
- props.distance.x = props.x - props.origin.x;
77
- props.distance.y = props.y - props.origin.y;
78
- props.delta.x *= dampFactor;
79
- props.delta.y *= dampFactor;
80
- if (props.mode !== MODES.INERTIA) {
81
- props.mode = MODES.INERTIA;
82
- }
83
- trigger(props);
84
- if (Math.abs(props.delta.x) < 0.1 && Math.abs(props.delta.y) < 0.1) {
85
- stop();
86
- }
87
- }
88
- }
89
- function drag(event) {
90
- if (props.isGrabbing) {
91
- const position = getEventPosition(event);
92
- props.x = position.x;
93
- props.y = position.y;
94
- if (previousEvent) {
95
- const previousPosition = getEventPosition(previousEvent);
96
- props.delta.x = position.x - previousPosition.x;
97
- props.delta.y = position.y - previousPosition.y;
98
- }
99
- props.final.x = position.x;
100
- props.final.y = position.y;
101
- props.distance.x = props.x - props.origin.x;
102
- props.distance.y = props.y - props.origin.y;
103
- if (props.mode !== MODES.DRAG) {
104
- props.mode = MODES.DRAG;
105
- }
106
- trigger(props);
107
- previousEvent = event;
108
- }
109
- }
110
- function handleEvent(event) {
111
- switch (event.type) {
112
- case "dragstart":
113
- event.preventDefault();
114
- break;
115
- case "click":
116
- if (shouldPreventClick()) {
117
- event.stopImmediatePropagation();
118
- event.stopPropagation();
119
- event.preventDefault();
120
- }
121
- break;
122
- case "pointerup":
123
- case "touchend":
124
- drop();
125
- break;
126
- case "touchmove":
127
- case "mousemove":
128
- drag(event);
129
- break;
130
- default:
131
- if (event.button === 0) {
132
- start(event.x, event.y);
133
- }
134
- }
135
- }
136
- const { add, remove, has, trigger, props } = useService({
137
- props: {
138
- target,
139
- mode: void 0,
140
- isGrabbing: false,
141
- hasInertia: false,
142
- x: 0,
143
- y: 0,
144
- delta: {
145
- x: 0,
146
- y: 0
147
- },
148
- origin: {
149
- x: 0,
150
- y: 0
151
- },
152
- distance: {
153
- x: 0,
154
- y: 0
155
- },
156
- final: {
157
- x: 0,
158
- y: 0
159
- }
160
- },
161
- init() {
162
- for (const event of targetEvents) {
163
- target.addEventListener(event, handleEvent, passiveEventOptions);
164
- }
165
- for (const event of windowEvents) {
166
- window.addEventListener(event, handleEvent, passiveEventOptions);
167
- }
168
- target.addEventListener("dragstart", handleEvent, { capture: true });
169
- target.addEventListener("click", handleEvent, { capture: true });
170
- },
171
- kill() {
172
- for (const event of targetEvents) {
173
- target.removeEventListener(event, handleEvent);
174
- }
175
- for (const event of windowEvents) {
176
- window.removeEventListener(event, handleEvent);
177
- }
178
- target.removeEventListener("dragstart", handleEvent);
179
- target.removeEventListener("click", handleEvent);
180
- }
181
- });
182
- return {
183
- add,
184
- remove,
185
- has,
186
- props: () => props
187
- };
188
- }
189
- const instances = /* @__PURE__ */ new WeakMap();
190
- function useDrag(target, options) {
191
- if (!instances.has(target)) {
192
- instances.set(target, createDragService(target, options));
193
- }
194
- return instances.get(target);
195
- }
196
- export {
197
- useDrag as default
198
- };
199
- //# sourceMappingURL=drag.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../packages/js-toolkit/services/drag.ts"],
4
- "sourcesContent": ["/* eslint-disable no-use-before-define, @typescript-eslint/no-use-before-define */\nimport { useService } from './service.js';\nimport useRaf from './raf.js';\nimport inertiaFinalValue from '../utils/math/inertiaFinalValue.js';\nimport { isDefined } from '../utils/index.js';\nimport type { ServiceInterface } from './index.js';\n\nexport type DragService = ServiceInterface<DragServiceProps>;\n\ntype DragLifecycle = 'start' | 'drag' | 'drop' | 'inertia' | 'stop';\n\nexport interface DragServiceProps {\n /**\n * The current mode of the dragging logic.\n */\n mode: DragLifecycle;\n /**\n * The target element of the drag.\n */\n target: HTMLElement;\n /**\n * Whether the user is currently grabbing the targeted element or not.\n */\n isGrabbing: boolean;\n /**\n * Whether the drag currently has inertia or not.\n */\n hasInertia: boolean;\n /**\n * The current horizontal position in the viewport.\n */\n x: number;\n /**\n * The current vertical position in the viewport.\n */\n y: number;\n /**\n * The delta between the current position and the last.\n */\n delta: { x: number; y: number };\n /**\n * The initial position where the dragging started.\n */\n origin: { x: number; y: number };\n /**\n * The distance from the current position to the origin.\n */\n distance: { x: number; y: number };\n /**\n * The final position that will be reached at the end of the inertia.\n */\n final: { x: number; y: number };\n}\n\nexport interface DragServiceOptions {\n dampFactor?: number;\n dragTreshold?: number;\n}\n\nconst MODES: Record<Uppercase<DragLifecycle>, DragLifecycle> = {\n START: 'start',\n DRAG: 'drag',\n DROP: 'drop',\n INERTIA: 'inertia',\n STOP: 'stop',\n};\n\nlet count = 0;\nconst targetEvents = ['pointerdown'];\nconst windowEvents = ['pointerup', 'touchend'];\nconst passiveEventOptions = { passive: true };\n\n/**\n * Get the client value for the given axis.\n */\nfunction getEventPosition(event: MouseEvent | TouchEvent): { x: number; y: number } {\n // @ts-ignore\n const eventOrTouch = isDefined(event.touches) ? event.touches[0] : event;\n return {\n x: eventOrTouch.clientX,\n y: eventOrTouch.clientY,\n };\n}\n\n/**\n * Get drag service.\n */\nfunction createDragService(\n target: HTMLElement,\n { dampFactor = 0.85, dragTreshold = 10 }: DragServiceOptions = {},\n): DragService {\n count += 1;\n const id = `drag-${count}`;\n let previousEvent;\n\n /**\n * Test if we should allow click on links and buttons.\n */\n function shouldPreventClick(): boolean {\n return Math.abs(props.distance.x) > dragTreshold || Math.abs(props.distance.y) > dragTreshold;\n }\n\n /**\n * Start the drag.\n *\n * @param {number} x The initial horizontal position.\n * @param {number} y The initial vertical position.\n * @returns {void}\n */\n function start(x: number, y: number) {\n if (props.isGrabbing) {\n return;\n }\n\n // Reset state\n props.x = x;\n props.y = y;\n props.origin.x = x;\n props.origin.y = y;\n props.delta.x = 0;\n props.delta.y = 0;\n props.distance.x = 0;\n props.distance.y = 0;\n props.final.x = x;\n props.final.y = y;\n\n props.mode = MODES.START;\n\n // Enable grabbing\n props.isGrabbing = true;\n\n trigger(props);\n\n document.addEventListener('touchmove', handleEvent, passiveEventOptions);\n document.addEventListener('mousemove', handleEvent, passiveEventOptions);\n }\n\n /**\n * Stop the drag, or drop.\n */\n function drop() {\n document.removeEventListener('touchmove', handleEvent);\n document.removeEventListener('mousemove', handleEvent);\n props.isGrabbing = false;\n props.mode = MODES.DROP;\n\n props.hasInertia = true;\n props.final.x = inertiaFinalValue(props.x, props.delta.x, dampFactor);\n props.final.y = inertiaFinalValue(props.y, props.delta.y, dampFactor);\n\n trigger(props);\n\n setTimeout(() => {\n const raf = useRaf();\n raf.remove(id);\n raf.add(id, rafHandler);\n }, 0);\n }\n\n /**\n * Stop the drag.\n */\n function stop() {\n useRaf().remove(id);\n props.isGrabbing = false;\n props.hasInertia = false;\n props.mode = MODES.STOP;\n trigger(props);\n }\n\n /**\n * Raf service handler.\n */\n function rafHandler() {\n if (!props.isGrabbing) {\n props.x += props.delta.x;\n props.y += props.delta.y;\n props.distance.x = props.x - props.origin.x;\n props.distance.y = props.y - props.origin.y;\n\n props.delta.x *= dampFactor;\n props.delta.y *= dampFactor;\n\n if (props.mode !== MODES.INERTIA) {\n props.mode = MODES.INERTIA;\n }\n\n trigger(props);\n\n if (Math.abs(props.delta.x) < 0.1 && Math.abs(props.delta.y) < 0.1) {\n stop();\n }\n }\n }\n\n /**\n * Pointer service handler.\n */\n function drag(event: TouchEvent | MouseEvent) {\n if (props.isGrabbing) {\n const position = getEventPosition(event);\n props.x = position.x;\n props.y = position.y;\n\n if (previousEvent) {\n const previousPosition = getEventPosition(previousEvent);\n props.delta.x = position.x - previousPosition.x;\n props.delta.y = position.y - previousPosition.y;\n }\n\n props.final.x = position.x;\n props.final.y = position.y;\n props.distance.x = props.x - props.origin.x;\n props.distance.y = props.y - props.origin.y;\n\n if (props.mode !== MODES.DRAG) {\n props.mode = MODES.DRAG;\n }\n\n trigger(props);\n previousEvent = event;\n }\n }\n\n /**\n * Handle any event.\n */\n function handleEvent(event: MouseEvent | PointerEvent | DragEvent) {\n switch (event.type) {\n case 'dragstart':\n event.preventDefault();\n break;\n case 'click':\n if (shouldPreventClick()) {\n event.stopImmediatePropagation();\n event.stopPropagation();\n event.preventDefault();\n }\n break;\n case 'pointerup':\n case 'touchend':\n drop();\n break;\n case 'touchmove':\n case 'mousemove':\n drag(event);\n break;\n default:\n if (event.button === 0) {\n start(event.x, event.y);\n }\n }\n }\n\n const { add, remove, has, trigger, props } = useService({\n props: {\n target,\n mode: undefined,\n isGrabbing: false,\n hasInertia: false,\n x: 0,\n y: 0,\n delta: {\n x: 0,\n y: 0,\n },\n origin: {\n x: 0,\n y: 0,\n },\n distance: {\n x: 0,\n y: 0,\n },\n final: {\n x: 0,\n y: 0,\n },\n } as DragServiceProps,\n init() {\n for (const event of targetEvents) {\n target.addEventListener(event, handleEvent, passiveEventOptions);\n }\n for (const event of windowEvents) {\n window.addEventListener(event, handleEvent, passiveEventOptions);\n }\n target.addEventListener('dragstart', handleEvent, { capture: true });\n target.addEventListener('click', handleEvent, { capture: true });\n },\n kill() {\n for (const event of targetEvents) {\n target.removeEventListener(event, handleEvent);\n }\n for (const event of windowEvents) {\n window.removeEventListener(event, handleEvent);\n }\n target.removeEventListener('dragstart', handleEvent);\n target.removeEventListener('click', handleEvent);\n },\n });\n\n return {\n add,\n remove,\n has,\n props: () => props,\n };\n}\n\nconst instances: WeakMap<HTMLElement, DragService | undefined> = new WeakMap();\n\n/**\n * Use the drag service.\n *\n * ```js\n * import { useDrag } from '@studiometa/js-toolkit/services';\n * const { add, remove, props } = useDrag();\n * const draggableElement = document.querySelector('.draggable');\n * add(draggableElement, (props) => {}, { factor: 0.8 });\n * remove(draggableElement);\n * props(draggableElement);\n * ```\n */\nexport default function useDrag(target: HTMLElement, options: DragServiceOptions): DragService {\n if (!instances.has(target)) {\n instances.set(target, createDragService(target, options));\n }\n\n return instances.get(target);\n}\n"],
5
- "mappings": "AACA,SAAS,kBAAkB;AAC3B,OAAO,YAAY;AACnB,OAAO,uBAAuB;AAC9B,SAAS,iBAAiB;AAuD1B,MAAM,QAAyD;AAAA,EAC7D,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,SAAS;AAAA,EACT,MAAM;AACR;AAEA,IAAI,QAAQ;AACZ,MAAM,eAAe,CAAC,aAAa;AACnC,MAAM,eAAe,CAAC,aAAa,UAAU;AAC7C,MAAM,sBAAsB,EAAE,SAAS,KAAK;AAK5C,SAAS,iBAAiB,OAA0D;AAElF,QAAM,eAAe,UAAU,MAAM,OAAO,IAAI,MAAM,QAAQ,CAAC,IAAI;AACnE,SAAO;AAAA,IACL,GAAG,aAAa;AAAA,IAChB,GAAG,aAAa;AAAA,EAClB;AACF;AAKA,SAAS,kBACP,QACA,EAAE,aAAa,MAAM,eAAe,GAAG,IAAwB,CAAC,GACnD;AACb,WAAS;AACT,QAAM,KAAK,QAAQ,KAAK;AACxB,MAAI;AAKJ,WAAS,qBAA8B;AACrC,WAAO,KAAK,IAAI,MAAM,SAAS,CAAC,IAAI,gBAAgB,KAAK,IAAI,MAAM,SAAS,CAAC,IAAI;AAAA,EACnF;AASA,WAAS,MAAM,GAAW,GAAW;AACnC,QAAI,MAAM,YAAY;AACpB;AAAA,IACF;AAGA,UAAM,IAAI;AACV,UAAM,IAAI;AACV,UAAM,OAAO,IAAI;AACjB,UAAM,OAAO,IAAI;AACjB,UAAM,MAAM,IAAI;AAChB,UAAM,MAAM,IAAI;AAChB,UAAM,SAAS,IAAI;AACnB,UAAM,SAAS,IAAI;AACnB,UAAM,MAAM,IAAI;AAChB,UAAM,MAAM,IAAI;AAEhB,UAAM,OAAO,MAAM;AAGnB,UAAM,aAAa;AAEnB,YAAQ,KAAK;AAEb,aAAS,iBAAiB,aAAa,aAAa,mBAAmB;AACvE,aAAS,iBAAiB,aAAa,aAAa,mBAAmB;AAAA,EACzE;AAKA,WAAS,OAAO;AACd,aAAS,oBAAoB,aAAa,WAAW;AACrD,aAAS,oBAAoB,aAAa,WAAW;AACrD,UAAM,aAAa;AACnB,UAAM,OAAO,MAAM;AAEnB,UAAM,aAAa;AACnB,UAAM,MAAM,IAAI,kBAAkB,MAAM,GAAG,MAAM,MAAM,GAAG,UAAU;AACpE,UAAM,MAAM,IAAI,kBAAkB,MAAM,GAAG,MAAM,MAAM,GAAG,UAAU;AAEpE,YAAQ,KAAK;AAEb,eAAW,MAAM;AACf,YAAM,MAAM,OAAO;AACnB,UAAI,OAAO,EAAE;AACb,UAAI,IAAI,IAAI,UAAU;AAAA,IACxB,GAAG,CAAC;AAAA,EACN;AAKA,WAAS,OAAO;AACd,WAAO,EAAE,OAAO,EAAE;AAClB,UAAM,aAAa;AACnB,UAAM,aAAa;AACnB,UAAM,OAAO,MAAM;AACnB,YAAQ,KAAK;AAAA,EACf;AAKA,WAAS,aAAa;AACpB,QAAI,CAAC,MAAM,YAAY;AACrB,YAAM,KAAK,MAAM,MAAM;AACvB,YAAM,KAAK,MAAM,MAAM;AACvB,YAAM,SAAS,IAAI,MAAM,IAAI,MAAM,OAAO;AAC1C,YAAM,SAAS,IAAI,MAAM,IAAI,MAAM,OAAO;AAE1C,YAAM,MAAM,KAAK;AACjB,YAAM,MAAM,KAAK;AAEjB,UAAI,MAAM,SAAS,MAAM,SAAS;AAChC,cAAM,OAAO,MAAM;AAAA,MACrB;AAEA,cAAQ,KAAK;AAEb,UAAI,KAAK,IAAI,MAAM,MAAM,CAAC,IAAI,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC,IAAI,KAAK;AAClE,aAAK;AAAA,MACP;AAAA,IACF;AAAA,EACF;AAKA,WAAS,KAAK,OAAgC;AAC5C,QAAI,MAAM,YAAY;AACpB,YAAM,WAAW,iBAAiB,KAAK;AACvC,YAAM,IAAI,SAAS;AACnB,YAAM,IAAI,SAAS;AAEnB,UAAI,eAAe;AACjB,cAAM,mBAAmB,iBAAiB,aAAa;AACvD,cAAM,MAAM,IAAI,SAAS,IAAI,iBAAiB;AAC9C,cAAM,MAAM,IAAI,SAAS,IAAI,iBAAiB;AAAA,MAChD;AAEA,YAAM,MAAM,IAAI,SAAS;AACzB,YAAM,MAAM,IAAI,SAAS;AACzB,YAAM,SAAS,IAAI,MAAM,IAAI,MAAM,OAAO;AAC1C,YAAM,SAAS,IAAI,MAAM,IAAI,MAAM,OAAO;AAE1C,UAAI,MAAM,SAAS,MAAM,MAAM;AAC7B,cAAM,OAAO,MAAM;AAAA,MACrB;AAEA,cAAQ,KAAK;AACb,sBAAgB;AAAA,IAClB;AAAA,EACF;AAKA,WAAS,YAAY,OAA8C;AACjE,YAAQ,MAAM,MAAM;AAAA,MAClB,KAAK;AACH,cAAM,eAAe;AACrB;AAAA,MACF,KAAK;AACH,YAAI,mBAAmB,GAAG;AACxB,gBAAM,yBAAyB;AAC/B,gBAAM,gBAAgB;AACtB,gBAAM,eAAe;AAAA,QACvB;AACA;AAAA,MACF,KAAK;AAAA,MACL,KAAK;AACH,aAAK;AACL;AAAA,MACF,KAAK;AAAA,MACL,KAAK;AACH,aAAK,KAAK;AACV;AAAA,MACF;AACE,YAAI,MAAM,WAAW,GAAG;AACtB,gBAAM,MAAM,GAAG,MAAM,CAAC;AAAA,QACxB;AAAA,IACJ;AAAA,EACF;AAEA,QAAM,EAAE,KAAK,QAAQ,KAAK,SAAS,MAAM,IAAI,WAAW;AAAA,IACtD,OAAO;AAAA,MACL;AAAA,MACA,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,GAAG;AAAA,MACH,GAAG;AAAA,MACH,OAAO;AAAA,QACL,GAAG;AAAA,QACH,GAAG;AAAA,MACL;AAAA,MACA,QAAQ;AAAA,QACN,GAAG;AAAA,QACH,GAAG;AAAA,MACL;AAAA,MACA,UAAU;AAAA,QACR,GAAG;AAAA,QACH,GAAG;AAAA,MACL;AAAA,MACA,OAAO;AAAA,QACL,GAAG;AAAA,QACH,GAAG;AAAA,MACL;AAAA,IACF;AAAA,IACA,OAAO;AACL,iBAAW,SAAS,cAAc;AAChC,eAAO,iBAAiB,OAAO,aAAa,mBAAmB;AAAA,MACjE;AACA,iBAAW,SAAS,cAAc;AAChC,eAAO,iBAAiB,OAAO,aAAa,mBAAmB;AAAA,MACjE;AACA,aAAO,iBAAiB,aAAa,aAAa,EAAE,SAAS,KAAK,CAAC;AACnE,aAAO,iBAAiB,SAAS,aAAa,EAAE,SAAS,KAAK,CAAC;AAAA,IACjE;AAAA,IACA,OAAO;AACL,iBAAW,SAAS,cAAc;AAChC,eAAO,oBAAoB,OAAO,WAAW;AAAA,MAC/C;AACA,iBAAW,SAAS,cAAc;AAChC,eAAO,oBAAoB,OAAO,WAAW;AAAA,MAC/C;AACA,aAAO,oBAAoB,aAAa,WAAW;AACnD,aAAO,oBAAoB,SAAS,WAAW;AAAA,IACjD;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO,MAAM;AAAA,EACf;AACF;AAEA,MAAM,YAA2D,oBAAI,QAAQ;AAc9D,SAAR,QAAyB,QAAqB,SAA0C;AAC7F,MAAI,CAAC,UAAU,IAAI,MAAM,GAAG;AAC1B,cAAU,IAAI,QAAQ,kBAAkB,QAAQ,OAAO,CAAC;AAAA,EAC1D;AAEA,SAAO,UAAU,IAAI,MAAM;AAC7B;",
6
- "names": []
7
- }
package/services/key.d.ts DELETED
@@ -1,21 +0,0 @@
1
- import type { ServiceInterface } from './index.js';
2
- export type KeyService = ServiceInterface<KeyServiceProps>;
3
- export interface KeyServiceProps {
4
- event: KeyboardEvent;
5
- triggered: number;
6
- direction: 'up' | 'down' | 'none';
7
- isUp: boolean;
8
- isDown: boolean;
9
- ENTER: boolean;
10
- SPACE: boolean;
11
- TAB: boolean;
12
- ESC: boolean;
13
- LEFT: boolean;
14
- UP: boolean;
15
- RIGHT: boolean;
16
- DOWN: boolean;
17
- }
18
- /**
19
- * Use the keyboard service.
20
- */
21
- export default function useKey(): KeyService;
package/services/key.js DELETED
@@ -1,65 +0,0 @@
1
- import { useService } from "./service.js";
2
- import keyCodes from "../utils/keyCodes.js";
3
- function getInitialKeyCodes() {
4
- return Object.fromEntries(Object.keys(keyCodes).map((key2) => [key2, false]));
5
- }
6
- function createKeyService() {
7
- let previousEvent;
8
- function updateProps(event) {
9
- props.event = event;
10
- for (const [name, code] of Object.entries(keyCodes)) {
11
- props[name] = code === event.keyCode;
12
- }
13
- if (!previousEvent) {
14
- props.triggered = 0;
15
- }
16
- if (props.event.type === "keydown" && previousEvent?.type === "keydown") {
17
- props.triggered += 1;
18
- } else {
19
- props.triggered = 1;
20
- }
21
- previousEvent = props.event;
22
- props.direction = props.event.type === "keydown" ? "down" : "up";
23
- props.isUp = props.event.type === "keyup";
24
- props.isDown = props.event.type === "keydown";
25
- return props;
26
- }
27
- function onKey(event) {
28
- trigger(updateProps(event));
29
- }
30
- const { add, remove, has, trigger, props } = useService({
31
- props: {
32
- event: null,
33
- triggered: 0,
34
- isUp: false,
35
- isDown: false,
36
- direction: "none",
37
- ...getInitialKeyCodes()
38
- },
39
- init() {
40
- document.addEventListener("keydown", onKey);
41
- document.addEventListener("keyup", onKey);
42
- },
43
- kill() {
44
- document.removeEventListener("keydown", onKey);
45
- document.removeEventListener("keyup", onKey);
46
- }
47
- });
48
- return {
49
- add,
50
- remove,
51
- has,
52
- props: () => props
53
- };
54
- }
55
- let key;
56
- function useKey() {
57
- if (!key) {
58
- key = createKeyService();
59
- }
60
- return key;
61
- }
62
- export {
63
- useKey as default
64
- };
65
- //# sourceMappingURL=key.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../packages/js-toolkit/services/key.ts"],
4
- "sourcesContent": ["/* eslint-disable no-use-before-define, @typescript-eslint/no-use-before-define */\nimport { useService } from './service.js';\nimport keyCodes from '../utils/keyCodes.js';\nimport type { ServiceInterface } from './index.js';\n\n/**\n * Get initial key codes.\n */\nfunction getInitialKeyCodes(): Record<keyof typeof keyCodes, false> {\n return Object.fromEntries(Object.keys(keyCodes).map((key) => [key, false])) as Record<\n keyof typeof keyCodes,\n false\n >;\n}\n\nexport type KeyService = ServiceInterface<KeyServiceProps>;\n\nexport interface KeyServiceProps {\n event: KeyboardEvent;\n triggered: number;\n direction: 'up' | 'down' | 'none';\n isUp: boolean;\n isDown: boolean;\n ENTER: boolean;\n SPACE: boolean;\n TAB: boolean;\n ESC: boolean;\n LEFT: boolean;\n UP: boolean;\n RIGHT: boolean;\n DOWN: boolean;\n}\n\n/**\n * Create key service.\n */\nfunction createKeyService(): KeyService {\n let previousEvent;\n\n /**\n * Update props.\n */\n function updateProps(event: KeyboardEvent): KeyServiceProps {\n props.event = event;\n\n for (const [name, code] of Object.entries(keyCodes)) {\n props[name] = code === event.keyCode;\n }\n\n if (!previousEvent) {\n props.triggered = 0;\n }\n\n if (props.event.type === 'keydown' && previousEvent?.type === 'keydown') {\n props.triggered += 1;\n } else {\n props.triggered = 1;\n }\n\n previousEvent = props.event;\n\n props.direction = props.event.type === 'keydown' ? 'down' : 'up';\n props.isUp = props.event.type === 'keyup';\n props.isDown = props.event.type === 'keydown';\n\n return props;\n }\n\n /**\n * Trigger callbacks on keyboard event.\n */\n function onKey(event: KeyboardEvent) {\n trigger(updateProps(event));\n }\n\n const { add, remove, has, trigger, props } = useService({\n props: {\n event: null,\n triggered: 0,\n isUp: false,\n isDown: false,\n direction: 'none',\n ...getInitialKeyCodes(),\n } as KeyServiceProps,\n init() {\n document.addEventListener('keydown', onKey);\n document.addEventListener('keyup', onKey);\n },\n kill() {\n document.removeEventListener('keydown', onKey);\n document.removeEventListener('keyup', onKey);\n },\n });\n\n return {\n add,\n remove,\n has,\n props: () => props,\n };\n}\n\nlet key;\n\n/**\n * Use the keyboard service.\n */\nexport default function useKey(): KeyService {\n if (!key) {\n key = createKeyService();\n }\n\n return key;\n}\n"],
5
- "mappings": "AACA,SAAS,kBAAkB;AAC3B,OAAO,cAAc;AAMrB,SAAS,qBAA2D;AAClE,SAAO,OAAO,YAAY,OAAO,KAAK,QAAQ,EAAE,IAAI,CAACA,SAAQ,CAACA,MAAK,KAAK,CAAC,CAAC;AAI5E;AAuBA,SAAS,mBAA+B;AACtC,MAAI;AAKJ,WAAS,YAAY,OAAuC;AAC1D,UAAM,QAAQ;AAEd,eAAW,CAAC,MAAM,IAAI,KAAK,OAAO,QAAQ,QAAQ,GAAG;AACnD,YAAM,IAAI,IAAI,SAAS,MAAM;AAAA,IAC/B;AAEA,QAAI,CAAC,eAAe;AAClB,YAAM,YAAY;AAAA,IACpB;AAEA,QAAI,MAAM,MAAM,SAAS,aAAa,eAAe,SAAS,WAAW;AACvE,YAAM,aAAa;AAAA,IACrB,OAAO;AACL,YAAM,YAAY;AAAA,IACpB;AAEA,oBAAgB,MAAM;AAEtB,UAAM,YAAY,MAAM,MAAM,SAAS,YAAY,SAAS;AAC5D,UAAM,OAAO,MAAM,MAAM,SAAS;AAClC,UAAM,SAAS,MAAM,MAAM,SAAS;AAEpC,WAAO;AAAA,EACT;AAKA,WAAS,MAAM,OAAsB;AACnC,YAAQ,YAAY,KAAK,CAAC;AAAA,EAC5B;AAEA,QAAM,EAAE,KAAK,QAAQ,KAAK,SAAS,MAAM,IAAI,WAAW;AAAA,IACtD,OAAO;AAAA,MACL,OAAO;AAAA,MACP,WAAW;AAAA,MACX,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,GAAG,mBAAmB;AAAA,IACxB;AAAA,IACA,OAAO;AACL,eAAS,iBAAiB,WAAW,KAAK;AAC1C,eAAS,iBAAiB,SAAS,KAAK;AAAA,IAC1C;AAAA,IACA,OAAO;AACL,eAAS,oBAAoB,WAAW,KAAK;AAC7C,eAAS,oBAAoB,SAAS,KAAK;AAAA,IAC7C;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO,MAAM;AAAA,EACf;AACF;AAEA,IAAI;AAKW,SAAR,SAAsC;AAC3C,MAAI,CAAC,KAAK;AACR,UAAM,iBAAiB;AAAA,EACzB;AAEA,SAAO;AACT;",
6
- "names": ["key"]
7
- }
@@ -1,11 +0,0 @@
1
- import type { ServiceInterface } from './index.js';
2
- export type LoadService = ServiceInterface<LoadServiceProps>;
3
- export interface LoadServiceProps {
4
- time: DOMHighResTimeStamp;
5
- }
6
- /**
7
- * Use the load service.
8
- *
9
- * @returns {LoadService}
10
- */
11
- export default function useLoad(): any;
package/services/load.js DELETED
@@ -1,38 +0,0 @@
1
- import { useService } from "./service.js";
2
- function createLoadService() {
3
- function onLoad() {
4
- props.time = window.performance.now();
5
- trigger(props);
6
- }
7
- const { add, remove, has, props, trigger } = useService({
8
- /**
9
- * @type {LoadServiceProps}
10
- */
11
- props: {
12
- time: performance.now()
13
- },
14
- init() {
15
- window.addEventListener("load", onLoad);
16
- },
17
- kill() {
18
- window.removeEventListener("load", onLoad);
19
- }
20
- });
21
- return {
22
- add,
23
- remove,
24
- has,
25
- props: () => props
26
- };
27
- }
28
- let load;
29
- function useLoad() {
30
- if (!load) {
31
- load = createLoadService();
32
- }
33
- return load;
34
- }
35
- export {
36
- useLoad as default
37
- };
38
- //# sourceMappingURL=load.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../packages/js-toolkit/services/load.ts"],
4
- "sourcesContent": ["/* eslint-disable no-use-before-define, @typescript-eslint/no-use-before-define */\nimport { useService } from './service.js';\nimport type { ServiceInterface } from './index.js';\n\nexport type LoadService = ServiceInterface<LoadServiceProps>;\n\nexport interface LoadServiceProps {\n time: DOMHighResTimeStamp;\n}\n\n/**\n * Get load service.\n *\n * @returns {LoadService}\n */\nfunction createLoadService() {\n /**\n * Trigger on load\n *\n * @returns {void}\n */\n function onLoad() {\n // eslint-disable-next-line no-use-before-define\n props.time = window.performance.now();\n // eslint-disable-next-line no-use-before-define\n trigger(props);\n }\n\n const { add, remove, has, props, trigger } = useService({\n /**\n * @type {LoadServiceProps}\n */\n props: {\n time: performance.now(),\n },\n init() {\n window.addEventListener('load', onLoad);\n },\n kill() {\n window.removeEventListener('load', onLoad);\n },\n });\n\n return {\n add,\n remove,\n has,\n props: () => props,\n };\n}\n\nlet load;\n\n/**\n * Use the load service.\n *\n * @returns {LoadService}\n */\nexport default function useLoad() {\n if (!load) {\n load = createLoadService();\n }\n\n return load;\n}\n"],
5
- "mappings": "AACA,SAAS,kBAAkB;AAc3B,SAAS,oBAAoB;AAM3B,WAAS,SAAS;AAEhB,UAAM,OAAO,OAAO,YAAY,IAAI;AAEpC,YAAQ,KAAK;AAAA,EACf;AAEA,QAAM,EAAE,KAAK,QAAQ,KAAK,OAAO,QAAQ,IAAI,WAAW;AAAA;AAAA;AAAA;AAAA,IAItD,OAAO;AAAA,MACL,MAAM,YAAY,IAAI;AAAA,IACxB;AAAA,IACA,OAAO;AACL,aAAO,iBAAiB,QAAQ,MAAM;AAAA,IACxC;AAAA,IACA,OAAO;AACL,aAAO,oBAAoB,QAAQ,MAAM;AAAA,IAC3C;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO,MAAM;AAAA,EACf;AACF;AAEA,IAAI;AAOW,SAAR,UAA2B;AAChC,MAAI,CAAC,MAAM;AACT,WAAO,kBAAkB;AAAA,EAC3B;AAEA,SAAO;AACT;",
6
- "names": []
7
- }