数通智联化工云平台
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

7109 lines
199 KiB

2 years ago
import { noop, makeDestructurable, camelize, toValue, isClient, isObject, tryOnScopeDispose, isIOS, tryOnMounted, computedWithControl, objectOmit, promiseTimeout, until, increaseWithUnit, objectEntries, useTimeoutFn, pausableWatch, toRef, createEventHook, timestamp, pausableFilter, watchIgnorable, debounceFilter, createFilterWrapper, bypassFilter, createSingletonPromise, toRefs, useIntervalFn, notNullish, containsProp, hasOwn, throttleFilter, useDebounceFn, useThrottleFn, clamp, syncRef, objectPick, tryOnUnmounted, watchWithFilter, identity, isDef } from '@vueuse/shared';
2 years ago
export * from '@vueuse/shared';
import { isRef, ref, shallowRef, watchEffect, computed, inject, isVue3, version, defineComponent, h, TransitionGroup, shallowReactive, Fragment, watch, getCurrentInstance, customRef, onUpdated, onMounted, readonly, nextTick, reactive, markRaw, getCurrentScope, isVue2, set, del, isReadonly, onBeforeUpdate } from 'vue-demi';
function computedAsync(evaluationCallback, initialState, optionsOrRef) {
let options;
if (isRef(optionsOrRef)) {
options = {
evaluating: optionsOrRef
};
} else {
options = optionsOrRef || {};
}
const {
lazy = false,
evaluating = void 0,
shallow = true,
onError = noop
} = options;
const started = ref(!lazy);
const current = shallow ? shallowRef(initialState) : ref(initialState);
let counter = 0;
watchEffect(async (onInvalidate) => {
if (!started.value)
return;
counter++;
const counterAtBeginning = counter;
let hasFinished = false;
if (evaluating) {
Promise.resolve().then(() => {
evaluating.value = true;
});
}
try {
const result = await evaluationCallback((cancelCallback) => {
onInvalidate(() => {
if (evaluating)
evaluating.value = false;
if (!hasFinished)
cancelCallback();
});
});
if (counterAtBeginning === counter)
current.value = result;
} catch (e) {
onError(e);
} finally {
if (evaluating && counterAtBeginning === counter)
evaluating.value = false;
hasFinished = true;
}
});
if (lazy) {
return computed(() => {
started.value = true;
return current.value;
});
} else {
return current;
}
}
function computedInject(key, options, defaultSource, treatDefaultAsFactory) {
let source = inject(key);
if (defaultSource)
source = inject(key, defaultSource);
if (treatDefaultAsFactory)
source = inject(key, defaultSource, treatDefaultAsFactory);
if (typeof options === "function") {
return computed((ctx) => options(source, ctx));
} else {
return computed({
get: (ctx) => options.get(source, ctx),
set: options.set
});
}
}
2 years ago
function createReusableTemplate(options = {}) {
2 years ago
if (!isVue3 && !version.startsWith("2.7.")) {
if (process.env.NODE_ENV !== "production")
throw new Error("[VueUse] createReusableTemplate only works in Vue 2.7 or above.");
return;
}
2 years ago
const {
inheritAttrs = true
} = options;
2 years ago
const render = shallowRef();
const define = /* #__PURE__ */ defineComponent({
setup(_, { slots }) {
return () => {
render.value = slots.default;
};
}
});
const reuse = /* #__PURE__ */ defineComponent({
2 years ago
inheritAttrs,
2 years ago
setup(_, { attrs, slots }) {
return () => {
var _a;
if (!render.value && process.env.NODE_ENV !== "production")
throw new Error("[VueUse] Failed to find the definition of reusable template");
2 years ago
const vnode = (_a = render.value) == null ? void 0 : _a.call(render, { ...keysToCamelKebabCase(attrs), $slots: slots });
return inheritAttrs && (vnode == null ? void 0 : vnode.length) === 1 ? vnode[0] : vnode;
2 years ago
};
}
});
return makeDestructurable(
{ define, reuse },
[define, reuse]
);
}
2 years ago
function keysToCamelKebabCase(obj) {
const newObj = {};
for (const key in obj)
newObj[camelize(key)] = obj[key];
return newObj;
}
2 years ago
function createTemplatePromise(options = {}) {
if (!isVue3) {
if (process.env.NODE_ENV !== "production")
throw new Error("[VueUse] createTemplatePromise only works in Vue 3 or above.");
return;
}
let index = 0;
const instances = ref([]);
function create(...args) {
const props = shallowReactive({
key: index++,
args,
promise: void 0,
resolve: () => {
},
reject: () => {
},
isResolving: false,
options
});
instances.value.push(props);
props.promise = new Promise((_resolve, _reject) => {
props.resolve = (v) => {
props.isResolving = true;
return _resolve(v);
};
props.reject = _reject;
}).finally(() => {
props.promise = void 0;
const index2 = instances.value.indexOf(props);
if (index2 !== -1)
instances.value.splice(index2, 1);
});
return props.promise;
}
function start(...args) {
if (options.singleton && instances.value.length > 0)
return instances.value[0].promise;
return create(...args);
}
const component = /* #__PURE__ */ defineComponent((_, { slots }) => {
const renderList = () => instances.value.map((props) => {
var _a;
return h(Fragment, { key: props.key }, (_a = slots.default) == null ? void 0 : _a.call(slots, props));
});
if (options.transition)
return () => h(TransitionGroup, options.transition, renderList);
return renderList;
});
component.start = start;
return component;
}
function createUnrefFn(fn) {
return function(...args) {
return fn.apply(this, args.map((i) => toValue(i)));
};
}
function unrefElement(elRef) {
var _a;
const plain = toValue(elRef);
return (_a = plain == null ? void 0 : plain.$el) != null ? _a : plain;
}
const defaultWindow = isClient ? window : void 0;
const defaultDocument = isClient ? window.document : void 0;
const defaultNavigator = isClient ? window.navigator : void 0;
const defaultLocation = isClient ? window.location : void 0;
function useEventListener(...args) {
let target;
let events;
let listeners;
let options;
if (typeof args[0] === "string" || Array.isArray(args[0])) {
[events, listeners, options] = args;
target = defaultWindow;
} else {
[target, events, listeners, options] = args;
}
if (!target)
return noop;
if (!Array.isArray(events))
events = [events];
if (!Array.isArray(listeners))
listeners = [listeners];
const cleanups = [];
const cleanup = () => {
cleanups.forEach((fn) => fn());
cleanups.length = 0;
};
const register = (el, event, listener, options2) => {
el.addEventListener(event, listener, options2);
return () => el.removeEventListener(event, listener, options2);
};
const stopWatch = watch(
() => [unrefElement(target), toValue(options)],
([el, options2]) => {
cleanup();
if (!el)
return;
2 years ago
const optionsClone = isObject(options2) ? { ...options2 } : options2;
2 years ago
cleanups.push(
...events.flatMap((event) => {
2 years ago
return listeners.map((listener) => register(el, event, listener, optionsClone));
2 years ago
})
);
},
{ immediate: true, flush: "post" }
);
const stop = () => {
stopWatch();
cleanup();
};
tryOnScopeDispose(stop);
return stop;
}
let _iOSWorkaround = false;
function onClickOutside(target, handler, options = {}) {
const { window = defaultWindow, ignore = [], capture = true, detectIframe = false } = options;
if (!window)
return;
if (isIOS && !_iOSWorkaround) {
_iOSWorkaround = true;
Array.from(window.document.body.children).forEach((el) => el.addEventListener("click", noop));
2 years ago
window.document.documentElement.addEventListener("click", noop);
2 years ago
}
let shouldListen = true;
const shouldIgnore = (event) => {
return ignore.some((target2) => {
if (typeof target2 === "string") {
return Array.from(window.document.querySelectorAll(target2)).some((el) => el === event.target || event.composedPath().includes(el));
} else {
const el = unrefElement(target2);
return el && (event.target === el || event.composedPath().includes(el));
}
});
};
const listener = (event) => {
const el = unrefElement(target);
if (!el || el === event.target || event.composedPath().includes(el))
return;
if (event.detail === 0)
shouldListen = !shouldIgnore(event);
if (!shouldListen) {
shouldListen = true;
return;
}
handler(event);
};
const cleanup = [
useEventListener(window, "click", listener, { passive: true, capture }),
useEventListener(window, "pointerdown", (e) => {
const el = unrefElement(target);
if (el)
shouldListen = !e.composedPath().includes(el) && !shouldIgnore(e);
}, { passive: true }),
detectIframe && useEventListener(window, "blur", (event) => {
2 years ago
setTimeout(() => {
var _a;
const el = unrefElement(target);
if (((_a = window.document.activeElement) == null ? void 0 : _a.tagName) === "IFRAME" && !(el == null ? void 0 : el.contains(window.document.activeElement)))
handler(event);
}, 0);
2 years ago
})
].filter(Boolean);
const stop = () => cleanup.forEach((fn) => fn());
return stop;
}
function createKeyPredicate(keyFilter) {
if (typeof keyFilter === "function")
return keyFilter;
else if (typeof keyFilter === "string")
return (event) => event.key === keyFilter;
else if (Array.isArray(keyFilter))
return (event) => keyFilter.includes(event.key);
return () => true;
}
function onKeyStroke(...args) {
let key;
let handler;
let options = {};
if (args.length === 3) {
key = args[0];
handler = args[1];
options = args[2];
} else if (args.length === 2) {
if (typeof args[1] === "object") {
key = true;
handler = args[0];
options = args[1];
} else {
key = args[0];
handler = args[1];
}
} else {
key = true;
handler = args[0];
}
const {
target = defaultWindow,
eventName = "keydown",
passive = false,
dedupe = false
} = options;
const predicate = createKeyPredicate(key);
const listener = (e) => {
if (e.repeat && toValue(dedupe))
return;
if (predicate(e))
handler(e);
};
return useEventListener(target, eventName, listener, passive);
}
function onKeyDown(key, handler, options = {}) {
2 years ago
return onKeyStroke(key, handler, { ...options, eventName: "keydown" });
2 years ago
}
function onKeyPressed(key, handler, options = {}) {
2 years ago
return onKeyStroke(key, handler, { ...options, eventName: "keypress" });
2 years ago
}
function onKeyUp(key, handler, options = {}) {
2 years ago
return onKeyStroke(key, handler, { ...options, eventName: "keyup" });
2 years ago
}
const DEFAULT_DELAY = 500;
function onLongPress(target, handler, options) {
var _a, _b;
const elementRef = computed(() => unrefElement(target));
let timeout;
function clear() {
if (timeout) {
clearTimeout(timeout);
timeout = void 0;
}
}
function onDown(ev) {
var _a2, _b2, _c, _d;
if (((_a2 = options == null ? void 0 : options.modifiers) == null ? void 0 : _a2.self) && ev.target !== elementRef.value)
return;
clear();
if ((_b2 = options == null ? void 0 : options.modifiers) == null ? void 0 : _b2.prevent)
ev.preventDefault();
if ((_c = options == null ? void 0 : options.modifiers) == null ? void 0 : _c.stop)
ev.stopPropagation();
timeout = setTimeout(
() => handler(ev),
(_d = options == null ? void 0 : options.delay) != null ? _d : DEFAULT_DELAY
);
}
const listenerOptions = {
capture: (_a = options == null ? void 0 : options.modifiers) == null ? void 0 : _a.capture,
once: (_b = options == null ? void 0 : options.modifiers) == null ? void 0 : _b.once
};
useEventListener(elementRef, "pointerdown", onDown, listenerOptions);
2 years ago
useEventListener(elementRef, ["pointerup", "pointerleave"], clear, listenerOptions);
2 years ago
}
function isFocusedElementEditable() {
const { activeElement, body } = document;
if (!activeElement)
return false;
if (activeElement === body)
return false;
switch (activeElement.tagName) {
case "INPUT":
case "TEXTAREA":
return true;
}
return activeElement.hasAttribute("contenteditable");
}
function isTypedCharValid({
keyCode,
metaKey,
ctrlKey,
altKey
}) {
if (metaKey || ctrlKey || altKey)
return false;
if (keyCode >= 48 && keyCode <= 57)
return true;
if (keyCode >= 65 && keyCode <= 90)
return true;
if (keyCode >= 97 && keyCode <= 122)
return true;
return false;
}
function onStartTyping(callback, options = {}) {
const { document: document2 = defaultDocument } = options;
const keydown = (event) => {
!isFocusedElementEditable() && isTypedCharValid(event) && callback(event);
};
if (document2)
useEventListener(document2, "keydown", keydown, { passive: true });
}
function templateRef(key, initialValue = null) {
const instance = getCurrentInstance();
let _trigger = () => {
};
const element = customRef((track, trigger) => {
_trigger = trigger;
return {
get() {
var _a, _b;
track();
return (_b = (_a = instance == null ? void 0 : instance.proxy) == null ? void 0 : _a.$refs[key]) != null ? _b : initialValue;
},
set() {
}
};
});
tryOnMounted(_trigger);
onUpdated(_trigger);
return element;
}
function useActiveElement(options = {}) {
var _a;
2 years ago
const {
window = defaultWindow,
deep = true
} = options;
2 years ago
const document = (_a = options.document) != null ? _a : window == null ? void 0 : window.document;
2 years ago
const getDeepActiveElement = () => {
var _a2;
let element = document == null ? void 0 : document.activeElement;
if (deep) {
while (element == null ? void 0 : element.shadowRoot)
element = (_a2 = element == null ? void 0 : element.shadowRoot) == null ? void 0 : _a2.activeElement;
}
return element;
};
2 years ago
const activeElement = computedWithControl(
() => null,
2 years ago
() => getDeepActiveElement()
2 years ago
);
if (window) {
useEventListener(window, "blur", (event) => {
if (event.relatedTarget !== null)
return;
activeElement.trigger();
}, true);
useEventListener(window, "focus", activeElement.trigger, true);
}
return activeElement;
}
function useMounted() {
const isMounted = ref(false);
if (getCurrentInstance()) {
onMounted(() => {
isMounted.value = true;
});
}
return isMounted;
}
function useSupported(callback) {
const isMounted = useMounted();
return computed(() => {
isMounted.value;
return Boolean(callback());
});
}
function useRafFn(fn, options = {}) {
const {
immediate = true,
2 years ago
fpsLimit = void 0,
2 years ago
window = defaultWindow
} = options;
const isActive = ref(false);
2 years ago
const intervalLimit = fpsLimit ? 1e3 / fpsLimit : null;
2 years ago
let previousFrameTimestamp = 0;
let rafId = null;
function loop(timestamp) {
if (!isActive.value || !window)
return;
2 years ago
const delta = timestamp - (previousFrameTimestamp || timestamp);
if (intervalLimit && delta < intervalLimit) {
rafId = window.requestAnimationFrame(loop);
return;
}
2 years ago
fn({ delta, timestamp });
previousFrameTimestamp = timestamp;
rafId = window.requestAnimationFrame(loop);
}
function resume() {
if (!isActive.value && window) {
isActive.value = true;
rafId = window.requestAnimationFrame(loop);
}
}
function pause() {
isActive.value = false;
if (rafId != null && window) {
window.cancelAnimationFrame(rafId);
rafId = null;
}
}
if (immediate)
resume();
tryOnScopeDispose(pause);
return {
isActive: readonly(isActive),
pause,
resume
};
}
function useAnimate(target, keyframes, options) {
let config;
let animateOptions;
if (isObject(options)) {
config = options;
animateOptions = objectOmit(options, ["window", "immediate", "commitStyles", "persist", "onReady", "onError"]);
} else {
config = { duration: options };
animateOptions = options;
}
const {
window = defaultWindow,
immediate = true,
commitStyles,
persist,
playbackRate: _playbackRate = 1,
onReady,
onError = (e) => {
console.error(e);
}
} = config;
const isSupported = useSupported(() => window && HTMLElement && "animate" in HTMLElement.prototype);
const animate = shallowRef(void 0);
const store = shallowReactive({
startTime: null,
currentTime: null,
timeline: null,
playbackRate: _playbackRate,
pending: false,
playState: immediate ? "idle" : "paused",
replaceState: "active"
});
const pending = computed(() => store.pending);
const playState = computed(() => store.playState);
const replaceState = computed(() => store.replaceState);
const startTime = computed({
get() {
return store.startTime;
},
set(value) {
store.startTime = value;
if (animate.value)
animate.value.startTime = value;
}
});
const currentTime = computed({
get() {
return store.currentTime;
},
set(value) {
store.currentTime = value;
if (animate.value) {
animate.value.currentTime = value;
syncResume();
}
}
});
const timeline = computed({
get() {
return store.timeline;
},
set(value) {
store.timeline = value;
if (animate.value)
animate.value.timeline = value;
}
});
const playbackRate = computed({
get() {
return store.playbackRate;
},
set(value) {
store.playbackRate = value;
if (animate.value)
animate.value.playbackRate = value;
}
});
const play = () => {
if (animate.value) {
try {
animate.value.play();
syncResume();
} catch (e) {
syncPause();
onError(e);
}
} else {
update();
}
};
const pause = () => {
var _a;
try {
(_a = animate.value) == null ? void 0 : _a.pause();
syncPause();
} catch (e) {
onError(e);
}
};
const reverse = () => {
var _a;
!animate.value && update();
try {
(_a = animate.value) == null ? void 0 : _a.reverse();
syncResume();
} catch (e) {
syncPause();
onError(e);
}
};
const finish = () => {
var _a;
try {
(_a = animate.value) == null ? void 0 : _a.finish();
syncPause();
} catch (e) {
onError(e);
}
};
const cancel = () => {
var _a;
try {
(_a = animate.value) == null ? void 0 : _a.cancel();
syncPause();
} catch (e) {
onError(e);
}
};
watch(() => unrefElement(target), (el) => {
el && update();
});
watch(() => keyframes, (value) => {
!animate.value && update();
if (!unrefElement(target) && animate.value) {
animate.value.effect = new KeyframeEffect(
unrefElement(target),
toValue(value),
animateOptions
);
}
}, { deep: true });
tryOnMounted(() => {
nextTick(() => update(true));
});
tryOnScopeDispose(cancel);
function update(init) {
const el = unrefElement(target);
if (!isSupported.value || !el)
return;
animate.value = el.animate(toValue(keyframes), animateOptions);
if (commitStyles)
animate.value.commitStyles();
if (persist)
animate.value.persist();
if (_playbackRate !== 1)
animate.value.playbackRate = _playbackRate;
if (init && !immediate)
animate.value.pause();
else
syncResume();
onReady == null ? void 0 : onReady(animate.value);
}
2 years ago
useEventListener(animate, ["cancel", "finish", "remove"], syncPause);
2 years ago
const { resume: resumeRef, pause: pauseRef } = useRafFn(() => {
if (!animate.value)
return;
store.pending = animate.value.pending;
store.playState = animate.value.playState;
store.replaceState = animate.value.replaceState;
store.startTime = animate.value.startTime;
store.currentTime = animate.value.currentTime;
store.timeline = animate.value.timeline;
store.playbackRate = animate.value.playbackRate;
}, { immediate: false });
function syncResume() {
if (isSupported.value)
resumeRef();
}
function syncPause() {
if (isSupported.value && window)
window.requestAnimationFrame(pauseRef);
}
return {
isSupported,
animate,
// actions
play,
pause,
reverse,
finish,
cancel,
// state
pending,
playState,
replaceState,
startTime,
currentTime,
timeline,
playbackRate
};
}
2 years ago
function useAsyncQueue(tasks, options) {
2 years ago
const {
interrupt = true,
onError = noop,
2 years ago
onFinished = noop,
signal
} = options || {};
2 years ago
const promiseState = {
2 years ago
aborted: "aborted",
fulfilled: "fulfilled",
2 years ago
pending: "pending",
2 years ago
rejected: "rejected"
2 years ago
};
2 years ago
const initialResult = Array.from(Array.from({ length: tasks.length }), () => ({ state: promiseState.pending, data: null }));
2 years ago
const result = reactive(initialResult);
const activeIndex = ref(-1);
if (!tasks || tasks.length === 0) {
onFinished();
return {
activeIndex,
result
};
}
function updateResult(state, res) {
activeIndex.value++;
result[activeIndex.value].data = res;
result[activeIndex.value].state = state;
}
tasks.reduce((prev, curr) => {
return prev.then((prevRes) => {
var _a;
2 years ago
if (signal == null ? void 0 : signal.aborted) {
updateResult(promiseState.aborted, new Error("aborted"));
return;
}
2 years ago
if (((_a = result[activeIndex.value]) == null ? void 0 : _a.state) === promiseState.rejected && interrupt) {
onFinished();
return;
}
2 years ago
const done = curr(prevRes).then((currentRes) => {
2 years ago
updateResult(promiseState.fulfilled, currentRes);
activeIndex.value === tasks.length - 1 && onFinished();
return currentRes;
});
2 years ago
if (!signal)
return done;
return Promise.race([done, whenAborted(signal)]);
2 years ago
}).catch((e) => {
2 years ago
if (signal == null ? void 0 : signal.aborted) {
updateResult(promiseState.aborted, e);
return e;
}
2 years ago
updateResult(promiseState.rejected, e);
onError();
return e;
});
}, Promise.resolve());
return {
activeIndex,
result
};
}
2 years ago
function whenAborted(signal) {
return new Promise((resolve, reject) => {
const error = new Error("aborted");
if (signal.aborted)
reject(error);
else
signal.addEventListener("abort", () => reject(error), { once: true });
});
}
2 years ago
function useAsyncState(promise, initialState, options) {
const {
immediate = true,
delay = 0,
onError = noop,
onSuccess = noop,
resetOnExecute = true,
shallow = true,
throwError
} = options != null ? options : {};
const state = shallow ? shallowRef(initialState) : ref(initialState);
const isReady = ref(false);
const isLoading = ref(false);
const error = shallowRef(void 0);
async function execute(delay2 = 0, ...args) {
if (resetOnExecute)
state.value = initialState;
error.value = void 0;
isReady.value = false;
isLoading.value = true;
if (delay2 > 0)
await promiseTimeout(delay2);
const _promise = typeof promise === "function" ? promise(...args) : promise;
try {
const data = await _promise;
state.value = data;
isReady.value = true;
onSuccess(data);
} catch (e) {
error.value = e;
onError(e);
if (throwError)
throw e;
} finally {
isLoading.value = false;
}
return state.value;
}
if (immediate)
execute(delay);
const shell = {
state,
isReady,
isLoading,
error,
execute
};
function waitUntilIsLoaded() {
return new Promise((resolve, reject) => {
until(isLoading).toBe(false).then(() => resolve(shell)).catch(reject);
});
}
2 years ago
return {
...shell,
2 years ago
then(onFulfilled, onRejected) {
return waitUntilIsLoaded().then(onFulfilled, onRejected);
}
2 years ago
};
2 years ago
}
const defaults = {
array: (v) => JSON.stringify(v),
object: (v) => JSON.stringify(v),
set: (v) => JSON.stringify(Array.from(v)),
map: (v) => JSON.stringify(Object.fromEntries(v)),
null: () => ""
};
function getDefaultSerialization(target) {
if (!target)
return defaults.null;
if (target instanceof Map)
return defaults.map;
else if (target instanceof Set)
return defaults.set;
else if (Array.isArray(target))
return defaults.array;
else
return defaults.object;
}
function useBase64(target, options) {
const base64 = ref("");
const promise = ref();
function execute() {
if (!isClient)
return;
promise.value = new Promise((resolve, reject) => {
try {
const _target = toValue(target);
if (_target == null) {
resolve("");
} else if (typeof _target === "string") {
resolve(blobToBase64(new Blob([_target], { type: "text/plain" })));
} else if (_target instanceof Blob) {
resolve(blobToBase64(_target));
} else if (_target instanceof ArrayBuffer) {
resolve(window.btoa(String.fromCharCode(...new Uint8Array(_target))));
} else if (_target instanceof HTMLCanvasElement) {
resolve(_target.toDataURL(options == null ? void 0 : options.type, options == null ? void 0 : options.quality));
} else if (_target instanceof HTMLImageElement) {
const img = _target.cloneNode(false);
img.crossOrigin = "Anonymous";
imgLoaded(img).then(() => {
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
resolve(canvas.toDataURL(options == null ? void 0 : options.type, options == null ? void 0 : options.quality));
}).catch(reject);
} else if (typeof _target === "object") {
const _serializeFn = (options == null ? void 0 : options.serializer) || getDefaultSerialization(_target);
const serialized = _serializeFn(_target);
return resolve(blobToBase64(new Blob([serialized], { type: "application/json" })));
} else {
reject(new Error("target is unsupported types"));
}
} catch (error) {
reject(error);
}
});
promise.value.then((res) => base64.value = res);
return promise.value;
}
if (isRef(target) || typeof target === "function")
watch(target, execute, { immediate: true });
else
execute();
return {
base64,
promise,
execute
};
}
function imgLoaded(img) {
return new Promise((resolve, reject) => {
if (!img.complete) {
img.onload = () => {
resolve();
};
img.onerror = reject;
} else {
resolve();
}
});
}
function blobToBase64(blob) {
return new Promise((resolve, reject) => {
const fr = new FileReader();
fr.onload = (e) => {
resolve(e.target.result);
};
fr.onerror = reject;
fr.readAsDataURL(blob);
});
}
2 years ago
function useBattery(options = {}) {
const { navigator = defaultNavigator } = options;
2 years ago
const events = ["chargingchange", "chargingtimechange", "dischargingtimechange", "levelchange"];
const isSupported = useSupported(() => navigator && "getBattery" in navigator);
const charging = ref(false);
const chargingTime = ref(0);
const dischargingTime = ref(0);
const level = ref(1);
let battery;
function updateBatteryInfo() {
charging.value = this.charging;
chargingTime.value = this.chargingTime || 0;
dischargingTime.value = this.dischargingTime || 0;
level.value = this.level;
}
if (isSupported.value) {
navigator.getBattery().then((_battery) => {
battery = _battery;
updateBatteryInfo.call(battery);
2 years ago
useEventListener(battery, events, updateBatteryInfo, { passive: true });
2 years ago
});
}
return {
isSupported,
charging,
chargingTime,
dischargingTime,
level
};
}
function useBluetooth(options) {
let {
acceptAllDevices = false
} = options || {};
const {
filters = void 0,
optionalServices = void 0,
navigator = defaultNavigator
} = options || {};
const isSupported = useSupported(() => navigator && "bluetooth" in navigator);
const device = shallowRef(void 0);
const error = shallowRef(null);
watch(device, () => {
connectToBluetoothGATTServer();
});
async function requestDevice() {
if (!isSupported.value)
return;
error.value = null;
if (filters && filters.length > 0)
acceptAllDevices = false;
try {
device.value = await (navigator == null ? void 0 : navigator.bluetooth.requestDevice({
acceptAllDevices,
filters,
optionalServices
}));
} catch (err) {
error.value = err;
}
}
const server = ref();
const isConnected = computed(() => {
var _a;
return ((_a = server.value) == null ? void 0 : _a.connected) || false;
});
async function connectToBluetoothGATTServer() {
error.value = null;
if (device.value && device.value.gatt) {
device.value.addEventListener("gattserverdisconnected", () => {
});
try {
server.value = await device.value.gatt.connect();
} catch (err) {
error.value = err;
}
}
}
tryOnMounted(() => {
var _a;
if (device.value)
(_a = device.value.gatt) == null ? void 0 : _a.connect();
});
tryOnScopeDispose(() => {
var _a;
if (device.value)
(_a = device.value.gatt) == null ? void 0 : _a.disconnect();
});
return {
isSupported,
isConnected,
// Device:
device,
requestDevice,
// Server:
server,
// Errors:
error
};
}
function useMediaQuery(query, options = {}) {
const { window = defaultWindow } = options;
const isSupported = useSupported(() => window && "matchMedia" in window && typeof window.matchMedia === "function");
let mediaQuery;
const matches = ref(false);
2 years ago
const handler = (event) => {
matches.value = event.matches;
};
2 years ago
const cleanup = () => {
if (!mediaQuery)
return;
if ("removeEventListener" in mediaQuery)
2 years ago
mediaQuery.removeEventListener("change", handler);
2 years ago
else
2 years ago
mediaQuery.removeListener(handler);
2 years ago
};
2 years ago
const stopWatch = watchEffect(() => {
2 years ago
if (!isSupported.value)
return;
cleanup();
2 years ago
mediaQuery = window.matchMedia(toValue(query));
2 years ago
if ("addEventListener" in mediaQuery)
2 years ago
mediaQuery.addEventListener("change", handler);
2 years ago
else
2 years ago
mediaQuery.addListener(handler);
matches.value = mediaQuery.matches;
});
tryOnScopeDispose(() => {
stopWatch();
cleanup();
mediaQuery = void 0;
});
2 years ago
return matches;
}
const breakpointsTailwind = {
"sm": 640,
"md": 768,
"lg": 1024,
"xl": 1280,
"2xl": 1536
};
const breakpointsBootstrapV5 = {
2 years ago
xs: 0,
2 years ago
sm: 576,
md: 768,
lg: 992,
xl: 1200,
xxl: 1400
};
const breakpointsVuetify = {
xs: 600,
sm: 960,
md: 1264,
lg: 1904
};
const breakpointsAntDesign = {
xs: 480,
sm: 576,
md: 768,
lg: 992,
xl: 1200,
xxl: 1600
};
const breakpointsQuasar = {
xs: 600,
sm: 1024,
md: 1440,
lg: 1920
};
const breakpointsSematic = {
mobileS: 320,
mobileM: 375,
mobileL: 425,
tablet: 768,
laptop: 1024,
laptopL: 1440,
desktop4K: 2560
};
const breakpointsMasterCss = {
"3xs": 360,
"2xs": 480,
"xs": 600,
"sm": 768,
"md": 1024,
"lg": 1280,
"xl": 1440,
"2xl": 1600,
"3xl": 1920,
"4xl": 2560
};
2 years ago
const breakpointsPrimeFlex = {
sm: 576,
md: 768,
lg: 992,
xl: 1200
};
2 years ago
function useBreakpoints(breakpoints, options = {}) {
function getValue(k, delta) {
let v = breakpoints[k];
if (delta != null)
v = increaseWithUnit(v, delta);
if (typeof v === "number")
v = `${v}px`;
return v;
}
const { window = defaultWindow } = options;
function match(query) {
if (!window)
return false;
return window.matchMedia(query).matches;
}
const greaterOrEqual = (k) => {
return useMediaQuery(`(min-width: ${getValue(k)})`, options);
};
const shortcutMethods = Object.keys(breakpoints).reduce((shortcuts, k) => {
Object.defineProperty(shortcuts, k, {
get: () => greaterOrEqual(k),
enumerable: true,
configurable: true
});
return shortcuts;
}, {});
return Object.assign(shortcutMethods, {
greater(k) {
return useMediaQuery(`(min-width: ${getValue(k, 0.1)})`, options);
},
greaterOrEqual,
smaller(k) {
return useMediaQuery(`(max-width: ${getValue(k, -0.1)})`, options);
},
smallerOrEqual(k) {
return useMediaQuery(`(max-width: ${getValue(k)})`, options);
},
between(a, b) {
return useMediaQuery(`(min-width: ${getValue(a)}) and (max-width: ${getValue(b, -0.1)})`, options);
},
isGreater(k) {
return match(`(min-width: ${getValue(k, 0.1)})`);
},
isGreaterOrEqual(k) {
return match(`(min-width: ${getValue(k)})`);
},
isSmaller(k) {
return match(`(max-width: ${getValue(k, -0.1)})`);
},
isSmallerOrEqual(k) {
return match(`(max-width: ${getValue(k)})`);
},
isInBetween(a, b) {
return match(`(min-width: ${getValue(a)}) and (max-width: ${getValue(b, -0.1)})`);
},
current() {
const points = Object.keys(breakpoints).map((i) => [i, greaterOrEqual(i)]);
return computed(() => points.filter(([, v]) => v.value).map(([k]) => k));
}
});
}
function useBroadcastChannel(options) {
const {
name,
window = defaultWindow
} = options;
const isSupported = useSupported(() => window && "BroadcastChannel" in window);
const isClosed = ref(false);
const channel = ref();
const data = ref();
const error = shallowRef(null);
const post = (data2) => {
if (channel.value)
channel.value.postMessage(data2);
};
const close = () => {
if (channel.value)
channel.value.close();
isClosed.value = true;
};
if (isSupported.value) {
tryOnMounted(() => {
error.value = null;
channel.value = new BroadcastChannel(name);
channel.value.addEventListener("message", (e) => {
data.value = e.data;
}, { passive: true });
channel.value.addEventListener("messageerror", (e) => {
error.value = e;
}, { passive: true });
channel.value.addEventListener("close", () => {
isClosed.value = true;
});
});
}
tryOnScopeDispose(() => {
close();
});
return {
isSupported,
channel,
data,
post,
close,
error,
isClosed
};
}
const WRITABLE_PROPERTIES = [
"hash",
"host",
"hostname",
"href",
"pathname",
"port",
"protocol",
"search"
];
2 years ago
function useBrowserLocation(options = {}) {
const { window = defaultWindow } = options;
2 years ago
const refs = Object.fromEntries(
WRITABLE_PROPERTIES.map((key) => [key, ref()])
);
for (const [key, ref2] of objectEntries(refs)) {
watch(ref2, (value) => {
if (!(window == null ? void 0 : window.location) || window.location[key] === value)
return;
window.location[key] = value;
});
}
const buildState = (trigger) => {
var _a;
const { state: state2, length } = (window == null ? void 0 : window.history) || {};
const { origin } = (window == null ? void 0 : window.location) || {};
for (const key of WRITABLE_PROPERTIES)
refs[key].value = (_a = window == null ? void 0 : window.location) == null ? void 0 : _a[key];
2 years ago
return reactive({
2 years ago
trigger,
state: state2,
length,
2 years ago
origin,
...refs
});
2 years ago
};
const state = ref(buildState("load"));
if (window) {
useEventListener(window, "popstate", () => state.value = buildState("popstate"), { passive: true });
useEventListener(window, "hashchange", () => state.value = buildState("hashchange"), { passive: true });
}
return state;
}
function useCached(refValue, comparator = (a, b) => a === b, watchOptions) {
const cachedValue = ref(refValue.value);
watch(() => refValue.value, (value) => {
if (!comparator(value, cachedValue.value))
cachedValue.value = value;
}, watchOptions);
return cachedValue;
}
function useClipboard(options = {}) {
const {
navigator = defaultNavigator,
read = false,
source,
copiedDuring = 1500,
legacy = false
} = options;
const isClipboardApiSupported = useSupported(() => navigator && "clipboard" in navigator);
const isSupported = computed(() => isClipboardApiSupported.value || legacy);
const text = ref("");
const copied = ref(false);
const timeout = useTimeoutFn(() => copied.value = false, copiedDuring);
function updateText() {
if (isClipboardApiSupported.value) {
navigator.clipboard.readText().then((value) => {
text.value = value;
});
} else {
text.value = legacyRead();
}
}
2 years ago
if (isSupported.value && read)
useEventListener(["copy", "cut"], updateText);
2 years ago
async function copy(value = toValue(source)) {
if (isSupported.value && value != null) {
if (isClipboardApiSupported.value)
await navigator.clipboard.writeText(value);
else
legacyCopy(value);
text.value = value;
copied.value = true;
timeout.start();
}
}
function legacyCopy(value) {
const ta = document.createElement("textarea");
ta.value = value != null ? value : "";
ta.style.position = "absolute";
ta.style.opacity = "0";
document.body.appendChild(ta);
ta.select();
document.execCommand("copy");
ta.remove();
}
function legacyRead() {
var _a, _b, _c;
return (_c = (_b = (_a = document == null ? void 0 : document.getSelection) == null ? void 0 : _a.call(document)) == null ? void 0 : _b.toString()) != null ? _c : "";
}
return {
isSupported,
text,
copied,
copy
};
}
function cloneFnJSON(source) {
return JSON.parse(JSON.stringify(source));
}
function useCloned(source, options = {}) {
const cloned = ref({});
const {
manual,
clone = cloneFnJSON,
// watch options
deep = true,
immediate = true
} = options;
function sync() {
cloned.value = clone(toValue(source));
}
2 years ago
if (!manual && (isRef(source) || typeof source === "function")) {
watch(source, sync, {
...options,
2 years ago
deep,
immediate
2 years ago
});
2 years ago
} else {
sync();
}
return { cloned, sync };
}
const _global = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
const globalKey = "__vueuse_ssr_handlers__";
const handlers = /* @__PURE__ */ getHandlers();
function getHandlers() {
if (!(globalKey in _global))
_global[globalKey] = _global[globalKey] || {};
return _global[globalKey];
}
function getSSRHandler(key, fallback) {
return handlers[key] || fallback;
}
function setSSRHandler(key, fn) {
handlers[key] = fn;
}
function guessSerializerType(rawInit) {
return rawInit == null ? "any" : rawInit instanceof Set ? "set" : rawInit instanceof Map ? "map" : rawInit instanceof Date ? "date" : typeof rawInit === "boolean" ? "boolean" : typeof rawInit === "string" ? "string" : typeof rawInit === "object" ? "object" : !Number.isNaN(rawInit) ? "number" : "any";
}
const StorageSerializers = {
boolean: {
read: (v) => v === "true",
write: (v) => String(v)
},
object: {
read: (v) => JSON.parse(v),
write: (v) => JSON.stringify(v)
},
number: {
read: (v) => Number.parseFloat(v),
write: (v) => String(v)
},
any: {
read: (v) => v,
write: (v) => String(v)
},
string: {
read: (v) => v,
write: (v) => String(v)
},
map: {
read: (v) => new Map(JSON.parse(v)),
write: (v) => JSON.stringify(Array.from(v.entries()))
},
set: {
read: (v) => new Set(JSON.parse(v)),
write: (v) => JSON.stringify(Array.from(v))
},
date: {
read: (v) => new Date(v),
write: (v) => v.toISOString()
}
};
const customStorageEventName = "vueuse-storage";
function useStorage(key, defaults, storage, options = {}) {
var _a;
const {
flush = "pre",
deep = true,
listenToStorageChanges = true,
writeDefaults = true,
mergeDefaults = false,
shallow,
window = defaultWindow,
eventFilter,
onError = (e) => {
console.error(e);
}
} = options;
const data = (shallow ? shallowRef : ref)(defaults);
if (!storage) {
try {
storage = getSSRHandler("getDefaultStorage", () => {
var _a2;
return (_a2 = defaultWindow) == null ? void 0 : _a2.localStorage;
})();
} catch (e) {
onError(e);
}
}
if (!storage)
return data;
const rawInit = toValue(defaults);
const type = guessSerializerType(rawInit);
const serializer = (_a = options.serializer) != null ? _a : StorageSerializers[type];
const { pause: pauseWatch, resume: resumeWatch } = pausableWatch(
data,
() => write(data.value),
{ flush, deep, eventFilter }
);
if (window && listenToStorageChanges) {
useEventListener(window, "storage", update);
useEventListener(window, customStorageEventName, updateFromCustomEvent);
}
update();
return data;
function write(v) {
try {
if (v == null) {
storage.removeItem(key);
} else {
const serialized = serializer.write(v);
const oldValue = storage.getItem(key);
if (oldValue !== serialized) {
storage.setItem(key, serialized);
if (window) {
window.dispatchEvent(new CustomEvent(customStorageEventName, {
detail: {
key,
oldValue,
newValue: serialized,
storageArea: storage
}
}));
}
}
}
} catch (e) {
onError(e);
}
}
function read(event) {
const rawValue = event ? event.newValue : storage.getItem(key);
if (rawValue == null) {
if (writeDefaults && rawInit !== null)
storage.setItem(key, serializer.write(rawInit));
return rawInit;
} else if (!event && mergeDefaults) {
const value = serializer.read(rawValue);
if (typeof mergeDefaults === "function")
return mergeDefaults(value, rawInit);
else if (type === "object" && !Array.isArray(value))
2 years ago
return { ...rawInit, ...value };
2 years ago
return value;
} else if (typeof rawValue !== "string") {
return rawValue;
} else {
return serializer.read(rawValue);
}
}
function updateFromCustomEvent(event) {
update(event.detail);
}
function update(event) {
if (event && event.storageArea !== storage)
return;
if (event && event.key == null) {
data.value = rawInit;
return;
}
if (event && event.key !== key)
return;
pauseWatch();
try {
2 years ago
if ((event == null ? void 0 : event.newValue) !== serializer.write(data.value))
data.value = read(event);
2 years ago
} catch (e) {
onError(e);
} finally {
if (event)
nextTick(resumeWatch);
else
resumeWatch();
}
}
}
function usePreferredDark(options) {
return useMediaQuery("(prefers-color-scheme: dark)", options);
}
function useColorMode(options = {}) {
const {
selector = "html",
attribute = "class",
initialValue = "auto",
window = defaultWindow,
storage,
storageKey = "vueuse-color-scheme",
listenToStorageChanges = true,
storageRef,
emitAuto,
disableTransition = true
} = options;
2 years ago
const modes = {
2 years ago
auto: "",
light: "light",
2 years ago
dark: "dark",
...options.modes || {}
};
2 years ago
const preferredDark = usePreferredDark({ window });
const system = computed(() => preferredDark.value ? "dark" : "light");
const store = storageRef || (storageKey == null ? toRef(initialValue) : useStorage(storageKey, initialValue, storage, { window, listenToStorageChanges }));
2 years ago
const state = computed(() => store.value === "auto" ? system.value : store.value);
2 years ago
const updateHTMLAttrs = getSSRHandler(
"updateHTMLAttrs",
(selector2, attribute2, value) => {
const el = typeof selector2 === "string" ? window == null ? void 0 : window.document.querySelector(selector2) : unrefElement(selector2);
if (!el)
return;
let style;
if (disableTransition) {
style = window.document.createElement("style");
2 years ago
const styleString = "*,*::before,*::after{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}";
style.appendChild(document.createTextNode(styleString));
2 years ago
window.document.head.appendChild(style);
}
if (attribute2 === "class") {
const current = value.split(/\s/g);
Object.values(modes).flatMap((i) => (i || "").split(/\s/g)).filter(Boolean).forEach((v) => {
if (current.includes(v))
el.classList.add(v);
else
el.classList.remove(v);
});
} else {
el.setAttribute(attribute2, value);
}
if (disableTransition) {
window.getComputedStyle(style).opacity;
document.head.removeChild(style);
}
}
);
function defaultOnChanged(mode) {
var _a;
updateHTMLAttrs(selector, attribute, (_a = modes[mode]) != null ? _a : mode);
}
function onChanged(mode) {
if (options.onChanged)
options.onChanged(mode, defaultOnChanged);
else
defaultOnChanged(mode);
}
watch(state, onChanged, { flush: "post", immediate: true });
tryOnMounted(() => onChanged(state.value));
const auto = computed({
get() {
return emitAuto ? store.value : state.value;
},
set(v) {
store.value = v;
}
});
try {
return Object.assign(auto, { store, system, state });
} catch (e) {
return auto;
}
}
function useConfirmDialog(revealed = ref(false)) {
const confirmHook = createEventHook();
const cancelHook = createEventHook();
const revealHook = createEventHook();
let _resolve = noop;
const reveal = (data) => {
revealHook.trigger(data);
revealed.value = true;
return new Promise((resolve) => {
_resolve = resolve;
});
};
const confirm = (data) => {
revealed.value = false;
confirmHook.trigger(data);
_resolve({ data, isCanceled: false });
};
const cancel = (data) => {
revealed.value = false;
cancelHook.trigger(data);
_resolve({ data, isCanceled: true });
};
return {
isRevealed: computed(() => revealed.value),
reveal,
confirm,
cancel,
onReveal: revealHook.on,
onConfirm: confirmHook.on,
onCancel: cancelHook.on
};
}
function useMutationObserver(target, callback, options = {}) {
2 years ago
const { window = defaultWindow, ...mutationOptions } = options;
2 years ago
let observer;
const isSupported = useSupported(() => window && "MutationObserver" in window);
const cleanup = () => {
if (observer) {
observer.disconnect();
observer = void 0;
}
};
const stopWatch = watch(
() => unrefElement(target),
(el) => {
cleanup();
if (isSupported.value && window && el) {
observer = new MutationObserver(callback);
observer.observe(el, mutationOptions);
}
},
{ immediate: true }
);
const stop = () => {
cleanup();
stopWatch();
};
tryOnScopeDispose(stop);
return {
isSupported,
stop
};
}
function useCssVar(prop, target, options = {}) {
const { window = defaultWindow, initialValue = "", observe = false } = options;
const variable = ref(initialValue);
const elRef = computed(() => {
var _a;
return unrefElement(target) || ((_a = window == null ? void 0 : window.document) == null ? void 0 : _a.documentElement);
});
function updateCssVar() {
var _a;
const key = toValue(prop);
const el = toValue(elRef);
if (el && window) {
const value = (_a = window.getComputedStyle(el).getPropertyValue(key)) == null ? void 0 : _a.trim();
variable.value = value || initialValue;
}
}
if (observe) {
useMutationObserver(elRef, updateCssVar, {
2 years ago
attributeFilter: ["style", "class"],
2 years ago
window
});
}
watch(
[elRef, () => toValue(prop)],
updateCssVar,
{ immediate: true }
);
watch(
variable,
(val) => {
var _a;
if ((_a = elRef.value) == null ? void 0 : _a.style)
elRef.value.style.setProperty(toValue(prop), val);
}
);
return variable;
}
function useCurrentElement() {
const vm = getCurrentInstance();
const currentElement = computedWithControl(
() => null,
() => vm.proxy.$el
);
onUpdated(currentElement.trigger);
onMounted(currentElement.trigger);
return currentElement;
}
function useCycleList(list, options) {
const state = shallowRef(getInitialValue());
const listRef = toRef(list);
const index = computed({
get() {
var _a;
const targetList = listRef.value;
let index2 = (options == null ? void 0 : options.getIndexOf) ? options.getIndexOf(state.value, targetList) : targetList.indexOf(state.value);
if (index2 < 0)
index2 = (_a = options == null ? void 0 : options.fallbackIndex) != null ? _a : 0;
return index2;
},
set(v) {
set(v);
}
});
function set(i) {
const targetList = listRef.value;
const length = targetList.length;
const index2 = (i % length + length) % length;
const value = targetList[index2];
state.value = value;
return value;
}
function shift(delta = 1) {
return set(index.value + delta);
}
function next(n = 1) {
return shift(n);
}
function prev(n = 1) {
return shift(-n);
}
function getInitialValue() {
var _a, _b;
return (_b = toValue((_a = options == null ? void 0 : options.initialValue) != null ? _a : toValue(list)[0])) != null ? _b : void 0;
}
watch(listRef, () => set(index.value));
return {
state,
index,
next,
prev
};
}
function useDark(options = {}) {
const {
valueDark = "dark",
valueLight = ""
} = options;
2 years ago
const mode = useColorMode({
...options,
2 years ago
onChanged: (mode2, defaultHandler) => {
var _a;
if (options.onChanged)
(_a = options.onChanged) == null ? void 0 : _a.call(options, mode2 === "dark", defaultHandler, mode2);
else
defaultHandler(mode2);
},
modes: {
dark: valueDark,
light: valueLight
}
2 years ago
});
2 years ago
const isDark = computed({
get() {
return mode.value === "dark";
},
set(v) {
const modeVal = v ? "dark" : "light";
if (mode.system.value === modeVal)
mode.value = "auto";
else
mode.value = modeVal;
}
});
return isDark;
}
function fnBypass(v) {
return v;
}
function fnSetSource(source, value) {
return source.value = value;
}
function defaultDump(clone) {
return clone ? typeof clone === "function" ? clone : cloneFnJSON : fnBypass;
}
function defaultParse(clone) {
return clone ? typeof clone === "function" ? clone : cloneFnJSON : fnBypass;
}
function useManualRefHistory(source, options = {}) {
const {
clone = false,
dump = defaultDump(clone),
parse = defaultParse(clone),
setSource = fnSetSource
} = options;
function _createHistoryRecord() {
return markRaw({
snapshot: dump(source.value),
timestamp: timestamp()
});
}
const last = ref(_createHistoryRecord());
const undoStack = ref([]);
const redoStack = ref([]);
const _setSource = (record) => {
setSource(source, parse(record.snapshot));
last.value = record;
};
const commit = () => {
undoStack.value.unshift(last.value);
last.value = _createHistoryRecord();
if (options.capacity && undoStack.value.length > options.capacity)
2 years ago
undoStack.value.splice(options.capacity, Number.POSITIVE_INFINITY);
2 years ago
if (redoStack.value.length)
redoStack.value.splice(0, redoStack.value.length);
};
const clear = () => {
undoStack.value.splice(0, undoStack.value.length);
redoStack.value.splice(0, redoStack.value.length);
};
const undo = () => {
const state = undoStack.value.shift();
if (state) {
redoStack.value.unshift(last.value);
_setSource(state);
}
};
const redo = () => {
const state = redoStack.value.shift();
if (state) {
undoStack.value.unshift(last.value);
_setSource(state);
}
};
const reset = () => {
_setSource(last.value);
};
const history = computed(() => [last.value, ...undoStack.value]);
const canUndo = computed(() => undoStack.value.length > 0);
const canRedo = computed(() => redoStack.value.length > 0);
return {
source,
undoStack,
redoStack,
last,
history,
canUndo,
canRedo,
clear,
commit,
reset,
undo,
redo
};
}
function useRefHistory(source, options = {}) {
const {
deep = false,
flush = "pre",
eventFilter
} = options;
const {
eventFilter: composedFilter,
pause,
resume: resumeTracking,
isActive: isTracking
} = pausableFilter(eventFilter);
const {
ignoreUpdates,
ignorePrevAsyncUpdates,
stop
} = watchIgnorable(
source,
commit,
{ deep, flush, eventFilter: composedFilter }
);
function setSource(source2, value) {
ignorePrevAsyncUpdates();
ignoreUpdates(() => {
source2.value = value;
});
}
2 years ago
const manualHistory = useManualRefHistory(source, { ...options, clone: options.clone || deep, setSource });
2 years ago
const { clear, commit: manualCommit } = manualHistory;
function commit() {
ignorePrevAsyncUpdates();
manualCommit();
}
function resume(commitNow) {
resumeTracking();
if (commitNow)
commit();
}
function batch(fn) {
let canceled = false;
const cancel = () => canceled = true;
ignoreUpdates(() => {
fn(cancel);
});
if (!canceled)
commit();
}
function dispose() {
stop();
clear();
}
2 years ago
return {
...manualHistory,
2 years ago
isTracking,
pause,
resume,
commit,
batch,
dispose
2 years ago
};
2 years ago
}
function useDebouncedRefHistory(source, options = {}) {
const filter = options.debounce ? debounceFilter(options.debounce) : void 0;
2 years ago
const history = useRefHistory(source, { ...options, eventFilter: filter });
return {
...history
};
2 years ago
}
function useDeviceMotion(options = {}) {
const {
window = defaultWindow,
eventFilter = bypassFilter
} = options;
const acceleration = ref({ x: null, y: null, z: null });
const rotationRate = ref({ alpha: null, beta: null, gamma: null });
const interval = ref(0);
const accelerationIncludingGravity = ref({
x: null,
y: null,
z: null
});
if (window) {
const onDeviceMotion = createFilterWrapper(
eventFilter,
(event) => {
acceleration.value = event.acceleration;
accelerationIncludingGravity.value = event.accelerationIncludingGravity;
rotationRate.value = event.rotationRate;
interval.value = event.interval;
}
);
useEventListener(window, "devicemotion", onDeviceMotion);
}
return {
acceleration,
accelerationIncludingGravity,
rotationRate,
interval
};
}
function useDeviceOrientation(options = {}) {
const { window = defaultWindow } = options;
const isSupported = useSupported(() => window && "DeviceOrientationEvent" in window);
const isAbsolute = ref(false);
const alpha = ref(null);
const beta = ref(null);
const gamma = ref(null);
if (window && isSupported.value) {
useEventListener(window, "deviceorientation", (event) => {
isAbsolute.value = event.absolute;
alpha.value = event.alpha;
beta.value = event.beta;
gamma.value = event.gamma;
});
}
return {
isSupported,
isAbsolute,
alpha,
beta,
gamma
};
}
2 years ago
function useDevicePixelRatio(options = {}) {
const {
window = defaultWindow
} = options;
2 years ago
const pixelRatio = ref(1);
if (window) {
2 years ago
let observe2 = function() {
2 years ago
pixelRatio.value = window.devicePixelRatio;
2 years ago
cleanup2();
2 years ago
media = window.matchMedia(`(resolution: ${pixelRatio.value}dppx)`);
2 years ago
media.addEventListener("change", observe2, { once: true });
}, cleanup2 = function() {
media == null ? void 0 : media.removeEventListener("change", observe2);
2 years ago
};
let media;
2 years ago
observe2();
tryOnScopeDispose(cleanup2);
2 years ago
}
return { pixelRatio };
}
function usePermission(permissionDesc, options = {}) {
const {
controls = false,
navigator = defaultNavigator
} = options;
const isSupported = useSupported(() => navigator && "permissions" in navigator);
let permissionStatus;
const desc = typeof permissionDesc === "string" ? { name: permissionDesc } : permissionDesc;
const state = ref();
const onChange = () => {
if (permissionStatus)
state.value = permissionStatus.state;
};
const query = createSingletonPromise(async () => {
if (!isSupported.value)
return;
if (!permissionStatus) {
try {
permissionStatus = await navigator.permissions.query(desc);
useEventListener(permissionStatus, "change", onChange);
onChange();
} catch (e) {
state.value = "prompt";
}
}
return permissionStatus;
});
query();
if (controls) {
return {
state,
isSupported,
query
};
} else {
return state;
}
}
function useDevicesList(options = {}) {
const {
navigator = defaultNavigator,
requestPermissions = false,
constraints = { audio: true, video: true },
onUpdated
} = options;
const devices = ref([]);
const videoInputs = computed(() => devices.value.filter((i) => i.kind === "videoinput"));
const audioInputs = computed(() => devices.value.filter((i) => i.kind === "audioinput"));
const audioOutputs = computed(() => devices.value.filter((i) => i.kind === "audiooutput"));
const isSupported = useSupported(() => navigator && navigator.mediaDevices && navigator.mediaDevices.enumerateDevices);
const permissionGranted = ref(false);
let stream;
async function update() {
if (!isSupported.value)
return;
devices.value = await navigator.mediaDevices.enumerateDevices();
onUpdated == null ? void 0 : onUpdated(devices.value);
if (stream) {
stream.getTracks().forEach((t) => t.stop());
stream = null;
}
}
async function ensurePermissions() {
if (!isSupported.value)
return false;
if (permissionGranted.value)
return true;
const { state, query } = usePermission("camera", { controls: true });
await query();
if (state.value !== "granted") {
stream = await navigator.mediaDevices.getUserMedia(constraints);
update();
permissionGranted.value = true;
} else {
permissionGranted.value = true;
}
return permissionGranted.value;
}
if (isSupported.value) {
if (requestPermissions)
ensurePermissions();
useEventListener(navigator.mediaDevices, "devicechange", update);
update();
}
return {
devices,
ensurePermissions,
permissionGranted,
videoInputs,
audioInputs,
audioOutputs,
isSupported
};
}
function useDisplayMedia(options = {}) {
var _a;
const enabled = ref((_a = options.enabled) != null ? _a : false);
const video = options.video;
const audio = options.audio;
const { navigator = defaultNavigator } = options;
const isSupported = useSupported(() => {
var _a2;
return (_a2 = navigator == null ? void 0 : navigator.mediaDevices) == null ? void 0 : _a2.getDisplayMedia;
});
const constraint = { audio, video };
const stream = shallowRef();
async function _start() {
if (!isSupported.value || stream.value)
return;
stream.value = await navigator.mediaDevices.getDisplayMedia(constraint);
return stream.value;
}
async function _stop() {
var _a2;
(_a2 = stream.value) == null ? void 0 : _a2.getTracks().forEach((t) => t.stop());
stream.value = void 0;
}
function stop() {
_stop();
enabled.value = false;
}
async function start() {
await _start();
if (stream.value)
enabled.value = true;
return stream.value;
}
watch(
enabled,
(v) => {
if (v)
_start();
else
_stop();
},
{ immediate: true }
);
return {
isSupported,
stream,
start,
stop,
enabled
};
}
2 years ago
function useDocumentVisibility(options = {}) {
const { document = defaultDocument } = options;
2 years ago
if (!document)
return ref("visible");
const visibility = ref(document.visibilityState);
useEventListener(document, "visibilitychange", () => {
visibility.value = document.visibilityState;
});
return visibility;
}
function useDraggable(target, options = {}) {
var _a, _b;
const {
pointerTypes,
preventDefault,
stopPropagation,
exact,
onMove,
onEnd,
onStart,
initialValue,
axis = "both",
draggingElement = defaultWindow,
2 years ago
containerElement,
2 years ago
handle: draggingHandle = target
} = options;
const position = ref(
(_a = toValue(initialValue)) != null ? _a : { x: 0, y: 0 }
);
const pressedDelta = ref();
const filterEvent = (e) => {
if (pointerTypes)
return pointerTypes.includes(e.pointerType);
return true;
};
const handleEvent = (e) => {
if (toValue(preventDefault))
e.preventDefault();
if (toValue(stopPropagation))
e.stopPropagation();
};
const start = (e) => {
2 years ago
var _a2;
2 years ago
if (!filterEvent(e))
return;
if (toValue(exact) && e.target !== toValue(target))
return;
2 years ago
const container = (_a2 = toValue(containerElement)) != null ? _a2 : toValue(target);
const rect = container.getBoundingClientRect();
2 years ago
const pos = {
x: e.clientX - rect.left,
y: e.clientY - rect.top
};
if ((onStart == null ? void 0 : onStart(pos, e)) === false)
return;
pressedDelta.value = pos;
handleEvent(e);
};
const move = (e) => {
if (!filterEvent(e))
return;
if (!pressedDelta.value)
return;
let { x, y } = position.value;
if (axis === "x" || axis === "both")
x = e.clientX - pressedDelta.value.x;
if (axis === "y" || axis === "both")
y = e.clientY - pressedDelta.value.y;
position.value = {
x,
y
};
onMove == null ? void 0 : onMove(position.value, e);
handleEvent(e);
};
const end = (e) => {
if (!filterEvent(e))
return;
if (!pressedDelta.value)
return;
pressedDelta.value = void 0;
onEnd == null ? void 0 : onEnd(position.value, e);
handleEvent(e);
};
if (isClient) {
const config = { capture: (_b = options.capture) != null ? _b : true };
useEventListener(draggingHandle, "pointerdown", start, config);
useEventListener(draggingElement, "pointermove", move, config);
useEventListener(draggingElement, "pointerup", end, config);
}
2 years ago
return {
...toRefs(position),
2 years ago
position,
isDragging: computed(() => !!pressedDelta.value),
style: computed(
() => `left:${position.value.x}px;top:${position.value.y}px;`
)
2 years ago
};
2 years ago
}
2 years ago
function useDropZone(target, options = {}) {
2 years ago
const isOverDropZone = ref(false);
2 years ago
const files = shallowRef(null);
2 years ago
let counter = 0;
if (isClient) {
2 years ago
const _options = typeof options === "function" ? { onDrop: options } : options;
const getFiles = (event) => {
var _a, _b;
const list = Array.from((_b = (_a = event.dataTransfer) == null ? void 0 : _a.files) != null ? _b : []);
return files.value = list.length === 0 ? null : list;
};
2 years ago
useEventListener(target, "dragenter", (event) => {
2 years ago
var _a;
2 years ago
event.preventDefault();
counter += 1;
isOverDropZone.value = true;
2 years ago
(_a = _options.onEnter) == null ? void 0 : _a.call(_options, getFiles(event), event);
2 years ago
});
useEventListener(target, "dragover", (event) => {
2 years ago
var _a;
2 years ago
event.preventDefault();
2 years ago
(_a = _options.onOver) == null ? void 0 : _a.call(_options, getFiles(event), event);
2 years ago
});
useEventListener(target, "dragleave", (event) => {
2 years ago
var _a;
2 years ago
event.preventDefault();
counter -= 1;
if (counter === 0)
isOverDropZone.value = false;
2 years ago
(_a = _options.onLeave) == null ? void 0 : _a.call(_options, getFiles(event), event);
2 years ago
});
useEventListener(target, "drop", (event) => {
2 years ago
var _a;
2 years ago
event.preventDefault();
counter = 0;
isOverDropZone.value = false;
2 years ago
(_a = _options.onDrop) == null ? void 0 : _a.call(_options, getFiles(event), event);
2 years ago
});
}
return {
2 years ago
files,
2 years ago
isOverDropZone
};
}
function useResizeObserver(target, callback, options = {}) {
2 years ago
const { window = defaultWindow, ...observerOptions } = options;
2 years ago
let observer;
const isSupported = useSupported(() => window && "ResizeObserver" in window);
const cleanup = () => {
if (observer) {
observer.disconnect();
observer = void 0;
}
};
2 years ago
const targets = computed(() => Array.isArray(target) ? target.map((el) => unrefElement(el)) : [unrefElement(target)]);
2 years ago
const stopWatch = watch(
targets,
(els) => {
cleanup();
if (isSupported.value && window) {
observer = new ResizeObserver(callback);
for (const _el of els)
_el && observer.observe(_el, observerOptions);
}
},
{ immediate: true, flush: "post", deep: true }
);
const stop = () => {
cleanup();
stopWatch();
};
tryOnScopeDispose(stop);
return {
isSupported,
stop
};
}
function useElementBounding(target, options = {}) {
const {
reset = true,
windowResize = true,
windowScroll = true,
immediate = true
} = options;
const height = ref(0);
const bottom = ref(0);
const left = ref(0);
const right = ref(0);
const top = ref(0);
const width = ref(0);
const x = ref(0);
const y = ref(0);
function update() {
const el = unrefElement(target);
if (!el) {
if (reset) {
height.value = 0;
bottom.value = 0;
left.value = 0;
right.value = 0;
top.value = 0;
width.value = 0;
x.value = 0;
y.value = 0;
}
return;
}
const rect = el.getBoundingClientRect();
height.value = rect.height;
bottom.value = rect.bottom;
left.value = rect.left;
right.value = rect.right;
top.value = rect.top;
width.value = rect.width;
x.value = rect.x;
y.value = rect.y;
}
useResizeObserver(target, update);
watch(() => unrefElement(target), (ele) => !ele && update());
if (windowScroll)
useEventListener("scroll", update, { capture: true, passive: true });
if (windowResize)
useEventListener("resize", update, { passive: true });
tryOnMounted(() => {
if (immediate)
update();
});
return {
height,
bottom,
left,
right,
top,
width,
x,
y,
update
};
}
function useElementByPoint(options) {
2 years ago
const {
x,
y,
document = defaultDocument,
multiple,
interval = "requestAnimationFrame",
immediate = true
} = options;
const isSupported = useSupported(() => {
if (toValue(multiple))
return document && "elementsFromPoint" in document;
return document && "elementFromPoint" in document;
2 years ago
});
2 years ago
const element = ref(null);
const cb = () => {
var _a, _b;
element.value = toValue(multiple) ? (_a = document == null ? void 0 : document.elementsFromPoint(toValue(x), toValue(y))) != null ? _a : [] : (_b = document == null ? void 0 : document.elementFromPoint(toValue(x), toValue(y))) != null ? _b : null;
};
const controls = interval === "requestAnimationFrame" ? useRafFn(cb, { immediate }) : useIntervalFn(cb, interval, { immediate });
return {
isSupported,
element,
...controls
};
2 years ago
}
function useElementHover(el, options = {}) {
const {
delayEnter = 0,
delayLeave = 0,
window = defaultWindow
} = options;
const isHovered = ref(false);
let timer;
const toggle = (entering) => {
const delay = entering ? delayEnter : delayLeave;
if (timer) {
clearTimeout(timer);
timer = void 0;
}
if (delay)
timer = setTimeout(() => isHovered.value = entering, delay);
else
isHovered.value = entering;
};
if (!window)
return isHovered;
useEventListener(el, "mouseenter", () => toggle(true), { passive: true });
useEventListener(el, "mouseleave", () => toggle(false), { passive: true });
return isHovered;
}
function useElementSize(target, initialSize = { width: 0, height: 0 }, options = {}) {
const { window = defaultWindow, box = "content-box" } = options;
const isSVG = computed(() => {
var _a, _b;
return (_b = (_a = unrefElement(target)) == null ? void 0 : _a.namespaceURI) == null ? void 0 : _b.includes("svg");
});
const width = ref(initialSize.width);
const height = ref(initialSize.height);
useResizeObserver(
target,
([entry]) => {
const boxSize = box === "border-box" ? entry.borderBoxSize : box === "content-box" ? entry.contentBoxSize : entry.devicePixelContentBoxSize;
if (window && isSVG.value) {
const $elem = unrefElement(target);
if ($elem) {
const styles = window.getComputedStyle($elem);
2 years ago
width.value = Number.parseFloat(styles.width);
height.value = Number.parseFloat(styles.height);
2 years ago
}
} else {
if (boxSize) {
const formatBoxSize = Array.isArray(boxSize) ? boxSize : [boxSize];
width.value = formatBoxSize.reduce((acc, { inlineSize }) => acc + inlineSize, 0);
height.value = formatBoxSize.reduce((acc, { blockSize }) => acc + blockSize, 0);
} else {
width.value = entry.contentRect.width;
height.value = entry.contentRect.height;
}
}
},
options
);
watch(
() => unrefElement(target),
(ele) => {
width.value = ele ? initialSize.width : 0;
height.value = ele ? initialSize.height : 0;
}
);
return {
width,
height
};
}
function useIntersectionObserver(target, callback, options = {}) {
const {
root,
rootMargin = "0px",
threshold = 0.1,
window = defaultWindow,
immediate = true
} = options;
const isSupported = useSupported(() => window && "IntersectionObserver" in window);
const targets = computed(() => {
const _target = toValue(target);
return (Array.isArray(_target) ? _target : [_target]).map(unrefElement).filter(notNullish);
});
let cleanup = noop;
const isActive = ref(immediate);
const stopWatch = isSupported.value ? watch(
() => [targets.value, unrefElement(root), isActive.value],
([targets2, root2]) => {
cleanup();
if (!isActive.value)
return;
if (!targets2.length)
return;
const observer = new IntersectionObserver(
callback,
{
root: unrefElement(root2),
rootMargin,
threshold
}
);
targets2.forEach((el) => el && observer.observe(el));
cleanup = () => {
observer.disconnect();
cleanup = noop;
};
},
{ immediate, flush: "post" }
) : noop;
const stop = () => {
cleanup();
stopWatch();
isActive.value = false;
};
tryOnScopeDispose(stop);
return {
isSupported,
isActive,
pause() {
cleanup();
isActive.value = false;
},
resume() {
isActive.value = true;
},
stop
};
}
2 years ago
function useElementVisibility(element, options = {}) {
const { window = defaultWindow, scrollTarget } = options;
2 years ago
const elementIsVisible = ref(false);
useIntersectionObserver(
element,
([{ isIntersecting }]) => {
elementIsVisible.value = isIntersecting;
},
{
root: scrollTarget,
2 years ago
window,
threshold: 0
2 years ago
}
);
return elementIsVisible;
}
const events = /* @__PURE__ */ new Map();
function useEventBus(key) {
const scope = getCurrentScope();
function on(listener) {
var _a;
const listeners = events.get(key) || /* @__PURE__ */ new Set();
listeners.add(listener);
events.set(key, listeners);
const _off = () => off(listener);
(_a = scope == null ? void 0 : scope.cleanups) == null ? void 0 : _a.push(_off);
return _off;
}
function once(listener) {
function _listener(...args) {
off(_listener);
listener(...args);
}
return on(_listener);
}
function off(listener) {
const listeners = events.get(key);
if (!listeners)
return;
listeners.delete(listener);
if (!listeners.size)
reset();
}
function reset() {
events.delete(key);
}
function emit(event, payload) {
var _a;
(_a = events.get(key)) == null ? void 0 : _a.forEach((v) => v(event, payload));
}
return { on, once, off, emit, reset };
}
function useEventSource(url, events = [], options = {}) {
const event = ref(null);
const data = ref(null);
const status = ref("CONNECTING");
const eventSource = ref(null);
const error = shallowRef(null);
const {
withCredentials = false
} = options;
const close = () => {
if (eventSource.value) {
eventSource.value.close();
eventSource.value = null;
status.value = "CLOSED";
}
};
const es = new EventSource(url, { withCredentials });
eventSource.value = es;
es.onopen = () => {
status.value = "OPEN";
error.value = null;
};
es.onerror = (e) => {
status.value = "CLOSED";
error.value = e;
};
es.onmessage = (e) => {
event.value = null;
data.value = e.data;
};
for (const event_name of events) {
useEventListener(es, event_name, (e) => {
event.value = event_name;
data.value = e.data || null;
});
}
tryOnScopeDispose(() => {
close();
});
return {
eventSource,
event,
data,
status,
error,
close
};
}
function useEyeDropper(options = {}) {
const { initialValue = "" } = options;
const isSupported = useSupported(() => typeof window !== "undefined" && "EyeDropper" in window);
const sRGBHex = ref(initialValue);
async function open(openOptions) {
if (!isSupported.value)
return;
const eyeDropper = new window.EyeDropper();
const result = await eyeDropper.open(openOptions);
sRGBHex.value = result.sRGBHex;
return result;
}
return { isSupported, sRGBHex, open };
}
function useFavicon(newIcon = null, options = {}) {
const {
baseUrl = "",
rel = "icon",
document = defaultDocument
} = options;
const favicon = toRef(newIcon);
const applyIcon = (icon) => {
2 years ago
const elements = document == null ? void 0 : document.head.querySelectorAll(`link[rel*="${rel}"]`);
if (!elements || elements.length === 0) {
const link = document == null ? void 0 : document.createElement("link");
if (link) {
link.rel = rel;
link.href = `${baseUrl}${icon}`;
link.type = `image/${icon.split(".").pop()}`;
document == null ? void 0 : document.head.append(link);
}
return;
}
elements == null ? void 0 : elements.forEach((el) => el.href = `${baseUrl}${icon}`);
2 years ago
};
watch(
favicon,
(i, o) => {
if (typeof i === "string" && i !== o)
applyIcon(i);
},
{ immediate: true }
);
return favicon;
}
const payloadMapping = {
json: "application/json",
text: "text/plain"
};
function isFetchOptions(obj) {
2 years ago
return obj && containsProp(obj, "immediate", "refetch", "initialData", "timeout", "beforeFetch", "afterFetch", "onFetchError", "fetch", "updateDataOnError");
2 years ago
}
function isAbsoluteURL(url) {
return /^([a-z][a-z\d+\-.]*:)?\/\//i.test(url);
}
function headersToObject(headers) {
if (typeof Headers !== "undefined" && headers instanceof Headers)
return Object.fromEntries([...headers.entries()]);
return headers;
}
function combineCallbacks(combination, ...callbacks) {
if (combination === "overwrite") {
return async (ctx) => {
const callback = callbacks[callbacks.length - 1];
if (callback)
2 years ago
return { ...ctx, ...await callback(ctx) };
2 years ago
return ctx;
};
} else {
return async (ctx) => {
for (const callback of callbacks) {
if (callback)
2 years ago
ctx = { ...ctx, ...await callback(ctx) };
2 years ago
}
return ctx;
};
}
}
function createFetch(config = {}) {
const _combination = config.combination || "chain";
const _options = config.options || {};
const _fetchOptions = config.fetchOptions || {};
function useFactoryFetch(url, ...args) {
const computedUrl = computed(() => {
const baseUrl = toValue(config.baseUrl);
const targetUrl = toValue(url);
return baseUrl && !isAbsoluteURL(targetUrl) ? joinPaths(baseUrl, targetUrl) : targetUrl;
});
let options = _options;
let fetchOptions = _fetchOptions;
if (args.length > 0) {
if (isFetchOptions(args[0])) {
2 years ago
options = {
...options,
...args[0],
2 years ago
beforeFetch: combineCallbacks(_combination, _options.beforeFetch, args[0].beforeFetch),
afterFetch: combineCallbacks(_combination, _options.afterFetch, args[0].afterFetch),
onFetchError: combineCallbacks(_combination, _options.onFetchError, args[0].onFetchError)
2 years ago
};
2 years ago
} else {
2 years ago
fetchOptions = {
...fetchOptions,
...args[0],
headers: {
...headersToObject(fetchOptions.headers) || {},
...headersToObject(args[0].headers) || {}
}
};
2 years ago
}
}
if (args.length > 1 && isFetchOptions(args[1])) {
2 years ago
options = {
...options,
...args[1],
2 years ago
beforeFetch: combineCallbacks(_combination, _options.beforeFetch, args[1].beforeFetch),
afterFetch: combineCallbacks(_combination, _options.afterFetch, args[1].afterFetch),
onFetchError: combineCallbacks(_combination, _options.onFetchError, args[1].onFetchError)
2 years ago
};
2 years ago
}
return useFetch(computedUrl, fetchOptions, options);
}
return useFactoryFetch;
}
function useFetch(url, ...args) {
var _a;
const supportsAbort = typeof AbortController === "function";
let fetchOptions = {};
2 years ago
let options = {
immediate: true,
refetch: false,
timeout: 0,
updateDataOnError: false
};
2 years ago
const config = {
method: "GET",
type: "text",
payload: void 0
};
if (args.length > 0) {
if (isFetchOptions(args[0]))
2 years ago
options = { ...options, ...args[0] };
2 years ago
else
fetchOptions = args[0];
}
if (args.length > 1) {
if (isFetchOptions(args[1]))
2 years ago
options = { ...options, ...args[1] };
2 years ago
}
const {
fetch = (_a = defaultWindow) == null ? void 0 : _a.fetch,
initialData,
timeout
} = options;
const responseEvent = createEventHook();
const errorEvent = createEventHook();
const finallyEvent = createEventHook();
const isFinished = ref(false);
const isFetching = ref(false);
const aborted = ref(false);
const statusCode = ref(null);
const response = shallowRef(null);
const error = shallowRef(null);
const data = shallowRef(initialData || null);
const canAbort = computed(() => supportsAbort && isFetching.value);
let controller;
let timer;
const abort = () => {
if (supportsAbort) {
controller == null ? void 0 : controller.abort();
controller = new AbortController();
controller.signal.onabort = () => aborted.value = true;
2 years ago
fetchOptions = {
...fetchOptions,
2 years ago
signal: controller.signal
2 years ago
};
2 years ago
}
};
const loading = (isLoading) => {
isFetching.value = isLoading;
isFinished.value = !isLoading;
};
if (timeout)
timer = useTimeoutFn(abort, timeout, { immediate: false });
const execute = async (throwOnFailed = false) => {
var _a2;
abort();
loading(true);
error.value = null;
statusCode.value = null;
aborted.value = false;
const defaultFetchOptions = {
method: config.method,
headers: {}
};
if (config.payload) {
const headers = headersToObject(defaultFetchOptions.headers);
2 years ago
const payload = toValue(config.payload);
if (!config.payloadType && payload && Object.getPrototypeOf(payload) === Object.prototype && !(payload instanceof FormData))
config.payloadType = "json";
2 years ago
if (config.payloadType)
headers["Content-Type"] = (_a2 = payloadMapping[config.payloadType]) != null ? _a2 : config.payloadType;
defaultFetchOptions.body = config.payloadType === "json" ? JSON.stringify(payload) : payload;
}
let isCanceled = false;
const context = {
url: toValue(url),
2 years ago
options: {
...defaultFetchOptions,
...fetchOptions
},
2 years ago
cancel: () => {
isCanceled = true;
}
};
if (options.beforeFetch)
Object.assign(context, await options.beforeFetch(context));
if (isCanceled || !fetch) {
loading(false);
return Promise.resolve(null);
}
let responseData = null;
if (timer)
timer.start();
return new Promise((resolve, reject) => {
var _a3;
fetch(
context.url,
2 years ago
{
...defaultFetchOptions,
...context.options,
headers: {
...headersToObject(defaultFetchOptions.headers),
...headersToObject((_a3 = context.options) == null ? void 0 : _a3.headers)
}
}
2 years ago
).then(async (fetchResponse) => {
response.value = fetchResponse;
statusCode.value = fetchResponse.status;
responseData = await fetchResponse[config.type]();
if (!fetchResponse.ok) {
data.value = initialData || null;
throw new Error(fetchResponse.statusText);
}
2 years ago
if (options.afterFetch) {
({ data: responseData } = await options.afterFetch({
data: responseData,
response: fetchResponse
}));
}
2 years ago
data.value = responseData;
responseEvent.trigger(fetchResponse);
return resolve(fetchResponse);
}).catch(async (fetchError) => {
let errorData = fetchError.message || fetchError.name;
2 years ago
if (options.onFetchError) {
({ error: errorData, data: responseData } = await options.onFetchError({
data: responseData,
error: fetchError,
response: response.value
}));
}
2 years ago
error.value = errorData;
2 years ago
if (options.updateDataOnError)
data.value = responseData;
2 years ago
errorEvent.trigger(fetchError);
if (throwOnFailed)
return reject(fetchError);
return resolve(null);
}).finally(() => {
loading(false);
if (timer)
timer.stop();
finallyEvent.trigger(null);
});
});
};
const refetch = toRef(options.refetch);
watch(
[
refetch,
toRef(url)
],
([refetch2]) => refetch2 && execute(),
{ deep: true }
);
const shell = {
isFinished,
statusCode,
response,
error,
data,
isFetching,
canAbort,
aborted,
abort,
execute,
onFetchResponse: responseEvent.on,
onFetchError: errorEvent.on,
onFetchFinally: finallyEvent.on,
// method
get: setMethod("GET"),
put: setMethod("PUT"),
post: setMethod("POST"),
delete: setMethod("DELETE"),
patch: setMethod("PATCH"),
head: setMethod("HEAD"),
options: setMethod("OPTIONS"),
// type
json: setType("json"),
text: setType("text"),
blob: setType("blob"),
arrayBuffer: setType("arrayBuffer"),
formData: setType("formData")
};
function setMethod(method) {
return (payload, payloadType) => {
if (!isFetching.value) {
config.method = method;
config.payload = payload;
config.payloadType = payloadType;
if (isRef(config.payload)) {
watch(
[
refetch,
toRef(config.payload)
],
([refetch2]) => refetch2 && execute(),
{ deep: true }
);
}
2 years ago
return {
...shell,
2 years ago
then(onFulfilled, onRejected) {
return waitUntilFinished().then(onFulfilled, onRejected);
}
2 years ago
};
2 years ago
}
return void 0;
};
}
function waitUntilFinished() {
return new Promise((resolve, reject) => {
until(isFinished).toBe(true).then(() => resolve(shell)).catch((error2) => reject(error2));
});
}
function setType(type) {
return () => {
if (!isFetching.value) {
config.type = type;
2 years ago
return {
...shell,
2 years ago
then(onFulfilled, onRejected) {
return waitUntilFinished().then(onFulfilled, onRejected);
}
2 years ago
};
2 years ago
}
return void 0;
};
}
if (options.immediate)
Promise.resolve().then(() => execute());
2 years ago
return {
...shell,
2 years ago
then(onFulfilled, onRejected) {
return waitUntilFinished().then(onFulfilled, onRejected);
}
2 years ago
};
2 years ago
}
function joinPaths(start, end) {
if (!start.endsWith("/") && !end.startsWith("/"))
return `${start}/${end}`;
return `${start}${end}`;
}
const DEFAULT_OPTIONS = {
multiple: true,
2 years ago
accept: "*",
reset: false
2 years ago
};
function useFileDialog(options = {}) {
const {
document = defaultDocument
} = options;
const files = ref(null);
const { on: onChange, trigger } = createEventHook();
let input;
if (document) {
input = document.createElement("input");
input.type = "file";
input.onchange = (event) => {
const result = event.target;
files.value = result.files;
trigger(files.value);
};
}
2 years ago
const reset = () => {
files.value = null;
if (input)
input.value = "";
};
2 years ago
const open = (localOptions) => {
if (!input)
return;
2 years ago
const _options = {
...DEFAULT_OPTIONS,
...options,
...localOptions
};
2 years ago
input.multiple = _options.multiple;
input.accept = _options.accept;
if (hasOwn(_options, "capture"))
input.capture = _options.capture;
2 years ago
if (_options.reset)
reset();
2 years ago
input.click();
};
return {
files: readonly(files),
open,
reset,
onChange
};
}
function useFileSystemAccess(options = {}) {
const {
window: _window = defaultWindow,
dataType = "Text"
} = options;
const window = _window;
const isSupported = useSupported(() => window && "showSaveFilePicker" in window && "showOpenFilePicker" in window);
const fileHandle = ref();
const data = ref();
const file = ref();
const fileName = computed(() => {
var _a, _b;
return (_b = (_a = file.value) == null ? void 0 : _a.name) != null ? _b : "";
});
const fileMIME = computed(() => {
var _a, _b;
return (_b = (_a = file.value) == null ? void 0 : _a.type) != null ? _b : "";
});
const fileSize = computed(() => {
var _a, _b;
return (_b = (_a = file.value) == null ? void 0 : _a.size) != null ? _b : 0;
});
const fileLastModified = computed(() => {
var _a, _b;
return (_b = (_a = file.value) == null ? void 0 : _a.lastModified) != null ? _b : 0;
});
async function open(_options = {}) {
if (!isSupported.value)
return;
2 years ago
const [handle] = await window.showOpenFilePicker({ ...toValue(options), ..._options });
2 years ago
fileHandle.value = handle;
await updateFile();
await updateData();
}
async function create(_options = {}) {
if (!isSupported.value)
return;
2 years ago
fileHandle.value = await window.showSaveFilePicker({ ...options, ..._options });
2 years ago
data.value = void 0;
await updateFile();
await updateData();
}
async function save(_options = {}) {
if (!isSupported.value)
return;
if (!fileHandle.value)
return saveAs(_options);
if (data.value) {
const writableStream = await fileHandle.value.createWritable();
await writableStream.write(data.value);
await writableStream.close();
}
await updateFile();
}
async function saveAs(_options = {}) {
if (!isSupported.value)
return;
2 years ago
fileHandle.value = await window.showSaveFilePicker({ ...options, ..._options });
2 years ago
if (data.value) {
const writableStream = await fileHandle.value.createWritable();
await writableStream.write(data.value);
await writableStream.close();
}
await updateFile();
}
async function updateFile() {
var _a;
file.value = await ((_a = fileHandle.value) == null ? void 0 : _a.getFile());
}
async function updateData() {
var _a, _b;
const type = toValue(dataType);
if (type === "Text")
data.value = await ((_a = file.value) == null ? void 0 : _a.text());
else if (type === "ArrayBuffer")
data.value = await ((_b = file.value) == null ? void 0 : _b.arrayBuffer());
else if (type === "Blob")
data.value = file.value;
}
watch(() => toValue(dataType), updateData);
return {
isSupported,
data,
file,
fileName,
fileMIME,
fileSize,
fileLastModified,
open,
create,
save,
saveAs,
updateData
};
}
function useFocus(target, options = {}) {
2 years ago
const { initialValue = false, focusVisible = false } = options;
2 years ago
const innerFocused = ref(false);
const targetElement = computed(() => unrefElement(target));
2 years ago
useEventListener(targetElement, "focus", (event) => {
var _a, _b;
if (!focusVisible || ((_b = (_a = event.target).matches) == null ? void 0 : _b.call(_a, ":focus-visible")))
innerFocused.value = true;
});
2 years ago
useEventListener(targetElement, "blur", () => innerFocused.value = false);
const focused = computed({
get: () => innerFocused.value,
set(value) {
var _a, _b;
if (!value && innerFocused.value)
(_a = targetElement.value) == null ? void 0 : _a.blur();
else if (value && !innerFocused.value)
(_b = targetElement.value) == null ? void 0 : _b.focus();
}
});
watch(
targetElement,
() => {
focused.value = initialValue;
},
{ immediate: true, flush: "post" }
);
return { focused };
}
function useFocusWithin(target, options = {}) {
const activeElement = useActiveElement(options);
const targetElement = computed(() => unrefElement(target));
const focused = computed(() => targetElement.value && activeElement.value ? targetElement.value.contains(activeElement.value) : false);
return { focused };
}
function useFps(options) {
var _a;
const fps = ref(0);
if (typeof performance === "undefined")
return fps;
const every = (_a = options == null ? void 0 : options.every) != null ? _a : 10;
let last = performance.now();
let ticks = 0;
useRafFn(() => {
ticks += 1;
if (ticks >= every) {
const now = performance.now();
const diff = now - last;
fps.value = Math.round(1e3 / (diff / ticks));
last = now;
ticks = 0;
}
});
return fps;
}
const eventHandlers = [
"fullscreenchange",
"webkitfullscreenchange",
"webkitendfullscreen",
"mozfullscreenchange",
"MSFullscreenChange"
];
function useFullscreen(target, options = {}) {
const {
document = defaultDocument,
autoExit = false
} = options;
const targetRef = computed(() => {
var _a;
return (_a = unrefElement(target)) != null ? _a : document == null ? void 0 : document.querySelector("html");
});
const isFullscreen = ref(false);
const requestMethod = computed(() => {
return [
"requestFullscreen",
"webkitRequestFullscreen",
"webkitEnterFullscreen",
"webkitEnterFullScreen",
"webkitRequestFullScreen",
"mozRequestFullScreen",
"msRequestFullscreen"
].find((m) => document && m in document || targetRef.value && m in targetRef.value);
});
const exitMethod = computed(() => {
return [
"exitFullscreen",
"webkitExitFullscreen",
"webkitExitFullScreen",
"webkitCancelFullScreen",
"mozCancelFullScreen",
"msExitFullscreen"
].find((m) => document && m in document || targetRef.value && m in targetRef.value);
});
const fullscreenEnabled = computed(() => {
return [
"fullScreen",
"webkitIsFullScreen",
"webkitDisplayingFullscreen",
"mozFullScreen",
"msFullscreenElement"
].find((m) => document && m in document || targetRef.value && m in targetRef.value);
});
const fullscreenElementMethod = [
"fullscreenElement",
"webkitFullscreenElement",
"mozFullScreenElement",
"msFullscreenElement"
].find((m) => document && m in document);
2 years ago
const isSupported = useSupported(() => targetRef.value && document && requestMethod.value !== void 0 && exitMethod.value !== void 0 && fullscreenEnabled.value !== void 0);
2 years ago
const isCurrentElementFullScreen = () => {
if (fullscreenElementMethod)
return (document == null ? void 0 : document[fullscreenElementMethod]) === targetRef.value;
return false;
};
const isElementFullScreen = () => {
if (fullscreenEnabled.value) {
if (document && document[fullscreenEnabled.value] != null) {
return document[fullscreenEnabled.value];
} else {
const target2 = targetRef.value;
if ((target2 == null ? void 0 : target2[fullscreenEnabled.value]) != null) {
return Boolean(target2[fullscreenEnabled.value]);
}
}
}
return false;
};
async function exit() {
2 years ago
if (!isSupported.value || !isFullscreen.value)
2 years ago
return;
if (exitMethod.value) {
if ((document == null ? void 0 : document[exitMethod.value]) != null) {
await document[exitMethod.value]();
} else {
const target2 = targetRef.value;
if ((target2 == null ? void 0 : target2[exitMethod.value]) != null)
await target2[exitMethod.value]();
}
}
isFullscreen.value = false;
}
async function enter() {
2 years ago
if (!isSupported.value || isFullscreen.value)
2 years ago
return;
if (isElementFullScreen())
await exit();
const target2 = targetRef.value;
if (requestMethod.value && (target2 == null ? void 0 : target2[requestMethod.value]) != null) {
await target2[requestMethod.value]();
isFullscreen.value = true;
}
}
async function toggle() {
await (isFullscreen.value ? exit() : enter());
}
const handlerCallback = () => {
const isElementFullScreenValue = isElementFullScreen();
if (!isElementFullScreenValue || isElementFullScreenValue && isCurrentElementFullScreen())
isFullscreen.value = isElementFullScreenValue;
};
useEventListener(document, eventHandlers, handlerCallback, false);
useEventListener(() => unrefElement(targetRef), eventHandlers, handlerCallback, false);
if (autoExit)
tryOnScopeDispose(exit);
return {
isSupported,
isFullscreen,
enter,
exit,
toggle
};
}
function mapGamepadToXbox360Controller(gamepad) {
return computed(() => {
if (gamepad.value) {
return {
buttons: {
a: gamepad.value.buttons[0],
b: gamepad.value.buttons[1],
x: gamepad.value.buttons[2],
y: gamepad.value.buttons[3]
},
bumper: {
left: gamepad.value.buttons[4],
right: gamepad.value.buttons[5]
},
triggers: {
left: gamepad.value.buttons[6],
right: gamepad.value.buttons[7]
},
stick: {
left: {
horizontal: gamepad.value.axes[0],
vertical: gamepad.value.axes[1],
button: gamepad.value.buttons[10]
},
right: {
horizontal: gamepad.value.axes[2],
vertical: gamepad.value.axes[3],
button: gamepad.value.buttons[11]
}
},
dpad: {
up: gamepad.value.buttons[12],
down: gamepad.value.buttons[13],
left: gamepad.value.buttons[14],
right: gamepad.value.buttons[15]
},
back: gamepad.value.buttons[8],
start: gamepad.value.buttons[9]
};
}
return null;
});
}
function useGamepad(options = {}) {
const {
navigator = defaultNavigator
} = options;
const isSupported = useSupported(() => navigator && "getGamepads" in navigator);
const gamepads = ref([]);
const onConnectedHook = createEventHook();
const onDisconnectedHook = createEventHook();
const stateFromGamepad = (gamepad) => {
const hapticActuators = [];
const vibrationActuator = "vibrationActuator" in gamepad ? gamepad.vibrationActuator : null;
if (vibrationActuator)
hapticActuators.push(vibrationActuator);
if (gamepad.hapticActuators)
hapticActuators.push(...gamepad.hapticActuators);
return {
2 years ago
...gamepad,
2 years ago
id: gamepad.id,
hapticActuators,
axes: gamepad.axes.map((axes) => axes),
buttons: gamepad.buttons.map((button) => ({ pressed: button.pressed, touched: button.touched, value: button.value }))
};
};
const updateGamepadState = () => {
const _gamepads = (navigator == null ? void 0 : navigator.getGamepads()) || [];
for (let i = 0; i < _gamepads.length; ++i) {
const gamepad = _gamepads[i];
if (gamepad) {
const index = gamepads.value.findIndex(({ index: index2 }) => index2 === gamepad.index);
if (index > -1)
gamepads.value[index] = stateFromGamepad(gamepad);
}
}
};
const { isActive, pause, resume } = useRafFn(updateGamepadState);
const onGamepadConnected = (gamepad) => {
if (!gamepads.value.some(({ index }) => index === gamepad.index)) {
gamepads.value.push(stateFromGamepad(gamepad));
onConnectedHook.trigger(gamepad.index);
}
resume();
};
const onGamepadDisconnected = (gamepad) => {
gamepads.value = gamepads.value.filter((x) => x.index !== gamepad.index);
onDisconnectedHook.trigger(gamepad.index);
};
useEventListener("gamepadconnected", (e) => onGamepadConnected(e.gamepad));
useEventListener("gamepaddisconnected", (e) => onGamepadDisconnected(e.gamepad));
tryOnMounted(() => {
const _gamepads = (navigator == null ? void 0 : navigator.getGamepads()) || [];
if (_gamepads) {
for (let i = 0; i < _gamepads.length; ++i) {
const gamepad = _gamepads[i];
if (gamepad)
onGamepadConnected(gamepad);
}
}
});
pause();
return {
isSupported,
onConnected: onConnectedHook.on,
onDisconnected: onDisconnectedHook.on,
gamepads,
pause,
resume,
isActive
};
}
function useGeolocation(options = {}) {
const {
enableHighAccuracy = true,
maximumAge = 3e4,
timeout = 27e3,
navigator = defaultNavigator,
immediate = true
} = options;
const isSupported = useSupported(() => navigator && "geolocation" in navigator);
const locatedAt = ref(null);
const error = shallowRef(null);
const coords = ref({
accuracy: 0,
2 years ago
latitude: Number.POSITIVE_INFINITY,
longitude: Number.POSITIVE_INFINITY,
2 years ago
altitude: null,
altitudeAccuracy: null,
heading: null,
speed: null
});
function updatePosition(position) {
locatedAt.value = position.timestamp;
coords.value = position.coords;
error.value = null;
}
let watcher;
function resume() {
if (isSupported.value) {
watcher = navigator.geolocation.watchPosition(
updatePosition,
(err) => error.value = err,
{
enableHighAccuracy,
maximumAge,
timeout
}
);
}
}
if (immediate)
resume();
function pause() {
if (watcher && navigator)
navigator.geolocation.clearWatch(watcher);
}
tryOnScopeDispose(() => {
pause();
});
return {
isSupported,
coords,
locatedAt,
error,
resume,
pause
};
}
const defaultEvents$1 = ["mousemove", "mousedown", "resize", "keydown", "touchstart", "wheel"];
const oneMinute = 6e4;
function useIdle(timeout = oneMinute, options = {}) {
const {
initialState = false,
listenForVisibilityChange = true,
events = defaultEvents$1,
window = defaultWindow,
eventFilter = throttleFilter(50)
} = options;
const idle = ref(initialState);
const lastActive = ref(timestamp());
let timer;
const reset = () => {
idle.value = false;
clearTimeout(timer);
timer = setTimeout(() => idle.value = true, timeout);
};
const onEvent = createFilterWrapper(
eventFilter,
() => {
lastActive.value = timestamp();
reset();
}
);
if (window) {
const document = window.document;
for (const event of events)
useEventListener(window, event, onEvent, { passive: true });
if (listenForVisibilityChange) {
useEventListener(document, "visibilitychange", () => {
if (!document.hidden)
onEvent();
});
}
reset();
}
return {
idle,
lastActive,
reset
};
}
async function loadImage(options) {
return new Promise((resolve, reject) => {
const img = new Image();
2 years ago
const { src, srcset, sizes, class: clazz, loading, crossorigin, referrerPolicy } = options;
2 years ago
img.src = src;
if (srcset)
img.srcset = srcset;
if (sizes)
img.sizes = sizes;
if (clazz)
img.className = clazz;
if (loading)
img.loading = loading;
if (crossorigin)
img.crossOrigin = crossorigin;
2 years ago
if (referrerPolicy)
img.referrerPolicy = referrerPolicy;
2 years ago
img.onload = () => resolve(img);
img.onerror = reject;
});
}
function useImage(options, asyncStateOptions = {}) {
const state = useAsyncState(
() => loadImage(toValue(options)),
void 0,
2 years ago
{
resetOnExecute: true,
...asyncStateOptions
}
2 years ago
);
watch(
() => toValue(options),
() => state.execute(asyncStateOptions.delay),
{ deep: true }
);
return state;
}
const ARRIVED_STATE_THRESHOLD_PIXELS = 1;
function useScroll(element, options = {}) {
const {
throttle = 0,
idle = 200,
onStop = noop,
onScroll = noop,
offset = {
left: 0,
right: 0,
top: 0,
bottom: 0
},
eventListenerOptions = {
capture: false,
passive: true
},
2 years ago
behavior = "auto",
window = defaultWindow
2 years ago
} = options;
const internalX = ref(0);
const internalY = ref(0);
const x = computed({
get() {
return internalX.value;
},
set(x2) {
scrollTo(x2, void 0);
}
});
const y = computed({
get() {
return internalY.value;
},
set(y2) {
scrollTo(void 0, y2);
}
});
function scrollTo(_x, _y) {
var _a, _b, _c;
2 years ago
if (!window)
return;
2 years ago
const _element = toValue(element);
if (!_element)
return;
2 years ago
(_c = _element instanceof Document ? window.document.body : _element) == null ? void 0 : _c.scrollTo({
2 years ago
top: (_a = toValue(_y)) != null ? _a : y.value,
left: (_b = toValue(_x)) != null ? _b : x.value,
behavior: toValue(behavior)
});
}
const isScrolling = ref(false);
const arrivedState = reactive({
left: true,
right: false,
top: true,
bottom: false
});
const directions = reactive({
left: false,
right: false,
top: false,
bottom: false
});
const onScrollEnd = (e) => {
if (!isScrolling.value)
return;
isScrolling.value = false;
directions.left = false;
directions.right = false;
directions.top = false;
directions.bottom = false;
onStop(e);
};
const onScrollEndDebounced = useDebounceFn(onScrollEnd, throttle + idle);
const setArrivedState = (target) => {
2 years ago
var _a;
if (!window)
return;
const el = target.document ? target.document.documentElement : (_a = target.documentElement) != null ? _a : target;
2 years ago
const { display, flexDirection } = getComputedStyle(el);
const scrollLeft = el.scrollLeft;
directions.left = scrollLeft < internalX.value;
directions.right = scrollLeft > internalX.value;
const left = Math.abs(scrollLeft) <= 0 + (offset.left || 0);
const right = Math.abs(scrollLeft) + el.clientWidth >= el.scrollWidth - (offset.right || 0) - ARRIVED_STATE_THRESHOLD_PIXELS;
if (display === "flex" && flexDirection === "row-reverse") {
arrivedState.left = right;
arrivedState.right = left;
} else {
arrivedState.left = left;
arrivedState.right = right;
}
internalX.value = scrollLeft;
let scrollTop = el.scrollTop;
2 years ago
if (target === window.document && !scrollTop)
scrollTop = window.document.body.scrollTop;
2 years ago
directions.top = scrollTop < internalY.value;
directions.bottom = scrollTop > internalY.value;
const top = Math.abs(scrollTop) <= 0 + (offset.top || 0);
const bottom = Math.abs(scrollTop) + el.clientHeight >= el.scrollHeight - (offset.bottom || 0) - ARRIVED_STATE_THRESHOLD_PIXELS;
if (display === "flex" && flexDirection === "column-reverse") {
arrivedState.top = bottom;
arrivedState.bottom = top;
} else {
arrivedState.top = top;
arrivedState.bottom = bottom;
}
internalY.value = scrollTop;
};
const onScrollHandler = (e) => {
2 years ago
var _a;
if (!window)
return;
const eventTarget = (_a = e.target.documentElement) != null ? _a : e.target;
2 years ago
setArrivedState(eventTarget);
isScrolling.value = true;
onScrollEndDebounced(e);
onScroll(e);
};
useEventListener(
element,
"scroll",
throttle ? useThrottleFn(onScrollHandler, throttle, true, false) : onScrollHandler,
eventListenerOptions
);
useEventListener(
element,
"scrollend",
onScrollEnd,
eventListenerOptions
);
return {
x,
y,
isScrolling,
arrivedState,
directions,
measure() {
const _element = toValue(element);
2 years ago
if (window && _element)
2 years ago
setArrivedState(_element);
}
};
}
2 years ago
function resolveElement(el) {
if (typeof Window !== "undefined" && el instanceof Window)
return el.document.documentElement;
if (typeof Document !== "undefined" && el instanceof Document)
return el.documentElement;
return el;
}
2 years ago
function useInfiniteScroll(element, onLoadMore, options = {}) {
var _a;
const {
direction = "bottom",
interval = 100
} = options;
const state = reactive(useScroll(
element,
2 years ago
{
...options,
offset: {
[direction]: (_a = options.distance) != null ? _a : 0,
...options.offset
}
}
2 years ago
));
const promise = ref();
const isLoading = computed(() => !!promise.value);
2 years ago
const observedElement = computed(() => {
return resolveElement(toValue(element));
});
const isElementVisible = useElementVisibility(observedElement);
2 years ago
function checkAndLoad() {
state.measure();
2 years ago
if (!observedElement.value || !isElementVisible.value)
2 years ago
return;
2 years ago
const { scrollHeight, clientHeight, scrollWidth, clientWidth } = observedElement.value;
const isNarrower = direction === "bottom" || direction === "top" ? scrollHeight <= clientHeight : scrollWidth <= clientWidth;
2 years ago
if (state.arrivedState[direction] || isNarrower) {
if (!promise.value) {
promise.value = Promise.all([
onLoadMore(state),
new Promise((resolve) => setTimeout(resolve, interval))
]).finally(() => {
promise.value = null;
nextTick(() => checkAndLoad());
});
}
}
}
watch(
2 years ago
() => [state.arrivedState[direction], isElementVisible.value],
2 years ago
checkAndLoad,
{ immediate: true }
);
return {
isLoading
};
}
const defaultEvents = ["mousedown", "mouseup", "keydown", "keyup"];
function useKeyModifier(modifier, options = {}) {
const {
events = defaultEvents,
document = defaultDocument,
initial = null
} = options;
const state = ref(initial);
if (document) {
events.forEach((listenerEvent) => {
useEventListener(document, listenerEvent, (evt) => {
if (typeof evt.getModifierState === "function")
state.value = evt.getModifierState(modifier);
});
});
}
return state;
}
function useLocalStorage(key, initialValue, options = {}) {
const { window = defaultWindow } = options;
return useStorage(key, initialValue, window == null ? void 0 : window.localStorage, options);
}
const DefaultMagicKeysAliasMap = {
ctrl: "control",
command: "meta",
cmd: "meta",
option: "alt",
up: "arrowup",
down: "arrowdown",
left: "arrowleft",
right: "arrowright"
};
function useMagicKeys(options = {}) {
const {
reactive: useReactive = false,
target = defaultWindow,
aliasMap = DefaultMagicKeysAliasMap,
passive = true,
onEventFired = noop
} = options;
const current = reactive(/* @__PURE__ */ new Set());
const obj = {
toJSON() {
return {};
},
current
};
const refs = useReactive ? reactive(obj) : obj;
const metaDeps = /* @__PURE__ */ new Set();
const usedKeys = /* @__PURE__ */ new Set();
function setRefs(key, value) {
if (key in refs) {
if (useReactive)
refs[key] = value;
else
refs[key].value = value;
}
}
function reset() {
current.clear();
for (const key of usedKeys)
setRefs(key, false);
}
function updateRefs(e, value) {
var _a, _b;
const key = (_a = e.key) == null ? void 0 : _a.toLowerCase();
const code = (_b = e.code) == null ? void 0 : _b.toLowerCase();
const values = [code, key].filter(Boolean);
if (key) {
if (value)
current.add(key);
else
current.delete(key);
}
for (const key2 of values) {
usedKeys.add(key2);
setRefs(key2, value);
}
if (key === "meta" && !value) {
metaDeps.forEach((key2) => {
current.delete(key2);
setRefs(key2, false);
});
metaDeps.clear();
} else if (typeof e.getModifierState === "function" && e.getModifierState("Meta") && value) {
[...current, ...values].forEach((key2) => metaDeps.add(key2));
}
}
useEventListener(target, "keydown", (e) => {
updateRefs(e, true);
return onEventFired(e);
}, { passive });
useEventListener(target, "keyup", (e) => {
updateRefs(e, false);
return onEventFired(e);
}, { passive });
useEventListener("blur", reset, { passive: true });
useEventListener("focus", reset, { passive: true });
const proxy = new Proxy(
refs,
{
get(target2, prop, rec) {
if (typeof prop !== "string")
return Reflect.get(target2, prop, rec);
prop = prop.toLowerCase();
if (prop in aliasMap)
prop = aliasMap[prop];
if (!(prop in refs)) {
if (/[+_-]/.test(prop)) {
const keys = prop.split(/[+_-]/g).map((i) => i.trim());
refs[prop] = computed(() => keys.every((key) => toValue(proxy[key])));
} else {
refs[prop] = ref(false);
}
}
const r = Reflect.get(target2, prop, rec);
return useReactive ? toValue(r) : r;
}
}
);
return proxy;
}
function usingElRef(source, cb) {
if (toValue(source))
cb(toValue(source));
}
function timeRangeToArray(timeRanges) {
let ranges = [];
for (let i = 0; i < timeRanges.length; ++i)
ranges = [...ranges, [timeRanges.start(i), timeRanges.end(i)]];
return ranges;
}
function tracksToArray(tracks) {
return Array.from(tracks).map(({ label, kind, language, mode, activeCues, cues, inBandMetadataTrackDispatchType }, id) => ({ id, label, kind, language, mode, activeCues, cues, inBandMetadataTrackDispatchType }));
}
const defaultOptions = {
src: "",
tracks: []
};
function useMediaControls(target, options = {}) {
2 years ago
options = {
...defaultOptions,
...options
};
2 years ago
const {
document = defaultDocument
} = options;
const currentTime = ref(0);
const duration = ref(0);
const seeking = ref(false);
const volume = ref(1);
const waiting = ref(false);
const ended = ref(false);
const playing = ref(false);
const rate = ref(1);
const stalled = ref(false);
const buffered = ref([]);
const tracks = ref([]);
const selectedTrack = ref(-1);
const isPictureInPicture = ref(false);
const muted = ref(false);
const supportsPictureInPicture = document && "pictureInPictureEnabled" in document;
const sourceErrorEvent = createEventHook();
const disableTrack = (track) => {
usingElRef(target, (el) => {
if (track) {
const id = typeof track === "number" ? track : track.id;
el.textTracks[id].mode = "disabled";
} else {
for (let i = 0; i < el.textTracks.length; ++i)
el.textTracks[i].mode = "disabled";
}
selectedTrack.value = -1;
});
};
const enableTrack = (track, disableTracks = true) => {
usingElRef(target, (el) => {
const id = typeof track === "number" ? track : track.id;
if (disableTracks)
disableTrack();
el.textTracks[id].mode = "showing";
selectedTrack.value = id;
});
};
const togglePictureInPicture = () => {
return new Promise((resolve, reject) => {
usingElRef(target, async (el) => {
if (supportsPictureInPicture) {
if (!isPictureInPicture.value) {
el.requestPictureInPicture().then(resolve).catch(reject);
} else {
document.exitPictureInPicture().then(resolve).catch(reject);
}
}
});
});
};
watchEffect(() => {
if (!document)
return;
const el = toValue(target);
if (!el)
return;
const src = toValue(options.src);
let sources = [];
if (!src)
return;
if (typeof src === "string")
sources = [{ src }];
else if (Array.isArray(src))
sources = src;
else if (isObject(src))
sources = [src];
el.querySelectorAll("source").forEach((e) => {
e.removeEventListener("error", sourceErrorEvent.trigger);
e.remove();
});
sources.forEach(({ src: src2, type }) => {
const source = document.createElement("source");
source.setAttribute("src", src2);
source.setAttribute("type", type || "");
source.addEventListener("error", sourceErrorEvent.trigger);
el.appendChild(source);
});
el.load();
});
tryOnScopeDispose(() => {
const el = toValue(target);
if (!el)
return;
el.querySelectorAll("source").forEach((e) => e.removeEventListener("error", sourceErrorEvent.trigger));
});
watch([target, volume], () => {
const el = toValue(target);
if (!el)
return;
el.volume = volume.value;
});
watch([target, muted], () => {
const el = toValue(target);
if (!el)
return;
el.muted = muted.value;
});
watch([target, rate], () => {
const el = toValue(target);
if (!el)
return;
el.playbackRate = rate.value;
});
watchEffect(() => {
if (!document)
return;
const textTracks = toValue(options.tracks);
const el = toValue(target);
if (!textTracks || !textTracks.length || !el)
return;
el.querySelectorAll("track").forEach((e) => e.remove());
textTracks.forEach(({ default: isDefault, kind, label, src, srcLang }, i) => {
const track = document.createElement("track");
track.default = isDefault || false;
track.kind = kind;
track.label = label;
track.src = src;
track.srclang = srcLang;
if (track.default)
selectedTrack.value = i;
el.appendChild(track);
});
});
const { ignoreUpdates: ignoreCurrentTimeUpdates } = watchIgnorable(currentTime, (time) => {
const el = toValue(target);
if (!el)
return;
el.currentTime = time;
});
const { ignoreUpdates: ignorePlayingUpdates } = watchIgnorable(playing, (isPlaying) => {
const el = toValue(target);
if (!el)
return;
isPlaying ? el.play() : el.pause();
});
useEventListener(target, "timeupdate", () => ignoreCurrentTimeUpdates(() => currentTime.value = toValue(target).currentTime));
useEventListener(target, "durationchange", () => duration.value = toValue(target).duration);
useEventListener(target, "progress", () => buffered.value = timeRangeToArray(toValue(target).buffered));
useEventListener(target, "seeking", () => seeking.value = true);
useEventListener(target, "seeked", () => seeking.value = false);
2 years ago
useEventListener(target, ["waiting", "loadstart"], () => {
waiting.value = true;
ignorePlayingUpdates(() => playing.value = false);
});
useEventListener(target, "loadeddata", () => waiting.value = false);
2 years ago
useEventListener(target, "playing", () => {
waiting.value = false;
ended.value = false;
2 years ago
ignorePlayingUpdates(() => playing.value = true);
2 years ago
});
useEventListener(target, "ratechange", () => rate.value = toValue(target).playbackRate);
useEventListener(target, "stalled", () => stalled.value = true);
useEventListener(target, "ended", () => ended.value = true);
useEventListener(target, "pause", () => ignorePlayingUpdates(() => playing.value = false));
useEventListener(target, "play", () => ignorePlayingUpdates(() => playing.value = true));
useEventListener(target, "enterpictureinpicture", () => isPictureInPicture.value = true);
useEventListener(target, "leavepictureinpicture", () => isPictureInPicture.value = false);
useEventListener(target, "volumechange", () => {
const el = toValue(target);
if (!el)
return;
volume.value = el.volume;
muted.value = el.muted;
});
const listeners = [];
const stop = watch([target], () => {
const el = toValue(target);
if (!el)
return;
stop();
listeners[0] = useEventListener(el.textTracks, "addtrack", () => tracks.value = tracksToArray(el.textTracks));
listeners[1] = useEventListener(el.textTracks, "removetrack", () => tracks.value = tracksToArray(el.textTracks));
listeners[2] = useEventListener(el.textTracks, "change", () => tracks.value = tracksToArray(el.textTracks));
});
tryOnScopeDispose(() => listeners.forEach((listener) => listener()));
return {
currentTime,
duration,
waiting,
seeking,
ended,
stalled,
buffered,
playing,
rate,
// Volume
volume,
muted,
// Tracks
tracks,
selectedTrack,
enableTrack,
disableTrack,
// Picture in Picture
supportsPictureInPicture,
togglePictureInPicture,
isPictureInPicture,
// Events
onSourceError: sourceErrorEvent.on
};
}
function getMapVue2Compat() {
const data = reactive({});
return {
get: (key) => data[key],
set: (key, value) => set(data, key, value),
has: (key) => hasOwn(data, key),
delete: (key) => del(data, key),
clear: () => {
Object.keys(data).forEach((key) => {
del(data, key);
});
}
};
}
function useMemoize(resolver, options) {
const initCache = () => {
if (options == null ? void 0 : options.cache)
return reactive(options.cache);
if (isVue2)
return getMapVue2Compat();
return reactive(/* @__PURE__ */ new Map());
};
const cache = initCache();
const generateKey = (...args) => (options == null ? void 0 : options.getKey) ? options.getKey(...args) : JSON.stringify(args);
const _loadData = (key, ...args) => {
cache.set(key, resolver(...args));
return cache.get(key);
};
const loadData = (...args) => _loadData(generateKey(...args), ...args);
const deleteData = (...args) => {
cache.delete(generateKey(...args));
};
const clearData = () => {
cache.clear();
};
const memoized = (...args) => {
const key = generateKey(...args);
if (cache.has(key))
return cache.get(key);
return _loadData(key, ...args);
};
memoized.load = loadData;
memoized.delete = deleteData;
memoized.clear = clearData;
memoized.generateKey = generateKey;
memoized.cache = cache;
return memoized;
}
function useMemory(options = {}) {
const memory = ref();
const isSupported = useSupported(() => typeof performance !== "undefined" && "memory" in performance);
if (isSupported.value) {
const { interval = 1e3 } = options;
useIntervalFn(() => {
memory.value = performance.memory;
}, interval, { immediate: options.immediate, immediateCallback: options.immediateCallback });
}
return { isSupported, memory };
}
2 years ago
const UseMouseBuiltinExtractors = {
2 years ago
page: (event) => [event.pageX, event.pageY],
client: (event) => [event.clientX, event.clientY],
screen: (event) => [event.screenX, event.screenY],
movement: (event) => event instanceof Touch ? null : [event.movementX, event.movementY]
};
function useMouse(options = {}) {
const {
type = "page",
touch = true,
resetOnTouchEnds = false,
initialValue = { x: 0, y: 0 },
window = defaultWindow,
target = window,
2 years ago
scroll = true,
2 years ago
eventFilter
} = options;
2 years ago
let _prevMouseEvent = null;
2 years ago
const x = ref(initialValue.x);
const y = ref(initialValue.y);
const sourceType = ref(null);
2 years ago
const extractor = typeof type === "function" ? type : UseMouseBuiltinExtractors[type];
2 years ago
const mouseHandler = (event) => {
const result = extractor(event);
2 years ago
_prevMouseEvent = event;
2 years ago
if (result) {
[x.value, y.value] = result;
sourceType.value = "mouse";
}
};
const touchHandler = (event) => {
if (event.touches.length > 0) {
const result = extractor(event.touches[0]);
if (result) {
[x.value, y.value] = result;
sourceType.value = "touch";
}
}
};
2 years ago
const scrollHandler = () => {
if (!_prevMouseEvent || !window)
return;
const pos = extractor(_prevMouseEvent);
if (_prevMouseEvent instanceof MouseEvent && pos) {
x.value = pos[0] + window.scrollX;
y.value = pos[1] + window.scrollY;
}
};
2 years ago
const reset = () => {
x.value = initialValue.x;
y.value = initialValue.y;
};
const mouseHandlerWrapper = eventFilter ? (event) => eventFilter(() => mouseHandler(event), {}) : (event) => mouseHandler(event);
const touchHandlerWrapper = eventFilter ? (event) => eventFilter(() => touchHandler(event), {}) : (event) => touchHandler(event);
2 years ago
const scrollHandlerWrapper = eventFilter ? () => eventFilter(() => scrollHandler(), {}) : () => scrollHandler();
2 years ago
if (target) {
2 years ago
const listenerOptions = { passive: true };
useEventListener(target, ["mousemove", "dragover"], mouseHandlerWrapper, listenerOptions);
2 years ago
if (touch && type !== "movement") {
2 years ago
useEventListener(target, ["touchstart", "touchmove"], touchHandlerWrapper, listenerOptions);
2 years ago
if (resetOnTouchEnds)
2 years ago
useEventListener(target, "touchend", reset, listenerOptions);
2 years ago
}
2 years ago
if (scroll && type === "page")
useEventListener(window, "scroll", scrollHandlerWrapper, { passive: true });
2 years ago
}
return {
x,
y,
sourceType
};
}
function useMouseInElement(target, options = {}) {
const {
handleOutside = true,
window = defaultWindow
} = options;
const { x, y, sourceType } = useMouse(options);
const targetRef = ref(target != null ? target : window == null ? void 0 : window.document.body);
const elementX = ref(0);
const elementY = ref(0);
const elementPositionX = ref(0);
const elementPositionY = ref(0);
const elementHeight = ref(0);
const elementWidth = ref(0);
const isOutside = ref(true);
let stop = () => {
};
if (window) {
stop = watch(
[targetRef, x, y],
() => {
const el = unrefElement(targetRef);
if (!el)
return;
const {
left,
top,
width,
height
} = el.getBoundingClientRect();
elementPositionX.value = left + window.pageXOffset;
elementPositionY.value = top + window.pageYOffset;
elementHeight.value = height;
elementWidth.value = width;
const elX = x.value - elementPositionX.value;
const elY = y.value - elementPositionY.value;
isOutside.value = width === 0 || height === 0 || elX < 0 || elY < 0 || elX > width || elY > height;
if (handleOutside || !isOutside.value) {
elementX.value = elX;
elementY.value = elY;
}
},
{ immediate: true }
);
useEventListener(document, "mouseleave", () => {
isOutside.value = true;
});
}
return {
x,
y,
sourceType,
elementX,
elementY,
elementPositionX,
elementPositionY,
elementHeight,
elementWidth,
isOutside,
stop
};
}
function useMousePressed(options = {}) {
const {
touch = true,
drag = true,
2 years ago
capture = false,
2 years ago
initialValue = false,
window = defaultWindow
} = options;
const pressed = ref(initialValue);
const sourceType = ref(null);
if (!window) {
return {
pressed,
sourceType
};
}
const onPressed = (srcType) => () => {
pressed.value = true;
sourceType.value = srcType;
};
const onReleased = () => {
pressed.value = false;
sourceType.value = null;
};
const target = computed(() => unrefElement(options.target) || window);
2 years ago
useEventListener(target, "mousedown", onPressed("mouse"), { passive: true, capture });
useEventListener(window, "mouseleave", onReleased, { passive: true, capture });
useEventListener(window, "mouseup", onReleased, { passive: true, capture });
2 years ago
if (drag) {
2 years ago
useEventListener(target, "dragstart", onPressed("mouse"), { passive: true, capture });
useEventListener(window, "drop", onReleased, { passive: true, capture });
useEventListener(window, "dragend", onReleased, { passive: true, capture });
2 years ago
}
if (touch) {
2 years ago
useEventListener(target, "touchstart", onPressed("touch"), { passive: true, capture });
useEventListener(window, "touchend", onReleased, { passive: true, capture });
useEventListener(window, "touchcancel", onReleased, { passive: true, capture });
2 years ago
}
return {
pressed,
sourceType
};
}
function useNavigatorLanguage(options = {}) {
const { window = defaultWindow } = options;
const navigator = window == null ? void 0 : window.navigator;
const isSupported = useSupported(() => navigator && "language" in navigator);
const language = ref(navigator == null ? void 0 : navigator.language);
useEventListener(window, "languagechange", () => {
if (navigator)
language.value = navigator.language;
});
return {
isSupported,
language
};
}
function useNetwork(options = {}) {
const { window = defaultWindow } = options;
const navigator = window == null ? void 0 : window.navigator;
const isSupported = useSupported(() => navigator && "connection" in navigator);
const isOnline = ref(true);
const saveData = ref(false);
const offlineAt = ref(void 0);
const onlineAt = ref(void 0);
const downlink = ref(void 0);
const downlinkMax = ref(void 0);
const rtt = ref(void 0);
const effectiveType = ref(void 0);
const type = ref("unknown");
const connection = isSupported.value && navigator.connection;
function updateNetworkInformation() {
if (!navigator)
return;
isOnline.value = navigator.onLine;
offlineAt.value = isOnline.value ? void 0 : Date.now();
onlineAt.value = isOnline.value ? Date.now() : void 0;
if (connection) {
downlink.value = connection.downlink;
downlinkMax.value = connection.downlinkMax;
effectiveType.value = connection.effectiveType;
rtt.value = connection.rtt;
saveData.value = connection.saveData;
type.value = connection.type;
}
}
if (window) {
useEventListener(window, "offline", () => {
isOnline.value = false;
offlineAt.value = Date.now();
});
useEventListener(window, "online", () => {
isOnline.value = true;
onlineAt.value = Date.now();
});
}
if (connection)
useEventListener(connection, "change", updateNetworkInformation, false);
updateNetworkInformation();
return {
isSupported,
isOnline,
saveData,
offlineAt,
onlineAt,
downlink,
downlinkMax,
effectiveType,
rtt,
type
};
}
function useNow(options = {}) {
const {
controls: exposeControls = false,
interval = "requestAnimationFrame"
} = options;
const now = ref(/* @__PURE__ */ new Date());
const update = () => now.value = /* @__PURE__ */ new Date();
const controls = interval === "requestAnimationFrame" ? useRafFn(update, { immediate: true }) : useIntervalFn(update, interval, { immediate: true });
if (exposeControls) {
2 years ago
return {
now,
...controls
};
2 years ago
} else {
return now;
}
}
function useObjectUrl(object) {
const url = ref();
const release = () => {
if (url.value)
URL.revokeObjectURL(url.value);
url.value = void 0;
};
watch(
() => toValue(object),
(newObject) => {
release();
if (newObject)
url.value = URL.createObjectURL(newObject);
},
{ immediate: true }
);
tryOnScopeDispose(release);
return readonly(url);
}
function useClamp(value, min, max) {
if (typeof value === "function" || isReadonly(value))
return computed(() => clamp(toValue(value), toValue(min), toValue(max)));
const _value = ref(value);
return computed({
get() {
return _value.value = clamp(_value.value, toValue(min), toValue(max));
},
set(value2) {
_value.value = clamp(value2, toValue(min), toValue(max));
}
});
}
function useOffsetPagination(options) {
const {
2 years ago
total = Number.POSITIVE_INFINITY,
2 years ago
pageSize = 10,
page = 1,
onPageChange = noop,
onPageSizeChange = noop,
onPageCountChange = noop
} = options;
2 years ago
const currentPageSize = useClamp(pageSize, 1, Number.POSITIVE_INFINITY);
2 years ago
const pageCount = computed(() => Math.max(
1,
Math.ceil(toValue(total) / toValue(currentPageSize))
));
const currentPage = useClamp(page, 1, pageCount);
const isFirstPage = computed(() => currentPage.value === 1);
const isLastPage = computed(() => currentPage.value === pageCount.value);
if (isRef(page))
syncRef(page, currentPage);
if (isRef(pageSize))
syncRef(pageSize, currentPageSize);
function prev() {
currentPage.value--;
}
function next() {
currentPage.value++;
}
const returnValue = {
currentPage,
currentPageSize,
pageCount,
isFirstPage,
isLastPage,
prev,
next
};
watch(currentPage, () => {
onPageChange(reactive(returnValue));
});
watch(currentPageSize, () => {
onPageSizeChange(reactive(returnValue));
});
watch(pageCount, () => {
onPageCountChange(reactive(returnValue));
});
return returnValue;
}
function useOnline(options = {}) {
const { isOnline } = useNetwork(options);
return isOnline;
}
function usePageLeave(options = {}) {
const { window = defaultWindow } = options;
const isLeft = ref(false);
const handler = (event) => {
if (!window)
return;
event = event || window.event;
const from = event.relatedTarget || event.toElement;
isLeft.value = !from;
};
if (window) {
useEventListener(window, "mouseout", handler, { passive: true });
useEventListener(window.document, "mouseleave", handler, { passive: true });
useEventListener(window.document, "mouseenter", handler, { passive: true });
}
return isLeft;
}
function useParallax(target, options = {}) {
const {
deviceOrientationTiltAdjust = (i) => i,
deviceOrientationRollAdjust = (i) => i,
mouseTiltAdjust = (i) => i,
mouseRollAdjust = (i) => i,
window = defaultWindow
} = options;
const orientation = reactive(useDeviceOrientation({ window }));
const {
elementX: x,
elementY: y,
elementWidth: width,
elementHeight: height
} = useMouseInElement(target, { handleOutside: false, window });
const source = computed(() => {
if (orientation.isSupported && (orientation.alpha != null && orientation.alpha !== 0 || orientation.gamma != null && orientation.gamma !== 0))
return "deviceOrientation";
return "mouse";
});
const roll = computed(() => {
if (source.value === "deviceOrientation") {
const value = -orientation.beta / 90;
return deviceOrientationRollAdjust(value);
} else {
const value = -(y.value - height.value / 2) / height.value;
return mouseRollAdjust(value);
}
});
const tilt = computed(() => {
if (source.value === "deviceOrientation") {
const value = orientation.gamma / 90;
return deviceOrientationTiltAdjust(value);
} else {
const value = (x.value - width.value / 2) / width.value;
return mouseTiltAdjust(value);
}
});
return { roll, tilt, source };
}
function useParentElement(element = useCurrentElement()) {
const parentElement = shallowRef();
const update = () => {
const el = unrefElement(element);
if (el)
parentElement.value = el.parentElement;
};
tryOnMounted(update);
watch(() => toValue(element), update);
return parentElement;
}
function usePerformanceObserver(options, callback) {
2 years ago
const {
2 years ago
window = defaultWindow,
2 years ago
immediate = true,
...performanceOptions
} = options;
2 years ago
const isSupported = useSupported(() => window && "PerformanceObserver" in window);
let observer;
const stop = () => {
observer == null ? void 0 : observer.disconnect();
};
const start = () => {
if (isSupported.value) {
stop();
observer = new PerformanceObserver(callback);
observer.observe(performanceOptions);
}
};
tryOnScopeDispose(stop);
if (immediate)
start();
return {
isSupported,
start,
stop
};
}
const defaultState = {
x: 0,
y: 0,
pointerId: 0,
pressure: 0,
tiltX: 0,
tiltY: 0,
width: 0,
height: 0,
twist: 0,
pointerType: null
};
const keys = /* @__PURE__ */ Object.keys(defaultState);
function usePointer(options = {}) {
const {
target = defaultWindow
} = options;
const isInside = ref(false);
const state = ref(options.initialValue || {});
Object.assign(state.value, defaultState, state.value);
const handler = (event) => {
isInside.value = true;
if (options.pointerTypes && !options.pointerTypes.includes(event.pointerType))
return;
state.value = objectPick(event, keys, false);
};
if (target) {
2 years ago
const listenerOptions = { passive: true };
useEventListener(target, ["pointerdown", "pointermove", "pointerup"], handler, listenerOptions);
useEventListener(target, "pointerleave", () => isInside.value = false, listenerOptions);
2 years ago
}
2 years ago
return {
...toRefs(state),
2 years ago
isInside
2 years ago
};
2 years ago
}
function usePointerLock(target, options = {}) {
const { document = defaultDocument, pointerLockOptions } = options;
const isSupported = useSupported(() => document && "pointerLockElement" in document);
const element = ref();
const triggerElement = ref();
let targetElement;
if (isSupported.value) {
useEventListener(document, "pointerlockchange", () => {
var _a;
const currentElement = (_a = document.pointerLockElement) != null ? _a : element.value;
if (targetElement && currentElement === targetElement) {
element.value = document.pointerLockElement;
if (!element.value)
targetElement = triggerElement.value = null;
}
});
useEventListener(document, "pointerlockerror", () => {
var _a;
const currentElement = (_a = document.pointerLockElement) != null ? _a : element.value;
if (targetElement && currentElement === targetElement) {
const action = document.pointerLockElement ? "release" : "acquire";
throw new Error(`Failed to ${action} pointer lock.`);
}
});
}
async function lock(e, options2) {
var _a;
if (!isSupported.value)
throw new Error("Pointer Lock API is not supported by your browser.");
triggerElement.value = e instanceof Event ? e.currentTarget : null;
targetElement = e instanceof Event ? (_a = unrefElement(target)) != null ? _a : triggerElement.value : unrefElement(e);
if (!targetElement)
throw new Error("Target element undefined.");
targetElement.requestPointerLock(options2 != null ? options2 : pointerLockOptions);
return await until(element).toBe(targetElement);
}
async function unlock() {
if (!element.value)
return false;
document.exitPointerLock();
await until(element).toBeNull();
return true;
}
return {
isSupported,
element,
triggerElement,
lock,
unlock
};
}
function usePointerSwipe(target, options = {}) {
const targetRef = toRef(target);
const {
threshold = 50,
onSwipe,
onSwipeEnd,
onSwipeStart
} = options;
const posStart = reactive({ x: 0, y: 0 });
const updatePosStart = (x, y) => {
posStart.x = x;
posStart.y = y;
};
const posEnd = reactive({ x: 0, y: 0 });
const updatePosEnd = (x, y) => {
posEnd.x = x;
posEnd.y = y;
};
const distanceX = computed(() => posStart.x - posEnd.x);
const distanceY = computed(() => posStart.y - posEnd.y);
const { max, abs } = Math;
const isThresholdExceeded = computed(() => max(abs(distanceX.value), abs(distanceY.value)) >= threshold);
const isSwiping = ref(false);
const isPointerDown = ref(false);
const direction = computed(() => {
if (!isThresholdExceeded.value)
return "none";
if (abs(distanceX.value) > abs(distanceY.value)) {
return distanceX.value > 0 ? "left" : "right";
} else {
return distanceY.value > 0 ? "up" : "down";
}
});
const eventIsAllowed = (e) => {
var _a, _b, _c;
const isReleasingButton = e.buttons === 0;
const isPrimaryButton = e.buttons === 1;
return (_c = (_b = (_a = options.pointerTypes) == null ? void 0 : _a.includes(e.pointerType)) != null ? _b : isReleasingButton || isPrimaryButton) != null ? _c : true;
};
const stops = [
useEventListener(target, "pointerdown", (e) => {
var _a, _b;
if (!eventIsAllowed(e))
return;
isPointerDown.value = true;
(_b = (_a = targetRef.value) == null ? void 0 : _a.style) == null ? void 0 : _b.setProperty("touch-action", "none");
const eventTarget = e.target;
eventTarget == null ? void 0 : eventTarget.setPointerCapture(e.pointerId);
const { clientX: x, clientY: y } = e;
updatePosStart(x, y);
updatePosEnd(x, y);
onSwipeStart == null ? void 0 : onSwipeStart(e);
}),
useEventListener(target, "pointermove", (e) => {
if (!eventIsAllowed(e))
return;
if (!isPointerDown.value)
return;
const { clientX: x, clientY: y } = e;
updatePosEnd(x, y);
if (!isSwiping.value && isThresholdExceeded.value)
isSwiping.value = true;
if (isSwiping.value)
onSwipe == null ? void 0 : onSwipe(e);
}),
useEventListener(target, "pointerup", (e) => {
var _a, _b;
if (!eventIsAllowed(e))
return;
if (isSwiping.value)
onSwipeEnd == null ? void 0 : onSwipeEnd(e, direction.value);
isPointerDown.value = false;
isSwiping.value = false;
(_b = (_a = targetRef.value) == null ? void 0 : _a.style) == null ? void 0 : _b.setProperty("touch-action", "initial");
})
];
const stop = () => stops.forEach((s) => s());
return {
isSwiping: readonly(isSwiping),
direction: readonly(direction),
posStart: readonly(posStart),
posEnd: readonly(posEnd),
distanceX,
distanceY,
stop
};
}
function usePreferredColorScheme(options) {
const isLight = useMediaQuery("(prefers-color-scheme: light)", options);
const isDark = useMediaQuery("(prefers-color-scheme: dark)", options);
return computed(() => {
if (isDark.value)
return "dark";
if (isLight.value)
return "light";
return "no-preference";
});
}
function usePreferredContrast(options) {
const isMore = useMediaQuery("(prefers-contrast: more)", options);
const isLess = useMediaQuery("(prefers-contrast: less)", options);
const isCustom = useMediaQuery("(prefers-contrast: custom)", options);
return computed(() => {
if (isMore.value)
return "more";
if (isLess.value)
return "less";
if (isCustom.value)
return "custom";
return "no-preference";
});
}
function usePreferredLanguages(options = {}) {
const { window = defaultWindow } = options;
if (!window)
return ref(["en"]);
const navigator = window.navigator;
const value = ref(navigator.languages);
useEventListener(window, "languagechange", () => {
value.value = navigator.languages;
});
return value;
}
function usePreferredReducedMotion(options) {
const isReduced = useMediaQuery("(prefers-reduced-motion: reduce)", options);
return computed(() => {
if (isReduced.value)
return "reduce";
return "no-preference";
});
}
function usePrevious(value, initialValue) {
const previous = shallowRef(initialValue);
watch(
toRef(value),
(_, oldValue) => {
previous.value = oldValue;
},
{ flush: "sync" }
);
return readonly(previous);
}
function useScreenOrientation(options = {}) {
const {
window = defaultWindow
} = options;
const isSupported = useSupported(() => window && "screen" in window && "orientation" in window.screen);
const screenOrientation = isSupported.value ? window.screen.orientation : {};
const orientation = ref(screenOrientation.type);
const angle = ref(screenOrientation.angle || 0);
if (isSupported.value) {
useEventListener(window, "orientationchange", () => {
orientation.value = screenOrientation.type;
angle.value = screenOrientation.angle;
});
}
const lockOrientation = (type) => {
if (!isSupported.value)
return Promise.reject(new Error("Not supported"));
return screenOrientation.lock(type);
};
const unlockOrientation = () => {
if (isSupported.value)
screenOrientation.unlock();
};
return {
isSupported,
orientation,
angle,
lockOrientation,
unlockOrientation
};
}
const topVarName = "--vueuse-safe-area-top";
const rightVarName = "--vueuse-safe-area-right";
const bottomVarName = "--vueuse-safe-area-bottom";
const leftVarName = "--vueuse-safe-area-left";
function useScreenSafeArea() {
const top = ref("");
const right = ref("");
const bottom = ref("");
const left = ref("");
if (isClient) {
const topCssVar = useCssVar(topVarName);
const rightCssVar = useCssVar(rightVarName);
const bottomCssVar = useCssVar(bottomVarName);
const leftCssVar = useCssVar(leftVarName);
topCssVar.value = "env(safe-area-inset-top, 0px)";
rightCssVar.value = "env(safe-area-inset-right, 0px)";
bottomCssVar.value = "env(safe-area-inset-bottom, 0px)";
leftCssVar.value = "env(safe-area-inset-left, 0px)";
update();
useEventListener("resize", useDebounceFn(update));
}
function update() {
top.value = getValue(topVarName);
right.value = getValue(rightVarName);
bottom.value = getValue(bottomVarName);
left.value = getValue(leftVarName);
}
return {
top,
right,
bottom,
left,
update
};
}
function getValue(position) {
return getComputedStyle(document.documentElement).getPropertyValue(position);
}
function useScriptTag(src, onLoaded = noop, options = {}) {
const {
immediate = true,
manual = false,
type = "text/javascript",
async = true,
crossOrigin,
referrerPolicy,
noModule,
defer,
document = defaultDocument,
attrs = {}
} = options;
const scriptTag = ref(null);
let _promise = null;
const loadScript = (waitForScriptLoad) => new Promise((resolve, reject) => {
const resolveWithElement = (el2) => {
scriptTag.value = el2;
resolve(el2);
return el2;
};
if (!document) {
resolve(false);
return;
}
let shouldAppend = false;
let el = document.querySelector(`script[src="${toValue(src)}"]`);
if (!el) {
el = document.createElement("script");
el.type = type;
el.async = async;
el.src = toValue(src);
if (defer)
el.defer = defer;
if (crossOrigin)
el.crossOrigin = crossOrigin;
if (noModule)
el.noModule = noModule;
if (referrerPolicy)
el.referrerPolicy = referrerPolicy;
Object.entries(attrs).forEach(([name, value]) => el == null ? void 0 : el.setAttribute(name, value));
shouldAppend = true;
} else if (el.hasAttribute("data-loaded")) {
resolveWithElement(el);
}
el.addEventListener("error", (event) => reject(event));
el.addEventListener("abort", (event) => reject(event));
el.addEventListener("load", () => {
el.setAttribute("data-loaded", "true");
onLoaded(el);
resolveWithElement(el);
});
if (shouldAppend)
el = document.head.appendChild(el);
if (!waitForScriptLoad)
resolveWithElement(el);
});
const load = (waitForScriptLoad = true) => {
if (!_promise)
_promise = loadScript(waitForScriptLoad);
return _promise;
};
const unload = () => {
if (!document)
return;
_promise = null;
if (scriptTag.value)
scriptTag.value = null;
const el = document.querySelector(`script[src="${toValue(src)}"]`);
if (el)
document.head.removeChild(el);
};
if (immediate && !manual)
tryOnMounted(load);
if (!manual)
tryOnUnmounted(unload);
return { scriptTag, load, unload };
}
function checkOverflowScroll(ele) {
const style = window.getComputedStyle(ele);
2 years ago
if (style.overflowX === "scroll" || style.overflowY === "scroll" || style.overflowX === "auto" && ele.clientWidth < ele.scrollWidth || style.overflowY === "auto" && ele.clientHeight < ele.scrollHeight) {
2 years ago
return true;
} else {
const parent = ele.parentNode;
if (!parent || parent.tagName === "BODY")
return false;
return checkOverflowScroll(parent);
}
}
function preventDefault(rawEvent) {
const e = rawEvent || window.event;
const _target = e.target;
if (checkOverflowScroll(_target))
return false;
if (e.touches.length > 1)
return true;
if (e.preventDefault)
e.preventDefault();
return false;
}
function useScrollLock(element, initialState = false) {
const isLocked = ref(initialState);
let stopTouchMoveListener = null;
let initialOverflow;
watch(toRef(element), (el) => {
2 years ago
const target = resolveElement(toValue(el));
if (target) {
const ele = target;
2 years ago
initialOverflow = ele.style.overflow;
if (isLocked.value)
ele.style.overflow = "hidden";
}
}, {
immediate: true
});
const lock = () => {
2 years ago
const el = resolveElement(toValue(element));
if (!el || isLocked.value)
2 years ago
return;
if (isIOS) {
stopTouchMoveListener = useEventListener(
2 years ago
el,
2 years ago
"touchmove",
(e) => {
preventDefault(e);
},
{ passive: false }
);
}
2 years ago
el.style.overflow = "hidden";
2 years ago
isLocked.value = true;
};
const unlock = () => {
2 years ago
const el = resolveElement(toValue(element));
if (!el || !isLocked.value)
2 years ago
return;
isIOS && (stopTouchMoveListener == null ? void 0 : stopTouchMoveListener());
2 years ago
el.style.overflow = initialOverflow;
2 years ago
isLocked.value = false;
};
tryOnScopeDispose(unlock);
return computed({
get() {
return isLocked.value;
},
set(v) {
if (v)
lock();
else
unlock();
}
});
}
function useSessionStorage(key, initialValue, options = {}) {
const { window = defaultWindow } = options;
return useStorage(key, initialValue, window == null ? void 0 : window.sessionStorage, options);
}
function useShare(shareOptions = {}, options = {}) {
const { navigator = defaultNavigator } = options;
const _navigator = navigator;
const isSupported = useSupported(() => _navigator && "canShare" in _navigator);
const share = async (overrideOptions = {}) => {
if (isSupported.value) {
2 years ago
const data = {
...toValue(shareOptions),
...toValue(overrideOptions)
};
2 years ago
let granted = true;
if (data.files && _navigator.canShare)
granted = _navigator.canShare({ files: data.files });
if (granted)
return _navigator.share(data);
}
};
return {
isSupported,
share
};
}
const defaultSortFn = (source, compareFn) => source.sort(compareFn);
const defaultCompare = (a, b) => a - b;
function useSorted(...args) {
var _a, _b, _c, _d;
const [source] = args;
let compareFn = defaultCompare;
let options = {};
if (args.length === 2) {
if (typeof args[1] === "object") {
options = args[1];
compareFn = (_a = options.compareFn) != null ? _a : defaultCompare;
} else {
compareFn = (_b = args[1]) != null ? _b : defaultCompare;
}
} else if (args.length > 2) {
compareFn = (_c = args[1]) != null ? _c : defaultCompare;
options = (_d = args[2]) != null ? _d : {};
}
const {
dirty = false,
sortFn = defaultSortFn
} = options;
if (!dirty)
return computed(() => sortFn([...toValue(source)], compareFn));
watchEffect(() => {
const result = sortFn(toValue(source), compareFn);
if (isRef(source))
source.value = result;
else
source.splice(0, source.length, ...result);
});
return source;
}
function useSpeechRecognition(options = {}) {
const {
interimResults = true,
continuous = true,
window = defaultWindow
} = options;
const lang = toRef(options.lang || "en-US");
const isListening = ref(false);
const isFinal = ref(false);
const result = ref("");
const error = shallowRef(void 0);
const toggle = (value = !isListening.value) => {
isListening.value = value;
};
const start = () => {
isListening.value = true;
};
const stop = () => {
isListening.value = false;
};
const SpeechRecognition = window && (window.SpeechRecognition || window.webkitSpeechRecognition);
const isSupported = useSupported(() => SpeechRecognition);
let recognition;
if (isSupported.value) {
recognition = new SpeechRecognition();
recognition.continuous = continuous;
recognition.interimResults = interimResults;
recognition.lang = toValue(lang);
recognition.onstart = () => {
isFinal.value = false;
};
watch(lang, (lang2) => {
if (recognition && !isListening.value)
recognition.lang = lang2;
});
recognition.onresult = (event) => {
const transcript = Array.from(event.results).map((result2) => {
isFinal.value = result2.isFinal;
return result2[0];
}).map((result2) => result2.transcript).join("");
result.value = transcript;
error.value = void 0;
};
recognition.onerror = (event) => {
error.value = event;
};
recognition.onend = () => {
isListening.value = false;
recognition.lang = toValue(lang);
};
watch(isListening, () => {
if (isListening.value)
recognition.start();
else
recognition.stop();
});
}
tryOnScopeDispose(() => {
isListening.value = false;
});
return {
isSupported,
isListening,
isFinal,
recognition,
result,
error,
toggle,
start,
stop
};
}
function useSpeechSynthesis(text, options = {}) {
const {
pitch = 1,
rate = 1,
volume = 1,
window = defaultWindow
} = options;
const synth = window && window.speechSynthesis;
const isSupported = useSupported(() => synth);
const isPlaying = ref(false);
const status = ref("init");
const spokenText = toRef(text || "");
const lang = toRef(options.lang || "en-US");
const error = shallowRef(void 0);
const toggle = (value = !isPlaying.value) => {
isPlaying.value = value;
};
const bindEventsForUtterance = (utterance2) => {
utterance2.lang = toValue(lang);
utterance2.voice = toValue(options.voice) || null;
2 years ago
utterance2.pitch = toValue(pitch);
utterance2.rate = toValue(rate);
2 years ago
utterance2.volume = volume;
utterance2.onstart = () => {
isPlaying.value = true;
status.value = "play";
};
utterance2.onpause = () => {
isPlaying.value = false;
status.value = "pause";
};
utterance2.onresume = () => {
isPlaying.value = true;
status.value = "play";
};
utterance2.onend = () => {
isPlaying.value = false;
status.value = "end";
};
utterance2.onerror = (event) => {
error.value = event;
};
};
const utterance = computed(() => {
isPlaying.value = false;
status.value = "init";
const newUtterance = new SpeechSynthesisUtterance(spokenText.value);
bindEventsForUtterance(newUtterance);
return newUtterance;
});
const speak = () => {
synth.cancel();
utterance && synth.speak(utterance.value);
};
const stop = () => {
synth.cancel();
isPlaying.value = false;
};
if (isSupported.value) {
bindEventsForUtterance(utterance.value);
watch(lang, (lang2) => {
if (utterance.value && !isPlaying.value)
utterance.value.lang = lang2;
});
if (options.voice) {
watch(options.voice, () => {
synth.cancel();
});
}
watch(isPlaying, () => {
if (isPlaying.value)
synth.resume();
else
synth.pause();
});
}
tryOnScopeDispose(() => {
isPlaying.value = false;
});
return {
isSupported,
isPlaying,
status,
utterance,
error,
stop,
toggle,
speak
};
}
function useStepper(steps, initialStep) {
const stepsRef = ref(steps);
const stepNames = computed(() => Array.isArray(stepsRef.value) ? stepsRef.value : Object.keys(stepsRef.value));
const index = ref(stepNames.value.indexOf(initialStep != null ? initialStep : stepNames.value[0]));
const current = computed(() => at(index.value));
const isFirst = computed(() => index.value === 0);
const isLast = computed(() => index.value === stepNames.value.length - 1);
const next = computed(() => stepNames.value[index.value + 1]);
const previous = computed(() => stepNames.value[index.value - 1]);
function at(index2) {
if (Array.isArray(stepsRef.value))
return stepsRef.value[index2];
return stepsRef.value[stepNames.value[index2]];
}
function get(step) {
if (!stepNames.value.includes(step))
return;
return at(stepNames.value.indexOf(step));
}
function goTo(step) {
if (stepNames.value.includes(step))
index.value = stepNames.value.indexOf(step);
}
function goToNext() {
if (isLast.value)
return;
index.value++;
}
function goToPrevious() {
if (isFirst.value)
return;
index.value--;
}
function goBackTo(step) {
if (isAfter(step))
goTo(step);
}
function isNext(step) {
return stepNames.value.indexOf(step) === index.value + 1;
}
function isPrevious(step) {
return stepNames.value.indexOf(step) === index.value - 1;
}
function isCurrent(step) {
return stepNames.value.indexOf(step) === index.value;
}
function isBefore(step) {
return index.value < stepNames.value.indexOf(step);
}
function isAfter(step) {
return index.value > stepNames.value.indexOf(step);
}
return {
steps: stepsRef,
stepNames,
index,
current,
next,
previous,
isFirst,
isLast,
at,
get,
goTo,
goToNext,
goToPrevious,
goBackTo,
isNext,
isPrevious,
isCurrent,
isBefore,
isAfter
};
}
function useStorageAsync(key, initialValue, storage, options = {}) {
var _a;
const {
flush = "pre",
deep = true,
listenToStorageChanges = true,
writeDefaults = true,
mergeDefaults = false,
shallow,
window = defaultWindow,
eventFilter,
onError = (e) => {
console.error(e);
}
} = options;
const rawInit = toValue(initialValue);
const type = guessSerializerType(rawInit);
const data = (shallow ? shallowRef : ref)(initialValue);
const serializer = (_a = options.serializer) != null ? _a : StorageSerializers[type];
if (!storage) {
try {
storage = getSSRHandler("getDefaultStorage", () => {
var _a2;
return (_a2 = defaultWindow) == null ? void 0 : _a2.localStorage;
})();
} catch (e) {
onError(e);
}
}
async function read(event) {
if (!storage || event && event.key !== key)
return;
try {
const rawValue = event ? event.newValue : await storage.getItem(key);
if (rawValue == null) {
data.value = rawInit;
if (writeDefaults && rawInit !== null)
await storage.setItem(key, await serializer.write(rawInit));
} else if (mergeDefaults) {
const value = await serializer.read(rawValue);
if (typeof mergeDefaults === "function")
data.value = mergeDefaults(value, rawInit);
else if (type === "object" && !Array.isArray(value))
2 years ago
data.value = { ...rawInit, ...value };
2 years ago
else
data.value = value;
} else {
data.value = await serializer.read(rawValue);
}
} catch (e) {
onError(e);
}
}
read();
if (window && listenToStorageChanges)
useEventListener(window, "storage", (e) => Promise.resolve().then(() => read(e)));
if (storage) {
watchWithFilter(
data,
async () => {
try {
if (data.value == null)
await storage.removeItem(key);
else
await storage.setItem(key, await serializer.write(data.value));
} catch (e) {
onError(e);
}
},
{
flush,
deep,
eventFilter
}
);
}
return data;
}
let _id = 0;
function useStyleTag(css, options = {}) {
const isLoaded = ref(false);
const {
document = defaultDocument,
immediate = true,
manual = false,
id = `vueuse_styletag_${++_id}`
} = options;
const cssRef = ref(css);
let stop = () => {
};
const load = () => {
if (!document)
return;
const el = document.getElementById(id) || document.createElement("style");
if (!el.isConnected) {
el.id = id;
if (options.media)
el.media = options.media;
document.head.appendChild(el);
}
if (isLoaded.value)
return;
stop = watch(
cssRef,
(value) => {
el.textContent = value;
},
{ immediate: true }
);
isLoaded.value = true;
};
const unload = () => {
if (!document || !isLoaded.value)
return;
stop();
document.head.removeChild(document.getElementById(id));
isLoaded.value = false;
};
if (immediate && !manual)
tryOnMounted(load);
if (!manual)
tryOnScopeDispose(unload);
return {
id,
css: cssRef,
unload,
load,
isLoaded: readonly(isLoaded)
};
}
function useSwipe(target, options = {}) {
const {
threshold = 50,
onSwipe,
onSwipeEnd,
onSwipeStart,
passive = true,
window = defaultWindow
} = options;
const coordsStart = reactive({ x: 0, y: 0 });
const coordsEnd = reactive({ x: 0, y: 0 });
const diffX = computed(() => coordsStart.x - coordsEnd.x);
const diffY = computed(() => coordsStart.y - coordsEnd.y);
const { max, abs } = Math;
const isThresholdExceeded = computed(() => max(abs(diffX.value), abs(diffY.value)) >= threshold);
const isSwiping = ref(false);
const direction = computed(() => {
if (!isThresholdExceeded.value)
return "none";
if (abs(diffX.value) > abs(diffY.value)) {
return diffX.value > 0 ? "left" : "right";
} else {
return diffY.value > 0 ? "up" : "down";
}
});
const getTouchEventCoords = (e) => [e.touches[0].clientX, e.touches[0].clientY];
const updateCoordsStart = (x, y) => {
coordsStart.x = x;
coordsStart.y = y;
};
const updateCoordsEnd = (x, y) => {
coordsEnd.x = x;
coordsEnd.y = y;
};
let listenerOptions;
const isPassiveEventSupported = checkPassiveEventSupport(window == null ? void 0 : window.document);
if (!passive)
listenerOptions = isPassiveEventSupported ? { passive: false, capture: true } : { capture: true };
else
listenerOptions = isPassiveEventSupported ? { passive: true } : { capture: false };
const onTouchEnd = (e) => {
if (isSwiping.value)
onSwipeEnd == null ? void 0 : onSwipeEnd(e, direction.value);
isSwiping.value = false;
};
const stops = [
useEventListener(target, "touchstart", (e) => {
if (e.touches.length !== 1)
return;
if (listenerOptions.capture && !listenerOptions.passive)
e.preventDefault();
const [x, y] = getTouchEventCoords(e);
updateCoordsStart(x, y);
updateCoordsEnd(x, y);
onSwipeStart == null ? void 0 : onSwipeStart(e);
}, listenerOptions),
useEventListener(target, "touchmove", (e) => {
if (e.touches.length !== 1)
return;
const [x, y] = getTouchEventCoords(e);
updateCoordsEnd(x, y);
if (!isSwiping.value && isThresholdExceeded.value)
isSwiping.value = true;
if (isSwiping.value)
onSwipe == null ? void 0 : onSwipe(e);
}, listenerOptions),
2 years ago
useEventListener(target, ["touchend", "touchcancel"], onTouchEnd, listenerOptions)
2 years ago
];
const stop = () => stops.forEach((s) => s());
return {
isPassiveEventSupported,
isSwiping,
direction,
coordsStart,
coordsEnd,
lengthX: diffX,
lengthY: diffY,
stop
};
}
function checkPassiveEventSupport(document) {
if (!document)
return false;
let supportsPassive = false;
const optionsBlock = {
get passive() {
supportsPassive = true;
return false;
}
};
document.addEventListener("x", noop, optionsBlock);
document.removeEventListener("x", noop);
return supportsPassive;
}
function useTemplateRefsList() {
const refs = ref([]);
refs.value.set = (el) => {
if (el)
refs.value.push(el);
};
onBeforeUpdate(() => {
refs.value.length = 0;
});
return refs;
}
function useTextDirection(options = {}) {
const {
document = defaultDocument,
selector = "html",
observe = false,
initialValue = "ltr"
} = options;
function getValue() {
var _a, _b;
return (_b = (_a = document == null ? void 0 : document.querySelector(selector)) == null ? void 0 : _a.getAttribute("dir")) != null ? _b : initialValue;
}
const dir = ref(getValue());
tryOnMounted(() => dir.value = getValue());
if (observe && document) {
useMutationObserver(
document.querySelector(selector),
() => dir.value = getValue(),
{ attributes: true }
);
}
return computed({
get() {
return dir.value;
},
set(v) {
var _a, _b;
dir.value = v;
if (!document)
return;
if (dir.value)
(_a = document.querySelector(selector)) == null ? void 0 : _a.setAttribute("dir", dir.value);
else
(_b = document.querySelector(selector)) == null ? void 0 : _b.removeAttribute("dir");
}
});
}
function getRangesFromSelection(selection) {
var _a;
const rangeCount = (_a = selection.rangeCount) != null ? _a : 0;
2 years ago
return Array.from({ length: rangeCount }, (_, i) => selection.getRangeAt(i));
2 years ago
}
function useTextSelection(options = {}) {
const {
window = defaultWindow
} = options;
const selection = ref(null);
const text = computed(() => {
var _a, _b;
return (_b = (_a = selection.value) == null ? void 0 : _a.toString()) != null ? _b : "";
});
const ranges = computed(() => selection.value ? getRangesFromSelection(selection.value) : []);
const rects = computed(() => ranges.value.map((range) => range.getBoundingClientRect()));
function onSelectionChange() {
selection.value = null;
if (window)
selection.value = window.getSelection();
}
if (window)
useEventListener(window.document, "selectionchange", onSelectionChange);
return {
text,
rects,
ranges,
selection
};
}
function useTextareaAutosize(options) {
const textarea = ref(options == null ? void 0 : options.element);
const input = ref(options == null ? void 0 : options.input);
const textareaScrollHeight = ref(1);
function triggerResize() {
var _a, _b;
if (!textarea.value)
return;
let height = "";
textarea.value.style.height = "1px";
textareaScrollHeight.value = (_a = textarea.value) == null ? void 0 : _a.scrollHeight;
if (options == null ? void 0 : options.styleTarget)
toValue(options.styleTarget).style.height = `${textareaScrollHeight.value}px`;
else
height = `${textareaScrollHeight.value}px`;
textarea.value.style.height = height;
(_b = options == null ? void 0 : options.onResize) == null ? void 0 : _b.call(options);
}
2 years ago
watch([input, textarea], () => nextTick(triggerResize), { immediate: true });
2 years ago
useResizeObserver(textarea, () => triggerResize());
if (options == null ? void 0 : options.watch)
watch(options.watch, triggerResize, { immediate: true, deep: true });
return {
textarea,
input,
triggerResize
};
}
function useThrottledRefHistory(source, options = {}) {
const { throttle = 200, trailing = true } = options;
const filter = throttleFilter(throttle, trailing);
2 years ago
const history = useRefHistory(source, { ...options, eventFilter: filter });
return {
...history
};
}
2 years ago
const DEFAULT_UNITS = [
{ max: 6e4, value: 1e3, name: "second" },
{ max: 276e4, value: 6e4, name: "minute" },
{ max: 72e6, value: 36e5, name: "hour" },
{ max: 5184e5, value: 864e5, name: "day" },
{ max: 24192e5, value: 6048e5, name: "week" },
{ max: 28512e6, value: 2592e6, name: "month" },
2 years ago
{ max: Number.POSITIVE_INFINITY, value: 31536e6, name: "year" }
2 years ago
];
const DEFAULT_MESSAGES = {
justNow: "just now",
past: (n) => n.match(/\d/) ? `${n} ago` : n,
future: (n) => n.match(/\d/) ? `in ${n}` : n,
month: (n, past) => n === 1 ? past ? "last month" : "next month" : `${n} month${n > 1 ? "s" : ""}`,
year: (n, past) => n === 1 ? past ? "last year" : "next year" : `${n} year${n > 1 ? "s" : ""}`,
day: (n, past) => n === 1 ? past ? "yesterday" : "tomorrow" : `${n} day${n > 1 ? "s" : ""}`,
week: (n, past) => n === 1 ? past ? "last week" : "next week" : `${n} week${n > 1 ? "s" : ""}`,
hour: (n) => `${n} hour${n > 1 ? "s" : ""}`,
minute: (n) => `${n} minute${n > 1 ? "s" : ""}`,
second: (n) => `${n} second${n > 1 ? "s" : ""}`,
invalid: ""
};
function DEFAULT_FORMATTER(date) {
return date.toISOString().slice(0, 10);
}
function useTimeAgo(time, options = {}) {
const {
controls: exposeControls = false,
updateInterval = 3e4
} = options;
2 years ago
const { now, ...controls } = useNow({ interval: updateInterval, controls: true });
const timeAgo = computed(() => formatTimeAgo(new Date(toValue(time)), options, toValue(now)));
2 years ago
if (exposeControls) {
2 years ago
return {
timeAgo,
...controls
};
2 years ago
} else {
return timeAgo;
}
}
function formatTimeAgo(from, options = {}, now = Date.now()) {
var _a;
const {
max,
messages = DEFAULT_MESSAGES,
fullDateFormatter = DEFAULT_FORMATTER,
units = DEFAULT_UNITS,
showSecond = false,
rounding = "round"
} = options;
const roundFn = typeof rounding === "number" ? (n) => +n.toFixed(rounding) : Math[rounding];
const diff = +now - +from;
const absDiff = Math.abs(diff);
function getValue(diff2, unit) {
return roundFn(Math.abs(diff2) / unit.value);
}
function format(diff2, unit) {
const val = getValue(diff2, unit);
const past = diff2 > 0;
const str = applyFormat(unit.name, val, past);
return applyFormat(past ? "past" : "future", str, past);
}
function applyFormat(name, val, isPast) {
const formatter = messages[name];
if (typeof formatter === "function")
return formatter(val, isPast);
return formatter.replace("{0}", val.toString());
}
if (absDiff < 6e4 && !showSecond)
return messages.justNow;
if (typeof max === "number" && absDiff > max)
return fullDateFormatter(new Date(from));
if (typeof max === "string") {
const unitMax = (_a = units.find((i) => i.name === max)) == null ? void 0 : _a.max;
if (unitMax && absDiff > unitMax)
return fullDateFormatter(new Date(from));
}
for (const [idx, unit] of units.entries()) {
const val = getValue(diff, unit);
if (val <= 0 && units[idx - 1])
return format(diff, units[idx - 1]);
if (absDiff < unit.max)
return format(diff, unit);
}
return messages.invalid;
}
function useTimeoutPoll(fn, interval, timeoutPollOptions) {
2 years ago
const { start } = useTimeoutFn(loop, interval, { immediate: false });
2 years ago
const isActive = ref(false);
async function loop() {
if (!isActive.value)
return;
await fn();
start();
}
function resume() {
if (!isActive.value) {
isActive.value = true;
loop();
}
}
function pause() {
isActive.value = false;
}
if (timeoutPollOptions == null ? void 0 : timeoutPollOptions.immediate)
resume();
tryOnScopeDispose(pause);
return {
isActive,
pause,
resume
};
}
function useTimestamp(options = {}) {
const {
controls: exposeControls = false,
offset = 0,
immediate = true,
interval = "requestAnimationFrame",
callback
} = options;
const ts = ref(timestamp() + offset);
const update = () => ts.value = timestamp() + offset;
const cb = callback ? () => {
update();
callback(ts.value);
} : update;
const controls = interval === "requestAnimationFrame" ? useRafFn(cb, { immediate }) : useIntervalFn(cb, interval, { immediate });
if (exposeControls) {
2 years ago
return {
timestamp: ts,
...controls
};
2 years ago
} else {
return ts;
}
}
function useTitle(newTitle = null, options = {}) {
var _a, _b;
const {
document = defaultDocument
} = options;
const title = toRef((_a = newTitle != null ? newTitle : document == null ? void 0 : document.title) != null ? _a : null);
const isReadonly = newTitle && typeof newTitle === "function";
function format(t) {
if (!("titleTemplate" in options))
return t;
const template = options.titleTemplate || "%s";
return typeof template === "function" ? template(t) : toValue(template).replace(/%s/g, t);
}
watch(
title,
(t, o) => {
if (t !== o && document)
document.title = format(typeof t === "string" ? t : "");
},
{ immediate: true }
);
if (options.observe && !options.titleTemplate && document && !isReadonly) {
useMutationObserver(
(_b = document.head) == null ? void 0 : _b.querySelector("title"),
() => {
if (document && document.title !== title.value)
title.value = format(document.title);
},
{ childList: true }
);
}
return title;
}
const _TransitionPresets = {
easeInSine: [0.12, 0, 0.39, 0],
easeOutSine: [0.61, 1, 0.88, 1],
easeInOutSine: [0.37, 0, 0.63, 1],
easeInQuad: [0.11, 0, 0.5, 0],
easeOutQuad: [0.5, 1, 0.89, 1],
easeInOutQuad: [0.45, 0, 0.55, 1],
easeInCubic: [0.32, 0, 0.67, 0],
easeOutCubic: [0.33, 1, 0.68, 1],
easeInOutCubic: [0.65, 0, 0.35, 1],
easeInQuart: [0.5, 0, 0.75, 0],
easeOutQuart: [0.25, 1, 0.5, 1],
easeInOutQuart: [0.76, 0, 0.24, 1],
easeInQuint: [0.64, 0, 0.78, 0],
easeOutQuint: [0.22, 1, 0.36, 1],
easeInOutQuint: [0.83, 0, 0.17, 1],
easeInExpo: [0.7, 0, 0.84, 0],
easeOutExpo: [0.16, 1, 0.3, 1],
easeInOutExpo: [0.87, 0, 0.13, 1],
easeInCirc: [0.55, 0, 1, 0.45],
easeOutCirc: [0, 0.55, 0.45, 1],
easeInOutCirc: [0.85, 0, 0.15, 1],
easeInBack: [0.36, 0, 0.66, -0.56],
easeOutBack: [0.34, 1.56, 0.64, 1],
easeInOutBack: [0.68, -0.6, 0.32, 1.6]
};
const TransitionPresets = /* @__PURE__ */ Object.assign({}, { linear: identity }, _TransitionPresets);
function createEasingFunction([p0, p1, p2, p3]) {
const a = (a1, a2) => 1 - 3 * a2 + 3 * a1;
const b = (a1, a2) => 3 * a2 - 6 * a1;
const c = (a1) => 3 * a1;
const calcBezier = (t, a1, a2) => ((a(a1, a2) * t + b(a1, a2)) * t + c(a1)) * t;
const getSlope = (t, a1, a2) => 3 * a(a1, a2) * t * t + 2 * b(a1, a2) * t + c(a1);
const getTforX = (x) => {
let aGuessT = x;
for (let i = 0; i < 4; ++i) {
const currentSlope = getSlope(aGuessT, p0, p2);
if (currentSlope === 0)
return aGuessT;
const currentX = calcBezier(aGuessT, p0, p2) - x;
aGuessT -= currentX / currentSlope;
}
return aGuessT;
};
return (x) => p0 === p1 && p2 === p3 ? x : calcBezier(getTforX(x), p1, p3);
}
function lerp(a, b, alpha) {
return a + alpha * (b - a);
}
function toVec(t) {
return (typeof t === "number" ? [t] : t) || [];
}
function executeTransition(source, from, to, options = {}) {
var _a, _b;
const fromVal = toValue(from);
const toVal = toValue(to);
const v1 = toVec(fromVal);
const v2 = toVec(toVal);
const duration = (_a = toValue(options.duration)) != null ? _a : 1e3;
const startedAt = Date.now();
const endAt = Date.now() + duration;
const trans = typeof options.transition === "function" ? options.transition : (_b = toValue(options.transition)) != null ? _b : identity;
const ease = typeof trans === "function" ? trans : createEasingFunction(trans);
return new Promise((resolve) => {
source.value = fromVal;
const tick = () => {
var _a2;
if ((_a2 = options.abort) == null ? void 0 : _a2.call(options)) {
resolve();
return;
}
const now = Date.now();
const alpha = ease((now - startedAt) / duration);
const arr = toVec(source.value).map((n, i) => lerp(v1[i], v2[i], alpha));
if (Array.isArray(source.value))
source.value = arr.map((n, i) => {
var _a3, _b2;
return lerp((_a3 = v1[i]) != null ? _a3 : 0, (_b2 = v2[i]) != null ? _b2 : 0, alpha);
});
else if (typeof source.value === "number")
source.value = arr[0];
if (now < endAt) {
requestAnimationFrame(tick);
} else {
source.value = toVal;
resolve();
}
};
tick();
});
}
function useTransition(source, options = {}) {
let currentId = 0;
const sourceVal = () => {
const v = toValue(source);
return typeof v === "number" ? v : v.map(toValue);
};
const outputRef = ref(sourceVal());
watch(sourceVal, async (to) => {
var _a, _b;
if (toValue(options.disabled))
return;
const id = ++currentId;
if (options.delay)
await promiseTimeout(toValue(options.delay));
if (id !== currentId)
return;
const toVal = Array.isArray(to) ? to.map(toValue) : toValue(to);
(_a = options.onStarted) == null ? void 0 : _a.call(options);
2 years ago
await executeTransition(outputRef, outputRef.value, toVal, {
...options,
2 years ago
abort: () => {
var _a2;
return id !== currentId || ((_a2 = options.abort) == null ? void 0 : _a2.call(options));
}
2 years ago
});
2 years ago
(_b = options.onFinished) == null ? void 0 : _b.call(options);
}, { deep: true });
watch(() => toValue(options.disabled), (disabled) => {
if (disabled) {
currentId++;
outputRef.value = sourceVal();
}
});
tryOnScopeDispose(() => {
currentId++;
});
return computed(() => toValue(options.disabled) ? sourceVal() : outputRef.value);
}
function useUrlSearchParams(mode = "history", options = {}) {
const {
initialValue = {},
removeNullishValues = true,
removeFalsyValues = false,
write: enableWrite = true,
window = defaultWindow
} = options;
if (!window)
return reactive(initialValue);
const state = reactive({});
function getRawParams() {
if (mode === "history") {
return window.location.search || "";
} else if (mode === "hash") {
const hash = window.location.hash || "";
const index = hash.indexOf("?");
return index > 0 ? hash.slice(index) : "";
} else {
return (window.location.hash || "").replace(/^#/, "");
}
}
function constructQuery(params) {
const stringified = params.toString();
if (mode === "history")
return `${stringified ? `?${stringified}` : ""}${window.location.hash || ""}`;
if (mode === "hash-params")
return `${window.location.search || ""}${stringified ? `#${stringified}` : ""}`;
const hash = window.location.hash || "#";
const index = hash.indexOf("?");
if (index > 0)
return `${hash.slice(0, index)}${stringified ? `?${stringified}` : ""}`;
return `${hash}${stringified ? `?${stringified}` : ""}`;
}
function read() {
return new URLSearchParams(getRawParams());
}
function updateState(params) {
const unusedKeys = new Set(Object.keys(state));
for (const key of params.keys()) {
const paramsForKey = params.getAll(key);
state[key] = paramsForKey.length > 1 ? paramsForKey : params.get(key) || "";
unusedKeys.delete(key);
}
Array.from(unusedKeys).forEach((key) => delete state[key]);
}
const { pause, resume } = pausableWatch(
state,
() => {
const params = new URLSearchParams("");
Object.keys(state).forEach((key) => {
const mapEntry = state[key];
if (Array.isArray(mapEntry))
mapEntry.forEach((value) => params.append(key, value));
else if (removeNullishValues && mapEntry == null)
params.delete(key);
else if (removeFalsyValues && !mapEntry)
params.delete(key);
else
params.set(key, mapEntry);
});
write(params);
},
{ deep: true }
);
function write(params, shouldUpdate) {
pause();
if (shouldUpdate)
updateState(params);
window.history.replaceState(
window.history.state,
window.document.title,
window.location.pathname + constructQuery(params)
);
resume();
}
function onChanged() {
if (!enableWrite)
return;
write(read(), true);
}
useEventListener(window, "popstate", onChanged, false);
if (mode !== "history")
useEventListener(window, "hashchange", onChanged, false);
const initial = read();
if (initial.keys().next().value)
updateState(initial);
else
Object.assign(state, initialValue);
return state;
}
function useUserMedia(options = {}) {
var _a, _b;
const enabled = ref((_a = options.enabled) != null ? _a : false);
const autoSwitch = ref((_b = options.autoSwitch) != null ? _b : true);
const constraints = ref(options.constraints);
const { navigator = defaultNavigator } = options;
const isSupported = useSupported(() => {
var _a2;
return (_a2 = navigator == null ? void 0 : navigator.mediaDevices) == null ? void 0 : _a2.getUserMedia;
});
const stream = shallowRef();
function getDeviceOptions(type) {
switch (type) {
case "video": {
if (constraints.value)
return constraints.value.video || false;
break;
}
case "audio": {
if (constraints.value)
return constraints.value.audio || false;
break;
}
}
}
async function _start() {
if (!isSupported.value || stream.value)
return;
stream.value = await navigator.mediaDevices.getUserMedia({
video: getDeviceOptions("video"),
audio: getDeviceOptions("audio")
});
return stream.value;
}
function _stop() {
var _a2;
(_a2 = stream.value) == null ? void 0 : _a2.getTracks().forEach((t) => t.stop());
stream.value = void 0;
}
function stop() {
_stop();
enabled.value = false;
}
async function start() {
await _start();
if (stream.value)
enabled.value = true;
return stream.value;
}
async function restart() {
_stop();
return await start();
}
watch(
enabled,
(v) => {
if (v)
_start();
else
_stop();
},
{ immediate: true }
);
watch(
constraints,
() => {
if (autoSwitch.value && stream.value)
restart();
},
{ immediate: true }
);
return {
isSupported,
stream,
start,
stop,
restart,
constraints,
enabled,
autoSwitch
};
}
function useVModel(props, key, emit, options = {}) {
var _a, _b, _c, _d, _e;
const {
clone = false,
passive = false,
eventName,
deep = false,
defaultValue,
shouldEmit
} = options;
const vm = getCurrentInstance();
const _emit = emit || (vm == null ? void 0 : vm.emit) || ((_a = vm == null ? void 0 : vm.$emit) == null ? void 0 : _a.bind(vm)) || ((_c = (_b = vm == null ? void 0 : vm.proxy) == null ? void 0 : _b.$emit) == null ? void 0 : _c.bind(vm == null ? void 0 : vm.proxy));
let event = eventName;
if (!key) {
if (isVue2) {
const modelOptions = (_e = (_d = vm == null ? void 0 : vm.proxy) == null ? void 0 : _d.$options) == null ? void 0 : _e.model;
key = (modelOptions == null ? void 0 : modelOptions.value) || "value";
if (!eventName)
event = (modelOptions == null ? void 0 : modelOptions.event) || "input";
} else {
key = "modelValue";
}
}
2 years ago
event = event || `update:${key.toString()}`;
2 years ago
const cloneFn = (val) => !clone ? val : typeof clone === "function" ? clone(val) : cloneFnJSON(val);
const getValue = () => isDef(props[key]) ? cloneFn(props[key]) : defaultValue;
const triggerEmit = (value) => {
if (shouldEmit) {
if (shouldEmit(value))
_emit(event, value);
} else {
_emit(event, value);
}
};
if (passive) {
const initialValue = getValue();
const proxy = ref(initialValue);
2 years ago
let isUpdating = false;
2 years ago
watch(
() => props[key],
2 years ago
(v) => {
if (!isUpdating) {
isUpdating = true;
proxy.value = cloneFn(v);
nextTick(() => isUpdating = false);
}
}
2 years ago
);
watch(
proxy,
(v) => {
2 years ago
if (!isUpdating && (v !== props[key] || deep))
2 years ago
triggerEmit(v);
},
{ deep }
);
return proxy;
} else {
return computed({
get() {
return getValue();
},
set(value) {
triggerEmit(value);
}
});
}
}
function useVModels(props, emit, options = {}) {
const ret = {};
2 years ago
for (const key in props) {
ret[key] = useVModel(
props,
key,
emit,
options
);
}
2 years ago
return ret;
}
function useVibrate(options) {
const {
pattern = [],
interval = 0,
navigator = defaultNavigator
} = options || {};
const isSupported = useSupported(() => typeof navigator !== "undefined" && "vibrate" in navigator);
const patternRef = toRef(pattern);
let intervalControls;
const vibrate = (pattern2 = patternRef.value) => {
if (isSupported.value)
navigator.vibrate(pattern2);
};
const stop = () => {
if (isSupported.value)
navigator.vibrate(0);
intervalControls == null ? void 0 : intervalControls.pause();
};
if (interval > 0) {
intervalControls = useIntervalFn(
vibrate,
interval,
{
immediate: false,
immediateCallback: false
}
);
}
return {
isSupported,
pattern,
intervalControls,
vibrate,
stop
};
}
function useVirtualList(list, options) {
const { containerStyle, wrapperProps, scrollTo, calculateRange, currentList, containerRef } = "itemHeight" in options ? useVerticalVirtualList(options, list) : useHorizontalVirtualList(options, list);
return {
list: currentList,
scrollTo,
containerProps: {
ref: containerRef,
onScroll: () => {
calculateRange();
},
style: containerStyle
},
wrapperProps
};
}
function useVirtualListResources(list) {
const containerRef = ref(null);
const size = useElementSize(containerRef);
const currentList = ref([]);
const source = shallowRef(list);
const state = ref({ start: 0, end: 10 });
return { state, source, currentList, size, containerRef };
}
function createGetViewCapacity(state, source, itemSize) {
return (containerSize) => {
if (typeof itemSize === "number")
return Math.ceil(containerSize / itemSize);
const { start = 0 } = state.value;
let sum = 0;
let capacity = 0;
for (let i = start; i < source.value.length; i++) {
const size = itemSize(i);
sum += size;
capacity = i;
if (sum > containerSize)
break;
}
return capacity - start;
};
}
function createGetOffset(source, itemSize) {
return (scrollDirection) => {
if (typeof itemSize === "number")
return Math.floor(scrollDirection / itemSize) + 1;
let sum = 0;
let offset = 0;
for (let i = 0; i < source.value.length; i++) {
const size = itemSize(i);
sum += size;
if (sum >= scrollDirection) {
offset = i;
break;
}
}
return offset + 1;
};
}
function createCalculateRange(type, overscan, getOffset, getViewCapacity, { containerRef, state, currentList, source }) {
return () => {
const element = containerRef.value;
if (element) {
const offset = getOffset(type === "vertical" ? element.scrollTop : element.scrollLeft);
const viewCapacity = getViewCapacity(type === "vertical" ? element.clientHeight : element.clientWidth);
const from = offset - overscan;
const to = offset + viewCapacity + overscan;
state.value = {
start: from < 0 ? 0 : from,
end: to > source.value.length ? source.value.length : to
};
currentList.value = source.value.slice(state.value.start, state.value.end).map((ele, index) => ({
data: ele,
index: index + state.value.start
}));
}
};
}
function createGetDistance(itemSize, source) {
return (index) => {
if (typeof itemSize === "number") {
const size2 = index * itemSize;
return size2;
}
const size = source.value.slice(0, index).reduce((sum, _, i) => sum + itemSize(i), 0);
return size;
};
}
function useWatchForSizes(size, list, calculateRange) {
watch([size.width, size.height, list], () => {
calculateRange();
});
}
function createComputedTotalSize(itemSize, source) {
return computed(() => {
if (typeof itemSize === "number")
return source.value.length * itemSize;
return source.value.reduce((sum, _, index) => sum + itemSize(index), 0);
});
}
const scrollToDictionaryForElementScrollKey = {
horizontal: "scrollLeft",
vertical: "scrollTop"
};
function createScrollTo(type, calculateRange, getDistance, containerRef) {
return (index) => {
if (containerRef.value) {
containerRef.value[scrollToDictionaryForElementScrollKey[type]] = getDistance(index);
calculateRange();
}
};
}
function useHorizontalVirtualList(options, list) {
const resources = useVirtualListResources(list);
const { state, source, currentList, size, containerRef } = resources;
const containerStyle = { overflowX: "auto" };
const { itemWidth, overscan = 5 } = options;
const getViewCapacity = createGetViewCapacity(state, source, itemWidth);
const getOffset = createGetOffset(source, itemWidth);
const calculateRange = createCalculateRange("horizontal", overscan, getOffset, getViewCapacity, resources);
const getDistanceLeft = createGetDistance(itemWidth, source);
const offsetLeft = computed(() => getDistanceLeft(state.value.start));
const totalWidth = createComputedTotalSize(itemWidth, source);
useWatchForSizes(size, list, calculateRange);
const scrollTo = createScrollTo("horizontal", calculateRange, getDistanceLeft, containerRef);
const wrapperProps = computed(() => {
return {
style: {
height: "100%",
width: `${totalWidth.value - offsetLeft.value}px`,
marginLeft: `${offsetLeft.value}px`,
display: "flex"
}
};
});
return {
scrollTo,
calculateRange,
wrapperProps,
containerStyle,
currentList,
containerRef
};
}
function useVerticalVirtualList(options, list) {
const resources = useVirtualListResources(list);
const { state, source, currentList, size, containerRef } = resources;
const containerStyle = { overflowY: "auto" };
const { itemHeight, overscan = 5 } = options;
const getViewCapacity = createGetViewCapacity(state, source, itemHeight);
const getOffset = createGetOffset(source, itemHeight);
const calculateRange = createCalculateRange("vertical", overscan, getOffset, getViewCapacity, resources);
const getDistanceTop = createGetDistance(itemHeight, source);
const offsetTop = computed(() => getDistanceTop(state.value.start));
const totalHeight = createComputedTotalSize(itemHeight, source);
useWatchForSizes(size, list, calculateRange);
const scrollTo = createScrollTo("vertical", calculateRange, getDistanceTop, containerRef);
const wrapperProps = computed(() => {
return {
style: {
width: "100%",
height: `${totalHeight.value - offsetTop.value}px`,
marginTop: `${offsetTop.value}px`
}
};
});
return {
calculateRange,
scrollTo,
containerStyle,
wrapperProps,
currentList,
containerRef
};
}
function useWakeLock(options = {}) {
const {
navigator = defaultNavigator,
document = defaultDocument
} = options;
let wakeLock;
const isSupported = useSupported(() => navigator && "wakeLock" in navigator);
const isActive = ref(false);
async function onVisibilityChange() {
if (!isSupported.value || !wakeLock)
return;
if (document && document.visibilityState === "visible")
wakeLock = await navigator.wakeLock.request("screen");
isActive.value = !wakeLock.released;
}
if (document)
useEventListener(document, "visibilitychange", onVisibilityChange, { passive: true });
async function request(type) {
if (!isSupported.value)
return;
wakeLock = await navigator.wakeLock.request(type);
isActive.value = !wakeLock.released;
}
async function release() {
if (!isSupported.value || !wakeLock)
return;
await wakeLock.release();
isActive.value = !wakeLock.released;
wakeLock = null;
}
return {
isSupported,
isActive,
request,
release
};
}
2 years ago
function useWebNotification(options = {}) {
2 years ago
const {
2 years ago
window = defaultWindow,
requestPermissions: _requestForPermissions = true
} = options;
const defaultWebNotificationOptions = options;
2 years ago
const isSupported = useSupported(() => !!window && "Notification" in window);
2 years ago
const permissionGranted = ref(isSupported.value && "permission" in Notification && Notification.permission === "granted");
2 years ago
const notification = ref(null);
2 years ago
const ensurePermissions = async () => {
2 years ago
if (!isSupported.value)
return;
2 years ago
if (!permissionGranted.value && Notification.permission !== "denied") {
const result = await Notification.requestPermission();
if (result === "granted")
permissionGranted.value = true;
}
return permissionGranted.value;
2 years ago
};
const { on: onClick, trigger: clickTrigger } = createEventHook();
const { on: onShow, trigger: showTrigger } = createEventHook();
const { on: onError, trigger: errorTrigger } = createEventHook();
const { on: onClose, trigger: closeTrigger } = createEventHook();
const show = async (overrides) => {
2 years ago
if (!isSupported.value || !permissionGranted.value)
2 years ago
return;
2 years ago
const options2 = Object.assign({}, defaultWebNotificationOptions, overrides);
notification.value = new Notification(options2.title || "", options2);
2 years ago
notification.value.onclick = clickTrigger;
notification.value.onshow = showTrigger;
notification.value.onerror = errorTrigger;
notification.value.onclose = closeTrigger;
return notification.value;
};
const close = () => {
if (notification.value)
notification.value.close();
notification.value = null;
};
2 years ago
if (_requestForPermissions)
tryOnMounted(ensurePermissions);
2 years ago
tryOnScopeDispose(close);
if (isSupported.value && window) {
const document = window.document;
useEventListener(document, "visibilitychange", (e) => {
e.preventDefault();
if (document.visibilityState === "visible") {
close();
}
});
}
return {
isSupported,
notification,
2 years ago
ensurePermissions,
permissionGranted,
2 years ago
show,
close,
onClick,
onShow,
onError,
onClose
};
}
const DEFAULT_PING_MESSAGE = "ping";
function resolveNestedOptions(options) {
if (options === true)
return {};
return options;
}
function useWebSocket(url, options = {}) {
const {
onConnected,
onDisconnected,
onError,
onMessage,
immediate = true,
autoClose = true,
protocols = []
} = options;
const data = ref(null);
const status = ref("CLOSED");
const wsRef = ref();
const urlRef = toRef(url);
let heartbeatPause;
let heartbeatResume;
let explicitlyClosed = false;
let retried = 0;
let bufferedData = [];
let pongTimeoutWait;
const _sendBuffer = () => {
if (bufferedData.length && wsRef.value && status.value === "OPEN") {
for (const buffer of bufferedData)
wsRef.value.send(buffer);
bufferedData = [];
}
};
const resetHeartbeat = () => {
clearTimeout(pongTimeoutWait);
pongTimeoutWait = void 0;
};
2 years ago
const close = (code = 1e3, reason) => {
if (!isClient || !wsRef.value)
return;
explicitlyClosed = true;
resetHeartbeat();
heartbeatPause == null ? void 0 : heartbeatPause();
wsRef.value.close(code, reason);
};
2 years ago
const send = (data2, useBuffer = true) => {
if (!wsRef.value || status.value !== "OPEN") {
if (useBuffer)
bufferedData.push(data2);
return false;
}
_sendBuffer();
wsRef.value.send(data2);
return true;
};
const _init = () => {
if (explicitlyClosed || typeof urlRef.value === "undefined")
return;
const ws = new WebSocket(urlRef.value, protocols);
wsRef.value = ws;
status.value = "CONNECTING";
ws.onopen = () => {
status.value = "OPEN";
onConnected == null ? void 0 : onConnected(ws);
heartbeatResume == null ? void 0 : heartbeatResume();
_sendBuffer();
};
ws.onclose = (ev) => {
status.value = "CLOSED";
wsRef.value = void 0;
onDisconnected == null ? void 0 : onDisconnected(ws, ev);
if (!explicitlyClosed && options.autoReconnect) {
const {
retries = -1,
delay = 1e3,
onFailed
} = resolveNestedOptions(options.autoReconnect);
retried += 1;
if (typeof retries === "number" && (retries < 0 || retried < retries))
setTimeout(_init, delay);
else if (typeof retries === "function" && retries())
setTimeout(_init, delay);
else
onFailed == null ? void 0 : onFailed();
}
};
ws.onerror = (e) => {
onError == null ? void 0 : onError(ws, e);
};
ws.onmessage = (e) => {
if (options.heartbeat) {
resetHeartbeat();
const {
message = DEFAULT_PING_MESSAGE
} = resolveNestedOptions(options.heartbeat);
if (e.data === message)
return;
}
data.value = e.data;
onMessage == null ? void 0 : onMessage(ws, e);
};
};
if (options.heartbeat) {
const {
message = DEFAULT_PING_MESSAGE,
interval = 1e3,
pongTimeout = 1e3
} = resolveNestedOptions(options.heartbeat);
const { pause, resume } = useIntervalFn(
() => {
send(message, false);
if (pongTimeoutWait != null)
return;
pongTimeoutWait = setTimeout(() => {
close();
2 years ago
explicitlyClosed = false;
2 years ago
}, pongTimeout);
},
interval,
{ immediate: false }
);
heartbeatPause = pause;
heartbeatResume = resume;
}
if (autoClose) {
2 years ago
useEventListener("beforeunload", () => close());
2 years ago
tryOnScopeDispose(close);
}
const open = () => {
2 years ago
if (!isClient)
return;
2 years ago
close();
explicitlyClosed = false;
retried = 0;
_init();
};
if (immediate)
watch(urlRef, open, { immediate: true });
return {
data,
status,
close,
send,
open,
ws: wsRef
};
}
function useWebWorker(arg0, workerOptions, options) {
const {
window = defaultWindow
} = options != null ? options : {};
const data = ref(null);
const worker = shallowRef();
2 years ago
const post = (...args) => {
2 years ago
if (!worker.value)
return;
2 years ago
worker.value.postMessage(...args);
2 years ago
};
const terminate = function terminate2() {
if (!worker.value)
return;
worker.value.terminate();
};
if (window) {
if (typeof arg0 === "string")
worker.value = new Worker(arg0, workerOptions);
else if (typeof arg0 === "function")
worker.value = arg0();
else
worker.value = arg0;
worker.value.onmessage = (e) => {
data.value = e.data;
};
tryOnScopeDispose(() => {
if (worker.value)
worker.value.terminate();
});
}
return {
data,
post,
terminate,
worker
};
}
function jobRunner(userFunc) {
return (e) => {
const userFuncArgs = e.data[0];
return Promise.resolve(userFunc.apply(void 0, userFuncArgs)).then((result) => {
postMessage(["SUCCESS", result]);
}).catch((error) => {
postMessage(["ERROR", error]);
});
};
}
function depsParser(deps) {
if (deps.length === 0)
return "";
const depsString = deps.map((dep) => `'${dep}'`).toString();
return `importScripts(${depsString})`;
}
function createWorkerBlobUrl(fn, deps) {
const blobCode = `${depsParser(deps)}; onmessage=(${jobRunner})(${fn})`;
const blob = new Blob([blobCode], { type: "text/javascript" });
const url = URL.createObjectURL(blob);
return url;
}
function useWebWorkerFn(fn, options = {}) {
const {
dependencies = [],
timeout,
window = defaultWindow
} = options;
const worker = ref();
const workerStatus = ref("PENDING");
const promise = ref({});
const timeoutId = ref();
const workerTerminate = (status = "PENDING") => {
if (worker.value && worker.value._url && window) {
worker.value.terminate();
URL.revokeObjectURL(worker.value._url);
promise.value = {};
worker.value = void 0;
window.clearTimeout(timeoutId.value);
workerStatus.value = status;
}
};
workerTerminate();
tryOnScopeDispose(workerTerminate);
const generateWorker = () => {
const blobUrl = createWorkerBlobUrl(fn, dependencies);
const newWorker = new Worker(blobUrl);
newWorker._url = blobUrl;
newWorker.onmessage = (e) => {
const { resolve = () => {
}, reject = () => {
} } = promise.value;
const [status, result] = e.data;
switch (status) {
case "SUCCESS":
resolve(result);
workerTerminate(status);
break;
default:
reject(result);
workerTerminate("ERROR");
break;
}
};
newWorker.onerror = (e) => {
const { reject = () => {
} } = promise.value;
2 years ago
e.preventDefault();
2 years ago
reject(e);
workerTerminate("ERROR");
};
if (timeout) {
timeoutId.value = setTimeout(
() => workerTerminate("TIMEOUT_EXPIRED"),
timeout
);
}
return newWorker;
};
const callWorker = (...fnArgs) => new Promise((resolve, reject) => {
promise.value = {
resolve,
reject
};
worker.value && worker.value.postMessage([[...fnArgs]]);
workerStatus.value = "RUNNING";
});
const workerFn = (...fnArgs) => {
if (workerStatus.value === "RUNNING") {
console.error(
"[useWebWorkerFn] You can only run one instance of the worker at a time."
);
return Promise.reject();
}
worker.value = generateWorker();
return callWorker(...fnArgs);
};
return {
workerFn,
workerStatus,
workerTerminate
};
}
2 years ago
function useWindowFocus(options = {}) {
const { window = defaultWindow } = options;
2 years ago
if (!window)
return ref(false);
const focused = ref(window.document.hasFocus());
useEventListener(window, "blur", () => {
focused.value = false;
});
useEventListener(window, "focus", () => {
focused.value = true;
});
return focused;
}
2 years ago
function useWindowScroll(options = {}) {
const { window = defaultWindow } = options;
2 years ago
if (!window) {
return {
x: ref(0),
y: ref(0)
};
}
const x = ref(window.scrollX);
const y = ref(window.scrollY);
useEventListener(
window,
"scroll",
() => {
x.value = window.scrollX;
y.value = window.scrollY;
},
{
capture: false,
passive: true
}
);
return { x, y };
}
function useWindowSize(options = {}) {
const {
window = defaultWindow,
2 years ago
initialWidth = Number.POSITIVE_INFINITY,
initialHeight = Number.POSITIVE_INFINITY,
2 years ago
listenOrientation = true,
includeScrollbar = true
} = options;
const width = ref(initialWidth);
const height = ref(initialHeight);
const update = () => {
if (window) {
if (includeScrollbar) {
width.value = window.innerWidth;
height.value = window.innerHeight;
} else {
width.value = window.document.documentElement.clientWidth;
height.value = window.document.documentElement.clientHeight;
}
}
};
update();
tryOnMounted(update);
useEventListener("resize", update, { passive: true });
if (listenOrientation) {
const matches = useMediaQuery("(orientation: portrait)");
watch(matches, () => update());
}
return { width, height };
}
2 years ago
export { DefaultMagicKeysAliasMap, StorageSerializers, TransitionPresets, computedAsync as asyncComputed, breakpointsAntDesign, breakpointsBootstrapV5, breakpointsMasterCss, breakpointsPrimeFlex, breakpointsQuasar, breakpointsSematic, breakpointsTailwind, breakpointsVuetify, cloneFnJSON, computedAsync, computedInject, createFetch, createReusableTemplate, createTemplatePromise, createUnrefFn, customStorageEventName, defaultDocument, defaultLocation, defaultNavigator, defaultWindow, executeTransition, formatTimeAgo, getSSRHandler, mapGamepadToXbox360Controller, onClickOutside, onKeyDown, onKeyPressed, onKeyStroke, onKeyUp, onLongPress, onStartTyping, setSSRHandler, templateRef, unrefElement, useActiveElement, useAnimate, useAsyncQueue, useAsyncState, useBase64, useBattery, useBluetooth, useBreakpoints, useBroadcastChannel, useBrowserLocation, useCached, useClipboard, useCloned, useColorMode, useConfirmDialog, useCssVar, useCurrentElement, useCycleList, useDark, useDebouncedRefHistory, useDeviceMotion, useDeviceOrientation, useDevicePixelRatio, useDevicesList, useDisplayMedia, useDocumentVisibility, useDraggable, useDropZone, useElementBounding, useElementByPoint, useElementHover, useElementSize, useElementVisibility, useEventBus, useEventListener, useEventSource, useEyeDropper, useFavicon, useFetch, useFileDialog, useFileSystemAccess, useFocus, useFocusWithin, useFps, useFullscreen, useGamepad, useGeolocation, useIdle, useImage, useInfiniteScroll, useIntersectionObserver, useKeyModifier, useLocalStorage, useMagicKeys, useManualRefHistory, useMediaControls, useMediaQuery, useMemoize, useMemory, useMounted, useMouse, useMouseInElement, useMousePressed, useMutationObserver, useNavigatorLanguage, useNetwork, useNow, useObjectUrl, useOffsetPagination, useOnline, usePageLeave, useParallax, useParentElement, usePerformanceObserver, usePermission, usePointer, usePointerLock, usePointerSwipe, usePreferredColorScheme, usePreferredContrast, usePreferredDark, usePreferredLanguages, usePreferredReducedMotion, usePrevious, useRafFn, useRefHistory, useResizeObserver, useScreenOrientation, useScreenSafeArea, useScriptTag, useScroll, useScrollLock, useSessionStorage, useShare, useSorted, useSpeechRecognition, useSpeechSynthesis, useStepper, useStorage, useStorageAsync, useStyleTag, useSupported, useSwipe, useTemplateRefsList, useTextDirection, useTextSelection, useTextareaAutosize, useThrottledRefHistory, useTimeAgo, useTimeoutPoll, useTimestamp, useTitle, useTransition, useUrlSearchParams, useUserMedia, useVModel, useVModels, useVibrate, useVirtualList, useWakeLock, useWebNotification, useWebSocket, useWebWorker, useWebWorkerFn, useWindowFocus, useWindowScroll, useWindowSize };