@page-agent/page-controller 1.7.1 → 1.8.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.
@@ -92,19 +92,6 @@
92
92
  console.error("vite-plugin-css-injected-by-js", e);
93
93
  }
94
94
  })();
95
- var __defProp = Object.defineProperty;
96
- var __typeError = (msg) => {
97
- throw TypeError(msg);
98
- };
99
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
100
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
101
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
102
- var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
103
- var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
104
- var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
105
- var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
106
- var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
107
- var _cursor, _currentCursorX, _currentCursorY, _targetCursorX, _targetCursorY, _SimulatorMask_instances, createCursor_fn, moveCursorToTarget_fn;
108
95
  import { Motion } from "ai-motion";
109
96
  function hasDarkModeClass() {
110
97
  const DEFAULT_DARK_MODE_CLASSES = ["dark", "dark-mode", "theme-dark", "night", "night-mode"];
@@ -121,7 +108,6 @@ function hasDarkModeClass() {
121
108
  }
122
109
  return false;
123
110
  }
124
- __name(hasDarkModeClass, "hasDarkModeClass");
125
111
  function parseRgbColor(colorString) {
126
112
  const rgbMatch = /rgba?\((\d+),\s*(\d+),\s*(\d+)/.exec(colorString);
127
113
  if (!rgbMatch) {
@@ -133,7 +119,6 @@ function parseRgbColor(colorString) {
133
119
  b: parseInt(rgbMatch[3])
134
120
  };
135
121
  }
136
- __name(parseRgbColor, "parseRgbColor");
137
122
  function isColorDark(colorString, threshold = 128) {
138
123
  if (!colorString || colorString === "transparent" || colorString.startsWith("rgba(0, 0, 0, 0)")) {
139
124
  return false;
@@ -145,7 +130,6 @@ function isColorDark(colorString, threshold = 128) {
145
130
  const luminance = 0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.b;
146
131
  return luminance < threshold;
147
132
  }
148
- __name(isColorDark, "isColorDark");
149
133
  function isBackgroundDark() {
150
134
  const htmlStyle = window.getComputedStyle(document.documentElement);
151
135
  const bodyStyle = window.getComputedStyle(document.body || document.documentElement);
@@ -158,7 +142,6 @@ function isBackgroundDark() {
158
142
  }
159
143
  return false;
160
144
  }
161
- __name(isBackgroundDark, "isBackgroundDark");
162
145
  function isPageDark() {
163
146
  try {
164
147
  if (hasDarkModeClass()) {
@@ -173,7 +156,6 @@ function isPageDark() {
173
156
  return false;
174
157
  }
175
158
  }
176
- __name(isPageDark, "isPageDark");
177
159
  const wrapper = "_wrapper_1ooyb_1";
178
160
  const visible = "_visible_1ooyb_11";
179
161
  const styles = {
@@ -192,18 +174,18 @@ const cursorStyles = {
192
174
  cursorRipple,
193
175
  clicking
194
176
  };
195
- const _SimulatorMask = class _SimulatorMask extends EventTarget {
177
+ class SimulatorMask extends EventTarget {
178
+ shown = false;
179
+ wrapper = document.createElement("div");
180
+ motion = null;
181
+ #disposed = false;
182
+ #cursor = document.createElement("div");
183
+ #currentCursorX = 0;
184
+ #currentCursorY = 0;
185
+ #targetCursorX = 0;
186
+ #targetCursorY = 0;
196
187
  constructor() {
197
188
  super();
198
- __privateAdd(this, _SimulatorMask_instances);
199
- __publicField(this, "shown", false);
200
- __publicField(this, "wrapper", document.createElement("div"));
201
- __publicField(this, "motion", null);
202
- __privateAdd(this, _cursor, document.createElement("div"));
203
- __privateAdd(this, _currentCursorX, 0);
204
- __privateAdd(this, _currentCursorY, 0);
205
- __privateAdd(this, _targetCursorX, 0);
206
- __privateAdd(this, _targetCursorY, 0);
207
189
  this.wrapper.id = "page-agent-runtime_simulator-mask";
208
190
  this.wrapper.className = styles.wrapper;
209
191
  this.wrapper.setAttribute("data-browser-use-ignore", "true");
@@ -247,22 +229,22 @@ const _SimulatorMask = class _SimulatorMask extends EventTarget {
247
229
  e.stopPropagation();
248
230
  e.preventDefault();
249
231
  });
250
- __privateMethod(this, _SimulatorMask_instances, createCursor_fn).call(this);
232
+ this.#createCursor();
251
233
  document.body.appendChild(this.wrapper);
252
- __privateMethod(this, _SimulatorMask_instances, moveCursorToTarget_fn).call(this);
253
- const movePointerToListener = /* @__PURE__ */ __name((event) => {
234
+ this.#moveCursorToTarget();
235
+ const movePointerToListener = (event) => {
254
236
  const { x, y } = event.detail;
255
237
  this.setCursorPosition(x, y);
256
- }, "movePointerToListener");
257
- const clickPointerListener = /* @__PURE__ */ __name(() => {
238
+ };
239
+ const clickPointerListener = () => {
258
240
  this.triggerClickAnimation();
259
- }, "clickPointerListener");
260
- const enablePassThroughListener = /* @__PURE__ */ __name(() => {
241
+ };
242
+ const enablePassThroughListener = () => {
261
243
  this.wrapper.style.pointerEvents = "none";
262
- }, "enablePassThroughListener");
263
- const disablePassThroughListener = /* @__PURE__ */ __name(() => {
244
+ };
245
+ const disablePassThroughListener = () => {
264
246
  this.wrapper.style.pointerEvents = "auto";
265
- }, "disablePassThroughListener");
247
+ };
266
248
  window.addEventListener("PageAgent::MovePointerTo", movePointerToListener);
267
249
  window.addEventListener("PageAgent::ClickPointer", clickPointerListener);
268
250
  window.addEventListener("PageAgent::EnablePassThrough", enablePassThroughListener);
@@ -274,90 +256,86 @@ const _SimulatorMask = class _SimulatorMask extends EventTarget {
274
256
  window.removeEventListener("PageAgent::DisablePassThrough", disablePassThroughListener);
275
257
  });
276
258
  }
259
+ #createCursor() {
260
+ this.#cursor.className = cursorStyles.cursor;
261
+ const rippleContainer = document.createElement("div");
262
+ rippleContainer.className = cursorStyles.cursorRipple;
263
+ this.#cursor.appendChild(rippleContainer);
264
+ const fillingLayer = document.createElement("div");
265
+ fillingLayer.className = cursorStyles.cursorFilling;
266
+ this.#cursor.appendChild(fillingLayer);
267
+ const borderLayer = document.createElement("div");
268
+ borderLayer.className = cursorStyles.cursorBorder;
269
+ this.#cursor.appendChild(borderLayer);
270
+ this.wrapper.appendChild(this.#cursor);
271
+ }
272
+ #moveCursorToTarget() {
273
+ if (this.#disposed) return;
274
+ const newX = this.#currentCursorX + (this.#targetCursorX - this.#currentCursorX) * 0.2;
275
+ const newY = this.#currentCursorY + (this.#targetCursorY - this.#currentCursorY) * 0.2;
276
+ const xDistance = Math.abs(newX - this.#targetCursorX);
277
+ if (xDistance > 0) {
278
+ if (xDistance < 2) {
279
+ this.#currentCursorX = this.#targetCursorX;
280
+ } else {
281
+ this.#currentCursorX = newX;
282
+ }
283
+ this.#cursor.style.left = `${this.#currentCursorX}px`;
284
+ }
285
+ const yDistance = Math.abs(newY - this.#targetCursorY);
286
+ if (yDistance > 0) {
287
+ if (yDistance < 2) {
288
+ this.#currentCursorY = this.#targetCursorY;
289
+ } else {
290
+ this.#currentCursorY = newY;
291
+ }
292
+ this.#cursor.style.top = `${this.#currentCursorY}px`;
293
+ }
294
+ requestAnimationFrame(() => this.#moveCursorToTarget());
295
+ }
277
296
  setCursorPosition(x, y) {
278
- __privateSet(this, _targetCursorX, x);
279
- __privateSet(this, _targetCursorY, y);
297
+ if (this.#disposed) return;
298
+ this.#targetCursorX = x;
299
+ this.#targetCursorY = y;
280
300
  }
281
301
  triggerClickAnimation() {
282
- __privateGet(this, _cursor).classList.remove(cursorStyles.clicking);
283
- void __privateGet(this, _cursor).offsetHeight;
284
- __privateGet(this, _cursor).classList.add(cursorStyles.clicking);
302
+ if (this.#disposed) return;
303
+ this.#cursor.classList.remove(cursorStyles.clicking);
304
+ void this.#cursor.offsetHeight;
305
+ this.#cursor.classList.add(cursorStyles.clicking);
285
306
  }
286
307
  show() {
287
- if (this.shown) return;
308
+ if (this.shown || this.#disposed) return;
288
309
  this.shown = true;
289
310
  this.motion?.start();
290
311
  this.motion?.fadeIn();
291
312
  this.wrapper.classList.add(styles.visible);
292
- __privateSet(this, _currentCursorX, window.innerWidth / 2);
293
- __privateSet(this, _currentCursorY, window.innerHeight / 2);
294
- __privateSet(this, _targetCursorX, __privateGet(this, _currentCursorX));
295
- __privateSet(this, _targetCursorY, __privateGet(this, _currentCursorY));
296
- __privateGet(this, _cursor).style.left = `${__privateGet(this, _currentCursorX)}px`;
297
- __privateGet(this, _cursor).style.top = `${__privateGet(this, _currentCursorY)}px`;
313
+ this.#currentCursorX = window.innerWidth / 2;
314
+ this.#currentCursorY = window.innerHeight / 2;
315
+ this.#targetCursorX = this.#currentCursorX;
316
+ this.#targetCursorY = this.#currentCursorY;
317
+ this.#cursor.style.left = `${this.#currentCursorX}px`;
318
+ this.#cursor.style.top = `${this.#currentCursorY}px`;
298
319
  }
299
320
  hide() {
300
- if (!this.shown) return;
321
+ if (!this.shown || this.#disposed) return;
301
322
  this.shown = false;
302
323
  this.motion?.fadeOut();
303
324
  this.motion?.pause();
304
- __privateGet(this, _cursor).classList.remove(cursorStyles.clicking);
325
+ this.#cursor.classList.remove(cursorStyles.clicking);
305
326
  setTimeout(() => {
306
327
  this.wrapper.classList.remove(styles.visible);
307
328
  }, 800);
308
329
  }
309
330
  dispose() {
331
+ this.#disposed = true;
310
332
  console.log("dispose SimulatorMask");
311
333
  this.motion?.dispose();
312
334
  this.wrapper.remove();
313
335
  this.dispatchEvent(new Event("dispose"));
314
336
  }
315
- };
316
- _cursor = new WeakMap();
317
- _currentCursorX = new WeakMap();
318
- _currentCursorY = new WeakMap();
319
- _targetCursorX = new WeakMap();
320
- _targetCursorY = new WeakMap();
321
- _SimulatorMask_instances = new WeakSet();
322
- createCursor_fn = /* @__PURE__ */ __name(function() {
323
- __privateGet(this, _cursor).className = cursorStyles.cursor;
324
- const rippleContainer = document.createElement("div");
325
- rippleContainer.className = cursorStyles.cursorRipple;
326
- __privateGet(this, _cursor).appendChild(rippleContainer);
327
- const fillingLayer = document.createElement("div");
328
- fillingLayer.className = cursorStyles.cursorFilling;
329
- __privateGet(this, _cursor).appendChild(fillingLayer);
330
- const borderLayer = document.createElement("div");
331
- borderLayer.className = cursorStyles.cursorBorder;
332
- __privateGet(this, _cursor).appendChild(borderLayer);
333
- this.wrapper.appendChild(__privateGet(this, _cursor));
334
- }, "#createCursor");
335
- moveCursorToTarget_fn = /* @__PURE__ */ __name(function() {
336
- const newX = __privateGet(this, _currentCursorX) + (__privateGet(this, _targetCursorX) - __privateGet(this, _currentCursorX)) * 0.2;
337
- const newY = __privateGet(this, _currentCursorY) + (__privateGet(this, _targetCursorY) - __privateGet(this, _currentCursorY)) * 0.2;
338
- const xDistance = Math.abs(newX - __privateGet(this, _targetCursorX));
339
- if (xDistance > 0) {
340
- if (xDistance < 2) {
341
- __privateSet(this, _currentCursorX, __privateGet(this, _targetCursorX));
342
- } else {
343
- __privateSet(this, _currentCursorX, newX);
344
- }
345
- __privateGet(this, _cursor).style.left = `${__privateGet(this, _currentCursorX)}px`;
346
- }
347
- const yDistance = Math.abs(newY - __privateGet(this, _targetCursorY));
348
- if (yDistance > 0) {
349
- if (yDistance < 2) {
350
- __privateSet(this, _currentCursorY, __privateGet(this, _targetCursorY));
351
- } else {
352
- __privateSet(this, _currentCursorY, newY);
353
- }
354
- __privateGet(this, _cursor).style.top = `${__privateGet(this, _currentCursorY)}px`;
355
- }
356
- requestAnimationFrame(() => __privateMethod(this, _SimulatorMask_instances, moveCursorToTarget_fn).call(this));
357
- }, "#moveCursorToTarget");
358
- __name(_SimulatorMask, "SimulatorMask");
359
- let SimulatorMask = _SimulatorMask;
337
+ }
360
338
  export {
361
339
  SimulatorMask
362
340
  };
363
- //# sourceMappingURL=SimulatorMask-CU7szDjy.js.map
341
+ //# sourceMappingURL=SimulatorMask-BfJiQVCo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SimulatorMask-BfJiQVCo.js","sources":["../../src/mask/checkDarkMode.ts","../../src/mask/SimulatorMask.ts"],"sourcesContent":["/**\n * Checks for common dark mode CSS classes on the html or body elements.\n * @returns {boolean} - True if a common dark mode class is found.\n */\nfunction hasDarkModeClass() {\n\tconst DEFAULT_DARK_MODE_CLASSES = ['dark', 'dark-mode', 'theme-dark', 'night', 'night-mode']\n\n\tconst htmlElement = document.documentElement\n\tconst bodyElement = document.body || document.documentElement // can be null in some cases\n\n\t// Check class names on <html> and <body>\n\tfor (const className of DEFAULT_DARK_MODE_CLASSES) {\n\t\tif (htmlElement.classList.contains(className) || bodyElement?.classList.contains(className)) {\n\t\t\treturn true\n\t\t}\n\t}\n\n\t// Some sites use data attributes\n\tconst darkThemeAttribute = htmlElement.getAttribute('data-theme')\n\tif (darkThemeAttribute?.toLowerCase().includes('dark')) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n/**\n * Parses an RGB or RGBA color string and returns an object with r, g, b properties.\n * @param {string} colorString - e.g., \"rgb(34, 34, 34)\" or \"rgba(0, 0, 0, 0.5)\"\n * @returns {{r: number, g: number, b: number}|null}\n */\nfunction parseRgbColor(colorString: string) {\n\tconst rgbMatch = /rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)/.exec(colorString)\n\tif (!rgbMatch) {\n\t\treturn null // Not a valid rgb/rgba string\n\t}\n\treturn {\n\t\tr: parseInt(rgbMatch[1]),\n\t\tg: parseInt(rgbMatch[2]),\n\t\tb: parseInt(rgbMatch[3]),\n\t}\n}\n\n/**\n * Determines if a color is \"dark\" based on its calculated luminance.\n * @param {string} colorString - The CSS color string (e.g., \"rgb(50, 50, 50)\").\n * @param {number} threshold - A value between 0 and 255. Colors with luminance below this will be considered dark. Default is 128.\n * @returns {boolean} - True if the color is considered dark.\n */\nfunction isColorDark(colorString: string, threshold = 128) {\n\tif (!colorString || colorString === 'transparent' || colorString.startsWith('rgba(0, 0, 0, 0)')) {\n\t\treturn false // Transparent is not dark\n\t}\n\n\tconst rgb = parseRgbColor(colorString)\n\tif (!rgb) {\n\t\treturn false // Could not parse color\n\t}\n\n\t// Calculate perceived luminance using the standard formula\n\tconst luminance = 0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.b\n\n\treturn luminance < threshold\n}\n\n/**\n * Checks the background color of the body element to determine if the page is dark.\n * @returns {boolean}\n */\nfunction isBackgroundDark() {\n\t// We check both <html> and <body> because some pages set the color on <html>\n\tconst htmlStyle = window.getComputedStyle(document.documentElement)\n\tconst bodyStyle = window.getComputedStyle(document.body || document.documentElement)\n\n\t// Get background colors\n\tconst htmlBgColor = htmlStyle.backgroundColor\n\tconst bodyBgColor = bodyStyle.backgroundColor\n\n\t// The body's background might be transparent, in which case we should\n\t// fall back to the html element's background.\n\tif (isColorDark(bodyBgColor)) {\n\t\treturn true\n\t} else if (bodyBgColor === 'transparent' || bodyBgColor.startsWith('rgba(0, 0, 0, 0)')) {\n\t\treturn isColorDark(htmlBgColor)\n\t}\n\n\treturn false\n}\n\n/**\n * A comprehensive function to determine if the page is currently in a dark theme.\n * It combines class checking and background color analysis.\n * @returns {boolean} - True if the page is likely dark.\n */\nexport function isPageDark() {\n\ttry {\n\t\t// Strategy 1: Check for common dark mode classes\n\t\tif (hasDarkModeClass()) {\n\t\t\treturn true\n\t\t}\n\n\t\t// Strategy 2: Analyze the computed background color\n\t\tif (isBackgroundDark()) {\n\t\t\treturn true\n\t\t}\n\n\t\t// @TODO add more checks here, e.g., analyzing text color,\n\t\t// or checking the background of major layout elements like <main> or #app.\n\n\t\treturn false\n\t} catch (error) {\n\t\tconsole.warn('Error determining if page is dark:', error)\n\t\treturn false\n\t}\n}\n","import { Motion } from 'ai-motion'\n\nimport { isPageDark } from './checkDarkMode'\n\nimport styles from './SimulatorMask.module.css'\nimport cursorStyles from './cursor.module.css'\n\nexport class SimulatorMask extends EventTarget {\n\tshown: boolean = false\n\twrapper = document.createElement('div')\n\tmotion: Motion | null = null\n\n\t#disposed = false\n\n\t#cursor = document.createElement('div')\n\n\t#currentCursorX = 0\n\t#currentCursorY = 0\n\n\t#targetCursorX = 0\n\t#targetCursorY = 0\n\n\tconstructor() {\n\t\tsuper()\n\n\t\tthis.wrapper.id = 'page-agent-runtime_simulator-mask'\n\t\tthis.wrapper.className = styles.wrapper\n\t\tthis.wrapper.setAttribute('data-browser-use-ignore', 'true')\n\t\tthis.wrapper.setAttribute('data-page-agent-ignore', 'true')\n\n\t\ttry {\n\t\t\tconst motion = new Motion({\n\t\t\t\tmode: isPageDark() ? 'dark' : 'light',\n\t\t\t\tstyles: { position: 'absolute', inset: '0' },\n\t\t\t})\n\t\t\tthis.motion = motion\n\t\t\tthis.wrapper.appendChild(motion.element)\n\t\t\tmotion.autoResize(this.wrapper)\n\t\t} catch (e) {\n\t\t\tconsole.warn('[SimulatorMask] Motion overlay unavailable:', e)\n\t\t}\n\n\t\t// Capture all mouse, keyboard, and wheel events\n\t\tthis.wrapper.addEventListener('click', (e) => {\n\t\t\te.stopPropagation()\n\t\t\te.preventDefault()\n\t\t})\n\t\tthis.wrapper.addEventListener('mousedown', (e) => {\n\t\t\te.stopPropagation()\n\t\t\te.preventDefault()\n\t\t})\n\t\tthis.wrapper.addEventListener('mouseup', (e) => {\n\t\t\te.stopPropagation()\n\t\t\te.preventDefault()\n\t\t})\n\t\tthis.wrapper.addEventListener('mousemove', (e) => {\n\t\t\te.stopPropagation()\n\t\t\te.preventDefault()\n\t\t})\n\t\tthis.wrapper.addEventListener('wheel', (e) => {\n\t\t\te.stopPropagation()\n\t\t\te.preventDefault()\n\t\t})\n\t\tthis.wrapper.addEventListener('keydown', (e) => {\n\t\t\te.stopPropagation()\n\t\t\te.preventDefault()\n\t\t})\n\t\tthis.wrapper.addEventListener('keyup', (e) => {\n\t\t\te.stopPropagation()\n\t\t\te.preventDefault()\n\t\t})\n\n\t\t// Create AI cursor\n\t\tthis.#createCursor()\n\t\t// this.show()\n\n\t\tdocument.body.appendChild(this.wrapper)\n\n\t\tthis.#moveCursorToTarget()\n\n\t\t// global events\n\t\t// @note Mask should be isolated from the rest of the code.\n\t\t// Global events are easier to manage and cleanup.\n\n\t\tconst movePointerToListener = (event: Event) => {\n\t\t\tconst { x, y } = (event as CustomEvent).detail\n\t\t\tthis.setCursorPosition(x, y)\n\t\t}\n\t\tconst clickPointerListener = () => {\n\t\t\tthis.triggerClickAnimation()\n\t\t}\n\t\tconst enablePassThroughListener = () => {\n\t\t\tthis.wrapper.style.pointerEvents = 'none'\n\t\t}\n\t\tconst disablePassThroughListener = () => {\n\t\t\tthis.wrapper.style.pointerEvents = 'auto'\n\t\t}\n\n\t\twindow.addEventListener('PageAgent::MovePointerTo', movePointerToListener)\n\t\twindow.addEventListener('PageAgent::ClickPointer', clickPointerListener)\n\t\twindow.addEventListener('PageAgent::EnablePassThrough', enablePassThroughListener)\n\t\twindow.addEventListener('PageAgent::DisablePassThrough', disablePassThroughListener)\n\n\t\tthis.addEventListener('dispose', () => {\n\t\t\twindow.removeEventListener('PageAgent::MovePointerTo', movePointerToListener)\n\t\t\twindow.removeEventListener('PageAgent::ClickPointer', clickPointerListener)\n\t\t\twindow.removeEventListener('PageAgent::EnablePassThrough', enablePassThroughListener)\n\t\t\twindow.removeEventListener('PageAgent::DisablePassThrough', disablePassThroughListener)\n\t\t})\n\t}\n\n\t#createCursor() {\n\t\tthis.#cursor.className = cursorStyles.cursor\n\n\t\t// Create ripple effect container\n\t\tconst rippleContainer = document.createElement('div')\n\t\trippleContainer.className = cursorStyles.cursorRipple\n\t\tthis.#cursor.appendChild(rippleContainer)\n\n\t\t// Create filling layer\n\t\tconst fillingLayer = document.createElement('div')\n\t\tfillingLayer.className = cursorStyles.cursorFilling\n\t\tthis.#cursor.appendChild(fillingLayer)\n\n\t\t// Create border layer\n\t\tconst borderLayer = document.createElement('div')\n\t\tborderLayer.className = cursorStyles.cursorBorder\n\t\tthis.#cursor.appendChild(borderLayer)\n\n\t\tthis.wrapper.appendChild(this.#cursor)\n\t}\n\n\t#moveCursorToTarget() {\n\t\tif (this.#disposed) return\n\n\t\tconst newX = this.#currentCursorX + (this.#targetCursorX - this.#currentCursorX) * 0.2\n\t\tconst newY = this.#currentCursorY + (this.#targetCursorY - this.#currentCursorY) * 0.2\n\n\t\tconst xDistance = Math.abs(newX - this.#targetCursorX)\n\t\tif (xDistance > 0) {\n\t\t\tif (xDistance < 2) {\n\t\t\t\tthis.#currentCursorX = this.#targetCursorX\n\t\t\t} else {\n\t\t\t\tthis.#currentCursorX = newX\n\t\t\t}\n\t\t\tthis.#cursor.style.left = `${this.#currentCursorX}px`\n\t\t}\n\n\t\tconst yDistance = Math.abs(newY - this.#targetCursorY)\n\t\tif (yDistance > 0) {\n\t\t\tif (yDistance < 2) {\n\t\t\t\tthis.#currentCursorY = this.#targetCursorY\n\t\t\t} else {\n\t\t\t\tthis.#currentCursorY = newY\n\t\t\t}\n\t\t\tthis.#cursor.style.top = `${this.#currentCursorY}px`\n\t\t}\n\n\t\trequestAnimationFrame(() => this.#moveCursorToTarget())\n\t}\n\n\tsetCursorPosition(x: number, y: number) {\n\t\tif (this.#disposed) return\n\n\t\tthis.#targetCursorX = x\n\t\tthis.#targetCursorY = y\n\t}\n\n\ttriggerClickAnimation() {\n\t\tif (this.#disposed) return\n\n\t\tthis.#cursor.classList.remove(cursorStyles.clicking)\n\t\t// Force reflow to restart animation\n\t\tvoid this.#cursor.offsetHeight\n\t\tthis.#cursor.classList.add(cursorStyles.clicking)\n\t}\n\n\tshow() {\n\t\tif (this.shown || this.#disposed) return\n\n\t\tthis.shown = true\n\t\tthis.motion?.start()\n\t\tthis.motion?.fadeIn()\n\n\t\tthis.wrapper.classList.add(styles.visible)\n\n\t\t// Initialize cursor position\n\t\tthis.#currentCursorX = window.innerWidth / 2\n\t\tthis.#currentCursorY = window.innerHeight / 2\n\t\tthis.#targetCursorX = this.#currentCursorX\n\t\tthis.#targetCursorY = this.#currentCursorY\n\t\tthis.#cursor.style.left = `${this.#currentCursorX}px`\n\t\tthis.#cursor.style.top = `${this.#currentCursorY}px`\n\t}\n\n\thide() {\n\t\tif (!this.shown || this.#disposed) return\n\n\t\tthis.shown = false\n\t\tthis.motion?.fadeOut()\n\t\tthis.motion?.pause()\n\n\t\tthis.#cursor.classList.remove(cursorStyles.clicking)\n\n\t\tsetTimeout(() => {\n\t\t\tthis.wrapper.classList.remove(styles.visible)\n\t\t}, 800) // Match the animation duration\n\t}\n\n\tdispose() {\n\t\tthis.#disposed = true\n\t\tconsole.log('dispose SimulatorMask')\n\t\tthis.motion?.dispose()\n\t\tthis.wrapper.remove()\n\t\tthis.dispatchEvent(new Event('dispose'))\n\t}\n}\n"],"names":[],"mappings":"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"}