| | <!DOCTYPE html> |
| | <html lang="fr"> |
| | <head> |
| | <meta charset="UTF-8"> |
| | <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| | <title>CléfistAI - Générateur de Code ClemScript</title> |
| | <style> |
| | body { |
| | font-family: Arial, sans-serif; |
| | max-width: 900px; |
| | margin: 0 auto; |
| | padding: 20px; |
| | background-color: #EEC4C9; |
| | } |
| | h1 { |
| | color: #F9429E; |
| | } |
| | textarea { |
| | width: 100%; |
| | height: 150px; |
| | margin: 10px 0; |
| | padding: 10px; |
| | border-radius: 5px; |
| | border: 1px solid #ddd; |
| | } |
| | button { |
| | background-color: #ff6b6b; |
| | color: white; |
| | border: none; |
| | padding: 12px 20px; |
| | cursor: pointer; |
| | font-size: 16px; |
| | border-radius: 5px; |
| | margin-right: 10px; |
| | } |
| | button:hover { |
| | background-color: #ff5252; |
| | } |
| | #result { |
| | background-color: white; |
| | border: 1px solid #ddd; |
| | padding: 15px; |
| | margin-top: 20px; |
| | border-radius: 5px; |
| | white-space: pre-wrap; |
| | font-family: monospace; |
| | min-height: 300px; |
| | } |
| | .examples { |
| | margin-top: 30px; |
| | background-color: white; |
| | padding: 15px; |
| | border-radius: 5px; |
| | border: 1px solid #ddd; |
| | } |
| | .examples h3 { |
| | margin-top: 0; |
| | } |
| | .examples ul { |
| | padding-left: 20px; |
| | } |
| | </style> |
| | </head> |
| | <body> |
| | <h1>CléfistAI - Générateur de Code ClemScript</h1> |
| | <p>Décrivez ce que vous voulez faire en français naturel. Exemples ci-dessous :</p> |
| | <textarea id="prompt" placeholder="Ex: Je veux une variable 'score' qui vaut 100, une boucle de 1 à 10 qui affiche la valeur, et une condition qui vérifie si 'score' est supérieur à 50..."></textarea> |
| | <button onclick="generateCode()">Générer le code</button> |
| | <button onclick="copyCode()">Copier le code</button> |
| | <h2>Code ClemScript généré :</h2> |
| | <div id="result"></div> |
| |
|
| | <div class="examples"> |
| | <h3>Exemples de demandes naturelles :</h3> |
| | <ul> |
| | <li>Je veux une variable appelée "compteur" avec la valeur 10.</li> |
| | <li>Crée une boucle de 1 à 5 qui affiche "Valeur actuelle : [i]".</li> |
| | <li>Ajoute une condition : si "age" est supérieur à 18, affiche "Majeur" en vert, sinon affiche "Mineur" en rouge.</li> |
| | <li>Fais un quiz avec la question "Quelle est la capitale de la France ?", les options "Paris", "Londres", "Berlin", et la bonne réponse est "Paris".</li> |
| | <li>Génère un nombre aléatoire entre 1 et 100 et stocke-le dans une variable "hasard".</li> |
| | <li>Demande à l'utilisateur son prénom et affiche "Bonjour [prénom] !".</li> |
| | <li>Calcule le carré de 8 et stocke le résultat dans "carré".</li> |
| | <li>Si l'utilisateur choisit "forêt", affiche "Tu explores la forêt", et si c'est "montagne", affiche "Tu escalades la montagne".</li> |
| | </ul> |
| | </div> |
| |
|
| | <script> |
| | |
| | const codeTemplates = { |
| | variable: ({ nom, valeur }) => |
| | `Clem var Script ${nom} = ${valeur};\n`, |
| | |
| | afficher: ({ message, couleur }) => { |
| | if (couleur) { |
| | return `Clem color Script "${couleur}" "${message}";\n`; |
| | } else { |
| | return `Clem console Script -> "${message}";\n`; |
| | } |
| | }, |
| | |
| | boucle: ({ variable, debut, fin, corps }) => |
| | `Clem for Script ${variable} Clem from Script ${debut} Clem to Script ${fin} Clem do Script {\n` + |
| | ` ${corps}\n` + |
| | `}\n`, |
| | |
| | condition: ({ condition, siVrai, siFaux, couleurSiVrai, couleurSiFaux }) => { |
| | let code = `Clem if Script (${condition}) Clem then Script {\n`; |
| | if (couleurSiVrai) { |
| | code += ` Clem color Script "${couleurSiVrai}" "${siVrai}";\n`; |
| | } else { |
| | code += ` Clem console Script -> "${siVrai}";\n`; |
| | } |
| | code += `}`; |
| | if (siFaux) { |
| | code += ` Clem else Script {\n`; |
| | if (couleurSiFaux) { |
| | code += ` Clem color Script "${couleurSiFaux}" "${siFaux}";\n`; |
| | } else { |
| | code += ` Clem console Script -> "${siFaux}";\n`; |
| | } |
| | code += `}`; |
| | } |
| | return code + `\n`; |
| | }, |
| | |
| | saisie: ({ variable, message }) => |
| | `Clem input Script ${variable} "${message}";\n`, |
| | |
| | quiz: ({ question, options, reponse }) => { |
| | const optionsStr = options.map(opt => `"${opt}"`).join(' '); |
| | return `Clem quiz Script "${question}"\n` + |
| | ` Clem options Script ${optionsStr} Clem answer Script ${reponse};\n`; |
| | }, |
| | |
| | interaction: ({ variable, motsCles, reponses }) => { |
| | let code = `Clem var Script ${variable};\n` + |
| | `Clem input Script ${variable} "Faites un choix : ";\n`; |
| | motsCles.forEach((motCle, i) => { |
| | code += `Clem if Script (${variable} == "${motCle}") Clem then Script {\n` + |
| | ` Clem console Script -> "${reponses[i]}";\n` + |
| | `}\n`; |
| | }); |
| | return code; |
| | }, |
| | |
| | aleatoireNombre: ({ variable, min, max }) => |
| | `Clem var Script ${variable} = Clem random valeur Script ${min} ${max};\n`, |
| | |
| | aleatoireTexte: ({ textes }) => |
| | `Clem random text Script ${textes.map(t => `"${t}"`).join(', ')};\n`, |
| | |
| | mathCarre: ({ variable, valeur }) => |
| | `Clem var Script ${variable} = Clem math Script square ${valeur};\n`, |
| | |
| | mathRacine: ({ variable, valeur }) => |
| | `Clem var Script ${variable} = Clem math Script sqrt ${valeur};\n`, |
| | |
| | mathAbsolu: ({ variable, valeur }) => |
| | `Clem var Script ${variable} = Clem math Script abs ${valeur};\n`, |
| | }; |
| | |
| | |
| | const domainDetectors = [ |
| | { |
| | name: "variable", |
| | keywords: ["variable", "créer une variable", "déclarer une variable", "stocker dans"], |
| | extract: (text) => { |
| | const nomMatch = text.match(/une? variable (?:appelée|nommée|["']?)([\w]+)/i); |
| | const valeurMatch = text.match(/(?:valeur|vaut|égale à|=) ([\d]+|"[^"]+")/i); |
| | return { |
| | nom: nomMatch ? nomMatch[1] : "maVariable", |
| | valeur: valeurMatch ? valeurMatch[1].replace(/"/g, '') : "0" |
| | }; |
| | } |
| | }, |
| | { |
| | name: "afficher", |
| | keywords: ["afficher", "montrer", "écrire", "dire", "affiche"], |
| | extract: (text) => { |
| | const messageMatch = text.match(/["']([^"']+)["']/); |
| | const couleurMatch = text.match(/(rouge|vert|bleu|jaune|magenta|cyan|blanc)/i); |
| | return { |
| | message: messageMatch ? messageMatch[1] : "Message par défaut", |
| | couleur: couleurMatch ? couleurMatch[0].toLowerCase() : null |
| | }; |
| | } |
| | }, |
| | { |
| | name: "boucle", |
| | keywords: ["boucle", "pour", "de", "à", "itérer", "répéter"], |
| | extract: (text) => { |
| | const varMatch = text.match(/variable ["']?([\w]+)["']?/i); |
| | const debutMatch = text.match(/de ["']?(\d+)["']?/i); |
| | const finMatch = text.match(/à ["']?(\d+)["']?/i); |
| | const corpsMatch = text.match(/affiche ["']([^"']+)["']/i); |
| | const variable = varMatch ? varMatch[1] : "i"; |
| | const corps = corpsMatch ? |
| | `Clem console Script -> "${corpsMatch[1].replace(/x|i/g, variable)}";` : |
| | `Clem console Script -> "Itération : " + ${variable};`; |
| | return { |
| | variable: variable, |
| | debut: debutMatch ? debutMatch[1] : "0", |
| | fin: finMatch ? finMatch[1] : "5", |
| | corps: corps |
| | }; |
| | } |
| | }, |
| | { |
| | name: "condition", |
| | keywords: ["condition", "si", "alors", "sinon", "vérifie", "teste"], |
| | extract: (text) => { |
| | const conditionMatch = text.match(/si ["']?([^"']+)["']?/i); |
| | const siVraiMatch = text.match(/alors (?:affiche|montre) ["']([^"']+)["'](?: en (\w+))?/i); |
| | const siFauxMatch = text.match(/sinon (?:affiche|montre) ["']([^"']+)["'](?: en (\w+))?/i); |
| | return { |
| | condition: conditionMatch ? conditionMatch[1] : "true", |
| | siVrai: siVraiMatch ? siVraiMatch[1] : "Condition vraie", |
| | couleurSiVrai: siVraiMatch && siVraiMatch[2] ? siVraiMatch[2].toLowerCase() : null, |
| | siFaux: siFauxMatch ? siFauxMatch[1] : null, |
| | couleurSiFaux: siFauxMatch && siFauxMatch[2] ? siFauxMatch[2].toLowerCase() : null |
| | }; |
| | } |
| | }, |
| | { |
| | name: "saisie", |
| | keywords: ["demande", "saisie", "input", "question", "demander à l'utilisateur"], |
| | extract: (text) => { |
| | const varMatch = text.match(/(?:son|sa|le) ([\w]+)/i); |
| | const messageMatch = text.match(/["']([^"']+)["']/); |
| | return { |
| | variable: varMatch ? varMatch[1] : "reponse", |
| | message: messageMatch ? messageMatch[1] : "Entrez une valeur :" |
| | }; |
| | } |
| | }, |
| | { |
| | name: "quiz", |
| | keywords: ["quiz", "question", "réponse", "options", "qcm"], |
| | extract: (text) => { |
| | const questionMatch = text.match(/question ["']([^"']+)["']/i); |
| | const optionsMatch = text.match(/options (?:["']([^"']+)["'](?:, ["']([^"']+)["'](?:, ["']([^"']+)["'])?)?)/i); |
| | const reponseMatch = text.match(/réponse (?:est|["']?)([^"',]+)/i); |
| | const options = optionsMatch ? |
| | [optionsMatch[1], optionsMatch[2], optionsMatch[3]].filter(Boolean) : |
| | ["Option 1", "Option 2"]; |
| | const reponse = reponseMatch ? |
| | options.indexOf(reponseMatch[1]) + 1 : |
| | 1; |
| | return { |
| | question: questionMatch ? questionMatch[1] : "Question ?", |
| | options: options, |
| | reponse: reponse |
| | }; |
| | } |
| | }, |
| | { |
| | name: "interaction", |
| | keywords: ["interaction", "choix", "si.*choisit", "menu", "option"], |
| | extract: (text) => { |
| | const motsClesMatch = text.match(/choisit ["']([^"']+)["'].*affiche ["']([^"']+)["'](?:.*choisit ["']([^"']+)["'].*affiche ["']([^"']+)["'])?/i); |
| | const motsCles = motsClesMatch ? |
| | [motsClesMatch[1], motsClesMatch[3]].filter(Boolean) : |
| | ["forêt", "montagne"]; |
| | const reponses = motsClesMatch ? |
| | [motsClesMatch[2], motsClesMatch[4]].filter(Boolean) : |
| | ["Réponse 1", "Réponse 2"]; |
| | return { |
| | variable: "choix", |
| | motsCles: motsCles, |
| | reponses: reponses |
| | }; |
| | } |
| | }, |
| | { |
| | name: "aleatoireNombre", |
| | keywords: ["nombre aléatoire", "random", "entre", "hasard", "aléatoire"], |
| | extract: (text) => { |
| | const minMatch = text.match(/entre ["']?(\d+)["']?/i); |
| | const maxMatch = text.match(/et ["']?(\d+)["']?/i); |
| | const varMatch = text.match(/dans (?:une variable|["']?)([\w]+)/i); |
| | return { |
| | variable: varMatch ? varMatch[1] : "aleatoire", |
| | min: minMatch ? minMatch[1] : "1", |
| | max: maxMatch ? maxMatch[1] : "100" |
| | }; |
| | } |
| | }, |
| | { |
| | name: "aleatoireTexte", |
| | keywords: ["texte aléatoire", "random texte", "parmi", "au hasard"], |
| | extract: (text) => { |
| | const textesMatch = text.match(/parmi (?:["']([^"']+)["'](?:, ["']([^"']+)["'](?:, ["']([^"']+)["'])?)?)/i); |
| | const textes = textesMatch ? |
| | [textesMatch[1], textesMatch[2], textesMatch[3]].filter(Boolean) : |
| | ["Texte 1", "Texte 2"]; |
| | return { textes }; |
| | } |
| | }, |
| | { |
| | name: "mathCarre", |
| | keywords: ["carré", "square", "au carré"], |
| | extract: (text) => { |
| | const valeurMatch = text.match(/de ["']?(\d+)["']?/i); |
| | const varMatch = text.match(/dans (?:une variable|["']?)([\w]+)/i); |
| | return { |
| | variable: varMatch ? varMatch[1] : "carre", |
| | valeur: valeurMatch ? valeurMatch[1] : "5" |
| | }; |
| | } |
| | }, |
| | { |
| | name: "mathRacine", |
| | keywords: ["racine", "sqrt", "racine carrée"], |
| | extract: (text) => { |
| | const valeurMatch = text.match(/de ["']?(\d+)["']?/i); |
| | const varMatch = text.match(/dans (?:une variable|["']?)([\w]+)/i); |
| | return { |
| | variable: varMatch ? varMatch[1] : "racine", |
| | valeur: valeurMatch ? valeurMatch[1] : "16" |
| | }; |
| | } |
| | }, |
| | { |
| | name: "mathAbsolu", |
| | keywords: ["absolu", "abs", "valeur absolue"], |
| | extract: (text) => { |
| | const valeurMatch = text.match(/de ["']?(-?\d+)["']?/i); |
| | const varMatch = text.match(/dans (?:une variable|["']?)([\w]+)/i); |
| | return { |
| | variable: varMatch ? varMatch[1] : "absolu", |
| | valeur: valeurMatch ? valeurMatch[1] : "-8" |
| | }; |
| | } |
| | } |
| | ]; |
| | |
| | |
| | function detectDomains(prompt) { |
| | const domains = []; |
| | const promptLower = prompt.toLowerCase(); |
| | |
| | domainDetectors.forEach(detector => { |
| | if (detector.keywords.some(keyword => promptLower.includes(keyword))) { |
| | domains.push({ |
| | name: detector.name, |
| | params: detector.extract(prompt) |
| | }); |
| | } |
| | }); |
| | |
| | return domains; |
| | } |
| | |
| | |
| | function generateCode() { |
| | const prompt = document.getElementById('prompt').value; |
| | const domains = detectDomains(prompt); |
| | let generatedCode = ''; |
| | |
| | if (domains.length > 0) { |
| | domains.forEach(domain => { |
| | try { |
| | generatedCode += `// ${domain.name}\n` + codeTemplates[domain.name](domain.params) + '\n'; |
| | } catch (e) { |
| | generatedCode += `// Erreur pour ${domain.name} : ${e.message}\n`; |
| | } |
| | }); |
| | } else { |
| | generatedCode = "// Désolé, je n'ai pas compris votre demande. Essayez de reformuler ou consultez les exemples.\n"; |
| | } |
| | |
| | document.getElementById('result').textContent = generatedCode; |
| | } |
| | |
| | |
| | function copyCode() { |
| | const code = document.getElementById('result').textContent; |
| | navigator.clipboard.writeText(code) |
| | .then(() => alert("Code copié dans le presse-papiers !")) |
| | .catch(() => alert("Échec de la copie.")); |
| | } |
| | </script> |
| | </body> |
| | </html> |
| |
|