@exyconn/common 1.0.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +121 -36
  2. package/dist/client/index.d.mts +2 -2
  3. package/dist/client/index.d.ts +2 -2
  4. package/dist/client/index.js +2330 -176
  5. package/dist/client/index.js.map +1 -1
  6. package/dist/client/index.mjs +2284 -178
  7. package/dist/client/index.mjs.map +1 -1
  8. package/dist/client/utils/index.d.mts +123 -1
  9. package/dist/client/utils/index.d.ts +123 -1
  10. package/dist/client/utils/index.js +207 -0
  11. package/dist/client/utils/index.js.map +1 -1
  12. package/dist/client/utils/index.mjs +204 -1
  13. package/dist/client/utils/index.mjs.map +1 -1
  14. package/dist/index-BLltj-zN.d.ts +1236 -0
  15. package/dist/index-CIUdLBjA.d.mts +1236 -0
  16. package/dist/{index-iTKxFa78.d.ts → index-DEzgM15j.d.ts} +10 -2
  17. package/dist/{index-ClWtDfwk.d.ts → index-DNFVgQx8.d.ts} +544 -2
  18. package/dist/{index-CcrANHAQ.d.mts → index-DbV04Dx8.d.mts} +10 -2
  19. package/dist/{index-DSW6JfD-.d.mts → index-DfqEP6Oe.d.mts} +544 -2
  20. package/dist/index.d.mts +582 -7
  21. package/dist/index.d.ts +582 -7
  22. package/dist/index.js +3428 -221
  23. package/dist/index.js.map +1 -1
  24. package/dist/index.mjs +3430 -223
  25. package/dist/index.mjs.map +1 -1
  26. package/dist/server/index.d.mts +1 -1
  27. package/dist/server/index.d.ts +1 -1
  28. package/dist/server/index.js +197 -0
  29. package/dist/server/index.js.map +1 -1
  30. package/dist/server/index.mjs +194 -2
  31. package/dist/server/index.mjs.map +1 -1
  32. package/dist/server/utils/index.d.mts +73 -1
  33. package/dist/server/utils/index.d.ts +73 -1
  34. package/dist/server/utils/index.js +199 -0
  35. package/dist/server/utils/index.js.map +1 -1
  36. package/dist/server/utils/index.mjs +195 -1
  37. package/dist/server/utils/index.mjs.map +1 -1
  38. package/dist/shared/index.d.mts +1 -1
  39. package/dist/shared/index.d.ts +1 -1
  40. package/dist/shared/index.js +296 -0
  41. package/dist/shared/index.js.map +1 -1
  42. package/dist/shared/index.mjs +274 -1
  43. package/dist/shared/index.mjs.map +1 -1
  44. package/package.json +9 -2
  45. package/dist/index-BNdT-2X4.d.ts +0 -229
  46. package/dist/index-Du0LLt9f.d.mts +0 -229
@@ -582,6 +582,1795 @@ var createErrorResponse = (message, statusCode = 400, error) => ({
582
582
  error,
583
583
  statusCode
584
584
  });
