style: mobile ui

This commit is contained in:
Neko Ayaka
2024-12-27 17:41:37 +08:00
parent ea3f23683a
commit 6ac91262a7
18 changed files with 672 additions and 71 deletions
+2 -1
View File
@@ -37,6 +37,7 @@ words:
- hiyori
- huggingface
- huggingspace
- hyoban
- iconify
- intlify
- kwaa
@@ -63,6 +64,7 @@ words:
- pixiv
- pretrained
- rehype
- Shadcn
- shiki
- shikijs
- silero
@@ -81,6 +83,5 @@ words:
- webgpu
- worklet
- xsai
- hfup
ignoreWords: []
import: []
+3
View File
@@ -65,6 +65,7 @@
"three": "^0.171.0",
"unified": "^11.0.5",
"valibot": "1.0.0-beta.9",
"vaul-vue": "^0.2.0",
"vue": "^3.5.13",
"vue-demi": "^0.14.10",
"vue-i18n": "^10.0.5",
@@ -90,6 +91,8 @@
"@vueuse/motion": "^2.2.6",
"hfup": "workspace:^",
"markdown-it-link-attributes": "^4.0.1",
"unocss-preset-animations": "^1.1.0",
"unocss-preset-shadcn": "^0.3.1",
"unocss-preset-theme": "^0.14.1",
"unplugin-auto-import": "^0.19.0",
"unplugin-vue-components": "^0.28.0",
@@ -3,7 +3,7 @@ import Settings from '../Settings.vue'
</script>
<template>
<header flex="~" mb-1 w-full gap-2>
<header mb-1 w-full gap-2>
<div flex="~ 1" w-full items-center gap-2 px-2 text-nowrap text-2xl>
<div i-solar:cat-outline text="[#ed869d]" />
<div font-cute>
@@ -101,7 +101,7 @@ onAfterSend(async () => {
</script>
<template>
<div flex="~ col" h-full w-full items-center pt-4>
<div flex="col" h-full w-full items-center pt-4>
<fieldset flex="~ row" w-fit rounded-lg>
<label
:class="[
@@ -0,0 +1,10 @@
<template>
<header mb-1 w-full gap-2>
<div flex="~ 1" w-full items-center justify-center gap-2 px-2 text-nowrap text-lg>
<div i-solar:cat-outline text="[#ed869d]" />
<div font-cute>
<span>アイリ</span>
</div>
</div>
</header>
</template>
@@ -0,0 +1,127 @@
<script setup lang="ts">
// import { useDevicesList } from '@vueuse/core'
import { storeToRefs } from 'pinia'
import { DrawerContent, DrawerOverlay, DrawerPortal, DrawerRoot, DrawerTrigger } from 'vaul-vue'
import { onMounted, ref, watch } from 'vue'
import { useI18n } from 'vue-i18n'
import { useMicVAD } from '../../composables/micvad'
// import { useAudioContext } from '../../stores/audio'
import { useChatStore } from '../../stores/chat'
import { useSettings } from '../../stores/settings'
import MobileSettings from '../Widgets/MobileSettings.vue'
const messageInput = ref('')
const listening = ref(false)
// const { audioInputs } = useDevicesList({ constraints: { audio: true }, requestPermissions: true })
// const { selectedAudioDevice, isAudioInputOn, selectedAudioDeviceId } = storeToRefs(useSettings())
const { isAudioInputOn, selectedAudioDeviceId } = storeToRefs(useSettings())
const { send, onAfterSend } = useChatStore()
const { t } = useI18n()
async function handleSend() {
if (!messageInput.value.trim()) {
return
}
await send(messageInput.value)
}
const { destroy, start } = useMicVAD(selectedAudioDeviceId, {
onSpeechStart: () => {
// TODO: interrupt the playback
// TODO: interrupt any of the ongoing TTS
// TODO: interrupt any of the ongoing LLM requests
// TODO: interrupt any of the ongoing animation of Live2D or VRM
// TODO: once interrupted, we should somehow switch to listen or thinking
// emotion / expression?
listening.value = true
},
// VAD misfire means while speech end is detected but
// the frames of the segment of the audio buffer
// is not enough to be considered as a speech segment
// which controlled by the `minSpeechFrames` parameter
onVADMisfire: () => {
// TODO: do audio buffer send to whisper
listening.value = false
},
onSpeechEnd: (buffer) => {
// TODO: do audio buffer send to whisper
listening.value = false
handleTranscription(buffer)
},
auto: false,
})
function handleTranscription(_buffer: Float32Array<ArrayBufferLike>) {
// eslint-disable-next-line no-alert
alert('Transcription is not implemented yet')
}
// async function handleAudioInputChange(event: Event) {
// const target = event.target as HTMLSelectElement
// const found = audioInputs.value.find(d => d.deviceId === target.value)
// if (!found) {
// selectedAudioDevice.value = undefined
// return
// }
// selectedAudioDevice.value = found
// }
watch(isAudioInputOn, async (value) => {
if (value === 'false') {
destroy()
}
})
onAfterSend(async () => {
messageInput.value = ''
})
onMounted(() => {
start()
})
</script>
<template>
<div w-full flex gap-1>
<div flex flex-1>
<BasicTextarea
v-model="messageInput"
:placeholder="t('stage.message')"
border="solid 2 pink-100 dark:pink-400/20"
text="pink-400 hover:pink-600 dark:pink-400/50 dark:hover:pink-600 placeholder:pink-400 placeholder:hover:pink-600 placeholder:dark:pink-400/50 placeholder:dark:hover:pink-600"
bg="pink-50 dark:pink-400/20" max-h="[10lh]" min-h="[1lh]"
w-full resize-none overflow-y-scroll rounded-l-xl p-2 font-medium outline-none
transition="all duration-250 ease-in-out placeholder:all placeholder:duration-250 placeholder:ease-in-out"
@submit="handleSend"
/>
</div>
<DrawerRoot should-scale-background>
<DrawerTrigger
class="px-4 py-2.5"
border="solid 2 pink-100 dark:pink-400/20"
text="lg pink-400 hover:pink-600 dark:pink-400/50 dark:hover:pink-600 placeholder:pink-400 placeholder:hover:pink-600 placeholder:dark:pink-400/50 placeholder:dark:hover:pink-600"
bg="pink-50 dark:pink-400/20" max-h="[10lh]" min-h="[1lh]" rounded-r-xl
>
<div i-solar:settings-bold-duotone />
</DrawerTrigger>
<DrawerPortal>
<DrawerOverlay class="fixed inset-0 bg-black/40" />
<DrawerContent
max-h="[75%]"
fixed bottom-0 left-0 right-0
mt-24 h-full flex flex-col
rounded-t-lg bg="[#fffbff] dark:[#1f1a1d]"
>
<div class="flex flex-1 flex-col rounded-t-lg p-5" bg="[#fffbff] dark:[#1f1a1d]" gap-2>
<MobileSettings />
</div>
</DrawerContent>
</DrawerPortal>
</DrawerRoot>
</div>
</template>
@@ -35,7 +35,7 @@ defineExpose({
<template>
<Screen v-slot="{ width, height }" relative>
<Live2DViewer ref="modelRef" :canvas-width="width" :canvas-height="height" :model="model" :mouth-open-size="mouthOpenSize" />
<div absolute top="2">
<div absolute bottom="2" right="2">
<div
flex="~ row"
bg="zinc-100 dark:zinc-700"
+1 -1
View File
@@ -54,7 +54,7 @@ defineExpose({
@error="(val) => emit('error', val)"
/>
</TresCanvas>
<div absolute top="2">
<div absolute bottom="2" right="2">
<div
flex="~ row"
bg="zinc-100 dark:zinc-700"
+1 -1
View File
@@ -3,8 +3,8 @@ import { useDark } from '@vueuse/core'
import { storeToRefs } from 'pinia'
import { onMounted, ref, watch } from 'vue'
import { useI18n } from 'vue-i18n'
import { useLLM } from '../stores/llm'
import { useLLM } from '../stores/llm'
import { useSettings } from '../stores/settings'
import TransitionVertical from './TransitionVertical.vue'
@@ -0,0 +1,82 @@
<script setup lang="ts">
import { useElementBounding, useScroll } from '@vueuse/core'
import { storeToRefs } from 'pinia'
import { nextTick, ref } from 'vue'
import { useMarkdown } from '../../composables/markdown'
import { useChatStore } from '../../stores/chat'
const chatHistoryRef = ref<HTMLDivElement>()
const { messages } = storeToRefs(useChatStore())
const bounding = useElementBounding(chatHistoryRef, { immediate: true, windowScroll: true, windowResize: true })
const { y: chatHistoryContainerY } = useScroll(chatHistoryRef)
const { process } = useMarkdown()
const { onBeforeMessageComposed, onTokenLiteral } = useChatStore()
onBeforeMessageComposed(async () => {
// Scroll down to the new sent message
nextTick().then(() => {
bounding.update()
chatHistoryContainerY.value = bounding.height.value
})
})
onTokenLiteral(async () => {
// Scroll down to the new responding message
nextTick().then(() => {
bounding.update()
chatHistoryContainerY.value = bounding.height.value
})
})
</script>
<template>
<div
relative
class="<md:(absolute left-0 top-0 from-zinc-100/80 to-zinc-800/0 bg-gradient-to-t p-2 dark:from-zinc-800/80)"
px="<sm:2" py="<sm:2" flex="~ col"
rounded="lg"
overflow-hidden
>
<div flex-1 /> <!-- spacer -->
<div ref="chatHistoryRef" v-auto-animate h-full w-full flex="~ col" overflow-scroll>
<div flex-1 /> <!-- spacer -->
<div v-for="(message, index) in messages" :key="index" mb-2>
<div v-if="message.role === 'assistant'" flex mr="12">
<div
flex="~ col"
border="4 solid pink-200/50 dark:pink-500/50"
shadow="md pink-200/50 dark:none"
min-w-20 rounded-lg px-2 py-1
h="unset <sm:fit"
bg="<md:pink-500/25"
>
<div>
<span text-xs text="pink-400/90 dark:pink-600/90" font-semibold class="inline <sm:hidden">Airi</span>
</div>
<div v-if="message.content" class="markdown-content" text="base <sm:xs" v-html="process(message.content as string)" />
<div v-else i-eos-icons:three-dots-loading />
</div>
</div>
<div v-else-if="message.role === 'user'" flex="~ row-reverse" ml="12">
<div
flex="~ col"
border="4 solid teal-200/50 dark:teal-500/50"
shadow="md teal-200/50 dark:none"
px="2"
h="unset <sm:fit" min-w-20 rounded-lg px-2 py-1
bg="<md:teal-500/25"
>
<div>
<span text-xs text="teal-400/90 dark:teal-600/90" font-semibold class="inline <sm:hidden">You</span>
</div>
<div v-if="message.content" class="markdown-content" text="base <sm:xs" v-html="process(message.content as string)" />
<div v-else />
</div>
</div>
</div>
</div>
</div>
</template>
@@ -0,0 +1,181 @@
<script setup lang="ts">
import { useDark } from '@vueuse/core'
import { storeToRefs } from 'pinia'
import { onMounted, ref, watch } from 'vue'
import { useI18n } from 'vue-i18n'
import { useLLM } from '../../stores/llm'
import { useSettings } from '../../stores/settings'
const { t } = useI18n()
const settings = useSettings()
const dark = useDark({ disableTransition: false })
const supportedModels = ref<{ id: string, name?: string }[]>([])
const { models } = useLLM()
const { openAiModel, openAiApiBaseURL, openAiApiKey } = storeToRefs(settings)
function handleModelChange(event: Event) {
const target = event.target as HTMLSelectElement
const found = supportedModels.value.find(m => m.id === target.value)
if (!found) {
openAiModel.value = undefined
return
}
openAiModel.value = found
}
function handleViewChange(event: Event) {
const target = event.target as HTMLSelectElement
settings.stageView = target.value
}
watch([openAiApiBaseURL, openAiApiKey], async ([baseUrl, apiKey]) => {
if (!baseUrl || !apiKey) {
supportedModels.value = []
return
}
supportedModels.value = await models(baseUrl, apiKey)
})
onMounted(async () => {
if (!openAiApiBaseURL.value || !openAiApiKey.value)
return
supportedModels.value = await models(openAiApiBaseURL.value, openAiApiKey.value)
})
</script>
<template>
<div>
<h2 text="slate-800/80 dark:slate-200/80 xl" font-bold>
Settings
</h2>
<div flex="~" gap-2>
<div
grid="~ cols-[140px_1fr]" my-2 items-center gap-1.5 rounded-lg
bg="[#fff6fc] dark:[#2c2529]" px-2 py-1 text="pink-400"
>
<div text="sm pink-500">
<span>{{ t('settings.openai-base-url.label') }}</span>
</div>
<div flex="~ row" w-full text="sm">
<input
v-model="settings.openAiApiBaseURL"
type="text"
:placeholder="t('settings.openai-base-url.placeholder')"
w-full rounded-md bg-transparent px-2 py-1 text-right font-mono outline-none
>
</div>
<div text="sm pink-500">
<span>{{ t('settings.openai-api-key.label') }}</span>
</div>
<div flex="~ row" w-full text="sm">
<input
v-model="settings.openAiApiKey"
type="text"
:placeholder="t('settings.openai-api-key.placeholder')"
w-full rounded-md bg-transparent px-2 py-1 text-right font-mono outline-none
>
</div>
<div text="sm pink-500">
<span>{{ t('settings.elevenlabs-api-key.label') }}</span>
</div>
<div flex="~ row" w-full text="sm">
<input
v-model="settings.elevenLabsApiKey"
type="text"
:placeholder="t('settings.elevenlabs-api-key.placeholder')"
w-full rounded-md bg-transparent px-2 py-1 text-right font-mono outline-none
>
</div>
<div text="sm pink-500">
<span>{{ t('settings.language') }}</span>
</div>
<div flex="~ row" w-full text="sm">
<select
v-model="settings.language"
w-full rounded-md bg-transparent px-2 py-1 text-right font-mono outline-none
>
<option value="en-US">
English
</option>
<option value="zh-CN">
简体中文
</option>
</select>
</div>
<div text="sm pink-500">
<span>{{ t('settings.models') }}</span>
</div>
<div flex="~ row" w-full text="sm">
<select
w-full rounded-md bg-transparent px-2 py-1 font-mono outline-none
@change="handleModelChange"
>
<option disabled class="bg-white dark:bg-zinc-800">
{{ t('stage.select-a-model') }}
</option>
<option v-if="settings.openAiModel" :value="settings.openAiModel.id">
{{ 'name' in settings.openAiModel ? `${settings.openAiModel.name} (${settings.openAiModel.id})` : settings.openAiModel.id }}
</option>
<option v-for="m in supportedModels" :key="m.id" :value="m.id">
{{ 'name' in m ? `${m.name} (${m.id})` : m.id }}
</option>
</select>
</div>
</div>
</div>
<h2 text="slate-800/80 dark:slate-200/80 xl" font-bold>
View
</h2>
<div>
<div
grid="~ cols-[140px_1fr]" my-2 items-center gap-1.5 rounded-lg
bg="[#fff6fc] dark:[#2c2529]" px-2 py-1 text="pink-400"
>
<div text="sm pink-500">
<span>Theme</span>
</div>
<label
h-fit cursor-pointer rounded-md px-2 py-2
>
<select
w-full rounded-md bg-transparent px-2 py-1 text-right font-mono outline-none
@change="handleViewChange"
>
<option value="2d">
2D
</option>
<option value="3d">
3D
</option>
</select>
</label>
<div text="sm pink-500">
<span>Theme</span>
</div>
<label
h-fit cursor-pointer rounded-md px-2 py-2
>
<input
v-model="dark"
:checked="dark"
:aria-checked="dark"
name="stageView"
type="checkbox"
hidden appearance-none outline-none
>
<div flex select-none justify-end>
<Transition name="slide-away" mode="out-in">
<div v-if="dark" i-solar:sun-fog-bold-duotone text="lg hover:pink-600 dark:hover:pink-300" transition="all ease-in-out duration-250" />
<div v-else i-solar:moon-stars-bold-duotone text="lg hover:pink-600 dark:hover:pink-300" transition="all ease-in-out duration-250" />
</Transition>
</div>
</label>
</div>
</div>
</div>
</template>
+8 -4
View File
@@ -1,15 +1,19 @@
<script setup lang="ts">
import Header from '../components/Layouts/Header.vue'
import InteractiveArea from '../components/Layouts/InteractiveArea.vue'
import MobileHeader from '../components/Layouts/MobileHeader.vue'
import MobileInteractiveArea from '../components/Layouts/MobileInteractiveArea.vue'
import Stage from '../components/Widgets/Stage.vue'
</script>
<template>
<div h-full max-h="[100vh]" max-w="[100vw]" p="2" flex="~ col" overflow-hidden>
<Header />
<div flex="~ row 1 <md:col" relative h-full w-full items-end gap-2>
<Stage w="full <md:100%" h="full <md:60%" />
<InteractiveArea w="full <md:100%" h="full <md:40%" />
<Header class="flex <md:hidden" />
<MobileHeader class="hidden <md:block" />
<div flex="~ 1 row <md:col" relative h-full w-full items-end gap-2>
<Stage h-full w-full flex-1 mb="<md:18" min-w="50%" />
<InteractiveArea w="full <md:100%" h="full <md:40%" class="flex <md:hidden" />
<MobileInteractiveArea w="full" class="md:hidden <md:flex" absolute bottom-0 />
</div>
</div>
</template>
+3 -1
View File
@@ -1,4 +1,4 @@
import type { AssistantMessage, Message } from '@xsai/shared-chat'
import { assistant, type AssistantMessage, type Message, user } from '@xsai/shared-chat'
import { defineStore, storeToRefs } from 'pinia'
import { ref } from 'vue'
@@ -55,6 +55,8 @@ export const useChatStore = defineStore('chat', () => {
t('prompt.prefix'),
t('prompt.suffix'),
),
user('Hello!'),
assistant('Hello!'),
])
const streamingMessage = ref<AssistantMessage>({ role: 'assistant', content: '' })
+1
View File
@@ -6,6 +6,7 @@ body,
height: 100%;
margin: 0;
padding: 0;
overscroll-behavior: none;
}
html {
-9
View File
@@ -18,14 +18,5 @@ declare module 'vue-router/auto-routes' {
* Route name map generated by unplugin-vue-router
*/
export interface RouteNamedMap {
'/': RouteRecordInfo<'/', '/', Record<never, never>, Record<never, never>>,
'/[...all]': RouteRecordInfo<'/[...all]', '/:all(.*)', { all: ParamValue<true> }, { all: ParamValue<false> }>,
'/audio': RouteRecordInfo<'/audio', '/audio', Record<never, never>, Record<never, never>>,
'/devtools/image': RouteRecordInfo<'/devtools/image', '/devtools/image', Record<never, never>, Record<never, never>>,
'/queue': RouteRecordInfo<'/queue', '/queue', Record<never, never>, Record<never, never>>,
'/test/filter-message': RouteRecordInfo<'/test/filter-message', '/test/filter-message', Record<never, never>, Record<never, never>>,
'/test/queues/delays': RouteRecordInfo<'/test/queues/delays', '/test/queues/delays', Record<never, never>, Record<never, never>>,
'/test/queues/emotions': RouteRecordInfo<'/test/queues/emotions', '/test/queues/emotions', Record<never, never>, Record<never, never>>,
'/test/queues/messages': RouteRecordInfo<'/test/queues/messages', '/test/queues/messages', Record<never, never>, Record<never, never>>,
}
}
+24 -39
View File
@@ -1,49 +1,11 @@
import { defineConfig, mergeConfigs, presetWebFonts } from 'unocss'
// import presetTheme from 'unocss-preset-theme'
import presetAnimations from 'unocss-preset-animations'
import UnoCSSConfig from '../../uno.config'
export default defineConfig(mergeConfigs([
UnoCSSConfig,
{
presets: [
// presetTheme({
// theme: {
// light: {
// colors: {
// primary: {
// 50: 'var(--airi-theme-primary-50)',
// 100: 'var(--airi-theme-primary-100)',
// 200: 'var(--airi-theme-primary-200)',
// 300: 'var(--airi-theme-primary-300)',
// 400: 'var(--airi-theme-primary-400)',
// 500: 'var(--airi-theme-primary-500)',
// 600: 'var(--airi-theme-primary-600)',
// 700: 'var(--airi-theme-primary-700)',
// 800: 'var(--airi-theme-primary-800)',
// 900: 'var(--airi-theme-primary-900)',
// 950: 'var(--airi-theme-primary-950)',
// },
// },
// },
// dark: {
// colors: {
// primary: {
// 50: 'var(--airi-theme-primary-50)',
// 100: 'var(--airi-theme-primary-100)',
// 200: 'var(--airi-theme-primary-200)',
// 300: 'var(--airi-theme-primary-300)',
// 400: 'var(--airi-theme-primary-400)',
// 500: 'var(--airi-theme-primary-500)',
// 600: 'var(--airi-theme-primary-600)',
// 700: 'var(--airi-theme-primary-700)',
// 800: 'var(--airi-theme-primary-800)',
// 900: 'var(--airi-theme-primary-900)',
// 950: 'var(--airi-theme-primary-950)',
// },
// },
// },
// },
// }),
presetWebFonts({
fonts: {
sans: 'DM Sans',
@@ -53,6 +15,29 @@ export default defineConfig(mergeConfigs([
cuteen: 'Sniglet',
},
}),
// hyoban/unocss-preset-shadcn: Use shadcn ui with UnoCSS
// https://github.com/hyoban/unocss-preset-shadcn
presetAnimations(),
],
// hyoban/unocss-preset-shadcn: Use shadcn ui with UnoCSS
// https://github.com/hyoban/unocss-preset-shadcn
//
// Thanks to
// https://github.com/unovue/shadcn-vue/issues/34#issuecomment-2467318118
// https://github.com/hyoban-template/shadcn-vue-unocss-starter
//
// By default, `.ts` and `.js` files are NOT extracted.
// If you want to extract them, use the following configuration.
// It's necessary to add the following configuration if you use shadcn-vue or shadcn-svelte.
content: {
pipeline: {
include: [
// the default
/\.(vue|svelte|[jt]sx|mdx?|astro|elm|php|phtml|html)($|\?)/,
// include js/ts files
'(components|src)/**/*.{js,ts}',
],
},
},
},
]))
+9 -12
View File
@@ -1,8 +1,8 @@
import { Buffer } from 'node:buffer'
import { copyFile, cp, mkdir, readFile, writeFile } from 'node:fs/promises'
import path, { join, resolve } from 'node:path'
import { env } from 'node:process'
import VueI18n from '@intlify/unplugin-vue-i18n/vite'
import { templateCompilerOptions } from '@tresjs/core'
import Vue from '@vitejs/plugin-vue'
@@ -22,14 +22,6 @@ import { unzip } from './scripts/unzip'
import { appName } from './src/constants'
export default defineConfig({
build: {
rollupOptions: {
external: [
'virtual:pwa-register',
],
},
},
optimizeDeps: {
exclude: [
'public/assets/*',
@@ -50,6 +42,14 @@ export default defineConfig({
],
},
build: {
rollupOptions: {
external: [
'virtual:pwa-register',
],
},
},
plugins: [
VueMacros({
plugins: {
@@ -115,9 +115,6 @@ export default defineConfig({
include: [path.resolve(__dirname, 'locales/**')],
}),
// https://github.com/feat-agency/vite-plugin-webfont-dl
// WebfontDownload(),
// https://github.com/webfansplz/vite-plugin-vue-devtools
VueDevTools(),
+217
View File
@@ -303,6 +303,9 @@ importers:
valibot:
specifier: 1.0.0-beta.9
version: 1.0.0-beta.9(typescript@5.7.2)
vaul-vue:
specifier: ^0.2.0
version: 0.2.0(radix-vue@1.9.11(vue@3.5.13(typescript@5.7.2)))(vue@3.5.13(typescript@5.7.2))
vue:
specifier: ^3.5.13
version: 3.5.13(typescript@5.7.2)
@@ -373,6 +376,12 @@ importers:
markdown-it-link-attributes:
specifier: ^4.0.1
version: 4.0.1
unocss-preset-animations:
specifier: ^1.1.0
version: 1.1.0(@unocss/preset-wind@0.65.3)(unocss@0.65.3(postcss@8.4.49)(rollup@2.79.1)(vite@6.0.5(@types/node@22.10.2)(jiti@2.4.0)(terser@5.17.6)(tsx@4.19.2)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.2)))
unocss-preset-shadcn:
specifier: ^0.3.1
version: 0.3.1(unocss-preset-animations@1.1.0(@unocss/preset-wind@0.65.3)(unocss@0.65.3(postcss@8.4.49)(rollup@2.79.1)(vite@6.0.5(@types/node@22.10.2)(jiti@2.4.0)(terser@5.17.6)(tsx@4.19.2)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.2))))(unocss@0.65.3(postcss@8.4.49)(rollup@2.79.1)(vite@6.0.5(@types/node@22.10.2)(jiti@2.4.0)(terser@5.17.6)(tsx@4.19.2)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.2)))
unocss-preset-theme:
specifier: ^0.14.1
version: 0.14.1(@unocss/core@0.65.3)
@@ -1764,6 +1773,18 @@ packages:
resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==}
engines: {node: '>=14'}
'@floating-ui/core@1.6.8':
resolution: {integrity: sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==}
'@floating-ui/dom@1.6.12':
resolution: {integrity: sha512-NP83c0HjokcGVEMeoStg317VD9W7eDlGK7457dMBANbKA6GJZdc7rjujdgqzTaz93jkGgc5P/jeWbaCHnMNc+w==}
'@floating-ui/utils@0.2.8':
resolution: {integrity: sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==}
'@floating-ui/vue@1.1.5':
resolution: {integrity: sha512-ynL1p5Z+woPVSwgMGqeDrx6HrJfGIDzFyESFkyqJKilGW1+h/8yVY29Khn0LaU6wHBRwZ13ntG6reiHWK6jyzw==}
'@formkit/auto-animate@0.8.2':
resolution: {integrity: sha512-SwPWfeRa5veb1hOIBMdzI+73te5puUBHmqqaF1Bu7FjvxlYSz/kJcZKSa9Cg60zL0uRNeJL2SbRxV6Jp6Q1nFQ==}
@@ -1927,6 +1948,12 @@ packages:
cpu: [x64]
os: [win32]
'@internationalized/date@3.6.0':
resolution: {integrity: sha512-+z6ti+CcJnRlLHok/emGEsWQhe7kfSmEW+/6qCzvKY67YPh7YOBfvc7+/+NXq+zJlbArg30tYpqLjNgcAYv2YQ==}
'@internationalized/number@3.6.0':
resolution: {integrity: sha512-PtrRcJVy7nw++wn4W2OuePQQfTqDzfusSuY1QTtui4wa7r+rGVtR75pO8CyKvHvzyQYi3Q1uO5sY0AsB4e65Bw==}
'@intlify/bundle-utils@10.0.0':
resolution: {integrity: sha512-BR5yLOkF2dzrARTbAg7RGAIPcx9Aark7p1K/0O285F7rfzso9j2dsa+S4dA67clZ0rToZ10NSSTfbyUptVu7Bg==}
engines: {node: '>= 18'}
@@ -2527,6 +2554,17 @@ packages:
'@surma/rollup-plugin-off-main-thread@2.2.3':
resolution: {integrity: sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==}
'@swc/helpers@0.5.15':
resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==}
'@tanstack/virtual-core@3.11.2':
resolution: {integrity: sha512-vTtpNt7mKCiZ1pwU9hfKPhpdVO2sVzFQsxoVBGtOSHxlrRRzYr8iQ2TlwbAcRYCcEiZ9ECAM8kBzH0v2+VzfKw==}
'@tanstack/vue-virtual@3.11.2':
resolution: {integrity: sha512-y0b1p1FTlzxcSt/ZdGWY1AZ52ddwSU69pvFRYAELUSdLLxV8QOPe9dyT/KATO43UCb3DAwiyzi96h2IoYstBOQ==}
peerDependencies:
vue: ^2.7.0 || ^3.0.0
'@tresjs/cientos@4.0.3':
resolution: {integrity: sha512-6urkgwGtXzxj7JBZh0HjX5sJwaoNVHXXclFNwFyWVIOBHBikAxFF52GhxTaAlOYfMnun2YKBW/StjnWutq7zAQ==}
peerDependencies:
@@ -3318,6 +3356,10 @@ packages:
argparse@2.0.1:
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
aria-hidden@1.2.4:
resolution: {integrity: sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==}
engines: {node: '>=10'}
array-buffer-byte-length@1.0.0:
resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==}
@@ -6078,6 +6120,11 @@ packages:
queue-microtask@1.2.3:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
radix-vue@1.9.11:
resolution: {integrity: sha512-C+MtJ66jf8J28DO5bKgNwhGCi6WQYuEosD/tY/Orry9BTDcuF/Mps4HlFd2Tq4YlXF44BEPLQ2Paz89Mz70ZgA==}
peerDependencies:
vue: '>= 3.2.0'
randombytes@2.1.0:
resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==}
@@ -6909,6 +6956,18 @@ packages:
resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==}
engines: {node: '>= 10.0.0'}
unocss-preset-animations@1.1.0:
resolution: {integrity: sha512-wCcVnu1IvQmzKK9dZpeZbPPuXO5sKmYGe5VaASjH8st6G3wgw4tw7HsVRP0bXHRhO0PXGtC5Kw9IRKh6dPGPtA==}
peerDependencies:
'@unocss/preset-wind': '>= 0.56.0 < 1'
unocss: '>= 0.56.0 < 1'
unocss-preset-shadcn@0.3.1:
resolution: {integrity: sha512-b17P8vUKYuxEYthgCVlrMLvy4FVSWxAwAf6d0kYsWYFymbb8VBacBfXrpu+anLTv7IiIgHgkRVNTnruVKIjC8Q==}
peerDependencies:
unocss: '>= 0.56.0 < 1'
unocss-preset-animations: ^1.0.1
unocss-preset-theme@0.14.1:
resolution: {integrity: sha512-j2sFIUeKy0FC3DejIZ/+tyiKEszoMiAAsuOyZBubw7XErHL5ZvpwBmLM5Qj/czbfKbv1TdeJW5RO4PRKACiRGw==}
peerDependencies:
@@ -7072,6 +7131,12 @@ packages:
resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==}
engines: {node: '>= 0.8'}
vaul-vue@0.2.0:
resolution: {integrity: sha512-YV0zqxc8NiVzr1z/Awwbaty0UDDchxj5BfhFbLiYu+Uz0rCfSaDK2zwmuXZvejBJKLGbWw9I5GLHJRse14lQew==}
peerDependencies:
radix-vue: ^1.4.0
vue: ^3.3.0
vfile-message@4.0.2:
resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==}
@@ -8724,6 +8789,26 @@ snapshots:
'@fastify/busboy@2.1.1': {}
'@floating-ui/core@1.6.8':
dependencies:
'@floating-ui/utils': 0.2.8
'@floating-ui/dom@1.6.12':
dependencies:
'@floating-ui/core': 1.6.8
'@floating-ui/utils': 0.2.8
'@floating-ui/utils@0.2.8': {}
'@floating-ui/vue@1.1.5(vue@3.5.13(typescript@5.7.2))':
dependencies:
'@floating-ui/dom': 1.6.12
'@floating-ui/utils': 0.2.8
vue-demi: 0.14.10(vue@3.5.13(typescript@5.7.2))
transitivePeerDependencies:
- '@vue/composition-api'
- vue
'@formkit/auto-animate@0.8.2': {}
'@gcornut/valibot-json-schema@0.42.0(esbuild@0.24.0)(typescript@5.7.2)':
@@ -8872,6 +8957,14 @@ snapshots:
'@img/sharp-win32-x64@0.33.5':
optional: true
'@internationalized/date@3.6.0':
dependencies:
'@swc/helpers': 0.5.15
'@internationalized/number@3.6.0':
dependencies:
'@swc/helpers': 0.5.15
'@intlify/bundle-utils@10.0.0(vue-i18n@10.0.5(vue@3.5.13(typescript@5.7.2)))':
dependencies:
'@intlify/message-compiler': 11.0.0-rc.1
@@ -9551,6 +9644,17 @@ snapshots:
magic-string: 0.25.9
string.prototype.matchall: 4.0.8
'@swc/helpers@0.5.15':
dependencies:
tslib: 2.8.1
'@tanstack/virtual-core@3.11.2': {}
'@tanstack/vue-virtual@3.11.2(vue@3.5.13(typescript@5.7.2))':
dependencies:
'@tanstack/virtual-core': 3.11.2
vue: 3.5.13(typescript@5.7.2)
'@tresjs/cientos@4.0.3(@tresjs/core@4.3.1(three@0.171.0)(vue@3.5.13(typescript@5.7.2)))(@types/three@0.171.0)(react@18.3.1)(three@0.171.0)(vue@3.5.13(typescript@5.7.2))':
dependencies:
'@tresjs/core': 4.3.1(three@0.171.0)(vue@3.5.13(typescript@5.7.2))
@@ -9879,6 +9983,18 @@ snapshots:
unhead: 1.11.14
vue: 3.5.13(typescript@5.7.2)
'@unocss/astro@0.65.3(rollup@2.79.1)(vite@6.0.5(@types/node@22.10.2)(jiti@2.4.0)(terser@5.17.6)(tsx@4.19.2)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.2))':
dependencies:
'@unocss/core': 0.65.3
'@unocss/reset': 0.65.3
'@unocss/vite': 0.65.3(rollup@2.79.1)(vite@6.0.5(@types/node@22.10.2)(jiti@2.4.0)(terser@5.17.6)(tsx@4.19.2)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.2))
optionalDependencies:
vite: 6.0.5(@types/node@22.10.2)(jiti@2.4.0)(terser@5.17.6)(tsx@4.19.2)(yaml@2.6.1)
transitivePeerDependencies:
- rollup
- supports-color
- vue
'@unocss/astro@0.65.3(rollup@4.29.1)(vite@6.0.5(@types/node@22.10.2)(jiti@2.4.0)(terser@5.17.6)(tsx@4.19.2)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.2))':
dependencies:
'@unocss/core': 0.65.3
@@ -9891,6 +10007,25 @@ snapshots:
- supports-color
- vue
'@unocss/cli@0.65.3(rollup@2.79.1)':
dependencies:
'@ampproject/remapping': 2.3.0
'@rollup/pluginutils': 5.1.4(rollup@2.79.1)
'@unocss/config': 0.65.3
'@unocss/core': 0.65.3
'@unocss/preset-uno': 0.65.3
cac: 6.7.14
chokidar: 3.6.0
colorette: 2.0.20
consola: 3.3.1
magic-string: 0.30.17
pathe: 1.1.2
perfect-debounce: 1.0.0
tinyglobby: 0.2.10
transitivePeerDependencies:
- rollup
- supports-color
'@unocss/cli@0.65.3(rollup@4.29.1)':
dependencies:
'@ampproject/remapping': 2.3.0
@@ -10041,6 +10176,22 @@ snapshots:
dependencies:
'@unocss/core': 0.65.3
'@unocss/vite@0.65.3(rollup@2.79.1)(vite@6.0.5(@types/node@22.10.2)(jiti@2.4.0)(terser@5.17.6)(tsx@4.19.2)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.2))':
dependencies:
'@ampproject/remapping': 2.3.0
'@rollup/pluginutils': 5.1.4(rollup@2.79.1)
'@unocss/config': 0.65.3
'@unocss/core': 0.65.3
'@unocss/inspector': 0.65.3(vue@3.5.13(typescript@5.7.2))
chokidar: 3.6.0
magic-string: 0.30.17
tinyglobby: 0.2.10
vite: 6.0.5(@types/node@22.10.2)(jiti@2.4.0)(terser@5.17.6)(tsx@4.19.2)(yaml@2.6.1)
transitivePeerDependencies:
- rollup
- supports-color
- vue
'@unocss/vite@0.65.3(rollup@4.29.1)(vite@6.0.5(@types/node@22.10.2)(jiti@2.4.0)(terser@5.17.6)(tsx@4.19.2)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.2))':
dependencies:
'@ampproject/remapping': 2.3.0
@@ -10739,6 +10890,10 @@ snapshots:
argparse@2.0.1: {}
aria-hidden@1.2.4:
dependencies:
tslib: 2.8.1
array-buffer-byte-length@1.0.0:
dependencies:
call-bind: 1.0.7
@@ -13954,6 +14109,23 @@ snapshots:
queue-microtask@1.2.3: {}
radix-vue@1.9.11(vue@3.5.13(typescript@5.7.2)):
dependencies:
'@floating-ui/dom': 1.6.12
'@floating-ui/vue': 1.1.5(vue@3.5.13(typescript@5.7.2))
'@internationalized/date': 3.6.0
'@internationalized/number': 3.6.0
'@tanstack/vue-virtual': 3.11.2(vue@3.5.13(typescript@5.7.2))
'@vueuse/core': 10.11.1(vue@3.5.13(typescript@5.7.2))
'@vueuse/shared': 10.11.1(vue@3.5.13(typescript@5.7.2))
aria-hidden: 1.2.4
defu: 6.1.4
fast-deep-equal: 3.1.3
nanoid: 5.0.9
vue: 3.5.13(typescript@5.7.2)
transitivePeerDependencies:
- '@vue/composition-api'
randombytes@2.1.0:
dependencies:
safe-buffer: 5.2.1
@@ -15027,11 +15199,48 @@ snapshots:
universalify@2.0.0: {}
unocss-preset-animations@1.1.0(@unocss/preset-wind@0.65.3)(unocss@0.65.3(postcss@8.4.49)(rollup@2.79.1)(vite@6.0.5(@types/node@22.10.2)(jiti@2.4.0)(terser@5.17.6)(tsx@4.19.2)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.2))):
dependencies:
'@unocss/preset-wind': 0.65.3
unocss: 0.65.3(postcss@8.4.49)(rollup@2.79.1)(vite@6.0.5(@types/node@22.10.2)(jiti@2.4.0)(terser@5.17.6)(tsx@4.19.2)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.2))
unocss-preset-shadcn@0.3.1(unocss-preset-animations@1.1.0(@unocss/preset-wind@0.65.3)(unocss@0.65.3(postcss@8.4.49)(rollup@2.79.1)(vite@6.0.5(@types/node@22.10.2)(jiti@2.4.0)(terser@5.17.6)(tsx@4.19.2)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.2))))(unocss@0.65.3(postcss@8.4.49)(rollup@2.79.1)(vite@6.0.5(@types/node@22.10.2)(jiti@2.4.0)(terser@5.17.6)(tsx@4.19.2)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.2))):
dependencies:
unocss: 0.65.3(postcss@8.4.49)(rollup@2.79.1)(vite@6.0.5(@types/node@22.10.2)(jiti@2.4.0)(terser@5.17.6)(tsx@4.19.2)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.2))
unocss-preset-animations: 1.1.0(@unocss/preset-wind@0.65.3)(unocss@0.65.3(postcss@8.4.49)(rollup@2.79.1)(vite@6.0.5(@types/node@22.10.2)(jiti@2.4.0)(terser@5.17.6)(tsx@4.19.2)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.2)))
unocss-preset-theme@0.14.1(@unocss/core@0.65.3):
dependencies:
'@unocss/core': 0.65.3
'@unocss/rule-utils': 0.63.6
unocss@0.65.3(postcss@8.4.49)(rollup@2.79.1)(vite@6.0.5(@types/node@22.10.2)(jiti@2.4.0)(terser@5.17.6)(tsx@4.19.2)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.2)):
dependencies:
'@unocss/astro': 0.65.3(rollup@2.79.1)(vite@6.0.5(@types/node@22.10.2)(jiti@2.4.0)(terser@5.17.6)(tsx@4.19.2)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.2))
'@unocss/cli': 0.65.3(rollup@2.79.1)
'@unocss/core': 0.65.3
'@unocss/postcss': 0.65.3(postcss@8.4.49)
'@unocss/preset-attributify': 0.65.3
'@unocss/preset-icons': 0.65.3
'@unocss/preset-mini': 0.65.3
'@unocss/preset-tagify': 0.65.3
'@unocss/preset-typography': 0.65.3
'@unocss/preset-uno': 0.65.3
'@unocss/preset-web-fonts': 0.65.3
'@unocss/preset-wind': 0.65.3
'@unocss/transformer-attributify-jsx': 0.65.3
'@unocss/transformer-compile-class': 0.65.3
'@unocss/transformer-directives': 0.65.3
'@unocss/transformer-variant-group': 0.65.3
'@unocss/vite': 0.65.3(rollup@2.79.1)(vite@6.0.5(@types/node@22.10.2)(jiti@2.4.0)(terser@5.17.6)(tsx@4.19.2)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.2))
optionalDependencies:
vite: 6.0.5(@types/node@22.10.2)(jiti@2.4.0)(terser@5.17.6)(tsx@4.19.2)(yaml@2.6.1)
transitivePeerDependencies:
- postcss
- rollup
- supports-color
- vue
unocss@0.65.3(postcss@8.4.49)(rollup@4.29.1)(vite@6.0.5(@types/node@22.10.2)(jiti@2.4.0)(terser@5.17.6)(tsx@4.19.2)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.2)):
dependencies:
'@unocss/astro': 0.65.3(rollup@4.29.1)(vite@6.0.5(@types/node@22.10.2)(jiti@2.4.0)(terser@5.17.6)(tsx@4.19.2)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.2))
@@ -15268,6 +15477,14 @@ snapshots:
vary@1.1.2: {}
vaul-vue@0.2.0(radix-vue@1.9.11(vue@3.5.13(typescript@5.7.2)))(vue@3.5.13(typescript@5.7.2)):
dependencies:
'@vueuse/core': 10.11.1(vue@3.5.13(typescript@5.7.2))
radix-vue: 1.9.11(vue@3.5.13(typescript@5.7.2))
vue: 3.5.13(typescript@5.7.2)
transitivePeerDependencies:
- '@vue/composition-api'
vfile-message@4.0.2:
dependencies:
'@types/unist': 3.0.0