6 Commits

Author SHA1 Message Date
21952738fa 🐛 Fix locale duplicate prefix in layout 2025-11-30 15:30:38 +08:00
17bbae1ab2 💄 Optimize experience of multilang 2025-11-30 15:28:56 +08:00
16ece63ae2 Globalization 2025-11-30 15:24:31 +08:00
83b16b1cf4 🐛 Bug fixes in product catalog 2025-11-30 14:30:47 +08:00
5cf9d5e541 Redesigned solar network page 2025-11-30 14:19:23 +08:00
da9e789ca9 ♻️ Content based about page 2025-11-30 13:42:18 +08:00
16 changed files with 16250 additions and 337 deletions

View File

@@ -1,5 +1,5 @@
<template>
<naive-config>
<naive-config :data-theme="colorMode.colorMode.value">
<n-global-style />
<n-loading-bar-provider>
<n-dialog-provider>
@@ -22,6 +22,8 @@ import {
} from "naive-ui";
import "@fontsource-variable/nunito";
const colorMode = useNaiveColorMode();
</script>
<style>

4
app/components.d.ts vendored
View File

@@ -15,9 +15,7 @@ declare module 'vue' {
NAvatar: typeof import('naive-ui')['NAvatar']
NButton: typeof import('naive-ui')['NButton']
NCard: typeof import('naive-ui')['NCard']
NDropdown: typeof import('naive-ui')['NDropdown']
NIcon: typeof import('naive-ui')['NIcon']
NMenu: typeof import('naive-ui')['NMenu']
NPopover: typeof import('naive-ui')['NPopover']
NTag: typeof import('naive-ui')['NTag']
RouterLink: typeof import('vue-router')['RouterLink']
@@ -30,9 +28,7 @@ declare global {
const NAvatar: typeof import('naive-ui')['NAvatar']
const NButton: typeof import('naive-ui')['NButton']
const NCard: typeof import('naive-ui')['NCard']
const NDropdown: typeof import('naive-ui')['NDropdown']
const NIcon: typeof import('naive-ui')['NIcon']
const NMenu: typeof import('naive-ui')['NMenu']
const NPopover: typeof import('naive-ui')['NPopover']
const NTag: typeof import('naive-ui')['NTag']
const RouterLink: typeof import('vue-router')['RouterLink']

View File

@@ -4,9 +4,9 @@
class="navbar bg-transparent shadow-lg fixed top-0 left-0 right-0 backdrop-blur-2xl z-1000 h-[64px]"
>
<div class="container mx-auto flex items-center justify-between px-5">
<nuxt-link to="/">
<nuxt-link-locale to="/">
<nuxt-img src="/favicon.png" alt="Solsynth" class="w-8 h-8" />
</nuxt-link>
</nuxt-link-locale>
<n-menu
v-if="breakpoints.isGreaterOrEqual('md')"
@@ -32,7 +32,16 @@
/>
</n-popover>
<naive-color-mode-switch />
<div class="flex gap-4">
<naive-color-mode-switch />
<n-dropdown
trigger="hover"
:options="localeDropdownOptions"
@select="handleLocaleSelect"
>
<n-button text>{{ locale.toUpperCase().split("-")[0] }}</n-button>
</n-dropdown>
</div>
</div>
</header>
@@ -46,39 +55,45 @@
<aside>
<nuxt-img src="/favicon.png" alt="Solsynth" class="w-12 h-12" />
<div>
<h3 class="text-lg font-bold">Solsynth</h3>
Making software, hardware and experiences since 2024
<h3 class="text-lg font-bold">{{ t("common.solsynth") }}</h3>
{{ t("layout.default.footer.tagline") }}
</div>
</aside>
<nav>
<h6 class="footer-title">Products</h6>
<a href="https://solian.app" target="_blank" class="link link-hover"
>Solar Network</a
>
<nuxt-link to="/products" class="link link-hover">Catalog</nuxt-link>
<h6 class="footer-title">{{ t("layout.default.footer.products") }}</h6>
<a href="https://solian.app" target="_blank" class="link link-hover">{{
t("layout.default.footer.solarNetwork")
}}</a>
<nuxt-link-locale to="/products" class="link link-hover">{{
t("layout.default.footer.catalog")
}}</nuxt-link-locale>
</nav>
<nav>
<h6 class="footer-title">Company</h6>
<nuxt-link to="/about" class="link link-hover">About us</nuxt-link>
<h6 class="footer-title">{{ t("layout.default.footer.company") }}</h6>
<nuxt-link-locale to="/about" class="link link-hover">{{
t("layout.default.footer.about")
}}</nuxt-link-locale>
<a
href="https://github.com/Solsynth"
target="_blank"
class="link link-hover"
>GitHub</a
>{{ t("layout.default.footer.github") }}</a
>
</nav>
<nav>
<h6 class="footer-title">Legal</h6>
<nuxt-link to="/terms/user-agreement" class="link link-hover"
>Terms of Service</nuxt-link
>
<nuxt-link to="/terms/privacy-policy" class="link link-hover"
>Privacy Policy</nuxt-link
>
<nuxt-link to="/terms/refund-policy" class="link link-hover"
>Refund Policy</nuxt-link
>
<nuxt-link to="/terms" class="link link-hover">All Documents</nuxt-link>
<h6 class="footer-title">{{ t("layout.default.footer.legal") }}</h6>
<nuxt-link-locale to="/terms/user-agreement" class="link link-hover">{{
t("layout.default.footer.tos")
}}</nuxt-link-locale>
<nuxt-link-locale to="/terms/privacy-policy" class="link link-hover">{{
t("layout.default.footer.privacy")
}}</nuxt-link-locale>
<nuxt-link-locale to="/terms/refund-policy" class="link link-hover">{{
t("layout.default.footer.refund")
}}</nuxt-link-locale>
<nuxt-link-locale to="/terms" class="link link-hover">{{
t("layout.default.footer.allDocs")
}}</nuxt-link-locale>
</nav>
</footer>
</div>
@@ -86,9 +101,10 @@
<script lang="ts" setup>
import type { MenuOption } from "naive-ui";
import { NIcon, NAvatar, NMenu } from "naive-ui";
import { NIcon, NAvatar, NMenu, NDropdown, NButton } from "naive-ui";
import { computed, h } from "vue";
import { useRoute, RouterLink } from "vue-router";
import { useRoute, useRouter, RouterLink } from "vue-router";
import { useI18n } from "vue-i18n";
import {
ExploreOutlined,
CategoryOutlined,
@@ -96,11 +112,26 @@ import {
} from "@vicons/material";
import { breakpointsTailwind } from "@vueuse/core";
const router = useRouter();
const switchLocalePath = useSwitchLocalePath();
const { t, locale, locales } = useI18n();
const localeDropdownOptions = computed(() => {
return locales.value?.map((l: any) => ({
label: l.name,
key: l.code,
}));
});
const handleLocaleSelect = (key: string) => {
router.push(switchLocalePath(key as any));
};
const route = useRoute();
const breakpoints = useBreakpoints(breakpointsTailwind);
const { data: recentProducts } = await useAsyncData("recent-products", () =>
queryCollection("products").order("updatedDate", "DESC").limit(5).all()
queryCollection("products").order("updatedDate", "DESC").limit(5).all(),
);
const activeKey = computed(() => {
@@ -115,7 +146,9 @@ function renderIcon(icon: any) {
}
function renderLabel(label: string, route: string) {
return () => h(RouterLink, { to: route }, { default: () => label });
const localePrefix = locale.value == "en" ? "" : `/${locale.value}`;
return () =>
h(RouterLink, { to: localePrefix + route }, { default: () => label });
}
function renderExternalLabel(label: string, url: string) {
@@ -148,12 +181,12 @@ const menuOptions = computed<MenuOption[]>(() => {
return [
{
label: renderLabel("Explore", "/"),
label: renderLabel(t("layout.default.menu.explore"), "/"),
key: "explore",
icon: renderIcon(ExploreOutlined),
},
{
label: renderLabel("Products", "/products"),
label: renderLabel(t("layout.default.menu.products"), "/products"),
key: "products",
icon: renderIcon(CategoryOutlined),
children: productChildren,

View File

@@ -1,10 +1,12 @@
<template>
<main class="container mx-auto h-full px-8 flex flex-col gap-16 py-16">
<main
class="container max-w-2xl text-center mx-auto h-full px-8 flex flex-col gap-16 py-16"
>
<!-- Hero Section -->
<div
class="text-center flex flex-col items-center justify-center animate-fade-in-up"
>
<h1 class="text-5xl font-extrabold mb-6">About Us</h1>
<h1 class="text-4xl font-extrabold mb-3">About Us</h1>
<p class="text-xl max-w-2xl opacity-80">
We are a collective of creators, dreamers, and builders.
</p>
@@ -12,27 +14,33 @@
<!-- Mission Section -->
<section
class="grid grid-cols-1 md:grid-cols-2 gap-12 items-center animate-fade-in-up delay-100"
class="flex flex-col gap-12 items-center animate-fade-in-up delay-100"
>
<div>
<h2 class="text-3xl font-bold mb-4">Our Mission</h2>
<p class="text-lg opacity-90 leading-relaxed">
Our aim is not making a profit.
<i class="text-sm opacity-70">At least not yet.</i> <br /><br />
Instead, we hope we can spread the love to the world and make everyone
enjoy the fun of the Internet and technology. We believe in open
source, collaboration, and building things that bring joy.
</p>
<h2 class="text-2xl font-bold">Our Mission</h2>
<div class="text-lg opacity-90 leading-relaxed flex flex-col gap-2">
<p>
Our aim is not making a profit.
<i class="text-sm opacity-70">At least not yet.</i>
</p>
<p>
Instead, we hope we can spread the love to the world and make
everyone enjoy the fun of the Internet and technology. We believe in
open source, collaboration, and building things that bring joy.
</p>
</div>
</div>
<div class="flex justify-center">
<n-card class="max-w-sm w-full bg-opacity-50 backdrop-blur-sm">
<div class="flex flex-col items-center text-center p-4">
<n-icon size="48" class="mb-4 text-primary">
<heart-outlined />
</n-icon>
<n-icon
size="48"
class="mb-4 text-primary"
:component="FavoriteRound"
/>
<h3 class="text-xl font-bold mb-2">Built with Love</h3>
<p class="opacity-80">
Every line of code is written with passion and care.
Every line of code is written with passion and care in mind.
</p>
</div>
</n-card>
@@ -45,22 +53,21 @@
<div class="flex flex-wrap justify-center gap-8">
<!-- Team Member Card -->
<n-card
v-for="member in team"
:key="member.name"
class="max-w-xs w-full hover:shadow-lg transition-shadow duration-300"
>
<div class="flex flex-col items-center text-center">
<n-avatar
src="https://fs.solian.app/api/files/200ee92546244ed1a6a02202f5ca9cc9"
:size="120"
class="mb-4 shadow-md"
/>
<h3 class="text-xl font-bold">LittleSheep</h3>
<n-avatar :src="member.avatar" :size="120" class="mb-4 shadow-md" />
<h3 class="text-xl font-bold">{{ member.name }}</h3>
<div class="flex items-center gap-2 mt-1 mb-3">
<n-tag size="small" type="primary" round>Founder</n-tag>
<n-tag size="small" type="primary" round>{{ member.role }}</n-tag>
<n-button
v-if="member.profileUrl"
text
tag="a"
size="small"
href="https://id.solian.app/@littlesheep"
:href="member.profileUrl"
target="_blank"
>
<n-icon size="18">
@@ -69,23 +76,21 @@
</n-button>
</div>
<p class="text-sm opacity-75 mb-4">
Founder, CEO, CTO, Senior Developer, Marketing Engineer, Customer
Service Engineer, DevOps, Database Administrator, Product Manager,
UI/UX Designer, QA Engineer, Mobile Developer, Security Engineer,
Technical Writer, Project Manager, Community Manager, Software
Architect
{{ member.bio }}
</p>
<div class="flex gap-3">
<div class="flex gap-3" v-if="member.socials">
<n-button
v-for="social in member.socials"
:key="social.url"
circle
size="small"
tag="a"
href="https://github.com/LittleSheep"
:href="social.url"
target="_blank"
>
<template #icon
><n-icon><logo-github /></n-icon
></template>
<template #icon>
<n-icon :component="getIcon(social.icon)" />
</template>
</n-button>
</div>
</div>
@@ -96,11 +101,24 @@
</template>
<script setup lang="ts">
import { InfoOutlined } from "@vicons/material";
import { InfoOutlined, FavoriteRound, CodeRound } from "@vicons/material";
useHead({
title: "About Us - Solsynth",
title: "About Us",
});
const { data: team } = await useAsyncData("team", () =>
queryCollection("team").all()
);
function getIcon(name: string) {
switch (name) {
case "github":
return CodeRound;
default:
return InfoOutlined;
}
}
</script>
<style scoped>

View File

@@ -2,7 +2,7 @@
<main class="container mx-auto h-full px-8 flex flex-col gap-24 pb-24">
<!-- Hero Section -->
<div
class="text-center min-h-[80vh] flex flex-col items-center justify-center relative"
class="text-center min-h-[80vh] flex flex-col items-center justify-center relative isolate"
>
<!-- Background decoration -->
<div
@@ -11,11 +11,11 @@
<nuxt-img src="/favicon.png" class="w-32 h-32 mb-8 animate-float" />
<h1 class="text-6xl font-extrabold mb-6 tracking-tight">
We <span ref="typedElement" class="text-primary" />
{{ t("page.index.hero.we") }}
<span ref="typedElement" class="text-primary" />
</h1>
<p class="text-2xl mb-10 opacity-80 max-w-2xl">
We are a group of friends that make software, hardware and any stuff
that is interesting.
{{ t("page.index.hero.subtitle") }}
</p>
<n-space justify="center" size="large">
<n-button
@@ -26,10 +26,10 @@
href="#products"
class="px-8 text-lg font-bold shadow-lg shadow-primary/30 hover:shadow-primary/50 transition-shadow"
>
Explore Products
{{ t("page.index.hero.explore") }}
</n-button>
<n-button size="large" round tag="a" href="/about" class="px-8 text-lg">
About Us
{{ t("page.index.hero.about") }}
</n-button>
</n-space>
@@ -45,10 +45,11 @@
<!-- Products Section -->
<div id="products" class="scroll-mt-24">
<div class="text-center mb-16">
<h2 class="text-4xl font-bold mb-4">Our Creations</h2>
<h2 class="text-4xl font-bold mb-4">
{{ t("page.index.creations.title") }}
</h2>
<p class="text-xl opacity-70 max-w-2xl mx-auto">
From social networks to cloud drives, we build tools that empower and
connect.
{{ t("page.index.creations.subtitle") }}
</p>
</div>
@@ -79,9 +80,8 @@
tag="a"
:href="product.repo"
target="_blank"
class="text-black"
>
<n-icon><code-round /></n-icon>
<n-icon :component="CodeRound" color="black"></n-icon>
</n-button>
<n-button
v-if="product.url"
@@ -91,10 +91,17 @@
tag="a"
:href="product.url"
target="_blank"
class="text-black"
>
<n-icon><launch-round /></n-icon>
<n-icon :component="LaunchRound" color="black"></n-icon>
</n-button>
<nuxt-link-locale
v-if="product.hasPage"
:to="`/products/${product.stem.split('/').pop()}`"
>
<n-button circle color="white" size="small">
<n-icon :component="InfoRound" color="black"></n-icon>
</n-button>
</nuxt-link-locale>
</div>
<div class="absolute bottom-0 left-0 right-0 p-6">
@@ -128,14 +135,14 @@
class="flex flex-col md:flex-row items-center gap-12 relative z-10 p-8"
>
<div class="flex-1">
<h2 class="text-3xl font-bold mb-4">More Than Just Code</h2>
<h2 class="text-3xl font-bold mb-4">
{{ t("page.index.about.title") }}
</h2>
<p class="text-lg opacity-80 mb-6 leading-relaxed">
We are a community-driven team focused on creating meaningful
experiences. Our mission goes beyond softwareit's about
connection, innovation, and fun.
{{ t("page.index.about.subtitle") }}
</p>
<n-button type="primary" ghost size="large" tag="a" href="/about">
Read Our Story
{{ t("page.index.about.readStory") }}
<template #icon>
<n-icon :component="ChevronRightOutlined"></n-icon>
</template>
@@ -171,15 +178,20 @@ import {
CodeRound,
ChevronRightOutlined,
ArrowDownwardOutlined,
InfoRound,
} from "@vicons/material";
import Typed from "typed.js";
import { useI18n } from "vue-i18n";
const { t } = useI18n();
const route = useRoute();
const typedElement = ref(null);
const typed = shallowRef(null);
useHead({
title: "Solsynth - Creating Experiences",
title: t("page.index.title"),
titleTemplate: "%s",
});
onMounted(() => {
@@ -189,11 +201,11 @@ onMounted(() => {
}
typed.value = new Typed(typedElement.value, {
strings: [
"make software",
"make hardware",
"craft experiences",
"write stories",
"are Solsynth",
t("page.index.hero.typed.makeSoftware"),
t("page.index.hero.typed.makeHardware"),
t("page.index.hero.typed.craftExperiences"),
t("page.index.hero.typed.writeStories"),
t("page.index.hero.typed.areSolsynth"),
],
typeSpeed: 50,
backDelay: 1500,

View File

@@ -2,10 +2,14 @@
<div class="container max-w-xl mx-auto my-16 px-8">
<h1 class="text-4xl font-bold mb-8">Our Products</h1>
<nuxt-link
<nuxt-link-locale
v-for="product in products"
:key="product.url"
:to="product.url"
:to="
product.hasPage
? `/products/${product.stem.split('/').pop()}`
: product.url
"
class="no-underline block mb-4"
>
<n-card hoverable>
@@ -37,7 +41,7 @@
</div>
</template>
</n-card>
</nuxt-link>
</nuxt-link-locale>
</div>
</template>
@@ -45,7 +49,7 @@
import { NCard } from "naive-ui";
const { data: products } = await useAsyncData("products", () =>
queryCollection("products").all()
queryCollection("products").all(),
);
useHead({

View File

@@ -1,259 +1,444 @@
<template>
<main class="container mx-auto h-full px-8 flex flex-col gap-16">
<div class="text-center py-56 flex flex-col items-center justify-center">
<img src="/solar-network/icon.png" class="w-28 h-28 mb-4" />
<h1 class="text-5xl font-extrabold mb-3">Solar Network</h1>
<p class="text-xl mb-8">
The amazing social network for technology, programming, ACG fans.
</p>
<n-alert
type="warning"
title="Under Construction"
class="max-w-lg mx-auto mb-8"
closable
>
<n-marquee>
<div style="margin-right: 64px">
小羊懒得施工产品介绍所以懂得都懂不懂得我也不好多说如果你真的知道可以去看我们的宣传片如果你连宣传片都不知道在哪里的话我也不知道怎么办了
</div>
</n-marquee>
</n-alert>
<n-space justify="center">
<n-button type="primary" size="large" round tag="a" href="#features">
Explore features
</n-button>
<n-button type="default" size="large" round tag="a" href="#download">
Download
</n-button>
</n-space>
<main class="min-h-screen overflow-x-hidden transition-colors duration-300">
<!-- Hero Section -->
<div
class="relative min-h-screen flex flex-col items-center justify-center px-4 overflow-hidden"
>
<!-- Background Elements -->
<div class="absolute top-0 left-0 w-full h-full overflow-hidden -z-10">
<div
class="absolute top-1/4 left-1/4 w-[500px] h-[500px] bg-primary/20 rounded-full blur-[120px] animate-pulse-slow"
></div>
<div
class="absolute bottom-1/4 right-1/4 w-[400px] h-[400px] bg-secondary/20 rounded-full blur-[100px] animate-pulse-slow delay-1000"
></div>
</div>
<div class="text-center z-10 max-w-4xl mx-auto">
<div class="mb-8 relative inline-block">
<div
class="absolute inset-0 bg-primary/30 blur-xl rounded-full animate-pulse"
></div>
<img
src="/solar-network/icon.png"
class="w-32 h-32 relative z-10 animate-float"
alt="Solar Network Logo"
/>
</div>
<h1 class="text-6xl md:text-7xl font-extrabold mb-6 tracking-tight">
{{ t('page.product.solarNetwork.hero.title') }}
</h1>
<p class="text-xl md:text-2xl mb-10 max-w-2xl mx-auto leading-relaxed">
{{ t('page.product.solarNetwork.hero.subtitle', [t('page.product.solarNetwork.hero.subtitle.enthusiasts'), t('page.product.solarNetwork.hero.subtitle.developers'), t('page.product.solarNetwork.hero.subtitle.acg')]) }}
</p>
<n-space justify="center" size="large" class="mb-16">
<n-button
type="primary"
size="large"
round
tag="a"
href="#download"
class="px-8 py-6 text-lg font-bold shadow-lg shadow-primary/25 hover:shadow-primary/40 transition-all download-button"
>
{{ t('page.product.solarNetwork.hero.getStarted') }}
<template #icon>
<n-icon :component="ArrowDownwardRound" />
</template>
</n-button>
<n-button
size="large"
round
secondary
tag="a"
href="#features"
class="px-8 py-6 text-lg hover:bg-gray-100 dark:hover:bg-white/10 transition-all"
>
{{ t('page.product.solarNetwork.hero.learnMore') }}
</n-button>
</n-space>
</div>
<!-- Scroll Indicator -->
<div class="absolute bottom-10 animate-bounce">
<n-icon size="32" class="text-gray-400 dark:text-gray-500">
<ArrowDownwardRound />
</n-icon>
</div>
</div>
<div id="features" class="pb-56">
<client-only>
<n-grid cols="1 m:2 l:2" responsive="screen" x-gap="32" y-gap="16">
<!-- Features Section -->
<div id="features" class="py-32 px-4 relative">
<div class="container mx-auto max-w-6xl">
<div class="text-center mb-20">
<h2 class="text-4xl md:text-5xl font-bold mb-6">
{{ t('page.product.solarNetwork.features.title') }}
</h2>
<p class="text-xl max-w-2xl mx-auto">
{{ t('page.product.solarNetwork.features.subtitle') }}
</p>
</div>
<n-grid cols="1 m:2 l:2" responsive="screen" x-gap="32" y-gap="32">
<n-gi>
<div class="flex items-center justify-center">
<div class="feature-card group">
<div class="p-8 h-full flex flex-col">
<div
class="w-14 h-14 rounded-2xl bg-primary/10 dark:bg-primary/20 flex items-center justify-center mb-6 text-primary group-hover:scale-110 transition-transform"
>
<n-icon size="32" :component="CodeRound" />
</div>
<h3 class="text-2xl font-bold mb-4">
{{ t('page.product.solarNetwork.features.devFirst.title') }}
</h3>
<p class="opacity-80 leading-relaxed">
{{ t('page.product.solarNetwork.features.devFirst.content') }}
</p>
</div>
</div>
</n-gi>
<n-gi>
<div class="feature-card group">
<div class="p-8 h-full flex flex-col">
<div
class="w-14 h-14 rounded-2xl bg-secondary/10 dark:bg-secondary/20 flex items-center justify-center mb-6 text-secondary group-hover:scale-110 transition-transform"
>
<n-icon size="32" :component="ApiRound" />
</div>
<h3 class="text-2xl font-bold mb-4">
{{ t('page.product.solarNetwork.features.openapi.title') }}
</h3>
<p class="opacity-80 leading-relaxed">
{{ t('page.product.solarNetwork.features.openapi.content') }}
</p>
</div>
</div>
</n-gi>
<n-gi>
<div class="feature-card group">
<div class="p-8 h-full flex flex-col">
<div
class="w-14 h-14 rounded-2xl bg-info/10 dark:bg-info/20 flex items-center justify-center mb-6 text-info group-hover:scale-110 transition-transform"
>
<n-icon size="32" :component="AutoAwesomeRound" />
</div>
<h3 class="text-2xl font-bold mb-4">
{{ t('page.product.solarNetwork.features.acg.title') }}
</h3>
<p class="opacity-80 leading-relaxed">
{{ t('page.product.solarNetwork.features.acg.content') }}
</p>
</div>
</div>
</n-gi>
<n-gi>
<div class="feature-card group">
<div class="p-8 h-full flex flex-col">
<div
class="w-14 h-14 rounded-2xl bg-success/10 dark:bg-success/20 flex items-center justify-center mb-6 text-success group-hover:scale-110 transition-transform"
>
<n-icon size="32" :component="FavoriteRound" />
</div>
<h3 class="text-2xl font-bold mb-4">
{{ t('page.product.solarNetwork.features.community.title') }}
</h3>
<p class="opacity-80 leading-relaxed">
{{ t('page.product.solarNetwork.features.community.content') }}
</p>
</div>
</div>
</n-gi>
</n-grid>
<!-- Video Showcase -->
<div
class="mt-32 relative rounded-3xl overflow-hidden border shadow-2xl backdrop-blur-sm glassy-card"
>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-0">
<div class="p-12 flex flex-col justify-center">
<h3 class="text-3xl font-bold mb-6">
{{ t('page.product.solarNetwork.experience.title') }}
</h3>
<p class="text-lg mb-8">
{{ t('page.product.solarNetwork.experience.content') }}
</p>
<div class="flex gap-4">
<n-tag type="warning" round :bordered="false">
<template #icon
><n-icon :component="ConstructionRound"
/></template>
{{ t('page.product.solarNetwork.experience.wip') }}
</n-tag>
</div>
</div>
<div
class="relative aspect-video lg:aspect-auto lg:h-full min-h-[300px]"
>
<iframe
width="560"
height="315"
class="absolute inset-0 w-full h-full"
src="https://www.youtube-nocookie.com/embed/xhK5UBqGw5Q"
title="YouTube video player"
title="Solar Network Promo"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
referrerpolicy="strict-origin-when-cross-origin"
allow="
accelerometer;
autoplay;
clipboard-write;
encrypted-media;
gyroscope;
picture-in-picture;
web-share;
"
allowfullscreen
></iframe>
</div>
</n-gi>
<n-gi>
<div
class="flex justify-center text-right h-full py-8 px-4 flex-col"
>
<h2 class="text-3xl font-bold mb-3">Features</h2>
<p class="text-lg mb-1">
As the alert described, this part is under construction. For now
you can check out the video on the left.
</p>
<p class="text-md">
如果你看得懂这行字就说明你有可能访问不了
YouTube你可以去哔哩哔哩上搜一下 Solar Network
我懒得放链接了
</p>
</div>
</n-gi>
</n-grid>
</client-only>
</div>
</div>
</div>
</div>
<div id="download" class="pb-56">
<client-only>
<n-grid cols="1 m:2 l:2" responsive="screen" x-gap="32" y-gap="16">
<n-gi>
<div
class="flex justify-center text-left h-full py-8 px-4 flex-col"
>
<h2 class="text-3xl font-bold mb-3">Download</h2>
<p class="text-lg mb-1">
Get the latest version of Solar Network for your device.
</p>
<p class="text-lg">
File-hosting & versioning by
<a
class="underline"
href="https://github.com/Solsynth/Solian"
target="_blank"
>GitHub</a
>
</p>
<!-- Download Section -->
<div
id="download"
class="py-32 px-4 bg-linear-to-b from-transparent to-primary/5"
>
<div class="container mx-auto max-w-5xl">
<div class="text-center mb-20">
<h2 class="text-2xl md:text-3xl font-bold mb-2">
{{ t('page.product.solarNetwork.download.title') }}
</h2>
<p class="text-xl">
{{ t('page.product.solarNetwork.download.subtitle') }}
</p>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-8 mb-16">
<!-- Faster Release Card -->
<div
class="download-card relative overflow-hidden group border-primary/50"
>
<div class="absolute top-0 right-0 p-4">
<n-tag
type="success"
round
:bordered="false"
class="shadow-lg shadow-success/20"
>
<template #icon><n-icon :component="StarRound" /></template>
{{ t('page.product.solarNetwork.download.faster.recommended') }}
</n-tag>
</div>
</n-gi>
<n-gi>
<div class="flex items-center justify-center flex-col gap-4">
<n-card title="iOS / macOS">
<div class="grid gird-cols-1 md:grid-cols-2 gap-4">
<div class="flex flex-col">
<div class="mb-3">
<n-tag round :bordered="false" type="success">
Recommended
<template #icon>
<n-icon :component="StarRound" />
</template>
</n-tag>
</div>
<h3 class="text-lg font-bold">Download via TestFlight</h3>
<p>
Latest version, new features and bug fixes. 中国可用
</p>
<n-button
type="primary"
tag="a"
target="_blank"
round
class="mt-4"
href="https://testflight.apple.com/join/YJ0lmN6O"
>
Join TestFlight
<template #icon>
<n-icon>
<launch-round />
</n-icon>
</template>
</n-button>
</div>
<div class="flex flex-col">
<div class="mb-3">
<n-tag round :bordered="false" type="info">
Not that recommended
<template #icon>
<n-icon :component="StarOutlineRound" />
</template>
</n-tag>
</div>
<h3 class="text-lg font-bold">Download via App Store</h3>
<p>
Can leave reviews to increase the popularity of the Solar
Network.
</p>
<n-button
type="primary"
tag="a"
target="_blank"
round
class="mt-4"
href="https://apps.apple.com/us/app/solian/id6499032345"
>
Go to App Store
<template #icon>
<n-icon>
<launch-round />
</n-icon>
</template>
</n-button>
</div>
</div>
</n-card>
<n-card v-if="latestRelease.data.value" title="Latest Release">
<p>
<code>{{ latestRelease.data.value?.tag_name }}</code>
</p>
<p class="font-bold text-lg">
{{ latestRelease.data.value?.name }}
</p>
<div class="p-8 flex flex-col h-full relative z-10">
<div
class="w-16 h-16 rounded-2xl bg-linear-to-br from-blue-500 to-blue-600 flex items-center justify-center mb-6 shadow-lg shadow-blue-500/30"
>
<n-icon size="36" color="white" :component="IosShareRound" />
</div>
<h3 class="text-2xl font-bold mb-2">
{{ t('page.product.solarNetwork.download.faster.title') }}
</h3>
<p class="opacity-80 mb-8 grow">
{{ t('page.product.solarNetwork.download.faster.content') }}
<br />
<span class="text-xs opacity-70 mt-2 block">
<n-space size="small" align="center">
<n-icon :component="LogoApple" />
<n-icon :component="LogoAndroid" />
<n-icon :component="LogoWindows" />
<n-icon :component="LogoTux" />
</n-space>
</span>
</p>
<div class="flex flex-col gap-3">
<n-button
type="primary"
tag="a"
target="_blank"
size="large"
block
round
class="mt-4"
:href="latestRelease.data.value?.html_url"
tag="a"
href="https://testflight.apple.com/join/YJ0lmN6O"
target="_blank"
class="py-6 font-bold"
>
Go to GitHub and Download
<template #icon>
<n-icon>
<launch-round />
</n-icon>
</template>
{{ t('page.product.solarNetwork.download.faster.testflight') }}
<template #icon><n-icon :component="LaunchRound" /></template>
</n-button>
</n-card>
<a href="https://web.solian.app" target="_blank">
<n-tag round :bordered="false" size="small" class="cursor-pointer">
Open the web version (Strongly not recommended, only for
preview)
<template #icon>
<n-icon :component="WebRound" />
</template>
</n-tag>
</a>
<n-button
secondary
size="large"
block
round
tag="a"
href="https://fs.solsynth.dev/official/solian"
target="_blank"
class="py-6 font-bold"
>
{{ t('page.product.solarNetwork.download.faster.direct') }}
<template #icon
><n-icon :component="CloudDownloadRound"
/></template>
</n-button>
<n-button
tertiary
size="large"
block
round
tag="a"
href="https://web.solian.app"
target="_blank"
class="py-2 font-bold text-primary hover:underline"
>
{{ t('page.product.solarNetwork.download.faster.browser') }}
<template #icon><n-icon :component="WebRound" /></template>
</n-button>
</div>
</div>
</n-gi>
</n-grid>
</client-only>
</div>
<div id="download" class="pb-56">
<client-only>
<n-grid cols="1 m:2 l:2" responsive="screen" x-gap="32" y-gap="16">
<n-gi>
<!-- Glow effect -->
<div
class="flex justify-center text-left h-full py-8 px-4 flex-col"
>
<h2 class="text-3xl font-bold mb-3">Feedback & Support</h2>
<p class="text-lg mb-1">
Due to the Solar Network always under active development, if you
have any idea or issues. Feel free to told us!
class="absolute -bottom-20 -right-20 w-64 h-64 bg-primary/20 rounded-full blur-[80px] group-hover:bg-primary/30 transition-colors duration-500"
></div>
</div>
<!-- App Store Card -->
<div class="download-card relative overflow-hidden group">
<div class="p-8 flex flex-col h-full relative z-10">
<div
class="w-16 h-16 rounded-2xl bg-linear-to-br from-gray-700 to-gray-800 flex items-center justify-center mb-6 shadow-lg"
>
<n-icon size="36" color="white" :component="LogoApple" />
</div>
<h3 class="text-2xl font-bold mb-2">
{{ t('page.product.solarNetwork.download.appstore.title') }}
</h3>
<p class="opacity-80 mb-8 grow">
{{ t('page.product.solarNetwork.download.appstore.content') }}
</p>
</div>
</n-gi>
<n-gi>
<div class="flex items-center justify-center flex-col gap-4">
<n-card
title="GitHub Issues"
hoverable
href="https://github.com/Solsynth/Solian/issues"
target="_blank"
<n-button
secondary
size="large"
block
round
tag="a"
>
If you have any new idea or function that don't work as
expected. Go to GitHub and create an issue to feedback!
</n-card>
<n-card
title="Customer Service"
hoverable
href="mailto:lily@solsynth.dev"
href="https://apps.apple.com/us/app/solian/id6499032345"
target="_blank"
tag="a"
class="py-6 font-bold"
>
If you have any account and payments related problems, please
contact our customer service via email at
<address class="font-italic">lily [at] solsynth.dev</address>
</n-card>
{{ t('page.product.solarNetwork.download.appstore.visit') }}
<template #icon><n-icon :component="LaunchRound" /></template>
</n-button>
</div>
</n-gi>
</n-grid>
</client-only>
</div>
</div>
<!-- Latest Release Info -->
<div v-if="latestRelease.data.value" class="max-w-2xl mx-auto">
<div
class="download-card rounded-2xl p-6 border backdrop-blur-md flex items-center justify-between gap-4"
>
<div class="flex items-center gap-4">
<div
class="w-10 h-10 rounded-full bg-gray-100 dark:bg-white/10 flex items-center justify-center text-gray-900 dark:text-white"
>
<n-icon :size="24" :component="LogoGithub" />
</div>
<div>
<div
class="text-xs opacity-80 uppercase tracking-wider font-bold mb-1"
>
{{ t('page.product.solarNetwork.download.latest.title') }}
</div>
<div class="font-mono text-primary font-bold">
{{ latestRelease.data.value?.tag_name }}
</div>
</div>
</div>
<n-button
text
tag="a"
:href="latestRelease.data.value?.html_url"
target="_blank"
>
{{ t('page.product.solarNetwork.download.latest.view') }}
<template #icon
><n-icon :component="ArrowForwardRound"
/></template>
</n-button>
</div>
</div>
</div>
</div>
<!-- Footer / Support -->
<div class="py-24 bg-primary/5">
<div class="container mx-auto px-4 text-center">
<h2 class="text-2xl font-bold mb-2">
{{ t('page.product.solarNetwork.support.title') }}
</h2>
<p class="mb-12 text-lg">
{{ t('page.product.solarNetwork.support.content') }}
</p>
<div class="flex flex-wrap justify-center gap-8">
<a
href="https://github.com/Solsynth/Solian/issues"
target="_blank"
class="flex items-center gap-3 px-6 py-4 rounded-xl bg-white dark:bg-white/5 hover:bg-gray-100 dark:hover:bg-white/10 transition-colors border border-gray-200 dark:border-white/5 text-gray-900 dark:text-white shadow-sm"
>
<n-icon :component="LogoGithub" size="24" />
<span class="font-semibold">{{ t('page.product.solarNetwork.support.report') }}</span>
</a>
<a
href="mailto:lily@solsynth.dev"
class="flex items-center gap-3 px-6 py-4 rounded-xl bg-white dark:bg-white/5 hover:bg-gray-100 dark:hover:bg-white/10 transition-colors border border-gray-200 dark:border-white/5 text-gray-900 dark:text-white shadow-sm"
>
<n-icon :component="MailOutlineRound" size="24" />
<span class="font-semibold">{{ t('page.product.solarNetwork.support.contact') }}</span>
</a>
</div>
</div>
</div>
</main>
</template>
<script lang="ts" setup>
import {
NSpace,
NButton,
NGrid,
NGi,
NCard,
NAlert,
NIcon,
NMarquee,
NTag,
} from "naive-ui";
import { NSpace, NButton, NGrid, NGi, NIcon, NTag } from "naive-ui";
import { Octokit } from "@octokit/rest";
import {
LaunchRound,
StarOutlineRound,
StarRound,
ArrowDownwardRound,
CodeRound,
AutoAwesomeRound,
ConstructionRound,
IosShareRound,
ArrowForwardRound,
MailOutlineRound,
CloudDownloadRound,
WebRound,
ApiRound,
FavoriteRound,
} from "@vicons/material";
import {
LogoGithub,
LogoApple,
LogoAndroid,
LogoWindows,
LogoTux,
} from "@vicons/ionicons5";
import { useI18n } from "vue-i18n";
const { t } = useI18n();
useHead({
title: "Solar Network",
title: t('page.product.solarNetwork.title'),
meta: [
{
name: "description",
content: t('page.product.solarNetwork.description'),
},
],
});
const latestRelease = useAsyncData("sn-latest-release", async () => {
@@ -265,3 +450,98 @@ const latestRelease = useAsyncData("sn-latest-release", async () => {
return resp.data;
});
</script>
<style scoped>
.animate-float {
animation: float 6s ease-in-out infinite;
}
.animate-pulse-slow {
animation: pulse 8s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
@keyframes float {
0% {
transform: translateY(0px);
}
50% {
transform: translateY(-20px);
}
100% {
transform: translateY(0px);
}
}
.feature-card {
background: rgba(255, 255, 255, 0.8);
border: 1px solid rgba(0, 0, 0, 0.05);
border-radius: 1.5rem;
transition: all 0.3s ease;
height: 100%;
}
.dark .feature-card {
background: rgba(255, 255, 255, 0.03);
border: 1px solid rgba(255, 255, 255, 0.05);
}
.feature-card:hover {
background: rgba(255, 255, 255, 1);
border-color: rgba(0, 0, 0, 0.1);
transform: translateY(-5px);
box-shadow: 0 10px 30px -10px rgba(0, 0, 0, 0.1);
}
.dark .feature-card:hover {
background: rgba(255, 255, 255, 0.06);
border-color: rgba(255, 255, 255, 0.1);
box-shadow: none;
}
.glassy-card {
background: rgba(255, 255, 255, 0.8);
border: 1px solid rgba(0, 0, 0, 0.05);
border-radius: 2rem;
transition: all 0.3s ease;
}
.dark .glassy-card {
background: rgba(255, 255, 255, 0.03);
border: 1px solid rgba(255, 255, 255, 0.05);
}
.download-card {
background: rgba(255, 255, 255, 0.8);
border: 1px solid rgba(0, 0, 0, 0.05);
border-radius: 2rem;
transition: all 0.3s ease;
}
.dark .download-card {
background: rgba(255, 255, 255, 0.03);
border: 1px solid rgba(255, 255, 255, 0.05);
}
.download-card:hover {
background: rgba(255, 255, 255, 1);
border-color: rgba(0, 0, 0, 0.1);
transform: translateY(-5px);
box-shadow: 0 20px 40px -15px rgba(0, 0, 0, 0.1);
}
.dark .download-card:hover {
background: rgba(255, 255, 255, 0.06);
border-color: rgba(255, 255, 255, 0.1);
box-shadow: 0 20px 40px -15px rgba(0, 0, 0, 0.5);
}
.download-button {
transition:
transform 0.3s ease,
top 0.1s ease;
}
.download-button:hover {
transform: translateY(-0.25rem); /* Equivalent to hover:-translate-y-1 */
}
</style>

View File

@@ -26,6 +26,8 @@
},
"devDependencies": {
"@tailwindcss/typography": "^0.5.19",
"@tailwindcss/vite": "^4.1.17",
"@vicons/ionicons5": "^0.13.0",
"@vicons/material": "^0.13.0",
"daisyui": "^5.5.5",
"naive-ui": "^2.43.2",
@@ -179,7 +181,7 @@
"@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.4", "", { "os": "openbsd", "cpu": "x64" }, "sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw=="],
"@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.27.0", "", { "os": "none", "cpu": "arm64" }, "sha512-nyvsBccxNAsNYz2jVFYwEGuRRomqZ149A39SHWk4hV0jWxKM0hjBPm3AmdxcbHiFLbBSwG6SbpIcUbXjgyECfA=="],
"@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg=="],
"@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.4", "", { "os": "sunos", "cpu": "x64" }, "sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q=="],
@@ -585,8 +587,38 @@
"@stylistic/eslint-plugin": ["@stylistic/eslint-plugin@5.6.1", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.9.0", "@typescript-eslint/types": "^8.47.0", "eslint-visitor-keys": "^4.2.1", "espree": "^10.4.0", "estraverse": "^5.3.0", "picomatch": "^4.0.3" }, "peerDependencies": { "eslint": ">=9.0.0" } }, "sha512-JCs+MqoXfXrRPGbGmho/zGS/jMcn3ieKl/A8YImqib76C8kjgZwq5uUFzc30lJkMvcchuRn6/v8IApLxli3Jyw=="],
"@tailwindcss/node": ["@tailwindcss/node@4.1.17", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "enhanced-resolve": "^5.18.3", "jiti": "^2.6.1", "lightningcss": "1.30.2", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", "tailwindcss": "4.1.17" } }, "sha512-csIkHIgLb3JisEFQ0vxr2Y57GUNYh447C8xzwj89U/8fdW8LhProdxvnVH6U8M2Y73QKiTIH+LWbK3V2BBZsAg=="],
"@tailwindcss/oxide": ["@tailwindcss/oxide@4.1.17", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.1.17", "@tailwindcss/oxide-darwin-arm64": "4.1.17", "@tailwindcss/oxide-darwin-x64": "4.1.17", "@tailwindcss/oxide-freebsd-x64": "4.1.17", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.17", "@tailwindcss/oxide-linux-arm64-gnu": "4.1.17", "@tailwindcss/oxide-linux-arm64-musl": "4.1.17", "@tailwindcss/oxide-linux-x64-gnu": "4.1.17", "@tailwindcss/oxide-linux-x64-musl": "4.1.17", "@tailwindcss/oxide-wasm32-wasi": "4.1.17", "@tailwindcss/oxide-win32-arm64-msvc": "4.1.17", "@tailwindcss/oxide-win32-x64-msvc": "4.1.17" } }, "sha512-F0F7d01fmkQhsTjXezGBLdrl1KresJTcI3DB8EkScCldyKp3Msz4hub4uyYaVnk88BAS1g5DQjjF6F5qczheLA=="],
"@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.1.17", "", { "os": "android", "cpu": "arm64" }, "sha512-BMqpkJHgOZ5z78qqiGE6ZIRExyaHyuxjgrJ6eBO5+hfrfGkuya0lYfw8fRHG77gdTjWkNWEEm+qeG2cDMxArLQ=="],
"@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.1.17", "", { "os": "darwin", "cpu": "arm64" }, "sha512-EquyumkQweUBNk1zGEU/wfZo2qkp/nQKRZM8bUYO0J+Lums5+wl2CcG1f9BgAjn/u9pJzdYddHWBiFXJTcxmOg=="],
"@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.1.17", "", { "os": "darwin", "cpu": "x64" }, "sha512-gdhEPLzke2Pog8s12oADwYu0IAw04Y2tlmgVzIN0+046ytcgx8uZmCzEg4VcQh+AHKiS7xaL8kGo/QTiNEGRog=="],
"@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.1.17", "", { "os": "freebsd", "cpu": "x64" }, "sha512-hxGS81KskMxML9DXsaXT1H0DyA+ZBIbyG/sSAjWNe2EDl7TkPOBI42GBV3u38itzGUOmFfCzk1iAjDXds8Oh0g=="],
"@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.1.17", "", { "os": "linux", "cpu": "arm" }, "sha512-k7jWk5E3ldAdw0cNglhjSgv501u7yrMf8oeZ0cElhxU6Y2o7f8yqelOp3fhf7evjIS6ujTI3U8pKUXV2I4iXHQ=="],
"@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.1.17", "", { "os": "linux", "cpu": "arm64" }, "sha512-HVDOm/mxK6+TbARwdW17WrgDYEGzmoYayrCgmLEw7FxTPLcp/glBisuyWkFz/jb7ZfiAXAXUACfyItn+nTgsdQ=="],
"@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.1.17", "", { "os": "linux", "cpu": "arm64" }, "sha512-HvZLfGr42i5anKtIeQzxdkw/wPqIbpeZqe7vd3V9vI3RQxe3xU1fLjss0TjyhxWcBaipk7NYwSrwTwK1hJARMg=="],
"@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.1.17", "", { "os": "linux", "cpu": "x64" }, "sha512-M3XZuORCGB7VPOEDH+nzpJ21XPvK5PyjlkSFkFziNHGLc5d6g3di2McAAblmaSUNl8IOmzYwLx9NsE7bplNkwQ=="],
"@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.1.17", "", { "os": "linux", "cpu": "x64" }, "sha512-k7f+pf9eXLEey4pBlw+8dgfJHY4PZ5qOUFDyNf7SI6lHjQ9Zt7+NcscjpwdCEbYi6FI5c2KDTDWyf2iHcCSyyQ=="],
"@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.1.17", "", { "dependencies": { "@emnapi/core": "^1.6.0", "@emnapi/runtime": "^1.6.0", "@emnapi/wasi-threads": "^1.1.0", "@napi-rs/wasm-runtime": "^1.0.7", "@tybys/wasm-util": "^0.10.1", "tslib": "^2.4.0" }, "cpu": "none" }, "sha512-cEytGqSSoy7zK4JRWiTCx43FsKP/zGr0CsuMawhH67ONlH+T79VteQeJQRO/X7L0juEUA8ZyuYikcRBf0vsxhg=="],
"@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.1.17", "", { "os": "win32", "cpu": "arm64" }, "sha512-JU5AHr7gKbZlOGvMdb4722/0aYbU+tN6lv1kONx0JK2cGsh7g148zVWLM0IKR3NeKLv+L90chBVYcJ8uJWbC9A=="],
"@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.1.17", "", { "os": "win32", "cpu": "x64" }, "sha512-SKWM4waLuqx0IH+FMDUw6R66Hu4OuTALFgnleKbqhgGU30DY20NORZMZUKgLRjQXNN2TLzKvh48QXTig4h4bGw=="],
"@tailwindcss/typography": ["@tailwindcss/typography@0.5.19", "", { "dependencies": { "postcss-selector-parser": "6.0.10" }, "peerDependencies": { "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1" } }, "sha512-w31dd8HOx3k9vPtcQh5QHP9GwKcgbMp87j58qi6xgiBnFFtKEAgCWnDw4qUT8aHwkCp8bKvb/KGKWWHedP0AAg=="],
"@tailwindcss/vite": ["@tailwindcss/vite@4.1.17", "", { "dependencies": { "@tailwindcss/node": "4.1.17", "@tailwindcss/oxide": "4.1.17", "tailwindcss": "4.1.17" }, "peerDependencies": { "vite": "^5.2.0 || ^6 || ^7" } }, "sha512-4+9w8ZHOiGnpcGI6z1TVVfWaX/koK7fKeSYF3qlYg2xpBtbteP2ddBxiarL+HVgfSJGeK5RIxRQmKm4rTJJAwA=="],
"@trysound/sax": ["@trysound/sax@0.2.0", "", {}, "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA=="],
"@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="],
@@ -681,6 +713,8 @@
"@vercel/nft": ["@vercel/nft@0.30.4", "", { "dependencies": { "@mapbox/node-pre-gyp": "^2.0.0", "@rollup/pluginutils": "^5.1.3", "acorn": "^8.6.0", "acorn-import-attributes": "^1.9.5", "async-sema": "^3.1.1", "bindings": "^1.4.0", "estree-walker": "2.0.2", "glob": "^10.5.0", "graceful-fs": "^4.2.9", "node-gyp-build": "^4.2.2", "picomatch": "^4.0.2", "resolve-from": "^5.0.0" }, "bin": { "nft": "out/cli.js" } }, "sha512-wE6eAGSXScra60N2l6jWvNtVK0m+sh873CpfZW4KI2v8EHuUQp+mSEi4T+IcdPCSEDgCdAS/7bizbhQlkjzrSA=="],
"@vicons/ionicons5": ["@vicons/ionicons5@0.13.0", "", {}, "sha512-zvZKBPjEXKN7AXNo2Na2uy+nvuv6SP4KAMQxpKL2vfHMj0fSvuw7JZcOPCjQC3e7ayssKnaoFVAhbYcW6v41qQ=="],
"@vicons/material": ["@vicons/material@0.13.0", "", {}, "sha512-lKVxFNprM+CaBkUH3gt6VjIeiMsKQl2zARQMwTCZruQl2vRHzyeZiKeCflWS99CEfv2JzX/6y697smxlzyxcVw=="],
"@vitejs/plugin-vue": ["@vitejs/plugin-vue@6.0.2", "", { "dependencies": { "@rolldown/pluginutils": "1.0.0-beta.50" }, "peerDependencies": { "vite": "^5.0.0 || ^6.0.0 || ^7.0.0", "vue": "^3.2.25" } }, "sha512-iHmwV3QcVGGvSC1BG5bZ4z6iwa1SOpAPWmnjOErd4Ske+lZua5K9TtAVdx0gMBClJ28DViCbSmZitjWZsWO3LA=="],
@@ -893,7 +927,7 @@
"comma-separated-tokens": ["comma-separated-tokens@2.0.3", "", {}, "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg=="],
"commander": ["commander@7.2.0", "", {}, "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="],
"commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="],
"comment-parser": ["comment-parser@1.4.1", "", {}, "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg=="],
@@ -1037,6 +1071,8 @@
"engine.io-parser": ["engine.io-parser@5.2.3", "", {}, "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q=="],
"enhanced-resolve": ["enhanced-resolve@5.18.3", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww=="],
"entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
"error-stack-parser-es": ["error-stack-parser-es@1.0.5", "", {}, "sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA=="],
@@ -1381,6 +1417,30 @@
"levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="],
"lightningcss": ["lightningcss@1.30.2", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.30.2", "lightningcss-darwin-arm64": "1.30.2", "lightningcss-darwin-x64": "1.30.2", "lightningcss-freebsd-x64": "1.30.2", "lightningcss-linux-arm-gnueabihf": "1.30.2", "lightningcss-linux-arm64-gnu": "1.30.2", "lightningcss-linux-arm64-musl": "1.30.2", "lightningcss-linux-x64-gnu": "1.30.2", "lightningcss-linux-x64-musl": "1.30.2", "lightningcss-win32-arm64-msvc": "1.30.2", "lightningcss-win32-x64-msvc": "1.30.2" } }, "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ=="],
"lightningcss-android-arm64": ["lightningcss-android-arm64@1.30.2", "", { "os": "android", "cpu": "arm64" }, "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A=="],
"lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.30.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA=="],
"lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.30.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ=="],
"lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.30.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA=="],
"lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.30.2", "", { "os": "linux", "cpu": "arm" }, "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA=="],
"lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.30.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A=="],
"lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.30.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA=="],
"lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.30.2", "", { "os": "linux", "cpu": "x64" }, "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w=="],
"lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.30.2", "", { "os": "linux", "cpu": "x64" }, "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA=="],
"lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.30.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ=="],
"lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.30.2", "", { "os": "win32", "cpu": "x64" }, "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw=="],
"lilconfig": ["lilconfig@3.1.3", "", {}, "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw=="],
"listhen": ["listhen@1.9.0", "", { "dependencies": { "@parcel/watcher": "^2.4.1", "@parcel/watcher-wasm": "^2.4.1", "citty": "^0.1.6", "clipboardy": "^4.0.0", "consola": "^3.2.3", "crossws": ">=0.2.0 <0.4.0", "defu": "^6.1.4", "get-port-please": "^3.1.2", "h3": "^1.12.0", "http-shutdown": "^1.2.2", "jiti": "^2.1.2", "mlly": "^1.7.1", "node-forge": "^1.3.1", "pathe": "^1.1.2", "std-env": "^3.7.0", "ufo": "^1.5.4", "untun": "^0.1.3", "uqr": "^0.1.2" }, "bin": { "listen": "bin/listhen.mjs", "listhen": "bin/listhen.mjs" } }, "sha512-I8oW2+QL5KJo8zXNWX046M134WchxsXC7SawLPvRQpogCbkyQIaFxPE89A2HiwR7vAK2Dm2ERBAmyjTYGYEpBg=="],
@@ -1545,7 +1605,7 @@
"naive-ui": ["naive-ui@2.43.2", "", { "dependencies": { "@css-render/plugin-bem": "^0.15.14", "@css-render/vue3-ssr": "^0.15.14", "@types/katex": "^0.16.2", "@types/lodash": "^4.17.20", "@types/lodash-es": "^4.17.12", "async-validator": "^4.2.5", "css-render": "^0.15.14", "csstype": "^3.1.3", "date-fns": "^4.1.0", "date-fns-tz": "^3.2.0", "evtd": "^0.2.4", "highlight.js": "^11.8.0", "lodash": "^4.17.21", "lodash-es": "^4.17.21", "seemly": "^0.3.10", "treemate": "^0.3.11", "vdirs": "^0.1.8", "vooks": "^0.2.12", "vueuc": "^0.4.65" }, "peerDependencies": { "vue": "^3.0.0" } }, "sha512-YlLMnGrwGTOc+zMj90sG3ubaH5/7czsgLgGcjTLA981IUaz8r6t4WIujNt8r9PNr+dqv6XNEr0vxkARgPPjfBQ=="],
"nanoid": ["nanoid@5.1.6", "", { "bin": { "nanoid": "bin/nanoid.js" } }, "sha512-c7+7RQ+dMB5dPwwCp4ee1/iV/q2P6aK1mTZcfr1BTuVlyW9hJYiMPybJCcnBlQtuSmTIWNeazm/zqNoZSSElBg=="],
"nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
"nanotar": ["nanotar@0.2.0", "", {}, "sha512-9ca1h0Xjvo9bEkE4UOxgAzLV0jHKe6LMaxo37ND2DAhhAtd0j8pR1Wxz+/goMrZO8AEZTWCmyaOsFI/W5AdpCQ=="],
@@ -1969,6 +2029,8 @@
"tailwindcss": ["tailwindcss@4.1.17", "", {}, "sha512-j9Ee2YjuQqYT9bbRTfTZht9W/ytp5H+jJpZKiYdP/bpnXARAuELt9ofP0lPnmHjbga7SNQIxdTAXCmtKVYjN+Q=="],
"tapable": ["tapable@2.3.0", "", {}, "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg=="],
"tar": ["tar@7.5.2", "", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.1.0", "yallist": "^5.0.0" } }, "sha512-7NyxrTE4Anh8km8iEy7o0QYPs+0JKBTj5ZaqHg6B39erLg0qYXN3BijtShwbsNSvQ+LN75+KV+C4QR/f6Gwnpg=="],
"tar-fs": ["tar-fs@2.1.4", "", { "dependencies": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", "tar-stream": "^2.1.4" } }, "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ=="],
@@ -2255,6 +2317,18 @@
"@rollup/pluginutils/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="],
"@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.7.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" }, "bundled": true }, "sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg=="],
"@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.7.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA=="],
"@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.1.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ=="],
"@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.0.7", "", { "dependencies": { "@emnapi/core": "^1.5.0", "@emnapi/runtime": "^1.5.0", "@tybys/wasm-util": "^0.10.1" }, "bundled": true }, "sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw=="],
"@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="],
"@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
"@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="],
"@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
@@ -2271,6 +2345,8 @@
"@vue/compiler-sfc/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="],
"@vue/devtools-core/nanoid": ["nanoid@5.1.6", "", { "bin": { "nanoid": "bin/nanoid.js" } }, "sha512-c7+7RQ+dMB5dPwwCp4ee1/iV/q2P6aK1mTZcfr1BTuVlyW9hJYiMPybJCcnBlQtuSmTIWNeazm/zqNoZSSElBg=="],
"@vueuse/nuxt/@vueuse/core": ["@vueuse/core@13.6.0", "", { "dependencies": { "@types/web-bluetooth": "^0.0.21", "@vueuse/metadata": "13.6.0", "@vueuse/shared": "13.6.0" }, "peerDependencies": { "vue": "^3.5.0" } }, "sha512-DJbD5fV86muVmBgS9QQPddVX7d9hWYswzlf4bIyUD2dj8GC46R1uNClZhVAmsdVts4xb2jwp1PbpuiA50Qee1A=="],
"@vueuse/nuxt/@vueuse/metadata": ["@vueuse/metadata@13.6.0", "", {}, "sha512-rnIH7JvU7NjrpexTsl2Iwv0V0yAx9cw7+clymjKuLSXG0QMcLD0LDgdNmXic+qL0SGvgSVPEpM9IDO/wqo1vkQ=="],
@@ -2367,8 +2443,6 @@
"parse5/entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="],
"postcss/nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
"postcss-calc/postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="],
"postcss-discard-comments/postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="],
@@ -2403,9 +2477,9 @@
"stylehacks/postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="],
"tar-fs/chownr": ["chownr@1.1.4", "", {}, "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="],
"svgo/commander": ["commander@7.2.0", "", {}, "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="],
"terser/commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="],
"tar-fs/chownr": ["chownr@1.1.4", "", {}, "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="],
"unimport/escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="],
@@ -2415,8 +2489,6 @@
"vite-plugin-checker/npm-run-path": ["npm-run-path@6.0.0", "", { "dependencies": { "path-key": "^4.0.0", "unicorn-magic": "^0.3.0" } }, "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA=="],
"xss/commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="],
"zip-stream/readable-stream": ["readable-stream@4.7.0", "", { "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", "events": "^3.3.0", "process": "^0.11.10", "string_decoder": "^1.3.0" } }, "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg=="],
"@babel/helper-compilation-targets/lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="],
@@ -2463,6 +2535,8 @@
"@eslint/config-inspector/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.27.0", "", { "os": "openbsd", "cpu": "x64" }, "sha512-aCwlRdSNMNxkGGqQajMUza6uXzR/U0dIl1QmLjPtRbLOx3Gy3otfFu/VjATy4yQzo9yFDGTxYDo1FfAD9oRD2A=="],
"@eslint/config-inspector/esbuild/@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.27.0", "", { "os": "none", "cpu": "arm64" }, "sha512-nyvsBccxNAsNYz2jVFYwEGuRRomqZ149A39SHWk4hV0jWxKM0hjBPm3AmdxcbHiFLbBSwG6SbpIcUbXjgyECfA=="],
"@eslint/config-inspector/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.27.0", "", { "os": "sunos", "cpu": "x64" }, "sha512-Q1KY1iJafM+UX6CFEL+F4HRTgygmEW568YMqDA5UV97AuZSm21b7SXIrRJDwXWPzr8MGr75fUZPV67FdtMHlHA=="],
"@eslint/config-inspector/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.27.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-W1eyGNi6d+8kOmZIwi/EDjrL9nxQIQ0MiGqe/AWc6+IaHloxHSGoeRgDRKHFISThLmsewZ5nHFvGFWdBYlgKPg=="],
@@ -2529,8 +2603,6 @@
"@nuxt/vite-builder/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.12", "", { "os": "openbsd", "cpu": "x64" }, "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw=="],
"@nuxt/vite-builder/esbuild/@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg=="],
"@nuxt/vite-builder/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.12", "", { "os": "sunos", "cpu": "x64" }, "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w=="],
"@nuxt/vite-builder/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg=="],
@@ -2611,8 +2683,6 @@
"nitropack/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.12", "", { "os": "openbsd", "cpu": "x64" }, "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw=="],
"nitropack/esbuild/@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg=="],
"nitropack/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.12", "", { "os": "sunos", "cpu": "x64" }, "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w=="],
"nitropack/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg=="],
@@ -2683,8 +2753,6 @@
"vite/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.12", "", { "os": "openbsd", "cpu": "x64" }, "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw=="],
"vite/esbuild/@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg=="],
"vite/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.12", "", { "os": "sunos", "cpu": "x64" }, "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w=="],
"vite/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg=="],

