Dateien nach "competitor-analysis" hochladen
This commit is contained in:
286
competitor-analysis/translations.ts
Normal file
286
competitor-analysis/translations.ts
Normal file
@@ -0,0 +1,286 @@
|
|||||||
|
export const translations = {
|
||||||
|
de: {
|
||||||
|
appTitle: "B2B Competitor Analysis Agent",
|
||||||
|
restartAnalysis: "Analyse neustarten",
|
||||||
|
nextStepButton: "Bestätigen & Nächster Schritt",
|
||||||
|
companyCard: {
|
||||||
|
title: "Ausgangsunternehmen",
|
||||||
|
},
|
||||||
|
inputForm: {
|
||||||
|
title: "Wettbewerbsanalyse starten",
|
||||||
|
subtitle: "Geben Sie die Website eines Unternehmens ein, um die Analyse zu beginnen.",
|
||||||
|
startUrlLabel: "Start-URL des Unternehmens",
|
||||||
|
maxCompetitorsLabel: "Max. Wettbewerber",
|
||||||
|
marketScopeLabel: "Marktfokus",
|
||||||
|
marketScopePlaceholder: "z.B. DACH, EU, global",
|
||||||
|
languageLabel: "Sprache",
|
||||||
|
submitButton: "Analyse starten",
|
||||||
|
},
|
||||||
|
loadingSpinner: {
|
||||||
|
message: "AI analysiert, bitte warten...",
|
||||||
|
},
|
||||||
|
errors: {
|
||||||
|
title: "Fehler:",
|
||||||
|
step1: "Fehler bei der Analyse der Start-URL. Bitte überprüfen Sie die URL und versuchen Sie es erneut.",
|
||||||
|
generic: (step: number) => `Ein Fehler ist in Schritt ${step} aufgetreten. Bitte versuchen Sie es erneut.`,
|
||||||
|
},
|
||||||
|
stepIndicator: {
|
||||||
|
title: "Fortschritt",
|
||||||
|
steps: ["Extraktion", "Keywords", "Wettbewerber", "Analyse", "Silver Bullets", "Fazit", "Battlecards", "Referenzen"],
|
||||||
|
},
|
||||||
|
step1: {
|
||||||
|
title: "Schritt 1: Extraktion der Unternehmensinformationen",
|
||||||
|
subtitle: "Überprüfen, bearbeiten oder ergänzen Sie die vom AI-Agenten extrahierten Produkte und Zielbranchen.",
|
||||||
|
addProductTitle: "Neues Produkt per URL hinzufügen",
|
||||||
|
productNameLabel: "Produktname",
|
||||||
|
productUrlLabel: "Produkt-URL",
|
||||||
|
productNamePlaceholder: "z.B. mobileX-Dispatch",
|
||||||
|
addProductError: "Produkt konnte nicht recherchiert werden. Bitte URL überprüfen.",
|
||||||
|
addButton: "Produkt hinzufügen",
|
||||||
|
addingButton: "Recherchiere...",
|
||||||
|
productsTitle: "Produkte / Lösungen",
|
||||||
|
purposeLabel: "Zweckbeschreibung",
|
||||||
|
industriesTitle: "Zielmärkte / Branchen",
|
||||||
|
industryNameLabel: "Branchenname",
|
||||||
|
editableCard: { add: "Hinzufügen", cancel: "Abbrechen", save: "Speichern" }
|
||||||
|
},
|
||||||
|
step2: {
|
||||||
|
title: "Schritt 2: Abgeleitete Keywords",
|
||||||
|
subtitle: "Überprüfen Sie die für die Wettbewerbssuche generierten Keywords und passen Sie sie bei Bedarf an.",
|
||||||
|
cardTitle: "Keyword-Set",
|
||||||
|
termLabel: "Keyword / Phrase",
|
||||||
|
rationaleLabel: "Begründung",
|
||||||
|
editableCard: { add: "Hinzufügen", cancel: "Abbrechen", save: "Speichern" }
|
||||||
|
},
|
||||||
|
step3: {
|
||||||
|
title: "Schritt 3: Wettbewerber finden",
|
||||||
|
subtitle: (max: number) => `Hier ist die Longlist potenzieller Wettbewerber. Entfernen oder ergänzen Sie Einträge. Die Top ${max} nach Konfidenz werden für die Detailanalyse in die Shortlist übernommen.`,
|
||||||
|
cardTitle: "Wettbewerber-Kandidaten",
|
||||||
|
nameLabel: "Name",
|
||||||
|
whyLabel: "Begründung",
|
||||||
|
visitButton: "Besuchen",
|
||||||
|
shortlistBoundary: "SHORTLIST-GRENZE",
|
||||||
|
editableCard: { add: "Hinzufügen", cancel: "Abbrechen", save: "Speichern" }
|
||||||
|
},
|
||||||
|
step4: {
|
||||||
|
title: "Schritt 4: Portfolio- & Positionierungsanalyse",
|
||||||
|
subtitle: "Detailanalyse der Shortlist-Wettbewerber. Die relevantesten (höchster Overlap) stehen oben.",
|
||||||
|
downloadJson_title: "Analyse herunterladen",
|
||||||
|
portfolio: "Produktportfolio",
|
||||||
|
differentiators: "Alleinstellungsmerkmale",
|
||||||
|
targetIndustries: "Zielbranchen & Modell",
|
||||||
|
overlapScore: "Overlap Score",
|
||||||
|
},
|
||||||
|
step5: {
|
||||||
|
title: "Schritt 5: Silver Bullets",
|
||||||
|
generating: "Positionierungsaussagen werden generiert...",
|
||||||
|
subtitle: "Dies sind prägnante Positionierungsaussagen, um Ihr Unternehmen im direkten Gespräch vom jeweiligen Wettbewerber abzugrenzen.",
|
||||||
|
cardTitle: "Gegenüber",
|
||||||
|
},
|
||||||
|
step6: {
|
||||||
|
title: "Schritt 6: Vergleich & Fazit",
|
||||||
|
generating: "Fazit wird generiert...",
|
||||||
|
subtitle: "Zusammenfassende Analyse und strategische Einordnung.",
|
||||||
|
downloadButton: "Gesamtbericht laden",
|
||||||
|
downloadJson: "JSON herunterladen",
|
||||||
|
downloadMd: "Markdown (MD) herunterladen",
|
||||||
|
downloadPdf: "PDF herunterladen",
|
||||||
|
productMatrix: "Produkt-Matrix",
|
||||||
|
industryMatrix: "Branchen-Matrix",
|
||||||
|
summary: "Zusammenfassung & Positionierung",
|
||||||
|
opportunities: (name: string) => `Chancen & Lücken für ${name}`,
|
||||||
|
nextQuestions: "Nächste Fragen & Unsicherheiten",
|
||||||
|
markdown: {
|
||||||
|
title: "B2B Wettbewerbsanalyse",
|
||||||
|
startUrl: "Start-URL",
|
||||||
|
marketScope: "Marktfokus",
|
||||||
|
step1_title: "Schritt 1: Extraktion",
|
||||||
|
step1_products: "Produkte / Lösungen",
|
||||||
|
step1_industries: "Zielbranchen",
|
||||||
|
step4_title: "Schritt 4: Detaillierte Analyse",
|
||||||
|
portfolio: "Portfolio",
|
||||||
|
targetIndustries: "Zielbranchen",
|
||||||
|
differentiators: "Alleinstellungsmerkmale",
|
||||||
|
step5_title: "Schritt 5: Silver Bullets",
|
||||||
|
against: "Gegen",
|
||||||
|
step7_title: "Schritt 7: Sales Battlecards",
|
||||||
|
profile: "Profil",
|
||||||
|
focus: "Fokus",
|
||||||
|
positioning: "Positionierung",
|
||||||
|
strengthsVsWeaknesses: "Unsere Stärken vs. Ihre Schwächen",
|
||||||
|
landmineQuestions: '"Landminen"-Fragen',
|
||||||
|
silverBullet: "Silver Bullet",
|
||||||
|
step8_title: "Schritt 8: Referenzkunden-Analyse",
|
||||||
|
caseStudyLink: "Case Study Link",
|
||||||
|
noReferencesFound: "Keine Referenzen gefunden.",
|
||||||
|
sources: "Quellen für Referenz-Analyse",
|
||||||
|
step6_title: "Schritt 6: Fazit",
|
||||||
|
productMatrix: "Produkt-Matrix",
|
||||||
|
industryMatrix: "Branchen-Matrix",
|
||||||
|
summary: "Zusammenfassung & Positionierung",
|
||||||
|
opportunities: "Chancen & Lücken",
|
||||||
|
nextQuestions: "Nächste Fragen",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
step7: {
|
||||||
|
title: "Schritt 7: Sales Battlecards",
|
||||||
|
generating: "Battlecards werden generiert...",
|
||||||
|
subtitle: "Nutzen Sie diese \"Battlecards\" zur Vorbereitung auf Vertriebsgespräche. Jede Karte fasst die wichtigsten Argumente gegen einen spezifischen Wettbewerber zusammen.",
|
||||||
|
card: {
|
||||||
|
profile: "Competitor Profile",
|
||||||
|
strengths: "Our Strengths vs. Their Weaknesses",
|
||||||
|
landmines: "\"Landmine\" Questions to Ask",
|
||||||
|
silverBullet: "Silver Bullet",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
step8: {
|
||||||
|
title: "Schritt 8: Referenzkunden-Analyse",
|
||||||
|
subtitle: "Analyse der Testimonials und Case Studies der Wettbewerber, um deren Marktpräsenz und Erfolgsgeschichten zu verstehen. Die Ergebnisse basieren auf einer Google-Suche.",
|
||||||
|
noReferencesFound: "Keine öffentlichen Referenzkunden auf der offiziellen Website gefunden.",
|
||||||
|
caseStudyLink: "Case Study",
|
||||||
|
sourcesTitle: "Recherche-Quellen",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
en: {
|
||||||
|
appTitle: "B2B Competitor Analysis Agent",
|
||||||
|
restartAnalysis: "Restart Analysis",
|
||||||
|
nextStepButton: "Confirm & Next Step",
|
||||||
|
companyCard: {
|
||||||
|
title: "Initial Company",
|
||||||
|
},
|
||||||
|
inputForm: {
|
||||||
|
title: "Start Competitor Analysis",
|
||||||
|
subtitle: "Enter a company's website to begin the analysis.",
|
||||||
|
startUrlLabel: "Company Start URL",
|
||||||
|
maxCompetitorsLabel: "Max Competitors",
|
||||||
|
marketScopeLabel: "Market Focus",
|
||||||
|
marketScopePlaceholder: "e.g., DACH, EU, global",
|
||||||
|
languageLabel: "Language",
|
||||||
|
submitButton: "Start Analysis",
|
||||||
|
},
|
||||||
|
loadingSpinner: {
|
||||||
|
message: "AI is analyzing, please wait...",
|
||||||
|
},
|
||||||
|
errors: {
|
||||||
|
title: "Error:",
|
||||||
|
step1: "Error analyzing the start URL. Please check the URL and try again.",
|
||||||
|
generic: (step: number) => `An error occurred in step ${step}. Please try again.`,
|
||||||
|
},
|
||||||
|
stepIndicator: {
|
||||||
|
title: "Progress",
|
||||||
|
steps: ["Extraction", "Keywords", "Competitors", "Analysis", "Silver Bullets", "Conclusion", "Battlecards", "References"],
|
||||||
|
},
|
||||||
|
step1: {
|
||||||
|
title: "Step 1: Company Information Extraction",
|
||||||
|
subtitle: "Review, edit, or add to the products and target industries extracted by the AI agent.",
|
||||||
|
addProductTitle: "Add New Product by URL",
|
||||||
|
productNameLabel: "Product Name",
|
||||||
|
productUrlLabel: "Product URL",
|
||||||
|
productNamePlaceholder: "e.g., mobileX-Dispatch",
|
||||||
|
addProductError: "Could not research product. Please check the URL.",
|
||||||
|
addButton: "Add Product",
|
||||||
|
addingButton: "Researching...",
|
||||||
|
productsTitle: "Products / Solutions",
|
||||||
|
purposeLabel: "Purpose Description",
|
||||||
|
industriesTitle: "Target Markets / Industries",
|
||||||
|
industryNameLabel: "Industry Name",
|
||||||
|
editableCard: { add: "Add", cancel: "Cancel", save: "Save" }
|
||||||
|
},
|
||||||
|
step2: {
|
||||||
|
title: "Step 2: Derived Keywords",
|
||||||
|
subtitle: "Review and adjust the keywords generated for the competitor search if necessary.",
|
||||||
|
cardTitle: "Keyword Set",
|
||||||
|
termLabel: "Keyword / Phrase",
|
||||||
|
rationaleLabel: "Rationale",
|
||||||
|
editableCard: { add: "Add", cancel: "Cancel", save: "Save" }
|
||||||
|
},
|
||||||
|
step3: {
|
||||||
|
title: "Step 3: Find Competitors",
|
||||||
|
subtitle: (max: number) => `Here is the longlist of potential competitors. Remove or add entries. The top ${max} by confidence will be shortlisted for detailed analysis.`,
|
||||||
|
cardTitle: "Competitor Candidates",
|
||||||
|
nameLabel: "Name",
|
||||||
|
whyLabel: "Justification",
|
||||||
|
visitButton: "Visit",
|
||||||
|
shortlistBoundary: "SHORTLIST BOUNDARY",
|
||||||
|
editableCard: { add: "Add", cancel: "Cancel", save: "Save" }
|
||||||
|
},
|
||||||
|
step4: {
|
||||||
|
title: "Step 4: Portfolio & Positioning Analysis",
|
||||||
|
subtitle: "Detailed analysis of the shortlisted competitors. The most relevant (highest overlap) are at the top.",
|
||||||
|
downloadJson_title: "Download Analysis",
|
||||||
|
portfolio: "Product Portfolio",
|
||||||
|
differentiators: "Differentiators",
|
||||||
|
targetIndustries: "Target Industries & Model",
|
||||||
|
overlapScore: "Overlap Score",
|
||||||
|
},
|
||||||
|
step5: {
|
||||||
|
title: "Step 5: Silver Bullets",
|
||||||
|
generating: "Generating positioning statements...",
|
||||||
|
subtitle: "These are concise positioning statements to differentiate your company from each competitor in direct conversation.",
|
||||||
|
cardTitle: "Against",
|
||||||
|
},
|
||||||
|
step6: {
|
||||||
|
title: "Step 6: Comparison & Conclusion",
|
||||||
|
generating: "Generating conclusion...",
|
||||||
|
subtitle: "Summary analysis and strategic classification.",
|
||||||
|
downloadButton: "Download Full Report",
|
||||||
|
downloadJson: "Download JSON",
|
||||||
|
downloadMd: "Download Markdown (MD)",
|
||||||
|
downloadPdf: "Download PDF",
|
||||||
|
productMatrix: "Product Matrix",
|
||||||
|
industryMatrix: "Industry Matrix",
|
||||||
|
summary: "Summary & Positioning",
|
||||||
|
opportunities: (name: string) => `Opportunities & Gaps for ${name}`,
|
||||||
|
nextQuestions: "Next Questions & Uncertainties",
|
||||||
|
markdown: {
|
||||||
|
title: "B2B Competitor Analysis",
|
||||||
|
startUrl: "Start URL",
|
||||||
|
marketScope: "Market Focus",
|
||||||
|
step1_title: "Step 1: Extraction",
|
||||||
|
step1_products: "Products / Solutions",
|
||||||
|
step1_industries: "Target Industries",
|
||||||
|
step4_title: "Step 4: Detailed Analysis",
|
||||||
|
portfolio: "Portfolio",
|
||||||
|
targetIndustries: "Target Industries",
|
||||||
|
differentiators: "Differentiators",
|
||||||
|
step5_title: "Step 5: Silver Bullets",
|
||||||
|
against: "Against",
|
||||||
|
step7_title: "Step 7: Sales Battlecards",
|
||||||
|
profile: "Profile",
|
||||||
|
focus: "Focus",
|
||||||
|
positioning: "Positioning",
|
||||||
|
strengthsVsWeaknesses: "Our Strengths vs. Their Weaknesses",
|
||||||
|
landmineQuestions: '"Landmine" Questions',
|
||||||
|
silverBullet: "Silver Bullet",
|
||||||
|
step8_title: "Step 8: Reference Customer Analysis",
|
||||||
|
caseStudyLink: "Case Study Link",
|
||||||
|
noReferencesFound: "No references found.",
|
||||||
|
sources: "Sources for Reference Analysis",
|
||||||
|
step6_title: "Step 6: Conclusion",
|
||||||
|
productMatrix: "Product Matrix",
|
||||||
|
industryMatrix: "Industry Matrix",
|
||||||
|
summary: "Summary & Positioning",
|
||||||
|
opportunities: "Opportunities & Gaps",
|
||||||
|
nextQuestions: "Next Questions",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
step7: {
|
||||||
|
title: "Step 7: Sales Battlecards",
|
||||||
|
generating: "Generating battlecards...",
|
||||||
|
subtitle: "Use these \"Battlecards\" to prepare for sales conversations. Each card summarizes the key arguments against a specific competitor.",
|
||||||
|
card: {
|
||||||
|
profile: "Competitor Profile",
|
||||||
|
strengths: "Our Strengths vs. Their Weaknesses",
|
||||||
|
landmines: "\"Landmine\" Questions to Ask",
|
||||||
|
silverBullet: "Silver Bullet",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
step8: {
|
||||||
|
title: "Step 8: Reference Customer Analysis",
|
||||||
|
subtitle: "Analysis of competitor testimonials and case studies to understand their market presence and success stories. The results are based on a Google search.",
|
||||||
|
noReferencesFound: "No public reference customers found on the official website.",
|
||||||
|
caseStudyLink: "Case Study",
|
||||||
|
sourcesTitle: "Research Sources",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
29
competitor-analysis/tsconfig.json
Normal file
29
competitor-analysis/tsconfig.json
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2022",
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"useDefineForClassFields": false,
|
||||||
|
"module": "ESNext",
|
||||||
|
"lib": [
|
||||||
|
"ES2022",
|
||||||
|
"DOM",
|
||||||
|
"DOM.Iterable"
|
||||||
|
],
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"types": [
|
||||||
|
"node"
|
||||||
|
],
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"isolatedModules": true,
|
||||||
|
"moduleDetection": "force",
|
||||||
|
"allowJs": true,
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
"paths": {
|
||||||
|
"@/*": [
|
||||||
|
"./*"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"allowImportingTsExtensions": true,
|
||||||
|
"noEmit": true
|
||||||
|
}
|
||||||
|
}
|
||||||
120
competitor-analysis/types.ts
Normal file
120
competitor-analysis/types.ts
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
|
||||||
|
|
||||||
|
export interface Evidence {
|
||||||
|
url: string;
|
||||||
|
snippet: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Product {
|
||||||
|
name: string;
|
||||||
|
purpose: string;
|
||||||
|
evidence: Evidence[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TargetIndustry {
|
||||||
|
name: string;
|
||||||
|
evidence: Evidence[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Keyword {
|
||||||
|
term: string;
|
||||||
|
rationale: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CompetitorCandidate {
|
||||||
|
name: string;
|
||||||
|
url: string;
|
||||||
|
confidence: number;
|
||||||
|
why: string;
|
||||||
|
evidence: Evidence[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ShortlistedCompetitor {
|
||||||
|
name: string;
|
||||||
|
url: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Analysis {
|
||||||
|
competitor: {
|
||||||
|
name: string;
|
||||||
|
url: string;
|
||||||
|
};
|
||||||
|
portfolio: {
|
||||||
|
product: string;
|
||||||
|
purpose: string;
|
||||||
|
}[];
|
||||||
|
target_industries: string[];
|
||||||
|
delivery_model: string;
|
||||||
|
overlap_score: number;
|
||||||
|
differentiators: string[];
|
||||||
|
evidence: Evidence[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SilverBullet {
|
||||||
|
competitor_name: string;
|
||||||
|
statement: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Conclusion {
|
||||||
|
product_matrix: {
|
||||||
|
product: string;
|
||||||
|
availability: { competitor: string; has_offering: boolean; }[];
|
||||||
|
}[];
|
||||||
|
industry_matrix: {
|
||||||
|
industry: string;
|
||||||
|
availability: { competitor: string; has_offering: boolean; }[];
|
||||||
|
}[];
|
||||||
|
overlap_scores: { competitor: string; score: number }[];
|
||||||
|
summary: string;
|
||||||
|
opportunities: string;
|
||||||
|
next_questions: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Battlecard {
|
||||||
|
competitor_name: string;
|
||||||
|
competitor_profile: {
|
||||||
|
focus: string;
|
||||||
|
positioning: string;
|
||||||
|
};
|
||||||
|
strengths_vs_weaknesses: string[];
|
||||||
|
landmine_questions: string[];
|
||||||
|
silver_bullet: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ReferenceCustomer {
|
||||||
|
name: string;
|
||||||
|
industry: string;
|
||||||
|
testimonial_snippet: string;
|
||||||
|
case_study_url: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ReferenceAnalysis {
|
||||||
|
competitor_name: string;
|
||||||
|
references: ReferenceCustomer[];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export interface AppState {
|
||||||
|
step: number;
|
||||||
|
initial_params: {
|
||||||
|
start_url: string;
|
||||||
|
max_competitors: number;
|
||||||
|
market_scope: string;
|
||||||
|
language: 'de' | 'en';
|
||||||
|
};
|
||||||
|
company: {
|
||||||
|
name: string;
|
||||||
|
start_url: string;
|
||||||
|
};
|
||||||
|
products: Product[];
|
||||||
|
target_industries: TargetIndustry[];
|
||||||
|
keywords: Keyword[];
|
||||||
|
competitor_candidates: CompetitorCandidate[];
|
||||||
|
competitors_shortlist: ShortlistedCompetitor[];
|
||||||
|
analyses: Analysis[];
|
||||||
|
silver_bullets: SilverBullet[];
|
||||||
|
conclusion: Conclusion | null;
|
||||||
|
battlecards: Battlecard[];
|
||||||
|
reference_analysis: ReferenceAnalysis[];
|
||||||
|
reference_analysis_grounding: any[];
|
||||||
|
}
|
||||||
23
competitor-analysis/vite.config.ts
Normal file
23
competitor-analysis/vite.config.ts
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import path from 'path';
|
||||||
|
import { defineConfig, loadEnv } from 'vite';
|
||||||
|
import react from '@vitejs/plugin-react';
|
||||||
|
|
||||||
|
export default defineConfig(({ mode }) => {
|
||||||
|
const env = loadEnv(mode, '.', '');
|
||||||
|
return {
|
||||||
|
server: {
|
||||||
|
port: 3000,
|
||||||
|
host: '0.0.0.0',
|
||||||
|
},
|
||||||
|
plugins: [react()],
|
||||||
|
define: {
|
||||||
|
'process.env.API_KEY': JSON.stringify(env.GEMINI_API_KEY),
|
||||||
|
'process.env.GEMINI_API_KEY': JSON.stringify(env.GEMINI_API_KEY)
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'@': path.resolve(__dirname, '.'),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user