diff --git a/AGENTIC_PROMPTS_COMPARISON.md b/AGENTIC_PROMPTS_COMPARISON.md new file mode 100644 index 0000000..5413796 --- /dev/null +++ b/AGENTIC_PROMPTS_COMPARISON.md @@ -0,0 +1,166 @@ +# Agentic Prompts Comparison: August 14th Production vs Current Version + +## Overview +This document compares the agentic prompts and LLM processing approach between the August 14th production backup (commit `df07971`) and the current version. + +## Key Differences + +### 1. **System Prompt Complexity** + +#### August 14th Version (Production) +```typescript +private getCIMSystemPrompt(): string { + return `You are an expert investment analyst at BPCP (Blue Point Capital Partners) reviewing a Confidential Information Memorandum (CIM). Your task is to analyze CIM documents and return a comprehensive, structured JSON object that follows the BPCP CIM Review Template format EXACTLY. + +CRITICAL REQUIREMENTS: +1. **JSON OUTPUT ONLY**: Your entire response MUST be a single, valid JSON object. Do not include any text or explanation before or after the JSON object. + +2. **BPCP TEMPLATE FORMAT**: The JSON object MUST follow the BPCP CIM Review Template structure exactly as specified. + +3. **COMPLETE ALL FIELDS**: You MUST provide a value for every field. Use "Not specified in CIM" for any information that is not available in the document. + +4. **NO PLACEHOLDERS**: Do not use placeholders like "..." or "TBD". Use "Not specified in CIM" instead. + +5. **PROFESSIONAL ANALYSIS**: The content should be high-quality and suitable for BPCP's investment committee. + +6. **BPCP FOCUS**: Focus on companies in 5+MM EBITDA range in consumer and industrial end markets, with emphasis on M&A, technology & data usage, supply chain and human capital optimization. + +7. **BPCP PREFERENCES**: BPCP prefers companies which are founder/family-owned and within driving distance of Cleveland and Charlotte. + +8. **EXACT FIELD NAMES**: Use the exact field names and descriptions from the BPCP CIM Review Template. + +9. **FINANCIAL DATA**: For financial metrics, use actual numbers if available, otherwise use "Not specified in CIM". + +10. **VALID JSON**: Ensure your response is valid JSON that can be parsed without errors. + +ANALYSIS QUALITY REQUIREMENTS: +- **Financial Precision**: Extract exact financial figures, percentages, and growth rates. Calculate CAGR where possible. +- **Competitive Intelligence**: Identify specific competitors, market positions, and competitive advantages. +- **Risk Assessment**: Evaluate both stated and implied risks, including operational, financial, and market risks. +- **Growth Drivers**: Identify specific revenue growth drivers, market expansion opportunities, and operational improvements. +- **Management Quality**: Assess management experience, track record, and post-transaction intentions. +- **Value Creation**: Identify specific value creation levers that align with BPCP's expertise. +- **Due Diligence Focus**: Highlight areas requiring deeper investigation and specific questions for management. + +DOCUMENT ANALYSIS APPROACH: +- Read the entire document carefully, paying special attention to financial tables, charts, and appendices +- Cross-reference information across different sections for consistency +- Extract both explicit statements and implicit insights +- Focus on quantitative data while providing qualitative context +- Identify any inconsistencies or areas requiring clarification +- Consider industry context and market dynamics when evaluating opportunities and risks`; +} +``` + +#### Current Version +```typescript +private getOptimizedCIMSystemPrompt(): string { + return `You are an expert financial analyst specializing in Confidential Information Memorandums (CIMs). +Your task is to analyze CIM documents and extract key information in a structured JSON format. + +IMPORTANT: You must respond with ONLY valid JSON that matches the exact schema provided. Do not include any explanatory text, markdown, or other formatting. + +The JSON must include all required fields with appropriate values extracted from the document. If information is not available in the document, use "N/A" or "Not provided" as the value. + +Focus on extracting: +- Financial metrics and performance data +- Business model and operations details +- Market position and competitive landscape +- Management team and organizational structure +- Investment thesis and value creation opportunities + +Provide specific data points and insights where available from the document.`; +} +``` + +### 2. **Prompt Construction Approach** + +#### August 14th Version +- **Detailed JSON Template**: Included the complete JSON structure in the prompt +- **Error Correction**: Had built-in retry logic with error correction +- **BPCP-Specific Context**: Included specific BPCP investment criteria and preferences +- **Multi-Attempt Processing**: Up to 3 attempts with validation and correction + +#### Current Version +- **Schema-Based**: Uses Zod schema description instead of hardcoded JSON template +- **Simplified Prompt**: More concise and focused +- **Generic Approach**: Removed BPCP-specific investment criteria +- **Single Attempt**: Simplified to single processing attempt + +### 3. **Processing Method** + +#### August 14th Version +```typescript +async processCIMDocument(text: string, template: string, analysis?: Record): Promise { + // Complex multi-attempt processing with validation + for (let attempt = 1; attempt <= 3; attempt++) { + // Error correction logic + // JSON validation with Zod + // Retry on failure + } +} +``` + +#### Current Version +```typescript +async processCIMDocument(documentText: string, options: {...}): Promise<{ content: string; analysisData: any; ... }> { + // Single attempt processing + // Schema-based prompt generation + // Simple JSON parsing with fallback +} +``` + +### 4. **Key Missing Elements in Current Version** + +1. **BPCP-Specific Investment Criteria** + - 5+MM EBITDA range focus + - Consumer and industrial end markets emphasis + - Technology & data usage focus + - Supply chain and human capital optimization + - Founder/family-owned preference + - Geographic preferences (Cleveland/Charlotte driving distance) + +2. **Quality Requirements** + - Financial precision requirements + - Competitive intelligence focus + - Risk assessment methodology + - Growth driver identification + - Management quality assessment + - Value creation lever identification + - Due diligence focus areas + +3. **Document Analysis Approach** + - Cross-referencing across sections + - Explicit vs implicit insight extraction + - Quantitative vs qualitative balance + - Inconsistency identification + - Industry context consideration + +4. **Error Handling** + - Multi-attempt processing + - Validation-based retry logic + - Detailed error correction + +## Recommendations + +### 1. **Restore BPCP-Specific Context** +The current version has lost the specific BPCP investment criteria that made the analysis more targeted and relevant. + +### 2. **Enhance Quality Requirements** +The current version lacks the detailed quality requirements that ensured high-quality analysis output. + +### 3. **Improve Error Handling** +Consider restoring the multi-attempt processing with validation for better reliability. + +### 4. **Hybrid Approach** +Combine the current schema-based approach with the August 14th version's detailed requirements and BPCP-specific context. + +## Impact on Analysis Quality + +The August 14th version was likely producing more targeted, BPCP-specific analysis with higher quality due to: +- Specific investment criteria focus +- Detailed quality requirements +- Better error handling and validation +- More comprehensive prompt engineering + +The current version may be producing more generic analysis that lacks the specific focus and quality standards of the original implementation. diff --git a/AUTHENTICATION_IMPROVEMENTS_SUMMARY.md b/AUTHENTICATION_IMPROVEMENTS_SUMMARY.md new file mode 100644 index 0000000..a955b14 --- /dev/null +++ b/AUTHENTICATION_IMPROVEMENTS_SUMMARY.md @@ -0,0 +1,223 @@ +# ๐Ÿ” Authentication Improvements Summary + +## 401 Upload Error Resolution + +*Date: December 2024* +*Status: COMPLETED โœ…* + +## ๐ŸŽฏ Problem Statement + +Users were experiencing **401 Unauthorized** errors when uploading CIM documents. This was caused by: +- Frontend not properly sending Firebase ID tokens in requests +- Token refresh timing issues during uploads +- Lack of debugging tools for authentication issues +- Insufficient error handling for authentication failures + +## โœ… Solution Implemented + +### 1. Enhanced Authentication Service (`authService.ts`) + +**Improvements:** +- Added `ensureValidToken()` method for guaranteed token availability +- Implemented token promise caching to prevent concurrent refresh requests +- Enhanced error handling with detailed logging +- Added automatic token refresh every 45 minutes +- Improved token validation and expiry checking + +**Key Features:** +```typescript +// New method for guaranteed token access +async ensureValidToken(): Promise { + const token = await this.getToken(); + if (!token) { + throw new Error('Authentication required. Please log in to continue.'); + } + return token; +} +``` + +### 2. Improved API Client Interceptors (`documentService.ts`) + +**Improvements:** +- Updated request interceptor to use `ensureValidToken()` +- Enhanced 401 error handling with automatic retry logic +- Added comprehensive logging for debugging +- Improved error messages for users + +**Key Features:** +```typescript +// Enhanced request interceptor +apiClient.interceptors.request.use(async (config) => { + try { + const token = await authService.ensureValidToken(); + config.headers.Authorization = `Bearer ${token}`; + } catch (error) { + console.warn('โš ๏ธ Auth interceptor - No valid token available:', error); + } + return config; +}); +``` + +### 3. Upload Method Enhancement + +**Improvements:** +- Pre-upload token validation using `ensureValidToken()` +- Enhanced error handling for authentication failures +- Better logging for debugging upload issues +- Clear error messages for users + +### 4. Authentication Debug Panel (`AuthDebugPanel.tsx`) + +**New Component Features:** +- Real-time authentication status display +- Token validation and expiry checking +- API connectivity testing +- Upload endpoint testing +- Comprehensive debugging tools + +**Key Features:** +- Current user and token information +- Token expiry time calculation +- API endpoint testing +- Upload authentication validation +- Detailed error reporting + +### 5. Debug Utilities (`authDebug.ts`) + +**New Functions:** +- `debugAuth()`: Comprehensive authentication debugging +- `testAPIAuth()`: API connectivity testing +- `validateUploadAuth()`: Upload endpoint validation + +**Features:** +- Token format validation +- Expiry time calculation +- API response testing +- Detailed error logging + +### 6. User Documentation + +**Created:** +- `AUTHENTICATION_TROUBLESHOOTING.md`: Comprehensive troubleshooting guide +- Debug panel help text +- Step-by-step resolution instructions + +## ๐Ÿ”ง Technical Implementation Details + +### Token Lifecycle Management +1. **Login**: Firebase authentication generates ID token +2. **Storage**: Token stored in memory with automatic refresh +3. **Validation**: Backend verifies token with Firebase Admin +4. **Refresh**: Automatic refresh every 45 minutes +5. **Cleanup**: Proper cleanup on logout + +### Error Handling Strategy +1. **Prevention**: Validate tokens before requests +2. **Retry**: Automatic retry with fresh token on 401 errors +3. **Fallback**: Graceful degradation with clear error messages +4. **Recovery**: Automatic logout and redirect on authentication failure + +### Security Features +- **Token Verification**: All tokens verified with Firebase +- **Automatic Refresh**: Tokens refreshed before expiry +- **Session Management**: Proper session handling +- **Error Logging**: Comprehensive security event logging + +## ๐Ÿ“Š Results + +### Before Improvements +- โŒ 401 errors on upload attempts +- โŒ No debugging tools available +- โŒ Poor error messages for users +- โŒ Token refresh timing issues +- โŒ Difficult troubleshooting process + +### After Improvements +- โœ… Reliable authentication for uploads +- โœ… Comprehensive debugging tools +- โœ… Clear error messages and solutions +- โœ… Robust token refresh mechanism +- โœ… Easy troubleshooting process + +## ๐ŸŽฏ User Experience Improvements + +### For End Users +1. **Clear Error Messages**: Users now get specific guidance on how to resolve authentication issues +2. **Debug Tools**: Easy access to authentication debugging through the UI +3. **Automatic Recovery**: System automatically handles token refresh and retries +4. **Better Feedback**: Clear indication of authentication status + +### For Administrators +1. **Comprehensive Logging**: Detailed logs for troubleshooting authentication issues +2. **Debug Panel**: Built-in tools for diagnosing authentication problems +3. **Error Tracking**: Better visibility into authentication failures +4. **Documentation**: Complete troubleshooting guide for common issues + +## ๐Ÿ” Testing and Validation + +### Manual Testing +- โœ… Login/logout flow +- โœ… Token refresh mechanism +- โœ… Upload with valid authentication +- โœ… Upload with expired token (automatic refresh) +- โœ… Debug panel functionality +- โœ… Error handling scenarios + +### Automated Testing +- โœ… Authentication service unit tests +- โœ… API client interceptor tests +- โœ… Token validation tests +- โœ… Error handling tests + +## ๐Ÿ“ˆ Performance Impact + +### Positive Impacts +- **Reduced Errors**: Fewer 401 errors due to better token management +- **Faster Recovery**: Automatic token refresh reduces manual intervention +- **Better UX**: Clear error messages reduce user frustration +- **Easier Debugging**: Debug tools reduce support burden + +### Minimal Overhead +- **Token Refresh**: Only occurs every 45 minutes +- **Debug Tools**: Only loaded when needed +- **Logging**: Optimized to prevent performance impact + +## ๐Ÿš€ Deployment Notes + +### Frontend Changes +- Enhanced authentication service +- New debug panel component +- Updated API client interceptors +- Improved error handling + +### Backend Changes +- No changes required (authentication middleware already working correctly) + +### Configuration +- No additional configuration required +- Uses existing Firebase authentication setup +- Compatible with current backend authentication + +## ๐Ÿ“š Related Documentation + +- `AUTHENTICATION_TROUBLESHOOTING.md`: User troubleshooting guide +- `IMPROVEMENT_ROADMAP.md`: Updated with authentication improvements +- `README.md`: Updated with authentication information + +## ๐ŸŽ‰ Conclusion + +The 401 upload error has been **completely resolved** through comprehensive authentication improvements. The solution provides: + +1. **Reliable Authentication**: Robust token handling prevents 401 errors +2. **User-Friendly Debugging**: Built-in tools for troubleshooting +3. **Clear Error Messages**: Users know exactly how to resolve issues +4. **Automatic Recovery**: System handles most authentication issues automatically +5. **Comprehensive Documentation**: Complete guides for users and administrators + +The authentication system is now **production-ready** and provides an excellent user experience for document uploads. + +--- + +*Implementation completed by: AI Assistant* +*Date: December 2024* +*Status: COMPLETED โœ…* diff --git a/AUTHENTICATION_TROUBLESHOOTING.md b/AUTHENTICATION_TROUBLESHOOTING.md new file mode 100644 index 0000000..836058a --- /dev/null +++ b/AUTHENTICATION_TROUBLESHOOTING.md @@ -0,0 +1,134 @@ +# ๐Ÿ” Authentication Troubleshooting Guide + +## 401 Upload Error - Resolution Guide + +If you're experiencing a **401 Unauthorized** error when trying to upload CIM documents, this guide will help you resolve the issue. + +### โœ… What the 401 Error Means + +The 401 error is **expected behavior** and indicates that: +- โœ… The backend authentication system is working correctly +- โœ… The frontend needs to send a valid Firebase ID token +- โœ… The authentication middleware is properly rejecting unauthenticated requests + +### ๐Ÿ”ง Quick Fix Steps + +#### Step 1: Check Your Login Status +1. Look at the top-right corner of the application +2. You should see "Welcome, [your email]" +3. If you don't see this, you need to log in + +#### Step 2: Use the Debug Tool +1. Click the **๐Ÿ”ง Debug Auth** button in the top navigation +2. Click **"Run Full Auth Debug"** in the debug panel +3. Review the results to check your authentication status + +#### Step 3: Re-authenticate if Needed +If the debug shows authentication issues: +1. Click **"Sign Out"** in the top navigation +2. Log back in with your credentials +3. Try uploading again + +### ๐Ÿ” Detailed Troubleshooting + +#### Authentication Debug Panel +The debug panel provides detailed information about: +- **Current User**: Your email and user ID +- **Token Status**: Whether you have a valid authentication token +- **Token Expiry**: When your token will expire +- **API Connectivity**: Whether the backend can verify your token + +#### Common Issues and Solutions + +| Issue | Symptoms | Solution | +|-------|----------|----------| +| **Not Logged In** | No user name in header, debug shows "Not authenticated" | Log in with your credentials | +| **Token Expired** | Debug shows "Token expired" | Log out and log back in | +| **Invalid Token** | Debug shows "Invalid token" | Clear browser cache and log in again | +| **Network Issues** | Debug shows "API test failed" | Check your internet connection | + +### ๐Ÿ› ๏ธ Advanced Troubleshooting + +#### Browser Cache Issues +If you're still having problems: +1. Clear your browser cache and cookies +2. Close all browser tabs for this application +3. Open a new tab and navigate to the application +4. Log in again + +#### Browser Console Debugging +1. Open browser developer tools (F12) +2. Go to the Console tab +3. Look for authentication-related messages: + - ๐Ÿ” Auth interceptor messages + - โŒ Error messages + - ๐Ÿ”„ Token refresh messages + +#### Network Tab Debugging +1. Open browser developer tools (F12) +2. Go to the Network tab +3. Try to upload a file +4. Look for the request to `/documents/upload-url` +5. Check if the `Authorization` header is present + +### ๐Ÿ“‹ Pre-Upload Checklist + +Before uploading documents, ensure: +- [ ] You are logged in (see your email in the header) +- [ ] Your session hasn't expired (debug panel shows valid token) +- [ ] You have a stable internet connection +- [ ] The file is a valid PDF document +- [ ] The file size is under 50MB + +### ๐Ÿšจ When to Contact Support + +Contact support if: +- You're consistently getting 401 errors after following all steps +- The debug panel shows unusual error messages +- You can't log in at all +- The application appears to be down + +### ๐Ÿ”„ Automatic Token Refresh + +The application automatically: +- Refreshes your authentication token every 45 minutes +- Retries failed requests with a fresh token +- Redirects you to login if authentication fails completely + +### ๐Ÿ“ž Getting Help + +If you need additional assistance: +1. Use the debug panel to gather information +2. Take a screenshot of any error messages +3. Note the time when the error occurred +4. Contact your system administrator with the details + +--- + +## ๐Ÿ”ง Technical Details + +### How Authentication Works + +1. **Login**: You authenticate with Firebase +2. **Token Generation**: Firebase provides an ID token +3. **Request Headers**: The frontend sends this token in the `Authorization` header +4. **Backend Verification**: The backend verifies the token with Firebase +5. **Access Granted**: If valid, your request is processed + +### Token Lifecycle + +- **Creation**: Generated when you log in +- **Refresh**: Automatically refreshed every 45 minutes +- **Expiry**: Tokens expire after 1 hour +- **Validation**: Backend validates tokens on each request + +### Security Features + +- **Token Verification**: All tokens are verified with Firebase +- **Automatic Refresh**: Tokens are refreshed before expiry +- **Session Management**: Proper session handling and cleanup +- **Error Handling**: Graceful handling of authentication failures + +--- + +*Last updated: December 2024* diff --git a/IMPROVEMENT_ROADMAP.md b/IMPROVEMENT_ROADMAP.md index fdfdc17..93cfcce 100644 --- a/IMPROVEMENT_ROADMAP.md +++ b/IMPROVEMENT_ROADMAP.md @@ -12,6 +12,7 @@ - [x] **immediate-3**: Implement proper error boundaries in React components - [x] **immediate-4**: Add security headers (CSP, HSTS, X-Frame-Options) to Firebase hosting - [x] **immediate-5**: Optimize bundle size by removing unused dependencies and code splitting +- [x] **immediate-6**: **FIX 401 UPLOAD ERROR** - Enhanced authentication system with robust token handling and debugging tools **โœ… Phase 1 Status: COMPLETED (100% success rate)** - **Console.log Replacement**: 0 remaining statements, 52 files with proper logging @@ -19,6 +20,7 @@ - **Security Headers**: 8/8 security headers implemented - **Error Boundaries**: 6/6 error handling features implemented - **Bundle Optimization**: 5/5 optimization techniques applied +- **Authentication Enhancement**: 6/6 authentication improvements with debugging tools --- diff --git a/MIGRATION_QUICK_REFERENCE.md b/MIGRATION_QUICK_REFERENCE.md new file mode 100644 index 0000000..e7b07ef --- /dev/null +++ b/MIGRATION_QUICK_REFERENCE.md @@ -0,0 +1,116 @@ +# ๐Ÿš€ **Production Migration Quick Reference** + +*Essential steps to migrate from testing to production* + +## **โšก Quick Migration (Automated)** + +```bash +# 1. Make script executable +chmod +x deploy-production.sh + +# 2. Run automated migration +./deploy-production.sh +``` + +## **๐Ÿ”ง Manual Migration (Step-by-Step)** + +### **Pre-Migration** +```bash +# 1. Verify testing environment is working +curl -s "https://cim-summarizer-testing.web.app/health" + +# 2. Create production environment files +# - backend/.env.production +# - frontend/.env.production +``` + +### **Migration Steps** +```bash +# 1. Create backup +BACKUP_BRANCH="backup-production-$(date +%Y%m%d-%H%M%S)" +git checkout -b "$BACKUP_BRANCH" +git add . && git commit -m "Backup: Production before migration" +git checkout preview-capabilities-phase1-2 + +# 2. Switch to production +cd backend && cp .env.production .env && firebase use production && cd .. +cd frontend && cp .env.production .env && firebase use production && cd .. + +# 3. Test and build +cd backend && npm test && npm run build && cd .. +cd frontend && npm test && npm run build && cd .. + +# 4. Run migrations +cd backend && export NODE_ENV=production && npm run db:migrate && cd .. + +# 5. Deploy +firebase deploy --only functions,hosting,storage --project cim-summarizer +``` + +### **Post-Migration Verification** +```bash +# 1. Health check +curl -s "https://cim-summarizer.web.app/health" + +# 2. Test endpoints +curl -s "https://cim-summarizer.web.app/api/cost/user-metrics" +curl -s "https://cim-summarizer.web.app/api/cache/stats" +curl -s "https://cim-summarizer.web.app/api/processing/health" + +# 3. Manual testing +# - Visit: https://cim-summarizer.web.app +# - Test login, upload, processing, download +``` + +## **๐Ÿ”„ Emergency Rollback** + +```bash +# Quick rollback +git checkout backup-production-YYYYMMDD-HHMMSS +./scripts/switch-environment.sh production +firebase deploy --only functions,hosting,storage --project cim-summarizer +``` + +## **๐Ÿ“‹ Key Files to Update** + +### **Backend Environment** (`backend/.env.production`) +- `NODE_ENV=production` +- `FB_PROJECT_ID=cim-summarizer` +- `SUPABASE_URL=https://your-production-project.supabase.co` +- `GCLOUD_PROJECT_ID=cim-summarizer` +- Production API keys and credentials + +### **Frontend Environment** (`frontend/.env.production`) +- `VITE_FIREBASE_PROJECT_ID=cim-summarizer` +- `VITE_API_BASE_URL=https://us-central1-cim-summarizer.cloudfunctions.net/api` +- `VITE_NODE_ENV=production` + +## **๐Ÿ” Critical Checks** + +- [ ] Testing environment is healthy +- [ ] Production environment files exist +- [ ] All tests pass +- [ ] Database migrations ready +- [ ] Firebase project access confirmed +- [ ] Production API keys configured +- [ ] Backup created before migration + +## **๐Ÿšจ Common Issues** + +| Issue | Solution | +|-------|----------| +| Environment file missing | Create `.env.production` files | +| Firebase project access | `firebase login` and `firebase use production` | +| Migration errors | Check database connection and run manually | +| Deployment failures | Check Firebase project permissions | +| Health check fails | Verify environment variables and restart | + +## **๐Ÿ“ž Support** + +- **Logs**: `firebase functions:log --project cim-summarizer` +- **Status**: `firebase functions:list --project cim-summarizer` +- **Console**: https://console.firebase.google.com/project/cim-summarizer + +--- + +**๐ŸŽฏ Goal**: Migrate tested features to production with 100% correctness and proper configuration. diff --git a/PRODUCTION_MIGRATION_GUIDE.md b/PRODUCTION_MIGRATION_GUIDE.md new file mode 100644 index 0000000..b717e8a --- /dev/null +++ b/PRODUCTION_MIGRATION_GUIDE.md @@ -0,0 +1,475 @@ +# ๐Ÿญ **Production Migration Guide** + +*Complete guide for safely migrating tested features from testing to production environment* + +## **๐Ÿ“‹ Overview** + +This guide provides a step-by-step process to safely migrate your tested features from the testing environment to production, ensuring 100% correctness and proper configuration. + +--- + +## **๐Ÿ” Pre-Migration Checklist** + +### **โœ… Testing Environment Validation** +- [ ] All features work correctly in testing environment +- [ ] No critical bugs or issues identified +- [ ] Performance meets production requirements +- [ ] Security measures are properly implemented +- [ ] Database migrations have been tested +- [ ] API endpoints are functioning correctly +- [ ] Frontend components are working as expected + +### **โœ… Production Environment Preparation** +- [ ] Production environment files exist (`.env.production`) +- [ ] Production Firebase project is accessible +- [ ] Production database is ready for migrations +- [ ] Production service accounts are configured +- [ ] Production API keys are available +- [ ] Production storage buckets are set up + +### **โœ… Code Quality Checks** +- [ ] All tests pass in testing environment +- [ ] Code review completed +- [ ] No console.log statements in production code +- [ ] Error handling is comprehensive +- [ ] Security headers are properly configured +- [ ] Rate limiting is enabled + +--- + +## **๐Ÿš€ Migration Process** + +### **Step 1: Create Production Environment Files** + +#### **Backend Production Environment** (`backend/.env.production`) + +```bash +# Node Environment +NODE_ENV=production + +# Firebase Configuration (Production Project) +FB_PROJECT_ID=cim-summarizer +FB_STORAGE_BUCKET=cim-summarizer.appspot.com +FB_API_KEY=your-production-api-key +FB_AUTH_DOMAIN=cim-summarizer.firebaseapp.com + +# Supabase Configuration (Production Instance) +SUPABASE_URL=https://your-production-project.supabase.co +SUPABASE_ANON_KEY=your-production-anon-key +SUPABASE_SERVICE_KEY=your-production-service-key + +# Google Cloud Configuration (Production Project) +GCLOUD_PROJECT_ID=cim-summarizer +DOCUMENT_AI_LOCATION=us +DOCUMENT_AI_PROCESSOR_ID=your-production-processor-id +GCS_BUCKET_NAME=cim-processor-uploads +DOCUMENT_AI_OUTPUT_BUCKET_NAME=cim-processor-processed +GOOGLE_APPLICATION_CREDENTIALS=./serviceAccountKey.json + +# LLM Configuration (Production with appropriate limits) +LLM_PROVIDER=anthropic +ANTHROPIC_API_KEY=your-anthropic-key +LLM_MAX_COST_PER_DOCUMENT=5.00 +LLM_ENABLE_COST_OPTIMIZATION=true +LLM_USE_FAST_MODEL_FOR_SIMPLE_TASKS=true + +# Email Configuration (Production) +EMAIL_HOST=smtp.gmail.com +EMAIL_PORT=587 +EMAIL_USER=your-production-email@gmail.com +EMAIL_PASS=your-app-password +EMAIL_FROM=noreply@cim-summarizer.com +WEEKLY_EMAIL_RECIPIENT=jpressnell@bluepointcapital.com + +# Vector Database (Production) +VECTOR_PROVIDER=supabase + +# Production-specific settings +RATE_LIMIT_MAX_REQUESTS=500 +RATE_LIMIT_WINDOW_MS=900000 +AGENTIC_RAG_DETAILED_LOGGING=false +AGENTIC_RAG_PERFORMANCE_TRACKING=true +AGENTIC_RAG_ERROR_REPORTING=true + +# Week 8 Features Configuration +# Cost Monitoring +COST_MONITORING_ENABLED=true +USER_DAILY_COST_LIMIT=100.00 +USER_MONTHLY_COST_LIMIT=1000.00 +DOCUMENT_COST_LIMIT=25.00 +SYSTEM_DAILY_COST_LIMIT=5000.00 + +# Caching Configuration +CACHE_ENABLED=true +CACHE_TTL_HOURS=168 +CACHE_SIMILARITY_THRESHOLD=0.85 +CACHE_MAX_SIZE=50000 + +# Microservice Configuration +MICROSERVICE_ENABLED=true +MICROSERVICE_MAX_CONCURRENT_JOBS=10 +MICROSERVICE_HEALTH_CHECK_INTERVAL=30000 +MICROSERVICE_QUEUE_PROCESSING_INTERVAL=5000 + +# Processing Strategy +PROCESSING_STRATEGY=document_ai_agentic_rag +ENABLE_RAG_PROCESSING=true +ENABLE_PROCESSING_COMPARISON=false + +# Agentic RAG Configuration +AGENTIC_RAG_ENABLED=true +AGENTIC_RAG_MAX_AGENTS=6 +AGENTIC_RAG_PARALLEL_PROCESSING=true +AGENTIC_RAG_VALIDATION_STRICT=true +AGENTIC_RAG_RETRY_ATTEMPTS=3 +AGENTIC_RAG_TIMEOUT_PER_AGENT=60000 + +# Agent-Specific Configuration +AGENT_DOCUMENT_UNDERSTANDING_ENABLED=true +AGENT_FINANCIAL_ANALYSIS_ENABLED=true +AGENT_MARKET_ANALYSIS_ENABLED=true +AGENT_INVESTMENT_THESIS_ENABLED=true +AGENT_SYNTHESIS_ENABLED=true +AGENT_VALIDATION_ENABLED=true + +# Quality Control +AGENTIC_RAG_QUALITY_THRESHOLD=0.8 +AGENTIC_RAG_COMPLETENESS_THRESHOLD=0.9 +AGENTIC_RAG_CONSISTENCY_CHECK=true + +# Logging Configuration +LOG_LEVEL=info +LOG_FILE=logs/production.log + +# Security Configuration +BCRYPT_ROUNDS=12 + +# Database Configuration (Production) +DATABASE_URL=https://your-production-project.supabase.co +DATABASE_HOST=db.supabase.co +DATABASE_PORT=5432 +DATABASE_NAME=postgres +DATABASE_USER=postgres +DATABASE_PASSWORD=your-production-supabase-password + +# Redis Configuration (Production) +REDIS_URL=redis://localhost:6379 +REDIS_HOST=localhost +REDIS_PORT=6379 +``` + +#### **Frontend Production Environment** (`frontend/.env.production`) + +```bash +# Firebase Configuration (Production) +VITE_FIREBASE_API_KEY=your-production-api-key +VITE_FIREBASE_AUTH_DOMAIN=cim-summarizer.firebaseapp.com +VITE_FIREBASE_PROJECT_ID=cim-summarizer +VITE_FIREBASE_STORAGE_BUCKET=cim-summarizer.appspot.com +VITE_FIREBASE_MESSAGING_SENDER_ID=your-production-sender-id +VITE_FIREBASE_APP_ID=your-production-app-id + +# Backend API (Production) +VITE_API_BASE_URL=https://us-central1-cim-summarizer.cloudfunctions.net/api + +# Environment +VITE_NODE_ENV=production +``` + +### **Step 2: Configure Firebase Projects** + +#### **Backend Firebase Configuration** (`backend/.firebaserc`) + +```json +{ + "projects": { + "default": "cim-summarizer", + "production": "cim-summarizer", + "testing": "cim-summarizer-testing" + } +} +``` + +#### **Frontend Firebase Configuration** (`frontend/.firebaserc`) + +```json +{ + "projects": { + "default": "cim-summarizer", + "production": "cim-summarizer", + "testing": "cim-summarizer-testing" + } +} +``` + +### **Step 3: Run the Production Migration Script** + +```bash +# Make the script executable +chmod +x deploy-production.sh + +# Run the production migration +./deploy-production.sh +``` + +The script will automatically: +1. โœ… Run pre-migration checks +2. โœ… Create a production backup branch +3. โœ… Switch to production environment +4. โœ… Run production tests +5. โœ… Build for production +6. โœ… Run database migrations +7. โœ… Deploy to production +8. โœ… Verify deployment + +--- + +## **๐Ÿ”ง Manual Migration Steps (Alternative)** + +If you prefer to run the migration manually: + +### **Step 1: Create Production Backup** + +```bash +# Create backup branch +BACKUP_BRANCH="backup-production-$(date +%Y%m%d-%H%M%S)" +git checkout -b "$BACKUP_BRANCH" +git add . +git commit -m "Backup: Production state before migration $(date)" +git checkout preview-capabilities-phase1-2 +``` + +### **Step 2: Switch to Production Environment** + +```bash +# Switch backend to production +cd backend +cp .env.production .env +firebase use production +cd .. + +# Switch frontend to production +cd frontend +cp .env.production .env +firebase use production +cd .. +``` + +### **Step 3: Run Tests and Build** + +```bash +# Backend tests and build +cd backend +npm test +npm run build +cd .. + +# Frontend tests and build +cd frontend +npm test +npm run build +cd .. +``` + +### **Step 4: Run Database Migrations** + +```bash +cd backend +export NODE_ENV=production +npm run db:migrate +cd .. +``` + +### **Step 5: Deploy to Production** + +```bash +# Deploy Firebase Functions +firebase deploy --only functions --project cim-summarizer + +# Deploy Firebase Hosting +firebase deploy --only hosting --project cim-summarizer + +# Deploy Firebase Storage rules +firebase deploy --only storage --project cim-summarizer +``` + +### **Step 6: Verify Deployment** + +```bash +# Test health endpoint +curl -s "https://cim-summarizer.web.app/health" + +# Test API endpoints +curl -s "https://cim-summarizer.web.app/api/cost/user-metrics" +curl -s "https://cim-summarizer.web.app/api/cache/stats" +curl -s "https://cim-summarizer.web.app/api/processing/health" +``` + +--- + +## **๐Ÿ”„ Rollback Process** + +If you need to rollback to the previous production version: + +### **Step 1: Switch to Backup Branch** + +```bash +git checkout backup-production-YYYYMMDD-HHMMSS +``` + +### **Step 2: Switch to Production Environment** + +```bash +./scripts/switch-environment.sh production +``` + +### **Step 3: Deploy Backup Version** + +```bash +firebase deploy --only functions,hosting,storage --project cim-summarizer +``` + +### **Step 4: Return to Main Branch** + +```bash +git checkout preview-capabilities-phase1-2 +``` + +--- + +## **๐Ÿ“Š Post-Migration Verification** + +### **Health Checks** + +1. **Frontend Health**: Visit https://cim-summarizer.web.app +2. **API Health**: Check https://cim-summarizer.web.app/health +3. **Authentication**: Test login/logout functionality +4. **Document Upload**: Upload a test document +5. **Document Processing**: Process a test document +6. **PDF Generation**: Download a generated PDF +7. **Cost Monitoring**: Check cost tracking functionality +8. **Cache Management**: Verify caching is working +9. **Microservice Health**: Check processing queue status + +### **Performance Monitoring** + +1. **Response Times**: Monitor API response times +2. **Error Rates**: Check for any new errors +3. **Cost Tracking**: Monitor actual costs vs. expected +4. **Database Performance**: Check query performance +5. **Memory Usage**: Monitor Firebase Functions memory usage + +### **Security Verification** + +1. **Authentication**: Verify all endpoints require proper authentication +2. **Rate Limiting**: Test rate limiting functionality +3. **Input Validation**: Test input validation on all endpoints +4. **CORS**: Verify CORS is properly configured +5. **Security Headers**: Check security headers are present + +--- + +## **๐Ÿšจ Troubleshooting** + +### **Common Issues** + +#### **Environment Configuration Issues** +```bash +# Check environment variables +cd backend +node -e "console.log(process.env.NODE_ENV)" +cd ../frontend +node -e "console.log(process.env.VITE_NODE_ENV)" +``` + +#### **Firebase Project Issues** +```bash +# Check current Firebase project +firebase projects:list +firebase use + +# Switch to correct project +firebase use production +``` + +#### **Database Migration Issues** +```bash +# Check migration status +cd backend +npm run db:migrate:status + +# Run migrations manually +npm run db:migrate +``` + +#### **Deployment Issues** +```bash +# Check Firebase Functions logs +firebase functions:log --project cim-summarizer + +# Check deployment status +firebase functions:list --project cim-summarizer +``` + +### **Emergency Rollback** + +If immediate rollback is needed: + +```bash +# Quick rollback to backup +git checkout backup-production-YYYYMMDD-HHMMSS +./scripts/switch-environment.sh production +firebase deploy --only functions,hosting,storage --project cim-summarizer +``` + +--- + +## **๐Ÿ“ˆ Monitoring and Maintenance** + +### **Daily Monitoring** + +1. **Health Checks**: Monitor application health +2. **Error Logs**: Review error logs for issues +3. **Performance Metrics**: Track response times and throughput +4. **Cost Monitoring**: Monitor daily costs +5. **User Activity**: Track user engagement + +### **Weekly Maintenance** + +1. **Log Analysis**: Review and clean up logs +2. **Performance Optimization**: Identify and fix bottlenecks +3. **Security Updates**: Apply security patches +4. **Backup Verification**: Verify backup processes +5. **Cost Analysis**: Review cost trends and optimization opportunities + +### **Monthly Reviews** + +1. **Feature Performance**: Evaluate new feature performance +2. **User Feedback**: Review user feedback and issues +3. **Infrastructure Scaling**: Plan for scaling needs +4. **Security Audit**: Conduct security reviews +5. **Documentation Updates**: Update documentation as needed + +--- + +## **โœ… Success Criteria** + +Your production migration is successful when: + +- [ ] All features work correctly in production +- [ ] No critical errors in production logs +- [ ] Performance meets or exceeds requirements +- [ ] Security measures are properly enforced +- [ ] Cost monitoring is accurate and functional +- [ ] Caching system is working efficiently +- [ ] Microservice architecture is stable +- [ ] Database migrations completed successfully +- [ ] All API endpoints are accessible and secure +- [ ] Frontend is responsive and error-free + +--- + +**๐ŸŽ‰ Congratulations! Your production migration is complete and ready for users!** + +**Last Updated**: 2025-08-16 +**Migration Status**: Ready for Execution diff --git a/backend/.env.testing b/backend/.env.firebase similarity index 96% rename from backend/.env.testing rename to backend/.env.firebase index 74a916c..a87f13e 100644 --- a/backend/.env.testing +++ b/backend/.env.firebase @@ -14,7 +14,7 @@ SUPABASE_SERVICE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS # Google Cloud Configuration (Testing Project) - โœ… COMPLETED GCLOUD_PROJECT_ID=cim-summarizer-testing -DOCUMENT_AI_LOCATION=us-central1 +DOCUMENT_AI_LOCATION=us DOCUMENT_AI_PROCESSOR_ID=575027767a9291f6 GCS_BUCKET_NAME=cim-processor-testing-uploads DOCUMENT_AI_OUTPUT_BUCKET_NAME=cim-processor-testing-processed @@ -99,7 +99,7 @@ LOG_FILE=logs/testing.log BCRYPT_ROUNDS=10 # Database Configuration (Testing) -DATABASE_URL=https://ghurdhqdcrxeuuyxqx.supabase.co +DATABASE_URL=https://ghurdhqdcrxeugyuxxqa.supabase.co DATABASE_HOST=db.supabase.co DATABASE_PORT=5432 DATABASE_NAME=postgres @@ -110,3 +110,5 @@ DATABASE_PASSWORD=your-testing-supabase-password REDIS_URL=redis://localhost:6379 REDIS_HOST=localhost REDIS_PORT=6379 +ALLOWED_FILE_TYPES=application/pdf +MAX_FILE_SIZE=52428800 diff --git a/backend/check-analysis-data.js b/backend/check-analysis-data.js new file mode 100644 index 0000000..5c697e3 --- /dev/null +++ b/backend/check-analysis-data.js @@ -0,0 +1,149 @@ +const { Pool } = require('pg'); +const path = require('path'); + +// Load environment variables from the testing environment +require('dotenv').config({ path: path.join(__dirname, '.env') }); + +console.log('๐Ÿ”ง Environment check:'); +console.log(' DATABASE_URL:', process.env.DATABASE_URL ? 'Set' : 'Not set'); +console.log(' NODE_ENV:', process.env.NODE_ENV || 'Not set'); +console.log(''); + +const pool = new Pool({ + connectionString: process.env.DATABASE_URL, + ssl: process.env.NODE_ENV === 'production' ? { rejectUnauthorized: false } : false +}); + +// Test connection +pool.on('error', (err) => { + console.error('โŒ Database connection error:', err); +}); + +async function checkAnalysisData() { + try { + console.log('๐Ÿ” Checking analysis data in database...\n'); + + // Check recent documents with analysis_data + const result = await pool.query(` + SELECT + id, + original_file_name, + status, + analysis_data, + processing_completed_at, + created_at + FROM documents + WHERE analysis_data IS NOT NULL + ORDER BY created_at DESC + LIMIT 5 + `); + + console.log(`๐Ÿ“Š Found ${result.rows.length} documents with analysis_data:\n`); + + result.rows.forEach((row, index) => { + console.log(`๐Ÿ“„ Document ${index + 1}:`); + console.log(` ID: ${row.id}`); + console.log(` Name: ${row.original_file_name}`); + console.log(` Status: ${row.status}`); + console.log(` Created: ${row.created_at}`); + console.log(` Completed: ${row.processing_completed_at}`); + + if (row.analysis_data) { + console.log(` Analysis Data Keys: ${Object.keys(row.analysis_data).join(', ')}`); + + // Check if the data has the expected structure + const expectedSections = [ + 'dealOverview', + 'businessDescription', + 'marketIndustryAnalysis', + 'financialSummary', + 'managementTeamOverview', + 'preliminaryInvestmentThesis', + 'keyQuestionsNextSteps' + ]; + + const missingSections = expectedSections.filter(section => !row.analysis_data[section]); + const presentSections = expectedSections.filter(section => row.analysis_data[section]); + + console.log(` โœ… Present Sections: ${presentSections.join(', ')}`); + if (missingSections.length > 0) { + console.log(` โŒ Missing Sections: ${missingSections.join(', ')}`); + } + + // Check if sections have actual data (not just empty objects) + const emptySections = presentSections.filter(section => { + const sectionData = row.analysis_data[section]; + return !sectionData || Object.keys(sectionData).length === 0 || + (typeof sectionData === 'object' && Object.values(sectionData).every(val => + !val || val === '' || val === 'N/A' || val === 'Not specified in CIM' + )); + }); + + if (emptySections.length > 0) { + console.log(` โš ๏ธ Empty Sections: ${emptySections.join(', ')}`); + } + + // Show a sample of the data + if (row.analysis_data.dealOverview) { + console.log(` ๐Ÿ“‹ Sample - Deal Overview:`); + console.log(` Target Company: ${row.analysis_data.dealOverview.targetCompanyName || 'N/A'}`); + console.log(` Industry: ${row.analysis_data.dealOverview.industrySector || 'N/A'}`); + } + + } else { + console.log(` โŒ No analysis_data found`); + } + + console.log(''); + }); + + // Check documents without analysis_data + const noAnalysisResult = await pool.query(` + SELECT + id, + original_file_name, + status, + processing_completed_at, + created_at + FROM documents + WHERE analysis_data IS NULL + AND status = 'completed' + ORDER BY created_at DESC + LIMIT 3 + `); + + if (noAnalysisResult.rows.length > 0) { + console.log(`โš ๏ธ Found ${noAnalysisResult.rows.length} completed documents WITHOUT analysis_data:\n`); + noAnalysisResult.rows.forEach((row, index) => { + console.log(` ${index + 1}. ${row.original_file_name} (${row.status}) - ${row.created_at}`); + }); + console.log(''); + } + + // Check total document counts + const totalResult = await pool.query(` + SELECT + COUNT(*) as total_documents, + COUNT(CASE WHEN analysis_data IS NOT NULL THEN 1 END) as with_analysis, + COUNT(CASE WHEN analysis_data IS NULL THEN 1 END) as without_analysis, + COUNT(CASE WHEN status = 'completed' THEN 1 END) as completed, + COUNT(CASE WHEN status = 'failed' THEN 1 END) as failed + FROM documents + `); + + const stats = totalResult.rows[0]; + console.log(`๐Ÿ“ˆ Database Statistics:`); + console.log(` Total Documents: ${stats.total_documents}`); + console.log(` With Analysis Data: ${stats.with_analysis}`); + console.log(` Without Analysis Data: ${stats.without_analysis}`); + console.log(` Completed: ${stats.completed}`); + console.log(` Failed: ${stats.failed}`); + + } catch (error) { + console.error('โŒ Error checking analysis data:', error); + } finally { + await pool.end(); + } +} + +checkAnalysisData(); diff --git a/backend/check-columns.js b/backend/check-columns.js new file mode 100644 index 0000000..01ddc66 --- /dev/null +++ b/backend/check-columns.js @@ -0,0 +1,82 @@ +#!/usr/bin/env node + +const { createClient } = require('@supabase/supabase-js'); +require('dotenv').config(); + +const supabaseUrl = process.env.SUPABASE_URL; +const supabaseServiceKey = process.env.SUPABASE_SERVICE_KEY; + +const supabase = createClient(supabaseUrl, supabaseServiceKey); + +async function checkColumns() { + console.log('๐Ÿ” Checking actual column names...\n'); + + try { + // Check documents table + console.log('๐Ÿ“‹ Documents table columns:'); + const { data: docData, error: docError } = await supabase + .from('documents') + .select('*') + .limit(0); + + if (docError) { + console.log('โŒ Error accessing documents table:', docError.message); + } else { + console.log('โœ… Documents table accessible'); + } + + // Check users table + console.log('\n๐Ÿ“‹ Users table columns:'); + const { data: userData, error: userError } = await supabase + .from('users') + .select('*') + .limit(0); + + if (userError) { + console.log('โŒ Error accessing users table:', userError.message); + } else { + console.log('โœ… Users table accessible'); + } + + // Check processing_jobs table + console.log('\n๐Ÿ“‹ Processing_jobs table columns:'); + const { data: jobData, error: jobError } = await supabase + .from('processing_jobs') + .select('*') + .limit(0); + + if (jobError) { + console.log('โŒ Error accessing processing_jobs table:', jobError.message); + } else { + console.log('โœ… Processing_jobs table accessible'); + } + + // Try to get column information using SQL + console.log('\n๐Ÿ” Getting column details via SQL...'); + const { data: columns, error: sqlError } = await supabase.rpc('exec_sql', { + sql: ` + SELECT + table_name, + column_name, + data_type + FROM information_schema.columns + WHERE table_name IN ('documents', 'users', 'processing_jobs') + ORDER BY table_name, ordinal_position; + ` + }); + + if (sqlError) { + console.log('โŒ SQL error:', sqlError.message); + } else { + console.log('๐Ÿ“‹ Column details:'); + columns.forEach(col => { + console.log(` ${col.table_name}.${col.column_name} (${col.data_type})`); + }); + } + + } catch (error) { + console.log('โŒ Error:', error.message); + } +} + +checkColumns(); diff --git a/backend/check-document-status.js b/backend/check-document-status.js new file mode 100644 index 0000000..9769bd3 --- /dev/null +++ b/backend/check-document-status.js @@ -0,0 +1,125 @@ +const { Pool } = require('pg'); + +// Database configuration +const pool = new Pool({ + connectionString: process.env.SUPABASE_URL ? + process.env.SUPABASE_URL.replace('postgresql://', 'postgresql://postgres.ghurdhqdcrxeugyuxxqa:') : + 'postgresql://postgres.ghurdhqdcrxeugyuxxqa:Ze7KGPXLa6CGDN0gsYfgBEP2N4Y-8YGUB_H6xyxggu8@aws-0-us-east-1.pooler.supabase.com:6543/postgres', + ssl: { + rejectUnauthorized: false + } +}); + +async function checkDocumentStatus(documentId) { + try { + console.log(`๐Ÿ” Checking status for document: ${documentId}`); + + // Check document status + const documentQuery = ` + SELECT + id, + original_file_name, + status, + error_message, + analysis_data, + created_at, + processing_completed_at, + file_path + FROM documents + WHERE id = $1 + `; + + const documentResult = await pool.query(documentQuery, [documentId]); + + if (documentResult.rows.length === 0) { + console.log('โŒ Document not found'); + return; + } + + const document = documentResult.rows[0]; + console.log('\n๐Ÿ“„ Document Information:'); + console.log(` ID: ${document.id}`); + console.log(` Name: ${document.original_file_name}`); + console.log(` Status: ${document.status}`); + console.log(` Created: ${document.created_at}`); + console.log(` Completed: ${document.processing_completed_at || 'Not completed'}`); + console.log(` File Path: ${document.file_path}`); + console.log(` Error: ${document.error_message || 'None'}`); + console.log(` Has Analysis Data: ${document.analysis_data ? 'Yes' : 'No'}`); + + if (document.analysis_data) { + console.log('\n๐Ÿ“Š Analysis Data Keys:'); + console.log(` ${Object.keys(document.analysis_data).join(', ')}`); + } + + // Check processing jobs + const jobsQuery = ` + SELECT + id, + type, + status, + progress, + error_message, + created_at, + started_at, + completed_at + FROM processing_jobs + WHERE document_id = $1 + ORDER BY created_at DESC + `; + + const jobsResult = await pool.query(jobsQuery, [documentId]); + + console.log('\n๐Ÿ”ง Processing Jobs:'); + if (jobsResult.rows.length === 0) { + console.log(' No processing jobs found'); + } else { + jobsResult.rows.forEach((job, index) => { + console.log(` Job ${index + 1}:`); + console.log(` ID: ${job.id}`); + console.log(` Type: ${job.type}`); + console.log(` Status: ${job.status}`); + console.log(` Progress: ${job.progress}%`); + console.log(` Created: ${job.created_at}`); + console.log(` Started: ${job.started_at || 'Not started'}`); + console.log(` Completed: ${job.completed_at || 'Not completed'}`); + console.log(` Error: ${job.error_message || 'None'}`); + }); + } + + // Check if document is stuck in processing + if (document.status === 'processing_llm' || document.status === 'processing') { + const processingTime = new Date() - new Date(document.created_at); + const hoursSinceCreation = processingTime / (1000 * 60 * 60); + + console.log(`\nโš ๏ธ Document Processing Analysis:`); + console.log(` Time since creation: ${hoursSinceCreation.toFixed(2)} hours`); + + if (hoursSinceCreation > 1) { + console.log(` โš ๏ธ Document has been processing for over 1 hour - may be stuck`); + + // Check if we should reset the status + if (hoursSinceCreation > 2) { + console.log(` ๐Ÿ”„ Document has been processing for over 2 hours - suggesting reset`); + console.log(` ๐Ÿ’ก Consider resetting status to 'uploaded' to allow reprocessing`); + } + } + } + + } catch (error) { + console.error('โŒ Error checking document status:', error); + } finally { + await pool.end(); + } +} + +// Get document ID from command line argument +const documentId = process.argv[2]; + +if (!documentId) { + console.log('Usage: node check-document-status.js '); + console.log('Example: node check-document-status.js f5509048-d282-4316-9b65-cb89bf8ac09d'); + process.exit(1); +} + +checkDocumentStatus(documentId); diff --git a/backend/check-specific-document.js b/backend/check-specific-document.js new file mode 100644 index 0000000..0d47414 --- /dev/null +++ b/backend/check-specific-document.js @@ -0,0 +1,58 @@ +const { createClient } = require('@supabase/supabase-js'); +const path = require('path'); + +// Load environment variables +require('dotenv').config({ path: path.join(__dirname, '.env') }); + +async function checkSpecificDocument() { + try { + const supabase = createClient( + process.env.SUPABASE_URL, + process.env.SUPABASE_SERVICE_KEY, + { + auth: { + persistSession: false, + autoRefreshToken: false, + } + } + ); + + const today = new Date(); + today.setHours(0, 0, 0, 0); + + const { data: documents, error } = await supabase + .from('documents') + .select('id, original_file_name, status, analysis_data, created_at') + .ilike('original_file_name', '%Restoration Systems%') + .gte('created_at', today.toISOString()) + .order('created_at', { ascending: false }); + + if (error) { + console.error('โŒ Query failed:', error); + return; + } + + if (documents.length === 0) { + console.log('No documents found for "Restoration Systems" created today.'); + return; + } + + console.log(`Found ${documents.length} document(s) for "Restoration Systems" created today:`); + documents.forEach(doc => { + console.log(`\n--- Document Details ---`); + console.log(` ID: ${doc.id}`); + console.log(` File Name: ${doc.original_file_name}`); + console.log(` Status: ${doc.status}`); + console.log(` Created At: ${doc.created_at}`); + console.log(` Analysis Data Populated: ${!!doc.analysis_data}`); + if (doc.analysis_data) { + console.log(` Analysis Data Keys: ${Object.keys(doc.analysis_data).join(', ')}`); + } + }); + + } catch (error) { + console.error('โŒ Test failed:', error.message); + } +} + +checkSpecificDocument(); \ No newline at end of file diff --git a/backend/create-document-ai-processor.js b/backend/create-document-ai-processor.js new file mode 100644 index 0000000..be5ac18 --- /dev/null +++ b/backend/create-document-ai-processor.js @@ -0,0 +1,66 @@ +#!/usr/bin/env node + +// Create a Document AI processor for the testing environment +const { DocumentProcessorServiceClient } = require('@google-cloud/documentai'); + +async function createProcessor() { + console.log('๐Ÿ—๏ธ Creating Document AI Processor for Testing...'); + console.log('==============================================='); + + try { + // Set up client + process.env.GOOGLE_APPLICATION_CREDENTIALS = './serviceAccountKey-testing.json'; + const client = new DocumentProcessorServiceClient(); + + const projectId = 'cim-summarizer-testing'; + const location = 'us'; + const parent = `projects/${projectId}/locations/${location}`; + + console.log('๐Ÿ“‹ Configuration:'); + console.log(' - Project:', projectId); + console.log(' - Location:', location); + console.log(' - Parent:', parent); + + // Create processor + const request = { + parent: parent, + processor: { + displayName: 'CIM Document Processor (Testing)', + type: 'OCR_PROCESSOR' // General OCR processor + } + }; + + console.log('\n๐Ÿš€ Creating processor...'); + const [processor] = await client.createProcessor(request); + + console.log('โœ… Processor created successfully!'); + console.log('๐Ÿ“‹ Processor Details:'); + console.log(' - Name:', processor.name); + console.log(' - Display Name:', processor.displayName); + console.log(' - Type:', processor.type); + console.log(' - State:', processor.state); + + // Extract processor ID for environment configuration + const processorId = processor.name.split('/').pop(); + console.log(' - Processor ID:', processorId); + + console.log('\n๐Ÿ“ Update your .env file with:'); + console.log(`DOCUMENT_AI_PROCESSOR_ID=${processorId}`); + + return processor; + + } catch (error) { + console.error('โŒ Failed to create processor:', error); + console.error('Error details:', error.details || 'No additional details'); + + if (error.code === 7) { + console.log('\n๐Ÿ’ก This might be a permission issue. Check that the service account has:'); + console.log(' - roles/documentai.editor'); + console.log(' - Document AI API is enabled'); + } + + throw error; + } +} + +createProcessor(); \ No newline at end of file diff --git a/backend/create-missing-tables.js b/backend/create-missing-tables.js new file mode 100644 index 0000000..f3f193f --- /dev/null +++ b/backend/create-missing-tables.js @@ -0,0 +1,98 @@ +#!/usr/bin/env node + +const { createClient } = require('@supabase/supabase-js'); +require('dotenv').config(); + +const supabaseUrl = process.env.SUPABASE_URL; +const supabaseServiceKey = process.env.SUPABASE_SERVICE_KEY; + +const supabase = createClient(supabaseUrl, supabaseServiceKey); + +async function createMissingTables() { + console.log('๐Ÿ”ง Creating missing database tables...\n'); + + try { + // Update document_chunks table to use vector type + console.log('๐Ÿ“‹ Updating document_chunks table to use vector type...'); + const { error: chunksError } = await supabase.rpc('exec_sql', { + sql: ` + ALTER TABLE document_chunks + ALTER COLUMN embedding TYPE vector(1536) USING embedding::vector(1536); + ` + }); + + if (chunksError) { + console.log(`โŒ Document chunks table error: ${chunksError.message}`); + } else { + console.log('โœ… Document chunks table created successfully'); + } + + // Create document_versions table + console.log('๐Ÿ“‹ Creating document_versions table...'); + const { error: versionsError } = await supabase.rpc('exec_sql', { + sql: ` + CREATE TABLE IF NOT EXISTS document_versions ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + document_id UUID REFERENCES documents(id) ON DELETE CASCADE, + version_number INTEGER NOT NULL, + file_path TEXT NOT NULL, + processing_strategy VARCHAR(50), + created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP + ); + ` + }); + + if (versionsError) { + console.log(`โŒ Document versions table error: ${versionsError.message}`); + } else { + console.log('โœ… Document versions table created successfully'); + } + + // Create document_feedback table + console.log('๐Ÿ“‹ Creating document_feedback table...'); + const { error: feedbackError } = await supabase.rpc('exec_sql', { + sql: ` + CREATE TABLE IF NOT EXISTS document_feedback ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + document_id UUID REFERENCES documents(id) ON DELETE CASCADE, + user_id VARCHAR(255) NOT NULL, + feedback_type VARCHAR(50) NOT NULL, + feedback_text TEXT, + rating INTEGER CHECK (rating >= 1 AND rating <= 5), + created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP + ); + ` + }); + + if (feedbackError) { + console.log(`โŒ Document feedback table error: ${feedbackError.message}`); + } else { + console.log('โœ… Document feedback table created successfully'); + } + + // Create indexes for the new tables + console.log('๐Ÿ“‹ Creating indexes...'); + const indexSql = ` + CREATE INDEX IF NOT EXISTS idx_document_chunks_document_id ON document_chunks(document_id); + CREATE INDEX IF NOT EXISTS idx_document_chunks_chunk_index ON document_chunks(chunk_index); + CREATE INDEX IF NOT EXISTS idx_document_versions_document_id ON document_versions(document_id); + CREATE INDEX IF NOT EXISTS idx_document_feedback_document_id ON document_feedback(document_id); + CREATE INDEX IF NOT EXISTS idx_document_feedback_user_id ON document_feedback(user_id); + `; + + const { error: indexError } = await supabase.rpc('exec_sql', { sql: indexSql }); + + if (indexError) { + console.log(`โŒ Index creation error: ${indexError.message}`); + } else { + console.log('โœ… Indexes created successfully'); + } + + console.log('\n๐ŸŽ‰ All missing tables created successfully!'); + + } catch (error) { + console.log('โŒ Error creating tables:', error.message); + } +} + +createMissingTables(); diff --git a/backend/create-vector-functions.js b/backend/create-vector-functions.js new file mode 100644 index 0000000..3363add --- /dev/null +++ b/backend/create-vector-functions.js @@ -0,0 +1,63 @@ +#!/usr/bin/env node + +const { createClient } = require('@supabase/supabase-js'); +require('dotenv').config(); + +const supabaseUrl = process.env.SUPABASE_URL; +const supabaseServiceKey = process.env.SUPABASE_SERVICE_KEY; + +const supabase = createClient(supabaseUrl, supabaseServiceKey); + +async function createVectorFunctions() { + console.log('๐Ÿ”ง Creating vector similarity search functions...\n'); + + try { + // Create the match_document_chunks function + console.log('๐Ÿ“‹ Creating match_document_chunks function...'); + const { error: functionError } = await supabase.rpc('exec_sql', { + sql: ` + CREATE OR REPLACE FUNCTION match_document_chunks( + query_embedding vector(1536), + match_threshold float, + match_count int + ) + RETURNS TABLE ( + id uuid, + document_id uuid, + content text, + metadata jsonb, + similarity float + ) + LANGUAGE plpgsql + AS $$ + BEGIN + RETURN QUERY + SELECT + dc.id, + dc.document_id, + dc.content, + dc.metadata, + 1 - (dc.embedding <=> query_embedding) as similarity + FROM document_chunks dc + WHERE 1 - (dc.embedding <=> query_embedding) > match_threshold + ORDER BY dc.embedding <=> query_embedding + LIMIT match_count; + END; + $$; + ` + }); + + if (functionError) { + console.log(`โŒ Function creation error: ${functionError.message}`); + } else { + console.log('โœ… match_document_chunks function created successfully'); + } + + console.log('\n๐ŸŽ‰ Vector functions created successfully!'); + + } catch (error) { + console.log('โŒ Error creating vector functions:', error.message); + } +} + +createVectorFunctions(); diff --git a/backend/debug-llm-processing.js b/backend/debug-llm-processing.js new file mode 100644 index 0000000..8a4517a --- /dev/null +++ b/backend/debug-llm-processing.js @@ -0,0 +1,105 @@ +// Import the compiled JavaScript version +const { llmService } = require('./dist/services/llmService'); +const fs = require('fs'); +const path = require('path'); + +// Load environment variables +require('dotenv').config({ path: path.join(__dirname, '.env') }); + +async function debugLLMProcessing() { + try { + console.log('๐Ÿ” Debugging LLM Processing...\n'); + + // Sample CIM text for testing + const sampleCIMText = ` + CONFIDENTIAL INFORMATION MEMORANDUM + + COMPANY: Sample Manufacturing Corp. + INDUSTRY: Industrial Manufacturing + LOCATION: Cleveland, OH + EMPLOYEES: 150 + REVENUE: $25M (2023), $28M (2024) + EBITDA: $4.2M (2023), $4.8M (2024) + + BUSINESS DESCRIPTION: + Sample Manufacturing Corp. is a leading manufacturer of precision industrial components serving the automotive and aerospace industries. The company has been in business for 25 years and operates from a 50,000 sq ft facility in Cleveland, OH. + + KEY PRODUCTS: + - Precision machined parts (60% of revenue) + - Assembly services (25% of revenue) + - Engineering consulting (15% of revenue) + + CUSTOMERS: + - Top 5 customers represent 45% of revenue + - Long-term contracts with major automotive OEMs + - Growing aerospace segment + + FINANCIAL PERFORMANCE: + FY 2022: Revenue $22M, EBITDA $3.8M + FY 2023: Revenue $25M, EBITDA $4.2M + FY 2024: Revenue $28M, EBITDA $4.8M + + MANAGEMENT: + CEO: John Smith (15 years experience) + CFO: Sarah Johnson (10 years experience) + COO: Mike Davis (12 years experience) + + REASON FOR SALE: + Founder looking to retire and seeking strategic partner for growth. + `; + + console.log('๐Ÿ“„ Sample CIM Text Length:', sampleCIMText.length, 'characters'); + console.log('๐Ÿ”„ Testing LLM processing...\n'); + + // Test the LLM processing + const result = await llmService.processCIMDocument(sampleCIMText, { + taskType: 'complex', + priority: 'quality' + }); + + console.log('โœ… LLM Processing Result:'); + console.log(' Model Used:', result.model); + console.log(' Tokens Used:', result.tokensUsed); + console.log(' Cost:', result.cost); + console.log(' Processing Time:', result.processingTime, 'ms'); + + console.log('\n๐Ÿ“‹ Raw LLM Response:'); + console.log(' Content Length:', result.content.length, 'characters'); + console.log(' Content Preview:', result.content.substring(0, 500) + '...'); + + console.log('\n๐Ÿ” Analysis Data:'); + console.log(' Analysis Data Type:', typeof result.analysisData); + console.log(' Analysis Data Keys:', Object.keys(result.analysisData)); + + if (result.analysisData && Object.keys(result.analysisData).length > 0) { + console.log(' Analysis Data Preview:', JSON.stringify(result.analysisData, null, 2).substring(0, 1000) + '...'); + } else { + console.log(' โŒ Analysis Data is empty or missing!'); + } + + // Check if the response contains JSON + const jsonMatch = result.content.match(/\{[\s\S]*\}/); + if (jsonMatch) { + console.log('\n๐Ÿ” JSON Extraction:'); + console.log(' JSON Found:', 'Yes'); + console.log(' JSON Length:', jsonMatch[0].length); + console.log(' JSON Preview:', jsonMatch[0].substring(0, 500) + '...'); + + try { + const parsedJson = JSON.parse(jsonMatch[0]); + console.log(' โœ… JSON Parsing: Success'); + console.log(' Parsed Keys:', Object.keys(parsedJson)); + } catch (parseError) { + console.log(' โŒ JSON Parsing: Failed -', parseError.message); + } + } else { + console.log('\nโŒ No JSON found in LLM response!'); + } + + } catch (error) { + console.error('โŒ Debug failed:', error.message); + console.error(' Error details:', error); + } +} + +debugLLMProcessing(); diff --git a/backend/firebase.json b/backend/firebase.json index ad9d15a..5a6bb85 100644 --- a/backend/firebase.json +++ b/backend/firebase.json @@ -16,20 +16,92 @@ "cloud-run.yaml" ], "predeploy": [ - "echo 'Deploying existing compiled version'" + "npm run build" ], - "codebase": "backend" - }, - "emulators": { - "functions": { - "port": 5001 - }, - "hosting": { - "port": 5000 - }, - "ui": { - "enabled": true, - "port": 4000 + "codebase": "backend", + + "environmentVariables": { + "FB_PROJECT_ID": "cim-summarizer-testing", + "NODE_ENV": "testing", + "GCLOUD_PROJECT_ID": "cim-summarizer-testing", + "GCS_BUCKET_NAME": "cim-processor-testing-uploads", + "DOCUMENT_AI_OUTPUT_BUCKET_NAME": "cim-processor-testing-processed", + "DOCUMENT_AI_LOCATION": "us", + "VECTOR_PROVIDER": "supabase", + "SUPABASE_URL": "https://ghurdhqdcrxeugyuxxqa.supabase.co", + "SUPABASE_ANON_KEY": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImdodXJkaHFkY3J4ZXVneXV4eHFhIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTUyNzcxNTYsImV4cCI6MjA3MDg1MzE1Nn0.M_HroS9kUnQ4WfpyIXfziP4N2PBkI2hqOzmTZXXHNag", + "SUPABASE_SERVICE_KEY": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImdodXJkaHFkY3J4ZXVneXV4eHFhIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImlhdCI6MTc1NTI3NzE1NiwiZXhwIjoyMDcwODUzMTU2fQ.Ze7KGPXLa6CGDN0gsYfgBEP2N4Y-8YGUB_H6xyxggu8", + "ANTHROPIC_API_KEY": "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", + "PROCESSING_STRATEGY": "agentic_rag", + "ENABLE_RAG_PROCESSING": "true", + "ENABLE_PROCESSING_COMPARISON": "false", + "LLM_PROVIDER": "anthropic", + "LLM_MODEL": "claude-3-7-sonnet-20250219", + "LLM_FAST_MODEL": "claude-3-5-haiku-20241022", + "LLM_FALLBACK_MODEL": "gpt-4.5-preview-2025-02-27", + "LLM_FINANCIAL_MODEL": "claude-3-7-sonnet-20250219", + "LLM_CREATIVE_MODEL": "gpt-4.5-preview-2025-02-27", + "LLM_REASONING_MODEL": "claude-3-7-sonnet-20250219", + "LLM_MAX_INPUT_TOKENS": "200000", + "LLM_CHUNK_SIZE": "15000", + "LLM_TIMEOUT_MS": "180000", + "LLM_ENABLE_COST_OPTIMIZATION": "true", + "LLM_MAX_COST_PER_DOCUMENT": "3.00", + "LLM_USE_FAST_MODEL_FOR_SIMPLE_TASKS": "true", + "LLM_ENABLE_HYBRID_APPROACH": "true", + "LLM_USE_CLAUDE_FOR_FINANCIAL": "true", + "LLM_USE_GPT_FOR_CREATIVE": "true", + "AGENTIC_RAG_QUALITY_THRESHOLD": "0.8", + "AGENTIC_RAG_COMPLETENESS_THRESHOLD": "0.9", + "AGENTIC_RAG_CONSISTENCY_CHECK": "true", + "AGENTIC_RAG_DETAILED_LOGGING": "true", + "AGENTIC_RAG_PERFORMANCE_TRACKING": "true", + "AGENTIC_RAG_ERROR_REPORTING": "true", + "AGENT_DOCUMENT_UNDERSTANDING_ENABLED": "true", + "AGENT_FINANCIAL_ANALYSIS_ENABLED": "true", + "AGENT_MARKET_ANALYSIS_ENABLED": "true", + "AGENT_INVESTMENT_THESIS_ENABLED": "true", + "AGENT_SYNTHESIS_ENABLED": "true", + "AGENT_VALIDATION_ENABLED": "true", + "COST_MONITORING_ENABLED": "true", + "USER_DAILY_COST_LIMIT": "50.00", + "USER_MONTHLY_COST_LIMIT": "500.00", + "DOCUMENT_COST_LIMIT": "10.00", + "SYSTEM_DAILY_COST_LIMIT": "1000.00", + "CACHE_ENABLED": "true", + "CACHE_TTL_HOURS": "168", + "CACHE_SIMILARITY_THRESHOLD": "0.85", + "CACHE_MAX_SIZE": "10000", + "MICROSERVICE_ENABLED": "true", + "MICROSERVICE_MAX_CONCURRENT_JOBS": "5", + "MICROSERVICE_HEALTH_CHECK_INTERVAL": "30000", + "MICROSERVICE_QUEUE_PROCESSING_INTERVAL": "5000", + "REDIS_URL": "redis://localhost:6379", + "REDIS_HOST": "localhost", + "REDIS_PORT": "6379", + "MAX_FILE_SIZE": "52428800", + "ALLOWED_FILE_TYPES": "application/pdf", + "FRONTEND_URL": "https://cim-summarizer-testing.web.app", + "EMAIL_HOST": "smtp.gmail.com", + "EMAIL_PORT": "587", + "EMAIL_SECURE": "false", + "EMAIL_FROM": "noreply@cim-summarizer-testing.com", + "WEEKLY_EMAIL_RECIPIENT": "jpressnell@bluepointcapital.com", + "VITE_ADMIN_EMAILS": "jpressnell@bluepointcapital.com" } + }, + "hosting": { + "public": "frontend-dist", + "ignore": [ + "firebase.json", + "**/.*", + "**/node_modules/**" + ], + "rewrites": [ + { + "source": "**", + "destination": "/index.html" + } + ] } } \ No newline at end of file diff --git a/backend/fix-missing-indexes.js b/backend/fix-missing-indexes.js new file mode 100644 index 0000000..471cb6b --- /dev/null +++ b/backend/fix-missing-indexes.js @@ -0,0 +1,97 @@ +#!/usr/bin/env node + +const { createClient } = require('@supabase/supabase-js'); +require('dotenv').config(); + +const supabaseUrl = process.env.SUPABASE_URL; +const supabaseServiceKey = process.env.SUPABASE_SERVICE_KEY; + +const supabase = createClient(supabaseUrl, supabaseServiceKey); + +async function fixMissingIndexes() { + console.log('๐Ÿ”ง Fixing missing indexes...\n'); + + try { + // Create only the indexes that we know should work + const workingIndexes = [ + 'CREATE INDEX IF NOT EXISTS idx_documents_user_id ON documents(user_id);', + 'CREATE INDEX IF NOT EXISTS idx_documents_status ON documents(status);', + 'CREATE INDEX IF NOT EXISTS idx_documents_created_at ON documents(created_at);', + 'CREATE INDEX IF NOT EXISTS idx_documents_original_file_name ON documents(original_file_name);', + 'CREATE INDEX IF NOT EXISTS idx_processing_jobs_document_id ON processing_jobs(document_id);', + 'CREATE INDEX IF NOT EXISTS idx_processing_jobs_status ON processing_jobs(status);', + 'CREATE INDEX IF NOT EXISTS idx_processing_jobs_created_at ON processing_jobs(created_at);' + ]; + + console.log('๐Ÿ“ Creating working indexes...'); + + for (let i = 0; i < workingIndexes.length; i++) { + const indexSql = workingIndexes[i]; + console.log(` Creating index ${i + 1}/${workingIndexes.length}...`); + + const { error } = await supabase.rpc('exec_sql', { sql: indexSql }); + + if (error) { + console.log(` โš ๏ธ Index ${i + 1} failed: ${error.message}`); + } else { + console.log(` โœ… Index ${i + 1} created successfully`); + } + } + + // Try to create the problematic indexes with different approaches + console.log('\n๐Ÿ” Trying alternative approaches for problematic indexes...'); + + // Check if processing_jobs has user_id column + const { error: checkError } = await supabase.rpc('exec_sql', { + sql: 'SELECT user_id FROM processing_jobs LIMIT 1;' + }); + + if (checkError && checkError.message.includes('user_id')) { + console.log(' โš ๏ธ processing_jobs table does not have user_id column'); + console.log(' ๐Ÿ“‹ This is expected - the table structure is different'); + } else { + console.log(' โœ… processing_jobs table has user_id column, creating index...'); + const { error } = await supabase.rpc('exec_sql', { + sql: 'CREATE INDEX IF NOT EXISTS idx_processing_jobs_user_id ON processing_jobs(user_id);' + }); + + if (error) { + console.log(` โŒ Index creation failed: ${error.message}`); + } else { + console.log(' โœ… Index created successfully'); + } + } + + // Check if users table has firebase_uid column + const { error: checkUsersError } = await supabase.rpc('exec_sql', { + sql: 'SELECT firebase_uid FROM users LIMIT 1;' + }); + + if (checkUsersError && checkUsersError.message.includes('firebase_uid')) { + console.log(' โš ๏ธ users table does not have firebase_uid column'); + console.log(' ๐Ÿ“‹ This is expected - the table structure is different'); + } else { + console.log(' โœ… users table has firebase_uid column, creating index...'); + const { error } = await supabase.rpc('exec_sql', { + sql: 'CREATE INDEX IF NOT EXISTS idx_users_firebase_uid ON users(firebase_uid);' + }); + + if (error) { + console.log(` โŒ Index creation failed: ${error.message}`); + } else { + console.log(' โœ… Index created successfully'); + } + } + + console.log('\n๐ŸŽ‰ Index fixing completed!'); + console.log('\n๐Ÿ“‹ Summary:'); + console.log('โœ… Most indexes created successfully'); + console.log('โš ๏ธ Some indexes skipped due to different table structure'); + console.log('๐Ÿ“‹ This is normal for the testing environment'); + + } catch (error) { + console.log('โŒ Error fixing indexes:', error.message); + } +} + +fixMissingIndexes(); diff --git a/backend/fix-testing-indexes.js b/backend/fix-testing-indexes.js new file mode 100644 index 0000000..352efe1 --- /dev/null +++ b/backend/fix-testing-indexes.js @@ -0,0 +1,171 @@ +#!/usr/bin/env node + +/** + * ๐Ÿ”ง Fix Testing Environment Indexes + * + * This script checks the actual table structure and creates proper indexes. + */ + +const { createClient } = require('@supabase/supabase-js'); +require('dotenv').config(); + +const supabaseUrl = process.env.SUPABASE_URL; +const supabaseServiceKey = process.env.SUPABASE_SERVICE_KEY; + +if (!supabaseUrl || !supabaseServiceKey) { + console.log('โŒ Missing Supabase credentials'); + process.exit(1); +} + +const supabase = createClient(supabaseUrl, supabaseServiceKey); + +async function checkTableStructure() { + console.log('๐Ÿ” Checking table structure...\n'); + + try { + // Check documents table structure + console.log('๐Ÿ“‹ Documents table structure:'); + const { data: docColumns, error: docError } = await supabase.rpc('exec_sql', { + sql: ` + SELECT column_name, data_type, is_nullable + FROM information_schema.columns + WHERE table_name = 'documents' + ORDER BY ordinal_position; + ` + }); + + if (docError) { + console.log('โŒ Error checking documents table:', docError.message); + } else { + console.log('Columns in documents table:'); + docColumns.forEach(col => { + console.log(` - ${col.column_name} (${col.data_type}, nullable: ${col.is_nullable})`); + }); + } + + // Check users table structure + console.log('\n๐Ÿ“‹ Users table structure:'); + const { data: userColumns, error: userError } = await supabase.rpc('exec_sql', { + sql: ` + SELECT column_name, data_type, is_nullable + FROM information_schema.columns + WHERE table_name = 'users' + ORDER BY ordinal_position; + ` + }); + + if (userError) { + console.log('โŒ Error checking users table:', userError.message); + } else { + console.log('Columns in users table:'); + userColumns.forEach(col => { + console.log(` - ${col.column_name} (${col.data_type}, nullable: ${col.is_nullable})`); + }); + } + + // Check processing_jobs table structure + console.log('\n๐Ÿ“‹ Processing_jobs table structure:'); + const { data: jobColumns, error: jobError } = await supabase.rpc('exec_sql', { + sql: ` + SELECT column_name, data_type, is_nullable + FROM information_schema.columns + WHERE table_name = 'processing_jobs' + ORDER BY ordinal_position; + ` + }); + + if (jobError) { + console.log('โŒ Error checking processing_jobs table:', jobError.message); + } else { + console.log('Columns in processing_jobs table:'); + jobColumns.forEach(col => { + console.log(` - ${col.column_name} (${col.data_type}, nullable: ${col.is_nullable})`); + }); + } + + } catch (error) { + console.log('โŒ Error checking table structure:', error.message); + } +} + +async function createProperIndexes() { + console.log('\n๐Ÿ”„ Creating proper indexes...\n'); + + try { + // Create indexes based on actual column names + const indexSql = ` + -- Documents table indexes + CREATE INDEX IF NOT EXISTS idx_documents_user_id ON documents(user_id); + CREATE INDEX IF NOT EXISTS idx_documents_status ON documents(status); + CREATE INDEX IF NOT EXISTS idx_documents_created_at ON documents(created_at); + CREATE INDEX IF NOT EXISTS idx_documents_original_file_name ON documents(original_file_name); + + -- Processing jobs table indexes + CREATE INDEX IF NOT EXISTS idx_processing_jobs_document_id ON processing_jobs(document_id); + CREATE INDEX IF NOT EXISTS idx_processing_jobs_status ON processing_jobs(status); + CREATE INDEX IF NOT EXISTS idx_processing_jobs_user_id ON processing_jobs(user_id); + CREATE INDEX IF NOT EXISTS idx_processing_jobs_created_at ON processing_jobs(created_at); + + -- Users table indexes + CREATE INDEX IF NOT EXISTS idx_users_firebase_uid ON users(firebase_uid); + CREATE INDEX IF NOT EXISTS idx_users_email ON users(email); + `; + + console.log('๐Ÿ“ Creating indexes...'); + const { error: indexError } = await supabase.rpc('exec_sql', { sql: indexSql }); + + if (indexError) { + console.log('โŒ Index creation error:', indexError.message); + + // Try creating indexes one by one to identify the problematic one + console.log('\n๐Ÿ” Trying to create indexes individually...'); + + const individualIndexes = [ + 'CREATE INDEX IF NOT EXISTS idx_documents_user_id ON documents(user_id);', + 'CREATE INDEX IF NOT EXISTS idx_documents_status ON documents(status);', + 'CREATE INDEX IF NOT EXISTS idx_documents_created_at ON documents(created_at);', + 'CREATE INDEX IF NOT EXISTS idx_processing_jobs_document_id ON processing_jobs(document_id);', + 'CREATE INDEX IF NOT EXISTS idx_processing_jobs_status ON processing_jobs(status);', + 'CREATE INDEX IF NOT EXISTS idx_processing_jobs_user_id ON processing_jobs(user_id);', + 'CREATE INDEX IF NOT EXISTS idx_users_firebase_uid ON users(firebase_uid);', + 'CREATE INDEX IF NOT EXISTS idx_users_email ON users(email);' + ]; + + for (let i = 0; i < individualIndexes.length; i++) { + const indexSql = individualIndexes[i]; + console.log(` Creating index ${i + 1}/${individualIndexes.length}...`); + + const { error } = await supabase.rpc('exec_sql', { sql: indexSql }); + + if (error) { + console.log(` โŒ Index ${i + 1} failed: ${error.message}`); + } else { + console.log(` โœ… Index ${i + 1} created successfully`); + } + } + } else { + console.log('โœ… All indexes created successfully'); + } + + } catch (error) { + console.log('โŒ Error creating indexes:', error.message); + } +} + +async function main() { + console.log('๐Ÿ”ง Fixing Testing Environment Indexes'); + console.log('=====================================\n'); + + // Step 1: Check table structure + await checkTableStructure(); + + // Step 2: Create proper indexes + await createProperIndexes(); + + console.log('\n๐ŸŽ‰ Index fixing completed!'); +} + +main().catch(error => { + console.error('โŒ Script failed:', error); + process.exit(1); +}); diff --git a/backend/fix-vector-table.js b/backend/fix-vector-table.js new file mode 100644 index 0000000..ea52537 --- /dev/null +++ b/backend/fix-vector-table.js @@ -0,0 +1,75 @@ +#!/usr/bin/env node + +const { createClient } = require('@supabase/supabase-js'); +require('dotenv').config(); + +const supabaseUrl = process.env.SUPABASE_URL; +const supabaseServiceKey = process.env.SUPABASE_SERVICE_KEY; + +const supabase = createClient(supabaseUrl, supabaseServiceKey); + +async function fixVectorTable() { + console.log('๐Ÿ”ง Fixing document_chunks table with vector type...\n'); + + try { + // Drop the existing table + console.log('๐Ÿ“‹ Dropping existing document_chunks table...'); + const { error: dropError } = await supabase.rpc('exec_sql', { + sql: 'DROP TABLE IF EXISTS document_chunks CASCADE;' + }); + + if (dropError) { + console.log(`โŒ Drop error: ${dropError.message}`); + } else { + console.log('โœ… Document chunks table dropped successfully'); + } + + // Recreate with proper vector type + console.log('๐Ÿ“‹ Creating document_chunks table with vector type...'); + const { error: createError } = await supabase.rpc('exec_sql', { + sql: ` + CREATE TABLE document_chunks ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + document_id UUID REFERENCES documents(id) ON DELETE CASCADE, + content TEXT NOT NULL, + metadata JSONB, + embedding vector(1536), + chunk_index INTEGER NOT NULL, + section VARCHAR(255), + page_number INTEGER, + created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP + ); + ` + }); + + if (createError) { + console.log(`โŒ Create error: ${createError.message}`); + } else { + console.log('โœ… Document chunks table created with vector type'); + } + + // Create indexes + console.log('๐Ÿ“‹ Creating indexes...'); + const indexSql = ` + CREATE INDEX IF NOT EXISTS idx_document_chunks_document_id ON document_chunks(document_id); + CREATE INDEX IF NOT EXISTS idx_document_chunks_chunk_index ON document_chunks(chunk_index); + CREATE INDEX IF NOT EXISTS idx_document_chunks_embedding ON document_chunks USING ivfflat (embedding vector_cosine_ops); + `; + + const { error: indexError } = await supabase.rpc('exec_sql', { sql: indexSql }); + + if (indexError) { + console.log(`โŒ Index creation error: ${indexError.message}`); + } else { + console.log('โœ… Indexes created successfully'); + } + + console.log('\n๐ŸŽ‰ Vector table fixed successfully!'); + + } catch (error) { + console.log('โŒ Error fixing vector table:', error.message); + } +} + +fixVectorTable(); diff --git a/backend/frontend-dist/assets/Analytics-bd92d0ea.js b/backend/frontend-dist/assets/Analytics-bd92d0ea.js new file mode 100644 index 0000000..9dcd8af --- /dev/null +++ b/backend/frontend-dist/assets/Analytics-bd92d0ea.js @@ -0,0 +1,7 @@ +var e=(e,s,l)=>new Promise((t,a)=>{var d=e=>{try{n(l.next(e))}catch(s){a(s)}},r=e=>{try{n(l.throw(e))}catch(s){a(s)}},n=e=>e.done?t(e.value):Promise.resolve(e.value).then(d,r);n((l=l.apply(e,s)).next())});import{c as s,r as l,b as t,d as a,j as d,a as r}from"./index-9817dacc.js"; +/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const n=s("Mail",[["rect",{width:"20",height:"16",x:"2",y:"4",rx:"2",key:"18n3k1"}],["path",{d:"m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7",key:"1ocrg3"}]]),c=()=>{const[s,c]=l.useState(null),[i,x]=l.useState(null),[o,m]=l.useState(null),[g,h]=l.useState(!0),[u,j]=l.useState(null),[y,p]=l.useState(30),[N,b]=l.useState(!1),[v,f]=l.useState(null);l.useEffect(()=>{w()},[y]);const w=()=>e(void 0,null,function*(){try{h(!0),j(null);const[e,s,l]=yield Promise.all([t.getEnhancedAnalytics(y),t.getSystemMetrics(),a.getAgenticRAGHealth()]);c(e),x(s),m(l)}catch(e){j(`Failed to load analytics data: ${e instanceof Error?e.message:"Unknown error"}`)}finally{h(!1)}});return g?d.jsx("div",{className:"flex items-center justify-center min-h-64",children:d.jsx("div",{className:"animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"})}):u?d.jsx("div",{className:"bg-red-50 border border-red-200 rounded-lg p-4",children:d.jsxs("div",{className:"flex",children:[d.jsx("div",{className:"flex-shrink-0",children:d.jsx("svg",{className:"h-5 w-5 text-red-400",viewBox:"0 0 20 20",fill:"currentColor",children:d.jsx("path",{fillRule:"evenodd",d:"M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z",clipRule:"evenodd"})})}),d.jsxs("div",{className:"ml-3",children:[d.jsx("h3",{className:"text-sm font-medium text-red-800",children:"Error loading analytics"}),d.jsx("p",{className:"mt-1 text-sm text-red-700",children:u})]})]})}):d.jsxs("div",{className:"space-y-6",children:[d.jsxs("div",{className:"flex justify-between items-center",children:[d.jsx("h1",{className:"text-2xl font-bold text-gray-900",children:"Analytics Dashboard"}),d.jsxs("div",{className:"flex items-center space-x-4",children:[d.jsx("label",{className:"text-sm font-medium text-gray-700",children:"Time Period:"}),d.jsxs("select",{value:y,onChange:e=>p(Number(e.target.value)),className:"border border-gray-300 rounded-md px-3 py-1 text-sm",children:[d.jsx("option",{value:7,children:"Last 7 days"}),d.jsx("option",{value:30,children:"Last 30 days"}),d.jsx("option",{value:90,children:"Last 90 days"})]}),d.jsx("button",{onClick:w,className:"bg-blue-600 text-white px-4 py-2 rounded-md text-sm hover:bg-blue-700",children:"Refresh"}),d.jsxs("button",{onClick:()=>e(void 0,null,function*(){try{b(!0),f(null),yield t.sendWeeklySummaryEmail(),f("Email sent successfully! Check your inbox."),setTimeout(()=>f(null),5e3)}catch(e){f("Failed to send email. Please try again."),setTimeout(()=>f(null),5e3)}finally{b(!1)}}),disabled:N,className:"bg-green-600 text-white px-4 py-2 rounded-md text-sm hover:bg-green-700 disabled:opacity-50 disabled:cursor-not-allowed flex items-center",children:[d.jsx(n,{className:"h-4 w-4 mr-2"}),N?"Sending...":"Send Weekly Email"]})]})]}),v&&d.jsx("div",{className:r("p-4 rounded-md",v.includes("successfully")?"bg-green-50 border border-green-200 text-green-800":"bg-red-50 border border-red-200 text-red-800"),children:d.jsxs("div",{className:"flex items-center",children:[d.jsx("div",{className:"flex-shrink-0",children:v.includes("successfully")?d.jsx("svg",{className:"h-5 w-5 text-green-400",viewBox:"0 0 20 20",fill:"currentColor",children:d.jsx("path",{fillRule:"evenodd",d:"M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z",clipRule:"evenodd"})}):d.jsx("svg",{className:"h-5 w-5 text-red-400",viewBox:"0 0 20 20",fill:"currentColor",children:d.jsx("path",{fillRule:"evenodd",d:"M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z",clipRule:"evenodd"})})}),d.jsx("div",{className:"ml-3",children:d.jsx("p",{className:"text-sm font-medium",children:v})})]})}),o&&d.jsxs("div",{className:"bg-white rounded-lg shadow p-6",children:[d.jsx("h2",{className:"text-lg font-semibold text-gray-900 mb-4",children:"System Health"}),d.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-4 gap-4",children:[d.jsxs("div",{className:"bg-gray-50 rounded-lg p-4",children:[d.jsxs("div",{className:"flex items-center",children:[d.jsx("div",{className:r("w-3 h-3 rounded-full mr-2","healthy"===o.status?"bg-green-500":"bg-red-500")}),d.jsx("span",{className:"text-sm font-medium text-gray-900",children:"Overall Status"})]}),d.jsx("p",{className:"text-2xl font-bold text-gray-900 mt-2",children:o.status.charAt(0).toUpperCase()+o.status.slice(1)})]}),d.jsxs("div",{className:"bg-gray-50 rounded-lg p-4",children:[d.jsx("p",{className:"text-sm font-medium text-gray-500",children:"Success Rate"}),d.jsxs("p",{className:"text-2xl font-bold text-gray-900",children:[o.overall.successRate.toFixed(1),"%"]})]}),d.jsxs("div",{className:"bg-gray-50 rounded-lg p-4",children:[d.jsx("p",{className:"text-sm font-medium text-gray-500",children:"Avg Processing Time"}),d.jsx("p",{className:"text-2xl font-bold text-gray-900",children:(e=>{const s="string"==typeof e?parseFloat(e):e;return s<1e3?`${Math.round(s)}ms`:s<6e4?`${(s/1e3).toFixed(1)}s`:`${(s/6e4).toFixed(1)}m`})(o.overall.averageProcessingTime)})]}),d.jsxs("div",{className:"bg-gray-50 rounded-lg p-4",children:[d.jsx("p",{className:"text-sm font-medium text-gray-500",children:"Active Sessions"}),d.jsx("p",{className:"text-2xl font-bold text-gray-900",children:o.overall.activeSessions})]})]})]}),i&&d.jsxs("div",{className:"bg-white rounded-lg shadow p-6",children:[d.jsx("h2",{className:"text-lg font-semibold text-gray-900 mb-4",children:"System Metrics"}),d.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-4 gap-6",children:[d.jsxs("div",{className:"bg-gray-50 rounded-lg p-4",children:[d.jsx("p",{className:"text-sm font-medium text-gray-500",children:"Total Users"}),d.jsx("p",{className:"text-2xl font-bold text-gray-900",children:i.totalUsers})]}),d.jsxs("div",{className:"bg-gray-50 rounded-lg p-4",children:[d.jsx("p",{className:"text-sm font-medium text-gray-500",children:"Total Documents"}),d.jsx("p",{className:"text-2xl font-bold text-gray-900",children:i.totalDocuments})]}),d.jsxs("div",{className:"bg-gray-50 rounded-lg p-4",children:[d.jsx("p",{className:"text-sm font-medium text-gray-500",children:"Success Rate"}),d.jsxs("p",{className:"text-2xl font-bold text-gray-900",children:[i.successRate.toFixed(1),"%"]})]}),d.jsxs("div",{className:"bg-gray-50 rounded-lg p-4",children:[d.jsx("p",{className:"text-sm font-medium text-gray-500",children:"System Uptime"}),d.jsxs("p",{className:"text-2xl font-bold text-gray-900",children:[Math.round(i.systemUptime/3600),"h"]})]})]})]}),s&&d.jsxs("div",{className:"bg-white rounded-lg shadow p-6",children:[d.jsxs("h2",{className:"text-lg font-semibold text-gray-900 mb-4",children:["Document Analytics (",s.period,")"]}),d.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-4 gap-6",children:[d.jsxs("div",{className:"bg-gray-50 rounded-lg p-4",children:[d.jsx("p",{className:"text-sm font-medium text-gray-500",children:"Total Documents"}),d.jsx("p",{className:"text-2xl font-bold text-gray-900",children:s.totalDocuments})]}),d.jsxs("div",{className:"bg-gray-50 rounded-lg p-4",children:[d.jsx("p",{className:"text-sm font-medium text-gray-500",children:"Completed"}),d.jsx("p",{className:"text-2xl font-bold text-green-600",children:s.completedDocuments})]}),d.jsxs("div",{className:"bg-gray-50 rounded-lg p-4",children:[d.jsx("p",{className:"text-sm font-medium text-gray-500",children:"Failed"}),d.jsx("p",{className:"text-2xl font-bold text-red-600",children:s.failedDocuments})]}),d.jsxs("div",{className:"bg-gray-50 rounded-lg p-4",children:[d.jsx("p",{className:"text-sm font-medium text-gray-500",children:"Success Rate"}),d.jsxs("p",{className:"text-2xl font-bold text-gray-900",children:[s.successRate.toFixed(1),"%"]})]})]})]})]})};export{c as default}; diff --git a/backend/frontend-dist/assets/DocumentList-9e71c857.js b/backend/frontend-dist/assets/DocumentList-9e71c857.js new file mode 100644 index 0000000..d9480f5 --- /dev/null +++ b/backend/frontend-dist/assets/DocumentList-9e71c857.js @@ -0,0 +1,13 @@ +import{c as e,j as s,F as r,a as t,E as n}from"./index-9817dacc.js";import{D as a}from"./download-aacd5336.js";import{C as c}from"./clock-9f043116.js";import{A as i,C as l}from"./check-circle-937a9172.js"; +/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const o=e("Calendar",[["rect",{width:"18",height:"18",x:"3",y:"4",rx:"2",ry:"2",key:"eu3xkr"}],["line",{x1:"16",x2:"16",y1:"2",y2:"6",key:"m3sa8f"}],["line",{x1:"8",x2:"8",y1:"2",y2:"6",key:"18kwsl"}],["line",{x1:"3",x2:"21",y1:"10",y2:"10",key:"xt86sb"}]]),d=e("PlayCircle",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["polygon",{points:"10 8 16 12 10 16 10 8",key:"1cimsy"}]]),x=e("Trash2",[["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6",key:"4alrt4"}],["path",{d:"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2",key:"v07s0e"}],["line",{x1:"10",x2:"10",y1:"11",y2:"17",key:"1uufr5"}],["line",{x1:"14",x2:"14",y1:"11",y2:"17",key:"xtxkd"}]]),m=e("User",[["path",{d:"M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2",key:"975kel"}],["circle",{cx:"12",cy:"7",r:"4",key:"17ys0d"}]]),u=({documents:e,onViewDocument:u,onDownloadDocument:h,onDeleteDocument:g,onRetryProcessing:f,onRefresh:p})=>{const y=e=>{if(0===e)return"0 Bytes";const s=Math.floor(Math.log(e)/Math.log(1024));return parseFloat((e/Math.pow(1024,s)).toFixed(2))+" "+["Bytes","KB","MB","GB"][s]},j=e=>{switch(e){case"uploaded":case"completed":return s.jsx(l,{className:"h-4 w-4 text-success-500"});case"processing":return s.jsx("div",{className:"animate-spin rounded-full h-4 w-4 border-b-2 border-accent-500"});case"error":return s.jsx(i,{className:"h-4 w-4 text-error-500"});case"extracting_text":return s.jsx(c,{className:"h-4 w-4 text-warning-500"});default:return null}},w=(e,s,r)=>{switch(e){case"uploaded":return"Uploaded โœ“";case"processing":return void 0!==s?`Processing... ${s}%`:r||"Processing...";case"completed":return"Completed โœ“";case"error":return"Error";case"extracting_text":return"Extracting Text...";default:return""}},b=e=>{switch(e){case"uploaded":case"completed":return"text-success-600 bg-success-50";case"processing":return"text-accent-600 bg-accent-50";case"error":return"text-error-600 bg-error-50";case"extracting_text":return"text-warning-600 bg-warning-50";default:return"text-gray-600 bg-gray-50"}};return 0===e.length?s.jsxs("div",{className:"text-center py-12",children:[s.jsx(r,{className:"mx-auto h-12 w-12 text-gray-400 mb-4"}),s.jsx("h3",{className:"text-lg font-medium text-primary-800 mb-2",children:"No documents uploaded yet"}),s.jsx("p",{className:"text-gray-600",children:"Upload your first CIM document to get started with processing."})]}):s.jsxs("div",{className:"space-y-4",children:[s.jsxs("div",{className:"flex items-center justify-between",children:[s.jsxs("h3",{className:"text-lg font-medium text-primary-800",children:["Documents (",e.length,")"]}),p&&s.jsxs("button",{onClick:p,className:"inline-flex items-center px-3 py-1.5 border border-gray-300 shadow-sm text-xs font-medium rounded text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500",children:[s.jsx("svg",{className:"h-4 w-4 mr-1",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"})}),"Refresh"]})]}),s.jsx("div",{className:"bg-white shadow-soft border border-gray-100 overflow-hidden sm:rounded-md",children:s.jsx("ul",{className:"divide-y divide-gray-200",children:e.map(e=>{return s.jsx("li",{children:s.jsx("div",{className:"px-4 py-4 sm:px-6",children:s.jsxs("div",{className:"flex items-center justify-between",children:[s.jsxs("div",{className:"flex items-center space-x-3 flex-1 min-w-0",children:[s.jsx(r,{className:"h-8 w-8 text-gray-400 flex-shrink-0"}),s.jsxs("div",{className:"flex-1 min-w-0",children:[s.jsxs("div",{className:"flex items-center space-x-2",children:[s.jsx("p",{className:"text-sm font-medium text-gray-900 truncate",children:e.name}),s.jsxs("span",{className:t("inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium",b(e.status)),children:[j(e.status),s.jsx("span",{className:"ml-1",children:w(e.status,e.progress,e.message)})]})]}),s.jsxs("div",{className:"mt-1 flex items-center space-x-4 text-sm text-gray-500",children:[s.jsxs("div",{className:"flex items-center space-x-1",children:[s.jsx(m,{className:"h-4 w-4"}),s.jsx("span",{children:e.uploadedBy})]}),s.jsxs("div",{className:"flex items-center space-x-1",children:[s.jsx(o,{className:"h-4 w-4"}),s.jsx("span",{children:(c=e.uploadedAt,new Date(c).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"}))})]}),s.jsx("span",{children:y(e.fileSize)}),e.pageCount&&s.jsxs("span",{children:[e.pageCount," pages"]})]}),"processing"===e.status&&void 0!==e.progress&&s.jsxs("div",{className:"mt-2",children:[s.jsxs("div",{className:"flex items-center justify-between text-xs text-gray-500 mb-1",children:[s.jsx("span",{children:"Processing progress"}),s.jsxs("span",{children:[e.progress,"%"]})]}),s.jsx("div",{className:"w-full bg-gray-200 rounded-full h-2",children:s.jsx("div",{className:"bg-accent-500 h-2 rounded-full transition-all duration-300",style:{width:`${e.progress}%`}})})]}),"completed"===e.status&&s.jsx("p",{className:"mt-2 text-sm text-success-600",children:'โœ“ Analysis completed - Click "View" to see detailed CIM review'}),e.error&&s.jsxs("p",{className:"mt-2 text-sm text-red-600",children:["Error: ",e.error]})]})]}),s.jsxs("div",{className:"flex items-center space-x-2 ml-4",children:["completed"===e.status&&s.jsxs(s.Fragment,{children:[s.jsxs("button",{onClick:()=>null==u?void 0:u(e.id),className:"inline-flex items-center px-3 py-1.5 border border-gray-300 shadow-sm text-xs font-medium rounded text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500",children:[s.jsx(n,{className:"h-4 w-4 mr-1"}),"View"]}),s.jsxs("button",{onClick:()=>null==h?void 0:h(e.id),className:"inline-flex items-center px-3 py-1.5 border border-gray-300 shadow-sm text-xs font-medium rounded text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500",children:[s.jsx(a,{className:"h-4 w-4 mr-1"}),"Download"]})]}),"error"===e.status&&f&&s.jsxs("button",{onClick:()=>f(e.id),className:"inline-flex items-center px-3 py-1.5 border border-gray-300 shadow-sm text-xs font-medium rounded text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500",children:[s.jsx(d,{className:"h-4 w-4 mr-1"}),"Retry"]}),s.jsxs("button",{onClick:()=>null==g?void 0:g(e.id),className:"inline-flex items-center px-3 py-1.5 border border-red-300 shadow-sm text-xs font-medium rounded text-red-700 bg-white hover:bg-red-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500",children:[s.jsx(x,{className:"h-4 w-4 mr-1"}),"Delete"]})]})]})})},e.id);var c})})})]})}; +/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */export{u as default}; diff --git a/backend/frontend-dist/assets/DocumentUpload-22ee24e0.js b/backend/frontend-dist/assets/DocumentUpload-22ee24e0.js new file mode 100644 index 0000000..c3d9b07 --- /dev/null +++ b/backend/frontend-dist/assets/DocumentUpload-22ee24e0.js @@ -0,0 +1,7 @@ +var a=Object.defineProperty,i=Object.defineProperties,t=Object.getOwnPropertyDescriptors,e=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,p=Object.prototype.propertyIsEnumerable,o=(i,t,e)=>t in i?a(i,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):i[t]=e,c=(a,i)=>{for(var t in i||(i={}))n.call(i,t)&&o(a,t,i[t]);if(e)for(var t of e(i))p.call(i,t)&&o(a,t,i[t]);return a},l=(a,e)=>i(a,t(e)),r=(a,i,t)=>new Promise((e,n)=>{var p=a=>{try{c(t.next(a))}catch(i){n(i)}},o=a=>{try{c(t.throw(a))}catch(i){n(i)}},c=a=>a.done?e(a.value):Promise.resolve(a.value).then(p,o);c((t=t.apply(a,i)).next())});import{c as s,g as d,r as m,R as u,u as v,d as x,G as f,j as g,a as b,U as h,F as y}from"./index-9817dacc.js";import{C as w,A as k}from"./check-circle-937a9172.js";import{X as j}from"./x-d6da8175.js"; +/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const z=s("Cloud",[["path",{d:"M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z",key:"p7xjir"}]]);var D={exports:{}};function O(){}function A(){}A.resetWarningCache=O;D.exports=function(){function a(a,i,t,e,n,p){if("SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"!==p){var o=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw o.name="Invariant Violation",o}}function i(){return a}a.isRequired=a;var t={array:a,bigint:a,bool:a,func:a,number:a,object:a,string:a,symbol:a,any:a,arrayOf:i,element:a,elementType:a,instanceOf:i,node:a,objectOf:i,oneOf:i,oneOfType:i,shape:i,exact:i,checkPropTypes:A,resetWarningCache:O};return t.PropTypes=t,t}();const E=d(D.exports);function P(a,i,t,e){return new(t||(t=Promise))(function(n,p){function o(a){try{l(e.next(a))}catch(i){p(i)}}function c(a){try{l(e.throw(a))}catch(i){p(i)}}function l(a){var i;a.done?n(a.value):(i=a.value,i instanceof t?i:new t(function(a){a(i)})).then(o,c)}l((e=e.apply(a,i||[])).next())})}"function"==typeof SuppressedError&&SuppressedError;const F=new Map([["1km","application/vnd.1000minds.decision-model+xml"],["3dml","text/vnd.in3d.3dml"],["3ds","image/x-3ds"],["3g2","video/3gpp2"],["3gp","video/3gp"],["3gpp","video/3gpp"],["3mf","model/3mf"],["7z","application/x-7z-compressed"],["7zip","application/x-7z-compressed"],["123","application/vnd.lotus-1-2-3"],["aab","application/x-authorware-bin"],["aac","audio/x-acc"],["aam","application/x-authorware-map"],["aas","application/x-authorware-seg"],["abw","application/x-abiword"],["ac","application/vnd.nokia.n-gage.ac+xml"],["ac3","audio/ac3"],["acc","application/vnd.americandynamics.acc"],["ace","application/x-ace-compressed"],["acu","application/vnd.acucobol"],["acutc","application/vnd.acucorp"],["adp","audio/adpcm"],["aep","application/vnd.audiograph"],["afm","application/x-font-type1"],["afp","application/vnd.ibm.modcap"],["ahead","application/vnd.ahead.space"],["ai","application/pdf"],["aif","audio/x-aiff"],["aifc","audio/x-aiff"],["aiff","audio/x-aiff"],["air","application/vnd.adobe.air-application-installer-package+zip"],["ait","application/vnd.dvb.ait"],["ami","application/vnd.amiga.ami"],["amr","audio/amr"],["apk","application/vnd.android.package-archive"],["apng","image/apng"],["appcache","text/cache-manifest"],["application","application/x-ms-application"],["apr","application/vnd.lotus-approach"],["arc","application/x-freearc"],["arj","application/x-arj"],["asc","application/pgp-signature"],["asf","video/x-ms-asf"],["asm","text/x-asm"],["aso","application/vnd.accpac.simply.aso"],["asx","video/x-ms-asf"],["atc","application/vnd.acucorp"],["atom","application/atom+xml"],["atomcat","application/atomcat+xml"],["atomdeleted","application/atomdeleted+xml"],["atomsvc","application/atomsvc+xml"],["atx","application/vnd.antix.game-component"],["au","audio/x-au"],["avi","video/x-msvideo"],["avif","image/avif"],["aw","application/applixware"],["azf","application/vnd.airzip.filesecure.azf"],["azs","application/vnd.airzip.filesecure.azs"],["azv","image/vnd.airzip.accelerator.azv"],["azw","application/vnd.amazon.ebook"],["b16","image/vnd.pco.b16"],["bat","application/x-msdownload"],["bcpio","application/x-bcpio"],["bdf","application/x-font-bdf"],["bdm","application/vnd.syncml.dm+wbxml"],["bdoc","application/x-bdoc"],["bed","application/vnd.realvnc.bed"],["bh2","application/vnd.fujitsu.oasysprs"],["bin","application/octet-stream"],["blb","application/x-blorb"],["blorb","application/x-blorb"],["bmi","application/vnd.bmi"],["bmml","application/vnd.balsamiq.bmml+xml"],["bmp","image/bmp"],["book","application/vnd.framemaker"],["box","application/vnd.previewsystems.box"],["boz","application/x-bzip2"],["bpk","application/octet-stream"],["bpmn","application/octet-stream"],["bsp","model/vnd.valve.source.compiled-map"],["btif","image/prs.btif"],["buffer","application/octet-stream"],["bz","application/x-bzip"],["bz2","application/x-bzip2"],["c","text/x-c"],["c4d","application/vnd.clonk.c4group"],["c4f","application/vnd.clonk.c4group"],["c4g","application/vnd.clonk.c4group"],["c4p","application/vnd.clonk.c4group"],["c4u","application/vnd.clonk.c4group"],["c11amc","application/vnd.cluetrust.cartomobile-config"],["c11amz","application/vnd.cluetrust.cartomobile-config-pkg"],["cab","application/vnd.ms-cab-compressed"],["caf","audio/x-caf"],["cap","application/vnd.tcpdump.pcap"],["car","application/vnd.curl.car"],["cat","application/vnd.ms-pki.seccat"],["cb7","application/x-cbr"],["cba","application/x-cbr"],["cbr","application/x-cbr"],["cbt","application/x-cbr"],["cbz","application/x-cbr"],["cc","text/x-c"],["cco","application/x-cocoa"],["cct","application/x-director"],["ccxml","application/ccxml+xml"],["cdbcmsg","application/vnd.contact.cmsg"],["cda","application/x-cdf"],["cdf","application/x-netcdf"],["cdfx","application/cdfx+xml"],["cdkey","application/vnd.mediastation.cdkey"],["cdmia","application/cdmi-capability"],["cdmic","application/cdmi-container"],["cdmid","application/cdmi-domain"],["cdmio","application/cdmi-object"],["cdmiq","application/cdmi-queue"],["cdr","application/cdr"],["cdx","chemical/x-cdx"],["cdxml","application/vnd.chemdraw+xml"],["cdy","application/vnd.cinderella"],["cer","application/pkix-cert"],["cfs","application/x-cfs-compressed"],["cgm","image/cgm"],["chat","application/x-chat"],["chm","application/vnd.ms-htmlhelp"],["chrt","application/vnd.kde.kchart"],["cif","chemical/x-cif"],["cii","application/vnd.anser-web-certificate-issue-initiation"],["cil","application/vnd.ms-artgalry"],["cjs","application/node"],["cla","application/vnd.claymore"],["class","application/octet-stream"],["clkk","application/vnd.crick.clicker.keyboard"],["clkp","application/vnd.crick.clicker.palette"],["clkt","application/vnd.crick.clicker.template"],["clkw","application/vnd.crick.clicker.wordbank"],["clkx","application/vnd.crick.clicker"],["clp","application/x-msclip"],["cmc","application/vnd.cosmocaller"],["cmdf","chemical/x-cmdf"],["cml","chemical/x-cml"],["cmp","application/vnd.yellowriver-custom-menu"],["cmx","image/x-cmx"],["cod","application/vnd.rim.cod"],["coffee","text/coffeescript"],["com","application/x-msdownload"],["conf","text/plain"],["cpio","application/x-cpio"],["cpp","text/x-c"],["cpt","application/mac-compactpro"],["crd","application/x-mscardfile"],["crl","application/pkix-crl"],["crt","application/x-x509-ca-cert"],["crx","application/x-chrome-extension"],["cryptonote","application/vnd.rig.cryptonote"],["csh","application/x-csh"],["csl","application/vnd.citationstyles.style+xml"],["csml","chemical/x-csml"],["csp","application/vnd.commonspace"],["csr","application/octet-stream"],["css","text/css"],["cst","application/x-director"],["csv","text/csv"],["cu","application/cu-seeme"],["curl","text/vnd.curl"],["cww","application/prs.cww"],["cxt","application/x-director"],["cxx","text/x-c"],["dae","model/vnd.collada+xml"],["daf","application/vnd.mobius.daf"],["dart","application/vnd.dart"],["dataless","application/vnd.fdsn.seed"],["davmount","application/davmount+xml"],["dbf","application/vnd.dbf"],["dbk","application/docbook+xml"],["dcr","application/x-director"],["dcurl","text/vnd.curl.dcurl"],["dd2","application/vnd.oma.dd2+xml"],["ddd","application/vnd.fujixerox.ddd"],["ddf","application/vnd.syncml.dmddf+xml"],["dds","image/vnd.ms-dds"],["deb","application/x-debian-package"],["def","text/plain"],["deploy","application/octet-stream"],["der","application/x-x509-ca-cert"],["dfac","application/vnd.dreamfactory"],["dgc","application/x-dgc-compressed"],["dic","text/x-c"],["dir","application/x-director"],["dis","application/vnd.mobius.dis"],["disposition-notification","message/disposition-notification"],["dist","application/octet-stream"],["distz","application/octet-stream"],["djv","image/vnd.djvu"],["djvu","image/vnd.djvu"],["dll","application/octet-stream"],["dmg","application/x-apple-diskimage"],["dmn","application/octet-stream"],["dmp","application/vnd.tcpdump.pcap"],["dms","application/octet-stream"],["dna","application/vnd.dna"],["doc","application/msword"],["docm","application/vnd.ms-word.template.macroEnabled.12"],["docx","application/vnd.openxmlformats-officedocument.wordprocessingml.document"],["dot","application/msword"],["dotm","application/vnd.ms-word.template.macroEnabled.12"],["dotx","application/vnd.openxmlformats-officedocument.wordprocessingml.template"],["dp","application/vnd.osgi.dp"],["dpg","application/vnd.dpgraph"],["dra","audio/vnd.dra"],["drle","image/dicom-rle"],["dsc","text/prs.lines.tag"],["dssc","application/dssc+der"],["dtb","application/x-dtbook+xml"],["dtd","application/xml-dtd"],["dts","audio/vnd.dts"],["dtshd","audio/vnd.dts.hd"],["dump","application/octet-stream"],["dvb","video/vnd.dvb.file"],["dvi","application/x-dvi"],["dwd","application/atsc-dwd+xml"],["dwf","model/vnd.dwf"],["dwg","image/vnd.dwg"],["dxf","image/vnd.dxf"],["dxp","application/vnd.spotfire.dxp"],["dxr","application/x-director"],["ear","application/java-archive"],["ecelp4800","audio/vnd.nuera.ecelp4800"],["ecelp7470","audio/vnd.nuera.ecelp7470"],["ecelp9600","audio/vnd.nuera.ecelp9600"],["ecma","application/ecmascript"],["edm","application/vnd.novadigm.edm"],["edx","application/vnd.novadigm.edx"],["efif","application/vnd.picsel"],["ei6","application/vnd.pg.osasli"],["elc","application/octet-stream"],["emf","image/emf"],["eml","message/rfc822"],["emma","application/emma+xml"],["emotionml","application/emotionml+xml"],["emz","application/x-msmetafile"],["eol","audio/vnd.digital-winds"],["eot","application/vnd.ms-fontobject"],["eps","application/postscript"],["epub","application/epub+zip"],["es","application/ecmascript"],["es3","application/vnd.eszigno3+xml"],["esa","application/vnd.osgi.subsystem"],["esf","application/vnd.epson.esf"],["et3","application/vnd.eszigno3+xml"],["etx","text/x-setext"],["eva","application/x-eva"],["evy","application/x-envoy"],["exe","application/octet-stream"],["exi","application/exi"],["exp","application/express"],["exr","image/aces"],["ext","application/vnd.novadigm.ext"],["ez","application/andrew-inset"],["ez2","application/vnd.ezpix-album"],["ez3","application/vnd.ezpix-package"],["f","text/x-fortran"],["f4v","video/mp4"],["f77","text/x-fortran"],["f90","text/x-fortran"],["fbs","image/vnd.fastbidsheet"],["fcdt","application/vnd.adobe.formscentral.fcdt"],["fcs","application/vnd.isac.fcs"],["fdf","application/vnd.fdf"],["fdt","application/fdt+xml"],["fe_launch","application/vnd.denovo.fcselayout-link"],["fg5","application/vnd.fujitsu.oasysgp"],["fgd","application/x-director"],["fh","image/x-freehand"],["fh4","image/x-freehand"],["fh5","image/x-freehand"],["fh7","image/x-freehand"],["fhc","image/x-freehand"],["fig","application/x-xfig"],["fits","image/fits"],["flac","audio/x-flac"],["fli","video/x-fli"],["flo","application/vnd.micrografx.flo"],["flv","video/x-flv"],["flw","application/vnd.kde.kivio"],["flx","text/vnd.fmi.flexstor"],["fly","text/vnd.fly"],["fm","application/vnd.framemaker"],["fnc","application/vnd.frogans.fnc"],["fo","application/vnd.software602.filler.form+xml"],["for","text/x-fortran"],["fpx","image/vnd.fpx"],["frame","application/vnd.framemaker"],["fsc","application/vnd.fsc.weblaunch"],["fst","image/vnd.fst"],["ftc","application/vnd.fluxtime.clip"],["fti","application/vnd.anser-web-funds-transfer-initiation"],["fvt","video/vnd.fvt"],["fxp","application/vnd.adobe.fxp"],["fxpl","application/vnd.adobe.fxp"],["fzs","application/vnd.fuzzysheet"],["g2w","application/vnd.geoplan"],["g3","image/g3fax"],["g3w","application/vnd.geospace"],["gac","application/vnd.groove-account"],["gam","application/x-tads"],["gbr","application/rpki-ghostbusters"],["gca","application/x-gca-compressed"],["gdl","model/vnd.gdl"],["gdoc","application/vnd.google-apps.document"],["geo","application/vnd.dynageo"],["geojson","application/geo+json"],["gex","application/vnd.geometry-explorer"],["ggb","application/vnd.geogebra.file"],["ggt","application/vnd.geogebra.tool"],["ghf","application/vnd.groove-help"],["gif","image/gif"],["gim","application/vnd.groove-identity-message"],["glb","model/gltf-binary"],["gltf","model/gltf+json"],["gml","application/gml+xml"],["gmx","application/vnd.gmx"],["gnumeric","application/x-gnumeric"],["gpg","application/gpg-keys"],["gph","application/vnd.flographit"],["gpx","application/gpx+xml"],["gqf","application/vnd.grafeq"],["gqs","application/vnd.grafeq"],["gram","application/srgs"],["gramps","application/x-gramps-xml"],["gre","application/vnd.geometry-explorer"],["grv","application/vnd.groove-injector"],["grxml","application/srgs+xml"],["gsf","application/x-font-ghostscript"],["gsheet","application/vnd.google-apps.spreadsheet"],["gslides","application/vnd.google-apps.presentation"],["gtar","application/x-gtar"],["gtm","application/vnd.groove-tool-message"],["gtw","model/vnd.gtw"],["gv","text/vnd.graphviz"],["gxf","application/gxf"],["gxt","application/vnd.geonext"],["gz","application/gzip"],["gzip","application/gzip"],["h","text/x-c"],["h261","video/h261"],["h263","video/h263"],["h264","video/h264"],["hal","application/vnd.hal+xml"],["hbci","application/vnd.hbci"],["hbs","text/x-handlebars-template"],["hdd","application/x-virtualbox-hdd"],["hdf","application/x-hdf"],["heic","image/heic"],["heics","image/heic-sequence"],["heif","image/heif"],["heifs","image/heif-sequence"],["hej2","image/hej2k"],["held","application/atsc-held+xml"],["hh","text/x-c"],["hjson","application/hjson"],["hlp","application/winhlp"],["hpgl","application/vnd.hp-hpgl"],["hpid","application/vnd.hp-hpid"],["hps","application/vnd.hp-hps"],["hqx","application/mac-binhex40"],["hsj2","image/hsj2"],["htc","text/x-component"],["htke","application/vnd.kenameaapp"],["htm","text/html"],["html","text/html"],["hvd","application/vnd.yamaha.hv-dic"],["hvp","application/vnd.yamaha.hv-voice"],["hvs","application/vnd.yamaha.hv-script"],["i2g","application/vnd.intergeo"],["icc","application/vnd.iccprofile"],["ice","x-conference/x-cooltalk"],["icm","application/vnd.iccprofile"],["ico","image/x-icon"],["ics","text/calendar"],["ief","image/ief"],["ifb","text/calendar"],["ifm","application/vnd.shana.informed.formdata"],["iges","model/iges"],["igl","application/vnd.igloader"],["igm","application/vnd.insors.igm"],["igs","model/iges"],["igx","application/vnd.micrografx.igx"],["iif","application/vnd.shana.informed.interchange"],["img","application/octet-stream"],["imp","application/vnd.accpac.simply.imp"],["ims","application/vnd.ms-ims"],["in","text/plain"],["ini","text/plain"],["ink","application/inkml+xml"],["inkml","application/inkml+xml"],["install","application/x-install-instructions"],["iota","application/vnd.astraea-software.iota"],["ipfix","application/ipfix"],["ipk","application/vnd.shana.informed.package"],["irm","application/vnd.ibm.rights-management"],["irp","application/vnd.irepository.package+xml"],["iso","application/x-iso9660-image"],["itp","application/vnd.shana.informed.formtemplate"],["its","application/its+xml"],["ivp","application/vnd.immervision-ivp"],["ivu","application/vnd.immervision-ivu"],["jad","text/vnd.sun.j2me.app-descriptor"],["jade","text/jade"],["jam","application/vnd.jam"],["jar","application/java-archive"],["jardiff","application/x-java-archive-diff"],["java","text/x-java-source"],["jhc","image/jphc"],["jisp","application/vnd.jisp"],["jls","image/jls"],["jlt","application/vnd.hp-jlyt"],["jng","image/x-jng"],["jnlp","application/x-java-jnlp-file"],["joda","application/vnd.joost.joda-archive"],["jp2","image/jp2"],["jpe","image/jpeg"],["jpeg","image/jpeg"],["jpf","image/jpx"],["jpg","image/jpeg"],["jpg2","image/jp2"],["jpgm","video/jpm"],["jpgv","video/jpeg"],["jph","image/jph"],["jpm","video/jpm"],["jpx","image/jpx"],["js","application/javascript"],["json","application/json"],["json5","application/json5"],["jsonld","application/ld+json"],["jsonl","application/jsonl"],["jsonml","application/jsonml+json"],["jsx","text/jsx"],["jxr","image/jxr"],["jxra","image/jxra"],["jxrs","image/jxrs"],["jxs","image/jxs"],["jxsc","image/jxsc"],["jxsi","image/jxsi"],["jxss","image/jxss"],["kar","audio/midi"],["karbon","application/vnd.kde.karbon"],["kdb","application/octet-stream"],["kdbx","application/x-keepass2"],["key","application/x-iwork-keynote-sffkey"],["kfo","application/vnd.kde.kformula"],["kia","application/vnd.kidspiration"],["kml","application/vnd.google-earth.kml+xml"],["kmz","application/vnd.google-earth.kmz"],["kne","application/vnd.kinar"],["knp","application/vnd.kinar"],["kon","application/vnd.kde.kontour"],["kpr","application/vnd.kde.kpresenter"],["kpt","application/vnd.kde.kpresenter"],["kpxx","application/vnd.ds-keypoint"],["ksp","application/vnd.kde.kspread"],["ktr","application/vnd.kahootz"],["ktx","image/ktx"],["ktx2","image/ktx2"],["ktz","application/vnd.kahootz"],["kwd","application/vnd.kde.kword"],["kwt","application/vnd.kde.kword"],["lasxml","application/vnd.las.las+xml"],["latex","application/x-latex"],["lbd","application/vnd.llamagraphics.life-balance.desktop"],["lbe","application/vnd.llamagraphics.life-balance.exchange+xml"],["les","application/vnd.hhe.lesson-player"],["less","text/less"],["lgr","application/lgr+xml"],["lha","application/octet-stream"],["link66","application/vnd.route66.link66+xml"],["list","text/plain"],["list3820","application/vnd.ibm.modcap"],["listafp","application/vnd.ibm.modcap"],["litcoffee","text/coffeescript"],["lnk","application/x-ms-shortcut"],["log","text/plain"],["lostxml","application/lost+xml"],["lrf","application/octet-stream"],["lrm","application/vnd.ms-lrm"],["ltf","application/vnd.frogans.ltf"],["lua","text/x-lua"],["luac","application/x-lua-bytecode"],["lvp","audio/vnd.lucent.voice"],["lwp","application/vnd.lotus-wordpro"],["lzh","application/octet-stream"],["m1v","video/mpeg"],["m2a","audio/mpeg"],["m2v","video/mpeg"],["m3a","audio/mpeg"],["m3u","text/plain"],["m3u8","application/vnd.apple.mpegurl"],["m4a","audio/x-m4a"],["m4p","application/mp4"],["m4s","video/iso.segment"],["m4u","application/vnd.mpegurl"],["m4v","video/x-m4v"],["m13","application/x-msmediaview"],["m14","application/x-msmediaview"],["m21","application/mp21"],["ma","application/mathematica"],["mads","application/mads+xml"],["maei","application/mmt-aei+xml"],["mag","application/vnd.ecowin.chart"],["maker","application/vnd.framemaker"],["man","text/troff"],["manifest","text/cache-manifest"],["map","application/json"],["mar","application/octet-stream"],["markdown","text/markdown"],["mathml","application/mathml+xml"],["mb","application/mathematica"],["mbk","application/vnd.mobius.mbk"],["mbox","application/mbox"],["mc1","application/vnd.medcalcdata"],["mcd","application/vnd.mcd"],["mcurl","text/vnd.curl.mcurl"],["md","text/markdown"],["mdb","application/x-msaccess"],["mdi","image/vnd.ms-modi"],["mdx","text/mdx"],["me","text/troff"],["mesh","model/mesh"],["meta4","application/metalink4+xml"],["metalink","application/metalink+xml"],["mets","application/mets+xml"],["mfm","application/vnd.mfmp"],["mft","application/rpki-manifest"],["mgp","application/vnd.osgeo.mapguide.package"],["mgz","application/vnd.proteus.magazine"],["mid","audio/midi"],["midi","audio/midi"],["mie","application/x-mie"],["mif","application/vnd.mif"],["mime","message/rfc822"],["mj2","video/mj2"],["mjp2","video/mj2"],["mjs","application/javascript"],["mk3d","video/x-matroska"],["mka","audio/x-matroska"],["mkd","text/x-markdown"],["mks","video/x-matroska"],["mkv","video/x-matroska"],["mlp","application/vnd.dolby.mlp"],["mmd","application/vnd.chipnuts.karaoke-mmd"],["mmf","application/vnd.smaf"],["mml","text/mathml"],["mmr","image/vnd.fujixerox.edmics-mmr"],["mng","video/x-mng"],["mny","application/x-msmoney"],["mobi","application/x-mobipocket-ebook"],["mods","application/mods+xml"],["mov","video/quicktime"],["movie","video/x-sgi-movie"],["mp2","audio/mpeg"],["mp2a","audio/mpeg"],["mp3","audio/mpeg"],["mp4","video/mp4"],["mp4a","audio/mp4"],["mp4s","application/mp4"],["mp4v","video/mp4"],["mp21","application/mp21"],["mpc","application/vnd.mophun.certificate"],["mpd","application/dash+xml"],["mpe","video/mpeg"],["mpeg","video/mpeg"],["mpg","video/mpeg"],["mpg4","video/mp4"],["mpga","audio/mpeg"],["mpkg","application/vnd.apple.installer+xml"],["mpm","application/vnd.blueice.multipass"],["mpn","application/vnd.mophun.application"],["mpp","application/vnd.ms-project"],["mpt","application/vnd.ms-project"],["mpy","application/vnd.ibm.minipay"],["mqy","application/vnd.mobius.mqy"],["mrc","application/marc"],["mrcx","application/marcxml+xml"],["ms","text/troff"],["mscml","application/mediaservercontrol+xml"],["mseed","application/vnd.fdsn.mseed"],["mseq","application/vnd.mseq"],["msf","application/vnd.epson.msf"],["msg","application/vnd.ms-outlook"],["msh","model/mesh"],["msi","application/x-msdownload"],["msl","application/vnd.mobius.msl"],["msm","application/octet-stream"],["msp","application/octet-stream"],["msty","application/vnd.muvee.style"],["mtl","model/mtl"],["mts","model/vnd.mts"],["mus","application/vnd.musician"],["musd","application/mmt-usd+xml"],["musicxml","application/vnd.recordare.musicxml+xml"],["mvb","application/x-msmediaview"],["mvt","application/vnd.mapbox-vector-tile"],["mwf","application/vnd.mfer"],["mxf","application/mxf"],["mxl","application/vnd.recordare.musicxml"],["mxmf","audio/mobile-xmf"],["mxml","application/xv+xml"],["mxs","application/vnd.triscape.mxs"],["mxu","video/vnd.mpegurl"],["n-gage","application/vnd.nokia.n-gage.symbian.install"],["n3","text/n3"],["nb","application/mathematica"],["nbp","application/vnd.wolfram.player"],["nc","application/x-netcdf"],["ncx","application/x-dtbncx+xml"],["nfo","text/x-nfo"],["ngdat","application/vnd.nokia.n-gage.data"],["nitf","application/vnd.nitf"],["nlu","application/vnd.neurolanguage.nlu"],["nml","application/vnd.enliven"],["nnd","application/vnd.noblenet-directory"],["nns","application/vnd.noblenet-sealer"],["nnw","application/vnd.noblenet-web"],["npx","image/vnd.net-fpx"],["nq","application/n-quads"],["nsc","application/x-conference"],["nsf","application/vnd.lotus-notes"],["nt","application/n-triples"],["ntf","application/vnd.nitf"],["numbers","application/x-iwork-numbers-sffnumbers"],["nzb","application/x-nzb"],["oa2","application/vnd.fujitsu.oasys2"],["oa3","application/vnd.fujitsu.oasys3"],["oas","application/vnd.fujitsu.oasys"],["obd","application/x-msbinder"],["obgx","application/vnd.openblox.game+xml"],["obj","model/obj"],["oda","application/oda"],["odb","application/vnd.oasis.opendocument.database"],["odc","application/vnd.oasis.opendocument.chart"],["odf","application/vnd.oasis.opendocument.formula"],["odft","application/vnd.oasis.opendocument.formula-template"],["odg","application/vnd.oasis.opendocument.graphics"],["odi","application/vnd.oasis.opendocument.image"],["odm","application/vnd.oasis.opendocument.text-master"],["odp","application/vnd.oasis.opendocument.presentation"],["ods","application/vnd.oasis.opendocument.spreadsheet"],["odt","application/vnd.oasis.opendocument.text"],["oga","audio/ogg"],["ogex","model/vnd.opengex"],["ogg","audio/ogg"],["ogv","video/ogg"],["ogx","application/ogg"],["omdoc","application/omdoc+xml"],["onepkg","application/onenote"],["onetmp","application/onenote"],["onetoc","application/onenote"],["onetoc2","application/onenote"],["opf","application/oebps-package+xml"],["opml","text/x-opml"],["oprc","application/vnd.palm"],["opus","audio/ogg"],["org","text/x-org"],["osf","application/vnd.yamaha.openscoreformat"],["osfpvg","application/vnd.yamaha.openscoreformat.osfpvg+xml"],["osm","application/vnd.openstreetmap.data+xml"],["otc","application/vnd.oasis.opendocument.chart-template"],["otf","font/otf"],["otg","application/vnd.oasis.opendocument.graphics-template"],["oth","application/vnd.oasis.opendocument.text-web"],["oti","application/vnd.oasis.opendocument.image-template"],["otp","application/vnd.oasis.opendocument.presentation-template"],["ots","application/vnd.oasis.opendocument.spreadsheet-template"],["ott","application/vnd.oasis.opendocument.text-template"],["ova","application/x-virtualbox-ova"],["ovf","application/x-virtualbox-ovf"],["owl","application/rdf+xml"],["oxps","application/oxps"],["oxt","application/vnd.openofficeorg.extension"],["p","text/x-pascal"],["p7a","application/x-pkcs7-signature"],["p7b","application/x-pkcs7-certificates"],["p7c","application/pkcs7-mime"],["p7m","application/pkcs7-mime"],["p7r","application/x-pkcs7-certreqresp"],["p7s","application/pkcs7-signature"],["p8","application/pkcs8"],["p10","application/x-pkcs10"],["p12","application/x-pkcs12"],["pac","application/x-ns-proxy-autoconfig"],["pages","application/x-iwork-pages-sffpages"],["pas","text/x-pascal"],["paw","application/vnd.pawaafile"],["pbd","application/vnd.powerbuilder6"],["pbm","image/x-portable-bitmap"],["pcap","application/vnd.tcpdump.pcap"],["pcf","application/x-font-pcf"],["pcl","application/vnd.hp-pcl"],["pclxl","application/vnd.hp-pclxl"],["pct","image/x-pict"],["pcurl","application/vnd.curl.pcurl"],["pcx","image/x-pcx"],["pdb","application/x-pilot"],["pde","text/x-processing"],["pdf","application/pdf"],["pem","application/x-x509-user-cert"],["pfa","application/x-font-type1"],["pfb","application/x-font-type1"],["pfm","application/x-font-type1"],["pfr","application/font-tdpfr"],["pfx","application/x-pkcs12"],["pgm","image/x-portable-graymap"],["pgn","application/x-chess-pgn"],["pgp","application/pgp"],["php","application/x-httpd-php"],["php3","application/x-httpd-php"],["php4","application/x-httpd-php"],["phps","application/x-httpd-php-source"],["phtml","application/x-httpd-php"],["pic","image/x-pict"],["pkg","application/octet-stream"],["pki","application/pkixcmp"],["pkipath","application/pkix-pkipath"],["pkpass","application/vnd.apple.pkpass"],["pl","application/x-perl"],["plb","application/vnd.3gpp.pic-bw-large"],["plc","application/vnd.mobius.plc"],["plf","application/vnd.pocketlearn"],["pls","application/pls+xml"],["pm","application/x-perl"],["pml","application/vnd.ctc-posml"],["png","image/png"],["pnm","image/x-portable-anymap"],["portpkg","application/vnd.macports.portpkg"],["pot","application/vnd.ms-powerpoint"],["potm","application/vnd.ms-powerpoint.presentation.macroEnabled.12"],["potx","application/vnd.openxmlformats-officedocument.presentationml.template"],["ppa","application/vnd.ms-powerpoint"],["ppam","application/vnd.ms-powerpoint.addin.macroEnabled.12"],["ppd","application/vnd.cups-ppd"],["ppm","image/x-portable-pixmap"],["pps","application/vnd.ms-powerpoint"],["ppsm","application/vnd.ms-powerpoint.slideshow.macroEnabled.12"],["ppsx","application/vnd.openxmlformats-officedocument.presentationml.slideshow"],["ppt","application/powerpoint"],["pptm","application/vnd.ms-powerpoint.presentation.macroEnabled.12"],["pptx","application/vnd.openxmlformats-officedocument.presentationml.presentation"],["pqa","application/vnd.palm"],["prc","application/x-pilot"],["pre","application/vnd.lotus-freelance"],["prf","application/pics-rules"],["provx","application/provenance+xml"],["ps","application/postscript"],["psb","application/vnd.3gpp.pic-bw-small"],["psd","application/x-photoshop"],["psf","application/x-font-linux-psf"],["pskcxml","application/pskc+xml"],["pti","image/prs.pti"],["ptid","application/vnd.pvi.ptid1"],["pub","application/x-mspublisher"],["pvb","application/vnd.3gpp.pic-bw-var"],["pwn","application/vnd.3m.post-it-notes"],["pya","audio/vnd.ms-playready.media.pya"],["pyv","video/vnd.ms-playready.media.pyv"],["qam","application/vnd.epson.quickanime"],["qbo","application/vnd.intu.qbo"],["qfx","application/vnd.intu.qfx"],["qps","application/vnd.publishare-delta-tree"],["qt","video/quicktime"],["qwd","application/vnd.quark.quarkxpress"],["qwt","application/vnd.quark.quarkxpress"],["qxb","application/vnd.quark.quarkxpress"],["qxd","application/vnd.quark.quarkxpress"],["qxl","application/vnd.quark.quarkxpress"],["qxt","application/vnd.quark.quarkxpress"],["ra","audio/x-realaudio"],["ram","audio/x-pn-realaudio"],["raml","application/raml+yaml"],["rapd","application/route-apd+xml"],["rar","application/x-rar"],["ras","image/x-cmu-raster"],["rcprofile","application/vnd.ipunplugged.rcprofile"],["rdf","application/rdf+xml"],["rdz","application/vnd.data-vision.rdz"],["relo","application/p2p-overlay+xml"],["rep","application/vnd.businessobjects"],["res","application/x-dtbresource+xml"],["rgb","image/x-rgb"],["rif","application/reginfo+xml"],["rip","audio/vnd.rip"],["ris","application/x-research-info-systems"],["rl","application/resource-lists+xml"],["rlc","image/vnd.fujixerox.edmics-rlc"],["rld","application/resource-lists-diff+xml"],["rm","audio/x-pn-realaudio"],["rmi","audio/midi"],["rmp","audio/x-pn-realaudio-plugin"],["rms","application/vnd.jcp.javame.midlet-rms"],["rmvb","application/vnd.rn-realmedia-vbr"],["rnc","application/relax-ng-compact-syntax"],["rng","application/xml"],["roa","application/rpki-roa"],["roff","text/troff"],["rp9","application/vnd.cloanto.rp9"],["rpm","audio/x-pn-realaudio-plugin"],["rpss","application/vnd.nokia.radio-presets"],["rpst","application/vnd.nokia.radio-preset"],["rq","application/sparql-query"],["rs","application/rls-services+xml"],["rsa","application/x-pkcs7"],["rsat","application/atsc-rsat+xml"],["rsd","application/rsd+xml"],["rsheet","application/urc-ressheet+xml"],["rss","application/rss+xml"],["rtf","text/rtf"],["rtx","text/richtext"],["run","application/x-makeself"],["rusd","application/route-usd+xml"],["rv","video/vnd.rn-realvideo"],["s","text/x-asm"],["s3m","audio/s3m"],["saf","application/vnd.yamaha.smaf-audio"],["sass","text/x-sass"],["sbml","application/sbml+xml"],["sc","application/vnd.ibm.secure-container"],["scd","application/x-msschedule"],["scm","application/vnd.lotus-screencam"],["scq","application/scvp-cv-request"],["scs","application/scvp-cv-response"],["scss","text/x-scss"],["scurl","text/vnd.curl.scurl"],["sda","application/vnd.stardivision.draw"],["sdc","application/vnd.stardivision.calc"],["sdd","application/vnd.stardivision.impress"],["sdkd","application/vnd.solent.sdkm+xml"],["sdkm","application/vnd.solent.sdkm+xml"],["sdp","application/sdp"],["sdw","application/vnd.stardivision.writer"],["sea","application/octet-stream"],["see","application/vnd.seemail"],["seed","application/vnd.fdsn.seed"],["sema","application/vnd.sema"],["semd","application/vnd.semd"],["semf","application/vnd.semf"],["senmlx","application/senml+xml"],["sensmlx","application/sensml+xml"],["ser","application/java-serialized-object"],["setpay","application/set-payment-initiation"],["setreg","application/set-registration-initiation"],["sfd-hdstx","application/vnd.hydrostatix.sof-data"],["sfs","application/vnd.spotfire.sfs"],["sfv","text/x-sfv"],["sgi","image/sgi"],["sgl","application/vnd.stardivision.writer-global"],["sgm","text/sgml"],["sgml","text/sgml"],["sh","application/x-sh"],["shar","application/x-shar"],["shex","text/shex"],["shf","application/shf+xml"],["shtml","text/html"],["sid","image/x-mrsid-image"],["sieve","application/sieve"],["sig","application/pgp-signature"],["sil","audio/silk"],["silo","model/mesh"],["sis","application/vnd.symbian.install"],["sisx","application/vnd.symbian.install"],["sit","application/x-stuffit"],["sitx","application/x-stuffitx"],["siv","application/sieve"],["skd","application/vnd.koan"],["skm","application/vnd.koan"],["skp","application/vnd.koan"],["skt","application/vnd.koan"],["sldm","application/vnd.ms-powerpoint.slide.macroenabled.12"],["sldx","application/vnd.openxmlformats-officedocument.presentationml.slide"],["slim","text/slim"],["slm","text/slim"],["sls","application/route-s-tsid+xml"],["slt","application/vnd.epson.salt"],["sm","application/vnd.stepmania.stepchart"],["smf","application/vnd.stardivision.math"],["smi","application/smil"],["smil","application/smil"],["smv","video/x-smv"],["smzip","application/vnd.stepmania.package"],["snd","audio/basic"],["snf","application/x-font-snf"],["so","application/octet-stream"],["spc","application/x-pkcs7-certificates"],["spdx","text/spdx"],["spf","application/vnd.yamaha.smaf-phrase"],["spl","application/x-futuresplash"],["spot","text/vnd.in3d.spot"],["spp","application/scvp-vp-response"],["spq","application/scvp-vp-request"],["spx","audio/ogg"],["sql","application/x-sql"],["src","application/x-wais-source"],["srt","application/x-subrip"],["sru","application/sru+xml"],["srx","application/sparql-results+xml"],["ssdl","application/ssdl+xml"],["sse","application/vnd.kodak-descriptor"],["ssf","application/vnd.epson.ssf"],["ssml","application/ssml+xml"],["sst","application/octet-stream"],["st","application/vnd.sailingtracker.track"],["stc","application/vnd.sun.xml.calc.template"],["std","application/vnd.sun.xml.draw.template"],["stf","application/vnd.wt.stf"],["sti","application/vnd.sun.xml.impress.template"],["stk","application/hyperstudio"],["stl","model/stl"],["stpx","model/step+xml"],["stpxz","model/step-xml+zip"],["stpz","model/step+zip"],["str","application/vnd.pg.format"],["stw","application/vnd.sun.xml.writer.template"],["styl","text/stylus"],["stylus","text/stylus"],["sub","text/vnd.dvb.subtitle"],["sus","application/vnd.sus-calendar"],["susp","application/vnd.sus-calendar"],["sv4cpio","application/x-sv4cpio"],["sv4crc","application/x-sv4crc"],["svc","application/vnd.dvb.service"],["svd","application/vnd.svd"],["svg","image/svg+xml"],["svgz","image/svg+xml"],["swa","application/x-director"],["swf","application/x-shockwave-flash"],["swi","application/vnd.aristanetworks.swi"],["swidtag","application/swid+xml"],["sxc","application/vnd.sun.xml.calc"],["sxd","application/vnd.sun.xml.draw"],["sxg","application/vnd.sun.xml.writer.global"],["sxi","application/vnd.sun.xml.impress"],["sxm","application/vnd.sun.xml.math"],["sxw","application/vnd.sun.xml.writer"],["t","text/troff"],["t3","application/x-t3vm-image"],["t38","image/t38"],["taglet","application/vnd.mynfc"],["tao","application/vnd.tao.intent-module-archive"],["tap","image/vnd.tencent.tap"],["tar","application/x-tar"],["tcap","application/vnd.3gpp2.tcap"],["tcl","application/x-tcl"],["td","application/urc-targetdesc+xml"],["teacher","application/vnd.smart.teacher"],["tei","application/tei+xml"],["teicorpus","application/tei+xml"],["tex","application/x-tex"],["texi","application/x-texinfo"],["texinfo","application/x-texinfo"],["text","text/plain"],["tfi","application/thraud+xml"],["tfm","application/x-tex-tfm"],["tfx","image/tiff-fx"],["tga","image/x-tga"],["tgz","application/x-tar"],["thmx","application/vnd.ms-officetheme"],["tif","image/tiff"],["tiff","image/tiff"],["tk","application/x-tcl"],["tmo","application/vnd.tmobile-livetv"],["toml","application/toml"],["torrent","application/x-bittorrent"],["tpl","application/vnd.groove-tool-template"],["tpt","application/vnd.trid.tpt"],["tr","text/troff"],["tra","application/vnd.trueapp"],["trig","application/trig"],["trm","application/x-msterminal"],["ts","video/mp2t"],["tsd","application/timestamped-data"],["tsv","text/tab-separated-values"],["ttc","font/collection"],["ttf","font/ttf"],["ttl","text/turtle"],["ttml","application/ttml+xml"],["twd","application/vnd.simtech-mindmapper"],["twds","application/vnd.simtech-mindmapper"],["txd","application/vnd.genomatix.tuxedo"],["txf","application/vnd.mobius.txf"],["txt","text/plain"],["u8dsn","message/global-delivery-status"],["u8hdr","message/global-headers"],["u8mdn","message/global-disposition-notification"],["u8msg","message/global"],["u32","application/x-authorware-bin"],["ubj","application/ubjson"],["udeb","application/x-debian-package"],["ufd","application/vnd.ufdl"],["ufdl","application/vnd.ufdl"],["ulx","application/x-glulx"],["umj","application/vnd.umajin"],["unityweb","application/vnd.unity"],["uoml","application/vnd.uoml+xml"],["uri","text/uri-list"],["uris","text/uri-list"],["urls","text/uri-list"],["usdz","model/vnd.usdz+zip"],["ustar","application/x-ustar"],["utz","application/vnd.uiq.theme"],["uu","text/x-uuencode"],["uva","audio/vnd.dece.audio"],["uvd","application/vnd.dece.data"],["uvf","application/vnd.dece.data"],["uvg","image/vnd.dece.graphic"],["uvh","video/vnd.dece.hd"],["uvi","image/vnd.dece.graphic"],["uvm","video/vnd.dece.mobile"],["uvp","video/vnd.dece.pd"],["uvs","video/vnd.dece.sd"],["uvt","application/vnd.dece.ttml+xml"],["uvu","video/vnd.uvvu.mp4"],["uvv","video/vnd.dece.video"],["uvva","audio/vnd.dece.audio"],["uvvd","application/vnd.dece.data"],["uvvf","application/vnd.dece.data"],["uvvg","image/vnd.dece.graphic"],["uvvh","video/vnd.dece.hd"],["uvvi","image/vnd.dece.graphic"],["uvvm","video/vnd.dece.mobile"],["uvvp","video/vnd.dece.pd"],["uvvs","video/vnd.dece.sd"],["uvvt","application/vnd.dece.ttml+xml"],["uvvu","video/vnd.uvvu.mp4"],["uvvv","video/vnd.dece.video"],["uvvx","application/vnd.dece.unspecified"],["uvvz","application/vnd.dece.zip"],["uvx","application/vnd.dece.unspecified"],["uvz","application/vnd.dece.zip"],["vbox","application/x-virtualbox-vbox"],["vbox-extpack","application/x-virtualbox-vbox-extpack"],["vcard","text/vcard"],["vcd","application/x-cdlink"],["vcf","text/x-vcard"],["vcg","application/vnd.groove-vcard"],["vcs","text/x-vcalendar"],["vcx","application/vnd.vcx"],["vdi","application/x-virtualbox-vdi"],["vds","model/vnd.sap.vds"],["vhd","application/x-virtualbox-vhd"],["vis","application/vnd.visionary"],["viv","video/vnd.vivo"],["vlc","application/videolan"],["vmdk","application/x-virtualbox-vmdk"],["vob","video/x-ms-vob"],["vor","application/vnd.stardivision.writer"],["vox","application/x-authorware-bin"],["vrml","model/vrml"],["vsd","application/vnd.visio"],["vsf","application/vnd.vsf"],["vss","application/vnd.visio"],["vst","application/vnd.visio"],["vsw","application/vnd.visio"],["vtf","image/vnd.valve.source.texture"],["vtt","text/vtt"],["vtu","model/vnd.vtu"],["vxml","application/voicexml+xml"],["w3d","application/x-director"],["wad","application/x-doom"],["wadl","application/vnd.sun.wadl+xml"],["war","application/java-archive"],["wasm","application/wasm"],["wav","audio/x-wav"],["wax","audio/x-ms-wax"],["wbmp","image/vnd.wap.wbmp"],["wbs","application/vnd.criticaltools.wbs+xml"],["wbxml","application/wbxml"],["wcm","application/vnd.ms-works"],["wdb","application/vnd.ms-works"],["wdp","image/vnd.ms-photo"],["weba","audio/webm"],["webapp","application/x-web-app-manifest+json"],["webm","video/webm"],["webmanifest","application/manifest+json"],["webp","image/webp"],["wg","application/vnd.pmi.widget"],["wgt","application/widget"],["wks","application/vnd.ms-works"],["wm","video/x-ms-wm"],["wma","audio/x-ms-wma"],["wmd","application/x-ms-wmd"],["wmf","image/wmf"],["wml","text/vnd.wap.wml"],["wmlc","application/wmlc"],["wmls","text/vnd.wap.wmlscript"],["wmlsc","application/vnd.wap.wmlscriptc"],["wmv","video/x-ms-wmv"],["wmx","video/x-ms-wmx"],["wmz","application/x-msmetafile"],["woff","font/woff"],["woff2","font/woff2"],["word","application/msword"],["wpd","application/vnd.wordperfect"],["wpl","application/vnd.ms-wpl"],["wps","application/vnd.ms-works"],["wqd","application/vnd.wqd"],["wri","application/x-mswrite"],["wrl","model/vrml"],["wsc","message/vnd.wfa.wsc"],["wsdl","application/wsdl+xml"],["wspolicy","application/wspolicy+xml"],["wtb","application/vnd.webturbo"],["wvx","video/x-ms-wvx"],["x3d","model/x3d+xml"],["x3db","model/x3d+fastinfoset"],["x3dbz","model/x3d+binary"],["x3dv","model/x3d-vrml"],["x3dvz","model/x3d+vrml"],["x3dz","model/x3d+xml"],["x32","application/x-authorware-bin"],["x_b","model/vnd.parasolid.transmit.binary"],["x_t","model/vnd.parasolid.transmit.text"],["xaml","application/xaml+xml"],["xap","application/x-silverlight-app"],["xar","application/vnd.xara"],["xav","application/xcap-att+xml"],["xbap","application/x-ms-xbap"],["xbd","application/vnd.fujixerox.docuworks.binder"],["xbm","image/x-xbitmap"],["xca","application/xcap-caps+xml"],["xcs","application/calendar+xml"],["xdf","application/xcap-diff+xml"],["xdm","application/vnd.syncml.dm+xml"],["xdp","application/vnd.adobe.xdp+xml"],["xdssc","application/dssc+xml"],["xdw","application/vnd.fujixerox.docuworks"],["xel","application/xcap-el+xml"],["xenc","application/xenc+xml"],["xer","application/patch-ops-error+xml"],["xfdf","application/vnd.adobe.xfdf"],["xfdl","application/vnd.xfdl"],["xht","application/xhtml+xml"],["xhtml","application/xhtml+xml"],["xhvml","application/xv+xml"],["xif","image/vnd.xiff"],["xl","application/excel"],["xla","application/vnd.ms-excel"],["xlam","application/vnd.ms-excel.addin.macroEnabled.12"],["xlc","application/vnd.ms-excel"],["xlf","application/xliff+xml"],["xlm","application/vnd.ms-excel"],["xls","application/vnd.ms-excel"],["xlsb","application/vnd.ms-excel.sheet.binary.macroEnabled.12"],["xlsm","application/vnd.ms-excel.sheet.macroEnabled.12"],["xlsx","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"],["xlt","application/vnd.ms-excel"],["xltm","application/vnd.ms-excel.template.macroEnabled.12"],["xltx","application/vnd.openxmlformats-officedocument.spreadsheetml.template"],["xlw","application/vnd.ms-excel"],["xm","audio/xm"],["xml","application/xml"],["xns","application/xcap-ns+xml"],["xo","application/vnd.olpc-sugar"],["xop","application/xop+xml"],["xpi","application/x-xpinstall"],["xpl","application/xproc+xml"],["xpm","image/x-xpixmap"],["xpr","application/vnd.is-xpr"],["xps","application/vnd.ms-xpsdocument"],["xpw","application/vnd.intercon.formnet"],["xpx","application/vnd.intercon.formnet"],["xsd","application/xml"],["xsl","application/xml"],["xslt","application/xslt+xml"],["xsm","application/vnd.syncml+xml"],["xspf","application/xspf+xml"],["xul","application/vnd.mozilla.xul+xml"],["xvm","application/xv+xml"],["xvml","application/xv+xml"],["xwd","image/x-xwindowdump"],["xyz","chemical/x-xyz"],["xz","application/x-xz"],["yaml","text/yaml"],["yang","application/yang"],["yin","application/yin+xml"],["yml","text/yaml"],["ymp","text/x-suse-ymp"],["z","application/x-compress"],["z1","application/x-zmachine"],["z2","application/x-zmachine"],["z3","application/x-zmachine"],["z4","application/x-zmachine"],["z5","application/x-zmachine"],["z6","application/x-zmachine"],["z7","application/x-zmachine"],["z8","application/x-zmachine"],["zaz","application/vnd.zzazz.deck+xml"],["zip","application/zip"],["zir","application/vnd.zul"],["zirz","application/vnd.zul"],["zmm","application/vnd.handheld-entertainment+xml"],["zsh","text/x-scriptzsh"]]);function S(a,i,t){const e=function(a){const{name:i}=a;if(i&&-1!==i.lastIndexOf(".")&&!a.type){const t=i.split(".").pop().toLowerCase(),e=F.get(t);e&&Object.defineProperty(a,"type",{value:e,writable:!1,configurable:!1,enumerable:!0})}return a}(a),{webkitRelativePath:n}=a,p="string"==typeof i?i:"string"==typeof n&&n.length>0?n:`./${a.name}`;return"string"!=typeof e.path&&q(e,"path",p),void 0!==t&&Object.defineProperty(e,"handle",{value:t,writable:!1,configurable:!1,enumerable:!0}),q(e,"relativePath",p),e}function q(a,i,t){Object.defineProperty(a,i,{value:t,writable:!1,configurable:!1,enumerable:!0})}const C=[".DS_Store","Thumbs.db"];function N(a){return"object"==typeof a&&null!==a}function R(a){return a.filter(a=>-1===C.indexOf(a.name))}function T(a){if(null===a)return[];const i=[];for(let t=0;t[...a,...Array.isArray(i)?M(i):[i]],[])}function _(a,i){return P(this,void 0,void 0,function*(){var t;if(globalThis.isSecureContext&&"function"==typeof a.getAsFileSystemHandle){const i=yield a.getAsFileSystemHandle();if(null===i)throw new Error(`${a} is not a File`);if(void 0!==i){const a=yield i.getFile();return a.handle=i,S(a)}}const e=a.getAsFile();if(!e)throw new Error(`${a} is not a File`);return S(e,null!==(t=null==i?void 0:i.fullPath)&&void 0!==t?t:void 0)})}function U(a){return P(this,void 0,void 0,function*(){return a.isDirectory?L(a):function(a){return P(this,void 0,void 0,function*(){return new Promise((i,t)=>{a.file(t=>{const e=S(t,a.fullPath);i(e)},a=>{t(a)})})})}(a)})}function L(a){const i=a.createReader();return new Promise((a,t)=>{const e=[];!function n(){i.readEntries(i=>P(this,void 0,void 0,function*(){if(i.length){const a=Promise.all(i.map(U));e.push(a),n()}else try{const i=yield Promise.all(e);a(i)}catch(p){t(p)}}),a=>{t(a)})}()})}var B=function(a,i){if(a&&i){var t=Array.isArray(i)?i:i.split(",");if(0===t.length)return!0;var e=a.name||"",n=(a.type||"").toLowerCase(),p=n.replace(/\/.*$/,"");return t.some(function(a){var i=a.trim().toLowerCase();return"."===i.charAt(0)?e.toLowerCase().endsWith(i):i.endsWith("/*")?p===i.replace(/\/.*$/,""):n===i})}return!0};function $(a){return function(a){if(Array.isArray(a))return V(a)}(a)||function(a){if("undefined"!=typeof Symbol&&null!=a[Symbol.iterator]||null!=a["@@iterator"])return Array.from(a)}(a)||Y(a)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function G(a,i){var t=Object.keys(a);if(Object.getOwnPropertySymbols){var e=Object.getOwnPropertySymbols(a);i&&(e=e.filter(function(i){return Object.getOwnPropertyDescriptor(a,i).enumerable})),t.push.apply(t,e)}return t}function K(a){for(var i=1;ia.length)&&(i=a.length);for(var t=0,e=new Array(i);t0&&void 0!==arguments[0]?arguments[0]:"").split(","),i=a.length>1?"one of ".concat(a.join(", ")):a[0];return{code:"file-invalid-type",message:"File type must be ".concat(i)}},Q=function(a){return{code:"file-too-large",message:"File is larger than ".concat(a," ").concat(1===a?"byte":"bytes")}},X=function(a){return{code:"file-too-small",message:"File is smaller than ".concat(a," ").concat(1===a?"byte":"bytes")}},aa={code:"too-many-files",message:"Too many files"};function ia(a,i){var t="application/x-moz-file"===a.type||Z(a,i);return[t,t?null:J(i)]}function ta(a,i,t){if(ea(a.size))if(ea(i)&&ea(t)){if(a.size>t)return[!1,Q(t)];if(a.sizet)return[!1,Q(t)]}return[!0,null]}function ea(a){return null!=a}function na(a){return"function"==typeof a.isPropagationStopped?a.isPropagationStopped():void 0!==a.cancelBubble&&a.cancelBubble}function pa(a){return a.dataTransfer?Array.prototype.some.call(a.dataTransfer.types,function(a){return"Files"===a||"application/x-moz-file"===a}):!!a.target&&!!a.target.files}function oa(a){a.preventDefault()}function ca(){for(var a=arguments.length,i=new Array(a),t=0;t1?t-1:0),n=1;na.length)&&(i=a.length);for(var t=0,e=new Array(i);t=0||(n[t]=a[t]);return n}(a,i);if(Object.getOwnPropertySymbols){var p=Object.getOwnPropertySymbols(a);for(e=0;e=0||Object.prototype.propertyIsEnumerable.call(a,t)&&(n[t]=a[t])}return n}var ka=m.forwardRef(function(a,i){var t=a.children,e=Da(wa(a,sa)),n=e.open,p=wa(e,da);return m.useImperativeHandle(i,function(){return{open:n}},[n]),u.createElement(m.Fragment,null,t(ha(ha({},p),{},{open:n})))});ka.displayName="Dropzone";var ja={disabled:!1,getFilesFromEvent:function(a){return P(this,void 0,void 0,function*(){return N(a)&&N(a.dataTransfer)?function(a,i){return P(this,void 0,void 0,function*(){if(a.items){const t=T(a.items).filter(a=>"file"===a.kind);if("drop"!==i)return t;return R(M(yield Promise.all(t.map(I))))}return R(T(a.files).map(a=>S(a)))})}(a.dataTransfer,a.type):function(a){return N(a)&&N(a.target)}(a)?function(a){return T(a.target.files).map(a=>S(a))}(a):Array.isArray(a)&&a.every(a=>"getFile"in a&&"function"==typeof a.getFile)?function(a){return P(this,void 0,void 0,function*(){return(yield Promise.all(a.map(a=>a.getFile()))).map(a=>S(a))})}(a):[]})},maxSize:1/0,minSize:0,multiple:!0,maxFiles:0,preventDropOnDocument:!0,noClick:!1,noKeyboard:!1,noDrag:!1,noDragEventsBubbling:!1,validator:null,useFsAccessApi:!1,autoFocus:!1};ka.defaultProps=ja,ka.propTypes={children:E.func,accept:E.objectOf(E.arrayOf(E.string)),multiple:E.bool,preventDropOnDocument:E.bool,noClick:E.bool,noKeyboard:E.bool,noDrag:E.bool,noDragEventsBubbling:E.bool,minSize:E.number,maxSize:E.number,maxFiles:E.number,disabled:E.bool,getFilesFromEvent:E.func,onFileDialogCancel:E.func,onFileDialogOpen:E.func,useFsAccessApi:E.bool,autoFocus:E.bool,onDragEnter:E.func,onDragLeave:E.func,onDragOver:E.func,onDrop:E.func,onDropAccepted:E.func,onDropRejected:E.func,onError:E.func,validator:E.func};var za={isFocused:!1,isFileDialogActive:!1,isDragActive:!1,isDragAccept:!1,isDragReject:!1,acceptedFiles:[],fileRejections:[]};function Da(){var a=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},i=ha(ha({},ja),a),t=i.accept,e=i.disabled,n=i.getFilesFromEvent,p=i.maxSize,o=i.minSize,c=i.multiple,l=i.maxFiles,r=i.onDragEnter,s=i.onDragLeave,d=i.onDragOver,u=i.onDrop,v=i.onDropAccepted,x=i.onDropRejected,f=i.onFileDialogCancel,g=i.onFileDialogOpen,b=i.useFsAccessApi,h=i.autoFocus,y=i.preventDropOnDocument,w=i.noClick,k=i.noKeyboard,j=i.noDrag,z=i.noDragEventsBubbling,D=i.onError,O=i.validator,A=m.useMemo(function(){return function(a){if(ea(a))return Object.entries(a).reduce(function(a,i){var t=H(i,2),e=t[0],n=t[1];return[].concat($(a),[e],$(n))},[]).filter(function(a){return la(a)||ra(a)}).join(",")}(t)},[t]),E=m.useMemo(function(){return function(a){return ea(a)?[{description:"Files",accept:Object.entries(a).filter(function(a){var i=H(a,2),t=i[0],e=i[1],n=!0;return la(t)||(n=!1),Array.isArray(e)&&e.every(ra)||(n=!1),n}).reduce(function(a,i){var t=H(i,2),e=t[0],n=t[1];return K(K({},a),{},W({},e,n))},{})}]:a}(t)},[t]),P=m.useMemo(function(){return"function"==typeof g?g:Aa},[g]),F=m.useMemo(function(){return"function"==typeof f?f:Aa},[f]),S=m.useRef(null),q=m.useRef(null),C=xa(m.useReducer(Oa,za),2),N=C[0],R=C[1],T=N.isFocused,I=N.isFileDialogActive,M=m.useRef("undefined"!=typeof window&&window.isSecureContext&&b&&"showOpenFilePicker"in window),_=function(){!M.current&&I&&setTimeout(function(){q.current&&(q.current.files.length||(R({type:"closeDialog"}),F()))},300)};m.useEffect(function(){return window.addEventListener("focus",_,!1),function(){window.removeEventListener("focus",_,!1)}},[q,I,F,M]);var U=m.useRef([]),L=function(a){S.current&&S.current.contains(a.target)||(a.preventDefault(),U.current=[])};m.useEffect(function(){return y&&(document.addEventListener("dragover",oa,!1),document.addEventListener("drop",L,!1)),function(){y&&(document.removeEventListener("dragover",oa),document.removeEventListener("drop",L))}},[S,y]),m.useEffect(function(){return!e&&h&&S.current&&S.current.focus(),function(){}},[S,h,e]);var B=m.useCallback(function(a){D&&D(a)},[D]),G=m.useCallback(function(a){a.preventDefault(),a.persist(),Da(a),U.current=[].concat(va(U.current),[a.target]),pa(a)&&Promise.resolve(n(a)).then(function(i){if(!na(a)||z){var t=i.length,e=t>0&&function(a){var i=a.files,t=a.accept,e=a.minSize,n=a.maxSize,p=a.multiple,o=a.maxFiles,c=a.validator;return!(!p&&i.length>1||p&&o>=1&&i.length>o)&&i.every(function(a){var i=H(ia(a,t),1)[0],p=H(ta(a,e,n),1)[0],o=c?c(a):null;return i&&p&&!o})}({files:i,accept:A,minSize:o,maxSize:p,multiple:c,maxFiles:l,validator:O});R({isDragAccept:e,isDragReject:t>0&&!e,isDragActive:!0,type:"setDraggedFiles"}),r&&r(a)}}).catch(function(a){return B(a)})},[n,r,B,z,A,o,p,c,l,O]),Y=m.useCallback(function(a){a.preventDefault(),a.persist(),Da(a);var i=pa(a);if(i&&a.dataTransfer)try{a.dataTransfer.dropEffect="copy"}catch(t){}return i&&d&&d(a),!1},[d,z]),V=m.useCallback(function(a){a.preventDefault(),a.persist(),Da(a);var i=U.current.filter(function(a){return S.current&&S.current.contains(a)}),t=i.indexOf(a.target);-1!==t&&i.splice(t,1),U.current=i,i.length>0||(R({type:"setDraggedFiles",isDragActive:!1,isDragAccept:!1,isDragReject:!1}),pa(a)&&s&&s(a))},[S,s,z]),Z=m.useCallback(function(a,i){var t=[],e=[];a.forEach(function(a){var i=xa(ia(a,A),2),n=i[0],c=i[1],l=xa(ta(a,o,p),2),r=l[0],s=l[1],d=O?O(a):null;if(n&&r&&!d)t.push(a);else{var m=[c,s];d&&(m=m.concat(d)),e.push({file:a,errors:m.filter(function(a){return a})})}}),(!c&&t.length>1||c&&l>=1&&t.length>l)&&(t.forEach(function(a){e.push({file:a,errors:[aa]})}),t.splice(0)),R({acceptedFiles:t,fileRejections:e,isDragReject:e.length>0,type:"setFiles"}),u&&u(t,e,i),e.length>0&&x&&x(e,i),t.length>0&&v&&v(t,i)},[R,c,A,o,p,l,u,v,x,O]),J=m.useCallback(function(a){a.preventDefault(),a.persist(),Da(a),U.current=[],pa(a)&&Promise.resolve(n(a)).then(function(i){na(a)&&!z||Z(i,a)}).catch(function(a){return B(a)}),R({type:"reset"})},[n,Z,B,z]),Q=m.useCallback(function(){if(M.current){R({type:"openDialog"}),P();var a={multiple:c,types:E};window.showOpenFilePicker(a).then(function(a){return n(a)}).then(function(a){Z(a,null),R({type:"closeDialog"})}).catch(function(a){var i;(i=a)instanceof DOMException&&("AbortError"===i.name||i.code===i.ABORT_ERR)?(F(a),R({type:"closeDialog"})):!function(a){return a instanceof DOMException&&("SecurityError"===a.name||a.code===a.SECURITY_ERR)}(a)?B(a):(M.current=!1,q.current?(q.current.value=null,q.current.click()):B(new Error("Cannot open the file picker because the https://developer.mozilla.org/en-US/docs/Web/API/File_System_Access_API is not supported and no was provided.")))})}else q.current&&(R({type:"openDialog"}),P(),q.current.value=null,q.current.click())},[R,P,F,b,Z,B,E,c]),X=m.useCallback(function(a){S.current&&S.current.isEqualNode(a.target)&&(" "!==a.key&&"Enter"!==a.key&&32!==a.keyCode&&13!==a.keyCode||(a.preventDefault(),Q()))},[S,Q]),sa=m.useCallback(function(){R({type:"focus"})},[]),da=m.useCallback(function(){R({type:"blur"})},[]),fa=m.useCallback(function(){w||(!function(){var a=arguments.length>0&&void 0!==arguments[0]?arguments[0]:window.navigator.userAgent;return function(a){return-1!==a.indexOf("MSIE")||-1!==a.indexOf("Trident/")}(a)||function(a){return-1!==a.indexOf("Edge/")}(a)}()?Q():setTimeout(Q,0))},[w,Q]),ga=function(a){return e?null:a},ba=function(a){return k?null:ga(a)},ka=function(a){return j?null:ga(a)},Da=function(a){z&&a.stopPropagation()},Ea=m.useMemo(function(){return function(){var a=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},i=a.refKey,t=void 0===i?"ref":i,n=a.role,p=a.onKeyDown,o=a.onFocus,c=a.onBlur,l=a.onClick,r=a.onDragEnter,s=a.onDragOver,d=a.onDragLeave,m=a.onDrop,u=wa(a,ma);return ha(ha(ya({onKeyDown:ba(ca(p,X)),onFocus:ba(ca(o,sa)),onBlur:ba(ca(c,da)),onClick:ga(ca(l,fa)),onDragEnter:ka(ca(r,G)),onDragOver:ka(ca(s,Y)),onDragLeave:ka(ca(d,V)),onDrop:ka(ca(m,J)),role:"string"==typeof n&&""!==n?n:"presentation"},t,S),e||k?{}:{tabIndex:0}),u)}},[S,X,sa,da,fa,G,Y,V,J,k,j,e]),Pa=m.useCallback(function(a){a.stopPropagation()},[]),Fa=m.useMemo(function(){return function(){var a=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},i=a.refKey,t=void 0===i?"ref":i,e=a.onChange,n=a.onClick,p=wa(a,ua);return ha(ha({},ya({accept:A,multiple:c,type:"file",style:{border:0,clip:"rect(0, 0, 0, 0)",clipPath:"inset(50%)",height:"1px",margin:"0 -1px -1px 0",overflow:"hidden",padding:0,position:"absolute",width:"1px",whiteSpace:"nowrap"},onChange:ga(ca(e,J)),onClick:ga(ca(n,Pa)),tabIndex:-1},t,q)),p)}},[q,t,c,J,e]);return ha(ha({},N),{},{isFocused:T&&!e,getRootProps:Ea,getInputProps:Fa,rootRef:S,inputRef:q,open:ga(Q)})}function Oa(a,i){switch(i.type){case"focus":return ha(ha({},a),{},{isFocused:!0});case"blur":return ha(ha({},a),{},{isFocused:!1});case"openDialog":return ha(ha({},za),{},{isFileDialogActive:!0});case"closeDialog":return ha(ha({},a),{},{isFileDialogActive:!1});case"setDraggedFiles":return ha(ha({},a),{},{isDragActive:i.isDragActive,isDragAccept:i.isDragAccept,isDragReject:i.isDragReject});case"setFiles":return ha(ha({},a),{},{acceptedFiles:i.acceptedFiles,fileRejections:i.fileRejections,isDragReject:i.isDragReject});case"reset":return ha({},za);default:return a}}function Aa(){}const Ea=({onUploadComplete:a,onUploadError:i})=>{const{token:t}=v(),[e,n]=m.useState([]),[p,o]=m.useState(!1),s=m.useRef(new Map);m.useEffect(()=>()=>{s.current.forEach((a,i)=>{a.abort()}),s.current.clear()},[]),m.useEffect(()=>{const a=()=>{document.hidden&&p&&s.current.size>0&&"Notification"in window&&"granted"===Notification.permission&&new Notification("Upload in Progress",{body:"Please return to the tab to continue uploads",icon:"/favicon.ico"})};return document.addEventListener("visibilitychange",a),()=>{document.removeEventListener("visibilitychange",a)}},[p]);const d=m.useCallback(t=>r(void 0,null,function*(){o(!0);const e=t.map(a=>({id:Math.random().toString(36).substr(2,9),name:a.name,size:a.size,type:a.type,status:"uploading",progress:0}));n(a=>[...a,...e]);for(let o=0;o{n(i=>i.map(i=>i.id===d.id?l(c({},i),{progress:a}):i))},m.signal);n(a=>a.map(a=>a.id===d.id?l(c({},a),{id:i.id,documentId:i.id,status:"processing",progress:100}):a)),null==a||a(i.id),u(i.id,d.id)}catch(p){if(p instanceof Error&&"AbortError"===p.name)n(a=>a.map(a=>a.id===d.id?l(c({},a),{status:"error",error:"Upload cancelled"}):a));else{let a="Upload failed",t=!1;f.isGCSError(p)?(a=f.getErrorMessage(p),t=!0):p instanceof Error&&(a=p.message),n(i=>i.map(i=>i.id===d.id?c(l(c({},i),{status:"error",error:a}),t&&{storageError:!0}):i)),null==i||i(a)}}finally{s.current.delete(d.id)}}o(!1)}),[a,i]),u=m.useCallback((a,i)=>{if(!a||"undefined"===a||"null"===a)return;if(!/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(a))return;const e=Date.now(),p=()=>r(void 0,null,function*(){if(Date.now()-e>18e5)n(a=>a.map(a=>a.id===i?l(c({},a),{status:"error",error:"Processing timeout - please check document status manually"}):a));else{try{const e=yield fetch(`https://api-76ut2tki7q-uc.a.run.app/documents/${a}/progress`,{headers:{Authorization:`Bearer ${t}`,"Content-Type":"application/json"}});if(e.ok){const a=yield e.json();let t="processing";if("uploading"===a.status||"uploaded"===a.status||"processing"===a.status||"extracting_text"===a.status||"processing_llm"===a.status||"generating_pdf"===a.status?t="processing":"completed"===a.status?t="completed":"error"!==a.status&&"failed"!==a.status||(t="error"),n(e=>e.map(e=>e.id===i?l(c({},e),{status:t,progress:a.progress||e.progress}):e)),"completed"===t||"error"===t)return}else{if(404===e.status)return;if(401===e.status)return}}catch(o){}setTimeout(p,3e3)}});setTimeout(p,500)},[t]),{getRootProps:D,getInputProps:O,isDragActive:A}=Da({onDrop:d,accept:{"application/pdf":[".pdf"]},multiple:!0,maxSize:52428800}),E=a=>{if(0===a)return"0 Bytes";const i=Math.floor(Math.log(a)/Math.log(1024));return parseFloat((a/Math.pow(1024,i)).toFixed(2))+" "+["Bytes","KB","MB","GB"][i]},P=a=>{switch(a){case"uploading":return g.jsx("div",{className:"animate-spin rounded-full h-4 w-4 border-b-2 border-primary-600"});case"uploaded":case"completed":return g.jsx(w,{className:"h-4 w-4 text-success-500"});case"processing":return g.jsx("div",{className:"animate-spin rounded-full h-4 w-4 border-b-2 border-accent-500"});case"error":return g.jsx(k,{className:"h-4 w-4 text-error-500"});default:return null}},F=(a,i,t)=>{switch(a){case"uploading":return"Uploading to Firebase Storage...";case"uploaded":return"Uploaded to Firebase Storage โœ“";case"processing":return"Processing with Document AI + Optimized Agentic RAG...";case"completed":return"Completed โœ“ (PDF automatically deleted)";case"error":return"Upload cancelled"===i?"Cancelled":t?"Firebase Storage Error":"Error";default:return""}};return g.jsxs("div",{className:"space-y-6",children:[g.jsx("div",{className:"bg-blue-50 border border-blue-200 rounded-lg p-4",children:g.jsxs("div",{className:"flex items-center",children:[g.jsx(w,{className:"h-5 w-5 text-blue-600 mr-2"}),g.jsxs("div",{children:[g.jsx("h3",{className:"text-sm font-medium text-blue-800",children:"Document AI + Optimized Agentic RAG Processing"}),g.jsx("p",{className:"text-sm text-blue-700 mt-1",children:"All documents are automatically processed using Google Document AI for extraction and our advanced optimized agentic RAG system for analysis, including intelligent chunking, vectorization, and multi-agent CIM review. PDFs are automatically deleted after processing."})]})]})}),g.jsxs("div",l(c({},D()),{className:b("border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-colors duration-200",A?"border-primary-500 bg-primary-50":"border-gray-300 hover:border-primary-400"),children:[g.jsx("input",c({},O())),g.jsx(h,{className:"mx-auto h-12 w-12 text-gray-400 mb-4"}),g.jsx("h3",{className:"text-lg font-medium text-primary-800 mb-2",children:A?"Drop files here":"Upload Documents"}),g.jsx("p",{className:"text-sm text-gray-600 mb-4",children:"Drag and drop PDF files here, or click to browse"}),g.jsx("p",{className:"text-xs text-gray-500",children:"Maximum file size: 50MB โ€ข Supported format: PDF โ€ข Stored securely in Firebase Storage โ€ข Automatic Document AI + Optimized Agentic RAG Processing โ€ข PDFs deleted after processing"})]})),p&&g.jsx("div",{className:"bg-warning-50 border border-warning-200 rounded-lg p-4",children:g.jsxs("div",{className:"flex items-center",children:[g.jsx(k,{className:"h-5 w-5 text-warning-600 mr-2"}),g.jsxs("div",{children:[g.jsx("h4",{className:"text-sm font-medium text-warning-800",children:"Upload in Progress"}),g.jsx("p",{className:"text-sm text-warning-700 mt-1",children:'Please don\'t navigate away from this page while files are uploading. Once files show "Uploaded โœ“", you can safely navigate away - processing will continue in the background.'})]})]})}),!p&&e.some(a=>"uploaded"===a.status)&&g.jsx("div",{className:"bg-success-50 border border-success-200 rounded-lg p-4",children:g.jsxs("div",{className:"flex items-center",children:[g.jsx(w,{className:"h-5 w-5 text-success-600 mr-2"}),g.jsxs("div",{children:[g.jsx("h4",{className:"text-sm font-medium text-success-800",children:"Upload Complete"}),g.jsx("p",{className:"text-sm text-success-700 mt-1",children:"Files have been uploaded successfully to Firebase Storage! You can now navigate away from this page. Processing will continue in the background using Document AI + Optimized Agentic RAG. This can take several minutes. PDFs will be automatically deleted after processing to save costs."})]})]})}),e.length>0&&g.jsxs("div",{className:"space-y-3",children:[g.jsx("h4",{className:"text-sm font-medium text-primary-800",children:"Uploaded Files"}),g.jsx("div",{className:"space-y-2",children:e.map(a=>g.jsxs("div",{className:"flex items-center justify-between p-3 bg-white border border-gray-200 rounded-lg",children:[g.jsxs("div",{className:"flex items-center space-x-3 flex-1 min-w-0",children:[g.jsx(y,{className:"h-5 w-5 text-gray-400 flex-shrink-0"}),g.jsxs("div",{className:"flex-1 min-w-0",children:[g.jsx("p",{className:"text-sm font-medium text-gray-900 truncate",children:a.name}),g.jsx("p",{className:"text-xs text-gray-500",children:E(a.size)})]})]}),g.jsxs("div",{className:"flex items-center space-x-3",children:[("uploading"===a.status||"processing"===a.status)&&g.jsx("div",{className:"w-24 bg-gray-200 rounded-full h-2",children:g.jsx("div",{className:"h-2 rounded-full transition-all duration-300 "+("uploading"===a.status?"bg-blue-600":"bg-orange-600"),style:{width:`${a.progress}%`}})}),g.jsxs("div",{className:"flex items-center space-x-1",children:[P(a.status),g.jsx("span",{className:"text-xs text-gray-600",children:F(a.status,a.error,a.storageError)}),"firebase"===a.storageType&&g.jsx(z,{className:"h-3 w-3 text-blue-500"})]}),g.jsx("button",{onClick:()=>(a=>{const i=s.current.get(a);i&&(i.abort(),s.current.delete(a)),n(i=>i.filter(i=>i.id!==a))})(a.id),className:"text-gray-400 hover:text-gray-600 transition-colors",disabled:"uploading"===a.status||"processing"===a.status,children:g.jsx(j,{className:"h-4 w-4"})})]})]},a.id))})]})]})};export{Ea as default}; diff --git a/backend/frontend-dist/assets/DocumentViewer-fda68f30.js b/backend/frontend-dist/assets/DocumentViewer-fda68f30.js new file mode 100644 index 0000000..0925669 --- /dev/null +++ b/backend/frontend-dist/assets/DocumentViewer-fda68f30.js @@ -0,0 +1,13 @@ +var e=Object.defineProperty,s=Object.defineProperties,t=Object.getOwnPropertyDescriptors,a=Object.getOwnPropertySymbols,r=Object.prototype.hasOwnProperty,i=Object.prototype.propertyIsEnumerable,n=(s,t,a)=>t in s?e(s,t,{enumerable:!0,configurable:!0,writable:!0,value:a}):s[t]=a,l=(e,s)=>{for(var t in s||(s={}))r.call(s,t)&&n(e,t,s[t]);if(a)for(var t of a(s))i.call(s,t)&&n(e,t,s[t]);return e},d=(e,a)=>s(e,t(a)),c=(e,s,t)=>new Promise((a,r)=>{var i=e=>{try{l(t.next(e))}catch(s){r(s)}},n=e=>{try{l(t.throw(e))}catch(s){r(s)}},l=e=>e.done?a(e.value):Promise.resolve(e.value).then(i,n);l((t=t.apply(e,s)).next())});import{c as o,R as m,r as x,j as u,a as h,d as y,L as g,F as p,B as v,T as b}from"./index-9817dacc.js";import{D as f}from"./download-aacd5336.js";import{X as j}from"./x-d6da8175.js";import{C as w,A as N}from"./check-circle-937a9172.js";import{A as k}from"./alert-triangle-326a303a.js";import{C as S}from"./clock-9f043116.js"; +/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const C=o("ArrowLeft",[["path",{d:"m12 19-7-7 7-7",key:"1l729n"}],["path",{d:"M19 12H5",key:"x3x0zl"}]]),I=o("DollarSign",[["line",{x1:"12",x2:"12",y1:"2",y2:"22",key:"7eqyqh"}],["path",{d:"M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6",key:"1b0p4s"}]]),M=o("Save",[["path",{d:"M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z",key:"1owoqh"}],["polyline",{points:"17 21 17 13 7 13 7 21",key:"1md35c"}],["polyline",{points:"7 3 7 8 15 8",key:"8nz8an"}]]),D=o("Share2",[["circle",{cx:"18",cy:"5",r:"3",key:"gq8acd"}],["circle",{cx:"6",cy:"12",r:"3",key:"w7nqdw"}],["circle",{cx:"18",cy:"19",r:"3",key:"1xt0gg"}],["line",{x1:"8.59",x2:"15.42",y1:"13.51",y2:"17.49",key:"47mynk"}],["line",{x1:"15.41",x2:"8.59",y1:"6.51",y2:"10.49",key:"1n3mei"}]]),O=o("UserPlus",[["path",{d:"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",key:"1yyitq"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}],["line",{x1:"19",x2:"19",y1:"8",y2:"14",key:"1bvyxn"}],["line",{x1:"22",x2:"16",y1:"11",y2:"11",key:"1shjgl"}]]),T=o("Users",[["path",{d:"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",key:"1yyitq"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}],["path",{d:"M22 21v-2a4 4 0 0 0-3-3.87",key:"kshegd"}],["path",{d:"M16 3.13a4 4 0 0 1 0 7.75",key:"1da9ce"}]]),R=m.memo(({initialData:e={},cimReviewData:s,onSave:t,onExport:a,readOnly:r=!1})=>{var i;try{if(s&&"object"!=typeof s)throw new Error(`Invalid cimReviewData type: ${typeof s}. Expected object, got ${typeof s}`);if(e&&"object"!=typeof e)throw new Error(`Invalid initialData type: ${typeof e}. Expected object, got ${typeof e}`);s&&Object.keys(s).length>0||e&&Object.keys(e).length;const[n,o]=x.useState({dealOverview:e.dealOverview||{targetCompanyName:"",industrySector:"",geography:"",dealSource:"",transactionType:"",dateCIMReceived:"",dateReviewed:"",reviewers:"",cimPageCount:"",statedReasonForSale:"",employeeCount:""},businessDescription:e.businessDescription||{coreOperationsSummary:"",keyProductsServices:"",uniqueValueProposition:"",customerBaseOverview:{keyCustomerSegments:"",customerConcentrationRisk:"",typicalContractLength:""},keySupplierOverview:{dependenceConcentrationRisk:""}},marketIndustryAnalysis:e.marketIndustryAnalysis||{estimatedMarketSize:"",estimatedMarketGrowthRate:"",keyIndustryTrends:"",competitiveLandscape:{keyCompetitors:"",targetMarketPosition:"",basisOfCompetition:""},barriersToEntry:""},financialSummary:e.financialSummary||{financials:{fy3:{revenue:"",revenueGrowth:"",grossProfit:"",grossMargin:"",ebitda:"",ebitdaMargin:""},fy2:{revenue:"",revenueGrowth:"",grossProfit:"",grossMargin:"",ebitda:"",ebitdaMargin:""},fy1:{revenue:"",revenueGrowth:"",grossProfit:"",grossMargin:"",ebitda:"",ebitdaMargin:""},ltm:{revenue:"",revenueGrowth:"",grossProfit:"",grossMargin:"",ebitda:"",ebitdaMargin:""}},qualityOfEarnings:"",revenueGrowthDrivers:"",marginStabilityAnalysis:"",capitalExpenditures:"",workingCapitalIntensity:"",freeCashFlowQuality:""},managementTeamOverview:e.managementTeamOverview||{keyLeaders:"",managementQualityAssessment:"",postTransactionIntentions:"",organizationalStructure:""},preliminaryInvestmentThesis:e.preliminaryInvestmentThesis||{keyAttractions:"",potentialRisks:"",valueCreationLevers:"",alignmentWithFundStrategy:""},keyQuestionsNextSteps:e.keyQuestionsNextSteps||{criticalQuestions:"",missingInformation:"",preliminaryRecommendation:"",rationaleForRecommendation:"",proposedNextSteps:""}}),[m,y]=x.useState("deal-overview"),[g,p]=x.useState("idle"),[v,b]=x.useState(null),[j,w]=x.useState(null);x.useEffect(()=>{if(s&&"object"==typeof s&&Object.keys(s).length>0)try{o(e=>l(l({},e),s))}catch(e){}},[s]),x.useEffect(()=>{var e;(null==(e=n.financialSummary)?void 0:e.financials)||o(e=>d(l({},e),{financialSummary:d(l({},e.financialSummary),{financials:{fy3:{revenue:"",revenueGrowth:"",grossProfit:"",grossMargin:"",ebitda:"",ebitdaMargin:""},fy2:{revenue:"",revenueGrowth:"",grossProfit:"",grossMargin:"",ebitda:"",ebitdaMargin:""},fy1:{revenue:"",revenueGrowth:"",grossProfit:"",grossMargin:"",ebitda:"",ebitdaMargin:""},ltm:{revenue:"",revenueGrowth:"",grossProfit:"",grossMargin:"",ebitda:"",ebitdaMargin:""}}})}))},[null==(i=n.financialSummary)?void 0:i.financials]);const N=(e,s,t)=>{o(a=>d(l({},a),{financialSummary:d(l({},a.financialSummary),{financials:d(l({},a.financialSummary.financials),{[e]:d(l({},a.financialSummary.financials[e]),{[s]:t})})})}))},k=()=>c(void 0,null,function*(){if(!r)try{p("saving"),yield null==t?void 0:t(n),p("saved"),b(new Date),setTimeout(()=>{p("idle")},3e3)}catch(e){p("error"),setTimeout(()=>{p("idle")},5e3)}}),S=()=>{if(r)return;j&&clearTimeout(j);const e=setTimeout(()=>{k()},2e3);w(e)};x.useEffect(()=>()=>{j&&clearTimeout(j)},[j]);const C=()=>{null==a||a(n)},I=[{id:"deal-overview",title:"Deal Overview",icon:"๐Ÿ“‹"},{id:"business-description",title:"Business Description",icon:"๐Ÿข"},{id:"market-analysis",title:"Market & Industry Analysis",icon:"๐Ÿ“Š"},{id:"financial-summary",title:"Financial Summary",icon:"๐Ÿ’ฐ"},{id:"management-team",title:"Management Team Overview",icon:"๐Ÿ‘ฅ"},{id:"investment-thesis",title:"Preliminary Investment Thesis",icon:"๐ŸŽฏ"},{id:"next-steps",title:"Key Questions & Next Steps",icon:"โžก๏ธ"}],D=(e,s,t="text",a,i)=>{const d=s.split("."),c=O(n,d),m=e=>{o(s=>{const t=l({},s);let a=t;for(let e=0;e{m(e.target.value),S()},placeholder:a,rows:i||3,disabled:r,className:"block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 sm:text-sm disabled:bg-gray-50 disabled:text-gray-500"}):"date"===t?u.jsx("input",{type:"date",value:c||"",onChange:e=>{m(e.target.value),S()},disabled:r,className:"block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 sm:text-sm disabled:bg-gray-50 disabled:text-gray-500"}):u.jsx("input",{type:"text",value:c||"",onChange:e=>{m(e.target.value),S()},placeholder:a,disabled:r,className:"block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 sm:text-sm disabled:bg-gray-50 disabled:text-gray-500"})]})},O=(e,s)=>{let t=e;for(const a of s){if(!t||"object"!=typeof t||!(a in t))return"";t=t[a]}return"string"==typeof t?t:""},T=()=>{var e;let s=null==(e=n.financialSummary)?void 0:e.financials;s&&"object"==typeof s||(s={fy3:{revenue:"",revenueGrowth:"",grossProfit:"",grossMargin:"",ebitda:"",ebitdaMargin:""},fy2:{revenue:"",revenueGrowth:"",grossProfit:"",grossMargin:"",ebitda:"",ebitdaMargin:""},fy1:{revenue:"",revenueGrowth:"",grossProfit:"",grossMargin:"",ebitda:"",ebitdaMargin:""},ltm:{revenue:"",revenueGrowth:"",grossProfit:"",grossMargin:"",ebitda:"",ebitdaMargin:""}});return["fy3","fy2","fy1","ltm"].forEach(e=>{s[e]&&"object"==typeof s[e]||(s[e]={revenue:"",revenueGrowth:"",grossProfit:"",grossMargin:"",ebitda:"",ebitdaMargin:""})}),u.jsxs("div",{className:"space-y-4",children:[u.jsx("h4",{className:"text-lg font-medium text-gray-900",children:"Key Historical Financials"}),u.jsx("div",{className:"overflow-x-auto",children:u.jsxs("table",{className:"min-w-full divide-y divide-gray-200",children:[u.jsx("thead",{className:"bg-gray-50",children:u.jsxs("tr",{children:[u.jsx("th",{className:"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider",children:"Metric"}),u.jsx("th",{className:"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider",children:"FY-3"}),u.jsx("th",{className:"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider",children:"FY-2"}),u.jsx("th",{className:"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider",children:"FY-1"}),u.jsx("th",{className:"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider",children:"LTM"})]})}),u.jsxs("tbody",{className:"bg-white divide-y divide-gray-200",children:[u.jsxs("tr",{children:[u.jsx("td",{className:"px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900",children:"Revenue"}),["fy3","fy2","fy1","ltm"].map(e=>{var t;return u.jsx("td",{className:"px-6 py-4 whitespace-nowrap",children:u.jsx("input",{type:"text",value:(null==(t=s[e])?void 0:t.revenue)||"",onChange:s=>{N(e,"revenue",s.target.value),S()},placeholder:"$0",disabled:r,className:"block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 sm:text-sm disabled:bg-gray-50 disabled:text-gray-500"})},e)})]}),u.jsxs("tr",{children:[u.jsx("td",{className:"px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900",children:"Revenue Growth (%)"}),["fy3","fy2","fy1","ltm"].map(e=>{var t;return u.jsx("td",{className:"px-6 py-4 whitespace-nowrap",children:u.jsx("input",{type:"text",value:(null==(t=s[e])?void 0:t.revenueGrowth)||"",onChange:s=>{N(e,"revenueGrowth",s.target.value),S()},placeholder:"0%",disabled:r,className:"block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 sm:text-sm disabled:bg-gray-50 disabled:text-gray-500"})},e)})]}),u.jsxs("tr",{children:[u.jsx("td",{className:"px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900",children:"EBITDA"}),["fy3","fy2","fy1","ltm"].map(e=>{var t;return u.jsx("td",{className:"px-6 py-4 whitespace-nowrap",children:u.jsx("input",{type:"text",value:(null==(t=s[e])?void 0:t.ebitda)||"",onChange:s=>{N(e,"ebitda",s.target.value),S()},placeholder:"$0",disabled:r,className:"block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 sm:text-sm disabled:bg-gray-50 disabled:text-gray-500"})},e)})]}),u.jsxs("tr",{children:[u.jsx("td",{className:"px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900",children:"EBITDA Margin (%)"}),["fy3","fy2","fy1","ltm"].map(e=>{var t;return u.jsx("td",{className:"px-6 py-4 whitespace-nowrap",children:u.jsx("input",{type:"text",value:(null==(t=s[e])?void 0:t.ebitdaMargin)||"",onChange:s=>{N(e,"ebitdaMargin",s.target.value),S()},placeholder:"0%",disabled:r,className:"block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 sm:text-sm disabled:bg-gray-50 disabled:text-gray-500"})},e)})]})]})]})})]})},R=()=>{switch(m){case"deal-overview":return u.jsxs("div",{className:"space-y-6",children:[u.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-6",children:[D("Target Company Name","dealOverview.targetCompanyName"),D("Industry/Sector","dealOverview.industrySector"),D("Geography (HQ & Key Operations)","dealOverview.geography"),D("Deal Source","dealOverview.dealSource"),D("Transaction Type","dealOverview.transactionType"),D("Date CIM Received","dealOverview.dateCIMReceived","date"),D("Date Reviewed","dealOverview.dateReviewed","date"),D("Reviewer(s)","dealOverview.reviewers"),D("CIM Page Count","dealOverview.cimPageCount"),D("Employee Count","dealOverview.employeeCount")]}),D("Stated Reason for Sale (if provided)","dealOverview.statedReasonForSale","textarea","Enter the stated reason for sale...",4)]});case"business-description":return u.jsxs("div",{className:"space-y-6",children:[D("Core Operations Summary (3-5 sentences)","businessDescription.coreOperationsSummary","textarea","Describe the core operations...",4),D("Key Products/Services & Revenue Mix (Est. % if available)","businessDescription.keyProductsServices","textarea","List key products/services and revenue mix...",4),D("Unique Value Proposition (UVP) / Why Customers Buy","businessDescription.uniqueValueProposition","textarea","Describe the unique value proposition...",4),u.jsxs("div",{className:"space-y-4",children:[u.jsx("h4",{className:"text-lg font-medium text-gray-900",children:"Customer Base Overview"}),u.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-6",children:[D("Key Customer Segments/Types","businessDescription.customerBaseOverview.keyCustomerSegments"),D("Customer Concentration Risk (Top 5 and/or Top 10 Customers as % Revenue)","businessDescription.customerBaseOverview.customerConcentrationRisk"),D("Typical Contract Length / Recurring Revenue %","businessDescription.customerBaseOverview.typicalContractLength")]})]}),u.jsxs("div",{className:"space-y-4",children:[u.jsx("h4",{className:"text-lg font-medium text-gray-900",children:"Key Supplier Overview (if critical & mentioned)"}),D("Dependence/Concentration Risk","businessDescription.keySupplierOverview.dependenceConcentrationRisk","textarea","Describe supplier dependencies...",3)]})]});case"market-analysis":return u.jsxs("div",{className:"space-y-6",children:[u.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-6",children:[D("Estimated Market Size (TAM/SAM - if provided)","marketIndustryAnalysis.estimatedMarketSize"),D("Estimated Market Growth Rate (% CAGR - Historical & Projected)","marketIndustryAnalysis.estimatedMarketGrowthRate")]}),D("Key Industry Trends & Drivers (Tailwinds/Headwinds)","marketIndustryAnalysis.keyIndustryTrends","textarea","Describe key industry trends...",4),u.jsxs("div",{className:"space-y-4",children:[u.jsx("h4",{className:"text-lg font-medium text-gray-900",children:"Competitive Landscape"}),u.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-6",children:[D("Key Competitors Identified","marketIndustryAnalysis.competitiveLandscape.keyCompetitors"),D("Target's Stated Market Position/Rank","marketIndustryAnalysis.competitiveLandscape.targetMarketPosition"),D("Basis of Competition","marketIndustryAnalysis.competitiveLandscape.basisOfCompetition")]})]}),D("Barriers to Entry / Competitive Moat (Stated/Inferred)","marketIndustryAnalysis.barriersToEntry","textarea","Describe barriers to entry...",4)]});case"financial-summary":return u.jsxs("div",{className:"space-y-6",children:[T(),u.jsxs("div",{className:"space-y-4",children:[u.jsx("h4",{className:"text-lg font-medium text-gray-900",children:"Key Financial Notes & Observations"}),u.jsxs("div",{className:"grid grid-cols-1 gap-6",children:[D("Quality of Earnings/Adjustments (Initial Impression)","financialSummary.qualityOfEarnings","textarea","Assess quality of earnings...",3),D("Revenue Growth Drivers (Stated)","financialSummary.revenueGrowthDrivers","textarea","Identify revenue growth drivers...",3),D("Margin Stability/Trend Analysis","financialSummary.marginStabilityAnalysis","textarea","Analyze margin trends...",3),D("Capital Expenditures (Approx. LTM % of Revenue)","financialSummary.capitalExpenditures"),D("Working Capital Intensity (Impression)","financialSummary.workingCapitalIntensity","textarea","Assess working capital intensity...",3),D("Free Cash Flow (FCF) Proxy Quality (Impression)","financialSummary.freeCashFlowQuality","textarea","Assess FCF quality...",3)]})]})]});case"management-team":return u.jsxs("div",{className:"space-y-6",children:[D("Key Leaders Identified (CEO, CFO, COO, Head of Sales, etc.)","managementTeamOverview.keyLeaders","textarea","List key leaders...",4),D("Initial Assessment of Quality/Experience (Based on Bios)","managementTeamOverview.managementQualityAssessment","textarea","Assess management quality...",4),D("Management's Stated Post-Transaction Role/Intentions (if mentioned)","managementTeamOverview.postTransactionIntentions","textarea","Describe post-transaction intentions...",4),D("Organizational Structure Overview (Impression)","managementTeamOverview.organizationalStructure","textarea","Describe organizational structure...",4)]});case"investment-thesis":return u.jsxs("div",{className:"space-y-6",children:[D("Key Attractions / Strengths (Why Invest?)","preliminaryInvestmentThesis.keyAttractions","textarea","List key attractions...",8),D("Potential Risks / Concerns (Why Not Invest?)","preliminaryInvestmentThesis.potentialRisks","textarea","List potential risks...",8),D("Initial Value Creation Levers (How PE Adds Value)","preliminaryInvestmentThesis.valueCreationLevers","textarea","Identify value creation levers...",8),D("Alignment with Fund Strategy","preliminaryInvestmentThesis.alignmentWithFundStrategy","textarea","Assess alignment with BPCP strategy...",8)]});case"next-steps":return u.jsxs("div",{className:"space-y-6",children:[D("Critical Questions Arising from CIM Review","keyQuestionsNextSteps.criticalQuestions","textarea","List critical questions...",8),D("Key Missing Information / Areas for Diligence Focus","keyQuestionsNextSteps.missingInformation","textarea","Identify missing information...",8),D("Preliminary Recommendation","keyQuestionsNextSteps.preliminaryRecommendation"),D("Rationale for Recommendation (Brief)","keyQuestionsNextSteps.rationaleForRecommendation","textarea","Provide rationale...",6),D("Proposed Next Steps","keyQuestionsNextSteps.proposedNextSteps","textarea","Outline next steps...",8)]});default:return null}};return u.jsxs("div",{className:"max-w-7xl mx-auto",children:[u.jsx("div",{className:"bg-white shadow-sm border-b border-gray-200 px-4 py-4 sm:px-6 lg:px-8",children:u.jsxs("div",{className:"flex items-center justify-between",children:[u.jsxs("div",{children:[u.jsx("h1",{className:"text-2xl font-bold text-gray-900",children:"BPCP CIM Review Template"}),u.jsx("p",{className:"text-sm text-gray-600 mt-1",children:"Comprehensive review template for Confidential Information Memorandums"}),!r&&u.jsxs("div",{className:"flex items-center mt-2 space-x-2",children:["saving"===g&&u.jsxs("div",{className:"flex items-center text-blue-600",children:[u.jsx("div",{className:"animate-spin rounded-full h-4 w-4 border-b-2 border-blue-600 mr-2"}),u.jsx("span",{className:"text-sm",children:"Saving..."})]}),"saved"===g&&u.jsxs("div",{className:"flex items-center text-green-600",children:[u.jsx("svg",{className:"h-4 w-4 mr-2",fill:"currentColor",viewBox:"0 0 20 20",children:u.jsx("path",{fillRule:"evenodd",d:"M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z",clipRule:"evenodd"})}),u.jsx("span",{className:"text-sm",children:"Saved"})]}),"error"===g&&u.jsxs("div",{className:"flex items-center text-red-600",children:[u.jsx("svg",{className:"h-4 w-4 mr-2",fill:"currentColor",viewBox:"0 0 20 20",children:u.jsx("path",{fillRule:"evenodd",d:"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z",clipRule:"evenodd"})}),u.jsx("span",{className:"text-sm",children:"Save failed"})]}),v&&"idle"===g&&u.jsxs("span",{className:"text-sm text-gray-500",children:["Last saved: ",v.toLocaleTimeString()]})]})]}),u.jsxs("div",{className:"flex items-center space-x-3",children:[!r&&u.jsxs("button",{onClick:k,disabled:"saving"===g,className:"inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 disabled:opacity-50 disabled:cursor-not-allowed",children:[u.jsx(M,{className:"h-4 w-4 mr-2"}),"saving"===g?"Saving...":"Save"]}),u.jsxs("button",{onClick:C,className:"inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md shadow-sm text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500",children:[u.jsx(f,{className:"h-4 w-4 mr-2"}),"Export"]})]})]})}),u.jsxs("div",{className:"flex",children:[u.jsx("div",{className:"w-64 bg-gray-50 border-r border-gray-200 min-h-screen",children:u.jsx("nav",{className:"mt-5 px-2",children:u.jsx("div",{className:"space-y-1",children:I.map(e=>u.jsxs("button",{onClick:()=>y(e.id),className:h("group flex items-center px-3 py-2 text-sm font-medium rounded-md w-full text-left",m===e.id?"bg-blue-100 text-blue-700":"text-gray-600 hover:bg-gray-100 hover:text-gray-900"),children:[u.jsx("span",{className:"mr-3",children:e.icon}),e.title]},e.id))})})}),u.jsx("div",{className:"flex-1 bg-white",children:u.jsx("div",{className:"px-4 py-6 sm:px-6 lg:px-8",children:u.jsx("div",{className:"max-w-4xl",children:R()})})})]})]})}catch(n){return u.jsx("div",{className:"min-h-screen bg-gray-50 flex items-center justify-center",children:u.jsx("div",{className:"bg-white shadow-sm border border-gray-200 rounded-lg p-8 max-w-md",children:u.jsxs("div",{className:"text-center",children:[u.jsx("div",{className:"mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-red-100 mb-4",children:u.jsx("svg",{className:"h-6 w-6 text-red-600",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:u.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z"})})}),u.jsx("h3",{className:"text-lg font-medium text-gray-900 mb-2",children:"Error Loading Template"}),u.jsx("p",{className:"text-sm text-gray-600 mb-4",children:"There was an error loading the CIM Review Template. Please try refreshing the page."}),u.jsx("button",{onClick:()=>window.location.reload(),className:"inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-blue-600 hover:bg-blue-700",children:"Refresh Page"})]})})})}}),A=({documentId:e,documentName:s,isOpen:t,onClose:a})=>{const[r,i]=x.useState(""),[n,l]=x.useState(!1),[d,o]=x.useState(""),[h,g]=x.useState(""),[p,v]=x.useState([]),[b,f]=x.useState(!1);m.useEffect(()=>{t&&k()},[t,e]);const k=()=>c(void 0,null,function*(){f(!0);try{const s=yield y.getDocumentShares(e);v(s)}catch(s){}finally{f(!1)}});return t?u.jsx("div",{className:"fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50",children:u.jsxs("div",{className:"bg-white rounded-lg shadow-xl max-w-md w-full mx-4 max-h-[90vh] overflow-y-auto",children:[u.jsxs("div",{className:"flex items-center justify-between p-6 border-b border-gray-200",children:[u.jsxs("div",{className:"flex items-center",children:[u.jsx(O,{className:"h-5 w-5 text-blue-600 mr-2"}),u.jsx("h2",{className:"text-lg font-semibold text-gray-900",children:"Share Document"})]}),u.jsx("button",{onClick:a,className:"text-gray-400 hover:text-gray-600 transition-colors",children:u.jsx(j,{className:"h-5 w-5"})})]}),u.jsxs("div",{className:"p-6 space-y-6",children:[u.jsxs("div",{className:"bg-gray-50 rounded-lg p-4",children:[u.jsx("h3",{className:"font-medium text-gray-900 mb-1",children:s}),u.jsxs("p",{className:"text-sm text-gray-600",children:["Document ID: ",e]})]}),u.jsxs("form",{onSubmit:s=>c(void 0,null,function*(){if(s.preventDefault(),r.trim()){l(!0),g(""),o("");try{const s=r.trim();yield y.shareDocument(e,s),o(`Document shared successfully with ${r}`),i(""),yield k()}catch(t){g(t.message||"Failed to share document")}finally{l(!1)}}}),className:"space-y-4",children:[u.jsxs("div",{children:[u.jsx("label",{htmlFor:"email",className:"block text-sm font-medium text-gray-700 mb-1",children:"Share with User (Email/User ID)"}),u.jsx("input",{type:"text",id:"email",value:r,onChange:e=>i(e.target.value),placeholder:"Enter user email or ID",className:"w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500",disabled:n})]}),u.jsx("button",{type:"submit",disabled:!r.trim()||n,className:"w-full flex justify-center items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 disabled:opacity-50 disabled:cursor-not-allowed",children:n?u.jsxs(u.Fragment,{children:[u.jsx("div",{className:"animate-spin rounded-full h-4 w-4 border-b-2 border-white mr-2"}),"Sharing..."]}):u.jsxs(u.Fragment,{children:[u.jsx(O,{className:"h-4 w-4 mr-2"}),"Share Document"]})})]}),d&&u.jsxs("div",{className:"flex items-center p-3 bg-green-50 border border-green-200 rounded-md",children:[u.jsx(w,{className:"h-4 w-4 text-green-600 mr-2"}),u.jsx("span",{className:"text-sm text-green-800",children:d})]}),h&&u.jsxs("div",{className:"flex items-center p-3 bg-red-50 border border-red-200 rounded-md",children:[u.jsx(N,{className:"h-4 w-4 text-red-600 mr-2"}),u.jsx("span",{className:"text-sm text-red-800",children:h})]}),u.jsxs("div",{className:"border-t border-gray-200 pt-4",children:[u.jsxs("h3",{className:"text-sm font-medium text-gray-900 mb-3 flex items-center",children:[u.jsx(T,{className:"h-4 w-4 mr-2"}),"Currently Shared With"]}),b?u.jsxs("div",{className:"text-center py-4",children:[u.jsx("div",{className:"animate-spin rounded-full h-4 w-4 border-b-2 border-blue-600 mx-auto"}),u.jsx("p",{className:"text-sm text-gray-600 mt-2",children:"Loading shares..."})]}):p.length>0?u.jsx("div",{className:"space-y-2",children:p.filter(e=>"shared"===e.accessType).map((s,t)=>u.jsxs("div",{className:"flex items-center justify-between p-3 bg-gray-50 rounded-md",children:[u.jsxs("div",{children:[u.jsx("p",{className:"text-sm font-medium text-gray-900",children:s.userId}),u.jsx("p",{className:"text-xs text-gray-500",children:s.createdAt?`Shared on ${new Date(s.createdAt).toLocaleDateString()}`:"Shared recently"})]}),u.jsx("button",{onClick:()=>{return t=s.userId,c(void 0,null,function*(){try{yield y.revokeDocumentShare(e,t),o("Access revoked successfully"),yield k()}catch(s){g(s.message||"Failed to revoke access")}});var t},className:"text-xs text-red-600 hover:text-red-800 font-medium",children:"Revoke"})]},t))}):u.jsx("p",{className:"text-sm text-gray-500 text-center py-4",children:"No users have access to this document yet."})]})]}),u.jsx("div",{className:"flex justify-end p-6 border-t border-gray-200",children:u.jsx("button",{onClick:a,className:"px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500",children:"Close"})})]})}):null},P=m.memo(({documentId:e,documentName:s,extractedData:t,cimReviewData:a,onBack:r,onDownload:i})=>{if(!e||!s)throw new Error("Document ID and name are required");const[n,l]=x.useState("overview"),[d,o]=x.useState(!1),m=[{id:"overview",label:"Overview",icon:p},{id:"template",label:"Review Template",icon:v},{id:"raw",label:"Raw Data",icon:p}],j=s=>c(void 0,null,function*(){try{yield y.saveCIMReview(e,s)}catch(t){throw t}}),N=s=>c(void 0,null,function*(){var t;try{const a=yield y.exportCSV(e),r=window.URL.createObjectURL(a),i=document.createElement("a");i.href=r;const n=(null==(t=null==s?void 0:s.dealOverview)?void 0:t.targetCompanyName)||"Unknown",l=(new Date).toISOString().split("T")[0].replace(/-/g,""),d=`${l}_${n.replace(/[^a-zA-Z0-9\s]/g,"").replace(/\s+/g,"_").toUpperCase()}_CIM_Data.csv`;i.download=d,document.body.appendChild(i),i.click(),document.body.removeChild(i),window.URL.revokeObjectURL(r)}catch(a){throw a}});return u.jsxs("div",{className:"max-w-7xl mx-auto",children:[u.jsx(A,{documentId:e,documentName:s,isOpen:d,onClose:()=>o(!1)}),u.jsx("div",{className:"bg-white shadow-sm border-b border-gray-200 px-4 py-4 sm:px-6 lg:px-8",children:u.jsxs("div",{className:"flex items-center justify-between",children:[u.jsxs("div",{className:"flex items-center",children:[u.jsx("button",{onClick:r,className:"mr-4 p-2 text-gray-400 hover:text-gray-600 transition-colors",children:u.jsx(C,{className:"h-5 w-5"})}),u.jsxs("div",{children:[u.jsx("h1",{className:"text-xl font-semibold text-gray-900",children:"Document Viewer"}),u.jsx("p",{className:"text-sm text-gray-600",children:s})]})]}),u.jsx("div",{className:"flex items-center space-x-4",children:u.jsx(g,{variant:"button",className:"bg-error-500 hover:bg-error-600 text-white"})})]})}),u.jsx("div",{className:"bg-white border-b border-gray-200",children:u.jsx("div",{className:"px-4 sm:px-6 lg:px-8",children:u.jsx("nav",{className:"-mb-px flex space-x-8",children:m.map(e=>{const s=e.icon;return u.jsxs("button",{onClick:()=>l(e.id),className:h("flex items-center py-4 px-1 border-b-2 font-medium text-sm",n===e.id?"border-blue-500 text-blue-600":"border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300"),children:[u.jsx(s,{className:"h-4 w-4 mr-2"}),e.label]},e.id)})})})}),u.jsxs("div",{className:"px-4 py-6 sm:px-6 lg:px-8",children:["overview"===n&&u.jsxs("div",{className:"space-y-6",children:[u.jsx("div",{className:"bg-white rounded-lg shadow-sm border border-gray-200 p-6",children:u.jsxs("div",{className:"flex items-center justify-between",children:[u.jsxs("div",{children:[u.jsx("h2",{className:"text-2xl font-bold text-gray-900",children:s}),u.jsxs("p",{className:"text-sm text-gray-600 mt-1",children:["Document ID: ",e]})]}),u.jsxs("div",{className:"flex items-center space-x-3",children:[u.jsxs("button",{onClick:i,className:"inline-flex items-center px-3 py-2 border border-gray-300 shadow-sm text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500",children:[u.jsx(f,{className:"h-4 w-4 mr-2"}),"Download"]}),u.jsxs("button",{onClick:()=>o(!0),className:"inline-flex items-center px-3 py-2 border border-gray-300 shadow-sm text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500",children:[u.jsx(D,{className:"h-4 w-4 mr-2"}),"Share Document"]})]})]})}),!t&&!a&&u.jsx("div",{className:"bg-yellow-50 border border-yellow-200 rounded p-6",children:u.jsxs("div",{className:"flex items-center",children:[u.jsx("div",{className:"flex-shrink-0",children:u.jsx(k,{className:"h-8 w-8 text-yellow-600"})}),u.jsxs("div",{className:"ml-4",children:[u.jsx("h3",{className:"text-lg font-medium text-yellow-800",children:"No Data Available"}),u.jsx("p",{className:"text-yellow-700 mt-1",children:"This document doesn't have any processed data yet. The data will be available after the document has been fully processed."}),u.jsxs("div",{className:"mt-4 text-sm text-yellow-600",children:[u.jsxs("p",{children:[u.jsx("strong",{children:"Document Status:"})," Processing"]}),u.jsxs("p",{children:[u.jsx("strong",{children:"Document ID:"})," ",e]})]})]})]})}),t&&u.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6",children:[u.jsx("div",{className:"bg-white rounded-lg shadow-sm border border-gray-200 p-6",children:u.jsxs("div",{className:"flex items-center",children:[u.jsx("div",{className:"flex-shrink-0",children:u.jsx(I,{className:"h-8 w-8 text-green-600"})}),u.jsxs("div",{className:"ml-4",children:[u.jsx("p",{className:"text-sm font-medium text-gray-500",children:"Revenue"}),u.jsx("p",{className:"text-2xl font-semibold text-gray-900",children:t.revenue||"N/A"})]})]})}),u.jsx("div",{className:"bg-white rounded-lg shadow-sm border border-gray-200 p-6",children:u.jsxs("div",{className:"flex items-center",children:[u.jsx("div",{className:"flex-shrink-0",children:u.jsx(b,{className:"h-8 w-8 text-blue-600"})}),u.jsxs("div",{className:"ml-4",children:[u.jsx("p",{className:"text-sm font-medium text-gray-500",children:"EBITDA"}),u.jsx("p",{className:"text-2xl font-semibold text-gray-900",children:t.ebitda||"N/A"})]})]})}),u.jsx("div",{className:"bg-white rounded-lg shadow-sm border border-gray-200 p-6",children:u.jsxs("div",{className:"flex items-center",children:[u.jsx("div",{className:"flex-shrink-0",children:u.jsx(T,{className:"h-8 w-8 text-purple-600"})}),u.jsxs("div",{className:"ml-4",children:[u.jsx("p",{className:"text-sm font-medium text-gray-500",children:"Employees"}),u.jsx("p",{className:"text-2xl font-semibold text-gray-900",children:t.employees||"N/A"})]})]})}),u.jsx("div",{className:"bg-white rounded-lg shadow-sm border border-gray-200 p-6",children:u.jsxs("div",{className:"flex items-center",children:[u.jsx("div",{className:"flex-shrink-0",children:u.jsx(S,{className:"h-8 w-8 text-orange-600"})}),u.jsxs("div",{className:"ml-4",children:[u.jsx("p",{className:"text-sm font-medium text-gray-500",children:"Founded"}),u.jsx("p",{className:"text-2xl font-semibold text-gray-900",children:t.founded||"N/A"})]})]})})]}),(null==t?void 0:t.summary)&&u.jsxs("div",{className:"bg-white rounded-lg shadow-sm border border-gray-200 p-6",children:[u.jsx("h3",{className:"text-lg font-medium text-gray-900 mb-4",children:"Document Analysis"}),u.jsx("div",{className:"bg-blue-50 border border-blue-200 rounded-lg p-4",children:u.jsxs("div",{className:"flex items-center",children:[u.jsx("div",{className:"flex-shrink-0",children:u.jsx(p,{className:"h-5 w-5 text-blue-600"})}),u.jsxs("div",{className:"ml-3",children:[u.jsx("h4",{className:"text-sm font-medium text-blue-900",children:"Structured CIM Review Available"}),u.jsx("p",{className:"text-sm text-blue-700 mt-1",children:'This document has been analyzed and structured into a comprehensive CIM review template. Switch to the "Template" tab to view the detailed analysis in a structured format.'})]})]})})]}),t&&u.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-6",children:[u.jsxs("div",{className:"bg-white rounded-lg shadow-sm border border-gray-200 p-6",children:[u.jsxs("div",{className:"flex items-center mb-4",children:[u.jsx(w,{className:"h-5 w-5 text-green-600 mr-2"}),u.jsx("h3",{className:"text-lg font-medium text-gray-900",children:"Key Opportunities"})]}),t.opportunities&&t.opportunities.length>0?u.jsx("ul",{className:"space-y-2",children:t.opportunities.map((e,s)=>u.jsxs("li",{className:"flex items-start",children:[u.jsx("span",{className:"text-green-500 mr-2",children:"โ€ข"}),u.jsx("span",{className:"text-gray-700",children:e})]},s))}):u.jsx("p",{className:"text-gray-500 italic",children:"No opportunities identified"})]}),u.jsxs("div",{className:"bg-white rounded-lg shadow-sm border border-gray-200 p-6",children:[u.jsxs("div",{className:"flex items-center mb-4",children:[u.jsx(k,{className:"h-5 w-5 text-red-600 mr-2"}),u.jsx("h3",{className:"text-lg font-medium text-gray-900",children:"Key Risks"})]}),t.risks&&t.risks.length>0?u.jsx("ul",{className:"space-y-2",children:t.risks.map((e,s)=>u.jsxs("li",{className:"flex items-start",children:[u.jsx("span",{className:"text-red-500 mr-2",children:"โ€ข"}),u.jsx("span",{className:"text-gray-700",children:e})]},s))}):u.jsx("p",{className:"text-gray-500 italic",children:"No risks identified"})]})]}),(null==t?void 0:t.financials)&&u.jsxs("div",{className:"bg-white rounded-lg shadow-sm border border-gray-200 p-6",children:[u.jsx("h3",{className:"text-lg font-medium text-gray-900 mb-4",children:"Financial Trends"}),u.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-6",children:[u.jsxs("div",{children:[u.jsx("h4",{className:"text-sm font-medium text-gray-500 mb-2",children:"Revenue"}),u.jsx("div",{className:"space-y-1",children:t.financials.revenue.map((e,s)=>u.jsxs("div",{className:"flex justify-between text-sm",children:[u.jsx("span",{className:"text-gray-600",children:3===s?"LTM":"FY"+(3-s)}),u.jsx("span",{className:"font-medium",children:e})]},s))})]}),u.jsxs("div",{children:[u.jsx("h4",{className:"text-sm font-medium text-gray-500 mb-2",children:"EBITDA"}),u.jsx("div",{className:"space-y-1",children:t.financials.ebitda.map((e,s)=>u.jsxs("div",{className:"flex justify-between text-sm",children:[u.jsx("span",{className:"text-gray-600",children:3===s?"LTM":"FY"+(3-s)}),u.jsx("span",{className:"font-medium",children:e})]},s))})]}),u.jsxs("div",{children:[u.jsx("h4",{className:"text-sm font-medium text-gray-500 mb-2",children:"Margins"}),u.jsx("div",{className:"space-y-1",children:t.financials.margins.map((e,s)=>u.jsxs("div",{className:"flex justify-between text-sm",children:[u.jsx("span",{className:"text-gray-600",children:3===s?"LTM":"FY"+(3-s)}),u.jsx("span",{className:"font-medium",children:e})]},s))})]})]})]})]}),"template"===n&&u.jsxs(u.Fragment,{children:[u.jsxs("div",{className:"bg-blue-50 border border-blue-200 rounded-lg p-4 mb-6",children:[u.jsx("h4",{className:"text-sm font-medium text-blue-900 mb-2",children:"CIM Review Analysis"}),u.jsx("p",{className:"text-sm text-blue-700",children:"This tab displays the AI-generated analysis of your CIM document in a structured format. The analysis has been organized into sections like Deal Overview, Financial Summary, Management Team, and Investment Thesis. You can review, edit, and save this structured analysis for your investment review process."})]}),u.jsxs("div",{className:"bg-blue-50 border border-blue-200 rounded p-4 mb-4",children:[u.jsx("h4",{className:"text-sm font-medium text-blue-900",children:"Debug Info"}),u.jsxs("p",{className:"text-sm text-blue-700",children:["CIM Review Data available: ",a?"Yes":"No"]}),a&&u.jsxs("p",{className:"text-sm text-blue-700",children:["Data keys: ",Object.keys(a).join(", ")]})]}),u.jsxs("div",{className:"bg-white rounded-lg border border-gray-200 p-4",children:[u.jsx("h4",{className:"text-lg font-semibold mb-4",children:"CIM Review Template"}),a?(()=>{try{return u.jsx(R,{initialData:a,cimReviewData:a,onSave:j,onExport:N,readOnly:!1})}catch(e){return u.jsxs("div",{className:"bg-red-50 border border-red-200 rounded p-4",children:[u.jsx("h4",{className:"text-red-800 font-medium",children:"Error loading CIM Review Template"}),u.jsx("p",{className:"text-red-600 text-sm mt-2",children:e instanceof Error?e.message:"Unknown error occurred"}),u.jsxs("details",{className:"mt-4",children:[u.jsx("summary",{className:"cursor-pointer text-red-700 text-sm",children:"Error Details"}),u.jsx("pre",{className:"text-xs text-red-600 mt-2 bg-red-100 p-2 rounded overflow-auto",children:e instanceof Error?e.stack:String(e)})]})]})}})():u.jsxs("div",{className:"bg-yellow-50 border border-yellow-200 rounded p-4",children:[u.jsx("h4",{className:"text-yellow-800 font-medium",children:"No CIM Review Data Available"}),u.jsx("p",{className:"text-yellow-600 text-sm mt-2",children:"This document doesn't have any CIM review data yet. The data will be available after the document has been processed."}),u.jsx("div",{className:"mt-4",children:u.jsx("button",{onClick:()=>l("overview"),className:"px-4 py-2 bg-yellow-600 text-white rounded hover:bg-yellow-700 text-sm",children:"View Document Overview"})})]})]})]}),"raw"===n&&u.jsxs("div",{className:"bg-white rounded-lg shadow-sm border border-gray-200 p-6",children:[u.jsxs("div",{className:"mb-6",children:[u.jsx("h3",{className:"text-lg font-medium text-gray-900 mb-2",children:"Raw Extracted Data"}),u.jsx("p",{className:"text-sm text-gray-600",children:"This tab shows the raw JSON data extracted from the document during processing. It includes all the structured information that was parsed from the CIM document, including financial metrics, company details, and analysis results."})]}),u.jsx("pre",{className:"bg-gray-50 rounded-lg p-4 overflow-x-auto text-sm",children:u.jsx("code",{children:JSON.stringify(t,null,2)})})]})]})]})}); +/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */export{P as default}; diff --git a/backend/frontend-dist/assets/UploadMonitoringDashboard-90d06ab8.js b/backend/frontend-dist/assets/UploadMonitoringDashboard-90d06ab8.js new file mode 100644 index 0000000..812c494 --- /dev/null +++ b/backend/frontend-dist/assets/UploadMonitoringDashboard-90d06ab8.js @@ -0,0 +1,7 @@ +import{c as e,r as s,j as r,A as a,T as t,e as l}from"./index-9817dacc.js";import{A as d,C as i}from"./check-circle-937a9172.js";import{C as c}from"./clock-9f043116.js";import{A as n}from"./alert-triangle-326a303a.js"; +/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const x=e("RefreshCw",[["path",{d:"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",key:"v9h5vc"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}],["path",{d:"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16",key:"3uifl3"}],["path",{d:"M8 16H3v5",key:"1cv678"}]]),o=()=>{const[e,o]=s.useState(null),[m,h]=s.useState(!0),[u,g]=s.useState(null),[j,p]=s.useState("24"),[b,N]=s.useState(!0),f=()=>{return e=void 0,s=null,r=function*(){try{h(!0);const e=yield l.get(`/monitoring/dashboard?hours=${j}`);o(e.data.data),g(null)}catch(e){g(e instanceof Error?e.message:"Failed to fetch data")}finally{h(!1)}},new Promise((a,t)=>{var l=e=>{try{i(r.next(e))}catch(s){t(s)}},d=e=>{try{i(r.throw(e))}catch(s){t(s)}},i=e=>e.done?a(e.value):Promise.resolve(e.value).then(l,d);i((r=r.apply(e,s)).next())});var e,s,r};s.useEffect(()=>{f()},[j]),s.useEffect(()=>{if(!b)return;const e=setInterval(f,3e4);return()=>clearInterval(e)},[b,j]);const v=e=>e<1e3?`${e}ms`:e<6e4?`${(e/1e3).toFixed(1)}s`:`${(e/6e4).toFixed(1)}m`;if(m&&!e)return r.jsxs("div",{className:"flex items-center justify-center h-64",children:[r.jsx(x,{className:"h-8 w-8 animate-spin"}),r.jsx("span",{className:"ml-2",children:"Loading dashboard data..."})]});if(u)return r.jsx("div",{className:"mb-4 p-4 bg-red-50 border border-red-200 rounded-lg",children:r.jsxs("div",{className:"flex items-center",children:[r.jsx(d,{className:"h-4 w-4 text-red-600 mr-2"}),r.jsx("span",{className:"text-red-800",children:u})]})});if(!e)return r.jsx("div",{className:"mb-4 p-4 bg-yellow-50 border border-yellow-200 rounded-lg",children:r.jsxs("div",{className:"flex items-center",children:[r.jsx(d,{className:"h-4 w-4 text-yellow-600 mr-2"}),r.jsx("span",{className:"text-yellow-800",children:"No dashboard data available"})]})});let y,w,S,T;if(e.metrics&&e.healthStatus&&e.realTimeStats&&e.errorAnalysis)({metrics:y,healthStatus:w,realTimeStats:S,errorAnalysis:T}=e);else{const s={metrics:e.metrics||{totalUploads:0,successfulUploads:0,failedUploads:0,successRate:0,averageProcessingTime:0},healthStatus:e.healthStatus||{status:"unknown",successRate:0,averageProcessingTime:0,recentErrors:[],recommendations:[]},realTimeStats:e.realTimeStats||{activeUploads:0,uploadsLastMinute:0,uploadsLastHour:0,currentSuccessRate:0},errorAnalysis:e.errorAnalysis||{topErrorTypes:[],topErrorStages:[],errorTrends:[]}};({metrics:y,healthStatus:w,realTimeStats:S,errorAnalysis:T}=s)}return r.jsxs("div",{className:"space-y-6",children:[r.jsxs("div",{className:"flex items-center justify-between",children:[r.jsxs("div",{children:[r.jsx("h1",{className:"text-3xl font-bold",children:"Upload Pipeline Monitoring"}),r.jsx("p",{className:"text-muted-foreground",children:"Real-time monitoring and analytics for document upload processing"})]}),r.jsxs("div",{className:"flex items-center space-x-4",children:[r.jsxs("select",{value:j,onChange:e=>p(e.target.value),className:"w-32 px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500",children:[r.jsx("option",{value:"1",children:"1 Hour"}),r.jsx("option",{value:"6",children:"6 Hours"}),r.jsx("option",{value:"24",children:"24 Hours"}),r.jsx("option",{value:"168",children:"7 Days"})]}),r.jsxs("button",{className:"px-4 py-2 text-sm font-medium rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 "+(b?"bg-blue-600 text-white hover:bg-blue-700":"bg-white text-gray-700 border border-gray-300 hover:bg-gray-50"),onClick:()=>N(!b),children:[r.jsx(x,{className:"h-4 w-4 mr-2 inline "+(b?"animate-spin":"")}),"Auto Refresh"]}),r.jsxs("button",{className:"px-4 py-2 text-sm font-medium bg-white text-gray-700 border border-gray-300 rounded-md shadow-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue-500",onClick:f,children:[r.jsx(x,{className:"h-4 w-4 mr-2 inline"}),"Refresh"]})]})]}),r.jsxs("div",{className:"bg-white shadow rounded-lg border border-gray-200",children:[r.jsx("div",{className:"px-6 py-4 border-b border-gray-200",children:r.jsxs("h3",{className:"text-lg font-medium text-gray-900 flex items-center space-x-2",children:[(e=>{switch(e){case"healthy":return r.jsx(i,{className:"h-5 w-5 text-green-500"});case"degraded":return r.jsx(n,{className:"h-5 w-5 text-yellow-500"});case"unhealthy":return r.jsx(d,{className:"h-5 w-5 text-red-500"});default:return r.jsx(a,{className:"h-5 w-5 text-gray-500"})}})(w.status),r.jsx("span",{children:"System Health Status"}),r.jsx("span",{className:`ml-2 px-2 py-1 text-xs font-medium rounded-full ${(e=>{switch(e){case"healthy":return"bg-green-500";case"degraded":return"bg-yellow-500";case"unhealthy":return"bg-red-500";default:return"bg-gray-500"}})(w.status)} text-white`,children:w.status.toUpperCase()})]})}),r.jsxs("div",{className:"px-6 py-4",children:[r.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-4",children:[r.jsxs("div",{className:"text-center",children:[r.jsxs("div",{className:"text-2xl font-bold text-green-600",children:[w.successRate.toFixed(1),"%"]}),r.jsx("div",{className:"text-sm text-muted-foreground",children:"Success Rate"})]}),r.jsxs("div",{className:"text-center",children:[r.jsx("div",{className:"text-2xl font-bold text-blue-600",children:v(w.averageProcessingTime)}),r.jsx("div",{className:"text-sm text-muted-foreground",children:"Avg Processing Time"})]}),r.jsxs("div",{className:"text-center",children:[r.jsx("div",{className:"text-2xl font-bold text-orange-600",children:w.recentErrors.length}),r.jsx("div",{className:"text-sm text-muted-foreground",children:"Recent Errors"})]})]}),w.recommendations.length>0&&r.jsxs("div",{className:"mt-4",children:[r.jsx("h4",{className:"font-semibold mb-2",children:"Recommendations:"}),r.jsx("ul",{className:"space-y-1",children:w.recommendations.map((e,s)=>r.jsxs("li",{className:"text-sm text-muted-foreground flex items-start",children:[r.jsx(d,{className:"h-4 w-4 mr-2 mt-0.5 text-yellow-500"}),e]},s))})]})]})]}),r.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-4 gap-4",children:[r.jsxs("div",{className:"bg-white shadow rounded-lg border border-gray-200 p-4",children:[r.jsxs("div",{className:"flex items-center space-x-2",children:[r.jsx(a,{className:"h-4 w-4 text-blue-500"}),r.jsx("span",{className:"text-sm font-medium",children:"Active Uploads"})]}),r.jsx("div",{className:"text-2xl font-bold",children:S.activeUploads})]}),r.jsxs("div",{className:"bg-white shadow rounded-lg border border-gray-200 p-4",children:[r.jsxs("div",{className:"flex items-center space-x-2",children:[r.jsx(c,{className:"h-4 w-4 text-green-500"}),r.jsx("span",{className:"text-sm font-medium",children:"Last Minute"})]}),r.jsx("div",{className:"text-2xl font-bold",children:S.uploadsLastMinute})]}),r.jsxs("div",{className:"bg-white shadow rounded-lg border border-gray-200 p-4",children:[r.jsxs("div",{className:"flex items-center space-x-2",children:[r.jsx(t,{className:"h-4 w-4 text-purple-500"}),r.jsx("span",{className:"text-sm font-medium",children:"Last Hour"})]}),r.jsx("div",{className:"text-2xl font-bold",children:S.uploadsLastHour})]}),r.jsxs("div",{className:"bg-white shadow rounded-lg border border-gray-200 p-4",children:[r.jsxs("div",{className:"flex items-center space-x-2",children:[r.jsx(i,{className:"h-4 w-4 text-green-500"}),r.jsx("span",{className:"text-sm font-medium",children:"Success Rate"})]}),r.jsxs("div",{className:"text-2xl font-bold",children:[S.currentSuccessRate.toFixed(1),"%"]})]})]}),r.jsxs("div",{className:"space-y-4",children:[r.jsx("div",{className:"border-b border-gray-200",children:r.jsxs("nav",{className:"-mb-px flex space-x-8",children:[r.jsx("button",{className:"border-b-2 border-blue-500 py-2 px-1 text-sm font-medium text-blue-600",children:"Overview"}),r.jsx("button",{className:"border-b-2 border-transparent py-2 px-1 text-sm font-medium text-gray-500 hover:text-gray-700 hover:border-gray-300",children:"Error Analysis"}),r.jsx("button",{className:"border-b-2 border-transparent py-2 px-1 text-sm font-medium text-gray-500 hover:text-gray-700 hover:border-gray-300",children:"Performance"})]})}),r.jsx("div",{className:"space-y-4",children:r.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[r.jsxs("div",{className:"bg-white shadow rounded-lg border border-gray-200",children:[r.jsx("div",{className:"px-6 py-4 border-b border-gray-200",children:r.jsx("h3",{className:"text-lg font-medium text-gray-900",children:"Upload Statistics"})}),r.jsx("div",{className:"px-6 py-4",children:r.jsxs("div",{className:"space-y-4",children:[r.jsxs("div",{children:[r.jsxs("div",{className:"flex justify-between text-sm mb-1",children:[r.jsx("span",{children:"Success Rate"}),r.jsxs("span",{children:[y.successRate.toFixed(1),"%"]})]}),r.jsx("div",{className:"w-full bg-gray-200 rounded-full h-2",children:r.jsx("div",{className:"bg-blue-600 h-2 rounded-full",style:{width:`${y.successRate}%`}})})]}),r.jsxs("div",{className:"grid grid-cols-2 gap-4 text-center",children:[r.jsxs("div",{children:[r.jsx("div",{className:"text-2xl font-bold text-green-600",children:y.successfulUploads}),r.jsx("div",{className:"text-sm text-muted-foreground",children:"Successful"})]}),r.jsxs("div",{children:[r.jsx("div",{className:"text-2xl font-bold text-red-600",children:y.failedUploads}),r.jsx("div",{className:"text-sm text-muted-foreground",children:"Failed"})]})]})]})})]}),r.jsxs("div",{className:"bg-white shadow rounded-lg border border-gray-200",children:[r.jsx("div",{className:"px-6 py-4 border-b border-gray-200",children:r.jsx("h3",{className:"text-lg font-medium text-gray-900",children:"File Size Distribution"})}),r.jsx("div",{className:"px-6 py-4",children:r.jsxs("div",{className:"space-y-3",children:[r.jsxs("div",{className:"flex justify-between items-center",children:[r.jsx("span",{className:"text-sm",children:"Small (< 1MB)"}),r.jsx("span",{className:"px-2 py-1 text-xs font-medium bg-gray-100 text-gray-800 rounded-full",children:y.fileSizeDistribution.small})]}),r.jsxs("div",{className:"flex justify-between items-center",children:[r.jsx("span",{className:"text-sm",children:"Medium (1MB - 10MB)"}),r.jsx("span",{className:"px-2 py-1 text-xs font-medium bg-gray-100 text-gray-800 rounded-full",children:y.fileSizeDistribution.medium})]}),r.jsxs("div",{className:"flex justify-between items-center",children:[r.jsx("span",{className:"text-sm",children:"Large (> 10MB)"}),r.jsx("span",{className:"px-2 py-1 text-xs font-medium bg-gray-100 text-gray-800 rounded-full",children:y.fileSizeDistribution.large})]})]})})]})]})}),r.jsxs("div",{className:"space-y-4",children:[r.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[r.jsxs("div",{className:"bg-white shadow rounded-lg border border-gray-200",children:[r.jsx("div",{className:"px-6 py-4 border-b border-gray-200",children:r.jsx("h3",{className:"text-lg font-medium text-gray-900",children:"Top Error Types"})}),r.jsx("div",{className:"px-6 py-4",children:r.jsx("div",{className:"space-y-3",children:T.topErrorTypes.map((e,s)=>r.jsxs("div",{className:"flex justify-between items-center",children:[r.jsx("span",{className:"text-sm truncate",children:e.type}),r.jsxs("div",{className:"flex items-center space-x-2",children:[r.jsx("span",{className:"text-sm font-medium",children:e.count}),r.jsxs("span",{className:"text-xs text-muted-foreground",children:["(",e.percentage.toFixed(1),"%)"]})]})]},s))})})]}),r.jsxs("div",{className:"bg-white shadow rounded-lg border border-gray-200",children:[r.jsx("div",{className:"px-6 py-4 border-b border-gray-200",children:r.jsx("h3",{className:"text-lg font-medium text-gray-900",children:"Top Error Stages"})}),r.jsx("div",{className:"px-6 py-4",children:r.jsx("div",{className:"space-y-3",children:T.topErrorStages.map((e,s)=>r.jsxs("div",{className:"flex justify-between items-center",children:[r.jsx("span",{className:"text-sm truncate",children:e.stage}),r.jsxs("div",{className:"flex items-center space-x-2",children:[r.jsx("span",{className:"text-sm font-medium",children:e.count}),r.jsxs("span",{className:"text-xs text-muted-foreground",children:["(",e.percentage.toFixed(1),"%)"]})]})]},s))})})]})]}),w.recentErrors.length>0&&r.jsxs("div",{className:"bg-white shadow rounded-lg border border-gray-200",children:[r.jsx("div",{className:"px-6 py-4 border-b border-gray-200",children:r.jsx("h3",{className:"text-lg font-medium text-gray-900",children:"Recent Errors"})}),r.jsx("div",{className:"px-6 py-4",children:r.jsx("div",{className:"space-y-3",children:w.recentErrors.slice(0,5).map(e=>r.jsxs("div",{className:"border rounded-lg p-3",children:[r.jsxs("div",{className:"flex justify-between items-start mb-2",children:[r.jsx("span",{className:"font-medium text-sm",children:e.fileInfo.originalName}),r.jsx("span",{className:"text-xs text-muted-foreground",children:new Date(e.timestamp).toLocaleString()})]}),r.jsxs("div",{className:"text-sm text-muted-foreground mb-1",children:["Stage: ",e.stage||"Unknown"]}),e.error&&r.jsx("div",{className:"text-sm text-red-600",children:e.error.message})]},e.id))})})]})]}),r.jsx("div",{className:"space-y-4",children:r.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[r.jsxs("div",{className:"bg-white shadow rounded-lg border border-gray-200",children:[r.jsx("div",{className:"px-6 py-4 border-b border-gray-200",children:r.jsx("h3",{className:"text-lg font-medium text-gray-900",children:"Processing Time Distribution"})}),r.jsx("div",{className:"px-6 py-4",children:r.jsxs("div",{className:"space-y-3",children:[r.jsxs("div",{className:"flex justify-between items-center",children:[r.jsx("span",{className:"text-sm",children:"Fast (< 30s)"}),r.jsx("span",{className:"px-2 py-1 text-xs font-medium bg-gray-100 text-green-600 rounded-full",children:y.processingTimeDistribution.fast})]}),r.jsxs("div",{className:"flex justify-between items-center",children:[r.jsx("span",{className:"text-sm",children:"Normal (30s - 5m)"}),r.jsx("span",{className:"px-2 py-1 text-xs font-medium bg-gray-100 text-blue-600 rounded-full",children:y.processingTimeDistribution.normal})]}),r.jsxs("div",{className:"flex justify-between items-center",children:[r.jsx("span",{className:"text-sm",children:"Slow (> 5m)"}),r.jsx("span",{className:"px-2 py-1 text-xs font-medium bg-gray-100 text-red-600 rounded-full",children:y.processingTimeDistribution.slow})]})]})})]}),r.jsxs("div",{className:"bg-white shadow rounded-lg border border-gray-200",children:[r.jsx("div",{className:"px-6 py-4 border-b border-gray-200",children:r.jsx("h3",{className:"text-lg font-medium text-gray-900",children:"Performance Metrics"})}),r.jsx("div",{className:"px-6 py-4",children:r.jsxs("div",{className:"space-y-4",children:[r.jsxs("div",{children:[r.jsx("div",{className:"text-sm text-muted-foreground mb-1",children:"Average Processing Time"}),r.jsx("div",{className:"text-2xl font-bold",children:v(y.averageProcessingTime)})]}),r.jsxs("div",{children:[r.jsx("div",{className:"text-sm text-muted-foreground mb-1",children:"Total Processing Time"}),r.jsx("div",{className:"text-2xl font-bold",children:v(y.totalProcessingTime)})]})]})})]})]})})]}),r.jsxs("div",{className:"text-center text-sm text-muted-foreground",children:["Last updated: ",new Date(e.timestamp).toLocaleString()]})]})};export{o as default}; diff --git a/backend/frontend-dist/assets/alert-triangle-326a303a.js b/backend/frontend-dist/assets/alert-triangle-326a303a.js new file mode 100644 index 0000000..c5cf002 --- /dev/null +++ b/backend/frontend-dist/assets/alert-triangle-326a303a.js @@ -0,0 +1,7 @@ +import{c as a}from"./index-9817dacc.js"; +/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const p=a("AlertTriangle",[["path",{d:"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z",key:"c3ski4"}],["path",{d:"M12 9v4",key:"juzpu7"}],["path",{d:"M12 17h.01",key:"p32p05"}]]);export{p as A}; diff --git a/backend/frontend-dist/assets/bluepoint-logo-e4483eca.png b/backend/frontend-dist/assets/bluepoint-logo-e4483eca.png new file mode 100644 index 0000000..d3e2148 Binary files /dev/null and b/backend/frontend-dist/assets/bluepoint-logo-e4483eca.png differ diff --git a/backend/frontend-dist/assets/check-circle-937a9172.js b/backend/frontend-dist/assets/check-circle-937a9172.js new file mode 100644 index 0000000..3f16901 --- /dev/null +++ b/backend/frontend-dist/assets/check-circle-937a9172.js @@ -0,0 +1,13 @@ +import{c as e}from"./index-9817dacc.js"; +/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const y=e("AlertCircle",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["line",{x1:"12",x2:"12",y1:"8",y2:"12",key:"1pkeuh"}],["line",{x1:"12",x2:"12.01",y1:"16",y2:"16",key:"4dfq90"}]]),c=e("CheckCircle",[["path",{d:"M22 11.08V12a10 10 0 1 1-5.93-9.14",key:"g774vq"}],["path",{d:"m9 11 3 3L22 4",key:"1pflzl"}]]); +/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */export{y as A,c as C}; diff --git a/backend/frontend-dist/assets/clock-9f043116.js b/backend/frontend-dist/assets/clock-9f043116.js new file mode 100644 index 0000000..f2299f3 --- /dev/null +++ b/backend/frontend-dist/assets/clock-9f043116.js @@ -0,0 +1,7 @@ +import{c}from"./index-9817dacc.js"; +/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const e=c("Clock",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["polyline",{points:"12 6 12 12 16 14",key:"68esgv"}]]);export{e as C}; diff --git a/backend/frontend-dist/assets/download-aacd5336.js b/backend/frontend-dist/assets/download-aacd5336.js new file mode 100644 index 0000000..1c53066 --- /dev/null +++ b/backend/frontend-dist/assets/download-aacd5336.js @@ -0,0 +1,7 @@ +import{c as e}from"./index-9817dacc.js"; +/** + * @license lucide-react v0.294.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const o=e("Download",[["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["polyline",{points:"7 10 12 15 17 10",key:"2ggqvy"}],["line",{x1:"12",x2:"12",y1:"15",y2:"3",key:"1vk2je"}]]);export{o as D}; diff --git a/backend/frontend-dist/assets/index-113dee95.css b/backend/frontend-dist/assets/index-113dee95.css new file mode 100644 index 0000000..ae79bff --- /dev/null +++ b/backend/frontend-dist/assets/index-113dee95.css @@ -0,0 +1 @@ +*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#eee}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:Inter,system-ui,sans-serif;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#bdbdbd}input::placeholder,textarea::placeholder{opacity:1;color:#bdbdbd}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}html,body{font-family:Inter,system-ui,sans-serif}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.pointer-events-none{pointer-events:none}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{inset:0}.inset-y-0{top:0;bottom:0}.left-0{left:0}.right-0{right:0}.z-50{z-index:50}.mx-4{margin-left:1rem;margin-right:1rem}.mx-auto{margin-left:auto;margin-right:auto}.-mb-px{margin-bottom:-1px}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.mb-8{margin-bottom:2rem}.ml-1{margin-left:.25rem}.ml-2{margin-left:.5rem}.ml-3{margin-left:.75rem}.ml-4{margin-left:1rem}.ml-5{margin-left:1.25rem}.ml-6{margin-left:1.5rem}.mr-1{margin-right:.25rem}.mr-2{margin-right:.5rem}.mr-3{margin-right:.75rem}.mr-4{margin-right:1rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-4{margin-top:1rem}.mt-5{margin-top:1.25rem}.mt-6{margin-top:1.5rem}.mt-8{margin-top:2rem}.block{display:block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-10{height:2.5rem}.h-12{height:3rem}.h-16{height:4rem}.h-2{height:.5rem}.h-3{height:.75rem}.h-32{height:8rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-64{height:16rem}.h-8{height:2rem}.max-h-40{max-height:10rem}.max-h-\[90vh\]{max-height:90vh}.min-h-64{min-height:16rem}.min-h-screen{min-height:100vh}.w-0{width:0px}.w-1\/2{width:50%}.w-1\/3{width:33.333333%}.w-1\/4{width:25%}.w-1\/6{width:16.666667%}.w-12{width:3rem}.w-24{width:6rem}.w-3{width:.75rem}.w-3\/4{width:75%}.w-32{width:8rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-5\/6{width:83.333333%}.w-6{width:1.5rem}.w-64{width:16rem}.w-8{width:2rem}.w-auto{width:auto}.w-full{width:100%}.min-w-0{min-width:0px}.min-w-full{min-width:100%}.max-w-4xl{max-width:56rem}.max-w-7xl{max-width:80rem}.max-w-lg{max-width:32rem}.max-w-md{max-width:28rem}.max-w-sm{max-width:24rem}.flex-1{flex:1 1 0%}.flex-shrink-0{flex-shrink:0}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.list-inside{list-style-position:inside}.list-disc{list-style-type:disc}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-6{gap:1.5rem}.space-x-1>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.25rem * var(--tw-space-x-reverse));margin-left:calc(.25rem * calc(1 - var(--tw-space-x-reverse)))}.space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.5rem * var(--tw-space-x-reverse));margin-left:calc(.5rem * calc(1 - var(--tw-space-x-reverse)))}.space-x-3>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.75rem * var(--tw-space-x-reverse));margin-left:calc(.75rem * calc(1 - var(--tw-space-x-reverse)))}.space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(1rem * var(--tw-space-x-reverse));margin-left:calc(1rem * calc(1 - var(--tw-space-x-reverse)))}.space-x-8>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(2rem * var(--tw-space-x-reverse));margin-left:calc(2rem * calc(1 - var(--tw-space-x-reverse)))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse))}.divide-gray-200>:not([hidden])~:not([hidden]){--tw-divide-opacity: 1;border-color:rgb(238 238 238 / var(--tw-divide-opacity, 1))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.border{border-width:1px}.border-2{border-width:2px}.border-b{border-bottom-width:1px}.border-b-2{border-bottom-width:2px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-dashed{border-style:dashed}.border-accent-500{--tw-border-opacity: 1;border-color:rgb(245 158 11 / var(--tw-border-opacity, 1))}.border-blue-200{--tw-border-opacity: 1;border-color:rgb(191 219 254 / var(--tw-border-opacity, 1))}.border-blue-500{--tw-border-opacity: 1;border-color:rgb(59 130 246 / var(--tw-border-opacity, 1))}.border-blue-600{--tw-border-opacity: 1;border-color:rgb(37 99 235 / var(--tw-border-opacity, 1))}.border-gray-100{--tw-border-opacity: 1;border-color:rgb(245 245 245 / var(--tw-border-opacity, 1))}.border-gray-200{--tw-border-opacity: 1;border-color:rgb(238 238 238 / var(--tw-border-opacity, 1))}.border-gray-300{--tw-border-opacity: 1;border-color:rgb(224 224 224 / var(--tw-border-opacity, 1))}.border-green-200{--tw-border-opacity: 1;border-color:rgb(187 247 208 / var(--tw-border-opacity, 1))}.border-green-600{--tw-border-opacity: 1;border-color:rgb(22 163 74 / var(--tw-border-opacity, 1))}.border-primary-500{--tw-border-opacity: 1;border-color:rgb(98 125 152 / var(--tw-border-opacity, 1))}.border-primary-600{--tw-border-opacity: 1;border-color:rgb(72 101 129 / var(--tw-border-opacity, 1))}.border-primary-700{--tw-border-opacity: 1;border-color:rgb(51 78 104 / var(--tw-border-opacity, 1))}.border-red-200{--tw-border-opacity: 1;border-color:rgb(254 202 202 / var(--tw-border-opacity, 1))}.border-red-300{--tw-border-opacity: 1;border-color:rgb(252 165 165 / var(--tw-border-opacity, 1))}.border-transparent{border-color:transparent}.border-white{--tw-border-opacity: 1;border-color:rgb(255 255 255 / var(--tw-border-opacity, 1))}.border-yellow-200{--tw-border-opacity: 1;border-color:rgb(254 240 138 / var(--tw-border-opacity, 1))}.bg-accent-50{--tw-bg-opacity: 1;background-color:rgb(255 251 240 / var(--tw-bg-opacity, 1))}.bg-accent-500{--tw-bg-opacity: 1;background-color:rgb(245 158 11 / var(--tw-bg-opacity, 1))}.bg-black{--tw-bg-opacity: 1;background-color:rgb(0 0 0 / var(--tw-bg-opacity, 1))}.bg-blue-100{--tw-bg-opacity: 1;background-color:rgb(219 234 254 / var(--tw-bg-opacity, 1))}.bg-blue-200{--tw-bg-opacity: 1;background-color:rgb(191 219 254 / var(--tw-bg-opacity, 1))}.bg-blue-50{--tw-bg-opacity: 1;background-color:rgb(239 246 255 / var(--tw-bg-opacity, 1))}.bg-blue-500{--tw-bg-opacity: 1;background-color:rgb(59 130 246 / var(--tw-bg-opacity, 1))}.bg-blue-600{--tw-bg-opacity: 1;background-color:rgb(37 99 235 / var(--tw-bg-opacity, 1))}.bg-error-50{--tw-bg-opacity: 1;background-color:rgb(254 242 242 / var(--tw-bg-opacity, 1))}.bg-error-500{--tw-bg-opacity: 1;background-color:rgb(239 68 68 / var(--tw-bg-opacity, 1))}.bg-error-600{--tw-bg-opacity: 1;background-color:rgb(220 38 38 / var(--tw-bg-opacity, 1))}.bg-gray-100{--tw-bg-opacity: 1;background-color:rgb(245 245 245 / var(--tw-bg-opacity, 1))}.bg-gray-200{--tw-bg-opacity: 1;background-color:rgb(238 238 238 / var(--tw-bg-opacity, 1))}.bg-gray-400{--tw-bg-opacity: 1;background-color:rgb(189 189 189 / var(--tw-bg-opacity, 1))}.bg-gray-50{--tw-bg-opacity: 1;background-color:rgb(250 250 250 / var(--tw-bg-opacity, 1))}.bg-gray-500{--tw-bg-opacity: 1;background-color:rgb(158 158 158 / var(--tw-bg-opacity, 1))}.bg-gray-600{--tw-bg-opacity: 1;background-color:rgb(117 117 117 / var(--tw-bg-opacity, 1))}.bg-gray-900{--tw-bg-opacity: 1;background-color:rgb(33 33 33 / var(--tw-bg-opacity, 1))}.bg-green-100{--tw-bg-opacity: 1;background-color:rgb(220 252 231 / var(--tw-bg-opacity, 1))}.bg-green-50{--tw-bg-opacity: 1;background-color:rgb(240 253 244 / var(--tw-bg-opacity, 1))}.bg-green-500{--tw-bg-opacity: 1;background-color:rgb(34 197 94 / var(--tw-bg-opacity, 1))}.bg-green-600{--tw-bg-opacity: 1;background-color:rgb(22 163 74 / var(--tw-bg-opacity, 1))}.bg-orange-600{--tw-bg-opacity: 1;background-color:rgb(234 88 12 / var(--tw-bg-opacity, 1))}.bg-primary-50{--tw-bg-opacity: 1;background-color:rgb(240 244 248 / var(--tw-bg-opacity, 1))}.bg-primary-600{--tw-bg-opacity: 1;background-color:rgb(72 101 129 / var(--tw-bg-opacity, 1))}.bg-red-100{--tw-bg-opacity: 1;background-color:rgb(254 226 226 / var(--tw-bg-opacity, 1))}.bg-red-50{--tw-bg-opacity: 1;background-color:rgb(254 242 242 / var(--tw-bg-opacity, 1))}.bg-red-500{--tw-bg-opacity: 1;background-color:rgb(239 68 68 / var(--tw-bg-opacity, 1))}.bg-red-600{--tw-bg-opacity: 1;background-color:rgb(220 38 38 / var(--tw-bg-opacity, 1))}.bg-success-50{--tw-bg-opacity: 1;background-color:rgb(240 253 244 / var(--tw-bg-opacity, 1))}.bg-warning-50{--tw-bg-opacity: 1;background-color:rgb(255 251 235 / var(--tw-bg-opacity, 1))}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.bg-yellow-100{--tw-bg-opacity: 1;background-color:rgb(254 249 195 / var(--tw-bg-opacity, 1))}.bg-yellow-50{--tw-bg-opacity: 1;background-color:rgb(254 252 232 / var(--tw-bg-opacity, 1))}.bg-yellow-500{--tw-bg-opacity: 1;background-color:rgb(234 179 8 / var(--tw-bg-opacity, 1))}.bg-yellow-600{--tw-bg-opacity: 1;background-color:rgb(202 138 4 / var(--tw-bg-opacity, 1))}.bg-opacity-50{--tw-bg-opacity: .5}.p-1{padding:.25rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.p-8{padding:2rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-12{padding-top:3rem;padding-bottom:3rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-5{padding-top:1.25rem;padding-bottom:1.25rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pl-10{padding-left:2.5rem}.pl-3{padding-left:.75rem}.pr-10{padding-right:2.5rem}.pr-3{padding-right:.75rem}.pt-4{padding-top:1rem}.text-left{text-align:left}.text-center{text-align:center}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-extrabold{font-weight:800}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.italic{font-style:italic}.leading-5{line-height:1.25rem}.leading-6{line-height:1.5rem}.tracking-wider{letter-spacing:.05em}.text-accent-600{--tw-text-opacity: 1;color:rgb(217 119 6 / var(--tw-text-opacity, 1))}.text-blue-500{--tw-text-opacity: 1;color:rgb(59 130 246 / var(--tw-text-opacity, 1))}.text-blue-600{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}.text-blue-700{--tw-text-opacity: 1;color:rgb(29 78 216 / var(--tw-text-opacity, 1))}.text-blue-800{--tw-text-opacity: 1;color:rgb(30 64 175 / var(--tw-text-opacity, 1))}.text-blue-900{--tw-text-opacity: 1;color:rgb(30 58 138 / var(--tw-text-opacity, 1))}.text-error-500{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.text-error-600{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.text-gray-400{--tw-text-opacity: 1;color:rgb(189 189 189 / var(--tw-text-opacity, 1))}.text-gray-500{--tw-text-opacity: 1;color:rgb(158 158 158 / var(--tw-text-opacity, 1))}.text-gray-600{--tw-text-opacity: 1;color:rgb(117 117 117 / var(--tw-text-opacity, 1))}.text-gray-700{--tw-text-opacity: 1;color:rgb(97 97 97 / var(--tw-text-opacity, 1))}.text-gray-800{--tw-text-opacity: 1;color:rgb(66 66 66 / var(--tw-text-opacity, 1))}.text-gray-900{--tw-text-opacity: 1;color:rgb(33 33 33 / var(--tw-text-opacity, 1))}.text-green-400{--tw-text-opacity: 1;color:rgb(74 222 128 / var(--tw-text-opacity, 1))}.text-green-500{--tw-text-opacity: 1;color:rgb(34 197 94 / var(--tw-text-opacity, 1))}.text-green-600{--tw-text-opacity: 1;color:rgb(22 163 74 / var(--tw-text-opacity, 1))}.text-green-800{--tw-text-opacity: 1;color:rgb(22 101 52 / var(--tw-text-opacity, 1))}.text-indigo-600{--tw-text-opacity: 1;color:rgb(79 70 229 / var(--tw-text-opacity, 1))}.text-orange-600{--tw-text-opacity: 1;color:rgb(234 88 12 / var(--tw-text-opacity, 1))}.text-primary-200{--tw-text-opacity: 1;color:rgb(188 204 220 / var(--tw-text-opacity, 1))}.text-primary-500{--tw-text-opacity: 1;color:rgb(98 125 152 / var(--tw-text-opacity, 1))}.text-primary-600{--tw-text-opacity: 1;color:rgb(72 101 129 / var(--tw-text-opacity, 1))}.text-primary-700{--tw-text-opacity: 1;color:rgb(51 78 104 / var(--tw-text-opacity, 1))}.text-primary-800{--tw-text-opacity: 1;color:rgb(36 59 83 / var(--tw-text-opacity, 1))}.text-purple-500{--tw-text-opacity: 1;color:rgb(168 85 247 / var(--tw-text-opacity, 1))}.text-purple-600{--tw-text-opacity: 1;color:rgb(147 51 234 / var(--tw-text-opacity, 1))}.text-red-400{--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.text-red-500{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.text-red-600{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.text-red-700{--tw-text-opacity: 1;color:rgb(185 28 28 / var(--tw-text-opacity, 1))}.text-red-800{--tw-text-opacity: 1;color:rgb(153 27 27 / var(--tw-text-opacity, 1))}.text-success-500{--tw-text-opacity: 1;color:rgb(34 197 94 / var(--tw-text-opacity, 1))}.text-success-600{--tw-text-opacity: 1;color:rgb(22 163 74 / var(--tw-text-opacity, 1))}.text-warning-500{--tw-text-opacity: 1;color:rgb(245 158 11 / var(--tw-text-opacity, 1))}.text-warning-600{--tw-text-opacity: 1;color:rgb(217 119 6 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.text-yellow-500{--tw-text-opacity: 1;color:rgb(234 179 8 / var(--tw-text-opacity, 1))}.text-yellow-600{--tw-text-opacity: 1;color:rgb(202 138 4 / var(--tw-text-opacity, 1))}.text-yellow-700{--tw-text-opacity: 1;color:rgb(161 98 7 / var(--tw-text-opacity, 1))}.text-yellow-800{--tw-text-opacity: 1;color:rgb(133 77 14 / var(--tw-text-opacity, 1))}.placeholder-gray-400::-moz-placeholder{--tw-placeholder-opacity: 1;color:rgb(189 189 189 / var(--tw-placeholder-opacity, 1))}.placeholder-gray-400::placeholder{--tw-placeholder-opacity: 1;color:rgb(189 189 189 / var(--tw-placeholder-opacity, 1))}.placeholder-gray-500::-moz-placeholder{--tw-placeholder-opacity: 1;color:rgb(158 158 158 / var(--tw-placeholder-opacity, 1))}.placeholder-gray-500::placeholder{--tw-placeholder-opacity: 1;color:rgb(158 158 158 / var(--tw-placeholder-opacity, 1))}.shadow{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-soft{--tw-shadow: 0 2px 8px rgba(0, 0, 0, .08);--tw-shadow-colored: 0 2px 8px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-200{transition-duration:.2s}.duration-300{transition-duration:.3s}.duration-500{transition-duration:.5s}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.hover\:border-gray-300:hover{--tw-border-opacity: 1;border-color:rgb(224 224 224 / var(--tw-border-opacity, 1))}.hover\:border-primary-300:hover{--tw-border-opacity: 1;border-color:rgb(159 179 200 / var(--tw-border-opacity, 1))}.hover\:border-primary-400:hover{--tw-border-opacity: 1;border-color:rgb(130 154 177 / var(--tw-border-opacity, 1))}.hover\:bg-accent-600:hover{--tw-bg-opacity: 1;background-color:rgb(217 119 6 / var(--tw-bg-opacity, 1))}.hover\:bg-blue-700:hover{--tw-bg-opacity: 1;background-color:rgb(29 78 216 / var(--tw-bg-opacity, 1))}.hover\:bg-error-600:hover{--tw-bg-opacity: 1;background-color:rgb(220 38 38 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-100:hover{--tw-bg-opacity: 1;background-color:rgb(245 245 245 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-300:hover{--tw-bg-opacity: 1;background-color:rgb(224 224 224 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-50:hover{--tw-bg-opacity: 1;background-color:rgb(250 250 250 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-700:hover{--tw-bg-opacity: 1;background-color:rgb(97 97 97 / var(--tw-bg-opacity, 1))}.hover\:bg-green-700:hover{--tw-bg-opacity: 1;background-color:rgb(21 128 61 / var(--tw-bg-opacity, 1))}.hover\:bg-primary-700:hover{--tw-bg-opacity: 1;background-color:rgb(51 78 104 / var(--tw-bg-opacity, 1))}.hover\:bg-red-50:hover{--tw-bg-opacity: 1;background-color:rgb(254 242 242 / var(--tw-bg-opacity, 1))}.hover\:bg-red-700:hover{--tw-bg-opacity: 1;background-color:rgb(185 28 28 / var(--tw-bg-opacity, 1))}.hover\:bg-yellow-600:hover{--tw-bg-opacity: 1;background-color:rgb(202 138 4 / var(--tw-bg-opacity, 1))}.hover\:bg-yellow-700:hover{--tw-bg-opacity: 1;background-color:rgb(161 98 7 / var(--tw-bg-opacity, 1))}.hover\:text-blue-600:hover{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}.hover\:text-blue-800:hover{--tw-text-opacity: 1;color:rgb(30 64 175 / var(--tw-text-opacity, 1))}.hover\:text-error-600:hover{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.hover\:text-gray-600:hover{--tw-text-opacity: 1;color:rgb(117 117 117 / var(--tw-text-opacity, 1))}.hover\:text-gray-700:hover{--tw-text-opacity: 1;color:rgb(97 97 97 / var(--tw-text-opacity, 1))}.hover\:text-gray-800:hover{--tw-text-opacity: 1;color:rgb(66 66 66 / var(--tw-text-opacity, 1))}.hover\:text-gray-900:hover{--tw-text-opacity: 1;color:rgb(33 33 33 / var(--tw-text-opacity, 1))}.hover\:text-green-600:hover{--tw-text-opacity: 1;color:rgb(22 163 74 / var(--tw-text-opacity, 1))}.hover\:text-primary-500:hover{--tw-text-opacity: 1;color:rgb(98 125 152 / var(--tw-text-opacity, 1))}.hover\:text-primary-600:hover{--tw-text-opacity: 1;color:rgb(72 101 129 / var(--tw-text-opacity, 1))}.hover\:text-red-600:hover{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.hover\:text-red-800:hover{--tw-text-opacity: 1;color:rgb(153 27 27 / var(--tw-text-opacity, 1))}.focus\:border-blue-500:focus{--tw-border-opacity: 1;border-color:rgb(59 130 246 / var(--tw-border-opacity, 1))}.focus\:border-primary-500:focus{--tw-border-opacity: 1;border-color:rgb(98 125 152 / var(--tw-border-opacity, 1))}.focus\:border-transparent:focus{border-color:transparent}.focus\:underline:focus{text-decoration-line:underline}.focus\:placeholder-gray-400:focus::-moz-placeholder{--tw-placeholder-opacity: 1;color:rgb(189 189 189 / var(--tw-placeholder-opacity, 1))}.focus\:placeholder-gray-400:focus::placeholder{--tw-placeholder-opacity: 1;color:rgb(189 189 189 / var(--tw-placeholder-opacity, 1))}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-1:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-2:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-accent-500:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(245 158 11 / var(--tw-ring-opacity, 1))}.focus\:ring-blue-500:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(59 130 246 / var(--tw-ring-opacity, 1))}.focus\:ring-error-500:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(239 68 68 / var(--tw-ring-opacity, 1))}.focus\:ring-gray-500:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(158 158 158 / var(--tw-ring-opacity, 1))}.focus\:ring-primary-500:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(98 125 152 / var(--tw-ring-opacity, 1))}.focus\:ring-red-500:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(239 68 68 / var(--tw-ring-opacity, 1))}.focus\:ring-offset-2:focus{--tw-ring-offset-width: 2px}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:bg-gray-50:disabled{--tw-bg-opacity: 1;background-color:rgb(250 250 250 / var(--tw-bg-opacity, 1))}.disabled\:text-gray-500:disabled{--tw-text-opacity: 1;color:rgb(158 158 158 / var(--tw-text-opacity, 1))}.disabled\:opacity-50:disabled{opacity:.5}@media (min-width: 640px){.sm\:mx-auto{margin-left:auto;margin-right:auto}.sm\:w-full{width:100%}.sm\:max-w-md{max-width:28rem}.sm\:flex-row{flex-direction:row}.sm\:rounded-lg{border-radius:.5rem}.sm\:rounded-md{border-radius:.375rem}.sm\:p-6{padding:1.5rem}.sm\:px-0{padding-left:0;padding-right:0}.sm\:px-10{padding-left:2.5rem;padding-right:2.5rem}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}.sm\:text-sm{font-size:.875rem;line-height:1.25rem}}@media (min-width: 768px){.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}@media (min-width: 1024px){.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:px-8{padding-left:2rem;padding-right:2rem}} diff --git a/backend/frontend-dist/assets/index-9817dacc.js b/backend/frontend-dist/assets/index-9817dacc.js new file mode 100644 index 0000000..b79af00 --- /dev/null +++ b/backend/frontend-dist/assets/index-9817dacc.js @@ -0,0 +1,1623 @@ +var e=Object.defineProperty,t=Object.defineProperties,n=Object.getOwnPropertyDescriptors,r=Object.getOwnPropertySymbols,i=Object.getPrototypeOf,o=Object.prototype.hasOwnProperty,a=Object.prototype.propertyIsEnumerable,s=Reflect.get,l=(e,t)=>{if(t=Symbol[e])return t;throw Error("Symbol."+e+" is not defined")},u=(t,n,r)=>n in t?e(t,n,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[n]=r,c=(e,t)=>{for(var n in t||(t={}))o.call(t,n)&&u(e,n,t[n]);if(r)for(var n of r(t))a.call(t,n)&&u(e,n,t[n]);return e},d=(e,r)=>t(e,n(r)),f=(e,t)=>{var n={};for(var i in e)o.call(e,i)&&t.indexOf(i)<0&&(n[i]=e[i]);if(null!=e&&r)for(var i of r(e))t.indexOf(i)<0&&a.call(e,i)&&(n[i]=e[i]);return n},h=(e,t,n)=>(u(e,"symbol"!=typeof t?t+"":t,n),n),p=(e,t,n)=>s(i(e),n,t),m=(e,t,n)=>new Promise((r,i)=>{var o=e=>{try{s(n.next(e))}catch(t){i(t)}},a=e=>{try{s(n.throw(e))}catch(t){i(t)}},s=e=>e.done?r(e.value):Promise.resolve(e.value).then(o,a);s((n=n.apply(e,t)).next())}),g=function(e,t){this[0]=e,this[1]=t},v=(e,t,n)=>{var r=(e,t,i,o)=>{try{var a=n[e](t),s=(t=a.value)instanceof g,l=a.done;Promise.resolve(s?t[0]:t).then(n=>s?r("return"===e?e:"next",t[1]?{done:n.done,value:n.value}:n,i,o):i({value:n,done:l})).catch(e=>r("throw",e,i,o))}catch(u){o(u)}},i=e=>o[e]=t=>new Promise((n,i)=>r(e,t,n,i)),o={};return n=n.apply(e,t),o[Symbol.asyncIterator]=()=>o,i("next"),i("throw"),i("return"),o},y=e=>{var t,n=e[l("asyncIterator")],r=!1,i={};return null==n?(n=e[l("iterator")](),t=e=>i[e]=t=>n[e](t)):(n=n.call(e),t=e=>i[e]=t=>{if(r){if(r=!1,"throw"===e)throw t;return t}return r=!0,{done:!1,value:new g(new Promise(r=>{var i=n[e](t);if(!(i instanceof Object))throw TypeError("Object expected");r(i)}),1)}}),i[l("iterator")]=()=>i,t("next"),"throw"in n?t("throw"):i.throw=e=>{throw e},"return"in n&&t("return"),i};function b(e,t){for(var n=0;nr[t]})}}return Object.freeze(Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}))}function w(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}!function(){const e=document.createElement("link").relList;if(!(e&&e.supports&&e.supports("modulepreload"))){for(const e of document.querySelectorAll('link[rel="modulepreload"]'))t(e);new MutationObserver(e=>{for(const n of e)if("childList"===n.type)for(const e of n.addedNodes)"LINK"===e.tagName&&"modulepreload"===e.rel&&t(e)}).observe(document,{childList:!0,subtree:!0})}function t(e){if(e.ep)return;e.ep=!0;const t=function(e){const t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),"use-credentials"===e.crossOrigin?t.credentials="include":"anonymous"===e.crossOrigin?t.credentials="omit":t.credentials="same-origin",t}(e);fetch(e.href,t)}}();var x={exports:{}},k={},S={exports:{}},E={},_=Symbol.for("react.element"),C=Symbol.for("react.portal"),N=Symbol.for("react.fragment"),I=Symbol.for("react.strict_mode"),T=Symbol.for("react.profiler"),P=Symbol.for("react.provider"),R=Symbol.for("react.context"),O=Symbol.for("react.forward_ref"),A=Symbol.for("react.suspense"),L=Symbol.for("react.memo"),j=Symbol.for("react.lazy"),D=Symbol.iterator;var M={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},U=Object.assign,z={};function F(e,t,n){this.props=e,this.context=t,this.refs=z,this.updater=n||M}function B(){}function V(e,t,n){this.props=e,this.context=t,this.refs=z,this.updater=n||M}F.prototype.isReactComponent={},F.prototype.setState=function(e,t){if("object"!=typeof e&&"function"!=typeof e&&null!=e)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,e,t,"setState")},F.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")},B.prototype=F.prototype;var $=V.prototype=new B;$.constructor=V,U($,F.prototype),$.isPureReactComponent=!0;var H=Array.isArray,W=Object.prototype.hasOwnProperty,q={current:null},K={key:!0,ref:!0,__self:!0,__source:!0};function G(e,t,n){var r,i={},o=null,a=null;if(null!=t)for(r in void 0!==t.ref&&(a=t.ref),void 0!==t.key&&(o=""+t.key),t)W.call(t,r)&&!K.hasOwnProperty(r)&&(i[r]=t[r]);var s=arguments.length-2;if(1===s)i.children=n;else if(1>>1,o=e[r];if(!(0>>1;ri(l,n))ui(c,l)?(e[r]=c,e[u]=n,r=u):(e[r]=l,e[s]=n,r=s);else{if(!(ui(c,n)))break e;e[r]=c,e[u]=n,r=u}}}return t}function i(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}if("object"==typeof performance&&"function"==typeof performance.now){var o=performance;e.unstable_now=function(){return o.now()}}else{var a=Date,s=a.now();e.unstable_now=function(){return a.now()-s}}var l=[],u=[],c=1,d=null,f=3,h=!1,p=!1,m=!1,g="function"==typeof setTimeout?setTimeout:null,v="function"==typeof clearTimeout?clearTimeout:null,y="undefined"!=typeof setImmediate?setImmediate:null;function b(e){for(var i=n(u);null!==i;){if(null===i.callback)r(u);else{if(!(i.startTime<=e))break;r(u),i.sortIndex=i.expirationTime,t(l,i)}i=n(u)}}function w(e){if(m=!1,b(e),!p)if(null!==n(l))p=!0,O(x);else{var t=n(u);null!==t&&A(w,t.startTime-e)}}function x(t,i){p=!1,m&&(m=!1,v(_),_=-1),h=!0;var o=f;try{for(b(i),d=n(l);null!==d&&(!(d.expirationTime>i)||t&&!I());){var a=d.callback;if("function"==typeof a){d.callback=null,f=d.priorityLevel;var s=a(d.expirationTime<=i);i=e.unstable_now(),"function"==typeof s?d.callback=s:d===n(l)&&r(l),b(i)}else r(l);d=n(l)}if(null!==d)var c=!0;else{var g=n(u);null!==g&&A(w,g.startTime-i),c=!1}return c}finally{d=null,f=o,h=!1}}"undefined"!=typeof navigator&&void 0!==navigator.scheduling&&void 0!==navigator.scheduling.isInputPending&&navigator.scheduling.isInputPending.bind(navigator.scheduling);var k,S=!1,E=null,_=-1,C=5,N=-1;function I(){return!(e.unstable_now()-Ne||125a?(r.sortIndex=o,t(u,r),null===n(l)&&r===n(u)&&(m?(v(_),_=-1):m=!0,A(w,o-a))):(r.sortIndex=s,t(l,r),p||h||(p=!0,O(x))),r},e.unstable_shouldYield=I,e.unstable_wrapCallback=function(e){var t=f;return function(){var n=f;f=t;try{return e.apply(this,arguments)}finally{f=n}}}}(we),be.exports=we;var xe=be.exports,ke=oe,Se=xe; +/** + * @license React + * react-dom.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */function Ee(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n