Spaces:
Running
Running
| /** | |
| * IronChronicle Main Logic - Version Pro Long Form | |
| * Support 100+ pages manuelles, undefinednull fixé définitivement | |
| */ | |
| // Configuration API - Clé primaire validée | |
| const API_CONFIG = { | |
| OPENROUTER_KEY: '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', | |
| BASE_URL: 'https://openrouter.ai/api/v1', | |
| DEFAULT_MODEL: 'deepseek/deepseek-r1', | |
| FALLBACK_MODEL: 'mistralai/mistral-small', | |
| LONGFORM_ENABLED: true | |
| }; | |
| // Gestionnaire de clé API sécurisé - Anti-undefinednull V2 | |
| class SecureKeyManager { | |
| static VALID_KEY_PATTERN = /^sk-or-v1-[a-f0-9]{64}$/i; | |
| static FALLBACK_KEY = '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'; | |
| static getKey() { | |
| try { | |
| let stored = localStorage.getItem('openrouter_api_key'); | |
| // Détection immédiate de corruption | |
| if (stored && this.isCorrupted(stored)) { | |
| console.warn('[SecureKeyManager] Nettoyage corruption:', stored.substring(0, 20)); | |
| localStorage.removeItem('openrouter_api_key'); | |
| stored = null; | |
| } | |
| // Validation stricte | |
| if (stored && this.VALID_KEY_PATTERN.test(stored) && stored.length > 60) { | |
| return stored; | |
| } | |
| // Retour au fallback sécurisé | |
| return this.FALLBACK_KEY; | |
| } catch (e) { | |
| return this.FALLBACK_KEY; | |
| } | |
| } | |
| static setKey(key) { | |
| if (!key || typeof key !== 'string') return false; | |
| if (this.isCorrupted(key)) return false; | |
| if (!this.VALID_KEY_PATTERN.test(key)) return false; | |
| try { | |
| localStorage.setItem('openrouter_api_key', key); | |
| return true; | |
| } catch (e) { | |
| return false; | |
| } | |
| } | |
| static isCorrupted(key) { | |
| if (!key || typeof key !== 'string') return true; | |
| if (key.length < 20) return true; | |
| // Patterns de corruption JavaScript courants | |
| const corruptionPatterns = [ | |
| 'undefinednull', | |
| 'undefined', | |
| 'null', | |
| '[object Object]', | |
| 'function', | |
| 'NaN', | |
| '••••••••' | |
| ]; | |
| return corruptionPatterns.some(p => key === p || key.includes(p)); | |
| } | |
| } | |
| // Exposer globalement immédiatement | |
| window.SecureKeyManager = SecureKeyManager; | |
| window.API_CONFIG = { | |
| OPENROUTER_KEY: SecureKeyManager.FALLBACK_KEY, | |
| initialized: true | |
| }; | |
| // Attendre que le DOM soit prêt | |
| document.addEventListener('DOMContentLoaded', () => { | |
| // Initialisation sécurisée immédiate | |
| window.SecureKeyManager = SecureKeyManager; | |
| // Vérification au démarrage avec log de sécurité | |
| const currentKey = SecureKeyManager.getKey(); | |
| const isValid = !SecureKeyManager.isCorrupted(currentKey); | |
| console.log('[IronChronicle] Système initialisé:', { | |
| status: isValid ? 'OPÉRATIONNEL' : 'FALLBACK ACTIF', | |
| keySource: currentKey === SecureKeyManager.FALLBACK_KEY ? 'Fallback' : 'Storage', | |
| keyPreview: currentKey.substring(0, 15) + '...' | |
| }); | |
| // Initialisation des composants Long Form - FORCÉE | |
| initLongFormSystem(); | |
| // Réactivation explicite des boutons | |
| setTimeout(() => { | |
| const generateBtn = document.getElementById('generate-btn'); | |
| if (generateBtn) { | |
| generateBtn.disabled = false; | |
| generateBtn.style.opacity = '1'; | |
| generateBtn.style.cursor = 'pointer'; | |
| } | |
| }, 100); | |
| }); | |
| function initLongFormSystem() { | |
| // Le composant long-narrative-handler est autonome | |
| // mais on ajoute des raccourcis globaux | |
| window.openLongDocument = (pages) => { | |
| const handler = document.querySelector('long-narrative-handler'); | |
| if (handler && pages) { | |
| handler.loadPages(pages); | |
| } | |
| }; | |
| } |