@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.
- package/README.md +121 -36
- package/dist/client/index.d.mts +2 -2
- package/dist/client/index.d.ts +2 -2
- package/dist/client/index.js +2330 -176
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +2284 -178
- package/dist/client/index.mjs.map +1 -1
- package/dist/client/utils/index.d.mts +123 -1
- package/dist/client/utils/index.d.ts +123 -1
- package/dist/client/utils/index.js +207 -0
- package/dist/client/utils/index.js.map +1 -1
- package/dist/client/utils/index.mjs +204 -1
- package/dist/client/utils/index.mjs.map +1 -1
- package/dist/index-BLltj-zN.d.ts +1236 -0
- package/dist/index-CIUdLBjA.d.mts +1236 -0
- package/dist/{index-iTKxFa78.d.ts → index-DEzgM15j.d.ts} +10 -2
- package/dist/{index-ClWtDfwk.d.ts → index-DNFVgQx8.d.ts} +544 -2
- package/dist/{index-CcrANHAQ.d.mts → index-DbV04Dx8.d.mts} +10 -2
- package/dist/{index-DSW6JfD-.d.mts → index-DfqEP6Oe.d.mts} +544 -2
- package/dist/index.d.mts +582 -7
- package/dist/index.d.ts +582 -7
- package/dist/index.js +3428 -221
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3430 -223
- package/dist/index.mjs.map +1 -1
- package/dist/server/index.d.mts +1 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +197 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +194 -2
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/utils/index.d.mts +73 -1
- package/dist/server/utils/index.d.ts +73 -1
- package/dist/server/utils/index.js +199 -0
- package/dist/server/utils/index.js.map +1 -1
- package/dist/server/utils/index.mjs +195 -1
- package/dist/server/utils/index.mjs.map +1 -1
- package/dist/shared/index.d.mts +1 -1
- package/dist/shared/index.d.ts +1 -1
- package/dist/shared/index.js +296 -0
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/index.mjs +274 -1
- package/dist/shared/index.mjs.map +1 -1
- package/package.json +9 -2
- package/dist/index-BNdT-2X4.d.ts +0 -229
- package/dist/index-Du0LLt9f.d.mts +0 -229
package/dist/client/index.js
CHANGED
|
@@ -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
|
|
2517
|
+
console.warn(`Error removing sessionStorage key "${key}":`, error);
|
|
645
2518
|
}
|
|
646
2519
|
}, [key, initialValue, log]);
|
|
647
2520
|
react.useEffect(() => {
|
|
648
|
-
if (
|
|
649
|
-
|
|
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
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
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
|
-
|
|
2538
|
+
window.removeEventListener("storage", handleStorageChange);
|
|
680
2539
|
};
|
|
681
|
-
}, [
|
|
682
|
-
return
|
|
2540
|
+
}, [key, initialValue, deserializer]);
|
|
2541
|
+
return [storedValue, setValue, removeValue];
|
|
683
2542
|
}
|
|
684
|
-
var
|
|
685
|
-
|
|
686
|
-
|
|
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
|
|
689
|
-
|
|
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
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
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
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
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
|
-
|
|
735
|
-
|
|
736
|
-
|
|
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
|
|
739
|
-
|
|
740
|
-
|
|
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 (
|
|
747
|
-
|
|
2727
|
+
if (removeOnUnmount) {
|
|
2728
|
+
remove();
|
|
748
2729
|
}
|
|
749
2730
|
};
|
|
750
|
-
}, [
|
|
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
|
|
753
|
-
function
|
|
754
|
-
const
|
|
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
|
-
|
|
757
|
-
}
|
|
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 (
|
|
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
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
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
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
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
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
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
|
|
2901
|
+
return { ref, dimensions, measure };
|
|
784
2902
|
}
|
|
785
|
-
var
|
|
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;
|