View File

@@ -28,5 +28,24 @@ export default defineContentConfig({
updatedDate: z.date().optional(),
}),
}),
team: defineCollection({
type: "data",
source: "team/**.json",
schema: z.object({
name: z.string(),
role: z.string(),
avatar: z.string(),
bio: z.string(),
profileUrl: z.string().optional(),
socials: z
.array(
z.object({
icon: z.string(),
url: z.string(),
})
)
.optional(),
}),
}),
},
});

View File

@@ -3,7 +3,7 @@
"background": "/solar-network/kp.jpg",
"name": "Solar Network",
"description": "The amazing social network for technology, programming, ACG fans.",
"url": "https://solsynth.dev/products/solar-network",
"url": "https://web.solian.app",
"repo": "https://github.com/Solsynth/Solian",
"releasedDate": "2024-01-27T08:00:00.000Z",
"version": "3.1.0",

View File

@@ -0,0 +1,13 @@
{
"name": "LittleSheep",
"role": "Founder",
"avatar": "https://api.solian.app/drive/files/thgJtsTgwBDM7zm9bPjNp",
"bio": "Founder, CEO, CTO, Senior Developer, Marketing Engineer, Customer Service Engineer, DevOps, Database Administrator, Product Manager, UI/UX Designer, QA Engineer, Mobile Developer, Security Engineer, Technical Writer, Project Manager, Community Manager, Software Architect",
"profileUrl": "https://id.solian.app/@littlesheep",
"socials": [
{
"icon": "github",
"url": "https://github.com/LittleSheep2Code"
}
]
}