585
+
586
+ // src/client/utils/packageCheck.ts
587
+ function parseVersion(version) {
588
+ return version.replace(/[\^~>=<|*x\s]/g, "").split(" ")[0] || "0.0.0";
589
+ }
590
+ function compareVersions(current, latest) {
591
+ const currentClean = parseVersion(current);
592
+ const latestClean = parseVersion(latest);
593
+ if (currentClean === latestClean) return "none";
594
+ const [curMajor, curMinor, curPatch] = currentClean.split(".").map(Number);
595
+ const [latMajor, latMinor, latPatch] = latestClean.split(".").map(Number);
596
+ if (latest.includes("-")) return "prerelease";
597
+ if (latMajor > curMajor) return "major";
598
+ if (latMinor > curMinor) return "minor";
599
+ if (latPatch > curPatch) return "patch";
600
+ return "none";
601
+ }
602
+ async function fetchLatestVersion(packageName) {
603
+ try {
604
+ const encodedName = packageName.startsWith("@") ? `@${encodeURIComponent(packageName.slice(1))}` : encodeURIComponent(packageName);
605
+ const response = await fetch(`https://registry.npmjs.org/${encodedName}`);
606
+ if (!response.ok) {
607
+ return null;
608
+ }
609
+ const data = await response.json();
610
+ return data["dist-tags"]?.latest || null;
611
+ } catch {
612
+ return null;
613
+ }
614
+ }
615
+ async function fetchPackageJson(source) {
616
+ if (typeof source === "object") {
617
+ return source;
618
+ }
619
+ if (source.startsWith("http://") || source.startsWith("https://")) {
620
+ const response = await fetch(source);
621
+ if (!response.ok) {
622
+ throw new Error(`Failed to fetch package.json from ${source}: ${response.status}`);
623
+ }
624
+ return response.json();
625
+ }
626
+ throw new Error(
627
+ "File path support requires Node.js environment. Use URL or pass package.json object directly."
628
+ );
629
+ }
630
+ async function checkDependencyType(deps, type, errors) {
631
+ if (!deps) return [];
632
+ const results = [];
633
+ const entries = Object.entries(deps);
634
+ const concurrencyLimit = 10;
635
+ for (let i = 0; i < entries.length; i += concurrencyLimit) {
636
+ const batch = entries.slice(i, i + concurrencyLimit);
637
+ const batchResults = await Promise.all(
638
+ batch.map(async ([name, currentVersion]) => {
639
+ try {
640
+ const latest = await fetchLatestVersion(name);
641
+ if (!latest) {
642
+ errors.push(`Could not fetch latest version for ${name}`);
643
+ return {
644
+ name,
645
+ current: currentVersion,
646
+ latest: "unknown",
647
+ hasUpdate: false,
648
+ updateType: "none",
649
+ dependencyType: type
650
+ };
651
+ }
652
+ const updateType = compareVersions(currentVersion, latest);
653
+ return {
654
+ name,
655
+ current: currentVersion,
656
+ latest,
657
+ hasUpdate: updateType !== "none",
658
+ updateType,
659
+ dependencyType: type
660
+ };
661
+ } catch (err) {
662
+ errors.push(`Error checking ${name}: ${err}`);
663
+ return {
664
+ name,
665
+ current: currentVersion,
666
+ latest: "error",
667
+ hasUpdate: false,
668
+ updateType: "none",
669
+ dependencyType: type
670
+ };
671
+ }
672
+ })
673
+ );
674
+ results.push(...batchResults);
675
+ }
676
+ return results;
677
+ }
678
+ async function checkPackage(source) {
679
+ const errors = [];
680
+ let pkg;
681
+ try {
682
+ pkg = await fetchPackageJson(source);
683
+ } catch (err) {
684
+ throw new Error(`Failed to load package.json: ${err}`);
685
+ }
686
+ const [dependencies, devDependencies, peerDependencies, optionalDependencies] = await Promise.all([
687
+ checkDependencyType(pkg.dependencies, "dependencies", errors),
688
+ checkDependencyType(pkg.devDependencies, "devDependencies", errors),
689
+ checkDependencyType(pkg.peerDependencies, "peerDependencies", errors),
690
+ checkDependencyType(pkg.optionalDependencies, "optionalDependencies", errors)
691
+ ]);
692
+ const allDeps = [...dependencies, ...devDependencies, ...peerDependencies, ...optionalDependencies];
693
+ return {
694
+ packageName: pkg.name || "unknown",
695
+ packageVersion: pkg.version || "0.0.0",
696
+ totalDependencies: allDeps.length,
697
+ outdatedCount: allDeps.filter((d) => d.hasUpdate).length,
698
+ dependencies: allDeps,
699
+ byType: {
700
+ dependencies,
701
+ devDependencies,
702
+ peerDependencies,
703
+ optionalDependencies
704
+ },
705
+ byUpdateType: {
706
+ major: allDeps.filter((d) => d.updateType === "major"),
707
+ minor: allDeps.filter((d) => d.updateType === "minor"),
708
+ patch: allDeps.filter((d) => d.updateType === "patch"),
709
+ prerelease: allDeps.filter((d) => d.updateType === "prerelease")
710
+ },
711
+ checkedAt: /* @__PURE__ */ new Date(),
712
+ errors
713
+ };
714
+ }
715
+ function formatPackageCheckResult(result) {
716
+ const lines = [];
717
+ lines.push(`\u{1F4E6} Package: ${result.packageName}@${result.packageVersion}`);
718
+ lines.push(`\u{1F4C5} Checked: ${result.checkedAt.toISOString()}`);
719
+ lines.push(`\u{1F4CA} Total: ${result.totalDependencies} | Outdated: ${result.outdatedCount}`);
720
+ lines.push("");
721
+ if (result.byUpdateType.major.length > 0) {
722
+ lines.push("\u{1F534} MAJOR Updates:");
723
+ result.byUpdateType.major.forEach((d) => {
724
+ lines.push(` ${d.name}: ${d.current} \u2192 ${d.latest}`);
725
+ });
726
+ lines.push("");
727
+ }
728
+ if (result.byUpdateType.minor.length > 0) {
729
+ lines.push("\u{1F7E1} MINOR Updates:");
730
+ result.byUpdateType.minor.forEach((d) => {
731
+ lines.push(` ${d.name}: ${d.current} \u2192 ${d.latest}`);
732
+ });
733
+ lines.push("");
734
+ }
735
+ if (result.byUpdateType.patch.length > 0) {
736
+ lines.push("\u{1F7E2} PATCH Updates:");
737
+ result.byUpdateType.patch.forEach((d) => {
738
+ lines.push(` ${d.name}: ${d.current} \u2192 ${d.latest}`);
739
+ });
740
+ lines.push("");
741
+ }
742
+ if (result.errors.length > 0) {
743
+ lines.push("\u26A0\uFE0F Errors:");
744
+ result.errors.forEach((e) => {
745
+ lines.push(` ${e}`);
746
+ });
747
+ }
748
+ return lines.join("\n");
749
+ }
750
+ function generateNcuCommand(result, options = {}) {
751
+ const { updateType = "all", interactive = false, upgrade = false } = options;
752
+ let packages = [];
753
+ switch (updateType) {
754
+ case "major":
755
+ packages = result.byUpdateType.major.map((d) => d.name);
756
+ break;
757
+ case "minor":
758
+ packages = result.byUpdateType.minor.map((d) => d.name);
759
+ break;
760
+ case "patch":
761
+ packages = result.byUpdateType.patch.map((d) => d.name);
762
+ break;
763
+ default:
764
+ packages = result.dependencies.filter((d) => d.hasUpdate).map((d) => d.name);
765
+ }
766
+ if (packages.length === 0) {
767
+ return "# No updates available";
768
+ }
769
+ let cmd = "npx npm-check-updates";
770
+ if (packages.length > 0 && packages.length < result.dependencies.length) {
771
+ cmd += ` --filter "${packages.join(",")}"`;
772
+ }
773
+ if (interactive) {
774
+ cmd += " --interactive";
775
+ }
776
+ if (upgrade) {
777
+ cmd += " --upgrade";
778
+ }
779
+ return cmd;
780
+ }
781
+ var packageCheck = {
782
+ check: checkPackage,
783
+ format: formatPackageCheckResult,
784
+ generateNcuCommand,
785
+ parseVersion,
786
+ compareVersions
787
+ };
788
+ function useToggle(initialValue = false) {
789
+ const [value, setValue] = react.useState(initialValue);
790
+ const toggle = react.useCallback(() => setValue((v) => !v), []);
791
+ const setTrue = react.useCallback(() => setValue(true), []);
792
+ const setFalse = react.useCallback(() => setValue(false), []);
793
+ return {
794
+ value,
795
+ toggle,
796
+ setTrue,
797
+ setFalse,
798
+ setValue
799
+ };
800
+ }
801
+ var useToggle_default = useToggle;
802
+ function useCounter(initialValue = 0, options = {}) {
803
+ const { min = -Infinity, max = Infinity, step = 1 } = options;
804
+ const clamp = react.useCallback(
805
+ (value) => Math.min(Math.max(value, min), max),
806
+ [min, max]
807
+ );
808
+ const [count, setCount] = react.useState(clamp(initialValue));
809
+ const increment = react.useCallback(() => {
810
+ setCount((c) => clamp(c + step));
811
+ }, [clamp, step]);
812
+ const decrement = react.useCallback(() => {
813
+ setCount((c) => clamp(c - step));
814
+ }, [clamp, step]);
815
+ const set = react.useCallback(
816
+ (value) => {
817
+ setCount(clamp(value));
818
+ },
819
+ [clamp]
820
+ );
821
+ const reset = react.useCallback(() => {
822
+ setCount(clamp(initialValue));
823
+ }, [clamp, initialValue]);
824
+ return { count, increment, decrement, set, reset };
825
+ }
826
+ var useCounter_default = useCounter;
827
+ function useDefault(initialValue, defaultValue) {
828
+ const [state, setState] = react.useState(initialValue);
829
+ const value = react.useMemo(() => {
830
+ return state === null || state === void 0 ? defaultValue : state;
831
+ }, [state, defaultValue]);
832
+ const setValue = react.useCallback((newValue) => {
833
+ setState(newValue);
834
+ }, []);
835
+ return [value, setValue];
836
+ }
837
+ var useDefault_default = useDefault;
838
+ function usePrevious(value, initialValue) {
839
+ const ref = react.useRef(initialValue);
840
+ react.useEffect(() => {
841
+ ref.current = value;
842
+ }, [value]);
843
+ return ref.current;
844
+ }
845
+ var usePrevious_default = usePrevious;
846
+ function useObjectState(initialState) {
847
+ const [state, setStateInternal] = react.useState(initialState);
848
+ const setState = react.useCallback((update) => {
849
+ setStateInternal((prev) => {
850
+ const newState = typeof update === "function" ? update(prev) : update;
851
+ return { ...prev, ...newState };
852
+ });
853
+ }, []);
854
+ const resetState = react.useCallback(() => {
855
+ setStateInternal(initialState);
856
+ }, [initialState]);
857
+ const setProperty = react.useCallback((key, value) => {
858
+ setStateInternal((prev) => ({ ...prev, [key]: value }));
859
+ }, []);
860
+ const removeProperty = react.useCallback((key) => {
861
+ setStateInternal((prev) => {
862
+ const newState = { ...prev };
863
+ delete newState[key];
864
+ return newState;
865
+ });
866
+ }, []);
867
+ return { state, setState, resetState, setProperty, removeProperty };
868
+ }
869
+ var useObjectState_default = useObjectState;
870
+ function useHistoryState(initialValue, options = {}) {
871
+ const { maxLength = 100 } = options;
872
+ const [history, setHistory] = react.useState([initialValue]);
873
+ const [pointer, setPointer] = react.useState(0);
874
+ const state = react.useMemo(() => history[pointer], [history, pointer]);
875
+ const setState = react.useCallback(
876
+ (value) => {
877
+ setHistory((prev) => {
878
+ const currentValue = prev[pointer];
879
+ const newValue = typeof value === "function" ? value(currentValue) : value;
880
+ const newHistory = prev.slice(0, pointer + 1);
881
+ newHistory.push(newValue);
882
+ if (newHistory.length > maxLength) {
883
+ newHistory.shift();
884
+ return newHistory;
885
+ }
886
+ return newHistory;
887
+ });
888
+ setPointer((prev) => Math.min(prev + 1, maxLength - 1));
889
+ },
890
+ [pointer, maxLength]
891
+ );
892
+ const undo = react.useCallback(() => {
893
+ setPointer((prev) => Math.max(0, prev - 1));
894
+ }, []);
895
+ const redo = react.useCallback(() => {
896
+ setPointer((prev) => Math.min(history.length - 1, prev + 1));
897
+ }, [history.length]);
898
+ const go = react.useCallback(
899
+ (index) => {
900
+ const targetIndex = Math.max(0, Math.min(history.length - 1, index));
901
+ setPointer(targetIndex);
902
+ },
903
+ [history.length]
904
+ );
905
+ const clear = react.useCallback(
906
+ (value) => {
907
+ const resetValue = value ?? initialValue;
908
+ setHistory([resetValue]);
909
+ setPointer(0);
910
+ },
911
+ [initialValue]
912
+ );
913
+ const canUndo = pointer > 0;
914
+ const canRedo = pointer < history.length - 1;
915
+ return {
916
+ state,
917
+ setState,
918
+ undo,
919
+ redo,
920
+ clear,
921
+ canUndo,
922
+ canRedo,
923
+ history,
924
+ pointer,
925
+ go
926
+ };
927
+ }
928
+ var useHistoryState_default = useHistoryState;
929
+ function useQueue(initialValue = []) {
930
+ const [queue, setQueue] = react.useState(initialValue);
931
+ const enqueue = react.useCallback((item) => {
932
+ setQueue((prev) => [...prev, item]);
933
+ }, []);
934
+ const enqueueAll = react.useCallback((items) => {
935
+ setQueue((prev) => [...prev, ...items]);
936
+ }, []);
937
+ const dequeue = react.useCallback(() => {
938
+ let dequeuedItem;
939
+ setQueue((prev) => {
940
+ if (prev.length === 0) return prev;
941
+ dequeuedItem = prev[0];
942
+ return prev.slice(1);
943
+ });
944
+ return dequeuedItem;
945
+ }, []);
946
+ const peek = react.useCallback(() => {
947
+ return queue[0];
948
+ }, [queue]);
949
+ const clear = react.useCallback(() => {
950
+ setQueue([]);
951
+ }, []);
952
+ const size = queue.length;
953
+ const isEmpty = size === 0;
954
+ const first = queue[0];
955
+ const last = queue[queue.length - 1];
956
+ return {
957
+ queue,
958
+ enqueue,
959
+ enqueueAll,
960
+ dequeue,
961
+ peek,
962
+ clear,
963
+ size,
964
+ isEmpty,
965
+ first,
966
+ last
967
+ };
968
+ }
969
+ var useQueue_default = useQueue;
970
+ function useList(initialValue = []) {
971
+ const [list, setList] = react.useState(initialValue);
972
+ const set = react.useCallback((newList) => {
973
+ setList(newList);
974
+ }, []);
975
+ const push = react.useCallback((item) => {
976
+ setList((prev) => [...prev, item]);
977
+ }, []);
978
+ const unshift = react.useCallback((item) => {
979
+ setList((prev) => [item, ...prev]);
980
+ }, []);
981
+ const removeAt = react.useCallback((index) => {
982
+ setList((prev) => prev.filter((_, i) => i !== index));
983
+ }, []);
984
+ const remove = react.useCallback((item) => {
985
+ setList((prev) => {
986
+ const index = prev.indexOf(item);
987
+ if (index === -1) return prev;
988
+ return prev.filter((_, i) => i !== index);
989
+ });
990
+ }, []);
991
+ const removeWhere = react.useCallback((predicate) => {
992
+ setList((prev) => prev.filter((item) => !predicate(item)));
993
+ }, []);
994
+ const updateAt = react.useCallback((index, item) => {
995
+ setList((prev) => prev.map((v, i) => i === index ? item : v));
996
+ }, []);
997
+ const updateWhere = react.useCallback(
998
+ (predicate, updater) => {
999
+ setList((prev) => prev.map((item) => predicate(item) ? updater(item) : item));
1000
+ },
1001
+ []
1002
+ );
1003
+ const insertAt = react.useCallback((index, item) => {
1004
+ setList((prev) => [...prev.slice(0, index), item, ...prev.slice(index)]);
1005
+ }, []);
1006
+ const move = react.useCallback((fromIndex, toIndex) => {
1007
+ setList((prev) => {
1008
+ const newList = [...prev];
1009
+ const [item] = newList.splice(fromIndex, 1);
1010
+ newList.splice(toIndex, 0, item);
1011
+ return newList;
1012
+ });
1013
+ }, []);
1014
+ const clear = react.useCallback(() => {
1015
+ setList([]);
1016
+ }, []);
1017
+ const reset = react.useCallback(() => {
1018
+ setList(initialValue);
1019
+ }, [initialValue]);
1020
+ const filter = react.useCallback((predicate) => {
1021
+ setList((prev) => prev.filter(predicate));
1022
+ }, []);
1023
+ const sort = react.useCallback((compareFn) => {
1024
+ setList((prev) => [...prev].sort(compareFn));
1025
+ }, []);
1026
+ const reverse = react.useCallback(() => {
1027
+ setList((prev) => [...prev].reverse());
1028
+ }, []);
1029
+ const size = list.length;
1030
+ const isEmpty = size === 0;
1031
+ const first = list[0];
1032
+ const last = list[list.length - 1];
1033
+ return {
1034
+ list,
1035
+ set,
1036
+ push,
1037
+ unshift,
1038
+ removeAt,
1039
+ remove,
1040
+ removeWhere,
1041
+ updateAt,
1042
+ updateWhere,
1043
+ insertAt,
1044
+ move,
1045
+ clear,
1046
+ reset,
1047
+ filter,
1048
+ sort,
1049
+ reverse,
1050
+ size,
1051
+ isEmpty,
1052
+ first,
1053
+ last
1054
+ };
1055
+ }
1056
+ var useList_default = useList;
1057
+ function useMap(initialValue = []) {
1058
+ const [map, setMap] = react.useState(() => new Map(initialValue));
1059
+ const get = react.useCallback((key) => {
1060
+ return map.get(key);
1061
+ }, [map]);
1062
+ const set = react.useCallback((key, value) => {
1063
+ setMap((prev) => {
1064
+ const newMap = new Map(prev);
1065
+ newMap.set(key, value);
1066
+ return newMap;
1067
+ });
1068
+ }, []);
1069
+ const setAll = react.useCallback((entries2) => {
1070
+ setMap((prev) => {
1071
+ const newMap = new Map(prev);
1072
+ for (const [key, value] of entries2) {
1073
+ newMap.set(key, value);
1074
+ }
1075
+ return newMap;
1076
+ });
1077
+ }, []);
1078
+ const has = react.useCallback((key) => {
1079
+ return map.has(key);
1080
+ }, [map]);
1081
+ const remove = react.useCallback((key) => {
1082
+ setMap((prev) => {
1083
+ const newMap = new Map(prev);
1084
+ newMap.delete(key);
1085
+ return newMap;
1086
+ });
1087
+ }, []);
1088
+ const removeAll = react.useCallback((keys2) => {
1089
+ setMap((prev) => {
1090
+ const newMap = new Map(prev);
1091
+ keys2.forEach((key) => newMap.delete(key));
1092
+ return newMap;
1093
+ });
1094
+ }, []);
1095
+ const clear = react.useCallback(() => {
1096
+ setMap(/* @__PURE__ */ new Map());
1097
+ }, []);
1098
+ const reset = react.useCallback(() => {
1099
+ setMap(new Map(initialValue));
1100
+ }, [initialValue]);
1101
+ const size = map.size;
1102
+ const keys = react.useMemo(() => Array.from(map.keys()), [map]);
1103
+ const values = react.useMemo(() => Array.from(map.values()), [map]);
1104
+ const entries = react.useMemo(() => Array.from(map.entries()), [map]);
1105
+ const isEmpty = size === 0;
1106
+ return {
1107
+ map,
1108
+ get,
1109
+ set,
1110
+ setAll,
1111
+ has,
1112
+ remove,
1113
+ removeAll,
1114
+ clear,
1115
+ reset,
1116
+ size,
1117
+ keys,
1118
+ values,
1119
+ entries,
1120
+ isEmpty
1121
+ };
1122
+ }
1123
+ var useMap_default = useMap;
1124
+ function useSet(initialValue = []) {
1125
+ const [set, setSet] = react.useState(() => new Set(initialValue));
1126
+ const add = react.useCallback((item) => {
1127
+ setSet((prev) => /* @__PURE__ */ new Set([...prev, item]));
1128
+ }, []);
1129
+ const addAll = react.useCallback((items) => {
1130
+ setSet((prev) => /* @__PURE__ */ new Set([...prev, ...items]));
1131
+ }, []);
1132
+ const has = react.useCallback((item) => {
1133
+ return set.has(item);
1134
+ }, [set]);
1135
+ const remove = react.useCallback((item) => {
1136
+ setSet((prev) => {
1137
+ const newSet = new Set(prev);
1138
+ newSet.delete(item);
1139
+ return newSet;
1140
+ });
1141
+ }, []);
1142
+ const removeAll = react.useCallback((items) => {
1143
+ setSet((prev) => {
1144
+ const newSet = new Set(prev);
1145
+ for (const item of items) {
1146
+ newSet.delete(item);
1147
+ }
1148
+ return newSet;
1149
+ });
1150
+ }, []);
1151
+ const toggle = react.useCallback((item) => {
1152
+ setSet((prev) => {
1153
+ const newSet = new Set(prev);
1154
+ if (newSet.has(item)) {
1155
+ newSet.delete(item);
1156
+ } else {
1157
+ newSet.add(item);
1158
+ }
1159
+ return newSet;
1160
+ });
1161
+ }, []);
1162
+ const clear = react.useCallback(() => {
1163
+ setSet(/* @__PURE__ */ new Set());
1164
+ }, []);
1165
+ const reset = react.useCallback(() => {
1166
+ setSet(new Set(initialValue));
1167
+ }, [initialValue]);
1168
+ const size = set.size;
1169
+ const values = react.useMemo(() => Array.from(set), [set]);
1170
+ const isEmpty = size === 0;
1171
+ return {
1172
+ set,
1173
+ add,
1174
+ addAll,
1175
+ has,
1176
+ remove,
1177
+ removeAll,
1178
+ toggle,
1179
+ clear,
1180
+ reset,
1181
+ size,
1182
+ values,
1183
+ isEmpty
1184
+ };
1185
+ }
1186
+ var useSet_default = useSet;
1187
+ function useDebounce(value, delay = 500) {
1188
+ const [debouncedValue, setDebouncedValue] = react.useState(value);
1189
+ react.useEffect(() => {
1190
+ const timer = setTimeout(() => {
1191
+ setDebouncedValue(value);
1192
+ }, delay);
1193
+ return () => {
1194
+ clearTimeout(timer);
1195
+ };
1196
+ }, [value, delay]);
1197
+ return debouncedValue;
1198
+ }
1199
+ var useDebounce_default = useDebounce;
1200
+ function useThrottle(value, interval = 500) {
1201
+ const [throttledValue, setThrottledValue] = react.useState(value);
1202
+ const lastUpdated = react.useRef(Date.now());
1203
+ react.useEffect(() => {
1204
+ const now = Date.now();
1205
+ const timeSinceLastUpdate = now - lastUpdated.current;
1206
+ if (timeSinceLastUpdate >= interval) {
1207
+ lastUpdated.current = now;
1208
+ setThrottledValue(value);
1209
+ return;
1210
+ } else {
1211
+ const timeoutId = setTimeout(() => {
1212
+ lastUpdated.current = Date.now();
1213
+ setThrottledValue(value);
1214
+ }, interval - timeSinceLastUpdate);
1215
+ return () => clearTimeout(timeoutId);
1216
+ }
1217
+ }, [value, interval]);
1218
+ return throttledValue;
1219
+ }
1220
+ var useThrottle_default = useThrottle;
1221
+ function useTimeout(callback, delay) {
1222
+ const savedCallback = react.useRef(callback);
1223
+ const timeoutId = react.useRef(null);
1224
+ react.useEffect(() => {
1225
+ savedCallback.current = callback;
1226
+ }, [callback]);
1227
+ const clear = react.useCallback(() => {
1228
+ if (timeoutId.current) {
1229
+ clearTimeout(timeoutId.current);
1230
+ timeoutId.current = null;
1231
+ }
1232
+ }, []);
1233
+ const reset = react.useCallback(() => {
1234
+ clear();
1235
+ if (delay !== null) {
1236
+ timeoutId.current = setTimeout(() => {
1237
+ savedCallback.current();
1238
+ }, delay);
1239
+ }
1240
+ }, [delay, clear]);
1241
+ react.useEffect(() => {
1242
+ if (delay === null) {
1243
+ return;
1244
+ }
1245
+ timeoutId.current = setTimeout(() => {
1246
+ savedCallback.current();
1247
+ }, delay);
1248
+ return clear;
1249
+ }, [delay, clear]);
1250
+ return { reset, clear };
1251
+ }
1252
+ var useTimeout_default = useTimeout;
1253
+ function useInterval(callback, delay) {
1254
+ const savedCallback = react.useRef(callback);
1255
+ react.useEffect(() => {
1256
+ savedCallback.current = callback;
1257
+ }, [callback]);
1258
+ react.useEffect(() => {
1259
+ if (delay === null) {
1260
+ return;
1261
+ }
1262
+ const tick = () => savedCallback.current();
1263
+ const id = setInterval(tick, delay);
1264
+ return () => clearInterval(id);
1265
+ }, [delay]);
1266
+ }
1267
+ var useInterval_default = useInterval;
1268
+ function useIntervalWhen(callback, delay, when, immediate = false) {
1269
+ const savedCallback = react.useRef(callback);
1270
+ const hasRunImmediate = react.useRef(false);
1271
+ react.useEffect(() => {
1272
+ savedCallback.current = callback;
1273
+ }, [callback]);
1274
+ react.useEffect(() => {
1275
+ if (!when) {
1276
+ hasRunImmediate.current = false;
1277
+ return;
1278
+ }
1279
+ if (immediate && !hasRunImmediate.current) {
1280
+ hasRunImmediate.current = true;
1281
+ savedCallback.current();
1282
+ }
1283
+ const id = setInterval(() => {
1284
+ savedCallback.current();
1285
+ }, delay);
1286
+ return () => clearInterval(id);
1287
+ }, [delay, when, immediate]);
1288
+ }
1289
+ var useIntervalWhen_default = useIntervalWhen;
1290
+ function useRandomInterval(callback, minDelay, maxDelay, enabled = true) {
1291
+ const savedCallback = react.useRef(callback);
1292
+ const timeoutId = react.useRef(null);
1293
+ react.useEffect(() => {
1294
+ savedCallback.current = callback;
1295
+ }, [callback]);
1296
+ const getRandomDelay = react.useCallback(() => {
1297
+ return Math.floor(Math.random() * (maxDelay - minDelay + 1)) + minDelay;
1298
+ }, [minDelay, maxDelay]);
1299
+ react.useEffect(() => {
1300
+ if (!enabled) {
1301
+ return;
1302
+ }
1303
+ const tick = () => {
1304
+ savedCallback.current();
1305
+ timeoutId.current = setTimeout(tick, getRandomDelay());
1306
+ };
1307
+ timeoutId.current = setTimeout(tick, getRandomDelay());
1308
+ return () => {
1309
+ if (timeoutId.current) {
1310
+ clearTimeout(timeoutId.current);
1311
+ }
1312
+ };
1313
+ }, [enabled, getRandomDelay]);
1314
+ }
1315
+ var useRandomInterval_default = useRandomInterval;
1316
+ function useCountdown(initialCount, options = {}) {
1317
+ const { interval = 1e3, onComplete, autoStart = false } = options;
1318
+ const [count, setCount] = react.useState(initialCount);
1319
+ const [isRunning, setIsRunning] = react.useState(autoStart);
1320
+ const intervalRef = react.useRef(null);
1321
+ const onCompleteRef = react.useRef(onComplete);
1322
+ react.useEffect(() => {
1323
+ onCompleteRef.current = onComplete;
1324
+ }, [onComplete]);
1325
+ const isComplete = count <= 0;
1326
+ const clear = react.useCallback(() => {
1327
+ if (intervalRef.current) {
1328
+ clearInterval(intervalRef.current);
1329
+ intervalRef.current = null;
1330
+ }
1331
+ }, []);
1332
+ const start = react.useCallback(() => {
1333
+ if (count <= 0) return;
1334
+ setIsRunning(true);
1335
+ }, [count]);
1336
+ const pause = react.useCallback(() => {
1337
+ setIsRunning(false);
1338
+ clear();
1339
+ }, [clear]);
1340
+ const resume = react.useCallback(() => {
1341
+ if (count > 0) {
1342
+ setIsRunning(true);
1343
+ }
1344
+ }, [count]);
1345
+ const reset = react.useCallback(
1346
+ (newCount) => {
1347
+ clear();
1348
+ setCount(newCount ?? initialCount);
1349
+ setIsRunning(false);
1350
+ },
1351
+ [clear, initialCount]
1352
+ );
1353
+ react.useEffect(() => {
1354
+ if (!isRunning || count <= 0) {
1355
+ clear();
1356
+ return;
1357
+ }
1358
+ intervalRef.current = setInterval(() => {
1359
+ setCount((prev) => {
1360
+ const newCount = prev - interval;
1361
+ if (newCount <= 0) {
1362
+ setIsRunning(false);
1363
+ onCompleteRef.current?.();
1364
+ return 0;
1365
+ }
1366
+ return newCount;
1367
+ });
1368
+ }, interval);
1369
+ return clear;
1370
+ }, [isRunning, interval, clear, count]);
1371
+ const formatted = {
1372
+ days: Math.floor(count / (1e3 * 60 * 60 * 24)),
1373
+ hours: Math.floor(count % (1e3 * 60 * 60 * 24) / (1e3 * 60 * 60)),
1374
+ minutes: Math.floor(count % (1e3 * 60 * 60) / (1e3 * 60)),
1375
+ seconds: Math.floor(count % (1e3 * 60) / 1e3)
1376
+ };
1377
+ return {
1378
+ count,
1379
+ start,
1380
+ pause,
1381
+ resume,
1382
+ reset,
1383
+ isRunning,
1384
+ isComplete,
1385
+ formatted
1386
+ };
1387
+ }
1388
+ var useCountdown_default = useCountdown;
1389
+ function useContinuousRetry(callback, options = {}) {
1390
+ const {
1391
+ maxAttempts = Infinity,
1392
+ delay = 1e3,
1393
+ exponentialBackoff = false,
1394
+ maxDelay = 3e4,
1395
+ autoStart = true
1396
+ } = options;
1397
+ const [attempts, setAttempts] = react.useState(0);
1398
+ const [error, setError] = react.useState(null);
1399
+ const [isRetrying, setIsRetrying] = react.useState(autoStart);
1400
+ const [isSuccess2, setIsSuccess] = react.useState(false);
1401
+ const callbackRef = react.useRef(callback);
1402
+ const timeoutRef = react.useRef(null);
1403
+ react.useEffect(() => {
1404
+ callbackRef.current = callback;
1405
+ }, [callback]);
1406
+ const isMaxAttempts = attempts >= maxAttempts;
1407
+ const calculateDelay = react.useCallback(
1408
+ (attempt) => {
1409
+ if (!exponentialBackoff) return delay;
1410
+ const exponentialDelay = delay * Math.pow(2, attempt);
1411
+ return Math.min(exponentialDelay, maxDelay);
1412
+ },
1413
+ [delay, exponentialBackoff, maxDelay]
1414
+ );
1415
+ const clear = react.useCallback(() => {
1416
+ if (timeoutRef.current) {
1417
+ clearTimeout(timeoutRef.current);
1418
+ timeoutRef.current = null;
1419
+ }
1420
+ }, []);
1421
+ const stop = react.useCallback(() => {
1422
+ clear();
1423
+ setIsRetrying(false);
1424
+ }, [clear]);
1425
+ const reset = react.useCallback(() => {
1426
+ clear();
1427
+ setAttempts(0);
1428
+ setError(null);
1429
+ setIsRetrying(false);
1430
+ setIsSuccess(false);
1431
+ }, [clear]);
1432
+ const start = react.useCallback(() => {
1433
+ reset();
1434
+ setIsRetrying(true);
1435
+ }, [reset]);
1436
+ react.useEffect(() => {
1437
+ if (!isRetrying || isSuccess2 || isMaxAttempts) {
1438
+ return;
1439
+ }
1440
+ const attemptCallback = async () => {
1441
+ try {
1442
+ setAttempts((prev) => prev + 1);
1443
+ const result = await callbackRef.current();
1444
+ if (result) {
1445
+ setIsSuccess(true);
1446
+ setIsRetrying(false);
1447
+ } else {
1448
+ const currentDelay = calculateDelay(attempts);
1449
+ timeoutRef.current = setTimeout(attemptCallback, currentDelay);
1450
+ }
1451
+ } catch (err) {
1452
+ setError(err instanceof Error ? err : new Error(String(err)));
1453
+ const currentDelay = calculateDelay(attempts);
1454
+ timeoutRef.current = setTimeout(attemptCallback, currentDelay);
1455
+ }
1456
+ };
1457
+ if (attempts === 0) {
1458
+ attemptCallback();
1459
+ }
1460
+ return clear;
1461
+ }, [isRetrying, isSuccess2, isMaxAttempts, attempts, calculateDelay, clear]);
1462
+ return {
1463
+ attempts,
1464
+ error,
1465
+ isRetrying,
1466
+ isSuccess: isSuccess2,
1467
+ isMaxAttempts,
1468
+ start,
1469
+ stop,
1470
+ reset
1471
+ };
1472
+ }
1473
+ var useContinuousRetry_default = useContinuousRetry;
1474
+ function useWindowSize(debounceMs = 100) {
1475
+ const getSize = () => ({
1476
+ width: typeof window !== "undefined" ? window.innerWidth : 0,
1477
+ height: typeof window !== "undefined" ? window.innerHeight : 0
1478
+ });
1479
+ const [windowSize, setWindowSize] = react.useState(getSize);
1480
+ react.useEffect(() => {
1481
+ if (typeof window === "undefined") return;
1482
+ let timeoutId;
1483
+ const handleResize = () => {
1484
+ clearTimeout(timeoutId);
1485
+ timeoutId = setTimeout(() => {
1486
+ setWindowSize(getSize());
1487
+ }, debounceMs);
1488
+ };
1489
+ setWindowSize(getSize());
1490
+ window.addEventListener("resize", handleResize);
1491
+ return () => {
1492
+ clearTimeout(timeoutId);
1493
+ window.removeEventListener("resize", handleResize);
1494
+ };
1495
+ }, [debounceMs]);
1496
+ return windowSize;
1497
+ }
1498
+ var useWindowSize_default = useWindowSize;
1499
+ function useWindowScroll() {
1500
+ const [scroll, setScroll] = react.useState({
1501
+ x: typeof window !== "undefined" ? window.scrollX : 0,
1502
+ y: typeof window !== "undefined" ? window.scrollY : 0,
1503
+ direction: null,
1504
+ isScrolling: false
1505
+ });
1506
+ react.useEffect(() => {
1507
+ if (typeof window === "undefined") return;
1508
+ let prevX = window.scrollX;
1509
+ let prevY = window.scrollY;
1510
+ let scrollTimeout;
1511
+ const handleScroll = () => {
1512
+ const x = window.scrollX;
1513
+ const y = window.scrollY;
1514
+ let direction = null;
1515
+ if (y > prevY) direction = "down";
1516
+ else if (y < prevY) direction = "up";
1517
+ else if (x > prevX) direction = "right";
1518
+ else if (x < prevX) direction = "left";
1519
+ prevX = x;
1520
+ prevY = y;
1521
+ setScroll({ x, y, direction, isScrolling: true });
1522
+ clearTimeout(scrollTimeout);
1523
+ scrollTimeout = setTimeout(() => {
1524
+ setScroll((prev) => ({ ...prev, isScrolling: false }));
1525
+ }, 150);
1526
+ };
1527
+ window.addEventListener("scroll", handleScroll, { passive: true });
1528
+ return () => {
1529
+ window.removeEventListener("scroll", handleScroll);
1530
+ clearTimeout(scrollTimeout);
1531
+ };
1532
+ }, []);
1533
+ const scrollTo = react.useCallback((options) => {
1534
+ if (typeof window !== "undefined") {
1535
+ window.scrollTo(options);
1536
+ }
1537
+ }, []);
1538
+ const scrollToTop = react.useCallback((behavior = "smooth") => {
1539
+ if (typeof window !== "undefined") {
1540
+ window.scrollTo({ top: 0, behavior });
1541
+ }
1542
+ }, []);
1543
+ const scrollToBottom = react.useCallback((behavior = "smooth") => {
1544
+ if (typeof window !== "undefined") {
1545
+ window.scrollTo({
1546
+ top: document.documentElement.scrollHeight,
1547
+ behavior
1548
+ });
1549
+ }
1550
+ }, []);
1551
+ return {
1552
+ ...scroll,
1553
+ scrollTo,
1554
+ scrollToTop,
1555
+ scrollToBottom
1556
+ };
1557
+ }
1558
+ var useWindowScroll_default = useWindowScroll;
1559
+ function useDocumentTitle(title, options = {}) {
1560
+ const { restoreOnUnmount = true, template } = options;
1561
+ const previousTitle = react.useRef(null);
1562
+ react.useEffect(() => {
1563
+ if (typeof document === "undefined") return;
1564
+ if (previousTitle.current === null) {
1565
+ previousTitle.current = document.title;
1566
+ }
1567
+ const finalTitle = template ? template.replace("%s", title) : title;
1568
+ document.title = finalTitle;
1569
+ return () => {
1570
+ if (restoreOnUnmount && previousTitle.current !== null) {
1571
+ document.title = previousTitle.current;
1572
+ }
1573
+ };
1574
+ }, [title, template, restoreOnUnmount]);
1575
+ }
1576
+ var useDocumentTitle_default = useDocumentTitle;
1577
+ function usePageTitle(title, options = {}) {
1578
+ const { suffix, separator = " | ", restoreOnUnmount = true } = options;
1579
+ react.useEffect(() => {
1580
+ const originalTitle = document.title;
1581
+ const newTitle = suffix ? `${title}${separator}${suffix}` : title;
1582
+ document.title = newTitle;
1583
+ return () => {
1584
+ if (restoreOnUnmount) {
1585
+ document.title = originalTitle;
1586
+ }
1587
+ };
1588
+ }, [title, suffix, separator, restoreOnUnmount]);
1589
+ }
1590
+ var usePageTitle_default = usePageTitle;
1591
+ function useFavicon(href, restoreOnUnmount = true) {
1592
+ const originalHref = react.useRef(null);
1593
+ react.useEffect(() => {
1594
+ if (typeof document === "undefined") return;
1595
+ const link = document.querySelector("link[rel*='icon']") || document.createElement("link");
1596
+ if (originalHref.current === null) {
1597
+ originalHref.current = link.href;
1598
+ }
1599
+ link.type = "image/x-icon";
1600
+ link.rel = "shortcut icon";
1601
+ link.href = href;
1602
+ document.head.appendChild(link);
1603
+ return () => {
1604
+ if (restoreOnUnmount && originalHref.current) {
1605
+ link.href = originalHref.current;
1606
+ }
1607
+ };
1608
+ }, [href, restoreOnUnmount]);
1609
+ }
1610
+ var useFavicon_default = useFavicon;
1611
+ function useVisibilityChange(onVisibilityChange) {
1612
+ const [state, setState] = react.useState(() => ({
1613
+ isVisible: typeof document !== "undefined" ? !document.hidden : true,
1614
+ visibilityState: typeof document !== "undefined" ? document.visibilityState : "visible",
1615
+ lastChanged: null
1616
+ }));
1617
+ const handleVisibilityChange = react.useCallback(() => {
1618
+ const isVisible = !document.hidden;
1619
+ const visibilityState = document.visibilityState;
1620
+ setState({
1621
+ isVisible,
1622
+ visibilityState,
1623
+ lastChanged: /* @__PURE__ */ new Date()
1624
+ });
1625
+ onVisibilityChange?.(isVisible);
1626
+ }, [onVisibilityChange]);
1627
+ react.useEffect(() => {
1628
+ if (typeof document === "undefined") return;
1629
+ document.addEventListener("visibilitychange", handleVisibilityChange);
1630
+ return () => {
1631
+ document.removeEventListener("visibilitychange", handleVisibilityChange);
1632
+ };
1633
+ }, [handleVisibilityChange]);
1634
+ return state;
1635
+ }
1636
+ var useVisibilityChange_default = useVisibilityChange;
1637
+ function usePageLeave(onLeave, options = {}) {
1638
+ const { showConfirmation = false, confirmationMessage = "" } = options;
1639
+ const onLeaveRef = react.useRef(onLeave);
1640
+ react.useEffect(() => {
1641
+ onLeaveRef.current = onLeave;
1642
+ }, [onLeave]);
1643
+ const handleMouseLeave = react.useCallback((e) => {
1644
+ if (e.clientY <= 0) {
1645
+ onLeaveRef.current?.();
1646
+ }
1647
+ }, []);
1648
+ const handleBeforeUnload = react.useCallback(
1649
+ (e) => {
1650
+ onLeaveRef.current?.();
1651
+ if (showConfirmation) {
1652
+ e.preventDefault();
1653
+ e.returnValue = confirmationMessage;
1654
+ return confirmationMessage;
1655
+ }
1656
+ },
1657
+ [showConfirmation, confirmationMessage]
1658
+ );
1659
+ react.useEffect(() => {
1660
+ if (typeof window === "undefined") return;
1661
+ document.addEventListener("mouseleave", handleMouseLeave);
1662
+ window.addEventListener("beforeunload", handleBeforeUnload);
1663
+ return () => {
1664
+ document.removeEventListener("mouseleave", handleMouseLeave);
1665
+ window.removeEventListener("beforeunload", handleBeforeUnload);
1666
+ };
1667
+ }, [handleMouseLeave, handleBeforeUnload]);
1668
+ }
1669
+ var usePageLeave_default = usePageLeave;
1670
+ function useLockBodyScroll(locked = true) {
1671
+ react.useEffect(() => {
1672
+ if (typeof document === "undefined" || !locked) return;
1673
+ const originalStyle = window.getComputedStyle(document.body).overflow;
1674
+ const originalPaddingRight = window.getComputedStyle(document.body).paddingRight;
1675
+ const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;
1676
+ document.body.style.overflow = "hidden";
1677
+ if (scrollbarWidth > 0) {
1678
+ document.body.style.paddingRight = `${scrollbarWidth}px`;
1679
+ }
1680
+ return () => {
1681
+ document.body.style.overflow = originalStyle;
1682
+ document.body.style.paddingRight = originalPaddingRight;
1683
+ };
1684
+ }, [locked]);
1685
+ }
1686
+ var useLockBodyScroll_default = useLockBodyScroll;
1687
+ function useIsClient() {
1688
+ const [isClient, setIsClient] = react.useState(false);
1689
+ react.useEffect(() => {
1690
+ setIsClient(true);
1691
+ }, []);
1692
+ return isClient;
1693
+ }
1694
+ var useIsClient_default = useIsClient;
1695
+ function useIsFirstRender() {
1696
+ const isFirst = react.useRef(true);
1697
+ if (isFirst.current) {
1698
+ isFirst.current = false;
1699
+ return true;
1700
+ }
1701
+ return isFirst.current;
1702
+ }
1703
+ var useIsFirstRender_default = useIsFirstRender;
1704
+ function useEventListener(eventName, handler, element, options) {
1705
+ const savedHandler = react.useRef(handler);
1706
+ react.useEffect(() => {
1707
+ savedHandler.current = handler;
1708
+ }, [handler]);
1709
+ react.useEffect(() => {
1710
+ const targetElement = element ?? (typeof window !== "undefined" ? window : null);
1711
+ if (!targetElement?.addEventListener) {
1712
+ return;
1713
+ }
1714
+ const eventListener = (event) => {
1715
+ savedHandler.current(event);
1716
+ };
1717
+ targetElement.addEventListener(eventName, eventListener, options);
1718
+ return () => {
1719
+ targetElement.removeEventListener(eventName, eventListener, options);
1720
+ };
1721
+ }, [eventName, element, options]);
1722
+ }
1723
+ var useEventListener_default = useEventListener;
1724
+ function useKeyPress(targetKey, callback, options = {}) {
1725
+ const {
1726
+ target,
1727
+ event: eventType = "keydown",
1728
+ preventDefault = false,
1729
+ stopPropagation = false
1730
+ } = options;
1731
+ const [pressed, setPressed] = react.useState(false);
1732
+ const [event, setEvent] = react.useState(null);
1733
+ const keys = Array.isArray(targetKey) ? targetKey : [targetKey];
1734
+ const downHandler = react.useCallback(
1735
+ (e) => {
1736
+ if (keys.includes(e.key)) {
1737
+ if (preventDefault) e.preventDefault();
1738
+ if (stopPropagation) e.stopPropagation();
1739
+ setPressed(true);
1740
+ setEvent(e);
1741
+ callback?.(e);
1742
+ }
1743
+ },
1744
+ [keys, callback, preventDefault, stopPropagation]
1745
+ );
1746
+ const upHandler = react.useCallback(
1747
+ (e) => {
1748
+ if (keys.includes(e.key)) {
1749
+ setPressed(false);
1750
+ }
1751
+ },
1752
+ [keys]
1753
+ );
1754
+ react.useEffect(() => {
1755
+ const targetElement = target ?? (typeof document !== "undefined" ? document : null);
1756
+ if (!targetElement) return;
1757
+ targetElement.addEventListener(eventType, downHandler);
1758
+ targetElement.addEventListener("keyup", upHandler);
1759
+ return () => {
1760
+ targetElement.removeEventListener(eventType, downHandler);
1761
+ targetElement.removeEventListener("keyup", upHandler);
1762
+ };
1763
+ }, [target, eventType, downHandler, upHandler]);
1764
+ return { pressed, event };
1765
+ }
1766
+ var useKeyPress_default = useKeyPress;
1767
+ function useHover(onHoverChange) {
1768
+ const [isHovered, setIsHovered] = react.useState(false);
1769
+ const ref = react.useRef(null);
1770
+ const onMouseEnter = react.useCallback(() => {
1771
+ setIsHovered(true);
1772
+ onHoverChange?.(true);
1773
+ }, [onHoverChange]);
1774
+ const onMouseLeave = react.useCallback(() => {
1775
+ setIsHovered(false);
1776
+ onHoverChange?.(false);
1777
+ }, [onHoverChange]);
1778
+ return {
1779
+ ref,
1780
+ isHovered,
1781
+ bind: {
1782
+ onMouseEnter,
1783
+ onMouseLeave
1784
+ }
1785
+ };
1786
+ }
1787
+ var useHover_default = useHover;
1788
+ function useClickAway(callback, events = ["mousedown", "touchstart"]) {
1789
+ const ref = react.useRef(null);
1790
+ const savedCallback = react.useRef(callback);
1791
+ react.useEffect(() => {
1792
+ savedCallback.current = callback;
1793
+ }, [callback]);
1794
+ const handleClickAway = react.useCallback((event) => {
1795
+ const el = ref.current;
1796
+ if (!el || el.contains(event.target)) {
1797
+ return;
1798
+ }
1799
+ savedCallback.current(event);
1800
+ }, []);
1801
+ react.useEffect(() => {
1802
+ if (typeof document === "undefined") return;
1803
+ events.forEach((eventType) => {
1804
+ document.addEventListener(eventType, handleClickAway);
1805
+ });
1806
+ return () => {
1807
+ events.forEach((eventType) => {
1808
+ document.removeEventListener(eventType, handleClickAway);
1809
+ });
1810
+ };
1811
+ }, [events, handleClickAway]);
1812
+ return ref;
1813
+ }
1814
+ var useClickAway_default = useClickAway;
1815
+ function useOnClickOutside(ref, handler, enabled = true) {
1816
+ react.useEffect(() => {
1817
+ if (!enabled) return;
1818
+ const listener = (event) => {
1819
+ const el = ref?.current;
1820
+ if (!el || el.contains(event.target)) {
1821
+ return;
1822
+ }
1823
+ handler(event);
1824
+ };
1825
+ document.addEventListener("mousedown", listener);
1826
+ document.addEventListener("touchstart", listener);
1827
+ return () => {
1828
+ document.removeEventListener("mousedown", listener);
1829
+ document.removeEventListener("touchstart", listener);
1830
+ };
1831
+ }, [ref, handler, enabled]);
1832
+ }
1833
+ var useOnClickOutside_default = useOnClickOutside;
1834
+ function useLongPress(options = {}) {
1835
+ const {
1836
+ threshold = 400,
1837
+ onLongPress,
1838
+ onClick,
1839
+ onStart,
1840
+ onFinish,
1841
+ onCancel
1842
+ } = options;
1843
+ const [isPressed, setIsPressed] = react.useState(false);
1844
+ const [isLongPress, setIsLongPress] = react.useState(false);
1845
+ const timerRef = react.useRef(null);
1846
+ const isLongPressRef = react.useRef(false);
1847
+ const start = react.useCallback(
1848
+ (event) => {
1849
+ setIsPressed(true);
1850
+ setIsLongPress(false);
1851
+ isLongPressRef.current = false;
1852
+ onStart?.(event);
1853
+ timerRef.current = setTimeout(() => {
1854
+ isLongPressRef.current = true;
1855
+ setIsLongPress(true);
1856
+ onLongPress?.(event);
1857
+ }, threshold);
1858
+ },
1859
+ [threshold, onLongPress, onStart]
1860
+ );
1861
+ const cancel = react.useCallback(
1862
+ (event) => {
1863
+ setIsPressed(false);
1864
+ if (timerRef.current) {
1865
+ clearTimeout(timerRef.current);
1866
+ timerRef.current = null;
1867
+ }
1868
+ if (!isLongPressRef.current) {
1869
+ onCancel?.(event);
1870
+ }
1871
+ },
1872
+ [onCancel]
1873
+ );
1874
+ const end = react.useCallback(
1875
+ (event) => {
1876
+ setIsPressed(false);
1877
+ if (timerRef.current) {
1878
+ clearTimeout(timerRef.current);
1879
+ timerRef.current = null;
1880
+ }
1881
+ if (isLongPressRef.current) {
1882
+ onFinish?.(event);
1883
+ } else {
1884
+ onClick?.(event);
1885
+ }
1886
+ },
1887
+ [onClick, onFinish]
1888
+ );
1889
+ return {
1890
+ isPressed,
1891
+ isLongPress,
1892
+ bind: {
1893
+ onMouseDown: start,
1894
+ onMouseUp: end,
1895
+ onMouseLeave: cancel,
1896
+ onTouchStart: start,
1897
+ onTouchEnd: end
1898
+ }
1899
+ };
1900
+ }
1901
+ var useLongPress_default = useLongPress;
1902
+ function useMouse(options = {}) {
1903
+ const { enabled = true } = options;
1904
+ const ref = react.useRef(null);
1905
+ const [position, setPosition] = react.useState({
1906
+ x: 0,
1907
+ y: 0,
1908
+ pageX: 0,
1909
+ pageY: 0,
1910
+ elementX: 0,
1911
+ elementY: 0,
1912
+ isInElement: false
1913
+ });
1914
+ const handleMouseMove = react.useCallback((event) => {
1915
+ let elementX = 0;
1916
+ let elementY = 0;
1917
+ let isInElement = false;
1918
+ if (ref.current) {
1919
+ const rect = ref.current.getBoundingClientRect();
1920
+ elementX = event.clientX - rect.left;
1921
+ elementY = event.clientY - rect.top;
1922
+ isInElement = elementX >= 0 && elementX <= rect.width && elementY >= 0 && elementY <= rect.height;
1923
+ }
1924
+ setPosition({
1925
+ x: event.clientX,
1926
+ y: event.clientY,
1927
+ pageX: event.pageX,
1928
+ pageY: event.pageY,
1929
+ elementX,
1930
+ elementY,
1931
+ isInElement
1932
+ });
1933
+ }, []);
1934
+ react.useEffect(() => {
1935
+ if (!enabled || typeof window === "undefined") return;
1936
+ window.addEventListener("mousemove", handleMouseMove);
1937
+ return () => {
1938
+ window.removeEventListener("mousemove", handleMouseMove);
1939
+ };
1940
+ }, [enabled, handleMouseMove]);
1941
+ return {
1942
+ ref,
1943
+ ...position
1944
+ };
1945
+ }
1946
+ var useMouse_default = useMouse;
1947
+ function useCopyToClipboard(resetDelay = 2e3) {
1948
+ const [copied, setCopied] = react.useState(false);
1949
+ const [error, setError] = react.useState(null);
1950
+ const reset = react.useCallback(() => {
1951
+ setCopied(false);
1952
+ setError(null);
1953
+ }, []);
1954
+ const copy = react.useCallback(
1955
+ async (text) => {
1956
+ if (!navigator?.clipboard) {
1957
+ try {
1958
+ const textarea = document.createElement("textarea");
1959
+ textarea.value = text;
1960
+ textarea.style.position = "fixed";
1961
+ textarea.style.left = "-999999px";
1962
+ textarea.style.top = "-999999px";
1963
+ document.body.appendChild(textarea);
1964
+ textarea.focus();
1965
+ textarea.select();
1966
+ const successful = document.execCommand("copy");
1967
+ document.body.removeChild(textarea);
1968
+ if (successful) {
1969
+ setCopied(true);
1970
+ setError(null);
1971
+ setTimeout(reset, resetDelay);
1972
+ return true;
1973
+ } else {
1974
+ throw new Error("execCommand failed");
1975
+ }
1976
+ } catch (err) {
1977
+ const message = err instanceof Error ? err.message : "Failed to copy to clipboard";
1978
+ setError(message);
1979
+ setCopied(false);
1980
+ return false;
1981
+ }
1982
+ }
1983
+ try {
1984
+ await navigator.clipboard.writeText(text);
1985
+ setCopied(true);
1986
+ setError(null);
1987
+ setTimeout(reset, resetDelay);
1988
+ return true;
1989
+ } catch (err) {
1990
+ const message = err instanceof Error ? err.message : "Failed to copy to clipboard";
1991
+ setError(message);
1992
+ setCopied(false);
1993
+ return false;
1994
+ }
1995
+ },
1996
+ [resetDelay, reset]
1997
+ );
1998
+ return { copy, copied, error, reset };
1999
+ }
2000
+ var useCopyToClipboard_default = useCopyToClipboard;
2001
+ function useMediaQuery(query) {
2002
+ const getMatches = (query2) => {
2003
+ if (typeof window === "undefined") return false;
2004
+ return window.matchMedia(query2).matches;
2005
+ };
2006
+ const [matches, setMatches] = react.useState(getMatches(query));
2007
+ react.useEffect(() => {
2008
+ if (typeof window === "undefined") return;
2009
+ const mediaQuery = window.matchMedia(query);
2010
+ const handleChange = () => setMatches(mediaQuery.matches);
2011
+ handleChange();
2012
+ mediaQuery.addEventListener("change", handleChange);
2013
+ return () => mediaQuery.removeEventListener("change", handleChange);
2014
+ }, [query]);
2015
+ return matches;
2016
+ }
2017
+ var useIsMobile = () => useMediaQuery("(max-width: 767px)");
2018
+ var useIsTablet = () => useMediaQuery("(min-width: 768px) and (max-width: 1023px)");
2019
+ var useIsDesktop = () => useMediaQuery("(min-width: 1024px)");
2020
+ var useIsMobileOrTablet = () => useMediaQuery("(max-width: 1023px)");
2021
+ var useMediaQuery_default = useMediaQuery;
2022
+ function useOrientation() {
2023
+ const getOrientation = () => {
2024
+ if (typeof window === "undefined" || !window.screen?.orientation) {
2025
+ return {
2026
+ angle: 0,
2027
+ type: "portrait-primary",
2028
+ isPortrait: true,
2029
+ isLandscape: false
2030
+ };
2031
+ }
2032
+ const { angle, type } = window.screen.orientation;
2033
+ const isPortrait = type.includes("portrait");
2034
+ const isLandscape = type.includes("landscape");
2035
+ return { angle, type, isPortrait, isLandscape };
2036
+ };
2037
+ const [orientation, setOrientation] = react.useState(getOrientation);
2038
+ react.useEffect(() => {
2039
+ if (typeof window === "undefined") return;
2040
+ const handleOrientationChange = () => {
2041
+ setOrientation(getOrientation());
2042
+ };
2043
+ if (window.screen?.orientation) {
2044
+ window.screen.orientation.addEventListener("change", handleOrientationChange);
2045
+ }
2046
+ window.addEventListener("orientationchange", handleOrientationChange);
2047
+ window.addEventListener("resize", handleOrientationChange);
2048
+ return () => {
2049
+ if (window.screen?.orientation) {
2050
+ window.screen.orientation.removeEventListener("change", handleOrientationChange);
2051
+ }
2052
+ window.removeEventListener("orientationchange", handleOrientationChange);
2053
+ window.removeEventListener("resize", handleOrientationChange);
2054
+ };
2055
+ }, []);
2056
+ return orientation;
2057
+ }
2058
+ var useOrientation_default = useOrientation;
2059
+ function useBattery() {
2060
+ const [battery, setBattery] = react.useState({
2061
+ isSupported: false,
2062
+ charging: false,
2063
+ chargingTime: Infinity,
2064
+ dischargingTime: Infinity,
2065
+ level: 1,
2066
+ percentage: 100
2067
+ });
2068
+ react.useEffect(() => {
2069
+ if (typeof navigator === "undefined") return;
2070
+ const nav = navigator;
2071
+ if (!nav.getBattery) {
2072
+ setBattery((prev) => ({ ...prev, isSupported: false }));
2073
+ return;
2074
+ }
2075
+ let batteryManager = null;
2076
+ const updateBattery = (battery2) => {
2077
+ setBattery({
2078
+ isSupported: true,
2079
+ charging: battery2.charging,
2080
+ chargingTime: battery2.chargingTime,
2081
+ dischargingTime: battery2.dischargingTime,
2082
+ level: battery2.level,
2083
+ percentage: Math.round(battery2.level * 100)
2084
+ });
2085
+ };
2086
+ const handleChange = () => {
2087
+ if (batteryManager) {
2088
+ updateBattery(batteryManager);
2089
+ }
2090
+ };
2091
+ nav.getBattery().then((battery2) => {
2092
+ batteryManager = battery2;
2093
+ updateBattery(battery2);
2094
+ battery2.addEventListener("chargingchange", handleChange);
2095
+ battery2.addEventListener("chargingtimechange", handleChange);
2096
+ battery2.addEventListener("dischargingtimechange", handleChange);
2097
+ battery2.addEventListener("levelchange", handleChange);
2098
+ });
2099
+ return () => {
2100
+ if (batteryManager) {
2101
+ batteryManager.removeEventListener("chargingchange", handleChange);
2102
+ batteryManager.removeEventListener("chargingtimechange", handleChange);
2103
+ batteryManager.removeEventListener("dischargingtimechange", handleChange);
2104
+ batteryManager.removeEventListener("levelchange", handleChange);
2105
+ }
2106
+ };
2107
+ }, []);
2108
+ return battery;
2109
+ }
2110
+ var useBattery_default = useBattery;
2111
+ function useNetworkState() {
2112
+ const getConnection = () => {
2113
+ if (typeof navigator === "undefined") return void 0;
2114
+ const nav = navigator;
2115
+ return nav.connection || nav.mozConnection || nav.webkitConnection;
2116
+ };
2117
+ const getNetworkState = () => {
2118
+ const online = typeof navigator !== "undefined" ? navigator.onLine : true;
2119
+ const connection = getConnection();
2120
+ return {
2121
+ online,
2122
+ offline: !online,
2123
+ downlink: connection?.downlink,
2124
+ effectiveType: connection?.effectiveType,
2125
+ rtt: connection?.rtt,
2126
+ saveData: connection?.saveData,
2127
+ type: connection?.type,
2128
+ since: /* @__PURE__ */ new Date()
2129
+ };
2130
+ };
2131
+ const [state, setState] = react.useState(getNetworkState);
2132
+ react.useEffect(() => {
2133
+ if (typeof window === "undefined") return;
2134
+ const handleOnline = () => {
2135
+ setState((prev) => ({ ...prev, online: true, offline: false, since: /* @__PURE__ */ new Date() }));
2136
+ };
2137
+ const handleOffline = () => {
2138
+ setState((prev) => ({ ...prev, online: false, offline: true, since: /* @__PURE__ */ new Date() }));
2139
+ };
2140
+ const handleConnectionChange = () => {
2141
+ setState(getNetworkState());
2142
+ };
2143
+ window.addEventListener("online", handleOnline);
2144
+ window.addEventListener("offline", handleOffline);
2145
+ const connection = getConnection();
2146
+ if (connection) {
2147
+ connection.addEventListener("change", handleConnectionChange);
2148
+ }
2149
+ return () => {
2150
+ window.removeEventListener("online", handleOnline);
2151
+ window.removeEventListener("offline", handleOffline);
2152
+ if (connection) {
2153
+ connection.removeEventListener("change", handleConnectionChange);
2154
+ }
2155
+ };
2156
+ }, []);
2157
+ return state;
2158
+ }
2159
+ var useNetworkState_default = useNetworkState;
2160
+ var DEFAULT_EVENTS = [
2161
+ "mousemove",
2162
+ "mousedown",
2163
+ "keydown",
2164
+ "touchstart",
2165
+ "scroll",
2166
+ "wheel"
2167
+ ];
2168
+ function useIdle(options = {}) {
2169
+ const {
2170
+ timeout = 6e4,
2171
+ events = DEFAULT_EVENTS,
2172
+ initialState = false,
2173
+ onIdle,
2174
+ onActive
2175
+ } = options;
2176
+ const [isIdle, setIsIdle] = react.useState(initialState);
2177
+ const [lastActive, setLastActive] = react.useState(/* @__PURE__ */ new Date());
2178
+ const [isTracking, setIsTracking] = react.useState(true);
2179
+ const timeoutRef = react.useRef(null);
2180
+ const onIdleRef = react.useRef(onIdle);
2181
+ const onActiveRef = react.useRef(onActive);
2182
+ react.useEffect(() => {
2183
+ onIdleRef.current = onIdle;
2184
+ onActiveRef.current = onActive;
2185
+ }, [onIdle, onActive]);
2186
+ const handleActivity = react.useCallback(() => {
2187
+ if (!isTracking) return;
2188
+ setLastActive(/* @__PURE__ */ new Date());
2189
+ if (isIdle) {
2190
+ setIsIdle(false);
2191
+ onActiveRef.current?.();
2192
+ }
2193
+ if (timeoutRef.current) {
2194
+ clearTimeout(timeoutRef.current);
2195
+ }
2196
+ timeoutRef.current = setTimeout(() => {
2197
+ setIsIdle(true);
2198
+ onIdleRef.current?.();
2199
+ }, timeout);
2200
+ }, [isIdle, isTracking, timeout]);
2201
+ const reset = react.useCallback(() => {
2202
+ handleActivity();
2203
+ }, [handleActivity]);
2204
+ const start = react.useCallback(() => {
2205
+ setIsTracking(true);
2206
+ handleActivity();
2207
+ }, [handleActivity]);
2208
+ const stop = react.useCallback(() => {
2209
+ setIsTracking(false);
2210
+ if (timeoutRef.current) {
2211
+ clearTimeout(timeoutRef.current);
2212
+ timeoutRef.current = null;
2213
+ }
2214
+ }, []);
2215
+ react.useEffect(() => {
2216
+ if (typeof window === "undefined" || !isTracking) return;
2217
+ timeoutRef.current = setTimeout(() => {
2218
+ setIsIdle(true);
2219
+ onIdleRef.current?.();
2220
+ }, timeout);
2221
+ events.forEach((event) => {
2222
+ window.addEventListener(event, handleActivity, { passive: true });
2223
+ });
2224
+ return () => {
2225
+ if (timeoutRef.current) {
2226
+ clearTimeout(timeoutRef.current);
2227
+ }
2228
+ events.forEach((event) => {
2229
+ window.removeEventListener(event, handleActivity);
2230
+ });
2231
+ };
2232
+ }, [events, handleActivity, isTracking, timeout]);
2233
+ return {
2234
+ isIdle,
2235
+ lastActive,
2236
+ reset,
2237
+ start,
2238
+ stop
2239
+ };
2240
+ }
2241
+ var useIdle_default = useIdle;
2242
+ function useGeolocation(options = {}) {
2243
+ const {
2244
+ enableHighAccuracy = false,
2245
+ maximumAge = 0,
2246
+ timeout = Infinity,
2247
+ watch = false
2248
+ } = options;
2249
+ const isSupported = typeof navigator !== "undefined" && "geolocation" in navigator;
2250
+ const [state, setState] = react.useState({
2251
+ loading: true,
2252
+ error: null,
2253
+ latitude: null,
2254
+ longitude: null,
2255
+ accuracy: null,
2256
+ altitude: null,
2257
+ altitudeAccuracy: null,
2258
+ heading: null,
2259
+ speed: null,
2260
+ timestamp: null
2261
+ });
2262
+ const handleSuccess = react.useCallback((position) => {
2263
+ setState({
2264
+ loading: false,
2265
+ error: null,
2266
+ latitude: position.coords.latitude,
2267
+ longitude: position.coords.longitude,
2268
+ accuracy: position.coords.accuracy,
2269
+ altitude: position.coords.altitude,
2270
+ altitudeAccuracy: position.coords.altitudeAccuracy,
2271
+ heading: position.coords.heading,
2272
+ speed: position.coords.speed,
2273
+ timestamp: position.timestamp
2274
+ });
2275
+ }, []);
2276
+ const handleError = react.useCallback((error) => {
2277
+ setState((prev) => ({
2278
+ ...prev,
2279
+ loading: false,
2280
+ error: error.message
2281
+ }));
2282
+ }, []);
2283
+ const refresh = react.useCallback(() => {
2284
+ if (!isSupported) return;
2285
+ setState((prev) => ({ ...prev, loading: true }));
2286
+ navigator.geolocation.getCurrentPosition(handleSuccess, handleError, {
2287
+ enableHighAccuracy,
2288
+ maximumAge,
2289
+ timeout
2290
+ });
2291
+ }, [isSupported, enableHighAccuracy, maximumAge, timeout, handleSuccess, handleError]);
2292
+ react.useEffect(() => {
2293
+ if (!isSupported) {
2294
+ setState((prev) => ({
2295
+ ...prev,
2296
+ loading: false,
2297
+ error: "Geolocation is not supported"
2298
+ }));
2299
+ return;
2300
+ }
2301
+ const positionOptions = {
2302
+ enableHighAccuracy,
2303
+ maximumAge,
2304
+ timeout
2305
+ };
2306
+ navigator.geolocation.getCurrentPosition(
2307
+ handleSuccess,
2308
+ handleError,
2309
+ positionOptions
2310
+ );
2311
+ let watchId = null;
2312
+ if (watch) {
2313
+ watchId = navigator.geolocation.watchPosition(
2314
+ handleSuccess,
2315
+ handleError,
2316
+ positionOptions
2317
+ );
2318
+ }
2319
+ return () => {
2320
+ if (watchId !== null) {
2321
+ navigator.geolocation.clearWatch(watchId);
2322
+ }
2323
+ };
2324
+ }, [isSupported, enableHighAccuracy, maximumAge, timeout, watch, handleSuccess, handleError]);
2325
+ return {
2326
+ ...state,
2327
+ refresh,
2328
+ isSupported
2329
+ };
2330
+ }
2331
+ var useGeolocation_default = useGeolocation;
2332
+ function usePreferredLanguage() {
2333
+ const getLanguageState = () => {
2334
+ if (typeof navigator === "undefined") {
2335
+ return { language: "en", languages: ["en"] };
2336
+ }
2337
+ return {
2338
+ language: navigator.language || "en",
2339
+ languages: navigator.languages || [navigator.language || "en"]
2340
+ };
2341
+ };
2342
+ const [state, setState] = react.useState(getLanguageState);
2343
+ react.useEffect(() => {
2344
+ if (typeof window === "undefined") return;
2345
+ const handleLanguageChange = () => {
2346
+ setState(getLanguageState());
2347
+ };
2348
+ window.addEventListener("languagechange", handleLanguageChange);
2349
+ return () => {
2350
+ window.removeEventListener("languagechange", handleLanguageChange);
2351
+ };
2352
+ }, []);
2353
+ return state;
2354
+ }
2355
+ var usePreferredLanguage_default = usePreferredLanguage;
2356
+ function useThemeDetector() {
2357
+ const getCurrentTheme = () => {
2358
+ if (typeof window === "undefined") return "light";
2359
+ return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
2360
+ };
2361
+ const [theme, setTheme] = react.useState(getCurrentTheme);
2362
+ react.useEffect(() => {
2363
+ if (typeof window === "undefined") return;
2364
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
2365
+ const handleChange = (e) => {
2366
+ setTheme(e.matches ? "dark" : "light");
2367
+ };
2368
+ mediaQuery.addEventListener("change", handleChange);
2369
+ return () => mediaQuery.removeEventListener("change", handleChange);
2370
+ }, []);
2371
+ return theme;
2372
+ }
2373
+ var useThemeDetector_default = useThemeDetector;
585
2374
  function useLocalStorage(key, initialValue, options = {}) {
586
2375
  const {
587
2376
  serializer = JSON.stringify,
@@ -639,150 +2428,532 @@ function useLocalStorage(key, initialValue, options = {}) {
639
2428
  window.localStorage.removeItem(key);
640
2429
  setStoredValue(initialValue);
641
2430
  log("Removed value");
642
- window.dispatchEvent(new StorageEvent("storage", { key, newValue: null }));
2431
+ window.dispatchEvent(new StorageEvent("storage", { key, newValue: null }));
2432
+ } catch (error) {
2433
+ console.warn(`Error removing localStorage key "${key}":`, error);
2434
+ }
2435
+ }, [key, initialValue, log]);
2436
+ react.useEffect(() => {
2437
+ if (!syncTabs || typeof window === "undefined") {
2438
+ return;
2439
+ }
2440
+ const handleStorageChange = (event) => {
2441
+ if (event.key !== key) {
2442
+ return;
2443
+ }
2444
+ log("Storage event received:", event.newValue);
2445
+ if (event.newValue === null) {
2446
+ setStoredValue(initialValue);
2447
+ } else {
2448
+ try {
2449
+ setStoredValue(deserializer(event.newValue));
2450
+ } catch {
2451
+ console.warn(`Error parsing localStorage change for key "${key}"`);
2452
+ }
2453
+ }
2454
+ };
2455
+ window.addEventListener("storage", handleStorageChange);
2456
+ return () => window.removeEventListener("storage", handleStorageChange);
2457
+ }, [key, initialValue, syncTabs, deserializer, log]);
2458
+ return [storedValue, setValue, removeValue];
2459
+ }
2460
+ var useLocalStorage_default = useLocalStorage;
2461
+ function useSessionStorage(key, initialValue, options = {}) {
2462
+ const {
2463
+ serializer = JSON.stringify,
2464
+ deserializer = JSON.parse,
2465
+ debug = false
2466
+ } = options;
2467
+ const log = react.useCallback(
2468
+ (...args) => {
2469
+ if (debug) console.log(`[useSessionStorage:${key}]`, ...args);
2470
+ },
2471
+ [debug, key]
2472
+ );
2473
+ const readValue = react.useCallback(() => {
2474
+ if (typeof window === "undefined") {
2475
+ return initialValue;
2476
+ }
2477
+ try {
2478
+ const item = window.sessionStorage.getItem(key);
2479
+ if (item === null) {
2480
+ return initialValue;
2481
+ }
2482
+ const parsed = deserializer(item);
2483
+ log("Read value:", parsed);
2484
+ return parsed;
2485
+ } catch (error) {
2486
+ console.warn(`Error reading sessionStorage key "${key}":`, error);
2487
+ return initialValue;
2488
+ }
2489
+ }, [key, initialValue, deserializer, log]);
2490
+ const [storedValue, setStoredValue] = react.useState(readValue);
2491
+ const setValue = react.useCallback(
2492
+ (value) => {
2493
+ if (typeof window === "undefined") {
2494
+ console.warn(`Cannot set sessionStorage key "${key}" in non-browser environment`);
2495
+ return;
2496
+ }
2497
+ try {
2498
+ const valueToStore = value instanceof Function ? value(storedValue) : value;
2499
+ setStoredValue(valueToStore);
2500
+ window.sessionStorage.setItem(key, serializer(valueToStore));
2501
+ log("Set value:", valueToStore);
2502
+ } catch (error) {
2503
+ console.warn(`Error setting sessionStorage key "${key}":`, error);
2504
+ }
2505
+ },
2506
+ [key, storedValue, serializer, log]
2507
+ );
2508
+ const removeValue = react.useCallback(() => {
2509
+ if (typeof window === "undefined") {
2510
+ return;
2511
+ }
2512
+ try {
2513
+ window.sessionStorage.removeItem(key);
2514
+ setStoredValue(initialValue);
2515
+ log("Removed value");
643
2516
  } catch (error) {
644
- console.warn(`Error removing localStorage key "${key}":`, error);
2517
+ console.warn(`Error removing sessionStorage key "${key}":`, error);
645
2518
  }
646
2519
  }, [key, initialValue, log]);
647
2520
  react.useEffect(() => {
648
- if (!syncTabs || typeof window === "undefined") {
649
- return;
650
- }
651
- const handleStorageChange = (event) => {
652
- if (event.key !== key) {
2521
+ if (typeof window === "undefined") return;
2522
+ const handleStorageChange = (e) => {
2523
+ if (e.storageArea !== sessionStorage || e.key !== key) {
653
2524
  return;
654
2525
  }
655
- log("Storage event received:", event.newValue);
656
- if (event.newValue === null) {
657
- setStoredValue(initialValue);
658
- } else {
659
- try {
660
- setStoredValue(deserializer(event.newValue));
661
- } catch {
662
- console.warn(`Error parsing localStorage change for key "${key}"`);
2526
+ try {
2527
+ if (e.newValue === null) {
2528
+ setStoredValue(initialValue);
2529
+ } else {
2530
+ setStoredValue(deserializer(e.newValue));
663
2531
  }
2532
+ } catch (error) {
2533
+ console.warn(`Error handling storage event for key "${key}":`, error);
664
2534
  }
665
2535
  };
666
2536
  window.addEventListener("storage", handleStorageChange);
667
- return () => window.removeEventListener("storage", handleStorageChange);
668
- }, [key, initialValue, syncTabs, deserializer, log]);
669
- return [storedValue, setValue, removeValue];
670
- }
671
- var useLocalStorage_default = useLocalStorage;
672
- function useDebounce(value, delay = 500) {
673
- const [debouncedValue, setDebouncedValue] = react.useState(value);
674
- react.useEffect(() => {
675
- const timer = setTimeout(() => {
676
- setDebouncedValue(value);
677
- }, delay);
678
2537
  return () => {
679
- clearTimeout(timer);
2538
+ window.removeEventListener("storage", handleStorageChange);
680
2539
  };
681
- }, [value, delay]);
682
- return debouncedValue;
2540
+ }, [key, initialValue, deserializer]);
2541
+ return [storedValue, setValue, removeValue];
683
2542
  }
684
- var useDebounce_default = useDebounce;
685
- function useCopyToClipboard(resetDelay = 2e3) {
686
- const [copied, setCopied] = react.useState(false);
2543
+ var useSessionStorage_default = useSessionStorage;
2544
+ var cache = /* @__PURE__ */ new Map();
2545
+ function useFetch(url, options = {}) {
2546
+ const {
2547
+ skip = false,
2548
+ transform,
2549
+ retries = 0,
2550
+ retryDelay = 1e3,
2551
+ cacheKey,
2552
+ cacheTime = 0,
2553
+ onSuccess,
2554
+ onError,
2555
+ body,
2556
+ ...fetchOptions
2557
+ } = options;
2558
+ const [data, setData] = react.useState(null);
2559
+ const [loading, setLoading] = react.useState(!skip && !!url);
2560
+ const [isFetching, setIsFetching] = react.useState(!skip && !!url);
687
2561
  const [error, setError] = react.useState(null);
688
- const reset = react.useCallback(() => {
689
- setCopied(false);
2562
+ const [status, setStatus] = react.useState(null);
2563
+ const abortControllerRef = react.useRef(null);
2564
+ const retriesRef = react.useRef(0);
2565
+ const fetchData = react.useCallback(async () => {
2566
+ if (!url) return null;
2567
+ const key = cacheKey || url;
2568
+ if (cacheTime > 0) {
2569
+ const cached = cache.get(key);
2570
+ if (cached && Date.now() - cached.timestamp < cacheTime) {
2571
+ const cachedData = cached.data;
2572
+ setData(cachedData);
2573
+ setLoading(false);
2574
+ setIsFetching(false);
2575
+ return cachedData;
2576
+ }
2577
+ }
2578
+ if (abortControllerRef.current) {
2579
+ abortControllerRef.current.abort();
2580
+ }
2581
+ abortControllerRef.current = new AbortController();
2582
+ setIsFetching(true);
690
2583
  setError(null);
691
- }, []);
692
- const copy = react.useCallback(
693
- async (text) => {
694
- if (!navigator?.clipboard) {
695
- try {
696
- const textarea = document.createElement("textarea");
697
- textarea.value = text;
698
- textarea.style.position = "fixed";
699
- textarea.style.left = "-999999px";
700
- textarea.style.top = "-999999px";
701
- document.body.appendChild(textarea);
702
- textarea.focus();
703
- textarea.select();
704
- const successful = document.execCommand("copy");
705
- document.body.removeChild(textarea);
706
- if (successful) {
707
- setCopied(true);
708
- setError(null);
709
- setTimeout(reset, resetDelay);
710
- return true;
711
- } else {
712
- throw new Error("execCommand failed");
713
- }
714
- } catch (err) {
715
- const message = err instanceof Error ? err.message : "Failed to copy to clipboard";
716
- setError(message);
717
- setCopied(false);
718
- return false;
2584
+ try {
2585
+ let processedBody;
2586
+ if (body !== null && body !== void 0) {
2587
+ if (typeof body === "object" && !(body instanceof FormData) && !(body instanceof Blob)) {
2588
+ processedBody = JSON.stringify(body);
2589
+ fetchOptions.headers = {
2590
+ "Content-Type": "application/json",
2591
+ ...fetchOptions.headers
2592
+ };
2593
+ } else {
2594
+ processedBody = body;
719
2595
  }
720
2596
  }
721
- try {
722
- await navigator.clipboard.writeText(text);
723
- setCopied(true);
724
- setError(null);
725
- setTimeout(reset, resetDelay);
726
- return true;
727
- } catch (err) {
728
- const message = err instanceof Error ? err.message : "Failed to copy to clipboard";
729
- setError(message);
730
- setCopied(false);
731
- return false;
2597
+ const response = await fetch(url, {
2598
+ ...fetchOptions,
2599
+ body: processedBody,
2600
+ signal: abortControllerRef.current.signal
2601
+ });
2602
+ setStatus(response.status);
2603
+ if (!response.ok) {
2604
+ throw new Error(`HTTP error! status: ${response.status}`);
732
2605
  }
733
- },
734
- [resetDelay, reset]
735
- );
736
- return { copy, copied, error, reset };
2606
+ const responseData = await response.json();
2607
+ const transformedData = transform ? transform(responseData) : responseData;
2608
+ if (cacheTime > 0) {
2609
+ cache.set(key, { data: transformedData, timestamp: Date.now() });
2610
+ }
2611
+ setData(transformedData);
2612
+ setError(null);
2613
+ setLoading(false);
2614
+ setIsFetching(false);
2615
+ retriesRef.current = 0;
2616
+ onSuccess?.(transformedData);
2617
+ return transformedData;
2618
+ } catch (err) {
2619
+ if (err.name === "AbortError") {
2620
+ return null;
2621
+ }
2622
+ const fetchError = err instanceof Error ? err : new Error(String(err));
2623
+ if (retriesRef.current < retries) {
2624
+ retriesRef.current++;
2625
+ await new Promise((resolve) => setTimeout(resolve, retryDelay));
2626
+ return fetchData();
2627
+ }
2628
+ setError(fetchError);
2629
+ setLoading(false);
2630
+ setIsFetching(false);
2631
+ retriesRef.current = 0;
2632
+ onError?.(fetchError);
2633
+ return null;
2634
+ }
2635
+ }, [url, cacheKey, cacheTime, transform, retries, retryDelay, body, fetchOptions, onSuccess, onError]);
2636
+ const abort = react.useCallback(() => {
2637
+ if (abortControllerRef.current) {
2638
+ abortControllerRef.current.abort();
2639
+ }
2640
+ }, []);
2641
+ const refetch = react.useCallback(async () => {
2642
+ const key = cacheKey || url || "";
2643
+ cache.delete(key);
2644
+ setLoading(true);
2645
+ return fetchData();
2646
+ }, [fetchData, cacheKey, url]);
2647
+ react.useEffect(() => {
2648
+ if (skip || !url) {
2649
+ setLoading(false);
2650
+ setIsFetching(false);
2651
+ return;
2652
+ }
2653
+ fetchData();
2654
+ return () => {
2655
+ abort();
2656
+ };
2657
+ }, [url, skip]);
2658
+ return {
2659
+ data,
2660
+ loading,
2661
+ error,
2662
+ refetch,
2663
+ abort,
2664
+ isFetching,
2665
+ status
2666
+ };
737
2667
  }
738
- var useCopyToClipboard_default = useCopyToClipboard;
739
- function usePageTitle(title, options = {}) {
740
- const { suffix, separator = " | ", restoreOnUnmount = true } = options;
2668
+ var useFetch_default = useFetch;
2669
+ var scriptCache = /* @__PURE__ */ new Map();
2670
+ function useScript(src, options = {}) {
2671
+ const { shouldLoad = true, removeOnUnmount = false, attributes = {} } = options;
2672
+ const [status, setStatus] = react.useState(() => {
2673
+ if (!src) return "idle";
2674
+ if (typeof window === "undefined") return "idle";
2675
+ const existingScript = document.querySelector(`script[src="${src}"]`);
2676
+ if (existingScript) {
2677
+ return scriptCache.get(src) || "ready";
2678
+ }
2679
+ return "idle";
2680
+ });
2681
+ const load = react.useCallback(() => {
2682
+ if (!src || typeof document === "undefined") return;
2683
+ const existingScript = document.querySelector(`script[src="${src}"]`);
2684
+ if (existingScript) {
2685
+ const cachedStatus = scriptCache.get(src);
2686
+ if (cachedStatus) {
2687
+ setStatus(cachedStatus);
2688
+ }
2689
+ return;
2690
+ }
2691
+ setStatus("loading");
2692
+ scriptCache.set(src, "loading");
2693
+ const script = document.createElement("script");
2694
+ script.src = src;
2695
+ script.async = true;
2696
+ Object.entries(attributes).forEach(([key, value]) => {
2697
+ script.setAttribute(key, value);
2698
+ });
2699
+ const handleLoad = () => {
2700
+ setStatus("ready");
2701
+ scriptCache.set(src, "ready");
2702
+ };
2703
+ const handleError = () => {
2704
+ setStatus("error");
2705
+ scriptCache.set(src, "error");
2706
+ };
2707
+ script.addEventListener("load", handleLoad);
2708
+ script.addEventListener("error", handleError);
2709
+ document.body.appendChild(script);
2710
+ }, [src, attributes]);
2711
+ const remove = react.useCallback(() => {
2712
+ if (!src || typeof document === "undefined") return;
2713
+ const existingScript = document.querySelector(`script[src="${src}"]`);
2714
+ if (existingScript) {
2715
+ document.body.removeChild(existingScript);
2716
+ scriptCache.delete(src);
2717
+ setStatus("idle");
2718
+ }
2719
+ }, [src]);
2720
+ react.useEffect(() => {
2721
+ if (shouldLoad && status === "idle") {
2722
+ load();
2723
+ }
2724
+ }, [shouldLoad, status, load]);
741
2725
  react.useEffect(() => {
742
- const originalTitle = document.title;
743
- const newTitle = suffix ? `${title}${separator}${suffix}` : title;
744
- document.title = newTitle;
745
2726
  return () => {
746
- if (restoreOnUnmount) {
747
- document.title = originalTitle;
2727
+ if (removeOnUnmount) {
2728
+ remove();
748
2729
  }
749
2730
  };
750
- }, [title, suffix, separator, restoreOnUnmount]);
2731
+ }, [removeOnUnmount, remove]);
2732
+ return {
2733
+ status,
2734
+ ready: status === "ready",
2735
+ loading: status === "loading",
2736
+ error: status === "error",
2737
+ load,
2738
+ remove
2739
+ };
751
2740
  }
752
- var usePageTitle_default = usePageTitle;
753
- function useInterval(callback, delay) {
754
- const savedCallback = react.useRef(callback);
2741
+ var useScript_default = useScript;
2742
+ function useRenderInfo(componentName = "Component") {
2743
+ const renderCount = react.useRef(0);
2744
+ const lastRenderTime = react.useRef(Date.now());
2745
+ const currentTime = Date.now();
2746
+ const sinceLastRender = currentTime - lastRenderTime.current;
2747
+ renderCount.current++;
2748
+ const renders = renderCount.current;
755
2749
  react.useEffect(() => {
756
- savedCallback.current = callback;
757
- }, [callback]);
2750
+ lastRenderTime.current = currentTime;
2751
+ });
2752
+ const info = {
2753
+ name: componentName,
2754
+ renders,
2755
+ sinceLastRender,
2756
+ timestamp: currentTime
2757
+ };
2758
+ if (process.env.NODE_ENV === "development") {
2759
+ console.log(`[${componentName}] Render #${renders} (${sinceLastRender}ms since last)`);
2760
+ }
2761
+ return info;
2762
+ }
2763
+ var useRenderInfo_default = useRenderInfo;
2764
+ function useRenderCount() {
2765
+ const renderCount = react.useRef(0);
2766
+ renderCount.current++;
2767
+ return renderCount.current;
2768
+ }
2769
+ var useRenderCount_default = useRenderCount;
2770
+ function useLogger(componentName, props, options = {}) {
2771
+ const {
2772
+ logProps = true,
2773
+ logLifecycle = true,
2774
+ logger = console.log
2775
+ } = options;
2776
+ const previousProps = react.useRef(props);
2777
+ const renderCount = react.useRef(0);
2778
+ renderCount.current++;
758
2779
  react.useEffect(() => {
759
- if (delay === null) {
2780
+ if (logLifecycle) {
2781
+ logger(`[${componentName}] Mounted`);
2782
+ }
2783
+ return () => {
2784
+ if (logLifecycle) {
2785
+ logger(`[${componentName}] Unmounted (rendered ${renderCount.current} times)`);
2786
+ }
2787
+ };
2788
+ }, []);
2789
+ react.useEffect(() => {
2790
+ if (!logProps || !props || !previousProps.current) {
2791
+ previousProps.current = props;
760
2792
  return;
761
2793
  }
762
- const tick = () => savedCallback.current();
763
- const id = setInterval(tick, delay);
764
- return () => clearInterval(id);
765
- }, [delay]);
2794
+ const changedProps = {};
2795
+ let hasChanges = false;
2796
+ Object.keys(props).forEach((key) => {
2797
+ if (previousProps.current?.[key] !== props[key]) {
2798
+ changedProps[key] = {
2799
+ from: previousProps.current?.[key],
2800
+ to: props[key]
2801
+ };
2802
+ hasChanges = true;
2803
+ }
2804
+ });
2805
+ if (previousProps.current) {
2806
+ Object.keys(previousProps.current).forEach((key) => {
2807
+ if (!(key in props)) {
2808
+ changedProps[key] = {
2809
+ from: previousProps.current?.[key],
2810
+ to: void 0
2811
+ };
2812
+ hasChanges = true;
2813
+ }
2814
+ });
2815
+ }
2816
+ if (hasChanges) {
2817
+ logger(`[${componentName}] Props changed:`, changedProps);
2818
+ }
2819
+ previousProps.current = props;
2820
+ }, [componentName, props, logProps, logger]);
2821
+ if (process.env.NODE_ENV === "development") {
2822
+ logger(`[${componentName}] Render #${renderCount.current}`);
2823
+ }
766
2824
  }
767
- var useInterval_default = useInterval;
768
- function useThemeDetector() {
769
- const getCurrentTheme = () => {
770
- if (typeof window === "undefined") return "light";
771
- return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
772
- };
773
- const [theme, setTheme] = react.useState(getCurrentTheme);
2825
+ var useLogger_default = useLogger;
2826
+ var defaultDimensions = {
2827
+ width: 0,
2828
+ height: 0,
2829
+ top: 0,
2830
+ left: 0,
2831
+ bottom: 0,
2832
+ right: 0,
2833
+ x: 0,
2834
+ y: 0
2835
+ };
2836
+ function useMeasure() {
2837
+ const [dimensions, setDimensions] = react.useState(defaultDimensions);
2838
+ const elementRef = react.useRef(null);
2839
+ const observerRef = react.useRef(null);
2840
+ const measure = react.useCallback(() => {
2841
+ if (!elementRef.current) return;
2842
+ const rect = elementRef.current.getBoundingClientRect();
2843
+ setDimensions({
2844
+ width: rect.width,
2845
+ height: rect.height,
2846
+ top: rect.top,
2847
+ left: rect.left,
2848
+ bottom: rect.bottom,
2849
+ right: rect.right,
2850
+ x: rect.x,
2851
+ y: rect.y
2852
+ });
2853
+ }, []);
2854
+ const ref = react.useCallback((node) => {
2855
+ if (observerRef.current) {
2856
+ observerRef.current.disconnect();
2857
+ observerRef.current = null;
2858
+ }
2859
+ if (node) {
2860
+ elementRef.current = node;
2861
+ if (typeof ResizeObserver !== "undefined") {
2862
+ observerRef.current = new ResizeObserver((entries) => {
2863
+ if (entries[0]) {
2864
+ const rect2 = entries[0].target.getBoundingClientRect();
2865
+ setDimensions({
2866
+ width: rect2.width,
2867
+ height: rect2.height,
2868
+ top: rect2.top,
2869
+ left: rect2.left,
2870
+ bottom: rect2.bottom,
2871
+ right: rect2.right,
2872
+ x: rect2.x,
2873
+ y: rect2.y
2874
+ });
2875
+ }
2876
+ });
2877
+ observerRef.current.observe(node);
2878
+ }
2879
+ const rect = node.getBoundingClientRect();
2880
+ setDimensions({
2881
+ width: rect.width,
2882
+ height: rect.height,
2883
+ top: rect.top,
2884
+ left: rect.left,
2885
+ bottom: rect.bottom,
2886
+ right: rect.right,
2887
+ x: rect.x,
2888
+ y: rect.y
2889
+ });
2890
+ } else {
2891
+ elementRef.current = null;
2892
+ }
2893
+ }, []);
774
2894
  react.useEffect(() => {
775
- if (typeof window === "undefined") return;
776
- const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
777
- const handleChange = (e) => {
778
- setTheme(e.matches ? "dark" : "light");
2895
+ return () => {
2896
+ if (observerRef.current) {
2897
+ observerRef.current.disconnect();
2898
+ }
779
2899
  };
780
- mediaQuery.addEventListener("change", handleChange);
781
- return () => mediaQuery.removeEventListener("change", handleChange);
782
2900
  }, []);
783
- return theme;
2901
+ return { ref, dimensions, measure };
784
2902
  }
785
- var useThemeDetector_default = useThemeDetector;
2903
+ var useMeasure_default = useMeasure;
2904
+ function useIntersectionObserver(options = {}) {
2905
+ const {
2906
+ root = null,
2907
+ rootMargin = "0px",
2908
+ threshold = 0,
2909
+ freezeOnceVisible = false,
2910
+ initialIsIntersecting = false,
2911
+ onChange
2912
+ } = options;
2913
+ const [entry, setEntry] = react.useState(null);
2914
+ const [isIntersecting, setIsIntersecting] = react.useState(initialIsIntersecting);
2915
+ const elementRef = react.useRef(null);
2916
+ const observerRef = react.useRef(null);
2917
+ const frozen = react.useRef(false);
2918
+ const ref = react.useCallback(
2919
+ (node) => {
2920
+ if (observerRef.current) {
2921
+ observerRef.current.disconnect();
2922
+ observerRef.current = null;
2923
+ }
2924
+ if (frozen.current) return;
2925
+ if (node && typeof IntersectionObserver !== "undefined") {
2926
+ elementRef.current = node;
2927
+ observerRef.current = new IntersectionObserver(
2928
+ ([observerEntry]) => {
2929
+ const newIsIntersecting = observerEntry.isIntersecting;
2930
+ setEntry(observerEntry);
2931
+ setIsIntersecting(newIsIntersecting);
2932
+ onChange?.(newIsIntersecting, observerEntry);
2933
+ if (freezeOnceVisible && newIsIntersecting) {
2934
+ frozen.current = true;
2935
+ observerRef.current?.disconnect();
2936
+ }
2937
+ },
2938
+ { root, rootMargin, threshold }
2939
+ );
2940
+ observerRef.current.observe(node);
2941
+ } else {
2942
+ elementRef.current = null;
2943
+ }
2944
+ },
2945
+ [root, rootMargin, threshold, freezeOnceVisible, onChange]
2946
+ );
2947
+ react.useEffect(() => {
2948
+ return () => {
2949
+ if (observerRef.current) {
2950
+ observerRef.current.disconnect();
2951
+ }
2952
+ };
2953
+ }, []);
2954
+ return { ref, isIntersecting, entry };
2955
+ }
2956
+ var useIntersectionObserver_default = useIntersectionObserver;
786
2957
  var DEFAULT_DURATION = 4e3;
787
2958
  function useSnackbar(defaultDuration = DEFAULT_DURATION) {
788
2959
  const [state, setState] = react.useState({
@@ -824,71 +2995,6 @@ function useSnackbar(defaultDuration = DEFAULT_DURATION) {
824
2995
  return { state, show, success, error, warning, info, close };
825
2996
  }
826
2997
  var useSnackbar_default = useSnackbar;
827
- function useMediaQuery(query) {
828
- const getMatches = (query2) => {
829
- if (typeof window === "undefined") return false;
830
- return window.matchMedia(query2).matches;
831
- };
832
- const [matches, setMatches] = react.useState(getMatches(query));
833
- react.useEffect(() => {
834
- if (typeof window === "undefined") return;
835
- const mediaQuery = window.matchMedia(query);
836
- const handleChange = () => setMatches(mediaQuery.matches);
837
- handleChange();
838
- mediaQuery.addEventListener("change", handleChange);
839
- return () => mediaQuery.removeEventListener("change", handleChange);
840
- }, [query]);
841
- return matches;
842
- }
843
- var useIsMobile = () => useMediaQuery("(max-width: 767px)");
844
- var useIsTablet = () => useMediaQuery("(min-width: 768px) and (max-width: 1023px)");
845
- var useIsDesktop = () => useMediaQuery("(min-width: 1024px)");
846
- var useIsMobileOrTablet = () => useMediaQuery("(max-width: 1023px)");
847
- var useMediaQuery_default = useMediaQuery;
848
- function useOnClickOutside(ref, handler, enabled = true) {
849
- react.useEffect(() => {
850
- if (!enabled) return;
851
- const listener = (event) => {
852
- const el = ref?.current;
853
- if (!el || el.contains(event.target)) {
854
- return;
855
- }
856
- handler(event);
857
- };
858
- document.addEventListener("mousedown", listener);
859
- document.addEventListener("touchstart", listener);
860
- return () => {
861
- document.removeEventListener("mousedown", listener);
862
- document.removeEventListener("touchstart", listener);
863
- };
864
- }, [ref, handler, enabled]);
865
- }
866
- var useOnClickOutside_default = useOnClickOutside;
867
- function useWindowSize(debounceMs = 100) {
868
- const getSize = () => ({
869
- width: typeof window !== "undefined" ? window.innerWidth : 0,
870
- height: typeof window !== "undefined" ? window.innerHeight : 0
871
- });
872
- const [windowSize, setWindowSize] = react.useState(getSize);
873
- react.useEffect(() => {
874
- if (typeof window === "undefined") return;
875
- let timeoutId;
876
- const handleResize = () => {
877
- clearTimeout(timeoutId);
878
- timeoutId = setTimeout(() => {
879
- setWindowSize(getSize());
880
- }, debounceMs);
881
- };
882
- setWindowSize(getSize());
883
- window.addEventListener("resize", handleResize);
884
- return () => {
885
- clearTimeout(timeoutId);
886
- window.removeEventListener("resize", handleResize);
887
- };
888
- }, [debounceMs]);
889
- return windowSize;
890
- }
891
- var useWindowSize_default = useWindowSize;
892
2998
 
893
2999
  exports.ApiUrlBuilder = ApiUrlBuilder;
894
3000
  exports.ClientLogger = ClientLogger;
@@ -898,6 +3004,7 @@ exports.appEvents = appEvents;
898
3004
  exports.camelToKebab = camelToKebab;
899
3005
  exports.capitalize = capitalize;
900
3006
  exports.capitalizeWords = capitalizeWords;
3007
+ exports.checkPackage = checkPackage;
901
3008
  exports.clientLogger = clientLogger;
902
3009
  exports.copyToClipboard = copyToClipboard;
903
3010
  exports.createApiEndpoints = createApiEndpoints;
@@ -913,7 +3020,9 @@ exports.formatDate = formatDate;
913
3020
  exports.formatDateForInput = formatDateForInput;
914
3021
  exports.formatDateTime = formatDateTime;
915
3022
  exports.formatDateTimeForInput = formatDateTimeForInput;
3023
+ exports.formatPackageCheckResult = formatPackageCheckResult;
916
3024
  exports.formatRelativeTime = formatRelativeTime;
3025
+ exports.generateNcuCommand = generateNcuCommand;
917
3026
  exports.getErrorMessage = getErrorMessage;
918
3027
  exports.getNextPage = getNextPage;
919
3028
  exports.getPrevPage = getPrevPage;
@@ -933,6 +3042,7 @@ exports.isSuccessResponse = isSuccessResponse;
933
3042
  exports.isToday = isToday;
934
3043
  exports.isUnauthorized = isUnauthorized;
935
3044
  exports.kebabToCamel = kebabToCamel;
3045
+ exports.packageCheck = packageCheck;
936
3046
  exports.parseError = parseError;
937
3047
  exports.parseFullResponse = parseFullResponse;
938
3048
  exports.parseResponse = parseResponse;
@@ -943,19 +3053,63 @@ exports.startOfDay = startOfDay;
943
3053
  exports.truncate = truncate;
944
3054
  exports.truncateWords = truncateWords;
945
3055
  exports.unslugify = unslugify;
3056
+ exports.useBattery = useBattery_default;
3057
+ exports.useClickAway = useClickAway_default;
3058
+ exports.useContinuousRetry = useContinuousRetry_default;
946
3059
  exports.useCopyToClipboard = useCopyToClipboard_default;
3060
+ exports.useCountdown = useCountdown_default;
3061
+ exports.useCounter = useCounter_default;
947
3062
  exports.useDebounce = useDebounce_default;
3063
+ exports.useDefault = useDefault_default;
3064
+ exports.useDocumentTitle = useDocumentTitle_default;
3065
+ exports.useEventListener = useEventListener_default;
3066
+ exports.useFavicon = useFavicon_default;
3067
+ exports.useFetch = useFetch_default;
3068
+ exports.useGeolocation = useGeolocation_default;
3069
+ exports.useHistoryState = useHistoryState_default;
3070
+ exports.useHover = useHover_default;
3071
+ exports.useIdle = useIdle_default;
3072
+ exports.useIntersectionObserver = useIntersectionObserver_default;
948
3073
  exports.useInterval = useInterval_default;
3074
+ exports.useIntervalWhen = useIntervalWhen_default;
3075
+ exports.useIsClient = useIsClient_default;
949
3076
  exports.useIsDesktop = useIsDesktop;
3077
+ exports.useIsFirstRender = useIsFirstRender_default;
950
3078
  exports.useIsMobile = useIsMobile;
951
3079
  exports.useIsMobileOrTablet = useIsMobileOrTablet;
952
3080
  exports.useIsTablet = useIsTablet;
3081
+ exports.useKeyPress = useKeyPress_default;
3082
+ exports.useList = useList_default;
953
3083
  exports.useLocalStorage = useLocalStorage_default;
3084
+ exports.useLockBodyScroll = useLockBodyScroll_default;
3085
+ exports.useLogger = useLogger_default;
3086
+ exports.useLongPress = useLongPress_default;
3087
+ exports.useMap = useMap_default;
3088
+ exports.useMeasure = useMeasure_default;
954
3089
  exports.useMediaQuery = useMediaQuery_default;
3090
+ exports.useMouse = useMouse_default;
3091
+ exports.useNetworkState = useNetworkState_default;
3092
+ exports.useObjectState = useObjectState_default;
955
3093
  exports.useOnClickOutside = useOnClickOutside_default;
3094
+ exports.useOrientation = useOrientation_default;
3095
+ exports.usePageLeave = usePageLeave_default;
956
3096
  exports.usePageTitle = usePageTitle_default;
3097
+ exports.usePreferredLanguage = usePreferredLanguage_default;
3098
+ exports.usePrevious = usePrevious_default;
3099
+ exports.useQueue = useQueue_default;
3100
+ exports.useRandomInterval = useRandomInterval_default;
3101
+ exports.useRenderCount = useRenderCount_default;
3102
+ exports.useRenderInfo = useRenderInfo_default;
3103
+ exports.useScript = useScript_default;
3104
+ exports.useSessionStorage = useSessionStorage_default;
3105
+ exports.useSet = useSet_default;
957
3106
  exports.useSnackbar = useSnackbar_default;
958
3107
  exports.useThemeDetector = useThemeDetector_default;
3108
+ exports.useThrottle = useThrottle_default;
3109
+ exports.useTimeout = useTimeout_default;
3110
+ exports.useToggle = useToggle_default;
3111
+ exports.useVisibilityChange = useVisibilityChange_default;
3112
+ exports.useWindowScroll = useWindowScroll_default;
959
3113
  exports.useWindowSize = useWindowSize_default;
960
3114
  exports.withAbortSignal = withAbortSignal;
961
3115
  exports.withFormData = withFormData;