1/* ============================================================ 2 * CREA SOURCES â TOUS les outils & ressources du réel, par domaine et sous-domaine. 3 * Pour que Créa (et les agents/DLM) s'appuient sur le réel au lieu d'inventer. 4 * 5 * ⢠OUTILS (services live) par domaine : heure mondiale, météo, géocodage, change, 6 * cartes, actualités, traduction, QR, Bible⦠(les sans-clé marchent côté client). 7 * ⢠RESSOURCES (savoir) par domaineâsous-domaine : Wikipedia, Wikidata, arXiv, PubMed, 8 * Légifrance, Service-Public, World Bank, Gutenberg, Open Library, NASA, Gallica⦠9 * ⢠Awareness injectée (routée par domaine = peu de tokens) : Créa sait Oà puiser. 10 * ⢠Outil sans-clé câblé en direct : taux de change (open.er-api.com). 11 * 12 * 100% autonome. Charge APRÃS app.js. Expose window.CREA_SOURCES. 13 * ============================================================ */ 14;(function () { 15 'use strict' 16 if (window.CREA_SOURCES) return 17 function lc(s) { return String(s || '').toLowerCase() } 18 function esc(s) { return String(s == null ? '' : s).replace(/[&<>"']/g, function (c) { return ({ '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' })[c] }) } 19 20 // Indice de confiance : 5=institution officielle/scientifique · 4=encyclopédique curé · 3=agrégateur qualité · 2=live/flux · 1=non vérifié 21 var TRUST_STARS = { 5: 'âââââ', 4: 'ââââ', 3: 'âââ', 2: 'ââ', 1: 'â' } 22 var TRUST_LABELS = { 5: 'institution officielle', 4: 'encyclopédie curée', 3: 'agrégateur qualité', 2: 'flux live', 1: 'non vérifié' } 23 24 // ---- OUTILS LIVE par domaine ---- 25 var TOOLS = [ 26 { d: 'Temps', icon: 'ð', name: 'Heure & date mondiales', src: 'horloge système + WorldTimeAPI', trust: 4, live: true }, 27 { d: 'Météo', icon: 'â ', name: 'Météo locale', src: 'Open-Meteo (sans clé)', trust: 3, live: true }, 28 { d: 'Localisation',icon: 'ð', name: 'Ville & adresse exactes', src: 'Nominatim/OSM + BigDataCloud', trust: 4, live: true }, 29 { d: 'Finance', icon: 'ð±', name: 'Taux de change', src: 'open.er-api.com (sans clé)', trust: 3, live: true }, 30 { d: 'Cartes', icon: 'ðºï¸', name: 'Cartes & itinéraires', src: 'OpenStreetMap / OSRM', trust: 4 }, 31 { d: 'Actualités', icon: 'ð°', name: 'Actualités (mondiales & locales)',src: 'flux RSS / recherche web', trust: 2 }, 32 { d: 'Langues', icon: 'ð', name: 'Traduction', src: 'LibreTranslate', trust: 3 }, 33 { d: 'Web', icon: 'ð', name: 'Recherche & lecture de pages', src: '/api/search · /api/browse', trust: 2 }, 34 { d: 'Foi', icon: 'âï¸', name: 'Bible', src: 'LSG embarquée + /api/bible', trust: 5 }, 35 { d: 'Utilitaires', icon: 'ð³', name: 'QR codes', src: '/api/qr', trust: 5 }, 36 { d: 'Démarches', icon: 'ðï¸', name: 'Service-Public / France Connect',src: 'flux officiel (consentement)', trust: 5 } 37 ] 38 39 // ---- RESSOURCES (savoir) par domaine â sous-domaines â sources fiables ---- 40 var RES = [ 41 { d: 'Général', icon: 'ð', sub: 'tout sujet', sources: 'Wikipedia · Wikidata', trust: 4 }, 42 { d: 'Science', icon: 'ð¬', sub: 'physique, chimie, biologie, IA',sources: 'arXiv · Wikipedia · Semantic Scholar', trust: 4 }, 43 { d: 'Mathématiques', icon: 'â', sub: 'algèbre, analyse, stats', sources: 'Wikipedia · OEIS · Wolfram', trust: 4 }, 44 { d: 'Santé', icon: 'â¤ï¸', sub: 'maladies, prévention, nutrition',sources: 'PubMed · MedlinePlus · OMS (jamais un diagnostic)', trust: 5 }, 45 { d: 'Droit', icon: 'âï¸', sub: 'lois, contrats, RGPD (FR)', sources: 'Légifrance · Service-Public.fr · EUR-Lex', trust: 5 }, 46 { d: 'Ãconomie', icon: 'ð°', sub: 'macro, marché, fiscalité', sources: 'World Bank · INSEE · OCDE · taux de change', trust: 4 }, 47 { d: 'Histoire & Culture',icon: 'ðï¸',sub: 'histoire, arts, patrimoine', sources: 'Wikipedia · Gallica (BnF) · Europeana', trust: 4 }, 48 { d: 'Géographie', icon: 'ð', sub: 'pays, villes, cartes', sources: 'OpenStreetMap · Wikidata · GeoNames', trust: 4 }, 49 { d: 'Livres & Littérature',icon:'ð',sub: 'Åuvres, citations', sources: 'Project Gutenberg · Open Library', trust: 4 }, 50 { d: 'Technologie & Code',icon: 'ð»',sub: 'langages, frameworks, API', sources: 'MDN · docs officielles · Wikipedia', trust: 4 }, 51 { d: 'Astronomie & Espace',icon:'ðª',sub: 'planètes, missions', sources: 'NASA APIs · Wikipedia', trust: 5 }, 52 { d: 'Environnement', icon: 'ð±', sub: 'climat, biodiversité, énergie', sources: 'GIEC · Our World in Data', trust: 5 }, 53 { d: 'Foi & Bible', icon: 'âï¸', sub: 'Ãcritures, thèmes, versets', sources: 'Bible LSG (domaine public) · /api/bible', trust: 5 }, 54 { d: 'Actualités', icon: 'ð°', sub: 'événements récents', sources: 'recherche web (toujours daté & vérifié)', trust: 2 } 55 ] 56 57 // Retourne l'indice de confiance (1-5) pour une source nommée (correspondance partielle) 58 function trustFor(sourceName) { 59 if (!sourceName) return 2 60 var q = String(sourceName).toLowerCase() 61 var all = TOOLS.concat(RES) 62 for (var i = 0; i < all.length; i++) { 63 var item = all[i] 64 if ((item.src || item.sources || '').toLowerCase().indexOf(q) >= 0 || 65 (item.name || item.d || '').toLowerCase().indexOf(q) >= 0) { 66 return item.trust || 3 67 } 68 } 69 // Heuristiques rapides
70 if (/pubmed|medline|oms|legifrance|service-public|nasa|giec|insee|eur-lex/i.test(q)) return 5 71 if (/wikipedia|wikidata|arxiv|openstreetmap|europeana/i.test(q)) return 4 72 if (/world.bank|ocde|open.meteo|gutenberg/i.test(q)) return 3 73 if (/gdelt|rss|twitter|flux|web/i.test(q)) return 2 74 return 3 75 } 76 77 function domainsFor(q) { 78 q = lc(q) 79 var map = { 80 science: 'Science', physique: 'Science', chimie: 'Science', biologie: 'Science', recherche: 'Science', étude: 'Science', photosynth: 'Science', cellule: 'Science', neuro: 'Science', 81 math: 'Mathématiques', équation: 'Mathématiques', calcul: 'Mathématiques', algèbre: 'Mathématiques', statistique: 'Mathématiques', 82 santé: 'Santé', maladie: 'Santé', symptôme: 'Santé', médic: 'Santé', nutrition: 'Santé', sommeil: 'Santé', vitamine: 'Santé', 83 droit: 'Droit', loi: 'Droit', contrat: 'Droit', rgpd: 'Droit', juridique: 'Droit', démarche: 'Droit', 84 économie: 'Ãconomie', argent: 'Ãconomie', fiscal: 'Ãconomie', impôt: 'Ãconomie', bourse: 'Ãconomie', inflation: 'Ãconomie', taux: 'Ãconomie', change: 'Ãconomie', 85 histoire: 'Histoire & Culture', guerre: 'Histoire & Culture', art: 'Histoire & Culture', musique: 'Histoire & Culture', peinture: 'Histoire & Culture', 86 pays: 'Géographie', ville: 'Géographie', capitale: 'Géographie', population: 'Géographie', carte: 'Géographie', 87 livre: 'Livres & Littérature', roman: 'Livres & Littérature', auteur: 'Livres & Littérature', citation: 'Livres & Littérature', poème: 'Livres & Littérature', 88 code: 'Technologie & Code', python: 'Technologie & Code', javascript: 'Technologie & Code', api: 'Technologie & Code', serveur: 'Technologie & Code', 89 planète: 'Astronomie & Espace', espace: 'Astronomie & Espace', étoile: 'Astronomie & Espace', nasa: 'Astronomie & Espace', galaxie: 'Astronomie & Espace', 90 climat: 'Environnement', co2: 'Environnement', énergie: 'Environnement', biodiversité: 'Environnement', réchauffement: 'Environnement', 91 bible: 'Foi & Bible', dieu: 'Foi & Bible', jésus: 'Foi & Bible', verset: 'Foi & Bible', prière: 'Foi & Bible', 92 actualité: 'Actualités', news: 'Actualités', récent: 'Actualités', aujourd: 'Actualités' 93 } 94 /* ââ UN MOT, PAS UNE SUITE DE LETTRES ââââââââââââââââââââââââââââââââ 95 * 96 * `q.indexOf(k) >= 0` attrapait le mot-clé PARTOUT, y compris au milieu 97 * d'un autre mot. Mesuré sur dix demandes ordinaires de CRÃA : NEUF 98 * réveillaient un domaine qu'elles ne concernent pas. 99 * 100 * « quelle est la cAPItale du Pérou » â Technologie & Code 101 * « fais un résumé rAPIde » â Technologie & Code 102 * « écris le chAPItre 3 » â Technologie & Code 103 * « déCODE ce message » â Technologie & Code 104 * « relis le PAYSage concurrentiel » â Géographie 105 * « calCULe le coût » â Mathématiques 106 * 107 * Le bloc a l'air conditionnel et partait sur presque tout : cinq cents 108 * caractères de sources hors sujet, à chaque message. C'est exactement le 109 * bloc que la règle du terrain interdit, déguisé en bloc jugé. 110 * 111 * `\b` NE MARCHE PAS ICI : les bornes de mot de JavaScript sont ASCII, et 112 * `é`, `è`, `ô` n'en sont pas. On borne donc sur « pas une lettre et pas un 113 * chiffre », en Unicode (`\p{L}`, drapeau `u`) â la même forme que les 114 * terrains de `crea-access.js`. 115 * 116 * ET LA BORNE DE DROITE TOLÃRE UNE LETTRE, pas trois : « cartes » et 117 * « calcule » doivent mordre, « paysage » ne doit pas. Trois lettres 118 * ramèneraient « paysage ». 119 * 120 * CINQ CLÃS SONT DES RACINES, PAS DES MOTS â `photosynth`, `médic`, 121 * `neuro`, `fiscal`, `aujourd`. Elles sont écrites pour attraper 122 * « photosynthèse », « médicament », « aujourd'hui » : leur imposer une 123 * borne à droite les rendrait muettes. Elles sont nommées ici, pas 124 * devinées, parce qu'une racine et un mot ne se distinguent pas à l'Åil. */ 125 var RACINES = { photosynth: 1, 'médic': 1, neuro: 1, fiscal: 1, aujourd: 1 } 126 var hit = {}
127 Object.keys(map).forEach(function (k) { 128 var m = k.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') 129 var motif = '(?:^|[^\\p{L}\\p{N}])' + m + (RACINES[k] ? '' : '(?:[se])?(?![\\p{L}\\p{N}])') 130 try { if (new RegExp(motif, 'iu').test(q)) hit[map[k]] = 1 } 131 catch (e) { if (q.indexOf(k) >= 0) hit[map[k]] = 1 /* moteur sans \p{L} : l'ancien comportement plutôt qu'un domaine perdu */ } 132 }) 133 return Object.keys(hit) 134 } 135 136 /* ââ LA DEMANDE ARRIVE EN ARGUMENT âââââââââââââââââââââââââââââââââââââââ 137 * 138 * Ce poste allait CHERCHER lui-même le dernier message du fil de chat. C'est 139 * le défaut que le dépôt a déjà payé sur la gorge, et qui est écrit dans 140 * CLAUDE.md : « dans le chat, la même phrase, invisible ; dans les douze 141 * studios, la mauvaise ». Mesuré ici, avec un fil qui parle du Pérou pendant 142 * qu'un studio demande un script Python : le bloc rendait les sources de la 143 * GÃOGRAPHIE. 144 * 145 * Viser la mauvaise phrase ne décale pas un bloc jugé : ça le fait mentir. 146 * La demande vient donc de l'appelant â la gorge la lui passe, comme à tous 147 * les autres postes. Une chaîne vide veut dire « pas de demande » : le bloc 148 * se tait, il n'hérite de rien. */ 149 function contextBlock(demande) { 150 var q = String(demande == null ? '' : demande) 151 var doms = domainsFor(q); if (!doms.length) return '' 152 var lines = doms.map(function (d) { var r = RES.find(function (x) { return x.d === d }); return r ? ('⢠' + r.d + ' [confiance ' + (r.trust||3) + '/5] â ' + r.sources) : null }).filter(Boolean) 153 if (!lines.length) return '' 154 return '=== SOURCES FIABLES PAR DOMAINE (puise ici, vérifie, CITE â n\'invente pas) ===\n' + lines.join('\n') + 155 '\nLégende confiance : 5=institution officielle · 4=encyclopédie curée · 3=agrégateur · 2=flux live · 1=non vérifié' + 156 '\nUtilise la recherche web pour atteindre ces sources, donne des faits datés, et termine par Sources · Limites quand c\'est important.\n\n' 157 } 158 159 /* ---- outil live câblé : taux de change (sans clé) ---- */ 160 function rate(from, to) { 161 return fetch('https://open.er-api.com/v6/latest/' + encodeURIComponent((from || 'EUR').toUpperCase())) 162 .then(function (r) { return r.ok ? r.json() : null }) 163 .then(function (j) { return (j && j.rates && j.rates[(to || 'USD').toUpperCase()]) || null }) 164 .catch(function () { return null }) 165 } 166 167 function open() { 168 var old = document.getElementById('crea-sources'); if (old) { old.remove(); return } 169 var ov = document.createElement('div'); ov.id = 'crea-sources' 170 var tools = TOOLS.map(function (t) { return '<div class="cs4-row"><span class="cs4-ic">' + t.icon + '</span><div class="cs4-tx"><b>' + esc(t.name) + '</b><span>' + esc(t.d) + ' · ' + esc(t.src) + '</span></div>' + (t.live ? '<span class="cs4-live">â live</span>' : '<span class="cs4-soon">via web</span>') + '</div>' }).join('') 171 var res = RES.map(function (r) { return '<div class="cs4-row"><span class="cs4-ic">' + r.icon + '</span><div class="cs4-tx"><b>' + esc(r.d) + '</b><span>' + esc(r.sub) + ' â ' + esc(r.sources) + '</span></div></div>' }).join('') 172 ov.innerHTML = '<div class="cs4-box"><div class="cs4-head"><span>ð§ Outils & ressources du réel (tout domaine)</span><button class="cs4-x" data-close>â</button></div>' + 173 '<div class="cs4-note">Créa s\'appuie sur ces sources réelles selon le domaine de ta question, au lieu d\'inventer â et il les cite.</div>' + 174 '<div class="cs4-t">ð§ Outils live</div><div class="cs4-list">' + tools + '</div>' + 175 '<div class="cs4-t">ð Ressources de savoir par domaine</div><div class="cs4-list">' + res + '</div></div>' 176 document.body.appendChild(ov) 177 ov.addEventListener('mousedown', function (e) { if (e.target === ov) ov.remove() }) 178 ov.addEventListener('click', function (e) { if (e.target.closest('[data-close]')) ov.remove() }) 179 document.addEventListener('keydown', function onEsc(e) { if (e.key === 'Escape') { ov.remove(); document.removeEventListener('keydown', onEsc) } }) 180 } 181 182 function css() { 183 if (document.getElementById('crea-sources-css')) return 184 var s = document.createElement('style'); s.id = 'crea-sources-css' 185 s.textContent = 186 '#crea-sources{position:fixed;inset:0;z-index:90020;background:rgba(0,0,0,.5);backdrop-filter:blur(3px);display:flex;align-items:center;justify-content:center;padding:16px}' + 187 '#crea-sources .cs4-box{width:min(620px,96vw);max-height:88vh;overflow-y:auto;background:var(--bg-secondary,#161616);border:1px solid var(--border,#333);border-radius:18px;box-shadow:0 24px 70px rgba(0,0,0,.5)}' + 188 '#crea-sources .cs4-head{display:flex;align-items:center;padding:15px 18px;border-bottom:1px solid var(--border,#333);position:sticky;top:0;background:var(--bg-secondary,#161616)}' + 189 '#crea-sources .cs4-head span{flex:1;color:var(--t-primary,#eee);font:700 14px Inter,system-ui,sans-serif}' + 190 '#crea-sources .cs4-x{background:none;border:0;color:var(--t-faint,#999);font-size:16px;cursor:pointer}' + 191 '#crea-sources .cs4-note{padding:12px 18px;color:var(--t-secondary,#bbb);font:500 12px/1.5 Inter;border-bottom:1px solid var(--border,#2a2a2a)}' + 192 '#crea-sources .cs4-t{color:var(--t-faint,#888);font:600 10px Inter;text-transform:uppercase;letter-spacing:.05em;padding:13px 18px 4px}' + 193 '#crea-sources .cs4-list{padding:0 12px 6px}' + 194 '#crea-sources .cs4-row{display:flex;align-items:center;gap:10px;padding:8px 8px;border-radius:10px}' + 195 '#crea-sources .cs4-row:hover{background:var(--bg-hover,rgba(255,255,255,.03))}' + 196 '#crea-sources .cs4-ic{font-size:16px;width:22px;text-align:center}' + 197 '#crea-sources .cs4-tx{flex:1;min-width:0}#crea-sources .cs4-tx b{display:block;color:var(--t-primary,#eee);font:600 12.5px Inter}#crea-sources .cs4-tx span{color:var(--t-faint,#888);font:500 11px Inter}' + 198 '#crea-sources .cs4-live{color:#10a37f;font:700 10px Inter;flex:0 0 auto}#crea-sources .cs4-soon{color:var(--t-faint,#888);font:600 10px Inter;flex:0 0 auto}' + 199 '#crea-sources .cs4-trust{font:600 9px Inter;flex:0 0 auto;opacity:.75;letter-spacing:.03em}' 200 document.head.appendChild(s) 201 } 202 if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', css); else css() 203 204 // Update panel render to show trust scores 205 var _origOpen = open 206 open = function () { 207 var old = document.getElementById('crea-sources'); if (old) { old.remove(); return } 208 css() 209 var ov = document.createElement('div'); ov.id = 'crea-sources' 210 function trustBadge(t) { 211 var stars = ['', 'â ', 'â â ', 'â â â ', 'â â â â ', 'â â â â â '][t || 3] || 'â â â ' 212 var color = ['', '#dc2626', '#d97706', '#2563eb', '#059669', '#10a37f'][t || 3] || '#2563eb' 213 return '<span class="cs4-trust" style="color:' + color + '">' + stars + '</span>' 214 } 215 var tools = TOOLS.map(function (t) { return '<div class="cs4-row"><span class="cs4-ic">' + t.icon + '</span><div class="cs4-tx"><b>' + esc(t.name) + '</b><span>' + esc(t.d) + ' · ' + esc(t.src) + '</span></div>' + trustBadge(t.trust) + (t.live ? '<span class="cs4-live">â live</span>' : '<span class="cs4-soon">via web</span>') + '</div>' }).join('') 216 var res = RES.map(function (r) { return '<div class="cs4-row"><span class="cs4-ic">' + r.icon + '</span><div class="cs4-tx"><b>' + esc(r.d) + '</b><span>' + esc(r.sub) + ' â ' + esc(r.sources) + '</span></div>' + trustBadge(r.trust) + '</div>' }).join('') 217 ov.innerHTML = '<div class="cs4-box"><div class="cs4-head"><span>ð§ Outils & ressources du réel (tout domaine)</span>
217<button class="cs4-x" data-close>â</button></div>' + 218 '<div class="cs4-note">Créa s\'appuie sur ces sources selon le domaine, les cite, et indique leur indice de confiance (â à â â â â â ).</div>' + 219 '<div class="cs4-t">ð§ Outils live</div><div class="cs4-list">' + tools + '</div>' + 220 '<div class="cs4-t">ð Ressources de savoir par domaine</div><div class="cs4-list">' + res + '</div></div>' 221 document.body.appendChild(ov) 222 ov.addEventListener('mousedown', function (e) { if (e.target === ov) ov.remove() }) 223 ov.addEventListener('click', function (e) { if (e.target.closest('[data-close]')) ov.remove() }) 224 document.addEventListener('keydown', function onEsc(e) { if (e.key === 'Escape') { ov.remove(); document.removeEventListener('keydown', onEsc) } }) 225 } 226 227 window.CREA_SOURCES = { TOOLS: TOOLS, RES: RES, domainsFor: domainsFor, contextBlock: contextBlock, rate: rate, open: open, trustFor: trustFor, TRUST_LABELS: TRUST_LABELS } 228})()
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.