@webmcp-auto-ui/agent 2.5.8 → 2.5.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/package.json +1 -1
  2. package/src/autoui-server.ts +134 -134
  3. package/src/diagnostics.ts +3 -3
  4. package/src/loop.ts +6 -6
  5. package/src/providers/wasm.ts +5 -5
  6. package/src/recipes/_generated.ts +446 -446
  7. package/src/recipes/afficher-oeuvres-art-collection-musee.md +45 -45
  8. package/src/recipes/analyser-actualites-hacker-news.md +52 -52
  9. package/src/recipes/cartographier-observations-biodiversite.md +44 -44
  10. package/src/recipes/cross-server.md +48 -48
  11. package/src/recipes/dashboard-kpi.md +45 -45
  12. package/src/recipes/explorer-dossiers-legislatifs-parcours-texte.md +48 -48
  13. package/src/recipes/gallery-images.md +33 -33
  14. package/src/recipes/parlementaire-profile.md +58 -58
  15. package/src/recipes/rechercher-textes-juridiques-legifrance.md +38 -38
  16. package/src/recipes/weather-viz.md +35 -35
  17. package/src/recipes/widgets/actions.md +6 -6
  18. package/src/recipes/widgets/alert.md +6 -6
  19. package/src/recipes/widgets/cards.md +10 -10
  20. package/src/recipes/widgets/carousel.md +8 -8
  21. package/src/recipes/widgets/chart-rich.md +10 -10
  22. package/src/recipes/widgets/chart.md +9 -9
  23. package/src/recipes/widgets/code.md +6 -6
  24. package/src/recipes/widgets/d3.md +10 -10
  25. package/src/recipes/widgets/data-table.md +10 -10
  26. package/src/recipes/widgets/gallery.md +10 -10
  27. package/src/recipes/widgets/grid-data.md +11 -11
  28. package/src/recipes/widgets/hemicycle.md +9 -9
  29. package/src/recipes/widgets/js-sandbox.md +10 -10
  30. package/src/recipes/widgets/json-viewer.md +8 -8
  31. package/src/recipes/widgets/kv.md +9 -9
  32. package/src/recipes/widgets/list.md +7 -7
  33. package/src/recipes/widgets/log.md +6 -6
  34. package/src/recipes/widgets/map.md +10 -10
  35. package/src/recipes/widgets/profile.md +9 -9
  36. package/src/recipes/widgets/recipe-browser.md +33 -33
  37. package/src/recipes/widgets/sankey.md +10 -10
  38. package/src/recipes/widgets/stat-card.md +7 -7
  39. package/src/recipes/widgets/stat.md +10 -10
  40. package/src/recipes/widgets/tags.md +6 -6
  41. package/src/recipes/widgets/text.md +6 -6
  42. package/src/recipes/widgets/timeline.md +6 -6
  43. package/src/recipes/widgets/trombinoscope.md +8 -8
  44. package/src/summarize.ts +6 -6
  45. package/src/tool-layers.ts +26 -26
@@ -1,48 +1,48 @@
1
1
  ---
2
2
  id: afficher-oeuvres-art-collection-musee
3
- name: Afficher les oeuvres d'art d'une collection de musee en galerie visuelle
3
+ name: Display artworks from a museum collection in a visual gallery
4
4
  components_used: [gallery, cards, kv, stat-card]
5
- when: l'utilisateur demande des oeuvres d'art, des collections de musee, des tableaux, sculptures ou objets d'art du Metropolitan Museum of Art
5
+ when: the user asks for artworks, museum collections, paintings, sculptures, or art objects from the Metropolitan Museum of Art
6
6
  servers: [metmuseum]
7
7
  layout:
8
8
  type: grid
9
9
  columns: 2
10
- arrangement: stats en haut, galerie pleine largeur au centre, details en bas
10
+ arrangement: stats at top, full-width gallery in the center, details at the bottom
11
11
  ---
12
12
 
