diff --git a/web/default/src/i18n/locales/en.json b/web/default/src/i18n/locales/en.json
index 4727c377511e..1907a93a3448 100644
--- a/web/default/src/i18n/locales/en.json
+++ b/web/default/src/i18n/locales/en.json
@@ -70,6 +70,7 @@
"AI model testing environment": "AI model testing environment",
"AI models": "AI models",
"AI models supported": "AI models supported",
+ "AI-powered code editor — use DeepRouter for completions and chat.": "AI-powered code editor — use DeepRouter for completions and chat.",
"AIGC2D": "AIGC2D",
"AILS": "AILS",
"AK/SK mode: use AccessKey|SecretAccessKey|Region": "AK/SK mode: use AccessKey|SecretAccessKey|Region",
@@ -318,6 +319,7 @@
"Answer": "Answer",
"Answers for common access and billing questions": "Answers for common access and billing questions",
"Anthropic": "Anthropic",
+ "Anthropic's CLI agent — route via DeepRouter using Anthropic-format keys.": "Anthropic's CLI agent — route via DeepRouter using Anthropic-format keys.",
"Any Match (OR)": "Any Match (OR)",
"App": "App",
"App rankings shown here are simulated for preview purposes and will be replaced with live usage data once the backend integration is complete.": "App rankings shown here are simulated for preview purposes and will be replaced with live usage data once the backend integration is complete.",
@@ -426,6 +428,7 @@
"Avg. latency": "Avg. latency",
"Azure": "Azure",
"Back": "Back",
+ "Back to API Keys": "Back to API Keys",
"Back to Home": "Back to Home",
"Back to Models": "Back to Models",
"Back to login": "Back to login",
@@ -563,6 +566,7 @@
"Calculating...": "Calculating...",
"Call Count Distribution": "Call Count Distribution",
"Call Count Ranking": "Call Count Ranking",
+ "Call DeepRouter directly from your application.": "Call DeepRouter directly from your application.",
"Call Proportion": "Call Proportion",
"Call Trend": "Call Trend",
"Callback Caller IP": "Callback Caller IP",
@@ -984,6 +988,7 @@
"Creem products must be a JSON array": "Creem products must be a JSON array",
"Cross-group": "Cross-group",
"Cross-group retry": "Cross-group retry",
+ "Cross-platform chat client (web + desktop).": "Cross-platform chat client (web + desktop).",
"Curate quick links to your different Domains": "Curate quick links to your different Domains",
"Currency": "Currency",
"Currency & Display": "Currency & Display",
@@ -1691,6 +1696,7 @@
"Forward requests directly to upstream providers without any post-processing.": "Forward requests directly to upstream providers without any post-processing.",
"Frames per second": "Frames per second",
"Free: {{free}} / Total: {{total}}": "Free: {{free}} / Total: {{total}}",
+ "Friendly desktop client — recommended for chat and writing.": "Friendly desktop client — recommended for chat and writing.",
"Friendly name to identify this channel": "Friendly name to identify this channel",
"From Address": "From Address",
"From IO.NET deployment": "From IO.NET deployment",
@@ -2564,6 +2570,7 @@
"Open the io.net console API Keys page": "Open the io.net console API Keys page",
"Open theme settings": "Open theme settings",
"Open weights": "Open weights",
+ "Open-source AI chat with plugins and multi-modal support.": "Open-source AI chat with plugins and multi-modal support.",
"OpenAI": "OpenAI",
"OpenAI Compatible": "OpenAI Compatible",
"OpenAI Organization": "OpenAI Organization",
@@ -3503,6 +3510,7 @@
"Special ratios override the token group ratio for specific user group and token group combinations.": "Special ratios override the token group ratio for specific user group and token group combinations.",
"Special usable group rules": "Special usable group rules",
"Special usable group rules can add, remove, or append selectable token groups for a specific user group.": "Special usable group rules can add, remove, or append selectable token groups for a specific user group.",
+ "Spent so far": "Spent so far",
"Standard": "Standard",
"Standard price": "Standard price",
"Start": "Start",
@@ -3837,6 +3845,8 @@
"Top model": "Top model",
"Top models": "Top models",
"Top up balance and view billing history.": "Top up balance and view billing history.",
+ "Top up to call AI models. Your trial credit covers your first few requests so you can try things out.": "Top up to call AI models. Your trial credit covers your first few requests so you can try things out.",
+ "Top up to start using AI models": "Top up to start using AI models",
"Top vendors": "Top vendors",
"Top {{count}}": "Top {{count}}",
"Top-Up Link": "Top-Up Link",
@@ -3855,6 +3865,7 @@
"Total Quota": "Total Quota",
"Total Tokens": "Total Tokens",
"Total Usage": "Total Usage",
+ "Total calls made": "Total calls made",
"Total check-ins": "Total check-ins",
"Total consumed": "Total consumed",
"Total consumed quota": "Total consumed quota",
@@ -3893,8 +3904,10 @@
"Trusted by developers shipping production AI features.": "Trusted by developers shipping production AI features.",
"Try adjusting your search": "Try adjusting your search",
"Try adjusting your search to locate a missing model.": "Try adjusting your search to locate a missing model.",
+ "Try in Playground": "Try in Playground",
"Tune selection priority, testing, status handling, and request overrides.": "Tune selection priority, testing, status handling, and request overrides.",
"Turnstile is enabled but site key is empty.": "Turnstile is enabled but site key is empty.",
+ "Tutorial not found": "Tutorial not found",
"Tutoring, learning aids, assessment": "Tutoring, learning aids, assessment",
"Two-Factor Authentication": "Two-Factor Authentication",
"Two-Step Verification": "Two-Step Verification",
@@ -4022,6 +4035,7 @@
"Use sidebar shortcut": "Use sidebar shortcut",
"Use the full-width table to scan prices, then select a row to edit it here.": "Use the full-width table to scan prices, then select a row to edit it here.",
"Use the pricing group table to manage the ratio and whether the group appears in the token creation dropdown.": "Use the pricing group table to manage the ratio and whether the group appears in the token creation dropdown.",
+ "Use these values in the steps below. Your API Key was shown when you created it on the Keys page.": "Use these values in the steps below. Your API Key was shown when you created it on the Keys page.",
"Use this in your client. We route it to the right model based on this key.": "Use this in your client. We route it to the right model based on this key.",
"Use this token for API authentication": "Use this token for API authentication",
"Use your Passkey": "Use your Passkey",
@@ -4163,6 +4177,7 @@
"Warning: This action is permanent and irreversible!": "Warning: This action is permanent and irreversible!",
"We apologize for the inconvenience.": "We apologize for the inconvenience.",
"We could not load the setup status.": "We could not load the setup status.",
+ "We don't have a guide for this client yet.": "We don't have a guide for this client yet.",
"We will prompt your device to confirm using biometrics or your hardware key.": "We will prompt your device to confirm using biometrics or your hardware key.",
"We'll be back online shortly.": "We'll be back online shortly.",
"WeChat": "WeChat",
@@ -4497,6 +4512,8 @@
"{{value}}ms": "{{value}}ms",
"{{value}}s": "{{value}}s",
"| Based on": "| Based on",
- "© 2025 Your Company. All rights reserved.": "© 2025 Your Company. All rights reserved."
+ "© 2025 Your Company. All rights reserved.": "© 2025 Your Company. All rights reserved.",
+ "≈ {{count}} chats": "≈ {{count}} chats",
+ "≈ {{count}} chats remaining": "≈ {{count}} chats remaining"
}
}
diff --git a/web/default/src/i18n/locales/zh.json b/web/default/src/i18n/locales/zh.json
index 311d66c42ebe..15fae5c46ed9 100644
--- a/web/default/src/i18n/locales/zh.json
+++ b/web/default/src/i18n/locales/zh.json
@@ -70,6 +70,7 @@
"AI model testing environment": "AI模型测试环境",
"AI models": "AI 模型",
"AI models supported": "支持的 AI 模型",
+ "AI-powered code editor — use DeepRouter for completions and chat.": "AI 代码编辑器 —— 用 DeepRouter 走对话和编辑。",
"AIGC2D": "AIGC2D",
"AILS": "AILS",
"AK/SK mode: use AccessKey|SecretAccessKey|Region": "AK/SK 模式:使用 AccessKey|SecretAccessKey|Region",
@@ -318,6 +319,7 @@
"Answer": "答案",
"Answers for common access and billing questions": "访问与计费常见问题解答",
"Anthropic": "Anthropic",
+ "Anthropic's CLI agent — route via DeepRouter using Anthropic-format keys.": "Anthropic CLI agent —— 通过 DeepRouter 用 Anthropic 接口调用。",
"Any Match (OR)": "任一满足(OR)",
"App": "应用",
"App rankings shown here are simulated for preview purposes and will be replaced with live usage data once the backend integration is complete.": "此处展示的应用排行为预览模拟数据,待后端对接完成后将替换为真实数据。",
@@ -426,6 +428,7 @@
"Avg. latency": "平均延迟",
"Azure": "Azure",
"Back": "返回",
+ "Back to API Keys": "返回 API 密钥",
"Back to Home": "返回主页",
"Back to Models": "返回模型",
"Back to login": "返回登录",
@@ -563,6 +566,7 @@
"Calculating...": "计算中...",
"Call Count Distribution": "调用次数分布",
"Call Count Ranking": "调用次数排行",
+ "Call DeepRouter directly from your application.": "在自己的代码里直接调用 DeepRouter。",
"Call Proportion": "调用比例",
"Call Trend": "调用趋势",
"Callback Caller IP": "回调调用者 IP",
@@ -984,6 +988,7 @@
"Creem products must be a JSON array": "Creem 产品必须是 JSON 数组",
"Cross-group": "跨分组",
"Cross-group retry": "跨分组重试",
+ "Cross-platform chat client (web + desktop).": "跨平台 AI 客户端(网页 / 桌面)。",
"Curate quick links to your different Domains": "整理到不同域的快速链接",
"Currency": "货币",
"Currency & Display": "货币与展示",
@@ -1691,6 +1696,7 @@
"Forward requests directly to upstream providers without any post-processing.": "将请求直接转发给上游提供商,不进行任何后处理。",
"Frames per second": "帧率",
"Free: {{free}} / Total: {{total}}": "可用空间: {{free}} / 总空间: {{total}}",
+ "Friendly desktop client — recommended for chat and writing.": "新手友好的桌面客户端 —— 适合聊天和写作。",
"Friendly name to identify this channel": "用于识别此渠道的友好名称",
"From Address": "发件地址",
"From IO.NET deployment": "来自 IO.NET 部署",
@@ -2564,6 +2570,7 @@
"Open the io.net console API Keys page": "打开 io.net 控制台 API 密钥页面",
"Open theme settings": "打开主题设置",
"Open weights": "开放权重",
+ "Open-source AI chat with plugins and multi-modal support.": "开源 AI 客户端,支持插件和多模态。",
"OpenAI": "OpenAI",
"OpenAI Compatible": "兼容 OpenAI",
"OpenAI Organization": "OpenAI 组织",
@@ -3503,6 +3510,7 @@
"Special ratios override the token group ratio for specific user group and token group combinations.": "特殊倍率会针对特定用户分组和令牌分组组合覆盖令牌分组倍率。",
"Special usable group rules": "特殊可用分组规则",
"Special usable group rules can add, remove, or append selectable token groups for a specific user group.": "特殊可用分组规则可以为特定用户分组添加、移除或追加可选令牌分组。",
+ "Spent so far": "累计消费",
"Standard": "标准",
"Standard price": "标准价格",
"Start": "开始",
@@ -3837,6 +3845,8 @@
"Top model": "领头模型",
"Top models": "热门模型",
"Top up balance and view billing history.": "充值余额并查看账单历史。",
+ "Top up to call AI models. Your trial credit covers your first few requests so you can try things out.": "充值后调用 AI 模型。注册赠送的额度够你试用前几次请求。",
+ "Top up to start using AI models": "充值后开始使用 AI 模型",
"Top vendors": "热门厂商",
"Top {{count}}": "前 {{count}}",
"Top-Up Link": "充值链接",
@@ -3855,6 +3865,7 @@
"Total Quota": "总额度",
"Total Tokens": "总 Token 数",
"Total Usage": "总用量",
+ "Total calls made": "累计调用次数",
"Total check-ins": "累计签到",
"Total consumed": "总消耗",
"Total consumed quota": "总消耗额度",
@@ -3893,8 +3904,10 @@
"Trusted by developers shipping production AI features.": "被一线 AI 开发者信赖。",
"Try adjusting your search": "请尝试调整搜索条件",
"Try adjusting your search to locate a missing model.": "尝试调整您的搜索以找到缺失的模型。",
+ "Try in Playground": "在试玩里试试",
"Tune selection priority, testing, status handling, and request overrides.": "调整选择优先级、测试、状态处理和请求覆盖。",
"Turnstile is enabled but site key is empty.": "Turnstile 已启用但站点密钥为空。",
+ "Tutorial not found": "教程未找到",
"Tutoring, learning aids, assessment": "辅导、学习辅助与测评",
"Two-Factor Authentication": "两步验证",
"Two-Step Verification": "两步验证",
@@ -4022,6 +4035,7 @@
"Use sidebar shortcut": "使用侧边栏快捷方式",
"Use the full-width table to scan prices, then select a row to edit it here.": "先在表格中快速浏览价格,然后选择一行在这里编辑。",
"Use the pricing group table to manage the ratio and whether the group appears in the token creation dropdown.": "使用定价分组表管理倍率,以及该分组是否出现在创建令牌的下拉框中。",
+ "Use these values in the steps below. Your API Key was shown when you created it on the Keys page.": "下面步骤中会用到这些值。API Key 在你创建时已经显示过。",
"Use this in your client. We route it to the right model based on this key.": "在客户端填这个名字,我们会根据 Key 路由到合适的模型。",
"Use this token for API authentication": "使用此令牌进行 API 身份验证",
"Use your Passkey": "使用您的通行密钥",
@@ -4163,6 +4177,7 @@
"Warning: This action is permanent and irreversible!": "警告:此操作是永久且不可逆的!",
"We apologize for the inconvenience.": "对于由此造成的不便,我们深表歉意。",
"We could not load the setup status.": "我们无法加载设置状态。",
+ "We don't have a guide for this client yet.": "暂无该客户端的接入指南。",
"We will prompt your device to confirm using biometrics or your hardware key.": "我们将提示您的设备使用生物识别或硬件密钥进行确认。",
"We'll be back online shortly.": "我们将很快恢复在线。",
"WeChat": "微信",
@@ -4497,6 +4512,8 @@
"{{value}}ms": "{{value}} 毫秒",
"{{value}}s": "{{value}} 秒",
"| Based on": "| 基于",
- "© 2025 Your Company. All rights reserved.": "© 2025 您的公司。保留所有权利。"
+ "© 2025 Your Company. All rights reserved.": "© 2025 您的公司。保留所有权利。",
+ "≈ {{count}} chats": "≈ 聊 {{count}} 次",
+ "≈ {{count}} chats remaining": "≈ 还能聊 {{count}} 次"
}
}
diff --git a/web/default/src/lib/usage-estimate.ts b/web/default/src/lib/usage-estimate.ts
new file mode 100644
index 000000000000..900b8e9fb9cd
--- /dev/null
+++ b/web/default/src/lib/usage-estimate.ts
@@ -0,0 +1,85 @@
+/*
+Copyright (C) 2023-2026 QuantumNous
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as
+published by the Free Software Foundation, either version 3 of the
+License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+
+For commercial licensing, please contact support@quantumnous.com
+*/
+
+/**
+ * Quota → human-friendly "how many chats can I afford" estimates.
+ *
+ * Quota is stored in units where 500,000 = $1 USD. We assume a mid-tier
+ * chat costs ~$0.005 (avg between gpt-4o-mini and gpt-4o):
+ * chats ≈ (quota / 500_000) / 0.005 = quota / 2_500
+ *
+ * Image / video / TTS estimates use coarser per-unit costs sourced from
+ * setting/alias_setting/seed/aliases.yaml YAML defaults.
+ *
+ * These are *order-of-magnitude* estimates for marketing-friendly UI
+ * copy — never treat them as billing-grade. Actual cost depends on the
+ * model the user invokes and conversation length.
+ */
+
+const QUOTA_PER_USD = 500_000
+const AVG_CHAT_COST_USD = 0.005 // mid-tier mix of gpt-4o-mini ($0.0004) and gpt-4o ($0.006)
+const AVG_IMAGE_COST_USD = 0.04 // DALL·E-3 standard
+const AVG_VIDEO_COST_USD = 0.6 // Veo-3 5-sec clip
+const AVG_MINUTE_COST_USD = 0.006 // Whisper-1 / TTS midpoint
+
+/**
+ * Estimate how many average chat turns a quota balance covers.
+ * Returns a non-negative integer; 0 when input is invalid or zero.
+ */
+export function estimateChats(quota: number | null | undefined): number {
+ if (!quota || !Number.isFinite(quota) || quota <= 0) return 0
+ const usd = quota / QUOTA_PER_USD
+ return Math.max(0, Math.floor(usd / AVG_CHAT_COST_USD))
+}
+
+/** Estimate images at DALL·E-3 standard price. */
+export function estimateImages(quota: number | null | undefined): number {
+ if (!quota || !Number.isFinite(quota) || quota <= 0) return 0
+ const usd = quota / QUOTA_PER_USD
+ return Math.max(0, Math.floor(usd / AVG_IMAGE_COST_USD))
+}
+
+/** Estimate ~5s video clips at Veo-3 price. */
+export function estimateVideoClips(quota: number | null | undefined): number {
+ if (!quota || !Number.isFinite(quota) || quota <= 0) return 0
+ const usd = quota / QUOTA_PER_USD
+ return Math.max(0, Math.floor(usd / AVG_VIDEO_COST_USD))
+}
+
+/** Estimate audio minutes (TTS/STT) at Whisper midpoint. */
+export function estimateAudioMinutes(
+ quota: number | null | undefined
+): number {
+ if (!quota || !Number.isFinite(quota) || quota <= 0) return 0
+ const usd = quota / QUOTA_PER_USD
+ return Math.max(0, Math.floor(usd / AVG_MINUTE_COST_USD))
+}
+
+/**
+ * Format an integer count with the appropriate "k" / "万" suffix for
+ * marketing copy. Returns "1.2k" / "12k" / "120k" / "1.2m" style strings.
+ * For zh-leaning UI you may prefer to render with 万 (ten-thousand) —
+ * this helper stays language-neutral; callers wrap with their own i18n.
+ */
+export function formatCount(n: number): string {
+ if (n < 1000) return String(n)
+ if (n < 10_000) return `${(n / 1000).toFixed(1).replace(/\.0$/, '')}k`
+ if (n < 1_000_000) return `${Math.floor(n / 1000)}k`
+ return `${(n / 1_000_000).toFixed(1).replace(/\.0$/, '')}m`
+}
diff --git a/web/default/src/routeTree.gen.ts b/web/default/src/routeTree.gen.ts
index 3fddc8342bf0..6adf861224cb 100644
--- a/web/default/src/routeTree.gen.ts
+++ b/web/default/src/routeTree.gen.ts
@@ -18,6 +18,7 @@ import { Route as SetupIndexRouteImport } from './routes/setup/index'
import { Route as RankingsIndexRouteImport } from './routes/rankings/index'
import { Route as PricingIndexRouteImport } from './routes/pricing/index'
import { Route as AboutIndexRouteImport } from './routes/about/index'
+import { Route as OnboardingSlugRouteImport } from './routes/onboarding/$slug'
import { Route as OauthProviderRouteImport } from './routes/oauth/$provider'
import { Route as ConsoleTopupRouteImport } from './routes/console/topup'
import { Route as ConsoleLogRouteImport } from './routes/console/log'
@@ -112,6 +113,11 @@ const AboutIndexRoute = AboutIndexRouteImport.update({
path: '/about/',
getParentRoute: () => rootRouteImport,
} as any)
+const OnboardingSlugRoute = OnboardingSlugRouteImport.update({
+ id: '/onboarding/$slug',
+ path: '/onboarding/$slug',
+ getParentRoute: () => rootRouteImport,
+} as any)
const OauthProviderRoute = OauthProviderRouteImport.update({
id: '/oauth/$provider',
path: '/oauth/$provider',
@@ -413,6 +419,7 @@ export interface FileRoutesByFullPath {
'/console/log': typeof ConsoleLogRoute
'/console/topup': typeof ConsoleTopupRoute
'/oauth/$provider': typeof OauthProviderRoute
+ '/onboarding/$slug': typeof OnboardingSlugRoute
'/about/': typeof AboutIndexRoute
'/pricing/': typeof PricingIndexRoute
'/rankings/': typeof RankingsIndexRoute
@@ -471,6 +478,7 @@ export interface FileRoutesByTo {
'/console/log': typeof ConsoleLogRoute
'/console/topup': typeof ConsoleTopupRoute
'/oauth/$provider': typeof OauthProviderRoute
+ '/onboarding/$slug': typeof OnboardingSlugRoute
'/about': typeof AboutIndexRoute
'/pricing': typeof PricingIndexRoute
'/rankings': typeof RankingsIndexRoute
@@ -533,6 +541,7 @@ export interface FileRoutesById {
'/console/log': typeof ConsoleLogRoute
'/console/topup': typeof ConsoleTopupRoute
'/oauth/$provider': typeof OauthProviderRoute
+ '/onboarding/$slug': typeof OnboardingSlugRoute
'/about/': typeof AboutIndexRoute
'/pricing/': typeof PricingIndexRoute
'/rankings/': typeof RankingsIndexRoute
@@ -594,6 +603,7 @@ export interface FileRouteTypes {
| '/console/log'
| '/console/topup'
| '/oauth/$provider'
+ | '/onboarding/$slug'
| '/about/'
| '/pricing/'
| '/rankings/'
@@ -652,6 +662,7 @@ export interface FileRouteTypes {
| '/console/log'
| '/console/topup'
| '/oauth/$provider'
+ | '/onboarding/$slug'
| '/about'
| '/pricing'
| '/rankings'
@@ -713,6 +724,7 @@ export interface FileRouteTypes {
| '/console/log'
| '/console/topup'
| '/oauth/$provider'
+ | '/onboarding/$slug'
| '/about/'
| '/pricing/'
| '/rankings/'
@@ -767,6 +779,7 @@ export interface RootRouteChildren {
ConsoleLogRoute: typeof ConsoleLogRoute
ConsoleTopupRoute: typeof ConsoleTopupRoute
OauthProviderRoute: typeof OauthProviderRoute
+ OnboardingSlugRoute: typeof OnboardingSlugRoute
AboutIndexRoute: typeof AboutIndexRoute
PricingIndexRoute: typeof PricingIndexRoute
RankingsIndexRoute: typeof RankingsIndexRoute
@@ -839,6 +852,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof AboutIndexRouteImport
parentRoute: typeof rootRouteImport
}
+ '/onboarding/$slug': {
+ id: '/onboarding/$slug'
+ path: '/onboarding/$slug'
+ fullPath: '/onboarding/$slug'
+ preLoaderRoute: typeof OnboardingSlugRouteImport
+ parentRoute: typeof rootRouteImport
+ }
'/oauth/$provider': {
id: '/oauth/$provider'
path: '/oauth/$provider'
@@ -1336,6 +1356,7 @@ const rootRouteChildren: RootRouteChildren = {
ConsoleLogRoute: ConsoleLogRoute,
ConsoleTopupRoute: ConsoleTopupRoute,
OauthProviderRoute: OauthProviderRoute,
+ OnboardingSlugRoute: OnboardingSlugRoute,
AboutIndexRoute: AboutIndexRoute,
PricingIndexRoute: PricingIndexRoute,
RankingsIndexRoute: RankingsIndexRoute,
diff --git a/web/default/src/routes/onboarding/$slug.tsx b/web/default/src/routes/onboarding/$slug.tsx
new file mode 100644
index 000000000000..a5cf47dfb39b
--- /dev/null
+++ b/web/default/src/routes/onboarding/$slug.tsx
@@ -0,0 +1,24 @@
+/*
+Copyright (C) 2023-2026 QuantumNous
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as
+published by the Free Software Foundation, either version 3 of the
+License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+
+For commercial licensing, please contact support@quantumnous.com
+*/
+import { createFileRoute } from '@tanstack/react-router'
+import { OnboardingTutorial } from '@/features/onboarding'
+
+export const Route = createFileRoute('/onboarding/$slug')({
+ component: OnboardingTutorial,
+})