From 742d86dfaa75a865b167616b56fdddd5a7f3e89a Mon Sep 17 00:00:00 2001 From: "gauthier.chombart" Date: Wed, 17 Jun 2026 18:38:56 +0200 Subject: [PATCH] =?UTF-8?q?Ajout=20d'une=20possibilit=C3=A9=20de=20correct?= =?UTF-8?q?ion=20pour=20le=20TP=20Nuisibles?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- exercices/TP_Nuisibles.html | 89 +++- exercices/admin_resultats.asp | 299 ------------ exercices/correction-tp-nuisibles.html | 650 +++++++++++++++++++++++++ exercices/save_results.asp | 213 -------- 4 files changed, 735 insertions(+), 516 deletions(-) delete mode 100644 exercices/admin_resultats.asp create mode 100644 exercices/correction-tp-nuisibles.html delete mode 100644 exercices/save_results.asp diff --git a/exercices/TP_Nuisibles.html b/exercices/TP_Nuisibles.html index c9a9eb2..e2266e8 100644 --- a/exercices/TP_Nuisibles.html +++ b/exercices/TP_Nuisibles.html @@ -628,6 +628,9 @@ + + +
@@ -688,7 +691,10 @@ - +
+ + Corriger +
@@ -697,7 +703,7 @@
-
Formation 2025
+
Formation
CERTIBIOCIDE
TRAVAUX PRATIQUES

Votre mission, si vous l'acceptez : maîtriser l'identification, le traitement et la sécurité face aux nuisibles.

@@ -1119,7 +1125,7 @@
🎉
Félicitations !
-

Vous avez complété les 3 travaux pratiques de la formation Certibiocide 2025. Le formateur va maintenant corriger à l'oral.

+

Vous avez complété les 3 travaux pratiques de la formation Certibiocide. Le formateur va maintenant corriger à l'oral.