13
- ## Quand utiliser
13
+ ## When to use
14
14
 
15
- L'utilisateur s'interesse a des oeuvres d'art ou des collections de musee :
16
- - "Montre-moi des tableaux impressionnistes du Met Museum"
17
- - "Les sculptures grecques du Metropolitan"
18
- - "Quelles oeuvres de Van Gogh sont au Met ?"
19
- - "Les oeuvres d'art egyptien du musee"
20
- - "Cherche des estampes japonaises"
15
+ The user is interested in artworks or museum collections:
16
+ - "Show me Impressionist paintings from the Met Museum"
17
+ - "Greek sculptures at the Metropolitan"
18
+ - "What Van Gogh works are at the Met?"
19
+ - "Egyptian art objects from the museum"
20
+ - "Search for Japanese woodblock prints"
21
21
 
22
- Le serveur Met Museum donne acces a la collection du Metropolitan Museum of Art de New York (plus de 470 000 oeuvres, dont beaucoup avec images en domaine public).
22
+ The Met Museum server provides access to the Metropolitan Museum of Art collection in New York (more than 470,000 objects, many with public domain images).
23
23
 
24
- ## Comment
24
+ ## How to use
25
25
 
26
- 1. **Rechercher les oeuvres** par theme, artiste ou departement :
26
+ 1. **Search for artworks** by theme, artist, or department:
27
27
  ```
28
28
  search_objects({query: "impressionism sunflower", hasImages: true})
29
29
  ```
30
- Retourne une liste d'`objectID`s.
30
+ Returns a list of `objectID`s.
31
31
 
32
- 2. **Recuperer les details** de chaque oeuvre (limiter a 5-10 pour la performance) :
32
+ 2. **Fetch the details** of each artwork (limit to 5-10 for performance):
33
33
  ```
34
34
  get_object({objectID: 436524})
35
35
  ```
36
- Retourne : `title`, `artistDisplayName`, `primaryImage`, `objectDate`, `medium`, `department`, `culture`, etc.
36
+ Returns: `title`, `artistDisplayName`, `primaryImage`, `objectDate`, `medium`, `department`, `culture`, etc.
37
37
 
38
- 3. **Afficher les statistiques** de la recherche :
38
+ 3. **Display search statistics**:
39
39
  ```
40
- component("stat-card", {label: "Resultats", value: total, icon: "image"})
41
- component("stat-card", {label: "Avec image", value: withImage, icon: "camera"})
42
- component("stat-card", {label: "Domaine public", value: publicDomain, icon: "unlock"})
40
+ component("stat-card", {label: "Results", value: total, icon: "image"})
41
+ component("stat-card", {label: "With image", value: withImage, icon: "camera"})
42
+ component("stat-card", {label: "Public domain", value: publicDomain, icon: "unlock"})
43
43
  ```
44
44
 
45
- 4. **Galerie des oeuvres** avec images haute definition :
45
+ 4. **Artwork gallery** with high-resolution images:
46
46
  ```
47
47
  component("gallery", {
48
48
  images: objects
@@ -55,64 +55,64 @@ Le serveur Met Museum donne acces a la collection du Metropolitan Museum of Art
55
55
  })
56
56
  ```
57
57
 
58
- 5. **Fiches detaillees** en cards pour les oeuvres principales :
58
+ 5. **Detailed cards** for the main artworks:
59
59
  ```
60
60
  component("cards", {
61
61
  items: objects.map(o => ({
62
62
  title: o.title,
63
- subtitle: o.artistDisplayName || "Artiste inconnu",
63
+ subtitle: o.artistDisplayName || "Unknown artist",
64
64
  image: o.primaryImageSmall,
65
65
  body: [o.objectDate, o.medium, o.department].filter(Boolean).join(" — ")
66
66
  }))
67
67
  })
68
68
  ```
69
69
 
