Compare commits
6 Commits
cloudflare
...
main
Author | SHA1 | Date | |
---|---|---|---|
79f575b9b9 | |||
c994529d01 | |||
3bd171683d | |||
|
6262432b64 | ||
|
e556f72fc7 | ||
|
aea55ee4bb |
203
.env.production
Normal file
203
.env.production
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Application BASE URL
|
||||||
|
# https://mksaas.com/docs/env#core-configuration
|
||||||
|
# For production, set to your domain, e.g. https://mksaas.com
|
||||||
|
# For development, set to http://localhost:3000 or any other port
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
NEXT_PUBLIC_BASE_URL="https://image.prmbr.com"
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Database
|
||||||
|
# https://mksaas.com/docs/database
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
DATABASE_URL="postgresql://neondb_owner:npg_mfEJ5NRrZbd2@ep-long-feather-a1ydksyq-pooler.ap-southeast-1.aws.neon.tech/neondb?sslmode=require&channel_binding=require"
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Better Auth
|
||||||
|
# https://mksaas.com/docs/auth
|
||||||
|
# Generate a random string for the secret key using `openssl rand -base64 32`
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
BETTER_AUTH_SECRET="Vi7Tugxf/Mh20VGtsLeZsf6dUULVGCiL7MKloRvLT+c="
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Github OAuth
|
||||||
|
# https://mksaas.com/docs/auth#2-configure-github-oauth
|
||||||
|
# https://www.better-auth.com/docs/authentication/github
|
||||||
|
# Get Client information from https://github.com/settings/developers
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
GITHUB_CLIENT_ID=""
|
||||||
|
GITHUB_CLIENT_SECRET=""
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Google OAuth
|
||||||
|
# https://mksaas.com/docs/auth#3-configure-google-oauth
|
||||||
|
# https://www.better-auth.com/docs/authentication/google
|
||||||
|
# Get Client information from https://console.cloud.google.com/apis/credentials
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
GOOGLE_CLIENT_ID="1011279317992-1irl2k5mqdso0t12sls0svd0vuuvleto.apps.googleusercontent.com"
|
||||||
|
GOOGLE_CLIENT_SECRET="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"
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Email / Newsletter (Resend)
|
||||||
|
# https://mksaas.com/docs/email
|
||||||
|
# https://mksaas.com/docs/newsletter
|
||||||
|
# Get API key and audience id from https://resend.com
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
RESEND_API_KEY="re_YGb7jyZk_CxpAWPDPSF53tooCAzoWK6u6"
|
||||||
|
RESEND_AUDIENCE_ID="c5a0dd69-3a22-4866-b9e6-e4047e83e0d0"
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Storage (Cloudflare R2 or S3-compatible service of your choice)
|
||||||
|
# https://mksaas.com/docs/storage
|
||||||
|
# Cloudflare R2: https://www.cloudflare.com/developer-platform/products/r2
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
STORAGE_REGION="auto"
|
||||||
|
STORAGE_BUCKET_NAME="prmbr-image"
|
||||||
|
STORAGE_ACCESS_KEY_ID="8da3b416c62642ef69cbb485d5673d58"
|
||||||
|
STORAGE_SECRET_ACCESS_KEY="d94f673573a595afb11e09d7963484b5f13914bbd01a598debaa1bf2314e1df1"
|
||||||
|
STORAGE_ENDPOINT="https://209b775a76842f6f305193e41de86be1.r2.cloudflarestorage.com"
|
||||||
|
STORAGE_PUBLIC_URL="https://image-cdn.prmbr.com"
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Payment (Stripe)
|
||||||
|
# https://mksaas.com/docs/payment
|
||||||
|
# Get Stripe key and secret from https://dashboard.stripe.com
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
STRIPE_SECRET_KEY=""
|
||||||
|
STRIPE_WEBHOOK_SECRET=""
|
||||||
|
# Pro plan - monthly subscription
|
||||||
|
NEXT_PUBLIC_STRIPE_PRICE_PRO_MONTHLY=""
|
||||||
|
# Pro plan - yearly subscription
|
||||||
|
NEXT_PUBLIC_STRIPE_PRICE_PRO_YEARLY=""
|
||||||
|
# Lifetime plan - one-time payment
|
||||||
|
NEXT_PUBLIC_STRIPE_PRICE_LIFETIME=""
|
||||||
|
# Credit package - basic
|
||||||
|
NEXT_PUBLIC_STRIPE_PRICE_CREDITS_BASIC=""
|
||||||
|
# Credit package - standard
|
||||||
|
NEXT_PUBLIC_STRIPE_PRICE_CREDITS_STANDARD=""
|
||||||
|
# Credit package - premium
|
||||||
|
NEXT_PUBLIC_STRIPE_PRICE_CREDITS_PREMIUM=""
|
||||||
|
# Credit package - enterprise
|
||||||
|
NEXT_PUBLIC_STRIPE_PRICE_CREDITS_ENTERPRISE=""
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Configurations
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Disable image optimization, check out next.config.ts for more details
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
DISABLE_IMAGE_OPTIMIZATION=false
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Run this website as demo website, in most cases, you should set this to false
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
NEXT_PUBLIC_DEMO_WEBSITE=false
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Analytics
|
||||||
|
# https://mksaas.com/docs/analytics
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Google Analytics (https://analytics.google.com)
|
||||||
|
# https://mksaas.com/docs/analytics#google
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
NEXT_PUBLIC_GOOGLE_ANALYTICS_ID="G-06MQ7YHDTT"
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Umami Analytics (https://umami.is)
|
||||||
|
# https://mksaas.com/docs/analytics#umami
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
NEXT_PUBLIC_UMAMI_WEBSITE_ID="ab7e1694-572d-48c9-a76b-8419e8c18111"
|
||||||
|
NEXT_PUBLIC_UMAMI_SCRIPT="https://umami.frytea.com/script.js"
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# OpenPanel Analytics (https://openpanel.dev)
|
||||||
|
# https://mksaas.com/docs/analytics#openpanel
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
NEXT_PUBLIC_OPENPANEL_CLIENT_ID=""
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Plausible Analytics (https://plausible.io)
|
||||||
|
# https://mksaas.com/docs/analytics#plausible
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
NEXT_PUBLIC_PLAUSIBLE_DOMAIN=""
|
||||||
|
NEXT_PUBLIC_PLAUSIBLE_SCRIPT="https://plausible.io/js/script.js"
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Ahrefs Analytics (https://ahrefs.com)
|
||||||
|
# https://mksaas.com/docs/analytics#ahrefs
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
NEXT_PUBLIC_AHREFS_WEBSITE_ID=""
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Seline Analytics
|
||||||
|
# https://mksaas.com/docs/analytics#seline
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
NEXT_PUBLIC_SELINE_TOKEN=""
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# DataFast Analytics (https://datafa.st)
|
||||||
|
# https://mksaas.com/docs/analytics#datafast
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
NEXT_PUBLIC_DATAFAST_WEBSITE_ID=""
|
||||||
|
NEXT_PUBLIC_DATAFAST_DOMAIN=""
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# PostHog Analytics (https://posthog.com)
|
||||||
|
# https://mksaas.com/docs/analytics#posthog
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
NEXT_PUBLIC_POSTHOG_KEY=""
|
||||||
|
NEXT_PUBLIC_POSTHOG_HOST=""
|
||||||
|
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Notification (Discord)
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
DISCORD_WEBHOOK_URL=""
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Notification (Feishu)
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
FEISHU_WEBHOOK_URL=""
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Affiliate
|
||||||
|
# https://mksaas.com/docs/affiliate
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Affonso
|
||||||
|
# https://affonso.com/
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
NEXT_PUBLIC_AFFILIATE_AFFONSO_ID=""
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# PromoteKit
|
||||||
|
# https://www.promotekit.com/
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
NEXT_PUBLIC_AFFILIATE_PROMOTEKIT_ID=""
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Captcha (Cloudflare Turnstile)
|
||||||
|
# https://mksaas.com/docs/captcha
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
NEXT_PUBLIC_TURNSTILE_SITE_KEY=""
|
||||||
|
TURNSTILE_SECRET_KEY=""
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Crisp
|
||||||
|
# https://mksaas.com/docs/chat
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
NEXT_PUBLIC_CRISP_WEBSITE_ID=""
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Cron Jobs
|
||||||
|
# https://mksaas.com/docs/cronjobs
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
CRON_JOBS_USERNAME="prmbr-image-crontab"
|
||||||
|
CRON_JOBS_PASSWORD="82AwL!Ya^n8ht2u%bE0U*EFI"
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# AI
|
||||||
|
# https://mksaas.com/docs/ai
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
AI_GATEWAY_API_KEY=""
|
||||||
|
FAL_API_KEY="7eb06562-078d-4a25-a9d8-a97529d8998e:5fc7ddd7ed48b2e669e7a6dee62e7262"
|
||||||
|
FIREWORKS_API_KEY=""
|
||||||
|
OPENAI_API_KEY=""
|
||||||
|
REPLICATE_API_TOKEN=""
|
||||||
|
GOOGLE_GENERATIVE_AI_API_KEY=""
|
||||||
|
DEEPSEEK_API_KEY=""
|
||||||
|
OPENROUTER_API_KEY="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"
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Web Content Analyzer (Firecrawl)
|
||||||
|
# https://firecrawl.dev/
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
FIRECRAWL_API_KEY=""
|
@ -35,6 +35,14 @@ After that, you can return to the blog post and you can read the rest of the blo
|
|||||||
|
|
||||||
For more details, please check out the documentation: [Blog](https://mksaas.com/docs/blog).
|
For more details, please check out the documentation: [Blog](https://mksaas.com/docs/blog).
|
||||||
|
|
||||||
|
Test show Tweet in the blog post.
|
||||||
|
|
||||||
|
<XEmbedClient url="https://x.com/mksaascom/status/1960417768505008291" width={500} />
|
||||||
|
|
||||||
|
Test show YouTube video in the blog post.
|
||||||
|
|
||||||
|
<YoutubeVideo url="https://www.youtube.com/embed/xvoeSnlFZJk" width={500} />
|
||||||
|
|
||||||
Now the rest of the blog post is premium content.
|
Now the rest of the blog post is premium content.
|
||||||
|
|
||||||
<PremiumContent>
|
<PremiumContent>
|
||||||
|
@ -35,6 +35,14 @@ CVV: 567
|
|||||||
|
|
||||||
更多详情,请参考文档:[博客](https://mksaas.com/docs/blog)。
|
更多详情,请参考文档:[博客](https://mksaas.com/docs/blog)。
|
||||||
|
|
||||||
|
测试展示 X 帖子。
|
||||||
|
|
||||||
|
<XEmbedClient url="https://x.com/mksaascom/status/1960417768505008291" width={500} />
|
||||||
|
|
||||||
|
测试展示 YouTube 视频。
|
||||||
|
|
||||||
|
<YoutubeVideo url="https://www.youtube.com/embed/xvoeSnlFZJk" width={500} />
|
||||||
|
|
||||||
现在剩下的内容是付费内容。
|
现在剩下的内容是付费内容。
|
||||||
|
|
||||||
<PremiumContent>
|
<PremiumContent>
|
||||||
|
@ -132,6 +132,12 @@ NEXT_PUBLIC_SELINE_TOKEN=""
|
|||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
NEXT_PUBLIC_DATAFAST_WEBSITE_ID=""
|
NEXT_PUBLIC_DATAFAST_WEBSITE_ID=""
|
||||||
NEXT_PUBLIC_DATAFAST_DOMAIN=""
|
NEXT_PUBLIC_DATAFAST_DOMAIN=""
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# PostHog Analytics (https://posthog.com)
|
||||||
|
# https://mksaas.com/docs/analytics#posthog
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
NEXT_PUBLIC_POSTHOG_KEY=""
|
||||||
|
NEXT_PUBLIC_POSTHOG_HOST=""
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
|
@ -333,6 +333,10 @@
|
|||||||
"title": "AI Image",
|
"title": "AI Image",
|
||||||
"description": "Show how to use AI to generate beautiful images"
|
"description": "Show how to use AI to generate beautiful images"
|
||||||
},
|
},
|
||||||
|
"images": {
|
||||||
|
"title": "AI Images",
|
||||||
|
"description": "use AI to generate beautiful images"
|
||||||
|
},
|
||||||
"chat": {
|
"chat": {
|
||||||
"title": "AI Chat",
|
"title": "AI Chat",
|
||||||
"description": "Show how to use AI to chat with your customers"
|
"description": "Show how to use AI to chat with your customers"
|
||||||
@ -1059,6 +1063,10 @@
|
|||||||
"title": "AI Image",
|
"title": "AI Image",
|
||||||
"description": "MkSaaS lets you make AI SaaS in days, simply and effortlessly"
|
"description": "MkSaaS lets you make AI SaaS in days, simply and effortlessly"
|
||||||
},
|
},
|
||||||
|
"AIImagesPage": {
|
||||||
|
"title": "AI Images Generator",
|
||||||
|
"description": "Is a AI Image Generator"
|
||||||
|
},
|
||||||
"AIChatPage": {
|
"AIChatPage": {
|
||||||
"title": "AI Chat",
|
"title": "AI Chat",
|
||||||
"description": "MkSaaS lets you make AI SaaS in days, simply and effortlessly"
|
"description": "MkSaaS lets you make AI SaaS in days, simply and effortlessly"
|
||||||
|
@ -333,6 +333,10 @@
|
|||||||
"title": "AI 图像",
|
"title": "AI 图像",
|
||||||
"description": "展示如何使用 AI 生成精美图像"
|
"description": "展示如何使用 AI 生成精美图像"
|
||||||
},
|
},
|
||||||
|
"images": {
|
||||||
|
"title": "AI 图像生成",
|
||||||
|
"description": "使用 AI 生成精美图像"
|
||||||
|
},
|
||||||
"chat": {
|
"chat": {
|
||||||
"title": "AI 聊天",
|
"title": "AI 聊天",
|
||||||
"description": "展示如何使用 AI 与客户聊天"
|
"description": "展示如何使用 AI 与客户聊天"
|
||||||
@ -1059,6 +1063,10 @@
|
|||||||
"title": "AI 图片",
|
"title": "AI 图片",
|
||||||
"description": "MkSaaS 让您在几天内轻松构建您的 AI SaaS,简单且毫不费力"
|
"description": "MkSaaS 让您在几天内轻松构建您的 AI SaaS,简单且毫不费力"
|
||||||
},
|
},
|
||||||
|
"AIImagesPage": {
|
||||||
|
"title": "AI 图片生成器",
|
||||||
|
"description": "但模型图片生成测试"
|
||||||
|
},
|
||||||
"AIChatPage": {
|
"AIChatPage": {
|
||||||
"title": "AI 聊天",
|
"title": "AI 聊天",
|
||||||
"description": "MkSaaS 让您在几天内轻松构建您的 AI SaaS,简单且毫不费力"
|
"description": "MkSaaS 让您在几天内轻松构建您的 AI SaaS,简单且毫不费力"
|
||||||
|
@ -113,6 +113,7 @@
|
|||||||
"next-themes": "^0.4.4",
|
"next-themes": "^0.4.4",
|
||||||
"nuqs": "^2.5.1",
|
"nuqs": "^2.5.1",
|
||||||
"postgres": "^3.4.5",
|
"postgres": "^3.4.5",
|
||||||
|
"posthog-js": "^1.261.7",
|
||||||
"radix-ui": "^1.4.2",
|
"radix-ui": "^1.4.2",
|
||||||
"react": "^19.0.0",
|
"react": "^19.0.0",
|
||||||
"react-day-picker": "8.10.1",
|
"react-day-picker": "8.10.1",
|
||||||
@ -120,6 +121,7 @@
|
|||||||
"react-hook-form": "^7.62.0",
|
"react-hook-form": "^7.62.0",
|
||||||
"react-remove-scroll": "^2.6.3",
|
"react-remove-scroll": "^2.6.3",
|
||||||
"react-resizable-panels": "^2.1.7",
|
"react-resizable-panels": "^2.1.7",
|
||||||
|
"react-social-media-embed": "^2.5.18",
|
||||||
"react-syntax-highlighter": "^15.6.3",
|
"react-syntax-highlighter": "^15.6.3",
|
||||||
"react-tweet": "^3.2.2",
|
"react-tweet": "^3.2.2",
|
||||||
"react-use-measure": "^2.1.7",
|
"react-use-measure": "^2.1.7",
|
||||||
|
172
pnpm-lock.yaml
generated
172
pnpm-lock.yaml
generated
@ -272,6 +272,9 @@ importers:
|
|||||||
postgres:
|
postgres:
|
||||||
specifier: ^3.4.5
|
specifier: ^3.4.5
|
||||||
version: 3.4.5
|
version: 3.4.5
|
||||||
|
posthog-js:
|
||||||
|
specifier: ^1.261.7
|
||||||
|
version: 1.261.7
|
||||||
radix-ui:
|
radix-ui:
|
||||||
specifier: ^1.4.2
|
specifier: ^1.4.2
|
||||||
version: 1.4.2(@types/react-dom@19.0.3(@types/react@19.0.9))(@types/react@19.0.9)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
version: 1.4.2(@types/react-dom@19.0.3(@types/react@19.0.9))(@types/react@19.0.9)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||||
@ -293,6 +296,9 @@ importers:
|
|||||||
react-resizable-panels:
|
react-resizable-panels:
|
||||||
specifier: ^2.1.7
|
specifier: ^2.1.7
|
||||||
version: 2.1.7(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
version: 2.1.7(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||||
|
react-social-media-embed:
|
||||||
|
specifier: ^2.5.18
|
||||||
|
version: 2.5.18(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||||
react-syntax-highlighter:
|
react-syntax-highlighter:
|
||||||
specifier: ^15.6.3
|
specifier: ^15.6.3
|
||||||
version: 15.6.3(react@19.0.0)
|
version: 15.6.3(react@19.0.0)
|
||||||
@ -1923,6 +1929,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
|
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
|
||||||
engines: {node: '>=14'}
|
engines: {node: '>=14'}
|
||||||
|
|
||||||
|
'@posthog/core@1.0.2':
|
||||||
|
resolution: {integrity: sha512-hWk3rUtJl2crQK0WNmwg13n82hnTwB99BT99/XI5gZSvIlYZ1TPmMZE8H2dhJJ98J/rm9vYJ/UXNzw3RV5HTpQ==}
|
||||||
|
|
||||||
'@radix-ui/number@1.1.0':
|
'@radix-ui/number@1.1.0':
|
||||||
resolution: {integrity: sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ==}
|
resolution: {integrity: sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ==}
|
||||||
|
|
||||||
@ -3676,6 +3685,9 @@ packages:
|
|||||||
'@types/unist@3.0.3':
|
'@types/unist@3.0.3':
|
||||||
resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==}
|
resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==}
|
||||||
|
|
||||||
|
'@types/youtube-player@5.5.11':
|
||||||
|
resolution: {integrity: sha512-pM41CDBqJqBmTeJWnF7NOGz82IQoYOhqzMYXv5vKCXBqGiYSLldxMtpCk6KAEtADTy49S45AriYaCaZyeUX38Q==}
|
||||||
|
|
||||||
'@typescript-eslint/project-service@8.40.0':
|
'@typescript-eslint/project-service@8.40.0':
|
||||||
resolution: {integrity: sha512-/A89vz7Wf5DEXsGVvcGdYKbVM9F7DyFXj52lNYUDS1L9yJfqjW/fIp5PgMuEJL/KeqVTe2QSbXAGUZljDUpArw==}
|
resolution: {integrity: sha512-/A89vz7Wf5DEXsGVvcGdYKbVM9F7DyFXj52lNYUDS1L9yJfqjW/fIp5PgMuEJL/KeqVTe2QSbXAGUZljDUpArw==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
@ -3939,6 +3951,9 @@ packages:
|
|||||||
class-variance-authority@0.7.1:
|
class-variance-authority@0.7.1:
|
||||||
resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==}
|
resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==}
|
||||||
|
|
||||||
|
classnames@2.5.1:
|
||||||
|
resolution: {integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==}
|
||||||
|
|
||||||
cli-cursor@3.1.0:
|
cli-cursor@3.1.0:
|
||||||
resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==}
|
resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@ -4016,6 +4031,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==}
|
resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
|
core-js@3.45.1:
|
||||||
|
resolution: {integrity: sha512-L4NPsJlCfZsPeXukyzHFlg/i7IIVwHSItR0wg0FLNqYClJ4MQYTYLbC7EkjKYRLZF2iof2MUgN0EGy7MdQFChg==}
|
||||||
|
|
||||||
cors@2.8.5:
|
cors@2.8.5:
|
||||||
resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==}
|
resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==}
|
||||||
engines: {node: '>= 0.10'}
|
engines: {node: '>= 0.10'}
|
||||||
@ -4086,6 +4104,14 @@ packages:
|
|||||||
resolution: {integrity: sha512-xRetU6gL1VJbs85Mc4FoEGSjQxzpdxRyFhe3lmWFyy2EzydIcD4xzUvRJMD+NPDfMwKNhxa3PvsIOU32luIWeA==}
|
resolution: {integrity: sha512-xRetU6gL1VJbs85Mc4FoEGSjQxzpdxRyFhe3lmWFyy2EzydIcD4xzUvRJMD+NPDfMwKNhxa3PvsIOU32luIWeA==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
|
debug@2.6.9:
|
||||||
|
resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==}
|
||||||
|
peerDependencies:
|
||||||
|
supports-color: '*'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
supports-color:
|
||||||
|
optional: true
|
||||||
|
|
||||||
debug@4.3.7:
|
debug@4.3.7:
|
||||||
resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==}
|
resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==}
|
||||||
engines: {node: '>=6.0'}
|
engines: {node: '>=6.0'}
|
||||||
@ -4486,6 +4512,9 @@ packages:
|
|||||||
picomatch:
|
picomatch:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
fflate@0.4.8:
|
||||||
|
resolution: {integrity: sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==}
|
||||||
|
|
||||||
file-entry-cache@8.0.0:
|
file-entry-cache@8.0.0:
|
||||||
resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==}
|
resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==}
|
||||||
engines: {node: '>=16.0.0'}
|
engines: {node: '>=16.0.0'}
|
||||||
@ -4983,6 +5012,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-6b6gd/RUXKaw5keVdSEtqFVdzWnU5jMxTUjA2bVcMNPLwSQ08Sv/UodBVtETLCn7k4S1Ibxwh7k68IwLZPgKaA==}
|
resolution: {integrity: sha512-6b6gd/RUXKaw5keVdSEtqFVdzWnU5jMxTUjA2bVcMNPLwSQ08Sv/UodBVtETLCn7k4S1Ibxwh7k68IwLZPgKaA==}
|
||||||
engines: {node: '>= 12.0.0'}
|
engines: {node: '>= 12.0.0'}
|
||||||
|
|
||||||
|
load-script@1.0.0:
|
||||||
|
resolution: {integrity: sha512-kPEjMFtZvwL9TaZo0uZ2ml+Ye9HUMmPwbYRJ324qF9tqMejwykJ5ggTyvzmrbBeapCAbk98BSbTeovHEEP1uCA==}
|
||||||
|
|
||||||
locate-path@6.0.0:
|
locate-path@6.0.0:
|
||||||
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
|
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@ -5269,6 +5301,9 @@ packages:
|
|||||||
react-dom:
|
react-dom:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
ms@2.0.0:
|
||||||
|
resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==}
|
||||||
|
|
||||||
ms@2.1.3:
|
ms@2.1.3:
|
||||||
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
|
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
|
||||||
|
|
||||||
@ -5604,6 +5639,20 @@ packages:
|
|||||||
resolution: {integrity: sha512-cDWgoah1Gez9rN3H4165peY9qfpEo+SA61oQv65O3cRUE1pOEoJWwddwcqKE8XZYjbblOJlYDlLV4h67HrEVDg==}
|
resolution: {integrity: sha512-cDWgoah1Gez9rN3H4165peY9qfpEo+SA61oQv65O3cRUE1pOEoJWwddwcqKE8XZYjbblOJlYDlLV4h67HrEVDg==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
posthog-js@1.261.7:
|
||||||
|
resolution: {integrity: sha512-Fjpbz6VfIMsEbKIN/UyTWhU1DGgVIngqoRjPGRolemIMOVzTfI77OZq8WwiBhMug+rU+wNhGCQhC41qRlR5CxA==}
|
||||||
|
peerDependencies:
|
||||||
|
'@rrweb/types': 2.0.0-alpha.17
|
||||||
|
rrweb-snapshot: 2.0.0-alpha.17
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@rrweb/types':
|
||||||
|
optional: true
|
||||||
|
rrweb-snapshot:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
preact@10.27.1:
|
||||||
|
resolution: {integrity: sha512-V79raXEWch/rbqoNc7nT9E4ep7lu+mI3+sBmfRD4i1M73R3WLYcCtdI0ibxGVf4eQL8ZIz2nFacqEC+rmnOORQ==}
|
||||||
|
|
||||||
prelude-ls@1.2.1:
|
prelude-ls@1.2.1:
|
||||||
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
|
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
|
||||||
engines: {node: '>= 0.8.0'}
|
engines: {node: '>= 0.8.0'}
|
||||||
@ -5698,6 +5747,12 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
react: ^16.8.0 || ^17 || ^18 || ^19
|
react: ^16.8.0 || ^17 || ^18 || ^19
|
||||||
|
|
||||||
|
react-html-props@2.1.1:
|
||||||
|
resolution: {integrity: sha512-tM+YCYlr90m3JontKUAa+gNVU2zkyprlCS7OQ9aa3z2MfyJjAioJzrSmi1Vef/+UCTE6CQlPqLX4ebdLIJDKxw==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0 || ^22.0.0
|
||||||
|
react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0 || ^22.0.0
|
||||||
|
|
||||||
react-is@16.13.1:
|
react-is@16.13.1:
|
||||||
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
|
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
|
||||||
|
|
||||||
@ -5761,6 +5816,12 @@ packages:
|
|||||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||||
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||||
|
|
||||||
|
react-social-media-embed@2.5.18:
|
||||||
|
resolution: {integrity: sha512-+PkzLRGAwnySkxKajaiK5VD+EjOhlFsh/vjNxgHsDfKBTseDpFxPrMXXQWkk6BRCwFBNVWX+V1HZ9AU0y54Wgw==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0 || ^22.0.0
|
||||||
|
react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0 || ^22.0.0
|
||||||
|
|
||||||
react-style-singleton@2.2.3:
|
react-style-singleton@2.2.3:
|
||||||
resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==}
|
resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@ -5771,6 +5832,12 @@ packages:
|
|||||||
'@types/react':
|
'@types/react':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
react-sub-unsub@2.2.8:
|
||||||
|
resolution: {integrity: sha512-o3tmiOOZPdQUCmRhkdCHXRFLOHnCwdz/N3QZ1JQ14fQGA2HysKMF0kWu56ERnQUCK7wYVCQzI8pFbnivAYNQ+A==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0 || ^22.0.0
|
||||||
|
react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0 || ^22.0.0
|
||||||
|
|
||||||
react-syntax-highlighter@15.6.3:
|
react-syntax-highlighter@15.6.3:
|
||||||
resolution: {integrity: sha512-HebdyA9r20hgmA0q8RyRJ4c/vB4E6KL2HeWb5MNjU3iJEiT2w9jfU2RJsmI6f3Cy3SGE5tm0AIkBzM/E7e9/lQ==}
|
resolution: {integrity: sha512-HebdyA9r20hgmA0q8RyRJ4c/vB4E6KL2HeWb5MNjU3iJEiT2w9jfU2RJsmI6f3Cy3SGE5tm0AIkBzM/E7e9/lQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -5788,6 +5855,13 @@ packages:
|
|||||||
react: ^18.0.0 || ^19.0.0
|
react: ^18.0.0 || ^19.0.0
|
||||||
react-dom: ^18.0.0 || ^19.0.0
|
react-dom: ^18.0.0 || ^19.0.0
|
||||||
|
|
||||||
|
react-twitter-embed@4.0.4:
|
||||||
|
resolution: {integrity: sha512-2JIL7qF+U62zRzpsh6SZDXNI3hRNVYf5vOZ1WRcMvwKouw+xC00PuFaD0aEp2wlyGaZ+f4x2VvX+uDadFQ3HVA==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^16.0.0 || ^17.0.0 || ^18.0.0
|
||||||
|
react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0
|
||||||
|
|
||||||
react-use-measure@2.1.7:
|
react-use-measure@2.1.7:
|
||||||
resolution: {integrity: sha512-KrvcAo13I/60HpwGO5jpW7E9DfusKyLPLvuHlUyP5zqnmAPhNc6qTRjUQrdTADl0lpPpDVU2/Gg51UlOGHXbdg==}
|
resolution: {integrity: sha512-KrvcAo13I/60HpwGO5jpW7E9DfusKyLPLvuHlUyP5zqnmAPhNc6qTRjUQrdTADl0lpPpDVU2/Gg51UlOGHXbdg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -5797,6 +5871,12 @@ packages:
|
|||||||
react-dom:
|
react-dom:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
react-youtube@10.1.0:
|
||||||
|
resolution: {integrity: sha512-ZfGtcVpk0SSZtWCSTYOQKhfx5/1cfyEW1JN/mugGNfAxT3rmVJeMbGpA9+e78yG21ls5nc/5uZJETE3cm3knBg==}
|
||||||
|
engines: {node: '>= 14.x'}
|
||||||
|
peerDependencies:
|
||||||
|
react: '>=0.14.1'
|
||||||
|
|
||||||
react@19.0.0:
|
react@19.0.0:
|
||||||
resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==}
|
resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@ -5908,6 +5988,9 @@ packages:
|
|||||||
scheduler@0.25.0:
|
scheduler@0.25.0:
|
||||||
resolution: {integrity: sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==}
|
resolution: {integrity: sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==}
|
||||||
|
|
||||||
|
scriptjs@2.5.9:
|
||||||
|
resolution: {integrity: sha512-qGVDoreyYiP1pkQnbnFAUIS5AjenNwwQBdl7zeos9etl+hYKWahjRTfzAZZYBv5xNHx7vNKCmaLDQZ6Fr2AEXg==}
|
||||||
|
|
||||||
scroll-into-view-if-needed@3.1.0:
|
scroll-into-view-if-needed@3.1.0:
|
||||||
resolution: {integrity: sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==}
|
resolution: {integrity: sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==}
|
||||||
|
|
||||||
@ -5970,6 +6053,9 @@ packages:
|
|||||||
simple-swizzle@0.2.2:
|
simple-swizzle@0.2.2:
|
||||||
resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
|
resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
|
||||||
|
|
||||||
|
sister@3.0.2:
|
||||||
|
resolution: {integrity: sha512-p19rtTs+NksBRKW9qn0UhZ8/TUI9BPw9lmtHny+Y3TinWlOa9jWh9xB0AtPSdmOy49NJJJSSe0Ey4C7h0TrcYA==}
|
||||||
|
|
||||||
smol-toml@1.3.4:
|
smol-toml@1.3.4:
|
||||||
resolution: {integrity: sha512-UOPtVuYkzYGee0Bd2Szz8d2G3RfMfJ2t3qVdZUAozZyAk+a0Sxa+QKix0YCwjL/A1RR0ar44nCxaoN9FxdJGwA==}
|
resolution: {integrity: sha512-UOPtVuYkzYGee0Bd2Szz8d2G3RfMfJ2t3qVdZUAozZyAk+a0Sxa+QKix0YCwjL/A1RR0ar44nCxaoN9FxdJGwA==}
|
||||||
engines: {node: '>= 18'}
|
engines: {node: '>= 18'}
|
||||||
@ -6295,6 +6381,9 @@ packages:
|
|||||||
web-namespaces@2.0.1:
|
web-namespaces@2.0.1:
|
||||||
resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==}
|
resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==}
|
||||||
|
|
||||||
|
web-vitals@4.2.4:
|
||||||
|
resolution: {integrity: sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw==}
|
||||||
|
|
||||||
which@2.0.2:
|
which@2.0.2:
|
||||||
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
|
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
|
||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
@ -6338,6 +6427,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
|
youtube-player@5.5.2:
|
||||||
|
resolution: {integrity: sha512-ZGtsemSpXnDky2AUYWgxjaopgB+shFHgXVpiJFeNB5nWEugpW1KWYDaHKuLqh2b67r24GtP6HoSW5swvf0fFIQ==}
|
||||||
|
|
||||||
zod-to-json-schema@3.24.2:
|
zod-to-json-schema@3.24.2:
|
||||||
resolution: {integrity: sha512-pNUqrcSxuuB3/+jBbU8qKUbTbDqYUaG1vf5cXFjbhGgoUuA1amO/y4Q8lzfOhHU8HNPK6VFJ18lBDKj3OHyDsg==}
|
resolution: {integrity: sha512-pNUqrcSxuuB3/+jBbU8qKUbTbDqYUaG1vf5cXFjbhGgoUuA1amO/y4Q8lzfOhHU8HNPK6VFJ18lBDKj3OHyDsg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -7530,6 +7622,8 @@ snapshots:
|
|||||||
'@pkgjs/parseargs@0.11.0':
|
'@pkgjs/parseargs@0.11.0':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@posthog/core@1.0.2': {}
|
||||||
|
|
||||||
'@radix-ui/number@1.1.0': {}
|
'@radix-ui/number@1.1.0': {}
|
||||||
|
|
||||||
'@radix-ui/number@1.1.1': {}
|
'@radix-ui/number@1.1.1': {}
|
||||||
@ -9420,6 +9514,8 @@ snapshots:
|
|||||||
|
|
||||||
'@types/unist@3.0.3': {}
|
'@types/unist@3.0.3': {}
|
||||||
|
|
||||||
|
'@types/youtube-player@5.5.11': {}
|
||||||
|
|
||||||
'@typescript-eslint/project-service@8.40.0(typescript@5.8.3)':
|
'@typescript-eslint/project-service@8.40.0(typescript@5.8.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/tsconfig-utils': 8.40.0(typescript@5.8.3)
|
'@typescript-eslint/tsconfig-utils': 8.40.0(typescript@5.8.3)
|
||||||
@ -9675,6 +9771,8 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
clsx: 2.1.1
|
clsx: 2.1.1
|
||||||
|
|
||||||
|
classnames@2.5.1: {}
|
||||||
|
|
||||||
cli-cursor@3.1.0:
|
cli-cursor@3.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
restore-cursor: 3.1.0
|
restore-cursor: 3.1.0
|
||||||
@ -9741,6 +9839,8 @@ snapshots:
|
|||||||
|
|
||||||
cookie@1.0.2: {}
|
cookie@1.0.2: {}
|
||||||
|
|
||||||
|
core-js@3.45.1: {}
|
||||||
|
|
||||||
cors@2.8.5:
|
cors@2.8.5:
|
||||||
dependencies:
|
dependencies:
|
||||||
object-assign: 4.1.1
|
object-assign: 4.1.1
|
||||||
@ -9800,6 +9900,10 @@ snapshots:
|
|||||||
|
|
||||||
debounce@2.0.0: {}
|
debounce@2.0.0: {}
|
||||||
|
|
||||||
|
debug@2.6.9:
|
||||||
|
dependencies:
|
||||||
|
ms: 2.0.0
|
||||||
|
|
||||||
debug@4.3.7:
|
debug@4.3.7:
|
||||||
dependencies:
|
dependencies:
|
||||||
ms: 2.1.3
|
ms: 2.1.3
|
||||||
@ -10264,6 +10368,8 @@ snapshots:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
picomatch: 4.0.2
|
picomatch: 4.0.2
|
||||||
|
|
||||||
|
fflate@0.4.8: {}
|
||||||
|
|
||||||
file-entry-cache@8.0.0:
|
file-entry-cache@8.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
flat-cache: 4.0.1
|
flat-cache: 4.0.1
|
||||||
@ -10813,6 +10919,8 @@ snapshots:
|
|||||||
lightningcss-win32-arm64-msvc: 1.29.2
|
lightningcss-win32-arm64-msvc: 1.29.2
|
||||||
lightningcss-win32-x64-msvc: 1.29.2
|
lightningcss-win32-x64-msvc: 1.29.2
|
||||||
|
|
||||||
|
load-script@1.0.0: {}
|
||||||
|
|
||||||
locate-path@6.0.0:
|
locate-path@6.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
p-locate: 5.0.0
|
p-locate: 5.0.0
|
||||||
@ -11362,6 +11470,8 @@ snapshots:
|
|||||||
react: 19.0.0
|
react: 19.0.0
|
||||||
react-dom: 19.0.0(react@19.0.0)
|
react-dom: 19.0.0(react@19.0.0)
|
||||||
|
|
||||||
|
ms@2.0.0: {}
|
||||||
|
|
||||||
ms@2.1.3: {}
|
ms@2.1.3: {}
|
||||||
|
|
||||||
nan@2.22.0:
|
nan@2.22.0:
|
||||||
@ -11709,6 +11819,16 @@ snapshots:
|
|||||||
|
|
||||||
postgres@3.4.5: {}
|
postgres@3.4.5: {}
|
||||||
|
|
||||||
|
posthog-js@1.261.7:
|
||||||
|
dependencies:
|
||||||
|
'@posthog/core': 1.0.2
|
||||||
|
core-js: 3.45.1
|
||||||
|
fflate: 0.4.8
|
||||||
|
preact: 10.27.1
|
||||||
|
web-vitals: 4.2.4
|
||||||
|
|
||||||
|
preact@10.27.1: {}
|
||||||
|
|
||||||
prelude-ls@1.2.1: {}
|
prelude-ls@1.2.1: {}
|
||||||
|
|
||||||
prettier@3.4.2: {}
|
prettier@3.4.2: {}
|
||||||
@ -11859,6 +11979,11 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
react: 19.0.0
|
react: 19.0.0
|
||||||
|
|
||||||
|
react-html-props@2.1.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
|
||||||
|
dependencies:
|
||||||
|
react: 19.0.0
|
||||||
|
react-dom: 19.0.0(react@19.0.0)
|
||||||
|
|
||||||
react-is@16.13.1: {}
|
react-is@16.13.1: {}
|
||||||
|
|
||||||
react-is@18.3.1: {}
|
react-is@18.3.1: {}
|
||||||
@ -11933,6 +12058,19 @@ snapshots:
|
|||||||
react-dom: 19.0.0(react@19.0.0)
|
react-dom: 19.0.0(react@19.0.0)
|
||||||
react-transition-group: 4.4.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
react-transition-group: 4.4.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||||
|
|
||||||
|
react-social-media-embed@2.5.18(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
|
||||||
|
dependencies:
|
||||||
|
'@types/youtube-player': 5.5.11
|
||||||
|
classnames: 2.5.1
|
||||||
|
react: 19.0.0
|
||||||
|
react-dom: 19.0.0(react@19.0.0)
|
||||||
|
react-html-props: 2.1.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||||
|
react-sub-unsub: 2.2.8(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||||
|
react-twitter-embed: 4.0.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||||
|
react-youtube: 10.1.0(react@19.0.0)
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
react-style-singleton@2.2.3(@types/react@19.0.9)(react@19.0.0):
|
react-style-singleton@2.2.3(@types/react@19.0.9)(react@19.0.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
get-nonce: 1.0.1
|
get-nonce: 1.0.1
|
||||||
@ -11941,6 +12079,11 @@ snapshots:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/react': 19.0.9
|
'@types/react': 19.0.9
|
||||||
|
|
||||||
|
react-sub-unsub@2.2.8(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
|
||||||
|
dependencies:
|
||||||
|
react: 19.0.0
|
||||||
|
react-dom: 19.0.0(react@19.0.0)
|
||||||
|
|
||||||
react-syntax-highlighter@15.6.3(react@19.0.0):
|
react-syntax-highlighter@15.6.3(react@19.0.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/runtime': 7.27.6
|
'@babel/runtime': 7.27.6
|
||||||
@ -11968,12 +12111,27 @@ snapshots:
|
|||||||
react-dom: 19.0.0(react@19.0.0)
|
react-dom: 19.0.0(react@19.0.0)
|
||||||
swr: 2.3.2(react@19.0.0)
|
swr: 2.3.2(react@19.0.0)
|
||||||
|
|
||||||
|
react-twitter-embed@4.0.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
|
||||||
|
dependencies:
|
||||||
|
react: 19.0.0
|
||||||
|
react-dom: 19.0.0(react@19.0.0)
|
||||||
|
scriptjs: 2.5.9
|
||||||
|
|
||||||
react-use-measure@2.1.7(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
|
react-use-measure@2.1.7(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
react: 19.0.0
|
react: 19.0.0
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
react-dom: 19.0.0(react@19.0.0)
|
react-dom: 19.0.0(react@19.0.0)
|
||||||
|
|
||||||
|
react-youtube@10.1.0(react@19.0.0):
|
||||||
|
dependencies:
|
||||||
|
fast-deep-equal: 3.1.3
|
||||||
|
prop-types: 15.8.1
|
||||||
|
react: 19.0.0
|
||||||
|
youtube-player: 5.5.2
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
react@19.0.0: {}
|
react@19.0.0: {}
|
||||||
|
|
||||||
readable-stream@3.6.2:
|
readable-stream@3.6.2:
|
||||||
@ -12156,6 +12314,8 @@ snapshots:
|
|||||||
|
|
||||||
scheduler@0.25.0: {}
|
scheduler@0.25.0: {}
|
||||||
|
|
||||||
|
scriptjs@2.5.9: {}
|
||||||
|
|
||||||
scroll-into-view-if-needed@3.1.0:
|
scroll-into-view-if-needed@3.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
compute-scroll-into-view: 3.1.1
|
compute-scroll-into-view: 3.1.1
|
||||||
@ -12271,6 +12431,8 @@ snapshots:
|
|||||||
is-arrayish: 0.3.2
|
is-arrayish: 0.3.2
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
sister@3.0.2: {}
|
||||||
|
|
||||||
smol-toml@1.3.4: {}
|
smol-toml@1.3.4: {}
|
||||||
|
|
||||||
socket.io-adapter@2.5.5:
|
socket.io-adapter@2.5.5:
|
||||||
@ -12627,6 +12789,8 @@ snapshots:
|
|||||||
|
|
||||||
web-namespaces@2.0.1: {}
|
web-namespaces@2.0.1: {}
|
||||||
|
|
||||||
|
web-vitals@4.2.4: {}
|
||||||
|
|
||||||
which@2.0.2:
|
which@2.0.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
isexe: 2.0.0
|
isexe: 2.0.0
|
||||||
@ -12655,6 +12819,14 @@ snapshots:
|
|||||||
|
|
||||||
yocto-queue@0.1.0: {}
|
yocto-queue@0.1.0: {}
|
||||||
|
|
||||||
|
youtube-player@5.5.2:
|
||||||
|
dependencies:
|
||||||
|
debug: 2.6.9
|
||||||
|
load-script: 1.0.0
|
||||||
|
sister: 3.0.2
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
zod-to-json-schema@3.24.2(zod@3.25.64):
|
zod-to-json-schema@3.24.2(zod@3.25.64):
|
||||||
dependencies:
|
dependencies:
|
||||||
zod: 3.25.64
|
zod: 3.25.64
|
||||||
|
122
src/ai/image/components/ImageGeneratorByProvider.tsx
Normal file
122
src/ai/image/components/ImageGeneratorByProvider.tsx
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { useState } from 'react';
|
||||||
|
import { useImageGeneration } from '../hooks/use-image-generation';
|
||||||
|
import {
|
||||||
|
MODEL_CONFIGS,
|
||||||
|
type ModelMode,
|
||||||
|
PROVIDERS,
|
||||||
|
type ProviderKey,
|
||||||
|
} from '../lib/provider-config';
|
||||||
|
import type { Suggestion } from '../lib/suggestions';
|
||||||
|
import { ImageGeneratorHeader } from './ImageGeneratorHeader';
|
||||||
|
import { ModelCardCarousel } from './ModelCardCarousel';
|
||||||
|
import { PromptInput } from './PromptInput';
|
||||||
|
|
||||||
|
export function ImageImageGeneratorByProvider({
|
||||||
|
suggestions,
|
||||||
|
providerKey,
|
||||||
|
}: {
|
||||||
|
suggestions: Suggestion[];
|
||||||
|
providerKey: ProviderKey;
|
||||||
|
}) {
|
||||||
|
const {
|
||||||
|
images,
|
||||||
|
timings,
|
||||||
|
failedProviders,
|
||||||
|
isLoading,
|
||||||
|
startGeneration,
|
||||||
|
activePrompt,
|
||||||
|
} = useImageGeneration();
|
||||||
|
|
||||||
|
const [showProviders, setShowProviders] = useState(true);
|
||||||
|
const [selectedModels, setSelectedModels] = useState<
|
||||||
|
Record<ProviderKey, string>
|
||||||
|
>(MODEL_CONFIGS.performance);
|
||||||
|
const [mode, setMode] = useState<ModelMode>('performance');
|
||||||
|
const toggleView = () => {
|
||||||
|
setShowProviders((prev) => !prev);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleModeChange = (newMode: ModelMode) => {
|
||||||
|
setMode(newMode);
|
||||||
|
setSelectedModels(MODEL_CONFIGS[newMode]);
|
||||||
|
setShowProviders(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleModelChange = (providerKey: ProviderKey, model: string) => {
|
||||||
|
setSelectedModels((prev) => ({ ...prev, [providerKey]: model }));
|
||||||
|
};
|
||||||
|
|
||||||
|
// Only map the active provider to its selected model
|
||||||
|
const providerToModel = {
|
||||||
|
[providerKey]: selectedModels[providerKey],
|
||||||
|
} as Record<ProviderKey, string>;
|
||||||
|
|
||||||
|
const handlePromptSubmit = (newPrompt: string) => {
|
||||||
|
const activeProviders: ProviderKey[] = [providerKey];
|
||||||
|
startGeneration(newPrompt, activeProviders, providerToModel);
|
||||||
|
setShowProviders(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="rounded-lg bg-background py-8 px-4 sm:px-6 lg:px-8">
|
||||||
|
<div className="mx-auto">
|
||||||
|
{/* header */}
|
||||||
|
<ImageGeneratorHeader />
|
||||||
|
|
||||||
|
{/* input prompt */}
|
||||||
|
<PromptInput
|
||||||
|
onSubmit={handlePromptSubmit}
|
||||||
|
isLoading={isLoading}
|
||||||
|
showProviders={showProviders}
|
||||||
|
onToggleProviders={toggleView}
|
||||||
|
mode={mode}
|
||||||
|
onModeChange={handleModeChange}
|
||||||
|
suggestions={suggestions}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* models carousel */}
|
||||||
|
{(() => {
|
||||||
|
const key = providerKey;
|
||||||
|
const provider = PROVIDERS[key];
|
||||||
|
if (!provider) return null;
|
||||||
|
|
||||||
|
const imageItem = images.find((img) => img.provider === key);
|
||||||
|
const imageData = imageItem?.image;
|
||||||
|
const modelId = imageItem?.modelId ?? selectedModels[key] ?? '';
|
||||||
|
const timing = timings[key];
|
||||||
|
|
||||||
|
const modelProps = {
|
||||||
|
label: provider.displayName,
|
||||||
|
models: provider.models,
|
||||||
|
value: selectedModels[key],
|
||||||
|
providerKey: key,
|
||||||
|
onChange: (model: string, pKey: ProviderKey) =>
|
||||||
|
handleModelChange(pKey, model),
|
||||||
|
iconPath: provider.iconPath,
|
||||||
|
color: provider.color,
|
||||||
|
enabled: true,
|
||||||
|
image: imageData,
|
||||||
|
modelId,
|
||||||
|
timing,
|
||||||
|
failed: failedProviders.includes(key),
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div>
|
||||||
|
<ModelCardCarousel models={[modelProps]} />
|
||||||
|
</div>
|
||||||
|
{activePrompt && activePrompt.length > 0 && (
|
||||||
|
<div className="text-center mt-8 text-muted-foreground">
|
||||||
|
{activePrompt}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
})()}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -78,7 +78,7 @@ export function ImagePlayground({
|
|||||||
<div className="rounded-lg bg-background py-8 px-4 sm:px-6 lg:px-8">
|
<div className="rounded-lg bg-background py-8 px-4 sm:px-6 lg:px-8">
|
||||||
<div className="mx-auto">
|
<div className="mx-auto">
|
||||||
{/* header */}
|
{/* header */}
|
||||||
{/* <ImageGeneratorHeader /> */}
|
<ImageGeneratorHeader />
|
||||||
|
|
||||||
{/* input prompt */}
|
{/* input prompt */}
|
||||||
<PromptInput
|
<PromptInput
|
||||||
|
@ -11,53 +11,53 @@ export const PROVIDERS: Record<
|
|||||||
}
|
}
|
||||||
> = {
|
> = {
|
||||||
// https://ai-sdk.dev/providers/ai-sdk-providers/replicate#image-models
|
// https://ai-sdk.dev/providers/ai-sdk-providers/replicate#image-models
|
||||||
replicate: {
|
// replicate: {
|
||||||
displayName: 'Replicate',
|
// displayName: 'Replicate',
|
||||||
iconPath: '/provider-icons/replicate.svg',
|
// iconPath: '/provider-icons/replicate.svg',
|
||||||
color: 'from-purple-500 to-blue-500',
|
// color: 'from-purple-500 to-blue-500',
|
||||||
models: [
|
// models: [
|
||||||
'black-forest-labs/flux-1.1-pro',
|
// 'black-forest-labs/flux-1.1-pro',
|
||||||
'black-forest-labs/flux-1.1-pro-ultra',
|
// 'black-forest-labs/flux-1.1-pro-ultra',
|
||||||
'black-forest-labs/flux-dev',
|
// 'black-forest-labs/flux-dev',
|
||||||
'black-forest-labs/flux-pro',
|
// 'black-forest-labs/flux-pro',
|
||||||
'black-forest-labs/flux-schnell',
|
// 'black-forest-labs/flux-schnell',
|
||||||
'ideogram-ai/ideogram-v2',
|
// 'ideogram-ai/ideogram-v2',
|
||||||
'ideogram-ai/ideogram-v2-turbo',
|
// 'ideogram-ai/ideogram-v2-turbo',
|
||||||
'luma/photon',
|
// 'luma/photon',
|
||||||
'luma/photon-flash',
|
// 'luma/photon-flash',
|
||||||
'recraft-ai/recraft-v3',
|
// 'recraft-ai/recraft-v3',
|
||||||
// 'recraft-ai/recraft-v3-svg', // added by Fox
|
// // 'recraft-ai/recraft-v3-svg', // added by Fox
|
||||||
// 'stability-ai/stable-diffusion-3.5-medium', // added by Fox
|
// // 'stability-ai/stable-diffusion-3.5-medium', // added by Fox
|
||||||
'stability-ai/stable-diffusion-3.5-large',
|
// 'stability-ai/stable-diffusion-3.5-large',
|
||||||
'stability-ai/stable-diffusion-3.5-large-turbo',
|
// 'stability-ai/stable-diffusion-3.5-large-turbo',
|
||||||
],
|
// ],
|
||||||
},
|
// },
|
||||||
// https://ai-sdk.dev/providers/ai-sdk-providers/openai#image-models
|
// https://ai-sdk.dev/providers/ai-sdk-providers/openai#image-models
|
||||||
openai: {
|
// openai: {
|
||||||
displayName: 'OpenAI',
|
// displayName: 'OpenAI',
|
||||||
iconPath: '/provider-icons/openai.svg',
|
// iconPath: '/provider-icons/openai.svg',
|
||||||
color: 'from-blue-500 to-cyan-500',
|
// color: 'from-blue-500 to-cyan-500',
|
||||||
models: [
|
// models: [
|
||||||
// 'gpt-image-1', // added by Fox
|
// // 'gpt-image-1', // added by Fox
|
||||||
'dall-e-2',
|
// 'dall-e-2',
|
||||||
'dall-e-3',
|
// 'dall-e-3',
|
||||||
],
|
// ],
|
||||||
},
|
// },
|
||||||
// https://ai-sdk.dev/providers/ai-sdk-providers/fireworks#image-models
|
// https://ai-sdk.dev/providers/ai-sdk-providers/fireworks#image-models
|
||||||
fireworks: {
|
// fireworks: {
|
||||||
displayName: 'Fireworks',
|
// displayName: 'Fireworks',
|
||||||
iconPath: '/provider-icons/fireworks.svg',
|
// iconPath: '/provider-icons/fireworks.svg',
|
||||||
color: 'from-orange-500 to-red-500',
|
// color: 'from-orange-500 to-red-500',
|
||||||
models: [
|
// models: [
|
||||||
'accounts/fireworks/models/flux-1-dev-fp8',
|
// 'accounts/fireworks/models/flux-1-dev-fp8',
|
||||||
'accounts/fireworks/models/flux-1-schnell-fp8',
|
// 'accounts/fireworks/models/flux-1-schnell-fp8',
|
||||||
'accounts/fireworks/models/playground-v2-5-1024px-aesthetic',
|
// 'accounts/fireworks/models/playground-v2-5-1024px-aesthetic',
|
||||||
'accounts/fireworks/models/japanese-stable-diffusion-xl',
|
// 'accounts/fireworks/models/japanese-stable-diffusion-xl',
|
||||||
'accounts/fireworks/models/playground-v2-1024px-aesthetic',
|
// 'accounts/fireworks/models/playground-v2-1024px-aesthetic',
|
||||||
'accounts/fireworks/models/SSD-1B',
|
// 'accounts/fireworks/models/SSD-1B',
|
||||||
'accounts/fireworks/models/stable-diffusion-xl-1024-v1-0',
|
// 'accounts/fireworks/models/stable-diffusion-xl-1024-v1-0',
|
||||||
],
|
// ],
|
||||||
},
|
// },
|
||||||
// https://ai-sdk.dev/providers/ai-sdk-providers/fal#image-models
|
// https://ai-sdk.dev/providers/ai-sdk-providers/fal#image-models
|
||||||
fal: {
|
fal: {
|
||||||
displayName: 'Fal',
|
displayName: 'Fal',
|
||||||
|
35
src/analytics/posthog-analytics.tsx
Normal file
35
src/analytics/posthog-analytics.tsx
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import posthog from 'posthog-js';
|
||||||
|
import { PostHogProvider as PHProvider } from 'posthog-js/react';
|
||||||
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PostHog Analytics
|
||||||
|
*
|
||||||
|
* https://posthog.com
|
||||||
|
* https://posthog.com/docs/libraries/next-js?tab=PostHog+provider
|
||||||
|
* https://mksaas.com/docs/analytics#posthog
|
||||||
|
*/
|
||||||
|
export function PostHogProvider({ children }: { children: React.ReactNode }) {
|
||||||
|
const posthogKey = process.env.NEXT_PUBLIC_POSTHOG_KEY;
|
||||||
|
const posthogHost = process.env.NEXT_PUBLIC_POSTHOG_HOST;
|
||||||
|
const isProduction = process.env.NODE_ENV === 'production';
|
||||||
|
const isPostHogEnabled = posthogKey && posthogHost && isProduction;
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isPostHogEnabled) {
|
||||||
|
posthog.init(posthogKey, {
|
||||||
|
api_host: posthogHost,
|
||||||
|
defaults: '2025-05-24',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [isPostHogEnabled, posthogKey, posthogHost]);
|
||||||
|
|
||||||
|
// If PostHog is not enabled, just return children without the provider
|
||||||
|
if (!isPostHogEnabled) {
|
||||||
|
return <>{children}</>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return <PHProvider client={posthog}>{children}</PHProvider>;
|
||||||
|
}
|
49
src/app/[locale]/(marketing)/ai/images/page.tsx
Normal file
49
src/app/[locale]/(marketing)/ai/images/page.tsx
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import { ImageGenerator } from '@/ai/image/components/ImageGenerator';
|
||||||
|
import { ImageImageGeneratorByProvider } from '@/ai/image/components/ImageGeneratorByProvider';
|
||||||
|
import { ImagePlayground } from '@/ai/image/components/ImagePlayground';
|
||||||
|
import { getRandomSuggestions } from '@/ai/image/lib/suggestions';
|
||||||
|
import { constructMetadata } from '@/lib/metadata';
|
||||||
|
import { getUrlWithLocale } from '@/lib/urls/urls';
|
||||||
|
import { ImageIcon } from 'lucide-react';
|
||||||
|
import type { Metadata } from 'next';
|
||||||
|
import type { Locale } from 'next-intl';
|
||||||
|
import { getTranslations } from 'next-intl/server';
|
||||||
|
|
||||||
|
export async function generateMetadata({
|
||||||
|
params,
|
||||||
|
}: {
|
||||||
|
params: Promise<{ locale: Locale }>;
|
||||||
|
}): Promise<Metadata | undefined> {
|
||||||
|
const { locale } = await params;
|
||||||
|
const t = await getTranslations({ locale, namespace: 'Metadata' });
|
||||||
|
const pt = await getTranslations({ locale, namespace: 'AIImagePage' });
|
||||||
|
|
||||||
|
return constructMetadata({
|
||||||
|
title: pt('title') + ' | ' + t('title'),
|
||||||
|
description: pt('description'),
|
||||||
|
canonicalUrl: getUrlWithLocale('/ai/image', locale),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export default async function AIImagesPage() {
|
||||||
|
const t = await getTranslations('AIImagesPage');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="min-h-screen bg-muted/50 rounded-lg">
|
||||||
|
<div className="container mx-auto px-4 py-8 md:py-16">
|
||||||
|
{/* Header Section */}
|
||||||
|
<div className="text-center space-y-6 mb-12">
|
||||||
|
<div className="inline-flex items-center gap-2 px-4 py-2 rounded-full bg-primary/10 text-primary text-sm font-medium">
|
||||||
|
<ImageIcon className="size-4" />
|
||||||
|
{t('title')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Image Playground Component */}
|
||||||
|
<div className="max-w-6xl mx-auto">
|
||||||
|
<ImageImageGeneratorByProvider suggestions={getRandomSuggestions(5)} providerKey='fal' />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
|
import { PostHogProvider } from '@/analytics/posthog-analytics';
|
||||||
import { ActiveThemeProvider } from '@/components/layout/active-theme-provider';
|
import { ActiveThemeProvider } from '@/components/layout/active-theme-provider';
|
||||||
import { QueryProvider } from '@/components/providers/query-provider';
|
import { QueryProvider } from '@/components/providers/query-provider';
|
||||||
import { TooltipProvider } from '@/components/ui/tooltip';
|
import { TooltipProvider } from '@/components/ui/tooltip';
|
||||||
@ -20,12 +21,12 @@ interface ProvidersProps {
|
|||||||
*
|
*
|
||||||
* This component is used to wrap the app in the providers.
|
* This component is used to wrap the app in the providers.
|
||||||
*
|
*
|
||||||
|
* - PostHogProvider: Provides the PostHog analytics to the app.
|
||||||
|
* - QueryProvider: Provides the query client to the app.
|
||||||
* - ThemeProvider: Provides the theme to the app.
|
* - ThemeProvider: Provides the theme to the app.
|
||||||
* - ActiveThemeProvider: Provides the active theme to the app.
|
* - ActiveThemeProvider: Provides the active theme to the app.
|
||||||
* - RootProvider: Provides the root provider for Fumadocs UI.
|
* - RootProvider: Provides the root provider for Fumadocs UI.
|
||||||
* - TooltipProvider: Provides the tooltip to the app.
|
* - TooltipProvider: Provides the tooltip to the app.
|
||||||
* - PaymentProvider: Provides the payment state to the app.
|
|
||||||
* - CreditsProvider: Provides the credits state to the app.
|
|
||||||
*/
|
*/
|
||||||
export function Providers({ children, locale }: ProvidersProps) {
|
export function Providers({ children, locale }: ProvidersProps) {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
@ -53,19 +54,24 @@ export function Providers({ children, locale }: ProvidersProps) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<QueryProvider>
|
<PostHogProvider>
|
||||||
<ThemeProvider
|
<QueryProvider>
|
||||||
attribute="class"
|
<ThemeProvider
|
||||||
defaultTheme={defaultMode}
|
attribute="class"
|
||||||
enableSystem={true}
|
defaultTheme={defaultMode}
|
||||||
disableTransitionOnChange
|
enableSystem={true}
|
||||||
>
|
disableTransitionOnChange
|
||||||
<ActiveThemeProvider>
|
>
|
||||||
<RootProvider theme={theme} i18n={{ locale, locales, translations }}>
|
<ActiveThemeProvider>
|
||||||
<TooltipProvider>{children}</TooltipProvider>
|
<RootProvider
|
||||||
</RootProvider>
|
theme={theme}
|
||||||
</ActiveThemeProvider>
|
i18n={{ locale, locales, translations }}
|
||||||
</ThemeProvider>
|
>
|
||||||
</QueryProvider>
|
<TooltipProvider>{children}</TooltipProvider>
|
||||||
|
</RootProvider>
|
||||||
|
</ActiveThemeProvider>
|
||||||
|
</ThemeProvider>
|
||||||
|
</QueryProvider>
|
||||||
|
</PostHogProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import defaultMdxComponents from 'fumadocs-ui/mdx';
|
|||||||
import * as LucideIcons from 'lucide-react';
|
import * as LucideIcons from 'lucide-react';
|
||||||
import type { MDXComponents } from 'mdx/types';
|
import type { MDXComponents } from 'mdx/types';
|
||||||
import type { ComponentProps, FC } from 'react';
|
import type { ComponentProps, FC } from 'react';
|
||||||
|
import { XEmbedClient } from './xembed';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enhanced MDX Content component that includes commonly used MDX components
|
* Enhanced MDX Content component that includes commonly used MDX components
|
||||||
@ -23,6 +24,7 @@ export function getMDXComponents(components?: MDXComponents): MDXComponents {
|
|||||||
...defaultMdxComponents,
|
...defaultMdxComponents,
|
||||||
...LucideIcons,
|
...LucideIcons,
|
||||||
// ...((await import('lucide-react')) as unknown as MDXComponents),
|
// ...((await import('lucide-react')) as unknown as MDXComponents),
|
||||||
|
XEmbedClient,
|
||||||
YoutubeVideo,
|
YoutubeVideo,
|
||||||
PremiumContent,
|
PremiumContent,
|
||||||
Tabs,
|
Tabs,
|
||||||
|
16
src/components/docs/xembed.tsx
Normal file
16
src/components/docs/xembed.tsx
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { XEmbed, type XEmbedProps } from 'react-social-media-embed';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Embedding X Posts in Fumadocs
|
||||||
|
*
|
||||||
|
* https://rjv.im/blog/solution/embed-x-post-in-fuma-docs
|
||||||
|
*/
|
||||||
|
export function XEmbedClient({ ...props }: XEmbedProps) {
|
||||||
|
return (
|
||||||
|
<div className="flex justify-center">
|
||||||
|
<XEmbed {...props} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -103,6 +103,13 @@ export function useNavbarLinks(): NestedMenuItem[] {
|
|||||||
href: Routes.AIChat,
|
href: Routes.AIChat,
|
||||||
external: false,
|
external: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: t('ai.items.images.title'),
|
||||||
|
description: t('ai.items.images.description'),
|
||||||
|
icon: <ImageIcon className="size-4 shrink-0" />,
|
||||||
|
href: Routes.AIImages,
|
||||||
|
external: false,
|
||||||
|
}
|
||||||
// {
|
// {
|
||||||
// title: t('ai.items.video.title'),
|
// title: t('ai.items.video.title'),
|
||||||
// description: t('ai.items.video.description'),
|
// description: t('ai.items.video.description'),
|
||||||
|
@ -52,7 +52,7 @@ export const websiteConfig: WebsiteConfig = {
|
|||||||
},
|
},
|
||||||
auth: {
|
auth: {
|
||||||
enableGoogleLogin: true,
|
enableGoogleLogin: true,
|
||||||
enableGithubLogin: true,
|
enableGithubLogin: false,
|
||||||
enableCredentialLogin: true,
|
enableCredentialLogin: true,
|
||||||
},
|
},
|
||||||
i18n: {
|
i18n: {
|
||||||
@ -155,7 +155,7 @@ export const websiteConfig: WebsiteConfig = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
credits: {
|
credits: {
|
||||||
enableCredits: process.env.NEXT_PUBLIC_DEMO_WEBSITE === 'true',
|
enableCredits: process.env.NEXT_PUBLIC_DEMO_WEBSITE != 'true',
|
||||||
enablePackagesForFreePlan: false,
|
enablePackagesForFreePlan: false,
|
||||||
registerGiftCredits: {
|
registerGiftCredits: {
|
||||||
enable: true,
|
enable: true,
|
||||||
|
@ -84,10 +84,13 @@ export class StripeProvider implements PaymentProvider {
|
|||||||
|
|
||||||
// Find user id by customer id
|
// Find user id by customer id
|
||||||
const userId = await this.findUserIdByCustomerId(customerId);
|
const userId = await this.findUserIdByCustomerId(customerId);
|
||||||
// user does not exist, update user with customer id
|
// If no userId found, it means the user record exists (by email) but lacks customerId
|
||||||
// in case you deleted user in database, but forgot to delete customer in Stripe
|
// This can happen when user was created before Stripe integration or data got out of sync
|
||||||
|
// Fix the data inconsistency by updating the user's customerId field
|
||||||
if (!userId) {
|
if (!userId) {
|
||||||
console.log('User does not exist, update with customer id (hidden)');
|
console.log(
|
||||||
|
'User exists but missing customerId, fixing data inconsistency'
|
||||||
|
);
|
||||||
await this.updateUserWithCustomerId(customerId, email);
|
await this.updateUserWithCustomerId(customerId, email);
|
||||||
}
|
}
|
||||||
return customerId;
|
return customerId;
|
||||||
|
@ -40,6 +40,7 @@ export enum Routes {
|
|||||||
// AI routes
|
// AI routes
|
||||||
AIText = '/ai/text',
|
AIText = '/ai/text',
|
||||||
AIImage = '/ai/image',
|
AIImage = '/ai/image',
|
||||||
|
AIImages = '/ai/images',
|
||||||
AIChat = '/ai/chat',
|
AIChat = '/ai/chat',
|
||||||
AIVideo = '/ai/video',
|
AIVideo = '/ai/video',
|
||||||
AIAudio = '/ai/audio',
|
AIAudio = '/ai/audio',
|
||||||
|
Loading…
Reference in New Issue
Block a user