{-# LANGUAGE OverloadedLists #-} module Rosetta.WritingSpec where import Data.GenValidity.Map () import Data.GenValidity.Sequence () import Data.GenValidity.Set () import Data.GenValidity.Text () import Data.List qualified as List import Data.Map.Strict qualified as Map import Data.Text qualified as Text import Data.Validity.Map () import Data.Validity.Set () import Data.Validity.Text () import System.FilePath (joinPath, pathSeparator, (<.>), ()) import Test.Syd import Language import Language.Chinese qualified as Chinese import Language.Pronunciation qualified as Pron import Rosetta.Reading qualified as Reading import Rosetta.Writing import Worksheets.Utils.Char qualified as Char import Worksheets.Utils.HTML (cm) import Worksheets.Utils.HTML qualified as HTML import Worksheets.Utils.Prelude runPages :: String -> Pages -> TestDefM (Chinese.ChineseDict : outers) () () runPages title pages_ = do descrPath <- getTestDescriptionPath let dirPath = List.reverse descrPath <&> Text.unpack . Text.replace (Text.pack ".") (Text.singleton pathSeparator) & joinPath let outPath = "tests" dirPath title "rosetta" <.> "html" itWithOuter title \dict -> do goldenByteStringBuilderFile outPath $ pagesHTML dict (Text.pack title) pages_ spec :: HasCallStack => Spec spec = aroundAll readDict do -- runPage "Avion" avion -- runPage "Bateau" bateau -- runPage "Chocolat" chocolat -- runPage "Pistache" pistache -- runPage "Egg" egg -- runPage "Pluie" pluie -- runPage "TarteAuxPommes" tarteAuxPommesDanniversaire -- runPage "ChatChevalVélo" chatChevalVélo -- runPage "chevauxDormirDebout" chevauxDormirDebout forM_ (rosettas & Map.toList) \(name, pages) -> runPages name pages where readDict :: (Chinese.ChineseDict -> IO ()) -> IO () -- readDict k = k mempty readDict = (Chinese.readChineseDict >>=) {- chocolat = mempty { pageParts = [ PagePart { partPicture = "Plantes/Cacao/Fruit-cacao-tree-source-cocoa-chocolate-plant.avif" , partDescription = "" , partLangue = LangueFrançais , partText = "Le chocolat contient du cacao" } , PagePart { partPicture = "Plantes/Cacao/42f651_95f537d693fb48068880a02efa662822~mv2.avif" , partDescription = "" , partLangue = LangueAnglais , partText = "Chocolate contains cocoa" } , PagePart { partPicture = "Plantes/Cacao/Chocolate-Ingredients_520x500_c496776e-df9b-4348-a662-5ff65279f5ca.avif" , partDescription = "" , partLangue = LangueMandarin , partText = "巧克力 含有 可可" } ] } pistache = mempty { pageParts = [ PagePart { partPicture = "Plantes/Pistache/581614a479ee6b4df250c4caddc04bca.avif" , partDescription = "" , partLangue = LangueFrançais , partText = "La glace à la pistache est délicieuse" } , PagePart { partPicture = "Plantes/Pistache/pistachios.avif" , partDescription = "" , partLangue = LangueAnglais , partText = "Pistachio ice cream is delicious" } , PagePart { partPicture = "Plantes/Pistache/No-Churn-Vegan-Pistachio-Ice-Cream-3-e1502503524224.avif" , partDescription = "" , partLangue = LangueMandarin , partText = "开心果 冰淇淋 很 好吃" } ] } avion = mempty { pageParts = [ PagePart { partPicture = "Avion/sound-barrier.avif" , partDescription = "" , partLangue = LangueFrançais , partText = "Avion dans le ciel" } , PagePart { partPicture = "Avion/mustang.avif" , partDescription = "" , partLangue = LangueAnglais , partText = "Airoplane in the sky" } , PagePart { partPicture = "Avion/cockpit.avif" , partDescription = "" , partLangue = LangueMandarin , partText = "天空 中 有 一 架 飞机" } ] } egg = mempty { pageParts = [ PagePart { partPicture = "Egg/R.avif" , partDescription = "" , partLangue = LangueFrançais , partText = "Les poules pondent des œufs" } , PagePart { partPicture = "Egg/everything-you-ever-wanted-to-know-about-chicken-eggs.avif" , partDescription = "" , partLangue = LangueAnglais , partText = "Hens lay eggs" } , PagePart { partPicture = "Egg/OIP.avif" , partDescription = "" , partLangue = LangueMandarin , partText = "母鸡 下蛋" } ] } pluie = mempty { pageParts = [ PagePart { partPicture = "Pluie/R.avif" , partDescription = "" , partLangue = LangueFrançais , partText = "L'eau de pluie retourne à l'océan" } , PagePart { partPicture = "Pluie/OIP2.avif" , partDescription = "" , partLangue = LangueAnglais , partText = "Rainwater returns to the ocean" } , PagePart { partPicture = "Pluie/c1b4767475208de5a389045b7ad856a0.avif" , partDescription = "" , partLangue = LangueMandarin , partText = "雨水 回归 海洋" } ] } tarteAuxPommesDanniversaire = mempty { pageParts = [ PagePart { partPicture = "TarteAuxPommesDanniversaire/IMG_20250605_180725.avif" , partDescription = "" , partLangue = LangueFrançais , partText = "Délicieuse tarte aux pommes d'anniversaire" } , PagePart { partPicture = "TarteAuxPommesDanniversaire/VID_20250605_214924.mp4.00-01-40-421.avif" , partDescription = "" , partLangue = LangueAnglais , partText = "Delicious birthday apple pie" } , PagePart { partPicture = "TarteAuxPommesDanniversaire/VID_20250605_214924.mp4.00-01-47-284.avif" , partDescription = "" , partLangue = LangueMandarin , partText = "美味 的 生日 苹果派" } ] } chatChevalVélo = mempty { pageParts = [ PagePart { partPicture = "Chat/IMG_20250605_194233_truffe.avif" , partDescription = "" , partLangue = LangueFrançais , partText = "chat cheval vélo" } , PagePart { partPicture = "Cheval/IMG_20250602_170549_himalaya.avif" , partDescription = "" , partLangue = LangueAnglais , partText = "cat horse bicycle" } , PagePart { partPicture = "Vélo/IMG_20250602_155624.fav.vélos.avif" , partDescription = "" , partLangue = LangueMandarin , partText = "猫 马 自行车" } ] } -} pages :: Pages pages = typeDefault { pagesDifficulties = langues & Map.fromSet \_lang -> Char.unicodeBlocks & Map.fromSet difficulty -- <&> (\v -> v{difficultyHiddenPatterns = True}) -- & Map.mapWithKey (\k v -> v{difficultyReading = v & difficultyReading & }) } page :: Page page = typeDefault difficulty :: Char.UnicodeBlock -> Difficulty difficulty ub = case ub of Char.UnicodeBlockLatin{} -> Difficulty { difficultyModel = True , difficultyHiddenPatterns = True , difficultyReading = Reading.Difficulty { Reading.difficultyCharWidth = 1 & cm , Reading.difficultyCharHeight = 1 & cm , Reading.difficultyWordSpacing = 0.5 & cm , Reading.difficultyFontSize = 0.7 & cm } } Char.UnicodeBlockCJK{} -> Difficulty { difficultyModel = False , difficultyHiddenPatterns = False , difficultyReading = Reading.Difficulty { Reading.difficultyCharWidth = 1.5 & cm , Reading.difficultyCharHeight = 1.5 & cm , Reading.difficultyWordSpacing = 0.5 & cm , Reading.difficultyFontSize = 1.20 & cm } } Char.UnicodeBlockHalfwidth_and_Fullwidth_Forms{} -> Difficulty { difficultyModel = True , difficultyHiddenPatterns = False , difficultyReading = Reading.Difficulty { Reading.difficultyCharWidth = 1.35 & cm , Reading.difficultyCharHeight = 1.35 & cm , Reading.difficultyWordSpacing = 0.5 & cm , Reading.difficultyFontSize = 1.10 & cm } } Char.UnicodeBlockMiscellaneous_Technical{} -> difficulty $ Char.UnicodeBlockLatin Char.UnicodeBlockLatin_Basic _ -> typeDefault rosettas :: Map String Pages rosettas = [] {- "bateau" := page { pageParts = [ typeDefault { partPicture = "Bateau/pirate-boat.avif" , partPictureCSS = HTML.cssBlockObjectFitCover <> ["object-position" := "center -1.2cm"] , partDescription = "" , partLangue = LangueFrançais , partText = "Un bateau flotte si moins dense que l’eau" } , typeDefault { partPicture = "Bateau/tanker.avif" , partPictureCSS = HTML.cssBlockObjectFitCover <> ["object-position" := "center -2.5cm"] , partDescription = "" , partLangue = LangueAnglais , partText = "A boat floats if less dense than water" } , typeDefault { partPicture = "Bateau/catamaran.avif" , partPictureCSS = HTML.cssBlockObjectFitCover <> ["object-position" := "center -0.8cm"] , partDescription = "" , partLangue = LangueMandarin , partText = "船 漂浮 如果 小 密度 于 水" } ] } & pagePortrait , "chocolat" := page { pageParts = [ typeDefault { partPicture = "Plantes/Cacao/Fruit-cacao-tree-source-cocoa-chocolate-plant.avif" , partDescription = "" , partLangue = LangueFrançais , partText = "Le chocolat contient du cacao" } , typeDefault { partPicture = "Plantes/Cacao/42f651_95f537d693fb48068880a02efa662822~mv2.avif" , partDescription = "" , partLangue = LangueAnglais , partText = "Chocolate contains cocoa" } , typeDefault { partPicture = "Plantes/Cacao/Chocolate-Ingredients_520x500_c496776e-df9b-4348-a662-5ff65279f5ca.avif" , partDescription = "" , partLangue = LangueMandarin , partText = "巧克力 含有 可可" } ] } & pageLandscape , "chevauxDormirDebout" := page { pageParts = [ typeDefault { partPicture = "Cheval/R5.avif" , partDescription = "" , partLangue = LangueFrançais , partText = "Les chevaux peuvent dormir debout" } , typeDefault { partPicture = "Cheval/Do-Horses-Lay-Down-to-Sleep.avif" , partDescription = "" , partLangue = LangueAnglais , partText = "Horses can sleep standing up" } , typeDefault { partPicture = "Cheval/3YVGNyR45fw5NwHQxvJ8P6.avif" , partDescription = "" , partLangue = LangueMandarin , partText = "马 可以 站 着 睡觉" } ] } & pageLandscape , "ponies" := page { pageParts = [ typeDefault { partPicture = "Poney/Horse-and-pony2.avif" , partPictureCSS = HTML.cssBlockObjectFitCover , partDescription = "" , partLangue = LangueFrançais , partText = "Les poneys sont petits mais costauds" } , typeDefault { partPicture = "Poney/A-girl-equestrian-athlete-jumps-on-a-horse-high-barrier-ss230301-768x448.jpg.avif" , partPictureCSS = HTML.cssBlockObjectFitCover , partDescription = "" , partLangue = LangueAnglais , partText = "Ponies are small but strong" } , typeDefault { partPicture = "Poney/horse-pull.avif" , partPictureCSS = HTML.cssBlockObjectFitCover , partDescription = "" , partLangue = LangueMandarin , partText = "小马 虽 小 但 很 强壮" } ] } & pageLandscape , "poniesRaces1" := page { pageParts = [ typeDefault { partPicture = "Poney/Shetland/Canva-Ponies-of-the-New-Forest-scaled.avif" , partPictureCSS = HTML.cssBlockObjectFitCover , partDescription = "Shetland Pony" , partLangue = LangueFrançais , partText = "Il existe environ 159 races de poneys" } , typeDefault { partPicture = "Poney/PoneyFrançaisDeSelle/pho11-1441004372-ulk-modele1.avif" , partPictureCSS = HTML.cssBlockObjectFitCover , partDescription = "Poney Français de Selle" , partLangue = LangueAnglais , partText = "There are approximately 159 pony breeds" } , typeDefault { partPicture = "Poney/NorwegianFjord/shutterstock_2092896190-1024x683.avif" , partPictureCSS = HTML.cssBlockObjectFitCover , partDescription = "Norwegian Fjord Pony" , partLangue = LangueMandarin , partText = "有 大约 159 个 小马 品种" } ] } & pageLandscape , "poniesRaces2" := page { pageParts = [ typeDefault { partPicture = "Poney/Haflinger/GettyImages-546441489-3087a0a3f3a0486f96e7e6d7eb0b6bc1.avif" , partPictureCSS = HTML.cssBlockObjectFitCover , partDescription = "Haflinger Pony" , partLangue = LangueFrançais , partText = "Il existe environ 159 races de poneys" } , typeDefault { partPicture = "Poney/Dartmoor/GettyImages-149824058-ee7fd8a5e9984f5a9dc73c5916a238aa.avif" , partPictureCSS = HTML.cssBlockObjectFitCover , partDescription = "Dartmoor Pony" , partLangue = LangueAnglais , partText = "There are approximately 159 pony breeds" } , typeDefault { partPicture = "Poney/Connemara/eaa17d54a2978f5962edc405f0beabb7.avif" , partPictureCSS = HTML.cssBlockObjectFitCover , partDescription = "Connemara Pony" , partLangue = LangueMandarin , partText = "有 大约 159 个 小马 品种" } ] } & pageLandscape , "poniesRaces3" := page { pageParts = [ typeDefault { partPicture = "Poney/AmericanQuarter/American-Quarter-Horse-stallion-1024x614.avif" , partPictureCSS = HTML.cssBlockObjectFitCover , partDescription = "American Quarter Pony" , partLangue = LangueFrançais , partText = "Il existe environ 159 races de poneys" } , typeDefault { partPicture = "Poney/Welsh/GettyImages-1318833798-1024x768.avif" , partPictureCSS = HTML.cssBlockObjectFitCover , partDescription = "Welsh Pony" , partLangue = LangueAnglais , partText = "There are approximately 159 pony breeds" } , typeDefault { partPicture = "Poney/PonyOfTheAmericas/GettyImages-519556294-1024x683.avif" , partPictureCSS = HTML.cssBlockObjectFitCover , partDescription = "Pony of the Americas" , partLangue = LangueMandarin , partText = "有 大约 159 个 小马 品种" } ] } & pageLandscape , "poniesRaces4" := page { pageParts = [ typeDefault { partPicture = "Poney/Haflinger/041221-haflinger-3.avif" , partPictureCSS = HTML.cssBlockObjectFitCover , partDescription = "Haflinger Pony" , partLangue = LangueFrançais , partText = "Il existe environ 159 races de poneys" } , typeDefault { partPicture = "Poney/Eriskay/shutterstock-2214350479-huge-licensed-scaled.avif" , partPictureCSS = HTML.cssBlockObjectFitCover , partDescription = "Eriskay Pony" , partLangue = LangueAnglais , partText = "There are approximately 159 pony breeds" } , typeDefault { partPicture = "Poney/BritishRiding/GettyImages-175411286-1024x683.avif" , partPictureCSS = HTML.cssBlockObjectFitCover , partDescription = "British Riding Pony" , partLangue = LangueMandarin , partText = "有 大约 159 个 小马 品种" } ] } & pageLandscape , "Culicoides" := page { pageParts = [ typeDefault { partPicture = "Culicoides/Blood-Feeding-Culicoides-Midges.avif" , partPictureCSS = HTML.cssBlockObjectFitCover , partLangue = LangueFrançais , partText = "Les moucherons culicoides sont des vampires infectieuses" } , typeDefault { partPicture = "Culicoides/Mosquito_(Ochlerotatus_annulipes)_and_Midge_(Culicoides_impunctatus)_biting_human_(me).avif" , partPictureCSS = HTML.cssBlockObjectFitCover , partLangue = LangueAnglais , partText = "Culicoides midges are infectious vampires" } , typeDefault { partPicture = "Culicoides/CSIRO_ScienceImage_1791_SEM_of_a_biting_midge_Culicoides_brevitarsis.avif" , partPictureCSS = HTML.cssBlockObjectFitCover , partLangue = LangueMandarin , partText = "库蠓属 具有 传染性 的 吸血鬼" } ] } & pageLandscape , "Fraise" := page { pageParts = [ typeDefault { partPicture = "Fraise/96caabc77f79887c4bbcb2383092707b.avif" , partLangue = LangueFrançais , partText = "Les fruits de la fraise sont les akènes" } , typeDefault { partPicture = "Fraise/OIP.avif" , partPictureCSS = HTML.cssBlockObjectFitCover , partLangue = LangueAnglais , partText = "Strawberry's fruits are the achenes" } , typeDefault { partPicture = "Fraise/Coupe_d'une_fraise_dont_les_akènes_ont_germés.avif" , partLangue = LangueMandarin , partText = "草莓 的 果实 是 瘦果" } ] } & pageLandscape , "poupéeArielle" := page { pageParts = [ typeDefault { partPicture = "ArielleLaPetiteSirène/3aff97d2a3c36b307c12e7ea36e2000b.avif" , partLangue = LangueFrançais , partText = "Arielle la poupée et Merlin le garçon" } , typeDefault { partPicture = "ArielleLaPetiteSirène/halle-bailey-as-ariel-in-the-little-mermaid-zk-1280x2120.small.avif" , partLangue = LangueAnglais , partText = "Ariel the doll and Merlin the boy" } , typeDefault { partPicture = "Poupée/IMG_20250613_111606.avif" , partLangue = LangueMandarin , partText = "娃娃 Arielle 和 男孩 梅林" } ] } & pageLandscape , "poupéeBella" := page { pageParts = [ typeDefault { partPicture = "LaBelleEtLaBête/batbjpg-fe2293_1280w.avif" , partLangue = LangueFrançais , partText = "Bella la poupée et Maya la fille" } , typeDefault { partPicture = "LaBelleEtLaBête/disney-live-action-02.avif" , partPictureCSS = HTML.cssBlockObjectFitCover , partLangue = LangueAnglais , partText = "Bella the doll and Maya the girl" } , typeDefault { partPicture = "Poupée/IMG_20250613_111730.avif" , partLangue = LangueMandarin , partText = "娃娃 Bella 和 女孩 马雅" -- 玛雅 } ] } & pagePortrait , "Mûre" := page { pageParts = [ typeDefault { partPicture = "Mûre/Bee-Feeding-on-Blackberry-Blossom.avif" , partPictureCSS = HTML.cssBlockObjectFitCover , partLangue = LangueFrançais , partText = "Les fruits de la mûre sont des drupéoles" } , typeDefault { partPicture = "Mûre/blackberry-anatomy.avif" , partLangue = LangueAnglais , partText = "Blackberry's fruits are drupelets" } , typeDefault { partPicture = "Mûre/berryblack.avif" , partPictureCSS = HTML.cssBlockObjectFitCover , partLangue = LangueMandarin , partText = "黑莓 的 果实 是 小 核果" } ] } & pageLandscape , "Framboise" := page { pageParts = [ typeDefault { partPicture = "Framboise/ghows-SR-6c5aadd8-13b2-7679-e053-0100007f79b5-ad44228b.avif" , partPictureCSS = HTML.cssBlockObjectFitCover <> ["object-position" := "left center"] , partLangue = LangueFrançais , partText = "Le réceptacle de la framboise reste accroché au buisson" } , typeDefault { partPicture = "Framboise/framboise-schema-fr.avif" , partLangue = LangueAnglais , partText = "Raspberry's receptacle clings to the bush" } , typeDefault { partPicture = "Framboise/OIP.avif" , partPictureCSS = HTML.cssBlockObjectFitCover <> ["object-position" := "right bottom"] , partLangue = LangueMandarin , partText = "山莓 的 花托 紧贴 灌木丛" } ] } & pageLandscape , "Mustang" := page { pageParts = [ typeDefault { partPicture = "Cheval/Mustang/2.avif" , partPictureCSS = HTML.cssBlockObjectFitCover <> ["object-position" := "left center"] , partLangue = LangueFrançais , partText = "La plupart des chevaux mustangs sont sauvages" } , typeDefault { partPicture = "Cheval/Mustang/10.avif" , partPictureCSS = HTML.cssBlockObjectFitCover <> ["object-position" := "left center"] , partLangue = LangueAnglais , partText = "Most mustang horses are wild" } , typeDefault { partPicture = "Cheval/Mustang/6.avif" , partPictureCSS = HTML.cssBlockObjectFitCover , partLangue = LangueMandarin , partText = "大多数 美洲野马 是 野马" } ] } & pageLandscape , "TortueDeMerMigration" := page { pageParts = [ typeDefault { partPicture = "Tortue/tumblr_mxnwydKTfm1qm9k25o1_1280.avif" , partPictureCSS = HTML.cssBlockObjectFitCover <> ["object-position" := "left center"] , partLangue = LangueFrançais , partText = "Les tortues de mer peuvent traverser un océan à la nage" } , typeDefault { partPicture = "Tortue/SWOT_XV_Global_Loggerhead_V3_20200220.crop.avif" , partPictureCSS = [ "object-fit" := "contain" , "object-position" := "center center" ] , partLangue = LangueAnglais , partText = "Sea turtles can swim across an ocean" } , typeDefault { partPicture = "Tortue/sea-turtle8.avif" , partPictureCSS = HTML.cssBlockObjectFitCover , partLangue = LangueMandarin , partText = "海龟 可以 游泳 横穿 海洋" } ] } & pageLandscape , "LoupsHurlent" := page { pageParts = [ typeDefault { partPicture = "Loup/197922.avif" , partPictureCSS = HTML.cssBlockObjectFitCover , partLangue = LangueFrançais , partText = "Les loups hurlent pour se rassembler ou pour alerter" } , typeDefault { partPicture = "Loup/portrait-of-arctic-wolf-free-photo.avif" , partPictureCSS = HTML.cssBlockObjectFitCover , partLangue = LangueAnglais , partText = "Wolves howl to reassemble or to alert" } , typeDefault { partPicture = "Loup/R.avif" , partPictureCSS = HTML.cssBlockObjectFitCover , partLangue = LangueMandarin , partText = "狼 嚎 以 团结 在一起 或 警告" } ] } & pageLandscape , "PapillonCitron" := page { pageParts = [ typeDefault { partPicture = "Papillon/Brimstone/t0109e2365f058fa5bb.avif" , partPictureCSS = [ "object-fit" := "cover" , "object-position" := "left center" ] , partLangue = LangueFrançais , partText = "Le papillon citron peut survivre à l'hiver" } , typeDefault { partPicture = "Papillon/Brimstone/brimstone_life_cycle_l.avif" , partPictureCSS = [ "object-fit" := "contain" ] , partLangue = LangueAnglais , partText = "The brimstone butterfly can survive the winter" } , typeDefault { partPicture = "Papillon/Brimstone/brimstone_characteristics_l.avif" , partPictureCSS = [ "object-fit" := "contain" ] , partLangue = LangueMandarin , partText = "钩粉蝶 可以 度过 冬天" } ] } & pageLandscape , "Seasons" := page { pageParts = [ typeDefault { partPicture = "Seasons/canadian-seasons-mircea-costina.jpg" , partPictureCSS = [ "object-fit" := "cover" , "object-position" := "center center" ] , partLangue = LangueFrançais , partText = "L'été, le soleil chauffe longtemps et frontalement" } , typeDefault { partPicture = "Seasons/summer.avif" , partPictureCSS = [ "object-fit" := "cover" ] , partLangue = LangueAnglais , partText = "In summer, sun's warming is longest and most frontal" } , typeDefault { partPicture = "Seasons/winter.avif" , partPictureCSS = [ "object-fit" := "cover" ] , partLangue = LangueMandarin , partText = "夏季, 太阳 的 加热 最 长 且 最 正面" } ] } & pageLandscape , "Christmas" := page { pageParts = [ typeDefault { partPicture = "Christmas/Cici-Fang-Christmas-Consumerism-1-pdf.avif" , partPictureCSS = [ "object-fit" := "cover" --, "object-position" := "center center" ] , partLangue = LangueFrançais , partText = "Noël est une fête de la consommation et de la fantaisie" } , typeDefault { partPicture = "Christmas/l_etrange_noel_de_monsieur_jack.avif" , partPictureCSS = [ "object-fit" := "cover" ] , partLangue = LangueAnglais , partText = "Christmas celebrates consumption and fantasy" } , typeDefault { partPicture = "Christmas/Olafs.Frozen.Adventure.2017.720p.BluRay.x264.AAC-[YTS.MX].mp4.00-09-29-527.avif" , partPictureCSS = [ "object-fit" := "cover" , "object-position" := "-1.75cm center" ] , partLangue = LangueMandarin , partText = "圣诞节 庆祝会 消费量 和 幻想" } ] } & pageLandscape , "LoupsEtCorbeaux" := page { pageParts = [ typeDefault { partPicture = "Loup/wolf-raven.avif" , partPictureCSS = HTML.cssBlockObjectFitCover , partLangue = LangueFrançais , partText = [Right "Loups et Corbeaux jouent et chassent souvent ensemble"] } , typeDefault { partPicture = "Loup/Screen Shot 2013-08-19 at 10.38.26 PM.avif" , partPictureCSS = HTML.cssBlockObjectFitCover , partLangue = LangueAnglais , partText = [Right "Wolves and ravens often play and hunt together"] } , typeDefault { partPicture = "Loup/NPS_WolfMagpiesRavens_NOV16_HerbertNeal.avif" , partPictureCSS = HTML.cssBlockObjectFitCover , partLangue = LangueMandarin , partText = [Right "狼 和 乌鸦 经常 玩耍 和 狩猎 一起"] } ] } & pageLandscape , "Crocodile" := page { pageParts = [ typeDefault { partPicture = "Crocodile/1562781.avif" , partPictureCSS = HTML.cssBlockObjectFitCover , partLangue = LangueFrançais , partText = "Les crocodiles versent des larmes en mangeant" } , typeDefault { partPicture = "Crocodile/Morelet's_Crocodile_(Crocodylus_moreletii)_big_male_attracting_Julia_Butterflies_(Dryas_iulia)_-_Rio_Usumacintla_Chiapas_2020.avif" , partPictureCSS = HTML.cssBlockObjectFitCover , partLangue = LangueAnglais , partText = "Crocodiles shed tears when eating" } , typeDefault { partPicture = "Crocodile/sn-crocodiletears.avif" , partPictureCSS = HTML.cssBlockObjectFitCover , partLangue = LangueMandarin , partText = "鳄鱼 流泪 吃 时" } ] } & pageLandscape , "FourmiIngénieurs" -- https://www.nationalgeographic.com/animals/article/european-red-wood-ants-impact := page { pageParts = [ typeDefault { partPicture = "Fourmi/Ingo_Arndt_MM10190_045-1.avif" , partPictureCSS = HTML.cssBlockObjectFitCover , partLangue = LangueFrançais , partText = "Les fourmis rousses des bois sont des ingénieures" } , typeDefault { partPicture = "Fourmi/STOCKPKG_MM10190_230605_206.avif" , partPictureCSS = HTML.cssBlockObjectFitCover , partLangue = LangueAnglais , partText = "Red wood ants are forest engineers" } , typeDefault { partPicture = "Fourmi/STOCKPKG_MM10190_230515_192.avif" , partPictureCSS = HTML.cssBlockObjectFitCover , partLangue = LangueMandarin -- 紅褐山蟻 , partText = "红木 蚂蚁 是 森林 工程师" } ] } & pageLandscape , "HayBales" := page { pageParts = [ typeDefault { partPicture = "HayBales/30-33-Lead-Image.avif" , partPictureCSS = [ "object-fit" := "cover" ] , partLangue = LangueFrançais , partText = "Les balles de foin sont plastifiées pour fermenter" } , typeDefault { partPicture = "HayBales/_DSC3737_0.avif" , partPictureCSS = [ "object-fit" := "cover" , "object-position" := "-0.7cm center" ] , partLangue = LangueAnglais , partText = "Hay bales are wrapped in plastic to ferment" } , typeDefault { partPicture = "HayBales/Figure-2-200-Heifers-feeding-from-multiple-bags.avif" , partPictureCSS = [ "object-fit" := "cover" ] , partLangue = LangueMandarin , partText = "干草 包裹 塑料 以便 发酵" } ] } & pageLandscape , "StarTrails1" := page { pageParts = [ typeDefault { partPicture = "Étoiles/SavudrijaSTARTRAILS_Nadj1024.avif" , partPictureCSS = [ "object-fit" := "cover" , "object-position" := "left top" ] , partLangue = LangueFrançais , partText = "La Terre tourne chaque jour autour d'un axe stable" } , typeDefault { partPicture = "Étoiles/trails-geminids.avif" , partPictureCSS = [ "object-fit" := "cover" , "object-position" := "left top" ] , partLangue = LangueAnglais , partText = "Earth spins each day around a stable axis" } , typeDefault { partPicture = "Étoiles/Earth_precession.svg.avif" , partPictureCSS = [ "object-fit" := "contain" , "object-position" := "right center" ] , partLangue = LangueMandarin , partText = "地球 围绕 每天 稳定 轴旋转" } ] } & pageLandscape , "StarTrails2" := page { pageParts = [ typeDefault { partPicture = "Étoiles/Iotw2246a_-_Beginning_to_End_of_a_Total_Lunar_Eclipse.avif" , partPictureCSS = [ "object-fit" := "cover" , "object-position" := "left top" ] , partLangue = LangueFrançais , partText = "La Terre tourne chaque jour autour d'un axe stable" } , typeDefault { partPicture = "Étoiles/Star-trail-of-planets1067.avif" , partPictureCSS = [ "object-fit" := "cover" , "object-position" := "left top" ] , partLangue = LangueAnglais , partText = "Earth spins each day around a stable axis" } , typeDefault { partPicture = "Étoiles/shows-precession-of-earth-which-cause-repetitions-of-climate-patterns-for-a-period-of.avif" , partPictureCSS = [ "object-fit" := "contain" , "object-position" := "center center" ] , partLangue = LangueMandarin -- 旋转 , partText = "地球 围绕 每天 稳定 轴旋转" } ] } & pageLandscape , "WateringCan" := page { pageParts = [ typeDefault { partPicture = "Arrosoir/OIP.avif" , partPictureCSS = [ "object-fit" := "cover" ] , partLangue = LangueFrançais , partText = "Utiliser un arrosoir est une corvée technique" } , typeDefault { partPicture = "Arrosoir/sub-buzz-1301-1687548112-1.avif" , partPictureCSS = [ "object-fit" := "contain" ] , partLangue = LangueAnglais , partText = "Using a watering can is a technical chore" } , typeDefault { partPicture = "Arrosoir/Watering-seedlings-with-a-pop-bottle-watering-can-1024x768.avif" , partPictureCSS = [ "object-fit" := "cover" ] , partLangue = LangueMandarin , partText = "使用 浇水 壶 是 技术 例行 工作" } ] } & pageLandscape , "Fireworks1" := page { pageParts = [ typeDefault { partPicture = "Fireworks/brian_titone_53841_1_262503.avif" , partPictureCSS = [ "object-fit" := "cover" , "object-position" := "center top" ] , partLangue = LangueFrançais , partText = "Un feu d'artifice pollue l'air, l'eau et le sol" } , typeDefault { partPicture = "Fireworks/The+Hidden+Science+of+Fireworks+-+Veritasium.avif" , partPictureCSS = [ "object-fit" := "contain" , "object-position" := "center center" ] , partLangue = LangueAnglais , partText = "Fireworks are bombs polluting the air, water and soil" } , typeDefault { partPicture = "Fireworks/2023-07-07 - The Hidden Science of Fireworks.lfkjm2YRG-Q.398+251.webm.00-20-58-624.avif" , partPictureCSS = [ "object-fit" := "cover" , "object-position" := "center center" ] , partLangue = LangueMandarin , partText = "烟花 是 炸弹 污染 空气、水 和 土壤" } ] } & pageLandscape , "Renard" := pages { pagesList = [ page { pageParts = [ typeDefault { partPicture = "Renard/ArticFox/200512612-001-56a006345f9b58eba4ae8b10.avif" , partPictureCSS = [ "object-fit" := "cover" ] , partDescription = "Artic Fox" , partLangue = LangueFrançais , partText = [Right "Il y a 12 espèces et 45 sous-espèces de renards"] } , typeDefault { partPicture = "Renard/SwiftFox/shutterstock-46600522.avif" , partDescription = "Swift Fox" , partPictureCSS = [ "object-fit" := "cover" ] , partLangue = LangueAnglais , partText = [Right "There are at least 12 species and 45 subspecies of foxes"] } , typeDefault { partPicture = "Renard/RedFox/v2.avif" , partDescription = "Red Fox" , partPictureCSS = [ "object-fit" := "cover" ] , partLangue = LangueMandarin , partText = [Right "有 至少 12 种 和 45 亚种 狐狸"] } ] } & pageLandscape , page { pageParts = [ typeDefault { partPicture = "Renard/CorsacFox/029f945789fcc419f8f637a93917278b.avif" , partPictureCSS = [ "object-fit" := "cover" , "object-position" := "0 -0.1cm" ] , partDescription = "Corsac Fox" , partLangue = LangueFrançais , partText = [Right "Il y a 12 espèces et 45 sous-espèces de renards"] } , typeDefault { partPicture = "Renard/BlandfordFox/2-blanfords-fox-vulpes-cana-eyal-bartov.avif" , partPictureCSS = [ "object-fit" := "cover" ] , partDescription = "Blandford's Fox" , partLangue = LangueAnglais , partText = [Right "There are at least 12 species and 45 subspecies of foxes"] } , typeDefault { partPicture = "Renard/CapeFox/shutterstock-220059658.avif" , partPictureCSS = [ "object-fit" := "cover" ] , partDescription = "Cape Fox" , partLangue = LangueMandarin , partText = [Right "有 至少 12 种 和 45 亚种 狐狸"] } ] } & pageLandscape ] } , "Fireworks2" := page { pageParts = [ typeDefault { partPicture = "Fireworks/skyrocket-collage-background-571127103-8430996ece5d423da30046df82620b4f.avif" , partPictureCSS = [ "object-fit" := "cover" , "object-position" := "center top" ] , partLangue = LangueFrançais , partText = [Right "Un feu d'artifice pollue l'air, l'eau et le sol"] } , typeDefault { partPicture = "Fireworks/The+Hidden+Science+of+Fireworks+-+Veritasium.avif" , partPictureCSS = [ "object-fit" := "contain" , "object-position" := "center center" ] , partLangue = LangueAnglais , partText = [Right "Fireworks are bombs polluting", Left (" the ", LexemePron "ðiː" []), Right "air, water and soil"] } , typeDefault { partPicture = "Fireworks/2023-07-07 - The Hidden Science of Fireworks.lfkjm2YRG-Q.398+251.webm.00-21-12-705.avif" , partPictureCSS = [ "object-fit" := "cover" , "object-position" := "center center" ] , partLangue = LangueMandarin , partText = [Right "烟花 是 炸弹 污染 空气、水 和 土壤"] } ] } & pageLandscape , "Arbre1" := page { pageParts = [ typeDefault { partPicture = "Arbre/R3.avif" , partPictureCSS = [ "object-fit" := "cover" , "object-position" := "center bottom" ] , partLangue = LangueFrançais , partText = [Right "Un pommier contre-attaque en changeant d'odeur"] } , typeDefault { partPicture = "Arbre/_14250.avif" , partPictureCSS = [ "object-fit" := "cover" , "object-position" := "center center" ] , partLangue = LangueAnglais , partText = [Right "An apple tree strikes back by changing its smell"] } , typeDefault { partPicture = "Arbre/5485248248_7e7244f769_b.crop.avif" , partPictureCSS = [ "object-fit" := "cover" , "object-position" := "left center" ] , partLangue = LangueMandarin , partText = [Right "苹果 树 变 味 为了 反击"] } ] } & pageLandscape , "Pression" := page { pageParts = [ typeDefault { partPicture = "" , partPictureCSS = [ "object-fit" := "cover" , "object-position" := "center bottom" ] , partLangue = LangueFrançais , partText = [Right ""] } , typeDefault { partPicture = "" , partPictureCSS = [ "object-fit" := "cover" , "object-position" := "center center" ] , partLangue = LangueAnglais , partText = [Right ""] } , typeDefault { partPicture = "" , partPictureCSS = [ "object-fit" := "cover" , "object-position" := "left center" ] , partLangue = LangueMandarin , partText = [Right ""] } ] } & pageLandscape "MistyMountains" := pages { pagesList = [ page { pageParts = [ typeDefault { partPicture = "LOTR/TheHobbit/bilbo-baggins-dwarves-gandalf.avif" , partPictureCSS = [ "object-fit" := "cover" , "object-position" := "center -5.3cm" ] , partLangue = LangueAnglais , partText = [Right "Far over the Misty Mountains cold"] } , typeDefault { partPicture = "LOTR/TheHobbit/Una_tertulia_inesperada_3.avif" , partPictureCSS = [ "object-fit" := "cover" , "object-position" := "center -0.4cm" ] , partLangue = LangueAnglais , partText = [Right "To dungeons deep and caverns old"] } , typeDefault { partPicture = "LOTR/TheHobbit/bilbo-baggins11.avif" , partPictureCSS = [ "object-fit" := "cover" , "object-position" := "center center" ] , partLangue = LangueAnglais , partText = [Right "We must away, ere break of day"] } , typeDefault { partPicture = "LOTR/TheHobbit/b8e91bf011890c7602faa4d6c2e00275.avif" , partPictureCSS = [ "object-fit" := "cover" , "object-position" := "center center" ] , partLangue = LangueAnglais , partText = [Right "To seek our pale enchanted gold"] } ] } & pageLandscape ] } -}