70
- 6. **Details d'une oeuvre specifique** en kv :
70
+ 6. **Details of a specific artwork** in kv:
71
71
  ```
72
72
  component("kv", {pairs: [
73
- ["Titre", obj.title],
74
- ["Artiste", obj.artistDisplayName],
73
+ ["Title", obj.title],
74
+ ["Artist", obj.artistDisplayName],
75
75
  ["Date", obj.objectDate],
76
76
  ["Medium", obj.medium],
77
77
  ["Dimensions", obj.dimensions],
78
- ["Departement", obj.department],
78
+ ["Department", obj.department],
79
79
  ["Culture", obj.culture],
80
80
  ["Credit", obj.creditLine],
81
- ["Domaine public", obj.isPublicDomain ? "Oui" : "Non"]
81
+ ["Public domain", obj.isPublicDomain ? "Yes" : "No"]
82
82
  ]})
83
83
  ```
84
84
 
85
- ## Exemples
85
+ ## Examples
86
86
 
87
- ### Tableaux de Van Gogh
87
+ ### Van Gogh paintings
88
88
  ```
89
- // 1. Recherche
89
+ // 1. Search
90
90
  search_objects({query: "van gogh", hasImages: true}) // → [436532, 436529, ...]
91
91
 
92
- // 2. Details (premiers 8 resultats)
92
+ // 2. Details (first 8 results)
93
93
  objectIDs.slice(0, 8).forEach(id => get_object({objectID: id}))
94
94
 
95
- // 3. Rendu
96
- component("stat-card", {label: "Oeuvres de Van Gogh", value: "8", icon: "palette"})
95
+ // 3. Render
96
+ component("stat-card", {label: "Van Gogh works", value: "8", icon: "palette"})
97
97
  component("gallery", {images: vanGoghWorks.map(w => ({src: w.primaryImageSmall, alt: w.title, caption: w.objectDate}))})
98
98
  component("cards", {items: vanGoghWorks.map(w => ({title: w.title, subtitle: w.objectDate, image: w.primaryImageSmall, body: w.medium}))})
99
99
  ```
100
100
 
101
- ### Art egyptien
101
+ ### Egyptian art
102
102
  ```
103
- // 1. Recherche par departement
103
+ // 1. Search by department
104
104
  search_objects({query: "egypt pharaoh", departmentId: 10, hasImages: true})
105
105
 
106
- // 2. Rendu avec metadonnees culturelles
106
+ // 2. Render with cultural metadata
107
107
  component("gallery", {images: egyptWorks.map(w => ({src: w.primaryImageSmall, alt: w.title}))})
108
- component("table", {columns: ["Titre", "Periode", "Culture", "Medium"], rows: egyptDetails})
109
- component("kv", {pairs: [["Departement", "Egyptian Art"], ["Source", "Met Museum — Open Access"]]})
108
+ component("table", {columns: ["Title", "Period", "Culture", "Medium"], rows: egyptDetails})
109
+ component("kv", {pairs: [["Department", "Egyptian Art"], ["Source", "Met Museum — Open Access"]]})
110
110
  ```
111
111
 
112
- ## Erreurs courantes
112
+ ## Common mistakes
113
113
 
114
- - **Trop d'appels `get_object`** : la recherche retourne parfois des centaines d'IDs — limiter a 5-10 appels detail pour la performance
115
- - **Oeuvres sans image** : beaucoup d'objets Met n'ont pas de `primaryImage` — toujours filtrer avec `hasImages: true` dans la recherche ou verifier le champ
116
- - **Images haute resolution cassees** : utiliser `primaryImageSmall` (web-large) pour la galerie et les cards — les URLs `primaryImage` (original) retournent souvent des 404
117
- - **Oublier la licence** : les oeuvres en domaine public (`isPublicDomain: true`) peuvent etre affichees librement, les autres ont un champ `rights` a respecter
118
- - **Artiste inconnu** : beaucoup d'oeuvres anciennes n'ont pas d'`artistDisplayName` — afficher "Artiste inconnu" ou la culture/periode a la place
114
+ - **Too many `get_object` calls**: a search sometimes returns hundreds of IDs — limit to 5-10 detail calls for performance
115
+ - **Artworks without images**: many Met objects have no `primaryImage` — always filter with `hasImages: true` in the search or check the field
116
+ - **Broken high-resolution images**: use `primaryImageSmall` (web-large) for the gallery and cards — `primaryImage` (original) URLs often return 404s
117
+ - **Forgetting the license**: works in the public domain (`isPublicDomain: true`) can be displayed freely; others have a `rights` field to respect
118
+ - **Unknown artist**: many ancient works have no `artistDisplayName` — display "Unknown artist" or the culture/period instead
@@ -1,59 +1,59 @@
1
1
  ---
