{% extends "clairvia/base.html" %} {% block page %}results{% endblock %} {% block meta %}{% endblock %} {#- Ce que la page dit d'elle-meme, a l'oreille (RGAA 8.6, 7.5) : nombre de resultats et moteurs muets, dans le titre (lu en premier, meme sans script) et dans l'annonce du lecteur d'ecran (clairvia.js). #} {%- set a11y_state = (t('partial_title') if results else t('down_title')) if engines_down else '' %} {%- set a11y_engines = [] %} {%- for e in engines_down %}{% set _ = a11y_engines.append(e.name|title ~ ', ' ~ t('reason_' ~ e.reason) ~ (', ' ~ t('suspended') if e.suspended else '')) %}{% endfor %} {%- set a11y_count = t('a11y_count', n=results|length) if results else t('no_results') %} {% block title %}{{ q }} - {{ a11y_count }}{% if a11y_state %} - {{ a11y_state }}{% endif %} - Clairvia{% endblock %} {% block header %}
{{ ic.mark(28) }}Clairvia {% include "clairvia/_search.html" %}
{%- if time_ranges %} {%- endif %} {%- if lenses %} {%- endif %} {%- if image_filter_groups %} {#- Filtres d'images (clairvia.imagefilter) : appliques par Clairvia aux images recues, rien ne part vers un moteur. Une puce active retire son filtre ; sans script. #} {%- endif %}
{% endblock %} {% block main %}

{{ t('results_title') }}

{#- Annonce a l'arrivee (clairvia.js la pose ici, une fois) : une region vivante presente au chargement n'est pas lue ; un moteur en echec doit etre ENTENDU, pas seulement affiche. Tout echoue : annonce immediate. #} {%- if engines_down %}
{{ ic.icon('alert') }}

{{ t('partial_title') if results else t('down_title') }}

{{ t('partial_d') if results else t('down_d') }}

    {%- for e in engines_down %}
  • {{ e.name|title }} {{ t('reason_' ~ e.reason) }}{% if e.suspended %} · {{ t('suspended') }}{% endif %}
  • {%- endfor %}
{%- endif %} {%- if bang_relay %}

{{ ic.icon('shield') }}{{ t('bang_relayed', bang='!!' ~ bang_relay.bang, engine=bang_relay.engine|title) }}

{%- endif %} {%- if summarize_url %}

{{ ic.icon('summary') }}{{ t('sm_go') }} · {{ summarize_url|truncate(80, True) }}

{%- endif %} {%- if corrections %}

{{ t('did_you_mean') }} {%- for c in corrections %} {{ c }}{% endfor %}

{%- endif %} {%- if translation %} {%- set tq = translation.query %}{% set tr = translation.results %}
{{ ic.icon('languages') }}

{{ t('tr_searched', lang=target_name) }}

{{ t('tr_by') }}

{{ tq.searched }}

{%- if tq.status in ('untranslated', 'unavailable') %}

{{ ic.icon('info') }}{{ t('tr_q_' ~ tq.status) }}

{%- endif %} {%- if tr.status in ('partial', 'rejected', 'unavailable') %}

{{ ic.icon('info') }}{{ t('tr_r_' ~ tr.status) }}

{%- endif %}
{%- endif %} {%- macro answer_body(turn, prefix, key='ans_') %} {%- if turn.status == 'ok' %}
{%- for claim in turn.claims %} {%- if claim.heading %}

{{ claim.text }}

{% else %}

{{ claim.text }}{% for c in claim.citations %}{{ c }}{% endfor %}

{%- endif %} {%- endfor %}
{%- else %}

{{ ic.icon('info') }}{{ t(key ~ turn.status) }}

{%- endif %} {%- endmacro %} {%- macro source_list(turn, prefix) %}
    {%- for s in turn.sources %}
  1. {{ s.id }}{{ s.title }}{{ s.host }} {%- if s.step %}{{ t('rs_found_by', n=s.step) }}{% endif %}
  2. {%- endfor %}
{%- endmacro %} {%- if synthesis %} {%- set conv = conversation %} {%- if conv and conv.history %} {#- Conversation de suivi (clairvia.followup) : les tours precedents, portes par la page seule. #}
    {%- for turn in conv.history %}
  1. {{ ic.icon('chat') }}{{ turn.question }}

    {{ answer_body(turn, 'source-t' ~ turn.n ~ '-') }} {%- if turn.sources and turn.status == 'ok' %}
    {{ t('ans_sources') }} · {{ turn.sources|length }} {{ source_list(turn, 'source-t' ~ turn.n ~ '-') }}
    {%- endif %}
  2. {%- endfor %}
{%- endif %}
{{ ic.icon('quote') }}

{{ t('ans_title') }}

{% if synthesis.status == 'ok' %}{{ ic.icon('check') }}{{ t('ans_by') }}{% endif %}
{%- if conv and conv.status in ('invalid', 'expired', 'full') %}

{{ ic.icon('info') }}{{ t('fu_' ~ conv.status, max=conv.max_turns) }}

{%- endif %} {%- if conv and conv.history %}

{{ ic.icon('chat') }}{{ conv.question }}

{%- if conv.query_status in ('rewritten', 'combined') %}

{{ ic.icon('search') }}{{ t('fu_searched') }} {{ conv.searched }} · {{ t('fu_q_' ~ conv.query_status) }}

{%- endif %} {%- endif %} {{ answer_body(synthesis, 'source-') }} {%- if synthesis.sources and synthesis.status == 'ok' %}

{{ t('ans_sources') }}

{{ source_list(synthesis, 'source-') }} {%- endif %} {%- if conv and conv.thread %} {#- Question suivante : POST (le jeton porte la conversation, jamais dans une adresse), sans script. #}
{%- for name in ('language', 'safesearch', 'lens', 'rank') %}{% if page_args.get(name) %} {% endif %}{% endfor %}

{{ ic.icon('lock') }}{{ t('fu_note', n=conv.turn, max=conv.max_turns) }}

{%- elif conv and conv.turn >= conv.max_turns %}

{{ ic.icon('info') }}{{ t('fu_last', max=conv.max_turns) }}

{%- endif %}
{%- endif %} {%- if research %} {#- Recherche approfondie (clairvia.research) : les recherches faites et leur cout, le rapport verifie. #} {%- set rs = research %}
{{ ic.icon('layers') }}

{{ t('rs_title') }}

{% if rs.status == 'ok' %}{{ ic.icon('check') }}{{ t('rs_by') }}{% endif %}
{{ ic.icon('search') }}{{ t('rs_steps', n=rs.steps|length) }}{{ ic.icon('chevron-down', 'rs-chevron') }}
    {%- for step in rs.steps %}
  1. {{ loop.index }}{{ step.query }}{{ t('rs_origin_' ~ step.origin) }} · {% if step.status == 'ok' %}{{ t('rs_results', n=step.results) }}{% else %}{{ t('rs_step_' ~ step.status) }}{% endif %}
  2. {%- endfor %}

{{ ic.icon('shield') }}{{ t('rs_cost', searches=rs.budget.searches, upstream=rs.budget.upstream) }}

{%- if rs.plan.status in ('refused', 'unavailable') %}

{{ ic.icon('info') }}{{ t('rs_plan_' ~ rs.plan.status) }}

{%- elif rs.plan.refused %}

{{ ic.icon('shield') }}{{ t('rs_plan_guarded', n=rs.plan.refused) }}

{%- endif %} {%- if rs.budget.status in ('instance', 'throttled', 'cap') %}

{{ ic.icon('clock') }}{{ t('rs_budget_' ~ rs.budget.status, max=rs.budget.max_searches) }}

{%- endif %} {%- if rs.budget.spared and rs.budget.searches > 1 %}

{{ ic.icon('shield') }}{{ t('rs_spared', engines=rs.budget.spared|map('title')|join(', ')) }}

{%- endif %} {{ answer_body(rs, 'rsource-', 'rs_') }} {%- if rs.sources %}

{{ t('ans_sources') }}

{{ source_list(rs, 'rsource-') }} {%- endif %}

{{ ic.icon('lock') }}{{ t('rs_note') }}

{%- endif %} {%- if rank_error %}

{{ ic.icon('alert') }}{{ t('rank_error') }}

{%- endif %} {%- if rank_off %} {%- set args = dict(page_args) %}{% set _ = args.pop('rank') %}

{{ ic.icon('info') }}{{ t('rank_off') }} {{ t('rank_on') }}

{%- endif %} {%- if rank_blocked_n %}

{{ ic.icon('ban') }}{{ t('rank_blocked', n=rank_blocked_n, sites=rank_blocked|map('first')|join(', ')) }} {{ t('rank_show_all') }} · {{ t('rank_manage') }}

{%- endif %} {%- if lens_id %} {%- set args = dict(page_args) %}{% set _ = args.pop('lens') %}{% set _ = args.pop('pageno', None) %}

{{ ic.icon('lens') }}{{ t('rank_lens_on', lens=t('lens_' ~ lens_id), n=rank_lensed) }} {{ t('rank_lens_off') }}

{%- endif %} {%- if image_outcome %} {%- set args = dict(page_args) %}{% set _ = args.pop('pageno', None) %}{% for f in image_fields %}{% set _ = args.pop(f, None) %}{% endfor %} {%- if image_outcome.error %}

{{ ic.icon('alert') }}{{ t('img_filter_error') }} {{ t('img_filter_off') }}

{%- else %} {%- set labels = [] %}{% for group, field in (('size', 'image_size'), ('layout', 'image_layout'), ('format', 'image_format'), ('license', 'image_license')) %}{% if image_filter.get(field) %}{% set _ = labels.append(image_label(group, image_filter[field])) %}{% endif %}{% endfor %}

{{ ic.icon('image') }}{{ t('img_filter_on', filters=labels|join(', '), n=image_outcome.removed) }} {%- if image_outcome.unknown > image_outcome.unknown_license %} {{ t('img_filter_unknown', n=image_outcome.unknown - image_outcome.unknown_license) }}{% endif %} {%- if image_outcome.unknown_license %} {{ t('img_filter_unlicensed', n=image_outcome.unknown_license) }}{% endif %} {{ t('img_filter_local') }} {{ t('img_filter_off') }}

{%- endif %} {%- endif %} {%- if ops_outcome %} {#- Operateurs de la requete (clairvia.operators) tenus sur les resultats de tous les moteurs, apres la fusion. #} {%- set args = dict(page_args, ops='off') %}{% set _ = args.pop('pageno', None) %} {%- if ops_outcome.error %}

{{ ic.icon('alert') }}{{ t('ops_error') }}

{%- else %}

{{ ic.icon('target') }}{{ t('ops_on', ops=ops_written|join(' '), n=ops_outcome.removed, engines=ops_engines|map('title')|join(', ')) }} {%- if ops_outcome.unknown_type %} {{ t('ops_unknown', n=ops_outcome.unknown_type) }}{% endif %} {{ t('ops_show') }}

{%- endif %} {%- elif ops_off %} {%- set args = dict(page_args) %}{% set _ = args.pop('ops', None) %}{% set _ = args.pop('pageno', None) %}

{{ ic.icon('target') }}{{ t('ops_unchecked') }} {{ t('ops_check') }}

{%- endif %} {%- if time_skipped %}

{{ ic.icon('clock') }}{{ t('time_skipped', engines=time_skipped|map('title')|join(', ')) }}

{%- endif %} {%- if maps %}

{{ ic.icon('shield') }}{{ t('map_private') }}

{%- elif players %}

{{ ic.icon('shield') }}{{ t('player_private') }}

{%- endif %} {%- for a in answers %} {%- if a.kind == 'weather' %}
{{ ic.icon(a.icon) }}

{{ a.label }}

{%- if a.message %}

{{ a.message }}

{%- else %} {%- if a.question %}

{{ a.question }}

{% endif %}
{{ ic.icon(a.icon, 'wx-glyph') }}

{{ a.value }}

{{ a.sky }}

{% for d in a.details %}{{ d }}{% endfor %}{% if a.wind %}{% if a.wind_to %}{{ ic.icon('arrow', 'wind-' ~ a.wind_to) }}{% endif %}{{ a.wind }}{% endif %}

{%- if a.hours %}

{{ t('wx_hours') }}

    {%- for h in a.hours %}
  1. {{ h.time }}{{ ic.icon(h.icon) }}{{ h.sky }}{{ h.temp }}
  2. {%- endfor %}
{%- endif %} {%- if a.days %}

{{ t('wx_days') }}

    {%- for d in a.days %}
  • {{ d.name }}{{ ic.icon(d.icon) }}{{ d.sky }}{{ d.high }}{{ d.low }}
  • {%- endfor %}
{%- endif %} {%- endif %}

{{ ic.icon('shield') }}{{ a.note }}

{%- else %}
{{ ic.icon(a.icon) }}

{{ a.label }}

{%- if a.question %}

{{ a.question }}

{% endif %} {#- 🔴 LA TAILLE DEPEND DE LA LONGUEUR, et c'est tout l'objet de cette classe. `instant-value` est calibre pour une reponse COURTE -- un calcul, une temperature, un taux : on la lit d'un coup d'oeil, et le grand corps est son interet. Applique a un paragraphe encyclopedique, il devient un mur qui ecrase les resultats en dessous (porteur, 2026-09-28 : << c'est peut etre ecrit un peu gros >>). ⭐ Le seuil separe une REPONSE d'une PROSE : au-dela de deux lignes, ce n'est plus un chiffre qu'on saisit, c'est un texte qu'on lit. -#}

{{ a.value }}

{%- if a.details %}

{% for d in a.details %}{{ d }}{% endfor %}

{% endif %} {%- if a.note %}

{{ ic.icon('shield') }}{{ a.note }}

{% endif %}
{%- endif %} {%- endfor %} {%- if results %}

{{ a11y_count }}

{% endif %}
{%- for r in results %} {%- if r.kind == 'image' %} {%- else %}
{{ r.host }}{% for p in r.path %}/{{ p }}{% endfor %}

{{ r.title }}

{%- if r.package %}

{{ r.package }}

{% endif %} {%- if r.published or r.author or r.length or r.views or r.source or r.badges %}

{%- if r.source %}{{ r.source }}{% endif %} {%- if r.published %}{{ ic.icon('clock') }}{{ r.published }}{% endif %} {%- if r.author %}{{ ic.icon('user') }}{{ r.author }}{% endif %} {%- if r.length %}{{ ic.icon('play') }}{{ r.length }}{% endif %} {%- if r.views %}{{ t('views', n=r.views) }}{% endif %} {%- for b in r.badges %}{{ b }}{% endfor %}

{%- endif %} {%- if r.content %}

{{ r.content }}

{% endif %} {%- if r.code %}
{% for n, line in r.code %}{{ n }}{{ line }}
{% endfor %}
{%- endif %} {%- if r.facts %}
{%- for label, value in r.facts %}
{{ label }}
{{ value }}
{%- endfor %}
{%- endif %} {%- if r.actions %}

{%- for a in r.actions %} {{ ic.icon(a.icon) }}{{ a.label }} {%- endfor %}

{%- endif %} {%- if r.translation %}
{{ t('tr_original') }}

{{ r.translation.title }}

{%- if r.translation.content %}

{{ r.translation.content }}

{% endif %}
{%- endif %}
{%- if r.official %}{{ ic.icon('seal') }}{{ t('official') }} · {{ t('official_' ~ r.official) }}{% endif %} {%- if r.rule and rank_applied %}{{ ic.icon(rank_icons[r.rule]) }}{{ t('rank_rule_' ~ r.rule) }}{% endif %}

{{ t('via') }}{% for e in r.engines %}{{ e }}{% endfor %}

{%- if r.summarize %} {{ ic.icon('summary') }}{{ t('sm_go') }} · {{ r.host }} {%- endif %} {%- if r.site and not rank_off %} {%- endif %}
{%- if r.thumbnail %} {%- endif %}
{%- endif %} {%- endfor %}
{%- if not results and ops_outcome and ops_outcome.removed %}
{{ ic.icon('target') }}

{{ t('ops_empty') }}

{{ t('ops_empty_d', n=ops_outcome.removed) }}

{%- elif not results and image_outcome and image_outcome.removed %}
{{ ic.icon('image') }}

{{ t('img_filter_empty') }}

{{ t('img_filter_empty_d', n=image_outcome.removed) }}

{%- elif not results %}
{{ ic.icon('search') }}

{{ t('no_results') }}

{{ t('no_results_d') }}

{%- endif %} {%- if paging and (results or (image_outcome and image_outcome.removed) or (ops_outcome and ops_outcome.removed)) %} {%- endif %} {%- if suggestions %} {%- endif %}
{%- if infoboxes %} {%- endif %}
{% endblock %}