71
i18n/en.json Normal file
View File

@@ -0,0 +1,71 @@
{
"common.solsynth": "Solsynth",
"layout.default.footer.tagline": "Making software, hardware and experiences since 2024",
"layout.default.footer.products": "Products",
"layout.default.footer.solarNetwork": "Solar Network",
"layout.default.footer.catalog": "Catalog",
"layout.default.footer.company": "Company",
"layout.default.footer.about": "About us",
"layout.default.footer.github": "GitHub",
"layout.default.footer.legal": "Legal",
"layout.default.footer.tos": "Terms of Service",
"layout.default.footer.privacy": "Privacy Policy",
"layout.default.footer.refund": "Refund Policy",
"layout.default.footer.allDocs": "All Documents",
"layout.default.menu.explore": "Explore",
"layout.default.menu.products": "Products",
"page.index.title": "We are Solsynth",
"page.index.hero.we": "We",
"page.index.hero.typed.makeSoftware": "make software",
"page.index.hero.typed.makeHardware": "make hardware",
"page.index.hero.typed.craftExperiences": "craft experiences",
"page.index.hero.typed.writeStories": "write stories",
"page.index.hero.typed.areSolsynth": "are Solsynth",
"page.index.hero.subtitle": "We are a group of friends that make software, hardware and any stuff that is interesting.",
"page.index.hero.explore": "Explore Products",
"page.index.hero.about": "About Us",
"page.index.creations.title": "Our Creations",
"page.index.creations.subtitle": "From social networks to cloud drives, we build tools that empower and connect.",
"page.index.about.title": "More Than Just Code",
"page.index.about.subtitle": "We are a community-driven team focused on creating meaningful experiences. Our mission goes beyond software—it's about connection, innovation, and fun.",
"page.index.about.readStory": "Read Our Story",
"page.product.solarNetwork.title": "Solar Network - Stay Connected",
"page.product.solarNetwork.description": "The amazing social network for technology, programming, and ACG fans.",
"page.product.solarNetwork.hero.title": "Solar Network",
"page.product.solarNetwork.hero.subtitle": "The next-generation social network designed for {0}, {1}, and {2}.",
"page.product.solarNetwork.hero.subtitle.enthusiasts": "technology enthusiasts",
"page.product.solarNetwork.hero.subtitle.developers": "developers",
"page.product.solarNetwork.hero.subtitle.acg": "ACG culture",
"page.product.solarNetwork.hero.getStarted": "Get Started",
"page.product.solarNetwork.hero.learnMore": "Learn More",
"page.product.solarNetwork.features.title": "Why Solar Network?",
"page.product.solarNetwork.features.subtitle": "Built for those who create, code, and connect. Experience a platform that understands your passions.",
"page.product.solarNetwork.features.devFirst.title": "Developer First",
"page.product.solarNetwork.features.devFirst.content": "Native syntax highlighting, code snippet sharing, and seamless integration with your favorite dev tools.",
"page.product.solarNetwork.features.openapi.title": "OpenAPI",
"page.product.solarNetwork.features.openapi.content": "Fully documented API, transparent rate limiting and risk control. Great start for developing your own app with the Solar Network!",
"page.product.solarNetwork.features.acg.title": "ACG Culture",
"page.product.solarNetwork.features.acg.content": "A dedicated space for Anime, Comic, and Game enthusiasts. Share your art, reviews, and passion.",
"page.product.solarNetwork.features.community.title": "Friendly Community",
"page.product.solarNetwork.features.community.content": "Join a vibrant community of like-minded individuals. Share your knowledge, ask questions, and connect with others.",
"page.product.solarNetwork.experience.title": "Experience the Future",
"page.product.solarNetwork.experience.content": "Watch our promotional video to see Solar Network in action. Discover a fluid, responsive, and beautiful interface designed for modern interactions.",
"page.product.solarNetwork.experience.wip": "Under Construction",
"page.product.solarNetwork.download.title": "Start Your Journey",
"page.product.solarNetwork.download.subtitle": "Available on iOS, Android, macOS, Windows, and Linux.",
"page.product.solarNetwork.download.faster.title": "Faster Release",
"page.product.solarNetwork.download.faster.recommended": "Recommended",
"page.product.solarNetwork.download.faster.content": "Get early access to the latest features on all platforms.",
"page.product.solarNetwork.download.faster.testflight": "Join TestFlight (iOS, macOS)",
"page.product.solarNetwork.download.faster.direct": "Direct Download",
"page.product.solarNetwork.download.faster.browser": "Open in your Browser",
"page.product.solarNetwork.download.appstore.title": "App Store",
"page.product.solarNetwork.download.appstore.content": "Stable release for general users. Leave a review to support us!",
"page.product.solarNetwork.download.appstore.visit": "Visit Store Page",
"page.product.solarNetwork.download.latest.title": "Latest Release",
"page.product.solarNetwork.download.latest.view": "View on GitHub",
"page.product.solarNetwork.support.title": "Need Help?",
"page.product.solarNetwork.support.content": "Feel free to contact your customer service or report a bug on the GitHub.",
"page.product.solarNetwork.support.report": "Report an Issue",
"page.product.solarNetwork.support.contact": "Contact Support"
}

