mirror of
				https://github.com/imezx/Warp.git
				synced 2025-10-31 10:19:17 +00:00 
			
		
		
		
	
		
			
	
	
		
			7582 lines
		
	
	
	
		
			232 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			7582 lines
		
	
	
	
		
			232 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | var VueDemi = (function (VueDemi, Vue, VueCompositionAPI) { | ||
|  |   if (VueDemi.install) { | ||
|  |     return VueDemi | ||
|  |   } | ||
|  |   if (!Vue) { | ||
|  |     console.error('[vue-demi] no Vue instance found, please be sure to import `vue` before `vue-demi`.') | ||
|  |     return VueDemi | ||
|  |   } | ||
|  | 
 | ||
|  |   // Vue 2.7
 | ||
|  |   if (Vue.version.slice(0, 4) === '2.7.') { | ||
|  |     for (var key in Vue) { | ||
|  |       VueDemi[key] = Vue[key] | ||
|  |     } | ||
|  |     VueDemi.isVue2 = true | ||
|  |     VueDemi.isVue3 = false | ||
|  |     VueDemi.install = function () {} | ||
|  |     VueDemi.Vue = Vue | ||
|  |     VueDemi.Vue2 = Vue | ||
|  |     VueDemi.version = Vue.version | ||
|  |     VueDemi.warn = Vue.util.warn | ||
|  |     VueDemi.hasInjectionContext = () => !!VueDemi.getCurrentInstance() | ||
|  |     function createApp(rootComponent, rootProps) { | ||
|  |       var vm | ||
|  |       var provide = {} | ||
|  |       var app = { | ||
|  |         config: Vue.config, | ||
|  |         use: Vue.use.bind(Vue), | ||
|  |         mixin: Vue.mixin.bind(Vue), | ||
|  |         component: Vue.component.bind(Vue), | ||
|  |         provide: function (key, value) { | ||
|  |           provide[key] = value | ||
|  |           return this | ||
|  |         }, | ||
|  |         directive: function (name, dir) { | ||
|  |           if (dir) { | ||
|  |             Vue.directive(name, dir) | ||
|  |             return app | ||
|  |           } else { | ||
|  |             return Vue.directive(name) | ||
|  |           } | ||
|  |         }, | ||
|  |         mount: function (el, hydrating) { | ||
|  |           if (!vm) { | ||
|  |             vm = new Vue(Object.assign({ propsData: rootProps }, rootComponent, { provide: Object.assign(provide, rootComponent.provide) })) | ||
|  |             vm.$mount(el, hydrating) | ||
|  |             return vm | ||
|  |           } else { | ||
|  |             return vm | ||
|  |           } | ||
|  |         }, | ||
|  |         unmount: function () { | ||
|  |           if (vm) { | ||
|  |             vm.$destroy() | ||
|  |             vm = undefined | ||
|  |           } | ||
|  |         }, | ||
|  |       } | ||
|  |       return app | ||
|  |     } | ||
|  |     VueDemi.createApp = createApp | ||
|  |   } | ||
|  |   // Vue 2.6.x
 | ||
|  |   else if (Vue.version.slice(0, 2) === '2.') { | ||
|  |     if (VueCompositionAPI) { | ||
|  |       for (var key in VueCompositionAPI) { | ||
|  |         VueDemi[key] = VueCompositionAPI[key] | ||
|  |       } | ||
|  |       VueDemi.isVue2 = true | ||
|  |       VueDemi.isVue3 = false | ||
|  |       VueDemi.install = function () {} | ||
|  |       VueDemi.Vue = Vue | ||
|  |       VueDemi.Vue2 = Vue | ||
|  |       VueDemi.version = Vue.version | ||
|  |       VueDemi.hasInjectionContext = () => !!VueDemi.getCurrentInstance() | ||
|  |     } else { | ||
|  |       console.error('[vue-demi] no VueCompositionAPI instance found, please be sure to import `@vue/composition-api` before `vue-demi`.') | ||
|  |     } | ||
|  |   } | ||
|  |   // Vue 3
 | ||
|  |   else if (Vue.version.slice(0, 2) === '3.') { | ||
|  |     for (var key in Vue) { | ||
|  |       VueDemi[key] = Vue[key] | ||
|  |     } | ||
|  |     VueDemi.isVue2 = false | ||
|  |     VueDemi.isVue3 = true | ||
|  |     VueDemi.install = function () {} | ||
|  |     VueDemi.Vue = Vue | ||
|  |     VueDemi.Vue2 = undefined | ||
|  |     VueDemi.version = Vue.version | ||
|  |     VueDemi.set = function (target, key, val) { | ||
|  |       if (Array.isArray(target)) { | ||
|  |         target.length = Math.max(target.length, key) | ||
|  |         target.splice(key, 1, val) | ||
|  |         return val | ||
|  |       } | ||
|  |       target[key] = val | ||
|  |       return val | ||
|  |     } | ||
|  |     VueDemi.del = function (target, key) { | ||
|  |       if (Array.isArray(target)) { | ||
|  |         target.splice(key, 1) | ||
|  |         return | ||
|  |       } | ||
|  |       delete target[key] | ||
|  |     } | ||
|  |   } else { | ||
|  |     console.error('[vue-demi] Vue version ' + Vue.version + ' is unsupported.') | ||
|  |   } | ||
|  |   return VueDemi | ||
|  | })( | ||
|  |   (this.VueDemi = this.VueDemi || (typeof VueDemi !== 'undefined' ? VueDemi : {})), | ||
|  |   this.Vue || (typeof Vue !== 'undefined' ? Vue : undefined), | ||
|  |   this.VueCompositionAPI || (typeof VueCompositionAPI !== 'undefined' ? VueCompositionAPI : undefined) | ||
|  | ); | ||
|  | ; | ||
|  | ;(function (exports, shared, vueDemi) { | ||
|  |   'use strict'; | ||
|  | 
 | ||
|  |   function computedAsync(evaluationCallback, initialState, optionsOrRef) { | ||
|  |     let options; | ||
|  |     if (vueDemi.isRef(optionsOrRef)) { | ||
|  |       options = { | ||
|  |         evaluating: optionsOrRef | ||
|  |       }; | ||
|  |     } else { | ||
|  |       options = optionsOrRef || {}; | ||
|  |     } | ||
|  |     const { | ||
|  |       lazy = false, | ||
|  |       evaluating = void 0, | ||
|  |       shallow = true, | ||
|  |       onError = shared.noop | ||
|  |     } = options; | ||
|  |     const started = vueDemi.ref(!lazy); | ||
|  |     const current = shallow ? vueDemi.shallowRef(initialState) : vueDemi.ref(initialState); | ||
|  |     let counter = 0; | ||
|  |     vueDemi.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 vueDemi.computed(() => { | ||
|  |         started.value = true; | ||
|  |         return current.value; | ||
|  |       }); | ||
|  |     } else { | ||
|  |       return current; | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   function computedInject(key, options, defaultSource, treatDefaultAsFactory) { | ||
|  |     let source = vueDemi.inject(key); | ||
|  |     if (defaultSource) | ||
|  |       source = vueDemi.inject(key, defaultSource); | ||
|  |     if (treatDefaultAsFactory) | ||
|  |       source = vueDemi.inject(key, defaultSource, treatDefaultAsFactory); | ||
|  |     if (typeof options === "function") { | ||
|  |       return vueDemi.computed((ctx) => options(source, ctx)); | ||
|  |     } else { | ||
|  |       return vueDemi.computed({ | ||
|  |         get: (ctx) => options.get(source, ctx), | ||
|  |         set: options.set | ||
|  |       }); | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   function createReusableTemplate(options = {}) { | ||
|  |     if (!vueDemi.isVue3 && !vueDemi.version.startsWith("2.7.")) { | ||
|  |       if (process.env.NODE_ENV !== "production") | ||
|  |         throw new Error("[VueUse] createReusableTemplate only works in Vue 2.7 or above."); | ||
|  |       return; | ||
|  |     } | ||
|  |     const { | ||
|  |       inheritAttrs = true | ||
|  |     } = options; | ||
|  |     const render = vueDemi.shallowRef(); | ||
|  |     const define = /* #__PURE__ */ vueDemi.defineComponent({ | ||
|  |       setup(_, { slots }) { | ||
|  |         return () => { | ||
|  |           render.value = slots.default; | ||
|  |         }; | ||
|  |       } | ||
|  |     }); | ||
|  |     const reuse = /* #__PURE__ */ vueDemi.defineComponent({ | ||
|  |       inheritAttrs, | ||
|  |       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"); | ||
|  |           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; | ||
|  |         }; | ||
|  |       } | ||
|  |     }); | ||
|  |     return shared.makeDestructurable( | ||
|  |       { define, reuse }, | ||
|  |       [define, reuse] | ||
|  |     ); | ||
|  |   } | ||
|  |   function keysToCamelKebabCase(obj) { | ||
|  |     const newObj = {}; | ||
|  |     for (const key in obj) | ||
|  |       newObj[shared.camelize(key)] = obj[key]; | ||
|  |     return newObj; | ||
|  |   } | ||
|  | 
 | ||
|  |   function createTemplatePromise(options = {}) { | ||
|  |     if (!vueDemi.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 = vueDemi.ref([]); | ||
|  |     function create(...args) { | ||
|  |       const props = vueDemi.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__ */ vueDemi.defineComponent((_, { slots }) => { | ||
|  |       const renderList = () => instances.value.map((props) => { | ||
|  |         var _a; | ||
|  |         return vueDemi.h(vueDemi.Fragment, { key: props.key }, (_a = slots.default) == null ? void 0 : _a.call(slots, props)); | ||
|  |       }); | ||
|  |       if (options.transition) | ||
|  |         return () => vueDemi.h(vueDemi.TransitionGroup, options.transition, renderList); | ||
|  |       return renderList; | ||
|  |     }); | ||
|  |     component.start = start; | ||
|  |     return component; | ||
|  |   } | ||
|  | 
 | ||
|  |   function createUnrefFn(fn) { | ||
|  |     return function(...args) { | ||
|  |       return fn.apply(this, args.map((i) => shared.toValue(i))); | ||
|  |     }; | ||
|  |   } | ||
|  | 
 | ||
|  |   function unrefElement(elRef) { | ||
|  |     var _a; | ||
|  |     const plain = shared.toValue(elRef); | ||
|  |     return (_a = plain == null ? void 0 : plain.$el) != null ? _a : plain; | ||
|  |   } | ||
|  | 
 | ||
|  |   const defaultWindow = shared.isClient ? window : void 0; | ||
|  |   const defaultDocument = shared.isClient ? window.document : void 0; | ||
|  |   const defaultNavigator = shared.isClient ? window.navigator : void 0; | ||
|  |   const defaultLocation = shared.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 shared.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 = vueDemi.watch( | ||
|  |       () => [unrefElement(target), shared.toValue(options)], | ||
|  |       ([el, options2]) => { | ||
|  |         cleanup(); | ||
|  |         if (!el) | ||
|  |           return; | ||
|  |         const optionsClone = shared.isObject(options2) ? { ...options2 } : options2; | ||
|  |         cleanups.push( | ||
|  |           ...events.flatMap((event) => { | ||
|  |             return listeners.map((listener) => register(el, event, listener, optionsClone)); | ||
|  |           }) | ||
|  |         ); | ||
|  |       }, | ||
|  |       { immediate: true, flush: "post" } | ||
|  |     ); | ||
|  |     const stop = () => { | ||
|  |       stopWatch(); | ||
|  |       cleanup(); | ||
|  |     }; | ||
|  |     shared.tryOnScopeDispose(stop); | ||
|  |     return stop; | ||
|  |   } | ||
|  | 
 | ||
|  |   let _iOSWorkaround = false; | ||
|  |   function onClickOutside(target, handler, options = {}) { | ||
|  |     const { window = defaultWindow, ignore = [], capture = true, detectIframe = false } = options; | ||
|  |     if (!window) | ||
|  |       return shared.noop; | ||
|  |     if (shared.isIOS && !_iOSWorkaround) { | ||
|  |       _iOSWorkaround = true; | ||
|  |       Array.from(window.document.body.children).forEach((el) => el.addEventListener("click", shared.noop)); | ||
|  |       window.document.documentElement.addEventListener("click", shared.noop); | ||
|  |     } | ||
|  |     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); | ||
|  |         shouldListen = !shouldIgnore(e) && !!(el && !e.composedPath().includes(el)); | ||
|  |       }, { passive: true }), | ||
|  |       detectIframe && useEventListener(window, "blur", (event) => { | ||
|  |         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); | ||
|  |       }) | ||
|  |     ].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 && shared.toValue(dedupe)) | ||
|  |         return; | ||
|  |       if (predicate(e)) | ||
|  |         handler(e); | ||
|  |     }; | ||
|  |     return useEventListener(target, eventName, listener, passive); | ||
|  |   } | ||
|  |   function onKeyDown(key, handler, options = {}) { | ||
|  |     return onKeyStroke(key, handler, { ...options, eventName: "keydown" }); | ||
|  |   } | ||
|  |   function onKeyPressed(key, handler, options = {}) { | ||
|  |     return onKeyStroke(key, handler, { ...options, eventName: "keypress" }); | ||
|  |   } | ||
|  |   function onKeyUp(key, handler, options = {}) { | ||
|  |     return onKeyStroke(key, handler, { ...options, eventName: "keyup" }); | ||
|  |   } | ||
|  | 
 | ||
|  |   const DEFAULT_DELAY = 500; | ||
|  |   const DEFAULT_THRESHOLD = 10; | ||
|  |   function onLongPress(target, handler, options) { | ||
|  |     var _a, _b; | ||
|  |     const elementRef = vueDemi.computed(() => unrefElement(target)); | ||
|  |     let timeout; | ||
|  |     let posStart; | ||
|  |     function clear() { | ||
|  |       if (timeout) { | ||
|  |         clearTimeout(timeout); | ||
|  |         timeout = void 0; | ||
|  |       } | ||
|  |       posStart = 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(); | ||
|  |       posStart = { | ||
|  |         x: ev.x, | ||
|  |         y: ev.y | ||
|  |       }; | ||
|  |       timeout = setTimeout( | ||
|  |         () => handler(ev), | ||
|  |         (_d = options == null ? void 0 : options.delay) != null ? _d : DEFAULT_DELAY | ||
|  |       ); | ||
|  |     } | ||
|  |     function onMove(ev) { | ||
|  |       var _a2, _b2, _c, _d; | ||
|  |       if (((_a2 = options == null ? void 0 : options.modifiers) == null ? void 0 : _a2.self) && ev.target !== elementRef.value) | ||
|  |         return; | ||
|  |       if (!posStart || (options == null ? void 0 : options.distanceThreshold) === false) | ||
|  |         return; | ||
|  |       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(); | ||
|  |       const dx = ev.x - posStart.x; | ||
|  |       const dy = ev.y - posStart.y; | ||
|  |       const distance = Math.sqrt(dx * dx + dy * dy); | ||
|  |       if (distance >= ((_d = options == null ? void 0 : options.distanceThreshold) != null ? _d : DEFAULT_THRESHOLD)) | ||
|  |         clear(); | ||
|  |     } | ||
|  |     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 | ||
|  |     }; | ||
|  |     const cleanup = [ | ||
|  |       useEventListener(elementRef, "pointerdown", onDown, listenerOptions), | ||
|  |       useEventListener(elementRef, "pointermove", onMove, listenerOptions), | ||
|  |       useEventListener(elementRef, ["pointerup", "pointerleave"], clear, listenerOptions) | ||
|  |     ]; | ||
|  |     const stop = () => cleanup.forEach((fn) => fn()); | ||
|  |     return stop; | ||
|  |   } | ||
|  | 
 | ||
|  |   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 = vueDemi.getCurrentInstance(); | ||
|  |     let _trigger = () => { | ||
|  |     }; | ||
|  |     const element = vueDemi.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() { | ||
|  |         } | ||
|  |       }; | ||
|  |     }); | ||
|  |     shared.tryOnMounted(_trigger); | ||
|  |     vueDemi.onUpdated(_trigger); | ||
|  |     return element; | ||
|  |   } | ||
|  | 
 | ||
|  |   function useActiveElement(options = {}) { | ||
|  |     var _a; | ||
|  |     const { | ||
|  |       window = defaultWindow, | ||
|  |       deep = true | ||
|  |     } = options; | ||
|  |     const document = (_a = options.document) != null ? _a : window == null ? void 0 : window.document; | ||
|  |     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; | ||
|  |     }; | ||
|  |     const activeElement = shared.computedWithControl( | ||
|  |       () => null, | ||
|  |       () => getDeepActiveElement() | ||
|  |     ); | ||
|  |     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 = vueDemi.ref(false); | ||
|  |     if (vueDemi.getCurrentInstance()) { | ||
|  |       vueDemi.onMounted(() => { | ||
|  |         isMounted.value = true; | ||
|  |       }); | ||
|  |     } | ||
|  |     return isMounted; | ||
|  |   } | ||
|  | 
 | ||
|  |   function useSupported(callback) { | ||
|  |     const isMounted = useMounted(); | ||
|  |     return vueDemi.computed(() => { | ||
|  |       isMounted.value; | ||
|  |       return Boolean(callback()); | ||
|  |     }); | ||
|  |   } | ||
|  | 
 | ||
|  |   function useRafFn(fn, options = {}) { | ||
|  |     const { | ||
|  |       immediate = true, | ||
|  |       fpsLimit = void 0, | ||
|  |       window = defaultWindow | ||
|  |     } = options; | ||
|  |     const isActive = vueDemi.ref(false); | ||
|  |     const intervalLimit = fpsLimit ? 1e3 / fpsLimit : null; | ||
|  |     let previousFrameTimestamp = 0; | ||
|  |     let rafId = null; | ||
|  |     function loop(timestamp) { | ||
|  |       if (!isActive.value || !window) | ||
|  |         return; | ||
|  |       const delta = timestamp - (previousFrameTimestamp || timestamp); | ||
|  |       if (intervalLimit && delta < intervalLimit) { | ||
|  |         rafId = window.requestAnimationFrame(loop); | ||
|  |         return; | ||
|  |       } | ||
|  |       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(); | ||
|  |     shared.tryOnScopeDispose(pause); | ||
|  |     return { | ||
|  |       isActive: vueDemi.readonly(isActive), | ||
|  |       pause, | ||
|  |       resume | ||
|  |     }; | ||
|  |   } | ||
|  | 
 | ||
|  |   function useAnimate(target, keyframes, options) { | ||
|  |     let config; | ||
|  |     let animateOptions; | ||
|  |     if (shared.isObject(options)) { | ||
|  |       config = options; | ||
|  |       animateOptions = shared.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 = vueDemi.shallowRef(void 0); | ||
|  |     const store = vueDemi.shallowReactive({ | ||
|  |       startTime: null, | ||
|  |       currentTime: null, | ||
|  |       timeline: null, | ||
|  |       playbackRate: _playbackRate, | ||
|  |       pending: false, | ||
|  |       playState: immediate ? "idle" : "paused", | ||
|  |       replaceState: "active" | ||
|  |     }); | ||
|  |     const pending = vueDemi.computed(() => store.pending); | ||
|  |     const playState = vueDemi.computed(() => store.playState); | ||
|  |     const replaceState = vueDemi.computed(() => store.replaceState); | ||
|  |     const startTime = vueDemi.computed({ | ||
|  |       get() { | ||
|  |         return store.startTime; | ||
|  |       }, | ||
|  |       set(value) { | ||
|  |         store.startTime = value; | ||
|  |         if (animate.value) | ||
|  |           animate.value.startTime = value; | ||
|  |       } | ||
|  |     }); | ||
|  |     const currentTime = vueDemi.computed({ | ||
|  |       get() { | ||
|  |         return store.currentTime; | ||
|  |       }, | ||
|  |       set(value) { | ||
|  |         store.currentTime = value; | ||
|  |         if (animate.value) { | ||
|  |           animate.value.currentTime = value; | ||
|  |           syncResume(); | ||
|  |         } | ||
|  |       } | ||
|  |     }); | ||
|  |     const timeline = vueDemi.computed({ | ||
|  |       get() { | ||
|  |         return store.timeline; | ||
|  |       }, | ||
|  |       set(value) { | ||
|  |         store.timeline = value; | ||
|  |         if (animate.value) | ||
|  |           animate.value.timeline = value; | ||
|  |       } | ||
|  |     }); | ||
|  |     const playbackRate = vueDemi.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); | ||
|  |       } | ||
|  |     }; | ||
|  |     vueDemi.watch(() => unrefElement(target), (el) => { | ||
|  |       el && update(); | ||
|  |     }); | ||
|  |     vueDemi.watch(() => keyframes, (value) => { | ||
|  |       !animate.value && update(); | ||
|  |       if (!unrefElement(target) && animate.value) { | ||
|  |         animate.value.effect = new KeyframeEffect( | ||
|  |           unrefElement(target), | ||
|  |           shared.toValue(value), | ||
|  |           animateOptions | ||
|  |         ); | ||
|  |       } | ||
|  |     }, { deep: true }); | ||
|  |     shared.tryOnMounted(() => { | ||
|  |       vueDemi.nextTick(() => update(true)); | ||
|  |     }); | ||
|  |     shared.tryOnScopeDispose(cancel); | ||
|  |     function update(init) { | ||
|  |       const el = unrefElement(target); | ||
|  |       if (!isSupported.value || !el) | ||
|  |         return; | ||
|  |       animate.value = el.animate(shared.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); | ||
|  |     } | ||
|  |     useEventListener(animate, ["cancel", "finish", "remove"], syncPause); | ||
|  |     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 | ||
|  |     }; | ||
|  |   } | ||
|  | 
 | ||