🗂️
@@ -1140,6 +1146,7 @@
+ Corriger
@@ -1243,6 +1250,7 @@ function goTo(n) { currentSlide = n; next.style.display = 'flex'; setTimeout(() => { next.classList.add('active', 'fade-in'); }, 10); + if (n === 13) setTimeout(launchConfetti, 200); updateUI(); updateCaseBanners(); } @@ -1497,7 +1505,7 @@ function exporterPDF() { .meta { font-size: 13px; color: #555; margin-bottom: 4px; } -

TP Nuisibles — Certibiocide 2025

+

TP Nuisibles — Certibiocide

Groupe / Stagiaire : ${escapeHtml(data.nom)}

Date de session : ${escapeHtml(data.date_session)}

Formateur : ${escapeHtml(data.formateur)}

@@ -1520,6 +1528,79 @@ function exporterPDF() { setTimeout(() => w.print(), 300); } +/* ======================== CONFETTI ======================== */ +function launchConfetti() { + const canvas = document.getElementById('confettiCanvas'); + if (!canvas) return; + const ctx = canvas.getContext('2d'); + canvas.width = window.innerWidth; + canvas.height = window.innerHeight; + canvas.style.display = 'block'; + + const colors = ['#BA7517', '#D85A30', '#F5DFB8', '#633806', '#F0A855', '#E8C068', '#FF8C5A']; + const particles = Array.from({ length: 180 }, () => ({ + x: Math.random() * canvas.width, + y: -(Math.random() * canvas.height * 0.5), + w: Math.random() * 10 + 5, + h: Math.random() * 5 + 3, + color: colors[Math.floor(Math.random() * colors.length)], + rotation: Math.random() * Math.PI * 2, + rotSpeed: (Math.random() - 0.5) * 0.18, + vx: (Math.random() - 0.5) * 2.5, + vy: Math.random() * 3 + 2, + opacity: 1, + shape: Math.random() < 0.4 ? 'circle' : 'rect' + })); + + let rafId; + let start = null; + const totalDuration = 3800; + + function draw(ts) { + if (!start) start = ts; + const elapsed = ts - start; + + ctx.clearRect(0, 0, canvas.width, canvas.height); + let active = false; + + particles.forEach(p => { + p.x += p.vx; + p.y += p.vy; + p.vy += 0.04; + p.rotation += p.rotSpeed; + p.opacity = elapsed < totalDuration * 0.55 + ? 1 + : Math.max(0, 1 - (elapsed - totalDuration * 0.55) / (totalDuration * 0.45)); + + if (p.y < canvas.height + 20) active = true; + + ctx.save(); + ctx.translate(p.x, p.y); + ctx.rotate(p.rotation); + ctx.globalAlpha = p.opacity; + ctx.fillStyle = p.color; + if (p.shape === 'circle') { + ctx.beginPath(); + ctx.arc(0, 0, p.w / 2, 0, Math.PI * 2); + ctx.fill(); + } else { + ctx.fillRect(-p.w / 2, -p.h / 2, p.w, p.h); + } + ctx.restore(); + }); + + if (active && elapsed < totalDuration * 1.3) { + rafId = requestAnimationFrame(draw); + } else { + canvas.style.display = 'none'; + ctx.clearRect(0, 0, canvas.width, canvas.height); + } + } + + if (rafId) cancelAnimationFrame(rafId); + rafId = requestAnimationFrame(draw); +} + function escapeHtml(str) { if (!str) return ''; return str.replace(/&/g, '&').replace(//g, '>'); diff --git a/exercices/admin_resultats.asp b/exercices/admin_resultats.asp deleted file mode 100644 index 6c33d05..0000000 --- a/exercices/admin_resultats.asp +++ /dev/null @@ -1,299 +0,0 @@ -<%@ Language="VBScript" %> -<% -Response.Buffer = True -Response.CharSet = "UTF-8" - -' ------- À ADAPTER : même chaîne de connexion que save_results.asp ------- -Dim connString -connString = "Provider=SQLOLEDB;Data Source=sql.bsite.net\MSSQL2016;" & _ - "Initial Catalog=nextgnformation_reponses_exercices;" & _ - "User ID=nextgnformation_reponses_exercices;" & _ - "Password=S5$NyFXzEjJCg6jD;" - -' ------- À ADAPTER : mot de passe d'accès à cette page ------- -Dim ADMIN_PASSWORD -ADMIN_PASSWORD = "Sm#gnttCaYE5f3ED" -' ----------------------------------------------------------------------- - -Dim authenticated -authenticated = False - -If Request.Cookies("tp_admin_auth") = "ok" Then - authenticated = True -End If - -If Request.Form("password") <> "" Then - If Request.Form("password") = ADMIN_PASSWORD Then - authenticated = True - Response.Cookies("tp_admin_auth") = "ok" - Response.Cookies("tp_admin_auth").Expires = DateAdd("h", 8, Now) - Else - authenticated = False - End If -End If - -Function HtmlEscape(s) - If IsNull(s) Then - HtmlEscape = "" - Exit Function - End If - s = CStr(s) - s = Replace(s, "&", "&") - s = Replace(s, "<", "<") - s = Replace(s, ">", ">") - HtmlEscape = s -End Function -%> - - - - - -Résultats des TP — NextGN Formation - - - - - - - -
-<% -If Not authenticated Then -%> - -<% -Else - Dim conn, rs - Set conn = Server.CreateObject("ADODB.Connection") - On Error Resume Next - conn.Open connString - If Err.Number <> 0 Then -%> -

Erreur de connexion à la base : <%= HtmlEscape(Err.Description) %>

-<% - Else - Err.Clear - Set rs = conn.Execute("SELECT * FROM tp_resultats ORDER BY date_enregistrement DESC") - If Err.Number <> 0 Then -%> -

La table tp_resultats n'existe pas encore — aucun envoi reçu pour le moment.

-<% - Else -%> -
-

Résultats des stagiaires

- <%= IIf_Count(rs) %> -
- - - - - - - - -<% - Dim rowIndex - rowIndex = 0 - Do While Not rs.EOF - rowIndex = rowIndex + 1 -%> - - - - - - - - - - -<% - rs.MoveNext - Loop -%> -
Groupe / StagiaireDate sessionCas pratiqueReçu leDétail
<%= HtmlEscape(rs("nom")) %><%= HtmlEscape(rs("date_session")) %><%= HtmlEscape(rs("cas_choisi")) %><%= HtmlEscape(rs("date_enregistrement")) %>
-
-

Réponses TP1 & TP2

- <%= RenderReponses(rs("reponses_json")) %> -

TP3 — Analyse de risques

-

Intitulé : <%= HtmlEscape(rs("tp3_intitule")) %>

-

Description : <%= HtmlEscape(rs("tp3_description")) %>

-

Lieu : <%= HtmlEscape(rs("tp3_lieu")) %>

-

Début prévu : <%= HtmlEscape(rs("tp3_debut")) %>

- <%= RenderTableau(rs("tp3_tableau_json")) %> -

Réalisée par : <%= HtmlEscape(rs("tp3_realise_par")) %> — - Vérifiée par : <%= HtmlEscape(rs("tp3_verifie_par")) %> — - MAJ par : <%= HtmlEscape(rs("tp3_maj_par")) %>

-
-
-<% - End If - conn.Close - End If -End If -%> -
- - - - -<% -Function IIf_Count(rs) - Dim n - n = 0 - Do While Not rs.EOF - n = n + 1 - rs.MoveNext - Loop - rs.MoveFirst - IIf_Count = n & " envoi(s)" -End Function - -' --- Parsing JSON minimal via ScriptControl pour l'affichage admin --- -Function RenderReponses(jsonStr) - Dim out - out = "" - If Trim(jsonStr) = "" Then - RenderReponses = "

Aucune réponse.

" - Exit Function - End If - Dim sc - Set sc = Server.CreateObject("MSScriptControl.ScriptControl") - sc.Language = "JScript" - sc.AddCode "function parseArr(s){ return eval('(' + s + ')'); }" - On Error Resume Next - Dim arr - Set arr = sc.Run("parseArr", jsonStr) - If Err.Number <> 0 Then - RenderReponses = "

Erreur de lecture des réponses.

" - Exit Function - End If - On Error Goto 0 - Dim i - For i = 0 To arr.length - 1 - Dim q, r - q = arr.Item(i).question - r = arr.Item(i).reponse - If Trim(r) = "" Then r = "(sans réponse)" - out = out & "

" & ServerHtmlEscape(q) & " : " & ServerHtmlEscape(r) & "

" - Next - RenderReponses = out -End Function - -Function RenderTableau(jsonStr) - Dim out - out = "" - If Trim(jsonStr) = "" Then - RenderTableau = "" - Exit Function - End If - Dim sc - Set sc = Server.CreateObject("MSScriptControl.ScriptControl") - sc.Language = "JScript" - sc.AddCode "function parseArr(s){ return eval('(' + s + ')'); }" - On Error Resume Next - Dim arr - Set arr = sc.Run("parseArr", jsonStr) - If Err.Number <> 0 Then - RenderTableau = "

Erreur de lecture du tableau.

" - Exit Function - End If - On Error Goto 0 - out = "" - Dim i - For i = 0 To arr.length - 1 - out = out & "" - Next - out = out & "
ÉtapeRisqueMesure
" & ServerHtmlEscape(arr.Item(i).etape) & "" & _ - ServerHtmlEscape(arr.Item(i).risque) & "" & _ - ServerHtmlEscape(arr.Item(i).mesure) & "
" - RenderTableau = out -End Function - -Function ServerHtmlEscape(s) - If IsNull(s) Then - ServerHtmlEscape = "" - Exit Function - End If - s = CStr(s) - s = Replace(s, "&", "&") - s = Replace(s, "<", "<") - s = Replace(s, ">", ">") - ServerHtmlEscape = s -End Function -%> diff --git a/exercices/correction-tp-nuisibles.html b/exercices/correction-tp-nuisibles.html new file mode 100644 index 0000000..2593052 --- /dev/null +++ b/exercices/correction-tp-nuisibles.html @@ -0,0 +1,650 @@ + + + + + +Correction TP Nuisibles — Certibiocide + + + + + +
+ + +
+ +
+ +
Certibiocide — Correction de TP
+

TP Nuisibles — Lecture du rendu

+ +
+
📄
+

Déposez le PDF du stagiaire ici

+

ou cliquez pour sélectionner le fichier exporté depuis le TP

+ +
+
+ +
+
+ + +
+ +
+ +
+
+ questions répondues +
+ + + +

Analyse de risques

+
+ +

+
+
+ +
+

© 2026 NextGN Formation - Formations Certibiocide & Techniques

+

Tous droits réservés — Gauthier Chombart & Nathan Chauwin — Formateurs indépendants

+
+ + + + + diff --git a/exercices/save_results.asp b/exercices/save_results.asp deleted file mode 100644 index 6a79465..0000000 --- a/exercices/save_results.asp +++ /dev/null @@ -1,213 +0,0 @@ -<%@ Language="VBScript" %> -<% -' ============================================================ -' save_results.asp -' Reçoit les réponses de l'exercice TP Nuisibles (JSON en POST) -' et les enregistre dans la base SQL Server. -' ============================================================ -Response.Buffer = True -Response.ContentType = "application/json" -Response.CharSet = "UTF-8" - -' ------- À ADAPTER : chaîne de connexion vers votre base ------- -' Récupérée depuis le panneau "Manage Databases" de FreeASPHosting : -' Server Name : sql.bsite.net\MSSQL2016 -' SQL Username : nextgnformation_reponses_exercices -' Database name : (généralement identique au username, à vérifier dans le panneau) -Dim connString -connString = "Provider=SQLOLEDB;Data Source=sql.bsite.net\MSSQL2016;" & _ - "Initial Catalog=nextgnformation_reponses_exercices;" & _ - "User ID=nextgnformation_reponses_exercices;" & _ - "Password=S5$NyFXzEjJCg6jD;" -' ----------------------------------------------------------------- - -Function JSONEscape(s) - s = Replace(s, "\", "\\") - s = Replace(s, Chr(34), "\""") - s = Replace(s, vbCrLf, "\n") - s = Replace(s, vbLf, "\n") - s = Replace(s, vbCr, "\n") - s = Replace(s, vbTab, "\t") - JSONEscape = s -End Function - -Sub SendJSON(success, message) - Dim out - out = "{""success"":" & LCase(CStr(success)) & ",""error"":""" & JSONEscape(message) & """}" - Response.Write out - Response.End -End Sub - -' --- Lecture du corps de la requête (JSON brut envoyé en POST) --- -Dim rawJSON -Dim totalBytes -totalBytes = Request.TotalBytes -If totalBytes = 0 Then - SendJSON False, "Aucune donnée reçue." -End If - -Dim binData -binData = Request.BinaryRead(totalBytes) - -' Conversion des octets UTF-8 en chaîne VBScript -Dim objStream -Set objStream = Server.CreateObject("ADODB.Stream") -objStream.Type = 1 ' adTypeBinary -objStream.Open -objStream.Write binData -objStream.Position = 0 -objStream.Type = 2 ' adTypeText -objStream.CharSet = "utf-8" -rawJSON = objStream.ReadText -objStream.Close -Set objStream = Nothing - -If Trim(rawJSON) = "" Then - SendJSON False, "Corps de requête vide." -End If - -' --- Parsing JSON minimal sans librairie externe --- -' On utilise le moteur JScript via ScriptControl pour parser le JSON de façon fiable. -Dim sc -Set sc = Server.CreateObject("MSScriptControl.ScriptControl") -sc.Language = "JScript" -sc.AddCode "function parseIt(s){ return eval('(' + s + ')'); } " & _ - "function getStr(o,k){ return (o && o[k] != null) ? String(o[k]) : ''; } " & _ - "function getReponsesJSON(o){ var arr = o.reponses || []; var out = []; " & _ - "for (var i=0;i 0 Then - SendJSON False, "JSON invalide : " & Err.Description -End If -On Error Goto 0 - -Dim nom, dateSession, casChoisi, casCle, dateEnvoi -Dim metaIntitule, metaDescription, metaLieu, metaDebut, metaRealise, metaVerifie, metaMaj - -nom = sc.Run("getStr", dataObj, "nom") -dateSession = sc.Run("getStr", dataObj, "date_session") -casChoisi = sc.Run("getStr", dataObj, "cas_choisi") -casCle = sc.Run("getStr", dataObj, "cas_cle") -dateEnvoi = sc.Run("getStr", dataObj, "date_envoi") - -Dim tp3Obj -tp3Obj = dataObj.tp3_meta -metaIntitule = sc.Run("getStr", tp3Obj, "intitule") -metaDescription = sc.Run("getStr", tp3Obj, "description") -metaLieu = sc.Run("getStr", tp3Obj, "lieu") -metaDebut = sc.Run("getStr", tp3Obj, "debut") -metaRealise = sc.Run("getStr", tp3Obj, "realise_par") -metaVerifie = sc.Run("getStr", tp3Obj, "verifie_par") -metaMaj = sc.Run("getStr", tp3Obj, "maj_par") - -If Trim(nom) = "" Then - SendJSON False, "Le nom du groupe est obligatoire." -End If - -' --- Sérialisation des réponses et du tableau en JSON texte (stockés en colonnes NVARCHAR(MAX)) --- -Dim reponsesArr, tableauArr -Set reponsesArr = sc.Run("getReponsesJSON", dataObj) -Set tableauArr = sc.Run("getTableauJSON", dataObj) - -Dim reponsesJSONStr, tableauJSONStr -reponsesJSONStr = "[" -Dim i -For i = 0 To reponsesArr.length - 1 - If i > 0 Then reponsesJSONStr = reponsesJSONStr & "," - reponsesJSONStr = reponsesJSONStr & "{""id"":""" & JSONEscape(reponsesArr.Item(i).id) & _ - """,""question"":""" & JSONEscape(reponsesArr.Item(i).question) & _ - """,""reponse"":""" & JSONEscape(reponsesArr.Item(i).reponse) & """}" -Next -reponsesJSONStr = reponsesJSONStr & "]" - -tableauJSONStr = "[" -For i = 0 To tableauArr.length - 1 - If i > 0 Then tableauJSONStr = tableauJSONStr & "," - tableauJSONStr = tableauJSONStr & "{""etape"":""" & JSONEscape(tableauArr.Item(i).etape) & _ - """,""risque"":""" & JSONEscape(tableauArr.Item(i).risque) & _ - """,""mesure"":""" & JSONEscape(tableauArr.Item(i).mesure) & """}" -Next -tableauJSONStr = tableauJSONStr & "]" - -' --- Connexion et insertion en base --- -Dim conn -Set conn = Server.CreateObject("ADODB.Connection") - -On Error Resume Next -conn.Open connString -If Err.Number <> 0 Then - SendJSON False, "Connexion BDD impossible : " & Err.Description -End If -On Error Goto 0 - -' Création de la table si elle n'existe pas encore -Dim createTableSQL -createTableSQL = "IF NOT EXISTS (SELECT * FROM sysobjects WHERE name='tp_resultats' AND xtype='U') " & _ - "CREATE TABLE tp_resultats (" & _ - "id INT IDENTITY(1,1) PRIMARY KEY, " & _ - "nom NVARCHAR(255), " & _ - "date_session NVARCHAR(50), " & _ - "cas_choisi NVARCHAR(255), " & _ - "cas_cle NVARCHAR(100), " & _ - "reponses_json NVARCHAR(MAX), " & _ - "tp3_intitule NVARCHAR(500), " & _ - "tp3_description NVARCHAR(1000), " & _ - "tp3_lieu NVARCHAR(500), " & _ - "tp3_debut NVARCHAR(50), " & _ - "tp3_realise_par NVARCHAR(255), " & _ - "tp3_verifie_par NVARCHAR(255), " & _ - "tp3_maj_par NVARCHAR(255), " & _ - "tp3_tableau_json NVARCHAR(MAX), " & _ - "date_envoi NVARCHAR(50), " & _ - "date_enregistrement DATETIME DEFAULT GETDATE())" - -On Error Resume Next -conn.Execute createTableSQL -If Err.Number <> 0 Then - SendJSON False, "Création de table impossible : " & Err.Description -End If -On Error Goto 0 - -' Insertion via requête paramétrée (Command) pour éviter les injections SQL -Dim cmd -Set cmd = Server.CreateObject("ADODB.Command") -cmd.ActiveConnection = conn -cmd.CommandText = "INSERT INTO tp_resultats " & _ - "(nom, date_session, cas_choisi, cas_cle, reponses_json, tp3_intitule, tp3_description, tp3_lieu, tp3_debut, tp3_realise_par, tp3_verifie_par, tp3_maj_par, tp3_tableau_json, date_envoi) " & _ - "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" -cmd.CommandType = 1 ' adCmdText - -Dim p -Set p = cmd.CreateParameter("nom", 202, 1, 255, nom) : cmd.Parameters.Append p -Set p = cmd.CreateParameter("date_session", 202, 1, 50, dateSession) : cmd.Parameters.Append p -Set p = cmd.CreateParameter("cas_choisi", 202, 1, 255, casChoisi) : cmd.Parameters.Append p -Set p = cmd.CreateParameter("cas_cle", 202, 1, 100, casCle) : cmd.Parameters.Append p -Set p = cmd.CreateParameter("reponses_json", 203, 1, Len(reponsesJSONStr), reponsesJSONStr) : cmd.Parameters.Append p -Set p = cmd.CreateParameter("tp3_intitule", 202, 1, 500, metaIntitule) : cmd.Parameters.Append p -Set p = cmd.CreateParameter("tp3_description", 202, 1, 1000, metaDescription) : cmd.Parameters.Append p -Set p = cmd.CreateParameter("tp3_lieu", 202, 1, 500, metaLieu) : cmd.Parameters.Append p -Set p = cmd.CreateParameter("tp3_debut", 202, 1, 50, metaDebut) : cmd.Parameters.Append p -Set p = cmd.CreateParameter("tp3_realise_par", 202, 1, 255, metaRealise) : cmd.Parameters.Append p -Set p = cmd.CreateParameter("tp3_verifie_par", 202, 1, 255, metaVerifie) : cmd.Parameters.Append p -Set p = cmd.CreateParameter("tp3_maj_par", 202, 1, 255, metaMaj) : cmd.Parameters.Append p -Set p = cmd.CreateParameter("tp3_tableau_json", 203, 1, Len(tableauJSONStr), tableauJSONStr) : cmd.Parameters.Append p -Set p = cmd.CreateParameter("date_envoi", 202, 1, 50, dateEnvoi) : cmd.Parameters.Append p - -On Error Resume Next -cmd.Execute -If Err.Number <> 0 Then - conn.Close - SendJSON False, "Erreur lors de l'insertion : " & Err.Description -End If -On Error Goto 0 - -conn.Close -Set conn = Nothing - -SendJSON True, "" -%>