2
2
  id: analyser-actualites-hacker-news
3
- name: Analyser les actualites et tendances Hacker News en tableau et graphiques
3
+ name: Analyze Hacker News news and trends with tables and charts
4
4
  components_used: [table, chart, stat-card, cards]
5
- when: l'utilisateur demande les actualites tech, les tendances Hacker News, les top stories, ou une analyse des discussions et commentaires HN
5
+ when: the user asks for tech news, Hacker News trends, top stories, or an analysis of HN discussions and comments
6
6
  servers: [hackernews]
7
7
  layout:
8
8
  type: grid
9
9
  columns: 2
10
- arrangement: stats en ligne, table pleine largeur, chart en bas
10
+ arrangement: stats in a row, full-width table, chart at the bottom
11
11
  ---
12
12
 
13
- ## Quand utiliser
13
+ ## When to use
14
14
 
15
- L'utilisateur s'interesse aux actualites technologiques ou aux tendances de la communaute Hacker News :
16
- - "Quelles sont les top stories Hacker News ?"
17
- - "Montre-moi les posts les plus commentes aujourd'hui"
18
- - "Les tendances tech de la semaine sur HN"
19
- - "Analyse les Ask HN recents"
20
- - "Quels sujets dominent Hacker News en ce moment ?"
15
+ The user is interested in technology news or Hacker News community trends:
16
+ - "What are the top Hacker News stories?"
17
+ - "Show me the most commented posts today"
18
+ - "This week's tech trends on HN"
19
+ - "Analyze recent Ask HN posts"
20
+ - "What topics are dominating Hacker News right now?"
21
21
 
22
- Le serveur Hacker News donne acces aux stories, commentaires, classements et metadonnees de posts.
22
+ The Hacker News server provides access to stories, comments, rankings, and post metadata.
23
23
 
24
- ## Comment
24
+ ## How to use
25
25
 
26
- 1. **Recuperer les top stories** :
26
+ 1. **Fetch the top stories**:
27
27
  ```
28
28
  get_top_stories({limit: 30})
29
29
  ```
30
- Retourne les IDs des stories les plus populaires.
30
+ Returns the IDs of the most popular stories.
31
31
 
32
- 2. **Recuperer les details** de chaque story :
32
+ 2. **Fetch the details** of each story:
33
33
  ```
34
34
  get_item({id: storyId})
35
35
  ```
36
- Retourne : `title`, `url`, `score`, `by` (auteur), `descendants` (nb commentaires), `time`, `type`.
36
+ Returns: `title`, `url`, `score`, `by` (author), `descendants` (comment count), `time`, `type`.
37
37
 
38
- 3. **Afficher les KPIs** en stat-cards :
38
+ 3. **Display KPIs** in stat-cards:
39
39
  ```
40
40
  component("stat-card", {label: "Top Stories", value: "30", icon: "newspaper"})
41
- component("stat-card", {label: "Score moyen", value: Math.round(avgScore), icon: "trending-up"})
42
- component("stat-card", {label: "Commentaires moyen", value: Math.round(avgComments), icon: "message-circle"})
43
- component("stat-card", {label: "Score max", value: maxScore + " pts", icon: "award"})
41
+ component("stat-card", {label: "Average score", value: Math.round(avgScore), icon: "trending-up"})
42
+ component("stat-card", {label: "Average comments", value: Math.round(avgComments), icon: "message-circle"})
43
+ component("stat-card", {label: "Max score", value: maxScore + " pts", icon: "award"})
44
44
  ```