|  |   function useAsyncQueue(tasks, options) { | ||
|  |     const { | ||
|  |       interrupt = true, | ||
|  |       onError = shared.noop, | ||
|  |       onFinished = shared.noop, | ||
|  |       signal | ||
|  |     } = options || {}; | ||
|  |     const promiseState = { | ||
|  |       aborted: "aborted", | ||
|  |       fulfilled: "fulfilled", | ||
|  |       pending: "pending", | ||
|  |       rejected: "rejected" | ||
|  |     }; | ||
|  |     const initialResult = Array.from(Array.from({ length: tasks.length }), () => ({ state: promiseState.pending, data: null })); | ||
|  |     const result = vueDemi.reactive(initialResult); | ||
|  |     const activeIndex = vueDemi.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; | ||
|  |         if (signal == null ? void 0 : signal.aborted) { | ||
|  |           updateResult(promiseState.aborted, new Error("aborted")); | ||
|  |           return; | ||
|  |         } | ||
|  |         if (((_a = result[activeIndex.value]) == null ? void 0 : _a.state) === promiseState.rejected && interrupt) { | ||
|  |           onFinished(); | ||
|  |           return; | ||
|  |         } | ||
|  |         const done = curr(prevRes).then((currentRes) => { | ||
|  |           updateResult(promiseState.fulfilled, currentRes); | ||
|  |           activeIndex.value === tasks.length - 1 && onFinished(); | ||
|  |           return currentRes; | ||
|  |         }); | ||
|  |         if (!signal) | ||
|  |           return done; | ||
|  |         return Promise.race([done, whenAborted(signal)]); | ||
|  |       }).catch((e) => { | ||
|  |         if (signal == null ? void 0 : signal.aborted) { | ||
|  |           updateResult(promiseState.aborted, e); | ||
|  |           return e; | ||
|  |         } | ||
|  |         updateResult(promiseState.rejected, e); | ||
|  |         onError(); | ||
|  |         return e; | ||
|  |       }); | ||
|  |     }, Promise.resolve()); | ||
|  |     return { | ||
|  |       activeIndex, | ||
|  |       result | ||
|  |     }; | ||
|  |   } | ||
|  |   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 }); | ||
|  |     }); | ||
|  |   } | ||
|  | 
 | ||
|  |   function useAsyncState(promise, initialState, options) { | ||
|  |     const { | ||
|  |       immediate = true, | ||
|  |       delay = 0, | ||
|  |       onError = shared.noop, | ||
|  |       onSuccess = shared.noop, | ||
|  |       resetOnExecute = true, | ||
|  |       shallow = true, | ||
|  |       throwError | ||
|  |     } = options != null ? options : {}; | ||
|  |     const state = shallow ? vueDemi.shallowRef(initialState) : vueDemi.ref(initialState); | ||
|  |     const isReady = vueDemi.ref(false); | ||
|  |     const isLoading = vueDemi.ref(false); | ||
|  |     const error = vueDemi.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 shared.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) => { | ||
|  |         shared.until(isLoading).toBe(false).then(() => resolve(shell)).catch(reject); | ||
|  |       }); | ||
|  |     } | ||
|  |     return { | ||
|  |       ...shell, | ||
|  |       then(onFulfilled, onRejected) { | ||
|  |         return waitUntilIsLoaded().then(onFulfilled, onRejected); | ||
|  |       } | ||
|  |     }; | ||
|  |   } | ||
|  | 
 | ||
|  |   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 = vueDemi.ref(""); | ||
|  |     const promise = vueDemi.ref(); | ||
|  |     function execute() { | ||
|  |       if (!shared.isClient) | ||
|  |         return; | ||
|  |       promise.value = new Promise((resolve, reject) => { | ||
|  |         try { | ||
|  |           const _target = shared.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 (vueDemi.isRef(target) || typeof target === "function") | ||
|  |       vueDemi.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); | ||
|  |     }); | ||
|  |   } | ||
|  | 
 | ||
|  |   function useBattery(options = {}) { | ||
|  |     const { navigator = defaultNavigator } = options; | ||
|  |     const events = ["chargingchange", "chargingtimechange", "dischargingtimechange", "levelchange"]; | ||
|  |     const isSupported = useSupported(() => navigator && "getBattery" in navigator); | ||
|  |     const charging = vueDemi.ref(false); | ||
|  |     const chargingTime = vueDemi.ref(0); | ||
|  |     const dischargingTime = vueDemi.ref(0); | ||
|  |     const level = vueDemi.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); | ||
|  |         useEventListener(battery, events, updateBatteryInfo, { passive: true }); | ||
|  |       }); | ||
|  |     } | ||
|  |     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 = vueDemi.shallowRef(void 0); | ||
|  |     const error = vueDemi.shallowRef(null); | ||
|  |     vueDemi.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 = vueDemi.ref(); | ||
|  |     const isConnected = vueDemi.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; | ||
|  |         } | ||
|  |       } | ||
|  |     } | ||
|  |     shared.tryOnMounted(() => { | ||
|  |       var _a; | ||
|  |       if (device.value) | ||
|  |         (_a = device.value.gatt) == null ? void 0 : _a.connect(); | ||
|  |     }); | ||
|  |     shared.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 = vueDemi.ref(false); | ||
|  |     const handler = (event) => { | ||
|  |       matches.value = event.matches; | ||
|  |     }; | ||
|  |     const cleanup = () => { | ||
|  |       if (!mediaQuery) | ||
|  |         return; | ||
|  |       if ("removeEventListener" in mediaQuery) | ||
|  |         mediaQuery.removeEventListener("change", handler); | ||
|  |       else | ||
|  |         mediaQuery.removeListener(handler); | ||
|  |     }; | ||
|  |     const stopWatch = vueDemi.watchEffect(() => { | ||
|  |       if (!isSupported.value) | ||
|  |         return; | ||
|  |       cleanup(); | ||
|  |       mediaQuery = window.matchMedia(shared.toValue(query)); | ||
|  |       if ("addEventListener" in mediaQuery) | ||
|  |         mediaQuery.addEventListener("change", handler); | ||
|  |       else | ||
|  |         mediaQuery.addListener(handler); | ||
|  |       matches.value = mediaQuery.matches; | ||
|  |     }); | ||
|  |     shared.tryOnScopeDispose(() => { | ||
|  |       stopWatch(); | ||
|  |       cleanup(); | ||
|  |       mediaQuery = void 0; | ||
|  |     }); | ||
|  |     return matches; | ||
|  |   } | ||
|  | 
 | ||
|  |   const breakpointsTailwind = { | ||
|  |     "sm": 640, | ||
|  |     "md": 768, | ||
|  |     "lg": 1024, | ||
|  |     "xl": 1280, | ||
|  |     "2xl": 1536 | ||
|  |   }; | ||
|  |   const breakpointsBootstrapV5 = { | ||
|  |     xs: 0, | ||
|  |     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 | ||
|  |   }; | ||
|  |   const breakpointsPrimeFlex = { | ||
|  |     sm: 576, | ||
|  |     md: 768, | ||
|  |     lg: 992, | ||
|  |     xl: 1200 | ||
|  |   }; | ||
|  | 
 | ||
|  |   function useBreakpoints(breakpoints, options = {}) { | ||
|  |     function getValue(k, delta) { | ||
|  |       let v = shared.toValue(breakpoints[k]); | ||
|  |       if (delta != null) | ||
|  |         v = shared.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 vueDemi.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 = vueDemi.ref(false); | ||
|  |     const channel = vueDemi.ref(); | ||
|  |     const data = vueDemi.ref(); | ||
|  |     const error = vueDemi.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) { | ||
|  |       shared.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; | ||
|  |         }); | ||
|  |       }); | ||
|  |     } | ||
|  |     shared.tryOnScopeDispose(() => { | ||
|  |       close(); | ||
|  |     }); | ||
|  |     return { | ||
|  |       isSupported, | ||
|  |       channel, | ||
|  |       data, | ||
|  |       post, | ||
|  |       close, | ||
|  |       error, | ||
|  |       isClosed | ||
|  |     }; | ||
|  |   } | ||
|  | 
 | ||
|  |   const WRITABLE_PROPERTIES = [ | ||
|  |     "hash", | ||
|  |     "host", | ||
|  |     "hostname", | ||
|  |     "href", | ||
|  |     "pathname", | ||
|  |     "port", | ||
|  |     "protocol", | ||
|  |     "search" | ||
|  |   ]; | ||
|  |   function useBrowserLocation(options = {}) { | ||
|  |     const { window = defaultWindow } = options; | ||
|  |     const refs = Object.fromEntries( | ||
|  |       WRITABLE_PROPERTIES.map((key) => [key, vueDemi.ref()]) | ||
|  |     ); | ||
|  |     for (const [key, ref2] of shared.objectEntries(refs)) { | ||
|  |       vueDemi.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]; | ||
|  |       return vueDemi.reactive({ | ||
|  |         trigger, | ||
|  |         state: state2, | ||
|  |         length, | ||
|  |         origin, | ||
|  |         ...refs | ||
|  |       }); | ||
|  |     }; | ||
|  |     const state = vueDemi.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 = vueDemi.ref(refValue.value); | ||
|  |     vueDemi.watch(() => refValue.value, (value) => { | ||
|  |       if (!comparator(value, cachedValue.value)) | ||
|  |         cachedValue.value = value; | ||
|  |     }, watchOptions); | ||
|  |     return cachedValue; | ||
|  |   } | ||
|  | 
 | ||
|  |   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 = vueDemi.ref(); | ||
|  |     const onChange = () => { | ||
|  |       if (permissionStatus) | ||
|  |         state.value = permissionStatus.state; | ||
|  |     }; | ||
|  |     const query = shared.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 useClipboard(options = {}) { | ||
|  |     const { | ||
|  |       navigator = defaultNavigator, | ||
|  |       read = false, | ||
|  |       source, | ||
|  |       copiedDuring = 1500, | ||
|  |       legacy = false | ||
|  |     } = options; | ||
|  |     const isClipboardApiSupported = useSupported(() => navigator && "clipboard" in navigator); | ||
|  |     const permissionRead = usePermission("clipboard-read"); | ||
|  |     const permissionWrite = usePermission("clipboard-write"); | ||
|  |     const isSupported = vueDemi.computed(() => isClipboardApiSupported.value || legacy); | ||
|  |     const text = vueDemi.ref(""); | ||
|  |     const copied = vueDemi.ref(false); | ||
|  |     const timeout = shared.useTimeoutFn(() => copied.value = false, copiedDuring); | ||
|  |     function updateText() { | ||
|  |       if (isClipboardApiSupported.value && permissionRead.value !== "denied") { | ||
|  |         navigator.clipboard.readText().then((value) => { | ||
|  |           text.value = value; | ||
|  |         }); | ||
|  |       } else { | ||
|  |         text.value = legacyRead(); | ||
|  |       } | ||
|  |     } | ||
|  |     if (isSupported.value && read) | ||
|  |       useEventListener(["copy", "cut"], updateText); | ||
|  |     async function copy(value = shared.toValue(source)) { | ||
|  |       if (isSupported.value && value != null) { | ||
|  |         if (isClipboardApiSupported.value && permissionWrite.value !== "denied") | ||
|  |           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 useClipboardItems(options = {}) { | ||
|  |     const { | ||
|  |       navigator = defaultNavigator, | ||
|  |       read = false, | ||
|  |       source, | ||
|  |       copiedDuring = 1500 | ||
|  |     } = options; | ||
|  |     const isSupported = useSupported(() => navigator && "clipboard" in navigator); | ||
|  |     const content = vueDemi.ref([]); | ||
|  |     const copied = vueDemi.ref(false); | ||
|  |     const timeout = shared.useTimeoutFn(() => copied.value = false, copiedDuring); | ||
|  |     function updateContent() { | ||
|  |       if (isSupported.value) { | ||
|  |         navigator.clipboard.read().then((items) => { | ||
|  |           content.value = items; | ||
|  |         }); | ||
|  |       } | ||
|  |     } | ||
|  |     if (isSupported.value && read) | ||
|  |       useEventListener(["copy", "cut"], updateContent); | ||
|  |     async function copy(value = shared.toValue(source)) { | ||
|  |       if (isSupported.value && value != null) { | ||
|  |         await navigator.clipboard.write(value); | ||
|  |         content.value = value; | ||
|  |         copied.value = true; | ||
|  |         timeout.start(); | ||
|  |       } | ||
|  |     } | ||
|  |     return { | ||
|  |       isSupported, | ||
|  |       content, | ||
|  |       copied, | ||
|  |       copy | ||
|  |     }; | ||
|  |   } | ||
|  | 
 | ||
|  |   function cloneFnJSON(source) { | ||
|  |     return JSON.parse(JSON.stringify(source)); | ||
|  |   } | ||
|  |   function useCloned(source, options = {}) { | ||
|  |     const cloned = vueDemi.ref({}); | ||
|  |     const { | ||
|  |       manual, | ||
|  |       clone = cloneFnJSON, | ||
|  |       // watch options
 | ||
|  |       deep = true, | ||
|  |       immediate = true | ||
|  |     } = options; | ||
|  |     function sync() { | ||
|  |       cloned.value = clone(shared.toValue(source)); | ||
|  |     } | ||
|  |     if (!manual && (vueDemi.isRef(source) || typeof source === "function")) { | ||
|  |       vueDemi.watch(source, sync, { | ||
|  |         ...options, | ||
|  |         deep, | ||
|  |         immediate | ||
|  |       }); | ||
|  |     } 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); | ||
|  |       }, | ||
|  |       initOnMounted | ||
|  |     } = options; | ||
|  |     const data = (shallow ? vueDemi.shallowRef : vueDemi.ref)(typeof defaults === "function" ? defaults() : 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 = shared.toValue(defaults); | ||
|  |     const type = guessSerializerType(rawInit); | ||
|  |     const serializer = (_a = options.serializer) != null ? _a : StorageSerializers[type]; | ||
|  |     const { pause: pauseWatch, resume: resumeWatch } = shared.pausableWatch( | ||
|  |       data, | ||
|  |       () => write(data.value), | ||
|  |       { flush, deep, eventFilter } | ||
|  |     ); | ||
|  |     if (window && listenToStorageChanges) { | ||
|  |       shared.tryOnMounted(() => { | ||
|  |         useEventListener(window, "storage", update); | ||
|  |         useEventListener(window, customStorageEventName, updateFromCustomEvent); | ||
|  |         if (initOnMounted) | ||
|  |           update(); | ||
|  |       }); | ||
|  |     } | ||
|  |     if (!initOnMounted) | ||
|  |       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)) | ||
|  |           return { ...rawInit, ...value }; | ||
|  |         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 { | ||
|  |         if ((event == null ? void 0 : event.newValue) !== serializer.write(data.value)) | ||
|  |           data.value = read(event); | ||
|  |       } catch (e) { | ||
|  |         onError(e); | ||
|  |       } finally { | ||
|  |         if (event) | ||
|  |           vueDemi.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; | ||
|  |     const modes = { | ||
|  |       auto: "", | ||
|  |       light: "light", | ||
|  |       dark: "dark", | ||
|  |       ...options.modes || {} | ||
|  |     }; | ||
|  |     const preferredDark = usePreferredDark({ window }); | ||
|  |     const system = vueDemi.computed(() => preferredDark.value ? "dark" : "light"); | ||
|  |     const store = storageRef || (storageKey == null ? shared.toRef(initialValue) : useStorage(storageKey, initialValue, storage, { window, listenToStorageChanges })); | ||
|  |     const state = vueDemi.computed(() => store.value === "auto" ? system.value : store.value); | ||
|  |     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"); | ||
|  |           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)); | ||
|  |           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); | ||
|  |     } | ||
|  |     vueDemi.watch(state, onChanged, { flush: "post", immediate: true }); | ||
|  |     shared.tryOnMounted(() => onChanged(state.value)); | ||
|  |     const auto = vueDemi.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 = vueDemi.ref(false)) { | ||
|  |     const confirmHook = shared.createEventHook(); | ||
|  |     const cancelHook = shared.createEventHook(); | ||
|  |     const revealHook = shared.createEventHook(); | ||
|  |     let _resolve = shared.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: vueDemi.computed(() => revealed.value), | ||
|  |       reveal, | ||
|  |       confirm, | ||
|  |       cancel, | ||
|  |       onReveal: revealHook.on, | ||
|  |       onConfirm: confirmHook.on, | ||
|  |       onCancel: cancelHook.on | ||
|  |     }; | ||
|  |   } | ||
|  | 
 | ||
|  |   function useMutationObserver(target, callback, options = {}) { | ||
|  |     const { window = defaultWindow, ...mutationOptions } = options; | ||
|  |     let observer; | ||
|  |     const isSupported = useSupported(() => window && "MutationObserver" in window); | ||
|  |     const cleanup = () => { | ||
|  |       if (observer) { | ||
|  |         observer.disconnect(); | ||
|  |         observer = void 0; | ||
|  |       } | ||
|  |     }; | ||
|  |     const stopWatch = vueDemi.watch( | ||
|  |       () => unrefElement(target), | ||
|  |       (el) => { | ||
|  |         cleanup(); | ||
|  |         if (isSupported.value && window && el) { | ||
|  |           observer = new MutationObserver(callback); | ||
|  |           observer.observe(el, mutationOptions); | ||
|  |         } | ||
|  |       }, | ||
|  |       { immediate: true } | ||
|  |     ); | ||
|  |     const takeRecords = () => { | ||
|  |       return observer == null ? void 0 : observer.takeRecords(); | ||
|  |     }; | ||
|  |     const stop = () => { | ||
|  |       cleanup(); | ||
|  |       stopWatch(); | ||
|  |     }; | ||
|  |     shared.tryOnScopeDispose(stop); | ||
|  |     return { | ||
|  |       isSupported, | ||
|  |       stop, | ||
|  |       takeRecords | ||
|  |     }; | ||
|  |   } | ||
|  | 
 | ||
