fix(pitch-deck): version-aware financial model + layout fix + COMPLAI spelling
All checks were successful
Build pitch-deck / build-push-deploy (push) Successful in 1m2s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-consent (push) Successful in 26s
CI / test-python-voice (push) Successful in 25s
CI / test-bqas (push) Successful in 26s
All checks were successful
Build pitch-deck / build-push-deploy (push) Successful in 1m2s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-consent (push) Successful in 26s
CI / test-python-voice (push) Successful in 25s
CI / test-bqas (push) Successful in 26s
Critical fix: All financial slides now use the version's preferred scenario instead of always defaulting to Base Case (1M). This ensures the Wandeldarlehen version shows its own lean financial plan. - useFinancialModel: add preferredScenarioId parameter - PitchDeck: extract default scenario from previewData.fm_scenarios - Pass preferredScenarioId to all 5 financial slides - FinancialsSlide layout: remove empty right column, full-width charts - Remove ScenarioSwitcher + unused slider from FinancialsSlide - Fix COMPLEI → COMPLAI in presenter script (only TTS pronunciation differs) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -69,6 +69,15 @@ export default function PitchDeck({ lang, onToggleLanguage, investor, onLogout,
|
|||||||
const [fabOpen, setFabOpen] = useState(false)
|
const [fabOpen, setFabOpen] = useState(false)
|
||||||
const isWandeldarlehen = (data?.funding?.instrument || '').toLowerCase().includes('wandeldarlehen')
|
const isWandeldarlehen = (data?.funding?.instrument || '').toLowerCase().includes('wandeldarlehen')
|
||||||
|
|
||||||
|
// For version previews: use the version's default FM scenario instead of base table default
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
const fmScenarios = (previewData as any)?.fm_scenarios as Array<{ id: string; is_default?: boolean }> | undefined
|
||||||
|
const preferredScenarioId = fmScenarios?.[0]?.is_default
|
||||||
|
? fmScenarios[0].id
|
||||||
|
: fmScenarios?.length === 1
|
||||||
|
? fmScenarios[0].id
|
||||||
|
: null
|
||||||
|
|
||||||
// Skip cap-table slide for Wandeldarlehen versions
|
// Skip cap-table slide for Wandeldarlehen versions
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (nav.currentSlide === 'cap-table' && isWandeldarlehen) {
|
if (nav.currentSlide === 'cap-table' && isWandeldarlehen) {
|
||||||
@@ -151,7 +160,7 @@ export default function PitchDeck({ lang, onToggleLanguage, investor, onLogout,
|
|||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
case 'executive-summary':
|
case 'executive-summary':
|
||||||
return <ExecutiveSummarySlide lang={lang} data={data} investorId={investor?.id || null} />
|
return <ExecutiveSummarySlide lang={lang} data={data} investorId={investor?.id || null} preferredScenarioId={preferredScenarioId} />
|
||||||
case 'cover':
|
case 'cover':
|
||||||
return <CoverSlide lang={lang} onNext={nav.nextSlide} funding={data.funding} />
|
return <CoverSlide lang={lang} onNext={nav.nextSlide} funding={data.funding} />
|
||||||
case 'problem':
|
case 'problem':
|
||||||
@@ -169,7 +178,7 @@ export default function PitchDeck({ lang, onToggleLanguage, investor, onLogout,
|
|||||||
case 'market':
|
case 'market':
|
||||||
return <MarketSlide lang={lang} market={data.market} />
|
return <MarketSlide lang={lang} market={data.market} />
|
||||||
case 'business-model':
|
case 'business-model':
|
||||||
return <BusinessModelSlide lang={lang} products={data.products} investorId={investor?.id || null} />
|
return <BusinessModelSlide lang={lang} products={data.products} investorId={investor?.id || null} preferredScenarioId={preferredScenarioId} />
|
||||||
case 'traction':
|
case 'traction':
|
||||||
return <TractionSlide lang={lang} milestones={data.milestones} metrics={data.metrics} />
|
return <TractionSlide lang={lang} milestones={data.milestones} metrics={data.metrics} />
|
||||||
case 'competition':
|
case 'competition':
|
||||||
@@ -177,7 +186,7 @@ export default function PitchDeck({ lang, onToggleLanguage, investor, onLogout,
|
|||||||
case 'team':
|
case 'team':
|
||||||
return <TeamSlide lang={lang} team={data.team} />
|
return <TeamSlide lang={lang} team={data.team} />
|
||||||
case 'financials':
|
case 'financials':
|
||||||
return <FinancialsSlide lang={lang} investorId={investor?.id || null} />
|
return <FinancialsSlide lang={lang} investorId={investor?.id || null} preferredScenarioId={preferredScenarioId} />
|
||||||
case 'the-ask':
|
case 'the-ask':
|
||||||
return <TheAskSlide lang={lang} funding={data.funding} />
|
return <TheAskSlide lang={lang} funding={data.funding} />
|
||||||
case 'cap-table':
|
case 'cap-table':
|
||||||
@@ -188,7 +197,7 @@ export default function PitchDeck({ lang, onToggleLanguage, investor, onLogout,
|
|||||||
case 'ai-qa':
|
case 'ai-qa':
|
||||||
return <AIQASlide lang={lang} />
|
return <AIQASlide lang={lang} />
|
||||||
case 'annex-assumptions':
|
case 'annex-assumptions':
|
||||||
return <AssumptionsSlide lang={lang} investorId={investor?.id || null} />
|
return <AssumptionsSlide lang={lang} investorId={investor?.id || null} preferredScenarioId={preferredScenarioId} />
|
||||||
case 'annex-architecture':
|
case 'annex-architecture':
|
||||||
return <ArchitectureSlide lang={lang} />
|
return <ArchitectureSlide lang={lang} />
|
||||||
case 'annex-gtm':
|
case 'annex-gtm':
|
||||||
@@ -204,7 +213,7 @@ export default function PitchDeck({ lang, onToggleLanguage, investor, onLogout,
|
|||||||
case 'annex-strategy':
|
case 'annex-strategy':
|
||||||
return <StrategySlide lang={lang} />
|
return <StrategySlide lang={lang} />
|
||||||
case 'annex-finanzplan':
|
case 'annex-finanzplan':
|
||||||
return <FinanzplanSlide lang={lang} investorId={investor?.id || null} />
|
return <FinanzplanSlide lang={lang} investorId={investor?.id || null} preferredScenarioId={preferredScenarioId} />
|
||||||
case 'annex-glossary':
|
case 'annex-glossary':
|
||||||
return <GlossarySlide lang={lang} />
|
return <GlossarySlide lang={lang} />
|
||||||
case 'legal-disclaimer':
|
case 'legal-disclaimer':
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import { useFinancialModel } from '@/lib/hooks/useFinancialModel'
|
|||||||
interface AssumptionsSlideProps {
|
interface AssumptionsSlideProps {
|
||||||
lang: Language
|
lang: Language
|
||||||
investorId?: string | null
|
investorId?: string | null
|
||||||
|
preferredScenarioId?: string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
function fmtArr(v: number, de: boolean): string {
|
function fmtArr(v: number, de: boolean): string {
|
||||||
@@ -35,12 +36,12 @@ function breakEvenYear(month: number | null): string {
|
|||||||
return String(year)
|
return String(year)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function AssumptionsSlide({ lang, investorId }: AssumptionsSlideProps) {
|
export default function AssumptionsSlide({ lang, investorId, preferredScenarioId }: AssumptionsSlideProps) {
|
||||||
const i = t(lang)
|
const i = t(lang)
|
||||||
const de = lang === 'de'
|
const de = lang === 'de'
|
||||||
|
|
||||||
// Load computed financial data for Base Case
|
// Load computed financial data for Base Case
|
||||||
const fm = useFinancialModel(investorId || null)
|
const fm = useFinancialModel(investorId || null, preferredScenarioId)
|
||||||
const summary = fm.activeResults?.summary
|
const summary = fm.activeResults?.summary
|
||||||
const results = fm.activeResults?.results || []
|
const results = fm.activeResults?.results || []
|
||||||
const lastResult = results.length > 0 ? results[results.length - 1] : null
|
const lastResult = results.length > 0 ? results[results.length - 1] : null
|
||||||
|
|||||||
@@ -12,12 +12,13 @@ interface BusinessModelSlideProps {
|
|||||||
lang: Language
|
lang: Language
|
||||||
products?: unknown[]
|
products?: unknown[]
|
||||||
investorId?: string | null
|
investorId?: string | null
|
||||||
|
preferredScenarioId?: string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function BusinessModelSlide({ lang, investorId }: BusinessModelSlideProps) {
|
export default function BusinessModelSlide({ lang, investorId, preferredScenarioId }: BusinessModelSlideProps) {
|
||||||
const i = t(lang)
|
const i = t(lang)
|
||||||
const de = lang === 'de'
|
const de = lang === 'de'
|
||||||
const fm = useFinancialModel(investorId || null)
|
const fm = useFinancialModel(investorId || null, preferredScenarioId)
|
||||||
const summary = fm.activeResults?.summary
|
const summary = fm.activeResults?.summary
|
||||||
const results = fm.activeResults?.results || []
|
const results = fm.activeResults?.results || []
|
||||||
const lastResult = results[results.length - 1]
|
const lastResult = results[results.length - 1]
|
||||||
|
|||||||
@@ -14,15 +14,16 @@ interface ExecutiveSummarySlideProps {
|
|||||||
lang: Language
|
lang: Language
|
||||||
data: PitchData
|
data: PitchData
|
||||||
investorId?: string | null
|
investorId?: string | null
|
||||||
|
preferredScenarioId?: string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function ExecutiveSummarySlide({ lang, data, investorId }: ExecutiveSummarySlideProps) {
|
export default function ExecutiveSummarySlide({ lang, data, investorId, preferredScenarioId }: ExecutiveSummarySlideProps) {
|
||||||
const i = t(lang)
|
const i = t(lang)
|
||||||
const es = i.executiveSummary
|
const es = i.executiveSummary
|
||||||
const de = lang === 'de'
|
const de = lang === 'de'
|
||||||
|
|
||||||
// Financial model for Unternehmensentwicklung
|
// Financial model for Unternehmensentwicklung
|
||||||
const fm = useFinancialModel(investorId || null)
|
const fm = useFinancialModel(investorId || null, preferredScenarioId)
|
||||||
const annualKPIs = useMemo(
|
const annualKPIs = useMemo(
|
||||||
() => computeAnnualKPIs(fm.activeResults?.results || []),
|
() => computeAnnualKPIs(fm.activeResults?.results || []),
|
||||||
[fm.activeResults],
|
[fm.activeResults],
|
||||||
|
|||||||
@@ -22,11 +22,12 @@ type FinTab = 'overview' | 'guv' | 'cashflow'
|
|||||||
interface FinancialsSlideProps {
|
interface FinancialsSlideProps {
|
||||||
lang: Language
|
lang: Language
|
||||||
investorId: string | null
|
investorId: string | null
|
||||||
|
preferredScenarioId?: string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function FinancialsSlide({ lang, investorId }: FinancialsSlideProps) {
|
export default function FinancialsSlide({ lang, investorId, preferredScenarioId }: FinancialsSlideProps) {
|
||||||
const i = t(lang)
|
const i = t(lang)
|
||||||
const fm = useFinancialModel(investorId)
|
const fm = useFinancialModel(investorId, preferredScenarioId)
|
||||||
const [activeTab, setActiveTab] = useState<FinTab>('overview')
|
const [activeTab, setActiveTab] = useState<FinTab>('overview')
|
||||||
const de = lang === 'de'
|
const de = lang === 'de'
|
||||||
|
|
||||||
@@ -125,10 +126,8 @@ export default function FinancialsSlide({ lang, investorId }: FinancialsSlidePro
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Main content: 3-column layout */}
|
{/* Main content: full width */}
|
||||||
<div className="grid md:grid-cols-12 gap-3">
|
<div className="space-y-3">
|
||||||
{/* Left: Charts (8 columns) */}
|
|
||||||
<div className="md:col-span-8 space-y-3">
|
|
||||||
|
|
||||||
{/* TAB: Overview — monatlicher Chart + Waterfall + Unit Economics */}
|
{/* TAB: Overview — monatlicher Chart + Waterfall + Unit Economics */}
|
||||||
{activeTab === 'overview' && (
|
{activeTab === 'overview' && (
|
||||||
@@ -222,38 +221,6 @@ export default function FinancialsSlide({ lang, investorId }: FinancialsSlidePro
|
|||||||
</div>
|
</div>
|
||||||
</FadeInView>
|
</FadeInView>
|
||||||
)}
|
)}
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Right: Controls (4 columns) */}
|
|
||||||
<div className="md:col-span-4 space-y-3">
|
|
||||||
{/* Scenario Switcher */}
|
|
||||||
<FadeInView delay={0.15}>
|
|
||||||
<div className="bg-white/[0.05] backdrop-blur-xl border border-white/10 rounded-2xl p-3">
|
|
||||||
<ScenarioSwitcher
|
|
||||||
scenarios={fm.scenarios}
|
|
||||||
activeId={fm.activeScenarioId}
|
|
||||||
compareMode={fm.compareMode}
|
|
||||||
onSelect={(id) => {
|
|
||||||
fm.setActiveScenarioId(id)
|
|
||||||
}}
|
|
||||||
onToggleCompare={() => {
|
|
||||||
if (!fm.compareMode) {
|
|
||||||
fm.computeAll()
|
|
||||||
}
|
|
||||||
fm.setCompareMode(!fm.compareMode)
|
|
||||||
}}
|
|
||||||
lang={lang}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</FadeInView>
|
|
||||||
|
|
||||||
{fm.computing && (
|
|
||||||
<div className="flex items-center gap-2 text-[10px] text-indigo-400">
|
|
||||||
<div className="w-3 h-3 border border-indigo-400 border-t-transparent rounded-full animate-spin" />
|
|
||||||
{de ? 'Berechne...' : 'Computing...'}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<ProjectionFooter lang={lang} />
|
<ProjectionFooter lang={lang} />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import { RefreshCw, Download, ChevronLeft, ChevronRight, BarChart3, Target } fro
|
|||||||
interface FinanzplanSlideProps {
|
interface FinanzplanSlideProps {
|
||||||
lang: Language
|
lang: Language
|
||||||
investorId?: string | null
|
investorId?: string | null
|
||||||
|
preferredScenarioId?: string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SheetMeta {
|
interface SheetMeta {
|
||||||
@@ -60,7 +61,7 @@ function formatCell(v: number | undefined): string {
|
|||||||
return Math.round(v).toLocaleString('de-DE', { maximumFractionDigits: 0 })
|
return Math.round(v).toLocaleString('de-DE', { maximumFractionDigits: 0 })
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function FinanzplanSlide({ lang, investorId }: FinanzplanSlideProps) {
|
export default function FinanzplanSlide({ lang, investorId, preferredScenarioId }: FinanzplanSlideProps) {
|
||||||
const [sheets, setSheets] = useState<SheetMeta[]>([])
|
const [sheets, setSheets] = useState<SheetMeta[]>([])
|
||||||
const [activeSheet, setActiveSheet] = useState<string>('personalkosten')
|
const [activeSheet, setActiveSheet] = useState<string>('personalkosten')
|
||||||
const [rows, setRows] = useState<SheetRow[]>([])
|
const [rows, setRows] = useState<SheetRow[]>([])
|
||||||
@@ -70,7 +71,7 @@ export default function FinanzplanSlide({ lang, investorId }: FinanzplanSlidePro
|
|||||||
const de = lang === 'de'
|
const de = lang === 'de'
|
||||||
|
|
||||||
// Financial model — same source as FinancialsSlide (Slide 15)
|
// Financial model — same source as FinancialsSlide (Slide 15)
|
||||||
const fm = useFinancialModel(investorId || null)
|
const fm = useFinancialModel(investorId || null, preferredScenarioId)
|
||||||
const annualKPIs = useMemo(
|
const annualKPIs = useMemo(
|
||||||
() => computeAnnualKPIs(fm.activeResults?.results || []),
|
() => computeAnnualKPIs(fm.activeResults?.results || []),
|
||||||
[fm.activeResults],
|
[fm.activeResults],
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
import { useState, useEffect, useCallback, useRef } from 'react'
|
import { useState, useEffect, useCallback, useRef } from 'react'
|
||||||
import { FMScenario, FMResult, FMComputeResponse, InvestorSnapshot } from '../types'
|
import { FMScenario, FMResult, FMComputeResponse, InvestorSnapshot } from '../types'
|
||||||
|
|
||||||
export function useFinancialModel(investorId?: string | null) {
|
export function useFinancialModel(investorId?: string | null, preferredScenarioId?: string | null) {
|
||||||
const [scenarios, setScenarios] = useState<FMScenario[]>([])
|
const [scenarios, setScenarios] = useState<FMScenario[]>([])
|
||||||
const [activeScenarioId, setActiveScenarioId] = useState<string | null>(null)
|
const [activeScenarioId, setActiveScenarioId] = useState<string | null>(null)
|
||||||
const [compareMode, setCompareMode] = useState(false)
|
const [compareMode, setCompareMode] = useState(false)
|
||||||
@@ -51,7 +51,9 @@ export function useFinancialModel(investorId?: string | null) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setScenarios(data)
|
setScenarios(data)
|
||||||
const defaultScenario = data.find(s => s.is_default) || data[0]
|
// Use preferred scenario if available, otherwise default
|
||||||
|
const preferred = preferredScenarioId ? data.find(s => s.id === preferredScenarioId) : null
|
||||||
|
const defaultScenario = preferred || data.find(s => s.is_default) || data[0]
|
||||||
if (defaultScenario) {
|
if (defaultScenario) {
|
||||||
setActiveScenarioId(defaultScenario.id)
|
setActiveScenarioId(defaultScenario.id)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ export const PRESENTER_SCRIPT: SlideScript[] = [
|
|||||||
duration: 45,
|
duration: 45,
|
||||||
paragraphs: [
|
paragraphs: [
|
||||||
{
|
{
|
||||||
text_de: 'Willkommen bei BreakPilot COMPLEI — der Compliance-Plattform, die produzierende Unternehmen endlich von der Regulierungslast befreit. Von der DSGVO ueber den AI Act bis zur CE-Kennzeichnung — alles aus einer Hand.',
|
text_de: 'Willkommen bei BreakPilot COMPLAI — der Compliance-Plattform, die produzierende Unternehmen endlich von der Regulierungslast befreit. Von der DSGVO ueber den AI Act bis zur CE-Kennzeichnung — alles aus einer Hand.',
|
||||||
text_en: 'Welcome to BreakPilot COMPLEI — the compliance platform that finally frees manufacturing companies from the regulatory burden. From GDPR to the AI Act to CE certification — all from a single source.',
|
text_en: 'Welcome to BreakPilot COMPLAI — the compliance platform that finally frees manufacturing companies from the regulatory burden. From GDPR to the AI Act to CE certification — all from a single source.',
|
||||||
pause_after: 1500,
|
pause_after: 1500,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -32,8 +32,8 @@ export const PRESENTER_SCRIPT: SlideScript[] = [
|
|||||||
duration: 30,
|
duration: 30,
|
||||||
paragraphs: [
|
paragraphs: [
|
||||||
{
|
{
|
||||||
text_de: 'Bevor wir ins Detail gehen, hier das Wichtigste auf einen Blick: BreakPilot COMPLEI ist die einzige Plattform, die organisatorische Compliance, Produkt-Compliance und Code-Security vereint — speziell fuer den produzierenden Mittelstand.',
|
text_de: 'Bevor wir ins Detail gehen, hier das Wichtigste auf einen Blick: BreakPilot COMPLAI ist die einzige Plattform, die organisatorische Compliance, Produkt-Compliance und Code-Security vereint — speziell fuer den produzierenden Mittelstand.',
|
||||||
text_en: 'Before we dive into details, here is the key summary: BreakPilot COMPLEI is the only platform that combines organizational compliance, product compliance and code security — specifically for the manufacturing mid-market.',
|
text_en: 'Before we dive into details, here is the key summary: BreakPilot COMPLAI is the only platform that combines organizational compliance, product compliance and code security — specifically for the manufacturing mid-market.',
|
||||||
pause_after: 1500,
|
pause_after: 1500,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -52,8 +52,8 @@ export const PRESENTER_SCRIPT: SlideScript[] = [
|
|||||||
duration: 20,
|
duration: 20,
|
||||||
paragraphs: [
|
paragraphs: [
|
||||||
{
|
{
|
||||||
text_de: 'BreakPilot COMPLEI — ueber 380 Regularien, 10 Branchen, eine Plattform. Kontinuierliche Compliance und Code-Security. Gruendung August 2026. Wir bauen die Zukunft der industriellen Compliance.',
|
text_de: 'BreakPilot COMPLAI — ueber 380 Regularien, 10 Branchen, eine Plattform. Kontinuierliche Compliance und Code-Security. Gruendung August 2026. Wir bauen die Zukunft der industriellen Compliance.',
|
||||||
text_en: 'BreakPilot COMPLEI — over 380 regulations, 10 industries, one platform. Continuous compliance and code security. Founding August 2026. We are building the future of industrial compliance.',
|
text_en: 'BreakPilot COMPLAI — over 380 regulations, 10 industries, one platform. Continuous compliance and code security. Founding August 2026. We are building the future of industrial compliance.',
|
||||||
pause_after: 1500,
|
pause_after: 1500,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -636,8 +636,8 @@ export const PRESENTER_SCRIPT: SlideScript[] = [
|
|||||||
duration: 20,
|
duration: 20,
|
||||||
paragraphs: [
|
paragraphs: [
|
||||||
{
|
{
|
||||||
text_de: 'Zum Abschluss der wichtige rechtliche Hinweis: Dieses Pitch Deck ist vertraulich und ausschliesslich fuer den eingeladenen Empfaenger bestimmt. Alle Finanzangaben sind Planzahlen. Vielen Dank fuer Ihre Zeit und Ihr Interesse an BreakPilot COMPLEI.',
|
text_de: 'Zum Abschluss der wichtige rechtliche Hinweis: Dieses Pitch Deck ist vertraulich und ausschliesslich fuer den eingeladenen Empfaenger bestimmt. Alle Finanzangaben sind Planzahlen. Vielen Dank fuer Ihre Zeit und Ihr Interesse an BreakPilot COMPLAI.',
|
||||||
text_en: 'To conclude, the important legal notice: This pitch deck is confidential and intended exclusively for the invited recipient. All financial figures are projections. Thank you for your time and interest in BreakPilot COMPLEI.',
|
text_en: 'To conclude, the important legal notice: This pitch deck is confidential and intended exclusively for the invited recipient. All financial figures are projections. Thank you for your time and interest in BreakPilot COMPLAI.',
|
||||||
pause_after: 1500,
|
pause_after: 1500,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
Reference in New Issue
Block a user