45
45
 
46
- 4. **Tableau des stories** trie par score :
46
+ 4. **Stories table** sorted by score:
47
47
  ```
48
48
  component("table", {
49
- columns: ["#", "Titre", "Score", "Commentaires", "Auteur"],
49
+ columns: ["#", "Title", "Score", "Comments", "Author"],
50
50
  rows: stories.sort((a, b) => b.score - a.score).map((s, i) => [
51
51
  i + 1, s.title, s.score, s.descendants, s.by
52
52
  ])
53
53
  })
54
54
  ```
55
55
 
56
- 5. **Graphique de distribution** des scores :
56
+ 5. **Score distribution chart**:
57
57
  ```
58
58
  component("chart", {
59
59
  type: "bar",
@@ -62,66 +62,66 @@ Le serveur Hacker News donne acces aux stories, commentaires, classements et met
62
62
  })
63
63
  ```
64
64
 
65
- 6. **Cards pour les stories vedettes** (top 5) :
65
+ 6. **Cards for featured stories** (top 5):
66
66
  ```
67
67
  component("cards", {
68
68
  items: top5.map(s => ({
69
69
  title: s.title,
70
70
  subtitle: s.by + " — " + s.score + " points",
71
- body: s.descendants + " commentaires | " + new Date(s.time * 1000).toLocaleDateString(),
71
+ body: s.descendants + " comments | " + new Date(s.time * 1000).toLocaleDateString(),
72
72
  url: s.url
73
73
  }))
74
74
  })
75
75
  ```
76
76
 
77
- ## Exemples
77
+ ## Examples
78
78
 
79
- ### Top 10 stories du moment
79
+ ### Top 10 stories right now
80
80
  ```
81
- // 1. Recuperer
81
+ // 1. Fetch
82
82
  get_top_stories({limit: 10})
83
- // Pour chaque ID: get_item({id})
83
+ // For each ID: get_item({id})
84
84
 
85
- // 2. Rendu
86
- component("stat-card", {label: "Score total", value: totalScore, icon: "zap"})
87
- component("stat-card", {label: "Commentaires total", value: totalComments, icon: "message-circle"})
85
+ // 2. Render
86
+ component("stat-card", {label: "Total score", value: totalScore, icon: "zap"})
87
+ component("stat-card", {label: "Total comments", value: totalComments, icon: "message-circle"})
88
88
  component("table", {
89
- columns: ["Rang", "Titre", "Score", "Commentaires", "Auteur", "Age"],
89
+ columns: ["Rank", "Title", "Score", "Comments", "Author", "Age"],
90
90
  rows: rankedStories
91
91
  })
92
92
  component("cards", {items: top3Stories})
93
93
  ```
94
94
 
95
- ### Analyse Ask HN
95
+ ### Ask HN analysis
96
96
  ```
97
- // 1. Rechercher les Ask HN recents
97
+ // 1. Fetch recent Ask HN posts
98
98
  get_ask_stories({limit: 20})
99
99
 
100
- // 2. Rendu
101
- component("stat-card", {label: "Ask HN recents", value: "20", icon: "help-circle"})
102
- component("stat-card", {label: "Reponses moyennes", value: avgReplies, icon: "message-circle"})
103
- component("table", {columns: ["Titre", "Reponses", "Score", "Auteur"], rows: askStories})
104
- component("chart", {type: "bar", labels: titles, datasets: [{label: "Reponses", data: replyCounts}]})
100
+ // 2. Render
101
+ component("stat-card", {label: "Recent Ask HN", value: "20", icon: "help-circle"})
102
+ component("stat-card", {label: "Average replies", value: avgReplies, icon: "message-circle"})
103
+ component("table", {columns: ["Title", "Replies", "Score", "Author"], rows: askStories})
104
+ component("chart", {type: "bar", labels: titles, datasets: [{label: "Replies", data: replyCounts}]})
105
105
  ```
