1/* DressKool â telemetrie produit (POST /api/ftrack). 2 Aucun envoi tant que l'eleve n'a pas laisse son email. Echec silencieux : le 3 tracking ne doit jamais casser le parcours. */ 4(function () { 5 var S = window.DK.S; 6 7 /* ââ PROVENANCE (premier contact) âââââââââââââââââââââââââââââââââââââ 8 Defaut reel du 01/09/2026 : `signup` etait ecrit sans AUCUNE indication 9 d'origine. Sur les 4 eleves reelles, personne â ni le journal, ni le 10 back-office, ni HubSpot â ne pouvait dire d'ou elles venaient. Or la 11 mesure du jour montre 506 arrivees Google par mois sur dresskool.com, 12 dont 497 sur un article de blog qui ne porte AUCUNE balise de mesure et 13 dont l'unique porte est un paiement Stripe a 79 EUR. Sans provenance a 14 l'inscription, il est impossible de trancher entre « le blog n'amene 15 personne » et « le blog amene mais la porte est la mauvaise ». 16 17 PREMIER CONTACT, pas dernier : on ecrit une seule fois, a la premiere 18 visite, et on ne recrase jamais. Une eleve qui arrive par le blog puis 19 revient en direct trois jours plus tard reste attribuee au blog. 20 Cle de stockage dediee (`dk_src`), volontairement DISTINCTE de l'etat de 21 progression (`dk10`) : rien ici ne peut abimer le parcours d'une eleve. 22 On ne conserve que le NOM DE DOMAINE du referent, jamais l'URL complete. */ 23 var SRC_KEY = 'dk_src'; 24 25 function bareHost(h) { return String(h || '').replace(/^www\./, '').toLowerCase(); } 26 27 function captureSource() { 28 var rec = null; 29 try { rec = JSON.parse(localStorage.getItem(SRC_KEY) || 'null'); } catch (e) {} 30 if (rec && typeof rec === 'object' && typeof rec.ref === 'string') return rec; 31 32 var utm = '', camp = ''; 33 try { 34 var sp = new URLSearchParams(window.location.search); 35 utm = (sp.get('utm_source') || '').slice(0, 60); 36 camp = (sp.get('utm_campaign') || '').slice(0, 60); 37 } catch (e) {} 38 39 var ref = ''; 40 try { 41 if (document.referrer) ref = bareHost(new URL(document.referrer).hostname); 42 } catch (e) {} 43 /* Une navigation interne n'est pas une provenance. */ 44 if (ref && ref === bareHost(window.location.hostname)) ref = ''; 45 if (!ref) ref = 'direct'; 46 47 rec = { ref: ref.slice(0, 60), utm: utm, camp: camp }; 48 try { localStorage.setItem(SRC_KEY, JSON.stringify(rec)); } catch (e) {} 49 return rec; 50 } 51 52 /* Capture AU CHARGEMENT, pas a l'inscription : au moment ou l'eleve laisse 53 son email, `document.referrer` a depuis longtemps disparu (navigation 54 interne a l'application). C'est exactement ce qui rendait la provenance 55 irrecuperable apres coup. */ 56 var SRC = captureSource(); 57 58 function ftrack(event, extra) { 59 if (!S.email) return; 60 var LEVELS = window.DK.LEVELS || []; 61 var lvl = LEVELS[window.DK.getLevel(S.xp || 0)] || {}; 62 var data = Object.assign({ 63 event: event, 64 email: S.email, 65 user: S.user, 66 total_xp: S.xp || 0, 67 done_count: Object.keys(S.done).length, 68 total_lessons: window.TOTAL || 0, 69 level: lvl.name || '', 70 lang: window.DK.lang 71 }, extra || {}); 72 /* La provenance ne voyage qu'avec `signup` : c'est le seul evenement ou 73 elle apporte une information, et l'attacher a tous les autres gonflerait 74 le journal sans rien ajouter. */ 75 if (event === 'signup' && SRC) { 76 data.src_ref = SRC.ref; 77 if (SRC.utm) data.src_utm = SRC.utm; 78 if (SRC.camp) data.src_camp = SRC.camp; 79 } 80 fetch('/api/ftrack', { 81 method: 'POST', 82 headers: { 'Content-Type': 'application/json' }, 83 body: JSON.stringify(data) 84 }).catch(function () {}); 85 } 86 87 window.DK.ftrack = ftrack; 88 window.ftrack = ftrack; 89})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.