|  |   function useCssVar(prop, target, options = {}) { | ||
|  |     const { window = defaultWindow, initialValue = "", observe = false } = options; | ||
|  |     const variable = vueDemi.ref(initialValue); | ||
|  |     const elRef = vueDemi.computed(() => { | ||
|  |       var _a; | ||
|  |       return unrefElement(target) || ((_a = window == null ? void 0 : window.document) == null ? void 0 : _a.documentElement); | ||
|  |     }); | ||
|  |     function updateCssVar() { | ||
|  |       var _a; | ||
|  |       const key = shared.toValue(prop); | ||
|  |       const el = shared.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, { | ||
|  |         attributeFilter: ["style", "class"], | ||
|  |         window | ||
|  |       }); | ||
|  |     } | ||
|  |     vueDemi.watch( | ||
|  |       [elRef, () => shared.toValue(prop)], | ||
|  |       updateCssVar, | ||
|  |       { immediate: true } | ||
|  |     ); | ||
|  |     vueDemi.watch( | ||
|  |       variable, | ||
|  |       (val) => { | ||
|  |         var _a; | ||
|  |         if ((_a = elRef.value) == null ? void 0 : _a.style) | ||
|  |           elRef.value.style.setProperty(shared.toValue(prop), val); | ||
|  |       } | ||
|  |     ); | ||
|  |     return variable; | ||
|  |   } | ||
|  | 
 | ||
|  |   function useCurrentElement() { | ||
|  |     const vm = vueDemi.getCurrentInstance(); | ||
|  |     const currentElement = shared.computedWithControl( | ||
|  |       () => null, | ||
|  |       () => vm.proxy.$el | ||
|  |     ); | ||
|  |     vueDemi.onUpdated(currentElement.trigger); | ||
|  |     vueDemi.onMounted(currentElement.trigger); | ||
|  |     return currentElement; | ||
|  |   } | ||
|  | 
 | ||
|  |   function useCycleList(list, options) { | ||
|  |     const state = vueDemi.shallowRef(getInitialValue()); | ||
|  |     const listRef = shared.toRef(list); | ||
|  |     const index = vueDemi.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 = shared.toValue((_a = options == null ? void 0 : options.initialValue) != null ? _a : shared.toValue(list)[0])) != null ? _b : void 0; | ||
|  |     } | ||
|  |     vueDemi.watch(listRef, () => set(index.value)); | ||
|  |     return { | ||
|  |       state, | ||
|  |       index, | ||
|  |       next, | ||
|  |       prev | ||
|  |     }; | ||
|  |   } | ||
|  | 
 | ||
|  |   function useDark(options = {}) { | ||
|  |     const { | ||
|  |       valueDark = "dark", | ||
|  |       valueLight = "", | ||
|  |       window = defaultWindow | ||
|  |     } = options; | ||
|  |     const mode = useColorMode({ | ||
|  |       ...options, | ||
|  |       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 | ||
|  |       } | ||
|  |     }); | ||
|  |     const system = vueDemi.computed(() => { | ||
|  |       if (mode.system) { | ||
|  |         return mode.system.value; | ||
|  |       } else { | ||
|  |         const preferredDark = usePreferredDark({ window }); | ||
|  |         return preferredDark.value ? "dark" : "light"; | ||
|  |       } | ||
|  |     }); | ||
|  |     const isDark = vueDemi.computed({ | ||
|  |       get() { | ||
|  |         return mode.value === "dark"; | ||
|  |       }, | ||
|  |       set(v) { | ||
|  |         const modeVal = v ? "dark" : "light"; | ||
|  |         if (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 vueDemi.markRaw({ | ||
|  |         snapshot: dump(source.value), | ||
|  |         timestamp: shared.timestamp() | ||
|  |       }); | ||
|  |     } | ||
|  |     const last = vueDemi.ref(_createHistoryRecord()); | ||
|  |     const undoStack = vueDemi.ref([]); | ||
|  |     const redoStack = vueDemi.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) | ||
|  |         undoStack.value.splice(options.capacity, Number.POSITIVE_INFINITY); | ||
|  |       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 = vueDemi.computed(() => [last.value, ...undoStack.value]); | ||
|  |     const canUndo = vueDemi.computed(() => undoStack.value.length > 0); | ||
|  |     const canRedo = vueDemi.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 | ||
|  |     } = shared.pausableFilter(eventFilter); | ||
|  |     const { | ||
|  |       ignoreUpdates, | ||
|  |       ignorePrevAsyncUpdates, | ||
|  |       stop | ||
|  |     } = shared.watchIgnorable( | ||
|  |       source, | ||
|  |       commit, | ||
|  |       { deep, flush, eventFilter: composedFilter } | ||
|  |     ); | ||
|  |     function setSource(source2, value) { | ||
|  |       ignorePrevAsyncUpdates(); | ||
|  |       ignoreUpdates(() => { | ||
|  |         source2.value = value; | ||
|  |       }); | ||
|  |     } | ||
|  |     const manualHistory = useManualRefHistory(source, { ...options, clone: options.clone || deep, setSource }); | ||
|  |     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(); | ||
|  |     } | ||
|  |     return { | ||
|  |       ...manualHistory, | ||
|  |       isTracking, | ||
|  |       pause, | ||
|  |       resume, | ||
|  |       commit, | ||
|  |       batch, | ||
|  |       dispose | ||
|  |     }; | ||
|  |   } | ||
|  | 
 | ||
|  |   function useDebouncedRefHistory(source, options = {}) { | ||
|  |     const filter = options.debounce ? shared.debounceFilter(options.debounce) : void 0; | ||
|  |     const history = useRefHistory(source, { ...options, eventFilter: filter }); | ||
|  |     return { | ||
|  |       ...history | ||
|  |     }; | ||
|  |   } | ||
|  | 
 | ||
|  |   function useDeviceMotion(options = {}) { | ||
|  |     const { | ||
|  |       window = defaultWindow, | ||
|  |       eventFilter = shared.bypassFilter | ||
|  |     } = options; | ||
|  |     const acceleration = vueDemi.ref({ x: null, y: null, z: null }); | ||
|  |     const rotationRate = vueDemi.ref({ alpha: null, beta: null, gamma: null }); | ||
|  |     const interval = vueDemi.ref(0); | ||
|  |     const accelerationIncludingGravity = vueDemi.ref({ | ||
|  |       x: null, | ||
|  |       y: null, | ||
|  |       z: null | ||
|  |     }); | ||
|  |     if (window) { | ||
|  |       const onDeviceMotion = shared.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 = vueDemi.ref(false); | ||
|  |     const alpha = vueDemi.ref(null); | ||
|  |     const beta = vueDemi.ref(null); | ||
|  |     const gamma = vueDemi.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 | ||
|  |     }; | ||
|  |   } | ||
|  | 
 | ||
|  |   function useDevicePixelRatio(options = {}) { | ||
|  |     const { | ||
|  |       window = defaultWindow | ||
|  |     } = options; | ||
|  |     const pixelRatio = vueDemi.ref(1); | ||
|  |     if (window) { | ||
|  |       let observe2 = function() { | ||
|  |         pixelRatio.value = window.devicePixelRatio; | ||
|  |         cleanup2(); | ||
|  |         media = window.matchMedia(`(resolution: ${pixelRatio.value}dppx)`); | ||
|  |         media.addEventListener("change", observe2, { once: true }); | ||
|  |       }, cleanup2 = function() { | ||
|  |         media == null ? void 0 : media.removeEventListener("change", observe2); | ||
|  |       }; | ||
|  |       let media; | ||
|  |       observe2(); | ||
|  |       shared.tryOnScopeDispose(cleanup2); | ||
|  |     } | ||
|  |     return { pixelRatio }; | ||
|  |   } | ||
|  | 
 | ||
|  |   function useDevicesList(options = {}) { | ||
|  |     const { | ||
|  |       navigator = defaultNavigator, | ||
|  |       requestPermissions = false, | ||
|  |       constraints = { audio: true, video: true }, | ||
|  |       onUpdated | ||
|  |     } = options; | ||
|  |     const devices = vueDemi.ref([]); | ||
|  |     const videoInputs = vueDemi.computed(() => devices.value.filter((i) => i.kind === "videoinput")); | ||
|  |     const audioInputs = vueDemi.computed(() => devices.value.filter((i) => i.kind === "audioinput")); | ||
|  |     const audioOutputs = vueDemi.computed(() => devices.value.filter((i) => i.kind === "audiooutput")); | ||
|  |     const isSupported = useSupported(() => navigator && navigator.mediaDevices && navigator.mediaDevices.enumerateDevices); | ||
|  |     const permissionGranted = vueDemi.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 = vueDemi.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 = vueDemi.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; | ||
|  |     } | ||
|  |     vueDemi.watch( | ||
|  |       enabled, | ||
|  |       (v) => { | ||
|  |         if (v) | ||
|  |           _start(); | ||
|  |         else | ||
|  |           _stop(); | ||
|  |       }, | ||
|  |       { immediate: true } | ||
|  |     ); | ||
|  |     return { | ||
|  |       isSupported, | ||
|  |       stream, | ||
|  |       start, | ||
|  |       stop, | ||
|  |       enabled | ||
|  |     }; | ||
|  |   } | ||
|  | 
 | ||
|  |   function useDocumentVisibility(options = {}) { | ||
|  |     const { document = defaultDocument } = options; | ||
|  |     if (!document) | ||
|  |       return vueDemi.ref("visible"); | ||
|  |     const visibility = vueDemi.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, | ||
|  |       containerElement, | ||
|  |       handle: draggingHandle = target | ||
|  |     } = options; | ||
|  |     const position = vueDemi.ref( | ||
|  |       (_a = shared.toValue(initialValue)) != null ? _a : { x: 0, y: 0 } | ||
|  |     ); | ||
|  |     const pressedDelta = vueDemi.ref(); | ||
|  |     const filterEvent = (e) => { | ||
|  |       if (pointerTypes) | ||
|  |         return pointerTypes.includes(e.pointerType); | ||
|  |       return true; | ||
|  |     }; | ||
|  |     const handleEvent = (e) => { | ||
|  |       if (shared.toValue(preventDefault)) | ||
|  |         e.preventDefault(); | ||
|  |       if (shared.toValue(stopPropagation)) | ||
|  |         e.stopPropagation(); | ||
|  |     }; | ||
|  |     const start = (e) => { | ||
|  |       var _a2; | ||
|  |       if (!filterEvent(e)) | ||
|  |         return; | ||
|  |       if (shared.toValue(exact) && e.target !== shared.toValue(target)) | ||
|  |         return; | ||
|  |       const container = shared.toValue(containerElement); | ||
|  |       const containerRect = (_a2 = container == null ? void 0 : container.getBoundingClientRect) == null ? void 0 : _a2.call(container); | ||
|  |       const targetRect = shared.toValue(target).getBoundingClientRect(); | ||
|  |       const pos = { | ||
|  |         x: e.clientX - (container ? targetRect.left - containerRect.left : targetRect.left), | ||
|  |         y: e.clientY - (container ? targetRect.top - containerRect.top : targetRect.top) | ||
|  |       }; | ||
|  |       if ((onStart == null ? void 0 : onStart(pos, e)) === false) | ||
|  |         return; | ||
|  |       pressedDelta.value = pos; | ||
|  |       handleEvent(e); | ||
|  |     }; | ||
|  |     const move = (e) => { | ||
|  |       var _a2; | ||
|  |       if (!filterEvent(e)) | ||
|  |         return; | ||
|  |       if (!pressedDelta.value) | ||
|  |         return; | ||
|  |       const container = shared.toValue(containerElement); | ||
|  |       const containerRect = (_a2 = container == null ? void 0 : container.getBoundingClientRect) == null ? void 0 : _a2.call(container); | ||
|  |       const targetRect = shared.toValue(target).getBoundingClientRect(); | ||
|  |       let { x, y } = position.value; | ||
|  |       if (axis === "x" || axis === "both") { | ||
|  |         x = e.clientX - pressedDelta.value.x; | ||
|  |         if (container) | ||
|  |           x = Math.min(Math.max(0, x), containerRect.width - targetRect.width); | ||
|  |       } | ||
|  |       if (axis === "y" || axis === "both") { | ||
|  |         y = e.clientY - pressedDelta.value.y; | ||
|  |         if (container) | ||
|  |           y = Math.min(Math.max(0, y), containerRect.height - targetRect.height); | ||
|  |       } | ||
|  |       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 (shared.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); | ||
|  |     } | ||
|  |     return { | ||
|  |       ...shared.toRefs(position), | ||
|  |       position, | ||
|  |       isDragging: vueDemi.computed(() => !!pressedDelta.value), | ||
|  |       style: vueDemi.computed( | ||
|  |         () => `left:${position.value.x}px;top:${position.value.y}px;` | ||
|  |       ) | ||
|  |     }; | ||
|  |   } | ||
|  | 
 | ||
|  |   function useDropZone(target, options = {}) { | ||
|  |     const isOverDropZone = vueDemi.ref(false); | ||
|  |     const files = vueDemi.shallowRef(null); | ||
|  |     let counter = 0; | ||
|  |     let isDataTypeIncluded = true; | ||
|  |     if (shared.isClient) { | ||
|  |       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; | ||
|  |       }; | ||
|  |       useEventListener(target, "dragenter", (event) => { | ||
|  |         var _a, _b; | ||
|  |         const types = Array.from(((_a = event == null ? void 0 : event.dataTransfer) == null ? void 0 : _a.items) || []).map((i) => i.kind === "file" ? i.type : null).filter(shared.notNullish); | ||
|  |         if (_options.dataTypes && event.dataTransfer) { | ||
|  |           const dataTypes = vueDemi.unref(_options.dataTypes); | ||
|  |           isDataTypeIncluded = typeof dataTypes === "function" ? dataTypes(types) : dataTypes ? dataTypes.some((item) => types.includes(item)) : true; | ||
|  |           if (!isDataTypeIncluded) | ||
|  |             return; | ||
|  |         } | ||
|  |         event.preventDefault(); | ||
|  |         counter += 1; | ||
|  |         isOverDropZone.value = true; | ||
|  |         (_b = _options.onEnter) == null ? void 0 : _b.call(_options, getFiles(event), event); | ||
|  |       }); | ||
|  |       useEventListener(target, "dragover", (event) => { | ||
|  |         var _a; | ||
|  |         if (!isDataTypeIncluded) | ||
|  |           return; | ||
|  |         event.preventDefault(); | ||
|  |         (_a = _options.onOver) == null ? void 0 : _a.call(_options, getFiles(event), event); | ||
|  |       }); | ||
|  |       useEventListener(target, "dragleave", (event) => { | ||
|  |         var _a; | ||
|  |         if (!isDataTypeIncluded) | ||
|  |           return; | ||
|  |         event.preventDefault(); | ||
|  |         counter -= 1; | ||
|  |         if (counter === 0) | ||
|  |           isOverDropZone.value = false; | ||
|  |         (_a = _options.onLeave) == null ? void 0 : _a.call(_options, getFiles(event), event); | ||
|  |       }); | ||
|  |       useEventListener(target, "drop", (event) => { | ||
|  |         var _a; | ||
|  |         event.preventDefault(); | ||
|  |         counter = 0; | ||
|  |         isOverDropZone.value = false; | ||
|  |         (_a = _options.onDrop) == null ? void 0 : _a.call(_options, getFiles(event), event); | ||
|  |       }); | ||
|  |     } | ||
|  |     return { | ||
|  |       files, | ||
|  |       isOverDropZone | ||
|  |     }; | ||
|  |   } | ||
|  | 
 | ||
|  |   function useResizeObserver(target, callback, options = {}) { | ||
|  |     const { window = defaultWindow, ...observerOptions } = options; | ||
|  |     let observer; | ||
|  |     const isSupported = useSupported(() => window && "ResizeObserver" in window); | ||
|  |     const cleanup = () => { | ||
|  |       if (observer) { | ||
|  |         observer.disconnect(); | ||
|  |         observer = void 0; | ||
|  |       } | ||
|  |     }; | ||
|  |     const targets = vueDemi.computed(() => Array.isArray(target) ? target.map((el) => unrefElement(el)) : [unrefElement(target)]); | ||
|  |     const stopWatch = vueDemi.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(); | ||
|  |     }; | ||
|  |     shared.tryOnScopeDispose(stop); | ||
|  |     return { | ||
|  |       isSupported, | ||
|  |       stop | ||
|  |     }; | ||
|  |   } | ||
|  | 
 | ||
|  |   function useElementBounding(target, options = {}) { | ||
|  |     const { | ||
|  |       reset = true, | ||
|  |       windowResize = true, | ||
|  |       windowScroll = true, | ||
|  |       immediate = true | ||
|  |     } = options; | ||
|  |     const height = vueDemi.ref(0); | ||
|  |     const bottom = vueDemi.ref(0); | ||
|  |     const left = vueDemi.ref(0); | ||
|  |     const right = vueDemi.ref(0); | ||
|  |     const top = vueDemi.ref(0); | ||
|  |     const width = vueDemi.ref(0); | ||
|  |     const x = vueDemi.ref(0); | ||
|  |     const y = vueDemi.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); | ||
|  |     vueDemi.watch(() => unrefElement(target), (ele) => !ele && update()); | ||
|  |     useMutationObserver(target, update, { | ||
|  |       attributeFilter: ["style", "class"] | ||
|  |     }); | ||
|  |     if (windowScroll) | ||
|  |       useEventListener("scroll", update, { capture: true, passive: true }); | ||
|  |     if (windowResize) | ||
|  |       useEventListener("resize", update, { passive: true }); | ||
|  |     shared.tryOnMounted(() => { | ||
|  |       if (immediate) | ||
|  |         update(); | ||
|  |     }); | ||
|  |     return { | ||
|  |       height, | ||
|  |       bottom, | ||
|  |       left, | ||
|  |       right, | ||
|  |       top, | ||
|  |       width, | ||
|  |       x, | ||
|  |       y, | ||
|  |       update | ||
|  |     }; | ||
|  |   } | ||
|  | 
 | ||
|  |   function useElementByPoint(options) { | ||
|  |     const { | ||
|  |       x, | ||
|  |       y, | ||
|  |       document = defaultDocument, | ||
|  |       multiple, | ||
|  |       interval = "requestAnimationFrame", | ||
|  |       immediate = true | ||
|  |     } = options; | ||
|  |     const isSupported = useSupported(() => { | ||
|  |       if (shared.toValue(multiple)) | ||
|  |         return document && "elementsFromPoint" in document; | ||
|  |       return document && "elementFromPoint" in document; | ||
|  |     }); | ||
|  |     const element = vueDemi.ref(null); | ||
|  |     const cb = () => { | ||
|  |       var _a, _b; | ||
|  |       element.value = shared.toValue(multiple) ? (_a = document == null ? void 0 : document.elementsFromPoint(shared.toValue(x), shared.toValue(y))) != null ? _a : [] : (_b = document == null ? void 0 : document.elementFromPoint(shared.toValue(x), shared.toValue(y))) != null ? _b : null; | ||
|  |     }; | ||
|  |     const controls = interval === "requestAnimationFrame" ? useRafFn(cb, { immediate }) : shared.useIntervalFn(cb, interval, { immediate }); | ||
|  |     return { | ||
|  |       isSupported, | ||
|  |       element, | ||
|  |       ...controls | ||
|  |     }; | ||
|  |   } | ||
|  | 
 | ||