106
106
 
107
- ### Tendances par domaine
107
+ ### Trends by domain
108
108
  ```
109
- // 1. Recuperer top stories et extraire les domaines des URLs
109
+ // 1. Fetch top stories and extract domains from URLs
110
110
  get_top_stories({limit: 50})
111
111
 
112
- // 2. Grouper par domaine
112
+ // 2. Group by domain
113
113
  const domains = groupBy(stories, s => new URL(s.url).hostname)
114
114
 
115
- // 3. Rendu
116
- component("stat-card", {label: "Domaines uniques", value: Object.keys(domains).length, icon: "globe"})
115
+ // 3. Render
116
+ component("stat-card", {label: "Unique domains", value: Object.keys(domains).length, icon: "globe"})
117
117
  component("chart", {type: "bar", labels: topDomains.map(d => d.name), datasets: [{label: "Stories", data: topDomains.map(d => d.count)}]})
118
- component("table", {columns: ["Domaine", "Stories", "Score total"], rows: domainStats})
118
+ component("table", {columns: ["Domain", "Stories", "Total score"], rows: domainStats})
119
119
  ```
120
120
 
121
- ## Erreurs courantes
121
+ ## Common mistakes
122
122
 
123
- - **Trop d'appels `get_item`** : chaque story necessite un appel individuellimiter a 20-30 pour eviter la lenteur
124
- - **Timestamps non convertis** : HN retourne des timestamps Unix convertir en dates lisibles
125
- - **Titres tronques dans les graphiques** : les titres HN sont longs tronquer a 30-40 caracteres pour les labels de graphiques
126
- - **Oublier les stories sans URL** : les "Ask HN", "Show HN" et "Tell HN" n'ont pas toujours d'URL externe gerer ce cas
127
- - **Ne pas distinguer les types** : HN a des stories, jobs, polls — filtrer par type si l'utilisateur demande un type specifique
123
+ - **Too many `get_item` calls**: each story requires an individual calllimit to 20-30 to avoid slowness
124
+ - **Unconverted timestamps**: HN returns Unix timestamps — convert them to human-readable dates
125
+ - **Truncated titles in charts**: HN titles are longtruncate to 30-40 characters for chart labels
126
+ - **Forgetting stories without a URL**: "Ask HN", "Show HN", and "Tell HN" posts don't always have an external URL — handle this case
127
+ - **Not distinguishing types**: HN has stories, jobs, and polls — filter by type if the user asks for a specific type
@@ -1,38 +1,38 @@
1
1
  ---
2
- id: cartographier-observations-biodiversite
3
- name: Cartographier les observations de biodiversite sur une zone geographique
2
+ id: map-biodiversity-observations
3
+ name: Map biodiversity observations on a geographic area
4
4
  components_used: [map, gallery, table, stat-card]
5
- when: l'utilisateur demande une carte des observations naturalistes, la biodiversite d'une zone, les especes presentes dans un lieu, ou les observations iNaturalist d'une region
5
+ when: the user asks for a map of naturalist observations, the biodiversity of an area, the species present in a location, or iNaturalist observations in a region
6
6
  servers: [inaturalist]
7
7
  layout:
8
8
  type: grid
9
9
  columns: 2
10
- arrangement: carte pleine largeur en haut, galerie + stats en dessous
10
+ arrangement: full-width map at top, gallery + stats below
11
11
  ---
12
12
 
13
- ## Quand utiliser
13
+ ## When to use
14
14
 
