From d48cafebb277e4ad4b31e883cbe4f55eef9ea4a4 Mon Sep 17 00:00:00 2001
From: Joris
Date: Sat, 29 May 2021 19:24:41 +0200
Subject: Rewrite in TypeScript
---
.gitignore | 8 +-
.gitlab-ci.yml | 25 --
.tmuxinator.yml | 11 -
LICENSE | 19 +
Makefile | 20 --
README.md | 34 +-
bin/dev-server | 8 +
bower.json | 8 -
data-extractor/extract.py | 58 +++
package.json | 6 -
public/index.html | 38 +-
public/main.css | 50 +--
shell.nix | 31 +-
src/Food.purs | 245 -------------
src/Format.purs | 70 ----
src/Indicator.purs | 20 --
src/Main.purs | 15 -
src/Order.purs | 54 ---
src/Page.purs | 129 -------
src/food.ts | 882 ++++++++++++++++++++++++++++++++++++++++++++++
src/lib/dom.ts | 6 +
src/lib/format.ts | 9 +
src/lib/function.ts | 7 +
src/lib/h.ts | 30 ++
src/lib/search.ts | 11 +
src/main.ts | 3 +
src/view/sort.ts | 53 +++
src/view/table.ts | 102 ++++++
test/Main.purs | 26 --
tsconfig.json | 13 +
30 files changed, 1279 insertions(+), 712 deletions(-)
delete mode 100644 .gitlab-ci.yml
delete mode 100644 .tmuxinator.yml
create mode 100644 LICENSE
delete mode 100644 Makefile
create mode 100755 bin/dev-server
delete mode 100644 bower.json
create mode 100644 data-extractor/extract.py
delete mode 100644 package.json
delete mode 100644 src/Food.purs
delete mode 100644 src/Format.purs
delete mode 100644 src/Indicator.purs
delete mode 100644 src/Main.purs
delete mode 100644 src/Order.purs
delete mode 100644 src/Page.purs
create mode 100644 src/food.ts
create mode 100644 src/lib/dom.ts
create mode 100644 src/lib/format.ts
create mode 100644 src/lib/function.ts
create mode 100644 src/lib/h.ts
create mode 100644 src/lib/search.ts
create mode 100644 src/main.ts
create mode 100644 src/view/sort.ts
create mode 100644 src/view/table.ts
delete mode 100644 test/Main.purs
create mode 100644 tsconfig.json
diff --git a/.gitignore b/.gitignore
index 7692a80..a4a3424 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,2 @@
-/public/main.js
-/output/
-/bower_components/
-/node_modules/
-/.psci_modules
-yarn.lock
+public/main.js
+data-extractor/export.json
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
deleted file mode 100644
index 4bfb623..0000000
--- a/.gitlab-ci.yml
+++ /dev/null
@@ -1,25 +0,0 @@
-image: node:latest
-
-cache:
- paths:
- - node_modules/
-
-before_script:
- - npm install bower
- - npm install purescript
- - npm install pulp
- - export PATH=node_modules/.bin:$PATH;
- - bower install --allow-root
-
-test:
- script:
- - make test
-
-pages:
- script:
- - make build
- artifacts:
- paths:
- - public
- only:
- - master
diff --git a/.tmuxinator.yml b/.tmuxinator.yml
deleted file mode 100644
index 2f71ef9..0000000
--- a/.tmuxinator.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-name: glycemie
-
-windows:
- - main:
- layout: 1074,239x57,0,0{144x57,0,0,0,94x57,145,0,2}
- panes:
- - # Empty
- - build:
- - fuser -k 9000/tcp
- - webfsd -r public -f index.html -p 9000
- - make install watch
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..c1e6c0b
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2020 Joris Guyonvarch
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/Makefile b/Makefile
deleted file mode 100644
index 2772fa5..0000000
--- a/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
-start:
- @nix-shell --command "mux local"
-
-stop:
- @pkill webfsd
- @tmux kill-session -t glycemie
-
-.PHONY: test
-test:
- @pulp test
-
-install:
- @yarn install
- @bower install
-
-build:
- @pulp build --to public/main.js
-
-watch:
- @pulp --watch --before clear build --to public/main.js
diff --git a/README.md b/README.md
index 29c343f..9f5b91f 100644
--- a/README.md
+++ b/README.md
@@ -1,35 +1,9 @@
-[Glycémie](https://guyonvarch.gitlab.io/glycemie)
-=================================================
+# Getting started
-[![build status](https://gitlab.com/guyonvarch/glycemie/badges/master/build.svg)](https://gitlab.com/guyonvarch/glycemie/commits/master)
-
-Getting started
----------------
-
-Install nix and follow the instructions:
-
-``` sh
-curl https://nixos.org/nix/install | sh
-```
-
-Start the environment with:
-
-``` sh
-./make start
-```
-
-Open your browser at [http://localhost:9000](http://localhost:9000).
-
-Later, stop the environment with:
+Run:
```sh
-./make stop
+nix-shell --run bin/watch.sh
```
-Sources
--------
-
-- http://www.aprifel.com/fiche-nutri-composant-glucides,6.html
-- http://www.montignac.com/fr/rechercher-l-index-glycemique-d-un-aliment/
-- http://www.monmenu.fr/
-- https://www.lanutrition.fr/
+Then, open your browser at `http://localhost:8000`.
diff --git a/bin/dev-server b/bin/dev-server
new file mode 100755
index 0000000..86eeab7
--- /dev/null
+++ b/bin/dev-server
@@ -0,0 +1,8 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+python -m http.server --directory public 8000 &
+
+trap "fuser -k 8000/tcp" EXIT
+
+tsc --target ES2017 --watch
diff --git a/bower.json b/bower.json
deleted file mode 100644
index 76a7ef5..0000000
--- a/bower.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "name": "glycemie",
- "private": true,
- "dependencies": {
- "purescript-halogen": "*",
- "purescript-spec": "*"
- }
-}
diff --git a/data-extractor/extract.py b/data-extractor/extract.py
new file mode 100644
index 0000000..0e9702e
--- /dev/null
+++ b/data-extractor/extract.py
@@ -0,0 +1,58 @@
+# Improvement: fix accents
+
+import json
+import urllib.request
+import time
+from bs4 import BeautifulSoup
+
+links = []
+with urllib.request.urlopen('https://www.lanutrition.fr/les-aliments-a-la-loupe') as fp:
+ content = fp.read()
+ soup = BeautifulSoup(content, 'html.parser')
+ for link in soup.find(id='nutriments_by_alpha').find_all('a'):
+ href = link.get('href')
+ links.append(f'https://www.lanutrition.fr{href}')
+
+def extractCarbohydrates(soup):
+ try:
+ return float(soup
+ .find('div', {"name": 'glucides'})
+ .find(class_='value-weight')
+ .get_text()
+ .split(' ')[0])
+ except:
+ return None
+
+def extractGlycemicIndex(soup):
+ try:
+ n = int(soup
+ .find(class_='aliment-poids')
+ .find(class_='nombre')
+ .get_text())
+ if n > 0:
+ return n
+ except:
+ return None
+
+aliments = []
+for link in links:
+ print(link)
+ time.sleep(0.5)
+ with urllib.request.urlopen(link) as fp:
+ content = fp.read()
+ soup = BeautifulSoup(content, 'html.parser')
+ name = soup.find('h1', {"id": 'page-title'}).get_text()
+ carbohydrates = extractCarbohydrates(soup)
+ glycemicIndex = extractGlycemicIndex(soup)
+ if name is not None and carbohydrates is not None and glycemicIndex is not None:
+ print('+')
+ aliments.append({
+ "name": name,
+ "glycemicIndex": glycemicIndex,
+ "carbohydrates": carbohydrates
+ })
+ else:
+ print('-')
+
+with open('export.json', 'w') as f:
+ f.write(json.dumps(aliments))
diff --git a/package.json b/package.json
deleted file mode 100644
index 7a740d4..0000000
--- a/package.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "private": true,
- "devDependencies": {
- "pulp": "^11.0.0"
- }
-}
diff --git a/public/index.html b/public/index.html
index 1639d26..27b8470 100644
--- a/public/index.html
+++ b/public/index.html
@@ -1,13 +1,27 @@
-
-
- Glycémie
-
-
-
-
-
-
-
-
-
+
+
+
+Glycémie
+
+
+
+
+
+
+
+
diff --git a/public/main.css b/public/main.css
index 29f031c..2736a7f 100644
--- a/public/main.css
+++ b/public/main.css
@@ -1,42 +1,51 @@
+/* Box sizing */
+
html {
box-sizing: border-box;
- overflow-y: scroll;
}
*, *:before, *:after {
box-sizing: inherit;
}
+/* */
+
+html {
+ overflow-y: scroll;
+}
+
body { margin: 0; }
@media screen and (min-width: 700px) {
- .page {
+ .g-Page {
width: 700px;
margin: 0 auto;
}
}
@media screen and (max-width: 700px) {
- .page { width: 100%; }
+ .g-Page { width: 100%; }
}
-.header {
+.g-Header {
position: fixed;
top: 0;
width: inherit;
}
-.line {
+.g-Aliments { margin-top: 110px; }
+
+.g-Line {
height: 50px;
display: flex;
align-items: center;
}
-.line.title {
+.g-Line.g-Title {
height: 60px;
}
-.line.title > * {
+.g-Line.g-Title > * {
border: 0;
background-color: #333333;
color: white;
@@ -48,11 +57,11 @@ body { margin: 0; }
transition: background-color 0.2s ease-in-out;
}
-.line.title > *.sorted {
+.g-Line.g-Title > .g-Header--Sorted {
background-color: #505050;
}
-.line.search {
+.g-Line.g-Search {
width: 100%;
padding: 0 15px;
border: none;
@@ -60,18 +69,19 @@ body { margin: 0; }
font-size: 14px;
}
-.aliments { margin-top: 110px; }
+.g-Line > * { padding: 15px; }
-.line > * { padding: 15px; }
+.g-Line > *:nth-child(1) { width: 40%; }
+.g-Line > *:nth-child(2) { width: 20%; }
+.g-Line > *:nth-child(3) { width: 20%; }
+.g-Line > *:nth-child(4) { width: 20%; }
-.line > *:nth-child(1) { width: 40%; }
-.line > *:nth-child(2) { width: 20%; }
-.line > *:nth-child(3) { width: 20%; }
-.line > *:nth-child(4) { width: 20%; }
+.g-Aliment:nth-child(2n+1) { background-color: #F6F6F6; }
-.line > .good { color: green; }
-.line > .medium { color: orange; }
-.line > .bad { color: red; }
-.line > .number { text-align: right; }
+.g-Number {
+ text-align: right;
+}
-.aliment:nth-child(2n+1) { background-color: #F6F6F6; }
+.g-Number--Low { color: green; }
+.g-Number--Middle { color: orange; }
+.g-Number--High { color: red; }
diff --git a/shell.nix b/shell.nix
index e7e0323..3bffe92 100644
--- a/shell.nix
+++ b/shell.nix
@@ -1,16 +1,17 @@
-with import {}; {
- env = stdenv.mkDerivation {
- name = "env";
- buildInputs = with pkgs; [
- yarn
- nodePackages.bower
- purescript
- tmux
- tmuxinator
- webfs
- ];
- shellHook = ''
- export PATH=node_modules/.bin:$PATH;
- '';
- };
+with (import (builtins.fetchGit {
+ name = "nixpkgs-20.09";
+ url = "git@github.com:nixos/nixpkgs.git";
+ rev = "cd63096d6d887d689543a0b97743d28995bc9bc3";
+ ref = "refs/tags/20.09";
+}){});
+
+mkShell {
+
+ buildInputs = [
+ nodePackages.typescript
+ python3
+ python3Packages.beautifulsoup4
+ psmisc # fuser
+ ];
+
}
diff --git a/src/Food.purs b/src/Food.purs
deleted file mode 100644
index fb66c9d..0000000
--- a/src/Food.purs
+++ /dev/null
@@ -1,245 +0,0 @@
-module Food
- ( Aliment
- , all
- , glycemicLoad
- ) where
-
-import Data.Int (toNumber)
-import Prelude
-
-type Aliment =
- { name :: String
- , glycemicIndex :: Int
- , carbohydrates :: Int -- for 100 grams
- }
-
-glycemicLoad :: Aliment -> Number
-glycemicLoad aliment = toNumber aliment.glycemicIndex * toNumber aliment.carbohydrates / 100.0
-
-all :: Array Aliment
-all =
- [ { name: "Abricot", glycemicIndex: 30, carbohydrates: 10 }
- , { name: "Abricot séché", glycemicIndex: 35, carbohydrates: 44 }
- , { name: "Ail", glycemicIndex: 30, carbohydrates: 25 }
- , { name: "Amande", glycemicIndex: 15, carbohydrates: 17 }
- , { name: "Amande en poudre", glycemicIndex: 20, carbohydrates: 17 }
- , { name: "Ananas", glycemicIndex: 45, carbohydrates: 12 }
- , { name: "Artichaut", glycemicIndex: 15, carbohydrates: 1 }
- , { name: "Asperge", glycemicIndex: 15, carbohydrates: 2 }
- , { name: "Aubergine", glycemicIndex: 20, carbohydrates: 3 }
- , { name: "Avocat", glycemicIndex: 10, carbohydrates: 4 }
-
- , { name: "Bambou pousses", glycemicIndex: 20, carbohydrates: 6 }
- , { name: "Banane", glycemicIndex: 60, carbohydrates: 22 }
- , { name: "Betterave crue", glycemicIndex: 30, carbohydrates: 9 }
- , { name: "Betterave cuite", glycemicIndex: 65, carbohydrates: 7 }
- , { name: "Boulghour", glycemicIndex: 55, carbohydrates: 20 }
- , { name: "Brocoli", glycemicIndex: 15, carbohydrates: 5 }
- , { name: "Brugnon", glycemicIndex: 35, carbohydrates: 14 }
-
- , { name: "Cacahuète", glycemicIndex: 15, carbohydrates: 11 }
- , { name: "Cacao en poudre", glycemicIndex: 20, carbohydrates: 25 }
- , { name: "Canneloni", glycemicIndex: 55, carbohydrates: 10 }
- , { name: "Carotte crue", glycemicIndex: 20, carbohydrates: 5 }
- , { name: "Carotte cuite", glycemicIndex: 35, carbohydrates: 5 }
- , { name: "Céleri branche", glycemicIndex: 15, carbohydrates: 2 }
- , { name: "Céleri-rave", glycemicIndex: 35, carbohydrates: 3 }
- , { name: "Céleri-rave rapé", glycemicIndex: 20, carbohydrates: 6 }
- , { name: "Cêpes", glycemicIndex: 15, carbohydrates: 4 }
- , { name: "Cerise", glycemicIndex: 25, carbohydrates: 16 }
- , { name: "Cerneaux de noix", glycemicIndex: 15, carbohydrates: 11 }
- , { name: "Champignon", glycemicIndex: 0, carbohydrates: 1 }
- , { name: "Chataigne grillée", glycemicIndex: 60, carbohydrates: 42 }
- , { name: "Croissant", glycemicIndex: 60, carbohydrates: 57 }
-
- , { name: "Chocolat noir 70%", glycemicIndex: 25, carbohydrates: 32 }
- , { name: "Chocolat noir 85%", glycemicIndex: 20, carbohydrates: 24 }
- , { name: "Choux blanc", glycemicIndex: 15, carbohydrates: 4 }
- , { name: "Choux chinois", glycemicIndex: 15, carbohydrates: 1 }
- , { name: "Choux de bruxelles", glycemicIndex: 15, carbohydrates: 3 }
- , { name: "Choux fleur", glycemicIndex: 15, carbohydrates: 2 }
- , { name: "Choux romanesco", glycemicIndex: 15, carbohydrates: 2 }
- , { name: "Choux rouge", glycemicIndex: 15, carbohydrates: 7 }
- , { name: "Choux vert", glycemicIndex: 15, carbohydrates: 1 }
- , { name: "Citron", glycemicIndex: 20, carbohydrates: 3 }
- , { name: "Citron vert", glycemicIndex: 20, carbohydrates: 7 }
- , { name: "Citrouille", glycemicIndex: 80, carbohydrates: 6 }
- , { name: "Clémentine", glycemicIndex: 30, carbohydrates: 9 }
- , { name: "Coeur de palmier", glycemicIndex: 20, carbohydrates: 11 }
- , { name: "Coing", glycemicIndex: 35, carbohydrates: 14 }
- , { name: "Compote de pomme", glycemicIndex: 35, carbohydrates: 18 }
- , { name: "Concombre", glycemicIndex: 15, carbohydrates: 2 }
- , { name: "Confiture de fruit", glycemicIndex: 65, carbohydrates: 60 }
- , { name: "Cornichon", glycemicIndex: 15, carbohydrates: 2 }
- , { name: "Coulis de tomate", glycemicIndex: 30, carbohydrates: 5 }
- , { name: "Courgette", glycemicIndex: 15, carbohydrates: 3 }
- , { name: "Cresson", glycemicIndex: 15, carbohydrates: 2 }
-
- , { name: "Dattes", glycemicIndex: 70, carbohydrates: 73 }
-
- , { name: "Echalote", glycemicIndex: 15, carbohydrates: 7 }
- , { name: "Endive", glycemicIndex: 15, carbohydrates: 4 }
- , { name: "Épinard", glycemicIndex: 15, carbohydrates: 3 }
-
- , { name: "Faisselle 0%", glycemicIndex: 30, carbohydrates: 4 }
- , { name: "Faisselle 40%", glycemicIndex: 30, carbohydrates: 3 }
- , { name: "Farine de blé", glycemicIndex: 85, carbohydrates: 71 }
- , { name: "Farine de blé à levure incorporée", glycemicIndex: 85, carbohydrates: 71 }
- , { name: "Farine de blé complète T130", glycemicIndex: 45, carbohydrates: 64 }
- , { name: "Farine de blé intégrale T150", glycemicIndex: 45, carbohydrates: 64 }
- , { name: "Farine de maïs", glycemicIndex: 85, carbohydrates: 85 }
- , { name: "Farine de quinoa", glycemicIndex: 40, carbohydrates: 64 }
- , { name: "Farine de riz", glycemicIndex: 95, carbohydrates: 85 }
- , { name: "Farine de seigle complète T130", glycemicIndex: 45, carbohydrates: 59 }
- , { name: "Farine de seigle intégrale T150", glycemicIndex: 45, carbohydrates: 59 }
- , { name: "Fécule de maïs", glycemicIndex: 85, carbohydrates: 88 }
- , { name: "Fenouil", glycemicIndex: 15, carbohydrates: 5 }
- , { name: "Fève", glycemicIndex: 15, carbohydrates: 14 }
- , { name: "Figue Blanche", glycemicIndex: 20, carbohydrates: 19 }
- , { name: "Figue noir", glycemicIndex: 35, carbohydrates: 13 }
- , { name: "Flageolet", glycemicIndex: 25, carbohydrates: 12 }
- , { name: "Flocons d'avoine", glycemicIndex: 40, carbohydrates: 62 }
- , { name: "Fraise", glycemicIndex: 25, carbohydrates: 7 }
- , { name: "Framboise", glycemicIndex: 25, carbohydrates: 8 }
- , { name: "Frites maison", glycemicIndex: 95, carbohydrates: 52 }
- , { name: "Fromage blanc", glycemicIndex: 30, carbohydrates: 4 }
- , { name: "Fruits rouges", glycemicIndex: 15, carbohydrates: 6 }
-
- , { name: "Galette de blé noir", glycemicIndex: 40, carbohydrates: 31 }
- , { name: "Gnocchi", glycemicIndex: 68, carbohydrates: 32 }
- , { name: "Grenade", glycemicIndex: 35, carbohydrates: 13 }
- , { name: "Groseilles", glycemicIndex: 25, carbohydrates: 10 }
- , { name: "Groseilles à maquereau", glycemicIndex: 25, carbohydrates: 6 }
-
- , { name: "Haricot beurre", glycemicIndex: 15, carbohydrates: 3 }
- , { name: "Haricot blanc", glycemicIndex: 35, carbohydrates: 14 }
- , { name: "Haricot mange tout", glycemicIndex: 15, carbohydrates: 7 }
- , { name: "Haricot noir", glycemicIndex: 35, carbohydrates: 24 }
- , { name: "Haricot rouge", glycemicIndex: 35, carbohydrates: 15 }
- , { name: "Haricot vert", glycemicIndex: 30, carbohydrates: 3 }
-
- , { name: "Jus d'abricot", glycemicIndex: 50, carbohydrates: 14 }
- , { name: "Jus d'ananas", glycemicIndex: 50, carbohydrates: 12 }
- , { name: "Jus d'orange", glycemicIndex: 45, carbohydrates: 11 }
- , { name: "Jus de citron", glycemicIndex: 20, carbohydrates: 9 }
- , { name: "Jus de framboise", glycemicIndex: 50, carbohydrates: 11 }
- , { name: "Jus de pamplemousse rose", glycemicIndex: 45, carbohydrates: 9 }
- , { name: "Jus de pomme", glycemicIndex: 50, carbohydrates: 11 }
- , { name: "Jus de pruneaux", glycemicIndex: 55, carbohydrates: 19 }
- , { name: "Jus de raisin", glycemicIndex: 55, carbohydrates: 15 }
- , { name: "Jus de tomate", glycemicIndex: 35, carbohydrates: 4 }
- , { name: "Jus multifruits", glycemicIndex: 50, carbohydrates: 12 }
- , { name: "Jus peche", glycemicIndex: 50, carbohydrates: 13 }
-
- , { name: "Kiwi", glycemicIndex: 50, carbohydrates: 11 }
-
- , { name: "Lait de coco", glycemicIndex: 40, carbohydrates: 3 }
- , { name: "lait demi écrémé", glycemicIndex: 30, carbohydrates: 5 }
- , { name: "Lait écrémé", glycemicIndex: 30, carbohydrates: 5 }
- , { name: "Lait en poudre", glycemicIndex: 30, carbohydrates: 38 }
- , { name: "Lait entier", glycemicIndex: 30, carbohydrates: 5 }
- , { name: "Lentilles cuites", glycemicIndex: 20, carbohydrates: 16 }
- , { name: "Levure chimique sachet", glycemicIndex: 35, carbohydrates: 19 }
- , { name: "Litchi", glycemicIndex: 50, carbohydrates: 17 }
-
- , { name: "Maïs", glycemicIndex: 70, carbohydrates: 19 }
- , { name: "Maïzena", glycemicIndex: 70, carbohydrates: 70 }
- , { name: "Mandarine", glycemicIndex: 30, carbohydrates: 9 }
- , { name: "Mangue", glycemicIndex: 50, carbohydrates: 15 }
- , { name: "Mélange noix", glycemicIndex: 15, carbohydrates: 24 }
- , { name: "Melon", glycemicIndex: 60, carbohydrates: 8 }
- , { name: "Miel", glycemicIndex: 90, carbohydrates: 86 }
- , { name: "Muesli Bjorg", glycemicIndex: 20, carbohydrates: 61 }
- , { name: "Mulet", glycemicIndex: 15, carbohydrates: 1 }
- , { name: "Mûre", glycemicIndex: 25, carbohydrates: 12 }
- , { name: "Myrtilles", glycemicIndex: 25, carbohydrates: 11 }
-
- , { name: "Navet", glycemicIndex: 70, carbohydrates: 7 }
- , { name: "Nectar d'abricot", glycemicIndex: 50, carbohydrates: 13 }
- , { name: "Nectar de banane", glycemicIndex: 50, carbohydrates: 10 }
- , { name: "Nectar de goyave", glycemicIndex: 50, carbohydrates: 10 }
- , { name: "Nectar de mangue", glycemicIndex: 50, carbohydrates: 12 }
- , { name: "Nectarine", glycemicIndex: 35, carbohydrates: 13 }
-
- , { name: "Noisette", glycemicIndex: 25, carbohydrates: 17 }
- , { name: "Noix de cajou", glycemicIndex: 15, carbohydrates: 21 }
- , { name: "Noix de coco", glycemicIndex: 35, carbohydrates: 10 }
- , { name: "Noix de coco râpée", glycemicIndex: 35, carbohydrates: 12 }
- , { name: "Noix de macadamia", glycemicIndex: 15, carbohydrates: 13 }
- , { name: "Noix de pecan", glycemicIndex: 15, carbohydrates: 14 }
-
- , { name: "Olive verte", glycemicIndex: 15, carbohydrates: 2 }
- , { name: "Olives noires", glycemicIndex: 15, carbohydrates: 2 }
- , { name: "Orange", glycemicIndex: 30, carbohydrates: 9 }
-
- , { name: "Pain", glycemicIndex: 70, carbohydrates: 56 }
- , { name: "Pain à Hamburger", glycemicIndex: 85, carbohydrates: 50 }
- , { name: "Pain au seigle", glycemicIndex: 65, carbohydrates: 50 }
- , { name: "pain aux céréales", glycemicIndex: 65, carbohydrates: 55 }
- , { name: "Pain aux raisins", glycemicIndex: 70, carbohydrates: 46 }
- , { name: "Pain au chocolat", glycemicIndex: 65, carbohydrates: 49 }
- , { name: "Pain complet", glycemicIndex: 65, carbohydrates: 44 }
- , { name: "Pain hamburger complet", glycemicIndex: 48, carbohydrates: 48 }
- , { name: "Pastèque", glycemicIndex: 75, carbohydrates: 7 }
- , { name: "Patate douce", glycemicIndex: 50, carbohydrates: 20 }
- , { name: "Pâtes", glycemicIndex: 75, carbohydrates: 35 }
- , { name: "Pâtes complètes", glycemicIndex: 45, carbohydrates: 19 }
- , { name: "Pâtes (spaghettis al dente)", glycemicIndex: 45, carbohydrates: 25 }
- , { name: "Pâte de fruit", glycemicIndex: 70, carbohydrates: 53 }
- , { name: "Petit pois", glycemicIndex: 35, carbohydrates: 11 }
- , { name: "Physalis", glycemicIndex: 25, carbohydrates: 6 }
- , { name: "Pissenlit", glycemicIndex: 15, carbohydrates: 6 }
- , { name: "Pistache", glycemicIndex: 15, carbohydrates: 15 }
- , { name: "Poire", glycemicIndex: 30, carbohydrates: 14 }
- , { name: "Poireau", glycemicIndex: 15, carbohydrates: 3 }
- , { name: "Pois cassés", glycemicIndex: 22, carbohydrates: 22 }
- , { name: "Pois chiches bouillis", glycemicIndex: 30, carbohydrates: 28 }
- , { name: "Pois chiches", glycemicIndex: 30, carbohydrates: 19 }
- , { name: "Poivron", glycemicIndex: 15, carbohydrates: 4 }
- , { name: "Pomme", glycemicIndex: 35, carbohydrates: 19 }
- , { name: "Pommes de terre au four", glycemicIndex: 95, carbohydrates: 23 }
- , { name: "Pommes de terre", glycemicIndex: 65, carbohydrates: 19 }
- , { name: "Potimarron", glycemicIndex: 80, carbohydrates: 6 }
- , { name: "Potiron", glycemicIndex: 80, carbohydrates: 5 }
- , { name: "Pulpe Tomate", glycemicIndex: 30, carbohydrates: 4 }
-
- , { name: "Raisin", glycemicIndex: 40, carbohydrates: 16 }
- , { name: "Raisin sec", glycemicIndex: 65, carbohydrates: 75 }
- , { name: "Rhubarbe", glycemicIndex: 15, carbohydrates: 3 }
- , { name: "Riz complet cuit à la vapeur", glycemicIndex: 50, carbohydrates: 24 }
- , { name: "Riz complet cuit dans un excès d'eau pendant 25 minutes", glycemicIndex: 72, carbohydrates: 24 }
- , { name: "Riz blanc", glycemicIndex: 83, carbohydrates: 29 }
- , { name: "Riz basmati blanc", glycemicIndex: 58, carbohydrates: 26 }
- , { name: "Riz basmati complet", glycemicIndex: 45, carbohydrates: 21 }
- , { name: "Riz inca (Quinoa)", glycemicIndex: 53, carbohydrates: 21 }
- , { name: "Riz sauvage", glycemicIndex: 57, carbohydrates: 29 }
-
- , { name: "Salade", glycemicIndex: 15, carbohydrates: 2 }
- , { name: "Salade feuille de chêne", glycemicIndex: 15, carbohydrates: 2 }
- , { name: "Salade frisée", glycemicIndex: 15, carbohydrates: 1 }
- , { name: "Salade laitue", glycemicIndex: 15, carbohydrates: 2 }
- , { name: "Salade mache", glycemicIndex: 15, carbohydrates: 1 }
- , { name: "Salade mesclun", glycemicIndex: 15, carbohydrates: 2 }
- , { name: "salade roquette", glycemicIndex: 15, carbohydrates: 4 }
- , { name: "Salsifis", glycemicIndex: 30, carbohydrates: 14 }
- , { name: "Sauge (feuille)", glycemicIndex: 40, carbohydrates: 60 }
- , { name: "Semoule", glycemicIndex: 68, carbohydrates: 24 }
- , { name: "Sirop d'érable", glycemicIndex: 65, carbohydrates: 65 }
- , { name: "Son d'avoine", glycemicIndex: 15, carbohydrates: 51 }
-
- , { name: "Tomate", glycemicIndex: 30, carbohydrates: 4 }
- , { name: "Tomate cerise", glycemicIndex: 30, carbohydrates: 4 }
- , { name: "Tomate grappe", glycemicIndex: 30, carbohydrates: 3 }
- , { name: "Tomate sechée", glycemicIndex: 35, carbohydrates: 8 }
- , { name: "Tomme de chèvre", glycemicIndex: 10, carbohydrates: 3 }
- , { name: "Topinambour", glycemicIndex: 15, carbohydrates: 14 }
- , { name: "Tranche pain de mie", glycemicIndex: 85, carbohydrates: 46 }
-
- , { name: "Yaourt", glycemicIndex: 35, carbohydrates: 5 }
- , { name: "Yaourt brassé nature", glycemicIndex: 35, carbohydrates: 6 }
- , { name: "Yaourt lait de brebis", glycemicIndex: 35, carbohydrates: 4 }
- , { name: "Yaourt lait entier", glycemicIndex: 35, carbohydrates: 5 }
- , { name: "Yaourt nature", glycemicIndex: 35, carbohydrates: 5 }
-
- , { name: "Zeste citron", glycemicIndex: 20, carbohydrates: 13 }
- ]
diff --git a/src/Format.purs b/src/Format.purs
deleted file mode 100644
index e8ab661..0000000
--- a/src/Format.purs
+++ /dev/null
@@ -1,70 +0,0 @@
-module Format
- ( number
- , string
- , unaccent
- ) where
-
-import Data.Array (replicate)
-import Data.Int (toNumber, fromNumber)
-import Data.Maybe (fromMaybe)
-import Data.String (length, joinWith, fromCharArray, toCharArray, toLower)
-import Math (round, trunc, pow)
-import Prelude
-
-number :: Int -> Number -> String
-number decimalLength num = formattedIntegerPart <> formattedDecimalPart
- where
- formattedIntegerPart =
- (if decimalLength > 0 then trunc num else round num)
- # fromNumber
- # fromMaybe 0
- # show
-
- formattedDecimalPart =
- if decimalLength > 0 then
- ((num - trunc num) * pow 10.0 (toNumber decimalLength))
- # round
- # fromNumber
- # fromMaybe 0
- # show
- # \str -> "," <> (joinWith "" $ replicate (decimalLength - length str) "0") <> str
- else
- ""
-
-string :: String -> String
-string = unaccent <<< toLower
-
-unaccent :: String -> String
-unaccent = fromCharArray <<< map unaccentChar <<< toCharArray
- where
- unaccentChar :: Char -> Char
- unaccentChar c = case c of
- 'à' -> 'a'
- 'á' -> 'a'
- 'â' -> 'a'
- 'ã' -> 'a'
- 'ä' -> 'a'
- 'ç' -> 'c'
- 'è' -> 'e'
- 'é' -> 'e'
- 'ê' -> 'e'
- 'ë' -> 'e'
- 'ì' -> 'i'
- 'í' -> 'i'
- 'î' -> 'i'
- 'ï' -> 'i'
- 'ñ' -> 'n'
- 'ò' -> 'o'
- 'ó' -> 'o'
- 'ô' -> 'o'
- 'õ' -> 'o'
- 'ö' -> 'o'
- 'š' -> 's'
- 'ù' -> 'u'
- 'ú' -> 'u'
- 'û' -> 'u'
- 'ü' -> 'u'
- 'ý' -> 'y'
- 'ÿ' -> 'y'
- 'ž' -> 'z'
- _ -> c
diff --git a/src/Indicator.purs b/src/Indicator.purs
deleted file mode 100644
index 29daa4f..0000000
--- a/src/Indicator.purs
+++ /dev/null
@@ -1,20 +0,0 @@
-module Indicator
- ( Indicator(..)
- , className
- , fromGlycemicLoad
- ) where
-
-import Prelude
-
-data Indicator = Good | Medium | Bad
-
-className :: Indicator -> String
-className Good = "good"
-className Medium = "medium"
-className Bad = "bad"
-
-fromGlycemicLoad :: Number -> Indicator
-fromGlycemicLoad n
- | n <= 8.0 = Good
- | n <= 20.0 = Medium
- | otherwise = Bad
diff --git a/src/Main.purs b/src/Main.purs
deleted file mode 100644
index 6c7fe42..0000000
--- a/src/Main.purs
+++ /dev/null
@@ -1,15 +0,0 @@
-module Main
- ( main
- ) where
-
-import Prelude
-import Control.Monad.Eff (Eff)
-import Halogen.Aff as HA
-import Halogen.VDom.Driver (runUI)
-
-import Page as Page
-
-main :: Eff (HA.HalogenEffects ()) Unit
-main = HA.runHalogenAff do
- body <- HA.awaitBody
- runUI Page.component Page.init body
diff --git a/src/Order.purs b/src/Order.purs
deleted file mode 100644
index 33c2be9..0000000
--- a/src/Order.purs
+++ /dev/null
@@ -1,54 +0,0 @@
-module Order
- ( Order
- , OrderKind(..)
- , OrderDirection(..)
- , init
- , select
- ) where
-
-import Prelude (class Eq, (==))
-import Data.Generic (class Generic, gEq)
-
-type Order =
- { kind :: OrderKind
- , direction :: OrderDirection
- }
-
-data OrderKind =
- Name
- | GlycemicIndex
- | Carbohydrates
- | GlycemicLoad
-
-derive instance genericOrderKind :: Generic OrderKind
-
-instance eqOrderKind :: Eq OrderKind where
- eq = gEq
-
-data OrderDirection =
- Ascending
- | Descending
-
-derive instance genericOrderDirection :: Generic OrderDirection
-
-instance eqOrderDirection :: Eq OrderDirection where
- eq = gEq
-
-init :: Order
-init =
- { kind: Name
- , direction: initDirection
- }
-
-select :: OrderKind -> Order -> Order
-select kind order =
- if order.kind == kind
- then order { direction = otherDirection order.direction }
- else order { kind = kind, direction = initDirection }
-
-otherDirection :: OrderDirection -> OrderDirection
-otherDirection Ascending = Descending
-otherDirection Descending = Ascending
-
-initDirection :: OrderDirection
-initDirection = Ascending
diff --git a/src/Page.purs b/src/Page.purs
deleted file mode 100644
index 40c8ddc..0000000
--- a/src/Page.purs
+++ /dev/null
@@ -1,129 +0,0 @@
-module Page
- ( component
- , Query
- , init
- ) where
-
-import Control.Monad.Aff (Aff)
-import Data.Array (sortBy, filter, reverse)
-import Data.Maybe (Maybe(..))
-import Data.String (contains, Pattern(..))
-import DOM (DOM)
-import Halogen as H
-import Halogen.HTML as HH
-import Halogen.HTML.Events as HE
-import Halogen.HTML.Properties as HP
-import Prelude
-
-import Food (Aliment)
-import Food as Food
-import Format as Format
-import Indicator as Indicator
-import Order (Order, OrderKind)
-import Order as Order
-
-data Query a =
- UpdateSearch String a
- | SelectOrder OrderKind a
-
-type State =
- { search :: String
- , order :: Order
- }
-
-init :: State
-init =
- { search: ""
- , order: Order.init
- }
-
-type Message = Unit
-
-component :: forall eff. H.Component HH.HTML Query State Message (Aff (dom :: DOM | eff))
-component =
- H.component
- { initialState: const init
- , render
- , eval
- , receiver: const Nothing
- }
- where
- render :: State -> H.ComponentHTML Query
- render state =
- HH.div
- [ HP.class_ $ HH.ClassName "page" ]
- [ renderHeader state.order.kind state.search
- , HH.div
- [ HP.class_ $ HH.ClassName "aliments" ]
- ( Food.all
- # filter (\a -> contains (Pattern $ Format.string state.search) (Format.string a.name))
- # sortBy compareAliments
- # (if state.order.direction == Order.Ascending then id else reverse)
- # map renderAliment
- )
- ]
- where
- compareAliments :: Aliment -> Aliment -> Ordering
- compareAliments a b =
- case state.order.kind of
- Order.Name -> compare (Format.string a.name) (Format.string b.name)
- Order.GlycemicIndex -> compare a.glycemicIndex b.glycemicIndex
- Order.Carbohydrates -> compare a.carbohydrates b.carbohydrates
- Order.GlycemicLoad -> compare (Food.glycemicLoad a) (Food.glycemicLoad b)
-
- eval :: Query ~> H.ComponentDSL State Query Message (Aff (dom :: DOM | eff))
- eval = case _ of
- UpdateSearch search next -> do
- state <- H.get
- H.put $ state { search = search }
- pure next
- SelectOrder kind next -> do
- state <- H.get
- H.put $ state { order = Order.select kind state.order }
- pure next
-
-renderHeader :: OrderKind -> String -> H.ComponentHTML Query
-renderHeader orderKind search =
- HH.div
- [ HP.class_ $ HH.ClassName "header" ]
- [ HH.div
- [ HP.class_ $ HH.ClassName "title line" ]
- [ button Order.Name "Aliment"
- , button Order.GlycemicIndex "Index glycémique"
- , button Order.Carbohydrates "Glucides pour 100 g"
- , button Order.GlycemicLoad "Charge glycémique"
- ]
- , HH.input
- [ HP.class_ $ HH.ClassName "search line"
- , HP.placeholder "Rechercher…"
- , HE.onValueInput (HE.input UpdateSearch)
- , HP.value search
- ]
- ]
- where
- button :: OrderKind -> String -> H.ComponentHTML Query
- button kind label =
- HH.button
- [ HE.onClick (HE.input_ (SelectOrder kind))
- , HP.class_ $ HH.ClassName (if orderKind == kind then "sorted" else "")
- ]
- [ HH.text label ]
-
-renderAliment :: Aliment -> H.ComponentHTML Query
-renderAliment aliment =
- HH.div
- [ HP.class_ $ HH.ClassName "aliment line" ]
- [ HH.div
- []
- [ HH.text aliment.name ]
- , HH.div
- [ HP.class_ $ HH.ClassName "number" ]
- [ HH.text (show aliment.glycemicIndex) ]
- , HH.div
- [ HP.class_ $ HH.ClassName "number" ]
- [ HH.text (show aliment.carbohydrates <> " g") ]
- , let glycemicLoad = Food.glycemicLoad aliment
- in HH.div
- [ HP.class_ $ HH.ClassName ("number " <> (Indicator.className $ Indicator.fromGlycemicLoad glycemicLoad)) ]
- [ HH.text (Format.number 2 glycemicLoad) ]
- ]
diff --git a/src/food.ts b/src/food.ts
new file mode 100644
index 0000000..975a900
--- /dev/null
+++ b/src/food.ts
@@ -0,0 +1,882 @@
+import * as Search from 'lib/search'
+
+export interface Aliment {
+ name: string,
+ glycemicIndex: number
+ carbohydrates: number, // for 100 grams
+}
+
+export function glycemicLoad(aliment: Aliment): number {
+ return aliment.glycemicIndex * aliment.carbohydrates / 100
+}
+
+export function search(s: string): Aliment[] {
+ return all.filter(a => Search.match(s, a.name))
+}
+
+export const all: Aliment[] =
+ [ {"name": "Abricot en conserve", "glycemicIndex": 60, "carbohydrates": 6.39},
+ {"name": "Abricot frais", "glycemicIndex": 57, "carbohydrates": 11.12},
+ {"name": "Abricot séché", "glycemicIndex": 31, "carbohydrates": 62.64},
+ {"name": "After Eight", "glycemicIndex": 50, "carbohydrates": 79.53},
+ {"name": "Agneau (coupes diverses)", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Aiglefin", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Ail cru", "glycemicIndex": 15, "carbohydrates": 33.06},
+ {"name": "Ail en poudre", "glycemicIndex": 1, "carbohydrates": 72.73},
+ {"name": "Aile de poulet rôti avec la peau", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Algue agar crue", "glycemicIndex": 15, "carbohydrates": 6.75},
+ {"name": "Algue Kombu (varech)", "glycemicIndex": 15, "carbohydrates": 9.57},
+ {"name": "Algue Nori crue", "glycemicIndex": 15, "carbohydrates": 5.11},
+ {"name": "All Bran (Kellogg's)", "glycemicIndex": 42, "carbohydrates": 76.0},
+ {"name": "Amande blanchie", "glycemicIndex": 15, "carbohydrates": 19.94},
+ {"name": "Amande non blanchie", "glycemicIndex": 15, "carbohydrates": 21.67},
+ {"name": "Amande rôtie à sec", "glycemicIndex": 20, "carbohydrates": 19.29},
+ {"name": "Amuse-gueule à base de maïs", "glycemicIndex": 72, "carbohydrates": 80.1},
+ {"name": "Amuse-gueule à base de maïs goût fromage", "glycemicIndex": 72, "carbohydrates": 51.6},
+ {"name": "Ananas", "glycemicIndex": 59, "carbohydrates": 13.12},
+ {"name": "Ananas confit", "glycemicIndex": 66, "carbohydrates": 80.0},
+ {"name": "Ananas en morceaux", "glycemicIndex": 59, "carbohydrates": 22.2},
+ {"name": "Anchois à l'huile d'olive", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Aneth (désydraté)", "glycemicIndex": 1, "carbohydrates": 55.82},
+ {"name": "Aneth (graines)", "glycemicIndex": 1, "carbohydrates": 55.17},
+ {"name": "Aneth frais", "glycemicIndex": 1, "carbohydrates": 7.02},
+ {"name": "Anguille", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Anis (graines)", "glycemicIndex": 1, "carbohydrates": 50.02},
+ {"name": "Araignée de mer", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Artichaut congelé", "glycemicIndex": 15, "carbohydrates": 9.18},
+ {"name": "Artichaut cru", "glycemicIndex": 15, "carbohydrates": 10.51},
+ {"name": "Artichaut cuit", "glycemicIndex": 15, "carbohydrates": 11.95},
+ {"name": "Asperge en conserve", "glycemicIndex": 15, "carbohydrates": 2.47},
+ {"name": "Asperge fraîche", "glycemicIndex": 15, "carbohydrates": 4.11},
+ {"name": "Aubergine", "glycemicIndex": 15, "carbohydrates": 8.73},
+ {"name": "Autruche", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Avocat", "glycemicIndex": 1, "carbohydrates": 8.53},
+ {"name": "Avoine", "glycemicIndex": 55, "carbohydrates": 66.27},
+ {"name": "Bacon cru", "glycemicIndex": 1, "carbohydrates": 0.9},
+ {"name": "Bacon de dinde", "glycemicIndex": 1, "carbohydrates": 3.1},
+ {"name": "Bacon grillé", "glycemicIndex": 1, "carbohydrates": 1.43},
+ {"name": "Banane", "glycemicIndex": 52, "carbohydrates": 22.84},
+ {"name": "Banane Plantain crue", "glycemicIndex": 70, "carbohydrates": 31.89},
+ {"name": "Banane Plantain cuite", "glycemicIndex": 70, "carbohydrates": 31.15},
+ {"name": "Bar", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Barbue de rivière élevage", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Barbue de rivière sauvage", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Basilic (déshydraté)", "glycemicIndex": 1, "carbohydrates": 60.96},
+ {"name": "Basilic frais", "glycemicIndex": 1, "carbohydrates": 2.65},
+ {"name": "Bâtonnets de poisson", "glycemicIndex": 1, "carbohydrates": 21.18},
+ {"name": "Beignet de palourde", "glycemicIndex": 1, "carbohydrates": 30.9},
+ {"name": "Beignet nature", "glycemicIndex": 76, "carbohydrates": 45.63},
+ {"name": "Beignet nature enrobé de chocolat", "glycemicIndex": 76, "carbohydrates": 51.33},
+ {"name": "Bette", "glycemicIndex": 15, "carbohydrates": 4.13},
+ {"name": "Betterave", "glycemicIndex": 64, "carbohydrates": 7.14},
+ {"name": "Beurre allégé demi-sel", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Beurre allégé doux", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Beurre doux", "glycemicIndex": 1, "carbohydrates": 0.06},
+ {"name": "Beurre fermier", "glycemicIndex": 1, "carbohydrates": 0.06},
+ {"name": "Beurre salé", "glycemicIndex": 1, "carbohydrates": 0.06},
+ {"name": "Bigorneau", "glycemicIndex": 1, "carbohydrates": 5.0},
+ {"name": "Biscuit à l'avoine", "glycemicIndex": 54, "carbohydrates": 68.7},
+ {"name": "Biscuit au sucre", "glycemicIndex": 77, "carbohydrates": 67.9},
+ {"name": "Biscuit aux figues", "glycemicIndex": 41, "carbohydrates": 70.9},
+ {"name": "Biscuit fourré au chocolat (BN)", "glycemicIndex": 52, "carbohydrates": 70.67},
+ {"name": "Biscuit petit beurre", "glycemicIndex": 51, "carbohydrates": 68.9},
+ {"name": "Bison", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Blanc de dinde rôtie", "glycemicIndex": 1, "carbohydrates": 7.7},
+ {"name": "Blanc de dinde rôtie avec la peau", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Blanc de poulet pané et frit", "glycemicIndex": 20, "carbohydrates": 12.01},
+ {"name": "Blanc de poulet rôti avec la peau", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Blanquette de veau", "glycemicIndex": 10, "carbohydrates": 3.0},
+ {"name": "Blé soufflé", "glycemicIndex": 74, "carbohydrates": 78.2},
+ {"name": "Blé soufflé givré", "glycemicIndex": 71, "carbohydrates": 86.667},
+ {"name": "Boisson aux agrumes", "glycemicIndex": 48, "carbohydrates": 11.42},
+ {"name": "Bonbon au caramel", "glycemicIndex": 36, "carbohydrates": 77.0},
+ {"name": "Bonbon enrobé de chocolat", "glycemicIndex": 43, "carbohydrates": 80.4},
+ {"name": "Bonbons à la menthe enrobés de chocolat", "glycemicIndex": 70, "carbohydrates": 80.99},
+ {"name": "Bonbons durs aux édulcorants", "glycemicIndex": 10, "carbohydrates": 98.6},
+ {"name": "Bouchées de chocolat au lait", "glycemicIndex": 38, "carbohydrates": 51.0},
+ {"name": "Boudin", "glycemicIndex": 1, "carbohydrates": 1.29},
+ {"name": "Bouillon ou consommé de bœuf (déshydraté)", "glycemicIndex": 1, "carbohydrates": 0.25},
+ {"name": "Bouillon ou consommé de poulet (déshydraté)", "glycemicIndex": 1, "carbohydrates": 0.3},
+ {"name": "Bran Flakes (Kellogg's)", "glycemicIndex": 74, "carbohydrates": 79.0},
+ {"name": "Braunschweiger", "glycemicIndex": 1, "carbohydrates": 3.1},
+ {"name": "Bretzels durs (apéritif)", "glycemicIndex": 83, "carbohydrates": 81.2},
+ {"name": "Brie", "glycemicIndex": 20, "carbohydrates": 0.45},
+ {"name": "Brioche aux raisins secs", "glycemicIndex": 68, "carbohydrates": 50.9},
+ {"name": "Brochet", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Brochette d'agneau", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Brocoli", "glycemicIndex": 15, "carbohydrates": 7.18},
+ {"name": "Bulgur cuit", "glycemicIndex": 48, "carbohydrates": 18.58},
+ {"name": "Burrito jambon et fromage", "glycemicIndex": 37, "carbohydrates": 28.1},
+ {"name": "Bœuf froid tranché (fin)", "glycemicIndex": 1, "carbohydrates": 2.59},
+ {"name": "Bœuf haché à point", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Bœuf haché cru", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Bœuf oriental, légumes et riz", "glycemicIndex": 60, "carbohydrates": 11.05},
+ {"name": "Cacahuètes salées", "glycemicIndex": 14, "carbohydrates": 21.51},
+ {"name": "Cacao en poudre", "glycemicIndex": 54, "carbohydrates": 51.39},
+ {"name": "Cacao en poudre non sucré (procédé néerlandais)", "glycemicIndex": 51, "carbohydrates": 58.3},
+ {"name": "Café", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Café décaféiné", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Café expresso", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Café instantané", "glycemicIndex": 1, "carbohydrates": 41.1},
+ {"name": "Caille", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Calmar", "glycemicIndex": 1, "carbohydrates": 7.79},
+ {"name": "Camembert", "glycemicIndex": 20, "carbohydrates": 0.46},
+ {"name": "Canard rôti avec la peau", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Canneberge séchée sucrée", "glycemicIndex": 52, "carbohydrates": 82.36},
+ {"name": "Cannelle en poudre", "glycemicIndex": 1, "carbohydrates": 80.59},
+ {"name": "Câpres", "glycemicIndex": 1, "carbohydrates": 4.89},
+ {"name": "Caramel", "glycemicIndex": 58, "carbohydrates": 91.6},
+ {"name": "Caramel à tartiner", "glycemicIndex": 36, "carbohydrates": 65.9},
+ {"name": "Cardamome en poudre", "glycemicIndex": 1, "carbohydrates": 68.47},
+ {"name": "Cardon", "glycemicIndex": 15, "carbohydrates": 5.33},
+ {"name": "Cari en poudre", "glycemicIndex": 1, "carbohydrates": 58.15},
+ {"name": "Carotte crue", "glycemicIndex": 16, "carbohydrates": 9.58},
+ {"name": "Carotte cuite", "glycemicIndex": 47, "carbohydrates": 8.22},
+ {"name": "Carpe", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Carvi (graines)", "glycemicIndex": 1, "carbohydrates": 49.9},
+ {"name": "Cassis", "glycemicIndex": 28, "carbohydrates": 15.38},
+ {"name": "Cassonade", "glycemicIndex": 70, "carbohydrates": 98.09},
+ {"name": "Caviar", "glycemicIndex": 1, "carbohydrates": 4.0},
+ {"name": "Céleri (graines)", "glycemicIndex": 1, "carbohydrates": 41.35},
+ {"name": "Céleri cru", "glycemicIndex": 15, "carbohydrates": 2.97},
+ {"name": "Céleri cuit", "glycemicIndex": 15, "carbohydrates": 4.0},
+ {"name": "Céleri-rave cru", "glycemicIndex": 15, "carbohydrates": 9.2},
+ {"name": "Céleri-rave cuit", "glycemicIndex": 15, "carbohydrates": 5.9},
+ {"name": "Céréales Nesquik", "glycemicIndex": 84, "carbohydrates": 90.0},
+ {"name": "Céréales Weetabix", "glycemicIndex": 74, "carbohydrates": 82.857},
+ {"name": "Cerfeuil (déshydraté)", "glycemicIndex": 1, "carbohydrates": 49.1},
+ {"name": "Cerise", "glycemicIndex": 63, "carbohydrates": 12.18},
+ {"name": "Cerise en conserve", "glycemicIndex": 63, "carbohydrates": 8.94},
+ {"name": "Cerise guigne", "glycemicIndex": 63, "carbohydrates": 16.01},
+ {"name": "Cerise guigne en conserve", "glycemicIndex": 63, "carbohydrates": 11.76},
+ {"name": "Cerises au marasquin", "glycemicIndex": 60, "carbohydrates": 41.97},
+ {"name": "Cervelas", "glycemicIndex": 1, "carbohydrates": 3.33},
+ {"name": "Cervelle d'agneau", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Cervelle de bœuf", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Cervelle de veau", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Champignon", "glycemicIndex": 15, "carbohydrates": 5.29},
+ {"name": "Champignon de Paris (conserve)", "glycemicIndex": 15, "carbohydrates": 5.09},
+ {"name": "Champignon de Paris cru", "glycemicIndex": 15, "carbohydrates": 3.28},
+ {"name": "Champignon enoki cru", "glycemicIndex": 15, "carbohydrates": 7.68},
+ {"name": "Chapon rôti", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Châtaigne", "glycemicIndex": 40, "carbohydrates": 44.17},
+ {"name": "Chausson à la viande", "glycemicIndex": 28, "carbohydrates": 3.9},
+ {"name": "Cheerios", "glycemicIndex": 74, "carbohydrates": 73.33},
+ {"name": "Cheval", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Chèvre", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Chevreuil", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Chewing gum sans sucre", "glycemicIndex": 10, "carbohydrates": 94.8},
+ {"name": "Chili con carne (conserve)", "glycemicIndex": 43, "carbohydrates": 11.43},
+ {"name": "Chili en poudre", "glycemicIndex": 1, "carbohydrates": 54.66},
+ {"name": "Chipolata", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Chips goût barbecue", "glycemicIndex": 54, "carbohydrates": 52.8},
+ {"name": "Chocolat au lait", "glycemicIndex": 49, "carbohydrates": 8.98},
+ {"name": "Chocolat au lait et riz soufflé", "glycemicIndex": 43, "carbohydrates": 59.67},
+ {"name": "Chocolat chaud (poudre)", "glycemicIndex": 36, "carbohydrates": 83.73},
+ {"name": "Chocolat chaud maison", "glycemicIndex": 45, "carbohydrates": 10.74},
+ {"name": "Chocolat liquide", "glycemicIndex": 31, "carbohydrates": 36.2},
+ {"name": "Chorizo", "glycemicIndex": 1, "carbohydrates": 1.86},
+ {"name": "Chou cavalier cru", "glycemicIndex": 15, "carbohydrates": 5.69},
+ {"name": "Chou cavalier cuit", "glycemicIndex": 15, "carbohydrates": 4.91},
+ {"name": "Chou cru", "glycemicIndex": 15, "carbohydrates": 5.8},
+ {"name": "Chou cuit", "glycemicIndex": 15, "carbohydrates": 5.51},
+ {"name": "Chou de Chine cru", "glycemicIndex": 15, "carbohydrates": 3.23},
+ {"name": "Chou de Chine cuit", "glycemicIndex": 15, "carbohydrates": 2.41},
+ {"name": "Chou en salade", "glycemicIndex": 15, "carbohydrates": 12.41},
+ {"name": "Chou gras cru", "glycemicIndex": 15, "carbohydrates": 7.3},
+ {"name": "Chou gras cuit", "glycemicIndex": 15, "carbohydrates": 5.0},
+ {"name": "Chou rouge cru", "glycemicIndex": 15, "carbohydrates": 7.37},
+ {"name": "Chou rouge cuit", "glycemicIndex": 15, "carbohydrates": 6.94},
+ {"name": "Chou vert frisé congelé", "glycemicIndex": 15, "carbohydrates": 4.9},
+ {"name": "Chou vert frisé cru", "glycemicIndex": 15, "carbohydrates": 10.01},
+ {"name": "Chou vert frisé cuit", "glycemicIndex": 15, "carbohydrates": 5.63},
+ {"name": "Chou-fleur", "glycemicIndex": 15, "carbohydrates": 4.11},
+ {"name": "Chou-fleur cru", "glycemicIndex": 15, "carbohydrates": 4.97},
+ {"name": "Chou-rave cru", "glycemicIndex": 15, "carbohydrates": 6.2},
+ {"name": "Chou-rave cuit", "glycemicIndex": 15, "carbohydrates": 6.69},
+ {"name": "Choucroute (conserve)", "glycemicIndex": 15, "carbohydrates": 4.28},
+ {"name": "Choux de Bruxelles", "glycemicIndex": 15, "carbohydrates": 7.1},
+ {"name": "Ciboulette", "glycemicIndex": 15, "carbohydrates": 4.35},
+ {"name": "Ciboulette lyophilisée", "glycemicIndex": 15, "carbohydrates": 64.29},
+ {"name": "Citron", "glycemicIndex": 28, "carbohydrates": 9.32},
+ {"name": "Citrouille", "glycemicIndex": 75, "carbohydrates": 8.09},
+ {"name": "Clou de girofle en poudre", "glycemicIndex": 1, "carbohydrates": 61.21},
+ {"name": "Coing", "glycemicIndex": 35, "carbohydrates": 6.3},
+ {"name": "Cola", "glycemicIndex": 58, "carbohydrates": 9.56},
+ {"name": "Cola allégé", "glycemicIndex": 1, "carbohydrates": 0.29},
+ {"name": "Cola décaféiné", "glycemicIndex": 1, "carbohydrates": 10.58},
+ {"name": "Colin", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Comté", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Concombre cru", "glycemicIndex": 15, "carbohydrates": 3.63},
+ {"name": "Confiture allégée", "glycemicIndex": 40, "carbohydrates": 53.6},
+ {"name": "Confiture d'abricot", "glycemicIndex": 55, "carbohydrates": 64.4},
+ {"name": "Confiture de fruit", "glycemicIndex": 55, "carbohydrates": 68.86},
+ {"name": "Conque", "glycemicIndex": 1, "carbohydrates": 1.7},
+ {"name": "Coquille à taco cuite", "glycemicIndex": 68, "carbohydrates": 62.72},
+ {"name": "Coquille St-Jacques", "glycemicIndex": 1, "carbohydrates": 10.13},
+ {"name": "Coriandre (brins)", "glycemicIndex": 15, "carbohydrates": 3.67},
+ {"name": "Coriandre (graines)", "glycemicIndex": 1, "carbohydrates": 54.99},
+ {"name": "Corn Flakes", "glycemicIndex": 81, "carbohydrates": 86.2},
+ {"name": "Corn Pops", "glycemicIndex": 80, "carbohydrates": 90.5},
+ {"name": "Corned beef", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Cornet de glace à la vanille", "glycemicIndex": 61, "carbohydrates": 26.36},
+ {"name": "Cornichons au vinaigre", "glycemicIndex": 15, "carbohydrates": 2.26},
+ {"name": "Cornichons sucrés", "glycemicIndex": 15, "carbohydrates": 21.15},
+ {"name": "Côte de veau", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Courge", "glycemicIndex": 15, "carbohydrates": 14.34},
+ {"name": "Courgette crue", "glycemicIndex": 15, "carbohydrates": 3.11},
+ {"name": "Courgette cuite", "glycemicIndex": 15, "carbohydrates": 2.69},
+ {"name": "Couscous cuit", "glycemicIndex": 65, "carbohydrates": 23.22},
+ {"name": "Couscous sec", "glycemicIndex": 65, "carbohydrates": 77.43},
+ {"name": "Crabe rouge", "glycemicIndex": 1, "carbohydrates": 1.43},
+ {"name": "crème fouettée fraîche", "glycemicIndex": 1, "carbohydrates": 2.84583},
+ {"name": "Crème fouettée (bombe)", "glycemicIndex": 30, "carbohydrates": 12.49},
+ {"name": "Crème glacée à la fraise", "glycemicIndex": 61, "carbohydrates": 27.6},
+ {"name": "Crème glacée à la vanille", "glycemicIndex": 38, "carbohydrates": 22.29},
+ {"name": "Crème glacée au chocolat", "glycemicIndex": 61, "carbohydrates": 28.2},
+ {"name": "Crêpe au beurre", "glycemicIndex": 80, "carbohydrates": 39.18},
+ {"name": "Crêpe nature (prête-à-manger)", "glycemicIndex": 67, "carbohydrates": 39.29},
+ {"name": "Crêpe nature maison", "glycemicIndex": 67, "carbohydrates": 28.3},
+ {"name": "Cresson cru", "glycemicIndex": 15, "carbohydrates": 5.5},
+ {"name": "Cresson cuit", "glycemicIndex": 15, "carbohydrates": 3.8},
+ {"name": "Cresson de fontaine cru", "glycemicIndex": 15, "carbohydrates": 1.29},
+ {"name": "Crevette", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Crevette panée et frite", "glycemicIndex": 1, "carbohydrates": 11.47},
+ {"name": "Crispix", "glycemicIndex": 87, "carbohydrates": 87.2},
+ {"name": "Croissant", "glycemicIndex": 67, "carbohydrates": 45.8},
+ {"name": "Croissant au jambon", "glycemicIndex": 50, "carbohydrates": 23.1},
+ {"name": "Croquette de dinde panée", "glycemicIndex": 1, "carbohydrates": 15.7},
+ {"name": "Croustilles de maïs (snack)", "glycemicIndex": 42, "carbohydrates": 63.01},
+ {"name": "Cubes de veau (pour ragout)", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Cuisse de dinde rôtie avec la peau", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Cuisse de faisan", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Cuisse de porc rôtie", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Cuisse de poulet bouilli avec la peau", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Cuisse de poulet rôti avec la peau", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Cuisses de grenouille", "glycemicIndex": 1, "carbohydrates": 18.0},
+ {"name": "Cumin (graines)", "glycemicIndex": 1, "carbohydrates": 44.24},
+ {"name": "Curcuma en poudre", "glycemicIndex": 1, "carbohydrates": 64.93},
+ {"name": "Cœur d'agneau", "glycemicIndex": 1, "carbohydrates": 1.93},
+ {"name": "Cœur de bœuf", "glycemicIndex": 1, "carbohydrates": 0.15},
+ {"name": "Cœur de veau", "glycemicIndex": 1, "carbohydrates": 0.13},
+ {"name": "Cœurs de palmier (conserve)", "glycemicIndex": 15, "carbohydrates": 4.62},
+ {"name": "Cœurs de palmier crus", "glycemicIndex": 15, "carbohydrates": 25.61},
+ {"name": "Datte séchée", "glycemicIndex": 103, "carbohydrates": 75.03},
+ {"name": "Dinde rôtie avec la peau", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Double hamburger", "glycemicIndex": 65, "carbohydrates": 11.04},
+ {"name": "Double hamburger au fromage", "glycemicIndex": 65, "carbohydrates": 15.37},
+ {"name": "Dragée", "glycemicIndex": 38, "carbohydrates": 68.26},
+ {"name": "Eau du robinet", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Échalote crue", "glycemicIndex": 15, "carbohydrates": 16.8},
+ {"name": "Échalote lyophilisée", "glycemicIndex": 15, "carbohydrates": 80.7},
+ {"name": "Écrevisse", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Edam", "glycemicIndex": 20, "carbohydrates": 1.43},
+ {"name": "Émeu", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Emmental", "glycemicIndex": 20, "carbohydrates": 5.38},
+ {"name": "Endive", "glycemicIndex": 15, "carbohydrates": 4.0},
+ {"name": "Épaule d'agneau grillée", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Epaule de porc", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Epaule de porc rôtie", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Éperlan", "glycemicIndex": 1, "carbohydrates": 12.11},
+ {"name": "Épinard (conserve)", "glycemicIndex": 15, "carbohydrates": 2.92},
+ {"name": "Épinard congelé", "glycemicIndex": 15, "carbohydrates": 4.8},
+ {"name": "Épinard cru", "glycemicIndex": 15, "carbohydrates": 3.63},
+ {"name": "Épinard cuit", "glycemicIndex": 15, "carbohydrates": 3.75},
+ {"name": "Escalope de veau", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Escargot cru", "glycemicIndex": 1, "carbohydrates": 2.0},
+ {"name": "Espadon", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Estragon (déshydraté)", "glycemicIndex": 1, "carbohydrates": 50.22},
+ {"name": "Esturgeon", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Esturgeon fumé", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Farine de blé à pain", "glycemicIndex": 71, "carbohydrates": 69.406},
+ {"name": "Farine de blé à gâteau", "glycemicIndex": 71, "carbohydrates": 74.79},
+ {"name": "Farine de blé avec levure", "glycemicIndex": 71, "carbohydrates": 74.22},
+ {"name": "Farine de blé complète", "glycemicIndex": 69, "carbohydrates": 68.509},
+ {"name": "Farine de maïs", "glycemicIndex": 69, "carbohydrates": 76.85},
+ {"name": "Farine de pois chiches", "glycemicIndex": 55, "carbohydrates": 0.18},
+ {"name": "Farine de seigle", "glycemicIndex": 39, "carbohydrates": 77.49},
+ {"name": "Fenouil (graines)", "glycemicIndex": 1, "carbohydrates": 52.29},
+ {"name": "Fenouil cru", "glycemicIndex": 15, "carbohydrates": 7.29},
+ {"name": "Fenugrec (graines)", "glycemicIndex": 1, "carbohydrates": 58.35},
+ {"name": "Féta", "glycemicIndex": 20, "carbohydrates": 4.09},
+ {"name": "Feuilles de pissenlit crues", "glycemicIndex": 15, "carbohydrates": 9.2},
+ {"name": "Feuilles de pissenlit cuites", "glycemicIndex": 15, "carbohydrates": 6.4},
+ {"name": "Fève de café enrobée de chocolat noir", "glycemicIndex": 33, "carbohydrates": 59.95},
+ {"name": "Fèves de soja cuites", "glycemicIndex": 30, "carbohydrates": 11.05},
+ {"name": "Fèves de soja germées à la vapeur", "glycemicIndex": 30, "carbohydrates": 6.53},
+ {"name": "Fèves de soja germées sautées", "glycemicIndex": 30, "carbohydrates": 9.4},
+ {"name": "Figue", "glycemicIndex": 28, "carbohydrates": 19.18},
+ {"name": "Figue sèche", "glycemicIndex": 61, "carbohydrates": 63.87},
+ {"name": "Filet de poisson pané", "glycemicIndex": 38, "carbohydrates": 16.97},
+ {"name": "Flan à la noix de coco", "glycemicIndex": 44, "carbohydrates": 91.2},
+ {"name": "Flan à la vanille", "glycemicIndex": 44, "carbohydrates": 22.6},
+ {"name": "Flan au caramel préparé (sachet)", "glycemicIndex": 38, "carbohydrates": 18.82},
+ {"name": "Flan au chocolat", "glycemicIndex": 44, "carbohydrates": 23.01},
+ {"name": "Flan au citron", "glycemicIndex": 44, "carbohydrates": 20.2},
+ {"name": "Flan pâtissier", "glycemicIndex": 65, "carbohydrates": 20.8},
+ {"name": "Flan pâtissier préparé (sachet)", "glycemicIndex": 38, "carbohydrates": 17.61},
+ {"name": "Flétan", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Flétan noir", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Flocons de maïs", "glycemicIndex": 81, "carbohydrates": 86.667},
+ {"name": "Flocons de maïs givrés", "glycemicIndex": 55, "carbohydrates": 90.0},
+ {"name": "Foie d'agneau", "glycemicIndex": 1, "carbohydrates": 3.78},
+ {"name": "Foie de bœuf", "glycemicIndex": 1, "carbohydrates": 5.13},
+ {"name": "Foie de morue", "glycemicIndex": 1, "carbohydrates": 6.0},
+ {"name": "Foie de porc", "glycemicIndex": 1, "carbohydrates": 3.76},
+ {"name": "Foie de veau", "glycemicIndex": 1, "carbohydrates": 4.47},
+ {"name": "Fondue savoyarde", "glycemicIndex": 20, "carbohydrates": 3.77},
+ {"name": "Fraise", "glycemicIndex": 40, "carbohydrates": 7.68},
+ {"name": "Framboise", "glycemicIndex": 26, "carbohydrates": 11.94},
+ {"name": "Frites", "glycemicIndex": 75, "carbohydrates": 37.51},
+ {"name": "Fromage allégé", "glycemicIndex": 20, "carbohydrates": 4.0},
+ {"name": "Fromage bleu", "glycemicIndex": 20, "carbohydrates": 2.34},
+ {"name": "Fromage de chèvre demi-sec", "glycemicIndex": 20, "carbohydrates": 2.54},
+ {"name": "Fromage de chèvre frais", "glycemicIndex": 20, "carbohydrates": 0.89},
+ {"name": "Fromage de chèvre sec", "glycemicIndex": 20, "carbohydrates": 2.17},
+ {"name": "Fromage de tête", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Fromage fondu", "glycemicIndex": 20, "carbohydrates": 2.1},
+ {"name": "Froot Loops", "glycemicIndex": 69, "carbohydrates": 89.1},
+ {"name": "Fruits au sirop (conserve)", "glycemicIndex": 55, "carbohydrates": 8.51},
+ {"name": "Galette de riz", "glycemicIndex": 78, "carbohydrates": 81.5},
+ {"name": "Galettes de maïs", "glycemicIndex": 55, "carbohydrates": 83.4},
+ {"name": "Gâteau au fromage blanc", "glycemicIndex": 45, "carbohydrates": 34.0},
+ {"name": "Gâteau de riz", "glycemicIndex": 59, "carbohydrates": 19.4},
+ {"name": "Gauffre nature", "glycemicIndex": 76, "carbohydrates": 32.9},
+ {"name": "Gaufrette fourrée", "glycemicIndex": 77, "carbohydrates": 70.1},
+ {"name": "Gelée de fruit", "glycemicIndex": 78, "carbohydrates": 69.95},
+ {"name": "Gésier de poulet mijoté", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Gigot d'agneau", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Gingembre (racine)", "glycemicIndex": 15, "carbohydrates": 17.77},
+ {"name": "Gingembre confit", "glycemicIndex": 10, "carbohydrates": 87.1},
+ {"name": "Gingembre en poudre", "glycemicIndex": 1, "carbohydrates": 70.79},
+ {"name": "Gingembre frais", "glycemicIndex": 10, "carbohydrates": 44.6},
+ {"name": "Golden Grahams", "glycemicIndex": 71, "carbohydrates": 83.333},
+ {"name": "Gouda", "glycemicIndex": 20, "carbohydrates": 2.22},
+ {"name": "Goyave", "glycemicIndex": 63, "carbohydrates": 14.32},
+ {"name": "Graine de courge rôtie", "glycemicIndex": 20, "carbohydrates": 14.71},
+ {"name": "Graine de sésame grillée", "glycemicIndex": 15, "carbohydrates": 25.74},
+ {"name": "Graine de soja rôtie", "glycemicIndex": 15, "carbohydrates": 33.55},
+ {"name": "Graine de tournesol grillée", "glycemicIndex": 20, "carbohydrates": 20.59},
+ {"name": "Graine de tournesol séchée", "glycemicIndex": 15, "carbohydrates": 20.0},
+ {"name": "Graisse de bœuf", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Graisse de canard", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Graisse de mouton", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Graisse de porc (saindoux)", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Gratin de pommes de terre", "glycemicIndex": 70, "carbohydrates": 11.27},
+ {"name": "Grenade", "glycemicIndex": 53, "carbohydrates": 18.7},
+ {"name": "Groseille", "glycemicIndex": 28, "carbohydrates": 13.8},
+ {"name": "Groseille à maquereau", "glycemicIndex": 28, "carbohydrates": 10.18},
+ {"name": "Gruyère", "glycemicIndex": 20, "carbohydrates": 0.36},
+ {"name": "Guimauves", "glycemicIndex": 70, "carbohydrates": 81.3},
+ {"name": "Hamburger", "glycemicIndex": 65, "carbohydrates": 18.02},
+ {"name": "Hamburger au fromage", "glycemicIndex": 65, "carbohydrates": 21.2},
+ {"name": "Hamburger au poisson et fromage", "glycemicIndex": 66, "carbohydrates": 26.03},
+ {"name": "Hareng fumé", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Hareng grillé", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Hareng mariné", "glycemicIndex": 1, "carbohydrates": 9.64},
+ {"name": "Haricots beurre crus", "glycemicIndex": 15, "carbohydrates": 60.7},
+ {"name": "Haricots beurre cuits", "glycemicIndex": 15, "carbohydrates": 25.27},
+ {"name": "Haricots blancs (conserve)", "glycemicIndex": 40, "carbohydrates": 21.14},
+ {"name": "Haricots blancs crus", "glycemicIndex": 15, "carbohydrates": 13.05},
+ {"name": "Haricots blancs cuits", "glycemicIndex": 15, "carbohydrates": 15.01},
+ {"name": "Haricots blancs maison", "glycemicIndex": 40, "carbohydrates": 21.63},
+ {"name": "Haricots blancs petits (conserve)", "glycemicIndex": 48, "carbohydrates": 20.45},
+ {"name": "Haricots de lima", "glycemicIndex": 38, "carbohydrates": 23.64},
+ {"name": "Haricots de lima (conserve)", "glycemicIndex": 38, "carbohydrates": 13.33},
+ {"name": "Haricots mungo germés crus", "glycemicIndex": 15, "carbohydrates": 5.94},
+ {"name": "Haricots mungo germés cuits", "glycemicIndex": 15, "carbohydrates": 4.19},
+ {"name": "Haricots pinto (conserve)", "glycemicIndex": 45, "carbohydrates": 15.25},
+ {"name": "Haricots pinto cuits", "glycemicIndex": 42, "carbohydrates": 30.88},
+ {"name": "Haricots roses", "glycemicIndex": 28, "carbohydrates": 27.91},
+ {"name": "Haricots rouges (conserve)", "glycemicIndex": 39, "carbohydrates": 15.54},
+ {"name": "Haricots rouges maison", "glycemicIndex": 39, "carbohydrates": 22.41},
+ {"name": "Haricots verts", "glycemicIndex": 15, "carbohydrates": 3.0},
+ {"name": "Homard d'Amérique", "glycemicIndex": 1, "carbohydrates": 1.28},
+ {"name": "Hoummos maison", "glycemicIndex": 6, "carbohydrates": 20.12},
+ {"name": "Huile d'arachide", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Huile d'avocat", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Huile d'olive", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Huile de carthame riche en acide linoléique", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Huile de carthame riche en acide oléique", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Huile de colza", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Huile de germe de blé", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Huile de lin", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Huile de maïs", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Huile de noisette", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Huile de noix", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Huile de noix de coco", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Huile de palme", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Huile de palmiste", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Huile de pépins de raisin", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Huile de sésame", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Huile de soja", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Huile de tournesol", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Huître crue", "glycemicIndex": 1, "carbohydrates": 3.91},
+ {"name": "Huître cuite", "glycemicIndex": 1, "carbohydrates": 7.82},
+ {"name": "Huître panée et frite", "glycemicIndex": 1, "carbohydrates": 11.62},
+ {"name": "Igname", "glycemicIndex": 15, "carbohydrates": 27.48},
+ {"name": "Jambon", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Jambon de dinde", "glycemicIndex": 1, "carbohydrates": 4.21},
+ {"name": "Jambon haché", "glycemicIndex": 1, "carbohydrates": 1.84},
+ {"name": "Jambon tranché", "glycemicIndex": 1, "carbohydrates": 3.83},
+ {"name": "Jus d'ananas", "glycemicIndex": 46, "carbohydrates": 44.3},
+ {"name": "Jus d'orange", "glycemicIndex": 52, "carbohydrates": 10.4},
+ {"name": "Jus d'orange et de pamplemousse", "glycemicIndex": 45, "carbohydrates": 10.28},
+ {"name": "Jus de carotte", "glycemicIndex": 43, "carbohydrates": 4.7},
+ {"name": "Jus de citron", "glycemicIndex": 15, "carbohydrates": 8.63},
+ {"name": "Jus de mandarine", "glycemicIndex": 50, "carbohydrates": 10.1},
+ {"name": "Jus de pamplemousse", "glycemicIndex": 48, "carbohydrates": 11.13},
+ {"name": "Jus de pomme", "glycemicIndex": 40, "carbohydrates": 11.3},
+ {"name": "Jus de tomate", "glycemicIndex": 38, "carbohydrates": 4.93},
+ {"name": "Kaki", "glycemicIndex": 63, "carbohydrates": 18.59},
+ {"name": "Kit Kat", "glycemicIndex": 43, "carbohydrates": 64.59},
+ {"name": "Kiwi", "glycemicIndex": 53, "carbohydrates": 14.66},
+ {"name": "Kumquat", "glycemicIndex": 40, "carbohydrates": 15.9},
+ {"name": "Lait concentré sucré", "glycemicIndex": 61, "carbohydrates": 54.4},
+ {"name": "Lait de chèvre", "glycemicIndex": 30, "carbohydrates": 4.45},
+ {"name": "Lait demi-écrémé 1% mat.gr.", "glycemicIndex": 30, "carbohydrates": 4.99},
+ {"name": "Lait demi-écrémé 2% mat. gr.", "glycemicIndex": 30, "carbohydrates": 4.8},
+ {"name": "Lait écrémé", "glycemicIndex": 32, "carbohydrates": 4.96},
+ {"name": "Lait écrémé (poudre)", "glycemicIndex": 35, "carbohydrates": 51.98},
+ {"name": "Lait écrémé instantané (poudre)", "glycemicIndex": 32, "carbohydrates": 52.19},
+ {"name": "Lait entier", "glycemicIndex": 27, "carbohydrates": 4.8},
+ {"name": "Lait entier (au chocolat)", "glycemicIndex": 53, "carbohydrates": 10.34},
+ {"name": "Lait entier (poudre)", "glycemicIndex": 27, "carbohydrates": 38.42},
+ {"name": "Lait fermenté bifidus nature", "glycemicIndex": 25, "carbohydrates": 5.4},
+ {"name": "Lait fermier", "glycemicIndex": 27, "carbohydrates": 4.65},
+ {"name": "Laitue pommée", "glycemicIndex": 15, "carbohydrates": 2.97},
+ {"name": "Laitue romaine", "glycemicIndex": 15, "carbohydrates": 3.29},
+ {"name": "Laitue-tige", "glycemicIndex": 15, "carbohydrates": 3.65},
+ {"name": "Langouste", "glycemicIndex": 1, "carbohydrates": 3.12},
+ {"name": "Langue de bœuf", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Langue de bœuf en conserve", "glycemicIndex": 1, "carbohydrates": 0.3},
+ {"name": "Langue de veau", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Lapin mijoté", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Lapin rôti", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Laurier (feuille)", "glycemicIndex": 1, "carbohydrates": 74.97},
+ {"name": "Lentilles", "glycemicIndex": 30, "carbohydrates": 20.13},
+ {"name": "Lièvre", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Limonade", "glycemicIndex": 58, "carbohydrates": 0.0},
+ {"name": "Limonade au citron", "glycemicIndex": 58, "carbohydrates": 10.14},
+ {"name": "Lin (graine moulue)", "glycemicIndex": 28, "carbohydrates": 28.88},
+ {"name": "Lingue", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Litchi", "glycemicIndex": 57, "carbohydrates": 16.53},
+ {"name": "Litchi séché", "glycemicIndex": 79, "carbohydrates": 70.7},
+ {"name": "Longe de porc braisée", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Loup", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "M & M's ( marron)", "glycemicIndex": 33, "carbohydrates": 71.19},
+ {"name": "M & M's (jaune)", "glycemicIndex": 33, "carbohydrates": 60.48},
+ {"name": "Macaron", "glycemicIndex": 51, "carbohydrates": 72.45},
+ {"name": "Macaroni au blé complet", "glycemicIndex": 47, "carbohydrates": 26.54},
+ {"name": "Macédoine de légumes (congelée)", "glycemicIndex": 15, "carbohydrates": 13.46},
+ {"name": "Macédoine de légumes (conserve)", "glycemicIndex": 15, "carbohydrates": 7.13},
+ {"name": "Mâche", "glycemicIndex": 15, "carbohydrates": 3.6},
+ {"name": "Maïs doux", "glycemicIndex": 54, "carbohydrates": 20.98},
+ {"name": "Maïs doux (congelé)", "glycemicIndex": 54, "carbohydrates": 22.33},
+ {"name": "Maïs doux (conserve)", "glycemicIndex": 54, "carbohydrates": 15.41},
+ {"name": "Maïs doux cru", "glycemicIndex": 54, "carbohydrates": 18.7},
+ {"name": "Maïs soufflé givré", "glycemicIndex": 80, "carbohydrates": 90.0},
+ {"name": "Maïs, beignet", "glycemicIndex": 75, "carbohydrates": 38.623},
+ {"name": "Mandarine", "glycemicIndex": 30, "carbohydrates": 13.34},
+ {"name": "Mangue", "glycemicIndex": 51, "carbohydrates": 17.0},
+ {"name": "Manioc", "glycemicIndex": 15, "carbohydrates": 38.06},
+ {"name": "Maquereau", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Maquereau espagnol", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Maquereau salé", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Marjolaine (déshydratée)", "glycemicIndex": 1, "carbohydrates": 60.56},
+ {"name": "Marmelade d'orange", "glycemicIndex": 55, "carbohydrates": 66.3},
+ {"name": "Mars", "glycemicIndex": 65, "carbohydrates": 71.17},
+ {"name": "Mars aux amandes", "glycemicIndex": 65, "carbohydrates": 62.7},
+ {"name": "Mayonnaise commerciale", "glycemicIndex": 1, "carbohydrates": 3.16},
+ {"name": "Mayonnaise commerciale allégée", "glycemicIndex": 1, "carbohydrates": 23.9},
+ {"name": "Melon", "glycemicIndex": 67, "carbohydrates": 8.16},
+ {"name": "Menthe poivrée fraîche", "glycemicIndex": 1, "carbohydrates": 14.89},
+ {"name": "Menthe verte déshydratée", "glycemicIndex": 1, "carbohydrates": 52.04},
+ {"name": "Menthe verte fraîche", "glycemicIndex": 1, "carbohydrates": 8.41},
+ {"name": "Merlan (lieu noir)", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Mérou", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Mets composés, mini ravioli au boeuf, sauce aux tomates et viande, conserve", "glycemicIndex": 39, "carbohydrates": 12.36},
+ {"name": "Miel", "glycemicIndex": 55, "carbohydrates": 82.4},
+ {"name": "Milky Way", "glycemicIndex": 44, "carbohydrates": 71.22},
+ {"name": "Millet cuit", "glycemicIndex": 71, "carbohydrates": 23.67},
+ {"name": "Mirabelle", "glycemicIndex": 39, "carbohydrates": 12.0},
+ {"name": "Morbier", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Mortadelle", "glycemicIndex": 1, "carbohydrates": 3.05},
+ {"name": "Morue Atlantique", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Morue charbonnière cuite", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Morue charbonnière fumée", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Morue fumée", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Morue salée", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Moule crue", "glycemicIndex": 1, "carbohydrates": 3.69},
+ {"name": "Moule cuite", "glycemicIndex": 1, "carbohydrates": 7.39},
+ {"name": "Mousse d'Irlande crue (algue)", "glycemicIndex": 15, "carbohydrates": 12.29},
+ {"name": "Moutarde brune", "glycemicIndex": 1, "carbohydrates": 5.3},
+ {"name": "Moutarde jaune", "glycemicIndex": 1, "carbohydrates": 5.33},
+ {"name": "Moutarde jaune (graines)", "glycemicIndex": 1, "carbohydrates": 28.09},
+ {"name": "Mozarella", "glycemicIndex": 20, "carbohydrates": 2.47},
+ {"name": "Mozzarella", "glycemicIndex": 20, "carbohydrates": 2.19},
+ {"name": "Muesli (weetabix)", "glycemicIndex": 55, "carbohydrates": 71.0},
+ {"name": "Mufffin aux raisins", "glycemicIndex": 50, "carbohydrates": 48.1},
+ {"name": "Muffin nature", "glycemicIndex": 77, "carbohydrates": 44.17},
+ {"name": "Mulet", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Munster", "glycemicIndex": 20, "carbohydrates": 1.12},
+ {"name": "Mure au sirop", "glycemicIndex": 60, "carbohydrates": 23.1},
+ {"name": "Mure fraîche", "glycemicIndex": 40, "carbohydrates": 9.61},
+ {"name": "Muscade en poudre", "glycemicIndex": 1, "carbohydrates": 49.29},
+ {"name": "Myrtille", "glycemicIndex": 28, "carbohydrates": 14.49},
+ {"name": "Navet", "glycemicIndex": 15, "carbohydrates": 6.43},
+ {"name": "Navet", "glycemicIndex": 15, "carbohydrates": 6.43},
+ {"name": "Nectar de papaye", "glycemicIndex": 60, "carbohydrates": 14.51},
+ {"name": "Nectar de pêche", "glycemicIndex": 55, "carbohydrates": 13.92},
+ {"name": "Nectar de poire", "glycemicIndex": 44, "carbohydrates": 15.76},
+ {"name": "Nectarine", "glycemicIndex": 43, "carbohydrates": 10.55},
+ {"name": "Nèfle du Japon", "glycemicIndex": 28, "carbohydrates": 12.14},
+ {"name": "Neufchatel", "glycemicIndex": 20, "carbohydrates": 3.59},
+ {"name": "Noisette", "glycemicIndex": 20, "carbohydrates": 17.6},
+ {"name": "Noix de Brésil", "glycemicIndex": 15, "carbohydrates": 12.27},
+ {"name": "Noix de cajou rôtie à sec", "glycemicIndex": 22, "carbohydrates": 32.69},
+ {"name": "Noix de coco crue", "glycemicIndex": 40, "carbohydrates": 15.23},
+ {"name": "Noix de Grenoble", "glycemicIndex": 15, "carbohydrates": 13.71},
+ {"name": "Noix de macadamia", "glycemicIndex": 15, "carbohydrates": 14.22},
+ {"name": "Noix de Pécan", "glycemicIndex": 20, "carbohydrates": 14.04},
+ {"name": "Noix de Pécan rôtie à sec", "glycemicIndex": 20, "carbohydrates": 13.72},
+ {"name": "Nougat", "glycemicIndex": 32, "carbohydrates": 92.39},
+ {"name": "Nouilles chinoises", "glycemicIndex": 61, "carbohydrates": 57.54},
+ {"name": "Nouilles de riz cuites", "glycemicIndex": 60, "carbohydrates": 24.9},
+ {"name": "Oeuf à la coque", "glycemicIndex": 1, "carbohydrates": 1.85},
+ {"name": "Oeuf au plat", "glycemicIndex": 1, "carbohydrates": 1.106},
+ {"name": "Oeuf de caille", "glycemicIndex": 1, "carbohydrates": 0.41},
+ {"name": "Oeuf frais", "glycemicIndex": 1, "carbohydrates": 0.9812},
+ {"name": "Oeuf poché", "glycemicIndex": 1, "carbohydrates": 0.977},
+ {"name": "Oeufs brouillés", "glycemicIndex": 1, "carbohydrates": 3.047},
+ {"name": "Oeufs de poisson", "glycemicIndex": 1, "carbohydrates": 1.92},
+ {"name": "Oie rôtie avec la peau", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Oignon cru", "glycemicIndex": 15, "carbohydrates": 9.34},
+ {"name": "Oignon cuit", "glycemicIndex": 15, "carbohydrates": 10.15},
+ {"name": "Oignon en poudre", "glycemicIndex": 1, "carbohydrates": 79.12},
+ {"name": "Oignon vert cuit", "glycemicIndex": 15, "carbohydrates": 6.5},
+ {"name": "Oignon vert cru", "glycemicIndex": 15, "carbohydrates": 7.34},
+ {"name": "Olives", "glycemicIndex": 28, "carbohydrates": 6.26},
+ {"name": "Olives vertes", "glycemicIndex": 10, "carbohydrates": 3.84},
+ {"name": "Orange", "glycemicIndex": 42, "carbohydrates": 12.54},
+ {"name": "Orge cuit", "glycemicIndex": 25, "carbohydrates": 28.22},
+ {"name": "Origan en poudre", "glycemicIndex": 1, "carbohydrates": 68.92},
+ {"name": "Ormeau cru", "glycemicIndex": 1, "carbohydrates": 6.01},
+ {"name": "Ormeau frit", "glycemicIndex": 1, "carbohydrates": 11.05},
+ {"name": "Pain (baguette)", "glycemicIndex": 95, "carbohydrates": 57.4},
+ {"name": "Pain au chocolat", "glycemicIndex": 60, "carbohydrates": 48.6},
+ {"name": "Pain au lait", "glycemicIndex": 60, "carbohydrates": 46.8},
+ {"name": "Pain au levain", "glycemicIndex": 65, "carbohydrates": 56.44},
+ {"name": "Pain au raisin", "glycemicIndex": 63, "carbohydrates": 52.3},
+ {"name": "Pain au son", "glycemicIndex": 70, "carbohydrates": 47.8},
+ {"name": "Pain aux céréales", "glycemicIndex": 50, "carbohydrates": 43.34},
+ {"name": "Pain classique", "glycemicIndex": 95, "carbohydrates": 49.5},
+ {"name": "Pain complet", "glycemicIndex": 55, "carbohydrates": 49.4},
+ {"name": "Pain d'épices", "glycemicIndex": 54, "carbohydrates": 70.0},
+ {"name": "Pain de seigle", "glycemicIndex": 65, "carbohydrates": 48.3},
+ {"name": "Pain de seigle foncé (Pumpernickel)", "glycemicIndex": 46, "carbohydrates": 47.5},
+ {"name": "Pain de viande au poivre", "glycemicIndex": 1, "carbohydrates": 4.53},
+ {"name": "Pain italien", "glycemicIndex": 73, "carbohydrates": 50.0},
+ {"name": "Palette de veau", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Palourde crue", "glycemicIndex": 1, "carbohydrates": 2.57},
+ {"name": "Palourde cuite", "glycemicIndex": 1, "carbohydrates": 5.13},
+ {"name": "Pamplemousse", "glycemicIndex": 25, "carbohydrates": 10.66},
+ {"name": "Panais", "glycemicIndex": 97, "carbohydrates": 17.01},
+ {"name": "Papaye", "glycemicIndex": 56, "carbohydrates": 9.81},
+ {"name": "Paprika", "glycemicIndex": 1, "carbohydrates": 55.74},
+ {"name": "Parmesan pâte dure", "glycemicIndex": 20, "carbohydrates": 3.22},
+ {"name": "Parmesan râpé", "glycemicIndex": 20, "carbohydrates": 4.06},
+ {"name": "Pastèque", "glycemicIndex": 72, "carbohydrates": 7.55},
+ {"name": "Pastrami", "glycemicIndex": 1, "carbohydrates": 0.36},
+ {"name": "Patate douce (conserve)", "glycemicIndex": 61, "carbohydrates": 21.12},
+ {"name": "Patate douce au four avec la peau", "glycemicIndex": 61, "carbohydrates": 20.71},
+ {"name": "Patate douce bouillie", "glycemicIndex": 61, "carbohydrates": 17.72},
+ {"name": "Pâte à tartiner chocolat-noisettes", "glycemicIndex": 33, "carbohydrates": 62.16},
+ {"name": "Pâté de crevette ou homard", "glycemicIndex": 1, "carbohydrates": 1.5},
+ {"name": "Pâté de foie", "glycemicIndex": 1, "carbohydrates": 1.5},
+ {"name": "Pâte de fruit", "glycemicIndex": 50, "carbohydrates": 78.5},
+ {"name": "Pâte feuilletée (prête-à-cuire)", "glycemicIndex": 59, "carbohydrates": 45.1},
+ {"name": "Pâtes aux œufs maison", "glycemicIndex": 40, "carbohydrates": 23.54},
+ {"name": "Pâtes maison", "glycemicIndex": 46, "carbohydrates": 25.12},
+ {"name": "Pâtisson", "glycemicIndex": 15, "carbohydrates": 3.3},
+ {"name": "Pavot (graines)", "glycemicIndex": 1, "carbohydrates": 28.13},
+ {"name": "Pêche", "glycemicIndex": 42, "carbohydrates": 9.54},
+ {"name": "Pêche au sirop", "glycemicIndex": 58, "carbohydrates": 11.57},
+ {"name": "Perche rose", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Perrier", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Persil (déshydraté)", "glycemicIndex": 1, "carbohydrates": 51.66},
+ {"name": "Persil frais", "glycemicIndex": 15, "carbohydrates": 6.33},
+ {"name": "Persil lyophilisé", "glycemicIndex": 15, "carbohydrates": 42.38},
+ {"name": "Petit-suisse", "glycemicIndex": 25, "carbohydrates": 3.3},
+ {"name": "Petits pois (congelés)", "glycemicIndex": 41, "carbohydrates": 13.62},
+ {"name": "Petits pois (conserve)", "glycemicIndex": 41, "carbohydrates": 9.75},
+ {"name": "Petits pois et carottes (congelés)", "glycemicIndex": 48, "carbohydrates": 11.15},
+ {"name": "Petits pois et carottes (conserve)", "glycemicIndex": 48, "carbohydrates": 8.48},
+ {"name": "Petits pois frais cuits", "glycemicIndex": 48, "carbohydrates": 15.63},
+ {"name": "Pétoncles", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Pieds de porc", "glycemicIndex": 1, "carbohydrates": 0.01},
+ {"name": "Pigeonneaux", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Pignon", "glycemicIndex": 15, "carbohydrates": 13.08},
+ {"name": "Pilon de poulet pané et frit", "glycemicIndex": 20, "carbohydrates": 10.61},
+ {"name": "Piment de cayenne", "glycemicIndex": 1, "carbohydrates": 56.63},
+ {"name": "Piment en poudre", "glycemicIndex": 1, "carbohydrates": 72.12},
+ {"name": "Piment fort (conserve)", "glycemicIndex": 15, "carbohydrates": 5.1},
+ {"name": "Piment rouge séché", "glycemicIndex": 15, "carbohydrates": 69.86},
+ {"name": "Pintade", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Pistache", "glycemicIndex": 20, "carbohydrates": 27.65},
+ {"name": "Pizza au fromage (congelée)", "glycemicIndex": 60, "carbohydrates": 29.02},
+ {"name": "Pizza au fromage (congelée, pâte lève-au-four)", "glycemicIndex": 60, "carbohydrates": 32.91},
+ {"name": "Pizza au poivron", "glycemicIndex": 49, "carbohydrates": 28.51},
+ {"name": "Pizza viande et légumes (congelée)", "glycemicIndex": 60, "carbohydrates": 25.14},
+ {"name": "Pizza viande et légumes (congelée, pâte lève-au-four)", "glycemicIndex": 60, "carbohydrates": 28.78},
+ {"name": "Poire asiatique", "glycemicIndex": 38, "carbohydrates": 10.65},
+ {"name": "Poire au sirop", "glycemicIndex": 43, "carbohydrates": 12.94},
+ {"name": "Poireaux crus", "glycemicIndex": 15, "carbohydrates": 14.15},
+ {"name": "Poireaux cuits", "glycemicIndex": 15, "carbohydrates": 7.62},
+ {"name": "Pois cajan", "glycemicIndex": 22, "carbohydrates": 23.25},
+ {"name": "Pois carrés cuits", "glycemicIndex": 15, "carbohydrates": 3.21},
+ {"name": "Pois cassés", "glycemicIndex": 22, "carbohydrates": 21.1},
+ {"name": "Pois chiches", "glycemicIndex": 28, "carbohydrates": 27.42},
+ {"name": "Pois mange-tout", "glycemicIndex": 15, "carbohydrates": 7.05},
+ {"name": "Pois mange-tout crus", "glycemicIndex": 48, "carbohydrates": 7.55},
+ {"name": "Pois pigeon (cajan)", "glycemicIndex": 48, "carbohydrates": 19.49},
+ {"name": "Poivre blanc", "glycemicIndex": 1, "carbohydrates": 68.61},
+ {"name": "Poivre noir", "glycemicIndex": 1, "carbohydrates": 64.81},
+ {"name": "Poivron", "glycemicIndex": 15, "carbohydrates": 3.9},
+ {"name": "Poivron jaune", "glycemicIndex": 15, "carbohydrates": 6.32},
+ {"name": "Poivron vert cru", "glycemicIndex": 15, "carbohydrates": 4.64},
+ {"name": "Poivron vert cuit", "glycemicIndex": 15, "carbohydrates": 6.7},
+ {"name": "Pomélo", "glycemicIndex": 25, "carbohydrates": 9.62},
+ {"name": "Pomme (avec la peau)", "glycemicIndex": 38, "carbohydrates": 13.81},
+ {"name": "Pomme (sans la peau)", "glycemicIndex": 38, "carbohydrates": 12.76},
+ {"name": "Pomme de terre bouillie (avec la peau)", "glycemicIndex": 60, "carbohydrates": 19.0},
+ {"name": "Pomme de terre bouillie (sans la peau)", "glycemicIndex": 101, "carbohydrates": 20.01},
+ {"name": "Pommes de terre rissolées", "glycemicIndex": 75, "carbohydrates": 35.11},
+ {"name": "Pommes de terre rissolées", "glycemicIndex": 75, "carbohydrates": 35.11},
+ {"name": "Port-Salut", "glycemicIndex": 20, "carbohydrates": 0.57},
+ {"name": "Potée auvergnate", "glycemicIndex": 50, "carbohydrates": 4.4},
+ {"name": "Poudre de cacao non sucré", "glycemicIndex": 51, "carbohydrates": 57.9},
+ {"name": "Poudre de noix de coco", "glycemicIndex": 28, "carbohydrates": 23.65},
+ {"name": "Poulet bouilli (sans peau)", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Poulet bouilli avec la peau", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Poulet frit (sans peau)", "glycemicIndex": 1, "carbohydrates": 1.69},
+ {"name": "Poulet mijoté", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Poulet pané et frit", "glycemicIndex": 1, "carbohydrates": 16.32},
+ {"name": "Poulet rôti (sans peau)", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Poulet rôti avec la peau", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Poulpe", "glycemicIndex": 1, "carbohydrates": 4.4},
+ {"name": "Pourpier cru", "glycemicIndex": 15, "carbohydrates": 3.43},
+ {"name": "Pourpier cuit", "glycemicIndex": 15, "carbohydrates": 3.55},
+ {"name": "Pousses de bambou", "glycemicIndex": 15, "carbohydrates": 1.92},
+ {"name": "Préparation pour crêpe au froment", "glycemicIndex": 80, "carbohydrates": 71.0},
+ {"name": "Préparation pour crêpe au sarrasin", "glycemicIndex": 102, "carbohydrates": 71.3},
+ {"name": "Préparation pour flan au chocolat", "glycemicIndex": 44, "carbohydrates": 89.3},
+ {"name": "Préparation pour flan au citron", "glycemicIndex": 44, "carbohydrates": 91.8},
+ {"name": "Prune", "glycemicIndex": 39, "carbohydrates": 11.42},
+ {"name": "Prune au sirop", "glycemicIndex": 39, "carbohydrates": 11.03},
+ {"name": "Prune Reine-Claude", "glycemicIndex": 39, "carbohydrates": 12.0},
+ {"name": "Pruneau", "glycemicIndex": 29, "carbohydrates": 89.07},
+ {"name": "Pruneau au sirop", "glycemicIndex": 29, "carbohydrates": 27.8},
+ {"name": "Purée de pommes de terre", "glycemicIndex": 74, "carbohydrates": 16.12},
+ {"name": "Purée de pommes de terre maison", "glycemicIndex": 75, "carbohydrates": 16.94},
+ {"name": "Quatre-quart", "glycemicIndex": 54, "carbohydrates": 52.5},
+ {"name": "Quatre-quart au beurre", "glycemicIndex": 54, "carbohydrates": 48.8},
+ {"name": "Queue de porc", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Quinoa cuit", "glycemicIndex": 53, "carbohydrates": 21.3},
+ {"name": "Radis", "glycemicIndex": 15, "carbohydrates": 3.4},
+ {"name": "Radis orientaux crus (daikons)", "glycemicIndex": 15, "carbohydrates": 4.1},
+ {"name": "Raifort (sauce)", "glycemicIndex": 1, "carbohydrates": 11.29},
+ {"name": "Raisin", "glycemicIndex": 43, "carbohydrates": 17.15},
+ {"name": "Raisin de Corinthe sec", "glycemicIndex": 64, "carbohydrates": 74.08},
+ {"name": "Ratatouille", "glycemicIndex": 10, "carbohydrates": 3.7},
+ {"name": "Ravioli de bœuf (conserve)", "glycemicIndex": 39, "carbohydrates": 13.58},
+ {"name": "Reblochon", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Rhubarbe", "glycemicIndex": 15, "carbohydrates": 4.54},
+ {"name": "Rice Krispies", "glycemicIndex": 82, "carbohydrates": 84.9},
+ {"name": "Ricotta au lait demi-écrémé", "glycemicIndex": 20, "carbohydrates": 5.14},
+ {"name": "Ricotta au lait entier", "glycemicIndex": 20, "carbohydrates": 3.04},
+ {"name": "Rillettes", "glycemicIndex": 1, "carbohydrates": 0.1},
+ {"name": "Ris de veau", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Riz blanc glutineux cuit", "glycemicIndex": 64, "carbohydrates": 21.09},
+ {"name": "Riz blanc glutineux sec", "glycemicIndex": 64, "carbohydrates": 81.68},
+ {"name": "Riz blanc grain court cuit", "glycemicIndex": 64, "carbohydrates": 28.73},
+ {"name": "Riz blanc grain court sec", "glycemicIndex": 64, "carbohydrates": 79.15},
+ {"name": "Riz blanc grain moyen cuit", "glycemicIndex": 64, "carbohydrates": 28.59},
+ {"name": "Riz blanc grain moyen sec", "glycemicIndex": 64, "carbohydrates": 79.34},
+ {"name": "Riz brun grain long cuit", "glycemicIndex": 55, "carbohydrates": 22.96},
+ {"name": "Riz brun grain moyen cuit", "glycemicIndex": 55, "carbohydrates": 23.51},
+ {"name": "Riz brun grain moyen sec", "glycemicIndex": 55, "carbohydrates": 76.17},
+ {"name": "Riz croustillant", "glycemicIndex": 82, "carbohydrates": 83.333},
+ {"name": "Riz sauvage", "glycemicIndex": 55, "carbohydrates": 21.34},
+ {"name": "Rognon d'agneau", "glycemicIndex": 1, "carbohydrates": 0.99},
+ {"name": "Rognon de bœuf", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Rognon de veau", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Rognons de porc crus", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Rognons de porc cuits", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Romarin (déshydraté)", "glycemicIndex": 1, "carbohydrates": 64.06},
+ {"name": "Romarin frais", "glycemicIndex": 1, "carbohydrates": 20.7},
+ {"name": "Roquefort", "glycemicIndex": 20, "carbohydrates": 2.0},
+ {"name": "Roquette", "glycemicIndex": 15, "carbohydrates": 3.65},
+ {"name": "Rôti de porc cuit", "glycemicIndex": 1, "carbohydrates": 1.05},
+ {"name": "Rôti de viande froid", "glycemicIndex": 1, "carbohydrates": 2.33},
+ {"name": "Roulé de dinde", "glycemicIndex": 1, "carbohydrates": 5.03},
+ {"name": "Roulé de poulet", "glycemicIndex": 1, "carbohydrates": 1.79},
+ {"name": "Rouleau de printemps", "glycemicIndex": 35, "carbohydrates": 16.6},
+ {"name": "Rutabaga", "glycemicIndex": 72, "carbohydrates": 8.74},
+ {"name": "Sablé", "glycemicIndex": 64, "carbohydrates": 64.5},
+ {"name": "Safran", "glycemicIndex": 1, "carbohydrates": 65.37},
+ {"name": "Salade de chou", "glycemicIndex": 30, "carbohydrates": 14.89},
+ {"name": "Salade de fruit (conserve)", "glycemicIndex": 55, "carbohydrates": 7.87},
+ {"name": "Salade de fruits tropicaux (conserve)", "glycemicIndex": 54, "carbohydrates": 22.36},
+ {"name": "Salade de légumes et crevettes", "glycemicIndex": 20, "carbohydrates": 2.8},
+ {"name": "Salade de légumes et poulet", "glycemicIndex": 20, "carbohydrates": 1.71},
+ {"name": "Salade de légumes sans sauce", "glycemicIndex": 20, "carbohydrates": 3.22},
+ {"name": "Salade de pâtes aux fruits de mer", "glycemicIndex": 20, "carbohydrates": 7.67},
+ {"name": "Salade de pommes de terre", "glycemicIndex": 70, "carbohydrates": 11.17},
+ {"name": "Salade frisée", "glycemicIndex": 15, "carbohydrates": 2.79},
+ {"name": "Salami cuit", "glycemicIndex": 1, "carbohydrates": 2.0},
+ {"name": "Salami de boeuf cuit", "glycemicIndex": 1, "carbohydrates": 1.9},
+ {"name": "Salami de boeuf sec", "glycemicIndex": 1, "carbohydrates": 3.8},
+ {"name": "Salami de dinde cuit", "glycemicIndex": 1, "carbohydrates": 1.55},
+ {"name": "Salami sec", "glycemicIndex": 1, "carbohydrates": 1.6},
+ {"name": "Salsifis", "glycemicIndex": 15, "carbohydrates": 15.36},
+ {"name": "Sandwich au jambon de poulet", "glycemicIndex": 66, "carbohydrates": 4.24},
+ {"name": "Sandwich au poulet", "glycemicIndex": 66, "carbohydrates": 6.75},
+ {"name": "Sandwich au poulet et fromage", "glycemicIndex": 66, "carbohydrates": 18.24},
+ {"name": "Sanglier", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Sanglier", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Sardine à l'huile (conserve)", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Sardines aux tomates (conserve)", "glycemicIndex": 1, "carbohydrates": 0.54},
+ {"name": "Sarrasin", "glycemicIndex": 54, "carbohydrates": 71.5},
+ {"name": "Sarriette en poudre", "glycemicIndex": 1, "carbohydrates": 68.73},
+ {"name": "Sauce aigre-douce", "glycemicIndex": 1, "carbohydrates": 24.79},
+ {"name": "Sauce barbecue", "glycemicIndex": 40, "carbohydrates": 36.25},
+ {"name": "Sauce béchamel", "glycemicIndex": 1, "carbohydrates": 7.4},
+ {"name": "Sauce chili", "glycemicIndex": 1, "carbohydrates": 19.79},
+ {"name": "Sauce salsa", "glycemicIndex": 28, "carbohydrates": 6.26},
+ {"name": "Sauce spaghetti", "glycemicIndex": 38, "carbohydrates": 13.76},
+ {"name": "Sauce tartare", "glycemicIndex": 28, "carbohydrates": 4.196},
+ {"name": "Sauce tomate", "glycemicIndex": 15, "carbohydrates": 9.94},
+ {"name": "Saucisse bratwurst", "glycemicIndex": 1, "carbohydrates": 2.6},
+ {"name": "Saucisse de bière (bœuf)", "glycemicIndex": 1, "carbohydrates": 4.1},
+ {"name": "Saucisse de bologne (bœuf)", "glycemicIndex": 1, "carbohydrates": 5.3},
+ {"name": "Saucisse de bœuf", "glycemicIndex": 1, "carbohydrates": 0.35},
+ {"name": "Saucisse de dinde", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Saucisse de Toulouse", "glycemicIndex": 1, "carbohydrates": 0.6},
+ {"name": "Saucisse de veau", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Saucisse fumée", "glycemicIndex": 1, "carbohydrates": 0.28},
+ {"name": "Saucisse fumée (bœuf)", "glycemicIndex": 1, "carbohydrates": 4.06},
+ {"name": "Saucisse fumée (porc et boeuf)", "glycemicIndex": 1, "carbohydrates": 2.42},
+ {"name": "Saucisse fumée (porc)", "glycemicIndex": 1, "carbohydrates": 0.18},
+ {"name": "Saucisse fumée (poulet)", "glycemicIndex": 1, "carbohydrates": 2.74},
+ {"name": "Saucisse knackwurst", "glycemicIndex": 1, "carbohydrates": 3.2},
+ {"name": "Saucisse porc et bœuf", "glycemicIndex": 1, "carbohydrates": 2.7},
+ {"name": "Saucisson de bière", "glycemicIndex": 1, "carbohydrates": 2.06},
+ {"name": "Saucisson de bière (porc et bœuf)", "glycemicIndex": 1, "carbohydrates": 4.27},
+ {"name": "Saucisson de bologne", "glycemicIndex": 1, "carbohydrates": 0.73},
+ {"name": "Saucisson de bologne (dinde)", "glycemicIndex": 1, "carbohydrates": 4.68},
+ {"name": "Saucisson de foie", "glycemicIndex": 1, "carbohydrates": 2.2},
+ {"name": "Saucisson de foie et de bacon", "glycemicIndex": 1, "carbohydrates": 4.3},
+ {"name": "Saucisson épicé", "glycemicIndex": 1, "carbohydrates": 3.3},
+ {"name": "Sauge en poudre", "glycemicIndex": 1, "carbohydrates": 60.73},
+ {"name": "Saumon Atlantique (élevage)", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Saumon Atlantique (sauvage)", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Saumon rose", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Saumon rose (conserve)", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Saumon rouge", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Saumon rouge (conserve)", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Scarole", "glycemicIndex": 15, "carbohydrates": 3.35},
+ {"name": "Seiche", "glycemicIndex": 1, "carbohydrates": 1.64},
+ {"name": "Seigle", "glycemicIndex": 34, "carbohydrates": 69.76},
+ {"name": "Sel de table", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Semoule de blé dur", "glycemicIndex": 55, "carbohydrates": 72.83},
+ {"name": "Semoule de maïs", "glycemicIndex": 69, "carbohydrates": 76.89},
+ {"name": "Shiitaké cuit", "glycemicIndex": 15, "carbohydrates": 14.39},
+ {"name": "Shiitaké séché", "glycemicIndex": 15, "carbohydrates": 75.37},
+ {"name": "Sirop d'érable", "glycemicIndex": 54, "carbohydrates": 66.89},
+ {"name": "Sirop de grenadine", "glycemicIndex": 70, "carbohydrates": 66.91},
+ {"name": "Skittles", "glycemicIndex": 70, "carbohydrates": 90.78},
+ {"name": "Snickers", "glycemicIndex": 55, "carbohydrates": 61.51},
+ {"name": "Soda à l'orange", "glycemicIndex": 68, "carbohydrates": 12.3},
+ {"name": "Sole (poisson plat)", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Son d'avoine cuit", "glycemicIndex": 28, "carbohydrates": 11.44},
+ {"name": "Sorbet à l'orange", "glycemicIndex": 34, "carbohydrates": 30.4},
+ {"name": "Sorbet allégé en sucre", "glycemicIndex": 34, "carbohydrates": 6.2},
+ {"name": "Sorbet au citron", "glycemicIndex": 34, "carbohydrates": 32.6},
+ {"name": "Soupe à l'oignon en sachet", "glycemicIndex": 28, "carbohydrates": 2.77},
+ {"name": "Soupe aux asperges en sachet", "glycemicIndex": 28, "carbohydrates": 3.57},
+ {"name": "Soupe aux champignons en sachet", "glycemicIndex": 28, "carbohydrates": 4.4},
+ {"name": "Soupe de poireaux en sachet", "glycemicIndex": 28, "carbohydrates": 4.5},
+ {"name": "Soupe de pois cassés", "glycemicIndex": 66, "carbohydrates": 8.37},
+ {"name": "Soupe de tomates en sachet", "glycemicIndex": 38, "carbohydrates": 7.17},
+ {"name": "Soupe minestrone en boîte", "glycemicIndex": 39, "carbohydrates": 8.64},
+ {"name": "Soupe minestrone en sachet", "glycemicIndex": 48, "carbohydrates": 4.69},
+ {"name": "Spaghetti", "glycemicIndex": 44, "carbohydrates": 30.86},
+ {"name": "Spaghetti au blé complet", "glycemicIndex": 37, "carbohydrates": 26.54},
+ {"name": "Spaghetti en sauce", "glycemicIndex": 52, "carbohydrates": 14.91},
+ {"name": "Special K", "glycemicIndex": 84, "carbohydrates": 75.5},
+ {"name": "Sucre d'orge", "glycemicIndex": 70, "carbohydrates": 98.0},
+ {"name": "Sucre de table", "glycemicIndex": 58, "carbohydrates": 100.0},
+ {"name": "Sucre glace", "glycemicIndex": 70, "carbohydrates": 99.77},
+ {"name": "Sundae caramel", "glycemicIndex": 70, "carbohydrates": 31.81},
+ {"name": "Sundae chocolat", "glycemicIndex": 70, "carbohydrates": 30.17},
+ {"name": "Sundae fraises", "glycemicIndex": 70, "carbohydrates": 29.18},
+ {"name": "Surimi", "glycemicIndex": 1, "carbohydrates": 6.85},
+ {"name": "Tablette de chocolat", "glycemicIndex": 43, "carbohydrates": 60.4},
+ {"name": "Tablette de chocolat (à dessert)", "glycemicIndex": 31, "carbohydrates": 29.84},
+ {"name": "Tablette de chocolat Crunch", "glycemicIndex": 43, "carbohydrates": 67.0},
+ {"name": "Taco", "glycemicIndex": 68, "carbohydrates": 15.63},
+ {"name": "Tapioca", "glycemicIndex": 81, "carbohydrates": 94.3},
+ {"name": "Tapioca sec", "glycemicIndex": 70, "carbohydrates": 88.69},
+ {"name": "Thé", "glycemicIndex": 1, "carbohydrates": 0.3},
+ {"name": "Thon à l'huile (en conserve)", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Thon albacore", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Thon au naturel (conserve)", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Thon blanc à l'huile (conserve)", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Thon rouge frais cru", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Thon rouge frais cuit", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Thym (déshydraté)", "glycemicIndex": 1, "carbohydrates": 63.94},
+ {"name": "Thym frais", "glycemicIndex": 1, "carbohydrates": 24.45},
+ {"name": "Thymus de bœuf", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Tisane", "glycemicIndex": 1, "carbohydrates": 0.2},
+ {"name": "Tofu", "glycemicIndex": 44, "carbohydrates": 5.15},
+ {"name": "Tomate farcie", "glycemicIndex": 10, "carbohydrates": 4.2},
+ {"name": "Tomate rouge d'hiver crue", "glycemicIndex": 15, "carbohydrates": 4.64},
+ {"name": "Tomate verte crue", "glycemicIndex": 15, "carbohydrates": 5.1},
+ {"name": "Tomate, purée (en conserve)", "glycemicIndex": 15, "carbohydrates": 8.98},
+ {"name": "Topinambour", "glycemicIndex": 52, "carbohydrates": 17.44},
+ {"name": "Tortellinis au fromage", "glycemicIndex": 50, "carbohydrates": 47.0},
+ {"name": "Tortilla nature", "glycemicIndex": 50, "carbohydrates": 65.56},
+ {"name": "Tortilla prêt-à-cuire", "glycemicIndex": 52, "carbohydrates": 44.64},
+ {"name": "Tourteau", "glycemicIndex": 1, "carbohydrates": 3.11},
+ {"name": "Tripes de boeuf", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Truite", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Truite arc-en-ciel", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Truite arc-en-ciel (élevage)", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Truite saumonée", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Turbot", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Twix", "glycemicIndex": 44, "carbohydrates": 64.8},
+ {"name": "Vanille (extrait)", "glycemicIndex": 1, "carbohydrates": 12.65},
+ {"name": "Veau gras", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Veau haché", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Veau maigre", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Végétaline", "glycemicIndex": 1, "carbohydrates": 0.0},
+ {"name": "Viande de grison", "glycemicIndex": 1, "carbohydrates": 2.76},
+ {"name": "Vin doux", "glycemicIndex": 28, "carbohydrates": 10.6},
+ {"name": "Vinaigre", "glycemicIndex": 1, "carbohydrates": 0.93},
+ {"name": "Vinaigrette (huile et vinaigre)", "glycemicIndex": 1, "carbohydrates": 2.5},
+ {"name": "Vinaigrette commerciale", "glycemicIndex": 1, "carbohydrates": 15.58},
+ {"name": "Vinaigrette maison", "glycemicIndex": 1, "carbohydrates": 3.4},
+ {"name": "Yaourt à boire", "glycemicIndex": 38, "carbohydrates": 11.7},
+ {"name": "Yaourt allégé sur lit de fruits", "glycemicIndex": 31, "carbohydrates": 10.77},
+ {"name": "Yaourt aux fruits allégé", "glycemicIndex": 40, "carbohydrates": 19.0},
+ {"name": "Yaourt aux fruits brassé", "glycemicIndex": 31, "carbohydrates": 17.28},
+ {"name": "Yaourt glacé", "glycemicIndex": 47, "carbohydrates": 24.2},
+ {"name": "Yaourt nature", "glycemicIndex": 27, "carbohydrates": 7.04},
+ {"name": "Yaourt nature allégé", "glycemicIndex": 24, "carbohydrates": 7.26},
+ {"name": "Yaourt nature au lait entier", "glycemicIndex": 24, "carbohydrates": 6.68},
+ {"name": "Yaourt nature brassé", "glycemicIndex": 36, "carbohydrates": 6.91},
+ {"name": "Yaourt normal sur lit de fruits", "glycemicIndex": 31, "carbohydrates": 17.76},
+ {"name": "Yaourt saveur vanille ou café", "glycemicIndex": 31, "carbohydrates": 15.49},
+ {"name": "Zeste d'orange", "glycemicIndex": 28, "carbohydrates": 25.0},
+ ]
diff --git a/src/lib/dom.ts b/src/lib/dom.ts
new file mode 100644
index 0000000..2ab4de5
--- /dev/null
+++ b/src/lib/dom.ts
@@ -0,0 +1,6 @@
+export function replaceChildren(parent: Element, ...newChildren: Element[]) {
+ while (parent.lastChild) {
+ parent.removeChild(parent.lastChild)
+ }
+ newChildren.forEach(c => parent.appendChild(c))
+}
diff --git a/src/lib/format.ts b/src/lib/format.ts
new file mode 100644
index 0000000..28aa50f
--- /dev/null
+++ b/src/lib/format.ts
@@ -0,0 +1,9 @@
+export function decimal(n: number): string {
+ const str = n.toString()
+ const xs = str.split('.')
+ if (xs.length == 2) {
+ return `${xs[0]},${xs[1].slice(0, 2).padEnd(2, '0')}`
+ } else {
+ return `${str},00`
+ }
+}
diff --git a/src/lib/function.ts b/src/lib/function.ts
new file mode 100644
index 0000000..db7b436
--- /dev/null
+++ b/src/lib/function.ts
@@ -0,0 +1,7 @@
+export function debounce(func: any, timeout = 300){
+ let timer: any;
+ return (...args: any) => {
+ clearTimeout(timer);
+ timer = setTimeout(() => { func.apply(this, args); }, timeout);
+ };
+}
diff --git a/src/lib/h.ts b/src/lib/h.ts
new file mode 100644
index 0000000..bb21efd
--- /dev/null
+++ b/src/lib/h.ts
@@ -0,0 +1,30 @@
+type Child = Element | Text | string | number
+
+export default function h(
+ tagName: string,
+ attrs: object,
+ ...children: Child[]
+): Element {
+ const isSvg = tagName === 'svg' || tagName === 'path'
+
+ let elem = isSvg
+ ? document.createElementNS('http://www.w3.org/2000/svg', tagName)
+ : document.createElement(tagName)
+
+ if (isSvg) {
+ Object.entries(attrs).forEach(([key, value]) => {
+ elem.setAttribute(key, value)
+ })
+ } else {
+ elem = Object.assign(elem, attrs)
+ }
+
+ for (const child of children) {
+ if (typeof child === 'number')
+ elem.append(child.toString())
+ else
+ elem.append(child)
+ }
+
+ return elem
+}
diff --git a/src/lib/search.ts b/src/lib/search.ts
new file mode 100644
index 0000000..7b9530e
--- /dev/null
+++ b/src/lib/search.ts
@@ -0,0 +1,11 @@
+export function match(search: string, target: string): boolean {
+ return search.split(/\s+/).every(s => format(target).includes(format(s)))
+}
+
+export function format(str: string): string {
+ return unaccent(str.toLowerCase())
+}
+
+function unaccent(str: string): string {
+ return str.normalize("NFD").replace(/[\u0300-\u036f]/g, "")
+}
diff --git a/src/main.ts b/src/main.ts
new file mode 100644
index 0000000..21990c3
--- /dev/null
+++ b/src/main.ts
@@ -0,0 +1,3 @@
+import * as Table from 'view/table'
+
+document.body.appendChild(Table.view())
diff --git a/src/view/sort.ts b/src/view/sort.ts
new file mode 100644
index 0000000..3fed7fd
--- /dev/null
+++ b/src/view/sort.ts
@@ -0,0 +1,53 @@
+import * as Food from 'food'
+import * as Search from 'lib/search'
+
+export interface Sort {
+ field: Field,
+ order: Order,
+}
+
+export enum Field {
+ Name,
+ GlycemicIndex,
+ Carbohydrates,
+ GlycemicLoad,
+}
+
+export enum Order {
+ Down,
+ Up,
+}
+
+export const init: Sort = {
+ field: Field.Name,
+ order: Order.Down,
+}
+
+export function aliments(a1: Food.Aliment, a2: Food.Aliment, sort: Sort) {
+ return getField(a1, sort.field) > getField(a2, sort.field)
+ ? (sort.order === Order.Down ? 1 : -1)
+ : (sort.order === Order.Down ? -1 : 1)
+}
+
+function getField(a: Food.Aliment, sort: Field) {
+ if (sort === Field.Name) {
+ return Search.format(a.name)
+ } else if (sort === Field.GlycemicIndex) {
+ return a.glycemicIndex
+ } else if (sort === Field.Carbohydrates) {
+ return a.carbohydrates
+ } else {
+ return Food.glycemicLoad(a)
+ }
+}
+
+export function toggle(sort: Sort, field: Field): Sort {
+ return {
+ field,
+ order: sort.field === field ? reverseOrder(sort.order) : Order.Down
+ }
+}
+
+function reverseOrder(order: Order): Order {
+ return order === Order.Down ? Order.Up : Order.Down
+}
diff --git a/src/view/table.ts b/src/view/table.ts
new file mode 100644
index 0000000..171300d
--- /dev/null
+++ b/src/view/table.ts
@@ -0,0 +1,102 @@
+import h from 'lib/h'
+import * as Format from 'lib/format'
+import * as Dom from 'lib/dom'
+import * as Function from 'lib/function'
+import * as Food from 'food'
+import * as Sort from 'view/sort'
+
+export function view(): Element {
+ const maxGlycemicLoad: number = Math.max(...Food.all.map(Food.glycemicLoad))
+ const aliments = h('div',
+ { className: 'g-Aliments' },
+ ...Food.all.sort((a1, a2) => Sort.aliments(a1, a2, Sort.init)).map(aliment => line(aliment, maxGlycemicLoad))
+ )
+
+ return h('div',
+ { className: 'g-Page' },
+ header(
+ (search: string, sort: Sort.Sort) => {
+ const lines = Food
+ .search(search)
+ .sort((a1, a2) => Sort.aliments(a1, a2, sort))
+ .map(aliment => line(aliment, maxGlycemicLoad))
+ Dom.replaceChildren(aliments, ...lines)
+ }
+ ),
+ aliments
+ )
+}
+
+function header(
+ onUpdateTable: (search: string, sort: Sort.Sort) => void
+): Element {
+ let search = ''
+ let sort = Sort.init
+
+ const alimentHeader = h('button', { className: 'g-Header--Sorted' }, 'Aliment')
+ const glycemicIndexHeader = h('button', {}, 'Index glycémique')
+ const carbohydratesHeader = h('button', {}, 'Glucides pour 100 g')
+ const glycemicLoadHeader = h('button', {}, 'Charge glycémique')
+
+ const onSort = (field: Sort.Field) => () => {
+ sort = Sort.toggle(sort, field)
+ onUpdateTable(search, sort)
+ alimentHeader.className = field === Sort.Field.Name ? 'g-Header--Sorted' : ''
+ glycemicIndexHeader.className = field === Sort.Field.GlycemicIndex ? 'g-Header--Sorted' : ''
+ carbohydratesHeader.className = field === Sort.Field.Carbohydrates ? 'g-Header--Sorted' : ''
+ glycemicLoadHeader.className = field === Sort.Field.GlycemicLoad ? 'g-Header--Sorted' : ''
+ }
+
+ alimentHeader.addEventListener('click', onSort(Sort.Field.Name))
+ glycemicIndexHeader.addEventListener('click', onSort(Sort.Field.GlycemicIndex))
+ carbohydratesHeader.addEventListener('click', onSort(Sort.Field.Carbohydrates))
+ glycemicLoadHeader.addEventListener('click', onSort(Sort.Field.GlycemicLoad))
+
+ return h('header',
+ { className: 'g-Header' },
+ h('div',
+ { className: 'g-Title g-Line' },
+ alimentHeader,
+ glycemicIndexHeader,
+ carbohydratesHeader,
+ glycemicLoadHeader,
+ ),
+ h('input',
+ { className: 'g-Search g-Line',
+ placeholder: 'Rechercher…',
+ oninput: Function.debounce((e: Event) => {
+ search = (e.target as HTMLInputElement).value
+ onUpdateTable(search, sort)
+ })
+ }
+ )
+ )
+}
+
+function line(aliment: Food.Aliment, maxGlycemicLoad: number): Element {
+ return h('div',
+ { className: 'g-Aliment g-Line' },
+ h('div', {}, aliment.name),
+ h('div', { className: 'g-Number' }, aliment.glycemicIndex),
+ h('div', { className: 'g-Number' }, `${Math.round(aliment.carbohydrates)} g`),
+ h('div', { className: 'g-Number' }, formatGlycemicLoad(aliment, maxGlycemicLoad))
+ )
+}
+
+function formatGlycemicLoad(aliment: Food.Aliment, maxGlycemicLoad: number): Element {
+ const glycemicLoad = Food.glycemicLoad(aliment)
+ return h('div',
+ { className: `number ${glycemicLoadNumberClass(glycemicLoad)}` },
+ Format.decimal(glycemicLoad)
+ )
+}
+
+function glycemicLoadNumberClass(index: number): string {
+ if (index < 8) {
+ return 'g-Number--Low'
+ } else if (index < 20) {
+ return 'g-Number--Middle'
+ } else {
+ return 'g-Number--High'
+ }
+}
diff --git a/test/Main.purs b/test/Main.purs
deleted file mode 100644
index 25352df..0000000
--- a/test/Main.purs
+++ /dev/null
@@ -1,26 +0,0 @@
-module Test.Main where
-
-import Prelude
-import Control.Monad.Eff (Eff)
-import Test.Spec (describe, it)
-import Test.Spec.Assertions (shouldEqual)
-import Test.Spec.Reporter.Console (consoleReporter)
-import Test.Spec.Runner (RunnerEffects, run)
-
-import Format as Format
-
-main :: Eff (RunnerEffects ()) Unit
-main = run [consoleReporter] do
-
- describe "Format" do
- it "format numbers" $ do
- (Format.number 0 0.0) `shouldEqual` "0"
- (Format.number 0 (-0.0)) `shouldEqual` "0"
- (Format.number 0 8.0) `shouldEqual` "8"
- (Format.number 0 (-4.0)) `shouldEqual` "-4"
- (Format.number 2 25.0) `shouldEqual` "25,00"
- (Format.number 5 25.0) `shouldEqual` "25,00000"
- (Format.number 5 25.13) `shouldEqual` "25,13000"
- (Format.number 1 25.13) `shouldEqual` "25,1"
- (Format.number 1 25.15) `shouldEqual` "25,1"
- (Format.number 1 25.19) `shouldEqual` "25,2"
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..3e7f32b
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,13 @@
+{
+ "compilerOptions": {
+ "module": "amd",
+ "target": "es5",
+ "baseUrl": "src",
+ "outFile": "public/main.js",
+ "noImplicitAny": true,
+ "strictNullChecks": true,
+ "removeComments": true,
+ "preserveConstEnums": true
+ },
+ "include": ["src/**/*"]
+}
--
cgit v1.2.3