|  |   function useElementHover(el, options = {}) { | ||
|  |     const { | ||
|  |       delayEnter = 0, | ||
|  |       delayLeave = 0, | ||
|  |       window = defaultWindow | ||
|  |     } = options; | ||
|  |     const isHovered = vueDemi.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 = vueDemi.computed(() => { | ||
|  |       var _a, _b; | ||
|  |       return (_b = (_a = unrefElement(target)) == null ? void 0 : _a.namespaceURI) == null ? void 0 : _b.includes("svg"); | ||
|  |     }); | ||
|  |     const width = vueDemi.ref(initialSize.width); | ||
|  |     const height = vueDemi.ref(initialSize.height); | ||
|  |     const { stop: stop1 } = 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); | ||
|  |             width.value = Number.parseFloat(styles.width); | ||
|  |             height.value = Number.parseFloat(styles.height); | ||
|  |           } | ||
|  |         } 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 | ||
|  |     ); | ||
|  |     shared.tryOnMounted(() => { | ||
|  |       const ele = unrefElement(target); | ||
|  |       if (ele) { | ||
|  |         width.value = "offsetWidth" in ele ? ele.offsetWidth : initialSize.width; | ||
|  |         height.value = "offsetHeight" in ele ? ele.offsetHeight : initialSize.height; | ||
|  |       } | ||
|  |     }); | ||
|  |     const stop2 = vueDemi.watch( | ||
|  |       () => unrefElement(target), | ||
|  |       (ele) => { | ||
|  |         width.value = ele ? initialSize.width : 0; | ||
|  |         height.value = ele ? initialSize.height : 0; | ||
|  |       } | ||
|  |     ); | ||
|  |     function stop() { | ||
|  |       stop1(); | ||
|  |       stop2(); | ||
|  |     } | ||
|  |     return { | ||
|  |       width, | ||
|  |       height, | ||
|  |       stop | ||
|  |     }; | ||
|  |   } | ||
|  | 
 | ||
|  |   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 = vueDemi.computed(() => { | ||
|  |       const _target = shared.toValue(target); | ||
|  |       return (Array.isArray(_target) ? _target : [_target]).map(unrefElement).filter(shared.notNullish); | ||
|  |     }); | ||
|  |     let cleanup = shared.noop; | ||
|  |     const isActive = vueDemi.ref(immediate); | ||
|  |     const stopWatch = isSupported.value ? vueDemi.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 = shared.noop; | ||
|  |         }; | ||
|  |       }, | ||
|  |       { immediate, flush: "post" } | ||
|  |     ) : shared.noop; | ||
|  |     const stop = () => { | ||
|  |       cleanup(); | ||
|  |       stopWatch(); | ||
|  |       isActive.value = false; | ||
|  |     }; | ||
|  |     shared.tryOnScopeDispose(stop); | ||
|  |     return { | ||
|  |       isSupported, | ||
|  |       isActive, | ||
|  |       pause() { | ||
|  |         cleanup(); | ||
|  |         isActive.value = false; | ||
|  |       }, | ||
|  |       resume() { | ||
|  |         isActive.value = true; | ||
|  |       }, | ||
|  |       stop | ||
|  |     }; | ||
|  |   } | ||
|  | 
 | ||
|  |   function useElementVisibility(element, options = {}) { | ||
|  |     const { window = defaultWindow, scrollTarget } = options; | ||
|  |     const elementIsVisible = vueDemi.ref(false); | ||
|  |     useIntersectionObserver( | ||
|  |       element, | ||
|  |       (intersectionObserverEntries) => { | ||
|  |         let isIntersecting = elementIsVisible.value; | ||
|  |         let latestTime = 0; | ||
|  |         for (const entry of intersectionObserverEntries) { | ||
|  |           if (entry.time >= latestTime) { | ||
|  |             latestTime = entry.time; | ||
|  |             isIntersecting = entry.isIntersecting; | ||
|  |           } | ||
|  |         } | ||
|  |         elementIsVisible.value = isIntersecting; | ||
|  |       }, | ||
|  |       { | ||
|  |         root: scrollTarget, | ||
|  |         window, | ||
|  |         threshold: 0 | ||
|  |       } | ||
|  |     ); | ||
|  |     return elementIsVisible; | ||
|  |   } | ||
|  | 
 | ||
|  |   const events = /* @__PURE__ */ new Map(); | ||
|  | 
 | ||