15
- L'utilisateur pose une question sur la biodiversite d'un lieu ou demande une carte des observations :
16
- - "Quelles especes d'oiseaux observe-t-on a Paris ?"
17
- - "Montre-moi une carte des observations de papillons dans les Alpes"
18
- - "Quelle est la biodiversite autour du lac d'Annecy ?"
19
- - "Les especes menacees observees en Ile-de-France"
15
+ The user asks a question about the biodiversity of a location or requests a map of observations:
16
+ - "What bird species are observed in Paris?"
17
+ - "Show me a map of butterfly observations in the Alps"
18
+ - "What is the biodiversity around Lake Annecy?"
19
+ - "Endangered species observed in Ile-de-France"
20
20
 
21
- Le serveur iNaturalist fournit des observations georeferencees avec photos, taxons, dates et observateurs.
21
+ The iNaturalist server provides georeferenced observations with photos, taxa, dates, and observers.
22
22
 
23
- ## Comment
23
+ ## How to use
24
24
 
25
- 1. **Rechercher les observations** dans la zone cible :
25
+ 1. **Search for observations** in the target area:
26
26
  ```
27
27
  search_observations({lat: 48.85, lng: 2.35, radius: 10, taxon_name: "Aves", per_page: 50})
28
28
  ```
29
- Parametres utiles :
30
- - `lat`, `lng`, `radius` : centre et rayon de la zone en km
31
- - `taxon_name` : filtre taxonomique ("Aves", "Lepidoptera", "Mammalia", etc.)
32
- - `quality_grade` : "research" pour les observations verifiees
33
- - `per_page` : nombre de resultats (max 200)
29
+ Useful parameters:
30
+ - `lat`, `lng`, `radius`: center and radius of the area in km
31
+ - `taxon_name`: taxonomic filter ("Aves", "Lepidoptera", "Mammalia", etc.)
32
+ - `quality_grade`: "research" for verified observations
33
+ - `per_page`: number of results (max 200)
34
34
 
35
- 2. **Afficher la carte** avec les marqueurs d'observation :
35
+ 2. **Display the map** with observation markers:
36
36
  ```
37
37
  component("map", {
38
38
  center: [48.85, 2.35],
@@ -46,15 +46,15 @@ Le serveur iNaturalist fournit des observations georeferencees avec photos, taxo
46
46
  })
47
47
  ```
48
48
 
49
- 3. **Statistiques de la zone** en stat-cards :
49
+ 3. **Area statistics** in stat-cards:
50
50
  ```
51
51
  component("stat-card", {label: "Observations", value: total_results, icon: "eye"})
52
- component("stat-card", {label: "Especes uniques", value: uniqueSpecies.length, icon: "leaf"})
53
- component("stat-card", {label: "Observateurs", value: uniqueObservers.length, icon: "users"})
54
- component("stat-card", {label: "Grade recherche", value: researchGradeCount, icon: "check-circle"})
52
+ component("stat-card", {label: "Unique species", value: uniqueSpecies.length, icon: "leaf"})
53
+ component("stat-card", {label: "Observers", value: uniqueObservers.length, icon: "users"})
54
+ component("stat-card", {label: "Research grade", value: researchGradeCount, icon: "check-circle"})
55
55
  ```
56
56
 
57
- 4. **Galerie des especes avec photos** :
57
+ 4. **Species gallery with photos**:
58
58
  ```
59
59
  component("gallery", {
60
60
  images: observations
@@ -67,45 +67,45 @@ Le serveur iNaturalist fournit des observations georeferencees avec photos, taxo
67
67
  })
68
68
  ```
69
69
 
70
- 5. **Tableau recapitulatif** des especes :
70
+ 5. **Summary table** of species:
71
71
  ```
72
72
  component("table", {
73
- columns: ["Espece", "Nom scientifique", "Observations", "Derniere obs."],
73
+ columns: ["Species", "Scientific name", "Observations", "Last obs."],
74
74
  rows: speciesSummary
75
75
  })
76
76
  ```
77
77
 