71
i18n/zh-cn.json Normal file
View File

@@ -0,0 +1,71 @@
{
"common.solsynth": "Solsynth",
"layout.default.footer.tagline": "自 2024 年以来,我们一直致力于软件、硬件和体验的创造。",
"layout.default.footer.products": "产品",
"layout.default.footer.solarNetwork": "Solar Network",
"layout.default.footer.catalog": "目录",
"layout.default.footer.company": "公司",
"layout.default.footer.about": "关于我们",
"layout.default.footer.github": "GitHub",
"layout.default.footer.legal": "法律",
"layout.default.footer.tos": "服务条款",
"layout.default.footer.privacy": "隐私政策",
"layout.default.footer.refund": "退款政策",
"layout.default.footer.allDocs": "所有文档",
"layout.default.menu.explore": "发现",
"layout.default.menu.products": "产品",
"page.index.title": "我们是 Solsynth",
"page.index.hero.we": "我们",
"page.index.hero.typed.makeSoftware": "创造软件",
"page.index.hero.typed.makeHardware": "构建硬件",
"page.index.hero.typed.craftExperiences": "打造体验",
"page.index.hero.typed.writeStories": "撰写故事",
"page.index.hero.typed.areSolsynth": "是 Solsynth",
"page.index.hero.subtitle": "我们是一群朋友,致力于创造有趣的软件、硬件和任何新奇玩意。",
"page.index.hero.explore": "探索产品",
"page.index.hero.about": "关于我们",
"page.index.creations.title": "我们的作品",
"page.index.creations.subtitle": "从社交网络到云存储,我们构建的工具旨在赋能与连接。",
"page.index.about.title": "不止于代码",
"page.index.about.subtitle": "我们是一个由社区驱动的团队,专注于创造有意义的体验。我们的使命超越软件——关乎连接、创新和乐趣。",
"page.index.about.readStory": "阅读我们的故事",
"page.product.solarNetwork.title": "Solar Network - 保持联系",
"page.product.solarNetwork.description": "为技术、编程和 ACG 爱好者打造的卓越社交网络。",
"page.product.solarNetwork.hero.title": "Solar Network",
"page.product.solarNetwork.hero.subtitle": "为 {0}、{1} 和 {2} 设计的下一代社交网络。",
"page.product.solarNetwork.hero.subtitle.enthusiasts": "技术爱好者",
"page.product.solarNetwork.hero.subtitle.developers": "开发者",
"page.product.solarNetwork.hero.subtitle.acg": "ACG 文化",
"page.product.solarNetwork.hero.getStarted": "开始使用",
"page.product.solarNetwork.hero.learnMore": "了解更多",
"page.product.solarNetwork.features.title": "为何选择 Solar Network",
"page.product.solarNetwork.features.subtitle": "为创造者、编码者和连接者而构建。体验一个懂你热情的平台。",
"page.product.solarNetwork.features.devFirst.title": "开发者优先",
"page.product.solarNetwork.features.devFirst.content": "原生语法高亮、代码片段分享,以及与你喜爱的开发工具无缝集成。",
"page.product.solarNetwork.features.openapi.title": "开放 API",
"page.product.solarNetwork.features.openapi.content": "提供完整文档的 API透明的速率限制和风险控制。是你利用 Solar Network 开发自己应用的绝佳起点!",
"page.product.solarNetwork.features.acg.title": "ACG 文化",
"page.product.solarNetwork.features.acg.content": "一个专为动漫、漫画和游戏爱好者打造的空间。分享你的艺术、评论和热情。",
"page.product.solarNetwork.features.community.title": "友好的社区",
"page.product.solarNetwork.features.community.content": "加入一个由志同道合的人组成的充满活力的社区。分享你的知识、提出问题并与他人建立联系。",
"page.product.solarNetwork.experience.title": "体验未来",
"page.product.solarNetwork.experience.content": "观看我们的宣传视频,了解 Solar Network 的实际运行情况。发现专为现代交互设计的流畅、响应迅速且美观的界面。",
"page.product.solarNetwork.experience.wip": "正在建设中",
"page.product.solarNetwork.download.title": "开启你的旅程",
"page.product.solarNetwork.download.subtitle": "支持 iOS、Android、macOS、Windows 和 Linux。",
"page.product.solarNetwork.download.faster.title": "抢先版",
"page.product.solarNetwork.download.faster.recommended": "推荐",
"page.product.solarNetwork.download.faster.content": "在所有平台上抢先体验最新功能。",
"page.product.solarNetwork.download.faster.testflight": "加入 TestFlight (iOS, macOS)",
"page.product.solarNetwork.download.faster.direct": "直接下载",
"page.product.solarNetwork.download.faster.browser": "在浏览器中打开",
"page.product.solarNetwork.download.appstore.title": "App Store",
"page.product.solarNetwork.download.appstore.content": "为普通用户提供的稳定版本。留下评论以支持我们!",
"page.product.solarNetwork.download.appstore.visit": "访问商店页面",
"page.product.solarNetwork.download.latest.title": "最新发布",
"page.product.solarNetwork.download.latest.view": "在 GitHub 上查看",
"page.product.solarNetwork.support.title": "需要帮助?",
"page.product.solarNetwork.support.content": "随时联系我们的客服或在 GitHub 上报告错误。",
"page.product.solarNetwork.support.report": "报告问题",
"page.product.solarNetwork.support.contact": "联系支持"
}

