directix 1.3.0 → 1.4.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.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * directix v1.3.0
2
+ * directix v1.4.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.
@@ -57,12 +57,12 @@ var __async = (__this, __arguments, generator) => {
57
57
  });
58
58
  };
59
59
  /*!
60
- * directix v1.3.0
60
+ * directix v1.4.0
61
61
  * A comprehensive, easy-to-use, and high-performance Vue custom directives library supporting both Vue 2 and Vue 3
62
62
  * (c) 2021-present saqqdy <https://github.com/saqqdy>
63
63
  * Released under the MIT License.
64
64
  */
65
- (function(exports) {
65
+ (function(exports, vue) {
66
66
  "use strict";
67
67
  function createVue2Directive(hooks) {
68
68
  const directive = {
@@ -218,8 +218,8 @@ var __async = (__this, __arguments, generator) => {
218
218
  }
219
219
  }
220
220
  try {
221
- const vue = require("vue");
222
- const version = parseVersion(vue == null ? void 0 : vue.version);
221
+ const vue2 = require("vue");
222
+ const version = parseVersion(vue2 == null ? void 0 : vue2.version);
223
223
  if (version !== null) {
224
224
  _vueVersion = version;
225
225
  return _vueVersion;
@@ -228,19 +228,19 @@ var __async = (__this, __arguments, generator) => {
228
228
  }
229
229
  if (typeof window !== "undefined") {
230
230
  const win = window;
231
- const vue = win.Vue;
232
- if (vue == null ? void 0 : vue.version) {
233
- const version = parseVersion(vue.version);
231
+ const vue2 = win.Vue;
232
+ if (vue2 == null ? void 0 : vue2.version) {
233
+ const version = parseVersion(vue2.version);
234
234
  if (version !== null) {
235
235
  _vueVersion = version;
236
236
  return _vueVersion;
237
237
  }
238
238
  }
239
- if (typeof (vue == null ? void 0 : vue.observable) === "function") {
239
+ if (typeof (vue2 == null ? void 0 : vue2.observable) === "function") {
240
240
  _vueVersion = 2;
241
241
  return _vueVersion;
242
242
  }
243
- if (typeof (vue == null ? void 0 : vue.createApp) === "function" && typeof (vue == null ? void 0 : vue.observable) !== "function") {
243
+ if (typeof (vue2 == null ? void 0 : vue2.createApp) === "function" && typeof (vue2 == null ? void 0 : vue2.observable) !== "function") {
244
244
  _vueVersion = 3;
245
245
  return _vueVersion;
246
246
  }
@@ -442,7 +442,7 @@ var __async = (__this, __arguments, generator) => {
442
442
  function isInputElement(el) {
443
443
  return el.tagName === "INPUT" || el.tagName === "TEXTAREA";
444
444
  }
445
- const DEFAULT_KEEP_LOWER = [
445
+ const DEFAULT_KEEP_LOWER$1 = [
446
446
  "a",
447
447
  "an",
448
448
  "the",
@@ -461,25 +461,25 @@ var __async = (__this, __arguments, generator) => {
461
461
  "with",
462
462
  "as"
463
463
  ];
464
- function capitalizeText(text, options) {
464
+ function capitalizeText$1(text, options) {
465
465
  if (!text) return text;
466
- const { every = true, keepLower = DEFAULT_KEEP_LOWER } = options;
466
+ const { every = true, keepLower = DEFAULT_KEEP_LOWER$1 } = options;
467
467
  if (every) {
468
468
  const words = text.toLowerCase().split(/\s+/);
469
469
  return words.map((word, index) => {
470
470
  if (index === 0) {
471
- return capitalizeWord(word);
471
+ return capitalizeWord$1(word);
472
472
  }
473
473
  if (keepLower.includes(word.toLowerCase())) {
474
474
  return word.toLowerCase();
475
475
  }
476
- return capitalizeWord(word);
476
+ return capitalizeWord$1(word);
477
477
  }).join(" ");
478
478
  } else {
479
- return capitalizeWord(text);
479
+ return capitalizeWord$1(text);
480
480
  }
481
481
  }
482
- function capitalizeWord(word) {
482
+ function capitalizeWord$1(word) {
483
483
  if (!word) return word;
484
484
  return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
485
485
  }
@@ -493,7 +493,7 @@ var __async = (__this, __arguments, generator) => {
493
493
  }
494
494
  return {
495
495
  every: (_a = binding.every) != null ? _a : true,
496
- keepLower: (_b = binding.keepLower) != null ? _b : DEFAULT_KEEP_LOWER,
496
+ keepLower: (_b = binding.keepLower) != null ? _b : DEFAULT_KEEP_LOWER$1,
497
497
  onInput: (_c = binding.onInput) != null ? _c : true
498
498
  };
499
499
  }
@@ -503,20 +503,20 @@ var __async = (__this, __arguments, generator) => {
503
503
  mounted(el, binding) {
504
504
  const options = normalizeOptions$B(binding.value);
505
505
  if (isInputElement(el)) {
506
- const cleanup2 = setupTextTransformInput(el, options, (text) => capitalizeText(text, options));
506
+ const cleanup2 = setupTextTransformInput(el, options, (text) => capitalizeText$1(text, options));
507
507
  el.__capitalcaseCleanup = cleanup2;
508
508
  } else {
509
- transformTextContent(el, (text) => capitalizeText(text, options));
509
+ transformTextContent(el, (text) => capitalizeText$1(text, options));
510
510
  }
511
511
  },
512
512
  updated(el, binding) {
513
513
  const options = normalizeOptions$B(binding.value);
514
514
  if (isInputElement(el)) {
515
515
  if (options.onInput) {
516
- el.value = capitalizeText(el.value, options);
516
+ el.value = capitalizeText$1(el.value, options);
517
517
  }
518
518
  } else {
519
- transformTextContent(el, (text) => capitalizeText(text, options));
519
+ transformTextContent(el, (text) => capitalizeText$1(text, options));
520
520
  }
521
521
  },
522
522
  unmounted(el) {
@@ -525,133 +525,15 @@ var __async = (__this, __arguments, generator) => {
525
525
  delete el.__capitalcaseCleanup;
526
526
  }
527
527
  });
528
- const vClickDelay = defineDirective({
529
- name: "click-delay",
530
- ssr: true,
531
- defaults: {
532
- delay: 300,
533
- disabled: false,
534
- pendingClass: "v-click-delay--pending",
535
- feedback: true
536
- },
537
- mounted(el, binding) {
538
- const options = normalizeOptions$A(binding.value, binding);
539
- if (options.disabled) return;
540
- const state = {
541
- options,
542
- handler: createClickHandler(el, options),
543
- isPending: false,
544
- timeoutId: null
545
- };
546
- el.__clickDelay = state;
547
- el.addEventListener("click", state.handler);
548
- el.addEventListener("touchend", state.handler);
549
- },
550
- updated(el, binding) {
551
- const state = el.__clickDelay;
552
- if (!state) {
553
- const options = normalizeOptions$A(binding.value, binding);
554
- if (!options.disabled) {
555
- const newState = {
556
- options,
557
- handler: createClickHandler(el, options),
558
- isPending: false,
559
- timeoutId: null
560
- };
561
- el.__clickDelay = newState;
562
- el.addEventListener("click", newState.handler);
563
- el.addEventListener("touchend", newState.handler);
564
- }
565
- return;
566
- }
567
- const newOptions = normalizeOptions$A(binding.value, binding);
568
- if (newOptions.disabled && !state.options.disabled) {
569
- el.removeEventListener("click", state.handler);
570
- el.removeEventListener("touchend", state.handler);
571
- if (state.timeoutId) {
572
- clearTimeout(state.timeoutId);
573
- }
574
- removePendingClass(el, state.options);
575
- delete el.__clickDelay;
576
- } else if (!newOptions.disabled && state.options.disabled) {
577
- state.handler = createClickHandler(el, newOptions);
578
- state.isPending = false;
579
- state.timeoutId = null;
580
- el.addEventListener("click", state.handler);
581
- el.addEventListener("touchend", state.handler);
582
- }
583
- state.options = newOptions;
584
- },
585
- unmounted(el) {
586
- const state = el.__clickDelay;
587
- if (!state) return;
588
- el.removeEventListener("click", state.handler);
589
- el.removeEventListener("touchend", state.handler);
590
- if (state.timeoutId) {
591
- clearTimeout(state.timeoutId);
592
- }
593
- removePendingClass(el, state.options);
594
- delete el.__clickDelay;
595
- }
596
- });
597
- function createClickHandler(el, options) {
598
- return (event) => {
599
- const state = el.__clickDelay;
600
- if (!state || state.isPending) {
601
- event.preventDefault();
602
- event.stopPropagation();
603
- return;
604
- }
605
- state.isPending = true;
606
- if (options.feedback && options.pendingClass) {
607
- el.classList.add(options.pendingClass);
608
- }
609
- options.handler(event);
610
- state.timeoutId = setTimeout(() => {
611
- state.isPending = false;
612
- state.timeoutId = null;
613
- removePendingClass(el, options);
614
- }, options.delay);
615
- };
616
- }
617
- function removePendingClass(el, options) {
618
- if (options.feedback && options.pendingClass) {
619
- el.classList.remove(options.pendingClass);
620
- }
528
+ const STATE_PREFIX = "__directix_";
529
+ function setState$1(el, key, state) {
530
+ el[STATE_PREFIX + key] = state;
621
531
  }
622
- function parseTime$1(arg) {
623
- if (!arg) return null;
624
- if (arg.endsWith("ms")) {
625
- return parseInt(arg, 10);
626
- }
627
- if (arg.endsWith("s")) {
628
- return parseFloat(arg) * 1e3;
629
- }
630
- const num = parseInt(arg, 10);
631
- return Number.isNaN(num) ? null : num;
532
+ function getState$1(el, key) {
533
+ return el[STATE_PREFIX + key];
632
534
  }
633
- function normalizeOptions$A(binding, directiveBinding) {
634
- var _a, _b, _c, _d;
635
- const delay = parseTime$1(directiveBinding.arg) || 300;
636
- if (typeof binding === "function") {
637
- return {
638
- handler: binding,
639
- delay,
640
- disabled: false,
641
- pendingClass: "v-click-delay--pending",
642
- feedback: true
643
- };
644
- }
645
- if (!binding) {
646
- throw new Error("[Directix] v-click-delay: handler is required");
647
- }
648
- return {
649
- handler: binding.handler,
650
- delay: (_a = binding.delay) != null ? _a : delay,
651
- disabled: (_b = binding.disabled) != null ? _b : false,
652
- pendingClass: (_c = binding.pendingClass) != null ? _c : "v-click-delay--pending",
653
- feedback: (_d = binding.feedback) != null ? _d : true
654
- };
535
+ function deleteState(el, key) {
536
+ delete el[STATE_PREFIX + key];
655
537
  }
656
538
  function isElement(value) {
657
539
  return value instanceof Element;
@@ -678,15 +560,15 @@ var __async = (__this, __arguments, generator) => {
678
560
  }
679
561
  function on(target, event, handler, options = false) {
680
562
  if (!isBrowser()) return;
681
- const opts = normalizeOptions$z(options);
563
+ const opts = normalizeOptions$A(options);
682
564
  target.addEventListener(event, handler, opts);
683
565
  }
684
566
  function off(target, event, handler, options = false) {
685
567
  if (!isBrowser()) return;
686
- const opts = normalizeOptions$z(options);
568
+ const opts = normalizeOptions$A(options);
687
569
  target.removeEventListener(event, handler, opts);
688
570
  }
689
- function normalizeOptions$z(options) {
571
+ function normalizeOptions$A(options) {
690
572
  if (typeof options === "boolean") {
691
573
  return options;
692
574
  }
@@ -696,7 +578,7 @@ var __async = (__this, __arguments, generator) => {
696
578
  }
697
579
  return capture;
698
580
  }
699
- function getEventPosition(e) {
581
+ function getEventPosition$1(e) {
700
582
  let clientX = 0, clientY = 0;
701
583
  if ("touches" in e && e.touches.length > 0) {
702
584
  clientX = e.touches[0].clientX;
@@ -712,6 +594,58 @@ var __async = (__this, __arguments, generator) => {
712
594
  clientY
713
595
  };
714
596
  }
597
+ function bindEvents$2(target, events, options = false) {
598
+ Object.entries(events).forEach(([event, handler]) => {
599
+ target.addEventListener(event, handler, typeof options === "boolean" ? options : normalizeOptionsObject(options));
600
+ });
601
+ return () => {
602
+ Object.entries(events).forEach(([event, handler]) => {
603
+ target.removeEventListener(event, handler, typeof options === "boolean" ? options : normalizeOptionsObject(options));
604
+ });
605
+ };
606
+ }
607
+ function normalizeOptionsObject(options) {
608
+ const { capture = false, passive = false, once = false } = options;
609
+ if (supportsPassive()) {
610
+ return { capture, passive, once };
611
+ }
612
+ return capture;
613
+ }
614
+ const EVENT_MODIFIERS = [
615
+ "click",
616
+ "input",
617
+ "change",
618
+ "submit",
619
+ "scroll",
620
+ "resize",
621
+ "mouseenter",
622
+ "mouseleave",
623
+ "mousemove",
624
+ "mousedown",
625
+ "mouseup",
626
+ "keydown",
627
+ "keyup",
628
+ "focus",
629
+ "blur",
630
+ "touchstart",
631
+ "touchmove",
632
+ "touchend"
633
+ ];
634
+ function getEventTypeFromModifiers(modifiers) {
635
+ for (const modifier of EVENT_MODIFIERS) {
636
+ if (modifiers[modifier]) {
637
+ return modifier;
638
+ }
639
+ }
640
+ return null;
641
+ }
642
+ function getDefaultEventType(el) {
643
+ const tagName = el.tagName.toLowerCase();
644
+ if (tagName === "input" || tagName === "textarea") {
645
+ return "input";
646
+ }
647
+ return "click";
648
+ }
715
649
  function isString(value) {
716
650
  return typeof value === "string";
717
651
  }
@@ -898,53 +832,171 @@ var __async = (__this, __arguments, generator) => {
898
832
  function generateId(prefix = "") {
899
833
  return `${prefix}${Date.now().toString(36)}${Math.random().toString(36).slice(2, 9)}`;
900
834
  }
901
- const vClickOutside = defineDirective({
902
- name: "click-outside",
903
- ssr: false,
835
+ const STATE_KEY$5 = "clickDelay";
836
+ function removePendingClass(el, options) {
837
+ if (options.feedback && options.pendingClass) {
838
+ el.classList.remove(options.pendingClass);
839
+ }
840
+ }
841
+ function createClickHandler(el, options) {
842
+ return (event) => {
843
+ const state = getState$1(el, STATE_KEY$5);
844
+ if (!state || state.isPending) {
845
+ event.preventDefault();
846
+ event.stopPropagation();
847
+ return;
848
+ }
849
+ state.isPending = true;
850
+ if (options.feedback && options.pendingClass) {
851
+ el.classList.add(options.pendingClass);
852
+ }
853
+ options.handler(event);
854
+ state.timeoutId = setTimeout(() => {
855
+ state.isPending = false;
856
+ state.timeoutId = null;
857
+ removePendingClass(el, options);
858
+ }, options.delay);
859
+ };
860
+ }
861
+ function normalizeOptions$z(binding, directiveBinding) {
862
+ var _a, _b, _c, _d;
863
+ const delay = parseTime(directiveBinding.arg) || 300;
864
+ if (typeof binding === "function") {
865
+ return {
866
+ handler: binding,
867
+ delay,
868
+ disabled: false,
869
+ pendingClass: "v-click-delay--pending",
870
+ feedback: true
871
+ };
872
+ }
873
+ if (!binding) {
874
+ throw new Error("[Directix] v-click-delay: handler is required");
875
+ }
876
+ return {
877
+ handler: binding.handler,
878
+ delay: (_a = binding.delay) != null ? _a : delay,
879
+ disabled: (_b = binding.disabled) != null ? _b : false,
880
+ pendingClass: (_c = binding.pendingClass) != null ? _c : "v-click-delay--pending",
881
+ feedback: (_d = binding.feedback) != null ? _d : true
882
+ };
883
+ }
884
+ const vClickDelay = defineDirective({
885
+ name: "click-delay",
886
+ ssr: true,
904
887
  defaults: {
905
- capture: true,
906
- events: ["click"],
888
+ delay: 300,
907
889
  disabled: false,
908
- stop: false,
909
- prevent: false
890
+ pendingClass: "v-click-delay--pending",
891
+ feedback: true
910
892
  },
911
893
  mounted(el, binding) {
912
- const options = normalizeOptions$y(binding.value);
894
+ const options = normalizeOptions$z(binding.value, binding);
913
895
  if (options.disabled) return;
914
896
  const state = {
915
897
  options,
916
- handlers: /* @__PURE__ */ new Map()
917
- };
918
- el.__clickOutside = state;
919
- const createHandler = (_eventType) => {
920
- return (event) => {
921
- if (!isValidClick(el, event, options)) {
922
- return;
923
- }
924
- if (options.stop) {
925
- event.stopPropagation();
926
- }
927
- if (options.prevent) {
928
- event.preventDefault();
929
- }
930
- options.handler(event);
931
- };
898
+ handler: createClickHandler(el, options),
899
+ isPending: false,
900
+ timeoutId: null
932
901
  };
933
- options.events.forEach((eventType) => {
934
- const handler = createHandler();
935
- state.handlers.set(eventType, handler);
936
- const listenerOptions = {
937
- capture: options.capture,
938
- passive: !options.prevent
939
- };
940
- on(document, eventType, handler, listenerOptions);
941
- });
902
+ setState$1(el, STATE_KEY$5, state);
903
+ el.addEventListener("click", state.handler);
904
+ el.addEventListener("touchend", state.handler);
942
905
  },
943
906
  updated(el, binding) {
944
- const state = el.__clickOutside;
945
- if (!state) return;
946
- const oldOptions = state.options;
947
- const newOptions = normalizeOptions$y(binding.value);
907
+ const state = getState$1(el, STATE_KEY$5);
908
+ if (!state) {
909
+ const options = normalizeOptions$z(binding.value, binding);
910
+ if (!options.disabled) {
911
+ const newState = {
912
+ options,
913
+ handler: createClickHandler(el, options),
914
+ isPending: false,
915
+ timeoutId: null
916
+ };
917
+ setState$1(el, STATE_KEY$5, newState);
918
+ el.addEventListener("click", newState.handler);
919
+ el.addEventListener("touchend", newState.handler);
920
+ }
921
+ return;
922
+ }
923
+ const newOptions = normalizeOptions$z(binding.value, binding);
924
+ if (newOptions.disabled && !state.options.disabled) {
925
+ el.removeEventListener("click", state.handler);
926
+ el.removeEventListener("touchend", state.handler);
927
+ if (state.timeoutId) {
928
+ clearTimeout(state.timeoutId);
929
+ }
930
+ removePendingClass(el, state.options);
931
+ deleteState(el, STATE_KEY$5);
932
+ } else if (!newOptions.disabled && state.options.disabled) {
933
+ state.handler = createClickHandler(el, newOptions);
934
+ state.isPending = false;
935
+ state.timeoutId = null;
936
+ el.addEventListener("click", state.handler);
937
+ el.addEventListener("touchend", state.handler);
938
+ }
939
+ state.options = newOptions;
940
+ },
941
+ unmounted(el) {
942
+ const state = getState$1(el, STATE_KEY$5);
943
+ if (!state) return;
944
+ el.removeEventListener("click", state.handler);
945
+ el.removeEventListener("touchend", state.handler);
946
+ if (state.timeoutId) {
947
+ clearTimeout(state.timeoutId);
948
+ }
949
+ removePendingClass(el, state.options);
950
+ deleteState(el, STATE_KEY$5);
951
+ }
952
+ });
953
+ const vClickOutside = defineDirective({
954
+ name: "click-outside",
955
+ ssr: false,
956
+ defaults: {
957
+ capture: true,
958
+ events: ["click"],
959
+ disabled: false,
960
+ stop: false,
961
+ prevent: false
962
+ },
963
+ mounted(el, binding) {
964
+ const options = normalizeOptions$y(binding.value);
965
+ if (options.disabled) return;
966
+ const state = {
967
+ options,
968
+ handlers: /* @__PURE__ */ new Map()
969
+ };
970
+ el.__clickOutside = state;
971
+ const createHandler = (_eventType) => {
972
+ return (event) => {
973
+ if (!isValidClick$1(el, event, options)) {
974
+ return;
975
+ }
976
+ if (options.stop) {
977
+ event.stopPropagation();
978
+ }
979
+ if (options.prevent) {
980
+ event.preventDefault();
981
+ }
982
+ options.handler(event);
983
+ };
984
+ };
985
+ options.events.forEach((eventType) => {
986
+ const handler = createHandler();
987
+ state.handlers.set(eventType, handler);
988
+ const listenerOptions = {
989
+ capture: options.capture,
990
+ passive: !options.prevent
991
+ };
992
+ on(document, eventType, handler, listenerOptions);
993
+ });
994
+ },
995
+ updated(el, binding) {
996
+ const state = el.__clickOutside;
997
+ if (!state) return;
998
+ const oldOptions = state.options;
999
+ const newOptions = normalizeOptions$y(binding.value);
948
1000
  if (oldOptions.disabled !== newOptions.disabled) {
949
1001
  if (newOptions.disabled) {
950
1002
  state.handlers.forEach((handler, eventType) => {
@@ -954,7 +1006,7 @@ var __async = (__this, __arguments, generator) => {
954
1006
  } else {
955
1007
  const createHandler = (_eventType) => {
956
1008
  return (event) => {
957
- if (!isValidClick(el, event, newOptions)) return;
1009
+ if (!isValidClick$1(el, event, newOptions)) return;
958
1010
  if (newOptions.stop) event.stopPropagation();
959
1011
  if (newOptions.prevent) event.preventDefault();
960
1012
  newOptions.handler(event);
@@ -1004,7 +1056,7 @@ var __async = (__this, __arguments, generator) => {
1004
1056
  prevent: (_e = binding.prevent) != null ? _e : false
1005
1057
  }, binding);
1006
1058
  }
1007
- function isValidClick(el, event, options) {
1059
+ function isValidClick$1(el, event, options) {
1008
1060
  var _a;
1009
1061
  const target = event.target;
1010
1062
  if (el.contains(target)) {
@@ -1020,7 +1072,7 @@ var __async = (__this, __arguments, generator) => {
1020
1072
  }
1021
1073
  return true;
1022
1074
  }
1023
- function copyToClipboard(text) {
1075
+ function copyToClipboard$1(text) {
1024
1076
  return __async(this, null, function* () {
1025
1077
  if (supportsClipboard()) {
1026
1078
  try {
@@ -1030,10 +1082,10 @@ var __async = (__this, __arguments, generator) => {
1030
1082
  console.warn("[Directix] Clipboard API failed, falling back to execCommand");
1031
1083
  }
1032
1084
  }
1033
- return copyWithExecCommand(text);
1085
+ return copyWithExecCommand$1(text);
1034
1086
  });
1035
1087
  }
1036
- function copyWithExecCommand(text) {
1088
+ function copyWithExecCommand$1(text) {
1037
1089
  const textarea = document.createElement("textarea");
1038
1090
  textarea.value = text;
1039
1091
  textarea.style.cssText = `
@@ -1075,7 +1127,7 @@ var __async = (__this, __arguments, generator) => {
1075
1127
  return;
1076
1128
  }
1077
1129
  try {
1078
- const success = yield copyToClipboard(text);
1130
+ const success = yield copyToClipboard$1(text);
1079
1131
  if (success) {
1080
1132
  (_b = (_a = state.options).onSuccess) == null ? void 0 : _b.call(_a, text);
1081
1133
  el.dispatchEvent(new CustomEvent("copy:success", { detail: { text } }));
@@ -1112,7 +1164,7 @@ var __async = (__this, __arguments, generator) => {
1112
1164
  }
1113
1165
  return binding;
1114
1166
  }
1115
- function parseTargetTime(target) {
1167
+ function parseTargetTime$1(target) {
1116
1168
  if (target instanceof Date) {
1117
1169
  return target.getTime();
1118
1170
  }
@@ -1121,7 +1173,7 @@ var __async = (__this, __arguments, generator) => {
1121
1173
  }
1122
1174
  return new Date(target).getTime();
1123
1175
  }
1124
- function calculateTime(remaining) {
1176
+ function calculateTime$1(remaining) {
1125
1177
  const total = Math.max(0, remaining);
1126
1178
  return {
1127
1179
  days: Math.floor(total / (1e3 * 60 * 60 * 24)),
@@ -1132,7 +1184,7 @@ var __async = (__this, __arguments, generator) => {
1132
1184
  total
1133
1185
  };
1134
1186
  }
1135
- function formatTime(time, format) {
1187
+ function formatTime$1(time, format) {
1136
1188
  if (typeof format === "function") {
1137
1189
  return format(time);
1138
1190
  }
@@ -1167,7 +1219,7 @@ var __async = (__this, __arguments, generator) => {
1167
1219
  ssr: true,
1168
1220
  mounted(el, binding) {
1169
1221
  const options = normalizeOptions$w(binding.value);
1170
- const targetTime = parseTargetTime(options.target);
1222
+ const targetTime = parseTargetTime$1(options.target);
1171
1223
  const state = {
1172
1224
  options,
1173
1225
  targetTime,
@@ -1185,7 +1237,7 @@ var __async = (__this, __arguments, generator) => {
1185
1237
  updated(el, binding) {
1186
1238
  const state = el.__countdown;
1187
1239
  const newOptions = normalizeOptions$w(binding.value);
1188
- const newTargetTime = parseTargetTime(newOptions.target);
1240
+ const newTargetTime = parseTargetTime$1(newOptions.target);
1189
1241
  if (newTargetTime !== state.targetTime) {
1190
1242
  state.targetTime = newTargetTime;
1191
1243
  state.options = newOptions;
@@ -1224,7 +1276,7 @@ var __async = (__this, __arguments, generator) => {
1224
1276
  }
1225
1277
  updateDisplay(el, state);
1226
1278
  if (state.options.onTick) {
1227
- const time = calculateTime(state.remaining);
1279
+ const time = calculateTime$1(state.remaining);
1228
1280
  state.options.onTick(time);
1229
1281
  }
1230
1282
  };
@@ -1238,45 +1290,10 @@ var __async = (__this, __arguments, generator) => {
1238
1290
  }
1239
1291
  }
1240
1292
  function updateDisplay(el, state) {
1241
- const time = calculateTime(state.remaining);
1242
- const display = formatTime(time, state.options.format || "hh:mm:ss");
1293
+ const time = calculateTime$1(state.remaining);
1294
+ const display = formatTime$1(time, state.options.format || "hh:mm:ss");
1243
1295
  el.textContent = display;
1244
1296
  }
1245
- const EVENT_MODIFIERS = [
1246
- "click",
1247
- "input",
1248
- "change",
1249
- "submit",
1250
- "scroll",
1251
- "resize",
1252
- "mouseenter",
1253
- "mouseleave",
1254
- "mousemove",
1255
- "mousedown",
1256
- "mouseup",
1257
- "keydown",
1258
- "keyup",
1259
- "focus",
1260
- "blur",
1261
- "touchstart",
1262
- "touchmove",
1263
- "touchend"
1264
- ];
1265
- function getEventTypeFromModifiers(modifiers) {
1266
- for (const modifier of EVENT_MODIFIERS) {
1267
- if (modifiers[modifier]) {
1268
- return modifier;
1269
- }
1270
- }
1271
- return null;
1272
- }
1273
- function getDefaultEventType(el) {
1274
- const tagName = el.tagName.toLowerCase();
1275
- if (tagName === "input" || tagName === "textarea") {
1276
- return "input";
1277
- }
1278
- return "click";
1279
- }
1280
1297
  function normalizeOptions$v(binding, directiveBinding) {
1281
1298
  const wait = parseTime(directiveBinding.arg) || 300;
1282
1299
  if (typeof binding === "function") {
@@ -1336,7 +1353,7 @@ var __async = (__this, __arguments, generator) => {
1336
1353
  delete el.__debounce;
1337
1354
  }
1338
1355
  });
1339
- function getBoundary(_el, boundary) {
1356
+ function getBoundary$1(_el, boundary) {
1340
1357
  var _a, _b;
1341
1358
  if (!boundary) return null;
1342
1359
  if (typeof boundary === "function") {
@@ -1349,7 +1366,7 @@ var __async = (__this, __arguments, generator) => {
1349
1366
  }
1350
1367
  return boundary.getBoundingClientRect();
1351
1368
  }
1352
- function getClientCoords(e) {
1369
+ function getClientCoords$1(e) {
1353
1370
  if (e.type.startsWith("touch")) {
1354
1371
  const touch = e.touches[0];
1355
1372
  return { clientX: touch.clientX, clientY: touch.clientY };
@@ -1357,7 +1374,7 @@ var __async = (__this, __arguments, generator) => {
1357
1374
  const mouseEvent = e;
1358
1375
  return { clientX: mouseEvent.clientX, clientY: mouseEvent.clientY };
1359
1376
  }
1360
- function parseTranslate(transform) {
1377
+ function parseTranslate$1(transform) {
1361
1378
  const match = transform.match(/translate\(([-\d.]+)px,\s*([-\d.]+)px\)/);
1362
1379
  if (match) {
1363
1380
  return { x: parseFloat(match[1]), y: parseFloat(match[2]) };
@@ -1420,15 +1437,15 @@ var __async = (__this, __arguments, generator) => {
1420
1437
  if (e.type === "touchstart") {
1421
1438
  e.preventDefault();
1422
1439
  }
1423
- const { clientX, clientY } = getClientCoords(e);
1440
+ const { clientX, clientY } = getClientCoords$1(e);
1424
1441
  state.isDragging = true;
1425
1442
  state.startX = clientX;
1426
1443
  state.startY = clientY;
1427
- const { x, y } = parseTranslate(el.style.transform);
1444
+ const { x, y } = parseTranslate$1(el.style.transform);
1428
1445
  state.offsetX = x;
1429
1446
  state.offsetY = y;
1430
1447
  if (state.options.constrain || state.options.boundary) {
1431
- const boundary = state.options.boundary ? getBoundary(el, state.options.boundary) : (_a = el.parentElement) == null ? void 0 : _a.getBoundingClientRect();
1448
+ const boundary = state.options.boundary ? getBoundary$1(el, state.options.boundary) : (_a = el.parentElement) == null ? void 0 : _a.getBoundingClientRect();
1432
1449
  if (boundary) {
1433
1450
  const elRect = el.getBoundingClientRect();
1434
1451
  state.initialLeft = elRect.left - boundary.left;
@@ -1443,7 +1460,7 @@ var __async = (__this, __arguments, generator) => {
1443
1460
  state.moveHandler = (moveEvent) => {
1444
1461
  var _a2, _b2;
1445
1462
  if (!state.isDragging) return;
1446
- const { clientX: moveX, clientY: moveY } = getClientCoords(moveEvent);
1463
+ const { clientX: moveX, clientY: moveY } = getClientCoords$1(moveEvent);
1447
1464
  let deltaX = moveX - state.startX, deltaY = moveY - state.startY;
1448
1465
  if (state.options.axis === "x") {
1449
1466
  deltaY = 0;
@@ -1481,7 +1498,7 @@ var __async = (__this, __arguments, generator) => {
1481
1498
  document.removeEventListener("mouseup", state.endHandler);
1482
1499
  document.removeEventListener("touchend", state.endHandler);
1483
1500
  }
1484
- const { x: finalX, y: finalY } = parseTranslate(el.style.transform);
1501
+ const { x: finalX, y: finalY } = parseTranslate$1(el.style.transform);
1485
1502
  (_b2 = (_a2 = state.options).onEnd) == null ? void 0 : _b2.call(_a2, { x: finalX, y: finalY }, new MouseEvent("mouseup"));
1486
1503
  };
1487
1504
  document.addEventListener("mousemove", state.moveHandler);
@@ -1657,7 +1674,7 @@ var __async = (__this, __arguments, generator) => {
1657
1674
  titleBehavior: (_d = binding == null ? void 0 : binding.titleBehavior) != null ? _d : "auto"
1658
1675
  };
1659
1676
  }
1660
- const FOCUSABLE_TAGS = /* @__PURE__ */ new Set(["input", "textarea", "select", "button"]);
1677
+ const FOCUSABLE_TAGS$1 = /* @__PURE__ */ new Set(["input", "textarea", "select", "button"]);
1661
1678
  function isEqual(a, b) {
1662
1679
  if (a === b) return true;
1663
1680
  if (typeof a !== "object" || typeof b !== "object" || a === null || b === null) return false;
@@ -1679,7 +1696,7 @@ var __async = (__this, __arguments, generator) => {
1679
1696
  mounted(el, binding) {
1680
1697
  if (!isBrowser()) return;
1681
1698
  const options = normalizeOptions$s(binding.value);
1682
- if (!options.focus || !isFocusable(el)) {
1699
+ if (!options.focus || !isFocusable$1(el)) {
1683
1700
  if (options.focus) {
1684
1701
  console.warn("[Directix] v-focus: Element is not focusable");
1685
1702
  }
@@ -1747,10 +1764,10 @@ var __async = (__this, __arguments, generator) => {
1747
1764
  refocus: false
1748
1765
  }, binding);
1749
1766
  }
1750
- function isFocusable(el) {
1767
+ function isFocusable$1(el) {
1751
1768
  if (!isBrowser()) return false;
1752
1769
  const tagName = el.tagName.toLowerCase();
1753
- if (FOCUSABLE_TAGS.has(tagName)) {
1770
+ if (FOCUSABLE_TAGS$1.has(tagName)) {
1754
1771
  return !el.disabled;
1755
1772
  }
1756
1773
  if (el.isContentEditable) return true;
@@ -1761,7 +1778,7 @@ var __async = (__this, __arguments, generator) => {
1761
1778
  }
1762
1779
  return false;
1763
1780
  }
1764
- const KEY_ALIASES = {
1781
+ const KEY_ALIASES$1 = {
1765
1782
  esc: "escape",
1766
1783
  space: " ",
1767
1784
  up: "arrowup",
@@ -1793,7 +1810,7 @@ var __async = (__this, __arguments, generator) => {
1793
1810
  const MODIFIER_KEYS = /* @__PURE__ */ new Set(["ctrl", "alt", "shift", "meta"]);
1794
1811
  function normalizeKey(key) {
1795
1812
  const lowerKey = key.toLowerCase();
1796
- return KEY_ALIASES[lowerKey] || lowerKey;
1813
+ return KEY_ALIASES$1[lowerKey] || lowerKey;
1797
1814
  }
1798
1815
  function parseHotkeyString(hotkey) {
1799
1816
  const parts = hotkey.toLowerCase().split(/[+.]/);
@@ -1808,7 +1825,7 @@ var __async = (__this, __arguments, generator) => {
1808
1825
  }
1809
1826
  return { key, modifiers };
1810
1827
  }
1811
- function matchesHotkey(event, entry) {
1828
+ function matchesHotkey$1(event, entry) {
1812
1829
  if (normalizeKey(event.key) !== entry.key) return false;
1813
1830
  const eventModifiers = /* @__PURE__ */ new Set();
1814
1831
  if (event.ctrlKey) eventModifiers.add("ctrl");
@@ -1895,7 +1912,7 @@ var __async = (__this, __arguments, generator) => {
1895
1912
  return (event) => {
1896
1913
  for (const entry of state.entries) {
1897
1914
  if (entry.disabled) continue;
1898
- if (!matchesHotkey(event, entry)) continue;
1915
+ if (!matchesHotkey$1(event, entry)) continue;
1899
1916
  if (entry.prevent) event.preventDefault();
1900
1917
  if (entry.stop) event.stopPropagation();
1901
1918
  entry.handler(event);
@@ -1935,6 +1952,61 @@ var __async = (__this, __arguments, generator) => {
1935
1952
  delete el.__hotkey;
1936
1953
  }
1937
1954
  });
1955
+ function useTimer() {
1956
+ const timeouts = /* @__PURE__ */ new Set();
1957
+ const intervals = /* @__PURE__ */ new Set();
1958
+ return {
1959
+ /**
1960
+ * Set a timeout (tracked for cleanup)
1961
+ */
1962
+ setTimeout(fn, delay) {
1963
+ const id = setTimeout(() => {
1964
+ timeouts.delete(id);
1965
+ fn();
1966
+ }, delay);
1967
+ timeouts.add(id);
1968
+ return id;
1969
+ },
1970
+ /**
1971
+ * Clear a specific timeout
1972
+ */
1973
+ clearTimeout(id) {
1974
+ clearTimeout(id);
1975
+ timeouts.delete(id);
1976
+ },
1977
+ /**
1978
+ * Set an interval (tracked for cleanup)
1979
+ */
1980
+ setInterval(fn, delay) {
1981
+ const id = setInterval(fn, delay);
1982
+ intervals.add(id);
1983
+ return id;
1984
+ },
1985
+ /**
1986
+ * Clear a specific interval
1987
+ */
1988
+ clearInterval(id) {
1989
+ clearInterval(id);
1990
+ intervals.delete(id);
1991
+ },
1992
+ /**
1993
+ * Clear all tracked timers
1994
+ */
1995
+ clearAll() {
1996
+ timeouts.forEach((id) => clearTimeout(id));
1997
+ intervals.forEach((id) => clearInterval(id));
1998
+ timeouts.clear();
1999
+ intervals.clear();
2000
+ },
2001
+ /**
2002
+ * Check if there are any active timers
2003
+ */
2004
+ hasActive() {
2005
+ return timeouts.size > 0 || intervals.size > 0;
2006
+ }
2007
+ };
2008
+ }
2009
+ const STATE_KEY$4 = "hover";
1938
2010
  function normalizeOptions$r(binding) {
1939
2011
  if (typeof binding === "function") {
1940
2012
  return { handler: binding, class: "v-hover" };
@@ -1946,6 +2018,26 @@ var __async = (__this, __arguments, generator) => {
1946
2018
  leaveDelay: 0
1947
2019
  }, binding);
1948
2020
  }
2021
+ function applyHoverState(el, state, e) {
2022
+ var _a, _b;
2023
+ const { options } = state;
2024
+ if (options.class) {
2025
+ el.classList.add(options.class);
2026
+ }
2027
+ el.dispatchEvent(new CustomEvent("hover:enter", { detail: { event: e } }));
2028
+ (_a = options.onEnter) == null ? void 0 : _a.call(options, e);
2029
+ (_b = options.handler) == null ? void 0 : _b.call(options, true, e);
2030
+ }
2031
+ function applyLeaveState(el, state, e) {
2032
+ var _a, _b;
2033
+ const { options } = state;
2034
+ if (options.class) {
2035
+ el.classList.remove(options.class);
2036
+ }
2037
+ el.dispatchEvent(new CustomEvent("hover:leave", { detail: { event: e } }));
2038
+ (_a = options.onLeave) == null ? void 0 : _a.call(options, e);
2039
+ (_b = options.handler) == null ? void 0 : _b.call(options, false, e);
2040
+ }
1949
2041
  const vHover = defineDirective({
1950
2042
  name: "hover",
1951
2043
  ssr: false,
@@ -1958,56 +2050,54 @@ var __async = (__this, __arguments, generator) => {
1958
2050
  mounted(el, binding) {
1959
2051
  const options = normalizeOptions$r(binding.value);
1960
2052
  if (options.disabled || !isBrowser()) return;
2053
+ const timer = useTimer();
2054
+ let isHovering = false;
1961
2055
  const state = {
1962
2056
  options,
1963
2057
  isHovering: false,
1964
- enterTimerId: null,
1965
- leaveTimerId: null,
1966
- enterHandler: () => {
1967
- },
1968
- leaveHandler: () => {
1969
- }
2058
+ timer,
2059
+ cleanup: null
1970
2060
  };
1971
- state.enterHandler = (e) => {
2061
+ const enterHandler = (e) => {
1972
2062
  const event = e;
1973
- if (state.leaveTimerId) {
1974
- clearTimeout(state.leaveTimerId);
1975
- state.leaveTimerId = null;
1976
- }
1977
- if (state.isHovering) return;
2063
+ timer.clearAll();
2064
+ if (isHovering) return;
1978
2065
  if (options.enterDelay && options.enterDelay > 0) {
1979
- state.enterTimerId = setTimeout(() => {
2066
+ timer.setTimeout(() => {
2067
+ isHovering = true;
1980
2068
  state.isHovering = true;
1981
2069
  applyHoverState(el, state, event);
1982
2070
  }, options.enterDelay);
1983
2071
  } else {
2072
+ isHovering = true;
1984
2073
  state.isHovering = true;
1985
2074
  applyHoverState(el, state, event);
1986
2075
  }
1987
2076
  };
1988
- state.leaveHandler = (e) => {
2077
+ const leaveHandler = (e) => {
1989
2078
  const event = e;
1990
- if (state.enterTimerId) {
1991
- clearTimeout(state.enterTimerId);
1992
- state.enterTimerId = null;
1993
- }
1994
- if (!state.isHovering) return;
2079
+ timer.clearAll();
2080
+ if (!isHovering) return;
1995
2081
  if (options.leaveDelay && options.leaveDelay > 0) {
1996
- state.leaveTimerId = setTimeout(() => {
2082
+ timer.setTimeout(() => {
2083
+ isHovering = false;
1997
2084
  state.isHovering = false;
1998
2085
  applyLeaveState(el, state, event);
1999
2086
  }, options.leaveDelay);
2000
2087
  } else {
2088
+ isHovering = false;
2001
2089
  state.isHovering = false;
2002
2090
  applyLeaveState(el, state, event);
2003
2091
  }
2004
2092
  };
2005
- el.__hover = state;
2006
- on(el, "mouseenter", state.enterHandler);
2007
- on(el, "mouseleave", state.leaveHandler);
2093
+ state.cleanup = bindEvents$2(el, {
2094
+ mouseenter: enterHandler,
2095
+ mouseleave: leaveHandler
2096
+ });
2097
+ setState$1(el, STATE_KEY$4, state);
2008
2098
  },
2009
2099
  updated(el, binding) {
2010
- const state = el.__hover;
2100
+ const state = getState$1(el, STATE_KEY$4);
2011
2101
  if (!state) return;
2012
2102
  const newOptions = normalizeOptions$r(binding.value);
2013
2103
  if (newOptions.disabled && !state.options.disabled) {
@@ -2016,40 +2106,15 @@ var __async = (__this, __arguments, generator) => {
2016
2106
  state.options = newOptions;
2017
2107
  },
2018
2108
  unmounted(el) {
2019
- const state = el.__hover;
2109
+ var _a;
2110
+ const state = getState$1(el, STATE_KEY$4);
2020
2111
  if (!state) return;
2021
- if (state.enterTimerId) {
2022
- clearTimeout(state.enterTimerId);
2023
- }
2024
- if (state.leaveTimerId) {
2025
- clearTimeout(state.leaveTimerId);
2026
- }
2027
- off(el, "mouseenter", state.enterHandler);
2028
- off(el, "mouseleave", state.leaveHandler);
2112
+ state.timer.clearAll();
2113
+ (_a = state.cleanup) == null ? void 0 : _a.call(state);
2029
2114
  el.classList.remove(state.options.class || "v-hover");
2030
- delete el.__hover;
2115
+ deleteState(el, STATE_KEY$4);
2031
2116
  }
2032
2117
  });
2033
- function applyHoverState(el, state, e) {
2034
- var _a, _b;
2035
- const { options } = state;
2036
- if (options.class) {
2037
- el.classList.add(options.class);
2038
- }
2039
- el.dispatchEvent(new CustomEvent("hover:enter", { detail: { event: e } }));
2040
- (_a = options.onEnter) == null ? void 0 : _a.call(options, e);
2041
- (_b = options.handler) == null ? void 0 : _b.call(options, true, e);
2042
- }
2043
- function applyLeaveState(el, state, e) {
2044
- var _a, _b;
2045
- const { options } = state;
2046
- if (options.class) {
2047
- el.classList.remove(options.class);
2048
- }
2049
- el.dispatchEvent(new CustomEvent("hover:leave", { detail: { event: e } }));
2050
- (_a = options.onLeave) == null ? void 0 : _a.call(options, e);
2051
- (_b = options.handler) == null ? void 0 : _b.call(options, false, e);
2052
- }
2053
2118
  const DEFAULTS = {
2054
2119
  minScale: 0.5,
2055
2120
  maxScale: 5,
@@ -2060,7 +2125,7 @@ var __async = (__this, __arguments, generator) => {
2060
2125
  zoomIndicatorDuration: 1500
2061
2126
  };
2062
2127
  let globalZIndex = 9999;
2063
- function getDistance$2(x1, y1, x2, y2) {
2128
+ function getDistance$3(x1, y1, x2, y2) {
2064
2129
  return Math.sqrt(__pow(x2 - x1, 2) + __pow(y2 - y1, 2));
2065
2130
  }
2066
2131
  function clamp(value, min, max) {
@@ -2243,7 +2308,7 @@ var __async = (__this, __arguments, generator) => {
2243
2308
  gesture.swipeStartY = e.touches[0].clientY;
2244
2309
  } else if (e.touches.length === 2 && options.enablePinchZoom !== false) {
2245
2310
  gesture.isDragging = false;
2246
- gesture.startDistance = getDistance$2(
2311
+ gesture.startDistance = getDistance$3(
2247
2312
  e.touches[0].clientX,
2248
2313
  e.touches[0].clientY,
2249
2314
  e.touches[1].clientX,
@@ -2264,7 +2329,7 @@ var __async = (__this, __arguments, generator) => {
2264
2329
  transform.translateY = constrained.y;
2265
2330
  updateTransform(false);
2266
2331
  } else if (e.touches.length === 2 && options.enablePinchZoom !== false) {
2267
- const currentDistance = getDistance$2(
2332
+ const currentDistance = getDistance$3(
2268
2333
  e.touches[0].clientX,
2269
2334
  e.touches[0].clientY,
2270
2335
  e.touches[1].clientX,
@@ -3033,7 +3098,7 @@ var __async = (__this, __arguments, generator) => {
3033
3098
  tickInterval: 100
3034
3099
  }, binding);
3035
3100
  }
3036
- function getDistance$1(p1, p2) {
3101
+ function getDistance$2(p1, p2) {
3037
3102
  return Math.sqrt(__pow(p2.x - p1.x, 2) + __pow(p2.y - p1.y, 2));
3038
3103
  }
3039
3104
  const vLongPress = defineDirective({
@@ -3080,7 +3145,7 @@ var __async = (__this, __arguments, generator) => {
3080
3145
  clearInterval(state.tickTimerId);
3081
3146
  state.tickTimerId = null;
3082
3147
  }
3083
- const pos = getEventPosition(event);
3148
+ const pos = getEventPosition$1(event);
3084
3149
  state.startPos = { x: pos.x, y: pos.y };
3085
3150
  state.startTime = Date.now();
3086
3151
  (_a = options.onStart) == null ? void 0 : _a.call(options, event);
@@ -3120,8 +3185,8 @@ var __async = (__this, __arguments, generator) => {
3120
3185
  var _a;
3121
3186
  if (!state.timerId) return;
3122
3187
  const event = e;
3123
- const pos = getEventPosition(event);
3124
- const distance = getDistance$1(state.startPos, { x: pos.x, y: pos.y });
3188
+ const pos = getEventPosition$1(event);
3189
+ const distance = getDistance$2(state.startPos, { x: pos.x, y: pos.y });
3125
3190
  if (distance > (options.distance || 10)) {
3126
3191
  if (state.timerId) {
3127
3192
  clearTimeout(state.timerId);
@@ -3356,7 +3421,7 @@ var __async = (__this, __arguments, generator) => {
3356
3421
  delete el[STATE_KEY$2];
3357
3422
  }
3358
3423
  });
3359
- function formatNumber(value, options) {
3424
+ function formatNumber$1(value, options) {
3360
3425
  const { precision = 0, separator = ",", decimal = ".", prefix = "", suffix = "" } = options;
3361
3426
  const fixed = value.toFixed(precision);
3362
3427
  const [intPart, decPart] = fixed.split(".");
@@ -3459,7 +3524,7 @@ var __async = (__this, __arguments, generator) => {
3459
3524
  el.removeEventListener("blur", onBlur);
3460
3525
  };
3461
3526
  }
3462
- function formatMoney(value, options) {
3527
+ function formatMoney$1(value, options) {
3463
3528
  const { precision = 2, separator = ",", decimal = ".", symbol = "$", symbolPosition = "before" } = options;
3464
3529
  const fixed = value.toFixed(precision);
3465
3530
  const [intPart, decPart] = fixed.split(".");
@@ -3480,14 +3545,14 @@ var __async = (__this, __arguments, generator) => {
3480
3545
  if (el.tagName === "INPUT" || el.tagName === "TEXTAREA") {
3481
3546
  const { symbol = "$", symbolPosition = "before" } = options;
3482
3547
  const prefix = symbolPosition === "before" ? symbol : "";
3483
- const cleanup2 = setupNumberInput(el, __spreadProps(__spreadValues({}, options), { prefix }), formatMoney);
3548
+ const cleanup2 = setupNumberInput(el, __spreadProps(__spreadValues({}, options), { prefix }), formatMoney$1);
3484
3549
  el.__money = { options, cleanup: cleanup2 };
3485
3550
  requestAnimationFrame(() => {
3486
3551
  const inputEl = el;
3487
3552
  if (inputEl.value) {
3488
3553
  const num = parseToNumber(inputEl.value, options.decimal || ".");
3489
3554
  if (num !== null) {
3490
- const formatted = formatMoney(clampValue(num, options), options);
3555
+ const formatted = formatMoney$1(clampValue(num, options), options);
3491
3556
  if (formatted !== inputEl.value) {
3492
3557
  inputEl.value = formatted;
3493
3558
  inputEl.dispatchEvent(new Event("input", { bubbles: true }));
@@ -3506,7 +3571,7 @@ var __async = (__this, __arguments, generator) => {
3506
3571
  }
3507
3572
  }
3508
3573
  if (value !== null) {
3509
- el.textContent = formatMoney(clampValue(value, options), options);
3574
+ el.textContent = formatMoney$1(clampValue(value, options), options);
3510
3575
  }
3511
3576
  }
3512
3577
  },
@@ -3523,7 +3588,7 @@ var __async = (__this, __arguments, generator) => {
3523
3588
  value = binding.value.value;
3524
3589
  }
3525
3590
  if (value !== null) {
3526
- el.textContent = formatMoney(clampValue(value, options), options);
3591
+ el.textContent = formatMoney$1(clampValue(value, options), options);
3527
3592
  }
3528
3593
  }
3529
3594
  },
@@ -3641,14 +3706,14 @@ var __async = (__this, __arguments, generator) => {
3641
3706
  var _a, _b;
3642
3707
  const options = typeof binding.value === "number" ? { precision: binding.value } : (_a = binding.value) != null ? _a : {};
3643
3708
  if (el.tagName === "INPUT" || el.tagName === "TEXTAREA") {
3644
- const cleanup2 = setupNumberInput(el, options, formatNumber);
3709
+ const cleanup2 = setupNumberInput(el, options, formatNumber$1);
3645
3710
  el.__number = { options, cleanup: cleanup2 };
3646
3711
  requestAnimationFrame(() => {
3647
3712
  const inputEl = el;
3648
3713
  if (inputEl.value) {
3649
3714
  const num = parseToNumber(inputEl.value, options.decimal || ".");
3650
3715
  if (num !== null) {
3651
- const formatted = formatNumber(clampValue(num, options), options);
3716
+ const formatted = formatNumber$1(clampValue(num, options), options);
3652
3717
  if (formatted !== inputEl.value) {
3653
3718
  inputEl.value = formatted;
3654
3719
  inputEl.dispatchEvent(new Event("input", { bubbles: true }));
@@ -3669,7 +3734,7 @@ var __async = (__this, __arguments, generator) => {
3669
3734
  }
3670
3735
  }
3671
3736
  if (value !== null) {
3672
- el.textContent = formatNumber(clampValue(value, options), options);
3737
+ el.textContent = formatNumber$1(clampValue(value, options), options);
3673
3738
  }
3674
3739
  }
3675
3740
  },
@@ -3687,7 +3752,7 @@ var __async = (__this, __arguments, generator) => {
3687
3752
  value = binding.value.value;
3688
3753
  }
3689
3754
  if (value !== null) {
3690
- el.textContent = formatNumber(clampValue(value, options), options);
3755
+ el.textContent = formatNumber$1(clampValue(value, options), options);
3691
3756
  }
3692
3757
  }
3693
3758
  },
@@ -3698,14 +3763,6 @@ var __async = (__this, __arguments, generator) => {
3698
3763
  }
3699
3764
  });
3700
3765
  const STATE_KEY$1 = "__permission";
3701
- const WILDCARD = "*";
3702
- let globalConfig = null;
3703
- function configurePermission(config) {
3704
- globalConfig = config;
3705
- }
3706
- function getPermissionConfig() {
3707
- return globalConfig;
3708
- }
3709
3766
  function normalizeOptions$h(binding) {
3710
3767
  if (!binding) {
3711
3768
  throw new Error("[Directix] v-permission: permission value is required");
@@ -3718,39 +3775,14 @@ var __async = (__this, __arguments, generator) => {
3718
3775
  }
3719
3776
  return binding;
3720
3777
  }
3721
- function hasPermission(required, permissions) {
3722
- return permissions.includes(WILDCARD) || permissions.includes(required);
3723
- }
3724
3778
  function verifyPermission(options) {
3725
- var _a;
3726
3779
  if (options.check) {
3727
3780
  return options.check(options.value, options.mode || "some");
3728
3781
  }
3729
- if (!globalConfig) {
3782
+ {
3730
3783
  console.warn("[Directix] v-permission: No permission config provided");
3731
3784
  return true;
3732
3785
  }
3733
- const permissions = globalConfig.getPermissions();
3734
- const roles = ((_a = globalConfig.getRoles) == null ? void 0 : _a.call(globalConfig)) || [];
3735
- const roleMap = globalConfig.roleMap || {};
3736
- const required = Array.isArray(options.value) ? options.value : [options.value];
3737
- const mode = options.mode || "some";
3738
- function checkSingle(value) {
3739
- if (value in roleMap) {
3740
- return roles.includes(value);
3741
- }
3742
- if (hasPermission(value, permissions)) {
3743
- return true;
3744
- }
3745
- for (const role of roles) {
3746
- const rolePermissions = roleMap[role] || [];
3747
- if (hasPermission(value, rolePermissions)) {
3748
- return true;
3749
- }
3750
- }
3751
- return false;
3752
- }
3753
- return mode === "every" ? required.every(checkSingle) : required.some(checkSingle);
3754
3786
  }
3755
3787
  function handleDenied(el, action, state) {
3756
3788
  var _a, _b;
@@ -3899,16 +3931,16 @@ var __async = (__this, __arguments, generator) => {
3899
3931
  return;
3900
3932
  }
3901
3933
  if (options.newWindow) {
3902
- yield printInNewWindow(targetEl, options);
3934
+ yield printInNewWindow$1(targetEl, options);
3903
3935
  } else {
3904
- yield printInIframe(targetEl, options);
3936
+ yield printInIframe$1(targetEl, options);
3905
3937
  }
3906
3938
  if (options.onAfterPrint) {
3907
3939
  options.onAfterPrint();
3908
3940
  }
3909
3941
  });
3910
3942
  }
3911
- function printInIframe(el, options) {
3943
+ function printInIframe$1(el, options) {
3912
3944
  return __async(this, null, function* () {
3913
3945
  var _a, _b, _c;
3914
3946
  const iframe = document.createElement("iframe");
@@ -3920,11 +3952,11 @@ var __async = (__this, __arguments, generator) => {
3920
3952
  document.body.removeChild(iframe);
3921
3953
  return;
3922
3954
  }
3923
- const content = buildPrintContent(el, options);
3955
+ const content = buildPrintContent$1(el, options);
3924
3956
  iframeDoc.open();
3925
3957
  iframeDoc.write(content);
3926
3958
  iframeDoc.close();
3927
- yield waitForImages(iframeDoc);
3959
+ yield waitForImages$1(iframeDoc);
3928
3960
  try {
3929
3961
  (_b = iframe.contentWindow) == null ? void 0 : _b.focus();
3930
3962
  (_c = iframe.contentWindow) == null ? void 0 : _c.print();
@@ -3936,18 +3968,18 @@ var __async = (__this, __arguments, generator) => {
3936
3968
  }, 1e3);
3937
3969
  });
3938
3970
  }
3939
- function printInNewWindow(el, options) {
3971
+ function printInNewWindow$1(el, options) {
3940
3972
  return __async(this, null, function* () {
3941
3973
  const printWindow = window.open("", "_blank");
3942
3974
  if (!printWindow) {
3943
3975
  console.warn("[Directix] v-print: Could not open print window");
3944
3976
  return;
3945
3977
  }
3946
- const content = buildPrintContent(el, options);
3978
+ const content = buildPrintContent$1(el, options);
3947
3979
  printWindow.document.open();
3948
3980
  printWindow.document.write(content);
3949
3981
  printWindow.document.close();
3950
- yield waitForImages(printWindow.document);
3982
+ yield waitForImages$1(printWindow.document);
3951
3983
  printWindow.focus();
3952
3984
  printWindow.print();
3953
3985
  setTimeout(() => {
@@ -3955,7 +3987,7 @@ var __async = (__this, __arguments, generator) => {
3955
3987
  }, 1e3);
3956
3988
  });
3957
3989
  }
3958
- function buildPrintContent(el, options) {
3990
+ function buildPrintContent$1(el, options) {
3959
3991
  let styles = "";
3960
3992
  document.querySelectorAll('style, link[rel="stylesheet"]').forEach((styleEl) => {
3961
3993
  if (styleEl.tagName === "STYLE") {
@@ -3996,7 +4028,7 @@ var __async = (__this, __arguments, generator) => {
3996
4028
  </body>
3997
4029
  </html>`;
3998
4030
  }
3999
- function waitForImages(doc) {
4031
+ function waitForImages$1(doc) {
4000
4032
  const images = doc.querySelectorAll("img");
4001
4033
  const promises = [];
4002
4034
  images.forEach((img) => {
@@ -4089,16 +4121,16 @@ var __async = (__this, __arguments, generator) => {
4089
4121
  try {
4090
4122
  yield internal.options.handler();
4091
4123
  setState(internal, "success");
4092
- yield sleep(internal.options.successDuration);
4124
+ yield sleep$1(internal.options.successDuration);
4093
4125
  } catch (e) {
4094
4126
  setState(internal, "error");
4095
- yield sleep(internal.options.errorDuration);
4127
+ yield sleep$1(internal.options.errorDuration);
4096
4128
  } finally {
4097
4129
  resetPosition(internal);
4098
4130
  }
4099
4131
  });
4100
4132
  }
4101
- function sleep(ms) {
4133
+ function sleep$1(ms) {
4102
4134
  return new Promise((resolve) => setTimeout(resolve, ms));
4103
4135
  }
4104
4136
  function createHandlers(internal) {
@@ -4824,8 +4856,8 @@ var __async = (__this, __arguments, generator) => {
4824
4856
  });
4825
4857
  const DEFAULT_THRESHOLD = 30;
4826
4858
  const DEFAULT_MAX_TIME = 500;
4827
- const DEFAULT_DIRECTIONS = ["left", "right", "up", "down"];
4828
- function getSwipeDirection(deltaX, deltaY, allowedDirections) {
4859
+ const DEFAULT_DIRECTIONS$1 = ["left", "right", "up", "down"];
4860
+ function getSwipeDirection$1(deltaX, deltaY, allowedDirections) {
4829
4861
  const absX = Math.abs(deltaX);
4830
4862
  const absY = Math.abs(deltaY);
4831
4863
  if (absX > absY) {
@@ -4843,7 +4875,7 @@ var __async = (__this, __arguments, generator) => {
4843
4875
  handler: binding.handler,
4844
4876
  threshold: (_a = binding.threshold) != null ? _a : DEFAULT_THRESHOLD,
4845
4877
  maxTime: (_b = binding.maxTime) != null ? _b : DEFAULT_MAX_TIME,
4846
- directions: (_c = binding.directions) != null ? _c : [...DEFAULT_DIRECTIONS],
4878
+ directions: (_c = binding.directions) != null ? _c : [...DEFAULT_DIRECTIONS$1],
4847
4879
  preventScrollOnSwipe: (_d = binding.preventScrollOnSwipe) != null ? _d : true,
4848
4880
  disabled: (_e = binding.disabled) != null ? _e : false,
4849
4881
  mouse: (_f = binding.mouse) != null ? _f : true,
@@ -4859,7 +4891,7 @@ var __async = (__this, __arguments, generator) => {
4859
4891
  if (deltaTime > ((_a = options.maxTime) != null ? _a : DEFAULT_MAX_TIME)) return;
4860
4892
  const distance = Math.max(Math.abs(deltaX), Math.abs(deltaY));
4861
4893
  if (distance < ((_b = options.threshold) != null ? _b : DEFAULT_THRESHOLD)) return;
4862
- const direction = getSwipeDirection(deltaX, deltaY, (_c = options.directions) != null ? _c : DEFAULT_DIRECTIONS);
4894
+ const direction = getSwipeDirection$1(deltaX, deltaY, (_c = options.directions) != null ? _c : DEFAULT_DIRECTIONS$1);
4863
4895
  if (!direction) return;
4864
4896
  if (options.preventScrollOnSwipe && event.cancelable) {
4865
4897
  event.preventDefault();
@@ -5348,7 +5380,7 @@ var __async = (__this, __arguments, generator) => {
5348
5380
  delete el.__tooltip;
5349
5381
  }
5350
5382
  });
5351
- const getDistance = (x1, y1, x2, y2) => Math.sqrt(__pow(x2 - x1, 2) + __pow(y2 - y1, 2));
5383
+ const getDistance$1 = (x1, y1, x2, y2) => Math.sqrt(__pow(x2 - x1, 2) + __pow(y2 - y1, 2));
5352
5384
  const getAngle = (x1, y1, x2, y2) => Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI;
5353
5385
  const MOUSE_IGNORE_DURATION = 400;
5354
5386
  const vTouch = defineDirective({
@@ -5426,7 +5458,7 @@ var __async = (__this, __arguments, generator) => {
5426
5458
  } else if (e.touches.length === 2) {
5427
5459
  clearLongPressTimer();
5428
5460
  const [t1, t2] = e.touches;
5429
- state.startDistance = getDistance(t1.clientX, t1.clientY, t2.clientX, t2.clientY);
5461
+ state.startDistance = getDistance$1(t1.clientX, t1.clientY, t2.clientX, t2.clientY);
5430
5462
  state.startAngle = getAngle(t1.clientX, t1.clientY, t2.clientX, t2.clientY);
5431
5463
  state.lastScale = 1;
5432
5464
  state.lastAngle = 0;
@@ -5443,7 +5475,7 @@ var __async = (__this, __arguments, generator) => {
5443
5475
  }
5444
5476
  if (e.touches.length === 2) {
5445
5477
  const [t1, t2] = e.touches;
5446
- const currentDistance = getDistance(t1.clientX, t1.clientY, t2.clientX, t2.clientY);
5478
+ const currentDistance = getDistance$1(t1.clientX, t1.clientY, t2.clientX, t2.clientY);
5447
5479
  const currentAngle = getAngle(t1.clientX, t1.clientY, t2.clientX, t2.clientY);
5448
5480
  if (state.options.enablePinch && state.options.onPinch) {
5449
5481
  const scale = currentDistance / state.startDistance;
@@ -5562,9 +5594,9 @@ var __async = (__this, __arguments, generator) => {
5562
5594
  onTouchEnd: binding == null ? void 0 : binding.onTouchEnd
5563
5595
  };
5564
5596
  }
5565
- function trimText(text, options) {
5597
+ function trimText$1(text, options) {
5566
5598
  const { position = "both", chars } = options;
5567
- const charPattern = chars ? `[\\s${escapeRegex(chars)}]` : "\\s";
5599
+ const charPattern = chars ? `[\\s${escapeRegex$2(chars)}]` : "\\s";
5568
5600
  switch (position) {
5569
5601
  case "start":
5570
5602
  return text.replace(new RegExp(`^${charPattern}+`, "g"), "");
@@ -5575,7 +5607,7 @@ var __async = (__this, __arguments, generator) => {
5575
5607
  return text.replace(new RegExp(`^${charPattern}+|${charPattern}+$`, "g"), "");
5576
5608
  }
5577
5609
  }
5578
- function escapeRegex(str) {
5610
+ function escapeRegex$2(str) {
5579
5611
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
5580
5612
  }
5581
5613
  const vTrim = defineDirective({
@@ -5587,7 +5619,7 @@ var __async = (__this, __arguments, generator) => {
5587
5619
  setupInputElement(el, options);
5588
5620
  } else {
5589
5621
  const text = el.textContent || "";
5590
- el.textContent = trimText(text, options);
5622
+ el.textContent = trimText$1(text, options);
5591
5623
  }
5592
5624
  },
5593
5625
  updated(el, binding) {
@@ -5599,7 +5631,7 @@ var __async = (__this, __arguments, generator) => {
5599
5631
  }
5600
5632
  } else {
5601
5633
  const text = el.textContent || "";
5602
- el.textContent = trimText(text, options);
5634
+ el.textContent = trimText$1(text, options);
5603
5635
  }
5604
5636
  },
5605
5637
  unmounted(el) {
@@ -5618,7 +5650,7 @@ var __async = (__this, __arguments, generator) => {
5618
5650
  el.__trim = state;
5619
5651
  const performTrim = () => {
5620
5652
  const originalValue = el.value;
5621
- const trimmed = trimText(originalValue, options);
5653
+ const trimmed = trimText$1(originalValue, options);
5622
5654
  if (originalValue !== trimmed) {
5623
5655
  el.value = trimmed;
5624
5656
  el.dispatchEvent(new Event("input", { bubbles: true }));
@@ -5667,7 +5699,7 @@ var __async = (__this, __arguments, generator) => {
5667
5699
  chars: binding.chars
5668
5700
  };
5669
5701
  }
5670
- function truncateText(text, options) {
5702
+ function truncateText$1(text, options) {
5671
5703
  const { length = 100, position = "end", ellipsis = "..." } = options;
5672
5704
  if (text.length <= length) {
5673
5705
  return text;
@@ -5730,7 +5762,7 @@ var __async = (__this, __arguments, generator) => {
5730
5762
  el.setAttribute("title", text);
5731
5763
  }
5732
5764
  } else {
5733
- const truncated = truncateText(text, options);
5765
+ const truncated = truncateText$1(text, options);
5734
5766
  el.textContent = truncated;
5735
5767
  if (showTitle && text && text !== truncated) {
5736
5768
  el.setAttribute("title", text);
@@ -6116,7 +6148,7 @@ var __async = (__this, __arguments, generator) => {
6116
6148
  state.options.handler(isVisible);
6117
6149
  }
6118
6150
  }
6119
- function createWatermarkCanvas(options) {
6151
+ function createWatermarkCanvas$1(options) {
6120
6152
  var _a;
6121
6153
  const canvas = document.createElement("canvas");
6122
6154
  const ctx = canvas.getContext("2d");
@@ -6232,7 +6264,7 @@ var __async = (__this, __arguments, generator) => {
6232
6264
  });
6233
6265
  function applyWatermark(el, state) {
6234
6266
  const options = state.options;
6235
- state.canvas = createWatermarkCanvas(options);
6267
+ state.canvas = createWatermarkCanvas$1(options);
6236
6268
  state.watermarkEl = createWatermarkElement(state.canvas, options);
6237
6269
  el.appendChild(state.watermarkEl);
6238
6270
  if (options.protect) {
@@ -6255,7 +6287,7 @@ var __async = (__this, __arguments, generator) => {
6255
6287
  state.observer = new MutationObserver((mutations) => {
6256
6288
  if (!state.watermarkEl || !el.contains(state.watermarkEl)) {
6257
6289
  if (!state.options.disabled) {
6258
- state.canvas = createWatermarkCanvas(state.options);
6290
+ state.canvas = createWatermarkCanvas$1(state.options);
6259
6291
  state.watermarkEl = createWatermarkElement(state.canvas, state.options);
6260
6292
  el.appendChild(state.watermarkEl);
6261
6293
  }
@@ -6280,6 +6312,2988 @@ var __async = (__this, __arguments, generator) => {
6280
6312
  attributeFilter: ["style", "class", "hidden"]
6281
6313
  });
6282
6314
  }
6315
+ const DEFAULT_KEEP_LOWER = [
6316
+ "a",
6317
+ "an",
6318
+ "the",
6319
+ "and",
6320
+ "but",
6321
+ "or",
6322
+ "for",
6323
+ "nor",
6324
+ "on",
6325
+ "at",
6326
+ "to",
6327
+ "from",
6328
+ "by",
6329
+ "in",
6330
+ "of",
6331
+ "with",
6332
+ "as"
6333
+ ];
6334
+ function capitalizeWord(word) {
6335
+ if (!word) return word;
6336
+ return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
6337
+ }
6338
+ function capitalizeText(text, options = {}) {
6339
+ if (!text) return text;
6340
+ const { every = true, keepLower = DEFAULT_KEEP_LOWER } = options;
6341
+ if (every) {
6342
+ const words = text.toLowerCase().split(/\s+/);
6343
+ return words.map((word, index) => {
6344
+ if (index === 0) {
6345
+ return capitalizeWord(word);
6346
+ }
6347
+ if (keepLower.includes(word.toLowerCase())) {
6348
+ return word.toLowerCase();
6349
+ }
6350
+ return capitalizeWord(word);
6351
+ }).join(" ");
6352
+ } else {
6353
+ return capitalizeWord(text);
6354
+ }
6355
+ }
6356
+ function useCapitalcase(options) {
6357
+ const {
6358
+ text,
6359
+ every = true,
6360
+ keepLower = DEFAULT_KEEP_LOWER
6361
+ } = options;
6362
+ const original = vue.ref(vue.unref(text));
6363
+ const capitalized = vue.ref("");
6364
+ function calculate() {
6365
+ const textValue = vue.unref(text);
6366
+ const everyValue = vue.unref(every);
6367
+ const keepLowerValue = vue.unref(keepLower);
6368
+ original.value = textValue;
6369
+ capitalized.value = capitalizeText(textValue, {
6370
+ every: everyValue,
6371
+ keepLower: keepLowerValue
6372
+ });
6373
+ }
6374
+ vue.watch(
6375
+ () => [vue.unref(text), vue.unref(every), vue.unref(keepLower)],
6376
+ () => calculate(),
6377
+ { immediate: true }
6378
+ );
6379
+ return {
6380
+ capitalized,
6381
+ original
6382
+ };
6383
+ }
6384
+ function createCapitalizer(options = {}) {
6385
+ return (text) => capitalizeText(text, options);
6386
+ }
6387
+ function useClickDelay(options) {
6388
+ const {
6389
+ handler,
6390
+ delay = 300,
6391
+ disabled = false
6392
+ } = options;
6393
+ const isPending = vue.ref(false);
6394
+ let timeoutId = null;
6395
+ const getDelay = () => vue.unref(delay);
6396
+ const getDisabled = () => vue.unref(disabled);
6397
+ function click(event) {
6398
+ if (getDisabled() || isPending.value) {
6399
+ event.preventDefault();
6400
+ event.stopPropagation();
6401
+ return;
6402
+ }
6403
+ isPending.value = true;
6404
+ handler(event);
6405
+ timeoutId = setTimeout(() => {
6406
+ isPending.value = false;
6407
+ timeoutId = null;
6408
+ }, getDelay());
6409
+ }
6410
+ function reset() {
6411
+ if (timeoutId) {
6412
+ clearTimeout(timeoutId);
6413
+ timeoutId = null;
6414
+ }
6415
+ isPending.value = false;
6416
+ }
6417
+ function cancel() {
6418
+ if (timeoutId) {
6419
+ clearTimeout(timeoutId);
6420
+ timeoutId = null;
6421
+ }
6422
+ }
6423
+ vue.onUnmounted(() => {
6424
+ cancel();
6425
+ });
6426
+ return {
6427
+ isPending,
6428
+ click,
6429
+ reset,
6430
+ cancel
6431
+ };
6432
+ }
6433
+ function createDelayedClick(handler, delay = 300) {
6434
+ let isPending = false;
6435
+ return (event) => {
6436
+ if (isPending) {
6437
+ event.preventDefault();
6438
+ event.stopPropagation();
6439
+ return;
6440
+ }
6441
+ isPending = true;
6442
+ handler(event);
6443
+ setTimeout(() => {
6444
+ isPending = false;
6445
+ }, delay);
6446
+ };
6447
+ }
6448
+ function isValidClick(el, event, exclude) {
6449
+ const target = event.target;
6450
+ if (el.contains(target)) {
6451
+ return false;
6452
+ }
6453
+ if (exclude == null ? void 0 : exclude.length) {
6454
+ for (const item of exclude) {
6455
+ const excludeEl = typeof item === "function" ? item() : vue.unref(item);
6456
+ const resolved = typeof excludeEl === "string" ? getElement(excludeEl) : excludeEl;
6457
+ if (resolved && (resolved === target || resolved.contains(target))) {
6458
+ return false;
6459
+ }
6460
+ }
6461
+ }
6462
+ return true;
6463
+ }
6464
+ function useClickOutside(options) {
6465
+ const {
6466
+ handler,
6467
+ exclude = [],
6468
+ capture = true,
6469
+ events = ["click"],
6470
+ stop = false,
6471
+ prevent = false
6472
+ } = options;
6473
+ let currentElement = null;
6474
+ const handlers = /* @__PURE__ */ new Map();
6475
+ function createEventHandler(_eventType) {
6476
+ return (event) => {
6477
+ if (!currentElement) return;
6478
+ if (!isValidClick(currentElement, event, exclude)) {
6479
+ return;
6480
+ }
6481
+ if (stop) {
6482
+ event.stopPropagation();
6483
+ }
6484
+ if (prevent) {
6485
+ event.preventDefault();
6486
+ }
6487
+ handler(event);
6488
+ };
6489
+ }
6490
+ function bind(element) {
6491
+ if (!isBrowser()) return () => {
6492
+ };
6493
+ unbind();
6494
+ currentElement = element;
6495
+ events.forEach((eventType) => {
6496
+ const eventHandler = createEventHandler();
6497
+ handlers.set(eventType, eventHandler);
6498
+ document.addEventListener(eventType, eventHandler, {
6499
+ capture,
6500
+ passive: !prevent
6501
+ });
6502
+ });
6503
+ return unbind;
6504
+ }
6505
+ function unbind() {
6506
+ handlers.forEach((eventHandler, eventType) => {
6507
+ document.removeEventListener(eventType, eventHandler, { capture });
6508
+ });
6509
+ handlers.clear();
6510
+ currentElement = null;
6511
+ }
6512
+ vue.onUnmounted(() => {
6513
+ unbind();
6514
+ });
6515
+ return {
6516
+ bind
6517
+ };
6518
+ }
6519
+ function copyToClipboard(text) {
6520
+ return __async(this, null, function* () {
6521
+ if (supportsClipboard()) {
6522
+ try {
6523
+ yield navigator.clipboard.writeText(text);
6524
+ return true;
6525
+ } catch (e) {
6526
+ console.warn("[Directix] Clipboard API failed, falling back to execCommand");
6527
+ }
6528
+ }
6529
+ return copyWithExecCommand(text);
6530
+ });
6531
+ }
6532
+ function copyWithExecCommand(text) {
6533
+ if (!isBrowser()) return false;
6534
+ const textarea = document.createElement("textarea");
6535
+ textarea.value = text;
6536
+ textarea.style.cssText = `
6537
+ position: fixed;
6538
+ top: -9999px;
6539
+ left: -9999px;
6540
+ opacity: 0;
6541
+ pointer-events: none;
6542
+ `;
6543
+ document.body.appendChild(textarea);
6544
+ try {
6545
+ textarea.select();
6546
+ textarea.setSelectionRange(0, textarea.value.length);
6547
+ return document.execCommand("copy");
6548
+ } catch (e) {
6549
+ return false;
6550
+ } finally {
6551
+ document.body.removeChild(textarea);
6552
+ }
6553
+ }
6554
+ function useCopy(options = {}) {
6555
+ const {
6556
+ source,
6557
+ onSuccess,
6558
+ onError,
6559
+ copiedTimeout = 1500
6560
+ } = options;
6561
+ const copied = vue.ref(false);
6562
+ const error = vue.ref(null);
6563
+ const isSupported = supportsClipboard() || isBrowser();
6564
+ let timeoutId = null;
6565
+ function copy(text) {
6566
+ return __async(this, null, function* () {
6567
+ const value = text != null ? text : vue.unref(source);
6568
+ if (!value) {
6569
+ console.warn("[Directix] useCopy: No text to copy");
6570
+ return false;
6571
+ }
6572
+ if (timeoutId) {
6573
+ clearTimeout(timeoutId);
6574
+ timeoutId = null;
6575
+ }
6576
+ error.value = null;
6577
+ try {
6578
+ const success = yield copyToClipboard(value);
6579
+ if (success) {
6580
+ copied.value = true;
6581
+ onSuccess == null ? void 0 : onSuccess(value);
6582
+ timeoutId = setTimeout(() => {
6583
+ copied.value = false;
6584
+ timeoutId = null;
6585
+ }, copiedTimeout);
6586
+ return true;
6587
+ } else {
6588
+ throw new Error("Copy failed");
6589
+ }
6590
+ } catch (err) {
6591
+ const copyError = err;
6592
+ error.value = copyError;
6593
+ copied.value = false;
6594
+ onError == null ? void 0 : onError(copyError);
6595
+ return false;
6596
+ }
6597
+ });
6598
+ }
6599
+ return {
6600
+ copy,
6601
+ copied: vue.readonly(copied),
6602
+ error: vue.readonly(error),
6603
+ isSupported
6604
+ };
6605
+ }
6606
+ function parseTargetTime(target) {
6607
+ if (target instanceof Date) {
6608
+ return target.getTime();
6609
+ }
6610
+ if (typeof target === "number") {
6611
+ return target;
6612
+ }
6613
+ return new Date(target).getTime();
6614
+ }
6615
+ function calculateTime(remaining) {
6616
+ const total = Math.max(0, remaining);
6617
+ return {
6618
+ days: Math.floor(total / (1e3 * 60 * 60 * 24)),
6619
+ hours: Math.floor(total % (1e3 * 60 * 60 * 24) / (1e3 * 60 * 60)),
6620
+ minutes: Math.floor(total % (1e3 * 60 * 60) / (1e3 * 60)),
6621
+ seconds: Math.floor(total % (1e3 * 60) / 1e3),
6622
+ milliseconds: total % 1e3,
6623
+ total
6624
+ };
6625
+ }
6626
+ function formatTime(time, format) {
6627
+ if (typeof format === "function") {
6628
+ return format(time);
6629
+ }
6630
+ const pad = (n, len = 2) => String(n).padStart(len, "0");
6631
+ const result = format.replace(/dd/gi, pad(time.days)).replace(/hh/gi, pad(time.hours)).replace(/mm/gi, pad(time.minutes)).replace(/ss/gi, pad(time.seconds)).replace(/S{3}/gi, pad(time.milliseconds, 3)).replace(/SS/gi, pad(Math.floor(time.milliseconds / 10))).replace(/S/gi, String(Math.floor(time.milliseconds / 100)));
6632
+ return result;
6633
+ }
6634
+ function useCountdown(options) {
6635
+ const {
6636
+ target,
6637
+ format = "hh:mm:ss",
6638
+ onComplete,
6639
+ onTick,
6640
+ interval = 1e3,
6641
+ autoStart = true
6642
+ } = options;
6643
+ const time = vue.ref(calculateTime(0));
6644
+ const formatted = vue.ref("");
6645
+ const running = vue.ref(false);
6646
+ const paused = vue.ref(false);
6647
+ const completed = vue.ref(false);
6648
+ let intervalId = null, targetTime = 0, remainingWhenPaused = 0;
6649
+ const getInterval = () => vue.unref(interval);
6650
+ const getFormat = () => vue.unref(format);
6651
+ function update() {
6652
+ const now = Date.now();
6653
+ const remaining = targetTime - now;
6654
+ if (remaining <= 0) {
6655
+ time.value = calculateTime(0);
6656
+ formatted.value = formatTime(time.value, getFormat());
6657
+ completed.value = true;
6658
+ running.value = false;
6659
+ stop();
6660
+ if (onComplete) {
6661
+ onComplete();
6662
+ }
6663
+ return;
6664
+ }
6665
+ time.value = calculateTime(remaining);
6666
+ formatted.value = formatTime(time.value, getFormat());
6667
+ if (onTick) {
6668
+ onTick(time.value);
6669
+ }
6670
+ }
6671
+ function start() {
6672
+ if (running.value) return;
6673
+ targetTime = parseTargetTime(vue.unref(target));
6674
+ running.value = true;
6675
+ paused.value = false;
6676
+ completed.value = false;
6677
+ update();
6678
+ intervalId = setInterval(update, getInterval());
6679
+ }
6680
+ function stop() {
6681
+ if (intervalId) {
6682
+ clearInterval(intervalId);
6683
+ intervalId = null;
6684
+ }
6685
+ running.value = false;
6686
+ }
6687
+ function pause() {
6688
+ if (!running.value) return;
6689
+ remainingWhenPaused = targetTime - Date.now();
6690
+ stop();
6691
+ paused.value = true;
6692
+ }
6693
+ function resume() {
6694
+ if (running.value || !paused.value) return;
6695
+ targetTime = Date.now() + remainingWhenPaused;
6696
+ running.value = true;
6697
+ paused.value = false;
6698
+ update();
6699
+ intervalId = setInterval(update, getInterval());
6700
+ }
6701
+ function reset() {
6702
+ stop();
6703
+ paused.value = false;
6704
+ completed.value = false;
6705
+ remainingWhenPaused = 0;
6706
+ time.value = calculateTime(0);
6707
+ formatted.value = formatTime(time.value, getFormat());
6708
+ }
6709
+ vue.watch(
6710
+ () => vue.unref(target),
6711
+ (newTarget) => {
6712
+ if (running.value) {
6713
+ targetTime = parseTargetTime(newTarget);
6714
+ }
6715
+ }
6716
+ );
6717
+ if (vue.unref(autoStart)) {
6718
+ start();
6719
+ }
6720
+ vue.onUnmounted(() => {
6721
+ stop();
6722
+ });
6723
+ return {
6724
+ time,
6725
+ formatted,
6726
+ running,
6727
+ paused,
6728
+ completed,
6729
+ start,
6730
+ pause,
6731
+ resume,
6732
+ reset
6733
+ };
6734
+ }
6735
+ function useDebounce(options) {
6736
+ const {
6737
+ handler,
6738
+ wait = 300,
6739
+ leading = false,
6740
+ trailing = true
6741
+ } = options;
6742
+ let timerId = null, lastArgs = null, lastThis = null;
6743
+ const invokeFunc = () => {
6744
+ if (lastArgs) {
6745
+ handler.apply(lastThis, lastArgs);
6746
+ lastArgs = null;
6747
+ lastThis = null;
6748
+ }
6749
+ };
6750
+ const getWait = () => vue.unref(wait);
6751
+ const getLeading = () => vue.unref(leading);
6752
+ const getTrailing = () => vue.unref(trailing);
6753
+ function run(...args) {
6754
+ lastArgs = args;
6755
+ lastThis = this;
6756
+ if (timerId) {
6757
+ clearTimeout(timerId);
6758
+ }
6759
+ if (getLeading() && !timerId) {
6760
+ invokeFunc();
6761
+ }
6762
+ timerId = setTimeout(() => {
6763
+ if (getTrailing()) {
6764
+ invokeFunc();
6765
+ }
6766
+ timerId = null;
6767
+ }, getWait());
6768
+ }
6769
+ function cancel() {
6770
+ if (timerId) {
6771
+ clearTimeout(timerId);
6772
+ timerId = null;
6773
+ }
6774
+ lastArgs = null;
6775
+ lastThis = null;
6776
+ }
6777
+ function flush() {
6778
+ if (timerId) {
6779
+ clearTimeout(timerId);
6780
+ invokeFunc();
6781
+ timerId = null;
6782
+ }
6783
+ }
6784
+ function pending() {
6785
+ return timerId !== null;
6786
+ }
6787
+ vue.onUnmounted(() => {
6788
+ cancel();
6789
+ });
6790
+ return {
6791
+ run,
6792
+ cancel,
6793
+ flush,
6794
+ pending
6795
+ };
6796
+ }
6797
+ function debounceFn(fn, wait = 300, options) {
6798
+ return debounce(fn, wait, options);
6799
+ }
6800
+ function getBoundary(boundary) {
6801
+ var _a, _b;
6802
+ if (!boundary) return null;
6803
+ if (typeof boundary === "function") {
6804
+ const boundaryEl = boundary();
6805
+ return (_a = boundaryEl == null ? void 0 : boundaryEl.getBoundingClientRect()) != null ? _a : null;
6806
+ }
6807
+ if (typeof boundary === "string") {
6808
+ const boundaryEl = document.querySelector(boundary);
6809
+ return (_b = boundaryEl == null ? void 0 : boundaryEl.getBoundingClientRect()) != null ? _b : null;
6810
+ }
6811
+ return boundary.getBoundingClientRect();
6812
+ }
6813
+ function getClientCoords(e) {
6814
+ if (e.type.startsWith("touch")) {
6815
+ const touch = e.touches[0] || e.changedTouches[0];
6816
+ return { clientX: touch.clientX, clientY: touch.clientY };
6817
+ }
6818
+ const mouseEvent = e;
6819
+ return { clientX: mouseEvent.clientX, clientY: mouseEvent.clientY };
6820
+ }
6821
+ function parseTranslate(transform) {
6822
+ const match = transform.match(/translate\(([-\d.]+)px,\s*([-\d.]+)px\)/);
6823
+ if (match) {
6824
+ return { x: parseFloat(match[1]), y: parseFloat(match[2]) };
6825
+ }
6826
+ return { x: 0, y: 0 };
6827
+ }
6828
+ function useDraggable(options = {}) {
6829
+ const {
6830
+ axis = "both",
6831
+ constrain = false,
6832
+ boundary,
6833
+ handle,
6834
+ grid,
6835
+ disabled = false,
6836
+ onStart,
6837
+ onDrag,
6838
+ onEnd
6839
+ } = options;
6840
+ const position = vue.ref({ x: 0, y: 0 });
6841
+ const isDragging = vue.ref(false);
6842
+ let currentElement = null, handleEl = null, startX = 0, startY = 0, offsetX = 0, offsetY = 0, initialLeft = 0, initialTop = 0, boundaryWidth = 0, boundaryHeight = 0, elWidth = 0, elHeight = 0;
6843
+ function startDrag(e) {
6844
+ var _a;
6845
+ if (vue.unref(disabled)) return;
6846
+ e.preventDefault();
6847
+ const { clientX, clientY } = getClientCoords(e);
6848
+ isDragging.value = true;
6849
+ startX = clientX;
6850
+ startY = clientY;
6851
+ const { x, y } = parseTranslate(currentElement.style.transform);
6852
+ offsetX = x;
6853
+ offsetY = y;
6854
+ if (vue.unref(constrain) || boundary) {
6855
+ const boundaryRect = boundary ? getBoundary(boundary) : (_a = currentElement.parentElement) == null ? void 0 : _a.getBoundingClientRect();
6856
+ if (boundaryRect) {
6857
+ const elRect = currentElement.getBoundingClientRect();
6858
+ initialLeft = elRect.left - boundaryRect.left;
6859
+ initialTop = elRect.top - boundaryRect.top;
6860
+ boundaryWidth = boundaryRect.width;
6861
+ boundaryHeight = boundaryRect.height;
6862
+ elWidth = elRect.width;
6863
+ elHeight = elRect.height;
6864
+ }
6865
+ }
6866
+ currentElement.classList.add("v-draggable--dragging");
6867
+ document.addEventListener("mousemove", handleDrag);
6868
+ document.addEventListener("mouseup", endDrag);
6869
+ document.addEventListener("touchmove", handleDrag, { passive: false });
6870
+ document.addEventListener("touchend", endDrag);
6871
+ onStart == null ? void 0 : onStart({ x: offsetX, y: offsetY }, e);
6872
+ }
6873
+ function handleDrag(e) {
6874
+ if (!isDragging.value || vue.unref(disabled)) return;
6875
+ e.preventDefault();
6876
+ const { clientX, clientY } = getClientCoords(e);
6877
+ let deltaX = clientX - startX, deltaY = clientY - startY, newX = offsetX + deltaX, newY = offsetY + deltaY;
6878
+ const currentAxis = vue.unref(axis);
6879
+ if (currentAxis === "x") {
6880
+ deltaY = 0;
6881
+ } else if (currentAxis === "y") {
6882
+ deltaX = 0;
6883
+ }
6884
+ const currentGrid = vue.unref(grid);
6885
+ if (currentGrid) {
6886
+ deltaX = Math.round(deltaX / currentGrid[0]) * currentGrid[0];
6887
+ deltaY = Math.round(deltaY / currentGrid[1]) * currentGrid[1];
6888
+ }
6889
+ if (vue.unref(constrain) || boundary) {
6890
+ const newLeft = initialLeft + deltaX;
6891
+ const newTop = initialTop + deltaY;
6892
+ const maxLeft = boundaryWidth - elWidth;
6893
+ const maxTop = boundaryHeight - elHeight;
6894
+ const constrainedLeft = Math.max(0, Math.min(newLeft, maxLeft));
6895
+ const constrainedTop = Math.max(0, Math.min(newTop, maxTop));
6896
+ newX = offsetX + (constrainedLeft - initialLeft);
6897
+ newY = offsetY + (constrainedTop - initialTop);
6898
+ }
6899
+ currentElement.style.transform = `translate(${newX}px, ${newY}px)`;
6900
+ position.value = { x: newX, y: newY };
6901
+ onDrag == null ? void 0 : onDrag({ x: newX, y: newY }, e);
6902
+ }
6903
+ function endDrag(e) {
6904
+ if (!isDragging.value) return;
6905
+ isDragging.value = false;
6906
+ currentElement == null ? void 0 : currentElement.classList.remove("v-draggable--dragging");
6907
+ document.removeEventListener("mousemove", handleDrag);
6908
+ document.removeEventListener("mouseup", endDrag);
6909
+ document.removeEventListener("touchmove", handleDrag);
6910
+ document.removeEventListener("touchend", endDrag);
6911
+ onEnd == null ? void 0 : onEnd(__spreadValues({}, position.value), e);
6912
+ }
6913
+ function reset() {
6914
+ if (currentElement) {
6915
+ currentElement.style.transform = "translate(0px, 0px)";
6916
+ position.value = { x: 0, y: 0 };
6917
+ }
6918
+ }
6919
+ function bind(element) {
6920
+ if (!isBrowser()) return () => {
6921
+ };
6922
+ unbind();
6923
+ currentElement = element;
6924
+ if (getComputedStyle(element).position === "static") {
6925
+ element.style.position = "absolute";
6926
+ }
6927
+ handleEl = handle ? element.querySelector(handle) : null;
6928
+ const target = handleEl || element;
6929
+ target.addEventListener("mousedown", startDrag);
6930
+ target.addEventListener("touchstart", startDrag, { passive: false });
6931
+ return unbind;
6932
+ }
6933
+ function unbind() {
6934
+ if (currentElement) {
6935
+ const target = handleEl || currentElement;
6936
+ target.removeEventListener("mousedown", startDrag);
6937
+ target.removeEventListener("touchstart", startDrag);
6938
+ }
6939
+ currentElement = null;
6940
+ handleEl = null;
6941
+ }
6942
+ vue.onUnmounted(() => {
6943
+ unbind();
6944
+ });
6945
+ return {
6946
+ position: vue.readonly(position),
6947
+ isDragging: vue.readonly(isDragging),
6948
+ reset,
6949
+ bind
6950
+ };
6951
+ }
6952
+ function measureTextWidth(text, fontSize = 14, fontFamily = "sans-serif") {
6953
+ if (typeof document === "undefined") return text.length * 8;
6954
+ const canvas = document.createElement("canvas");
6955
+ const ctx = canvas.getContext("2d");
6956
+ if (!ctx) return text.length * 8;
6957
+ ctx.font = `${fontSize}px ${fontFamily}`;
6958
+ return ctx.measureText(text).width;
6959
+ }
6960
+ function truncateToWidth(text, maxWidth, ellipsis = "...", fontSize = 14, fontFamily = "sans-serif") {
6961
+ if (maxWidth <= 0) return text;
6962
+ const textWidth = measureTextWidth(text, fontSize, fontFamily);
6963
+ if (textWidth <= maxWidth) return text;
6964
+ const ellipsisWidth = measureTextWidth(ellipsis, fontSize, fontFamily);
6965
+ const availableWidth = maxWidth - ellipsisWidth;
6966
+ if (availableWidth <= 0) return ellipsis;
6967
+ let low = 0, high = text.length;
6968
+ while (low < high) {
6969
+ const mid = Math.floor((low + high + 1) / 2);
6970
+ const truncatedText = text.slice(0, mid);
6971
+ const truncatedWidth = measureTextWidth(truncatedText, fontSize, fontFamily);
6972
+ if (truncatedWidth <= availableWidth) {
6973
+ low = mid;
6974
+ } else {
6975
+ high = mid - 1;
6976
+ }
6977
+ }
6978
+ return text.slice(0, low) + ellipsis;
6979
+ }
6980
+ function truncateToLines(text, lines, ellipsis = "...") {
6981
+ if (lines <= 0) return "";
6982
+ const avgCharsPerLine = 80;
6983
+ const maxChars = lines * avgCharsPerLine;
6984
+ if (text.length <= maxChars) return text;
6985
+ return text.slice(0, maxChars - ellipsis.length) + ellipsis;
6986
+ }
6987
+ function useEllipsis(options) {
6988
+ const {
6989
+ text,
6990
+ lines = 1,
6991
+ ellipsis = "...",
6992
+ maxWidth = 0
6993
+ } = options;
6994
+ const original = vue.ref(vue.unref(text));
6995
+ const truncated = vue.ref("");
6996
+ const isTruncated = vue.ref(false);
6997
+ function calculate() {
6998
+ const textValue = vue.unref(text);
6999
+ const linesValue = vue.unref(lines);
7000
+ const ellipsisValue = vue.unref(ellipsis);
7001
+ const maxWidthValue = vue.unref(maxWidth);
7002
+ original.value = textValue;
7003
+ if (!textValue) {
7004
+ truncated.value = "";
7005
+ isTruncated.value = false;
7006
+ return;
7007
+ }
7008
+ if (maxWidthValue > 0) {
7009
+ const result = truncateToWidth(textValue, maxWidthValue, ellipsisValue);
7010
+ truncated.value = result;
7011
+ isTruncated.value = result !== textValue;
7012
+ } else if (linesValue > 1) {
7013
+ const result = truncateToLines(textValue, linesValue, ellipsisValue);
7014
+ truncated.value = result;
7015
+ isTruncated.value = result !== textValue;
7016
+ } else {
7017
+ truncated.value = textValue;
7018
+ isTruncated.value = false;
7019
+ }
7020
+ }
7021
+ function calculateForWidth(width) {
7022
+ const textValue = vue.unref(text);
7023
+ const ellipsisValue = vue.unref(ellipsis);
7024
+ if (!textValue || width <= 0) return textValue || "";
7025
+ return truncateToWidth(textValue, width, ellipsisValue);
7026
+ }
7027
+ function wouldTruncate(width) {
7028
+ const textValue = vue.unref(text);
7029
+ if (!textValue || width <= 0) return false;
7030
+ const textWidth = measureTextWidth(textValue);
7031
+ return textWidth > width;
7032
+ }
7033
+ vue.watch(
7034
+ () => [vue.unref(text), vue.unref(lines), vue.unref(ellipsis), vue.unref(maxWidth)],
7035
+ () => calculate(),
7036
+ { immediate: true }
7037
+ );
7038
+ vue.onUnmounted(() => {
7039
+ });
7040
+ return {
7041
+ truncated,
7042
+ isTruncated,
7043
+ original,
7044
+ calculateForWidth,
7045
+ wouldTruncate
7046
+ };
7047
+ }
7048
+ function truncateText(text, maxLength, ellipsis = "...") {
7049
+ if (!text || text.length <= maxLength) return text;
7050
+ return text.slice(0, maxLength - ellipsis.length) + ellipsis;
7051
+ }
7052
+ function wouldTextTruncate(text, containerWidth, fontSize = 14) {
7053
+ return measureTextWidth(text, fontSize) > containerWidth;
7054
+ }
7055
+ const FOCUSABLE_TAGS = /* @__PURE__ */ new Set(["input", "textarea", "select", "button"]);
7056
+ function isFocusable(el) {
7057
+ if (!isBrowser()) return false;
7058
+ const tagName = el.tagName.toLowerCase();
7059
+ if (FOCUSABLE_TAGS.has(tagName)) {
7060
+ return !el.disabled;
7061
+ }
7062
+ if (el.isContentEditable) return true;
7063
+ const tabindex = el.getAttribute("tabindex");
7064
+ if (tabindex != null) return tabindex !== "-1";
7065
+ if (tagName === "a" || tagName === "area") {
7066
+ return el.hasAttribute("href");
7067
+ }
7068
+ return false;
7069
+ }
7070
+ function useFocus(options = {}) {
7071
+ const { onFocus, onBlur } = options;
7072
+ const isFocused = vue.ref(false);
7073
+ let currentElement = null, focusHandler = null, blurHandler = null;
7074
+ function focus() {
7075
+ if (currentElement && isFocusable(currentElement)) {
7076
+ currentElement.focus();
7077
+ }
7078
+ }
7079
+ function blur() {
7080
+ if (currentElement) {
7081
+ currentElement.blur();
7082
+ }
7083
+ }
7084
+ function bind(element) {
7085
+ if (!isBrowser()) return () => {
7086
+ };
7087
+ unbind();
7088
+ currentElement = element;
7089
+ focusHandler = (e) => {
7090
+ isFocused.value = true;
7091
+ onFocus == null ? void 0 : onFocus(e);
7092
+ };
7093
+ blurHandler = (e) => {
7094
+ isFocused.value = false;
7095
+ onBlur == null ? void 0 : onBlur(e);
7096
+ };
7097
+ element.addEventListener("focus", focusHandler);
7098
+ element.addEventListener("blur", blurHandler);
7099
+ isFocused.value = document.activeElement === element;
7100
+ return unbind;
7101
+ }
7102
+ function unbind() {
7103
+ if (currentElement) {
7104
+ if (focusHandler) {
7105
+ currentElement.removeEventListener("focus", focusHandler);
7106
+ }
7107
+ if (blurHandler) {
7108
+ currentElement.removeEventListener("blur", blurHandler);
7109
+ }
7110
+ }
7111
+ currentElement = null;
7112
+ focusHandler = null;
7113
+ blurHandler = null;
7114
+ isFocused.value = false;
7115
+ }
7116
+ vue.onUnmounted(() => {
7117
+ unbind();
7118
+ });
7119
+ return {
7120
+ isFocused: vue.readonly(isFocused),
7121
+ focus,
7122
+ blur,
7123
+ bind
7124
+ };
7125
+ }
7126
+ const KEY_ALIASES = {
7127
+ esc: "Escape",
7128
+ space: " ",
7129
+ up: "ArrowUp",
7130
+ down: "ArrowDown",
7131
+ left: "ArrowLeft",
7132
+ right: "ArrowRight",
7133
+ enter: "Enter",
7134
+ tab: "Tab",
7135
+ backspace: "Backspace",
7136
+ delete: "Delete",
7137
+ insert: "Insert",
7138
+ home: "Home",
7139
+ end: "End",
7140
+ pageup: "PageUp",
7141
+ pagedown: "PageDown",
7142
+ plus: "+",
7143
+ minus: "-"
7144
+ };
7145
+ const MODIFIERS = /* @__PURE__ */ new Set(["ctrl", "alt", "shift", "meta"]);
7146
+ function parseHotkey(hotkey) {
7147
+ const parts = hotkey.toLowerCase().split("+").map((p) => p.trim());
7148
+ const modifiers = /* @__PURE__ */ new Set();
7149
+ let key = "";
7150
+ for (const part of parts) {
7151
+ if (MODIFIERS.has(part)) {
7152
+ modifiers.add(part);
7153
+ } else {
7154
+ key = KEY_ALIASES[part] || part;
7155
+ }
7156
+ }
7157
+ return { key, modifiers };
7158
+ }
7159
+ function matchesHotkey(event, definition) {
7160
+ if (definition.modifiers.has("ctrl") !== (event.ctrlKey || event.metaKey)) return false;
7161
+ if (definition.modifiers.has("alt") !== event.altKey) return false;
7162
+ if (definition.modifiers.has("shift") !== event.shiftKey) return false;
7163
+ if (definition.modifiers.has("meta") !== event.metaKey) return false;
7164
+ const eventKey = event.key;
7165
+ const targetKey = definition.key;
7166
+ return eventKey.toLowerCase() === targetKey.toLowerCase();
7167
+ }
7168
+ function useHotkey(options = {}) {
7169
+ const {
7170
+ hotkey,
7171
+ hotkeys = [],
7172
+ target,
7173
+ enabled: initialEnabled = true
7174
+ } = options;
7175
+ const enabled = vue.ref(vue.unref(initialEnabled));
7176
+ const hotkeyMap = /* @__PURE__ */ new Map();
7177
+ let currentTarget = null, keydownHandler = null, keyupHandler = null;
7178
+ if (hotkey) {
7179
+ addHotkey(hotkey);
7180
+ }
7181
+ hotkeys.forEach(addHotkey);
7182
+ function addHotkey(def) {
7183
+ const parsed = parseHotkey(def.key);
7184
+ const key = parsed.key.toLowerCase();
7185
+ if (!hotkeyMap.has(key)) {
7186
+ hotkeyMap.set(key, []);
7187
+ }
7188
+ hotkeyMap.get(key).push(def);
7189
+ }
7190
+ function removeHotkey(key) {
7191
+ hotkeyMap.delete(key.toLowerCase());
7192
+ }
7193
+ function clearHotkeys() {
7194
+ hotkeyMap.clear();
7195
+ }
7196
+ function handleKeyEvent(event, isKeyup) {
7197
+ if (!enabled.value) return;
7198
+ const key = event.key.toLowerCase();
7199
+ const definitions = hotkeyMap.get(key);
7200
+ if (!definitions) return;
7201
+ for (const def of definitions) {
7202
+ if (vue.unref(def.disabled)) continue;
7203
+ if (!!def.keyup !== isKeyup) continue;
7204
+ const parsed = parseHotkey(def.key);
7205
+ if (matchesHotkey(event, parsed)) {
7206
+ if (def.prevent !== false) {
7207
+ event.preventDefault();
7208
+ }
7209
+ if (def.stop) {
7210
+ event.stopPropagation();
7211
+ }
7212
+ def.handler(event);
7213
+ break;
7214
+ }
7215
+ }
7216
+ }
7217
+ function bind() {
7218
+ if (!isBrowser()) return;
7219
+ unbind();
7220
+ currentTarget = target ? vue.unref(target) : document;
7221
+ keydownHandler = (e) => handleKeyEvent(e, false);
7222
+ keyupHandler = (e) => handleKeyEvent(e, true);
7223
+ currentTarget == null ? void 0 : currentTarget.addEventListener("keydown", keydownHandler);
7224
+ currentTarget == null ? void 0 : currentTarget.addEventListener("keyup", keyupHandler);
7225
+ }
7226
+ function unbind() {
7227
+ if (currentTarget) {
7228
+ if (keydownHandler) {
7229
+ currentTarget.removeEventListener("keydown", keydownHandler);
7230
+ }
7231
+ if (keyupHandler) {
7232
+ currentTarget.removeEventListener("keyup", keyupHandler);
7233
+ }
7234
+ }
7235
+ currentTarget = null;
7236
+ keydownHandler = null;
7237
+ keyupHandler = null;
7238
+ }
7239
+ function enable() {
7240
+ enabled.value = true;
7241
+ }
7242
+ function disable() {
7243
+ enabled.value = false;
7244
+ }
7245
+ function toggle() {
7246
+ enabled.value = !enabled.value;
7247
+ }
7248
+ vue.watch(enabled, (newEnabled) => {
7249
+ if (newEnabled) {
7250
+ bind();
7251
+ } else {
7252
+ unbind();
7253
+ }
7254
+ });
7255
+ if (target && typeof target === "object" && "value" in target) {
7256
+ vue.watch(target, () => {
7257
+ if (enabled.value) {
7258
+ bind();
7259
+ }
7260
+ });
7261
+ }
7262
+ if (enabled.value) {
7263
+ bind();
7264
+ }
7265
+ vue.onUnmounted(() => {
7266
+ unbind();
7267
+ });
7268
+ return {
7269
+ enabled,
7270
+ enable,
7271
+ disable,
7272
+ toggle,
7273
+ add: addHotkey,
7274
+ remove: removeHotkey,
7275
+ clear: clearHotkeys
7276
+ };
7277
+ }
7278
+ function useHover(options = {}) {
7279
+ const {
7280
+ onEnter,
7281
+ onLeave,
7282
+ class: hoverClass,
7283
+ enterDelay = 0,
7284
+ leaveDelay = 0
7285
+ } = options;
7286
+ const isHovering = vue.ref(false);
7287
+ let enterTimerId = null, leaveTimerId = null, currentElement = null;
7288
+ function clearTimers() {
7289
+ if (enterTimerId) {
7290
+ clearTimeout(enterTimerId);
7291
+ enterTimerId = null;
7292
+ }
7293
+ if (leaveTimerId) {
7294
+ clearTimeout(leaveTimerId);
7295
+ leaveTimerId = null;
7296
+ }
7297
+ }
7298
+ function handleMouseEnter(event) {
7299
+ if (leaveTimerId) {
7300
+ clearTimeout(leaveTimerId);
7301
+ leaveTimerId = null;
7302
+ }
7303
+ if (isHovering.value) return;
7304
+ const delay = vue.unref(enterDelay);
7305
+ if (delay && delay > 0) {
7306
+ enterTimerId = setTimeout(() => {
7307
+ isHovering.value = true;
7308
+ applyHoverState2();
7309
+ onEnter == null ? void 0 : onEnter(event);
7310
+ enterTimerId = null;
7311
+ }, delay);
7312
+ } else {
7313
+ isHovering.value = true;
7314
+ applyHoverState2();
7315
+ onEnter == null ? void 0 : onEnter(event);
7316
+ }
7317
+ }
7318
+ function handleMouseLeave(event) {
7319
+ if (enterTimerId) {
7320
+ clearTimeout(enterTimerId);
7321
+ enterTimerId = null;
7322
+ }
7323
+ if (!isHovering.value) return;
7324
+ const delay = vue.unref(leaveDelay);
7325
+ if (delay && delay > 0) {
7326
+ leaveTimerId = setTimeout(() => {
7327
+ isHovering.value = false;
7328
+ removeHoverState();
7329
+ onLeave == null ? void 0 : onLeave(event);
7330
+ leaveTimerId = null;
7331
+ }, delay);
7332
+ } else {
7333
+ isHovering.value = false;
7334
+ removeHoverState();
7335
+ onLeave == null ? void 0 : onLeave(event);
7336
+ }
7337
+ }
7338
+ function applyHoverState2() {
7339
+ if (currentElement && hoverClass) {
7340
+ currentElement.classList.add(hoverClass);
7341
+ }
7342
+ }
7343
+ function removeHoverState() {
7344
+ if (currentElement && hoverClass) {
7345
+ currentElement.classList.remove(hoverClass);
7346
+ }
7347
+ }
7348
+ function bind(element) {
7349
+ if (!isBrowser()) return () => {
7350
+ };
7351
+ currentElement = element;
7352
+ element.addEventListener("mouseenter", handleMouseEnter);
7353
+ element.addEventListener("mouseleave", handleMouseLeave);
7354
+ return () => {
7355
+ element.removeEventListener("mouseenter", handleMouseEnter);
7356
+ element.removeEventListener("mouseleave", handleMouseLeave);
7357
+ clearTimers();
7358
+ removeHoverState();
7359
+ currentElement = null;
7360
+ };
7361
+ }
7362
+ vue.onUnmounted(() => {
7363
+ clearTimers();
7364
+ removeHoverState();
7365
+ });
7366
+ return {
7367
+ isHovering,
7368
+ bind
7369
+ };
7370
+ }
7371
+ function useImagePreview(options = {}) {
7372
+ const {
7373
+ src: initialSrc,
7374
+ closeOnClickOutside = true,
7375
+ closeOnEsc = true,
7376
+ showCloseButton = true,
7377
+ onOpen,
7378
+ onClose
7379
+ } = options;
7380
+ const isOpen = vue.ref(false);
7381
+ const currentSrc = vue.ref("");
7382
+ let currentElement = null, overlay = null, clickHandler = null, keydownHandler = null;
7383
+ function createOverlay2() {
7384
+ const div = document.createElement("div");
7385
+ div.className = "v-image-preview";
7386
+ div.style.cssText = `
7387
+ position: fixed;
7388
+ top: 0;
7389
+ left: 0;
7390
+ right: 0;
7391
+ bottom: 0;
7392
+ z-index: 9999;
7393
+ background: rgba(0, 0, 0, 0.9);
7394
+ display: flex;
7395
+ align-items: center;
7396
+ justify-content: center;
7397
+ cursor: zoom-out;
7398
+ `;
7399
+ return div;
7400
+ }
7401
+ function open(src) {
7402
+ if (!isBrowser()) return;
7403
+ const imageSrc = src || (initialSrc && typeof initialSrc === "object" ? initialSrc.value : initialSrc);
7404
+ if (!imageSrc && !currentElement) return;
7405
+ const finalSrc = imageSrc || currentElement.src;
7406
+ currentSrc.value = finalSrc;
7407
+ overlay = createOverlay2();
7408
+ const img = document.createElement("img");
7409
+ img.src = finalSrc;
7410
+ img.style.cssText = `
7411
+ max-width: 90%;
7412
+ max-height: 90%;
7413
+ object-fit: contain;
7414
+ cursor: default;
7415
+ `;
7416
+ if (showCloseButton) {
7417
+ const closeBtn = document.createElement("button");
7418
+ closeBtn.className = "v-image-preview__close";
7419
+ closeBtn.innerHTML = "&times;";
7420
+ closeBtn.style.cssText = `
7421
+ position: absolute;
7422
+ top: 20px;
7423
+ right: 20px;
7424
+ width: 40px;
7425
+ height: 40px;
7426
+ border: none;
7427
+ background: rgba(255, 255, 255, 0.2);
7428
+ color: white;
7429
+ font-size: 24px;
7430
+ cursor: pointer;
7431
+ border-radius: 50%;
7432
+ display: flex;
7433
+ align-items: center;
7434
+ justify-content: center;
7435
+ `;
7436
+ closeBtn.addEventListener("click", (e) => {
7437
+ e.stopPropagation();
7438
+ close();
7439
+ });
7440
+ overlay.appendChild(closeBtn);
7441
+ }
7442
+ overlay.appendChild(img);
7443
+ document.body.appendChild(overlay);
7444
+ if (closeOnClickOutside) {
7445
+ clickHandler = close;
7446
+ overlay.addEventListener("click", clickHandler);
7447
+ }
7448
+ if (closeOnEsc) {
7449
+ keydownHandler = (e) => {
7450
+ if (e.key === "Escape") {
7451
+ close();
7452
+ }
7453
+ };
7454
+ document.addEventListener("keydown", keydownHandler);
7455
+ }
7456
+ isOpen.value = true;
7457
+ onOpen == null ? void 0 : onOpen();
7458
+ }
7459
+ function close() {
7460
+ if (overlay) {
7461
+ overlay.remove();
7462
+ overlay = null;
7463
+ }
7464
+ if (clickHandler) {
7465
+ document.removeEventListener("click", clickHandler);
7466
+ clickHandler = null;
7467
+ }
7468
+ if (keydownHandler) {
7469
+ document.removeEventListener("keydown", keydownHandler);
7470
+ keydownHandler = null;
7471
+ }
7472
+ isOpen.value = false;
7473
+ currentSrc.value = "";
7474
+ onClose == null ? void 0 : onClose();
7475
+ }
7476
+ function handleElementClick() {
7477
+ if (currentElement) {
7478
+ open(currentElement.src);
7479
+ }
7480
+ }
7481
+ function bind(element) {
7482
+ if (!isBrowser()) return () => {
7483
+ };
7484
+ unbind();
7485
+ currentElement = element;
7486
+ element.style.cursor = "zoom-in";
7487
+ element.addEventListener("click", handleElementClick);
7488
+ return unbind;
7489
+ }
7490
+ function unbind() {
7491
+ if (currentElement) {
7492
+ currentElement.style.cursor = "";
7493
+ currentElement.removeEventListener("click", handleElementClick);
7494
+ }
7495
+ currentElement = null;
7496
+ }
7497
+ vue.onUnmounted(() => {
7498
+ unbind();
7499
+ close();
7500
+ });
7501
+ return {
7502
+ isOpen: vue.readonly(isOpen),
7503
+ currentSrc: vue.readonly(currentSrc),
7504
+ open,
7505
+ close,
7506
+ bind
7507
+ };
7508
+ }
7509
+ function useIntersect(options = {}) {
7510
+ const {
7511
+ handler,
7512
+ onEnter,
7513
+ onLeave,
7514
+ onChange,
7515
+ root = null,
7516
+ rootMargin = "0px",
7517
+ threshold = 0,
7518
+ once = false
7519
+ } = options;
7520
+ const isIntersecting = vue.ref(false);
7521
+ const ratio = vue.ref(0);
7522
+ let observer = null, hasTriggeredOnce = false;
7523
+ function createObserver2() {
7524
+ if (!isBrowser() || !supportsIntersectionObserver()) {
7525
+ console.warn("[Directix] useIntersect: IntersectionObserver not supported");
7526
+ return null;
7527
+ }
7528
+ return new IntersectionObserver(
7529
+ (entries) => {
7530
+ for (const entry of entries) {
7531
+ if (once && hasTriggeredOnce) continue;
7532
+ const intersecting = entry.isIntersecting;
7533
+ isIntersecting.value = intersecting;
7534
+ ratio.value = entry.intersectionRatio;
7535
+ handler == null ? void 0 : handler(entry, observer);
7536
+ onChange == null ? void 0 : onChange(intersecting, entry);
7537
+ if (intersecting) {
7538
+ onEnter == null ? void 0 : onEnter(entry, observer);
7539
+ if (once) hasTriggeredOnce = true;
7540
+ } else {
7541
+ onLeave == null ? void 0 : onLeave(entry, observer);
7542
+ }
7543
+ }
7544
+ },
7545
+ {
7546
+ root: vue.unref(root),
7547
+ rootMargin,
7548
+ threshold
7549
+ }
7550
+ );
7551
+ }
7552
+ function bind(element) {
7553
+ if (!isBrowser()) return () => {
7554
+ };
7555
+ stop();
7556
+ observer = createObserver2();
7557
+ if (observer) {
7558
+ observer.observe(element);
7559
+ }
7560
+ return stop;
7561
+ }
7562
+ function stop() {
7563
+ if (observer) {
7564
+ observer.disconnect();
7565
+ observer = null;
7566
+ }
7567
+ isIntersecting.value = false;
7568
+ ratio.value = 0;
7569
+ }
7570
+ vue.onUnmounted(() => {
7571
+ stop();
7572
+ });
7573
+ return {
7574
+ isIntersecting: vue.readonly(isIntersecting),
7575
+ ratio: vue.readonly(ratio),
7576
+ bind,
7577
+ stop
7578
+ };
7579
+ }
7580
+ function getEventPosition(e) {
7581
+ if ("touches" in e && e.touches.length > 0) {
7582
+ return {
7583
+ x: e.touches[0].clientX,
7584
+ y: e.touches[0].clientY
7585
+ };
7586
+ }
7587
+ if ("clientX" in e) {
7588
+ return {
7589
+ x: e.clientX,
7590
+ y: e.clientY
7591
+ };
7592
+ }
7593
+ return { x: 0, y: 0 };
7594
+ }
7595
+ function getDistance(p1, p2) {
7596
+ return Math.sqrt(__pow(p2.x - p1.x, 2) + __pow(p2.y - p1.y, 2));
7597
+ }
7598
+ function useLongPress(options = {}) {
7599
+ const {
7600
+ duration = 500,
7601
+ distance = 10,
7602
+ onStart,
7603
+ onTrigger,
7604
+ onCancel,
7605
+ onTick,
7606
+ tickInterval = 100,
7607
+ prevent = true
7608
+ } = options;
7609
+ const isPressing = vue.ref(false);
7610
+ let timerId = null, tickTimerId = null, startPos = { x: 0, y: 0 }, startPosSet = false;
7611
+ function start(event) {
7612
+ if (!isBrowser()) return;
7613
+ if (prevent) {
7614
+ event.preventDefault();
7615
+ }
7616
+ clearTimers();
7617
+ startPos = getEventPosition(event);
7618
+ startPosSet = true;
7619
+ isPressing.value = true;
7620
+ onStart == null ? void 0 : onStart(event);
7621
+ if (onTick) {
7622
+ let remaining = vue.unref(duration);
7623
+ tickTimerId = setInterval(() => {
7624
+ remaining -= tickInterval;
7625
+ onTick == null ? void 0 : onTick(Math.max(0, remaining));
7626
+ }, tickInterval);
7627
+ }
7628
+ timerId = setTimeout(() => {
7629
+ clearTimers();
7630
+ isPressing.value = false;
7631
+ onTrigger == null ? void 0 : onTrigger(event);
7632
+ }, vue.unref(duration));
7633
+ }
7634
+ function stop(event) {
7635
+ if (!isPressing.value) return;
7636
+ clearTimers();
7637
+ startPosSet = false;
7638
+ isPressing.value = false;
7639
+ onCancel == null ? void 0 : onCancel(event);
7640
+ }
7641
+ function handleMove(event) {
7642
+ if (!isPressing.value || !startPosSet) return;
7643
+ const pos = getEventPosition(event);
7644
+ const dist = getDistance(startPos, pos);
7645
+ if (dist > vue.unref(distance)) {
7646
+ stop(event);
7647
+ }
7648
+ }
7649
+ function clearTimers() {
7650
+ if (timerId) {
7651
+ clearTimeout(timerId);
7652
+ timerId = null;
7653
+ }
7654
+ if (tickTimerId) {
7655
+ clearInterval(tickTimerId);
7656
+ tickTimerId = null;
7657
+ }
7658
+ }
7659
+ function bind(element) {
7660
+ element.addEventListener("mousedown", start);
7661
+ element.addEventListener("mouseup", stop);
7662
+ element.addEventListener("mouseleave", stop);
7663
+ element.addEventListener("mousemove", handleMove);
7664
+ element.addEventListener("touchstart", start, { passive: !prevent });
7665
+ element.addEventListener("touchend", stop);
7666
+ element.addEventListener("touchcancel", stop);
7667
+ element.addEventListener("touchmove", handleMove, { passive: true });
7668
+ return () => {
7669
+ element.removeEventListener("mousedown", start);
7670
+ element.removeEventListener("mouseup", stop);
7671
+ element.removeEventListener("mouseleave", stop);
7672
+ element.removeEventListener("mousemove", handleMove);
7673
+ element.removeEventListener("touchstart", start);
7674
+ element.removeEventListener("touchend", stop);
7675
+ element.removeEventListener("touchcancel", stop);
7676
+ element.removeEventListener("touchmove", handleMove);
7677
+ clearTimers();
7678
+ };
7679
+ }
7680
+ vue.onUnmounted(() => {
7681
+ clearTimers();
7682
+ });
7683
+ return {
7684
+ isPressing,
7685
+ start,
7686
+ stop,
7687
+ bind
7688
+ };
7689
+ }
7690
+ function lowercaseText(text, firstOnly = false) {
7691
+ if (!text) return text;
7692
+ if (firstOnly) {
7693
+ return text.charAt(0).toLowerCase() + text.slice(1);
7694
+ }
7695
+ return text.toLowerCase();
7696
+ }
7697
+ function useLowercase(options) {
7698
+ const {
7699
+ text,
7700
+ first = false
7701
+ } = options;
7702
+ const original = vue.ref(vue.unref(text));
7703
+ const transformed = vue.ref("");
7704
+ function calculate() {
7705
+ const textValue = vue.unref(text);
7706
+ const firstValue = vue.unref(first);
7707
+ original.value = textValue;
7708
+ transformed.value = lowercaseText(textValue, firstValue);
7709
+ }
7710
+ vue.watch(
7711
+ () => [vue.unref(text), vue.unref(first)],
7712
+ () => calculate(),
7713
+ { immediate: true }
7714
+ );
7715
+ return {
7716
+ transformed,
7717
+ original
7718
+ };
7719
+ }
7720
+ function createLowercaser(first = false) {
7721
+ return (text) => lowercaseText(text, first);
7722
+ }
7723
+ function formatMoney(value, options = {}) {
7724
+ const {
7725
+ precision = 2,
7726
+ separator = ",",
7727
+ decimal = ".",
7728
+ symbol = "$",
7729
+ symbolPosition = "before"
7730
+ } = options;
7731
+ const fixed = value.toFixed(precision);
7732
+ const [intPart, decPart] = fixed.split(".");
7733
+ const formattedInt = intPart.replace(/\B(?=(\d{3})+(?!\d))/g, separator);
7734
+ let result = formattedInt;
7735
+ if (precision > 0 && decPart) {
7736
+ result += decimal + decPart;
7737
+ }
7738
+ return symbolPosition === "before" ? symbol + result : result + symbol;
7739
+ }
7740
+ function parseMoney(formatted, options = {}) {
7741
+ const { decimal = ".", symbol = "$" } = options;
7742
+ let cleaned = formatted.replace(new RegExp(`[${symbol}\\s]`, "g"), "");
7743
+ if (decimal !== ".") {
7744
+ cleaned = cleaned.replace(/,/g, "");
7745
+ cleaned = cleaned.replace(new RegExp(`\\${decimal}`, "g"), ".");
7746
+ } else {
7747
+ cleaned = cleaned.replace(/,/g, "");
7748
+ }
7749
+ return parseFloat(cleaned) || 0;
7750
+ }
7751
+ function useMoney(options) {
7752
+ const {
7753
+ value,
7754
+ symbol = "$",
7755
+ symbolPosition = "before",
7756
+ precision = 2,
7757
+ separator = ",",
7758
+ decimal = "."
7759
+ } = options;
7760
+ const valueRef = vue.ref(vue.unref(value));
7761
+ function getFormatOptions() {
7762
+ return {
7763
+ precision: vue.unref(precision),
7764
+ separator: vue.unref(separator),
7765
+ decimal: vue.unref(decimal),
7766
+ symbol: vue.unref(symbol),
7767
+ symbolPosition: vue.unref(symbolPosition)
7768
+ };
7769
+ }
7770
+ const formatted = vue.computed(() => {
7771
+ return formatMoney(valueRef.value, getFormatOptions());
7772
+ });
7773
+ function parse(formattedString) {
7774
+ return parseMoney(formattedString, {
7775
+ decimal: vue.unref(decimal),
7776
+ symbol: vue.unref(symbol)
7777
+ });
7778
+ }
7779
+ vue.watch(
7780
+ () => vue.unref(value),
7781
+ (newValue) => {
7782
+ valueRef.value = newValue;
7783
+ }
7784
+ );
7785
+ return {
7786
+ value: valueRef,
7787
+ formatted,
7788
+ parse
7789
+ };
7790
+ }
7791
+ function createMoneyFormatter(options = {}) {
7792
+ return (value) => formatMoney(value, options);
7793
+ }
7794
+ function formatNumber(value, options = {}) {
7795
+ const {
7796
+ precision = 0,
7797
+ separator = ",",
7798
+ decimal = ".",
7799
+ prefix = "",
7800
+ suffix = ""
7801
+ } = options;
7802
+ const fixed = value.toFixed(precision);
7803
+ const [intPart, decPart] = fixed.split(".");
7804
+ const formattedInt = intPart.replace(/\B(?=(\d{3})+(?!\d))/g, separator);
7805
+ let result = formattedInt;
7806
+ if (precision > 0 && decPart) {
7807
+ result += decimal + decPart;
7808
+ }
7809
+ return prefix + result + suffix;
7810
+ }
7811
+ function parseNumber(formatted, options = {}) {
7812
+ const { decimal = ".", prefix = "", suffix = "" } = options;
7813
+ let cleaned = formatted.replace(new RegExp(`^${escapeRegex$1(prefix)}`), "").replace(new RegExp(`${escapeRegex$1(suffix)}$`), "").replace(/\s/g, "");
7814
+ if (decimal !== ".") {
7815
+ cleaned = cleaned.replace(/,/g, "");
7816
+ cleaned = cleaned.replace(new RegExp(`\\${decimal}`, "g"), ".");
7817
+ } else {
7818
+ cleaned = cleaned.replace(/,/g, "");
7819
+ }
7820
+ return parseFloat(cleaned) || 0;
7821
+ }
7822
+ function escapeRegex$1(str) {
7823
+ return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
7824
+ }
7825
+ function useNumber(options) {
7826
+ const {
7827
+ value,
7828
+ precision = 0,
7829
+ separator = ",",
7830
+ decimal = ".",
7831
+ prefix = "",
7832
+ suffix = ""
7833
+ } = options;
7834
+ const valueRef = vue.ref(vue.unref(value));
7835
+ function getFormatOptions() {
7836
+ return {
7837
+ precision: vue.unref(precision),
7838
+ separator: vue.unref(separator),
7839
+ decimal: vue.unref(decimal),
7840
+ prefix: vue.unref(prefix),
7841
+ suffix: vue.unref(suffix)
7842
+ };
7843
+ }
7844
+ const formatted = vue.computed(() => {
7845
+ return formatNumber(valueRef.value, getFormatOptions());
7846
+ });
7847
+ function parse(formattedString) {
7848
+ return parseNumber(formattedString, {
7849
+ decimal: vue.unref(decimal),
7850
+ prefix: vue.unref(prefix),
7851
+ suffix: vue.unref(suffix)
7852
+ });
7853
+ }
7854
+ vue.watch(
7855
+ () => vue.unref(value),
7856
+ (newValue) => {
7857
+ valueRef.value = newValue;
7858
+ }
7859
+ );
7860
+ return {
7861
+ value: valueRef,
7862
+ formatted,
7863
+ parse
7864
+ };
7865
+ }
7866
+ function createNumberFormatter(options = {}) {
7867
+ return (value) => formatNumber(value, options);
7868
+ }
7869
+ const WILDCARD = "*";
7870
+ function hasPermission(required, permissions) {
7871
+ return permissions.includes(WILDCARD) || permissions.includes(required);
7872
+ }
7873
+ function usePermission(options) {
7874
+ const {
7875
+ value,
7876
+ mode = "some",
7877
+ check,
7878
+ getPermissions,
7879
+ getRoles,
7880
+ roleMap = {}
7881
+ } = options;
7882
+ const granted = vue.ref(false);
7883
+ function verifyPermission2() {
7884
+ if (check) {
7885
+ return check(vue.unref(value), vue.unref(mode));
7886
+ }
7887
+ if (!getPermissions) {
7888
+ console.warn("[Directix] usePermission: getPermissions function is required");
7889
+ return true;
7890
+ }
7891
+ const permissions = getPermissions();
7892
+ const roles = (getRoles == null ? void 0 : getRoles()) || [];
7893
+ const required = Array.isArray(vue.unref(value)) ? vue.unref(value) : [vue.unref(value)];
7894
+ const currentMode = vue.unref(mode);
7895
+ function checkSingle(perm) {
7896
+ if (perm in roleMap) {
7897
+ return roles.includes(perm);
7898
+ }
7899
+ if (hasPermission(perm, permissions)) {
7900
+ return true;
7901
+ }
7902
+ for (const role of roles) {
7903
+ const rolePermissions = roleMap[role] || [];
7904
+ if (hasPermission(perm, rolePermissions)) {
7905
+ return true;
7906
+ }
7907
+ }
7908
+ return false;
7909
+ }
7910
+ return currentMode === "every" ? required.every(checkSingle) : required.some(checkSingle);
7911
+ }
7912
+ function recheck() {
7913
+ granted.value = verifyPermission2();
7914
+ }
7915
+ vue.watch(
7916
+ () => vue.unref(value),
7917
+ () => recheck(),
7918
+ { immediate: true }
7919
+ );
7920
+ if (typeof mode === "object" && "value" in mode) {
7921
+ vue.watch(mode, () => recheck());
7922
+ }
7923
+ return {
7924
+ granted: vue.readonly(granted),
7925
+ recheck
7926
+ };
7927
+ }
7928
+ function createPermissionChecker(config) {
7929
+ const { getPermissions, getRoles, roleMap = {} } = config;
7930
+ return (value, mode = "some") => {
7931
+ const permissions = getPermissions();
7932
+ const roles = (getRoles == null ? void 0 : getRoles()) || [];
7933
+ const required = Array.isArray(value) ? value : [value];
7934
+ function checkSingle(perm) {
7935
+ if (perm in roleMap) {
7936
+ return roles.includes(perm);
7937
+ }
7938
+ if (hasPermission(perm, permissions)) {
7939
+ return true;
7940
+ }
7941
+ for (const role of roles) {
7942
+ const rolePermissions = roleMap[role] || [];
7943
+ if (hasPermission(perm, rolePermissions)) {
7944
+ return true;
7945
+ }
7946
+ }
7947
+ return false;
7948
+ }
7949
+ return mode === "every" ? required.every(checkSingle) : required.some(checkSingle);
7950
+ };
7951
+ }
7952
+ function waitForImages(doc) {
7953
+ const images = doc.querySelectorAll("img");
7954
+ const promises = [];
7955
+ images.forEach((img) => {
7956
+ if (!img.complete) {
7957
+ promises.push(
7958
+ new Promise((resolve) => {
7959
+ img.onload = () => resolve();
7960
+ img.onerror = () => resolve();
7961
+ })
7962
+ );
7963
+ }
7964
+ });
7965
+ return Promise.all(promises);
7966
+ }
7967
+ function buildPrintContent(el, options) {
7968
+ let styles = "";
7969
+ if (typeof document !== "undefined") {
7970
+ document.querySelectorAll('style, link[rel="stylesheet"]').forEach((styleEl) => {
7971
+ if (styleEl.tagName === "STYLE") {
7972
+ styles += `<style>${styleEl.textContent}</style>`;
7973
+ } else if (styleEl.tagName === "LINK") {
7974
+ const href = styleEl.href;
7975
+ styles += `<link rel="stylesheet" href="${href}">`;
7976
+ }
7977
+ });
7978
+ }
7979
+ options.cssUrls.forEach((url) => {
7980
+ styles += `<link rel="stylesheet" href="${url}">`;
7981
+ });
7982
+ if (options.styles) {
7983
+ styles += `<style>${options.styles}</style>`;
7984
+ }
7985
+ styles += `
7986
+ <style>
7987
+ @media print {
7988
+ body { margin: 0; padding: 20px; }
7989
+ ${options.printClass ? `.${options.printClass} { page-break-inside: avoid; }` : ""}
7990
+ }
7991
+ </style>
7992
+ `;
7993
+ const title = options.title || (typeof document !== "undefined" ? document.title : "Print");
7994
+ const content = el.outerHTML;
7995
+ return `<!DOCTYPE html>
7996
+ <html>
7997
+ <head>
7998
+ <meta charset="utf-8">
7999
+ <title>${title}</title>
8000
+ ${styles}
8001
+ </head>
8002
+ <body>
8003
+ ${content}
8004
+ </body>
8005
+ </html>`;
8006
+ }
8007
+ function printInIframe(el, options) {
8008
+ return __async(this, null, function* () {
8009
+ var _a, _b, _c;
8010
+ const iframe = document.createElement("iframe");
8011
+ iframe.style.cssText = "position: absolute; top: -10000px; left: -10000px; width: 0; height: 0; border: none;";
8012
+ document.body.appendChild(iframe);
8013
+ const iframeDoc = iframe.contentDocument || ((_a = iframe.contentWindow) == null ? void 0 : _a.document);
8014
+ if (!iframeDoc) {
8015
+ console.warn("[Directix] usePrint: Could not access iframe document");
8016
+ document.body.removeChild(iframe);
8017
+ return;
8018
+ }
8019
+ const content = buildPrintContent(el, options);
8020
+ iframeDoc.open();
8021
+ iframeDoc.write(content);
8022
+ iframeDoc.close();
8023
+ yield waitForImages(iframeDoc);
8024
+ try {
8025
+ (_b = iframe.contentWindow) == null ? void 0 : _b.focus();
8026
+ (_c = iframe.contentWindow) == null ? void 0 : _c.print();
8027
+ } catch (err) {
8028
+ console.error("[Directix] usePrint: Print failed", err);
8029
+ }
8030
+ setTimeout(() => {
8031
+ document.body.removeChild(iframe);
8032
+ }, 1e3);
8033
+ });
8034
+ }
8035
+ function printInNewWindow(el, options) {
8036
+ return __async(this, null, function* () {
8037
+ const printWindow = window.open("", "_blank");
8038
+ if (!printWindow) {
8039
+ console.warn("[Directix] usePrint: Could not open print window");
8040
+ return;
8041
+ }
8042
+ const content = buildPrintContent(el, options);
8043
+ printWindow.document.open();
8044
+ printWindow.document.write(content);
8045
+ printWindow.document.close();
8046
+ yield waitForImages(printWindow.document);
8047
+ printWindow.focus();
8048
+ printWindow.print();
8049
+ setTimeout(() => {
8050
+ printWindow.close();
8051
+ }, 1e3);
8052
+ });
8053
+ }
8054
+ function usePrint(options = {}) {
8055
+ const {
8056
+ title,
8057
+ styles,
8058
+ cssUrls = [],
8059
+ onBeforePrint,
8060
+ onAfterPrint,
8061
+ newWindow = false,
8062
+ printClass
8063
+ } = options;
8064
+ const isPrinting = vue.ref(false);
8065
+ function print(target) {
8066
+ return __async(this, null, function* () {
8067
+ if (onBeforePrint) {
8068
+ const result = onBeforePrint();
8069
+ if (result === false) return;
8070
+ }
8071
+ isPrinting.value = true;
8072
+ try {
8073
+ let targetEl = null;
8074
+ if (typeof target === "string") {
8075
+ targetEl = document.querySelector(target);
8076
+ } else if (target instanceof HTMLElement) {
8077
+ targetEl = target;
8078
+ } else {
8079
+ targetEl = document.body;
8080
+ }
8081
+ if (!targetEl) {
8082
+ console.warn("[Directix] usePrint: Target element not found");
8083
+ return;
8084
+ }
8085
+ const printOptions = {
8086
+ title: vue.unref(title) || "",
8087
+ styles: Array.isArray(vue.unref(styles)) ? vue.unref(styles).join("\n") : vue.unref(styles) || "",
8088
+ cssUrls: vue.unref(cssUrls) || [],
8089
+ printClass: vue.unref(printClass)
8090
+ };
8091
+ if (vue.unref(newWindow)) {
8092
+ yield printInNewWindow(targetEl, printOptions);
8093
+ } else {
8094
+ yield printInIframe(targetEl, printOptions);
8095
+ }
8096
+ if (onAfterPrint) {
8097
+ onAfterPrint();
8098
+ }
8099
+ } finally {
8100
+ isPrinting.value = false;
8101
+ }
8102
+ });
8103
+ }
8104
+ function printPage() {
8105
+ return __async(this, null, function* () {
8106
+ yield print();
8107
+ });
8108
+ }
8109
+ vue.onUnmounted(() => {
8110
+ });
8111
+ return {
8112
+ isPrinting,
8113
+ print,
8114
+ printPage
8115
+ };
8116
+ }
8117
+ function quickPrint(_0) {
8118
+ return __async(this, arguments, function* (target, options = {}) {
8119
+ const { print } = usePrint(options);
8120
+ yield print(target);
8121
+ });
8122
+ }
8123
+ function sleep(ms) {
8124
+ return new Promise((resolve) => setTimeout(resolve, ms));
8125
+ }
8126
+ function usePullRefresh(options) {
8127
+ const {
8128
+ handler,
8129
+ distance = 60,
8130
+ maxDistance = 100,
8131
+ disabled = false,
8132
+ successDuration = 500,
8133
+ errorDuration = 1e3
8134
+ } = options;
8135
+ const state = vue.ref("idle");
8136
+ const distanceValue = vue.ref(0);
8137
+ const isPulling = vue.ref(false);
8138
+ const containerRef = vue.ref(null);
8139
+ let startY = 0, currentY = 0;
8140
+ const getDistance2 = () => vue.unref(distance);
8141
+ const getMaxDistance = () => vue.unref(maxDistance);
8142
+ const getDisabled = () => vue.unref(disabled);
8143
+ const getSuccessDuration = () => vue.unref(successDuration);
8144
+ const getErrorDuration = () => vue.unref(errorDuration);
8145
+ function reset() {
8146
+ state.value = "idle";
8147
+ distanceValue.value = 0;
8148
+ isPulling.value = false;
8149
+ }
8150
+ function refresh() {
8151
+ return __async(this, null, function* () {
8152
+ state.value = "loading";
8153
+ try {
8154
+ yield handler();
8155
+ state.value = "success";
8156
+ yield sleep(getSuccessDuration());
8157
+ } catch (e) {
8158
+ state.value = "error";
8159
+ yield sleep(getErrorDuration());
8160
+ } finally {
8161
+ reset();
8162
+ }
8163
+ });
8164
+ }
8165
+ function touchstart(e) {
8166
+ if (getDisabled() || state.value === "loading") return;
8167
+ const container = containerRef.value;
8168
+ if (container && container.scrollTop > 0) return;
8169
+ isPulling.value = true;
8170
+ startY = e.touches[0].clientY;
8171
+ currentY = startY;
8172
+ state.value = "idle";
8173
+ }
8174
+ function touchmove(e) {
8175
+ if (!isPulling.value || getDisabled() || state.value === "loading") return;
8176
+ currentY = e.touches[0].clientY;
8177
+ const diff = currentY - startY;
8178
+ if (diff <= 0) {
8179
+ distanceValue.value = 0;
8180
+ state.value = "idle";
8181
+ return;
8182
+ }
8183
+ e.preventDefault();
8184
+ const calculatedDistance = Math.min(diff * 0.5, getMaxDistance());
8185
+ distanceValue.value = calculatedDistance;
8186
+ const progress = calculatedDistance / getDistance2();
8187
+ state.value = progress >= 1 ? "ready" : "pulling";
8188
+ }
8189
+ function touchend() {
8190
+ if (!isPulling.value || getDisabled()) return;
8191
+ isPulling.value = false;
8192
+ if (state.value === "ready" && distanceValue.value >= getDistance2()) {
8193
+ refresh();
8194
+ } else {
8195
+ distanceValue.value = 0;
8196
+ reset();
8197
+ }
8198
+ }
8199
+ vue.onUnmounted(() => {
8200
+ reset();
8201
+ });
8202
+ return {
8203
+ state,
8204
+ distance: distanceValue,
8205
+ isPulling,
8206
+ events: {
8207
+ touchstart,
8208
+ touchmove,
8209
+ touchend
8210
+ },
8211
+ containerRef,
8212
+ refresh
8213
+ };
8214
+ }
8215
+ function useResize(options = {}) {
8216
+ const {
8217
+ debounce: debounce2 = 0,
8218
+ box = "content-box",
8219
+ onResize
8220
+ } = options;
8221
+ const width = vue.ref(0);
8222
+ const height = vue.ref(0);
8223
+ let observer = null, debounceTimer = null, fallbackIframe = null;
8224
+ function handleResize(entry) {
8225
+ const currentDebounce = vue.unref(debounce2);
8226
+ function doUpdate() {
8227
+ width.value = entry.contentRect.width;
8228
+ height.value = entry.contentRect.height;
8229
+ onResize == null ? void 0 : onResize({
8230
+ width: entry.contentRect.width,
8231
+ height: entry.contentRect.height,
8232
+ contentRect: entry.contentRect
8233
+ });
8234
+ }
8235
+ if (currentDebounce && currentDebounce > 0) {
8236
+ if (debounceTimer) {
8237
+ clearTimeout(debounceTimer);
8238
+ }
8239
+ debounceTimer = setTimeout(doUpdate, currentDebounce);
8240
+ } else {
8241
+ doUpdate();
8242
+ }
8243
+ }
8244
+ function createObserver2() {
8245
+ if (!isBrowser()) return;
8246
+ if (supportsResizeObserver()) {
8247
+ observer = new ResizeObserver((entries) => {
8248
+ for (const entry of entries) {
8249
+ handleResize(entry);
8250
+ }
8251
+ });
8252
+ }
8253
+ }
8254
+ function bind(element) {
8255
+ if (!isBrowser()) return () => {
8256
+ };
8257
+ stop();
8258
+ const rect = element.getBoundingClientRect();
8259
+ width.value = rect.width;
8260
+ height.value = rect.height;
8261
+ if (supportsResizeObserver()) {
8262
+ createObserver2();
8263
+ observer == null ? void 0 : observer.observe(element, { box });
8264
+ } else {
8265
+ fallbackIframe = document.createElement("iframe");
8266
+ fallbackIframe.style.cssText = `
8267
+ position: absolute;
8268
+ top: 0;
8269
+ left: 0;
8270
+ width: 100%;
8271
+ height: 100%;
8272
+ border: none;
8273
+ pointer-events: none;
8274
+ opacity: 0;
8275
+ `;
8276
+ const computedStyle = getComputedStyle(element);
8277
+ if (computedStyle.position === "static") {
8278
+ element.style.position = "relative";
8279
+ }
8280
+ element.appendChild(fallbackIframe);
8281
+ const iWindow = fallbackIframe.contentWindow;
8282
+ if (iWindow) {
8283
+ iWindow.addEventListener("resize", () => {
8284
+ const rect2 = element.getBoundingClientRect();
8285
+ handleResize({
8286
+ contentRect: rect2
8287
+ });
8288
+ });
8289
+ }
8290
+ }
8291
+ return stop;
8292
+ }
8293
+ function stop() {
8294
+ if (observer) {
8295
+ observer.disconnect();
8296
+ observer = null;
8297
+ }
8298
+ if (fallbackIframe) {
8299
+ fallbackIframe.remove();
8300
+ fallbackIframe = null;
8301
+ }
8302
+ if (debounceTimer) {
8303
+ clearTimeout(debounceTimer);
8304
+ debounceTimer = null;
8305
+ }
8306
+ }
8307
+ vue.onUnmounted(() => {
8308
+ stop();
8309
+ });
8310
+ return {
8311
+ width: vue.readonly(width),
8312
+ height: vue.readonly(height),
8313
+ bind,
8314
+ stop
8315
+ };
8316
+ }
8317
+ function getScrollInfoFromContainer(container, lastScrollLeft, lastScrollTop) {
8318
+ let scrollLeft = 0, scrollTop = 0, scrollLeftMax = 0, scrollTopMax = 0;
8319
+ if (container === window) {
8320
+ scrollLeft = window.scrollX || document.documentElement.scrollLeft;
8321
+ scrollTop = window.scrollY || document.documentElement.scrollTop;
8322
+ scrollLeftMax = document.documentElement.scrollWidth - window.innerWidth;
8323
+ scrollTopMax = document.documentElement.scrollHeight - window.innerHeight;
8324
+ } else {
8325
+ const el = container;
8326
+ scrollLeft = el.scrollLeft;
8327
+ scrollTop = el.scrollTop;
8328
+ scrollLeftMax = el.scrollWidth - el.clientWidth;
8329
+ scrollTopMax = el.scrollHeight - el.clientHeight;
8330
+ }
8331
+ const progressX = scrollLeftMax > 0 ? scrollLeft / scrollLeftMax : 0;
8332
+ const progressY = scrollTopMax > 0 ? scrollTop / scrollTopMax : 0;
8333
+ const directionX = scrollLeft !== lastScrollLeft ? scrollLeft > lastScrollLeft ? 1 : -1 : 0;
8334
+ const directionY = scrollTop !== lastScrollTop ? scrollTop > lastScrollTop ? 1 : -1 : 0;
8335
+ return {
8336
+ scrollLeft,
8337
+ scrollTop,
8338
+ scrollLeftMax,
8339
+ scrollTopMax,
8340
+ progressX,
8341
+ progressY,
8342
+ directionX,
8343
+ directionY
8344
+ };
8345
+ }
8346
+ function useScroll(options = {}) {
8347
+ const { throttle: throttle2 = 0, passive = true } = options;
8348
+ const scrollLeft = vue.ref(0);
8349
+ const scrollTop = vue.ref(0);
8350
+ const progressX = vue.ref(0);
8351
+ const progressY = vue.ref(0);
8352
+ const directionX = vue.ref(0);
8353
+ const directionY = vue.ref(0);
8354
+ const isScrolling = vue.ref(false);
8355
+ let container = null, lastScrollLeft = 0, lastScrollTop = 0, scrollHandler = null, throttleTimer = null, scrollTimeout = null;
8356
+ const info = vue.computed(() => ({
8357
+ scrollLeft: scrollLeft.value,
8358
+ scrollTop: scrollTop.value,
8359
+ scrollLeftMax: 0,
8360
+ scrollTopMax: 0,
8361
+ progressX: progressX.value,
8362
+ progressY: progressY.value,
8363
+ directionX: directionX.value,
8364
+ directionY: directionY.value
8365
+ }));
8366
+ function updateScrollInfo(_e) {
8367
+ if (!container) return;
8368
+ const currentThrottle = vue.unref(throttle2);
8369
+ function doUpdate() {
8370
+ const scrollInfo = getScrollInfoFromContainer(container, lastScrollLeft, lastScrollTop);
8371
+ scrollLeft.value = scrollInfo.scrollLeft;
8372
+ scrollTop.value = scrollInfo.scrollTop;
8373
+ progressX.value = scrollInfo.progressX;
8374
+ progressY.value = scrollInfo.progressY;
8375
+ directionX.value = scrollInfo.directionX;
8376
+ directionY.value = scrollInfo.directionY;
8377
+ lastScrollLeft = scrollInfo.scrollLeft;
8378
+ lastScrollTop = scrollInfo.scrollTop;
8379
+ isScrolling.value = true;
8380
+ if (scrollTimeout) {
8381
+ clearTimeout(scrollTimeout);
8382
+ }
8383
+ scrollTimeout = setTimeout(() => {
8384
+ isScrolling.value = false;
8385
+ }, 150);
8386
+ }
8387
+ if (currentThrottle && currentThrottle > 0) {
8388
+ if (!throttleTimer) {
8389
+ throttleTimer = setTimeout(() => {
8390
+ doUpdate();
8391
+ throttleTimer = null;
8392
+ }, currentThrottle);
8393
+ }
8394
+ } else {
8395
+ doUpdate();
8396
+ }
8397
+ }
8398
+ function bind(element) {
8399
+ if (!isBrowser()) return () => {
8400
+ };
8401
+ stop();
8402
+ if (element) {
8403
+ container = element;
8404
+ } else {
8405
+ container = window;
8406
+ }
8407
+ const initialInfo = getScrollInfoFromContainer(container, 0, 0);
8408
+ scrollLeft.value = initialInfo.scrollLeft;
8409
+ scrollTop.value = initialInfo.scrollTop;
8410
+ progressX.value = initialInfo.progressX;
8411
+ progressY.value = initialInfo.progressY;
8412
+ lastScrollLeft = initialInfo.scrollLeft;
8413
+ lastScrollTop = initialInfo.scrollTop;
8414
+ scrollHandler = updateScrollInfo;
8415
+ container.addEventListener("scroll", scrollHandler, { passive });
8416
+ return stop;
8417
+ }
8418
+ function stop() {
8419
+ if (container && scrollHandler) {
8420
+ container.removeEventListener("scroll", scrollHandler);
8421
+ }
8422
+ if (throttleTimer) {
8423
+ clearTimeout(throttleTimer);
8424
+ throttleTimer = null;
8425
+ }
8426
+ if (scrollTimeout) {
8427
+ clearTimeout(scrollTimeout);
8428
+ scrollTimeout = null;
8429
+ }
8430
+ container = null;
8431
+ scrollHandler = null;
8432
+ }
8433
+ function scrollTo(opts) {
8434
+ if (!container) return;
8435
+ const { top, left, behavior = "smooth" } = opts;
8436
+ if (container === window) {
8437
+ window.scrollTo({
8438
+ top,
8439
+ left,
8440
+ behavior
8441
+ });
8442
+ } else {
8443
+ const el = container;
8444
+ if (top !== void 0) el.scrollTop = top;
8445
+ if (left !== void 0) el.scrollLeft = left;
8446
+ }
8447
+ }
8448
+ vue.onUnmounted(() => {
8449
+ stop();
8450
+ });
8451
+ return {
8452
+ scrollLeft: vue.readonly(scrollLeft),
8453
+ scrollTop: vue.readonly(scrollTop),
8454
+ progressX: vue.readonly(progressX),
8455
+ progressY: vue.readonly(progressY),
8456
+ directionX: vue.readonly(directionX),
8457
+ directionY: vue.readonly(directionY),
8458
+ isScrolling: vue.readonly(isScrolling),
8459
+ info: vue.readonly(info),
8460
+ bind,
8461
+ stop,
8462
+ scrollTo
8463
+ };
8464
+ }
8465
+ const DEFAULT_DIRECTIONS = ["left", "right", "up", "down"];
8466
+ function getSwipeDirection(deltaX, deltaY, allowedDirections) {
8467
+ const absX = Math.abs(deltaX);
8468
+ const absY = Math.abs(deltaY);
8469
+ if (absX > absY) {
8470
+ const direction = deltaX > 0 ? "right" : "left";
8471
+ return allowedDirections.includes(direction) ? direction : null;
8472
+ } else {
8473
+ const direction = deltaY > 0 ? "down" : "up";
8474
+ return allowedDirections.includes(direction) ? direction : null;
8475
+ }
8476
+ }
8477
+ function useSwipe(options = {}) {
8478
+ const {
8479
+ handler,
8480
+ threshold = 30,
8481
+ maxTime = 500,
8482
+ directions = DEFAULT_DIRECTIONS,
8483
+ preventScrollOnSwipe = true,
8484
+ mouse = true,
8485
+ onLeft,
8486
+ onRight,
8487
+ onUp,
8488
+ onDown
8489
+ } = options;
8490
+ const direction = vue.ref(null);
8491
+ const lengthX = vue.ref(0);
8492
+ const lengthY = vue.ref(0);
8493
+ const isSwiping = vue.ref(false);
8494
+ let currentElement = null, startX = 0, startY = 0, startTime = 0;
8495
+ function triggerSwipe2(deltaX, deltaY, deltaTime, event) {
8496
+ var _a;
8497
+ const currentThreshold = vue.unref(threshold);
8498
+ const currentMaxTime = vue.unref(maxTime);
8499
+ if (deltaTime > currentMaxTime) return;
8500
+ const distance = Math.max(Math.abs(deltaX), Math.abs(deltaY));
8501
+ if (distance < currentThreshold) return;
8502
+ const swipeDirection = getSwipeDirection(deltaX, deltaY, directions);
8503
+ if (!swipeDirection) return;
8504
+ direction.value = swipeDirection;
8505
+ lengthX.value = deltaX;
8506
+ lengthY.value = deltaY;
8507
+ if (preventScrollOnSwipe && event.cancelable) {
8508
+ event.preventDefault();
8509
+ }
8510
+ handler == null ? void 0 : handler(swipeDirection, event);
8511
+ const callbacks = {
8512
+ left: onLeft,
8513
+ right: onRight,
8514
+ up: onUp,
8515
+ down: onDown
8516
+ };
8517
+ (_a = callbacks[swipeDirection]) == null ? void 0 : _a.call(callbacks);
8518
+ currentElement == null ? void 0 : currentElement.dispatchEvent(new CustomEvent("swipe", {
8519
+ detail: { direction: swipeDirection, deltaX, deltaY, deltaTime }
8520
+ }));
8521
+ }
8522
+ function handleStart(clientX, clientY) {
8523
+ startX = clientX;
8524
+ startY = clientY;
8525
+ startTime = Date.now();
8526
+ isSwiping.value = true;
8527
+ direction.value = null;
8528
+ lengthX.value = 0;
8529
+ lengthY.value = 0;
8530
+ }
8531
+ function handleEnd(clientX, clientY, event) {
8532
+ if (!isSwiping.value) return;
8533
+ isSwiping.value = false;
8534
+ const deltaX = clientX - startX;
8535
+ const deltaY = clientY - startY;
8536
+ const deltaTime = Date.now() - startTime;
8537
+ triggerSwipe2(deltaX, deltaY, deltaTime, event);
8538
+ }
8539
+ function touchStart(e) {
8540
+ handleStart(e.touches[0].clientX, e.touches[0].clientY);
8541
+ }
8542
+ function touchMove(e) {
8543
+ if (!isSwiping.value || !preventScrollOnSwipe) return;
8544
+ e.preventDefault();
8545
+ }
8546
+ function touchEnd(e) {
8547
+ const touch = e.changedTouches[0];
8548
+ handleEnd(touch.clientX, touch.clientY, e);
8549
+ }
8550
+ function mouseDown(e) {
8551
+ handleStart(e.clientX, e.clientY);
8552
+ }
8553
+ function mouseUp(e) {
8554
+ handleEnd(e.clientX, e.clientY, e);
8555
+ }
8556
+ function mouseLeave(e) {
8557
+ if (isSwiping.value) {
8558
+ handleEnd(e.clientX, e.clientY, e);
8559
+ }
8560
+ }
8561
+ function bind(element) {
8562
+ if (!isBrowser()) return () => {
8563
+ };
8564
+ unbind();
8565
+ currentElement = element;
8566
+ element.style.touchAction = "none";
8567
+ element.style.userSelect = "none";
8568
+ element.addEventListener("touchstart", touchStart, { passive: true });
8569
+ element.addEventListener("touchmove", touchMove, { passive: false });
8570
+ element.addEventListener("touchend", touchEnd);
8571
+ element.addEventListener("touchcancel", touchEnd);
8572
+ if (vue.unref(mouse)) {
8573
+ element.addEventListener("mousedown", mouseDown);
8574
+ element.addEventListener("mouseup", mouseUp);
8575
+ element.addEventListener("mouseleave", mouseLeave);
8576
+ }
8577
+ return unbind;
8578
+ }
8579
+ function unbind() {
8580
+ if (!currentElement) return;
8581
+ currentElement.removeEventListener("touchstart", touchStart);
8582
+ currentElement.removeEventListener("touchmove", touchMove);
8583
+ currentElement.removeEventListener("touchend", touchEnd);
8584
+ currentElement.removeEventListener("touchcancel", touchEnd);
8585
+ if (vue.unref(mouse)) {
8586
+ currentElement.removeEventListener("mousedown", mouseDown);
8587
+ currentElement.removeEventListener("mouseup", mouseUp);
8588
+ currentElement.removeEventListener("mouseleave", mouseLeave);
8589
+ }
8590
+ currentElement = null;
8591
+ }
8592
+ vue.onUnmounted(() => {
8593
+ unbind();
8594
+ });
8595
+ return {
8596
+ direction: vue.readonly(direction),
8597
+ lengthX: vue.readonly(lengthX),
8598
+ lengthY: vue.readonly(lengthY),
8599
+ isSwiping: vue.readonly(isSwiping),
8600
+ bind
8601
+ };
8602
+ }
8603
+ function useThrottle(options) {
8604
+ const {
8605
+ handler,
8606
+ wait = 300,
8607
+ leading = true,
8608
+ trailing = true
8609
+ } = options;
8610
+ let timerId = null, lastArgs = null, lastThis = null, lastCallTime = 0;
8611
+ const getWait = () => vue.unref(wait);
8612
+ const getLeading = () => vue.unref(leading);
8613
+ const getTrailing = () => vue.unref(trailing);
8614
+ const invokeFunc = () => {
8615
+ if (lastArgs) {
8616
+ handler.apply(lastThis, lastArgs);
8617
+ lastArgs = null;
8618
+ lastThis = null;
8619
+ }
8620
+ };
8621
+ function run(...args) {
8622
+ const now = Date.now();
8623
+ const currentWait = getWait();
8624
+ if (!lastCallTime && !getLeading()) {
8625
+ lastCallTime = now;
8626
+ }
8627
+ const remaining = currentWait - (now - lastCallTime);
8628
+ lastArgs = args;
8629
+ lastThis = this;
8630
+ if (remaining <= 0 || remaining > currentWait) {
8631
+ if (timerId) {
8632
+ clearTimeout(timerId);
8633
+ timerId = null;
8634
+ }
8635
+ lastCallTime = now;
8636
+ invokeFunc();
8637
+ } else if (!timerId && getTrailing()) {
8638
+ timerId = setTimeout(() => {
8639
+ lastCallTime = getLeading() ? Date.now() : 0;
8640
+ timerId = null;
8641
+ invokeFunc();
8642
+ }, remaining);
8643
+ }
8644
+ }
8645
+ function cancel() {
8646
+ if (timerId) {
8647
+ clearTimeout(timerId);
8648
+ timerId = null;
8649
+ }
8650
+ lastCallTime = 0;
8651
+ lastArgs = null;
8652
+ lastThis = null;
8653
+ }
8654
+ vue.onUnmounted(() => {
8655
+ cancel();
8656
+ });
8657
+ return {
8658
+ run,
8659
+ cancel
8660
+ };
8661
+ }
8662
+ function throttleFn(fn, wait = 300, options) {
8663
+ return throttle(fn, wait, options);
8664
+ }
8665
+ function useTouch(options = {}) {
8666
+ const {
8667
+ onSwipe,
8668
+ onSwipeLeft,
8669
+ onSwipeRight,
8670
+ onSwipeUp,
8671
+ onSwipeDown,
8672
+ onPinch,
8673
+ onRotate,
8674
+ onTap,
8675
+ onLongPress,
8676
+ swipeThreshold = 30,
8677
+ longPressDuration = 500,
8678
+ tapDuration = 250,
8679
+ disabled = false
8680
+ } = options;
8681
+ const gesture = vue.ref(null);
8682
+ let currentElement = null, startX = 0, startY = 0, startTime = 0, longPressTimer = null, initialPinchDistance = 0, initialAngle = 0;
8683
+ function getTouchCenter(touches) {
8684
+ let x = 0, y = 0;
8685
+ for (let i = 0; i < touches.length; i++) {
8686
+ x += touches[i].clientX;
8687
+ y += touches[i].clientY;
8688
+ }
8689
+ return { x: x / touches.length, y: y / touches.length };
8690
+ }
8691
+ function getDistance2(touch1, touch2) {
8692
+ const dx = touch1.clientX - touch2.clientX;
8693
+ const dy = touch1.clientY - touch2.clientY;
8694
+ return Math.sqrt(dx * dx + dy * dy);
8695
+ }
8696
+ function getAngle2(touch1, touch2) {
8697
+ return Math.atan2(touch2.clientY - touch1.clientY, touch2.clientX - touch1.clientX) * (180 / Math.PI);
8698
+ }
8699
+ function handleTouchStart(e) {
8700
+ if (vue.unref(disabled)) return;
8701
+ startTime = Date.now();
8702
+ gesture.value = null;
8703
+ if (e.touches.length === 1) {
8704
+ startX = e.touches[0].clientX;
8705
+ startY = e.touches[0].clientY;
8706
+ if (onLongPress) {
8707
+ longPressTimer = setTimeout(() => {
8708
+ gesture.value = "longPress";
8709
+ onLongPress({
8710
+ type: "longPress",
8711
+ center: { x: startX, y: startY },
8712
+ event: e
8713
+ });
8714
+ }, longPressDuration);
8715
+ }
8716
+ } else if (e.touches.length === 2) {
8717
+ initialPinchDistance = getDistance2(e.touches[0], e.touches[1]);
8718
+ initialAngle = getAngle2(e.touches[0], e.touches[1]);
8719
+ }
8720
+ }
8721
+ function handleTouchMove(e) {
8722
+ if (vue.unref(disabled)) return;
8723
+ if (longPressTimer) {
8724
+ clearTimeout(longPressTimer);
8725
+ longPressTimer = null;
8726
+ }
8727
+ if (e.touches.length === 2 && (onPinch || onRotate)) {
8728
+ const currentDistance = getDistance2(e.touches[0], e.touches[1]);
8729
+ const currentAngle = getAngle2(e.touches[0], e.touches[1]);
8730
+ if (onPinch && initialPinchDistance > 0) {
8731
+ const scale = currentDistance / initialPinchDistance;
8732
+ gesture.value = "pinch";
8733
+ onPinch({
8734
+ type: "pinch",
8735
+ scale,
8736
+ center: getTouchCenter(e.touches),
8737
+ event: e
8738
+ });
8739
+ }
8740
+ if (onRotate) {
8741
+ const rotation = currentAngle - initialAngle;
8742
+ gesture.value = "rotate";
8743
+ onRotate({
8744
+ type: "rotate",
8745
+ rotation,
8746
+ center: getTouchCenter(e.touches),
8747
+ event: e
8748
+ });
8749
+ }
8750
+ }
8751
+ }
8752
+ function handleTouchEnd(e) {
8753
+ if (vue.unref(disabled)) return;
8754
+ if (longPressTimer) {
8755
+ clearTimeout(longPressTimer);
8756
+ longPressTimer = null;
8757
+ }
8758
+ const duration = Date.now() - startTime;
8759
+ if (e.changedTouches.length === 1) {
8760
+ const endX = e.changedTouches[0].clientX;
8761
+ const endY = e.changedTouches[0].clientY;
8762
+ const deltaX = endX - startX;
8763
+ const deltaY = endY - startY;
8764
+ const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
8765
+ if (distance >= swipeThreshold) {
8766
+ gesture.value = "swipe";
8767
+ let direction;
8768
+ if (Math.abs(deltaX) > Math.abs(deltaY)) {
8769
+ direction = deltaX > 0 ? "right" : "left";
8770
+ } else {
8771
+ direction = deltaY > 0 ? "down" : "up";
8772
+ }
8773
+ const event = {
8774
+ type: "swipe",
8775
+ direction,
8776
+ distance,
8777
+ angle: Math.atan2(deltaY, deltaX) * (180 / Math.PI),
8778
+ center: { x: endX, y: endY },
8779
+ event: e
8780
+ };
8781
+ onSwipe == null ? void 0 : onSwipe(event);
8782
+ switch (direction) {
8783
+ case "left":
8784
+ onSwipeLeft == null ? void 0 : onSwipeLeft(event);
8785
+ break;
8786
+ case "right":
8787
+ onSwipeRight == null ? void 0 : onSwipeRight(event);
8788
+ break;
8789
+ case "up":
8790
+ onSwipeUp == null ? void 0 : onSwipeUp(event);
8791
+ break;
8792
+ case "down":
8793
+ onSwipeDown == null ? void 0 : onSwipeDown(event);
8794
+ break;
8795
+ }
8796
+ } else if (distance < 10 && duration < tapDuration && onTap) {
8797
+ gesture.value = "tap";
8798
+ onTap({
8799
+ type: "tap",
8800
+ center: { x: endX, y: endY },
8801
+ event: e
8802
+ });
8803
+ }
8804
+ }
8805
+ gesture.value = null;
8806
+ }
8807
+ function bind(element) {
8808
+ if (!isBrowser()) return () => {
8809
+ };
8810
+ unbind();
8811
+ currentElement = element;
8812
+ element.addEventListener("touchstart", handleTouchStart, { passive: true });
8813
+ element.addEventListener("touchmove", handleTouchMove, { passive: true });
8814
+ element.addEventListener("touchend", handleTouchEnd);
8815
+ element.addEventListener("touchcancel", handleTouchEnd);
8816
+ return unbind;
8817
+ }
8818
+ function unbind() {
8819
+ if (currentElement) {
8820
+ currentElement.removeEventListener("touchstart", handleTouchStart);
8821
+ currentElement.removeEventListener("touchmove", handleTouchMove);
8822
+ currentElement.removeEventListener("touchend", handleTouchEnd);
8823
+ currentElement.removeEventListener("touchcancel", handleTouchEnd);
8824
+ }
8825
+ if (longPressTimer) {
8826
+ clearTimeout(longPressTimer);
8827
+ longPressTimer = null;
8828
+ }
8829
+ currentElement = null;
8830
+ gesture.value = null;
8831
+ }
8832
+ vue.onUnmounted(() => {
8833
+ unbind();
8834
+ });
8835
+ return {
8836
+ gesture: vue.readonly(gesture),
8837
+ bind
8838
+ };
8839
+ }
8840
+ function escapeRegex(str) {
8841
+ return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
8842
+ }
8843
+ function trimText(text, position = "both", chars) {
8844
+ const charPattern = chars ? `[\\s${escapeRegex(chars)}]` : "\\s";
8845
+ switch (position) {
8846
+ case "start":
8847
+ return text.replace(new RegExp(`^${charPattern}+`, "g"), "");
8848
+ case "end":
8849
+ return text.replace(new RegExp(`${charPattern}+$`, "g"), "");
8850
+ case "both":
8851
+ default:
8852
+ return text.replace(new RegExp(`^${charPattern}+|${charPattern}+$`, "g"), "");
8853
+ }
8854
+ }
8855
+ function useTrim(options) {
8856
+ const {
8857
+ text,
8858
+ position = "both",
8859
+ chars
8860
+ } = options;
8861
+ const original = vue.ref(vue.unref(text));
8862
+ const trimmed = vue.ref("");
8863
+ const wasTrimmed = vue.ref(false);
8864
+ function calculate() {
8865
+ const textValue = vue.unref(text);
8866
+ const positionValue = vue.unref(position);
8867
+ const charsValue = vue.unref(chars);
8868
+ original.value = textValue;
8869
+ trimmed.value = trimText(textValue, positionValue, charsValue);
8870
+ wasTrimmed.value = trimmed.value !== textValue;
8871
+ }
8872
+ vue.watch(
8873
+ () => [vue.unref(text), vue.unref(position), vue.unref(chars)],
8874
+ () => calculate(),
8875
+ { immediate: true }
8876
+ );
8877
+ return {
8878
+ trimmed,
8879
+ original,
8880
+ wasTrimmed
8881
+ };
8882
+ }
8883
+ function createTrimmer(position = "both", chars) {
8884
+ return (text) => trimText(text, position, chars);
8885
+ }
8886
+ function uppercaseText(text, firstOnly = false) {
8887
+ if (!text) return text;
8888
+ if (firstOnly) {
8889
+ return text.charAt(0).toUpperCase() + text.slice(1);
8890
+ }
8891
+ return text.toUpperCase();
8892
+ }
8893
+ function useUppercase(options) {
8894
+ const {
8895
+ text,
8896
+ first = false
8897
+ } = options;
8898
+ const original = vue.ref(vue.unref(text));
8899
+ const transformed = vue.ref("");
8900
+ function calculate() {
8901
+ const textValue = vue.unref(text);
8902
+ const firstValue = vue.unref(first);
8903
+ original.value = textValue;
8904
+ transformed.value = uppercaseText(textValue, firstValue);
8905
+ }
8906
+ vue.watch(
8907
+ () => [vue.unref(text), vue.unref(first)],
8908
+ () => calculate(),
8909
+ { immediate: true }
8910
+ );
8911
+ return {
8912
+ transformed,
8913
+ original
8914
+ };
8915
+ }
8916
+ function createUppercaser(first = false) {
8917
+ return (text) => uppercaseText(text, first);
8918
+ }
8919
+ function useVirtualList(options) {
8920
+ const {
8921
+ items,
8922
+ itemSize = 50,
8923
+ height = 400,
8924
+ overscan = 3,
8925
+ keyField: _keyField = "id"
8926
+ } = options;
8927
+ const containerRef = vue.ref(null);
8928
+ const scrollTop = vue.ref(0);
8929
+ const startIndex = vue.ref(0);
8930
+ const endIndex = vue.ref(0);
8931
+ const getItems = () => vue.unref(items);
8932
+ const getItemSizeValue = () => vue.unref(itemSize);
8933
+ const getHeight = () => vue.unref(height);
8934
+ const getOverscan = () => vue.unref(overscan);
8935
+ const totalHeight = vue.computed(() => {
8936
+ const itemsList = getItems();
8937
+ const size = getItemSizeValue();
8938
+ if (typeof size === "function") {
8939
+ let total = 0;
8940
+ for (let i = 0; i < itemsList.length; i++) {
8941
+ total += size(i);
8942
+ }
8943
+ return total;
8944
+ }
8945
+ return size * itemsList.length;
8946
+ });
8947
+ function calculateVisibleRange2() {
8948
+ const itemsList = getItems();
8949
+ const size = getItemSizeValue();
8950
+ const containerHeight = getHeight();
8951
+ const overscanValue = getOverscan();
8952
+ const currentScrollTop = scrollTop.value;
8953
+ let start = 0, end = 0, offsetY = 0;
8954
+ if (typeof size === "function") {
8955
+ let currentOffset = 0;
8956
+ for (let i = 0; i < itemsList.length; i++) {
8957
+ const itemHeight = size(i);
8958
+ if (currentOffset + itemHeight > currentScrollTop) {
8959
+ start = i;
8960
+ offsetY = currentOffset;
8961
+ break;
8962
+ }
8963
+ currentOffset += itemHeight;
8964
+ }
8965
+ end = start;
8966
+ currentOffset = offsetY;
8967
+ while (end < itemsList.length && currentOffset < currentScrollTop + containerHeight) {
8968
+ currentOffset += size(end);
8969
+ end++;
8970
+ }
8971
+ start = Math.max(0, start - overscanValue);
8972
+ end = Math.min(itemsList.length, end + overscanValue);
8973
+ currentOffset = 0;
8974
+ for (let i = 0; i < start; i++) {
8975
+ currentOffset += size(i);
8976
+ }
8977
+ offsetY = currentOffset;
8978
+ } else {
8979
+ start = Math.max(0, Math.floor(currentScrollTop / size) - overscanValue);
8980
+ end = Math.min(itemsList.length, Math.ceil((currentScrollTop + containerHeight) / size) + overscanValue);
8981
+ offsetY = start * size;
8982
+ }
8983
+ return { start, end, offsetY };
8984
+ }
8985
+ const visibleItems = vue.computed(() => {
8986
+ const itemsList = getItems();
8987
+ const size = getItemSizeValue();
8988
+ const { start, end, offsetY } = calculateVisibleRange2();
8989
+ startIndex.value = start;
8990
+ endIndex.value = end;
8991
+ const result = [];
8992
+ let currentOffset = offsetY;
8993
+ for (let i = start; i < end; i++) {
8994
+ const item = itemsList[i];
8995
+ if (item !== void 0) {
8996
+ const itemHeight = typeof size === "function" ? size(i) : size;
8997
+ result.push({
8998
+ item,
8999
+ index: i,
9000
+ style: {
9001
+ position: "absolute",
9002
+ top: `${currentOffset}px`,
9003
+ height: `${itemHeight}px`,
9004
+ width: "100%"
9005
+ }
9006
+ });
9007
+ currentOffset += itemHeight;
9008
+ }
9009
+ }
9010
+ return result;
9011
+ });
9012
+ const listStyle = vue.computed(() => ({
9013
+ height: `${getHeight()}px`,
9014
+ overflow: "auto",
9015
+ position: "relative"
9016
+ }));
9017
+ function handleScroll(event) {
9018
+ const target = event.target;
9019
+ scrollTop.value = target.scrollTop;
9020
+ }
9021
+ function scrollToIndex(index) {
9022
+ if (!containerRef.value) return;
9023
+ const size = getItemSizeValue();
9024
+ const itemsList = getItems();
9025
+ if (typeof size === "function") {
9026
+ let offset = 0;
9027
+ for (let i = 0; i < Math.min(index, itemsList.length); i++) {
9028
+ offset += size(i);
9029
+ }
9030
+ containerRef.value.scrollTop = offset;
9031
+ } else {
9032
+ containerRef.value.scrollTop = index * size;
9033
+ }
9034
+ }
9035
+ function scrollTo(position) {
9036
+ if (!containerRef.value) return;
9037
+ containerRef.value.scrollTop = position;
9038
+ }
9039
+ vue.onMounted(() => {
9040
+ if (containerRef.value) {
9041
+ containerRef.value.addEventListener("scroll", handleScroll, { passive: true });
9042
+ }
9043
+ });
9044
+ vue.onUnmounted(() => {
9045
+ if (containerRef.value) {
9046
+ containerRef.value.removeEventListener("scroll", handleScroll);
9047
+ }
9048
+ });
9049
+ return {
9050
+ visibleItems,
9051
+ totalHeight,
9052
+ scrollTop,
9053
+ startIndex,
9054
+ endIndex,
9055
+ scrollToIndex,
9056
+ scrollTo,
9057
+ containerRef,
9058
+ listStyle
9059
+ };
9060
+ }
9061
+ function useVisible(options = {}) {
9062
+ const {
9063
+ initial = true,
9064
+ useHidden = false,
9065
+ onChange
9066
+ } = options;
9067
+ const visible = vue.ref(vue.unref(initial));
9068
+ let currentElement = null, originalDisplay = "", originalVisibility = "";
9069
+ function show() {
9070
+ visible.value = true;
9071
+ }
9072
+ function hide() {
9073
+ visible.value = false;
9074
+ }
9075
+ function toggle() {
9076
+ visible.value = !visible.value;
9077
+ }
9078
+ function applyVisibility2(isVisible) {
9079
+ if (!currentElement) return;
9080
+ if (isVisible) {
9081
+ currentElement.classList.remove("v-hidden");
9082
+ currentElement.classList.add("v-visible");
9083
+ if (useHidden) {
9084
+ currentElement.style.visibility = originalVisibility || "visible";
9085
+ } else {
9086
+ currentElement.style.display = originalDisplay;
9087
+ }
9088
+ } else {
9089
+ currentElement.classList.remove("v-visible");
9090
+ currentElement.classList.add("v-hidden");
9091
+ if (useHidden) {
9092
+ currentElement.style.visibility = "hidden";
9093
+ } else {
9094
+ currentElement.style.display = "none";
9095
+ }
9096
+ }
9097
+ }
9098
+ function bind(element) {
9099
+ if (!isBrowser()) return () => {
9100
+ };
9101
+ unbind();
9102
+ currentElement = element;
9103
+ originalDisplay = element.style.display;
9104
+ originalVisibility = element.style.visibility;
9105
+ applyVisibility2(visible.value);
9106
+ return unbind;
9107
+ }
9108
+ function unbind() {
9109
+ if (currentElement) {
9110
+ currentElement.style.display = originalDisplay;
9111
+ currentElement.style.visibility = originalVisibility;
9112
+ currentElement.classList.remove("v-hidden", "v-visible");
9113
+ }
9114
+ currentElement = null;
9115
+ }
9116
+ vue.watch(visible, (newValue, oldValue) => {
9117
+ if (newValue !== oldValue) {
9118
+ applyVisibility2(newValue);
9119
+ onChange == null ? void 0 : onChange(newValue);
9120
+ }
9121
+ });
9122
+ if (typeof initial === "object" && "value" in initial) {
9123
+ vue.watch(initial, (newValue) => {
9124
+ visible.value = newValue;
9125
+ });
9126
+ }
9127
+ vue.onUnmounted(() => {
9128
+ unbind();
9129
+ });
9130
+ return {
9131
+ visible,
9132
+ show,
9133
+ hide,
9134
+ toggle,
9135
+ bind
9136
+ };
9137
+ }
9138
+ function createWatermarkCanvas(options) {
9139
+ const canvas = document.createElement("canvas");
9140
+ const ctx = canvas.getContext("2d");
9141
+ if (!ctx) {
9142
+ throw new Error("[Directix] useWatermark: Could not get canvas context");
9143
+ }
9144
+ const {
9145
+ content,
9146
+ width,
9147
+ height,
9148
+ fontSize,
9149
+ fontFamily,
9150
+ fontWeight,
9151
+ color,
9152
+ rotate
9153
+ } = options;
9154
+ canvas.width = width;
9155
+ canvas.height = height;
9156
+ ctx.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
9157
+ ctx.fillStyle = color;
9158
+ ctx.textAlign = "center";
9159
+ ctx.textBaseline = "middle";
9160
+ ctx.translate(width / 2, height / 2);
9161
+ ctx.rotate(rotate * Math.PI / 180);
9162
+ const contentArray = Array.isArray(content) ? content : [content];
9163
+ const lineHeight = fontSize * 1.5;
9164
+ const startY = -((contentArray.length - 1) * lineHeight) / 2;
9165
+ contentArray.forEach((text, index) => {
9166
+ ctx.fillText(text, 0, startY + index * lineHeight);
9167
+ });
9168
+ return canvas;
9169
+ }
9170
+ function useWatermark(options) {
9171
+ const {
9172
+ content,
9173
+ width = 300,
9174
+ height = 200,
9175
+ rotate = -22,
9176
+ fontSize = 16,
9177
+ fontFamily = "sans-serif",
9178
+ fontWeight = "normal",
9179
+ color = "rgba(128, 128, 128, 0.15)",
9180
+ gap = [100, 100],
9181
+ zIndex = 9999,
9182
+ disabled = false,
9183
+ protect: _protect = true
9184
+ } = options;
9185
+ const canvas = vue.ref(null);
9186
+ const dataUrl = vue.ref("");
9187
+ const disabledRef = vue.ref(vue.unref(disabled));
9188
+ function generate() {
9189
+ const contentValue = vue.unref(content);
9190
+ const widthValue = vue.unref(width);
9191
+ const heightValue = vue.unref(height);
9192
+ const rotateValue = vue.unref(rotate);
9193
+ const fontSizeValue = vue.unref(fontSize);
9194
+ const fontFamilyValue = vue.unref(fontFamily);
9195
+ const fontWeightValue = vue.unref(fontWeight);
9196
+ const colorValue = vue.unref(color);
9197
+ canvas.value = createWatermarkCanvas({
9198
+ content: contentValue,
9199
+ width: widthValue,
9200
+ height: heightValue,
9201
+ fontSize: fontSizeValue,
9202
+ fontFamily: fontFamilyValue,
9203
+ fontWeight: fontWeightValue,
9204
+ color: colorValue,
9205
+ rotate: rotateValue
9206
+ });
9207
+ dataUrl.value = canvas.value.toDataURL();
9208
+ }
9209
+ const style = vue.ref({
9210
+ position: "absolute",
9211
+ top: "0",
9212
+ left: "0",
9213
+ width: "100%",
9214
+ height: "100%",
9215
+ pointerEvents: "none",
9216
+ zIndex: vue.unref(zIndex),
9217
+ backgroundImage: "",
9218
+ backgroundRepeat: "repeat",
9219
+ backgroundPosition: "0 0",
9220
+ backgroundSize: ""
9221
+ });
9222
+ function updateStyle() {
9223
+ const gapValue = vue.unref(gap);
9224
+ const zIndexValue = vue.unref(zIndex);
9225
+ const gapArray = Array.isArray(gapValue) ? gapValue : [gapValue, gapValue];
9226
+ const widthValue = vue.unref(width);
9227
+ const heightValue = vue.unref(height);
9228
+ style.value = __spreadProps(__spreadValues({}, style.value), {
9229
+ zIndex: zIndexValue,
9230
+ backgroundImage: `url("${dataUrl.value}")`,
9231
+ backgroundPosition: `${gapArray[0] / 2}px ${gapArray[1] / 2}px`,
9232
+ backgroundSize: `${widthValue + gapArray[0]}px ${heightValue + gapArray[1]}px`
9233
+ });
9234
+ }
9235
+ function update(newOptions) {
9236
+ Object.assign(options, newOptions);
9237
+ generate();
9238
+ updateStyle();
9239
+ }
9240
+ function enable() {
9241
+ disabledRef.value = false;
9242
+ }
9243
+ function disable() {
9244
+ disabledRef.value = true;
9245
+ }
9246
+ vue.watch(
9247
+ () => [
9248
+ vue.unref(content),
9249
+ vue.unref(width),
9250
+ vue.unref(height),
9251
+ vue.unref(rotate),
9252
+ vue.unref(fontSize),
9253
+ vue.unref(fontFamily),
9254
+ vue.unref(fontWeight),
9255
+ vue.unref(color),
9256
+ vue.unref(gap),
9257
+ vue.unref(zIndex)
9258
+ ],
9259
+ () => {
9260
+ generate();
9261
+ updateStyle();
9262
+ },
9263
+ { immediate: true }
9264
+ );
9265
+ vue.watch(disabledRef, (isDisabled) => {
9266
+ style.value.display = isDisabled ? "none" : "block";
9267
+ });
9268
+ if (vue.unref(disabled)) {
9269
+ style.value.display = "none";
9270
+ }
9271
+ vue.onUnmounted(() => {
9272
+ });
9273
+ return {
9274
+ canvas,
9275
+ dataUrl,
9276
+ style,
9277
+ disabled: disabledRef,
9278
+ update,
9279
+ enable,
9280
+ disable
9281
+ };
9282
+ }
9283
+ function createWatermarkUrl(content, options = {}) {
9284
+ var _a, _b, _c, _d, _e;
9285
+ const canvas = createWatermarkCanvas({
9286
+ content,
9287
+ width: (_a = options.width) != null ? _a : 300,
9288
+ height: (_b = options.height) != null ? _b : 200,
9289
+ fontSize: (_c = options.fontSize) != null ? _c : 16,
9290
+ fontFamily: "sans-serif",
9291
+ fontWeight: "normal",
9292
+ color: (_d = options.color) != null ? _d : "rgba(128, 128, 128, 0.15)",
9293
+ rotate: (_e = options.rotate) != null ? _e : -22
9294
+ });
9295
+ return canvas.toDataURL();
9296
+ }
6283
9297
  const allDirectives = {
6284
9298
  "click-outside": vClickOutside,
6285
9299
  "click-delay": vClickDelay,
@@ -6364,32 +9378,31 @@ var __async = (__this, __arguments, generator) => {
6364
9378
  exports.Directix = Directix;
6365
9379
  exports.addCleanupVue2 = addCleanup$1;
6366
9380
  exports.addCleanupVue3 = addCleanup;
6367
- exports.capitalcase = vCapitalcase;
6368
- exports.clickDelay = vClickDelay;
6369
- exports.clickOutside = vClickOutside;
6370
- exports.configurePermission = configurePermission;
6371
- exports.copy = vCopy;
6372
- exports.countdown = vCountdown;
9381
+ exports.calculateTime = calculateTime;
9382
+ exports.capitalizeText = capitalizeText;
9383
+ exports.capitalizeWord = capitalizeWord;
9384
+ exports.createCapitalizer = createCapitalizer;
9385
+ exports.createDelayedClick = createDelayedClick;
9386
+ exports.createLowercaser = createLowercaser;
9387
+ exports.createMoneyFormatter = createMoneyFormatter;
9388
+ exports.createNumberFormatter = createNumberFormatter;
9389
+ exports.createPermissionChecker = createPermissionChecker;
9390
+ exports.createTrimmer = createTrimmer;
9391
+ exports.createUppercaser = createUppercaser;
6373
9392
  exports.createVue2Directive = createVue2Directive;
6374
9393
  exports.createVue3Directive = createVue3Directive;
6375
- exports.debounce = vDebounce;
6376
- exports.debounceFn = debounce;
9394
+ exports.createWatermarkUrl = createWatermarkUrl;
9395
+ exports.debounceFn = debounceFn;
6377
9396
  exports.deepClone = deepClone;
6378
9397
  exports.deepMerge = deepMerge;
6379
9398
  exports.defineDirective = defineDirective;
6380
9399
  exports.defineDirectiveGroup = defineDirectiveGroup;
6381
- exports.draggable = vDraggable;
6382
- exports.ellipsis = vEllipsis;
6383
- exports.focus = vFocus;
9400
+ exports.formatMoney = formatMoney;
9401
+ exports.formatNumber = formatNumber;
9402
+ exports.formatTime = formatTime;
6384
9403
  exports.generateId = generateId;
6385
9404
  exports.get = get;
6386
- exports.getPermissionConfig = getPermissionConfig;
6387
9405
  exports.getVueVersion = getVueVersion;
6388
- exports.hotkey = vHotkey;
6389
- exports.hover = vHover;
6390
- exports.imagePreview = vImagePreview;
6391
- exports.infiniteScroll = vInfiniteScroll;
6392
- exports.intersect = vIntersect;
6393
9406
  exports.isArray = isArray;
6394
9407
  exports.isBoolean = isBoolean;
6395
9408
  exports.isBrowser = isBrowser;
@@ -6403,39 +9416,54 @@ var __async = (__this, __arguments, generator) => {
6403
9416
  exports.isVue2 = isVue2;
6404
9417
  exports.isVue27 = isVue27;
6405
9418
  exports.isVue3 = isVue3;
6406
- exports.lazy = vLazy;
6407
- exports.loading = vLoading;
6408
- exports.longPress = vLongPress;
6409
- exports.lowercase = vLowercase;
6410
- exports.mask = vMask;
6411
- exports.money = vMoney;
6412
- exports.mutation = vMutation;
6413
- exports.number = vNumber;
9419
+ exports.lowercaseText = lowercaseText;
9420
+ exports.parseMoney = parseMoney;
9421
+ exports.parseNumber = parseNumber;
9422
+ exports.parseTargetTime = parseTargetTime;
6414
9423
  exports.parseTime = parseTime;
6415
- exports.permission = vPermission;
6416
- exports.print = vPrint;
6417
- exports.pullRefresh = vPullRefresh;
9424
+ exports.quickPrint = quickPrint;
6418
9425
  exports.resetVueVersion = resetVueVersion;
6419
- exports.resize = vResize;
6420
- exports.ripple = vRipple;
6421
- exports.sanitize = vSanitize;
6422
- exports.scroll = vScroll;
6423
9426
  exports.set = set;
6424
9427
  exports.setVueVersion = setVueVersion;
6425
- exports.sticky = vSticky;
6426
9428
  exports.supportsClipboard = supportsClipboard;
6427
9429
  exports.supportsIntersectionObserver = supportsIntersectionObserver;
6428
9430
  exports.supportsMutationObserver = supportsMutationObserver;
6429
9431
  exports.supportsPassive = supportsPassive;
6430
9432
  exports.supportsResizeObserver = supportsResizeObserver;
6431
- exports.swipe = vSwipe;
6432
- exports.throttle = vThrottle;
6433
- exports.throttleFn = throttle;
6434
- exports.tooltip = vTooltip;
6435
- exports.touch = vTouch;
6436
- exports.trim = vTrim;
6437
- exports.truncate = vTruncate;
6438
- exports.uppercase = vUppercase;
9433
+ exports.throttleFn = throttleFn;
9434
+ exports.trimText = trimText;
9435
+ exports.truncateText = truncateText;
9436
+ exports.uppercaseText = uppercaseText;
9437
+ exports.useCapitalcase = useCapitalcase;
9438
+ exports.useClickDelay = useClickDelay;
9439
+ exports.useClickOutside = useClickOutside;
9440
+ exports.useCopy = useCopy;
9441
+ exports.useCountdown = useCountdown;
9442
+ exports.useDebounce = useDebounce;
9443
+ exports.useDraggable = useDraggable;
9444
+ exports.useEllipsis = useEllipsis;
9445
+ exports.useFocus = useFocus;
9446
+ exports.useHotkey = useHotkey;
9447
+ exports.useHover = useHover;
9448
+ exports.useImagePreview = useImagePreview;
9449
+ exports.useIntersect = useIntersect;
9450
+ exports.useLongPress = useLongPress;
9451
+ exports.useLowercase = useLowercase;
9452
+ exports.useMoney = useMoney;
9453
+ exports.useNumber = useNumber;
9454
+ exports.usePermission = usePermission;
9455
+ exports.usePrint = usePrint;
9456
+ exports.usePullRefresh = usePullRefresh;
9457
+ exports.useResize = useResize;
9458
+ exports.useScroll = useScroll;
9459
+ exports.useSwipe = useSwipe;
9460
+ exports.useThrottle = useThrottle;
9461
+ exports.useTouch = useTouch;
9462
+ exports.useTrim = useTrim;
9463
+ exports.useUppercase = useUppercase;
9464
+ exports.useVirtualList = useVirtualList;
9465
+ exports.useVisible = useVisible;
9466
+ exports.useWatermark = useWatermark;
6439
9467
  exports.vCapitalcase = vCapitalcase;
6440
9468
  exports.vClickDelay = vClickDelay;
6441
9469
  exports.vClickOutside = vClickOutside;
@@ -6476,9 +9504,7 @@ var __async = (__this, __arguments, generator) => {
6476
9504
  exports.vVirtualList = vVirtualList;
6477
9505
  exports.vVisible = vVisible;
6478
9506
  exports.vWatermark = vWatermark;
6479
- exports.virtualList = vVirtualList;
6480
- exports.visible = vVisible;
6481
- exports.watermark = vWatermark;
9507
+ exports.wouldTextTruncate = wouldTextTruncate;
6482
9508
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
6483
- })(this.Directix = this.Directix || {});
9509
+ })(this.Directix = this.Directix || {}, Vue);
6484
9510
  //# sourceMappingURL=index.iife.js.map