78
- ## Exemples
78
+ ## Examples
79
79
 
80
- ### Oiseaux de Paris
80
+ ### Birds of Paris
81
81
  ```
82
- // 1. Recherche
82
+ // 1. Search
83
83
  search_observations({lat: 48.8566, lng: 2.3522, radius: 10, taxon_name: "Aves", quality_grade: "research", per_page: 100})
84
84
 
85
- // 2. Rendu
85
+ // 2. Render
86
86
  component("map", {center: [48.8566, 2.3522], zoom: 12, markers: birdMarkers})
87
- component("stat-card", {label: "Especes d'oiseaux", value: "47", icon: "bird"})
88
- component("stat-card", {label: "Observations verifiees", value: "312", icon: "check"})
87
+ component("stat-card", {label: "Bird species", value: "47", icon: "bird"})
88
+ component("stat-card", {label: "Verified observations", value: "312", icon: "check"})
89
89
  component("gallery", {images: birdPhotos})
90
- component("table", {columns: ["Espece", "Observations", "Derniere"], rows: birdSummary})
90
+ component("table", {columns: ["Species", "Observations", "Last"], rows: birdSummary})
91
91
  ```
92
92
 
93
- ### Papillons des Alpes
93
+ ### Butterflies in the Alps
94
94
  ```
95
- // 1. Zone large autour de Chamonix
95
+ // 1. Wide area around Chamonix
96
96
  search_observations({lat: 45.9237, lng: 6.8694, radius: 30, taxon_name: "Lepidoptera", per_page: 100})
97
97
 
98
- // 2. Rendu avec clustering sur la carte
98
+ // 2. Render with clustering on the map
99
99
  component("map", {center: [45.9237, 6.8694], zoom: 10, markers: butterflyMarkers, cluster: true})
100
- component("stat-card", {label: "Especes de papillons", value: uniqueSpecies.length})
100
+ component("stat-card", {label: "Butterfly species", value: uniqueSpecies.length})
101
101
  component("gallery", {images: butterflyPhotos})
102
- component("table", {columns: ["Espece", "Altitude", "Mois", "Observateur"], rows: enrichedData})
102
+ component("table", {columns: ["Species", "Altitude", "Month", "Observer"], rows: enrichedData})
103
103
  ```
104
104
 
105
- ## Erreurs courantes
105
+ ## Common mistakes
106
106
 
107
- - **Rayon trop large** : un rayon de 100 km retourne trop de resultats et noie l'information — preferer 5-20 km et augmenter si peu de resultats
108
- - **Thumbnails iNaturalist** : les URLs par defaut sont en format "square" (75x75) — remplacer "square" par "medium" (200px) ou "large" (500px)
109
- - **Pas de filtre taxonomique** : sans filtre, iNaturalist retourne plantes + animaux + champignons ensembletoujours filtrer par groupe si l'utilisateur en mentionne un
110
- - **Oublier le grade de qualite** : les observations "casual" peuvent etre mal identifieespreferer `quality_grade: "research"` pour des donnees fiables
111
- - **Carte sans zoom adapte** : ajuster le zoom en fonction du rayon de recherche (5 km → zoom 13, 20 km → zoom 11, 50 km → zoom 9)
107
+ - **Radius too large**: a 100 km radius returns too many results and buries the information — prefer 5-20 km and increase if few results are found
108
+ - **iNaturalist thumbnails**: default URLs are in "square" format (75x75) — replace "square" with "medium" (200px) or "large" (500px)
109
+ - **No taxonomic filter**: without a filter, iNaturalist returns plants + animals + fungi togetheralways filter by group if the user mentions one
110
+ - **Forgetting the quality grade**: "casual" observations may be misidentifiedprefer `quality_grade: "research"` for reliable data
111
+ - **Map with wrong zoom level**: adjust zoom based on the search radius (5 km → zoom 13, 20 km → zoom 11, 50 km → zoom 9)