diff --git a/frontend/src/components/base/README b/frontend/src/components/base/README new file mode 100644 index 00000000..240cca2d --- /dev/null +++ b/frontend/src/components/base/README @@ -0,0 +1 @@ +无样式的基础组件 \ No newline at end of file diff --git a/frontend/src/components/base/index.ts b/frontend/src/components/base/index.ts new file mode 100644 index 00000000..a6ff8e66 --- /dev/null +++ b/frontend/src/components/base/index.ts @@ -0,0 +1 @@ +export { default as NTooltip } from "./tooltip" diff --git a/frontend/src/components/base/tooltip.tsx b/frontend/src/components/base/tooltip.tsx new file mode 100644 index 00000000..97a969a5 --- /dev/null +++ b/frontend/src/components/base/tooltip.tsx @@ -0,0 +1,150 @@ +import { syncRefs, useVModel } from "@vueuse/core" +import type { CSSProperties, PropType } from "vue"; +import { Teleport, Transition, computed, defineComponent, nextTick, reactive, ref, renderSlot, watch } from "vue" +import { provideShow } from "../hooks/show" + +export const tooltipProps = { + popClass: { + type: String + }, + position: { + type: String as PropType<"bottom" | "top" | "left" | "right" | "auto">, + default: () => "auto" + }, + offset: { + type: Number, + default: () => 8 + }, + lazy: { + type: Boolean, + default: () => false + }, + visible: { + type: Boolean, + default: () => false + }, + disabled: { + type: Boolean, + default: () => false + } +} + +export default defineComponent({ + name: "ITooltip", + props: tooltipProps, + emits: ["change", "update:visible"], + setup(props, { slots, emit }) { + const isOpen = ref(props.visible) + + syncRefs(useVModel(props, "visible"), isOpen) + + provideShow(isOpen) + + let timer: NodeJS.Timeout + + const triggerRef = ref() + const popupRef = ref() + + const dropdownPosition = reactive({ x: 0, y: 0 }) + + const isShow = computed(() => isOpen.value && triggerRef.value && popupRef.value && dropdownPosition.x + dropdownPosition.y > 0) + + const dropdownStyle = computed(() => { + return { + left: `${dropdownPosition.x}px`, + top: `${dropdownPosition.y}px`, + visibility: isShow.value ? "visible" : "hidden" + } + }) + + const mounted = ref(false) + + function onMouseover() { + if (props.disabled) { + return + } + timer = setTimeout( + () => { + isOpen.value = true + emit("change", true) + }, + props.lazy ? 800 : 100 + ) + } + + function onMouseout() { + if (props.disabled) { + return + } + clearTimeout(timer) + isOpen.value = false + emit("change", false) + } + + function resize() { + const trigger = triggerRef.value + const popup = popupRef.value + + if (!!trigger && !!popup) { + const { width, height, left, top } = trigger.getBoundingClientRect() + + const { clientWidth: pWidth, clientHeight: pHeight } = popup + + let x = 0 + let y = 0 + + const offset = props.offset + + switch (props.position) { + case "auto": + case "bottom": + x = left + width / 2 + y = top + height + offset + break + case "top": + x = left + y = top - pHeight - offset + break + case "left": + x = left - pWidth - offset + y = top + break + case "right": + x = left + width + offset + y = top + break + } + if (props.position == "auto") { + x = window.innerWidth - x > 500 ? x + 20 : x - 20 - 310 + y = window.innerHeight - y > popup.offsetHeight + 50 ? y : window.innerHeight - (popup.offsetHeight + 50) + } + dropdownPosition.x = x + dropdownPosition.y = y + } + } + + watch(isOpen, val => { + if (val) { + mounted.value = true + } + nextTick(resize) + }) + + return () => { + return ( +
+ {renderSlot(slots, "default")} + + + {mounted.value && !props.disabled && ( +
+ {renderSlot(slots, "popper")} +
+ )} +
+
+
+ ) + } + } +}) diff --git a/frontend/src/components/calc/README b/frontend/src/components/calc/README new file mode 100644 index 00000000..782a9261 --- /dev/null +++ b/frontend/src/components/calc/README @@ -0,0 +1 @@ +DNF风格定制组件 \ No newline at end of file diff --git a/frontend/src/components/calc/action-dialog/index.vue b/frontend/src/components/calc/action-dialog/index.vue new file mode 100644 index 00000000..d4f49b49 --- /dev/null +++ b/frontend/src/components/calc/action-dialog/index.vue @@ -0,0 +1,207 @@ + + + diff --git a/frontend/src/components/calc/autocomplete/index.vue b/frontend/src/components/calc/autocomplete/index.vue new file mode 100644 index 00000000..72b2ab0b --- /dev/null +++ b/frontend/src/components/calc/autocomplete/index.vue @@ -0,0 +1,222 @@ + + + diff --git a/frontend/src/components/calc/button/index.vue b/frontend/src/components/calc/button/index.vue new file mode 100644 index 00000000..4a0bae9b --- /dev/null +++ b/frontend/src/components/calc/button/index.vue @@ -0,0 +1,100 @@ + + + diff --git a/frontend/src/components/calc/cascader/img/down.png b/frontend/src/components/calc/cascader/img/down.png new file mode 100644 index 00000000..4861b24f Binary files /dev/null and b/frontend/src/components/calc/cascader/img/down.png differ diff --git a/frontend/src/components/calc/cascader/img/img/down.png b/frontend/src/components/calc/cascader/img/img/down.png new file mode 100644 index 00000000..4861b24f Binary files /dev/null and b/frontend/src/components/calc/cascader/img/img/down.png differ diff --git a/frontend/src/components/calc/cascader/img/img/select_down.png b/frontend/src/components/calc/cascader/img/img/select_down.png new file mode 100644 index 00000000..450ba106 Binary files /dev/null and b/frontend/src/components/calc/cascader/img/img/select_down.png differ diff --git a/frontend/src/components/calc/cascader/img/img/select_down_clicked.png b/frontend/src/components/calc/cascader/img/img/select_down_clicked.png new file mode 100644 index 00000000..a51fbeb7 Binary files /dev/null and b/frontend/src/components/calc/cascader/img/img/select_down_clicked.png differ diff --git a/frontend/src/components/calc/cascader/img/img/select_down_disabled.png b/frontend/src/components/calc/cascader/img/img/select_down_disabled.png new file mode 100644 index 00000000..c8d948ea Binary files /dev/null and b/frontend/src/components/calc/cascader/img/img/select_down_disabled.png differ diff --git a/frontend/src/components/calc/cascader/img/img/up.png b/frontend/src/components/calc/cascader/img/img/up.png new file mode 100644 index 00000000..b017add4 Binary files /dev/null and b/frontend/src/components/calc/cascader/img/img/up.png differ diff --git a/frontend/src/components/calc/cascader/img/select_down.png b/frontend/src/components/calc/cascader/img/select_down.png new file mode 100644 index 00000000..450ba106 Binary files /dev/null and b/frontend/src/components/calc/cascader/img/select_down.png differ diff --git a/frontend/src/components/calc/cascader/img/select_down_clicked.png b/frontend/src/components/calc/cascader/img/select_down_clicked.png new file mode 100644 index 00000000..a51fbeb7 Binary files /dev/null and b/frontend/src/components/calc/cascader/img/select_down_clicked.png differ diff --git a/frontend/src/components/calc/cascader/img/select_down_disabled.png b/frontend/src/components/calc/cascader/img/select_down_disabled.png new file mode 100644 index 00000000..c8d948ea Binary files /dev/null and b/frontend/src/components/calc/cascader/img/select_down_disabled.png differ diff --git a/frontend/src/components/calc/cascader/img/up.png b/frontend/src/components/calc/cascader/img/up.png new file mode 100644 index 00000000..b017add4 Binary files /dev/null and b/frontend/src/components/calc/cascader/img/up.png differ diff --git a/frontend/src/components/calc/cascader/index.vue b/frontend/src/components/calc/cascader/index.vue new file mode 100644 index 00000000..ad9744d5 --- /dev/null +++ b/frontend/src/components/calc/cascader/index.vue @@ -0,0 +1,271 @@ + + + diff --git a/frontend/src/components/calc/checkbox-group/index.vue b/frontend/src/components/calc/checkbox-group/index.vue new file mode 100644 index 00000000..0fd92385 --- /dev/null +++ b/frontend/src/components/calc/checkbox-group/index.vue @@ -0,0 +1,73 @@ + + + diff --git a/frontend/src/components/calc/checkbox/index.vue b/frontend/src/components/calc/checkbox/index.vue new file mode 100644 index 00000000..73164f2b --- /dev/null +++ b/frontend/src/components/calc/checkbox/index.vue @@ -0,0 +1,211 @@ + + + diff --git a/frontend/src/components/calc/collapse/index.vue b/frontend/src/components/calc/collapse/index.vue new file mode 100644 index 00000000..b99920ea --- /dev/null +++ b/frontend/src/components/calc/collapse/index.vue @@ -0,0 +1,33 @@ + diff --git a/frontend/src/components/calc/dialog/index.vue b/frontend/src/components/calc/dialog/index.vue new file mode 100644 index 00000000..6d88712b --- /dev/null +++ b/frontend/src/components/calc/dialog/index.vue @@ -0,0 +1,170 @@ + + + diff --git a/frontend/src/components/calc/iconselect/index.vue b/frontend/src/components/calc/iconselect/index.vue new file mode 100644 index 00000000..c60d6ccc --- /dev/null +++ b/frontend/src/components/calc/iconselect/index.vue @@ -0,0 +1,242 @@ + + + diff --git a/frontend/src/components/calc/index.ts b/frontend/src/components/calc/index.ts new file mode 100644 index 00000000..8a4a97a6 --- /dev/null +++ b/frontend/src/components/calc/index.ts @@ -0,0 +1,39 @@ +import type { App } from "vue" +import Button from "./button/index.vue" +import Tabs from "./tabs/index.vue" +import Tab from "./tab.vue" +import Select from "./select/index.vue" +import Option from "./option/index.vue" +import Menu from "./menu/menu.vue" +import Checkbox from "./checkbox/index.vue" +import Collapse from "./collapse/index.vue" +import Dialog from "./dialog/index.vue" +import Tooltip from "./tooltip/index.vue" +import Iconselct from "./iconselct/index.vue" +import Selection from "./selection/index.vue" + + +export const components = { + Button, + Tabs, + Option, + Tab, + Select, + Menu, + Checkbox, + Collapse, + Dialog, + Tooltip, + Iconselct, + Selection +} + +export type CalcComponents = typeof components + +export function install(app: App) { + for (const [key, value] of Object.entries(components)) { + app.component(`calc-${key.toLocaleLowerCase()}`, value) + } +} + +export default components diff --git a/frontend/src/components/calc/input/index.vue b/frontend/src/components/calc/input/index.vue new file mode 100644 index 00000000..40a497fb --- /dev/null +++ b/frontend/src/components/calc/input/index.vue @@ -0,0 +1,44 @@ + + + diff --git a/frontend/src/components/calc/item/index.vue b/frontend/src/components/calc/item/index.vue new file mode 100644 index 00000000..d807fbc1 --- /dev/null +++ b/frontend/src/components/calc/item/index.vue @@ -0,0 +1,4 @@ + diff --git a/frontend/src/components/calc/loading/index.vue b/frontend/src/components/calc/loading/index.vue new file mode 100644 index 00000000..074a6ad8 --- /dev/null +++ b/frontend/src/components/calc/loading/index.vue @@ -0,0 +1,69 @@ + + + diff --git a/frontend/src/components/calc/menu/img/plus.svg b/frontend/src/components/calc/menu/img/plus.svg new file mode 100644 index 00000000..f92ba0fd --- /dev/null +++ b/frontend/src/components/calc/menu/img/plus.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/src/components/calc/menu/menu.vue b/frontend/src/components/calc/menu/menu.vue new file mode 100644 index 00000000..048324fb --- /dev/null +++ b/frontend/src/components/calc/menu/menu.vue @@ -0,0 +1,71 @@ + + + diff --git a/frontend/src/components/calc/option/index.vue b/frontend/src/components/calc/option/index.vue new file mode 100644 index 00000000..d807fbc1 --- /dev/null +++ b/frontend/src/components/calc/option/index.vue @@ -0,0 +1,4 @@ + diff --git a/frontend/src/components/calc/pagination/index.vue b/frontend/src/components/calc/pagination/index.vue new file mode 100644 index 00000000..d3a5173a --- /dev/null +++ b/frontend/src/components/calc/pagination/index.vue @@ -0,0 +1,86 @@ + + + diff --git a/frontend/src/components/calc/progress/index.vue b/frontend/src/components/calc/progress/index.vue new file mode 100644 index 00000000..64b902d1 --- /dev/null +++ b/frontend/src/components/calc/progress/index.vue @@ -0,0 +1,39 @@ + + + diff --git a/frontend/src/components/calc/select/img/down.png b/frontend/src/components/calc/select/img/down.png new file mode 100644 index 00000000..4861b24f Binary files /dev/null and b/frontend/src/components/calc/select/img/down.png differ diff --git a/frontend/src/components/calc/select/img/select_down.png b/frontend/src/components/calc/select/img/select_down.png new file mode 100644 index 00000000..450ba106 Binary files /dev/null and b/frontend/src/components/calc/select/img/select_down.png differ diff --git a/frontend/src/components/calc/select/img/select_down_clicked.png b/frontend/src/components/calc/select/img/select_down_clicked.png new file mode 100644 index 00000000..a51fbeb7 Binary files /dev/null and b/frontend/src/components/calc/select/img/select_down_clicked.png differ diff --git a/frontend/src/components/calc/select/img/select_down_disabled.png b/frontend/src/components/calc/select/img/select_down_disabled.png new file mode 100644 index 00000000..c8d948ea Binary files /dev/null and b/frontend/src/components/calc/select/img/select_down_disabled.png differ diff --git a/frontend/src/components/calc/select/img/up.png b/frontend/src/components/calc/select/img/up.png new file mode 100644 index 00000000..b017add4 Binary files /dev/null and b/frontend/src/components/calc/select/img/up.png differ diff --git a/frontend/src/components/calc/select/index.vue b/frontend/src/components/calc/select/index.vue new file mode 100644 index 00000000..8cb45d8d --- /dev/null +++ b/frontend/src/components/calc/select/index.vue @@ -0,0 +1,304 @@ + + + diff --git a/frontend/src/components/calc/selection/index.vue b/frontend/src/components/calc/selection/index.vue new file mode 100644 index 00000000..2d16b51b --- /dev/null +++ b/frontend/src/components/calc/selection/index.vue @@ -0,0 +1,5 @@ + diff --git a/frontend/src/components/calc/shared.ts b/frontend/src/components/calc/shared.ts new file mode 100644 index 00000000..acb9ff67 --- /dev/null +++ b/frontend/src/components/calc/shared.ts @@ -0,0 +1,3 @@ +import type { InjectionKey } from "vue"; + +export const CHECKBOX_GROUP: InjectionKey = Symbol("checkbox-group") diff --git a/frontend/src/components/calc/tab/index.vue b/frontend/src/components/calc/tab/index.vue new file mode 100644 index 00000000..79e5bcfd --- /dev/null +++ b/frontend/src/components/calc/tab/index.vue @@ -0,0 +1,16 @@ + diff --git a/frontend/src/components/calc/tabs/constants.ts b/frontend/src/components/calc/tabs/constants.ts new file mode 100644 index 00000000..dc06fe9f --- /dev/null +++ b/frontend/src/components/calc/tabs/constants.ts @@ -0,0 +1,5 @@ +export const AciveSymbol = Symbol("[i-tabs]active") + +export const AciveClassSymbol = Symbol("[i-tabs]active-class") + +export const ChangeActiveSymbol = Symbol("[i-tabs]change-active") diff --git a/frontend/src/components/calc/tabs/index.vue b/frontend/src/components/calc/tabs/index.vue new file mode 100644 index 00000000..a6d82cbc --- /dev/null +++ b/frontend/src/components/calc/tabs/index.vue @@ -0,0 +1,123 @@ + + + diff --git a/frontend/src/components/calc/tooltip/index.vue b/frontend/src/components/calc/tooltip/index.vue new file mode 100644 index 00000000..2174da11 --- /dev/null +++ b/frontend/src/components/calc/tooltip/index.vue @@ -0,0 +1,25 @@ + + + diff --git a/frontend/src/components/calc/tree/img/collapse_down.png b/frontend/src/components/calc/tree/img/collapse_down.png new file mode 100644 index 00000000..bba85eac Binary files /dev/null and b/frontend/src/components/calc/tree/img/collapse_down.png differ diff --git a/frontend/src/components/calc/tree/img/collapse_up.png b/frontend/src/components/calc/tree/img/collapse_up.png new file mode 100644 index 00000000..9d4c0296 Binary files /dev/null and b/frontend/src/components/calc/tree/img/collapse_up.png differ diff --git a/frontend/src/components/calc/tree/img/dictionary_line.png b/frontend/src/components/calc/tree/img/dictionary_line.png new file mode 100644 index 00000000..1dd4cfd9 Binary files /dev/null and b/frontend/src/components/calc/tree/img/dictionary_line.png differ diff --git a/frontend/src/components/calc/tree/img/item_active.png b/frontend/src/components/calc/tree/img/item_active.png new file mode 100644 index 00000000..50d3f93e Binary files /dev/null and b/frontend/src/components/calc/tree/img/item_active.png differ diff --git a/frontend/src/components/calc/tree/img/item_hover.png b/frontend/src/components/calc/tree/img/item_hover.png new file mode 100644 index 00000000..3c0e1484 Binary files /dev/null and b/frontend/src/components/calc/tree/img/item_hover.png differ diff --git a/frontend/src/components/calc/tree/index.vue b/frontend/src/components/calc/tree/index.vue new file mode 100644 index 00000000..20f933c3 --- /dev/null +++ b/frontend/src/components/calc/tree/index.vue @@ -0,0 +1,92 @@ + + + diff --git a/frontend/src/components/calc/tree/node.vue b/frontend/src/components/calc/tree/node.vue new file mode 100644 index 00000000..c8b7ba8e --- /dev/null +++ b/frontend/src/components/calc/tree/node.vue @@ -0,0 +1,159 @@ + + + diff --git a/frontend/src/components/calc/tree/types.ts b/frontend/src/components/calc/tree/types.ts new file mode 100644 index 00000000..554d618d --- /dev/null +++ b/frontend/src/components/calc/tree/types.ts @@ -0,0 +1,10 @@ +export interface TreeNode { + label: string + id?: string | number + value?: any + children?: TreeNode[] + onSelect?: () => void + [key: string]: any +} + +export interface TreeData {} diff --git a/frontend/src/components/hooks/README b/frontend/src/components/hooks/README new file mode 100644 index 00000000..ad05ab2b --- /dev/null +++ b/frontend/src/components/hooks/README @@ -0,0 +1 @@ +通用的函数式组件 \ No newline at end of file diff --git a/frontend/src/components/hooks/dialog.ts b/frontend/src/components/hooks/dialog.ts index e69de29b..5a313d97 100644 --- a/frontend/src/components/hooks/dialog.ts +++ b/frontend/src/components/hooks/dialog.ts @@ -0,0 +1,194 @@ +import { h, reactive, renderList } from "vue" +import { createSharedComposable } from "@vueuse/core" +import ActionDialog from "@/components/calc/action-dialog/index.vue" +import type { JSX } from "vue/jsx-runtime" + +export type ConfirmDialogOption = Omit +export type AlertDialogOption = Omit +export type ElementLike = JSX.Element | string | ElementLike[] + +function randomId() { + return Symbol(Math.random().toString(36).slice(2, 9)) +} + +type DialogID = string | number | symbol + +export interface ShowDialogOption { + id?: DialogID + /** + * 标题 + */ + header?: string | boolean + /** + * 内容插槽 + */ + content?: (() => ElementLike) | ElementLike + /** + * 操作区插槽 + */ + action?: (() => ElementLike) | ElementLike + + cache?: boolean + + /** + * 超时自动关闭 + */ + timeout?: number + + /** + * 关闭时的延迟动画 + */ + duration?: number + + /** + * 确定按钮文本 为false时不显示 + */ + okButton?: string | boolean + /** + * 取消按钮文本 为false时不显示 + */ + cancelButton?: string | boolean + /** + * 拒绝按钮文本 为false时不显示 + */ + rejectButton?: string | boolean + + // 默认状态 + defaultStatus?: DialogResult["status"] + + mask?: boolean + + scale?: number +} + +export interface DialogInstance { + id?: DialogID + visible: boolean + render: (visible?: boolean) => ElementLike + resolve: (result: DialogResult) => void +} + +export interface DialogResult { + id: DialogID + status: "ok" | "reject" | "cancel" | "none" + data?: any + readonly isOk: boolean + readonly isCancel: boolean + readonly isReject: boolean +} + +export const useDialog = createSharedComposable(() => { + const dialogs = reactive(new Map()) + + // 注册窗口 + function open(dialog: DialogInstance) { + const id = dialog.id ?? randomId() + dialogs.set(id, dialog) + return id + } + + function close(id: DialogID, status = "cancel", duration = 400) { + const dialog = dialogs.get(id) + if (!dialog) { + return + } + dialog.resolve({ + id, + status: "ok", + get isOk() { + return status == "ok" + }, + get isCancel() { + return status == "cancel" + }, + get isReject() { + return status == "reject" + } + }) + dialog.visible = false + const fn = () => dialogs.delete(id) + if (duration > 0) { + setTimeout(fn, duration) + } else { + fn() + } + } + + function render() { + return renderList(dialogs.values(), e => e.render(e.visible)) + } + + async function show(option: ShowDialogOption = {}) { + return new Promise(resolve => { + const { id = randomId(), header = true, content, action, timeout, okButton = false, cancelButton = false, rejectButton = false, defaultStatus = "none", duration = 400, mask = false, scale = 1.0 } = option + + const onClose = (status: DialogResult["status"] = defaultStatus) => { + close(id, status, duration) + } + + open({ + id, + visible: true, + resolve, + render(visible = true) { + return h( + ActionDialog, + { + header, + okButton, + cancelButton, + rejectButton, + visible, + onClose, + mask, + scale + }, + { + default() { + switch (typeof content) { + case "function": + return content() + case "string": + return h("div", { class: "w-full justify-center text-hex-d4d6b6 text-center", style: "margin:10px" }, content) + default: + return content + } + }, + action: typeof action == "function" || !action ? action : () => action + } + ) + } + }) + + if (timeout) { + setTimeout(onClose, timeout) + } + }) + } + + async function alert(option: AlertDialogOption = {}) { + return show({ + ...option, + defaultStatus: "ok", + okButton: true, + cancelButton: false + }) + } + + async function confirm(option: ConfirmDialogOption = {}) { + return show({ + ...option, + defaultStatus: "cancel", + okButton: true, + cancelButton: true + }) + } + return { + confirm, + alert, + render, + show, + close, + randomId + } +}) diff --git a/frontend/src/components/hooks/show.ts b/frontend/src/components/hooks/show.ts new file mode 100644 index 00000000..f7fb6c62 --- /dev/null +++ b/frontend/src/components/hooks/show.ts @@ -0,0 +1,29 @@ +import type { Fn } from "@vueuse/core" +import type { InjectionKey, Ref } from "vue"; +import { inject, provide, ref, watch } from "vue" + +const IsOpenSymbol: InjectionKey> = Symbol("is-open") + +export function isShow() { + return inject(IsOpenSymbol, ref(false)) +} + +interface OnShowOption { + immediate?: boolean +} + +export function onShow(fn: Fn, { immediate = false }: OnShowOption = {}) { + return watch( + isShow(), + val => { + if (val) { + fn() + } + }, + { immediate } + ) +} + +export function provideShow(ref: Ref) { + provide(IsOpenSymbol, ref) +} diff --git a/frontend/src/components/hooks/types.ts b/frontend/src/components/hooks/types.ts new file mode 100644 index 00000000..6c837061 --- /dev/null +++ b/frontend/src/components/hooks/types.ts @@ -0,0 +1,11 @@ +import type { PropType } from "vue" + +export type ClassType = string | string[] + +export type BaseType = string | number | boolean | object | symbol | undefined + +export const valuePropType = [String, Number, Object, Boolean, Array] as PropType + +export const classPropType = [String, Array] as PropType + +export const labelPropType = [String, Function] as PropType string) | null> diff --git a/frontend/src/utils/open.ts b/frontend/src/utils/open.ts new file mode 100644 index 00000000..c921e904 --- /dev/null +++ b/frontend/src/utils/open.ts @@ -0,0 +1,100 @@ +import type { MaybeRef } from "@vueuse/core" +import querystring from "query-string" +import { h, isRef } from "vue" +import { useRouter } from "vue-router" +import { useDialog } from "@/components/hooks/dialog" + +interface UseOpenOption { + /* + + */ + width?: number + height?: number + scale?: number + query?: Record + + /** + * 是否打开新页面 + */ + target?: "_blank" | "_self" | false + + title?: string +} + +export function useOpenWindow(opt?: UseOpenOption & { immediate?: boolean }) { + const { show, close, randomId } = useDialog() + const router = useRouter() + + return async (maybeUrl: MaybeRef | (() => string), { width = 0, height = 0, target = "_self", query = {}, title = "DNF计算器 & Colg", scale = 1.0 }: UseOpenOption = {}) => { + let url = isRef(maybeUrl) ? maybeUrl.value : typeof maybeUrl === "function" ? maybeUrl() : maybeUrl + if (!url) { + return + } + + if (url.startsWith("/")) { + url = router.resolve(url).href + } + query.r = `${Math.random()}` + url = querystring.stringifyUrl({ url, query }) + try { + let _target = target + if (!_target) { + const rs = await show({ + content: "请确认打开新页面的方式", + okButton: "当前窗口", + rejectButton: "新窗口", + cancelButton: true, + defaultStatus: "cancel" + }) + if (rs.isOk) { + _target = "_self" + } else if (rs.isReject) { + _target = "_blank" + } + } + + if (_target == "_blank" || width * height < 1) { + window.open(url, _target as string) + + } else if (_target == "_self") { + + const id = randomId() + const onClose = (e: MessageEvent) => { + if (e.data == "close") { + close(id) + } + } + window.addEventListener("message", onClose) + const temp = await show({ + id, + header: title, + mask: true, + scale, + content() { + return h("iframe", { + name: Math.random().toString(36).slice(2), + referrerpolicy: "no-referrer", + frameborder: 0, + src: url, + style: { + width: `${width}px`, + height: `${height}px` + } + }) + } + }) + window.removeEventListener("message", onClose) + return temp + } + } catch (err) { + // let routerURL = router?.resolve({ + // path: url + // }) + // window.open(routerURL?.href) + // router.push(url) + // 网页端打开 + router?.push(url) + console.error(err) + } + } +} diff --git a/frontend/tsconfig.node.json b/frontend/tsconfig.node.json index c4575a8e..05c5f7ec 100644 --- a/frontend/tsconfig.node.json +++ b/frontend/tsconfig.node.json @@ -11,6 +11,7 @@ "compilerOptions": { "noEmit": true, "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "jsx": "preserve", "module": "ESNext", "moduleResolution": "Bundler", "types": ["node"] diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index 633c7c16..40f922dc 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -8,6 +8,7 @@ import Components from 'unplugin-vue-components/vite' import AutoImport from 'unplugin-auto-import/vite' import RekaResolver from 'reka-ui/resolver' import UnoCSS from 'unocss/vite' +import uncomponents from "unplugin-vue-components/vite" // https://vite.dev/config/ export default defineConfig({ @@ -16,6 +17,12 @@ export default defineConfig({ vueJsx(), // vueDevTools(), UnoCSS(), + uncomponents({ + dts: true, + dirs: ["src/components/"], + allowOverrides: true, + directoryAsNamespace: true + }), Components({ dts: 'src/types/components.d.ts', resolvers: [RekaResolver()], diff --git a/package.json b/package.json index 0f7b0199..7420bfba 100644 --- a/package.json +++ b/package.json @@ -10,5 +10,9 @@ }, "keywords": [], "author": "", - "license": "ISC" + "license": "ISC", + "dependencies": { + "hoci": "^0.6.0", + "query-string": "^9.1.1" + } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 00000000..89b82582 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,773 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + hoci: + specifier: ^0.6.0 + version: 0.6.0(@babel/parser@7.27.0)(@vueuse/core@9.0.0(vue@3.5.13))(vue@3.5.13) + query-string: + specifier: ^9.1.1 + version: 9.1.1 + +packages: + + '@antfu/utils@0.7.10': + resolution: {integrity: sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==} + + '@babel/helper-string-parser@7.25.9': + resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.25.9': + resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.27.0': + resolution: {integrity: sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/types@7.27.0': + resolution: {integrity: sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==} + engines: {node: '>=6.9.0'} + + '@hoci/components@0.6.0': + resolution: {integrity: sha512-FKWh6JmV5iezDGdQq/UOQ6PfJNRzWfjrN6C6s8Q2QoQMJTC3wAQXJjsKP+OsO2tdizYA1NBBwfow4Oi2X6GZcg==} + peerDependencies: + '@vueuse/core': '>=9.0.0' + vue: ^3.0.0-0 + + '@hoci/core@0.6.0': + resolution: {integrity: sha512-lFV5gFNNzdH5cTmXHonKRaRKt0FDZX9kQ18xwWP89yoDAXrpXbRt5ZK8oQgqCHdWYtwDcVrAMZ+IZmhkCBiO6g==} + peerDependencies: + vue: ^3.0.0-0 + + '@hoci/shared@0.6.0': + resolution: {integrity: sha512-XreSiu+AFisDKorgugX8zjNEsv889U6SbbkTLPHlYIcLvSYk33TmwQ5jHpHe1RAE2KE2Xxn9fBqYRlOCAn8ujg==} + peerDependencies: + '@vueuse/core': '>=9.0.0' + vue: ^3.0.0-0 + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@rollup/pluginutils@5.1.4': + resolution: {integrity: sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@types/estree@1.0.7': + resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} + + '@types/web-bluetooth@0.0.15': + resolution: {integrity: sha512-w7hEHXnPMEZ+4nGKl/KDRVpxkwYxYExuHOYXyzIzCDzEZ9ZCGMAewulr9IqJu2LR4N37fcnb1XVeuZ09qgOxhA==} + + '@vue/compiler-core@3.5.13': + resolution: {integrity: sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==} + + '@vue/compiler-dom@3.5.13': + resolution: {integrity: sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==} + + '@vue/compiler-sfc@3.5.13': + resolution: {integrity: sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==} + + '@vue/compiler-ssr@3.5.13': + resolution: {integrity: sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==} + + '@vue/reactivity@3.5.13': + resolution: {integrity: sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==} + + '@vue/runtime-core@3.5.13': + resolution: {integrity: sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==} + + '@vue/runtime-dom@3.5.13': + resolution: {integrity: sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==} + + '@vue/server-renderer@3.5.13': + resolution: {integrity: sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA==} + peerDependencies: + vue: 3.5.13 + + '@vue/shared@3.5.13': + resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==} + + '@vueuse/core@9.0.0': + resolution: {integrity: sha512-hMMc2ajuVknkL7Z39JdP9gFFND2OgnDTSS5mmuinWGAE1Vxy1AwDvTHm3+juyk+GzJjYRAktnBIPy7Fq53iOnw==} + + '@vueuse/metadata@9.0.0': + resolution: {integrity: sha512-79YVIsAP1bbWm5GdQuG7jDVF/9uuExzhkO0Sd4/TLuSfzH2uZOrHvGwy+ZNJHjbyRn3uf56rKINWLJdBuTLSqQ==} + + '@vueuse/shared@9.0.0': + resolution: {integrity: sha512-WRCyr/wIz5e/2gR/+qFucbCUcGMyJKkQZAzlECl3e71ebQQ9X/w3aBWT9FbnogJX+DNZ/t3Pj+TqPbC7TH1Yog==} + + acorn@8.14.1: + resolution: {integrity: sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==} + engines: {node: '>=0.4.0'} + hasBin: true + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + debug@4.4.0: + resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decode-uri-component@0.4.1: + resolution: {integrity: sha512-+8VxcR21HhTy8nOt6jf20w0c9CADrw1O8d+VZ/YzzCt4bJ3uBjw+D1q2osAB8RnpwwaeYBxy0HyKQxD5JBMuuQ==} + engines: {node: '>=14.16'} + + defu@6.1.4: + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fastq@1.19.1: + resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + filter-obj@5.1.0: + resolution: {integrity: sha512-qWeTREPoT7I0bifpPUXtxkZJ1XJzxWtfoWWkdVGqa+eCr3SHW/Ocp89o8vLvbUuQnadybJpjOKu4V+RwO6sGng==} + engines: {node: '>=14.16'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + hoci@0.6.0: + resolution: {integrity: sha512-PtSPRtQm5/OUKxSU8lVelhBc+3TVW2cB2hGlG9pfzQ0rbSBFgLHWSLImBgLZnau72wKOrMNjBxzprQ941+rTWw==} + peerDependencies: + vue: ^3.0.0 + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + local-pkg@0.5.1: + resolution: {integrity: sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==} + engines: {node: '>=14'} + + magic-string@0.30.17: + resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + + maybe-types@0.2.0: + resolution: {integrity: sha512-4ul+RHPcxNznI+Ke6xUT2/mcQTl54fYUdRZQ3QNkQsC4USfAxXkPTh+wEOx4UBsXYg214867v2ZeirQDJT7uOA==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + mlly@1.7.4: + resolution: {integrity: sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + picomatch@4.0.2: + resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + engines: {node: '>=12'} + + pkg-types@1.3.1: + resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + + postcss@8.5.3: + resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} + engines: {node: ^10 || ^12 || >=14} + + query-string@9.1.1: + resolution: {integrity: sha512-MWkCOVIcJP9QSKU52Ngow6bsAWAPlPK2MludXvcrS2bGZSl+T1qX9MZvRIkqUIkGLJquMJHWfsT6eRqUpp4aWg==} + engines: {node: '>=18'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + split-on-first@3.0.0: + resolution: {integrity: sha512-qxQJTx2ryR0Dw0ITYyekNQWpz6f8dGd7vffGNflQQ3Iqj9NJ6qiZ7ELpZsJ/QBhIVAiDfXdag3+Gp8RvWa62AA==} + engines: {node: '>=12'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + tslx@0.1.1: + resolution: {integrity: sha512-MYh2I7iw8owRx3xFVq8DXp3JWoJ7G7oMA5uUrCwGvuOipV6w9XvlJKo3yVJMh75Y+5caIaYhCsUZ1WTnxQRk7A==} + + type-fest@4.38.0: + resolution: {integrity: sha512-2dBz5D5ycHIoliLYLi0Q2V7KRaDlH0uWIvmk7TYlAg5slqwiPv1ezJdZm1QEM0xgk29oYWMCbIG7E6gHpvChlg==} + engines: {node: '>=16'} + + ufo@1.5.4: + resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} + + unplugin-vue-components@0.27.5: + resolution: {integrity: sha512-m9j4goBeNwXyNN8oZHHxvIIYiG8FQ9UfmKWeNllpDvhU7btKNNELGPt+o3mckQKuPwrE7e0PvCsx+IWuDSD9Vg==} + engines: {node: '>=14'} + peerDependencies: + '@babel/parser': ^7.15.8 + '@nuxt/kit': ^3.2.2 + vue: 2 || 3 + peerDependenciesMeta: + '@babel/parser': + optional: true + '@nuxt/kit': + optional: true + + unplugin@1.16.1: + resolution: {integrity: sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==} + engines: {node: '>=14.0.0'} + + vue-demi@0.14.10: + resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==} + engines: {node: '>=12'} + hasBin: true + peerDependencies: + '@vue/composition-api': ^1.0.0-rc.1 + vue: ^3.0.0-0 || ^2.6.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + + vue@3.5.13: + resolution: {integrity: sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + webpack-virtual-modules@0.6.2: + resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} + +snapshots: + + '@antfu/utils@0.7.10': + optional: true + + '@babel/helper-string-parser@7.25.9': {} + + '@babel/helper-validator-identifier@7.25.9': {} + + '@babel/parser@7.27.0': + dependencies: + '@babel/types': 7.27.0 + + '@babel/types@7.27.0': + dependencies: + '@babel/helper-string-parser': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + + '@hoci/components@0.6.0(@vueuse/core@9.0.0(vue@3.5.13))(vue@3.5.13)': + dependencies: + '@hoci/core': 0.6.0(vue@3.5.13) + '@hoci/shared': 0.6.0(@vueuse/core@9.0.0(vue@3.5.13))(vue@3.5.13) + '@vueuse/core': 9.0.0(vue@3.5.13) + maybe-types: 0.2.0 + tslx: 0.1.1 + vue: 3.5.13 + transitivePeerDependencies: + - '@vue/composition-api' + + '@hoci/core@0.6.0(vue@3.5.13)': + dependencies: + '@hoci/shared': 0.6.0(@vueuse/core@9.0.0(vue@3.5.13))(vue@3.5.13) + '@vueuse/core': 9.0.0(vue@3.5.13) + maybe-types: 0.2.0 + tslx: 0.1.1 + vue: 3.5.13 + transitivePeerDependencies: + - '@vue/composition-api' + + '@hoci/shared@0.6.0(@vueuse/core@9.0.0(vue@3.5.13))(vue@3.5.13)': + dependencies: + '@vueuse/core': 9.0.0(vue@3.5.13) + defu: 6.1.4 + maybe-types: 0.2.0 + type-fest: 4.38.0 + vue: 3.5.13 + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + optional: true + + '@nodelib/fs.stat@2.0.5': + optional: true + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.19.1 + optional: true + + '@rollup/pluginutils@5.1.4': + dependencies: + '@types/estree': 1.0.7 + estree-walker: 2.0.2 + picomatch: 4.0.2 + optional: true + + '@types/estree@1.0.7': + optional: true + + '@types/web-bluetooth@0.0.15': {} + + '@vue/compiler-core@3.5.13': + dependencies: + '@babel/parser': 7.27.0 + '@vue/shared': 3.5.13 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + + '@vue/compiler-dom@3.5.13': + dependencies: + '@vue/compiler-core': 3.5.13 + '@vue/shared': 3.5.13 + + '@vue/compiler-sfc@3.5.13': + dependencies: + '@babel/parser': 7.27.0 + '@vue/compiler-core': 3.5.13 + '@vue/compiler-dom': 3.5.13 + '@vue/compiler-ssr': 3.5.13 + '@vue/shared': 3.5.13 + estree-walker: 2.0.2 + magic-string: 0.30.17 + postcss: 8.5.3 + source-map-js: 1.2.1 + + '@vue/compiler-ssr@3.5.13': + dependencies: + '@vue/compiler-dom': 3.5.13 + '@vue/shared': 3.5.13 + + '@vue/reactivity@3.5.13': + dependencies: + '@vue/shared': 3.5.13 + + '@vue/runtime-core@3.5.13': + dependencies: + '@vue/reactivity': 3.5.13 + '@vue/shared': 3.5.13 + + '@vue/runtime-dom@3.5.13': + dependencies: + '@vue/reactivity': 3.5.13 + '@vue/runtime-core': 3.5.13 + '@vue/shared': 3.5.13 + csstype: 3.1.3 + + '@vue/server-renderer@3.5.13(vue@3.5.13)': + dependencies: + '@vue/compiler-ssr': 3.5.13 + '@vue/shared': 3.5.13 + vue: 3.5.13 + + '@vue/shared@3.5.13': {} + + '@vueuse/core@9.0.0(vue@3.5.13)': + dependencies: + '@types/web-bluetooth': 0.0.15 + '@vueuse/metadata': 9.0.0 + '@vueuse/shared': 9.0.0(vue@3.5.13) + vue-demi: 0.14.10(vue@3.5.13) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + '@vueuse/metadata@9.0.0': {} + + '@vueuse/shared@9.0.0(vue@3.5.13)': + dependencies: + vue-demi: 0.14.10(vue@3.5.13) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + acorn@8.14.1: + optional: true + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + optional: true + + balanced-match@1.0.2: + optional: true + + binary-extensions@2.3.0: + optional: true + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + optional: true + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + optional: true + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + optional: true + + confbox@0.1.8: + optional: true + + csstype@3.1.3: {} + + debug@4.4.0: + dependencies: + ms: 2.1.3 + optional: true + + decode-uri-component@0.4.1: {} + + defu@6.1.4: {} + + entities@4.5.0: {} + + estree-walker@2.0.2: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + optional: true + + fastq@1.19.1: + dependencies: + reusify: 1.1.0 + optional: true + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + optional: true + + filter-obj@5.1.0: {} + + fsevents@2.3.3: + optional: true + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + optional: true + + hoci@0.6.0(@babel/parser@7.27.0)(@vueuse/core@9.0.0(vue@3.5.13))(vue@3.5.13): + dependencies: + '@hoci/components': 0.6.0(@vueuse/core@9.0.0(vue@3.5.13))(vue@3.5.13) + '@hoci/core': 0.6.0(vue@3.5.13) + vue: 3.5.13 + optionalDependencies: + unplugin-vue-components: 0.27.5(@babel/parser@7.27.0)(vue@3.5.13) + transitivePeerDependencies: + - '@babel/parser' + - '@nuxt/kit' + - '@vue/composition-api' + - '@vueuse/core' + - rollup + - supports-color + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + optional: true + + is-extglob@2.1.1: + optional: true + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + optional: true + + is-number@7.0.0: + optional: true + + local-pkg@0.5.1: + dependencies: + mlly: 1.7.4 + pkg-types: 1.3.1 + optional: true + + magic-string@0.30.17: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + maybe-types@0.2.0: {} + + merge2@1.4.1: + optional: true + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + optional: true + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + optional: true + + mlly@1.7.4: + dependencies: + acorn: 8.14.1 + pathe: 2.0.3 + pkg-types: 1.3.1 + ufo: 1.5.4 + optional: true + + ms@2.1.3: + optional: true + + nanoid@3.3.11: {} + + normalize-path@3.0.0: + optional: true + + pathe@2.0.3: + optional: true + + picocolors@1.1.1: {} + + picomatch@2.3.1: + optional: true + + picomatch@4.0.2: + optional: true + + pkg-types@1.3.1: + dependencies: + confbox: 0.1.8 + mlly: 1.7.4 + pathe: 2.0.3 + optional: true + + postcss@8.5.3: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + query-string@9.1.1: + dependencies: + decode-uri-component: 0.4.1 + filter-obj: 5.1.0 + split-on-first: 3.0.0 + + queue-microtask@1.2.3: + optional: true + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + optional: true + + reusify@1.1.0: + optional: true + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + optional: true + + source-map-js@1.2.1: {} + + split-on-first@3.0.0: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + optional: true + + tslx@0.1.1: + dependencies: + csstype: 3.1.3 + + type-fest@4.38.0: {} + + ufo@1.5.4: + optional: true + + unplugin-vue-components@0.27.5(@babel/parser@7.27.0)(vue@3.5.13): + dependencies: + '@antfu/utils': 0.7.10 + '@rollup/pluginutils': 5.1.4 + chokidar: 3.6.0 + debug: 4.4.0 + fast-glob: 3.3.3 + local-pkg: 0.5.1 + magic-string: 0.30.17 + minimatch: 9.0.5 + mlly: 1.7.4 + unplugin: 1.16.1 + vue: 3.5.13 + optionalDependencies: + '@babel/parser': 7.27.0 + transitivePeerDependencies: + - rollup + - supports-color + optional: true + + unplugin@1.16.1: + dependencies: + acorn: 8.14.1 + webpack-virtual-modules: 0.6.2 + optional: true + + vue-demi@0.14.10(vue@3.5.13): + dependencies: + vue: 3.5.13 + + vue@3.5.13: + dependencies: + '@vue/compiler-dom': 3.5.13 + '@vue/compiler-sfc': 3.5.13 + '@vue/runtime-dom': 3.5.13 + '@vue/server-renderer': 3.5.13(vue@3.5.13) + '@vue/shared': 3.5.13 + + webpack-virtual-modules@0.6.2: + optional: true