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