|  |   function useEventBus(key) { | ||
|  |     const scope = vueDemi.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 = vueDemi.ref(null); | ||
|  |     const data = vueDemi.ref(null); | ||
|  |     const status = vueDemi.ref("CONNECTING"); | ||
|  |     const eventSource = vueDemi.ref(null); | ||
|  |     const error = vueDemi.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; | ||
|  |       }); | ||
|  |     } | ||
|  |     shared.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 = vueDemi.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 = shared.toRef(newIcon); | ||
|  |     const applyIcon = (icon) => { | ||
|  |       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}`); | ||
|  |     }; | ||
|  |     vueDemi.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) { | ||
|  |     return obj && shared.containsProp(obj, "immediate", "refetch", "initialData", "timeout", "beforeFetch", "afterFetch", "onFetchError", "fetch", "updateDataOnError"); | ||
|  |   } | ||
|  |   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) | ||
|  |           return { ...ctx, ...await callback(ctx) }; | ||
|  |         return ctx; | ||
|  |       }; | ||
|  |     } else { | ||
|  |       return async (ctx) => { | ||
|  |         for (const callback of callbacks) { | ||
|  |           if (callback) | ||
|  |             ctx = { ...ctx, ...await callback(ctx) }; | ||
|  |         } | ||
|  |         return ctx; | ||
|  |       }; | ||
|  |     } | ||
|  |   } | ||
|  |   function createFetch(config = {}) { | ||
|  |     const _combination = config.combination || "chain"; | ||
|  |     const _options = config.options || {}; | ||
|  |     const _fetchOptions = config.fetchOptions || {}; | ||
|  |     function useFactoryFetch(url, ...args) { | ||
|  |       const computedUrl = vueDemi.computed(() => { | ||
|  |         const baseUrl = shared.toValue(config.baseUrl); | ||
|  |         const targetUrl = shared.toValue(url); | ||
|  |         return baseUrl && !isAbsoluteURL(targetUrl) ? joinPaths(baseUrl, targetUrl) : targetUrl; | ||
|  |       }); | ||
|  |       let options = _options; | ||
|  |       let fetchOptions = _fetchOptions; | ||
|  |       if (args.length > 0) { | ||
|  |         if (isFetchOptions(args[0])) { | ||
|  |           options = { | ||
|  |             ...options, | ||
|  |             ...args[0], | ||
|  |             beforeFetch: combineCallbacks(_combination, _options.beforeFetch, args[0].beforeFetch), | ||
|  |             afterFetch: combineCallbacks(_combination, _options.afterFetch, args[0].afterFetch), | ||
|  |             onFetchError: combineCallbacks(_combination, _options.onFetchError, args[0].onFetchError) | ||
|  |           }; | ||
|  |         } else { | ||
|  |           fetchOptions = { | ||
|  |             ...fetchOptions, | ||
|  |             ...args[0], | ||
|  |             headers: { | ||
|  |               ...headersToObject(fetchOptions.headers) || {}, | ||
|  |               ...headersToObject(args[0].headers) || {} | ||
|  |             } | ||
|  |           }; | ||
|  |         } | ||
|  |       } | ||
|  |       if (args.length > 1 && isFetchOptions(args[1])) { | ||
|  |         options = { | ||
|  |           ...options, | ||
|  |           ...args[1], | ||
|  |           beforeFetch: combineCallbacks(_combination, _options.beforeFetch, args[1].beforeFetch), | ||
|  |           afterFetch: combineCallbacks(_combination, _options.afterFetch, args[1].afterFetch), | ||
|  |           onFetchError: combineCallbacks(_combination, _options.onFetchError, args[1].onFetchError) | ||
|  |         }; | ||
|  |       } | ||
|  |       return useFetch(computedUrl, fetchOptions, options); | ||
|  |     } | ||
|  |     return useFactoryFetch; | ||
|  |   } | ||
|  |   function useFetch(url, ...args) { | ||
|  |     var _a; | ||
|  |     const supportsAbort = typeof AbortController === "function"; | ||
|  |     let fetchOptions = {}; | ||
|  |     let options = { | ||
|  |       immediate: true, | ||
|  |       refetch: false, | ||
|  |       timeout: 0, | ||
|  |       updateDataOnError: false | ||
|  |     }; | ||
|  |     const config = { | ||
|  |       method: "GET", | ||
|  |       type: "text", | ||
|  |       payload: void 0 | ||
|  |     }; | ||
|  |     if (args.length > 0) { | ||
|  |       if (isFetchOptions(args[0])) | ||
|  |         options = { ...options, ...args[0] }; | ||
|  |       else | ||
|  |         fetchOptions = args[0]; | ||
|  |     } | ||
|  |     if (args.length > 1) { | ||
|  |       if (isFetchOptions(args[1])) | ||
|  |         options = { ...options, ...args[1] }; | ||
|  |     } | ||
|  |     const { | ||
|  |       fetch = (_a = defaultWindow) == null ? void 0 : _a.fetch, | ||
|  |       initialData, | ||
|  |       timeout | ||
|  |     } = options; | ||
|  |     const responseEvent = shared.createEventHook(); | ||
|  |     const errorEvent = shared.createEventHook(); | ||
|  |     const finallyEvent = shared.createEventHook(); | ||
|  |     const isFinished = vueDemi.ref(false); | ||
|  |     const isFetching = vueDemi.ref(false); | ||
|  |     const aborted = vueDemi.ref(false); | ||
|  |     const statusCode = vueDemi.ref(null); | ||
|  |     const response = vueDemi.shallowRef(null); | ||
|  |     const error = vueDemi.shallowRef(null); | ||
|  |     const data = vueDemi.shallowRef(initialData || null); | ||
|  |     const canAbort = vueDemi.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; | ||
|  |         fetchOptions = { | ||
|  |           ...fetchOptions, | ||
|  |           signal: controller.signal | ||
|  |         }; | ||
|  |       } | ||
|  |     }; | ||
|  |     const loading = (isLoading) => { | ||
|  |       isFetching.value = isLoading; | ||
|  |       isFinished.value = !isLoading; | ||
|  |     }; | ||
|  |     if (timeout) | ||
|  |       timer = shared.useTimeoutFn(abort, timeout, { immediate: false }); | ||
|  |     let executeCounter = 0; | ||
|  |     const execute = async (throwOnFailed = false) => { | ||
|  |       var _a2, _b; | ||
|  |       abort(); | ||
|  |       loading(true); | ||
|  |       error.value = null; | ||
|  |       statusCode.value = null; | ||
|  |       aborted.value = false; | ||
|  |       executeCounter += 1; | ||
|  |       const currentExecuteCounter = executeCounter; | ||
|  |       const defaultFetchOptions = { | ||
|  |         method: config.method, | ||
|  |         headers: {} | ||
|  |       }; | ||
|  |       if (config.payload) { | ||
|  |         const headers = headersToObject(defaultFetchOptions.headers); | ||
|  |         const payload = shared.toValue(config.payload); | ||
|  |         if (!config.payloadType && payload && Object.getPrototypeOf(payload) === Object.prototype && !(payload instanceof FormData)) | ||
|  |           config.payloadType = "json"; | ||
|  |         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: shared.toValue(url), | ||
|  |         options: { | ||
|  |           ...defaultFetchOptions, | ||
|  |           ...fetchOptions | ||
|  |         }, | ||
|  |         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 fetch( | ||
|  |         context.url, | ||
|  |         { | ||
|  |           ...defaultFetchOptions, | ||
|  |           ...context.options, | ||
|  |           headers: { | ||
|  |             ...headersToObject(defaultFetchOptions.headers), | ||
|  |             ...headersToObject((_b = context.options) == null ? void 0 : _b.headers) | ||
|  |           } | ||
|  |         } | ||
|  |       ).then(async (fetchResponse) => { | ||
|  |         response.value = fetchResponse; | ||
|  |         statusCode.value = fetchResponse.status; | ||
|  |         responseData = await fetchResponse.clone()[config.type](); | ||
|  |         if (!fetchResponse.ok) { | ||
|  |           data.value = initialData || null; | ||
|  |           throw new Error(fetchResponse.statusText); | ||
|  |         } | ||
|  |         if (options.afterFetch) { | ||
|  |           ({ data: responseData } = await options.afterFetch({ | ||
|  |             data: responseData, | ||
|  |             response: fetchResponse | ||
|  |           })); | ||
|  |         } | ||
|  |         data.value = responseData; | ||
|  |         responseEvent.trigger(fetchResponse); | ||
|  |         return fetchResponse; | ||
|  |       }).catch(async (fetchError) => { | ||
|  |         let errorData = fetchError.message || fetchError.name; | ||
|  |         if (options.onFetchError) { | ||
|  |           ({ error: errorData, data: responseData } = await options.onFetchError({ | ||
|  |             data: responseData, | ||
|  |             error: fetchError, | ||
|  |             response: response.value | ||
|  |           })); | ||
|  |         } | ||
|  |         error.value = errorData; | ||
|  |         if (options.updateDataOnError) | ||
|  |           data.value = responseData; | ||
|  |         errorEvent.trigger(fetchError); | ||
|  |         if (throwOnFailed) | ||
|  |           throw fetchError; | ||
|  |         return null; | ||
|  |       }).finally(() => { | ||
|  |         if (currentExecuteCounter === executeCounter) | ||
|  |           loading(false); | ||
|  |         if (timer) | ||
|  |           timer.stop(); | ||
|  |         finallyEvent.trigger(null); | ||
|  |       }); | ||
|  |     }; | ||
|  |     const refetch = shared.toRef(options.refetch); | ||
|  |     vueDemi.watch( | ||
|  |       [ | ||
|  |         refetch, | ||
|  |         shared.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 (vueDemi.isRef(config.payload)) { | ||
|  |             vueDemi.watch( | ||
|  |               [ | ||
|  |                 refetch, | ||
|  |                 shared.toRef(config.payload) | ||
|  |               ], | ||
|  |               ([refetch2]) => refetch2 && execute(), | ||
|  |               { deep: true } | ||
|  |             ); | ||
|  |           } | ||
|  |           return { | ||
|  |             ...shell, | ||
|  |             then(onFulfilled, onRejected) { | ||
|  |               return waitUntilFinished().then(onFulfilled, onRejected); | ||
|  |             } | ||
|  |           }; | ||
|  |         } | ||
|  |         return void 0; | ||
|  |       }; | ||
|  |     } | ||
|  |     function waitUntilFinished() { | ||
|  |       return new Promise((resolve, reject) => { | ||
|  |         shared.until(isFinished).toBe(true).then(() => resolve(shell)).catch((error2) => reject(error2)); | ||
|  |       }); | ||
|  |     } | ||
|  |     function setType(type) { | ||
|  |       return () => { | ||
|  |         if (!isFetching.value) { | ||
|  |           config.type = type; | ||
|  |           return { | ||
|  |             ...shell, | ||
|  |             then(onFulfilled, onRejected) { | ||
|  |               return waitUntilFinished().then(onFulfilled, onRejected); | ||
|  |             } | ||
|  |           }; | ||
|  |         } | ||
|  |         return void 0; | ||
|  |       }; | ||
|  |     } | ||
|  |     if (options.immediate) | ||
|  |       Promise.resolve().then(() => execute()); | ||
|  |     return { | ||
|  |       ...shell, | ||
|  |       then(onFulfilled, onRejected) { | ||
|  |         return waitUntilFinished().then(onFulfilled, onRejected); | ||
|  |       } | ||
|  |     }; | ||
|  |   } | ||
|  |   function joinPaths(start, end) { | ||
|  |     if (!start.endsWith("/") && !end.startsWith("/")) | ||
|  |       return `${start}/${end}`; | ||
|  |     return `${start}${end}`; | ||
|  |   } | ||
|  | 
 | ||
|  |   const DEFAULT_OPTIONS = { | ||
|  |     multiple: true, | ||
|  |     accept: "*", | ||
|  |     reset: false, | ||
|  |     directory: false | ||
|  |   }; | ||
|  |   function useFileDialog(options = {}) { | ||
|  |     const { | ||
|  |       document = defaultDocument | ||
|  |     } = options; | ||
|  |     const files = vueDemi.ref(null); | ||
|  |     const { on: onChange, trigger } = shared.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); | ||
|  |       }; | ||
|  |     } | ||
|  |     const reset = () => { | ||
|  |       files.value = null; | ||
|  |       if (input) { | ||
|  |         input.value = ""; | ||
|  |         trigger(null); | ||
|  |       } | ||
|  |     }; | ||
|  |     const open = (localOptions) => { | ||
|  |       if (!input) | ||
|  |         return; | ||
|  |       const _options = { | ||
|  |         ...DEFAULT_OPTIONS, | ||
|  |         ...options, | ||
|  |         ...localOptions | ||
|  |       }; | ||
|  |       input.multiple = _options.multiple; | ||
|  |       input.accept = _options.accept; | ||
|  |       input.webkitdirectory = _options.directory; | ||
|  |       if (shared.hasOwn(_options, "capture")) | ||
|  |         input.capture = _options.capture; | ||
|  |       if (_options.reset) | ||
|  |         reset(); | ||
|  |       input.click(); | ||
|  |     }; | ||
|  |     return { | ||
|  |       files: vueDemi.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 = vueDemi.ref(); | ||
|  |     const data = vueDemi.ref(); | ||
|  |     const file = vueDemi.ref(); | ||
|  |     const fileName = vueDemi.computed(() => { | ||
|  |       var _a, _b; | ||
|  |       return (_b = (_a = file.value) == null ? void 0 : _a.name) != null ? _b : ""; | ||
|  |     }); | ||
|  |     const fileMIME = vueDemi.computed(() => { | ||
|  |       var _a, _b; | ||
|  |       return (_b = (_a = file.value) == null ? void 0 : _a.type) != null ? _b : ""; | ||
|  |     }); | ||
|  |     const fileSize = vueDemi.computed(() => { | ||
|  |       var _a, _b; | ||
|  |       return (_b = (_a = file.value) == null ? void 0 : _a.size) != null ? _b : 0; | ||
|  |     }); | ||
|  |     const fileLastModified = vueDemi.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; | ||
|  |       const [handle] = await window.showOpenFilePicker({ ...shared.toValue(options), ..._options }); | ||
|  |       fileHandle.value = handle; | ||
|  |       await updateFile(); | ||
|  |       await updateData(); | ||
|  |     } | ||
|  |     async function create(_options = {}) { | ||
|  |       if (!isSupported.value) | ||
|  |         return; | ||
|  |       fileHandle.value = await window.showSaveFilePicker({ ...options, ..._options }); | ||
|  |       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; | ||
|  |       fileHandle.value = await window.showSaveFilePicker({ ...options, ..._options }); | ||
|  |       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 = shared.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; | ||
|  |     } | ||
|  |     vueDemi.watch(() => shared.toValue(dataType), updateData); | ||
|  |     return { | ||
|  |       isSupported, | ||
|  |       data, | ||
|  |       file, | ||
|  |       fileName, | ||
|  |       fileMIME, | ||
|  |       fileSize, | ||
|  |       fileLastModified, | ||
|  |       open, | ||
|  |       create, | ||
|  |       save, | ||
|  |       saveAs, | ||
|  |       updateData | ||
|  |     }; | ||
|  |   } | ||
|  | 
 | ||
|  |   function useFocus(target, options = {}) { | ||
|  |     const { initialValue = false, focusVisible = false } = options; | ||
|  |     const innerFocused = vueDemi.ref(false); | ||
|  |     const targetElement = vueDemi.computed(() => unrefElement(target)); | ||
|  |     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; | ||
|  |     }); | ||
|  |     useEventListener(targetElement, "blur", () => innerFocused.value = false); | ||
|  |     const focused = vueDemi.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(); | ||
|  |       } | ||
|  |     }); | ||
|  |     vueDemi.watch( | ||
|  |       targetElement, | ||
|  |       () => { | ||
|  |         focused.value = initialValue; | ||
|  |       }, | ||
|  |       { immediate: true, flush: "post" } | ||
|  |     ); | ||
|  |     return { focused }; | ||
|  |   } | ||
|  | 
 | ||
|  |   function useFocusWithin(target, options = {}) { | ||
|  |     const activeElement = useActiveElement(options); | ||
|  |     const targetElement = vueDemi.computed(() => unrefElement(target)); | ||
|  |     const focused = vueDemi.computed(() => targetElement.value && activeElement.value ? targetElement.value.contains(activeElement.value) : false); | ||
|  |     return { focused }; | ||
|  |   } | ||
|  | 
 | ||
|  |   function useFps(options) { | ||
|  |     var _a; | ||
|  |     const fps = vueDemi.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 = vueDemi.computed(() => { | ||
|  |       var _a; | ||
|  |       return (_a = unrefElement(target)) != null ? _a : document == null ? void 0 : document.querySelector("html"); | ||
|  |     }); | ||
|  |     const isFullscreen = vueDemi.ref(false); | ||
|  |     const requestMethod = vueDemi.computed(() => { | ||
|  |       return [ | ||
|  |         "requestFullscreen", | ||
|  |         "webkitRequestFullscreen", | ||
|  |         "webkitEnterFullscreen", | ||
|  |         "webkitEnterFullScreen", | ||
|  |         "webkitRequestFullScreen", | ||
|  |         "mozRequestFullScreen", | ||
|  |         "msRequestFullscreen" | ||
|  |       ].find((m) => document && m in document || targetRef.value && m in targetRef.value); | ||
|  |     }); | ||
|  |     const exitMethod = vueDemi.computed(() => { | ||
|  |       return [ | ||
|  |         "exitFullscreen", | ||
|  |         "webkitExitFullscreen", | ||
|  |         "webkitExitFullScreen", | ||
|  |         "webkitCancelFullScreen", | ||
|  |         "mozCancelFullScreen", | ||
|  |         "msExitFullscreen" | ||
|  |       ].find((m) => document && m in document || targetRef.value && m in targetRef.value); | ||
|  |     }); | ||
|  |     const fullscreenEnabled = vueDemi.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); | ||
|  |     const isSupported = useSupported(() => targetRef.value && document && requestMethod.value !== void 0 && exitMethod.value !== void 0 && fullscreenEnabled.value !== void 0); | ||
|  |     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() { | ||
|  |       if (!isSupported.value || !isFullscreen.value) | ||
|  |         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() { | ||
|  |       if (!isSupported.value || isFullscreen.value) | ||
|  |         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) | ||
|  |       shared.tryOnScopeDispose(exit); | ||
|  |     return { | ||
|  |       isSupported, | ||
|  |       isFullscreen, | ||
|  |       enter, | ||
|  |       exit, | ||
|  |       toggle | ||
|  |     }; | ||
|  |   } | ||
|  | 
 | ||
|  |   function mapGamepadToXbox360Controller(gamepad) { | ||
|  |     return vueDemi.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 = vueDemi.ref([]); | ||
|  |     const onConnectedHook = shared.createEventHook(); | ||
|  |     const onDisconnectedHook = shared.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 { | ||
|  |         ...gamepad, | ||
|  |         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)); | ||
|  |     shared.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 = vueDemi.ref(null); | ||
|  |     const error = vueDemi.shallowRef(null); | ||
|  |     const coords = vueDemi.ref({ | ||
|  |       accuracy: 0, | ||
|  |       latitude: Number.POSITIVE_INFINITY, | ||
|  |       longitude: Number.POSITIVE_INFINITY, | ||
|  |       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); | ||
|  |     } | ||
|  |     shared.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 = shared.throttleFilter(50) | ||
|  |     } = options; | ||
|  |     const idle = vueDemi.ref(initialState); | ||
|  |     const lastActive = vueDemi.ref(shared.timestamp()); | ||
|  |     let timer; | ||
|  |     const reset = () => { | ||
|  |       idle.value = false; | ||
|  |       clearTimeout(timer); | ||
|  |       timer = setTimeout(() => idle.value = true, timeout); | ||
|  |     }; | ||
|  |     const onEvent = shared.createFilterWrapper( | ||
|  |       eventFilter, | ||
|  |       () => { | ||
|  |         lastActive.value = shared.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(); | ||
|  |       const { src, srcset, sizes, class: clazz, loading, crossorigin, referrerPolicy } = options; | ||
|  |       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; | ||
|  |       if (referrerPolicy) | ||
|  |         img.referrerPolicy = referrerPolicy; | ||
|  |       img.onload = () => resolve(img); | ||
|  |       img.onerror = reject; | ||
|  |     }); | ||
|  |   } | ||
|  |   function useImage(options, asyncStateOptions = {}) { | ||
|  |     const state = useAsyncState( | ||
|  |       () => loadImage(shared.toValue(options)), | ||
|  |       void 0, | ||
|  |       { | ||
|  |         resetOnExecute: true, | ||
|  |         ...asyncStateOptions | ||
|  |       } | ||
|  |     ); | ||
|  |     vueDemi.watch( | ||
|  |       () => shared.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 = shared.noop, | ||
|  |       onScroll = shared.noop, | ||
|  |       offset = { | ||
|  |         left: 0, | ||
|  |         right: 0, | ||
|  |         top: 0, | ||
|  |         bottom: 0 | ||
|  |       }, | ||
|  |       eventListenerOptions = { | ||
|  |         capture: false, | ||
|  |         passive: true | ||
|  |       }, | ||
|  |       behavior = "auto", | ||
|  |       window = defaultWindow | ||
|  |     } = options; | ||
|  |     const internalX = vueDemi.ref(0); | ||
|  |     const internalY = vueDemi.ref(0); | ||
|  |     const x = vueDemi.computed({ | ||
|  |       get() { | ||
|  |         return internalX.value; | ||
|  |       }, | ||
|  |       set(x2) { | ||
|  |         scrollTo(x2, void 0); | ||
|  |       } | ||
|  |     }); | ||
|  |     const y = vueDemi.computed({ | ||
|  |       get() { | ||
|  |         return internalY.value; | ||
|  |       }, | ||
|  |       set(y2) { | ||
|  |         scrollTo(void 0, y2); | ||
|  |       } | ||
|  |     }); | ||
|  |     function scrollTo(_x, _y) { | ||
|  |       var _a, _b, _c; | ||
|  |       if (!window) | ||
|  |         return; | ||
|  |       const _element = shared.toValue(element); | ||
|  |       if (!_element) | ||
|  |         return; | ||
|  |       (_c = _element instanceof Document ? window.document.body : _element) == null ? void 0 : _c.scrollTo({ | ||
|  |         top: (_a = shared.toValue(_y)) != null ? _a : y.value, | ||
|  |         left: (_b = shared.toValue(_x)) != null ? _b : x.value, | ||
|  |         behavior: shared.toValue(behavior) | ||
|  |       }); | ||
|  |     } | ||
|  |     const isScrolling = vueDemi.ref(false); | ||
|  |     const arrivedState = vueDemi.reactive({ | ||
|  |       left: true, | ||
|  |       right: false, | ||
|  |       top: true, | ||
|  |       bottom: false | ||
|  |     }); | ||
|  |     const directions = vueDemi.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 = shared.useDebounceFn(onScrollEnd, throttle + idle); | ||
|  |     const setArrivedState = (target) => { | ||
|  |       var _a; | ||
|  |       if (!window) | ||
|  |         return; | ||
|  |       const el = target.document ? target.document.documentElement : (_a = target.documentElement) != null ? _a : target; | ||
|  |       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; | ||
|  |       if (target === window.document && !scrollTop) | ||
|  |         scrollTop = window.document.body.scrollTop; | ||
|  |       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) => { | ||
|  |       var _a; | ||
|  |       if (!window) | ||
|  |         return; | ||
|  |       const eventTarget = (_a = e.target.documentElement) != null ? _a : e.target; | ||
|  |       setArrivedState(eventTarget); | ||
|  |       isScrolling.value = true; | ||
|  |       onScrollEndDebounced(e); | ||
|  |       onScroll(e); | ||
|  |     }; | ||
|  |     useEventListener( | ||
|  |       element, | ||
|  |       "scroll", | ||
|  |       throttle ? shared.useThrottleFn(onScrollHandler, throttle, true, false) : onScrollHandler, | ||
|  |       eventListenerOptions | ||
|  |     ); | ||
|  |     shared.tryOnMounted(() => { | ||
|  |       const _element = shared.toValue(element); | ||
|  |       if (!_element) | ||
|  |         return; | ||
|  |       setArrivedState(_element); | ||
|  |     }); | ||
|  |     useEventListener( | ||
|  |       element, | ||
|  |       "scrollend", | ||
|  |       onScrollEnd, | ||
|  |       eventListenerOptions | ||
|  |     ); | ||
|  |     return { | ||
|  |       x, | ||
|  |       y, | ||
|  |       isScrolling, | ||
|  |       arrivedState, | ||
|  |       directions, | ||
|  |       measure() { | ||
|  |         const _element = shared.toValue(element); | ||
|  |         if (window && _element) | ||
|  |           setArrivedState(_element); | ||
|  |       } | ||
|  |     }; | ||
|  |   } | ||
|  | 
 | ||
|  |   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; | ||
|  |   } | ||
|  | 
 | ||
|  |   function useInfiniteScroll(element, onLoadMore, options = {}) { | ||
|  |     var _a; | ||
|  |     const { | ||
|  |       direction = "bottom", | ||
|  |       interval = 100, | ||
|  |       canLoadMore = () => true | ||
|  |     } = options; | ||
|  |     const state = vueDemi.reactive(useScroll( | ||
|  |       element, | ||
|  |       { | ||
|  |         ...options, | ||
|  |         offset: { | ||
|  |           [direction]: (_a = options.distance) != null ? _a : 0, | ||
|  |           ...options.offset | ||
|  |         } | ||
|  |       } | ||
|  |     )); | ||
|  |     const promise = vueDemi.ref(); | ||
|  |     const isLoading = vueDemi.computed(() => !!promise.value); | ||
|  |     const observedElement = vueDemi.computed(() => { | ||
|  |       return resolveElement(shared.toValue(element)); | ||
|  |     }); | ||
|  |     const isElementVisible = useElementVisibility(observedElement); | ||
|  |     function checkAndLoad() { | ||
|  |       state.measure(); | ||
|  |       if (!observedElement.value || !isElementVisible.value || !canLoadMore(observedElement.value)) | ||
|  |         return; | ||
|  |       const { scrollHeight, clientHeight, scrollWidth, clientWidth } = observedElement.value; | ||
|  |       const isNarrower = direction === "bottom" || direction === "top" ? scrollHeight <= clientHeight : scrollWidth <= clientWidth; | ||
|  |       if (state.arrivedState[direction] || isNarrower) { | ||
|  |         if (!promise.value) { | ||
|  |           promise.value = Promise.all([ | ||
|  |             onLoadMore(state), | ||
|  |             new Promise((resolve) => setTimeout(resolve, interval)) | ||
|  |           ]).finally(() => { | ||
|  |             promise.value = null; | ||
|  |             vueDemi.nextTick(() => checkAndLoad()); | ||
|  |           }); | ||
|  |         } | ||
|  |       } | ||
|  |     } | ||
|  |     vueDemi.watch( | ||
|  |       () => [state.arrivedState[direction], isElementVisible.value], | ||
|  |       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 = vueDemi.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 = shared.noop | ||
|  |     } = options; | ||
|  |     const current = vueDemi.reactive(/* @__PURE__ */ new Set()); | ||
|  |     const obj = { | ||
|  |       toJSON() { | ||
|  |         return {}; | ||
|  |       }, | ||
|  |       current | ||
|  |     }; | ||
|  |     const refs = useReactive ? vueDemi.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] = vueDemi.computed(() => keys.every((key) => shared.toValue(proxy[key]))); | ||
|  |             } else { | ||
|  |               refs[prop] = vueDemi.ref(false); | ||
|  |             } | ||
|  |           } | ||
|  |           const r = Reflect.get(target2, prop, rec); | ||
|  |           return useReactive ? shared.toValue(r) : r; | ||
|  |         } | ||
|  |       } | ||
|  |     ); | ||
|  |     return proxy; | ||
|  |   } | ||
|  | 
 | ||
|  |   function usingElRef(source, cb) { | ||
|  |     if (shared.toValue(source)) | ||
|  |       cb(shared.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 = {}) { | ||
|  |     options = { | ||
|  |       ...defaultOptions, | ||
|  |       ...options | ||
|  |     }; | ||
|  |     const { | ||
|  |       document = defaultDocument | ||
|  |     } = options; | ||
|  |     const currentTime = vueDemi.ref(0); | ||
|  |     const duration = vueDemi.ref(0); | ||
|  |     const seeking = vueDemi.ref(false); | ||
|  |     const volume = vueDemi.ref(1); | ||
|  |     const waiting = vueDemi.ref(false); | ||
|  |     const ended = vueDemi.ref(false); | ||
|  |     const playing = vueDemi.ref(false); | ||
|  |     const rate = vueDemi.ref(1); | ||
|  |     const stalled = vueDemi.ref(false); | ||
|  |     const buffered = vueDemi.ref([]); | ||
|  |     const tracks = vueDemi.ref([]); | ||
|  |     const selectedTrack = vueDemi.ref(-1); | ||
|  |     const isPictureInPicture = vueDemi.ref(false); | ||
|  |     const muted = vueDemi.ref(false); | ||
|  |     const supportsPictureInPicture = document && "pictureInPictureEnabled" in document; | ||
|  |     const sourceErrorEvent = shared.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); | ||
|  |             } | ||
|  |           } | ||
|  |         }); | ||
|  |       }); | ||
|  |     }; | ||
|  |     vueDemi.watchEffect(() => { | ||
|  |       if (!document) | ||
|  |         return; | ||
|  |       const el = shared.toValue(target); | ||
|  |       if (!el) | ||
|  |         return; | ||
|  |       const src = shared.toValue(options.src); | ||
|  |       let sources = []; | ||
|  |       if (!src) | ||
|  |         return; | ||
|  |       if (typeof src === "string") | ||
|  |         sources = [{ src }]; | ||
|  |       else if (Array.isArray(src)) | ||
|  |         sources = src; | ||
|  |       else if (shared.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(); | ||
|  |     }); | ||
|  |     shared.tryOnScopeDispose(() => { | ||
|  |       const el = shared.toValue(target); | ||
|  |       if (!el) | ||
|  |         return; | ||
|  |       el.querySelectorAll("source").forEach((e) => e.removeEventListener("error", sourceErrorEvent.trigger)); | ||
|  |     }); | ||
|  |     vueDemi.watch([target, volume], () => { | ||
|  |       const el = shared.toValue(target); | ||
|  |       if (!el) | ||
|  |         return; | ||
|  |       el.volume = volume.value; | ||
|  |     }); | ||
|  |     vueDemi.watch([target, muted], () => { | ||
|  |       const el = shared.toValue(target); | ||
|  |       if (!el) | ||
|  |         return; | ||
|  |       el.muted = muted.value; | ||
|  |     }); | ||
|  |     vueDemi.watch([target, rate], () => { | ||
|  |       const el = shared.toValue(target); | ||
|  |       if (!el) | ||
|  |         return; | ||
|  |       el.playbackRate = rate.value; | ||
|  |     }); | ||
|  |     vueDemi.watchEffect(() => { | ||
|  |       if (!document) | ||
|  |         return; | ||
|  |       const textTracks = shared.toValue(options.tracks); | ||
|  |       const el = shared.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 } = shared.watchIgnorable(currentTime, (time) => { | ||
|  |       const el = shared.toValue(target); | ||
|  |       if (!el) | ||
|  |         return; | ||
|  |       el.currentTime = time; | ||
|  |     }); | ||
|  |     const { ignoreUpdates: ignorePlayingUpdates } = shared.watchIgnorable(playing, (isPlaying) => { | ||
|  |       const el = shared.toValue(target); | ||
|  |       if (!el) | ||
|  |         return; | ||
|  |       isPlaying ? el.play() : el.pause(); | ||
|  |     }); | ||
|  |     useEventListener(target, "timeupdate", () => ignoreCurrentTimeUpdates(() => currentTime.value = shared.toValue(target).currentTime)); | ||
|  |     useEventListener(target, "durationchange", () => duration.value = shared.toValue(target).duration); | ||
|  |     useEventListener(target, "progress", () => buffered.value = timeRangeToArray(shared.toValue(target).buffered)); | ||
|  |     useEventListener(target, "seeking", () => seeking.value = true); | ||
|  |     useEventListener(target, "seeked", () => seeking.value = false); | ||
|  |     useEventListener(target, ["waiting", "loadstart"], () => { | ||
|  |       waiting.value = true; | ||
|  |       ignorePlayingUpdates(() => playing.value = false); | ||
|  |     }); | ||
|  |     useEventListener(target, "loadeddata", () => waiting.value = false); | ||
|  |     useEventListener(target, "playing", () => { | ||
|  |       waiting.value = false; | ||
|  |       ended.value = false; | ||
|  |       ignorePlayingUpdates(() => playing.value = true); | ||
|  |     }); | ||
|  |     useEventListener(target, "ratechange", () => rate.value = shared.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 = shared.toValue(target); | ||
|  |       if (!el) | ||
|  |         return; | ||
|  |       volume.value = el.volume; | ||
|  |       muted.value = el.muted; | ||
|  |     }); | ||
|  |     const listeners = []; | ||
|  |     const stop = vueDemi.watch([target], () => { | ||
|  |       const el = shared.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)); | ||
|  |     }); | ||
|  |     shared.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 = vueDemi.shallowReactive({}); | ||
|  |     return { | ||
|  |       get: (key) => data[key], | ||
|  |       set: (key, value) => vueDemi.set(data, key, value), | ||
|  |       has: (key) => shared.hasOwn(data, key), | ||
|  |       delete: (key) => vueDemi.del(data, key), | ||
|  |       clear: () => { | ||
|  |         Object.keys(data).forEach((key) => { | ||
|  |           vueDemi.del(data, key); | ||
|  |         }); | ||
|  |       } | ||
|  |     }; | ||
|  |   } | ||
|  |   function useMemoize(resolver, options) { | ||
|  |     const initCache = () => { | ||
|  |       if (options == null ? void 0 : options.cache) | ||
|  |         return vueDemi.shallowReactive(options.cache); | ||
|  |       if (vueDemi.isVue2) | ||
|  |         return getMapVue2Compat(); | ||
|  |       return vueDemi.shallowReactive(/* @__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 = vueDemi.ref(); | ||
|  |     const isSupported = useSupported(() => typeof performance !== "undefined" && "memory" in performance); | ||
|  |     if (isSupported.value) { | ||
|  |       const { interval = 1e3 } = options; | ||
|  |       shared.useIntervalFn(() => { | ||
|  |         memory.value = performance.memory; | ||
|  |       }, interval, { immediate: options.immediate, immediateCallback: options.immediateCallback }); | ||
|  |     } | ||
|  |     return { isSupported, memory }; | ||
|  |   } | ||
|  | 
 | ||
|  |   const UseMouseBuiltinExtractors = { | ||
|  |     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, | ||
|  |       scroll = true, | ||
|  |       eventFilter | ||
|  |     } = options; | ||
|  |     let _prevMouseEvent = null; | ||
|  |     const x = vueDemi.ref(initialValue.x); | ||
|  |     const y = vueDemi.ref(initialValue.y); | ||
|  |     const sourceType = vueDemi.ref(null); | ||
|  |     const extractor = typeof type === "function" ? type : UseMouseBuiltinExtractors[type]; | ||
|  |     const mouseHandler = (event) => { | ||
|  |       const result = extractor(event); | ||
|  |       _prevMouseEvent = event; | ||
|  |       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"; | ||
|  |         } | ||
|  |       } | ||
|  |     }; | ||
|  |     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; | ||
|  |       } | ||
|  |     }; | ||
|  |     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); | ||
|  |     const scrollHandlerWrapper = eventFilter ? () => eventFilter(() => scrollHandler(), {}) : () => scrollHandler(); | ||
|  |     if (target) { | ||
|  |       const listenerOptions = { passive: true }; | ||
|  |       useEventListener(target, ["mousemove", "dragover"], mouseHandlerWrapper, listenerOptions); | ||
|  |       if (touch && type !== "movement") { | ||
|  |         useEventListener(target, ["touchstart", "touchmove"], touchHandlerWrapper, listenerOptions); | ||
|  |         if (resetOnTouchEnds) | ||
|  |           useEventListener(target, "touchend", reset, listenerOptions); | ||
|  |       } | ||
|  |       if (scroll && type === "page") | ||
|  |         useEventListener(window, "scroll", scrollHandlerWrapper, { passive: true }); | ||
|  |     } | ||
|  |     return { | ||
|  |       x, | ||
|  |       y, | ||
|  |       sourceType | ||
|  |     }; | ||
|  |   } | ||
|  | 
 | ||
|  |   function useMouseInElement(target, options = {}) { | ||
|  |     const { | ||
|  |       handleOutside = true, | ||
|  |       window = defaultWindow | ||
|  |     } = options; | ||
|  |     const type = options.type || "page"; | ||
|  |     const { x, y, sourceType } = useMouse(options); | ||
|  |     const targetRef = vueDemi.ref(target != null ? target : window == null ? void 0 : window.document.body); | ||
|  |     const elementX = vueDemi.ref(0); | ||
|  |     const elementY = vueDemi.ref(0); | ||
|  |     const elementPositionX = vueDemi.ref(0); | ||
|  |     const elementPositionY = vueDemi.ref(0); | ||
|  |     const elementHeight = vueDemi.ref(0); | ||
|  |     const elementWidth = vueDemi.ref(0); | ||
|  |     const isOutside = vueDemi.ref(true); | ||
|  |     let stop = () => { | ||
|  |     }; | ||
|  |     if (window) { | ||
|  |       stop = vueDemi.watch( | ||
|  |         [targetRef, x, y], | ||
|  |         () => { | ||
|  |           const el = unrefElement(targetRef); | ||
|  |           if (!el) | ||
|  |             return; | ||
|  |           const { | ||
|  |             left, | ||
|  |             top, | ||
|  |             width, | ||
|  |             height | ||
|  |           } = el.getBoundingClientRect(); | ||
|  |           elementPositionX.value = left + (type === "page" ? window.pageXOffset : 0); | ||
|  |           elementPositionY.value = top + (type === "page" ? window.pageYOffset : 0); | ||
|  |           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, | ||
|  |       capture = false, | ||
|  |       initialValue = false, | ||
|  |       window = defaultWindow | ||
|  |     } = options; | ||
|  |     const pressed = vueDemi.ref(initialValue); | ||
|  |     const sourceType = vueDemi.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 = vueDemi.computed(() => unrefElement(options.target) || window); | ||
|  |     useEventListener(target, "mousedown", onPressed("mouse"), { passive: true, capture }); | ||
|  |     useEventListener(window, "mouseleave", onReleased, { passive: true, capture }); | ||
|  |     useEventListener(window, "mouseup", onReleased, { passive: true, capture }); | ||
|  |     if (drag) { | ||
|  |       useEventListener(target, "dragstart", onPressed("mouse"), { passive: true, capture }); | ||
|  |       useEventListener(window, "drop", onReleased, { passive: true, capture }); | ||
|  |       useEventListener(window, "dragend", onReleased, { passive: true, capture }); | ||
|  |     } | ||
|  |     if (touch) { | ||
|  |       useEventListener(target, "touchstart", onPressed("touch"), { passive: true, capture }); | ||
|  |       useEventListener(window, "touchend", onReleased, { passive: true, capture }); | ||
|  |       useEventListener(window, "touchcancel", onReleased, { passive: true, capture }); | ||
|  |     } | ||
|  |     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 = vueDemi.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 = vueDemi.ref(true); | ||
|  |     const saveData = vueDemi.ref(false); | ||
|  |     const offlineAt = vueDemi.ref(void 0); | ||
|  |     const onlineAt = vueDemi.ref(void 0); | ||
|  |     const downlink = vueDemi.ref(void 0); | ||
|  |     const downlinkMax = vueDemi.ref(void 0); | ||
|  |     const rtt = vueDemi.ref(void 0); | ||
|  |     const effectiveType = vueDemi.ref(void 0); | ||
|  |     const type = vueDemi.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 = vueDemi.ref(/* @__PURE__ */ new Date()); | ||
|  |     const update = () => now.value = /* @__PURE__ */ new Date(); | ||
|  |     const controls = interval === "requestAnimationFrame" ? useRafFn(update, { immediate: true }) : shared.useIntervalFn(update, interval, { immediate: true }); | ||
|  |     if (exposeControls) { | ||
|  |       return { | ||
|  |         now, | ||
|  |         ...controls | ||
|  |       }; | ||
|  |     } else { | ||
|  |       return now; | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   function useObjectUrl(object) { | ||
|  |     const url = vueDemi.ref(); | ||
|  |     const release = () => { | ||
|  |       if (url.value) | ||
|  |         URL.revokeObjectURL(url.value); | ||
|  |       url.value = void 0; | ||
|  |     }; | ||
|  |     vueDemi.watch( | ||
|  |       () => shared.toValue(object), | ||
|  |       (newObject) => { | ||
|  |         release(); | ||
|  |         if (newObject) | ||
|  |           url.value = URL.createObjectURL(newObject); | ||
|  |       }, | ||
|  |       { immediate: true } | ||
|  |     ); | ||
|  |     shared.tryOnScopeDispose(release); | ||
|  |     return vueDemi.readonly(url); | ||
|  |   } | ||
|  | 
 | ||
|  |   function useClamp(value, min, max) { | ||
|  |     if (typeof value === "function" || vueDemi.isReadonly(value)) | ||
|  |       return vueDemi.computed(() => shared.clamp(shared.toValue(value), shared.toValue(min), shared.toValue(max))); | ||
|  |     const _value = vueDemi.ref(value); | ||
|  |     return vueDemi.computed({ | ||
|  |       get() { | ||
|  |         return _value.value = shared.clamp(_value.value, shared.toValue(min), shared.toValue(max)); | ||
|  |       }, | ||
|  |       set(value2) { | ||
|  |         _value.value = shared.clamp(value2, shared.toValue(min), shared.toValue(max)); | ||
|  |       } | ||
|  |     }); | ||
|  |   } | ||
|  | 
 | ||
|  |   function useOffsetPagination(options) { | ||
|  |     const { | ||
|  |       total = Number.POSITIVE_INFINITY, | ||
|  |       pageSize = 10, | ||
|  |       page = 1, | ||
|  |       onPageChange = shared.noop, | ||
|  |       onPageSizeChange = shared.noop, | ||
|  |       onPageCountChange = shared.noop | ||
|  |     } = options; | ||
|  |     const currentPageSize = useClamp(pageSize, 1, Number.POSITIVE_INFINITY); | ||
|  |     const pageCount = vueDemi.computed(() => Math.max( | ||
|  |       1, | ||
|  |       Math.ceil(shared.toValue(total) / shared.toValue(currentPageSize)) | ||
|  |     )); | ||
|  |     const currentPage = useClamp(page, 1, pageCount); | ||
|  |     const isFirstPage = vueDemi.computed(() => currentPage.value === 1); | ||
|  |     const isLastPage = vueDemi.computed(() => currentPage.value === pageCount.value); | ||
|  |     if (vueDemi.isRef(page)) { | ||
|  |       shared.syncRef(page, currentPage, { | ||
|  |         direction: vueDemi.isReadonly(page) ? "ltr" : "both" | ||
|  |       }); | ||
|  |     } | ||
|  |     if (vueDemi.isRef(pageSize)) { | ||
|  |       shared.syncRef(pageSize, currentPageSize, { | ||
|  |         direction: vueDemi.isReadonly(pageSize) ? "ltr" : "both" | ||
|  |       }); | ||
|  |     } | ||
|  |     function prev() { | ||
|  |       currentPage.value--; | ||
|  |     } | ||
|  |     function next() { | ||
|  |       currentPage.value++; | ||
|  |     } | ||
|  |     const returnValue = { | ||
|  |       currentPage, | ||
|  |       currentPageSize, | ||
|  |       pageCount, | ||
|  |       isFirstPage, | ||
|  |       isLastPage, | ||
|  |       prev, | ||
|  |       next | ||
|  |     }; | ||
|  |     vueDemi.watch(currentPage, () => { | ||
|  |       onPageChange(vueDemi.reactive(returnValue)); | ||
|  |     }); | ||
|  |     vueDemi.watch(currentPageSize, () => { | ||
|  |       onPageSizeChange(vueDemi.reactive(returnValue)); | ||
|  |     }); | ||
|  |     vueDemi.watch(pageCount, () => { | ||
|  |       onPageCountChange(vueDemi.reactive(returnValue)); | ||
|  |     }); | ||
|  |     return returnValue; | ||
|  |   } | ||
|  | 
 | ||
|  |   function useOnline(options = {}) { | ||
|  |     const { isOnline } = useNetwork(options); | ||
|  |     return isOnline; | ||
|  |   } | ||
|  | 
 | ||
|  |   function usePageLeave(options = {}) { | ||
|  |     const { window = defaultWindow } = options; | ||
|  |     const isLeft = vueDemi.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 = vueDemi.reactive(useDeviceOrientation({ window })); | ||
|  |     const { | ||
|  |       elementX: x, | ||
|  |       elementY: y, | ||
|  |       elementWidth: width, | ||
|  |       elementHeight: height | ||
|  |     } = useMouseInElement(target, { handleOutside: false, window }); | ||
|  |     const source = vueDemi.computed(() => { | ||
|  |       if (orientation.isSupported && (orientation.alpha != null && orientation.alpha !== 0 || orientation.gamma != null && orientation.gamma !== 0)) | ||
|  |         return "deviceOrientation"; | ||
|  |       return "mouse"; | ||
|  |     }); | ||
|  |     const roll = vueDemi.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 = vueDemi.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 = vueDemi.shallowRef(); | ||
|  |     const update = () => { | ||
|  |       const el = unrefElement(element); | ||
|  |       if (el) | ||
|  |         parentElement.value = el.parentElement; | ||
|  |     }; | ||
|  |     shared.tryOnMounted(update); | ||
|  |     vueDemi.watch(() => shared.toValue(element), update); | ||
|  |     return parentElement; | ||
|  |   } | ||
|  | 
 | ||
|  |   function usePerformanceObserver(options, callback) { | ||
|  |     const { | ||
|  |       window = defaultWindow, | ||
|  |       immediate = true, | ||
|  |       ...performanceOptions | ||
|  |     } = options; | ||
|  |     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); | ||
|  |       } | ||
|  |     }; | ||
|  |     shared.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 = vueDemi.ref(false); | ||
|  |     const state = vueDemi.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 = shared.objectPick(event, keys, false); | ||
|  |     }; | ||
|  |     if (target) { | ||
|  |       const listenerOptions = { passive: true }; | ||
|  |       useEventListener(target, ["pointerdown", "pointermove", "pointerup"], handler, listenerOptions); | ||
|  |       useEventListener(target, "pointerleave", () => isInside.value = false, listenerOptions); | ||
|  |     } | ||
|  |     return { | ||
|  |       ...shared.toRefs(state), | ||
|  |       isInside | ||
|  |     }; | ||
|  |   } | ||
|  | 
 | ||
|  |   function usePointerLock(target, options = {}) { | ||
|  |     const { document = defaultDocument, pointerLockOptions } = options; | ||
|  |     const isSupported = useSupported(() => document && "pointerLockElement" in document); | ||
|  |     const element = vueDemi.ref(); | ||
|  |     const triggerElement = vueDemi.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 shared.until(element).toBe(targetElement); | ||
|  |     } | ||
|  |     async function unlock() { | ||
|  |       if (!element.value) | ||
|  |         return false; | ||
|  |       document.exitPointerLock(); | ||
|  |       await shared.until(element).toBeNull(); | ||
|  |       return true; | ||
|  |     } | ||
|  |     return { | ||
|  |       isSupported, | ||
|  |       element, | ||
|  |       triggerElement, | ||
|  |       lock, | ||
|  |       unlock | ||
|  |     }; | ||
|  |   } | ||
|  | 
 | ||
|  |   function usePointerSwipe(target, options = {}) { | ||
|  |     const targetRef = shared.toRef(target); | ||
|  |     const { | ||
|  |       threshold = 50, | ||
|  |       onSwipe, | ||
|  |       onSwipeEnd, | ||
|  |       onSwipeStart, | ||
|  |       disableTextSelect = false | ||
|  |     } = options; | ||
|  |     const posStart = vueDemi.reactive({ x: 0, y: 0 }); | ||
|  |     const updatePosStart = (x, y) => { | ||
|  |       posStart.x = x; | ||
|  |       posStart.y = y; | ||
|  |     }; | ||
|  |     const posEnd = vueDemi.reactive({ x: 0, y: 0 }); | ||
|  |     const updatePosEnd = (x, y) => { | ||
|  |       posEnd.x = x; | ||
|  |       posEnd.y = y; | ||
|  |     }; | ||
|  |     const distanceX = vueDemi.computed(() => posStart.x - posEnd.x); | ||
|  |     const distanceY = vueDemi.computed(() => posStart.y - posEnd.y); | ||
|  |     const { max, abs } = Math; | ||
|  |     const isThresholdExceeded = vueDemi.computed(() => max(abs(distanceX.value), abs(distanceY.value)) >= threshold); | ||
|  |     const isSwiping = vueDemi.ref(false); | ||
|  |     const isPointerDown = vueDemi.ref(false); | ||
|  |     const direction = vueDemi.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) => { | ||
|  |         if (!eventIsAllowed(e)) | ||
|  |           return; | ||
|  |         isPointerDown.value = true; | ||
|  |         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) => { | ||
|  |         if (!eventIsAllowed(e)) | ||
|  |           return; | ||
|  |         if (isSwiping.value) | ||
|  |           onSwipeEnd == null ? void 0 : onSwipeEnd(e, direction.value); | ||
|  |         isPointerDown.value = false; | ||
|  |         isSwiping.value = false; | ||
|  |       }) | ||
|  |     ]; | ||
|  |     shared.tryOnMounted(() => { | ||
|  |       var _a, _b, _c, _d, _e, _f, _g, _h; | ||
|  |       (_b = (_a = targetRef.value) == null ? void 0 : _a.style) == null ? void 0 : _b.setProperty("touch-action", "none"); | ||
|  |       if (disableTextSelect) { | ||
|  |         (_d = (_c = targetRef.value) == null ? void 0 : _c.style) == null ? void 0 : _d.setProperty("-webkit-user-select", "none"); | ||
|  |         (_f = (_e = targetRef.value) == null ? void 0 : _e.style) == null ? void 0 : _f.setProperty("-ms-user-select", "none"); | ||
|  |         (_h = (_g = targetRef.value) == null ? void 0 : _g.style) == null ? void 0 : _h.setProperty("user-select", "none"); | ||
|  |       } | ||
|  |     }); | ||
|  |     const stop = () => stops.forEach((s) => s()); | ||
|  |     return { | ||
|  |       isSwiping: vueDemi.readonly(isSwiping), | ||
|  |       direction: vueDemi.readonly(direction), | ||
|  |       posStart: vueDemi.readonly(posStart), | ||
|  |       posEnd: vueDemi.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 vueDemi.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 vueDemi.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 vueDemi.ref(["en"]); | ||
|  |     const navigator = window.navigator; | ||
|  |     const value = vueDemi.ref(navigator.languages); | ||
|  |     useEventListener(window, "languagechange", () => { | ||
|  |       value.value = navigator.languages; | ||
|  |     }); | ||
|  |     return value; | ||
|  |   } | ||
|  | 
 | ||
|  |   function usePreferredReducedMotion(options) { | ||
|  |     const isReduced = useMediaQuery("(prefers-reduced-motion: reduce)", options); | ||
|  |     return vueDemi.computed(() => { | ||
|  |       if (isReduced.value) | ||
|  |         return "reduce"; | ||
|  |       return "no-preference"; | ||
|  |     }); | ||
|  |   } | ||
|  | 
 | ||
|  |   function usePrevious(value, initialValue) { | ||
|  |     const previous = vueDemi.shallowRef(initialValue); | ||
|  |     vueDemi.watch( | ||
|  |       shared.toRef(value), | ||
|  |       (_, oldValue) => { | ||
|  |         previous.value = oldValue; | ||
|  |       }, | ||
|  |       { flush: "sync" } | ||
|  |     ); | ||
|  |     return vueDemi.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 = vueDemi.ref(screenOrientation.type); | ||
|  |     const angle = vueDemi.ref(screenOrientation.angle || 0); | ||
|  |     if (isSupported.value) { | ||
|  |       useEventListener(window, "orientationchange", () => { | ||
|  |         orientation.value = screenOrientation.type; | ||
|  |         angle.value = screenOrientation.angle; | ||
|  |       }); | ||
|  |     } | ||
|  |     const lockOrientation = (type) => { | ||
|  |       if (isSupported.value && typeof screenOrientation.lock === "function") | ||
|  |         return screenOrientation.lock(type); | ||
|  |       return Promise.reject(new Error("Not supported")); | ||
|  |     }; | ||
|  |     const unlockOrientation = () => { | ||
|  |       if (isSupported.value && typeof screenOrientation.unlock === "function") | ||
|  |         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 = vueDemi.ref(""); | ||
|  |     const right = vueDemi.ref(""); | ||
|  |     const bottom = vueDemi.ref(""); | ||
|  |     const left = vueDemi.ref(""); | ||
|  |     if (shared.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", shared.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 = shared.noop, options = {}) { | ||
|  |     const { | ||
|  |       immediate = true, | ||
|  |       manual = false, | ||
|  |       type = "text/javascript", | ||
|  |       async = true, | ||
|  |       crossOrigin, | ||
|  |       referrerPolicy, | ||
|  |       noModule, | ||
|  |       defer, | ||
|  |       document = defaultDocument, | ||
|  |       attrs = {} | ||
|  |     } = options; | ||
|  |     const scriptTag = vueDemi.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="${shared.toValue(src)}"]`); | ||
|  |       if (!el) { | ||
|  |         el = document.createElement("script"); | ||
|  |         el.type = type; | ||
|  |         el.async = async; | ||
|  |         el.src = shared.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="${shared.toValue(src)}"]`); | ||
|  |       if (el) | ||
|  |         document.head.removeChild(el); | ||
|  |     }; | ||
|  |     if (immediate && !manual) | ||
|  |       shared.tryOnMounted(load); | ||
|  |     if (!manual) | ||
|  |       shared.tryOnUnmounted(unload); | ||
|  |     return { scriptTag, load, unload }; | ||
|  |   } | ||
|  | 
 | ||
|  |   function checkOverflowScroll(ele) { | ||
|  |     const style = window.getComputedStyle(ele); | ||
|  |     if (style.overflowX === "scroll" || style.overflowY === "scroll" || style.overflowX === "auto" && ele.clientWidth < ele.scrollWidth || style.overflowY === "auto" && ele.clientHeight < ele.scrollHeight) { | ||
|  |       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; | ||
|  |   } | ||
|  |   const elInitialOverflow = /* @__PURE__ */ new WeakMap(); | ||
|  |   function useScrollLock(element, initialState = false) { | ||
|  |     const isLocked = vueDemi.ref(initialState); | ||
|  |     let stopTouchMoveListener = null; | ||
|  |     let initialOverflow; | ||
|  |     vueDemi.watch(shared.toRef(element), (el) => { | ||
|  |       const target = resolveElement(shared.toValue(el)); | ||
|  |       if (target) { | ||
|  |         const ele = target; | ||
|  |         if (!elInitialOverflow.get(ele)) | ||
|  |           elInitialOverflow.set(ele, initialOverflow); | ||
|  |         if (isLocked.value) | ||
|  |           ele.style.overflow = "hidden"; | ||
|  |       } | ||
|  |     }, { | ||
|  |       immediate: true | ||
|  |     }); | ||
|  |     const lock = () => { | ||
|  |       const el = resolveElement(shared.toValue(element)); | ||
|  |       if (!el || isLocked.value) | ||
|  |         return; | ||
|  |       if (shared.isIOS) { | ||
|  |         stopTouchMoveListener = useEventListener( | ||
|  |           el, | ||
|  |           "touchmove", | ||
|  |           (e) => { | ||
|  |             preventDefault(e); | ||
|  |           }, | ||
|  |           { passive: false } | ||
|  |         ); | ||
|  |       } | ||
|  |       el.style.overflow = "hidden"; | ||
|  |       isLocked.value = true; | ||
|  |     }; | ||
|  |     const unlock = () => { | ||
|  |       var _a; | ||
|  |       const el = resolveElement(shared.toValue(element)); | ||
|  |       if (!el || !isLocked.value) | ||
|  |         return; | ||
|  |       shared.isIOS && (stopTouchMoveListener == null ? void 0 : stopTouchMoveListener()); | ||
|  |       el.style.overflow = (_a = elInitialOverflow.get(el)) != null ? _a : ""; | ||
|  |       elInitialOverflow.delete(el); | ||
|  |       isLocked.value = false; | ||
|  |     }; | ||
|  |     shared.tryOnScopeDispose(unlock); | ||
|  |     return vueDemi.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) { | ||
|  |         const data = { | ||
|  |           ...shared.toValue(shareOptions), | ||
|  |           ...shared.toValue(overrideOptions) | ||
|  |         }; | ||
|  |         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 vueDemi.computed(() => sortFn([...shared.toValue(source)], compareFn)); | ||
|  |     vueDemi.watchEffect(() => { | ||
|  |       const result = sortFn(shared.toValue(source), compareFn); | ||
|  |       if (vueDemi.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 = shared.toRef(options.lang || "en-US"); | ||
|  |     const isListening = vueDemi.ref(false); | ||
|  |     const isFinal = vueDemi.ref(false); | ||
|  |     const result = vueDemi.ref(""); | ||
|  |     const error = vueDemi.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 = shared.toValue(lang); | ||
|  |       recognition.onstart = () => { | ||
|  |         isFinal.value = false; | ||
|  |       }; | ||
|  |       vueDemi.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 = shared.toValue(lang); | ||
|  |       }; | ||
|  |       vueDemi.watch(isListening, () => { | ||
|  |         if (isListening.value) | ||
|  |           recognition.start(); | ||
|  |         else | ||
|  |           recognition.stop(); | ||
|  |       }); | ||
|  |     } | ||
|  |     shared.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 = vueDemi.ref(false); | ||
|  |     const status = vueDemi.ref("init"); | ||
|  |     const spokenText = shared.toRef(text || ""); | ||
|  |     const lang = shared.toRef(options.lang || "en-US"); | ||
|  |     const error = vueDemi.shallowRef(void 0); | ||
|  |     const toggle = (value = !isPlaying.value) => { | ||
|  |       isPlaying.value = value; | ||
|  |     }; | ||
|  |     const bindEventsForUtterance = (utterance2) => { | ||
|  |       utterance2.lang = shared.toValue(lang); | ||
|  |       utterance2.voice = shared.toValue(options.voice) || null; | ||
|  |       utterance2.pitch = shared.toValue(pitch); | ||
|  |       utterance2.rate = shared.toValue(rate); | ||
|  |       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 = vueDemi.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); | ||
|  |       vueDemi.watch(lang, (lang2) => { | ||
|  |         if (utterance.value && !isPlaying.value) | ||
|  |           utterance.value.lang = lang2; | ||
|  |       }); | ||
|  |       if (options.voice) { | ||
|  |         vueDemi.watch(options.voice, () => { | ||
|  |           synth.cancel(); | ||
|  |         }); | ||
|  |       } | ||
|  |       vueDemi.watch(isPlaying, () => { | ||
|  |         if (isPlaying.value) | ||
|  |           synth.resume(); | ||
|  |         else | ||
|  |           synth.pause(); | ||
|  |       }); | ||
|  |     } | ||
|  |     shared.tryOnScopeDispose(() => { | ||
|  |       isPlaying.value = false; | ||
|  |     }); | ||
|  |     return { | ||
|  |       isSupported, | ||
|  |       isPlaying, | ||
|  |       status, | ||
|  |       utterance, | ||
|  |       error, | ||
|  |       stop, | ||
|  |       toggle, | ||
|  |       speak | ||
|  |     }; | ||
|  |   } | ||
|  | 
 | ||
|  |   function useStepper(steps, initialStep) { | ||
|  |     const stepsRef = vueDemi.ref(steps); | ||
|  |     const stepNames = vueDemi.computed(() => Array.isArray(stepsRef.value) ? stepsRef.value : Object.keys(stepsRef.value)); | ||
|  |     const index = vueDemi.ref(stepNames.value.indexOf(initialStep != null ? initialStep : stepNames.value[0])); | ||
|  |     const current = vueDemi.computed(() => at(index.value)); | ||
|  |     const isFirst = vueDemi.computed(() => index.value === 0); | ||
|  |     const isLast = vueDemi.computed(() => index.value === stepNames.value.length - 1); | ||
|  |     const next = vueDemi.computed(() => stepNames.value[index.value + 1]); | ||
|  |     const previous = vueDemi.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 = shared.toValue(initialValue); | ||
|  |     const type = guessSerializerType(rawInit); | ||
|  |     const data = (shallow ? vueDemi.shallowRef : vueDemi.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)) | ||
|  |             data.value = { ...rawInit, ...value }; | ||
|  |           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) { | ||
|  |       shared.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 = vueDemi.ref(false); | ||
|  |     const { | ||
|  |       document = defaultDocument, | ||
|  |       immediate = true, | ||
|  |       manual = false, | ||
|  |       id = `vueuse_styletag_${++_id}` | ||
|  |     } = options; | ||
|  |     const cssRef = vueDemi.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 = vueDemi.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) | ||
|  |       shared.tryOnMounted(load); | ||
|  |     if (!manual) | ||
|  |       shared.tryOnScopeDispose(unload); | ||
|  |     return { | ||
|  |       id, | ||
|  |       css: cssRef, | ||
|  |       unload, | ||
|  |       load, | ||
|  |       isLoaded: vueDemi.readonly(isLoaded) | ||
|  |     }; | ||
|  |   } | ||
|  | 
 | ||
|  |   function useSwipe(target, options = {}) { | ||
|  |     const { | ||
|  |       threshold = 50, | ||
|  |       onSwipe, | ||
|  |       onSwipeEnd, | ||
|  |       onSwipeStart, | ||
|  |       passive = true, | ||
|  |       window = defaultWindow | ||
|  |     } = options; | ||
|  |     const coordsStart = vueDemi.reactive({ x: 0, y: 0 }); | ||
|  |     const coordsEnd = vueDemi.reactive({ x: 0, y: 0 }); | ||
|  |     const diffX = vueDemi.computed(() => coordsStart.x - coordsEnd.x); | ||
|  |     const diffY = vueDemi.computed(() => coordsStart.y - coordsEnd.y); | ||
|  |     const { max, abs } = Math; | ||
|  |     const isThresholdExceeded = vueDemi.computed(() => max(abs(diffX.value), abs(diffY.value)) >= threshold); | ||
|  |     const isSwiping = vueDemi.ref(false); | ||
|  |     const direction = vueDemi.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), | ||
|  |       useEventListener(target, ["touchend", "touchcancel"], onTouchEnd, listenerOptions) | ||
|  |     ]; | ||
|  |     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", shared.noop, optionsBlock); | ||
|  |     document.removeEventListener("x", shared.noop); | ||
|  |     return supportsPassive; | ||
|  |   } | ||
|  | 
 | ||
|  |   function useTemplateRefsList() { | ||
|  |     const refs = vueDemi.ref([]); | ||
|  |     refs.value.set = (el) => { | ||
|  |       if (el) | ||
|  |         refs.value.push(el); | ||
|  |     }; | ||
|  |     vueDemi.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 = vueDemi.ref(getValue()); | ||
|  |     shared.tryOnMounted(() => dir.value = getValue()); | ||
|  |     if (observe && document) { | ||
|  |       useMutationObserver( | ||
|  |         document.querySelector(selector), | ||
|  |         () => dir.value = getValue(), | ||
|  |         { attributes: true } | ||
|  |       ); | ||
|  |     } | ||
|  |     return vueDemi.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; | ||
|  |     return Array.from({ length: rangeCount }, (_, i) => selection.getRangeAt(i)); | ||
|  |   } | ||
|  |   function useTextSelection(options = {}) { | ||
|  |     const { | ||
|  |       window = defaultWindow | ||
|  |     } = options; | ||
|  |     const selection = vueDemi.ref(null); | ||
|  |     const text = vueDemi.computed(() => { | ||
|  |       var _a, _b; | ||
|  |       return (_b = (_a = selection.value) == null ? void 0 : _a.toString()) != null ? _b : ""; | ||
|  |     }); | ||
|  |     const ranges = vueDemi.computed(() => selection.value ? getRangesFromSelection(selection.value) : []); | ||
|  |     const rects = vueDemi.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 = vueDemi.ref(options == null ? void 0 : options.element); | ||
|  |     const input = vueDemi.ref(options == null ? void 0 : options.input); | ||
|  |     const textareaScrollHeight = vueDemi.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) | ||
|  |         shared.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); | ||
|  |     } | ||
|  |     vueDemi.watch([input, textarea], () => vueDemi.nextTick(triggerResize), { immediate: true }); | ||
|  |     useResizeObserver(textarea, () => triggerResize()); | ||
|  |     if (options == null ? void 0 : options.watch) | ||
|  |       vueDemi.watch(options.watch, triggerResize, { immediate: true, deep: true }); | ||
|  |     return { | ||
|  |       textarea, | ||
|  |       input, | ||
|  |       triggerResize | ||
|  |     }; | ||
|  |   } | ||
|  | 
 | ||
|  |   function useThrottledRefHistory(source, options = {}) { | ||
|  |     const { throttle = 200, trailing = true } = options; | ||
|  |     const filter = shared.throttleFilter(throttle, trailing); | ||
|  |     const history = useRefHistory(source, { ...options, eventFilter: filter }); | ||
|  |     return { | ||
|  |       ...history | ||
|  |     }; | ||
|  |   } | ||
|  | 
 | ||
|  |   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" }, | ||
|  |     { max: Number.POSITIVE_INFINITY, value: 31536e6, name: "year" } | ||
|  |   ]; | ||
|  |   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; | ||
|  |     const { now, ...controls } = useNow({ interval: updateInterval, controls: true }); | ||
|  |     const timeAgo = vueDemi.computed(() => formatTimeAgo(new Date(shared.toValue(time)), options, shared.toValue(now))); | ||
|  |     if (exposeControls) { | ||
|  |       return { | ||
|  |         timeAgo, | ||
|  |         ...controls | ||
|  |       }; | ||
|  |     } 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) { | ||
|  |     const { start } = shared.useTimeoutFn(loop, interval, { immediate: false }); | ||
|  |     const isActive = vueDemi.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(); | ||
|  |     shared.tryOnScopeDispose(pause); | ||
|  |     return { | ||
|  |       isActive, | ||
|  |       pause, | ||
|  |       resume | ||
|  |     }; | ||
|  |   } | ||
|  | 
 | ||
|  |   function useTimestamp(options = {}) { | ||
|  |     const { | ||
|  |       controls: exposeControls = false, | ||
|  |       offset = 0, | ||
|  |       immediate = true, | ||
|  |       interval = "requestAnimationFrame", | ||
|  |       callback | ||
|  |     } = options; | ||
|  |     const ts = vueDemi.ref(shared.timestamp() + offset); | ||
|  |     const update = () => ts.value = shared.timestamp() + offset; | ||
|  |     const cb = callback ? () => { | ||
|  |       update(); | ||
|  |       callback(ts.value); | ||
|  |     } : update; | ||
|  |     const controls = interval === "requestAnimationFrame" ? useRafFn(cb, { immediate }) : shared.useIntervalFn(cb, interval, { immediate }); | ||
|  |     if (exposeControls) { | ||
|  |       return { | ||
|  |         timestamp: ts, | ||
|  |         ...controls | ||
|  |       }; | ||
|  |     } else { | ||
|  |       return ts; | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   function useTitle(newTitle = null, options = {}) { | ||
|  |     var _a, _b, _c; | ||
|  |     const { | ||
|  |       document = defaultDocument, | ||
|  |       restoreOnUnmount = (t) => t | ||
|  |     } = options; | ||
|  |     const originalTitle = (_a = document == null ? void 0 : document.title) != null ? _a : ""; | ||
|  |     const title = shared.toRef((_b = newTitle != null ? newTitle : document == null ? void 0 : document.title) != null ? _b : 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) : shared.toValue(template).replace(/%s/g, t); | ||
|  |     } | ||
|  |     vueDemi.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( | ||
|  |         (_c = document.head) == null ? void 0 : _c.querySelector("title"), | ||
|  |         () => { | ||
|  |           if (document && document.title !== title.value) | ||
|  |             title.value = format(document.title); | ||
|  |         }, | ||
|  |         { childList: true } | ||
|  |       ); | ||
|  |     } | ||
|  |     shared.tryOnBeforeUnmount(() => { | ||
|  |       if (restoreOnUnmount) { | ||
|  |         const restoredTitle = restoreOnUnmount(originalTitle, title.value || ""); | ||
|  |         if (restoredTitle != null && document) | ||
|  |           document.title = restoredTitle; | ||
|  |       } | ||
|  |     }); | ||
|  |     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: shared.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 = shared.toValue(from); | ||
|  |     const toVal = shared.toValue(to); | ||
|  |     const v1 = toVec(fromVal); | ||
|  |     const v2 = toVec(toVal); | ||
|  |     const duration = (_a = shared.toValue(options.duration)) != null ? _a : 1e3; | ||
|  |     const startedAt = Date.now(); | ||
|  |     const endAt = Date.now() + duration; | ||
|  |     const trans = typeof options.transition === "function" ? options.transition : (_b = shared.toValue(options.transition)) != null ? _b : shared.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 = shared.toValue(source); | ||
|  |       return typeof v === "number" ? v : v.map(shared.toValue); | ||
|  |     }; | ||
|  |     const outputRef = vueDemi.ref(sourceVal()); | ||
|  |     vueDemi.watch(sourceVal, async (to) => { | ||
|  |       var _a, _b; | ||
|  |       if (shared.toValue(options.disabled)) | ||
|  |         return; | ||
|  |       const id = ++currentId; | ||
|  |       if (options.delay) | ||
|  |         await shared.promiseTimeout(shared.toValue(options.delay)); | ||
|  |       if (id !== currentId) | ||
|  |         return; | ||
|  |       const toVal = Array.isArray(to) ? to.map(shared.toValue) : shared.toValue(to); | ||
|  |       (_a = options.onStarted) == null ? void 0 : _a.call(options); | ||
|  |       await executeTransition(outputRef, outputRef.value, toVal, { | ||
|  |         ...options, | ||
|  |         abort: () => { | ||
|  |           var _a2; | ||
|  |           return id !== currentId || ((_a2 = options.abort) == null ? void 0 : _a2.call(options)); | ||
|  |         } | ||
|  |       }); | ||
|  |       (_b = options.onFinished) == null ? void 0 : _b.call(options); | ||
|  |     }, { deep: true }); | ||
|  |     vueDemi.watch(() => shared.toValue(options.disabled), (disabled) => { | ||
|  |       if (disabled) { | ||
|  |         currentId++; | ||
|  |         outputRef.value = sourceVal(); | ||
|  |       } | ||
|  |     }); | ||
|  |     shared.tryOnScopeDispose(() => { | ||
|  |       currentId++; | ||
|  |     }); | ||
|  |     return vueDemi.computed(() => shared.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 vueDemi.reactive(initialValue); | ||
|  |     const state = vueDemi.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 } = shared.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 = vueDemi.ref((_a = options.enabled) != null ? _a : false); | ||
|  |     const autoSwitch = vueDemi.ref((_b = options.autoSwitch) != null ? _b : true); | ||
|  |     const constraints = vueDemi.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 = vueDemi.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(); | ||
|  |     } | ||
|  |     vueDemi.watch( | ||
|  |       enabled, | ||
|  |       (v) => { | ||
|  |         if (v) | ||
|  |           _start(); | ||
|  |         else | ||
|  |           _stop(); | ||
|  |       }, | ||
|  |       { immediate: true } | ||
|  |     ); | ||
|  |     vueDemi.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 = vueDemi.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 (vueDemi.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"; | ||
|  |       } | ||
|  |     } | ||
|  |     event = event || `update:${key.toString()}`; | ||
|  |     const cloneFn = (val) => !clone ? val : typeof clone === "function" ? clone(val) : cloneFnJSON(val); | ||
|  |     const getValue = () => shared.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 = vueDemi.ref(initialValue); | ||
|  |       let isUpdating = false; | ||
|  |       vueDemi.watch( | ||
|  |         () => props[key], | ||
|  |         (v) => { | ||
|  |           if (!isUpdating) { | ||
|  |             isUpdating = true; | ||
|  |             proxy.value = cloneFn(v); | ||
|  |             vueDemi.nextTick(() => isUpdating = false); | ||
|  |           } | ||
|  |         } | ||
|  |       ); | ||
|  |       vueDemi.watch( | ||
|  |         proxy, | ||
|  |         (v) => { | ||
|  |           if (!isUpdating && (v !== props[key] || deep)) | ||
|  |             triggerEmit(v); | ||
|  |         }, | ||
|  |         { deep } | ||
|  |       ); | ||
|  |       return proxy; | ||
|  |     } else { | ||
|  |       return vueDemi.computed({ | ||
|  |         get() { | ||
|  |           return getValue(); | ||
|  |         }, | ||
|  |         set(value) { | ||
|  |           triggerEmit(value); | ||
|  |         } | ||
|  |       }); | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   function useVModels(props, emit, options = {}) { | ||
|  |     const ret = {}; | ||
|  |     for (const key in props) { | ||
|  |       ret[key] = useVModel( | ||
|  |         props, | ||
|  |         key, | ||
|  |         emit, | ||
|  |         options | ||
|  |       ); | ||
|  |     } | ||
|  |     return ret; | ||
|  |   } | ||
|  | 
 | ||
|  |   function useVibrate(options) { | ||
|  |     const { | ||
|  |       pattern = [], | ||
|  |       interval = 0, | ||
|  |       navigator = defaultNavigator | ||
|  |     } = options || {}; | ||
|  |     const isSupported = useSupported(() => typeof navigator !== "undefined" && "vibrate" in navigator); | ||
|  |     const patternRef = shared.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 = shared.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 = vueDemi.ref(null); | ||
|  |     const size = useElementSize(containerRef); | ||
|  |     const currentList = vueDemi.ref([]); | ||
|  |     const source = vueDemi.shallowRef(list); | ||
|  |     const state = vueDemi.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) { | ||
|  |     vueDemi.watch([size.width, size.height, list], () => { | ||
|  |       calculateRange(); | ||
|  |     }); | ||
|  |   } | ||
|  |   function createComputedTotalSize(itemSize, source) { | ||
|  |     return vueDemi.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 = vueDemi.computed(() => getDistanceLeft(state.value.start)); | ||
|  |     const totalWidth = createComputedTotalSize(itemWidth, source); | ||
|  |     useWatchForSizes(size, list, calculateRange); | ||
|  |     const scrollTo = createScrollTo("horizontal", calculateRange, getDistanceLeft, containerRef); | ||
|  |     const wrapperProps = vueDemi.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 = vueDemi.computed(() => getDistanceTop(state.value.start)); | ||
|  |     const totalHeight = createComputedTotalSize(itemHeight, source); | ||
|  |     useWatchForSizes(size, list, calculateRange); | ||
|  |     const scrollTo = createScrollTo("vertical", calculateRange, getDistanceTop, containerRef); | ||
|  |     const wrapperProps = vueDemi.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 = vueDemi.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 | ||
|  |     }; | ||
|  |   } | ||
|  | 
 | ||
|  |   function useWebNotification(options = {}) { | ||
|  |     const { | ||
|  |       window = defaultWindow, | ||
|  |       requestPermissions: _requestForPermissions = true | ||
|  |     } = options; | ||
|  |     const defaultWebNotificationOptions = options; | ||
|  |     const isSupported = useSupported(() => !!window && "Notification" in window); | ||
|  |     const permissionGranted = vueDemi.ref(isSupported.value && "permission" in Notification && Notification.permission === "granted"); | ||
|  |     const notification = vueDemi.ref(null); | ||
|  |     const ensurePermissions = async () => { | ||
|  |       if (!isSupported.value) | ||
|  |         return; | ||
|  |       if (!permissionGranted.value && Notification.permission !== "denied") { | ||
|  |         const result = await Notification.requestPermission(); | ||
|  |         if (result === "granted") | ||
|  |           permissionGranted.value = true; | ||
|  |       } | ||
|  |       return permissionGranted.value; | ||
|  |     }; | ||
|  |     const { on: onClick, trigger: clickTrigger } = shared.createEventHook(); | ||
|  |     const { on: onShow, trigger: showTrigger } = shared.createEventHook(); | ||
|  |     const { on: onError, trigger: errorTrigger } = shared.createEventHook(); | ||
|  |     const { on: onClose, trigger: closeTrigger } = shared.createEventHook(); | ||
|  |     const show = async (overrides) => { | ||
|  |       if (!isSupported.value || !permissionGranted.value) | ||
|  |         return; | ||
|  |       const options2 = Object.assign({}, defaultWebNotificationOptions, overrides); | ||
|  |       notification.value = new Notification(options2.title || "", options2); | ||
|  |       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; | ||
|  |     }; | ||
|  |     if (_requestForPermissions) | ||
|  |       shared.tryOnMounted(ensurePermissions); | ||
|  |     shared.tryOnScopeDispose(close); | ||
|  |     if (isSupported.value && window) { | ||
|  |       const document = window.document; | ||
|  |       useEventListener(document, "visibilitychange", (e) => { | ||
|  |         e.preventDefault(); | ||
|  |         if (document.visibilityState === "visible") { | ||
|  |           close(); | ||
|  |         } | ||
|  |       }); | ||
|  |     } | ||
|  |     return { | ||
|  |       isSupported, | ||
|  |       notification, | ||
|  |       ensurePermissions, | ||
|  |       permissionGranted, | ||
|  |       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 = vueDemi.ref(null); | ||
|  |     const status = vueDemi.ref("CLOSED"); | ||
|  |     const wsRef = vueDemi.ref(); | ||
|  |     const urlRef = shared.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; | ||
|  |     }; | ||
|  |     const close = (code = 1e3, reason) => { | ||
|  |       if (!shared.isClient || !wsRef.value) | ||
|  |         return; | ||
|  |       explicitlyClosed = true; | ||
|  |       resetHeartbeat(); | ||
|  |       heartbeatPause == null ? void 0 : heartbeatPause(); | ||
|  |       wsRef.value.close(code, reason); | ||
|  |     }; | ||
|  |     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 } = shared.useIntervalFn( | ||
|  |         () => { | ||
|  |           send(message, false); | ||
|  |           if (pongTimeoutWait != null) | ||
|  |             return; | ||
|  |           pongTimeoutWait = setTimeout(() => { | ||
|  |             close(); | ||
|  |             explicitlyClosed = false; | ||
|  |           }, pongTimeout); | ||
|  |         }, | ||
|  |         interval, | ||
|  |         { immediate: false } | ||
|  |       ); | ||
|  |       heartbeatPause = pause; | ||
|  |       heartbeatResume = resume; | ||
|  |     } | ||
|  |     if (autoClose) { | ||
|  |       if (shared.isClient) | ||
|  |         useEventListener("beforeunload", () => close()); | ||
|  |       shared.tryOnScopeDispose(close); | ||
|  |     } | ||
|  |     const open = () => { | ||
|  |       if (!shared.isClient && !shared.isWorker) | ||
|  |         return; | ||
|  |       close(); | ||
|  |       explicitlyClosed = false; | ||
|  |       retried = 0; | ||
|  |       _init(); | ||
|  |     }; | ||
|  |     if (immediate) | ||
|  |       vueDemi.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 = vueDemi.ref(null); | ||
|  |     const worker = vueDemi.shallowRef(); | ||
|  |     const post = (...args) => { | ||
|  |       if (!worker.value) | ||
|  |         return; | ||
|  |       worker.value.postMessage(...args); | ||
|  |     }; | ||
|  |     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; | ||
|  |       }; | ||
|  |       shared.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 = vueDemi.ref(); | ||
|  |     const workerStatus = vueDemi.ref("PENDING"); | ||
|  |     const promise = vueDemi.ref({}); | ||
|  |     const timeoutId = vueDemi.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(); | ||
|  |     shared.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; | ||
|  |         e.preventDefault(); | ||
|  |         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 | ||
|  |     }; | ||
|  |   } | ||
|  | 
 | ||
|  |   function useWindowFocus(options = {}) { | ||
|  |     const { window = defaultWindow } = options; | ||
|  |     if (!window) | ||
|  |       return vueDemi.ref(false); | ||
|  |     const focused = vueDemi.ref(window.document.hasFocus()); | ||
|  |     useEventListener(window, "blur", () => { | ||
|  |       focused.value = false; | ||
|  |     }); | ||
|  |     useEventListener(window, "focus", () => { | ||
|  |       focused.value = true; | ||
|  |     }); | ||
|  |     return focused; | ||
|  |   } | ||
|  | 
 | ||
|  |   function useWindowScroll(options = {}) { | ||
|  |     const { window = defaultWindow, behavior = "auto" } = options; | ||
|  |     if (!window) { | ||
|  |       return { | ||
|  |         x: vueDemi.ref(0), | ||
|  |         y: vueDemi.ref(0) | ||
|  |       }; | ||
|  |     } | ||
|  |     const internalX = vueDemi.ref(window.scrollX); | ||
|  |     const internalY = vueDemi.ref(window.scrollY); | ||
|  |     const x = vueDemi.computed({ | ||
|  |       get() { | ||
|  |         return internalX.value; | ||
|  |       }, | ||
|  |       set(x2) { | ||
|  |         scrollTo({ left: x2, behavior }); | ||
|  |       } | ||
|  |     }); | ||
|  |     const y = vueDemi.computed({ | ||
|  |       get() { | ||
|  |         return internalY.value; | ||
|  |       }, | ||
|  |       set(y2) { | ||
|  |         scrollTo({ top: y2, behavior }); | ||
|  |       } | ||
|  |     }); | ||
|  |     useEventListener( | ||
|  |       window, | ||
|  |       "scroll", | ||
|  |       () => { | ||
|  |         internalX.value = window.scrollX; | ||
|  |         internalY.value = window.scrollY; | ||
|  |       }, | ||
|  |       { | ||
|  |         capture: false, | ||
|  |         passive: true | ||
|  |       } | ||
|  |     ); | ||
|  |     return { x, y }; | ||
|  |   } | ||
|  | 
 | ||
|  |   function useWindowSize(options = {}) { | ||
|  |     const { | ||
|  |       window = defaultWindow, | ||
|  |       initialWidth = Number.POSITIVE_INFINITY, | ||
|  |       initialHeight = Number.POSITIVE_INFINITY, | ||
|  |       listenOrientation = true, | ||
|  |       includeScrollbar = true | ||
|  |     } = options; | ||
|  |     const width = vueDemi.ref(initialWidth); | ||
|  |     const height = vueDemi.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(); | ||
|  |     shared.tryOnMounted(update); | ||
|  |     useEventListener("resize", update, { passive: true }); | ||
|  |     if (listenOrientation) { | ||
|  |       const matches = useMediaQuery("(orientation: portrait)"); | ||
|  |       vueDemi.watch(matches, () => update()); | ||
|  |     } | ||
|  |     return { width, height }; | ||
|  |   } | ||
|  | 
 | ||
|  |   exports.DefaultMagicKeysAliasMap = DefaultMagicKeysAliasMap; | ||
|  |   exports.StorageSerializers = StorageSerializers; | ||
|  |   exports.TransitionPresets = TransitionPresets; | ||
|  |   exports.asyncComputed = computedAsync; | ||
|  |   exports.breakpointsAntDesign = breakpointsAntDesign; | ||
|  |   exports.breakpointsBootstrapV5 = breakpointsBootstrapV5; | ||
|  |   exports.breakpointsMasterCss = breakpointsMasterCss; | ||
|  |   exports.breakpointsPrimeFlex = breakpointsPrimeFlex; | ||
|  |   exports.breakpointsQuasar = breakpointsQuasar; | ||
|  |   exports.breakpointsSematic = breakpointsSematic; | ||
|  |   exports.breakpointsTailwind = breakpointsTailwind; | ||
|  |   exports.breakpointsVuetify = breakpointsVuetify; | ||
|  |   exports.cloneFnJSON = cloneFnJSON; | ||
|  |   exports.computedAsync = computedAsync; | ||
|  |   exports.computedInject = computedInject; | ||
|  |   exports.createFetch = createFetch; | ||
|  |   exports.createReusableTemplate = createReusableTemplate; | ||
|  |   exports.createTemplatePromise = createTemplatePromise; | ||
|  |   exports.createUnrefFn = createUnrefFn; | ||
|  |   exports.customStorageEventName = customStorageEventName; | ||
|  |   exports.defaultDocument = defaultDocument; | ||
|  |   exports.defaultLocation = defaultLocation; | ||
|  |   exports.defaultNavigator = defaultNavigator; | ||
|  |   exports.defaultWindow = defaultWindow; | ||
|  |   exports.executeTransition = executeTransition; | ||
|  |   exports.formatTimeAgo = formatTimeAgo; | ||
|  |   exports.getSSRHandler = getSSRHandler; | ||
|  |   exports.mapGamepadToXbox360Controller = mapGamepadToXbox360Controller; | ||
|  |   exports.onClickOutside = onClickOutside; | ||
|  |   exports.onKeyDown = onKeyDown; | ||
|  |   exports.onKeyPressed = onKeyPressed; | ||
|  |   exports.onKeyStroke = onKeyStroke; | ||
|  |   exports.onKeyUp = onKeyUp; | ||
|  |   exports.onLongPress = onLongPress; | ||
|  |   exports.onStartTyping = onStartTyping; | ||
|  |   exports.setSSRHandler = setSSRHandler; | ||
|  |   exports.templateRef = templateRef; | ||
|  |   exports.unrefElement = unrefElement; | ||
|  |   exports.useActiveElement = useActiveElement; | ||
|  |   exports.useAnimate = useAnimate; | ||
|  |   exports.useAsyncQueue = useAsyncQueue; | ||
|  |   exports.useAsyncState = useAsyncState; | ||
|  |   exports.useBase64 = useBase64; | ||
|  |   exports.useBattery = useBattery; | ||
|  |   exports.useBluetooth = useBluetooth; | ||
|  |   exports.useBreakpoints = useBreakpoints; | ||
|  |   exports.useBroadcastChannel = useBroadcastChannel; | ||
|  |   exports.useBrowserLocation = useBrowserLocation; | ||
|  |   exports.useCached = useCached; | ||
|  |   exports.useClipboard = useClipboard; | ||
|  |   exports.useClipboardItems = useClipboardItems; | ||
|  |   exports.useCloned = useCloned; | ||
|  |   exports.useColorMode = useColorMode; | ||
|  |   exports.useConfirmDialog = useConfirmDialog; | ||
|  |   exports.useCssVar = useCssVar; | ||
|  |   exports.useCurrentElement = useCurrentElement; | ||
|  |   exports.useCycleList = useCycleList; | ||
|  |   exports.useDark = useDark; | ||
|  |   exports.useDebouncedRefHistory = useDebouncedRefHistory; | ||
|  |   exports.useDeviceMotion = useDeviceMotion; | ||
|  |   exports.useDeviceOrientation = useDeviceOrientation; | ||
|  |   exports.useDevicePixelRatio = useDevicePixelRatio; | ||
|  |   exports.useDevicesList = useDevicesList; | ||
|  |   exports.useDisplayMedia = useDisplayMedia; | ||
|  |   exports.useDocumentVisibility = useDocumentVisibility; | ||
|  |   exports.useDraggable = useDraggable; | ||
|  |   exports.useDropZone = useDropZone; | ||
|  |   exports.useElementBounding = useElementBounding; | ||
|  |   exports.useElementByPoint = useElementByPoint; | ||
|  |   exports.useElementHover = useElementHover; | ||
|  |   exports.useElementSize = useElementSize; | ||
|  |   exports.useElementVisibility = useElementVisibility; | ||
|  |   exports.useEventBus = useEventBus; | ||
|  |   exports.useEventListener = useEventListener; | ||
|  |   exports.useEventSource = useEventSource; | ||
|  |   exports.useEyeDropper = useEyeDropper; | ||
|  |   exports.useFavicon = useFavicon; | ||
|  |   exports.useFetch = useFetch; | ||
|  |   exports.useFileDialog = useFileDialog; | ||
|  |   exports.useFileSystemAccess = useFileSystemAccess; | ||
|  |   exports.useFocus = useFocus; | ||
|  |   exports.useFocusWithin = useFocusWithin; | ||
|  |   exports.useFps = useFps; | ||
|  |   exports.useFullscreen = useFullscreen; | ||
|  |   exports.useGamepad = useGamepad; | ||
|  |   exports.useGeolocation = useGeolocation; | ||
|  |   exports.useIdle = useIdle; | ||
|  |   exports.useImage = useImage; | ||
|  |   exports.useInfiniteScroll = useInfiniteScroll; | ||
|  |   exports.useIntersectionObserver = useIntersectionObserver; | ||
|  |   exports.useKeyModifier = useKeyModifier; | ||
|  |   exports.useLocalStorage = useLocalStorage; | ||
|  |   exports.useMagicKeys = useMagicKeys; | ||
|  |   exports.useManualRefHistory = useManualRefHistory; | ||
|  |   exports.useMediaControls = useMediaControls; | ||
|  |   exports.useMediaQuery = useMediaQuery; | ||
|  |   exports.useMemoize = useMemoize; | ||
|  |   exports.useMemory = useMemory; | ||
|  |   exports.useMounted = useMounted; | ||
|  |   exports.useMouse = useMouse; | ||
|  |   exports.useMouseInElement = useMouseInElement; | ||
|  |   exports.useMousePressed = useMousePressed; | ||
|  |   exports.useMutationObserver = useMutationObserver; | ||
|  |   exports.useNavigatorLanguage = useNavigatorLanguage; | ||
|  |   exports.useNetwork = useNetwork; | ||
|  |   exports.useNow = useNow; | ||
|  |   exports.useObjectUrl = useObjectUrl; | ||
|  |   exports.useOffsetPagination = useOffsetPagination; | ||
|  |   exports.useOnline = useOnline; | ||
|  |   exports.usePageLeave = usePageLeave; | ||
|  |   exports.useParallax = useParallax; | ||
|  |   exports.useParentElement = useParentElement; | ||
|  |   exports.usePerformanceObserver = usePerformanceObserver; | ||
|  |   exports.usePermission = usePermission; | ||
|  |   exports.usePointer = usePointer; | ||
|  |   exports.usePointerLock = usePointerLock; | ||
|  |   exports.usePointerSwipe = usePointerSwipe; | ||
|  |   exports.usePreferredColorScheme = usePreferredColorScheme; | ||
|  |   exports.usePreferredContrast = usePreferredContrast; | ||
|  |   exports.usePreferredDark = usePreferredDark; | ||
|  |   exports.usePreferredLanguages = usePreferredLanguages; | ||
|  |   exports.usePreferredReducedMotion = usePreferredReducedMotion; | ||
|  |   exports.usePrevious = usePrevious; | ||
|  |   exports.useRafFn = useRafFn; | ||
|  |   exports.useRefHistory = useRefHistory; | ||
|  |   exports.useResizeObserver = useResizeObserver; | ||
|  |   exports.useScreenOrientation = useScreenOrientation; | ||
|  |   exports.useScreenSafeArea = useScreenSafeArea; | ||
|  |   exports.useScriptTag = useScriptTag; | ||
|  |   exports.useScroll = useScroll; | ||
|  |   exports.useScrollLock = useScrollLock; | ||
|  |   exports.useSessionStorage = useSessionStorage; | ||
|  |   exports.useShare = useShare; | ||
|  |   exports.useSorted = useSorted; | ||
|  |   exports.useSpeechRecognition = useSpeechRecognition; | ||
|  |   exports.useSpeechSynthesis = useSpeechSynthesis; | ||
|  |   exports.useStepper = useStepper; | ||
|  |   exports.useStorage = useStorage; | ||
|  |   exports.useStorageAsync = useStorageAsync; | ||
|  |   exports.useStyleTag = useStyleTag; | ||
|  |   exports.useSupported = useSupported; | ||
|  |   exports.useSwipe = useSwipe; | ||
|  |   exports.useTemplateRefsList = useTemplateRefsList; | ||
|  |   exports.useTextDirection = useTextDirection; | ||
|  |   exports.useTextSelection = useTextSelection; | ||
|  |   exports.useTextareaAutosize = useTextareaAutosize; | ||
|  |   exports.useThrottledRefHistory = useThrottledRefHistory; | ||
|  |   exports.useTimeAgo = useTimeAgo; | ||
|  |   exports.useTimeoutPoll = useTimeoutPoll; | ||
|  |   exports.useTimestamp = useTimestamp; | ||
|  |   exports.useTitle = useTitle; | ||
|  |   exports.useTransition = useTransition; | ||
|  |   exports.useUrlSearchParams = useUrlSearchParams; | ||
|  |   exports.useUserMedia = useUserMedia; | ||
|  |   exports.useVModel = useVModel; | ||
|  |   exports.useVModels = useVModels; | ||
|  |   exports.useVibrate = useVibrate; | ||
|  |   exports.useVirtualList = useVirtualList; | ||
|  |   exports.useWakeLock = useWakeLock; | ||
|  |   exports.useWebNotification = useWebNotification; | ||
|  |   exports.useWebSocket = useWebSocket; | ||
|  |   exports.useWebWorker = useWebWorker; | ||
|  |   exports.useWebWorkerFn = useWebWorkerFn; | ||
|  |   exports.useWindowFocus = useWindowFocus; | ||
|  |   exports.useWindowScroll = useWindowScroll; | ||
|  |   exports.useWindowSize = useWindowSize; | ||
|  |   Object.keys(shared).forEach(function (k) { | ||
|  |     if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, { | ||
|  |       enumerable: true, | ||
|  |       get: function () { return shared[k]; } | ||
|  |     }); | ||
|  |   }); | ||
|  | 
 | ||
|  | })(this.VueUse = this.VueUse || {}, VueUse, VueDemi); |