directix 1.0.0 → 1.2.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.
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * directix v1.0.0
2
+ * directix v1.2.0
3
3
  * A comprehensive, easy-to-use, and high-performance Vue custom directives library supporting both Vue 2 and Vue 3
4
4
  * (c) 2021-present saqqdy <https://github.com/saqqdy>
5
5
  * Released under the MIT License.
@@ -10,6 +10,7 @@ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
10
10
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
11
11
  var __hasOwnProp = Object.prototype.hasOwnProperty;
12
12
  var __propIsEnum = Object.prototype.propertyIsEnumerable;
13
+ var __pow = Math.pow;
13
14
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
14
15
  var __spreadValues = (a, b) => {
15
16
  for (var prop in b || (b = {}))
@@ -56,69 +57,11 @@ var __async = (__this, __arguments, generator) => {
56
57
  });
57
58
  };
58
59
  /*!
59
- * directix v1.0.0
60
+ * directix v1.2.0
60
61
  * A comprehensive, easy-to-use, and high-performance Vue custom directives library supporting both Vue 2 and Vue 3
61
62
  * (c) 2021-present saqqdy <https://github.com/saqqdy>
62
63
  * Released under the MIT License.
63
64
  */
64
- let _vueVersion = null;
65
- function getVueVersion() {
66
- var _a, _b;
67
- if (_vueVersion !== null) return _vueVersion;
68
- try {
69
- const vue = require("vue");
70
- if ((_a = vue == null ? void 0 : vue.version) == null ? void 0 : _a.startsWith("2")) {
71
- _vueVersion = 2;
72
- } else if ((_b = vue == null ? void 0 : vue.version) == null ? void 0 : _b.startsWith("3")) {
73
- _vueVersion = 3;
74
- }
75
- } catch (e) {
76
- }
77
- if (_vueVersion === null) {
78
- if (typeof window !== "undefined") {
79
- console.warn(
80
- "[Directix] Unable to detect Vue version, defaulting to Vue 3. Please ensure Vue is installed correctly."
81
- );
82
- }
83
- _vueVersion = 3;
84
- }
85
- return _vueVersion;
86
- }
87
- const isVue2 = () => getVueVersion() === 2;
88
- const isVue3 = () => getVueVersion() === 3;
89
- const isBrowser = () => {
90
- return typeof window !== "undefined" && typeof document !== "undefined";
91
- };
92
- const isSSR = () => !isBrowser();
93
- const supportsPassive = () => {
94
- if (!isBrowser()) return false;
95
- let supports = false;
96
- try {
97
- const options = {
98
- get passive() {
99
- supports = true;
100
- return false;
101
- }
102
- };
103
- window.addEventListener("test", null, options);
104
- window.removeEventListener("test", null, options);
105
- } catch (e) {
106
- supports = false;
107
- }
108
- return supports;
109
- };
110
- const supportsIntersectionObserver = () => {
111
- return isBrowser() && "IntersectionObserver" in window;
112
- };
113
- const supportsResizeObserver = () => {
114
- return isBrowser() && "ResizeObserver" in window;
115
- };
116
- const supportsClipboard = () => {
117
- return isBrowser() && "clipboard" in navigator;
118
- };
119
- const supportsMutationObserver = () => {
120
- return isBrowser() && "MutationObserver" in window;
121
- };
122
65
  function createVue2Directive(hooks) {
123
66
  const directive = {
124
67
  bind(el, binding, vnode) {
@@ -247,6 +190,145 @@ function addCleanup(el, fn) {
247
190
  state.cleanup.push(fn);
248
191
  }
249
192
  }
193
+ let _vueVersion = null, _isVue2 = null, _isVue27 = null, _isVue3 = null;
194
+ function parseVersion(version) {
195
+ if (version.startsWith("2.7")) return 2.7;
196
+ if (version.startsWith("2")) return 2;
197
+ if (version.startsWith("3")) return 3;
198
+ return null;
199
+ }
200
+ function getVueVersion() {
201
+ var _a, _b;
202
+ if (_vueVersion !== null) return _vueVersion;
203
+ if (typeof process !== "undefined") {
204
+ const envVersion = process.env.DIRECTIX_VUE_VERSION;
205
+ if (envVersion === "2.7") {
206
+ _vueVersion = 2.7;
207
+ return _vueVersion;
208
+ }
209
+ if (envVersion === "2") {
210
+ _vueVersion = 2;
211
+ return _vueVersion;
212
+ }
213
+ if (envVersion === "3") {
214
+ _vueVersion = 3;
215
+ return _vueVersion;
216
+ }
217
+ }
218
+ try {
219
+ const vue = require("vue");
220
+ const version = parseVersion(vue == null ? void 0 : vue.version);
221
+ if (version !== null) {
222
+ _vueVersion = version;
223
+ return _vueVersion;
224
+ }
225
+ } catch (e) {
226
+ }
227
+ if (typeof window !== "undefined") {
228
+ const win = window;
229
+ const vue = win.Vue;
230
+ if (vue == null ? void 0 : vue.version) {
231
+ const version = parseVersion(vue.version);
232
+ if (version !== null) {
233
+ _vueVersion = version;
234
+ return _vueVersion;
235
+ }
236
+ }
237
+ if (typeof (vue == null ? void 0 : vue.observable) === "function") {
238
+ _vueVersion = 2;
239
+ return _vueVersion;
240
+ }
241
+ if (typeof (vue == null ? void 0 : vue.createApp) === "function" && typeof (vue == null ? void 0 : vue.observable) !== "function") {
242
+ _vueVersion = 3;
243
+ return _vueVersion;
244
+ }
245
+ const devtools = win.__VUE_DEVTOOLS_GLOBAL_HOOK__;
246
+ if ((_a = devtools == null ? void 0 : devtools.Vue) == null ? void 0 : _a.version) {
247
+ const version = parseVersion(devtools.Vue.version);
248
+ if (version !== null) {
249
+ _vueVersion = version;
250
+ return _vueVersion;
251
+ }
252
+ }
253
+ if ((_b = devtools == null ? void 0 : devtools.apps) == null ? void 0 : _b.length) {
254
+ _vueVersion = 3;
255
+ return _vueVersion;
256
+ }
257
+ }
258
+ if (_vueVersion === null) {
259
+ if (typeof window !== "undefined") {
260
+ console.warn(
261
+ "[Directix] Unable to detect Vue version, defaulting to Vue 3. Set DIRECTIX_VUE_VERSION=2 or call setVueVersion(2) if using Vue 2."
262
+ );
263
+ }
264
+ _vueVersion = 3;
265
+ }
266
+ return _vueVersion;
267
+ }
268
+ function setVueVersion(version) {
269
+ _vueVersion = version;
270
+ _isVue2 = version === 2 || version === 2.7;
271
+ _isVue27 = version === 2.7;
272
+ _isVue3 = version === 3;
273
+ }
274
+ function resetVueVersion() {
275
+ _vueVersion = null;
276
+ _isVue2 = null;
277
+ _isVue27 = null;
278
+ _isVue3 = null;
279
+ }
280
+ function isVue2() {
281
+ if (_isVue2 === null) {
282
+ const version = getVueVersion();
283
+ _isVue2 = version === 2 || version === 2.7;
284
+ }
285
+ return _isVue2;
286
+ }
287
+ function isVue27() {
288
+ if (_isVue27 === null) {
289
+ _isVue27 = getVueVersion() === 2.7;
290
+ }
291
+ return _isVue27;
292
+ }
293
+ function isVue3() {
294
+ if (_isVue3 === null) {
295
+ _isVue3 = getVueVersion() === 3;
296
+ }
297
+ return _isVue3;
298
+ }
299
+ const isBrowser = () => {
300
+ return typeof window !== "undefined" && typeof document !== "undefined";
301
+ };
302
+ const isSSR = () => !isBrowser();
303
+ const supportsPassive = () => {
304
+ if (!isBrowser()) return false;
305
+ let supports = false;
306
+ try {
307
+ const options = {
308
+ get passive() {
309
+ supports = true;
310
+ return false;
311
+ }
312
+ };
313
+ window.addEventListener("test", null, options);
314
+ window.removeEventListener("test", null, options);
315
+ } catch (e) {
316
+ supports = false;
317
+ }
318
+ return supports;
319
+ };
320
+ const supportsIntersectionObserver = () => {
321
+ return isBrowser() && "IntersectionObserver" in window;
322
+ };
323
+ const supportsResizeObserver = () => {
324
+ return isBrowser() && "ResizeObserver" in window;
325
+ };
326
+ const supportsClipboard = () => {
327
+ return isBrowser() && "clipboard" in navigator;
328
+ };
329
+ const supportsMutationObserver = () => {
330
+ return isBrowser() && "MutationObserver" in window;
331
+ };
250
332
  function defineDirective(definition) {
251
333
  var _b;
252
334
  const _a = definition, { name, version, ssr, defaults } = _a, hooks = __objRest(_a, ["name", "version", "ssr", "defaults"]);
@@ -260,19 +342,45 @@ function defineDirective(definition) {
260
342
  }
261
343
  const wrappedHooks = {
262
344
  mounted: hooks.mounted ? (el, binding, vnode) => {
263
- const mergedBinding = applyDefaults(binding, defaults);
264
- hooks.mounted(el, mergedBinding, vnode);
345
+ hooks.mounted(el, applyDefaults(binding, defaults), vnode);
265
346
  } : void 0,
266
347
  updated: hooks.updated ? (el, binding, vnode, prevBinding, prevVnode) => {
267
- const mergedBinding = applyDefaults(binding, defaults);
268
- hooks.updated(el, mergedBinding, vnode, prevBinding, prevVnode);
348
+ hooks.updated(el, applyDefaults(binding, defaults), vnode, prevBinding, prevVnode);
269
349
  } : void 0,
270
350
  unmounted: hooks.unmounted
271
351
  };
272
- if (isVue2()) {
273
- return createVue2Directive(wrappedHooks);
352
+ return createLazyDirective(wrappedHooks);
353
+ }
354
+ function createLazyDirective(hooks) {
355
+ let cachedDirective = null;
356
+ function getDirective() {
357
+ if (!cachedDirective) {
358
+ cachedDirective = getVueVersion() === 2 ? createVue2Directive(hooks) : createVue3Directive(hooks);
359
+ }
360
+ return cachedDirective;
361
+ }
362
+ function createHook(hookName) {
363
+ return function(el, binding, vnode, prevVnode) {
364
+ var _a, _b;
365
+ (_b = (_a = getDirective())[hookName]) == null ? void 0 : _b.call(_a, el, binding, vnode, prevVnode);
366
+ };
274
367
  }
275
- return createVue3Directive(wrappedHooks);
368
+ return {
369
+ // Vue 2 hooks
370
+ bind: createHook("bind"),
371
+ inserted: createHook("inserted"),
372
+ update: createHook("update"),
373
+ componentUpdated: createHook("componentUpdated"),
374
+ unbind: createHook("unbind"),
375
+ // Vue 3 hooks
376
+ created: createHook("created"),
377
+ beforeMount: createHook("beforeMount"),
378
+ mounted: createHook("mounted"),
379
+ beforeUpdate: createHook("beforeUpdate"),
380
+ updated: createHook("updated"),
381
+ beforeUnmount: createHook("beforeUnmount"),
382
+ unmounted: createHook("unmounted")
383
+ };
276
384
  }
277
385
  function applyDefaults(binding, defaults) {
278
386
  if (!defaults) return binding;
@@ -301,6 +409,120 @@ function defineDirectiveGroup(name, directives) {
301
409
  }
302
410
  };
303
411
  }
412
+ function setupTextTransformInput(el, options, transformFn) {
413
+ if (!options.onInput) {
414
+ return () => {
415
+ };
416
+ }
417
+ const handler = () => {
418
+ const start = el.selectionStart;
419
+ const end = el.selectionEnd;
420
+ const originalValue = el.value;
421
+ const transformed = transformFn(originalValue);
422
+ if (originalValue !== transformed) {
423
+ el.value = transformed;
424
+ if (start !== null && end !== null) {
425
+ el.setSelectionRange(start, end);
426
+ }
427
+ el.dispatchEvent(new Event("input", { bubbles: true }));
428
+ }
429
+ };
430
+ el.addEventListener("input", handler);
431
+ el.value = transformFn(el.value);
432
+ return () => {
433
+ el.removeEventListener("input", handler);
434
+ };
435
+ }
436
+ function transformTextContent(el, transformFn) {
437
+ const text = el.textContent || "";
438
+ el.textContent = transformFn(text);
439
+ }
440
+ function isInputElement(el) {
441
+ return el.tagName === "INPUT" || el.tagName === "TEXTAREA";
442
+ }
443
+ const DEFAULT_KEEP_LOWER = [
444
+ "a",
445
+ "an",
446
+ "the",
447
+ "and",
448
+ "but",
449
+ "or",
450
+ "for",
451
+ "nor",
452
+ "on",
453
+ "at",
454
+ "to",
455
+ "from",
456
+ "by",
457
+ "in",
458
+ "of",
459
+ "with",
460
+ "as"
461
+ ];
462
+ function capitalizeText(text, options) {
463
+ if (!text) return text;
464
+ const { every = true, keepLower = DEFAULT_KEEP_LOWER } = options;
465
+ if (every) {
466
+ const words = text.toLowerCase().split(/\s+/);
467
+ return words.map((word, index) => {
468
+ if (index === 0) {
469
+ return capitalizeWord(word);
470
+ }
471
+ if (keepLower.includes(word.toLowerCase())) {
472
+ return word.toLowerCase();
473
+ }
474
+ return capitalizeWord(word);
475
+ }).join(" ");
476
+ } else {
477
+ return capitalizeWord(text);
478
+ }
479
+ }
480
+ function capitalizeWord(word) {
481
+ if (!word) return word;
482
+ return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
483
+ }
484
+ function normalizeOptions$t(binding) {
485
+ var _a, _b, _c;
486
+ if (binding === void 0 || binding === true) {
487
+ return { every: true, onInput: true };
488
+ }
489
+ if (binding === false) {
490
+ return { every: false, onInput: false };
491
+ }
492
+ return {
493
+ every: (_a = binding.every) != null ? _a : true,
494
+ keepLower: (_b = binding.keepLower) != null ? _b : DEFAULT_KEEP_LOWER,
495
+ onInput: (_c = binding.onInput) != null ? _c : true
496
+ };
497
+ }
498
+ const vCapitalcase = defineDirective({
499
+ name: "capitalcase",
500
+ ssr: true,
501
+ mounted(el, binding) {
502
+ const options = normalizeOptions$t(binding.value);
503
+ if (isInputElement(el)) {
504
+ const cleanup2 = setupTextTransformInput(el, options, (text) => capitalizeText(text, options));
505
+ el.__capitalcaseCleanup = cleanup2;
506
+ } else {
507
+ transformTextContent(el, (text) => capitalizeText(text, options));
508
+ }
509
+ },
510
+ updated(el, binding) {
511
+ const options = normalizeOptions$t(binding.value);
512
+ if (isInputElement(el)) {
513
+ if (options.onInput) {
514
+ el.value = capitalizeText(el.value, options);
515
+ }
516
+ } else {
517
+ transformTextContent(el, (text) => capitalizeText(text, options));
518
+ }
519
+ },
520
+ unmounted(el) {
521
+ const cleanup2 = el.__capitalcaseCleanup;
522
+ cleanup2 == null ? void 0 : cleanup2();
523
+ delete el.__capitalcaseCleanup;
524
+ }
525
+ });
304
526
  function isElement(value) {
305
527
  return value instanceof Element;
306
528
  }
@@ -312,17 +534,29 @@ function getElement(target) {
312
534
  }
313
535
  return isElement(target) ? target : null;
314
536
  }
537
+ function getScrollParent(el) {
538
+ if (!isBrowser()) return window;
539
+ let parent = el.parentElement;
540
+ while (parent) {
541
+ const { overflow, overflowX, overflowY } = getComputedStyle(parent);
542
+ if (/(auto|scroll)/.test(overflow + overflowX + overflowY)) {
543
+ return parent;
544
+ }
545
+ parent = parent.parentElement;
546
+ }
547
+ return window;
548
+ }
315
549
  function on(target, event, handler, options = false) {
316
550
  if (!isBrowser()) return;
317
- const opts = normalizeOptions$5(options);
551
+ const opts = normalizeOptions$s(options);
318
552
  target.addEventListener(event, handler, opts);
319
553
  }
320
554
  function off(target, event, handler, options = false) {
321
555
  if (!isBrowser()) return;
322
- const opts = normalizeOptions$5(options);
556
+ const opts = normalizeOptions$s(options);
323
557
  target.removeEventListener(event, handler, opts);
324
558
  }
325
- function normalizeOptions$5(options) {
559
+ function normalizeOptions$s(options) {
326
560
  if (typeof options === "boolean") {
327
561
  return options;
328
562
  }
@@ -332,11 +566,27 @@ function normalizeOptions$5(options) {
332
566
  }
333
567
  return capture;
334
568
  }
569
+ function getEventPosition(e) {
570
+ let clientX = 0, clientY = 0;
571
+ if ("touches" in e && e.touches.length > 0) {
572
+ clientX = e.touches[0].clientX;
573
+ clientY = e.touches[0].clientY;
574
+ } else if ("clientX" in e) {
575
+ clientX = e.clientX;
576
+ clientY = e.clientY;
577
+ }
578
+ return {
579
+ x: clientX,
580
+ y: clientY,
581
+ clientX,
582
+ clientY
583
+ };
584
+ }
335
585
  function isString(value) {
336
586
  return typeof value === "string";
337
587
  }
338
588
  function isNumber(value) {
339
- return typeof value === "number" && !Number.isNaN(value);
589
+ return typeof value === "number" && !isNaN(value);
340
590
  }
341
591
  function isBoolean(value) {
342
592
  return typeof value === "boolean";
@@ -507,13 +757,13 @@ function throttle(func, wait = 300, options = {}) {
507
757
  function parseTime(arg) {
508
758
  if (!arg) return null;
509
759
  if (arg.endsWith("ms")) {
510
- return Number.parseInt(arg, 10);
760
+ return parseInt(arg, 10);
511
761
  }
512
762
  if (arg.endsWith("s")) {
513
- return Number.parseFloat(arg) * 1e3;
763
+ return parseFloat(arg) * 1e3;
514
764
  }
515
- const num = Number.parseInt(arg, 10);
516
- return Number.isNaN(num) ? null : num;
765
+ const num = parseInt(arg, 10);
766
+ return isNaN(num) ? null : num;
517
767
  }
518
768
  function generateId(prefix = "") {
519
769
  return `${prefix}${Date.now().toString(36)}${Math.random().toString(36).slice(2, 9)}`;
@@ -529,7 +779,7 @@ const vClickOutside = defineDirective({
529
779
  prevent: false
530
780
  },
531
781
  mounted(el, binding) {
532
- const options = normalizeOptions$4(binding.value);
782
+ const options = normalizeOptions$r(binding.value);
533
783
  if (options.disabled) return;
534
784
  const state = {
535
785
  options,
@@ -564,7 +814,7 @@ const vClickOutside = defineDirective({
564
814
  const state = el.__clickOutside;
565
815
  if (!state) return;
566
816
  const oldOptions = state.options;
567
- const newOptions = normalizeOptions$4(binding.value);
817
+ const newOptions = normalizeOptions$r(binding.value);
568
818
  if (oldOptions.disabled !== newOptions.disabled) {
569
819
  if (newOptions.disabled) {
570
820
  state.handlers.forEach((handler, eventType) => {
@@ -601,7 +851,7 @@ const vClickOutside = defineDirective({
601
851
  delete el.__clickOutside;
602
852
  }
603
853
  });
604
- function normalizeOptions$4(binding) {
854
+ function normalizeOptions$r(binding) {
605
855
  var _a, _b, _c, _d, _e;
606
856
  if (typeof binding === "function") {
607
857
  return {
@@ -678,7 +928,7 @@ const vCopy = defineDirective({
678
928
  name: "copy",
679
929
  ssr: false,
680
930
  mounted(el, binding) {
681
- const options = normalizeOptions$3(binding.value);
931
+ const options = normalizeOptions$q(binding.value);
682
932
  if (options.disabled) return;
683
933
  if (options.title) {
684
934
  el.setAttribute("title", options.title);
@@ -714,7 +964,7 @@ const vCopy = defineDirective({
714
964
  updated(el, binding) {
715
965
  const state = el.__copy;
716
966
  if (!state) return;
717
- state.options = normalizeOptions$3(binding.value);
967
+ state.options = normalizeOptions$q(binding.value);
718
968
  if (state.options.title) {
719
969
  el.setAttribute("title", state.options.title);
720
970
  }
@@ -726,23 +976,66 @@ const vCopy = defineDirective({
726
976
  delete el.__copy;
727
977
  }
728
978
  });
729
- function normalizeOptions$3(binding) {
979
+ function normalizeOptions$q(binding) {
730
980
  if (typeof binding === "string") {
731
981
  return { value: binding };
732
982
  }
733
983
  return binding;
734
984
  }
985
+ const EVENT_MODIFIERS = [
986
+ "click",
987
+ "input",
988
+ "change",
989
+ "submit",
990
+ "scroll",
991
+ "resize",
992
+ "mouseenter",
993
+ "mouseleave",
994
+ "mousemove",
995
+ "mousedown",
996
+ "mouseup",
997
+ "keydown",
998
+ "keyup",
999
+ "focus",
1000
+ "blur",
1001
+ "touchstart",
1002
+ "touchmove",
1003
+ "touchend"
1004
+ ];
1005
+ function getEventTypeFromModifiers(modifiers) {
1006
+ for (const modifier of EVENT_MODIFIERS) {
1007
+ if (modifiers[modifier]) {
1008
+ return modifier;
1009
+ }
1010
+ }
1011
+ return null;
1012
+ }
1013
+ function getDefaultEventType(el) {
1014
+ const tagName = el.tagName.toLowerCase();
1015
+ if (tagName === "input" || tagName === "textarea") {
1016
+ return "input";
1017
+ }
1018
+ return "click";
1019
+ }
1020
+ function normalizeOptions$p(binding, directiveBinding) {
1021
+ const wait = parseTime(directiveBinding.arg) || 300;
1022
+ if (typeof binding === "function") {
1023
+ return { handler: binding, wait };
1024
+ }
1025
+ return __spreadProps(__spreadValues({}, binding), { wait: binding.wait || wait });
1026
+ }
735
1027
  const vDebounce = defineDirective({
736
1028
  name: "debounce",
737
- ssr: false,
1029
+ ssr: true,
1030
+ // SSR safe - event binding is skipped on server
738
1031
  defaults: {
739
1032
  wait: 300,
740
1033
  leading: false,
741
1034
  trailing: true
742
1035
  },
743
1036
  mounted(el, binding) {
744
- const options = normalizeOptions$2(binding.value, binding);
745
- const eventType = getEventTypeFromModifiers$1(binding.modifiers) || getEventType$1(el);
1037
+ const options = normalizeOptions$p(binding.value, binding);
1038
+ const eventType = getEventTypeFromModifiers(binding.modifiers) || getDefaultEventType(el);
746
1039
  const debouncedFn = debounce(options.handler, options.wait, {
747
1040
  leading: options.leading,
748
1041
  trailing: options.trailing
@@ -757,7 +1050,7 @@ const vDebounce = defineDirective({
757
1050
  updated(el, binding) {
758
1051
  const state = el.__debounce;
759
1052
  if (!state) return;
760
- const newOptions = normalizeOptions$2(binding.value, binding);
1053
+ const newOptions = normalizeOptions$p(binding.value, binding);
761
1054
  if (newOptions.wait !== state.options.wait || newOptions.leading !== state.options.leading || newOptions.trailing !== state.options.trailing) {
762
1055
  state.debouncedFn.cancel();
763
1056
  const debouncedFn = debounce(newOptions.handler, newOptions.wait, {
@@ -783,141 +1076,183 @@ const vDebounce = defineDirective({
783
1076
  delete el.__debounce;
784
1077
  }
785
1078
  });
786
- function normalizeOptions$2(binding, directiveBinding) {
787
- const wait = parseTime(directiveBinding.arg) || 300;
788
- if (typeof binding === "function") {
789
- return { handler: binding, wait };
1079
+ function getBoundary(_el, boundary) {
1080
+ var _a, _b;
1081
+ if (!boundary) return null;
1082
+ if (typeof boundary === "function") {
1083
+ const boundaryEl = boundary();
1084
+ return (_a = boundaryEl == null ? void 0 : boundaryEl.getBoundingClientRect()) != null ? _a : null;
790
1085
  }
791
- return __spreadProps(__spreadValues({}, binding), { wait: binding.wait || wait });
1086
+ if (typeof boundary === "string") {
1087
+ const boundaryEl = document.querySelector(boundary);
1088
+ return (_b = boundaryEl == null ? void 0 : boundaryEl.getBoundingClientRect()) != null ? _b : null;
1089
+ }
1090
+ return boundary.getBoundingClientRect();
792
1091
  }
793
- function getEventType$1(el) {
794
- const tagName = el.tagName.toLowerCase();
795
- if (tagName === "input" || tagName === "textarea") {
796
- return "input";
1092
+ function getClientCoords(e) {
1093
+ if (e.type.startsWith("touch")) {
1094
+ const touch = e.touches[0];
1095
+ return { clientX: touch.clientX, clientY: touch.clientY };
797
1096
  }
798
- return "click";
1097
+ const mouseEvent = e;
1098
+ return { clientX: mouseEvent.clientX, clientY: mouseEvent.clientY };
799
1099
  }
800
- const EVENT_MODIFIERS$1 = [
801
- "click",
802
- "input",
803
- "change",
804
- "submit",
805
- "scroll",
806
- "resize",
807
- "mouseenter",
808
- "mouseleave",
809
- "mousemove",
810
- "mousedown",
811
- "mouseup",
812
- "keydown",
813
- "keyup",
814
- "focus",
815
- "blur",
816
- "touchstart",
817
- "touchmove",
818
- "touchend"
819
- ];
820
- function getEventTypeFromModifiers$1(modifiers) {
821
- for (const modifier of EVENT_MODIFIERS$1) {
822
- if (modifiers[modifier]) {
823
- return modifier;
824
- }
1100
+ function parseTranslate(transform) {
1101
+ const match = transform.match(/translate\(([-\d.]+)px,\s*([-\d.]+)px\)/);
1102
+ if (match) {
1103
+ return { x: parseFloat(match[1]), y: parseFloat(match[2]) };
825
1104
  }
826
- return null;
1105
+ return { x: 0, y: 0 };
827
1106
  }
828
- const vThrottle = defineDirective({
829
- name: "throttle",
830
- ssr: false,
831
- defaults: {
832
- wait: 300,
833
- leading: true,
834
- trailing: true
835
- },
1107
+ function normalizeOptions$o(binding) {
1108
+ var _a, _b, _c;
1109
+ if (binding === void 0 || binding === true) {
1110
+ return { axis: "both", constrain: false, disabled: false };
1111
+ }
1112
+ if (binding === false) {
1113
+ return { axis: "both", constrain: false, disabled: true };
1114
+ }
1115
+ return {
1116
+ axis: (_a = binding.axis) != null ? _a : "both",
1117
+ constrain: (_b = binding.constrain) != null ? _b : false,
1118
+ boundary: binding.boundary,
1119
+ handle: binding.handle,
1120
+ disabled: (_c = binding.disabled) != null ? _c : false,
1121
+ grid: binding.grid,
1122
+ onStart: binding.onStart,
1123
+ onDrag: binding.onDrag,
1124
+ onEnd: binding.onEnd
1125
+ };
1126
+ }
1127
+ const vDraggable = defineDirective({
1128
+ name: "draggable",
1129
+ ssr: false,
836
1130
  mounted(el, binding) {
837
- const options = normalizeOptions$1(binding.value, binding);
838
- const eventType = getEventTypeFromModifiers(binding.modifiers) || getEventType(el);
839
- const throttledFn = throttle(options.handler, options.wait, {
840
- leading: options.leading,
841
- trailing: options.trailing
842
- });
843
- el.addEventListener(eventType, throttledFn);
844
- el.__throttle = {
845
- throttledFn,
846
- eventType,
847
- options
1131
+ const options = normalizeOptions$o(binding.value);
1132
+ if (options.disabled) return;
1133
+ if (getComputedStyle(el).position === "static") {
1134
+ el.style.position = "absolute";
1135
+ }
1136
+ const state = {
1137
+ options,
1138
+ isDragging: false,
1139
+ startX: 0,
1140
+ startY: 0,
1141
+ offsetX: 0,
1142
+ offsetY: 0,
1143
+ initialLeft: 0,
1144
+ initialTop: 0,
1145
+ boundaryWidth: 0,
1146
+ boundaryHeight: 0,
1147
+ elWidth: 0,
1148
+ elHeight: 0,
1149
+ handleEl: options.handle ? el.querySelector(options.handle) : null,
1150
+ moveHandler: null,
1151
+ endHandler: null
848
1152
  };
1153
+ el.__draggable = state;
1154
+ const targetEl = state.handleEl || el;
1155
+ targetEl.addEventListener("mousedown", startDrag);
1156
+ targetEl.addEventListener("touchstart", startDrag, { passive: false });
1157
+ function startDrag(e) {
1158
+ var _a, _b, _c;
1159
+ if (state.options.disabled) return;
1160
+ if (e.type === "touchstart") {
1161
+ e.preventDefault();
1162
+ }
1163
+ const { clientX, clientY } = getClientCoords(e);
1164
+ state.isDragging = true;
1165
+ state.startX = clientX;
1166
+ state.startY = clientY;
1167
+ const { x, y } = parseTranslate(el.style.transform);
1168
+ state.offsetX = x;
1169
+ state.offsetY = y;
1170
+ if (state.options.constrain || state.options.boundary) {
1171
+ const boundary = state.options.boundary ? getBoundary(el, state.options.boundary) : (_a = el.parentElement) == null ? void 0 : _a.getBoundingClientRect();
1172
+ if (boundary) {
1173
+ const elRect = el.getBoundingClientRect();
1174
+ state.initialLeft = elRect.left - boundary.left;
1175
+ state.initialTop = elRect.top - boundary.top;
1176
+ state.boundaryWidth = boundary.width;
1177
+ state.boundaryHeight = boundary.height;
1178
+ state.elWidth = elRect.width;
1179
+ state.elHeight = elRect.height;
1180
+ }
1181
+ }
1182
+ el.classList.add("v-draggable--dragging");
1183
+ state.moveHandler = (moveEvent) => {
1184
+ var _a2, _b2;
1185
+ if (!state.isDragging) return;
1186
+ const { clientX: moveX, clientY: moveY } = getClientCoords(moveEvent);
1187
+ let deltaX = moveX - state.startX, deltaY = moveY - state.startY;
1188
+ if (state.options.axis === "x") {
1189
+ deltaY = 0;
1190
+ } else if (state.options.axis === "y") {
1191
+ deltaX = 0;
1192
+ }
1193
+ if (state.options.grid) {
1194
+ deltaX = Math.round(deltaX / state.options.grid[0]) * state.options.grid[0];
1195
+ deltaY = Math.round(deltaY / state.options.grid[1]) * state.options.grid[1];
1196
+ }
1197
+ let newX = state.offsetX + deltaX, newY = state.offsetY + deltaY;
1198
+ if (state.options.constrain || state.options.boundary) {
1199
+ const newLeft = state.initialLeft + deltaX;
1200
+ const newTop = state.initialTop + deltaY;
1201
+ const maxLeft = state.boundaryWidth - state.elWidth;
1202
+ const maxTop = state.boundaryHeight - state.elHeight;
1203
+ const constrainedLeft = Math.max(0, Math.min(newLeft, maxLeft));
1204
+ const constrainedTop = Math.max(0, Math.min(newTop, maxTop));
1205
+ newX = state.offsetX + (constrainedLeft - state.initialLeft);
1206
+ newY = state.offsetY + (constrainedTop - state.initialTop);
1207
+ }
1208
+ el.style.transform = `translate(${newX}px, ${newY}px)`;
1209
+ (_b2 = (_a2 = state.options).onDrag) == null ? void 0 : _b2.call(_a2, { x: newX, y: newY }, moveEvent);
1210
+ };
1211
+ state.endHandler = () => {
1212
+ var _a2, _b2;
1213
+ if (!state.isDragging) return;
1214
+ state.isDragging = false;
1215
+ el.classList.remove("v-draggable--dragging");
1216
+ if (state.moveHandler) {
1217
+ document.removeEventListener("mousemove", state.moveHandler);
1218
+ document.removeEventListener("touchmove", state.moveHandler);
1219
+ }
1220
+ if (state.endHandler) {
1221
+ document.removeEventListener("mouseup", state.endHandler);
1222
+ document.removeEventListener("touchend", state.endHandler);
1223
+ }
1224
+ const { x: finalX, y: finalY } = parseTranslate(el.style.transform);
1225
+ (_b2 = (_a2 = state.options).onEnd) == null ? void 0 : _b2.call(_a2, { x: finalX, y: finalY }, new MouseEvent("mouseup"));
1226
+ };
1227
+ document.addEventListener("mousemove", state.moveHandler);
1228
+ document.addEventListener("touchmove", state.moveHandler, { passive: false });
1229
+ document.addEventListener("mouseup", state.endHandler);
1230
+ document.addEventListener("touchend", state.endHandler);
1231
+ (_c = (_b = state.options).onStart) == null ? void 0 : _c.call(_b, { x: state.offsetX, y: state.offsetY }, e);
1232
+ }
849
1233
  },
850
1234
  updated(el, binding) {
851
- const state = el.__throttle;
1235
+ const state = el.__draggable;
852
1236
  if (!state) return;
853
- const newOptions = normalizeOptions$1(binding.value, binding);
854
- if (newOptions.wait !== state.options.wait || newOptions.leading !== state.options.leading || newOptions.trailing !== state.options.trailing) {
855
- state.throttledFn.cancel();
856
- const throttledFn = throttle(newOptions.handler, newOptions.wait, {
857
- leading: newOptions.leading,
858
- trailing: newOptions.trailing
859
- });
860
- el.removeEventListener(state.eventType, state.throttledFn);
861
- el.addEventListener(state.eventType, throttledFn);
862
- el.__throttle = {
863
- throttledFn,
864
- eventType: state.eventType,
865
- options: newOptions
866
- };
867
- } else if (newOptions.handler !== state.options.handler) {
868
- state.options.handler = newOptions.handler;
1237
+ state.options = normalizeOptions$o(binding.value);
1238
+ if (state.options.handle) {
1239
+ state.handleEl = el.querySelector(state.options.handle);
869
1240
  }
870
1241
  },
871
1242
  unmounted(el) {
872
- const state = el.__throttle;
1243
+ const state = el.__draggable;
873
1244
  if (!state) return;
874
- state.throttledFn.cancel();
875
- el.removeEventListener(state.eventType, state.throttledFn);
876
- delete el.__throttle;
877
- }
878
- });
879
- function normalizeOptions$1(binding, directiveBinding) {
880
- const wait = parseTime(directiveBinding.arg) || 300;
881
- if (typeof binding === "function") {
882
- return { handler: binding, wait };
883
- }
884
- return __spreadProps(__spreadValues({}, binding), { wait: binding.wait || wait });
885
- }
886
- function getEventType(el) {
887
- const tagName = el.tagName.toLowerCase();
888
- if (tagName === "input" || tagName === "textarea") {
889
- return "input";
890
- }
891
- return "click";
892
- }
893
- const EVENT_MODIFIERS = [
894
- "click",
895
- "input",
896
- "change",
897
- "submit",
898
- "scroll",
899
- "resize",
900
- "mouseenter",
901
- "mouseleave",
902
- "mousemove",
903
- "mousedown",
904
- "mouseup",
905
- "keydown",
906
- "keyup",
907
- "focus",
908
- "blur",
909
- "touchstart",
910
- "touchmove",
911
- "touchend"
912
- ];
913
- function getEventTypeFromModifiers(modifiers) {
914
- for (const modifier of EVENT_MODIFIERS) {
915
- if (modifiers[modifier]) {
916
- return modifier;
1245
+ if (state.moveHandler) {
1246
+ document.removeEventListener("mousemove", state.moveHandler);
1247
+ document.removeEventListener("touchmove", state.moveHandler);
917
1248
  }
1249
+ if (state.endHandler) {
1250
+ document.removeEventListener("mouseup", state.endHandler);
1251
+ document.removeEventListener("touchend", state.endHandler);
1252
+ }
1253
+ delete el.__draggable;
918
1254
  }
919
- return null;
920
- }
1255
+ });
921
1256
  const FOCUSABLE_TAGS = /* @__PURE__ */ new Set(["input", "textarea", "select", "button"]);
922
1257
  function isEqual(a, b) {
923
1258
  if (a === b) return true;
@@ -931,13 +1266,15 @@ function isEqual(a, b) {
931
1266
  }
932
1267
  const vFocus = defineDirective({
933
1268
  name: "focus",
934
- ssr: false,
1269
+ ssr: true,
1270
+ // SSR safe - will skip focus on server
935
1271
  defaults: {
936
1272
  focus: true,
937
1273
  refocus: false
938
1274
  },
939
1275
  mounted(el, binding) {
940
- const options = normalizeOptions(binding.value);
1276
+ if (!isBrowser()) return;
1277
+ const options = normalizeOptions$n(binding.value);
941
1278
  if (!options.focus || !isFocusable(el)) {
942
1279
  if (options.focus) {
943
1280
  console.warn("[Directix] v-focus: Element is not focusable");
@@ -965,7 +1302,7 @@ const vFocus = defineDirective({
965
1302
  updated(el, binding) {
966
1303
  const state = el.__focus;
967
1304
  if (!state) return;
968
- const newOptions = normalizeOptions(binding.value);
1305
+ const newOptions = normalizeOptions$n(binding.value);
969
1306
  if (newOptions.onFocus !== state.options.onFocus) {
970
1307
  el.removeEventListener("focus", state.handleFocus);
971
1308
  state.handleFocus = () => {
@@ -997,7 +1334,7 @@ const vFocus = defineDirective({
997
1334
  delete el.__focus;
998
1335
  }
999
1336
  });
1000
- function normalizeOptions(binding) {
1337
+ function normalizeOptions$n(binding) {
1001
1338
  if (typeof binding === "boolean") {
1002
1339
  return { focus: binding, refocus: false };
1003
1340
  }
@@ -1020,14 +1357,3483 @@ function isFocusable(el) {
1020
1357
  }
1021
1358
  return false;
1022
1359
  }
1023
- const allDirectives = {
1024
- "click-outside": vClickOutside,
1025
- copy: vCopy,
1026
- debounce: vDebounce,
1027
- throttle: vThrottle,
1028
- focus: vFocus
1360
+ function normalizeOptions$m(binding) {
1361
+ if (typeof binding === "function") {
1362
+ return { handler: binding, class: "v-hover" };
1363
+ }
1364
+ return __spreadValues({
1365
+ class: "v-hover",
1366
+ disabled: false,
1367
+ enterDelay: 0,
1368
+ leaveDelay: 0
1369
+ }, binding);
1370
+ }
1371
+ const vHover = defineDirective({
1372
+ name: "hover",
1373
+ ssr: false,
1374
+ defaults: {
1375
+ class: "v-hover",
1376
+ disabled: false,
1377
+ enterDelay: 0,
1378
+ leaveDelay: 0
1379
+ },
1380
+ mounted(el, binding) {
1381
+ const options = normalizeOptions$m(binding.value);
1382
+ if (options.disabled || !isBrowser()) return;
1383
+ const state = {
1384
+ options,
1385
+ isHovering: false,
1386
+ enterTimerId: null,
1387
+ leaveTimerId: null,
1388
+ enterHandler: () => {
1389
+ },
1390
+ leaveHandler: () => {
1391
+ }
1392
+ };
1393
+ state.enterHandler = (e) => {
1394
+ const event = e;
1395
+ if (state.leaveTimerId) {
1396
+ clearTimeout(state.leaveTimerId);
1397
+ state.leaveTimerId = null;
1398
+ }
1399
+ if (state.isHovering) return;
1400
+ if (options.enterDelay && options.enterDelay > 0) {
1401
+ state.enterTimerId = setTimeout(() => {
1402
+ state.isHovering = true;
1403
+ applyHoverState(el, state, event);
1404
+ }, options.enterDelay);
1405
+ } else {
1406
+ state.isHovering = true;
1407
+ applyHoverState(el, state, event);
1408
+ }
1409
+ };
1410
+ state.leaveHandler = (e) => {
1411
+ const event = e;
1412
+ if (state.enterTimerId) {
1413
+ clearTimeout(state.enterTimerId);
1414
+ state.enterTimerId = null;
1415
+ }
1416
+ if (!state.isHovering) return;
1417
+ if (options.leaveDelay && options.leaveDelay > 0) {
1418
+ state.leaveTimerId = setTimeout(() => {
1419
+ state.isHovering = false;
1420
+ applyLeaveState(el, state, event);
1421
+ }, options.leaveDelay);
1422
+ } else {
1423
+ state.isHovering = false;
1424
+ applyLeaveState(el, state, event);
1425
+ }
1426
+ };
1427
+ el.__hover = state;
1428
+ on(el, "mouseenter", state.enterHandler);
1429
+ on(el, "mouseleave", state.leaveHandler);
1430
+ },
1431
+ updated(el, binding) {
1432
+ const state = el.__hover;
1433
+ if (!state) return;
1434
+ const newOptions = normalizeOptions$m(binding.value);
1435
+ if (newOptions.disabled && !state.options.disabled) {
1436
+ el.classList.remove(state.options.class || "v-hover");
1437
+ } else if (!newOptions.disabled && state.options.disabled) ;
1438
+ state.options = newOptions;
1439
+ },
1440
+ unmounted(el) {
1441
+ const state = el.__hover;
1442
+ if (!state) return;
1443
+ if (state.enterTimerId) {
1444
+ clearTimeout(state.enterTimerId);
1445
+ }
1446
+ if (state.leaveTimerId) {
1447
+ clearTimeout(state.leaveTimerId);
1448
+ }
1449
+ off(el, "mouseenter", state.enterHandler);
1450
+ off(el, "mouseleave", state.leaveHandler);
1451
+ el.classList.remove(state.options.class || "v-hover");
1452
+ delete el.__hover;
1453
+ }
1454
+ });
1455
+ function applyHoverState(el, state, e) {
1456
+ var _a, _b;
1457
+ const { options } = state;
1458
+ if (options.class) {
1459
+ el.classList.add(options.class);
1460
+ }
1461
+ el.dispatchEvent(new CustomEvent("hover:enter", { detail: { event: e } }));
1462
+ (_a = options.onEnter) == null ? void 0 : _a.call(options, e);
1463
+ (_b = options.handler) == null ? void 0 : _b.call(options, true, e);
1464
+ }
1465
+ function applyLeaveState(el, state, e) {
1466
+ var _a, _b;
1467
+ const { options } = state;
1468
+ if (options.class) {
1469
+ el.classList.remove(options.class);
1470
+ }
1471
+ el.dispatchEvent(new CustomEvent("hover:leave", { detail: { event: e } }));
1472
+ (_a = options.onLeave) == null ? void 0 : _a.call(options, e);
1473
+ (_b = options.handler) == null ? void 0 : _b.call(options, false, e);
1474
+ }
1475
+ const DEFAULTS = {
1476
+ minScale: 0.5,
1477
+ maxScale: 5,
1478
+ doubleTapZoom: 2.5,
1479
+ tapTimeout: 300,
1480
+ animationDuration: 300,
1481
+ hintDuration: 3e3,
1482
+ zoomIndicatorDuration: 1500
1029
1483
  };
1030
- const install = (app, options = {}) => {
1484
+ let globalZIndex = 9999;
1485
+ function getDistance$2(x1, y1, x2, y2) {
1486
+ return Math.sqrt(__pow(x2 - x1, 2) + __pow(y2 - y1, 2));
1487
+ }
1488
+ function clamp(value, min, max) {
1489
+ return Math.max(min, Math.min(max, value));
1490
+ }
1491
+ function createOverlay(options) {
1492
+ var _a;
1493
+ const zIndex = (_a = options.zIndex) != null ? _a : ++globalZIndex;
1494
+ const overlay = document.createElement("div");
1495
+ overlay.className = "v-image-preview-overlay";
1496
+ if (options.class) overlay.classList.add(options.class);
1497
+ Object.assign(overlay.style, {
1498
+ position: "fixed",
1499
+ inset: "0",
1500
+ background: "rgba(0, 0, 0, 0.95)",
1501
+ display: "flex",
1502
+ alignItems: "center",
1503
+ justifyContent: "center",
1504
+ zIndex: String(zIndex),
1505
+ cursor: "zoom-out",
1506
+ opacity: "0",
1507
+ transition: "opacity 0.3s",
1508
+ touchAction: "none",
1509
+ overflow: "hidden"
1510
+ });
1511
+ const imageContainer = document.createElement("div");
1512
+ Object.assign(imageContainer.style, {
1513
+ position: "relative",
1514
+ transformOrigin: "center center",
1515
+ transition: "transform 0.1s ease-out",
1516
+ willChange: "transform"
1517
+ });
1518
+ const image = document.createElement("img");
1519
+ image.src = options.previewSrc || options.src || "";
1520
+ image.alt = options.alt || "";
1521
+ Object.assign(image.style, {
1522
+ maxWidth: "95vw",
1523
+ maxHeight: "90vh",
1524
+ objectFit: "contain",
1525
+ cursor: "grab",
1526
+ userSelect: "none",
1527
+ WebkitUserDrag: "none"
1528
+ });
1529
+ image.addEventListener("dragstart", (e) => e.preventDefault());
1530
+ imageContainer.appendChild(image);
1531
+ if (options.showCloseButton !== false) {
1532
+ const closeBtn = document.createElement("button");
1533
+ closeBtn.className = "v-image-preview-close";
1534
+ closeBtn.innerHTML = "×";
1535
+ closeBtn.setAttribute("aria-label", "Close preview");
1536
+ Object.assign(closeBtn.style, {
1537
+ position: "fixed",
1538
+ top: "16px",
1539
+ right: "16px",
1540
+ width: "44px",
1541
+ height: "44px",
1542
+ border: "none",
1543
+ background: "rgba(255, 255, 255, 0.15)",
1544
+ color: "white",
1545
+ fontSize: "28px",
1546
+ cursor: "pointer",
1547
+ borderRadius: "50%",
1548
+ transition: "background 0.2s, transform 0.2s",
1549
+ zIndex: String(zIndex + 1),
1550
+ display: "flex",
1551
+ alignItems: "center",
1552
+ justifyContent: "center",
1553
+ backdropFilter: "blur(10px)",
1554
+ WebkitBackdropFilter: "blur(10px)"
1555
+ });
1556
+ const setBtnStyle = (bg, scale) => {
1557
+ closeBtn.style.background = bg;
1558
+ closeBtn.style.transform = scale;
1559
+ };
1560
+ closeBtn.addEventListener("mouseenter", () => setBtnStyle("rgba(255, 255, 255, 0.25)", "scale(1.1)"));
1561
+ closeBtn.addEventListener("mouseleave", () => setBtnStyle("rgba(255, 255, 255, 0.15)", "scale(1)"));
1562
+ closeBtn.addEventListener("touchstart", () => setBtnStyle("rgba(255, 255, 255, 0.35)", "scale(1.15)"), { passive: true });
1563
+ closeBtn.addEventListener("touchend", () => setBtnStyle("rgba(255, 255, 255, 0.15)", "scale(1)"), { passive: true });
1564
+ overlay.appendChild(closeBtn);
1565
+ }
1566
+ if (options.showZoomIndicator !== false) {
1567
+ const zoomIndicator = document.createElement("div");
1568
+ zoomIndicator.className = "v-image-preview-zoom";
1569
+ zoomIndicator.textContent = "100%";
1570
+ Object.assign(zoomIndicator.style, {
1571
+ position: "fixed",
1572
+ bottom: "24px",
1573
+ left: "50%",
1574
+ transform: "translateX(-50%)",
1575
+ background: "rgba(0, 0, 0, 0.6)",
1576
+ color: "white",
1577
+ padding: "8px 16px",
1578
+ borderRadius: "20px",
1579
+ fontSize: "14px",
1580
+ fontWeight: "500",
1581
+ opacity: "0",
1582
+ transition: "opacity 0.3s",
1583
+ zIndex: String(zIndex + 1),
1584
+ backdropFilter: "blur(10px)",
1585
+ WebkitBackdropFilter: "blur(10px)"
1586
+ });
1587
+ overlay.appendChild(zoomIndicator);
1588
+ }
1589
+ const hint = document.createElement("div");
1590
+ hint.className = "v-image-preview-hint";
1591
+ hint.textContent = "Pinch to zoom • Double tap • Swipe up to close";
1592
+ Object.assign(hint.style, {
1593
+ position: "fixed",
1594
+ bottom: "60px",
1595
+ left: "50%",
1596
+ transform: "translateX(-50%)",
1597
+ color: "rgba(255, 255, 255, 0.6)",
1598
+ fontSize: "12px",
1599
+ opacity: "1",
1600
+ transition: "opacity 0.5s",
1601
+ zIndex: String(zIndex + 1),
1602
+ pointerEvents: "none"
1603
+ });
1604
+ overlay.appendChild(hint);
1605
+ setTimeout(() => hint.style.opacity = "0", DEFAULTS.hintDuration);
1606
+ overlay.appendChild(imageContainer);
1607
+ return { overlay, imageContainer, image };
1608
+ }
1609
+ function createTransformManager(state) {
1610
+ const updateTransform = (animate = false) => {
1611
+ var _a;
1612
+ if (!state.imageContainer) return;
1613
+ const { scale, translateX, translateY } = state.transform;
1614
+ state.imageContainer.style.transition = animate ? "transform 0.2s ease-out" : "none";
1615
+ state.imageContainer.style.transform = `translate(${translateX}px, ${translateY}px) scale(${scale})`;
1616
+ const zoomIndicator = (_a = state.overlay) == null ? void 0 : _a.querySelector(".v-image-preview-zoom");
1617
+ if (zoomIndicator) {
1618
+ zoomIndicator.textContent = `${Math.round(scale * 100)}%`;
1619
+ zoomIndicator.style.opacity = "1";
1620
+ clearTimeout(zoomIndicator._hideTimer);
1621
+ zoomIndicator._hideTimer = setTimeout(() => {
1622
+ zoomIndicator.style.opacity = "0";
1623
+ }, DEFAULTS.zoomIndicatorDuration);
1624
+ }
1625
+ };
1626
+ const resetTransform = () => {
1627
+ state.transform = { scale: 1, translateX: 0, translateY: 0 };
1628
+ updateTransform(true);
1629
+ };
1630
+ const constrainScale = (newScale) => {
1631
+ const { minScale = DEFAULTS.minScale, maxScale = DEFAULTS.maxScale } = state.options;
1632
+ return clamp(newScale, minScale, maxScale);
1633
+ };
1634
+ const constrainTranslate = (x, y) => {
1635
+ const { scale } = state.transform;
1636
+ if (!state.image || scale <= 1) return { x: 0, y: 0 };
1637
+ const rect = state.image.getBoundingClientRect();
1638
+ const maxX = rect.width * (scale - 1) / 2;
1639
+ const maxY = rect.height * (scale - 1) / 2;
1640
+ return {
1641
+ x: clamp(x, -maxX, maxX),
1642
+ y: clamp(y, -maxY, maxY)
1643
+ };
1644
+ };
1645
+ return { updateTransform, resetTransform, constrainScale, constrainTranslate };
1646
+ }
1647
+ function createGestureHandlers(state, transformManager, closePreview) {
1648
+ const { updateTransform, resetTransform, constrainScale, constrainTranslate } = transformManager;
1649
+ const handleTouchStart = (e) => {
1650
+ if (!state.imageContainer) return;
1651
+ const now = Date.now();
1652
+ const { gesture, transform, options } = state;
1653
+ if (e.touches.length === 1) {
1654
+ if (options.enableDoubleTap !== false && now - gesture.lastTapTime < DEFAULTS.tapTimeout) {
1655
+ e.preventDefault();
1656
+ transform.scale = transform.scale > 1 ? 1 : constrainScale(DEFAULTS.doubleTapZoom);
1657
+ gesture.lastTapTime = 0;
1658
+ updateTransform(true);
1659
+ return;
1660
+ }
1661
+ gesture.lastTapTime = now;
1662
+ gesture.isDragging = true;
1663
+ gesture.startX = e.touches[0].clientX - transform.translateX;
1664
+ gesture.startY = e.touches[0].clientY - transform.translateY;
1665
+ gesture.swipeStartY = e.touches[0].clientY;
1666
+ } else if (e.touches.length === 2 && options.enablePinchZoom !== false) {
1667
+ gesture.isDragging = false;
1668
+ gesture.startDistance = getDistance$2(
1669
+ e.touches[0].clientX,
1670
+ e.touches[0].clientY,
1671
+ e.touches[1].clientX,
1672
+ e.touches[1].clientY
1673
+ );
1674
+ gesture.startScale = transform.scale;
1675
+ }
1676
+ };
1677
+ const handleTouchMove = (e) => {
1678
+ if (!state.imageContainer) return;
1679
+ e.preventDefault();
1680
+ const { gesture, transform, options } = state;
1681
+ if (e.touches.length === 1 && gesture.isDragging) {
1682
+ const newX = e.touches[0].clientX - gesture.startX;
1683
+ const newY = e.touches[0].clientY - gesture.startY;
1684
+ const constrained = constrainTranslate(newX, newY);
1685
+ transform.translateX = constrained.x;
1686
+ transform.translateY = constrained.y;
1687
+ updateTransform(false);
1688
+ } else if (e.touches.length === 2 && options.enablePinchZoom !== false) {
1689
+ const currentDistance = getDistance$2(
1690
+ e.touches[0].clientX,
1691
+ e.touches[0].clientY,
1692
+ e.touches[1].clientX,
1693
+ e.touches[1].clientY
1694
+ );
1695
+ transform.scale = constrainScale(gesture.startScale * (currentDistance / gesture.startDistance));
1696
+ updateTransform(false);
1697
+ }
1698
+ };
1699
+ const handleTouchEnd = (e) => {
1700
+ const { gesture, transform, options } = state;
1701
+ gesture.isDragging = false;
1702
+ if (options.enableSwipeClose !== false && e.changedTouches.length === 1 && transform.scale <= 1) {
1703
+ const deltaY = e.changedTouches[0].clientY - gesture.swipeStartY;
1704
+ if (deltaY < -100) {
1705
+ closePreview();
1706
+ return;
1707
+ }
1708
+ }
1709
+ if (transform.scale < 1) {
1710
+ resetTransform();
1711
+ }
1712
+ };
1713
+ const handleMouseDown = (e) => {
1714
+ if (!state.imageContainer) return;
1715
+ state.gesture.isDragging = true;
1716
+ state.gesture.startX = e.clientX - state.transform.translateX;
1717
+ state.gesture.startY = e.clientY - state.transform.translateY;
1718
+ state.imageContainer.style.cursor = "grabbing";
1719
+ };
1720
+ const handleMouseMove = (e) => {
1721
+ if (!state.gesture.isDragging || !state.imageContainer) return;
1722
+ const newX = e.clientX - state.gesture.startX;
1723
+ const newY = e.clientY - state.gesture.startY;
1724
+ const constrained = constrainTranslate(newX, newY);
1725
+ state.transform.translateX = constrained.x;
1726
+ state.transform.translateY = constrained.y;
1727
+ updateTransform(false);
1728
+ };
1729
+ const handleMouseUp = () => {
1730
+ state.gesture.isDragging = false;
1731
+ if (state.imageContainer) {
1732
+ state.imageContainer.style.cursor = "grab";
1733
+ }
1734
+ };
1735
+ const handleWheel = (e) => {
1736
+ if (!state.imageContainer || state.options.enablePinchZoom === false) return;
1737
+ e.preventDefault();
1738
+ const delta = e.deltaY > 0 ? 0.9 : 1.1;
1739
+ state.transform.scale = constrainScale(state.transform.scale * delta);
1740
+ updateTransform(false);
1741
+ if (state.transform.scale < 0.8) {
1742
+ setTimeout(resetTransform, 100);
1743
+ }
1744
+ };
1745
+ return { handleTouchStart, handleTouchMove, handleTouchEnd, handleMouseDown, handleMouseMove, handleMouseUp, handleWheel };
1746
+ }
1747
+ function normalizeOptions$l(binding, el) {
1748
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
1749
+ const elSrc = el.tagName === "IMG" ? el.src : void 0;
1750
+ const elPreviewSrc = el.getAttribute("data-preview") || void 0;
1751
+ const elAlt = el.tagName === "IMG" ? el.alt : el.getAttribute("alt") || void 0;
1752
+ if (typeof binding === "string") {
1753
+ return {
1754
+ src: binding,
1755
+ previewSrc: elPreviewSrc,
1756
+ alt: elAlt,
1757
+ enablePinchZoom: true,
1758
+ enableDoubleTap: true,
1759
+ enableSwipeClose: true,
1760
+ showZoomIndicator: true,
1761
+ showCloseButton: true,
1762
+ closeOnClickOutside: true,
1763
+ closeOnEsc: true,
1764
+ minScale: DEFAULTS.minScale,
1765
+ maxScale: DEFAULTS.maxScale
1766
+ };
1767
+ }
1768
+ return {
1769
+ src: (binding == null ? void 0 : binding.src) || elSrc,
1770
+ previewSrc: (binding == null ? void 0 : binding.previewSrc) || elPreviewSrc,
1771
+ alt: (binding == null ? void 0 : binding.alt) || elAlt,
1772
+ disabled: (_a = binding == null ? void 0 : binding.disabled) != null ? _a : false,
1773
+ closeOnClickOutside: (_b = binding == null ? void 0 : binding.closeOnClickOutside) != null ? _b : true,
1774
+ closeOnEsc: (_c = binding == null ? void 0 : binding.closeOnEsc) != null ? _c : true,
1775
+ showCloseButton: (_d = binding == null ? void 0 : binding.showCloseButton) != null ? _d : true,
1776
+ zIndex: binding == null ? void 0 : binding.zIndex,
1777
+ class: binding == null ? void 0 : binding.class,
1778
+ enablePinchZoom: (_e = binding == null ? void 0 : binding.enablePinchZoom) != null ? _e : true,
1779
+ enableDoubleTap: (_f = binding == null ? void 0 : binding.enableDoubleTap) != null ? _f : true,
1780
+ enableSwipeClose: (_g = binding == null ? void 0 : binding.enableSwipeClose) != null ? _g : true,
1781
+ showZoomIndicator: (_h = binding == null ? void 0 : binding.showZoomIndicator) != null ? _h : true,
1782
+ minScale: (_i = binding == null ? void 0 : binding.minScale) != null ? _i : DEFAULTS.minScale,
1783
+ maxScale: (_j = binding == null ? void 0 : binding.maxScale) != null ? _j : DEFAULTS.maxScale,
1784
+ onOpen: binding == null ? void 0 : binding.onOpen,
1785
+ onClose: binding == null ? void 0 : binding.onClose
1786
+ };
1787
+ }
1788
+ const vImagePreview = defineDirective({
1789
+ name: "image-preview",
1790
+ ssr: false,
1791
+ mounted(el, binding) {
1792
+ const options = normalizeOptions$l(binding.value, el);
1793
+ const state = {
1794
+ options,
1795
+ overlay: null,
1796
+ imageContainer: null,
1797
+ image: null,
1798
+ isOpen: false,
1799
+ transform: { scale: 1, translateX: 0, translateY: 0 },
1800
+ gesture: {
1801
+ isDragging: false,
1802
+ startX: 0,
1803
+ startY: 0,
1804
+ startDistance: 0,
1805
+ startScale: 1,
1806
+ lastTapTime: 0,
1807
+ swipeStartY: 0
1808
+ },
1809
+ handlers: {
1810
+ click: () => {
1811
+ },
1812
+ esc: null,
1813
+ touchStart: null,
1814
+ touchMove: null,
1815
+ touchEnd: null,
1816
+ mouseDown: null,
1817
+ mouseMove: null,
1818
+ mouseUp: null,
1819
+ wheel: null
1820
+ }
1821
+ };
1822
+ el.__imagePreview = state;
1823
+ if (options.disabled) return;
1824
+ el.style.cursor = "zoom-in";
1825
+ const transformManager = createTransformManager(state);
1826
+ const closePreview = () => {
1827
+ if (!state.isOpen || !state.overlay) return;
1828
+ state.overlay.style.opacity = "0";
1829
+ setTimeout(() => {
1830
+ var _a, _b;
1831
+ if (!state.overlay) return;
1832
+ state.overlay.remove();
1833
+ state.overlay = null;
1834
+ state.imageContainer = null;
1835
+ state.image = null;
1836
+ state.isOpen = false;
1837
+ state.transform = { scale: 1, translateX: 0, translateY: 0 };
1838
+ document.body.style.overflow = "";
1839
+ const { handlers } = state;
1840
+ if (handlers.esc) document.removeEventListener("keydown", handlers.esc);
1841
+ if (handlers.touchStart) document.removeEventListener("touchstart", handlers.touchStart);
1842
+ if (handlers.touchMove) document.removeEventListener("touchmove", handlers.touchMove);
1843
+ if (handlers.touchEnd) document.removeEventListener("touchend", handlers.touchEnd);
1844
+ if (handlers.mouseDown) document.removeEventListener("mousedown", handlers.mouseDown);
1845
+ if (handlers.mouseMove) document.removeEventListener("mousemove", handlers.mouseMove);
1846
+ if (handlers.mouseUp) document.removeEventListener("mouseup", handlers.mouseUp);
1847
+ if (handlers.wheel) document.removeEventListener("wheel", handlers.wheel);
1848
+ (_b = (_a = state.options).onClose) == null ? void 0 : _b.call(_a);
1849
+ }, DEFAULTS.animationDuration);
1850
+ };
1851
+ const gestureHandlers = createGestureHandlers(state, transformManager, closePreview);
1852
+ const openPreview = () => {
1853
+ var _a, _b, _c;
1854
+ if (state.isOpen || state.options.disabled) return;
1855
+ const { overlay, imageContainer, image } = createOverlay(state.options);
1856
+ state.overlay = overlay;
1857
+ state.imageContainer = imageContainer;
1858
+ state.image = image;
1859
+ state.isOpen = true;
1860
+ document.body.appendChild(overlay);
1861
+ document.body.style.overflow = "hidden";
1862
+ requestAnimationFrame(() => overlay.style.opacity = "1");
1863
+ state.handlers.touchStart = gestureHandlers.handleTouchStart;
1864
+ state.handlers.touchMove = gestureHandlers.handleTouchMove;
1865
+ state.handlers.touchEnd = gestureHandlers.handleTouchEnd;
1866
+ state.handlers.mouseDown = gestureHandlers.handleMouseDown;
1867
+ state.handlers.mouseMove = gestureHandlers.handleMouseMove;
1868
+ state.handlers.mouseUp = gestureHandlers.handleMouseUp;
1869
+ state.handlers.wheel = gestureHandlers.handleWheel;
1870
+ overlay.addEventListener("touchstart", gestureHandlers.handleTouchStart, { passive: false });
1871
+ overlay.addEventListener("touchmove", gestureHandlers.handleTouchMove, { passive: false });
1872
+ overlay.addEventListener("touchend", gestureHandlers.handleTouchEnd, { passive: true });
1873
+ image.addEventListener("mousedown", gestureHandlers.handleMouseDown);
1874
+ document.addEventListener("mousemove", gestureHandlers.handleMouseMove);
1875
+ document.addEventListener("mouseup", gestureHandlers.handleMouseUp);
1876
+ overlay.addEventListener("wheel", gestureHandlers.handleWheel, { passive: false });
1877
+ (_a = overlay.querySelector(".v-image-preview-close")) == null ? void 0 : _a.addEventListener("click", (e) => {
1878
+ e.stopPropagation();
1879
+ closePreview();
1880
+ });
1881
+ if (state.options.closeOnClickOutside !== false) {
1882
+ overlay.addEventListener("click", () => {
1883
+ if (state.transform.scale <= 1) {
1884
+ closePreview();
1885
+ } else {
1886
+ transformManager.resetTransform();
1887
+ }
1888
+ });
1889
+ }
1890
+ if (state.options.closeOnEsc !== false) {
1891
+ state.handlers.esc = (e) => {
1892
+ if (e.key === "Escape") {
1893
+ state.transform.scale > 1 ? transformManager.resetTransform() : closePreview();
1894
+ }
1895
+ };
1896
+ document.addEventListener("keydown", state.handlers.esc);
1897
+ }
1898
+ (_c = (_b = state.options).onOpen) == null ? void 0 : _c.call(_b);
1899
+ };
1900
+ state.handlers.click = openPreview;
1901
+ el.addEventListener("click", openPreview);
1902
+ },
1903
+ updated(el, binding) {
1904
+ const state = el.__imagePreview;
1905
+ if (!state) return;
1906
+ state.options = normalizeOptions$l(binding.value, el);
1907
+ el.style.cursor = state.options.disabled ? "" : "zoom-in";
1908
+ },
1909
+ unmounted(el) {
1910
+ const state = el.__imagePreview;
1911
+ if (!state) return;
1912
+ el.removeEventListener("click", state.handlers.click);
1913
+ if (state.isOpen && state.overlay) {
1914
+ state.overlay.remove();
1915
+ document.body.style.overflow = "";
1916
+ }
1917
+ if (state.handlers.esc) document.removeEventListener("keydown", state.handlers.esc);
1918
+ if (state.handlers.touchStart) document.removeEventListener("touchstart", state.handlers.touchStart);
1919
+ if (state.handlers.touchMove) document.removeEventListener("touchmove", state.handlers.touchMove);
1920
+ if (state.handlers.touchEnd) document.removeEventListener("touchend", state.handlers.touchEnd);
1921
+ if (state.handlers.mouseDown) document.removeEventListener("mousedown", state.handlers.mouseDown);
1922
+ if (state.handlers.mouseMove) document.removeEventListener("mousemove", state.handlers.mouseMove);
1923
+ if (state.handlers.mouseUp) document.removeEventListener("mouseup", state.handlers.mouseUp);
1924
+ if (state.handlers.wheel) document.removeEventListener("wheel", state.handlers.wheel);
1925
+ delete el.__imagePreview;
1926
+ }
1927
+ });
1928
+ function normalizeOptions$k(binding) {
1929
+ if (typeof binding === "function") {
1930
+ return { handler: binding, distance: 0, throttle: 200, useIntersection: true };
1931
+ }
1932
+ if (!binding) {
1933
+ throw new Error("[Directix] v-infinite-scroll: handler is required");
1934
+ }
1935
+ return __spreadValues({
1936
+ distance: 0,
1937
+ disabled: false,
1938
+ loading: false,
1939
+ useIntersection: true,
1940
+ throttle: 200
1941
+ }, binding);
1942
+ }
1943
+ const vInfiniteScroll = defineDirective({
1944
+ name: "infinite-scroll",
1945
+ ssr: false,
1946
+ defaults: {
1947
+ distance: 0,
1948
+ disabled: false,
1949
+ loading: false,
1950
+ useIntersection: true,
1951
+ throttle: 200
1952
+ },
1953
+ mounted(el, binding) {
1954
+ const options = normalizeOptions$k(binding.value);
1955
+ if (options.disabled || !isBrowser()) return;
1956
+ let container;
1957
+ if (options.container) {
1958
+ if (typeof options.container === "string") {
1959
+ const found = document.querySelector(options.container);
1960
+ container = found || getScrollParent(el);
1961
+ } else {
1962
+ container = options.container;
1963
+ }
1964
+ } else {
1965
+ container = getScrollParent(el);
1966
+ }
1967
+ const state = {
1968
+ options,
1969
+ container,
1970
+ sentinel: null,
1971
+ observer: null,
1972
+ throttleTimer: null,
1973
+ isLoading: false,
1974
+ scrollHandler: (_e) => __async(null, null, function* () {
1975
+ if (state.isLoading || state.options.disabled || state.options.loading) {
1976
+ return;
1977
+ }
1978
+ if (state.throttleTimer) {
1979
+ return;
1980
+ }
1981
+ state.throttleTimer = setTimeout(() => {
1982
+ state.throttleTimer = null;
1983
+ }, options.throttle);
1984
+ const shouldLoad = checkShouldLoad(container, el, options.distance || 0);
1985
+ if (shouldLoad) {
1986
+ yield triggerLoad(state, el);
1987
+ }
1988
+ })
1989
+ };
1990
+ el.__infiniteScroll = state;
1991
+ if (options.useIntersection && supportsIntersectionObserver()) {
1992
+ setupIntersectionObserver(el, state);
1993
+ } else {
1994
+ on(container, "scroll", state.scrollHandler, { passive: true });
1995
+ }
1996
+ },
1997
+ updated(el, binding) {
1998
+ const state = el.__infiniteScroll;
1999
+ if (!state) return;
2000
+ state.options = normalizeOptions$k(binding.value);
2001
+ },
2002
+ unmounted(el) {
2003
+ const state = el.__infiniteScroll;
2004
+ if (!state) return;
2005
+ if (state.throttleTimer) {
2006
+ clearTimeout(state.throttleTimer);
2007
+ }
2008
+ if (state.observer) {
2009
+ state.observer.disconnect();
2010
+ }
2011
+ if (state.sentinel && state.sentinel.parentNode) {
2012
+ state.sentinel.parentNode.removeChild(state.sentinel);
2013
+ }
2014
+ off(state.container, "scroll", state.scrollHandler);
2015
+ delete el.__infiniteScroll;
2016
+ }
2017
+ });
2018
+ function checkShouldLoad(container, _el, distance) {
2019
+ if (container === window) {
2020
+ const scrollTop2 = window.scrollY || document.documentElement.scrollTop;
2021
+ const scrollHeight2 = document.documentElement.scrollHeight;
2022
+ const clientHeight2 = window.innerHeight;
2023
+ return scrollTop2 + clientHeight2 >= scrollHeight2 - distance;
2024
+ }
2025
+ const el = container;
2026
+ const scrollTop = el.scrollTop;
2027
+ const scrollHeight = el.scrollHeight;
2028
+ const clientHeight = el.clientHeight;
2029
+ return scrollTop + clientHeight >= scrollHeight - distance;
2030
+ }
2031
+ function triggerLoad(state, el) {
2032
+ return __async(this, null, function* () {
2033
+ var _a, _b, _c, _d, _e, _f;
2034
+ state.isLoading = true;
2035
+ (_b = (_a = state.options).onLoadStart) == null ? void 0 : _b.call(_a);
2036
+ el.classList.add("v-infinite-scroll--loading");
2037
+ try {
2038
+ yield state.options.handler();
2039
+ } catch (err) {
2040
+ (_d = (_c = state.options).onError) == null ? void 0 : _d.call(_c, err);
2041
+ } finally {
2042
+ state.isLoading = false;
2043
+ (_f = (_e = state.options).onLoadEnd) == null ? void 0 : _f.call(_e);
2044
+ el.classList.remove("v-infinite-scroll--loading");
2045
+ }
2046
+ });
2047
+ }
2048
+ function setupIntersectionObserver(el, state) {
2049
+ const sentinel = document.createElement("div");
2050
+ sentinel.className = "v-infinite-scroll__sentinel";
2051
+ sentinel.style.cssText = `
2052
+ height: 1px;
2053
+ width: 100%;
2054
+ clear: both;
2055
+ `;
2056
+ el.appendChild(sentinel);
2057
+ state.sentinel = sentinel;
2058
+ state.observer = new IntersectionObserver(
2059
+ (entries) => __async(null, null, function* () {
2060
+ for (const entry of entries) {
2061
+ if (entry.isIntersecting) {
2062
+ if (!state.isLoading && !state.options.disabled && !state.options.loading) {
2063
+ yield triggerLoad(state, el);
2064
+ }
2065
+ }
2066
+ }
2067
+ }),
2068
+ {
2069
+ root: state.container === window ? null : state.container,
2070
+ rootMargin: `${state.options.distance || 0}px`,
2071
+ threshold: 0
2072
+ }
2073
+ );
2074
+ state.observer.observe(sentinel);
2075
+ }
2076
+ const STATE_KEY$3 = "__intersect";
2077
+ function normalizeOptions$j(binding) {
2078
+ const options = typeof binding === "function" ? { handler: binding } : __spreadValues({}, binding);
2079
+ if (options.root !== null && typeof options.root === "object" && "value" in options.root) {
2080
+ options.root = options.root.value;
2081
+ }
2082
+ return options;
2083
+ }
2084
+ function createObserverCallback(el, state, options) {
2085
+ return (entries) => {
2086
+ var _a, _b, _c, _d;
2087
+ for (const entry of entries) {
2088
+ if (options.once && state.hasTriggeredOnce) continue;
2089
+ const { isIntersecting } = entry;
2090
+ (_a = options.handler) == null ? void 0 : _a.call(options, entry, state.observer);
2091
+ (_b = options.onChange) == null ? void 0 : _b.call(options, isIntersecting, entry);
2092
+ if (isIntersecting) {
2093
+ (_c = options.onEnter) == null ? void 0 : _c.call(options, entry, state.observer);
2094
+ if (options.once) state.hasTriggeredOnce = true;
2095
+ } else {
2096
+ (_d = options.onLeave) == null ? void 0 : _d.call(options, entry, state.observer);
2097
+ }
2098
+ el.dispatchEvent(new CustomEvent("intersect", { detail: { isIntersecting, entry } }));
2099
+ }
2100
+ };
2101
+ }
2102
+ function createObserver(el, state, options) {
2103
+ return new IntersectionObserver(createObserverCallback(el, state, options), {
2104
+ root: options.root,
2105
+ rootMargin: options.rootMargin,
2106
+ threshold: options.threshold
2107
+ });
2108
+ }
2109
+ const vIntersect = defineDirective({
2110
+ name: "intersect",
2111
+ ssr: false,
2112
+ defaults: {
2113
+ disabled: false,
2114
+ once: false,
2115
+ rootMargin: "0px",
2116
+ threshold: 0
2117
+ },
2118
+ mounted(el, binding) {
2119
+ const options = normalizeOptions$j(binding.value);
2120
+ if (options.disabled || !isBrowser() || !supportsIntersectionObserver()) {
2121
+ if (!supportsIntersectionObserver()) {
2122
+ console.warn("[Directix] v-intersect: IntersectionObserver not supported");
2123
+ }
2124
+ return;
2125
+ }
2126
+ const state = {
2127
+ options,
2128
+ observer: null,
2129
+ hasTriggeredOnce: false
2130
+ };
2131
+ state.observer = createObserver(el, state, options);
2132
+ el[STATE_KEY$3] = state;
2133
+ state.observer.observe(el);
2134
+ },
2135
+ updated(el, binding) {
2136
+ var _a, _b, _c;
2137
+ const state = el[STATE_KEY$3];
2138
+ if (!state) return;
2139
+ const newOptions = normalizeOptions$j(binding.value);
2140
+ const observerOptionsChanged = newOptions.root !== state.options.root || newOptions.rootMargin !== state.options.rootMargin || newOptions.threshold !== state.options.threshold;
2141
+ if (newOptions.disabled !== state.options.disabled) {
2142
+ if (newOptions.disabled) {
2143
+ (_a = state.observer) == null ? void 0 : _a.disconnect();
2144
+ } else {
2145
+ (_b = state.observer) == null ? void 0 : _b.observe(el);
2146
+ }
2147
+ }
2148
+ if (observerOptionsChanged) {
2149
+ (_c = state.observer) == null ? void 0 : _c.disconnect();
2150
+ state.observer = createObserver(el, state, newOptions);
2151
+ state.observer.observe(el);
2152
+ }
2153
+ state.options = newOptions;
2154
+ },
2155
+ unmounted(el) {
2156
+ var _a;
2157
+ const state = el[STATE_KEY$3];
2158
+ if (!state) return;
2159
+ (_a = state.observer) == null ? void 0 : _a.disconnect();
2160
+ delete el[STATE_KEY$3];
2161
+ }
2162
+ });
2163
+ let globalObserver = null;
2164
+ function getGlobalObserver(preload) {
2165
+ if (globalObserver) return globalObserver;
2166
+ globalObserver = new IntersectionObserver(
2167
+ (entries) => {
2168
+ entries.forEach((entry) => {
2169
+ if (entry.isIntersecting) {
2170
+ load(entry.target);
2171
+ globalObserver == null ? void 0 : globalObserver.unobserve(entry.target);
2172
+ }
2173
+ });
2174
+ },
2175
+ {
2176
+ rootMargin: `${preload}px`
2177
+ }
2178
+ );
2179
+ return globalObserver;
2180
+ }
2181
+ function setSrc(el, src) {
2182
+ if (el.tagName === "IMG") {
2183
+ el.src = src;
2184
+ } else {
2185
+ el.style.backgroundImage = `url("${src}")`;
2186
+ }
2187
+ }
2188
+ function setLazyState(el, state) {
2189
+ el.dataset.lazyState = state;
2190
+ }
2191
+ function getLazyState(el) {
2192
+ return el.dataset.lazyState || "pending";
2193
+ }
2194
+ function load(el) {
2195
+ const state = el.__lazy;
2196
+ if (!state || !state.options.src) return;
2197
+ if (state.options.filter && !state.options.filter(state.options.src)) {
2198
+ return;
2199
+ }
2200
+ setLazyState(el, "loading");
2201
+ state.attempt++;
2202
+ el.classList.add("v-lazy--loading");
2203
+ const img = new Image();
2204
+ img.onload = () => {
2205
+ var _a, _b;
2206
+ setSrc(el, state.options.src);
2207
+ setLazyState(el, "loaded");
2208
+ el.classList.remove("v-lazy--loading");
2209
+ el.classList.add("v-lazy--loaded");
2210
+ (_b = (_a = state.options).onLoad) == null ? void 0 : _b.call(_a, el);
2211
+ };
2212
+ img.onerror = () => {
2213
+ var _a, _b;
2214
+ el.classList.remove("v-lazy--loading");
2215
+ if (state.attempt < (state.options.attempt || 1)) {
2216
+ setTimeout(() => load(el), 1e3 * state.attempt);
2217
+ return;
2218
+ }
2219
+ if (state.options.error) {
2220
+ setSrc(el, state.options.error);
2221
+ }
2222
+ setLazyState(el, "error");
2223
+ el.classList.add("v-lazy--error");
2224
+ (_b = (_a = state.options).onError) == null ? void 0 : _b.call(_a, el, new Error("Failed to load image"));
2225
+ };
2226
+ img.src = state.options.src;
2227
+ }
2228
+ function observe(el) {
2229
+ const state = el.__lazy;
2230
+ if (!state) return;
2231
+ if (!supportsIntersectionObserver()) {
2232
+ load(el);
2233
+ return;
2234
+ }
2235
+ if (state.options.observer) {
2236
+ state.observer = state.options.observer;
2237
+ state.observer.observe(el);
2238
+ } else {
2239
+ const observer = getGlobalObserver(state.options.preload || 0);
2240
+ state.observer = observer;
2241
+ observer.observe(el);
2242
+ }
2243
+ }
2244
+ function unobserve(el) {
2245
+ const state = el.__lazy;
2246
+ if (!state) return;
2247
+ if (state.observer) {
2248
+ state.observer.unobserve(el);
2249
+ } else if (globalObserver) {
2250
+ globalObserver.unobserve(el);
2251
+ }
2252
+ }
2253
+ function normalizeOptions$i(binding) {
2254
+ if (typeof binding === "string") {
2255
+ return { src: binding };
2256
+ }
2257
+ return binding || {};
2258
+ }
2259
+ const vLazy = defineDirective({
2260
+ name: "lazy",
2261
+ ssr: false,
2262
+ defaults: {
2263
+ preload: 0,
2264
+ attempt: 1,
2265
+ disabled: false
2266
+ },
2267
+ mounted(el, binding) {
2268
+ const options = normalizeOptions$i(binding.value);
2269
+ if (options.disabled) return;
2270
+ if (!options.src) {
2271
+ console.warn("[Directix] v-lazy: No source provided");
2272
+ return;
2273
+ }
2274
+ setLazyState(el, "pending");
2275
+ if (options.placeholder) {
2276
+ setSrc(el, options.placeholder);
2277
+ }
2278
+ el.classList.add("v-lazy");
2279
+ const state = {
2280
+ options,
2281
+ attempt: 0
2282
+ };
2283
+ el.__lazy = state;
2284
+ observe(el);
2285
+ },
2286
+ updated(el, binding) {
2287
+ const state = el.__lazy;
2288
+ if (!state) return;
2289
+ const newOptions = normalizeOptions$i(binding.value);
2290
+ if (newOptions.disabled) {
2291
+ unobserve(el);
2292
+ return;
2293
+ }
2294
+ if (newOptions.src !== state.options.src) {
2295
+ state.options = newOptions;
2296
+ state.attempt = 0;
2297
+ if (getLazyState(el) !== "pending") {
2298
+ setLazyState(el, "pending");
2299
+ el.classList.remove("v-lazy--loaded", "v-lazy--error");
2300
+ if (newOptions.placeholder) {
2301
+ setSrc(el, newOptions.placeholder);
2302
+ }
2303
+ observe(el);
2304
+ }
2305
+ }
2306
+ },
2307
+ unmounted(el) {
2308
+ unobserve(el);
2309
+ delete el.__lazy;
2310
+ }
2311
+ });
2312
+ function normalizeOptions$h(binding) {
2313
+ if (typeof binding === "boolean") {
2314
+ return { value: binding };
2315
+ }
2316
+ return __spreadValues({
2317
+ value: true,
2318
+ loadingClass: "v-loading",
2319
+ spinnerClass: "v-loading__spinner",
2320
+ textClass: "v-loading__text",
2321
+ background: "rgba(255, 255, 255, 0.9)",
2322
+ lock: false,
2323
+ disabled: false
2324
+ }, binding);
2325
+ }
2326
+ const DEFAULT_SPINNER = `
2327
+ <svg class="v-loading__circular" viewBox="25 25 50 50">
2328
+ <circle class="v-loading__path" cx="50" cy="50" r="20" fill="none" stroke-width="2" stroke-miterlimit="10"/>
2329
+ </svg>
2330
+ `;
2331
+ function createLoadingOverlay(options) {
2332
+ const overlay = document.createElement("div");
2333
+ overlay.className = options.loadingClass || "v-loading";
2334
+ overlay.style.cssText = `
2335
+ position: absolute;
2336
+ top: 0;
2337
+ left: 0;
2338
+ right: 0;
2339
+ bottom: 0;
2340
+ z-index: 1000;
2341
+ background: ${options.background || "rgba(255, 255, 255, 0.9)"};
2342
+ display: flex;
2343
+ flex-direction: column;
2344
+ align-items: center;
2345
+ justify-content: center;
2346
+ `;
2347
+ const spinnerHtml = options.spinner || DEFAULT_SPINNER;
2348
+ const spinnerContainer = document.createElement("div");
2349
+ spinnerContainer.className = options.spinnerClass || "v-loading__spinner";
2350
+ spinnerContainer.innerHTML = spinnerHtml;
2351
+ overlay.appendChild(spinnerContainer);
2352
+ if (options.text) {
2353
+ const textEl = document.createElement("div");
2354
+ textEl.className = options.textClass || "v-loading__text";
2355
+ textEl.textContent = options.text;
2356
+ overlay.appendChild(textEl);
2357
+ }
2358
+ return overlay;
2359
+ }
2360
+ const vLoading = defineDirective({
2361
+ name: "loading",
2362
+ ssr: true,
2363
+ // SSR safe - will skip DOM manipulation on server
2364
+ defaults: {
2365
+ value: true,
2366
+ loadingClass: "v-loading",
2367
+ spinnerClass: "v-loading__spinner",
2368
+ textClass: "v-loading__text",
2369
+ background: "rgba(255, 255, 255, 0.9)",
2370
+ lock: false,
2371
+ disabled: false
2372
+ },
2373
+ mounted(el, binding) {
2374
+ if (!isBrowser()) return;
2375
+ const options = normalizeOptions$h(binding.value);
2376
+ if (options.disabled) return;
2377
+ const computedStyle = getComputedStyle(el);
2378
+ const originalPosition = el.style.position;
2379
+ const originalOverflow = el.style.overflow;
2380
+ const state = {
2381
+ options,
2382
+ loadingOverlay: null,
2383
+ originalPosition,
2384
+ originalOverflow
2385
+ };
2386
+ el.__loading = state;
2387
+ if (computedStyle.position === "static") {
2388
+ el.style.position = "relative";
2389
+ }
2390
+ if (options.value) {
2391
+ showLoading(el, state);
2392
+ }
2393
+ },
2394
+ updated(el, binding) {
2395
+ const state = el.__loading;
2396
+ if (!state) return;
2397
+ const newOptions = normalizeOptions$h(binding.value);
2398
+ if (newOptions.disabled) {
2399
+ hideLoading(el, state);
2400
+ return;
2401
+ }
2402
+ if (newOptions.value && !state.options.value) {
2403
+ showLoading(el, state);
2404
+ } else if (!newOptions.value && state.options.value) {
2405
+ hideLoading(el, state);
2406
+ }
2407
+ if (state.loadingOverlay && newOptions.text !== state.options.text) {
2408
+ const textEl = state.loadingOverlay.querySelector(`.${state.options.textClass}`);
2409
+ if (textEl) {
2410
+ textEl.textContent = newOptions.text || "";
2411
+ }
2412
+ }
2413
+ state.options = newOptions;
2414
+ },
2415
+ unmounted(el) {
2416
+ const state = el.__loading;
2417
+ if (!state) return;
2418
+ hideLoading(el, state);
2419
+ el.style.position = state.originalPosition;
2420
+ el.style.overflow = state.originalOverflow;
2421
+ delete el.__loading;
2422
+ }
2423
+ });
2424
+ function showLoading(el, state) {
2425
+ if (state.loadingOverlay) return;
2426
+ state.loadingOverlay = createLoadingOverlay(state.options);
2427
+ el.appendChild(state.loadingOverlay);
2428
+ if (state.options.lock) {
2429
+ el.style.overflow = "hidden";
2430
+ }
2431
+ el.classList.add("v-loading--active");
2432
+ }
2433
+ function hideLoading(el, state) {
2434
+ if (!state.loadingOverlay) return;
2435
+ state.loadingOverlay.remove();
2436
+ state.loadingOverlay = null;
2437
+ if (state.options.lock) {
2438
+ el.style.overflow = state.originalOverflow;
2439
+ }
2440
+ el.classList.remove("v-loading--active");
2441
+ }
2442
+ function normalizeOptions$g(binding) {
2443
+ if (typeof binding === "function") {
2444
+ return { handler: binding, duration: 500, distance: 10 };
2445
+ }
2446
+ if (!binding) {
2447
+ throw new Error("[Directix] v-long-press: handler is required");
2448
+ }
2449
+ return __spreadValues({
2450
+ duration: 500,
2451
+ distance: 10,
2452
+ disabled: false,
2453
+ prevent: true,
2454
+ stop: false,
2455
+ tickInterval: 100
2456
+ }, binding);
2457
+ }
2458
+ function getDistance$1(p1, p2) {
2459
+ return Math.sqrt(__pow(p2.x - p1.x, 2) + __pow(p2.y - p1.y, 2));
2460
+ }
2461
+ const vLongPress = defineDirective({
2462
+ name: "long-press",
2463
+ ssr: false,
2464
+ defaults: {
2465
+ duration: 500,
2466
+ distance: 10,
2467
+ disabled: false,
2468
+ prevent: true,
2469
+ stop: false,
2470
+ tickInterval: 100
2471
+ },
2472
+ mounted(el, binding) {
2473
+ const options = normalizeOptions$g(binding.value);
2474
+ if (options.disabled || !isBrowser()) return;
2475
+ const state = {
2476
+ options,
2477
+ timerId: null,
2478
+ tickTimerId: null,
2479
+ startTime: 0,
2480
+ startPos: { x: 0, y: 0 },
2481
+ startHandler: () => {
2482
+ },
2483
+ endHandler: () => {
2484
+ },
2485
+ moveHandler: () => {
2486
+ }
2487
+ };
2488
+ state.startHandler = (e) => {
2489
+ var _a;
2490
+ const event = e;
2491
+ if (options.prevent) {
2492
+ event.preventDefault();
2493
+ }
2494
+ if (options.stop) {
2495
+ event.stopPropagation();
2496
+ }
2497
+ if (state.timerId) {
2498
+ clearTimeout(state.timerId);
2499
+ state.timerId = null;
2500
+ }
2501
+ if (state.tickTimerId) {
2502
+ clearInterval(state.tickTimerId);
2503
+ state.tickTimerId = null;
2504
+ }
2505
+ const pos = getEventPosition(event);
2506
+ state.startPos = { x: pos.x, y: pos.y };
2507
+ state.startTime = Date.now();
2508
+ (_a = options.onStart) == null ? void 0 : _a.call(options, event);
2509
+ if (options.onTick) {
2510
+ let remaining = options.duration;
2511
+ state.tickTimerId = setInterval(() => {
2512
+ var _a2;
2513
+ remaining -= options.tickInterval;
2514
+ (_a2 = options.onTick) == null ? void 0 : _a2.call(options, Math.max(0, remaining));
2515
+ }, options.tickInterval);
2516
+ }
2517
+ state.timerId = setTimeout(() => {
2518
+ if (state.tickTimerId) {
2519
+ clearInterval(state.tickTimerId);
2520
+ state.tickTimerId = null;
2521
+ }
2522
+ options.handler(event);
2523
+ }, options.duration);
2524
+ };
2525
+ state.endHandler = (e) => {
2526
+ var _a;
2527
+ const event = e;
2528
+ if (state.timerId) {
2529
+ clearTimeout(state.timerId);
2530
+ state.timerId = null;
2531
+ }
2532
+ if (state.tickTimerId) {
2533
+ clearInterval(state.tickTimerId);
2534
+ state.tickTimerId = null;
2535
+ }
2536
+ if (state.startTime > 0) {
2537
+ (_a = options.onCancel) == null ? void 0 : _a.call(options, event);
2538
+ }
2539
+ state.startTime = 0;
2540
+ };
2541
+ state.moveHandler = (e) => {
2542
+ var _a;
2543
+ if (!state.timerId) return;
2544
+ const event = e;
2545
+ const pos = getEventPosition(event);
2546
+ const distance = getDistance$1(state.startPos, { x: pos.x, y: pos.y });
2547
+ if (distance > (options.distance || 10)) {
2548
+ if (state.timerId) {
2549
+ clearTimeout(state.timerId);
2550
+ state.timerId = null;
2551
+ }
2552
+ if (state.tickTimerId) {
2553
+ clearInterval(state.tickTimerId);
2554
+ state.tickTimerId = null;
2555
+ }
2556
+ (_a = options.onCancel) == null ? void 0 : _a.call(options, event);
2557
+ state.startTime = 0;
2558
+ }
2559
+ };
2560
+ el.__longPress = state;
2561
+ on(el, "mousedown", state.startHandler);
2562
+ on(el, "mouseup", state.endHandler);
2563
+ on(el, "mouseleave", state.endHandler);
2564
+ on(el, "mousemove", state.moveHandler);
2565
+ on(el, "touchstart", state.startHandler, { passive: !options.prevent });
2566
+ on(el, "touchend", state.endHandler);
2567
+ on(el, "touchcancel", state.endHandler);
2568
+ on(el, "touchmove", state.moveHandler, { passive: true });
2569
+ },
2570
+ updated(el, binding) {
2571
+ const state = el.__longPress;
2572
+ if (!state) {
2573
+ const options = normalizeOptions$g(binding.value);
2574
+ if (!options.disabled) {
2575
+ el.__longPress = null;
2576
+ }
2577
+ return;
2578
+ }
2579
+ state.options = normalizeOptions$g(binding.value);
2580
+ },
2581
+ unmounted(el) {
2582
+ const state = el.__longPress;
2583
+ if (!state) return;
2584
+ if (state.timerId) {
2585
+ clearTimeout(state.timerId);
2586
+ }
2587
+ if (state.tickTimerId) {
2588
+ clearInterval(state.tickTimerId);
2589
+ }
2590
+ off(el, "mousedown", state.startHandler);
2591
+ off(el, "mouseup", state.endHandler);
2592
+ off(el, "mouseleave", state.endHandler);
2593
+ off(el, "mousemove", state.moveHandler);
2594
+ off(el, "touchstart", state.startHandler);
2595
+ off(el, "touchend", state.endHandler);
2596
+ off(el, "touchcancel", state.endHandler);
2597
+ off(el, "touchmove", state.moveHandler);
2598
+ delete el.__longPress;
2599
+ }
2600
+ });
2601
+ function transformText$1(text, options) {
2602
+ if (!text) return text;
2603
+ if (options.first) {
2604
+ return text.charAt(0).toLowerCase() + text.slice(1);
2605
+ }
2606
+ return text.toLowerCase();
2607
+ }
2608
+ function normalizeOptions$f(binding) {
2609
+ var _a, _b;
2610
+ if (binding === void 0 || binding === true) {
2611
+ return { first: false, onInput: true };
2612
+ }
2613
+ if (binding === false) {
2614
+ return { first: false, onInput: false };
2615
+ }
2616
+ return {
2617
+ first: (_a = binding.first) != null ? _a : false,
2618
+ onInput: (_b = binding.onInput) != null ? _b : true
2619
+ };
2620
+ }
2621
+ const vLowercase = defineDirective({
2622
+ name: "lowercase",
2623
+ ssr: true,
2624
+ mounted(el, binding) {
2625
+ const options = normalizeOptions$f(binding.value);
2626
+ if (isInputElement(el)) {
2627
+ const cleanup2 = setupTextTransformInput(el, options, (text) => transformText$1(text, options));
2628
+ el.__lowercaseCleanup = cleanup2;
2629
+ } else {
2630
+ transformTextContent(el, (text) => transformText$1(text, options));
2631
+ }
2632
+ },
2633
+ updated(el, binding) {
2634
+ const options = normalizeOptions$f(binding.value);
2635
+ if (isInputElement(el)) {
2636
+ if (options.onInput) {
2637
+ el.value = transformText$1(el.value, options);
2638
+ }
2639
+ } else {
2640
+ transformTextContent(el, (text) => transformText$1(text, options));
2641
+ }
2642
+ },
2643
+ unmounted(el) {
2644
+ const cleanup2 = el.__lowercaseCleanup;
2645
+ cleanup2 == null ? void 0 : cleanup2();
2646
+ delete el.__lowercaseCleanup;
2647
+ }
2648
+ });
2649
+ const STATE_KEY$2 = "__mask";
2650
+ const TOKEN_PATTERNS = {
2651
+ "#": /\d/,
2652
+ A: /[A-Za-z]/,
2653
+ N: /[A-Za-z0-9]/,
2654
+ X: /./
2655
+ };
2656
+ function parseMask(mask, placeholder) {
2657
+ return [...mask].map((char) => {
2658
+ const pattern = TOKEN_PATTERNS[char];
2659
+ return pattern ? { pattern, placeholder, isLiteral: false } : { pattern: new RegExp(`\\${char}`), placeholder: char, isLiteral: true };
2660
+ });
2661
+ }
2662
+ function normalizeOptions$e(binding) {
2663
+ if (typeof binding === "string") return { mask: binding, placeholder: "_", showPlaceholder: true };
2664
+ if (!(binding == null ? void 0 : binding.mask)) throw new Error("[Directix] v-mask: mask is required");
2665
+ return __spreadValues({ placeholder: "_", showPlaceholder: true, showMaskOnBlur: false, clearIncomplete: false, disabled: false }, binding);
2666
+ }
2667
+ function isInput(el) {
2668
+ return el.tagName === "INPUT" || el.tagName === "TEXTAREA";
2669
+ }
2670
+ function formatValue(value, tokens, placeholder, showPlaceholder) {
2671
+ let result = "", valueIndex = 0;
2672
+ for (const token of tokens) {
2673
+ if (valueIndex >= value.length) {
2674
+ result += token.isLiteral ? token.placeholder : showPlaceholder ? placeholder : "";
2675
+ continue;
2676
+ }
2677
+ const inputChar = value[valueIndex];
2678
+ if (token.isLiteral) {
2679
+ if (inputChar === token.placeholder) valueIndex++;
2680
+ result += token.placeholder;
2681
+ } else if (token.pattern.test(inputChar)) {
2682
+ result += inputChar;
2683
+ valueIndex++;
2684
+ } else if (inputChar === placeholder) {
2685
+ result += showPlaceholder ? placeholder : "";
2686
+ valueIndex++;
2687
+ } else {
2688
+ valueIndex++;
2689
+ }
2690
+ }
2691
+ return result;
2692
+ }
2693
+ function getRawValue(value, tokens, placeholder) {
2694
+ let raw = "";
2695
+ for (let i = 0; i < value.length && i < tokens.length; i++) {
2696
+ if (!tokens[i].isLiteral && value[i] !== placeholder) {
2697
+ raw += value[i];
2698
+ }
2699
+ }
2700
+ return raw;
2701
+ }
2702
+ function isComplete(value, tokens, placeholder) {
2703
+ for (let i = 0; i < tokens.length; i++) {
2704
+ if (!tokens[i].isLiteral && (i >= value.length || value[i] === placeholder)) {
2705
+ return false;
2706
+ }
2707
+ }
2708
+ return true;
2709
+ }
2710
+ function getCursorPos(tokens, rawCursorPos) {
2711
+ let pos = rawCursorPos;
2712
+ while (pos < tokens.length && tokens[pos].isLiteral) {
2713
+ pos++;
2714
+ }
2715
+ return Math.min(pos, tokens.length);
2716
+ }
2717
+ const vMask = defineDirective({
2718
+ name: "mask",
2719
+ ssr: false,
2720
+ defaults: { placeholder: "_", showPlaceholder: true, showMaskOnBlur: false, clearIncomplete: false, disabled: false },
2721
+ mounted(el, binding) {
2722
+ var _a;
2723
+ if (!isInput(el)) {
2724
+ console.warn("[Directix] v-mask: directive must be used on input or textarea elements");
2725
+ return;
2726
+ }
2727
+ const options = normalizeOptions$e(binding.value);
2728
+ if (options.disabled || !isBrowser()) return;
2729
+ const placeholder = options.placeholder || "_";
2730
+ const tokens = parseMask(options.mask, placeholder);
2731
+ const inputHandler = (e) => {
2732
+ var _a2, _b, _c;
2733
+ const target = e.target;
2734
+ const rawValue = target.value;
2735
+ const cursorPos = target.selectionStart || 0;
2736
+ const formatted = formatValue(rawValue, tokens, placeholder, (_a2 = options.showPlaceholder) != null ? _a2 : true);
2737
+ if (formatted !== rawValue) {
2738
+ target.value = formatted;
2739
+ target.setSelectionRange(getCursorPos(tokens, cursorPos), getCursorPos(tokens, cursorPos));
2740
+ target.dispatchEvent(new Event("input", { bubbles: true }));
2741
+ return;
2742
+ }
2743
+ (_b = options.onChange) == null ? void 0 : _b.call(options, formatted, getRawValue(formatted, tokens, placeholder));
2744
+ if (isComplete(formatted, tokens, placeholder)) {
2745
+ (_c = options.onComplete) == null ? void 0 : _c.call(options, formatted);
2746
+ }
2747
+ };
2748
+ const focusHandler = () => {
2749
+ if (!el.value && options.showPlaceholder) {
2750
+ el.value = formatValue("", tokens, placeholder, true);
2751
+ }
2752
+ };
2753
+ const blurHandler = () => {
2754
+ if (!options.showMaskOnBlur && !isComplete(el.value, tokens, placeholder) && options.clearIncomplete) {
2755
+ el.value = "";
2756
+ }
2757
+ };
2758
+ on(el, "input", inputHandler);
2759
+ on(el, "focus", focusHandler);
2760
+ on(el, "blur", blurHandler);
2761
+ el[STATE_KEY$2] = { options, tokens, placeholder, inputHandler, focusHandler, blurHandler };
2762
+ if (el.value) {
2763
+ el.value = formatValue(el.value, tokens, placeholder, (_a = options.showPlaceholder) != null ? _a : true);
2764
+ }
2765
+ },
2766
+ updated(el, binding) {
2767
+ const state = el[STATE_KEY$2];
2768
+ if (!state) return;
2769
+ state.options = normalizeOptions$e(binding.value);
2770
+ state.tokens = parseMask(state.options.mask, state.placeholder);
2771
+ },
2772
+ unmounted(el) {
2773
+ const state = el[STATE_KEY$2];
2774
+ if (!state) return;
2775
+ off(el, "input", state.inputHandler);
2776
+ off(el, "focus", state.focusHandler);
2777
+ off(el, "blur", state.blurHandler);
2778
+ delete el[STATE_KEY$2];
2779
+ }
2780
+ });
2781
+ function formatNumber(value, options) {
2782
+ const { precision = 0, separator = ",", decimal = ".", prefix = "", suffix = "" } = options;
2783
+ const fixed = value.toFixed(precision);
2784
+ const [intPart, decPart] = fixed.split(".");
2785
+ const formattedInt = intPart.replace(/\B(?=(\d{3})+(?!\d))/g, separator);
2786
+ let result = formattedInt;
2787
+ if (precision > 0 && decPart) {
2788
+ result += decimal + decPart;
2789
+ }
2790
+ return prefix + result + suffix;
2791
+ }
2792
+ function parseToNumber(value, decimal) {
2793
+ const cleaned = value.replace(/[^\d.-]/g, "").replace(decimal, ".");
2794
+ const num = Number.parseFloat(cleaned);
2795
+ return isNaN(num) ? null : num;
2796
+ }
2797
+ function clampValue(value, options) {
2798
+ var _a;
2799
+ let result = value;
2800
+ const allowNegative = (_a = options.allowNegative) != null ? _a : true;
2801
+ if (!allowNegative && result < 0) {
2802
+ result = Math.abs(result);
2803
+ }
2804
+ if (options.min !== void 0) result = Math.max(options.min, result);
2805
+ if (options.max !== void 0) result = Math.min(options.max, result);
2806
+ return result;
2807
+ }
2808
+ function calculateCursorPosition(rawValue, formatted, cursorPos, startOffset = 0) {
2809
+ let digitsBeforeCursor = 0, digitCount = 0;
2810
+ for (let i = 0; i < cursorPos && i < rawValue.length; i++) {
2811
+ if (/\d/.test(rawValue[i])) {
2812
+ digitsBeforeCursor++;
2813
+ }
2814
+ }
2815
+ for (let i = startOffset; i < formatted.length; i++) {
2816
+ if (/\d/.test(formatted[i])) {
2817
+ digitCount++;
2818
+ }
2819
+ if (digitCount >= digitsBeforeCursor) {
2820
+ return i + 1;
2821
+ }
2822
+ }
2823
+ return formatted.length;
2824
+ }
2825
+ function setupNumberInput(el, options, formatFn) {
2826
+ const { decimal = ".", prefix = "" } = options;
2827
+ let isFormatting = false;
2828
+ const onInput = () => {
2829
+ if (isFormatting) return;
2830
+ const rawValue = el.value;
2831
+ const cursorPos = el.selectionStart || 0;
2832
+ if (!rawValue || rawValue === "-") {
2833
+ return;
2834
+ }
2835
+ const num = parseToNumber(rawValue, decimal);
2836
+ if (num === null) {
2837
+ isFormatting = true;
2838
+ el.value = "";
2839
+ el.dispatchEvent(new Event("input", { bubbles: true }));
2840
+ isFormatting = false;
2841
+ return;
2842
+ }
2843
+ const clamped = clampValue(num, options);
2844
+ const formatted = formatFn(clamped, options);
2845
+ if (formatted !== rawValue) {
2846
+ isFormatting = true;
2847
+ const startOffset = prefix.length;
2848
+ const newCursorPos = calculateCursorPosition(rawValue, formatted, cursorPos, startOffset);
2849
+ el.value = formatted;
2850
+ el.setSelectionRange(newCursorPos, newCursorPos);
2851
+ el.dispatchEvent(new Event("input", { bubbles: true }));
2852
+ isFormatting = false;
2853
+ }
2854
+ };
2855
+ const onBlur = () => {
2856
+ if (!el.value || el.value === "-") return;
2857
+ const num = parseToNumber(el.value, decimal);
2858
+ if (num !== null) {
2859
+ const clamped = clampValue(num, options);
2860
+ const formatted = formatFn(clamped, options);
2861
+ isFormatting = true;
2862
+ el.value = formatted;
2863
+ el.dispatchEvent(new Event("input", { bubbles: true }));
2864
+ isFormatting = false;
2865
+ }
2866
+ };
2867
+ el.addEventListener("input", onInput);
2868
+ el.addEventListener("blur", onBlur);
2869
+ if (el.value) {
2870
+ const num = parseToNumber(el.value, decimal);
2871
+ if (num !== null) {
2872
+ const formatted = formatFn(clampValue(num, options), options);
2873
+ isFormatting = true;
2874
+ el.value = formatted;
2875
+ el.dispatchEvent(new Event("input", { bubbles: true }));
2876
+ isFormatting = false;
2877
+ }
2878
+ }
2879
+ return () => {
2880
+ el.removeEventListener("input", onInput);
2881
+ el.removeEventListener("blur", onBlur);
2882
+ };
2883
+ }
2884
+ function formatMoney(value, options) {
2885
+ const { precision = 2, separator = ",", decimal = ".", symbol = "$", symbolPosition = "before" } = options;
2886
+ const fixed = value.toFixed(precision);
2887
+ const [intPart, decPart] = fixed.split(".");
2888
+ const formattedInt = intPart.replace(/\B(?=(\d{3})+(?!\d))/g, separator);
2889
+ let result = formattedInt;
2890
+ if (precision > 0 && decPart) {
2891
+ result += decimal + decPart;
2892
+ }
2893
+ return symbolPosition === "before" ? symbol + result : result + symbol;
2894
+ }
2895
+ const vMoney = defineDirective({
2896
+ name: "money",
2897
+ ssr: true,
2898
+ mounted(el, binding) {
2899
+ var _a, _b, _c;
2900
+ const options = typeof binding.value === "string" ? { symbol: binding.value } : (_a = binding.value) != null ? _a : {};
2901
+ options.precision = (_b = options.precision) != null ? _b : 2;
2902
+ if (el.tagName === "INPUT" || el.tagName === "TEXTAREA") {
2903
+ const { symbol = "$", symbolPosition = "before" } = options;
2904
+ const prefix = symbolPosition === "before" ? symbol : "";
2905
+ const cleanup2 = setupNumberInput(el, __spreadProps(__spreadValues({}, options), { prefix }), formatMoney);
2906
+ el.__money = { options, cleanup: cleanup2 };
2907
+ requestAnimationFrame(() => {
2908
+ const inputEl = el;
2909
+ if (inputEl.value) {
2910
+ const num = parseToNumber(inputEl.value, options.decimal || ".");
2911
+ if (num !== null) {
2912
+ const formatted = formatMoney(clampValue(num, options), options);
2913
+ if (formatted !== inputEl.value) {
2914
+ inputEl.value = formatted;
2915
+ inputEl.dispatchEvent(new Event("input", { bubbles: true }));
2916
+ }
2917
+ }
2918
+ }
2919
+ });
2920
+ } else {
2921
+ let value = null;
2922
+ if (binding.value && typeof binding.value === "object" && "value" in binding.value) {
2923
+ value = binding.value.value;
2924
+ } else {
2925
+ const textContent = (_c = el.textContent) == null ? void 0 : _c.trim();
2926
+ if (textContent) {
2927
+ value = parseToNumber(textContent, options.decimal || ".");
2928
+ }
2929
+ }
2930
+ if (value !== null) {
2931
+ el.textContent = formatMoney(clampValue(value, options), options);
2932
+ }
2933
+ }
2934
+ },
2935
+ updated(el, binding) {
2936
+ var _a, _b;
2937
+ const options = typeof binding.value === "string" ? { symbol: binding.value } : (_a = binding.value) != null ? _a : {};
2938
+ options.precision = (_b = options.precision) != null ? _b : 2;
2939
+ const state = el.__money;
2940
+ if (state) {
2941
+ state.options = options;
2942
+ } else if (!(el.tagName === "INPUT" || el.tagName === "TEXTAREA")) {
2943
+ let value = null;
2944
+ if (binding.value && typeof binding.value === "object" && "value" in binding.value) {
2945
+ value = binding.value.value;
2946
+ }
2947
+ if (value !== null) {
2948
+ el.textContent = formatMoney(clampValue(value, options), options);
2949
+ }
2950
+ }
2951
+ },
2952
+ unmounted(el) {
2953
+ const state = el.__money;
2954
+ state == null ? void 0 : state.cleanup();
2955
+ delete el.__money;
2956
+ }
2957
+ });
2958
+ function normalizeOptions$d(binding) {
2959
+ if (typeof binding === "function") {
2960
+ return { handler: binding, childList: true };
2961
+ }
2962
+ if (!binding || !binding.handler) {
2963
+ throw new Error("[Directix] v-mutation: handler is required");
2964
+ }
2965
+ return __spreadValues({
2966
+ attributes: false,
2967
+ childList: true,
2968
+ subtree: false,
2969
+ characterData: false,
2970
+ attributeOldValue: false,
2971
+ characterDataOldValue: false,
2972
+ disabled: false
2973
+ }, binding);
2974
+ }
2975
+ const vMutation = defineDirective({
2976
+ name: "mutation",
2977
+ ssr: false,
2978
+ defaults: {
2979
+ attributes: false,
2980
+ childList: true,
2981
+ subtree: false,
2982
+ characterData: false,
2983
+ attributeOldValue: false,
2984
+ characterDataOldValue: false,
2985
+ disabled: false
2986
+ },
2987
+ mounted(el, binding) {
2988
+ const options = normalizeOptions$d(binding.value);
2989
+ if (options.disabled || !isBrowser()) return;
2990
+ if (!supportsMutationObserver()) {
2991
+ console.warn("[Directix] v-mutation: MutationObserver not supported");
2992
+ return;
2993
+ }
2994
+ const state = {
2995
+ options,
2996
+ observer: null
2997
+ };
2998
+ state.observer = new MutationObserver((mutations, observer) => {
2999
+ options.handler(mutations, observer);
3000
+ });
3001
+ state.observer.observe(el, {
3002
+ attributes: options.attributes,
3003
+ attributeFilter: options.attributeFilter,
3004
+ childList: options.childList,
3005
+ subtree: options.subtree,
3006
+ characterData: options.characterData,
3007
+ attributeOldValue: options.attributeOldValue,
3008
+ characterDataOldValue: options.characterDataOldValue
3009
+ });
3010
+ el.__mutation = state;
3011
+ },
3012
+ updated(el, binding) {
3013
+ const state = el.__mutation;
3014
+ if (!state) return;
3015
+ const newOptions = normalizeOptions$d(binding.value);
3016
+ if (newOptions.disabled && !state.options.disabled) {
3017
+ if (state.observer) {
3018
+ state.observer.disconnect();
3019
+ }
3020
+ } else if (!newOptions.disabled && state.options.disabled) {
3021
+ if (state.observer) {
3022
+ state.observer.observe(el, {
3023
+ attributes: newOptions.attributes,
3024
+ attributeFilter: newOptions.attributeFilter,
3025
+ childList: newOptions.childList,
3026
+ subtree: newOptions.subtree,
3027
+ characterData: newOptions.characterData,
3028
+ attributeOldValue: newOptions.attributeOldValue,
3029
+ characterDataOldValue: newOptions.characterDataOldValue
3030
+ });
3031
+ }
3032
+ } else if (!newOptions.disabled) {
3033
+ if (newOptions.attributes !== state.options.attributes || newOptions.childList !== state.options.childList || newOptions.subtree !== state.options.subtree || newOptions.characterData !== state.options.characterData) {
3034
+ if (state.observer) {
3035
+ state.observer.disconnect();
3036
+ state.observer.observe(el, {
3037
+ attributes: newOptions.attributes,
3038
+ attributeFilter: newOptions.attributeFilter,
3039
+ childList: newOptions.childList,
3040
+ subtree: newOptions.subtree,
3041
+ characterData: newOptions.characterData,
3042
+ attributeOldValue: newOptions.attributeOldValue,
3043
+ characterDataOldValue: newOptions.characterDataOldValue
3044
+ });
3045
+ }
3046
+ }
3047
+ }
3048
+ state.options = newOptions;
3049
+ },
3050
+ unmounted(el) {
3051
+ const state = el.__mutation;
3052
+ if (!state) return;
3053
+ if (state.observer) {
3054
+ state.observer.disconnect();
3055
+ }
3056
+ delete el.__mutation;
3057
+ }
3058
+ });
3059
+ const vNumber = defineDirective({
3060
+ name: "number",
3061
+ ssr: true,
3062
+ mounted(el, binding) {
3063
+ var _a, _b;
3064
+ const options = typeof binding.value === "number" ? { precision: binding.value } : (_a = binding.value) != null ? _a : {};
3065
+ if (el.tagName === "INPUT" || el.tagName === "TEXTAREA") {
3066
+ const cleanup2 = setupNumberInput(el, options, formatNumber);
3067
+ el.__number = { options, cleanup: cleanup2 };
3068
+ requestAnimationFrame(() => {
3069
+ const inputEl = el;
3070
+ if (inputEl.value) {
3071
+ const num = parseToNumber(inputEl.value, options.decimal || ".");
3072
+ if (num !== null) {
3073
+ const formatted = formatNumber(clampValue(num, options), options);
3074
+ if (formatted !== inputEl.value) {
3075
+ inputEl.value = formatted;
3076
+ inputEl.dispatchEvent(new Event("input", { bubbles: true }));
3077
+ }
3078
+ }
3079
+ }
3080
+ });
3081
+ } else {
3082
+ let value = null;
3083
+ if (typeof binding.value === "number") {
3084
+ value = binding.value;
3085
+ } else if (binding.value && typeof binding.value === "object" && "value" in binding.value) {
3086
+ value = binding.value.value;
3087
+ } else {
3088
+ const textContent = (_b = el.textContent) == null ? void 0 : _b.trim();
3089
+ if (textContent) {
3090
+ value = parseToNumber(textContent, options.decimal || ".");
3091
+ }
3092
+ }
3093
+ if (value !== null) {
3094
+ el.textContent = formatNumber(clampValue(value, options), options);
3095
+ }
3096
+ }
3097
+ },
3098
+ updated(el, binding) {
3099
+ var _a;
3100
+ const options = typeof binding.value === "number" ? { precision: binding.value } : (_a = binding.value) != null ? _a : {};
3101
+ const state = el.__number;
3102
+ if (state) {
3103
+ state.options = options;
3104
+ } else if (!(el.tagName === "INPUT" || el.tagName === "TEXTAREA")) {
3105
+ let value = null;
3106
+ if (typeof binding.value === "number") {
3107
+ value = binding.value;
3108
+ } else if (binding.value && typeof binding.value === "object" && "value" in binding.value) {
3109
+ value = binding.value.value;
3110
+ }
3111
+ if (value !== null) {
3112
+ el.textContent = formatNumber(clampValue(value, options), options);
3113
+ }
3114
+ }
3115
+ },
3116
+ unmounted(el) {
3117
+ const state = el.__number;
3118
+ state == null ? void 0 : state.cleanup();
3119
+ delete el.__number;
3120
+ }
3121
+ });
3122
+ const STATE_KEY$1 = "__permission";
3123
+ const WILDCARD = "*";
3124
+ let globalConfig = null;
3125
+ function configurePermission(config) {
3126
+ globalConfig = config;
3127
+ }
3128
+ function getPermissionConfig() {
3129
+ return globalConfig;
3130
+ }
3131
+ function normalizeOptions$c(binding) {
3132
+ if (!binding) {
3133
+ throw new Error("[Directix] v-permission: permission value is required");
3134
+ }
3135
+ if (typeof binding === "string") {
3136
+ return { value: binding };
3137
+ }
3138
+ if (Array.isArray(binding)) {
3139
+ return { value: binding };
3140
+ }
3141
+ return binding;
3142
+ }
3143
+ function hasPermission(required, permissions) {
3144
+ return permissions.includes(WILDCARD) || permissions.includes(required);
3145
+ }
3146
+ function verifyPermission(options) {
3147
+ var _a;
3148
+ if (options.check) {
3149
+ return options.check(options.value, options.mode || "some");
3150
+ }
3151
+ if (!globalConfig) {
3152
+ console.warn("[Directix] v-permission: No permission config provided");
3153
+ return true;
3154
+ }
3155
+ const permissions = globalConfig.getPermissions();
3156
+ const roles = ((_a = globalConfig.getRoles) == null ? void 0 : _a.call(globalConfig)) || [];
3157
+ const roleMap = globalConfig.roleMap || {};
3158
+ const required = Array.isArray(options.value) ? options.value : [options.value];
3159
+ const mode = options.mode || "some";
3160
+ function checkSingle(value) {
3161
+ if (value in roleMap) {
3162
+ return roles.includes(value);
3163
+ }
3164
+ if (hasPermission(value, permissions)) {
3165
+ return true;
3166
+ }
3167
+ for (const role of roles) {
3168
+ const rolePermissions = roleMap[role] || [];
3169
+ if (hasPermission(value, rolePermissions)) {
3170
+ return true;
3171
+ }
3172
+ }
3173
+ return false;
3174
+ }
3175
+ return mode === "every" ? required.every(checkSingle) : required.some(checkSingle);
3176
+ }
3177
+ function handleDenied(el, action, state) {
3178
+ var _a, _b;
3179
+ switch (action) {
3180
+ case "remove":
3181
+ state.parentNode = el.parentNode;
3182
+ state.placeholder = document.createComment("v-permission");
3183
+ (_a = el.parentNode) == null ? void 0 : _a.insertBefore(state.placeholder, el);
3184
+ (_b = el.parentNode) == null ? void 0 : _b.removeChild(el);
3185
+ break;
3186
+ case "disable":
3187
+ state.originalDisabled = el.getAttribute("disabled") || false;
3188
+ el.setAttribute("disabled", "true");
3189
+ el.classList.add("v-permission--disabled");
3190
+ break;
3191
+ case "hide":
3192
+ state.originalDisplay = el.style.display;
3193
+ el.style.display = "none";
3194
+ el.classList.add("v-permission--hidden");
3195
+ break;
3196
+ }
3197
+ }
3198
+ function handleGranted(el, action, state) {
3199
+ switch (action) {
3200
+ case "remove":
3201
+ if (state.placeholder && state.parentNode) {
3202
+ state.parentNode.insertBefore(el, state.placeholder);
3203
+ state.parentNode.removeChild(state.placeholder);
3204
+ state.placeholder = null;
3205
+ }
3206
+ break;
3207
+ case "disable":
3208
+ if (state.originalDisabled === false) {
3209
+ el.removeAttribute("disabled");
3210
+ } else if (state.originalDisabled) {
3211
+ el.setAttribute("disabled", state.originalDisabled);
3212
+ }
3213
+ el.classList.remove("v-permission--disabled");
3214
+ break;
3215
+ case "hide":
3216
+ el.style.display = state.originalDisplay || "";
3217
+ el.classList.remove("v-permission--hidden");
3218
+ break;
3219
+ }
3220
+ }
3221
+ function getState(el) {
3222
+ if (!el[STATE_KEY$1]) {
3223
+ el[STATE_KEY$1] = {
3224
+ options: { value: "" },
3225
+ originalDisplay: "",
3226
+ originalDisabled: false,
3227
+ parentNode: null,
3228
+ placeholder: null
3229
+ };
3230
+ }
3231
+ return el[STATE_KEY$1];
3232
+ }
3233
+ function checkPermission(el, binding) {
3234
+ var _a, _b;
3235
+ const state = getState(el);
3236
+ state.options = normalizeOptions$c(binding.value);
3237
+ const granted = verifyPermission(state.options);
3238
+ (_b = (_a = state.options).onChange) == null ? void 0 : _b.call(_a, granted);
3239
+ const action = state.options.action || "remove";
3240
+ if (granted) {
3241
+ handleGranted(el, action, state);
3242
+ } else {
3243
+ handleDenied(el, action, state);
3244
+ }
3245
+ }
3246
+ function cleanup(el) {
3247
+ const state = el[STATE_KEY$1];
3248
+ if ((state == null ? void 0 : state.placeholder) && state.parentNode) {
3249
+ state.parentNode.removeChild(state.placeholder);
3250
+ }
3251
+ delete el[STATE_KEY$1];
3252
+ }
3253
+ const vPermission = defineDirective({
3254
+ name: "permission",
3255
+ ssr: true,
3256
+ mounted(el, binding) {
3257
+ checkPermission(el, binding);
3258
+ },
3259
+ updated(el, binding) {
3260
+ checkPermission(el, binding);
3261
+ },
3262
+ unmounted(el) {
3263
+ cleanup(el);
3264
+ }
3265
+ });
3266
+ function getResizeInfo(entry) {
3267
+ return {
3268
+ width: entry.contentRect.width,
3269
+ height: entry.contentRect.height,
3270
+ contentRect: entry.contentRect,
3271
+ borderBoxSize: entry.borderBoxSize,
3272
+ contentBoxSize: entry.contentBoxSize,
3273
+ devicePixelContentBoxSize: entry.devicePixelContentBoxSize
3274
+ };
3275
+ }
3276
+ function normalizeOptions$b(binding) {
3277
+ if (typeof binding === "function") {
3278
+ return { handler: binding };
3279
+ }
3280
+ if (!binding) {
3281
+ throw new Error("[Directix] v-resize: handler is required");
3282
+ }
3283
+ return __spreadValues({
3284
+ disabled: false,
3285
+ box: "content-box",
3286
+ debounce: 0
3287
+ }, binding);
3288
+ }
3289
+ function createFallbackResize(el, callback) {
3290
+ const iframe = document.createElement("iframe");
3291
+ iframe.style.cssText = `
3292
+ position: absolute;
3293
+ top: 0;
3294
+ left: 0;
3295
+ width: 100%;
3296
+ height: 100%;
3297
+ border: none;
3298
+ pointer-events: none;
3299
+ opacity: 0;
3300
+ `;
3301
+ el.appendChild(iframe);
3302
+ const iWindow = iframe.contentWindow;
3303
+ if (iWindow) {
3304
+ iWindow.addEventListener("resize", callback);
3305
+ }
3306
+ return {
3307
+ iframe,
3308
+ cleanup: () => {
3309
+ if (iWindow) {
3310
+ iWindow.removeEventListener("resize", callback);
3311
+ }
3312
+ iframe.remove();
3313
+ }
3314
+ };
3315
+ }
3316
+ const vResize = defineDirective({
3317
+ name: "resize",
3318
+ ssr: false,
3319
+ defaults: {
3320
+ disabled: false,
3321
+ box: "content-box",
3322
+ debounce: 0
3323
+ },
3324
+ mounted(el, binding) {
3325
+ const options = normalizeOptions$b(binding.value);
3326
+ if (options.disabled || !isBrowser()) return;
3327
+ const computedStyle = getComputedStyle(el);
3328
+ if (computedStyle.position === "static") {
3329
+ el.style.position = "relative";
3330
+ }
3331
+ const state = {
3332
+ options,
3333
+ observer: null,
3334
+ debounceTimer: null,
3335
+ pendingEntry: null,
3336
+ fallbackIframe: null,
3337
+ handler: (entry) => {
3338
+ if (options.debounce && options.debounce > 0) {
3339
+ state.pendingEntry = entry;
3340
+ if (!state.debounceTimer) {
3341
+ state.debounceTimer = setTimeout(() => {
3342
+ if (state.pendingEntry) {
3343
+ options.handler(state.pendingEntry);
3344
+ }
3345
+ state.debounceTimer = null;
3346
+ state.pendingEntry = null;
3347
+ }, options.debounce);
3348
+ }
3349
+ } else {
3350
+ options.handler(entry);
3351
+ }
3352
+ }
3353
+ };
3354
+ el.__resize = state;
3355
+ if (supportsResizeObserver()) {
3356
+ state.observer = new ResizeObserver((entries) => {
3357
+ for (const entry of entries) {
3358
+ state.handler(entry);
3359
+ }
3360
+ });
3361
+ state.observer.observe(el, { box: options.box });
3362
+ } else {
3363
+ console.warn("[Directix] v-resize: ResizeObserver not supported, using fallback");
3364
+ const { iframe, cleanup: cleanup2 } = createFallbackResize(el, () => {
3365
+ const rect = el.getBoundingClientRect();
3366
+ const entry = {
3367
+ target: el,
3368
+ contentRect: rect,
3369
+ borderBoxSize: [],
3370
+ contentBoxSize: [],
3371
+ devicePixelContentBoxSize: []
3372
+ };
3373
+ state.handler(entry);
3374
+ if (options.onFallback) {
3375
+ options.onFallback(getResizeInfo(entry));
3376
+ }
3377
+ });
3378
+ state.fallbackIframe = iframe;
3379
+ el.__resizeCleanup = cleanup2;
3380
+ }
3381
+ },
3382
+ updated(el, binding) {
3383
+ const state = el.__resize;
3384
+ if (!state) return;
3385
+ state.options = normalizeOptions$b(binding.value);
3386
+ },
3387
+ unmounted(el) {
3388
+ const state = el.__resize;
3389
+ if (!state) return;
3390
+ if (state.debounceTimer) {
3391
+ clearTimeout(state.debounceTimer);
3392
+ }
3393
+ if (state.observer) {
3394
+ state.observer.disconnect();
3395
+ }
3396
+ const cleanup2 = el.__resizeCleanup;
3397
+ if (cleanup2) {
3398
+ cleanup2();
3399
+ }
3400
+ delete el.__resize;
3401
+ delete el.__resizeCleanup;
3402
+ }
3403
+ });
3404
+ function normalizeOptions$a(binding) {
3405
+ if (binding === false) {
3406
+ return { disabled: true, color: "currentColor", duration: 600 };
3407
+ }
3408
+ if (typeof binding === "string") {
3409
+ return { color: binding, duration: 600 };
3410
+ }
3411
+ const base = {
3412
+ color: "currentColor",
3413
+ duration: 600,
3414
+ disabled: false,
3415
+ initialScale: 0,
3416
+ finalScale: 2
3417
+ };
3418
+ return binding && typeof binding === "object" ? __spreadValues(__spreadValues({}, base), binding) : base;
3419
+ }
3420
+ function createRipple(event, el, options) {
3421
+ const rect = el.getBoundingClientRect();
3422
+ const x = event.clientX - rect.left;
3423
+ const y = event.clientY - rect.top;
3424
+ const size = Math.max(rect.width, rect.height) * 2;
3425
+ const ripple = document.createElement("span");
3426
+ ripple.className = "v-ripple__wave";
3427
+ ripple.style.cssText = `
3428
+ position: absolute;
3429
+ border-radius: 50%;
3430
+ pointer-events: none;
3431
+ background-color: ${options.color};
3432
+ width: ${size}px;
3433
+ height: ${size}px;
3434
+ left: ${x - size / 2}px;
3435
+ top: ${y - size / 2}px;
3436
+ transform: scale(${options.initialScale});
3437
+ opacity: 0.3;
3438
+ z-index: 0;
3439
+ `;
3440
+ return ripple;
3441
+ }
3442
+ function animateRipple(ripple, options) {
3443
+ const duration = options.duration || 600;
3444
+ const initialScale = options.initialScale || 0;
3445
+ const finalScale = options.finalScale || 2;
3446
+ if (typeof ripple.animate === "function") {
3447
+ ripple.animate(
3448
+ [
3449
+ { transform: `scale(${initialScale})`, opacity: 0.3 },
3450
+ { transform: `scale(${finalScale})`, opacity: 0 }
3451
+ ],
3452
+ {
3453
+ duration,
3454
+ easing: "ease-out",
3455
+ fill: "forwards"
3456
+ }
3457
+ ).onfinish = () => {
3458
+ ripple.remove();
3459
+ };
3460
+ } else {
3461
+ ripple.style.transition = `transform ${duration}ms ease-out, opacity ${duration}ms ease-out`;
3462
+ String(ripple.offsetHeight);
3463
+ ripple.style.transform = `scale(${finalScale})`;
3464
+ ripple.style.opacity = "0";
3465
+ setTimeout(() => {
3466
+ ripple.remove();
3467
+ }, duration);
3468
+ }
3469
+ }
3470
+ const vRipple = defineDirective({
3471
+ name: "ripple",
3472
+ ssr: false,
3473
+ defaults: {
3474
+ color: "currentColor",
3475
+ duration: 600,
3476
+ disabled: false,
3477
+ initialScale: 0,
3478
+ finalScale: 2
3479
+ },
3480
+ mounted(el, binding) {
3481
+ const options = normalizeOptions$a(binding.value);
3482
+ if (options.disabled || !isBrowser()) return;
3483
+ const computedStyle = getComputedStyle(el);
3484
+ if (computedStyle.position === "static") {
3485
+ el.style.position = "relative";
3486
+ }
3487
+ if (computedStyle.overflow === "visible") {
3488
+ el.style.overflow = "hidden";
3489
+ }
3490
+ el.classList.add("v-ripple");
3491
+ const state = {
3492
+ options,
3493
+ clickHandler: (e) => {
3494
+ if (state.options.disabled) return;
3495
+ const mouseEvent = e;
3496
+ const ripple = createRipple(mouseEvent, el, state.options);
3497
+ if (ripple) {
3498
+ el.appendChild(ripple);
3499
+ animateRipple(ripple, state.options);
3500
+ }
3501
+ }
3502
+ };
3503
+ el.__ripple = state;
3504
+ on(el, "click", state.clickHandler);
3505
+ },
3506
+ updated(el, binding) {
3507
+ const state = el.__ripple;
3508
+ if (!state) return;
3509
+ state.options = normalizeOptions$a(binding.value);
3510
+ },
3511
+ unmounted(el) {
3512
+ const state = el.__ripple;
3513
+ if (!state) return;
3514
+ off(el, "click", state.clickHandler);
3515
+ el.classList.remove("v-ripple");
3516
+ delete el.__ripple;
3517
+ }
3518
+ });
3519
+ const DEFAULT_ALLOWED_TAGS = ["b", "i", "u", "strong", "em", "br", "p", "span", "div"];
3520
+ const DEFAULT_ALLOWED_ATTRIBUTES = ["title", "alt", "href", "src"];
3521
+ const DANGEROUS_TAGS = ["script", "iframe", "object", "embed", "form", "input", "style", "link", "meta", "base"];
3522
+ const DANGEROUS_ATTRIBUTES = ["onclick", "onerror", "onload", "onmouseover", "onfocus", "onblur", "onchange", "onsubmit"];
3523
+ function normalizeOptions$9(binding) {
3524
+ if (binding === false) {
3525
+ return { disabled: true };
3526
+ }
3527
+ if (binding === true) {
3528
+ return {
3529
+ allowedTags: DEFAULT_ALLOWED_TAGS,
3530
+ allowedAttributes: DEFAULT_ALLOWED_ATTRIBUTES
3531
+ };
3532
+ }
3533
+ return __spreadValues({
3534
+ allowedTags: DEFAULT_ALLOWED_TAGS,
3535
+ allowedAttributes: DEFAULT_ALLOWED_ATTRIBUTES,
3536
+ allowDataUrls: false,
3537
+ allowStyles: false,
3538
+ allowClass: false,
3539
+ allowId: false,
3540
+ disabled: false,
3541
+ sanitizeOnUpdate: true
3542
+ }, binding);
3543
+ }
3544
+ function sanitizeHtml(html, options) {
3545
+ var _a;
3546
+ if (options.handler) {
3547
+ return options.handler(html);
3548
+ }
3549
+ const temp = document.createElement("div");
3550
+ temp.innerHTML = html;
3551
+ for (const tag of DANGEROUS_TAGS) {
3552
+ const elements = temp.getElementsByTagName(tag);
3553
+ while (elements.length > 0) {
3554
+ (_a = elements[0].parentNode) == null ? void 0 : _a.removeChild(elements[0]);
3555
+ }
3556
+ }
3557
+ const processElement = (el) => {
3558
+ var _a2;
3559
+ const tagName = el.tagName.toLowerCase();
3560
+ if (options.allowedTags && !options.allowedTags.includes(tagName)) {
3561
+ const text = document.createTextNode(el.textContent || "");
3562
+ (_a2 = el.parentNode) == null ? void 0 : _a2.replaceChild(text, el);
3563
+ return;
3564
+ }
3565
+ for (const attr of DANGEROUS_ATTRIBUTES) {
3566
+ el.removeAttribute(attr);
3567
+ }
3568
+ const href = el.getAttribute("href");
3569
+ if (href && href.toLowerCase().startsWith("javascript:")) {
3570
+ el.removeAttribute("href");
3571
+ }
3572
+ if (!options.allowDataUrls) {
3573
+ const src = el.getAttribute("src");
3574
+ if (src && src.toLowerCase().startsWith("data:")) {
3575
+ el.removeAttribute("src");
3576
+ }
3577
+ }
3578
+ if (options.allowedAttributes) {
3579
+ const attrs = Array.from(el.attributes);
3580
+ for (const attr of attrs) {
3581
+ const isAllowed = options.allowedAttributes.includes(attr.name.toLowerCase());
3582
+ const isClass = attr.name === "class" && options.allowClass;
3583
+ const isId = attr.name === "id" && options.allowId;
3584
+ const isStyle = attr.name === "style" && options.allowStyles;
3585
+ if (!isAllowed && !isClass && !isId && !isStyle) {
3586
+ el.removeAttribute(attr.name);
3587
+ }
3588
+ }
3589
+ }
3590
+ for (const child of Array.from(el.children)) {
3591
+ processElement(child);
3592
+ }
3593
+ };
3594
+ for (const child of Array.from(temp.children)) {
3595
+ processElement(child);
3596
+ }
3597
+ return temp.innerHTML;
3598
+ }
3599
+ const vSanitize = defineDirective({
3600
+ name: "sanitize",
3601
+ ssr: true,
3602
+ defaults: {
3603
+ allowedTags: DEFAULT_ALLOWED_TAGS,
3604
+ allowedAttributes: DEFAULT_ALLOWED_ATTRIBUTES,
3605
+ allowDataUrls: false,
3606
+ allowStyles: false,
3607
+ allowClass: false,
3608
+ allowId: false,
3609
+ disabled: false,
3610
+ sanitizeOnUpdate: true
3611
+ },
3612
+ mounted(el, binding) {
3613
+ if (!isBrowser()) return;
3614
+ const options = normalizeOptions$9(binding.value);
3615
+ if (options.disabled) return;
3616
+ el.__sanitize = { options };
3617
+ const content = el.innerHTML;
3618
+ if (content) {
3619
+ el.innerHTML = sanitizeHtml(content, options);
3620
+ }
3621
+ },
3622
+ updated(el, binding) {
3623
+ const state = el.__sanitize;
3624
+ if (!state) return;
3625
+ state.options = normalizeOptions$9(binding.value);
3626
+ if (state.options.disabled || !state.options.sanitizeOnUpdate) return;
3627
+ const content = el.innerHTML;
3628
+ if (content) {
3629
+ el.innerHTML = sanitizeHtml(content, state.options);
3630
+ }
3631
+ },
3632
+ unmounted(el) {
3633
+ delete el.__sanitize;
3634
+ }
3635
+ });
3636
+ function getScrollInfo(container, lastScrollLeft, lastScrollTop) {
3637
+ let scrollLeft = 0, scrollTop = 0, scrollLeftMax = 0, scrollTopMax = 0;
3638
+ if (container === window) {
3639
+ scrollLeft = window.scrollX || document.documentElement.scrollLeft;
3640
+ scrollTop = window.scrollY || document.documentElement.scrollTop;
3641
+ scrollLeftMax = document.documentElement.scrollWidth - window.innerWidth;
3642
+ scrollTopMax = document.documentElement.scrollHeight - window.innerHeight;
3643
+ } else {
3644
+ const el = container;
3645
+ scrollLeft = el.scrollLeft;
3646
+ scrollTop = el.scrollTop;
3647
+ scrollLeftMax = el.scrollWidth - el.clientWidth;
3648
+ scrollTopMax = el.scrollHeight - el.clientHeight;
3649
+ }
3650
+ const progressX = scrollLeftMax > 0 ? scrollLeft / scrollLeftMax : 0;
3651
+ const progressY = scrollTopMax > 0 ? scrollTop / scrollTopMax : 0;
3652
+ const directionX = scrollLeft !== lastScrollLeft ? scrollLeft > lastScrollLeft ? 1 : -1 : 0;
3653
+ const directionY = scrollTop !== lastScrollTop ? scrollTop > lastScrollTop ? 1 : -1 : 0;
3654
+ return {
3655
+ scrollLeft,
3656
+ scrollTop,
3657
+ scrollLeftMax,
3658
+ scrollTopMax,
3659
+ progressX,
3660
+ progressY,
3661
+ directionX,
3662
+ directionY,
3663
+ container
3664
+ };
3665
+ }
3666
+ function normalizeOptions$8(binding) {
3667
+ if (typeof binding === "function") {
3668
+ return { handler: binding, passive: true };
3669
+ }
3670
+ if (!binding) {
3671
+ throw new Error("[Directix] v-scroll: handler is required");
3672
+ }
3673
+ return __spreadValues({
3674
+ passive: true,
3675
+ throttle: 0,
3676
+ disabled: false
3677
+ }, binding);
3678
+ }
3679
+ const vScroll = defineDirective({
3680
+ name: "scroll",
3681
+ ssr: false,
3682
+ defaults: {
3683
+ passive: true,
3684
+ throttle: 0,
3685
+ disabled: false
3686
+ },
3687
+ mounted(el, binding) {
3688
+ const options = normalizeOptions$8(binding.value);
3689
+ if (options.disabled || !isBrowser()) return;
3690
+ let container;
3691
+ if (options.container) {
3692
+ if (options.container === window) {
3693
+ container = window;
3694
+ } else if (typeof options.container === "string") {
3695
+ const found = document.querySelector(options.container);
3696
+ container = found || getScrollParent(el);
3697
+ } else {
3698
+ container = options.container;
3699
+ }
3700
+ } else {
3701
+ const { overflow, overflowX, overflowY } = getComputedStyle(el);
3702
+ const isSelfScrollable = /(auto|scroll)/.test(overflow + overflowX + overflowY);
3703
+ container = isSelfScrollable ? el : getScrollParent(el);
3704
+ }
3705
+ const state = {
3706
+ options,
3707
+ container,
3708
+ lastScrollLeft: 0,
3709
+ lastScrollTop: 0,
3710
+ throttleTimer: null,
3711
+ pendingEvent: null,
3712
+ scrollHandler: (e) => {
3713
+ if (options.throttle && options.throttle > 0) {
3714
+ state.pendingEvent = e;
3715
+ if (!state.throttleTimer) {
3716
+ state.throttleTimer = setTimeout(() => {
3717
+ if (state.pendingEvent) {
3718
+ const info = getScrollInfo(container, state.lastScrollLeft, state.lastScrollTop);
3719
+ state.lastScrollLeft = info.scrollLeft;
3720
+ state.lastScrollTop = info.scrollTop;
3721
+ options.handler(state.pendingEvent, info);
3722
+ }
3723
+ state.throttleTimer = null;
3724
+ state.pendingEvent = null;
3725
+ }, options.throttle);
3726
+ }
3727
+ } else {
3728
+ const info = getScrollInfo(container, state.lastScrollLeft, state.lastScrollTop);
3729
+ state.lastScrollLeft = info.scrollLeft;
3730
+ state.lastScrollTop = info.scrollTop;
3731
+ options.handler(e, info);
3732
+ }
3733
+ }
3734
+ };
3735
+ const initialInfo = getScrollInfo(container, 0, 0);
3736
+ state.lastScrollLeft = initialInfo.scrollLeft;
3737
+ state.lastScrollTop = initialInfo.scrollTop;
3738
+ el.__scroll = state;
3739
+ on(container, "scroll", state.scrollHandler, { passive: options.passive });
3740
+ },
3741
+ updated(el, binding) {
3742
+ const state = el.__scroll;
3743
+ if (!state) return;
3744
+ state.options = normalizeOptions$8(binding.value);
3745
+ },
3746
+ unmounted(el) {
3747
+ const state = el.__scroll;
3748
+ if (!state) return;
3749
+ if (state.throttleTimer) {
3750
+ clearTimeout(state.throttleTimer);
3751
+ }
3752
+ off(state.container, "scroll", state.scrollHandler);
3753
+ delete el.__scroll;
3754
+ }
3755
+ });
3756
+ const STATE_KEY = "__sticky";
3757
+ function normalizeOptions$7(binding) {
3758
+ if (binding === false) return { disabled: true, top: 0, zIndex: 100 };
3759
+ if (typeof binding === "number") return { top: binding, zIndex: 100 };
3760
+ return __spreadValues({
3761
+ top: 0,
3762
+ zIndex: 100,
3763
+ stickyClass: "v-sticky--fixed",
3764
+ disabled: false
3765
+ }, binding && typeof binding === "object" ? binding : {});
3766
+ }
3767
+ function parseOffset(value) {
3768
+ if (value === void 0) return "0";
3769
+ return typeof value === "number" ? `${value}px` : value;
3770
+ }
3771
+ function getScrollContainer(el, customContainer) {
3772
+ if (customContainer) {
3773
+ if (typeof customContainer === "string") {
3774
+ return document.querySelector(customContainer) || getScrollParent(el);
3775
+ }
3776
+ return customContainer;
3777
+ }
3778
+ const parent = el.parentElement;
3779
+ if (parent) {
3780
+ const { overflow, overflowX, overflowY } = getComputedStyle(parent);
3781
+ if (/(auto|scroll)/.test(overflow + overflowX + overflowY)) {
3782
+ return parent;
3783
+ }
3784
+ }
3785
+ return getScrollParent(el);
3786
+ }
3787
+ function checkSticky(el, state) {
3788
+ if (state.options.disabled) {
3789
+ unsetSticky(el, state);
3790
+ return;
3791
+ }
3792
+ const topOffset = parseFloat(parseOffset(state.options.top));
3793
+ const containerRect = state.container === window ? { top: 0 } : state.container.getBoundingClientRect();
3794
+ const referenceEl = state.placeholder || el;
3795
+ const rect = referenceEl.getBoundingClientRect();
3796
+ const elementTopRelativeToContainer = rect.top - containerRect.top;
3797
+ const shouldSticky = elementTopRelativeToContainer <= topOffset;
3798
+ if (shouldSticky && !state.isSticky) {
3799
+ setSticky(el, state, topOffset, containerRect.top);
3800
+ } else if (!shouldSticky && state.isSticky) {
3801
+ unsetSticky(el, state);
3802
+ }
3803
+ }
3804
+ function setSticky(el, state, topOffset, containerTop) {
3805
+ var _a, _b, _c;
3806
+ state.isSticky = true;
3807
+ const placeholder = document.createElement("div");
3808
+ placeholder.style.cssText = `width:${el.offsetWidth}px;height:${el.offsetHeight}px`;
3809
+ (_a = el.parentNode) == null ? void 0 : _a.insertBefore(placeholder, el);
3810
+ state.placeholder = placeholder;
3811
+ const fixedTop = state.container === window ? topOffset : containerTop + topOffset;
3812
+ el.style.position = "fixed";
3813
+ el.style.top = `${fixedTop}px`;
3814
+ el.style.zIndex = String(state.options.zIndex || 100);
3815
+ el.style.width = `${el.offsetWidth}px`;
3816
+ if (state.options.bottom !== void 0) {
3817
+ el.style.bottom = parseOffset(state.options.bottom);
3818
+ }
3819
+ state.options.stickyClass && el.classList.add(state.options.stickyClass);
3820
+ el.dispatchEvent(new CustomEvent("sticky:change", { detail: { isSticky: true } }));
3821
+ (_c = (_b = state.options).onChange) == null ? void 0 : _c.call(_b, true);
3822
+ }
3823
+ function unsetSticky(el, state) {
3824
+ var _a, _b, _c, _d;
3825
+ if (!state.isSticky) return;
3826
+ state.isSticky = false;
3827
+ (_b = (_a = state.placeholder) == null ? void 0 : _a.parentNode) == null ? void 0 : _b.removeChild(state.placeholder);
3828
+ state.placeholder = null;
3829
+ Object.assign(el.style, state.originalStyles);
3830
+ state.options.stickyClass && el.classList.remove(state.options.stickyClass);
3831
+ el.dispatchEvent(new CustomEvent("sticky:change", { detail: { isSticky: false } }));
3832
+ (_d = (_c = state.options).onChange) == null ? void 0 : _d.call(_c, false);
3833
+ }
3834
+ const vSticky = defineDirective({
3835
+ name: "sticky",
3836
+ ssr: false,
3837
+ defaults: { top: 0, zIndex: 100, stickyClass: "v-sticky--fixed", disabled: false },
3838
+ mounted(el, binding) {
3839
+ const options = normalizeOptions$7(binding.value);
3840
+ if (options.disabled || !isBrowser()) return;
3841
+ const container = getScrollContainer(el, options.container);
3842
+ const state = {
3843
+ options,
3844
+ placeholder: null,
3845
+ originalStyles: {
3846
+ position: el.style.position,
3847
+ top: el.style.top,
3848
+ bottom: el.style.bottom,
3849
+ zIndex: el.style.zIndex,
3850
+ width: el.style.width
3851
+ },
3852
+ isSticky: false,
3853
+ container,
3854
+ scrollHandler: () => checkSticky(el, state),
3855
+ resizeHandler: () => checkSticky(el, state)
3856
+ };
3857
+ el.classList.add("v-sticky");
3858
+ el[STATE_KEY] = state;
3859
+ on(container, "scroll", state.scrollHandler, { passive: true });
3860
+ on(window, "resize", state.resizeHandler, { passive: true });
3861
+ checkSticky(el, state);
3862
+ },
3863
+ updated(el, binding) {
3864
+ const state = el[STATE_KEY];
3865
+ if (!state) return;
3866
+ state.options = normalizeOptions$7(binding.value);
3867
+ checkSticky(el, state);
3868
+ },
3869
+ unmounted(el) {
3870
+ var _a, _b;
3871
+ const state = el[STATE_KEY];
3872
+ if (!state) return;
3873
+ (_b = (_a = state.placeholder) == null ? void 0 : _a.parentNode) == null ? void 0 : _b.removeChild(state.placeholder);
3874
+ Object.assign(el.style, state.originalStyles);
3875
+ el.classList.remove("v-sticky", state.options.stickyClass || "v-sticky--fixed");
3876
+ off(state.container, "scroll", state.scrollHandler);
3877
+ off(window, "resize", state.resizeHandler);
3878
+ delete el[STATE_KEY];
3879
+ }
3880
+ });
3881
+ function normalizeOptions$6(binding, directiveBinding) {
3882
+ const wait = parseTime(directiveBinding.arg) || 300;
3883
+ if (typeof binding === "function") {
3884
+ return { handler: binding, wait };
3885
+ }
3886
+ return __spreadProps(__spreadValues({}, binding), { wait: binding.wait || wait });
3887
+ }
3888
+ const vThrottle = defineDirective({
3889
+ name: "throttle",
3890
+ ssr: true,
3891
+ // SSR safe - event binding is skipped on server
3892
+ defaults: {
3893
+ wait: 300,
3894
+ leading: true,
3895
+ trailing: true
3896
+ },
3897
+ mounted(el, binding) {
3898
+ const options = normalizeOptions$6(binding.value, binding);
3899
+ const eventType = getEventTypeFromModifiers(binding.modifiers) || getDefaultEventType(el);
3900
+ const throttledFn = throttle(options.handler, options.wait, {
3901
+ leading: options.leading,
3902
+ trailing: options.trailing
3903
+ });
3904
+ el.addEventListener(eventType, throttledFn);
3905
+ el.__throttle = {
3906
+ throttledFn,
3907
+ eventType,
3908
+ options
3909
+ };
3910
+ },
3911
+ updated(el, binding) {
3912
+ const state = el.__throttle;
3913
+ if (!state) return;
3914
+ const newOptions = normalizeOptions$6(binding.value, binding);
3915
+ if (newOptions.wait !== state.options.wait || newOptions.leading !== state.options.leading || newOptions.trailing !== state.options.trailing) {
3916
+ state.throttledFn.cancel();
3917
+ const throttledFn = throttle(newOptions.handler, newOptions.wait, {
3918
+ leading: newOptions.leading,
3919
+ trailing: newOptions.trailing
3920
+ });
3921
+ el.removeEventListener(state.eventType, state.throttledFn);
3922
+ el.addEventListener(state.eventType, throttledFn);
3923
+ el.__throttle = {
3924
+ throttledFn,
3925
+ eventType: state.eventType,
3926
+ options: newOptions
3927
+ };
3928
+ } else if (newOptions.handler !== state.options.handler) {
3929
+ state.options.handler = newOptions.handler;
3930
+ }
3931
+ },
3932
+ unmounted(el) {
3933
+ const state = el.__throttle;
3934
+ if (!state) return;
3935
+ state.throttledFn.cancel();
3936
+ el.removeEventListener(state.eventType, state.throttledFn);
3937
+ delete el.__throttle;
3938
+ }
3939
+ });
3940
+ const TOOLTIP_STYLES = {
3941
+ padding: "8px 12px",
3942
+ background: "#333",
3943
+ color: "#fff",
3944
+ borderRadius: "6px",
3945
+ fontSize: "14px",
3946
+ lineHeight: "1.5",
3947
+ minWidth: "96px",
3948
+ maxWidth: "320px",
3949
+ boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)"
3950
+ };
3951
+ let tooltipContainer = null;
3952
+ function getTooltipContainer() {
3953
+ if (!tooltipContainer && typeof document !== "undefined") {
3954
+ tooltipContainer = document.createElement("div");
3955
+ tooltipContainer.id = "directix-tooltip-container";
3956
+ tooltipContainer.style.cssText = "position: fixed; top: 0; left: 0; pointer-events: none; z-index: 9999;";
3957
+ document.body.appendChild(tooltipContainer);
3958
+ }
3959
+ return tooltipContainer;
3960
+ }
3961
+ function createTooltip(options) {
3962
+ const tooltip = document.createElement("div");
3963
+ tooltip.className = `v-tooltip v-tooltip--${options.placement || "top"}`;
3964
+ if (options.class) tooltip.classList.add(options.class);
3965
+ const maxWidth = options.maxWidth ? typeof options.maxWidth === "number" ? `${options.maxWidth}px` : options.maxWidth : TOOLTIP_STYLES.maxWidth;
3966
+ tooltip.style.cssText = [
3967
+ "position: absolute",
3968
+ `padding: ${TOOLTIP_STYLES.padding}`,
3969
+ `background: ${TOOLTIP_STYLES.background}`,
3970
+ `color: ${TOOLTIP_STYLES.color}`,
3971
+ `border-radius: ${TOOLTIP_STYLES.borderRadius}`,
3972
+ `font-size: ${TOOLTIP_STYLES.fontSize}`,
3973
+ `line-height: ${TOOLTIP_STYLES.lineHeight}`,
3974
+ `min-width: ${TOOLTIP_STYLES.minWidth}`,
3975
+ `max-width: ${maxWidth}`,
3976
+ "word-wrap: break-word",
3977
+ `box-shadow: ${TOOLTIP_STYLES.boxShadow}`,
3978
+ "pointer-events: none",
3979
+ "opacity: 0",
3980
+ "transition: opacity 0.2s ease",
3981
+ `z-index: ${options.zIndex || 9999}`
3982
+ ].join(";");
3983
+ if (options.arrow !== false) {
3984
+ const arrow = document.createElement("div");
3985
+ arrow.className = "v-tooltip__arrow";
3986
+ arrow.style.cssText = "position: absolute; width: 8px; height: 8px; background: #333; transform: rotate(45deg);";
3987
+ tooltip.appendChild(arrow);
3988
+ }
3989
+ const content = document.createElement("div");
3990
+ content.className = "v-tooltip__content";
3991
+ content.textContent = options.content;
3992
+ tooltip.appendChild(content);
3993
+ return tooltip;
3994
+ }
3995
+ function positionTooltip(tooltip, el, placement, offset) {
3996
+ const elRect = el.getBoundingClientRect();
3997
+ const tooltipRect = tooltip.getBoundingClientRect();
3998
+ let top = 0, left = 0;
3999
+ switch (placement) {
4000
+ case "top":
4001
+ top = elRect.top - tooltipRect.height - offset;
4002
+ left = elRect.left + (elRect.width - tooltipRect.width) / 2;
4003
+ break;
4004
+ case "bottom":
4005
+ top = elRect.bottom + offset;
4006
+ left = elRect.left + (elRect.width - tooltipRect.width) / 2;
4007
+ break;
4008
+ case "left":
4009
+ top = elRect.top + (elRect.height - tooltipRect.height) / 2;
4010
+ left = elRect.left - tooltipRect.width - offset;
4011
+ break;
4012
+ case "right":
4013
+ top = elRect.top + (elRect.height - tooltipRect.height) / 2;
4014
+ left = elRect.right + offset;
4015
+ break;
4016
+ }
4017
+ const viewportWidth = window.innerWidth;
4018
+ const viewportHeight = window.innerHeight;
4019
+ if (left < 0) left = 8;
4020
+ if (left + tooltipRect.width > viewportWidth) left = viewportWidth - tooltipRect.width - 8;
4021
+ if (top < 0) top = 8;
4022
+ if (top + tooltipRect.height > viewportHeight) top = viewportHeight - tooltipRect.height - 8;
4023
+ tooltip.style.top = `${top}px`;
4024
+ tooltip.style.left = `${left}px`;
4025
+ const arrow = tooltip.querySelector(".v-tooltip__arrow");
4026
+ if (arrow) {
4027
+ const halfArrow = 4;
4028
+ switch (placement) {
4029
+ case "top":
4030
+ Object.assign(arrow.style, { bottom: `-${halfArrow}px`, left: "50%", transform: "translateX(-50%) rotate(45deg)" });
4031
+ break;
4032
+ case "bottom":
4033
+ Object.assign(arrow.style, { top: `-${halfArrow}px`, left: "50%", transform: "translateX(-50%) rotate(45deg)" });
4034
+ break;
4035
+ case "left":
4036
+ Object.assign(arrow.style, { right: `-${halfArrow}px`, top: "50%", transform: "translateY(-50%) rotate(45deg)" });
4037
+ break;
4038
+ case "right":
4039
+ Object.assign(arrow.style, { left: `-${halfArrow}px`, top: "50%", transform: "translateY(-50%) rotate(45deg)" });
4040
+ break;
4041
+ }
4042
+ }
4043
+ }
4044
+ function showTooltip(el, state) {
4045
+ if (state.isVisible || state.options.disabled) return;
4046
+ if (state.hideTimeout) {
4047
+ clearTimeout(state.hideTimeout);
4048
+ state.hideTimeout = null;
4049
+ }
4050
+ const doShow = () => {
4051
+ var _a, _b;
4052
+ const tooltip = createTooltip(state.options);
4053
+ state.tooltip = tooltip;
4054
+ getTooltipContainer().appendChild(tooltip);
4055
+ requestAnimationFrame(() => {
4056
+ positionTooltip(tooltip, el, state.options.placement || "top", state.options.offset || 8);
4057
+ requestAnimationFrame(() => {
4058
+ tooltip.style.opacity = "1";
4059
+ });
4060
+ });
4061
+ state.isVisible = true;
4062
+ (_b = (_a = state.options).onShow) == null ? void 0 : _b.call(_a);
4063
+ };
4064
+ if (state.options.delay && state.options.delay > 0) {
4065
+ state.showTimeout = setTimeout(doShow, state.options.delay);
4066
+ } else {
4067
+ doShow();
4068
+ }
4069
+ }
4070
+ function hideTooltip(state) {
4071
+ if (!state.isVisible) return;
4072
+ if (state.showTimeout) {
4073
+ clearTimeout(state.showTimeout);
4074
+ state.showTimeout = null;
4075
+ }
4076
+ const doHide = () => {
4077
+ var _a, _b;
4078
+ if (state.tooltip) {
4079
+ state.tooltip.style.opacity = "0";
4080
+ setTimeout(() => {
4081
+ var _a2;
4082
+ (_a2 = state.tooltip) == null ? void 0 : _a2.remove();
4083
+ state.tooltip = null;
4084
+ }, 200);
4085
+ }
4086
+ state.isVisible = false;
4087
+ (_b = (_a = state.options).onHide) == null ? void 0 : _b.call(_a);
4088
+ };
4089
+ if (state.options.hideDelay && state.options.hideDelay > 0) {
4090
+ state.hideTimeout = setTimeout(doHide, state.options.hideDelay);
4091
+ } else {
4092
+ doHide();
4093
+ }
4094
+ }
4095
+ function setupTriggerHandlers(el, state) {
4096
+ const { trigger = "hover" } = state.options;
4097
+ const show = () => showTooltip(el, state);
4098
+ const hide = () => hideTooltip(state);
4099
+ const toggle = () => state.isVisible ? hide() : show();
4100
+ state.handlers = { show, hide, toggle };
4101
+ switch (trigger) {
4102
+ case "hover":
4103
+ el.addEventListener("mouseenter", show);
4104
+ el.addEventListener("mouseleave", hide);
4105
+ break;
4106
+ case "click":
4107
+ el.addEventListener("click", toggle);
4108
+ document.addEventListener("click", state.handlers.docHide = (e) => {
4109
+ if (state.isVisible && !el.contains(e.target)) hide();
4110
+ });
4111
+ break;
4112
+ case "focus":
4113
+ el.addEventListener("focus", show);
4114
+ el.addEventListener("blur", hide);
4115
+ break;
4116
+ }
4117
+ }
4118
+ function removeTriggerHandlers(el, state) {
4119
+ const { show, hide, toggle, docHide } = state.handlers;
4120
+ if (show) {
4121
+ el.removeEventListener("mouseenter", show);
4122
+ el.removeEventListener("focus", show);
4123
+ }
4124
+ if (hide) {
4125
+ el.removeEventListener("mouseleave", hide);
4126
+ el.removeEventListener("blur", hide);
4127
+ }
4128
+ if (toggle) {
4129
+ el.removeEventListener("click", toggle);
4130
+ }
4131
+ if (docHide) {
4132
+ document.removeEventListener("click", docHide);
4133
+ }
4134
+ }
4135
+ function normalizeOptions$5(binding) {
4136
+ var _a, _b, _c, _d, _e, _f, _g, _h;
4137
+ if (typeof binding === "string") {
4138
+ return { content: binding, placement: "top", trigger: "hover" };
4139
+ }
4140
+ if (!binding) {
4141
+ return { content: "", placement: "top", trigger: "hover" };
4142
+ }
4143
+ return {
4144
+ content: binding.content,
4145
+ placement: (_a = binding.placement) != null ? _a : "top",
4146
+ trigger: (_b = binding.trigger) != null ? _b : "hover",
4147
+ delay: (_c = binding.delay) != null ? _c : 0,
4148
+ hideDelay: (_d = binding.hideDelay) != null ? _d : 0,
4149
+ offset: (_e = binding.offset) != null ? _e : 8,
4150
+ class: binding.class,
4151
+ arrow: (_f = binding.arrow) != null ? _f : true,
4152
+ disabled: (_g = binding.disabled) != null ? _g : false,
4153
+ maxWidth: binding.maxWidth,
4154
+ zIndex: (_h = binding.zIndex) != null ? _h : 9999,
4155
+ onShow: binding.onShow,
4156
+ onHide: binding.onHide
4157
+ };
4158
+ }
4159
+ function createState(options) {
4160
+ return {
4161
+ options,
4162
+ tooltip: null,
4163
+ showTimeout: null,
4164
+ hideTimeout: null,
4165
+ isVisible: false,
4166
+ handlers: {}
4167
+ };
4168
+ }
4169
+ const vTooltip = defineDirective({
4170
+ name: "tooltip",
4171
+ ssr: false,
4172
+ mounted(el, binding) {
4173
+ const options = normalizeOptions$5(binding.value);
4174
+ if (options.disabled || !options.content) return;
4175
+ const state = createState(options);
4176
+ el.__tooltip = state;
4177
+ setupTriggerHandlers(el, state);
4178
+ el.setAttribute("aria-describedby", "v-tooltip");
4179
+ },
4180
+ updated(el, binding) {
4181
+ const state = el.__tooltip;
4182
+ const newOptions = normalizeOptions$5(binding.value);
4183
+ if (!state) {
4184
+ if (!newOptions.disabled && newOptions.content) {
4185
+ const newState = createState(newOptions);
4186
+ el.__tooltip = newState;
4187
+ setupTriggerHandlers(el, newState);
4188
+ if (newOptions.trigger === "manual") {
4189
+ showTooltip(el, newState);
4190
+ }
4191
+ }
4192
+ return;
4193
+ }
4194
+ if (newOptions.trigger === "manual") {
4195
+ const oldDisabled = state.options.disabled;
4196
+ state.options = newOptions;
4197
+ if (newOptions.disabled && !oldDisabled) {
4198
+ hideTooltip(state);
4199
+ } else if (!newOptions.disabled && oldDisabled) {
4200
+ showTooltip(el, state);
4201
+ }
4202
+ return;
4203
+ }
4204
+ if (state.tooltip && state.isVisible) {
4205
+ const content = state.tooltip.querySelector(".v-tooltip__content");
4206
+ if (content) content.textContent = newOptions.content;
4207
+ }
4208
+ state.options = newOptions;
4209
+ },
4210
+ unmounted(el) {
4211
+ var _a;
4212
+ const state = el.__tooltip;
4213
+ if (!state) return;
4214
+ if (state.showTimeout) clearTimeout(state.showTimeout);
4215
+ if (state.hideTimeout) clearTimeout(state.hideTimeout);
4216
+ (_a = state.tooltip) == null ? void 0 : _a.remove();
4217
+ removeTriggerHandlers(el, state);
4218
+ delete el.__tooltip;
4219
+ }
4220
+ });
4221
+ const getDistance = (x1, y1, x2, y2) => Math.sqrt(__pow(x2 - x1, 2) + __pow(y2 - y1, 2));
4222
+ const getAngle = (x1, y1, x2, y2) => Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI;
4223
+ const MOUSE_IGNORE_DURATION = 400;
4224
+ const vTouch = defineDirective({
4225
+ name: "touch",
4226
+ ssr: false,
4227
+ mounted(el, binding) {
4228
+ const options = normalizeOptions$4(binding.value);
4229
+ const state = {
4230
+ options,
4231
+ startX: 0,
4232
+ startY: 0,
4233
+ startTime: 0,
4234
+ startDistance: 0,
4235
+ startAngle: 0,
4236
+ lastScale: 1,
4237
+ lastAngle: 0,
4238
+ longPressTimer: null,
4239
+ isLongPress: false,
4240
+ isMouseDown: false,
4241
+ lastTouchEndTime: 0,
4242
+ handlers: { touchStart: () => {
4243
+ }, touchMove: () => {
4244
+ }, touchEnd: () => {
4245
+ } }
4246
+ };
4247
+ el.__touch = state;
4248
+ const clearLongPressTimer = () => {
4249
+ if (state.longPressTimer) {
4250
+ clearTimeout(state.longPressTimer);
4251
+ state.longPressTimer = null;
4252
+ }
4253
+ };
4254
+ const startLongPressTimer = (event) => {
4255
+ clearLongPressTimer();
4256
+ if (state.options.enableLongPress && state.options.onLongPress) {
4257
+ state.longPressTimer = setTimeout(() => {
4258
+ state.isLongPress = true;
4259
+ state.options.onLongPress(event);
4260
+ }, state.options.longPressTimeout || 500);
4261
+ }
4262
+ };
4263
+ const exceedsThreshold = (x, y) => {
4264
+ const threshold = state.options.tapThreshold || 10;
4265
+ return Math.abs(x - state.startX) > threshold || Math.abs(y - state.startY) > threshold;
4266
+ };
4267
+ const handleGestureEnd = (endX, endY, event) => {
4268
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
4269
+ if (state.isLongPress) return;
4270
+ const duration = Date.now() - state.startTime;
4271
+ const deltaX = endX - state.startX;
4272
+ const deltaY = endY - state.startY;
4273
+ const distance = Math.sqrt(__pow(deltaX, 2) + __pow(deltaY, 2));
4274
+ if (state.options.enableSwipe && distance >= (state.options.swipeThreshold || 30) && duration <= (state.options.swipeTimeout || 500)) {
4275
+ const direction = Math.abs(deltaX) > Math.abs(deltaY) ? deltaX > 0 ? "right" : "left" : deltaY > 0 ? "down" : "up";
4276
+ (_b = (_a = state.options).onSwipe) == null ? void 0 : _b.call(_a, direction, event);
4277
+ if (direction === "left") (_d = (_c = state.options).onSwipeLeft) == null ? void 0 : _d.call(_c, event);
4278
+ else if (direction === "right") (_f = (_e = state.options).onSwipeRight) == null ? void 0 : _f.call(_e, event);
4279
+ else if (direction === "up") (_h = (_g = state.options).onSwipeUp) == null ? void 0 : _h.call(_g, event);
4280
+ else (_j = (_i = state.options).onSwipeDown) == null ? void 0 : _j.call(_i, event);
4281
+ } else if (state.options.enableTap && distance < (state.options.tapThreshold || 10) && duration < (state.options.tapTimeout || 250)) {
4282
+ (_l = (_k = state.options).onTap) == null ? void 0 : _l.call(_k, event);
4283
+ }
4284
+ };
4285
+ const handleTouchStart = (e) => {
4286
+ var _a, _b;
4287
+ if (e.touches.length > 1) {
4288
+ e.preventDefault();
4289
+ }
4290
+ state.startTime = Date.now();
4291
+ state.isLongPress = false;
4292
+ if (e.touches.length === 1) {
4293
+ state.startX = e.touches[0].clientX;
4294
+ state.startY = e.touches[0].clientY;
4295
+ startLongPressTimer(e);
4296
+ } else if (e.touches.length === 2) {
4297
+ clearLongPressTimer();
4298
+ const [t1, t2] = e.touches;
4299
+ state.startDistance = getDistance(t1.clientX, t1.clientY, t2.clientX, t2.clientY);
4300
+ state.startAngle = getAngle(t1.clientX, t1.clientY, t2.clientX, t2.clientY);
4301
+ state.lastScale = 1;
4302
+ state.lastAngle = 0;
4303
+ }
4304
+ (_b = (_a = state.options).onTouchStart) == null ? void 0 : _b.call(_a, e);
4305
+ };
4306
+ const handleTouchMove = (e) => {
4307
+ var _a, _b;
4308
+ if (e.touches.length >= 1) {
4309
+ e.preventDefault();
4310
+ }
4311
+ if (state.longPressTimer && e.touches.length === 1 && exceedsThreshold(e.touches[0].clientX, e.touches[0].clientY)) {
4312
+ clearLongPressTimer();
4313
+ }
4314
+ if (e.touches.length === 2) {
4315
+ const [t1, t2] = e.touches;
4316
+ const currentDistance = getDistance(t1.clientX, t1.clientY, t2.clientX, t2.clientY);
4317
+ const currentAngle = getAngle(t1.clientX, t1.clientY, t2.clientX, t2.clientY);
4318
+ if (state.options.enablePinch && state.options.onPinch) {
4319
+ const scale = currentDistance / state.startDistance;
4320
+ if (Math.abs(scale - state.lastScale) >= (state.options.pinchThreshold || 0.1)) {
4321
+ state.options.onPinch(scale, e);
4322
+ state.lastScale = scale;
4323
+ }
4324
+ }
4325
+ if (state.options.enableRotate && state.options.onRotate) {
4326
+ const angleDiff = currentAngle - state.startAngle;
4327
+ if (Math.abs(angleDiff - state.lastAngle) > 5) {
4328
+ state.options.onRotate(angleDiff, e);
4329
+ state.lastAngle = angleDiff;
4330
+ }
4331
+ }
4332
+ }
4333
+ (_b = (_a = state.options).onTouchMove) == null ? void 0 : _b.call(_a, e);
4334
+ };
4335
+ const handleTouchEnd = (e) => {
4336
+ var _a, _b;
4337
+ clearLongPressTimer();
4338
+ if (e.touches.length === 0) {
4339
+ state.lastTouchEndTime = Date.now();
4340
+ const touch = e.changedTouches[0];
4341
+ handleGestureEnd(touch.clientX, touch.clientY, e);
4342
+ }
4343
+ (_b = (_a = state.options).onTouchEnd) == null ? void 0 : _b.call(_a, e);
4344
+ };
4345
+ const handleMouseDown = (e) => {
4346
+ var _a, _b;
4347
+ if (!state.options.enableMouse) return;
4348
+ if (Date.now() - state.lastTouchEndTime < MOUSE_IGNORE_DURATION) return;
4349
+ e.preventDefault();
4350
+ state.isMouseDown = true;
4351
+ state.startTime = Date.now();
4352
+ state.startX = e.clientX;
4353
+ state.startY = e.clientY;
4354
+ state.isLongPress = false;
4355
+ startLongPressTimer(e);
4356
+ (_b = (_a = state.options).onTouchStart) == null ? void 0 : _b.call(_a, e);
4357
+ };
4358
+ const handleMouseMove = (e) => {
4359
+ var _a, _b;
4360
+ if (!state.isMouseDown || !state.options.enableMouse) return;
4361
+ if (state.longPressTimer && exceedsThreshold(e.clientX, e.clientY)) {
4362
+ clearLongPressTimer();
4363
+ }
4364
+ (_b = (_a = state.options).onTouchMove) == null ? void 0 : _b.call(_a, e);
4365
+ };
4366
+ const handleMouseUp = (e) => {
4367
+ var _a, _b;
4368
+ if (!state.isMouseDown || !state.options.enableMouse) return;
4369
+ state.isMouseDown = false;
4370
+ clearLongPressTimer();
4371
+ if (!state.isLongPress) {
4372
+ handleGestureEnd(e.clientX, e.clientY, e);
4373
+ }
4374
+ (_b = (_a = state.options).onTouchEnd) == null ? void 0 : _b.call(_a, e);
4375
+ };
4376
+ state.handlers = { touchStart: handleTouchStart, touchMove: handleTouchMove, touchEnd: handleTouchEnd, mouseDown: handleMouseDown, mouseMove: handleMouseMove, mouseUp: handleMouseUp };
4377
+ el.addEventListener("touchstart", handleTouchStart, { passive: false });
4378
+ el.addEventListener("touchmove", handleTouchMove, { passive: false });
4379
+ el.addEventListener("touchend", handleTouchEnd);
4380
+ el.addEventListener("touchcancel", handleTouchEnd);
4381
+ if (options.enableMouse) {
4382
+ el.addEventListener("mousedown", handleMouseDown);
4383
+ document.addEventListener("mousemove", handleMouseMove);
4384
+ document.addEventListener("mouseup", handleMouseUp);
4385
+ }
4386
+ },
4387
+ updated(el, binding) {
4388
+ const state = el.__touch;
4389
+ if (state) state.options = normalizeOptions$4(binding.value);
4390
+ },
4391
+ unmounted(el) {
4392
+ const state = el.__touch;
4393
+ if (state == null ? void 0 : state.longPressTimer) clearTimeout(state.longPressTimer);
4394
+ if (state == null ? void 0 : state.handlers) {
4395
+ el.removeEventListener("touchstart", state.handlers.touchStart);
4396
+ el.removeEventListener("touchmove", state.handlers.touchMove);
4397
+ el.removeEventListener("touchend", state.handlers.touchEnd);
4398
+ el.removeEventListener("touchcancel", state.handlers.touchEnd);
4399
+ if (state.handlers.mouseDown) el.removeEventListener("mousedown", state.handlers.mouseDown);
4400
+ if (state.handlers.mouseMove) document.removeEventListener("mousemove", state.handlers.mouseMove);
4401
+ if (state.handlers.mouseUp) document.removeEventListener("mouseup", state.handlers.mouseUp);
4402
+ }
4403
+ delete el.__touch;
4404
+ }
4405
+ });
4406
+ function normalizeOptions$4(binding) {
4407
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
4408
+ return {
4409
+ swipeThreshold: (_a = binding == null ? void 0 : binding.swipeThreshold) != null ? _a : 30,
4410
+ swipeTimeout: (_b = binding == null ? void 0 : binding.swipeTimeout) != null ? _b : 500,
4411
+ pinchThreshold: (_c = binding == null ? void 0 : binding.pinchThreshold) != null ? _c : 0.1,
4412
+ enableSwipe: (_d = binding == null ? void 0 : binding.enableSwipe) != null ? _d : true,
4413
+ enablePinch: (_e = binding == null ? void 0 : binding.enablePinch) != null ? _e : true,
4414
+ enableRotate: (_f = binding == null ? void 0 : binding.enableRotate) != null ? _f : true,
4415
+ enableTap: (_g = binding == null ? void 0 : binding.enableTap) != null ? _g : true,
4416
+ tapTimeout: (_h = binding == null ? void 0 : binding.tapTimeout) != null ? _h : 250,
4417
+ tapThreshold: (_i = binding == null ? void 0 : binding.tapThreshold) != null ? _i : 10,
4418
+ enableLongPress: (_j = binding == null ? void 0 : binding.enableLongPress) != null ? _j : true,
4419
+ longPressTimeout: (_k = binding == null ? void 0 : binding.longPressTimeout) != null ? _k : 500,
4420
+ enableMouse: (_l = binding == null ? void 0 : binding.enableMouse) != null ? _l : true,
4421
+ onSwipe: binding == null ? void 0 : binding.onSwipe,
4422
+ onSwipeLeft: binding == null ? void 0 : binding.onSwipeLeft,
4423
+ onSwipeRight: binding == null ? void 0 : binding.onSwipeRight,
4424
+ onSwipeUp: binding == null ? void 0 : binding.onSwipeUp,
4425
+ onSwipeDown: binding == null ? void 0 : binding.onSwipeDown,
4426
+ onPinch: binding == null ? void 0 : binding.onPinch,
4427
+ onRotate: binding == null ? void 0 : binding.onRotate,
4428
+ onTap: binding == null ? void 0 : binding.onTap,
4429
+ onLongPress: binding == null ? void 0 : binding.onLongPress,
4430
+ onTouchStart: binding == null ? void 0 : binding.onTouchStart,
4431
+ onTouchMove: binding == null ? void 0 : binding.onTouchMove,
4432
+ onTouchEnd: binding == null ? void 0 : binding.onTouchEnd
4433
+ };
4434
+ }
4435
+ function trimText(text, options) {
4436
+ const { position = "both", chars } = options;
4437
+ const charPattern = chars ? `[\\s${escapeRegex(chars)}]` : "\\s";
4438
+ switch (position) {
4439
+ case "start":
4440
+ return text.replace(new RegExp(`^${charPattern}+`, "g"), "");
4441
+ case "end":
4442
+ return text.replace(new RegExp(`${charPattern}+$`, "g"), "");
4443
+ case "both":
4444
+ default:
4445
+ return text.replace(new RegExp(`^${charPattern}+|${charPattern}+$`, "g"), "");
4446
+ }
4447
+ }
4448
+ function escapeRegex(str) {
4449
+ return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
4450
+ }
4451
+ const vTrim = defineDirective({
4452
+ name: "trim",
4453
+ ssr: true,
4454
+ mounted(el, binding) {
4455
+ const options = normalizeOptions$3(binding.value);
4456
+ if (el.tagName === "INPUT" || el.tagName === "TEXTAREA") {
4457
+ setupInputElement(el, options);
4458
+ } else {
4459
+ const text = el.textContent || "";
4460
+ el.textContent = trimText(text, options);
4461
+ }
4462
+ },
4463
+ updated(el, binding) {
4464
+ const options = normalizeOptions$3(binding.value);
4465
+ const state = el.__trim;
4466
+ if (el.tagName === "INPUT" || el.tagName === "TEXTAREA") {
4467
+ if (state) {
4468
+ state.options = options;
4469
+ }
4470
+ } else {
4471
+ const text = el.textContent || "";
4472
+ el.textContent = trimText(text, options);
4473
+ }
4474
+ },
4475
+ unmounted(el) {
4476
+ const state = el.__trim;
4477
+ if (state == null ? void 0 : state.inputHandler) {
4478
+ el.removeEventListener("input", state.inputHandler);
4479
+ }
4480
+ if (state == null ? void 0 : state.blurHandler) {
4481
+ el.removeEventListener("blur", state.blurHandler);
4482
+ }
4483
+ delete el.__trim;
4484
+ }
4485
+ });
4486
+ function setupInputElement(el, options) {
4487
+ const state = { options };
4488
+ el.__trim = state;
4489
+ const performTrim = () => {
4490
+ const originalValue = el.value;
4491
+ const trimmed = trimText(originalValue, options);
4492
+ if (originalValue !== trimmed) {
4493
+ el.value = trimmed;
4494
+ el.dispatchEvent(new Event("input", { bubbles: true }));
4495
+ }
4496
+ };
4497
+ if (options.onInput) {
4498
+ const inputHandler = () => {
4499
+ const originalValue = el.value;
4500
+ const cursorPos = el.selectionStart;
4501
+ const trimmed = originalValue.replace(/\s+$/g, "");
4502
+ if (originalValue !== trimmed) {
4503
+ el.value = trimmed;
4504
+ if (cursorPos !== null) {
4505
+ const newCursorPos = Math.min(cursorPos, trimmed.length);
4506
+ el.setSelectionRange(newCursorPos, newCursorPos);
4507
+ }
4508
+ }
4509
+ };
4510
+ el.addEventListener("input", inputHandler);
4511
+ state.inputHandler = inputHandler;
4512
+ }
4513
+ if (options.onBlur) {
4514
+ const blurHandler = () => performTrim();
4515
+ el.addEventListener("blur", blurHandler);
4516
+ state.blurHandler = blurHandler;
4517
+ }
4518
+ if (el.value) {
4519
+ performTrim();
4520
+ }
4521
+ }
4522
+ function normalizeOptions$3(binding) {
4523
+ var _a, _b, _c;
4524
+ if (binding === void 0 || binding === true) {
4525
+ return { position: "both", onInput: true, onBlur: true };
4526
+ }
4527
+ if (binding === false) {
4528
+ return { position: "both", onInput: false, onBlur: false };
4529
+ }
4530
+ if (typeof binding === "string") {
4531
+ return { position: binding, onInput: true, onBlur: true };
4532
+ }
4533
+ return {
4534
+ position: (_a = binding.position) != null ? _a : "both",
4535
+ onInput: (_b = binding.onInput) != null ? _b : true,
4536
+ onBlur: (_c = binding.onBlur) != null ? _c : true,
4537
+ chars: binding.chars
4538
+ };
4539
+ }
4540
+ function truncateText(text, options) {
4541
+ const { length = 100, position = "end", ellipsis = "..." } = options;
4542
+ if (text.length <= length) {
4543
+ return text;
4544
+ }
4545
+ switch (position) {
4546
+ case "start":
4547
+ return ellipsis + text.slice(-(length - ellipsis.length));
4548
+ case "middle": {
4549
+ const startLen = Math.ceil((length - ellipsis.length) / 2);
4550
+ const endLen = Math.floor((length - ellipsis.length) / 2);
4551
+ return text.slice(0, startLen) + ellipsis + text.slice(-endLen);
4552
+ }
4553
+ case "end":
4554
+ default:
4555
+ return text.slice(0, length - ellipsis.length) + ellipsis;
4556
+ }
4557
+ }
4558
+ const vTruncate = defineDirective({
4559
+ name: "truncate",
4560
+ ssr: true,
4561
+ mounted(el, binding) {
4562
+ const options = normalizeOptions$2(binding.value);
4563
+ const text = el.textContent || "";
4564
+ const state = {
4565
+ originalText: text,
4566
+ options
4567
+ };
4568
+ el.__truncate = state;
4569
+ applyTruncation(el, text, options);
4570
+ },
4571
+ updated(el, binding) {
4572
+ const state = el.__truncate;
4573
+ const newOptions = normalizeOptions$2(binding.value);
4574
+ if (state) {
4575
+ const originalText = state.originalText;
4576
+ if (JSON.stringify(newOptions) !== JSON.stringify(state.options)) {
4577
+ state.options = newOptions;
4578
+ applyTruncation(el, originalText, newOptions);
4579
+ }
4580
+ } else {
4581
+ const text = el.textContent || "";
4582
+ el.__truncate = {
4583
+ originalText: text,
4584
+ options: newOptions
4585
+ };
4586
+ applyTruncation(el, text, newOptions);
4587
+ }
4588
+ },
4589
+ unmounted(el) {
4590
+ delete el.__truncate;
4591
+ }
4592
+ });
4593
+ function applyTruncation(el, text, options) {
4594
+ const { useCss, showTitle = true } = options;
4595
+ if (useCss) {
4596
+ el.style.overflow = "hidden";
4597
+ el.style.textOverflow = "ellipsis";
4598
+ el.style.whiteSpace = "nowrap";
4599
+ if (showTitle && text) {
4600
+ el.setAttribute("title", text);
4601
+ }
4602
+ } else {
4603
+ const truncated = truncateText(text, options);
4604
+ el.textContent = truncated;
4605
+ if (showTitle && text && text !== truncated) {
4606
+ el.setAttribute("title", text);
4607
+ }
4608
+ }
4609
+ }
4610
+ function normalizeOptions$2(binding) {
4611
+ var _a, _b, _c, _d, _e;
4612
+ if (typeof binding === "number") {
4613
+ return {
4614
+ length: binding,
4615
+ position: "end",
4616
+ ellipsis: "...",
4617
+ useCss: false,
4618
+ showTitle: true
4619
+ };
4620
+ }
4621
+ return {
4622
+ length: (_a = binding == null ? void 0 : binding.length) != null ? _a : 100,
4623
+ position: (_b = binding == null ? void 0 : binding.position) != null ? _b : "end",
4624
+ ellipsis: (_c = binding == null ? void 0 : binding.ellipsis) != null ? _c : "...",
4625
+ useCss: (_d = binding == null ? void 0 : binding.useCss) != null ? _d : false,
4626
+ showTitle: (_e = binding == null ? void 0 : binding.showTitle) != null ? _e : true
4627
+ };
4628
+ }
4629
+ function transformText(text, options) {
4630
+ if (!text) return text;
4631
+ if (options.first) {
4632
+ return text.charAt(0).toUpperCase() + text.slice(1);
4633
+ }
4634
+ return text.toUpperCase();
4635
+ }
4636
+ function normalizeOptions$1(binding) {
4637
+ var _a, _b;
4638
+ if (binding === void 0 || binding === true) {
4639
+ return { first: false, onInput: true };
4640
+ }
4641
+ if (binding === false) {
4642
+ return { first: false, onInput: false };
4643
+ }
4644
+ return {
4645
+ first: (_a = binding.first) != null ? _a : false,
4646
+ onInput: (_b = binding.onInput) != null ? _b : true
4647
+ };
4648
+ }
4649
+ const vUppercase = defineDirective({
4650
+ name: "uppercase",
4651
+ ssr: true,
4652
+ mounted(el, binding) {
4653
+ const options = normalizeOptions$1(binding.value);
4654
+ if (isInputElement(el)) {
4655
+ const cleanup2 = setupTextTransformInput(el, options, (text) => transformText(text, options));
4656
+ el.__uppercaseCleanup = cleanup2;
4657
+ } else {
4658
+ transformTextContent(el, (text) => transformText(text, options));
4659
+ }
4660
+ },
4661
+ updated(el, binding) {
4662
+ const options = normalizeOptions$1(binding.value);
4663
+ if (isInputElement(el)) {
4664
+ if (options.onInput) {
4665
+ el.value = transformText(el.value, options);
4666
+ }
4667
+ } else {
4668
+ transformTextContent(el, (text) => transformText(text, options));
4669
+ }
4670
+ },
4671
+ unmounted(el) {
4672
+ const cleanup2 = el.__uppercaseCleanup;
4673
+ cleanup2 == null ? void 0 : cleanup2();
4674
+ delete el.__uppercaseCleanup;
4675
+ }
4676
+ });
4677
+ function normalizeOptions(binding) {
4678
+ if (typeof binding === "boolean") {
4679
+ return { initial: binding };
4680
+ }
4681
+ return __spreadValues({
4682
+ initial: true,
4683
+ disabled: false,
4684
+ useHidden: false
4685
+ }, binding);
4686
+ }
4687
+ const vVisible = defineDirective({
4688
+ name: "visible",
4689
+ ssr: true,
4690
+ // SSR safe - will set initial visibility on server
4691
+ defaults: {
4692
+ initial: true,
4693
+ disabled: false,
4694
+ useHidden: false
4695
+ },
4696
+ mounted(el, binding) {
4697
+ var _a, _b;
4698
+ if (!isBrowser()) return;
4699
+ const options = normalizeOptions(binding.value);
4700
+ const originalDisplay = el.style.display;
4701
+ const originalVisibility = el.style.visibility;
4702
+ const state = {
4703
+ options,
4704
+ isVisible: (_a = options.initial) != null ? _a : true,
4705
+ originalDisplay,
4706
+ originalVisibility,
4707
+ transitionEndHandler: (e) => {
4708
+ if (e.propertyName === "opacity" || e.propertyName === "visibility") {
4709
+ el.dispatchEvent(new CustomEvent("visible:transition-end", {
4710
+ detail: { isVisible: state.isVisible }
4711
+ }));
4712
+ }
4713
+ }
4714
+ };
4715
+ el.__visible = state;
4716
+ on(el, "transitionend", state.transitionEndHandler);
4717
+ applyVisibility(el, state, (_b = options.initial) != null ? _b : true);
4718
+ },
4719
+ updated(el, binding) {
4720
+ var _a;
4721
+ const state = el.__visible;
4722
+ if (!state) return;
4723
+ const newOptions = normalizeOptions(binding.value);
4724
+ let newVisibility;
4725
+ if (typeof binding.value === "boolean") {
4726
+ newVisibility = binding.value;
4727
+ } else {
4728
+ newVisibility = (_a = newOptions.initial) != null ? _a : true;
4729
+ }
4730
+ if (state.isVisible !== newVisibility) {
4731
+ applyVisibility(el, state, newVisibility);
4732
+ }
4733
+ state.options = newOptions;
4734
+ },
4735
+ unmounted(el) {
4736
+ const state = el.__visible;
4737
+ if (!state) return;
4738
+ off(el, "transitionend", state.transitionEndHandler);
4739
+ el.style.display = state.originalDisplay;
4740
+ el.style.visibility = state.originalVisibility;
4741
+ delete el.__visible;
4742
+ }
4743
+ });
4744
+ function applyVisibility(el, state, isVisible) {
4745
+ const previousVisibility = state.isVisible;
4746
+ state.isVisible = isVisible;
4747
+ if (isVisible) {
4748
+ el.classList.remove("v-hidden");
4749
+ el.classList.add("v-visible");
4750
+ } else {
4751
+ el.classList.remove("v-visible");
4752
+ el.classList.add("v-hidden");
4753
+ }
4754
+ if (state.options.useHidden) {
4755
+ if (isVisible) {
4756
+ el.style.visibility = state.originalVisibility || "visible";
4757
+ } else {
4758
+ const computedStyle = getComputedStyle(el);
4759
+ const hasTransition = computedStyle.transitionDuration !== "0s";
4760
+ if (hasTransition) {
4761
+ const handleTransitionEnd = (e) => {
4762
+ if (e.target === el && (e.propertyName === "opacity" || e.propertyName === "transform")) {
4763
+ if (!state.isVisible) {
4764
+ el.style.visibility = "hidden";
4765
+ }
4766
+ el.removeEventListener("transitionend", handleTransitionEnd);
4767
+ }
4768
+ };
4769
+ el.addEventListener("transitionend", handleTransitionEnd);
4770
+ } else {
4771
+ el.style.visibility = "hidden";
4772
+ }
4773
+ }
4774
+ } else {
4775
+ el.style.display = isVisible ? state.originalDisplay : "none";
4776
+ }
4777
+ el.dispatchEvent(new CustomEvent("visible:change", {
4778
+ detail: { isVisible, previousVisibility }
4779
+ }));
4780
+ if (state.options.handler && previousVisibility !== isVisible) {
4781
+ state.options.handler(isVisible);
4782
+ }
4783
+ }
4784
+ const allDirectives = {
4785
+ "click-outside": vClickOutside,
4786
+ copy: vCopy,
4787
+ debounce: vDebounce,
4788
+ throttle: vThrottle,
4789
+ focus: vFocus,
4790
+ lazy: vLazy,
4791
+ intersect: vIntersect,
4792
+ visible: vVisible,
4793
+ loading: vLoading,
4794
+ scroll: vScroll,
4795
+ "infinite-scroll": vInfiniteScroll,
4796
+ sticky: vSticky,
4797
+ "long-press": vLongPress,
4798
+ hover: vHover,
4799
+ ripple: vRipple,
4800
+ mask: vMask,
4801
+ permission: vPermission,
4802
+ sanitize: vSanitize,
4803
+ resize: vResize,
4804
+ mutation: vMutation,
4805
+ truncate: vTruncate,
4806
+ uppercase: vUppercase,
4807
+ lowercase: vLowercase,
4808
+ capitalcase: vCapitalcase,
4809
+ number: vNumber,
4810
+ money: vMoney,
4811
+ trim: vTrim,
4812
+ tooltip: vTooltip,
4813
+ draggable: vDraggable,
4814
+ touch: vTouch,
4815
+ "image-preview": vImagePreview
4816
+ };
4817
+ const install = (app, options = {}) => {
4818
+ var _a, _b, _c, _d, _e, _f, _g;
4819
+ let vueVersion = null;
4820
+ if (typeof app === "function" && ((_a = app.version) == null ? void 0 : _a.startsWith("2"))) {
4821
+ vueVersion = 2;
4822
+ } else if ((app == null ? void 0 : app.config) && ((_b = app == null ? void 0 : app.version) == null ? void 0 : _b.startsWith("3"))) {
4823
+ vueVersion = 3;
4824
+ } else if (typeof (app == null ? void 0 : app.directive) === "function" && typeof (app == null ? void 0 : app.mixin) === "function" && ((_c = app.version) == null ? void 0 : _c.startsWith("2"))) {
4825
+ vueVersion = 2;
4826
+ } else if (typeof window !== "undefined") {
4827
+ const win = window;
4828
+ if ((_e = (_d = win.Vue) == null ? void 0 : _d.version) == null ? void 0 : _e.startsWith("2")) {
4829
+ vueVersion = 2;
4830
+ } else if ((_g = (_f = win.Vue) == null ? void 0 : _f.version) == null ? void 0 : _g.startsWith("3")) {
4831
+ vueVersion = 3;
4832
+ }
4833
+ }
4834
+ if (vueVersion) {
4835
+ setVueVersion(vueVersion);
4836
+ }
1031
4837
  const { directives, all = false } = options;
1032
4838
  if (all || !directives) {
1033
4839
  Object.entries(allDirectives).forEach(([name, directive]) => {
@@ -1051,7 +4857,9 @@ export {
1051
4857
  Directix,
1052
4858
  addCleanup$1 as addCleanupVue2,
1053
4859
  addCleanup as addCleanupVue3,
4860
+ vCapitalcase as capitalcase,
1054
4861
  vClickOutside as clickOutside,
4862
+ configurePermission,
1055
4863
  vCopy as copy,
1056
4864
  createVue2Directive,
1057
4865
  createVue3Directive,
@@ -1061,10 +4869,16 @@ export {
1061
4869
  deepMerge,
1062
4870
  defineDirective,
1063
4871
  defineDirectiveGroup,
4872
+ vDraggable as draggable,
1064
4873
  vFocus as focus,
1065
4874
  generateId,
1066
4875
  get,
4876
+ getPermissionConfig,
1067
4877
  getVueVersion,
4878
+ vHover as hover,
4879
+ vImagePreview as imagePreview,
4880
+ vInfiniteScroll as infiniteScroll,
4881
+ vIntersect as intersect,
1068
4882
  isArray,
1069
4883
  isBoolean,
1070
4884
  isBrowser,
@@ -1076,9 +4890,26 @@ export {
1076
4890
  isSSR,
1077
4891
  isString,
1078
4892
  isVue2,
4893
+ isVue27,
1079
4894
  isVue3,
4895
+ vLazy as lazy,
4896
+ vLoading as loading,
4897
+ vLongPress as longPress,
4898
+ vLowercase as lowercase,
4899
+ vMask as mask,
4900
+ vMoney as money,
4901
+ vMutation as mutation,
4902
+ vNumber as number,
1080
4903
  parseTime,
4904
+ vPermission as permission,
4905
+ resetVueVersion,
4906
+ vResize as resize,
4907
+ vRipple as ripple,
4908
+ vSanitize as sanitize,
4909
+ vScroll as scroll,
1081
4910
  set,
4911
+ setVueVersion,
4912
+ vSticky as sticky,
1082
4913
  supportsClipboard,
1083
4914
  supportsIntersectionObserver,
1084
4915
  supportsMutationObserver,
@@ -1086,10 +4917,42 @@ export {
1086
4917
  supportsResizeObserver,
1087
4918
  vThrottle as throttle,
1088
4919
  throttle as throttleFn,
4920
+ vTooltip as tooltip,
4921
+ vTouch as touch,
4922
+ vTrim as trim,
4923
+ vTruncate as truncate,
4924
+ vUppercase as uppercase,
4925
+ vCapitalcase,
1089
4926
  vClickOutside,
1090
4927
  vCopy,
1091
4928
  vDebounce,
4929
+ vDraggable,
1092
4930
  vFocus,
1093
- vThrottle
4931
+ vHover,
4932
+ vImagePreview,
4933
+ vInfiniteScroll,
4934
+ vIntersect,
4935
+ vLazy,
4936
+ vLoading,
4937
+ vLongPress,
4938
+ vLowercase,
4939
+ vMask,
4940
+ vMoney,
4941
+ vMutation,
4942
+ vNumber,
4943
+ vPermission,
4944
+ vResize,
4945
+ vRipple,
4946
+ vSanitize,
4947
+ vScroll,
4948
+ vSticky,
4949
+ vThrottle,
4950
+ vTooltip,
4951
+ vTouch,
4952
+ vTrim,
4953
+ vTruncate,
4954
+ vUppercase,
4955
+ vVisible,
4956
+ vVisible as visible
1094
4957
  };
1095
4958
  //# sourceMappingURL=index.mjs.map