@supermousejs/core 2.5.0-beta.2 → 2.5.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,62 +1,76 @@
1
- const x = {
2
- rules: [
3
- { selector: "input", native: !0, hide: !0 },
4
- { selector: "textarea", native: !0, hide: !0 },
5
- { selector: "select", native: !0, hide: !0 },
6
- { selector: "[contenteditable]", native: !0, hide: !0 },
7
- { selector: "a", native: !1, hide: !0 },
8
- { selector: "button", native: !1, hide: !0 },
9
- { selector: '[role="button"]', native: !1, hide: !0 },
10
- { selector: "[tabindex]", native: !1, hide: !0 }
1
+ const S = {
2
+ native: ["input", "textarea", "select", "[contenteditable]"],
3
+ hide: [
4
+ "input",
5
+ "textarea",
6
+ "select",
7
+ "[contenteditable]",
8
+ "a",
9
+ "button",
10
+ '[role="button"]',
11
+ "[tabindex]",
12
+ "label"
11
13
  ]
12
14
  };
13
- function _(i) {
14
- if (!i) return x;
15
- if ("rules" in i) return i;
16
- const t = [], e = new Set(i.native ?? []), s = new Set(i.hide ?? []), n = /* @__PURE__ */ new Set([...e, ...s]);
17
- for (const o of n)
18
- t.push({
19
- selector: o,
20
- native: e.has(o),
21
- hide: s.has(o)
22
- });
23
- return { rules: t };
24
- }
25
- function A(i) {
26
- const t = [], e = [];
27
- for (const s of i.rules)
28
- s.native !== !1 && t.push(s.selector), s.hide !== !1 && e.push(s.selector);
29
- return { native: t, hide: e };
15
+ function b(n) {
16
+ return n ? {
17
+ native: n.native ?? [],
18
+ hide: n.hide ?? []
19
+ } : S;
30
20
  }
31
- let D = 0;
32
- class O {
21
+ let y = 0;
22
+ class P {
23
+ element;
24
+ scopeClass;
25
+ hideClass;
26
+ container;
27
+ currentCursorState = null;
28
+ originalContainerPosition = "";
29
+ originalContainerCursor = "";
30
+ _visible = !0;
33
31
  constructor(t, e) {
34
- if (this.container = t, !t || !(t instanceof HTMLElement))
35
- throw new Error(`[Supermouse] Invalid container: ${t}. Must be an HTMLElement.`);
36
- t.isConnected;
37
- const s = D++;
38
- this.scopeClass = `supermouse-scope-${s}`, this.hideClass = `supermouse-hide-${s}`;
39
- const n = t === document.body;
40
- if (this.element = document.createElement("div"), Object.assign(this.element.style, {
41
- position: n ? "fixed" : "absolute",
32
+ if (!t || !(t instanceof HTMLElement))
33
+ throw new Error(
34
+ `[Supermouse] Invalid container: ${t}. Must be an HTMLElement.`
35
+ );
36
+ const s = t.hasAttribute("data-supermouse-placeholder");
37
+ !t.isConnected && !s && console.warn(
38
+ "[Supermouse] container is not attached to the document — stage sizing/positioning will be wrong until it is."
39
+ );
40
+ const i = y++;
41
+ this.scopeClass = `supermouse-scope-${i}`, this.hideClass = `supermouse-hide-${i}`, this.element = document.createElement("div"), Object.assign(this.element.style, {
42
+ position: "absolute",
42
43
  inset: "0px",
43
44
  pointerEvents: "none",
44
45
  zIndex: String(e),
45
46
  opacity: "1",
46
47
  transition: "opacity 0.15s ease"
47
- }), !n) {
48
- const o = window.getComputedStyle(t);
49
- this.originalContainerPosition = o.position, o.position === "static" && (t.style.position = "relative");
48
+ }), this.container = t, this._attach(t);
49
+ }
50
+ _attach(t) {
51
+ const e = t === document.body;
52
+ if (this.element.style.position = e ? "fixed" : "absolute", e)
53
+ this.originalContainerPosition = "";
54
+ else {
55
+ const s = window.getComputedStyle(t);
56
+ this.originalContainerPosition = s.position, s.position === "static" && (t.style.position = "relative");
50
57
  }
51
58
  this.originalContainerCursor = t.style.cursor, t.appendChild(this.element), t.classList.add("supermouse-scope", this.scopeClass);
52
59
  }
53
- container;
54
- element;
55
- scopeClass;
56
- hideClass;
57
- currentCursorState = null;
58
- originalContainerPosition = "";
59
- originalContainerCursor = "";
60
+ _detach() {
61
+ const t = this.container;
62
+ t.classList.remove("supermouse-scope", this.scopeClass, this.hideClass), t !== document.body && this.originalContainerPosition === "static" && (t.style.position = ""), t.style.cursor = this.originalContainerCursor, this.element.remove();
63
+ }
64
+ /**
65
+ * Rebinds this stage to a new container. The previous container is
66
+ * restored to its pre-Supermouse state, and the current cursor
67
+ * suppression is re-applied to the new container.
68
+ */
69
+ attach(t) {
70
+ if (this.container === t) return;
71
+ const e = this.currentCursorState;
72
+ this._detach(), this.container = t, this._attach(t), this.currentCursorState = null, e && this.setNativeCursor(e);
73
+ }
60
74
  get containerElement() {
61
75
  return this.container;
62
76
  }
@@ -69,23 +83,31 @@ class O {
69
83
  return `:not(.${this.scopeClass} .supermouse-scope):not(.${this.scopeClass} .supermouse-scope *)`;
70
84
  }
71
85
  setVisibility(t) {
72
- this.element.style.opacity = t ? "1" : "0";
86
+ t !== this._visible && (this._visible = t, this.element.style.opacity = t ? "1" : "0");
73
87
  }
74
88
  setNativeCursor(t) {
75
- t !== this.currentCursorState && (this.currentCursorState = t, this.container.classList.toggle(this.hideClass, t === "none"), t === "none" ? this.container.style.cursor = "none" : this.container === document.body ? this.container.style.cursor = this.originalContainerCursor : this.container.style.cursor = this.originalContainerCursor || "auto");
89
+ t !== this.currentCursorState && (this.currentCursorState = t, this.container.classList.toggle(this.hideClass, t === "none"));
76
90
  }
77
91
  destroy() {
78
- this.element.remove(), this.container.style.cursor = this.originalContainerCursor, this.container.classList.remove("supermouse-scope", this.scopeClass, this.hideClass), this.container !== document.body && this.originalContainerPosition === "static" && (this.container.style.position = "");
92
+ this._detach();
79
93
  }
80
94
  }
81
- class L {
95
+ class C {
82
96
  constructor(t, e) {
83
97
  this.config = t, this.name = t.name, this.cursorMode = t.cursor ?? e.cursor, this.hoverSelectors = new Set(t.hoverSelectors ?? e.hoverSelectors), this.inheritDataAttributes = t.inheritDataAttributes ?? e.inheritDataAttributes, this.ruleEntries = t.rules ? Object.entries(t.rules) : e.ruleEntries;
84
- const s = t.cursorPolicy ? _(t.cursorPolicy) : e.cursorPolicy, n = A(s);
85
- this.nativeSelectors = n.native, this.hideSelectors = n.hide, this.stage = new O(t.container, t.zIndex ?? e.zIndex);
98
+ const s = t.cursorPolicy ? b(t.cursorPolicy) : e.cursorPolicy;
99
+ this.nativeSelectors = s.native, this.hideSelectors = s.hide;
100
+ let i;
101
+ typeof t.container == "string" ? (this.containerSelector = t.container, this._bound = !1, i = document.createElement("div"), i.setAttribute("data-supermouse-placeholder", "")) : (this.containerSelector = null, this._bound = !0, i = t.container), this.stage = new P(i, t.zIndex ?? e.zIndex);
86
102
  }
87
103
  config;
88
104
  stage;
105
+ /**
106
+ * The CSS selector used for lazy resolution, or null for eager scopes.
107
+ * Derived from `config.container` at construction: a string means lazy,
108
+ * an element means eager.
109
+ */
110
+ containerSelector;
89
111
  hoverSelectors;
90
112
  plugins = [];
91
113
  nativeSelectors;
@@ -94,13 +116,42 @@ class L {
94
116
  ruleEntries;
95
117
  name;
96
118
  cursorMode;
97
- disabled = !1;
98
- contains(t) {
99
- return this.stage.containerElement.contains(t);
100
- }
119
+ active = !0;
120
+ _bound;
101
121
  get container() {
102
122
  return this.stage.containerElement;
103
123
  }
124
+ /**
125
+ * True for eager scopes, and for selector scopes that have matched a
126
+ * live element at least once.
127
+ */
128
+ get resolved() {
129
+ return this._bound;
130
+ }
131
+ /**
132
+ * True if this scope owns the given element. Element equality for eager
133
+ * scopes; `Element.matches` for selector scopes. Invalid selectors are
134
+ * treated as non-matching; validation happens once at scope creation.
135
+ */
136
+ match(t) {
137
+ if (this.containerSelector === null)
138
+ return this.stage.containerElement === t;
139
+ try {
140
+ return t.matches(this.containerSelector);
141
+ } catch {
142
+ return !1;
143
+ }
144
+ }
145
+ /**
146
+ * Rebinds this scope's stage to a matched element. No-op for eager
147
+ * scopes, and no-op if the stage is already attached to `el`.
148
+ */
149
+ bind(t) {
150
+ this.containerSelector !== null && (this._bound && this.stage.containerElement === t || (this.stage.attach(t), this._bound = !0));
151
+ }
152
+ contains(t) {
153
+ return this._bound && this.stage.containerElement.contains(t);
154
+ }
104
155
  get hoverSelectorString() {
105
156
  return Array.from(this.hoverSelectors).join(", ");
106
157
  }
@@ -112,16 +163,16 @@ class L {
112
163
  `${t}${e} { cursor: none !important; }`,
113
164
  `${t} *${e} { cursor: none !important; }`
114
165
  ];
115
- for (const n of this.hideSelectors)
116
- s.push(`${t} ${n}${e} { cursor: none !important; }`);
117
- return s.push(`${t} label${e} { cursor: none !important; }`), s.push(`${t} select${e} { cursor: none !important; }`), s.push(
166
+ for (const i of this.hideSelectors)
167
+ s.push(`${t} ${i}${e} { cursor: none !important; }`);
168
+ return s.push(
118
169
  `${t} input[type="range"]${e}::-webkit-slider-thumb { cursor: none !important; }`
119
170
  ), s.push(
120
171
  `${t} input[type="range"]${e}::-moz-range-thumb { cursor: none !important; }`
121
172
  ), s;
122
173
  }
123
174
  }
124
- const f = { x: -100, y: -100 }, I = /* @__PURE__ */ new Set([
175
+ const d = { x: -100, y: -100 }, E = /* @__PURE__ */ new Set([
125
176
  "default",
126
177
  "auto",
127
178
  "pointer",
@@ -129,60 +180,24 @@ const f = { x: -100, y: -100 }, I = /* @__PURE__ */ new Set([
129
180
  "inherit",
130
181
  "grab",
131
182
  "grabbing"
132
- ]), R = [
183
+ ]), _ = [
133
184
  "a",
134
185
  "button",
135
186
  "input",
136
187
  "textarea",
137
188
  "[data-hover]",
138
189
  "[data-cursor]"
139
- ], u = /* @__PURE__ */ new Map(), M = /* @__PURE__ */ new Map();
140
- let v = null, g = !1, m = !1, C = 0;
141
- function E(i) {
142
- const t = i.getBoundingClientRect();
143
- return { left: t.left, top: t.top, width: t.width, height: t.height };
144
- }
145
- function T(i) {
146
- u.set(i, E(i));
147
- const t = M.get(i);
148
- if (t) for (const e of t) e();
149
- }
150
- function b() {
151
- for (const i of u.keys()) T(i);
152
- }
153
- function $() {
154
- v || typeof ResizeObserver > "u" || (v = new ResizeObserver((i) => {
155
- for (const t of i) {
156
- const e = t.target;
157
- u.has(e) && T(e);
158
- }
159
- }));
160
- }
161
- function B() {
162
- typeof window > "u" || (g || (window.addEventListener("scroll", b, { passive: !0, capture: !0 }), g = !0), m || (window.addEventListener("resize", b, { passive: !0 }), m = !0));
163
- }
164
- function H(i, t) {
165
- return C++, u.has(i) || (u.set(i, E(i)), $(), v?.observe(i), B()), () => {
166
- C--, C === 0 && (v?.disconnect(), v = null, u.clear(), M.clear(), g && (window.removeEventListener("scroll", b, { capture: !0 }), g = !1), m && (window.removeEventListener("resize", b), m = !1));
167
- };
168
- }
169
- function N(i) {
170
- let t = u.get(i);
171
- return t || (t = E(i), u.set(i, t)), t;
172
- }
173
- function z(i, t, e) {
174
- if (i === document.body) return { x: t, y: e };
175
- const s = N(i);
176
- return { x: t - s.left, y: e - s.top };
177
- }
178
- class k {
179
- constructor(t, e, s, n) {
180
- this.state = t, this.options = e, this.onEnableChange = s, this.onActiveScopeChange = n, this.dataPrefix = e.dataPrefix ?? "supermouse", this.normalizedDataPrefix = this.dataPrefix.toLowerCase(), this.ignoreAttribute = `data-${this.dataPrefix}-ignore`, this.checkDeviceCapability(), this.checkMotionPreference(), this.bindEvents();
190
+ ];
191
+ class w {
192
+ constructor(t, e, s, i, h, r) {
193
+ this.state = t, this.options = e, this.onEnableChange = s, this.onActiveScopeChange = i, this.resolveScope = h, this.onHoverSettled = r, this.dataPrefix = e.dataPrefix ?? "supermouse", this.normalizedDataPrefix = this.dataPrefix.toLowerCase(), this.ignoreAttribute = `data-${this.dataPrefix}-ignore`, this.checkDeviceCapability(), this.checkMotionPreference(), this.bindEvents();
181
194
  }
182
195
  state;
183
196
  options;
184
197
  onEnableChange;
185
198
  onActiveScopeChange;
199
+ resolveScope;
200
+ onHoverSettled;
186
201
  abortController = new AbortController();
187
202
  mediaQueryList;
188
203
  motionQuery;
@@ -190,36 +205,26 @@ class k {
190
205
  normalizedDataPrefix;
191
206
  ignoreAttribute;
192
207
  activeScope = null;
193
- scopeByContainer = /* @__PURE__ */ new Map();
194
208
  nativeTarget = null;
195
209
  currentTarget = null;
196
210
  lastParsedTarget = null;
197
- releaseViewport = null;
198
211
  hasSeenPointer = !1;
199
212
  isEnabled = !0;
200
213
  viewportX = 0;
201
214
  viewportY = 0;
202
215
  /** Cached matched rules per ancestor. Recomputed only when the hover target changes. */
203
216
  cachedChain = [];
204
- setScopes(t) {
205
- this.scopeByContainer.clear();
206
- for (const e of t) this.scopeByContainer.set(e.container, e);
207
- }
208
217
  setActiveScope(t) {
209
- t !== this.activeScope && (this.activeScope = t, this.lastParsedTarget = null, this.cachedChain = [], this.releaseViewport?.(), this.releaseViewport = t && t.container !== document.body ? H(t.container) : null, this.hasSeenPointer && (this.applyPointerToState(), this.state.target.x = this.state.smooth.x = this.state.pointer.x, this.state.target.y = this.state.smooth.y = this.state.pointer.y), this.onActiveScopeChange(t));
210
- }
211
- findScope(t) {
212
- let e = t;
213
- for (; e; ) {
214
- const s = this.scopeByContainer.get(e);
215
- if (s && !s.disabled) return s;
216
- e = e.parentElement;
217
- }
218
- return null;
218
+ t !== this.activeScope && (this.activeScope = t, this.lastParsedTarget = null, this.cachedChain = [], this.hasSeenPointer && (this.applyPointerToState(), this.state.target.x = this.state.smooth.x = this.state.pointer.x, this.state.target.y = this.state.smooth.y = this.state.pointer.y), this.onActiveScopeChange(t));
219
219
  }
220
220
  applyPointerToState() {
221
- const t = this.activeScope?.container ?? document.body, e = z(t, this.viewportX, this.viewportY);
222
- this.state.pointer.x = e.x, this.state.pointer.y = e.y;
221
+ const t = this.activeScope?.container ?? document.body;
222
+ if (t === document.body) {
223
+ this.state.pointer.x = this.viewportX, this.state.pointer.y = this.viewportY;
224
+ return;
225
+ }
226
+ const e = t.getBoundingClientRect();
227
+ this.state.pointer.x = this.viewportX - e.left, this.state.pointer.y = this.viewportY - e.top;
223
228
  }
224
229
  checkDeviceCapability() {
225
230
  this.options.autoDisableOnMobile && (this.mediaQueryList = window.matchMedia("(pointer: fine)"), this.updateEnabledState(this.mediaQueryList.matches), this.mediaQueryList.addEventListener("change", (t) => this.updateEnabledState(t.matches), {
@@ -240,42 +245,43 @@ class k {
240
245
  }
241
246
  parseDOMInteraction(t) {
242
247
  if (!this.activeScope) return;
243
- const e = this.activeScope.container, s = this.activeScope.inheritDataAttributes, n = this.normalizedDataPrefix, o = this.activeScope.ruleEntries;
248
+ const e = this.activeScope.container, s = this.activeScope.inheritDataAttributes, i = this.normalizedDataPrefix, h = this.activeScope.ruleEntries;
244
249
  if (t !== this.lastParsedTarget) {
245
250
  this.lastParsedTarget = t, this.cachedChain = [];
246
- let r = t;
247
- for (; r; ) {
251
+ let o = t;
252
+ for (; o; ) {
248
253
  const p = [];
249
- for (const [a, l] of o)
250
- this.matchesSelector(r, a) && p.push({ selector: a, rules: l });
251
- if (this.cachedChain.push({ element: r, matchedRules: p }), !s || r === e) break;
252
- const c = r.parentElement;
254
+ for (const [a, l] of h)
255
+ this.matchesSelector(o, a) && p.push({ selector: a, rules: l });
256
+ if (this.cachedChain.push({ element: o, matchedRules: p }), !s || o === e) break;
257
+ const c = o.parentElement;
253
258
  if (!c || !e.contains(c)) break;
254
- r = c;
259
+ o = c;
255
260
  }
256
261
  }
257
- const h = {};
258
- for (const { element: r, matchedRules: p } of this.cachedChain) {
262
+ const r = {};
263
+ for (const { element: o, matchedRules: p } of this.cachedChain) {
259
264
  const c = {};
260
265
  for (const { rules: a } of p)
261
266
  try {
262
- const l = typeof a == "function" ? a(r) : a;
267
+ const l = typeof a == "function" ? a(o) : a;
263
268
  if (!l || typeof l != "object") continue;
264
- for (const [S, d] of Object.entries(l))
265
- c[S] = typeof d == "function" ? d(r) : d;
266
- } catch {
269
+ for (const [v, u] of Object.entries(l))
270
+ c[v] = typeof u == "function" ? u(o) : u;
271
+ } catch (l) {
272
+ console.error("[Supermouse] Rule threw during evaluation:", l);
267
273
  }
268
- for (const a in r.dataset) {
269
- if (!a.toLowerCase().startsWith(n)) continue;
270
- const l = a.slice(n.length);
274
+ for (const a in o.dataset) {
275
+ if (!a.toLowerCase().startsWith(i)) continue;
276
+ const l = a.slice(i.length);
271
277
  if (!l) continue;
272
- const S = l[0].toLowerCase() + l.slice(1), d = r.dataset[a];
273
- c[S] = d == null || d === "" ? !0 : d;
278
+ const v = l[0].toLowerCase() + l.slice(1), u = o.dataset[a];
279
+ c[v] = u == null || u === "" ? !0 : u;
274
280
  }
275
281
  for (const [a, l] of Object.entries(c))
276
- a in h || (h[a] = l);
282
+ a in r || (r[a] = l);
277
283
  }
278
- this.state.interaction = h;
284
+ this.state.interaction = r;
279
285
  }
280
286
  matchesSelector(t, e) {
281
287
  try {
@@ -298,26 +304,33 @@ class k {
298
304
  };
299
305
  handleMouseOver = (t) => {
300
306
  if (!this.isEnabled) return;
301
- const e = t.target, s = this.findScope(e);
302
- if (s && s !== this.activeScope && this.setActiveScope(s), !this.activeScope) return;
303
- if (this.state.cursorMode === "auto" && e.closest(`[${this.ignoreAttribute}]`)) {
304
- this.clearHover(), this.state.isNative = !0, this.nativeTarget = e;
307
+ const e = t.target, s = this.resolveScope(e);
308
+ s && s !== this.activeScope && this.setActiveScope(s), this.activeScope && (this.settleHoverState(e), this.onHoverSettled());
309
+ };
310
+ isPointerInside(t) {
311
+ if (!this.hasSeenPointer) return !1;
312
+ const e = t.getBoundingClientRect();
313
+ return this.viewportX >= e.left && this.viewportX <= e.right && this.viewportY >= e.top && this.viewportY <= e.bottom;
314
+ }
315
+ settleHoverState(t) {
316
+ if (this.state.cursorMode === "auto" && t.closest(`[${this.ignoreAttribute}]`)) {
317
+ this.clearHover(), this.state.isNative = !0, this.nativeTarget = t;
305
318
  return;
306
319
  }
307
- this.state.isNative = !1, this.nativeTarget = null, this.currentTarget = e, this.parseDOMInteraction(e);
308
- const n = e.closest(this.activeScope.hoverSelectorString);
309
- if (n && (this.state.isHover = !0, this.state.hoverTarget = n), this.state.cursorMode === "auto") {
310
- if (this.matchesSelector(e, this.activeScope.nativeSelectorString)) {
311
- this.state.isNative = !0, this.nativeTarget = e;
320
+ this.state.isNative = !1, this.nativeTarget = null, this.currentTarget = t, this.parseDOMInteraction(t);
321
+ const e = t.closest(this.activeScope.hoverSelectorString);
322
+ if (e && (this.state.isHover = !0, this.state.hoverTarget = e), this.state.cursorMode === "auto") {
323
+ if (this.matchesSelector(t, this.activeScope.nativeSelectorString)) {
324
+ this.state.isNative = !0, this.nativeTarget = t;
312
325
  return;
313
326
  }
314
- (e.isContentEditable || !I.has(this.resolveComputedCursor(e))) && (this.state.isNative = !0, this.nativeTarget = e);
327
+ (t.isContentEditable || !E.has(this.resolveComputedCursor(t))) && (this.state.isNative = !0, this.nativeTarget = t);
315
328
  }
316
- };
329
+ }
317
330
  handleMouseOut = (t) => {
318
331
  if (!this.isEnabled) return;
319
332
  const e = t.target, s = t.relatedTarget;
320
- (e === this.state.hoverTarget || e.contains(this.state.hoverTarget)) && (!s || !this.state.hoverTarget?.contains(s)) && (this.state.isHover = !1, this.state.hoverTarget = null), this.nativeTarget && (e === this.nativeTarget || e.contains(this.nativeTarget)) && (!s || !this.nativeTarget.contains(s)) && (this.state.isNative = !1, this.nativeTarget = null), e === this.currentTarget && (this.currentTarget = null, this.lastParsedTarget = null, this.cachedChain = []), !s && this.options.hideOnLeave && (this.state.hasReceivedInput = !1, this.state.pointer = { ...f });
333
+ (e === this.state.hoverTarget || e.contains(this.state.hoverTarget)) && (!s || !this.state.hoverTarget?.contains(s)) && (this.state.isHover = !1, this.state.hoverTarget = null), this.nativeTarget && (e === this.nativeTarget || e.contains(this.nativeTarget)) && (!s || !this.nativeTarget.contains(s)) && (this.state.isNative = !1, this.nativeTarget = null), e === this.currentTarget && (this.currentTarget = null, this.lastParsedTarget = null, this.cachedChain = []), !s && this.options.hideOnLeave && (this.state.hasReceivedInput = !1, this.state.pointer = { ...d });
321
334
  };
322
335
  clearHover() {
323
336
  this.state.isHover = !1, this.state.hoverTarget = null, this.state.isNative = !1, this.nativeTarget = null, this.state.interaction = {}, this.currentTarget = null, this.lastParsedTarget = null, this.cachedChain = [];
@@ -330,38 +343,37 @@ class k {
330
343
  window.addEventListener("pointermove", this.handleMove, { passive: !0, signal: t }), window.addEventListener("pointerdown", this.handleDown, { passive: !0, signal: t }), window.addEventListener("pointerup", this.handleUp, { signal: t }), document.addEventListener("mouseover", this.handleMouseOver, { signal: t }), document.addEventListener("mouseout", this.handleMouseOut, { signal: t });
331
344
  }
332
345
  destroy() {
333
- this.abortController.abort(), this.releaseViewport?.(), this.cachedChain = [];
346
+ this.abortController.abort(), this.cachedChain = [];
334
347
  }
335
348
  }
336
- let V = 0;
337
- const y = /* @__PURE__ */ new Map();
338
- function F() {
339
- return V++;
349
+ let x = 0;
350
+ const f = /* @__PURE__ */ new Map();
351
+ function M() {
352
+ return x++;
340
353
  }
341
- function j(i, t) {
342
- let e = y.get(i);
343
- e || (e = document.createElement("style"), e.id = `supermouse-styles-${i}`, document.head.appendChild(e), y.set(i, e)), e.textContent = t.join(`
354
+ function T(n, t) {
355
+ let e = f.get(n);
356
+ e || (e = document.createElement("style"), e.id = `supermouse-styles-${n}`, document.head.appendChild(e), f.set(n, e)), e.textContent = t.join(`
344
357
  `);
345
358
  }
346
- function Q(i) {
347
- y.get(i)?.remove(), y.delete(i);
359
+ function A(n) {
360
+ f.get(n)?.remove(), f.delete(n);
348
361
  }
349
- const P = "2.5.0-beta.2";
350
- function U(i, t, e) {
351
- return i + (t - i) * e;
362
+ const g = "2.5.0-beta.3";
363
+ function D(n, t, e) {
364
+ return n + (t - n) * e;
352
365
  }
353
- function w(i, t, e, s) {
354
- return U(i, t, 1 - Math.exp(-e * s));
366
+ function m(n, t, e, s) {
367
+ return D(n, t, 1 - Math.exp(-e * s));
355
368
  }
356
- class Y {
357
- static version = P;
358
- version = P;
369
+ class I {
370
+ static version = g;
371
+ version = g;
359
372
  state;
360
373
  options;
361
374
  _scopes = [];
362
375
  _activeScope = null;
363
376
  _installingScope = null;
364
- scopeByContainer = /* @__PURE__ */ new Map();
365
377
  scopeByName = /* @__PURE__ */ new Map();
366
378
  scopeHandles = /* @__PURE__ */ new Map();
367
379
  input;
@@ -383,10 +395,10 @@ class Y {
383
395
  zIndex: 9999,
384
396
  inheritDataAttributes: !0,
385
397
  ...t
386
- }, this.styleOwner = F(), this.state = {
387
- pointer: { ...f },
388
- target: { ...f },
389
- smooth: { ...f },
398
+ }, this.styleOwner = M(), this.state = {
399
+ pointer: { ...d },
400
+ target: { ...d },
401
+ smooth: { ...d },
390
402
  velocity: { x: 0, y: 0 },
391
403
  displacement: { x: 0, y: 0 },
392
404
  angle: 0,
@@ -410,14 +422,16 @@ class Y {
410
422
  rules: this.options.rules,
411
423
  zIndex: this.options.zIndex
412
424
  });
413
- if (this.input = new k(
425
+ if (this.input = new w(
414
426
  this.state,
415
427
  this.options,
416
428
  (s) => {
417
429
  s || this.reset();
418
430
  },
419
- (s) => this.handleActiveScopeChange(s)
420
- ), this.input.setScopes(this._scopes), this.input.setActiveScope(e), this.installPlugins(e), this.options.scopes)
431
+ (s) => this.handleActiveScopeChange(s),
432
+ (s) => this.resolveScopeForNode(s),
433
+ () => this.applyCursorNow()
434
+ ), this.input.setActiveScope(e), this.installPlugins(e), this.options.scopes)
421
435
  for (const s of this.options.scopes) this.addScope(s);
422
436
  this.rebuildStylesheet(), this.bindVisibilityHandling(), this.options.autoStart && this.startLoop();
423
437
  }
@@ -434,12 +448,23 @@ class Y {
434
448
  get isRunning() {
435
449
  return this._running;
436
450
  }
451
+ /**
452
+ * Installs a plugin into the primary scope.
453
+ *
454
+ * In multi-scope mode, prefer `handle.use(plugin)` to target a specific
455
+ * scope. This method always installs to the primary scope, regardless of
456
+ * which scope is currently active.
457
+ */
437
458
  use(t) {
438
459
  return this.installPlugin(this._scopes[0], t), this;
439
460
  }
461
+ /**
462
+ * Searches every scope and returns the first plugin matching `name`.
463
+ * Scopes are searched in registration order (primary first).
464
+ */
440
465
  getPlugin(t) {
441
466
  for (const e of this._scopes) {
442
- const s = e.plugins.find((n) => n.name === t);
467
+ const s = e.plugins.find((i) => i.name === t);
443
468
  if (s) return s;
444
469
  }
445
470
  }
@@ -447,27 +472,48 @@ class Y {
447
472
  const e = this.scopeByName.get(t);
448
473
  return e ? this.scopeHandles.get(e) : void 0;
449
474
  }
475
+ /**
476
+ * Enables a plugin by name, wherever it lives.
477
+ *
478
+ * If the plugin's scope is currently active, the activation lifecycle
479
+ * runs immediately. If the scope is inactive, `isEnabled` is set but
480
+ * hooks do not fire until the scope next activates.
481
+ */
450
482
  enablePlugin(t) {
451
483
  const e = this.getPlugin(t);
452
484
  if (!e || e.isEnabled !== !1) return;
453
485
  e.isEnabled = !0;
454
- const s = this._activeScope;
455
- s && !s.disabled && s.plugins.includes(e) && this.scopeActivatePlugin(e);
486
+ const s = this.findScopeForPlugin(e);
487
+ s && s === this._activeScope && s.active && this.scopeActivatePlugin(e);
456
488
  }
489
+ /**
490
+ * Disables a plugin by name, wherever it lives.
491
+ *
492
+ * If the plugin's scope is currently active, the deactivation lifecycle
493
+ * runs immediately. If the scope is inactive, `isEnabled` is set but
494
+ * hooks do not fire — they already ran when the scope went inactive.
495
+ */
457
496
  disablePlugin(t) {
458
497
  const e = this.getPlugin(t);
459
- e && e.isEnabled !== !1 && this.deactivatePlugin(e);
498
+ if (!e || e.isEnabled === !1) return;
499
+ const s = this.findScopeForPlugin(e);
500
+ s !== null && s === this._activeScope && s.active ? this.deactivatePlugin(e) : e.isEnabled = !1;
460
501
  }
461
502
  togglePlugin(t) {
462
503
  const e = this.getPlugin(t);
463
504
  e && (e.isEnabled === !1 ? this.enablePlugin(t) : this.disablePlugin(t));
464
505
  }
506
+ /**
507
+ * Sets the cursor mode on the *active* scope.
508
+ *
509
+ * To set the mode on a specific scope, use `handle.setCursor(mode)`.
510
+ */
465
511
  setCursor(t) {
466
- this._activeScope && (this._activeScope.cursorMode = t, this.state.cursorMode = t);
512
+ this._activeScope && this.setScopeCursor(this._activeScope, t);
467
513
  }
468
514
  addScope(t) {
469
515
  const e = this.createScope(t);
470
- return this.input.setScopes(this._scopes), this.installPlugins(e), this.rebuildStylesheet(), this.scopeHandles.get(e);
516
+ return this.installPlugins(e), this.rebuildStylesheet(), this.scopeHandles.get(e);
471
517
  }
472
518
  enable() {
473
519
  this.input.isEnabled = !0, this.input.hasSeenPointer && (this.state.target.x = this.state.smooth.x = this.state.pointer.x, this.state.target.y = this.state.smooth.y = this.state.pointer.y, this.resetMotion(), this.state.hasReceivedInput = !0), this._activeScope && this._activeScope.stage.setNativeCursor(this.resolveCursorState());
@@ -476,7 +522,7 @@ class Y {
476
522
  this.input.isEnabled = !1, this._activeScope && (this._activeScope.stage.setNativeCursor("auto"), this._activeScope.stage.setVisibility(!1)), t?.reset && this.reset();
477
523
  }
478
524
  reset() {
479
- this.state.target = { ...f }, this.state.smooth = { ...f }, this.resetMotion(), this.state.angle = 0, this.state.hasReceivedInput = !1, this.state.shape = null, this.state.interaction = {};
525
+ this.state.target = { ...d }, this.state.smooth = { ...d }, this.resetMotion(), this.state.angle = 0, this.state.hasReceivedInput = !1, this.state.shape = null, this.state.interaction = {};
480
526
  }
481
527
  start() {
482
528
  this.startLoop();
@@ -490,25 +536,35 @@ class Y {
490
536
  for (const e of t.plugins)
491
537
  try {
492
538
  e.destroy?.(this);
493
- } catch {
539
+ } catch (s) {
540
+ console.error(s);
494
541
  }
495
542
  t.stage.destroy();
496
543
  }
497
- this._scopes = [], this.scopeByContainer.clear(), this.scopeByName.clear(), this.scopeHandles.clear(), this._activeScope = null, this.state.scope = null, Q(this.styleOwner);
544
+ this._scopes = [], this.scopeByName.clear(), this.scopeHandles.clear(), this._activeScope = null, this.state.scope = null, A(this.styleOwner);
498
545
  }
499
546
  // ─── Internal ───
500
547
  _running = !1;
501
548
  createScope(t) {
502
- this.scopeByContainer.has(t.container);
503
- const e = new L(t, {
549
+ if (typeof t.container != "string") {
550
+ const s = t.container;
551
+ for (const i of this._scopes)
552
+ if (i.containerSelector === null && i.container === s) {
553
+ console.warn(
554
+ "[Supermouse] A scope is already registered for this container. The previous scope will no longer activate."
555
+ );
556
+ break;
557
+ }
558
+ }
559
+ const e = new C(t, {
504
560
  cursor: this.options.cursor,
505
- hoverSelectors: this.options.hoverSelectors ?? R,
506
- cursorPolicy: this.options.cursorPolicy ? _(this.options.cursorPolicy) : x,
561
+ hoverSelectors: this.options.hoverSelectors ?? _,
562
+ cursorPolicy: this.options.cursorPolicy ? b(this.options.cursorPolicy) : S,
507
563
  zIndex: this.options.zIndex,
508
564
  inheritDataAttributes: this.options.inheritDataAttributes,
509
565
  ruleEntries: this.options.rules ? Object.entries(this.options.rules) : []
510
566
  });
511
- return this._scopes.push(e), this.scopeByContainer.set(e.container, e), e.name && this.scopeByName.set(e.name, e), this.scopeHandles.set(e, this.buildScopeHandle(e)), e;
567
+ return this._scopes.push(e), e.name && this.scopeByName.set(e.name, e), this.scopeHandles.set(e, this.buildScopeHandle(e)), e;
512
568
  }
513
569
  buildScopeHandle(t) {
514
570
  const e = {
@@ -516,55 +572,105 @@ class Y {
516
572
  return t.name;
517
573
  },
518
574
  get container() {
519
- return t.container;
575
+ return t.resolved ? t.container : null;
576
+ },
577
+ get active() {
578
+ return t.active;
520
579
  },
521
- get disabled() {
522
- return t.disabled;
580
+ get resolved() {
581
+ return t.resolved;
523
582
  },
524
- remove: () => this.removeScope(t),
583
+ destroy: () => this.destroyScope(t),
525
584
  setCursor: (s) => this.setScopeCursor(t, s),
526
- disable: () => this.disableScope(t),
527
- enable: () => this.enableScope(t),
585
+ deactivate: () => this.deactivateScope(t),
586
+ activate: () => this.activateScope(t),
528
587
  use: (s) => (this.installPlugin(t, s), e),
529
588
  removePlugin: (s) => this.removePluginFromScope(t, s),
530
- getPlugin: (s) => t.plugins.find((n) => n.name === s)
589
+ getPlugin: (s) => t.plugins.find((i) => i.name === s)
531
590
  };
532
591
  return e;
533
592
  }
534
- removeScope(t) {
593
+ destroyScope(t) {
535
594
  const e = this._scopes.indexOf(t);
536
595
  if (e !== -1) {
537
596
  for (const s of t.plugins)
538
597
  try {
539
598
  s.destroy?.(this);
540
- } catch {
599
+ } catch (i) {
600
+ console.error(i);
541
601
  }
542
- if (t.plugins.length = 0, t.stage.destroy(), this._scopes.splice(e, 1), this.scopeByContainer.delete(t.container), t.name && this.scopeByName.delete(t.name), this.scopeHandles.delete(t), this.input.setScopes(this._scopes), this._activeScope === t) {
543
- const s = this.findScopeAbove(t.container.parentElement) ?? this._scopes.find((n) => !n.disabled) ?? null;
544
- this.input.setActiveScope(s);
602
+ if (t.plugins.length = 0, t.stage.destroy(), this._scopes.splice(e, 1), t.name && this.scopeByName.delete(t.name), this.scopeHandles.delete(t), this._activeScope === t) {
603
+ const s = this.resolveScopeForNode(t.container.parentElement) ?? this._scopes.find((i) => i.active) ?? null;
604
+ this.input.setActiveScope(s), this.input.clearHover(), this.applyCursorNow();
545
605
  }
546
606
  this.rebuildStylesheet();
547
607
  }
548
608
  }
549
609
  setScopeCursor(t, e) {
550
- t.cursorMode = e, t === this._activeScope && (this.state.cursorMode = e);
610
+ t.cursorMode = e, t === this._activeScope && (this.state.cursorMode = e, this.applyCursorNow());
551
611
  }
552
- disableScope(t) {
553
- if (!t.disabled && (t.disabled = !0, this._activeScope === t)) {
554
- const e = this.findScopeAbove(t.container.parentElement) ?? this._scopes.find((s) => !s.disabled) ?? null;
555
- this.input.setActiveScope(e);
612
+ /**
613
+ * Marks the scope ineligible for activation and, if it was active, yields
614
+ * immediately to the nearest active ancestor scope (or nothing).
615
+ */
616
+ deactivateScope(t) {
617
+ if (t.active && (t.active = !1, this._activeScope === t)) {
618
+ const e = this.resolveScopeForNode(t.container.parentElement) ?? this._scopes.find((s) => s.active) ?? null;
619
+ this.input.setActiveScope(e), this.input.clearHover(), this.applyCursorNow();
556
620
  }
557
621
  }
558
- enableScope(t) {
559
- t.disabled = !1;
560
- }
561
- findScopeAbove(t) {
562
- let e = t;
563
- for (; e; ) {
564
- const s = this.scopeByContainer.get(e);
565
- if (s && !s.disabled) return s;
566
- e = e.parentElement;
622
+ /**
623
+ * Marks the scope eligible for activation.
624
+ *
625
+ * If the pointer is already inside the scope's container, the scope
626
+ * becomes active immediately. Otherwise it activates on the next
627
+ * `mouseover` inside the container. Deactivation is always eager.
628
+ */
629
+ activateScope(t) {
630
+ if (t.active = !0, this._activeScope !== t && this.input.hasSeenPointer) {
631
+ if (t.containerSelector !== null && !t.resolved) {
632
+ const e = document.querySelectorAll(t.containerSelector);
633
+ for (const s of e)
634
+ if (this.input.isPointerInside(s)) {
635
+ t.bind(s);
636
+ break;
637
+ }
638
+ }
639
+ t.resolved && this.input.isPointerInside(t.container) && (this.input.setActiveScope(t), this.applyCursorNow());
567
640
  }
641
+ }
642
+ /**
643
+ * Called by `Input` on every `mouseover`, and internally when the active
644
+ * scope is removed or deactivated. Walks from `node` up the ancestor
645
+ * chain, returning the innermost active scope whose `match` succeeds
646
+ * for an ancestor. The matched scope is bound to that ancestor before
647
+ * return.
648
+ *
649
+ * The walk order is what enforces "innermost wins": the first ancestor
650
+ * matching any active scope is, by construction, the closest one to the
651
+ * event target. Detached containers can never be ancestors of a live
652
+ * event target, so no cleanup of stale bindings is required here.
653
+ */
654
+ resolveScopeForNode(t) {
655
+ for (let e = t; e; e = e.parentElement)
656
+ for (const s of this._scopes)
657
+ if (s.active && s.match(e))
658
+ return s.bind(e), s;
659
+ return null;
660
+ }
661
+ /**
662
+ * Synchronously writes the current cursor and stage visibility for the
663
+ * active scope. Called after hover state settles, on cursor mode changes,
664
+ * and on programmatic scope transitions. The `update()` rAF path calls
665
+ * the same writers as a backstop.
666
+ */
667
+ applyCursorNow() {
668
+ const t = this._activeScope;
669
+ t && (t.stage.setVisibility(this.resolveStageVisibility()), this.input.isEnabled && t.stage.setNativeCursor(this.resolveCursorState()));
670
+ }
671
+ findScopeForPlugin(t) {
672
+ for (const e of this._scopes)
673
+ if (e.plugins.includes(t)) return e;
568
674
  return null;
569
675
  }
570
676
  installPlugins(t) {
@@ -572,32 +678,35 @@ class Y {
572
678
  for (const e of t.config.plugins) this.installPlugin(t, e);
573
679
  }
574
680
  installPlugin(t, e) {
575
- if (!t.plugins.some((s) => s.name === e.name)) {
576
- e.isEnabled ??= !0, this._installingScope = t;
577
- try {
578
- e.install?.(this);
579
- } catch {
580
- this._installingScope = null;
581
- return;
582
- }
583
- this._installingScope = null, t.plugins.push(e), t.plugins.sort((s, n) => (s.priority ?? 0) - (n.priority ?? 0)), (t !== this._activeScope || t.disabled) && e.element && (e.element.style.display = "none");
681
+ if (t.plugins.some((s) => s.name === e.name)) {
682
+ console.warn(`[Supermouse] Plugin "${e.name}" already installed.`);
683
+ return;
684
+ }
685
+ e.isEnabled ??= !0, this._installingScope = t;
686
+ try {
687
+ e.install?.(this);
688
+ } catch (s) {
689
+ console.error(`[Supermouse] Failed to install plugin '${e.name}'.`, s), this._installingScope = null;
690
+ return;
584
691
  }
692
+ this._installingScope = null, t.plugins.push(e), t.plugins.sort((s, i) => (s.priority ?? 0) - (i.priority ?? 0)), (t !== this._activeScope || !t.active) && e.element && (e.element.style.display = "none");
585
693
  }
586
694
  removePluginFromScope(t, e) {
587
- const s = t.plugins.findIndex((r) => r.name === e);
695
+ const s = t.plugins.findIndex((o) => o.name === e);
588
696
  if (s === -1) return;
589
- const n = t.plugins[s];
697
+ const i = t.plugins[s];
590
698
  t.plugins.splice(s, 1);
591
- const o = () => {
699
+ const h = () => {
592
700
  try {
593
- n.onDisable?.(this), n.destroy?.(this);
594
- } catch {
701
+ i.onDisable?.(this), i.destroy?.(this);
702
+ } catch (o) {
703
+ console.error(`[Supermouse] Plugin '${e}' cleanup threw:`, o);
595
704
  }
596
- n.element?.remove();
597
- }, h = n.onBeforeDisable?.(this);
598
- h && typeof h.then == "function" ? Promise.resolve(h).then(o).catch((r) => {
599
- o();
600
- }) : o();
705
+ i.element?.remove();
706
+ }, r = i.onBeforeDisable?.(this);
707
+ r && typeof r.then == "function" ? Promise.resolve(r).then(h).catch((o) => {
708
+ console.error(`[Supermouse] Plugin '${e}' onBeforeDisable threw:`, o), h();
709
+ }) : h();
601
710
  }
602
711
  handleActiveScopeChange(t) {
603
712
  const e = this._activeScope;
@@ -619,8 +728,8 @@ class Y {
619
728
  const e = () => {
620
729
  t.element && (t.element.style.display = "none"), t.onDisable?.(this);
621
730
  }, s = t.onBeforeDisable?.(this);
622
- s && typeof s.then == "function" ? Promise.resolve(s).then(e).catch((n) => {
623
- e();
731
+ s && typeof s.then == "function" ? Promise.resolve(s).then(e).catch((i) => {
732
+ console.error(`[Supermouse] Plugin '${t.name}' onBeforeDisable threw:`, i), e();
624
733
  }) : e();
625
734
  }
626
735
  /**
@@ -632,24 +741,24 @@ class Y {
632
741
  const e = () => {
633
742
  t.element && (t.element.style.display = "none"), t.onDisable?.(this);
634
743
  }, s = t.onBeforeDisable?.(this);
635
- s && typeof s.then == "function" ? Promise.resolve(s).then(e).catch((n) => {
636
- e();
744
+ s && typeof s.then == "function" ? Promise.resolve(s).then(e).catch((i) => {
745
+ console.error(`[Supermouse] Plugin '${t.name}' onBeforeDisable threw:`, i), e();
637
746
  }) : e();
638
747
  }
639
748
  scopeActivatePlugin(t) {
640
749
  t.element && (t.element.style.display = ""), t.onEnable?.(this);
641
750
  }
642
751
  rebuildStylesheet() {
643
- const t = [];
752
+ const t = [":where(.supermouse-scope .supermouse-scope) { cursor: auto }"];
644
753
  for (const e of this._scopes) t.push(...e.buildRules());
645
- j(this.styleOwner, t);
754
+ T(this.styleOwner, t);
646
755
  }
647
756
  runPluginSafe(t, e) {
648
757
  if (t.isEnabled !== !1)
649
758
  try {
650
759
  t.update?.(this, e);
651
- } catch {
652
- t.isEnabled = !1, this.crashedPlugins.push(t);
760
+ } catch (s) {
761
+ console.error(`[Supermouse] Plugin '${t.name}' crashed and has been disabled.`, s), t.isEnabled = !1, this.crashedPlugins.push(t);
653
762
  }
654
763
  }
655
764
  cleanupCrashedPlugins() {
@@ -664,7 +773,8 @@ class Y {
664
773
  }
665
774
  try {
666
775
  t.onDisable?.(this), t.destroy?.(this);
667
- } catch {
776
+ } catch (e) {
777
+ console.error(`[Supermouse] Failed to cleanup crashed plugin '${t.name}'.`, e);
668
778
  }
669
779
  t.element?.remove();
670
780
  }
@@ -683,17 +793,17 @@ class Y {
683
793
  update(t) {
684
794
  const e = t - this.lastTime, s = Math.min(e / 1e3, 0.1);
685
795
  this.lastTime = t;
686
- const n = this.input.getCurrentTarget();
687
- n && !n.isConnected ? this.input.clearHover() : n && this.input.parseDOMInteraction(n), this.input.isEnabled && this.state.hasReceivedInput && (this.state.target.x = this.state.pointer.x, this.state.target.y = this.state.pointer.y);
688
- const o = this._activeScope;
689
- if (o) {
690
- o.stage.setVisibility(this.resolveStageVisibility()), this.input.isEnabled && o.stage.setNativeCursor(this.resolveCursorState());
691
- for (let h = 0; h < o.plugins.length; h++)
692
- this.runPluginSafe(o.plugins[h], e);
796
+ const i = this.input.getCurrentTarget();
797
+ i && !i.isConnected ? this.input.clearHover() : i && this.input.parseDOMInteraction(i), this.input.isEnabled && this.state.hasReceivedInput && (this.state.target.x = this.state.pointer.x, this.state.target.y = this.state.pointer.y);
798
+ const h = this._activeScope;
799
+ if (h) {
800
+ h.stage.setVisibility(this.resolveStageVisibility()), this.input.isEnabled && h.stage.setNativeCursor(this.resolveCursorState());
801
+ for (let r = 0; r < h.plugins.length; r++)
802
+ this.runPluginSafe(h.plugins[r], e);
693
803
  }
694
804
  if (this.cleanupCrashedPlugins(), this.input.isEnabled) {
695
- const h = this.state.reducedMotion ? 1e3 : 1 / this.options.smoothness * 2, r = this.state.smooth.x, p = this.state.smooth.y;
696
- this.state.smooth.x = w(this.state.smooth.x, this.state.target.x, h, s), this.state.smooth.y = w(this.state.smooth.y, this.state.target.y, h, s), this.state.displacement.x = this.state.target.x - this.state.smooth.x, this.state.displacement.y = this.state.target.y - this.state.smooth.y, s > 0 ? (this.state.velocity.x = (this.state.smooth.x - r) / s, this.state.velocity.y = (this.state.smooth.y - p) / s) : (this.state.velocity.x = 0, this.state.velocity.y = 0);
805
+ const r = this.state.reducedMotion ? 1e3 : 1 / this.options.smoothness * 2, o = this.state.smooth.x, p = this.state.smooth.y;
806
+ this.state.smooth.x = m(this.state.smooth.x, this.state.target.x, r, s), this.state.smooth.y = m(this.state.smooth.y, this.state.target.y, r, s), this.state.displacement.x = this.state.target.x - this.state.smooth.x, this.state.displacement.y = this.state.target.y - this.state.smooth.y, s > 0 ? (this.state.velocity.x = (this.state.smooth.x - o) / s, this.state.velocity.y = (this.state.smooth.y - p) / s) : (this.state.velocity.x = 0, this.state.velocity.y = 0);
697
807
  const { x: c, y: a } = this.state.velocity;
698
808
  (Math.abs(c) > 0.1 || Math.abs(a) > 0.1) && (this.state.angle = Math.atan2(a, c) * (180 / Math.PI));
699
809
  }
@@ -713,22 +823,6 @@ class Y {
713
823
  startLoop() {
714
824
  this._running || (this._running = !0, !document.hidden && (this.lastTime = performance.now(), this.rafId = requestAnimationFrame(this.tick)));
715
825
  }
716
- /**
717
- * @deprecated Read from the active scope instead.
718
- * Exposed for tests and debugging.
719
- */
720
- get hoverSelectors() {
721
- const t = this._activeScope ?? this._scopes[0];
722
- return t ? t.hoverSelectors : /* @__PURE__ */ new Set();
723
- }
724
- /**
725
- * @deprecated Read from the active scope instead.
726
- * Exposed for tests and debugging.
727
- */
728
- get plugins() {
729
- const t = this._activeScope ?? this._scopes[0];
730
- return t ? t.plugins : [];
731
- }
732
826
  /**
733
827
  * Adds one or more hover selectors to the current scope. Intended for
734
828
  * raw-object plugins during `install`. Plugins written with `definePlugin`
@@ -739,13 +833,13 @@ class Y {
739
833
  const e = this._installingScope ?? this._activeScope ?? this._scopes[0];
740
834
  if (e)
741
835
  for (const s of t.split(",")) {
742
- const n = s.trim();
743
- n && e.hoverSelectors.add(n);
836
+ const i = s.trim();
837
+ i && e.hoverSelectors.add(i);
744
838
  }
745
839
  }
746
840
  }
747
841
  export {
748
- x as DEFAULT_CURSOR_POLICY,
749
- R as DEFAULT_HOVER_SELECTORS,
750
- Y as Supermouse
842
+ S as DEFAULT_CURSOR_POLICY,
843
+ _ as DEFAULT_HOVER_SELECTORS,
844
+ I as Supermouse
751
845
  };