feat: 🎉 Setup basic commands
Tim Izzo tim@5ika.ch
Fri, 02 Jan 2026 14:43:30 +0100
13 files changed,
1212 insertions(+),
0 deletions(-)
A
commands/list.ts
@@ -0,0 +1,15 @@
+import { Table } from "@cliffy/table"; +import type { DatabaseSync } from "node:sqlite"; + +export default (db: DatabaseSync) => { + const recipes = db.prepare("SELECT * FROM recipes").all(); + const cells = recipes.map((recipe) => [ + recipe.id as string, + recipe.name as string, + recipe.url as string, + recipe.createdAt as string, + ]); + const table = new Table(["ID", "Name", "URL", "Created At"], ...cells); + + console.log(table.border().toString()); +};
A
commands/select.ts
@@ -0,0 +1,34 @@
+import type { DatabaseSync } from "node:sqlite"; +import { Checkbox } from "@cliffy/prompt"; +import { Table } from "@cliffy/table"; + +export default async (db: DatabaseSync) => { + const recipes = db.prepare("SELECT * FROM recipes").all(); + + const choices = await Checkbox.prompt({ + message: "Select recipes", + options: recipes.map((recipe) => ({ + name: recipe.name as string, + value: recipe, + })), + }); + + const rawIngredients = choices.flatMap((recipe) => + JSON.parse(recipe.ingredients as string) + ); + + const ingredients = rawIngredients.reduce((acc, ingredient) => { + const existingIngredient = acc.find( + (i) => i.name === ingredient.name && i.unit === ingredient.unit + ); + if (existingIngredient) existingIngredient.value += ingredient.value; + else acc.push(ingredient); + return acc; + }, [] as { name: string; value: number; unit: string }[]); + + const table = new Table( + ...ingredients.map((item) => [item.name, item.value, item.unit]) + ).header(["Name", "Value", "Unit"]); + + console.log(table.border().sort().toString()); +};
A
commands/store.ts
@@ -0,0 +1,48 @@
+import type { DatabaseSync } from "node:sqlite"; +import { callLLM } from "../utils/llm.ts"; +import { decodeHtmlChars } from "../utils/html.ts"; + +export default async (db: DatabaseSync, recipeId: string) => { + let recipeUrl = ""; + if (!recipeId) throw new Error("Please provide a recipe ID"); + else if (recipeId.startsWith("https://")) recipeUrl = recipeId; + else recipeUrl = `https://cookidoo.fr/recipes/recipe/fr-FR/${recipeId}`; + + const recipePage = await fetch(recipeUrl).then((res) => res.text()); + const jsonLdTag = recipePage.match( + /<script type="application\/ld\+json">(.*?)<\/script>/s + )?.[1]; + if (!jsonLdTag) throw new Error("No JSON-LD tag found"); + + const recipeJson = JSON.parse(jsonLdTag); + + const existingItem = db + .prepare("SELECT * FROM recipes WHERE url = ?") + .get(recipeUrl); + if (existingItem) { + console.log("Recipe already exists in db"); + db.close(); + Deno.exit(0); + } + + const rawIngredientsJson = await callLLM(` + À partir de la liste suivante, renvoi un objet JSON avec unit, value, name pour chacun des éléments. + ${decodeHtmlChars(recipeJson.recipeIngredient.join("\n"))} + Si la quantité est un nombre décimal, convertis le. + Utilise de préférences les unités les plus courantes comme g, pincée, cuillère à café, gousse. + Les unités doivent toujours être au singulier. + `); + + const recipe = { + name: recipeJson.name, + ingredients: rawIngredientsJson, + imageUrl: recipeJson.image, + url: recipeUrl, + }; + + db.prepare( + `INSERT INTO recipes (url, name, ingredients, imageUrl) VALUES (?, ?, ?, ?)` + ).run(recipe.url, recipe.name, recipe.ingredients, recipe.imageUrl); + + console.log(`New recipe "${recipe.name}" added to db.`); +};
A
db.ts
@@ -0,0 +1,16 @@
+import { DatabaseSync } from "node:sqlite"; + +const db = new DatabaseSync("recipes.db"); + +db.exec(` + CREATE TABLE IF NOT EXISTS recipes ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + url TEXT, + name TEXT NOT NULL, + ingredients TEXT NOT NULL, + imageUrl TEXT, + createdAt DATETIME DEFAULT CURRENT_TIMESTAMP + ) + `); + +export default db;
A
deno.json
@@ -0,0 +1,11 @@
+{ + "tasks": { + "cli": "deno run --allow-net --allow-read --allow-write --allow-env main.ts" + }, + "imports": { + "@cliffy/command": "jsr:@cliffy/command@1.0.0-rc.8", + "@cliffy/table": "jsr:@cliffy/table@1.0.0-rc.8", + "@cliffy/prompt": "jsr:@cliffy/prompt@1.0.0-rc.8", + "@std/dotenv": "jsr:@std/dotenv@^0.225.6" + } +}
A
deno.lock
@@ -0,0 +1,99 @@
+{ + "version": "5", + "specifiers": { + "jsr:@cliffy/ansi@1.0.0-rc.8": "1.0.0-rc.8", + "jsr:@cliffy/command@1.0.0-rc.8": "1.0.0-rc.8", + "jsr:@cliffy/flags@1.0.0-rc.8": "1.0.0-rc.8", + "jsr:@cliffy/internal@1.0.0-rc.8": "1.0.0-rc.8", + "jsr:@cliffy/keycode@1.0.0-rc.8": "1.0.0-rc.8", + "jsr:@cliffy/prompt@1.0.0-rc.8": "1.0.0-rc.8", + "jsr:@cliffy/table@1.0.0-rc.8": "1.0.0-rc.8", + "jsr:@std/assert@~1.0.6": "1.0.16", + "jsr:@std/dotenv@~0.225.6": "0.225.6", + "jsr:@std/encoding@~1.0.5": "1.0.10", + "jsr:@std/fmt@~1.0.2": "1.0.8", + "jsr:@std/io@~0.224.9": "0.224.9", + "jsr:@std/path@~1.0.6": "1.0.9", + "jsr:@std/text@~1.0.7": "1.0.16" + }, + "jsr": { + "@cliffy/ansi@1.0.0-rc.8": { + "integrity": "ba37f10ce55bbfbdd8ddd987f91f029b17bce88385b98ba3058870f3b007b80c", + "dependencies": [ + "jsr:@cliffy/internal", + "jsr:@std/encoding", + "jsr:@std/io" + ] + }, + "@cliffy/command@1.0.0-rc.8": { + "integrity": "758147790797c74a707e5294cc7285df665422a13d2a483437092ffce40b5557", + "dependencies": [ + "jsr:@cliffy/flags", + "jsr:@cliffy/internal", + "jsr:@cliffy/table", + "jsr:@std/fmt", + "jsr:@std/text" + ] + }, + "@cliffy/flags@1.0.0-rc.8": { + "integrity": "0f1043ce6ef037ba1cb5fe6b1bcecb25dc2f29371a1c17f278ab0f45e4b6f46c", + "dependencies": [ + "jsr:@std/text" + ] + }, + "@cliffy/internal@1.0.0-rc.8": { + "integrity": "34cdf2fad9b084b5aed493b138d573f52d4e988767215f7460daf0b918ff43d8" + }, + "@cliffy/keycode@1.0.0-rc.8": { + "integrity": "76dbf85a67ec0aea2e29ca049b8507b6b3f62a2a971bd744d8d3fc447c177cd9" + }, + "@cliffy/prompt@1.0.0-rc.8": { + "integrity": "eba403ea1d47b9971bf2210fa35f4dc7ebd2aba87beec9540ae47552806e2f25", + "dependencies": [ + "jsr:@cliffy/ansi", + "jsr:@cliffy/internal", + "jsr:@cliffy/keycode", + "jsr:@std/assert", + "jsr:@std/fmt", + "jsr:@std/io", + "jsr:@std/path", + "jsr:@std/text" + ] + }, + "@cliffy/table@1.0.0-rc.8": { + "integrity": "8bbcdc2ba5e0061b4b13810a24e6f5c6ab19c09f0cce9eb691ccd76c7c6c9db5", + "dependencies": [ + "jsr:@std/fmt" + ] + }, + "@std/assert@1.0.16": { + "integrity": "6a7272ed1eaa77defe76e5ff63ca705d9c495077e2d5fd0126d2b53fc5bd6532" + }, + "@std/dotenv@0.225.6": { + "integrity": "1d6f9db72f565bd26790fa034c26e45ecb260b5245417be76c2279e5734c421b" + }, + "@std/encoding@1.0.10": { + "integrity": "8783c6384a2d13abd5e9e87a7ae0520a30e9f56aeeaa3bdf910a3eaaf5c811a1" + }, + "@std/fmt@1.0.8": { + "integrity": "71e1fc498787e4434d213647a6e43e794af4fd393ef8f52062246e06f7e372b7" + }, + "@std/io@0.224.9": { + "integrity": "4414664b6926f665102e73c969cfda06d2c4c59bd5d0c603fd4f1b1c840d6ee3" + }, + "@std/path@1.0.9": { + "integrity": "260a49f11edd3db93dd38350bf9cd1b4d1366afa98e81b86167b4e3dd750129e" + }, + "@std/text@1.0.16": { + "integrity": "ddb9853b75119a2473857d691cf1ec02ad90793a2e8b4a4ac49d7354281a0cf8" + } + }, + "workspace": { + "dependencies": [ + "jsr:@cliffy/command@1.0.0-rc.8", + "jsr:@cliffy/prompt@1.0.0-rc.8", + "jsr:@cliffy/table@1.0.0-rc.8", + "jsr:@std/dotenv@~0.225.6" + ] + } +}
A
main.ts
@@ -0,0 +1,27 @@
+import { Command } from "@cliffy/command"; +import db from "./db.ts"; + +import store from "./commands/store.ts"; +import list from "./commands/list.ts"; +import select from "./commands/select.ts"; + +await new Command() + .name("cookidoo") + .version("0.1.0") + .description("Recipe CLI") + .action(function () { + this.showHelp(); + }) + + .command("store <recipeId:string>", "Store a recipe in the database") + .action((_options, recipeId: string) => store(db, recipeId)) + + .command("list", "Liste stored recipes") + .action(() => list(db)) + + .command("select", "Select recipes for course list") + .action(() => select(db)) + + .parse(Deno.args); + +db.close();
A
recipe.html
@@ -0,0 +1,934 @@
+<!DOCTYPE html> +<html + lang="fr-FR" + class="cicd2-theme"> +<head> + <meta property="og:url" content="https://cookidoo.fr/recipes/recipe/fr-FR/r829310"/> + <meta property="og:title" content="Marinade à la jamaïcaine pour le poulet"/> + <meta property="og:description" content="Un monde de recettes Thermomix® – Cookidoo® vous propose des plats délicieux dans le monde entier. +Avec des milliers de recettes et d’idées, vous trouverez une source d’inspiration succulente à chaque fois que vous vous connecterez."/> + <meta property="og:image" content="https://assets.tmecosys.com/image/upload/t_web_rdp_recipe_584x480/img/recipe/ras/Assets/51ae122040bc0b935382af31b7e3ce26/Derivates/c034c47d3681d4ae91896e76361bdf5205a738f0.jpg"/> + <meta name="robots" content="noarchive"/> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> + <link rel="stylesheet" href="https://patternlib-all.prod.external.eu-tm-prod.vorwerk-digital.com/pl-core-29.0.0-18aff5db89ac31d72351aa87f8d2dd94.css"> + <link rel="stylesheet" href="https://patternlib-all.prod.external.eu-tm-prod.vorwerk-digital.com/cicd2-theme-29.0.0-5eba483bfbb03f3a99d1d6c8cc61c91f.css"> + <link rel="stylesheet" href="https://recipepublic-all.prod.external.eu-tm-prod.vorwerk-digital.com/bundle-700b0b14b57bb2a7bf72133389c7f0a6.css"> + <link rel="icon" href="https://patternlib-all.prod.external.eu-tm-prod.vorwerk-digital.com/favicon-02a92602e0cf506ebd0186892a17fd82.ico"> + <link rel="preconnect" href="https://assets.tmecosys.com" crossorigin="anonymous"> + <script>"use strict";(()=>{function c(n){let t=document.cookie.match(new RegExp("(^| )"+n+"=([^;]+)"));if(t)return t[2]}var e={get:c};e.get("v-authenticated")?document.documentElement.classList.add("is-authenticated"):document.documentElement.classList.add("is-unauthenticated");})(); +</script> + <title>Marinade à la jamaïcaine pour le poulet - Cookidoo® – la plateforme de recettes officielle de Thermomix®</title> + <link rel="stylesheet" href="https://patternlib-all.prod.external.eu-tm-prod.vorwerk-digital.com/pl-recipe-2.18.1-4949e3c3f2b6c536234d63e48d89c215.css"> + <script type="application/ld+json">{"@context":"http://schema.org/","@type":"Recipe","name":"Marinade à la jamaïcaine pour le poulet","image":"https://assets.tmecosys.com/image/upload/t_web_rdp_recipe_584x480_1_5x/img/recipe/ras/Assets/51ae122040bc0b935382af31b7e3ce26/Derivates/c034c47d3681d4ae91896e76361bdf5205a738f0.jpg","totalTime":"PT10M","cookTime":"PT10M","prepTime":"PT10M","recipeYield":"350 g","recipeCategory":["Sauces, dips et tartinades","Plat principal - Viandes"],"recipeIngredient":["1 c. à soupe d'origan déshydraté","1 c. à café de graines de coriandre","100 g d'oignons","150 g de tomates","½ c. à café de paprika","2 gousses d'ail","15 g gingembres frais","1 c. à café de thym déshydraté","1 - 2 piment frais","30 g d'huile d'olive","30 g de sauce de soja","15 g de jus de citron"],"nutrition":{"@type":"NutritionInformation","calories":"419.4 kcal","carbohydrateContent":"32.5 g","fatContent":"31.4 g","proteinContent":"7.6 g"},"inLanguage":"fr-FR","author":{"@type":"Organization","name":"Vorwerk International & Co. KmG","address":"Wolleraustrasse 11a\n8807 Freienbach\nSuisse","url":"https://cookidoo.fr"},"aggregateRating":{"@id":"AggregatedRating"}}</script> +</head> + +<body> + <core-user-info + condition="html.is-authenticated" + community-profile="/community/profile/fr-FR" + devices="/customer-devices/api/my-devices/versions" + > + </core-user-info> + + <div class="page-content"> + + <header tabindex="-1" class="page-header"> + <div class="page-header__content"> + <a href="#main-content" class="link--skip">Skip to main content</a> + <a class="logo page-header__home authenticated-only" href="/foundation/fr-FR/for-you" + aria-label="Link to the home page"> + <img class="logo" src="https://patternlib-all.prod.external.eu-tm-prod.vorwerk-digital.com/logo_thermomix-02469c2fb4fca55fc3c397286d9e7fe0.svg" + alt="Thermomix®"> + </a> + <a class="logo page-header__home unauthenticated-only" href="/foundation/fr-FR/explore" + aria-label="Link to the home page"> + <img class="logo" src="https://patternlib-all.prod.external.eu-tm-prod.vorwerk-digital.com/logo_thermomix-02469c2fb4fca55fc3c397286d9e7fe0.svg" + alt="Thermomix®"> + </a> + <core-nav class="page-header__nav"> + <nav class="core-nav__nav" role="navigation"> + <button class="core-nav__trigger">Menu</button> + <div class="core-nav__container"> + <ul class="core-nav__main-links authenticated-only"> + <li class="core-nav__item"> + <a href="/foundation/fr-FR/for-you" + class="core-nav__link">Pour Vous</a> + </li> + <li class="core-nav__item"> + <a href="/foundation/fr-FR/explore" + class="core-nav__link">Découvrir</a> + </li> + <li class="core-nav__item"> + <a href="/organize/fr-FR/my-recipes" + class="core-nav__link">Mes recettes</a> + </li> + <li class="core-nav__item"> + <a href="/planning/fr-FR/my-week" + class="core-nav__link">Ma semaine</a> + </li> + <li class="core-nav__item"> + <a href="/shopping/fr-FR" + class="core-nav__link">Liste de courses</a> + </li> + </ul> + <ul class=" core-nav__main-links unauthenticated-only"> + <li class="core-nav__item"> + <a href="/foundation/fr-FR/explore" + class="core-nav__link">Découvrir</a> + </li> + <li class="core-nav__item"> + <a href="/foundation/fr-FR/membership" + class="core-nav__link">Abonnement</a> + </li> + <li class="core-nav__item"> + <a href="/foundation/fr-FR/help" + class="core-nav__link">Aide</a> + </li> + </ul> + <ul class="core-nav__links unauthenticated-only"> + <li class="core-nav__item"> + <a href="/ciam/register/start" + class="core-nav__link page-header__sign-up page-header__icon">Créer un compte</a> + </li> + <li class="core-nav__item"> + <a href="/profile/fr-FR/login?redirectAfterLogin=%2Frecipes%2Frecipe%2Ffr-FR%2Fr829310" + class="core-nav__link page-header__login page-header__icon">Se connecter</a> + </li> + </ul> + <div role="separator" aria-orientation="vertical" + class="core-nav__separator separator-vertical separator-vertical--silver-20"></div> + <core-user-profile class="authenticated-only"> + <core-dropdown-menu class="core-nav__dropdown core-nav__dropdown--profile" align="bottom-right"> + <button class="core-dropdown-menu__trigger core-nav__dropdown-trigger"> + <span class="core-nav__dropdown-trigger-icon" aria-hidden="true"></span> + <img class="core-nav__dropdown-trigger-picture" src alt> + <span class="core-dropdown-menu__trigger-text"> + Profil + </span> + </button> + <div class="core-dropdown-menu__content core-nav__dropdown-content"> + <ul class="core-dropdown-list core-nav__dropdown-list"> + <li class="core-community-profile__link"> + <a href="/community/profile/fr-FR" + class="core-dropdown-list__item core-nav__link core-nav__link--community"> + <core-community-profile> + <span class="core-community-profile__icon" aria-hidden="true"></span> + <img class="core-community-profile__picture" src alt> + <div class="core-community-profile__heading-group"> + <span class="core-community-profile__header">Profil</span> + <span class="core-community-profile__subheader">Voir le profil</span> + </div> + </core-community-profile> + </a> + </li> + <li> + <a href="/commerce/fr-FR/membership" + class="core-dropdown-list__item core-nav__link">Mon compte</a> + </li> + <li> + <a href="/foundation/fr-FR/help" + class="core-dropdown-list__item core-nav__link">Aide</a> + </li> + <li> + <a href="/profile/logout" + class="core-dropdown-list__item core-nav__link">Se déconnecter</a> + </li> + </ul> + </div> + </core-dropdown-menu> + </core-user-profile> + </div> + <div role="separator" aria-orientation="vertical" + class="core-nav__separator separator-vertical separator-vertical--silver-20"></div> + </nav> + </core-nav> + <a class="page-header__search page-header__icon" href="/search/fr-FR" + aria-label="Recherche">Recherche</a> + </div> + </header> + <recipe-scrollspy> + <nav class="recipe-scrollspy__nav"> + <a href="#ingredients-section" class="recipe-scrollspy__link">Ingrédients</a> + + <a href="#difficulty-section" class="recipe-scrollspy__link">Niveau</a> + + <a href="#nutrition-section" class="recipe-scrollspy__link">Informations nutritionnelles</a> + + <a href="#also-featured-in-section" class="recipe-scrollspy__link">Également inclus dans</a> + + <a id="recipe-scrollspy-alternative-recipes" href="#alternative-recipes" class="recipe-scrollspy__link">Vous pourriez aussi aimer...</a> + </nav> + </recipe-scrollspy> + + <recipe-details id="main-content"> + <recipe-card> + <div class="recipe-card__wrapper"> + <div class="recipe-card__image-wrapper"> + <core-image-loader> + <img + class="recipe-card__image" + src="https://assets.tmecosys.com/image/upload/t_web_rdp_recipe_584x480/img/recipe/ras/Assets/51ae122040bc0b935382af31b7e3ce26/Derivates/c034c47d3681d4ae91896e76361bdf5205a738f0.jpg" + srcset="https://assets.tmecosys.com/image/upload/t_web_rdp_recipe_584x480/img/recipe/ras/Assets/51ae122040bc0b935382af31b7e3ce26/Derivates/c034c47d3681d4ae91896e76361bdf5205a738f0.jpg 584w, https://assets.tmecosys.com/image/upload/t_web_rdp_recipe_584x480_1_5x/img/recipe/ras/Assets/51ae122040bc0b935382af31b7e3ce26/Derivates/c034c47d3681d4ae91896e76361bdf5205a738f0.jpg 876w" + sizes="(min-width: 1333px) 584px, (min-width: 768px) 50vw, 100vw" + alt="Marinade à la jamaïcaine pour le poulet" + title="Marinade à la jamaïcaine pour le poulet"/> + </core-image-loader> + </div> + <div class="recipe-card__info"> + + <div class="recipe-card__header"> + <div class="recipe-card__header-left"> + <rdp-badges id="tm-versions-modal"> + <button class="core-chip-button core-chip-button--flat core-chip-button--x-small"> + TM7 + </button> + <button class="core-chip-button core-chip-button--flat core-chip-button--x-small"> + TM6 + </button> + </rdp-badges> + + <core-modal + trigger-id="tm-versions-modal" + class="tm-versions-modal" + prevent-body-scroll="true" + hidden> + <div class="core-modal__wrapper"> + <div class="core-modal__container" role="dialog" aria-modal="true"> + + <div class="core-modal__header"> + <h2>Appareils et accessoires</h2> + <button class="core-modal__close" aria-label="Close Modal"></button> + </div> + + <core-scrollbar class="core-modal__content" fadeout-top> + <div class="core-scrollbar__content"> + + <rdp-tm-versions> + <p class="rdp-tm-versions__description">Cette recette est conçue pour une combinaison spécifique d'appareils et d'accessoires. Sans cette configuration requise, nous ne pouvons pas garantir un résultat satisfaisant.</p> + <div class="rdp-tm-versions__list"> + <div class="rdp-tm-versions__item"> + <img src="https://patternlib-all.prod.external.eu-tm-prod.vorwerk-digital.com/tm7-83b22c91a1a1e7fee3797168f05f9754.png" class="rdp-tm-versions__image"/> + <div class="rdp-tm-versions__wrapper"> + <span class="rdp-tm-versions__name">Thermomix® TM7</span> + <span class="rdp-tm-versions__compatibility"> + <span class="icon icon--checkmark-circle icon--xxxs"></span>Compatible + </span> + </div> + </div> + <div class="rdp-tm-versions__item"> + <img src="https://patternlib-all.prod.external.eu-tm-prod.vorwerk-digital.com/tm6-fff867f1cfc7f35118b8b6dfffca8339.png" class="rdp-tm-versions__image"/> + <div class="rdp-tm-versions__wrapper"> + <span class="rdp-tm-versions__name">Thermomix® TM6</span> + <span class="rdp-tm-versions__compatibility"> + <span class="icon icon--checkmark-circle icon--xxxs"></span>Compatible + </span> + </div> + </div> + </div> + </rdp-tm-versions> + + + </div> + </core-scrollbar> + + <div class="core-modal__footer"> + <a class="button--inline rdp-tm-versions__more" href="/foundation/fr-FR/thermomix-compatibility">Plus d’informations</a> + </div> + </div> + </div> + </core-modal> + + </div> + </div> + + <div class="recipe-card__content"> + <core-ellipsis lines-count="3"> + <h1 class="recipe-card__section recipe-card__name">Marinade à la jamaïcaine pour le poulet</h1> + </core-ellipsis> + + <core-rating> + <div class="core-rating__rating-list"> + <span class="core-rating__point core-rating__point--full"></span> + <span class="core-rating__point core-rating__point--full"></span> + <span class="core-rating__point core-rating__point--full"></span> + <span class="core-rating__point core-rating__point--full"></span> + <span class="core-rating__point core-rating__point--half"></span> + </div> + <span class="core-rating__counter">4.3</span> + <span class="core-rating__label"> + + 42 évaluation + + + </span> + <script type="application/ld+json"> + { + "@context": "http://schema.org", + "@type": "AggregateRating", + "@id": "AggregatedRating", + "ratingValue": 4.3, + "reviewCount": 42 + } + </script> +</core-rating> + + <div class="recipe-card__cook-params"> + <div class="recipe-card__cook-param"> + <span class="icon icon--time-preparation"></span> + <span>Prép. 10min </span> + </div> + <div class="recipe-card__cook-param"> + <span class="icon icon--time"></span> + <span>Total 10min</span> + </div> + <div class="recipe-card__cook-param"> + <span class="icon icon--servings"></span> + <span>350 g</span> + </div> + </div> + </div> + + <div class="recipe-card__footer"> + <a class="button--primary recipe-card__action-button recipe-card__action-button--primary" + title="Créer un compte gratuitement" + href="/ciam/register/start">Créer un compte gratuitement</a> + </div> + </div> + </div> + </recipe-card> + + <recipe-content> + <div class="recipe-content__left"> + <div mobile-order="1"> + <div id="ingredients-section" class="recipe-content__section"> + <h4 class="recipe-content__title">Ingrédients</h4> + <div class="recipe-content__inner-section"> + <ul class="ul--clean"> + <li> + <recipe-ingredient> + <div class="recipe-ingredient__wrapper"> + <img class="recipe-ingredient__image" src="https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48/icons/ingredient_icons/1140" + srcset="https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48/icons/ingredient_icons/1140 48w, https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48_1_5x/icons/ingredient_icons/1140 72w, https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48_2x/icons/ingredient_icons/1140 96w" + sizes="48px" + /> + + <div class="recipe-ingredient__content"> + <span class="recipe-ingredient__name"> + 1 + c. à soupe + d'origan déshydraté + </span> + </div> + </div> + </recipe-ingredient> + </li> + <li> + <recipe-ingredient> + <div class="recipe-ingredient__wrapper"> + <img class="recipe-ingredient__image" src="https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48/icons/ingredient_icons/299" + srcset="https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48/icons/ingredient_icons/299 48w, https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48_1_5x/icons/ingredient_icons/299 72w, https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48_2x/icons/ingredient_icons/299 96w" + sizes="48px" + /> + + <div class="recipe-ingredient__content"> + <span class="recipe-ingredient__name"> + 1 + c. à café + de graines de coriandre + </span> + </div> + </div> + </recipe-ingredient> + </li> + <li> + <recipe-ingredient> + <div class="recipe-ingredient__wrapper"> + <img class="recipe-ingredient__image" src="https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48/icons/ingredient_icons/18" + srcset="https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48/icons/ingredient_icons/18 48w, https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48_1_5x/icons/ingredient_icons/18 72w, https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48_2x/icons/ingredient_icons/18 96w" + sizes="48px" + /> + + <div class="recipe-ingredient__content"> + <span class="recipe-ingredient__name"> + 100 + g + d'oignons + </span> + <span class="recipe-ingredient__description">coupés en deux</span> + </div> + </div> + </recipe-ingredient> + </li> + <li> + <recipe-ingredient> + <div class="recipe-ingredient__wrapper"> + <img class="recipe-ingredient__image" src="https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48/icons/ingredient_icons/30" + srcset="https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48/icons/ingredient_icons/30 48w, https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48_1_5x/icons/ingredient_icons/30 72w, https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48_2x/icons/ingredient_icons/30 96w" + sizes="48px" + /> + + <div class="recipe-ingredient__content"> + <span class="recipe-ingredient__name"> + 150 + g + de tomates + </span> + </div> + </div> + </recipe-ingredient> + </li> + <li> + <recipe-ingredient> + <div class="recipe-ingredient__wrapper"> + <img class="recipe-ingredient__image" src="https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48/icons/ingredient_icons/2765" + srcset="https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48/icons/ingredient_icons/2765 48w, https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48_1_5x/icons/ingredient_icons/2765 72w, https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48_2x/icons/ingredient_icons/2765 96w" + sizes="48px" + /> + + <div class="recipe-ingredient__content"> + <span class="recipe-ingredient__name"> + ½ + c. à café + de paprika + </span> + </div> + </div> + </recipe-ingredient> + </li> + <li> + <recipe-ingredient> + <div class="recipe-ingredient__wrapper"> + <img class="recipe-ingredient__image" src="https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48/icons/ingredient_icons/352" + srcset="https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48/icons/ingredient_icons/352 48w, https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48_1_5x/icons/ingredient_icons/352 72w, https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48_2x/icons/ingredient_icons/352 96w" + sizes="48px" + /> + + <div class="recipe-ingredient__content"> + <span class="recipe-ingredient__name"> + 2 + + gousses d'ail + </span> + </div> + </div> + </recipe-ingredient> + </li> + <li> + <recipe-ingredient> + <div class="recipe-ingredient__wrapper"> + <img class="recipe-ingredient__image" src="https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48/icons/ingredient_icons/11" + srcset="https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48/icons/ingredient_icons/11 48w, https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48_1_5x/icons/ingredient_icons/11 72w, https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48_2x/icons/ingredient_icons/11 96w" + sizes="48px" + /> + + <div class="recipe-ingredient__content"> + <span class="recipe-ingredient__name"> + 15 + g + gingembres frais + </span> + </div> + </div> + </recipe-ingredient> + </li> + <li> + <recipe-ingredient> + <div class="recipe-ingredient__wrapper"> + <img class="recipe-ingredient__image" src="https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48/icons/ingredient_icons/986" + srcset="https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48/icons/ingredient_icons/986 48w, https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48_1_5x/icons/ingredient_icons/986 72w, https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48_2x/icons/ingredient_icons/986 96w" + sizes="48px" + /> + + <div class="recipe-ingredient__content"> + <span class="recipe-ingredient__name"> + 1 + c. à café + de thym déshydraté + </span> + </div> + </div> + </recipe-ingredient> + </li> + <li> + <recipe-ingredient> + <div class="recipe-ingredient__wrapper"> + <img class="recipe-ingredient__image" src="https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48/icons/ingredient_icons/62" + srcset="https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48/icons/ingredient_icons/62 48w, https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48_1_5x/icons/ingredient_icons/62 72w, https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48_2x/icons/ingredient_icons/62 96w" + sizes="48px" + /> + + <div class="recipe-ingredient__content"> + <span class="recipe-ingredient__name"> + 1 - 2 + + piment frais + </span> + </div> + </div> + </recipe-ingredient> + </li> + <li> + <recipe-ingredient> + <div class="recipe-ingredient__wrapper"> + <img class="recipe-ingredient__image" src="https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48/icons/ingredient_icons/195" + srcset="https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48/icons/ingredient_icons/195 48w, https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48_1_5x/icons/ingredient_icons/195 72w, https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48_2x/icons/ingredient_icons/195 96w" + sizes="48px" + /> + + <div class="recipe-ingredient__content"> + <span class="recipe-ingredient__name"> + 30 + g + d'huile d'olive + </span> + </div> + </div> + </recipe-ingredient> + </li> + <li> + <recipe-ingredient> + <div class="recipe-ingredient__wrapper"> + <img class="recipe-ingredient__image" src="https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48/icons/ingredient_icons/159" + srcset="https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48/icons/ingredient_icons/159 48w, https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48_1_5x/icons/ingredient_icons/159 72w, https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48_2x/icons/ingredient_icons/159 96w" + sizes="48px" + /> + + <div class="recipe-ingredient__content"> + <span class="recipe-ingredient__name"> + 30 + g + de sauce de soja + </span> + </div> + </div> + </recipe-ingredient> + </li> + <li> + <recipe-ingredient> + <div class="recipe-ingredient__wrapper"> + <img class="recipe-ingredient__image" src="https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48/icons/ingredient_icons/46" + srcset="https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48/icons/ingredient_icons/46 48w, https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48_1_5x/icons/ingredient_icons/46 72w, https://assets.tmecosys.com/image/upload/t_web_ingredient_48x48_2x/icons/ingredient_icons/46 96w" + sizes="48px" + /> + + <div class="recipe-ingredient__content"> + <span class="recipe-ingredient__name"> + 15 + g + de jus de citron + </span> + </div> + </div> + </recipe-ingredient> + </li> + </ul> + </div> + </div> + <hr> + </div> + <div mobile-order="3"> + <div id="difficulty-section" class="recipe-content__section"> + <h4 class="recipe-content__title">Niveau</h4> + <rdp-difficulty> + <span class="icon icon--s icon--chef-hat"></span> + <p>facile</p> + </rdp-difficulty> + </div> + <hr> + <div id="nutrition-section" class="recipe-content__section"> + <h4 class="recipe-content__title"> + Infos nut. + <span class="recipe-content__subtitle">par 350 g</span> + </h4> + <rdp-nutritious> + <div class="rdp-nutritious__item"> + <span class="rdp-nutritious__name">Sodium</span> + <span class="rdp-nutritious__value"> + 1671.4 mg + </span> + </div> + <div class="rdp-nutritious__item"> + <span class="rdp-nutritious__name">Protides</span> + <span class="rdp-nutritious__value"> + 7.6 g + </span> + </div> + <div class="rdp-nutritious__item"> + <span class="rdp-nutritious__name">Calories</span> + <span class="rdp-nutritious__value"> + 1754.9 kJ / + 419.4 kcal + </span> + </div> + <div class="rdp-nutritious__item"> + <span class="rdp-nutritious__name">Lipides</span> + <span class="rdp-nutritious__value"> + 31.4 g + </span> + </div> + <div class="rdp-nutritious__item"> + <span class="rdp-nutritious__name">Fibre</span> + <span class="rdp-nutritious__value"> + 8 g + </span> + </div> + <div class="rdp-nutritious__item"> + <span class="rdp-nutritious__name">Graisses saturées</span> + <span class="rdp-nutritious__value"> + 4.3 g + </span> + </div> + <div class="rdp-nutritious__item"> + <span class="rdp-nutritious__name">Glucides</span> + <span class="rdp-nutritious__value"> + 32.5 g + </span> + </div> + </rdp-nutritious> + </div> + <hr> + </div> + </div> + <div class="recipe-content__right"> + <div mobile-order="2"> + <div class="recipe-content__section"> + <recipe-membership-banner> + <img src="https://patternlib-all.prod.external.eu-tm-prod.vorwerk-digital.com/cookidoo-world-da330b8ec91ef8ac5df385f0e440dffb.svg" class="recipe-membership-banner__image" /> + <h1 class="recipe-membership-banner__title">Vous aimez ce que vous voyez ?</h1> + <h4 class="recipe-membership-banner__subtitle">Cette recette et plus de 100 000 autres vous attendent !</h4> + <p class="recipe-membership-banner__description">Inscrivez-vous à notre essai gratuit de 30 jours et découvrez le monde de Cookidoo®. Sans engagement.</p> + <a href="/ciam/register/start" class="button--primary">Créer un compte gratuitement</a> + <a href="/foundation/fr-FR/membership" class="button--inline">Plus d’informations</a> + </recipe-membership-banner> + </div> + <hr> + </div> + <div mobile-order="4"> + <div id="also-featured-in-section" class="recipe-content__section"> + <h4 class="recipe-content__title">Également présenté dans</h4> + <rdp-collections> + <rdp-collection-tile> + <a class="rdp-collection-tile__wrapper" href="/collection/fr-FR/p/col460825"> + <img src="https://assets.tmecosys.com/image/upload/t_web_col_80x80/img/collection/ras/Assets/72a08da2e408dafd03e15df1953b8261/Derivates/ac5c5aec51ad95509a8772ef714942267e1eb53e.jpg" + srcset="https://assets.tmecosys.com/image/upload/t_web_col_80x80/img/collection/ras/Assets/72a08da2e408dafd03e15df1953b8261/Derivates/ac5c5aec51ad95509a8772ef714942267e1eb53e.jpg 80w, https://assets.tmecosys.com/image/upload/t_web_col_80x80_1_5x/img/collection/ras/Assets/72a08da2e408dafd03e15df1953b8261/Derivates/ac5c5aec51ad95509a8772ef714942267e1eb53e.jpg 120w, https://assets.tmecosys.com/image/upload/t_web_col_80x80_2x/img/collection/ras/Assets/72a08da2e408dafd03e15df1953b8261/Derivates/ac5c5aec51ad95509a8772ef714942267e1eb53e.jpg 160w" + sizes="80px" + class="rdp-collection-tile__image"> + <div class="rdp-collection-tile__content"> + <span class="rdp-collection-tile__name">Barbecue party</span> + <span class="rdp-collection-tile__info">7 Recettes<br>France</span> + </div> + </a> + </rdp-collection-tile> + </rdp-collections> + </div> + <hr> + </div> + </div> + </recipe-content> + </recipe-details> + + + + + <div id="alternative-recipes" class="l-content l-content--additional recipe-alternative-recipes"> + <core-stripe class="core-stripe--modern" aria-labelledby="stripe-header" aria-describedby="stripe-description" role="region" + data-category="VrkNavCategory-RPF-018"> + <h3 class="core-stripe__header" id="stripe-header"> + Vous pourriez aussi aimer... + </h3> + <div class="core-stripe__content"> + + + + <core-tile class="core-tile--expanded" id="r756329" data-recipe-id="r756329"><a class="link--alt" href="/recipes/recipe/fr-FR/r756329"><div class="core-tile__image-wrapper"> + <img + class="core-tile__image" + alt="Poulet à la jamaïcaine" + title="Poulet à la jamaïcaine" + src="https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240/img/recipe/ras/Assets/6b1d4157-9803-48f0-97c7-b6000dd91673/Derivates/c1b5d931-ec23-4a83-8298-7e64a8e2b778" + sizes="221px" + decoding="async" + srcset="https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240/img/recipe/ras/Assets/6b1d4157-9803-48f0-97c7-b6000dd91673/Derivates/c1b5d931-ec23-4a83-8298-7e64a8e2b778 221w, https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240_1_5x/img/recipe/ras/Assets/6b1d4157-9803-48f0-97c7-b6000dd91673/Derivates/c1b5d931-ec23-4a83-8298-7e64a8e2b778 331w, https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240_2x/img/recipe/ras/Assets/6b1d4157-9803-48f0-97c7-b6000dd91673/Derivates/c1b5d931-ec23-4a83-8298-7e64a8e2b778 442w" + /> + </div><div class="core-tile__description-wrapper"><div class="core-tile__description"><core-ellipsis><p class="core-tile__description-text">Poulet à la jamaïcaine</p></core-ellipsis><button class="core-tile__trigger authenticated-only context-menu-trigger" aria-label="open context menu" type="button"></button></div><core-rating class="core-rating--short core-rating--small"><span class="core-rating__counter">4.7</span><span class="core-rating__point core-rating__point--full"></span><span class="core-rating__label">(108)</span></core-rating><p class="core-tile__description-subline">1h 40min</p></div></a><core-context-menu trigger-class="context-menu-trigger" class="translate-x-[0.5px]"><ul class="core-dropdown-list"><li><core-transclude href="/planning/fr-FR/transclude/manage-cook-today/r756329" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/organize/fr-FR/transclude/manage-bookmark/r756329" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/organize/fr-FR/transclude/manage-custom-list/r756329" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/planning/fr-FR/transclude/manage-add-to-myweek/r756329" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/shopping/fr-FR/partial/add-to-shopping-list/r756329" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/created-recipes/fr-FR/partials/add-to-customer-recipes?recipeUrl=https%3A%2F%2Fcookidoo.fr%2Frecipes%2Frecipe%2Ffr-FR%2Fr756329" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li data-error="401" data-redirect-param="redirectAfterLogin" class="display-none"><a href="/profile/fr-FR/login?redirectAfterLogin=%2Fsearch%2Ffr-FR%2Ffragments%2Fstripe%3Flimit%3D12%26lazyLoading%3Dtrue%26accessories%3DincludingFriend%252CincludingBladeCoverWithPeeler%252CincludingCutter%252CincludingSensor%26includeRating%3Dtrue%26like%3Dr829310" class="core-dropdown-list__item"><span class="icon" aria-hidden="true">refresh</span>Actualiser la connexion</a></li></ul></core-context-menu></core-tile><core-tile class="core-tile--expanded" id="r908668" data-recipe-id="r908668"><a class="link--alt" href="/recipes/recipe/fr-FR/r908668"><div class="core-tile__image-wrapper"> + <img + class="core-tile__image" + alt="Poulet frit coréen" + title="Poulet frit coréen" + src="https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240/img/recipe/ras/Assets/810cab8c8e2db7d6f71b4a6681a8fa99/Derivates/b37cbe66dd81315b474ae2f36454c02fb1133cba" + sizes="221px" + decoding="async" + srcset="https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240/img/recipe/ras/Assets/810cab8c8e2db7d6f71b4a6681a8fa99/Derivates/b37cbe66dd81315b474ae2f36454c02fb1133cba 221w, https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240_1_5x/img/recipe/ras/Assets/810cab8c8e2db7d6f71b4a6681a8fa99/Derivates/b37cbe66dd81315b474ae2f36454c02fb1133cba 331w, https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240_2x/img/recipe/ras/Assets/810cab8c8e2db7d6f71b4a6681a8fa99/Derivates/b37cbe66dd81315b474ae2f36454c02fb1133cba 442w" + /> + </div><div class="core-tile__description-wrapper"><div class="core-tile__description"><core-ellipsis><p class="core-tile__description-text">Poulet frit coréen</p></core-ellipsis><button class="core-tile__trigger authenticated-only context-menu-trigger" aria-label="open context menu" type="button"></button></div><core-rating class="core-rating--short core-rating--small"><span class="core-rating__counter">4.9</span><span class="core-rating__point core-rating__point--full"></span><span class="core-rating__label">(75)</span></core-rating><p class="core-tile__description-subline">3h 10min</p></div></a><core-context-menu trigger-class="context-menu-trigger" class="translate-x-[0.5px]"><ul class="core-dropdown-list"><li><core-transclude href="/planning/fr-FR/transclude/manage-cook-today/r908668" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/organize/fr-FR/transclude/manage-bookmark/r908668" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/organize/fr-FR/transclude/manage-custom-list/r908668" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/planning/fr-FR/transclude/manage-add-to-myweek/r908668" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/shopping/fr-FR/partial/add-to-shopping-list/r908668" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/created-recipes/fr-FR/partials/add-to-customer-recipes?recipeUrl=https%3A%2F%2Fcookidoo.fr%2Frecipes%2Frecipe%2Ffr-FR%2Fr908668" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li data-error="401" data-redirect-param="redirectAfterLogin" class="display-none"><a href="/profile/fr-FR/login?redirectAfterLogin=%2Fsearch%2Ffr-FR%2Ffragments%2Fstripe%3Flimit%3D12%26lazyLoading%3Dtrue%26accessories%3DincludingFriend%252CincludingBladeCoverWithPeeler%252CincludingCutter%252CincludingSensor%26includeRating%3Dtrue%26like%3Dr829310" class="core-dropdown-list__item"><span class="icon" aria-hidden="true">refresh</span>Actualiser la connexion</a></li></ul></core-context-menu></core-tile><core-tile class="core-tile--expanded" id="r907216" data-recipe-id="r907216"><a class="link--alt" href="/recipes/recipe/fr-FR/r907216"><div class="core-tile__image-wrapper"> + <img + class="core-tile__image" + alt="Pastilla au poulet, aux amandes et à la cannelle" + title="Pastilla au poulet, aux amandes et à la cannelle" + src="https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240/img/recipe/ras/Assets/23c0d981598924410a9d979961e4650a/Derivates/4ccf128453e573890fd08f43531b2c58b5b59c62" + sizes="221px" + decoding="async" + srcset="https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240/img/recipe/ras/Assets/23c0d981598924410a9d979961e4650a/Derivates/4ccf128453e573890fd08f43531b2c58b5b59c62 221w, https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240_1_5x/img/recipe/ras/Assets/23c0d981598924410a9d979961e4650a/Derivates/4ccf128453e573890fd08f43531b2c58b5b59c62 331w, https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240_2x/img/recipe/ras/Assets/23c0d981598924410a9d979961e4650a/Derivates/4ccf128453e573890fd08f43531b2c58b5b59c62 442w" + /> + </div><div class="core-tile__description-wrapper"><div class="core-tile__description"><core-ellipsis><p class="core-tile__description-text">Pastilla au poulet, aux amandes et à la cannelle</p></core-ellipsis><button class="core-tile__trigger authenticated-only context-menu-trigger" aria-label="open context menu" type="button"></button></div><core-rating class="core-rating--short core-rating--small"><span class="core-rating__counter">3.9</span><span class="core-rating__point core-rating__point--full"></span><span class="core-rating__label">(17)</span></core-rating><p class="core-tile__description-subline">2h 5min</p></div></a><core-context-menu trigger-class="context-menu-trigger" class="translate-x-[0.5px]"><ul class="core-dropdown-list"><li><core-transclude href="/planning/fr-FR/transclude/manage-cook-today/r907216" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/organize/fr-FR/transclude/manage-bookmark/r907216" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/organize/fr-FR/transclude/manage-custom-list/r907216" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/planning/fr-FR/transclude/manage-add-to-myweek/r907216" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/shopping/fr-FR/partial/add-to-shopping-list/r907216" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/created-recipes/fr-FR/partials/add-to-customer-recipes?recipeUrl=https%3A%2F%2Fcookidoo.fr%2Frecipes%2Frecipe%2Ffr-FR%2Fr907216" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li data-error="401" data-redirect-param="redirectAfterLogin" class="display-none"><a href="/profile/fr-FR/login?redirectAfterLogin=%2Fsearch%2Ffr-FR%2Ffragments%2Fstripe%3Flimit%3D12%26lazyLoading%3Dtrue%26accessories%3DincludingFriend%252CincludingBladeCoverWithPeeler%252CincludingCutter%252CincludingSensor%26includeRating%3Dtrue%26like%3Dr829310" class="core-dropdown-list__item"><span class="icon" aria-hidden="true">refresh</span>Actualiser la connexion</a></li></ul></core-context-menu></core-tile><core-tile class="core-tile--expanded" id="r903087" data-recipe-id="r903087"><a class="link--alt" href="/recipes/recipe/fr-FR/r903087"><div class="core-tile__image-wrapper"> + <img + class="core-tile__image" + alt="Galettes de poisson thaïes" + title="Galettes de poisson thaïes" + src="https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240/img/recipe/ras/Assets/42f9ec10cbe31b2e8a9f8f2de8c160c2/Derivates/1312f74d6c7c2ba3ecd6d50e264b7b1c2d968449" + sizes="221px" + decoding="async" + srcset="https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240/img/recipe/ras/Assets/42f9ec10cbe31b2e8a9f8f2de8c160c2/Derivates/1312f74d6c7c2ba3ecd6d50e264b7b1c2d968449 221w, https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240_1_5x/img/recipe/ras/Assets/42f9ec10cbe31b2e8a9f8f2de8c160c2/Derivates/1312f74d6c7c2ba3ecd6d50e264b7b1c2d968449 331w, https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240_2x/img/recipe/ras/Assets/42f9ec10cbe31b2e8a9f8f2de8c160c2/Derivates/1312f74d6c7c2ba3ecd6d50e264b7b1c2d968449 442w" + /> + </div><div class="core-tile__description-wrapper"><div class="core-tile__description"><core-ellipsis><p class="core-tile__description-text">Galettes de poisson thaïes</p></core-ellipsis><button class="core-tile__trigger authenticated-only context-menu-trigger" aria-label="open context menu" type="button"></button></div><core-rating class="core-rating--short core-rating--small"><span class="core-rating__counter">3.3</span><span class="core-rating__point core-rating__point--full"></span><span class="core-rating__label">(7)</span></core-rating><p class="core-tile__description-subline">30min</p></div></a><core-context-menu trigger-class="context-menu-trigger" class="translate-x-[0.5px]"><ul class="core-dropdown-list"><li><core-transclude href="/planning/fr-FR/transclude/manage-cook-today/r903087" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/organize/fr-FR/transclude/manage-bookmark/r903087" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/organize/fr-FR/transclude/manage-custom-list/r903087" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/planning/fr-FR/transclude/manage-add-to-myweek/r903087" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/shopping/fr-FR/partial/add-to-shopping-list/r903087" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/created-recipes/fr-FR/partials/add-to-customer-recipes?recipeUrl=https%3A%2F%2Fcookidoo.fr%2Frecipes%2Frecipe%2Ffr-FR%2Fr903087" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li data-error="401" data-redirect-param="redirectAfterLogin" class="display-none"><a href="/profile/fr-FR/login?redirectAfterLogin=%2Fsearch%2Ffr-FR%2Ffragments%2Fstripe%3Flimit%3D12%26lazyLoading%3Dtrue%26accessories%3DincludingFriend%252CincludingBladeCoverWithPeeler%252CincludingCutter%252CincludingSensor%26includeRating%3Dtrue%26like%3Dr829310" class="core-dropdown-list__item"><span class="icon" aria-hidden="true">refresh</span>Actualiser la connexion</a></li></ul></core-context-menu></core-tile><core-tile class="core-tile--expanded" id="r901347" data-recipe-id="r901347"><a class="link--alt" href="/recipes/recipe/fr-FR/r901347"><div class="core-tile__image-wrapper"> + <img + class="core-tile__image" + alt="Salade de spaghetti de concombre coréen" + title="Salade de spaghetti de concombre coréen" + src="https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240/img/recipe/ras/Assets/f98f688fa551d6d8b43e746e29614d3f/Derivates/661cb4e1bc2b9fe228947a0134732878502b8ba5" + sizes="221px" + decoding="async" + srcset="https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240/img/recipe/ras/Assets/f98f688fa551d6d8b43e746e29614d3f/Derivates/661cb4e1bc2b9fe228947a0134732878502b8ba5 221w, https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240_1_5x/img/recipe/ras/Assets/f98f688fa551d6d8b43e746e29614d3f/Derivates/661cb4e1bc2b9fe228947a0134732878502b8ba5 331w, https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240_2x/img/recipe/ras/Assets/f98f688fa551d6d8b43e746e29614d3f/Derivates/661cb4e1bc2b9fe228947a0134732878502b8ba5 442w" + /> + </div><div class="core-tile__description-wrapper"><div class="core-tile__description"><core-ellipsis><p class="core-tile__description-text">Salade de spaghetti de concombre coréen</p></core-ellipsis><button class="core-tile__trigger authenticated-only context-menu-trigger" aria-label="open context menu" type="button"></button></div><core-rating class="core-rating--short core-rating--small"><span class="core-rating__counter">4.7</span><span class="core-rating__point core-rating__point--full"></span><span class="core-rating__label">(9)</span></core-rating><p class="core-tile__description-subline">25min</p></div></a><core-context-menu trigger-class="context-menu-trigger" class="translate-x-[0.5px]"><ul class="core-dropdown-list"><li><core-transclude href="/planning/fr-FR/transclude/manage-cook-today/r901347" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/organize/fr-FR/transclude/manage-bookmark/r901347" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/organize/fr-FR/transclude/manage-custom-list/r901347" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/planning/fr-FR/transclude/manage-add-to-myweek/r901347" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/shopping/fr-FR/partial/add-to-shopping-list/r901347" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/created-recipes/fr-FR/partials/add-to-customer-recipes?recipeUrl=https%3A%2F%2Fcookidoo.fr%2Frecipes%2Frecipe%2Ffr-FR%2Fr901347" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li data-error="401" data-redirect-param="redirectAfterLogin" class="display-none"><a href="/profile/fr-FR/login?redirectAfterLogin=%2Fsearch%2Ffr-FR%2Ffragments%2Fstripe%3Flimit%3D12%26lazyLoading%3Dtrue%26accessories%3DincludingFriend%252CincludingBladeCoverWithPeeler%252CincludingCutter%252CincludingSensor%26includeRating%3Dtrue%26like%3Dr829310" class="core-dropdown-list__item"><span class="icon" aria-hidden="true">refresh</span>Actualiser la connexion</a></li></ul></core-context-menu></core-tile><core-tile class="core-tile--expanded" id="r828641" data-recipe-id="r828641"><a class="link--alt" href="/recipes/recipe/fr-FR/r828641"><div class="core-tile__image-wrapper"> + <img + class="core-tile__image" + alt="Pad thaï au poulet" + title="Pad thaï au poulet" + src="https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240/img/recipe/ras/Assets/6a47c937e175adcf36f9fef947e800cc/Derivates/69dca562372f3db8e3eaace29bbd82f92de6abce" + sizes="221px" + decoding="async" + srcset="https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240/img/recipe/ras/Assets/6a47c937e175adcf36f9fef947e800cc/Derivates/69dca562372f3db8e3eaace29bbd82f92de6abce 221w, https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240_1_5x/img/recipe/ras/Assets/6a47c937e175adcf36f9fef947e800cc/Derivates/69dca562372f3db8e3eaace29bbd82f92de6abce 331w, https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240_2x/img/recipe/ras/Assets/6a47c937e175adcf36f9fef947e800cc/Derivates/69dca562372f3db8e3eaace29bbd82f92de6abce 442w" + /> + </div><div class="core-tile__description-wrapper"><div class="core-tile__description"><core-ellipsis><p class="core-tile__description-text">Pad thaï au poulet</p></core-ellipsis><button class="core-tile__trigger authenticated-only context-menu-trigger" aria-label="open context menu" type="button"></button></div><core-rating class="core-rating--short core-rating--small"><span class="core-rating__counter">3.6</span><span class="core-rating__point core-rating__point--full"></span><span class="core-rating__label">(122)</span></core-rating><p class="core-tile__description-subline">2h</p></div></a><core-context-menu trigger-class="context-menu-trigger" class="translate-x-[0.5px]"><ul class="core-dropdown-list"><li><core-transclude href="/planning/fr-FR/transclude/manage-cook-today/r828641" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/organize/fr-FR/transclude/manage-bookmark/r828641" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/organize/fr-FR/transclude/manage-custom-list/r828641" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/planning/fr-FR/transclude/manage-add-to-myweek/r828641" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/shopping/fr-FR/partial/add-to-shopping-list/r828641" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/created-recipes/fr-FR/partials/add-to-customer-recipes?recipeUrl=https%3A%2F%2Fcookidoo.fr%2Frecipes%2Frecipe%2Ffr-FR%2Fr828641" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li data-error="401" data-redirect-param="redirectAfterLogin" class="display-none"><a href="/profile/fr-FR/login?redirectAfterLogin=%2Fsearch%2Ffr-FR%2Ffragments%2Fstripe%3Flimit%3D12%26lazyLoading%3Dtrue%26accessories%3DincludingFriend%252CincludingBladeCoverWithPeeler%252CincludingCutter%252CincludingSensor%26includeRating%3Dtrue%26like%3Dr829310" class="core-dropdown-list__item"><span class="icon" aria-hidden="true">refresh</span>Actualiser la connexion</a></li></ul></core-context-menu></core-tile><core-tile class="core-tile--expanded" id="r828628" data-recipe-id="r828628"><a class="link--alt" href="/recipes/recipe/fr-FR/r828628"><div class="core-tile__image-wrapper"> + <img + class="core-tile__image" + alt="Ailes de poulet, sauce aux cacahuètes et riz basmati" + title="Ailes de poulet, sauce aux cacahuètes et riz basmati" + src="https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240/img/recipe/ras/Assets/97df9afaf5d541030f966f3cb7d25ac2/Derivates/098b33c682e55e4b348c6bea8aef2d45e7ffa06a" + sizes="221px" + decoding="async" + srcset="https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240/img/recipe/ras/Assets/97df9afaf5d541030f966f3cb7d25ac2/Derivates/098b33c682e55e4b348c6bea8aef2d45e7ffa06a 221w, https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240_1_5x/img/recipe/ras/Assets/97df9afaf5d541030f966f3cb7d25ac2/Derivates/098b33c682e55e4b348c6bea8aef2d45e7ffa06a 331w, https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240_2x/img/recipe/ras/Assets/97df9afaf5d541030f966f3cb7d25ac2/Derivates/098b33c682e55e4b348c6bea8aef2d45e7ffa06a 442w" + /> + </div><div class="core-tile__description-wrapper"><div class="core-tile__description"><core-ellipsis><p class="core-tile__description-text">Ailes de poulet, sauce aux cacahuètes et riz basmati</p></core-ellipsis><button class="core-tile__trigger authenticated-only context-menu-trigger" aria-label="open context menu" type="button"></button></div><core-rating class="core-rating--short core-rating--small"><span class="core-rating__counter">3.6</span><span class="core-rating__point core-rating__point--full"></span><span class="core-rating__label">(24)</span></core-rating><p class="core-tile__description-subline">50min</p></div></a><core-context-menu trigger-class="context-menu-trigger" class="translate-x-[0.5px]"><ul class="core-dropdown-list"><li><core-transclude href="/planning/fr-FR/transclude/manage-cook-today/r828628" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/organize/fr-FR/transclude/manage-bookmark/r828628" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/organize/fr-FR/transclude/manage-custom-list/r828628" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/planning/fr-FR/transclude/manage-add-to-myweek/r828628" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/shopping/fr-FR/partial/add-to-shopping-list/r828628" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/created-recipes/fr-FR/partials/add-to-customer-recipes?recipeUrl=https%3A%2F%2Fcookidoo.fr%2Frecipes%2Frecipe%2Ffr-FR%2Fr828628" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li data-error="401" data-redirect-param="redirectAfterLogin" class="display-none"><a href="/profile/fr-FR/login?redirectAfterLogin=%2Fsearch%2Ffr-FR%2Ffragments%2Fstripe%3Flimit%3D12%26lazyLoading%3Dtrue%26accessories%3DincludingFriend%252CincludingBladeCoverWithPeeler%252CincludingCutter%252CincludingSensor%26includeRating%3Dtrue%26like%3Dr829310" class="core-dropdown-list__item"><span class="icon" aria-hidden="true">refresh</span>Actualiser la connexion</a></li></ul></core-context-menu></core-tile><core-tile class="core-tile--expanded" id="r827021" data-recipe-id="r827021"><a class="link--alt" href="/recipes/recipe/fr-FR/r827021"><div class="core-tile__image-wrapper"> + <img + class="core-tile__image" + alt="Achards de légumes" + title="Achards de légumes" + src="https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240/img/recipe/ras/Assets/0008488e3118ecf745aa5ff579258323/Derivates/6f45dd4c422e2e2006d7c3ac84e93f587c015872" + sizes="221px" + decoding="async" + srcset="https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240/img/recipe/ras/Assets/0008488e3118ecf745aa5ff579258323/Derivates/6f45dd4c422e2e2006d7c3ac84e93f587c015872 221w, https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240_1_5x/img/recipe/ras/Assets/0008488e3118ecf745aa5ff579258323/Derivates/6f45dd4c422e2e2006d7c3ac84e93f587c015872 331w, https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240_2x/img/recipe/ras/Assets/0008488e3118ecf745aa5ff579258323/Derivates/6f45dd4c422e2e2006d7c3ac84e93f587c015872 442w" + /> + </div><div class="core-tile__description-wrapper"><div class="core-tile__description"><core-ellipsis><p class="core-tile__description-text">Achards de légumes</p></core-ellipsis><button class="core-tile__trigger authenticated-only context-menu-trigger" aria-label="open context menu" type="button"></button></div><core-rating class="core-rating--short core-rating--small"><span class="core-rating__counter">4.9</span><span class="core-rating__point core-rating__point--full"></span><span class="core-rating__label">(8)</span></core-rating><p class="core-tile__description-subline">40min</p></div></a><core-context-menu trigger-class="context-menu-trigger" class="translate-x-[0.5px]"><ul class="core-dropdown-list"><li><core-transclude href="/planning/fr-FR/transclude/manage-cook-today/r827021" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/organize/fr-FR/transclude/manage-bookmark/r827021" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/organize/fr-FR/transclude/manage-custom-list/r827021" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/planning/fr-FR/transclude/manage-add-to-myweek/r827021" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/shopping/fr-FR/partial/add-to-shopping-list/r827021" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/created-recipes/fr-FR/partials/add-to-customer-recipes?recipeUrl=https%3A%2F%2Fcookidoo.fr%2Frecipes%2Frecipe%2Ffr-FR%2Fr827021" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li data-error="401" data-redirect-param="redirectAfterLogin" class="display-none"><a href="/profile/fr-FR/login?redirectAfterLogin=%2Fsearch%2Ffr-FR%2Ffragments%2Fstripe%3Flimit%3D12%26lazyLoading%3Dtrue%26accessories%3DincludingFriend%252CincludingBladeCoverWithPeeler%252CincludingCutter%252CincludingSensor%26includeRating%3Dtrue%26like%3Dr829310" class="core-dropdown-list__item"><span class="icon" aria-hidden="true">refresh</span>Actualiser la connexion</a></li></ul></core-context-menu></core-tile><core-tile class="core-tile--expanded" id="r818197" data-recipe-id="r818197"><a class="link--alt" href="/recipes/recipe/fr-FR/r818197"><div class="core-tile__image-wrapper"> + <img + class="core-tile__image" + alt="Curry thaï de bœuf, pois gourmands et riz" + title="Curry thaï de bœuf, pois gourmands et riz" + src="https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240/img/recipe/ras/Assets/0de33bcf9fd7d19951a2084076babb50/Derivates/a987ef060d111f048e3749eec292734bc49cdd83" + sizes="221px" + decoding="async" + srcset="https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240/img/recipe/ras/Assets/0de33bcf9fd7d19951a2084076babb50/Derivates/a987ef060d111f048e3749eec292734bc49cdd83 221w, https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240_1_5x/img/recipe/ras/Assets/0de33bcf9fd7d19951a2084076babb50/Derivates/a987ef060d111f048e3749eec292734bc49cdd83 331w, https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240_2x/img/recipe/ras/Assets/0de33bcf9fd7d19951a2084076babb50/Derivates/a987ef060d111f048e3749eec292734bc49cdd83 442w" + /> + </div><div class="core-tile__description-wrapper"><div class="core-tile__description"><core-ellipsis><p class="core-tile__description-text">Curry thaï de bœuf, pois gourmands et riz</p></core-ellipsis><button class="core-tile__trigger authenticated-only context-menu-trigger" aria-label="open context menu" type="button"></button></div><core-rating class="core-rating--short core-rating--small"><span class="core-rating__counter">3.8</span><span class="core-rating__point core-rating__point--full"></span><span class="core-rating__label">(39)</span></core-rating><p class="core-tile__description-subline">1h 15min</p></div></a><core-context-menu trigger-class="context-menu-trigger" class="translate-x-[0.5px]"><ul class="core-dropdown-list"><li><core-transclude href="/planning/fr-FR/transclude/manage-cook-today/r818197" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/organize/fr-FR/transclude/manage-bookmark/r818197" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/organize/fr-FR/transclude/manage-custom-list/r818197" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/planning/fr-FR/transclude/manage-add-to-myweek/r818197" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/shopping/fr-FR/partial/add-to-shopping-list/r818197" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/created-recipes/fr-FR/partials/add-to-customer-recipes?recipeUrl=https%3A%2F%2Fcookidoo.fr%2Frecipes%2Frecipe%2Ffr-FR%2Fr818197" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li data-error="401" data-redirect-param="redirectAfterLogin" class="display-none"><a href="/profile/fr-FR/login?redirectAfterLogin=%2Fsearch%2Ffr-FR%2Ffragments%2Fstripe%3Flimit%3D12%26lazyLoading%3Dtrue%26accessories%3DincludingFriend%252CincludingBladeCoverWithPeeler%252CincludingCutter%252CincludingSensor%26includeRating%3Dtrue%26like%3Dr829310" class="core-dropdown-list__item"><span class="icon" aria-hidden="true">refresh</span>Actualiser la connexion</a></li></ul></core-context-menu></core-tile><core-tile class="core-tile--expanded" id="r908324" data-recipe-id="r908324"><a class="link--alt" href="/recipes/recipe/fr-FR/r908324"><div class="core-tile__image-wrapper"> + <img + class="core-tile__image" + alt="Poitrine de porc croustillante et salade de riz chaud" + title="Poitrine de porc croustillante et salade de riz chaud" + src="https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240/img/recipe/ras/Assets/158a8c8584e3e8a67f438d46814baf2a/Derivates/eaf5ab6a53e456a9fc1cae959960d89bf233fac7" + sizes="221px" + decoding="async" + srcset="https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240/img/recipe/ras/Assets/158a8c8584e3e8a67f438d46814baf2a/Derivates/eaf5ab6a53e456a9fc1cae959960d89bf233fac7 221w, https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240_1_5x/img/recipe/ras/Assets/158a8c8584e3e8a67f438d46814baf2a/Derivates/eaf5ab6a53e456a9fc1cae959960d89bf233fac7 331w, https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240_2x/img/recipe/ras/Assets/158a8c8584e3e8a67f438d46814baf2a/Derivates/eaf5ab6a53e456a9fc1cae959960d89bf233fac7 442w" + /> + </div><div class="core-tile__description-wrapper"><div class="core-tile__description"><core-ellipsis><p class="core-tile__description-text">Poitrine de porc croustillante et salade de riz chaud</p></core-ellipsis><button class="core-tile__trigger authenticated-only context-menu-trigger" aria-label="open context menu" type="button"></button></div><core-rating class="core-rating--short core-rating--small"><span class="core-rating__counter">4.7</span><span class="core-rating__point core-rating__point--full"></span><span class="core-rating__label">(10)</span></core-rating><p class="core-tile__description-subline">1h 30min</p></div></a><core-context-menu trigger-class="context-menu-trigger" class="translate-x-[0.5px]"><ul class="core-dropdown-list"><li><core-transclude href="/planning/fr-FR/transclude/manage-cook-today/r908324" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/organize/fr-FR/transclude/manage-bookmark/r908324" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/organize/fr-FR/transclude/manage-custom-list/r908324" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/planning/fr-FR/transclude/manage-add-to-myweek/r908324" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/shopping/fr-FR/partial/add-to-shopping-list/r908324" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/created-recipes/fr-FR/partials/add-to-customer-recipes?recipeUrl=https%3A%2F%2Fcookidoo.fr%2Frecipes%2Frecipe%2Ffr-FR%2Fr908324" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li data-error="401" data-redirect-param="redirectAfterLogin" class="display-none"><a href="/profile/fr-FR/login?redirectAfterLogin=%2Fsearch%2Ffr-FR%2Ffragments%2Fstripe%3Flimit%3D12%26lazyLoading%3Dtrue%26accessories%3DincludingFriend%252CincludingBladeCoverWithPeeler%252CincludingCutter%252CincludingSensor%26includeRating%3Dtrue%26like%3Dr829310" class="core-dropdown-list__item"><span class="icon" aria-hidden="true">refresh</span>Actualiser la connexion</a></li></ul></core-context-menu></core-tile><core-tile class="core-tile--expanded" id="r828643" data-recipe-id="r828643"><a class="link--alt" href="/recipes/recipe/fr-FR/r828643"><div class="core-tile__image-wrapper"> + <img + class="core-tile__image" + alt="Brochettes de poulet sauce satay et salade de concombres" + title="Brochettes de poulet sauce satay et salade de concombres" + src="https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240/img/recipe/ras/Assets/dd29ed1de21b1e86738986187fae87e6/Derivates/7ca357836bc9d6681ae3db44ec8d757e4b7f531c" + sizes="221px" + decoding="async" + srcset="https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240/img/recipe/ras/Assets/dd29ed1de21b1e86738986187fae87e6/Derivates/7ca357836bc9d6681ae3db44ec8d757e4b7f531c 221w, https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240_1_5x/img/recipe/ras/Assets/dd29ed1de21b1e86738986187fae87e6/Derivates/7ca357836bc9d6681ae3db44ec8d757e4b7f531c 331w, https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240_2x/img/recipe/ras/Assets/dd29ed1de21b1e86738986187fae87e6/Derivates/7ca357836bc9d6681ae3db44ec8d757e4b7f531c 442w" + /> + </div><div class="core-tile__description-wrapper"><div class="core-tile__description"><core-ellipsis><p class="core-tile__description-text">Brochettes de poulet sauce satay et salade de concombres</p></core-ellipsis><button class="core-tile__trigger authenticated-only context-menu-trigger" aria-label="open context menu" type="button"></button></div><core-rating class="core-rating--short core-rating--small"><span class="core-rating__counter">4.5</span><span class="core-rating__point core-rating__point--full"></span><span class="core-rating__label">(22)</span></core-rating><p class="core-tile__description-subline">1h 35min</p></div></a><core-context-menu trigger-class="context-menu-trigger" class="translate-x-[0.5px]"><ul class="core-dropdown-list"><li><core-transclude href="/planning/fr-FR/transclude/manage-cook-today/r828643" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/organize/fr-FR/transclude/manage-bookmark/r828643" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/organize/fr-FR/transclude/manage-custom-list/r828643" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/planning/fr-FR/transclude/manage-add-to-myweek/r828643" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/shopping/fr-FR/partial/add-to-shopping-list/r828643" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/created-recipes/fr-FR/partials/add-to-customer-recipes?recipeUrl=https%3A%2F%2Fcookidoo.fr%2Frecipes%2Frecipe%2Ffr-FR%2Fr828643" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li data-error="401" data-redirect-param="redirectAfterLogin" class="display-none"><a href="/profile/fr-FR/login?redirectAfterLogin=%2Fsearch%2Ffr-FR%2Ffragments%2Fstripe%3Flimit%3D12%26lazyLoading%3Dtrue%26accessories%3DincludingFriend%252CincludingBladeCoverWithPeeler%252CincludingCutter%252CincludingSensor%26includeRating%3Dtrue%26like%3Dr829310" class="core-dropdown-list__item"><span class="icon" aria-hidden="true">refresh</span>Actualiser la connexion</a></li></ul></core-context-menu></core-tile><core-tile class="core-tile--expanded" id="r907173" data-recipe-id="r907173"><a class="link--alt" href="/recipes/recipe/fr-FR/r907173"><div class="core-tile__image-wrapper"> + <img + class="core-tile__image" + alt="Bricks de pommes de terre au thon et à la coriandre" + title="Bricks de pommes de terre au thon et à la coriandre" + src="https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240/img/recipe/ras/Assets/1ce511d5f3b9a911d5c71366e152d339/Derivates/a8a3414bfa512da5a4fa11a4b1af0bb65f040a82" + sizes="221px" + decoding="async" + srcset="https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240/img/recipe/ras/Assets/1ce511d5f3b9a911d5c71366e152d339/Derivates/a8a3414bfa512da5a4fa11a4b1af0bb65f040a82 221w, https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240_1_5x/img/recipe/ras/Assets/1ce511d5f3b9a911d5c71366e152d339/Derivates/a8a3414bfa512da5a4fa11a4b1af0bb65f040a82 331w, https://assets.tmecosys.com/image/upload/t_web_shared_recipe_221x240_2x/img/recipe/ras/Assets/1ce511d5f3b9a911d5c71366e152d339/Derivates/a8a3414bfa512da5a4fa11a4b1af0bb65f040a82 442w" + /> + </div><div class="core-tile__description-wrapper"><div class="core-tile__description"><core-ellipsis><p class="core-tile__description-text">Bricks de pommes de terre au thon et à la coriandre</p></core-ellipsis><button class="core-tile__trigger authenticated-only context-menu-trigger" aria-label="open context menu" type="button"></button></div><core-rating class="core-rating--short core-rating--small"><span class="core-rating__counter">4.6</span><span class="core-rating__point core-rating__point--full"></span><span class="core-rating__label">(71)</span></core-rating><p class="core-tile__description-subline">1h 10min</p></div></a><core-context-menu trigger-class="context-menu-trigger" class="translate-x-[0.5px]"><ul class="core-dropdown-list"><li><core-transclude href="/planning/fr-FR/transclude/manage-cook-today/r907173" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/organize/fr-FR/transclude/manage-bookmark/r907173" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/organize/fr-FR/transclude/manage-custom-list/r907173" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/planning/fr-FR/transclude/manage-add-to-myweek/r907173" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/shopping/fr-FR/partial/add-to-shopping-list/r907173" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li><core-transclude href="/created-recipes/fr-FR/partials/add-to-customer-recipes?recipeUrl=https%3A%2F%2Fcookidoo.fr%2Frecipes%2Frecipe%2Ffr-FR%2Fr907173" prevent-page-reload="true" on="context-menu-open" context="core-context-menu"></core-transclude></li><li data-error="401" data-redirect-param="redirectAfterLogin" class="display-none"><a href="/profile/fr-FR/login?redirectAfterLogin=%2Fsearch%2Ffr-FR%2Ffragments%2Fstripe%3Flimit%3D12%26lazyLoading%3Dtrue%26accessories%3DincludingFriend%252CincludingBladeCoverWithPeeler%252CincludingCutter%252CincludingSensor%26includeRating%3Dtrue%26like%3Dr829310" class="core-dropdown-list__item"><span class="icon" aria-hidden="true">refresh</span>Actualiser la connexion</a></li></ul></core-context-menu></core-tile> + + + + </div> + + + </core-stripe> + </div> + <core-toast aria-live="assertive"></core-toast> + + + +<core-footer lang="fr-FR"> + <footer class="core-footer__content"> + <div class="footer-copyright"> + <span class="core-footer__copyright">© Copyright 2026</span> + </div> + <nav> + <ul class="core-footer__links"> + <li class="authenticated-only"> + <a class="core-footer__link link--alt" href="/consent/web/customers/fr-FR/documents/TOS"> + Conditions d'utilisation + </a> + </li> + <li class="authenticated-only"> + <a class="core-footer__link link--alt" href="/consent/web/customers/fr-FR/documents/PRIVACY"> + Politique de confidentialité + </a> + </li> + <li class="unauthenticated-only"> + <a class="core-footer__link link--alt" href="/consent/web/documents/fr-FR/latest/tos"> + Conditions d'utilisation + </a> + </li> + <li class="unauthenticated-only"> + <a class="core-footer__link link--alt" href="/consent/web/documents/fr-FR/latest/privacy"> + Politique de confidentialité + </a> + </li> + <li> + <a class="core-footer__link link--alt" href="/foundation/fr-FR/disclaimer">Non-responsabilité</a> + </li> + <li> + <a class="core-footer__link link--alt" href="/foundation/fr-FR/imprint">Mentions légales</a> + </li> + <li> + <a class="core-footer__link link--alt" href="/foundation/fr-FR/cookie-policy">Cookies</a> + </li> + <li> + <wf-fetch-modal + href="/foundation/fr-FR/partials/footer-modal-report-content?page=foundation/dsa" + selector="wf-report-content-modal" + > + <a class="core-footer__link link--alt" href="javascript:void(0)"> + Contenu du rapport + </a> + </wf-fetch-modal> + </li> + <li> + <a class="core-footer__link link--alt" href="/foundation/fr-FR/european-accessibility-act"> + Déclaration d'accessibilité + </a> + </li> + </ul> + </nav> + <core-fetch-modal + href="/foundation/fr-FR/partials/footer-modal?page=%2Frecipes%2Frecipe%2F%7Blang%7D%2Fr829310"> + <button class="core-footer__language-btn" aria-label="change language"> + <span class="icon" aria-hidden="true">language</span> + <span class="core-footer__current-lang">français</span> + <core-loader class="core-loader--dots"></core-loader> + </button> + </core-fetch-modal> + </footer> +</core-footer> + + <script + src="https://cdn.cookielaw.org/scripttemplates/otSDKStub.js" + type="text/javascript" + charset="UTF-8" + data-domain-script="9ccaf04f-2bce-4a4f-a618-ad33eaa5c8fd" + data-document-language="true"> + </script> + <script> + function OptanonWrapper() { + window.dispatchEvent(new CustomEvent('consentChange', { detail: { onetrustActiveGroups: window.OnetrustActiveGroups } })) + } + </script> +<script src="https://patternlib-all.prod.external.eu-tm-prod.vorwerk-digital.com/pl-web-foundation-footer-3.58.2-e4e3551269686cc40b4ef8bf6dcfa73d.js" crossorigin="anonymous"></script> +<link rel="stylesheet" href="https://patternlib-all.prod.external.eu-tm-prod.vorwerk-digital.com/pl-web-foundation-footer-3.58.2-7eeea7600f85cb74e2c24554e4440bb5.css" /> +<core-tos-privacy-update + update-url="/consent/web/customers/fr-FR/consent-update-flow" + button-text="Accepter" + default-headline="Des modifications ont été apportées à notre Politique de confidentialité ou à nos Conditions d'utilisation." + autoload-condition="html.is-authenticated" +></core-tos-privacy-update> +<core-feedback + url-api="/commerce/api/subscriptions/churn-feedback" + url-modal="/commerce/fr-FR/subscriptions/churn-feedback" + url-api-skip="/commerce/api/subscriptions/churn-feedback/skip" + message-success="Votre commentaire a été envoyé. Merci beaucoup !" + message-error="Une erreur s’est produite, votre commentaire n’a pas pu être envoyé. Veuillez réessayer." + call-on-init="true"> +</core-feedback> + <!-- Snowplow starts plowing --> + <meta name="xRequestMarket" content="fr"> + <meta name="marketCode" content="fr"> + <meta name="snowplowConnector" content="https://c.cookidoo.fr"> + <meta name="snowplowAppId" content="cookidoo"> + + <script type="text/javascript"> + window.addEventListener("consentChange", function(e) { + const oneTrustGroups = window.OnetrustActiveGroups + const userGivesConsent = oneTrustGroups.includes('C0002') + if (!userGivesConsent) { + if (!window.snowplow) return + window.snowplow('disableButtonClickTracking'); + window.snowplow('disableActivityTracking'); + window.snowplow('disableActivityTrackingCallback'); + window.snowplow('flushBuffer'); + window.snowplow('clearUserData'); + window.snowplow = undefined + return + } + + ;(function(p,l,o,w,i,n,g){if(!p[i]){p.GlobalSnowplowNamespace=p.GlobalSnowplowNamespace||[]; p.GlobalSnowplowNamespace.push(i);p[i]=function(){(p[i].q=p[i].q||[]).push(arguments) };p[i].q=p[i].q||[];n=l.createElement(o);g=l.getElementsByTagName(o)[0];n.async=1; n.src=w;g.parentNode.insertBefore(n,g)}}(window,document,"script",'/foundation/assets/qdyrnotslk.js',"snowplow")); + + const devMode = localStorage.getItem('snowplowDebug') === 'true' + window.snowplow('newTracker', 'sp1', 'https://c.cookidoo.fr', { + appId: 'cookidoo', + ...(devMode ? { + eventMethod: 'get', + credentials: 'omit', + } : {}), + discoverRootDomain: true, + cookieSameSite: 'Lax', + contexts: { + session: true, + performanceTiming: true, + }, + plugins: [] + }); + + if (window.snowplowReady) { + window.snowplowResolve && window.snowplowResolve() + return + } + window.snowplowReady = new Promise(r => r()) + }) + </script> + + +<style scoped> + @media only screen and (min-width: 1333px) { + .footer-copyright { + margin-bottom: 1.5rem; + margin-top: -1.5rem; + } + } +</style> + + + + </div> + <core-lazy-loading></core-lazy-loading> + <script crossorigin="anonymous" src="https://patternlib-all.prod.external.eu-tm-prod.vorwerk-digital.com/pl-core-29.0.0-ef7c31e69a40dfd9073ff607719ae635.js"></script> + <script crossorigin="anonymous" src="https://recipepublic-all.prod.external.eu-tm-prod.vorwerk-digital.com/bundle-16dfe1fa4c43ce84038ae2662c3667c0.js"></script> + <script crossorigin="anonymous" src="https://patternlib-all.prod.external.eu-tm-prod.vorwerk-digital.com/pl-recipe-2.18.1-8028f06cc62cca3548570453f00bad42.js"></script> +</body> +</html>
A
utils/html.ts
@@ -0,0 +1,2 @@
+export const decodeHtmlChars = (content: string) => + content.replaceAll("½", "1/2");
A
utils/llm.ts
@@ -0,0 +1,24 @@
+import { load } from "@std/dotenv"; + +const env = await load({ envPath: ".env" }); + +const mistralApiKey = env["MISTRAL_APIKEY"]; +const mistralApiUrl = "https://api.mistral.ai/v1/chat/completions"; + +export const callLLM = async (prompt: string) => { + const response = await fetch(mistralApiUrl, { + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${mistralApiKey}`, + }, + body: JSON.stringify({ + model: "mistral-small-latest", + response_format: { type: "json_object" }, + messages: [{ role: "user", content: prompt }], + }), + }); + + const data = await response.json(); + return data.choices[0].message.content; +};