View File

@@ -8,7 +8,6 @@ import { generateTailwindColorThemes } from "@bg-dev/nuxt-naiveui/utils";
export default defineNuxtConfig({
compatibilityDate: "2025-07-15",
devtools: { enabled: true },
ssr: false,
css: ["~/assets/css/main.css"],
app: {
pageTransition: { name: "page", mode: "out-in" },
@@ -18,7 +17,6 @@ export default defineNuxtConfig({
link: [{ rel: "icon", type: "image/png", href: "/favicon.png" }],
},
},
nitro: {},
modules: [
"@nuxt/content",
"@nuxt/eslint",
@@ -26,7 +24,25 @@ export default defineNuxtConfig({
"@nuxt/scripts",
"@vueuse/nuxt",
"@bg-dev/nuxt-naiveui",
"@nuxtjs/i18n",
],
i18n: {
langDir: ".",
strategy: "prefix_except_default",
locales: [
{
code: "en",
name: "English",
file: "en.json",
},
{
code: "zh-cn",
name: "简体中文",
file: "zh-cn.json",
},
],
defaultLocale: "en",
},
vite: {
plugins: [
tailwindcss(),
@@ -47,6 +63,27 @@ export default defineNuxtConfig({
}),
],
},
nitro: {
preset: "cloudflare_module",
cloudflare: {
deployConfig: true,
wrangler: {
d1_databases: [
{
binding: "DB",
database_name: "capital-content",
database_id: "73d65123-3c42-4dc9-b540-8e89678962a2",
},
],
},
},
},
content: {
database: {
type: "d1",
bindingName: "DB",
},
},
naiveui: {
colorModePreference: "system",
colorModePreferenceCookieName: "fi-ColorMode",

15285
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -7,7 +7,8 @@
"dev": "nuxt dev",
"generate": "nuxt generate",
"preview": "nuxt preview",
"postinstall": "nuxt prepare"
"postinstall": "nuxt prepare",
"deploy": "npx wrangler --cwd .output deploy --name capital"
},
"dependencies": {
"@bg-dev/nuxt-naiveui": "^2.0.0",
@@ -16,6 +17,7 @@
"@nuxt/eslint": "1.7.1",
"@nuxt/image": "1.10.0",
"@nuxt/scripts": "0.11.10",
"@nuxtjs/i18n": "10.2.1",
"@octokit/rest": "^22.0.1",
"@unhead/vue": "^2.0.19",
"@vueuse/core": "^13.9.0",
@@ -31,6 +33,8 @@
},
"devDependencies": {
"@tailwindcss/typography": "^0.5.19",
"@tailwindcss/vite": "^4.1.17",
"@vicons/ionicons5": "^0.13.0",
"@vicons/material": "^0.13.0",
"daisyui": "^5.5.5",
"naive-ui": "^2.43.2",