Full Code of l29ah/muesli for AI

master 344e8f02733b cached
12 files
32.9 KB
16.0k tokens
1 requests
Download .txt
Repository: l29ah/muesli
Branch: master
Commit: 344e8f02733b
Files: 12
Total size: 32.9 KB

Directory structure:
gitextract_lq3jvk9y/

├── .gitignore
├── Database.hs
├── DatabaseTools.hs
├── LICENSE
├── Main.hs
├── Muesli.hs
├── README.md
├── Setup.lhs
├── Types.hs
├── mktable.hs
├── mktable.sh
└── muesli.cabal

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
*.swp
*.hi
*.o
muesli


================================================
FILE: Database.hs
================================================
{-# OPTIONS_GHC -fno-warn-tabs #-}
module Database where

import qualified Data.Vector.Fixed as F

import DatabaseTools
import Types

-- nuts:prote,	fat,	carbs,	fiber,
-- elem:potass,	sodium,	calciu,	magnes,	phosph,	iron,	iodine,	zinc,	seleni,	copper,	chromi,	mangane,molybde,chlorid,fluoride,
-- vita:a,	c,	d,	e,	k,	thiami,	ribofl,	niacin,	pantot,	b6,	biotin,	folate,	b12,	choline,omega3,	omega6,
-- e aa:His,	Ile,	Leu,	Lys,	Met,	Phe,	Thr,	Trp,	Val,
-- o aa:Ala,	Arg,	Asn,	Asp,	Cys,	Glu,	Gln,	Gly,	Orn,	Pro,	Sel,	Ser,	Tyr
-- e fa:ALA,	EPA,	DPA,	DHA,	LA,	GLA,	AA
--                               ↘per 100g
raisins = Source "raisin" $ Substance 100 $ usda $ mkL
	3	0.5	79	5	-- USDA 09299 + http://www.whfoods.com/genpage.php?tname=nutrientprofile&dbid=24 + 09298
	0.773	0.017	0.044	0.032	0.097	2.1e-3	idk	240e-6	0.63e-6	328e-6	idk	0.29e-3	idk	idk	220e-6
	0	3.6e-3	0	120e-6	3.5e-6	75e-6	166e-6	1e-3	93e-6	228e-6	2e-6	3.7e-6	0	11.1e-3	0	1e-3
	7.20e-2	5.70e-2	9.60e-2	8.40e-2	7.70e-2	6.50e-2	7.70e-2	5.00e-2	8.30e-2	1.05e-1	4.13e-1	idk	1.10e-1	1.90e-2	1.64e-1	idk	8.00e-2	idk	2.54e-1	idk	7.00e-2	1.20e-2
	idk	0.000e0	0.000e0	0.000e0	idk	idk	idk

undevit = Source "undevit" $ Pill $ mkL
	0	0	0	0
	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
	1e-3	75e-3	0	10e-3	0	2e-3	2e-3	20e-3	3e-3	3e-3	0	70e-6	2e-6	0	0	0
	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0
undevitmar = Source "undevit" $ Pill $ mkL
	0	0	0	0
	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
	435e-6	60e-3	0	10e-3	0	1.4e-3	1.6e-3	18e-3	6.5e-3	2e-3	0	200e-6	1e-6	0	0	0
	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0
gendevit = Source "gendevit" $ Pill $ mkL
	0	0	0	0
	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
	1e-3	75e-3	6.25e-6	5e-3	0	1.5e-3	1.5e-3	10e-3	3e-3	2e-3	0	300e-6	10e-6	0	0	0
	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0

sunflowerOil = Source "sunfloweroil" $ Substance 100 $ usda $ mkL	-- USDA 04506, manually corrected assuming 18:2 is LA
	0.00e0	100.00e0	0.00e0	0.0e0	0e-3	0e-3	0e-3	0e-3	0e-3	0.00e-3	idk	0.00e-3	0.0e-6	0.000e-3	idk	idk	idk	idk	idk	0e-6	0.0e-3	0.0e-6	41.08e-3	5.4e-6	0.000e-3	0.000e-3	0.000e-3	0.000e-3	0.000e-3	idk	0e-6	0.00e-6	0.2e-3	0.0	65.7
	0.000e0	0.000e0	0.000e0	0.000e0	0.000e0	0.000e0	0.000e0	0.000e0	0.000e0	0.000e0	0.000e0	idk	0.000e0	0.000e0	0.000e0	idk	0.000e0	idk	0.000e0	idk	0.000e0	0.000e0
	idk	0.000e0	0.000e0	0.000e0	65.7	idk	idk
brazilNuts = Source "brazilnuts" $ Substance 100 $ usda $ mkL	-- USDA 12078
	14.32e0	67.10e0	11.74e0	7.5e0	659e-3	3e-3	160e-3	376e-3	725e-3	2.43e-3	idk	4.06e-3	1917.0e-6	1.743e-3	idk	1.223e-3	idk	idk	idk	0e-6	0.7e-3	0.0e-6	5.65e-3	0.0e-6	0.617e-3	0.035e-3	0.295e-3	0.184e-3	0.101e-3	idk	22e-6	0.00e-6	28.8e-3	1.8e-2	23.877000000000002
	0.409e0	0.518e0	1.190e0	0.490e0	0.365e0	0.639e0	0.365e0	0.135e0	0.760e0	0.609e0	2.140e0	idk	1.325e0	0.306e0	3.190e0	idk	0.733e0	idk	0.706e0	idk	0.676e0	0.416e0
	0.018e0	0.000e0	0.000e0	0.000e0	23.859e0	0.018e0	idk
oat = Source "oat" $ Substance 100 $ usda $ mkL	-- USDA 08120 + http://www.whfoods.com/genpage.php?tname=nutrientprofile&dbid=109
	13.15e0	6.52e0	67.70e0	10.1e0
	362e-3	6e-3	52e-3	138e-3	410e-3	4.25e-3	idk	3.64e-3	28.9e-6	0.391e-3	idk	3.630e-3	idk	idk	idk
	0e-6	0.0e-3	0.0e-6	0.42e-3	2.0e-6	0.460e-3	0.155e-3	1.125e-3	1.120e-3	0.100e-3	idk	32e-6	0.00e-6	40.4e-3	0.0	0.0
	0.405e0	0.694e0	1.284e0	0.701e0	0.575e0	0.895e0	0.575e0	0.234e0	0.937e0	0.881e0	1.192e0	idk	1.448e0	0.408e0	3.712e0	idk	0.841e0	idk	0.934e0	idk	0.750e0	0.573e0
	idk	idk	idk	idk	idk	idk	idk
buckwheat = Source "buckwheat" $ Substance 100 $ usda $ mkL	-- USDA 20008
	13.25e0	3.40e0	71.50e0	10.0e0	460e-3	1e-3	18e-3	231e-3	347e-3	2.20e-3	idk	2.40e-3	8.3e-6	1.100e-3	idk	1.300e-3	idk	idk	idk	0e-6	0.0e-3	0.0e-6	idk	idk	0.101e-3	0.425e-3	7.020e-3	1.233e-3	0.210e-3	idk	30e-6	0.00e-6	idk	idk	idk	0.309e0	0.498e0	0.832e0	0.672e0	0.506e0	0.520e0	0.506e0	0.192e0	0.678e0	0.748e0	0.982e0	idk	1.133e0	0.229e0	2.046e0	idk	1.031e0	idk	0.507e0	idk	0.685e0	0.241e0
	idk	0.000e0	0.000e0	0.000e0	idk	idk	idk
buckwheatFlakes = Source "buckwheatflakes" $ Substance 100 $ usda $ mkL	-- same as buckwheat
	13.25e0	3.40e0	71.50e0	10.0e0	460e-3	1e-3	18e-3	231e-3	347e-3	2.20e-3	idk	2.40e-3	8.3e-6	1.100e-3	idk	1.300e-3	idk	idk	idk	0e-6	0.0e-3	0.0e-6	idk	idk	0.101e-3	0.425e-3	7.020e-3	1.233e-3	0.210e-3	idk	30e-6	0.00e-6	idk	idk	idk	0.309e0	0.498e0	0.832e0	0.672e0	0.506e0	0.520e0	0.506e0	0.192e0	0.678e0	0.748e0	0.982e0	idk	1.133e0	0.229e0	2.046e0	idk	1.031e0	idk	0.507e0	idk	0.685e0	0.241e0
	idk	0.000e0	0.000e0	0.000e0	idk	idk	idk
parsley = Source "parsley" $ Substance 100 $ usda $ mkL	-- USDA 11297
	2.97e0	7.90e-1	6.33e0	3.30e0
	5.54e-1	5.60e-2	1.38e-1	5.00e-2	5.80e-2	6.20e-3	idk	1.07e-3	1.00e-7	1.49e-4	idk	1.60e-4	idk	idk	idk
	4.21e-4	idk	0.00e0	7.50e-4	1.64e-3	8.60e-5	9.80e-5	1.31e-3	4.00e-4	9.00e-5	idk	1.52e-4	0.00e0	12.8e-3	8e-3	118e-3	-- http://nutritiondata.self.com/facts/vegetables-and-vegetable-products/2513/2
	6.10e-2	1.18e-1	2.04e-1	1.81e-1	1.22e-1	1.45e-1	1.22e-1	4.50e-2	1.72e-1	1.95e-1	1.22e-1	idk	2.94e-1	1.40e-2	2.49e-1	idk	1.45e-1	idk	2.13e-1	idk	1.36e-1	8.20e-2
	idk	0.000e0	0.000e0	0.000e0	idk	idk	idk
parsleyDried = Source "parsleydried" $ Substance 100 $ usda $ mkL	-- USDA 02029
	26.63e0	5.48e0	50.64e0	26.7e0	2683e-3	452e-3	1140e-3	400e-3	436e-3	22.04e-3	idk	5.44e-3	14.1e-6	0.780e-3	idk	9.810e-3	idk	idk	idk	97e-6	125.0e-3	0.0e-6	8.96e-3	1359.5e-6	0.196e-3	2.383e-3	9.943e-3	1.062e-3	0.900e-3	idk	180e-6	0.00e-6	97.1e-3	1.86	1.264
	0.718e0	1.546e0	2.794e0	2.098e0	1.193e0	1.712e0	1.193e0	0.475e0	2.021e0	1.778e0	1.756e0	idk	3.169e0	0.298e0	3.688e0	idk	1.756e0	idk	2.010e0	idk	1.159e0	1.159e0
	1.860e0	0.000e0	0.000e0	0.000e0	1.248e0	0.016e0	idk
flaxseedOil = Source "flaxseedoil" $ Substance 100 $ usda $ mkL	-- USDA 42231
	0.11e0	99.98e0	0.00e0	0.0e0	0e-3	0e-3	1e-3	0e-3	1e-3	0.00e-3	idk	0.07e-3	0.0e-6	0.000e-3	idk	0.000e-3	idk	idk	idk	0e-6	0.0e-3	0.0e-6	0.47e-3	9.3e-6	0.000e-3	0.000e-3	0.000e-3	idk	0.000e-3	idk	0e-6	0.00e-6	0.2e-3	53.368	14.246
	idk	idk	idk	idk	idk	idk	idk	idk	idk	idk	idk	idk	idk	idk	idk	idk	idk	idk	idk	idk	idk	idk
	53.368e0	0.000e0	0.000e0	0.000e0	14.246e0	0.000e0	idk
fishOilCodLiver = Source "codliveroil" $ Substance 100 $ usda $ mkL	-- USDA 04589
	0.00e0	100.00e0	0.00e0	0.0e0	0e-3	0e-3	0e-3	0e-3	0e-3	0.00e-3	idk	0.00e-3	0.0e-6	0.000e-3	idk	0.000e-3	idk	idk	idk	30000e-6	0.0e-3	250.0e-6	idk	idk	idk	0.000e-3	0.000e-3	0.000e-3	0.000e-3	idk	0e-6	0.00e-6	idk	18.801000000000002	0.0
	idk	idk	idk	idk	idk	idk	idk	idk	idk	idk	idk	idk	idk	idk	idk	idk	idk	idk	idk	idk	idk	idk
	idk	6.898e0	0.935e0	10.968e0	idk	idk	idk
eggHardboiled = Source "egghardboiled" $ Substance 100 $ usda $ mkL	-- USDA 01129
	12.58e0	10.61e0	1.12e0	0.0e0	126e-3	124e-3	50e-3	10e-3	172e-3	1.19e-3	idk	1.05e-3	30.8e-6	0.013e-3	idk	0.026e-3	idk	idk	4.8e-6	149e-6	0.0e-3	2.2e-6	1.03e-3	0.3e-6	0.066e-3	0.513e-3	0.064e-3	1.398e-3	0.121e-3	idk	44e-6	1.11e-6	293.8e-3	4.3e-2	0.0
	0.298e0	0.686e0	1.075e0	0.904e0	0.604e0	0.668e0	0.604e0	0.153e0	0.767e0	0.700e0	0.755e0	idk	1.264e0	0.292e0	1.644e0	idk	0.423e0	idk	0.501e0	idk	0.936e0	0.513e0
	idk	0.005e0	0.000e0	0.038e0	idk	idk	idk
soyflourdefatted = Source "soyflourdefatted" $ Substance 100 $ usda $ mkL	-- USDA 16117
	51.46e0	1.22e0	33.92e0	17.5e0
	2384e-3	20e-3	241e-3	290e-3	674e-3	9.24e-3	idk	2.46e-3	1.7e-6	4.065e-3	idk	3.018e-3	idk	idk	idk
	2e-6	0.0e-3	0.0e-6	0.12e-3	4.1e-6	0.698e-3	0.253e-3	2.612e-3	1.995e-3	0.574e-3	idk	305e-6	0.00e-6	11.3e-3	0.0	0.0
	1.268e0	2.281e0	3.828e0	3.129e0	2.042e0	2.453e0	2.042e0	0.683e0	2.346e0	2.215e0	3.647e0	idk	5.911e0	0.757e0	9.106e0	idk	2.174e0	idk	2.750e0	idk	2.725e0	1.778e0
	idk	0.000e0	0.000e0	0.000e0	idk	idk	idk

naCl = Source "nacl" $ Substance 100 $ mkL
	0	0	0	0
	0	39.32	0	0	0	0	0	0	0	0	0	0	0	60.68	0
	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0
naClI = Source "nacl" $ Substance 100 $ mkL
	0	0	0	0
	0	39.32	0	0	0	0	2.5e-3	0	0	0	0	0	0	60.68	0
	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0
kCl = Source "kcl" $ Substance 100 $ mkL
	0	0	0	0
	52.41	0	0	0	0	0	0	0	0	0	0	0	0	47.6	0
	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0
kCitrateH2O = Source "kcitrate" $ Substance 100 $ mkL	-- K3C6H7O8
	0	0	0	0
	36.111	0	0	0	0	0	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0
kSelenate = Source "kselenate" $ Substance 100 $ mkL	-- K2SeO4
	0	0	0	0
	35.294	0	0	0	0	0	0	0	35.747	0	0	0	0	0	0
	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0
caCl = Source "cacl" $ Substance 100 $ mkL
	0	0	0	0
	0	0	36.1	0	0	0	0	0	0	0	0	0	0	63.9	0
	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0
caCl2x2H2O = Source "cacl2x2h2o" $ Substance 100 $ mkL
	0	0	0	0
	0	0	27.21	0	0	0	0	0	0	0	0	0	0	48.3	0
	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0
ca2CO3 = Source "chalk" $ Substance 100 $ mkL
	0	0	0	0
	0	0	57.1	0	0	0	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0
naI = Source "nai" $ Substance 1 $ mkL
	0	0	0	0
	0	0.1534	0	0	0	0	0.8466	0	0	0	0	0	0	60.68	0
	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0

ascorbicAcid = Source "ascorbica" $ Substance 100 $ mkL
	0	0	0	0
	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
	0	100	0	0	0	0	0	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0
d3 = Source "d3" $ Substance 100 $ mkL
	0	0	0	0
	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
	0	0	100	0	0	0	0	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0
vigantol = Source "vigantol" $ Pill $ mkL
	0	0	0	0
	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
	0	0	12.5e-6	0	0	0	0	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0
nowD35000 = Source "nowd3-5000" $ Pill $ mkL
	0	0	0	0
	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
	0	0	125e-6	0	0	0	0	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0
cholineBitartrate = Source "cholinebitartrate" $ Substance 100 $ mkL
	0	0	0	0
	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0	0	0	0	0	0	0	41.1	0	0
	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0
snK = Source "sourcenaturalsk" $ Pill $ mkL
	0	0	0	0
	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
	0	0	0	0	0.5e-3	0	0	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0	0	0	0	0	0	0
	0	0	0	0	0	0	0


================================================
FILE: DatabaseTools.hs
================================================
{-# LANGUAGE DataKinds, FlexibleContexts, TypeFamilies #-}
{-# OPTIONS_GHC -fno-warn-tabs #-}
module DatabaseTools where

import Data.Proxy
import qualified Data.Vector.Fixed as F
import qualified Data.Vector.Fixed.Cont as C

import Types

mkL = F.mkN (Proxy :: Proxy Nutrients)

-- TODO a better value that taints the calculation
idk :: Double
idk = 0

-- Put 'nan' when the value is unspecified or irrelevant in the target daily uptakes
nan = 0/0

-- Put 'todo' when the value is to be fetched
todo = idk

-- USDA considers fiber a carbohydrate, we don't
usda v = F.set (Proxy :: Proxy 2) ((F.index v (Proxy :: Proxy 2)) - (F.index v (Proxy :: Proxy 3))) v


================================================
FILE: LICENSE
================================================
            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
                    Version 2, December 2004

 Copyright (C) 2004 Sam Hocevar
  22 rue de Plaisance, 75014 Paris, France
 Everyone is permitted to copy and distribute verbatim or modified
 copies of this license document, and changing it is allowed as long
 as the name is changed.

            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

  0. You just DO WHAT THE FUCK YOU WANT TO.



================================================
FILE: Main.hs
================================================
module Main where
import qualified Muesli
main = Muesli.main


================================================
FILE: Muesli.hs
================================================
#!/usr/bin/env runhaskell
{-# LANGUAGE TemplateHaskell, DataKinds, FlexibleContexts #-}
{-# OPTIONS_GHC -fno-warn-tabs #-}

module Muesli where

import Control.Exception
import Control.Monad
import Data.List
import Data.Maybe
import Data.Vector.Fixed ((!))
import qualified Data.Vector.Fixed as F
import Data.Vector.Fixed.Boxed as V
import System.Console.ANSI
import System.Console.GetOpt
import System.Environment
import System.IO
import Text.Printf

import Database
import DatabaseTools
import Types

fromRecipe :: Recipe -> [(Amount, Source)]
fromRecipe (Recipe a b) = a ++ b

def :: Nutrients
def = F.replicate 0

getNutrients :: Component -> Nutrients
getNutrients (Substance _ n) = n
getNutrients (Pill n) = n

isPill :: Component -> Bool
isPill (Pill _) = True
isPill _ = False

-- target daily energy value
-- TODO fix the values hardcoded elsewhere
energy :: Kcal
energy = 2000

-- Calculate the energetic value
cal :: Nutrients -> Kcal
cal x = 4 * x!0 + 9 * x!1 + 4 * x!2

amountify :: Component -> Amount -> Component
amountify (Pill x) a = Pill $ F.map (* a) x
amountify (Substance mass x) a = Substance (mass * a) $ F.map (* a) x

sumNutrients :: [(Amount, Source)] -> Nutrients
sumNutrients as = foldl (\tsum cnut -> F.zipWith (+) tsum cnut) def $ nutrientify as

nutrientify :: [(Amount, Source)] -> [Nutrients]
nutrientify as = map (\(amount, (Source _ comp)) -> getNutrients $ amountify comp amount) as

energyMultiplier :: Nutrients -> Double
energyMultiplier n = energy / (cal n)

pills :: Recipe -> [(Amount, Source)]
pills r = filter (isPill . sComponent . snd) $ rFoods r
substances :: Recipe -> [(Amount, Source)]
substances r = filter (not . isPill . sComponent . snd) $ rFoods r

normalizeRecipe :: Recipe -> Recipe
normalizeRecipe r = let	mult = energyMultiplier $ sumNutrients $ substances r in
		Recipe ((map (\(amount, source) -> (mult * amount, source)) (substances r)) ++ (pills r)) $ rSupplements r


-- daily intakes, g at 2Mcal
fdardi = mkL
	50	78	275	28
	4.7	2.3	1.3	0.42	1.25	18e-3	150e-6	11e-3	55e-6	0.9e-3	35e-6	2.3e-3	45e-6	2.3	4e-3
	0.9e-3	0.09	20e-6	15e-3	120e-6	1.2e-3	1.3e-3	16e-3	5e-3	1.7e-3	30e-6	0.4e-3	2.4e-6	0.55	nan	nan
	nan	nan	nan	nan	nan	nan	nan	nan	nan
	nan	nan	nan	nan	nan	nan	nan	nan	nan	nan	nan	nan	nan
	nan	nan	nan	nan	nan	nan	nan
iomdrirda = mkL
	nan	nan	nan	nan
	4.7	1.5	1	0.4	0.7	15e-3	150e-6	11e-3	55e-6	0.9e-3	35e-6	2.3e-3	45e-6	2.3	4e-3
	0.9e-3	0.09	15e-6	15e-3	120e-6	1.2e-3	1.3e-3	16e-3	5e-3	1.3e-3	30e-6	0.4e-3	2.4e-6	0.55	1.6	17
	0.91	1.235	2.730	2.470	1.235	2.145	1.3	0.325	1.56
	nan	nan	nan	nan	1.235	nan	nan	nan	nan	nan	nan	nan	2.145
	nan	nan	nan	nan	nan	nan	nan
iomdriul = mkL
	nan	nan	nan	nan
	nan	2.3	2.5	0.7	4	45e-3	1.1e-3	40e-3	400e-6	10e-3	nan	11e-3	2e-3	3.6	10e-3
	3e-3	2	100e-6	1	nan	nan	nan	35e-3	nan	100e-3	nan	1e-3	nan	3.5	nan	nan
	nan	nan	nan	nan	nan	nan	nan	nan	nan
	nan	nan	nan	nan	nan	nan	nan	nan	nan	nan	nan	nan	nan
	nan	nan	nan	nan	nan	nan	nan

-- calculated for 65kg 18-29yo sedentary male 2450kcal
рсн = mkL
	59	66	292	16	-- balanced for 2000kcal
	2.5	1.3	1	0.4	0.8	10e-3	150e-6	12e-3	70e-6	1e-3	50e-6	2e-3	70e-6	2.3	4e-3
	900e-6	90e-3	10e-6	15e-3	120e-6	1.5e-3	1.8e-3	20e-3	5e-3	2e-3	50e-6	400e-6	3e-6	0.5	1.6	7
	nan	nan	nan	nan	nan	nan	nan	nan	nan
	nan	nan	nan	nan	nan	nan	nan	nan	nan	nan	nan	nan	nan
	nan	nan	nan	nan	nan	nan	nan

-- nuts:prote,	fat,	carbs,	fiber,
-- elem:potass,	sodium,	calciu,	magnes,	phosph,	iron,	iodine,	zinc,	seleni,	copper,	chromi,	mangane,molybde,chlorid,fluoride,
-- vita:a,	c,	d,	e,	k,	thiami,	ribofl,	niacin,	pantot,	b6,	biotin,	folate,	b12,	choline,omega3,	omega6,
-- e aa:His,	Ile,	Leu,	Lys,	Met,	Phe,	Thr,	Trp,	Val,
-- o aa:Ala,	Arg,	Asn,	Asp,	Cys,	Glu,	Gln,	Gly,	Orn,	Pro,	Sel,	Ser,	Tyr
-- e fa:ALA,	EPA,	DPA,	DHA,	LA,	GLA,	AA
-- the difference against iom rda as seen in https://lpi.oregonstate.edu/publications/rx-health
lpi = mkL
	nan	nan	nan	nan
	nan	nan	nan	nan	nan	nan	nan	nan	nan	nan	nan	nan	nan	nan	nan
	nan	0.4	50e-6	nan	nan	nan	nan	nan	nan	nan	nan	nan	nan	nan	nan	nan
	nan	nan	nan	nan	nan	nan	nan	nan	nan
	nan	nan	nan	nan	nan	nan	nan	nan	nan	nan	nan	nan	nan
	nan	nan	nan	nan	nan	nan	nan

attenuate :: [(Amount, Source)] -> Double -> [(Amount, Source)]
attenuate l z = map (\(x, y) -> (x * z, y)) l

-- Specify the mix
-- Syntax: (
-- 	[(fraction, product)],	-- meals
-- 	[(grams, product)]	-- supplements
-- 	)
-- WARNING: supplements must not seriously affect the energy value of the mix as they're omitted from the energy calculations
fatsOilsM = [
		(0.065, sunflowerOil),
		(0.025, flaxseedOil)
	]
plantM fats bulk = [
		(0.695, bulk),
		(0.195, raisins),
		(0.02, parsleyDried)
	] ++ fats
-- TODO fix the /100 kludge
electrolytesS = [
		(5/100, naClI),
		(7/100, kCitrateH2O),
		(2/100, ca2CO3)
	]
electrolytesClS = [
		(4/100, naClI),
		(3/100, kCl),
		(2.5/100, caCl2x2H2O)
	]
pPharmaS = [
		(0.3/100, ascorbicAcid),
		(2, undevit) -- two pills
	]
myPharmaS = (3/100, fishOilCodLiver) : pPharmaS
pharmaS = (1/100, cholineBitartrate) : myPharmaS
seNutsS = (7/100, brazilNuts)
kSelenateS = (250e-6/100, kSelenate)
vigantolS = (10, vigantol) -- ten drops of vigantol on days w/o at least half an hour of good uvb light exposure
nowD3S = (1, nowD35000)
iodineS = (200e-6, naI)
defaultS selenium = nowD3S : selenium : electrolytesS ++ pharmaS

simpleR bulk selenium = Recipe (plantM fatsOilsM bulk) (defaultS selenium)

l29ah :: Recipe
l29ah = Recipe
		((0.82, oat)
		:(0.15, soyflourdefatted)
		:fatsOilsM)

		(vigantolS
		:kSelenateS
		:(1, snK)
		:iodineS
		:electrolytesClS
		++pPharmaS)

recipes :: [(RecipeName, Recipe)]
recipes =
	[("l29ah-raisins", Recipe
		((0.81, oat)
		:(0.1, raisins)
		:fatsOilsM)

		(vigantolS
		:kSelenateS
		:(1, snK)
		:electrolytesClS
		++pPharmaS))
	,("l29ah", l29ah)
	,("l29ah-nosoy", Recipe
		((0.91, oat)
		:fatsOilsM)

		(vigantolS
		:kSelenateS
		:(1, snK)
		:electrolytesClS
		++pPharmaS))
	,("l29ah-choline", Recipe ((0.3, eggHardboiled) : attenuate (plantM fatsOilsM oat) 0.7) (vigantolS : kSelenateS : electrolytesClS ++ pPharmaS))
	,("default", l29ah)
	,("default-choline", simpleR oat kSelenateS)
	,("gluten-soy-free", Recipe
		((0.94, buckwheatFlakes)
		:fatsOilsM)

		(vigantolS
		:kSelenateS
		:(1, snK)
		:electrolytesClS
		++pPharmaS))
	,("gluten-free", Recipe
		((0.88, buckwheatFlakes)
		:(0.07, soyflourdefatted)
		:fatsOilsM)

		(vigantolS
		:kSelenateS
		:(1, snK)
		:electrolytesClS
		++pPharmaS))
	,("r2", Recipe (plantM fatsOilsM buckwheat) (nowD3S : kSelenateS : electrolytesClS ++ pPharmaS))
	]

references :: [Nutrients]
references = [рсн, fdardi, iomdrirda, iomdriul, lpi]

-- Compare the mix against the reference
comp :: Nutrients -> Nutrients -> Nutrients
comp p ref = F.zipWith (/) p ref

-- Compare the recipe against references
tbl :: Recipe -> [Nutrients]
tbl r = let nuts = sumNutrients $ fromRecipe r in
	nuts : map (\ref -> comp nuts ref) references

-- Some pretty-printing
printMass :: Double -> String
printMass x
	| x > 2     = printf "%4.1f  g" x
	| x > 2e-3  = printf "%4.1f mg" $ x * 1e3
	| otherwise = printf "%4.1f µg" $ x * 1e6

printPercent :: Bool -> (Double -> Color) -> Double -> String
printPercent useColors schema x
	| isNaN x = printf "       "
	| otherwise = let value = (printf "%6.0f%%" x) in if useColors then colorify schema x value else value

colorify :: (Double -> Color) -> Double -> String -> String
colorify schema x s =
		concat [
			setSGRCode [SetConsoleIntensity BoldIntensity, -- to be parseable by ansi2html and vivid in a real terminal emulator
				SetColor Foreground Dull (schema x)],
			s,
			setSGRCode [Reset]]

good x = if x < 75 then Red else if x < 125 then Yellow else Green
bad x = if x < 75 then Green else if x < 125 then Yellow else Red

report :: Bool -> Recipe -> String
report useColors rec = let [
				pr, fa, carb, fib,
				k, na, ca, mg, ph, fe, i, zn, se, cu, cr, mn, mo, cl, fl,
				vA, vC, vD, vE, vK, thi, rib, nia, pant, vB6, bio, fol, vB12, cho, o3, o6,
				his, ile, leu, lys, met, phe, thr, trp, val,
				ala, arg, asn, asp, cys, glu, gln, gly, orn, pro, sel, ser, tyr,
				alaa, epa, dpa, dha, la, gla, aa
				] = map (\(x:xs) -> x : map (* 100) xs) $ transpose $ map F.toList $ tbl rec in
	(printf "%-26s %14s %7s %7s %7s %7s %7s\n" ("" :: String) ("mass" :: String) ("РСН" :: String) ("FDA RDI" :: String) ("DRI RDA" :: String) ("LPI" :: String) ("DRI UL" :: String)) ++
	concatMap (\(a, [w, b, c, d, e, lpi]) -> printf "%-26s %14s %s %s %s %s %s\n" a (printMass w) (printPercent useColors good b) (printPercent useColors good c) (printPercent useColors good d) (printPercent useColors good lpi) (printPercent useColors bad e)) ([
		("Protein", pr),
		("Fat", fa),
		("Carbohydrates", carb),
		("Dietary fiber", fib),

		("Potassium", k),
		("Sodium", na),
		("Calcium", ca),
		("Magnesium", mg),
		("Phosphorus", ph),
		("Iron", fe),
		("Iodine", i),
		("Zinc", zn),
		("Selenium", se),
		("Copper", cu),
		("Chromium (*)", cr),
		("Manganese (*)", mn),
		("Molybdenum (*)", mo),
		("Chlorine", cl),
		("Fluoride (*)", fl),

		("Vitamin A", vA),
		("Vitamin C (*)", vC),
		("Vitamin D (*)", vD),
		("Vitamin E", vE),
		("Vitamin K", vK),
		("Thiamin", thi),
		("Riboflavin", rib),
		("Niacin", nia),
		("Pantothenic acid", pant),
		("Vitamin B6", vB6),
		("Biotin (*)", bio),
		("Folate", fol),
		("Vitamin B12", vB12),
		("Choline", cho),
		("Omega-3 fats", o3),
		("Omega-6 fats", o6),

		("Histidine", his),
		("Isoleucine", ile),
		("Leucine", leu),
		("Lysine", lys),
		("Methionine (a)", met),
		("Phenylalanine (b)", phe),
		("Threonine", thr),
		("Tryptophan", trp),
		("Valine", val),

		("Alanine", ala),
		("Arginine", arg),
		("Asparagine", asn),
		("Aspartic acid", asp),
		("Cysteine (a)", cys),
		("Glutamic acid", glu),
		("Glutamine", gln),
		("Glycine", gly),
		("Ornithine", orn),
		("Proline", pro),
		("Selenocysteine", sel),
		("Serine", ser),
		("Tyrosine (b)", tyr),

		("ALA (18:3 n-3)", alaa),
		("EPA (20:5 n-3)", epa),
		("DPA (22:5 n-3)", dpa),
		("DHA (22:6 n-3)", dha),
		("LA (18:2 n-6)", la),
		("GLA (18:3 n-6)", gla),
		("AA (20:4 n-6)", aa)
		] :: [(String, [Double])]) ++
	"(*) - see README\n" ++
	"(<letter>) - specified as the sum of components in IOM RDA"

printRecipeItem :: (Amount, Source) -> String
printRecipeItem (amount, (Source name cmp)) = printf "%-26s %14s\n" name (if isPill cmp then show amount else printMass $ amount * sServingMass cmp)

printRecipe :: Recipe -> Double -> String
printRecipe r days = "Recipe for " ++ show days ++ " days:\n" ++
	(concatMap printRecipeItem  $ attenuate (fromRecipe r) days)

usage = do
	pn <- getProgName
	putStr $ usageInfo ("Usage: " ++ pn ++ " <recipe name>\navailable recipes:\n\n" ++ (unlines $ map fst $ recipes)) options

data Flag = FReport | FColors | FDays Double deriving (Eq, Show)

options :: [OptDescr Flag]
options =
	[ Option ['r']	["report"]	(NoArg	FReport)		"print the nutrients report table"
	, Option ['c']	["colors"]	(NoArg	FColors)		"forcefully enable ANSI-colored output"
	, Option ['d']	["days"]	(ReqArg (FDays . read) "DAYS")	"print the sources' masses counted for DAYS of consumption"
	]

main = do
	args <- getArgs
	let (opts, strings, errs) = getOpt RequireOrder options args
	supportsColors <- hSupportsANSI stdout
	let useColors = or [supportsColors, elem FColors opts]
	fromMaybe usage $ do
		recipename <- listToMaybe strings
		rec <- lookup recipename recipes
		let nrec = normalizeRecipe rec
		return $ do
			putStrLn $ report useColors nrec
			let days = maybe 1 (\(FDays d) -> d) $ find (\x -> case x of FDays _ -> True; _ -> False) opts
			when (notElem FReport opts) $ putStrLn $ '\n' :
				(printRecipe nrec days) ++
				("\nApproximate mass: " ++ (printMass $ (days *) $ sum $ map (\(amount, (Source _ cmp)) -> if isPill cmp then amount else amount * sServingMass cmp) $ fromRecipe nrec))


================================================
FILE: README.md
================================================
# muesli

A muesli calculator. Prints a recipe and its nutritional value. Brought up because i'm not much into spreadsheets and hoped to write some clever algo to sort the mix out for me someday.

This project aims to provide one with nutritionally complete and easy to make food that needs to be chewed considerably to be consumed to trigger the corresponding digestive responses in one's body. There were also ideas about making it less bland for people unused to spice-free food, but i concluded it's quite individual stuff; i found sweeteners (like aspartame and sucralose), vanillin, apple flavoring, garlic or chili powder doing the job. It consumes about $1 and 15mins per day, excluding the research, for me. I believe in dogfooding, so you can check out the recipe i'm using at the moment by hitting `./Muesli.hs l29ah`.

[ansi2html'ed snapshot of the recipe](http://muesli.l29ah.blasux.ru/muesli-dump.html)

The current requirements are optimized for a median male. A female (or a frequent blood donor, or otherwise a person who loses erythrocytes quickly) would need to supplement iron additionally. TODO: requirement profiles

If you found it useful, you're eating the muesli for a long time, or having any problems with it, drop me a line.

## Installation:

* install ghc (9.2.0 or newer) and cabal-install
* `cabal update && cabal install ansi-terminal fixed-vector`

## Usage:

To see the nutrient profile and the current recipe, call:


```
$ ./Muesli.hs default
```

# What does it look like

Raw:
![raw muesli](http://muesli.l29ah.blasux.ru/a.jpeg)
Cooked:
![cooked muesli](http://muesli.l29ah.blasux.ru/b.jpeg)

# Sources
* [The original Soylent prototype](https://web.archive.org/web/20170305070025/http://robrhinehart.com/?p=424)
* https://www.bestpravo.com/federalnoje/bz-dokumenty/c5o/index.htm
* https://fdc.nal.usda.gov/fdc-app.html#/?query=
* https://lpi.oregonstate.edu/publications/rx-health
* Protein
  * should be 1,3-1,7g/kg body weight
    * 10.1123/ijsn.5.s1.s39
    * https://www.ncbi.nlm.nih.gov/pubmed/16779921
* Calcium
  * [Calcium Supplementation in Clinical Practice: A Review of Forms, Doses, and Indications](https://onlinelibrary.wiley.com/doi/full/10.1177/0115426507022003286)
  * [Stimulates gastric acid secretion](https://www.ncbi.nlm.nih.gov/pmc/articles/PMC1411522/)
* Magnesium
  * The IOM DRI UL is way too conservative, since at doses <2.5g the only side effect is possible mild diarrhea in some populations when supplemented
    * https://www.sciencedirect.com/science/article/pii/S2161831323013352
    * https://ec.europa.eu/food/fs/sc/scf/out105_en.pdf
* Potassium
  * https://www.nal.usda.gov/sites/default/files/fnic_uploads/water_full_report.pdf
* Sodium
  * https://www.nal.usda.gov/sites/default/files/fnic_uploads/water_full_report.pdf
* Chloride
  * no proper data from IOM
  * https://www.ahajournals.org/doi/full/10.1161/01.HYP.0000158264.36590.19 suggests chloride intake doesn't matter for blood pressure
* Manganese
  * Opinion of the scientific committee on food on the tolerable upper intake level of manganese 19.10.2009
    * manganese supplements are evil but no evidence of any damage from excessive intake from the food sources in diets of up to 20mg daily
  * https://discourse.soylent.com/t/have-you-asked-yourself-why-upper-limit-of-manganese-is-11mg-day/7660
  * https://lpi.oregonstate.edu/mic/minerals/manganese#toxicity
  * I got 8µg/L whole blood Mn while consuming 20.1mg Mn from oats per day
* Vitamin A
  * 1 IU = 300ng of retinol
  * EFSA [recommends 750μg retinol a day for adult men and 1300 for lactating women](https://efsa.onlinelibrary.wiley.com/doi/epdf/10.2903/j.efsa.2015.4028)
  * Dietary carotenoid bioavailability and conversion [is likely to be poor](https://pmc.ncbi.nlm.nih.gov/articles/PMC10261660/)
* Vitamin K
  * green veggies
* Vitamin C
  * https://academic.oup.com/ajcn/article/69/6/1086/4714888/
  * ascorbic acid also retards fat rancidification
* Vitamin D
  * comes from sunlight and supplements only, basically
  * quite a lot of inconclusive studies regarding cancer
  * amount
    * 1µg cholecalciferol = 40IU
    * https://www.sciencedaily.com/releases/2015/03/150317122458.htm
    * or even higher https://www.ncbi.nlm.nih.gov/m/pubmed/28768407/
    * my own experience re D3 -> 25(OH)D3: https://bnw.im/p/0DLNGK
* Biotin
  * Produced by body and generally abundant
  * https://en.wikipedia.org/wiki/Biotin_deficiency
* Chromium
  * No cases of deficiency if not on long-term i/v feeding
    * https://en.wikipedia.org/wiki/Chromium#Biological_role
* Molybdenum
  * Deficiency only on i/v feeding or in molybdenum-poor soils (northen China to Iran)
    * https://en.wikipedia.org/wiki/Molybdenum#Human_dietary_intake_and_deficiency
* Iodine
  * Salt form is unnecessary, molecular iodine is okay
    * https://www.zrtlab.com/blog/archive/guide-how-to-treat-iodine-deficiency/
    * 200µg I2 per 3L of water is 15-150 times less than used for drinking water disinfection
* Fluoride
  * Controversial
  * https://en.wikipedia.org/wiki/Fluoride_deficiency
  * No effect on bone strength
    * https://www.ncbi.nlm.nih.gov/pubmed/8897754
  * Seems to induce dental fluorosis at recommended dosages
    * https://www.ncbi.nlm.nih.gov/pubmed/2129630
  * Likely neurotoxic when present in drinking water
    * https://www.ncbi.nlm.nih.gov/pmc/articles/PMC6923889/
    * https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3491930/
* Choline
  * synthesized by body in small amounts
  * i didn't observe the signs of deficiency myself although being low on it for like the whole life; tried refilling it with eggs for two weeks, didn't notice anything interesting
* Fats
  * Polyunsaturated fatty acids
    * The oil should be unrefined, since refining converts some PUFAs into trans-isomeres.
    * https://www.sciencedirect.com/science/article/pii/S016378271300057X
    * https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4179179/
    * n-3
      * https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4179179/
      * https://www.ncbi.nlm.nih.gov/pubmed/16841858
      * DHA
        * brain (at least early and elderly); produced in small quantites from ALA in young females only
        * especially vulnerable to peroxidation in vivo: https://www.ncbi.nlm.nih.gov/pubmed/11110863
  * Refined oil has a lower degree of peroxidation
    * https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4486537/
  * Refined oil has much more trans fats
    * https://www.scielo.br/pdf/aabc/v79n2/a15v79n2.pdf


================================================
FILE: Setup.lhs
================================================
#!/usr/bin/env runhaskell

> import Distribution.Simple
> main = defaultMain


================================================
FILE: Types.hs
================================================
{-# LANGUAGE DataKinds, TypeFamilies, UndecidableInstances #-}
{-# OPTIONS_GHC -fno-warn-tabs #-}
module Types where

import Data.Vector.Fixed.Boxed as V

type Kcal = Double
type Grams = Double
type Elements = 64
type Nutrients = V.Vec Elements Grams

data Component = Substance
	{ sServingMass :: Grams	-- the total mass of the component described by sNutrients
	, sNutrients :: Nutrients
	} | Pill
	{ pNutrients :: Nutrients
	} deriving Show

data Source = Source
	{ sProdName :: String
	, sComponent :: Component
	} deriving Show

type RecipeName = String
type Amount = Double
data Recipe = Recipe
	{ rFoods :: [(Amount, Source)]
	, rSupplements :: [(Amount, Source)]
	} deriving Show


================================================
FILE: mktable.hs
================================================
#!/usr/bin/runhaskell
{-# OPTIONS_GHC -fno-warn-tabs #-}
import Data.List
import Text.CSV

llookup :: String -> [[String]] -> [String]
--llookup hx [] = ["","g","WTF " ++ hx]
llookup hx [] = []
llookup hx list = let (x:xs):ls = list in
	if x == hx then x:xs else llookup hx ls

utoe "g" = "e0"
utoe "mg" = "e-3"
utoe "µg" = "e-6"

tablify :: [String] -> String
tablify (name:unit:amount:_) = amount ++ utoe unit
tablify [] = "idk"

lookups csv components = map (\c -> tablify $ llookup c csv) components

-- Assume idk = 0
lookupFatty csv = sum . map (read :: String -> Double) . filter (/= "idk") . lookups csv

components1 = ["Protein", "Total lipid (fat)", "Carbohydrate, by difference", "Fiber, total dietary"]
components2 = ["Potassium, K", "Sodium, Na", "Calcium, Ca", "Magnesium, Mg", "Phosphorus, P", "Iron, Fe", "Iodine, I", "Zinc, Zn", "Selenium, Se", "Copper, Cu", "Chromium, Cr", "Manganese, Mn", "Molybden, Md", "Chloride, Cl", "Fluoride, F"]
componentsPreFat = ["Vitamin A, RAE", "Vitamin C, total ascorbic acid", "Vitamin D (D2 + D3)", "Vitamin E (alpha-tocopherol)", "Vitamin K (phylloquinone)", "Thiamin", "Riboflavin", "Niacin", "Pantothenic acid", "Vitamin B-6", "Biotin", "Folate, total", "Vitamin B-12", "Choline, total"]
componentsPostFat = ["Histidine", "Isoleucine", "Leucine", "Lysine", "Threonine", "Phenylalanine", "Threonine", "Tryptophan", "Valine", "Alanine", "Arginine", "Asparagine", "Aspartic acid", "Cystine", "Glutamic acid", "Glutamine", "Glycine", "Ornithine", "Proline", "Selenocysteine", "Serine", "Tyrosine"]

omega3 = ["18:3 n-3 c,c,c (ALA)", "20:5 n-3 (EPA)", "22:5 n-3 (DPA)", "22:6 n-3 (DHA)"]
omega6 = ["18:2 n-6 c,c", "18:3 n-6 c,c,c", "20:4 n-6"]

sep = "\t"
format comp csv = intercalate sep $ lookups csv comp

main = do
	c <- getContents
	let cp = parseCSV "" c
	either
		print
		(\r -> do
			putStrLn $ format components1 r
			putStrLn $ format components2 r
			putStrLn $ (intercalate sep $ concat [
				lookups r componentsPreFat,
				[show $ lookupFatty r omega3, show $ lookupFatty r omega6]])
			putStrLn $ (intercalate sep $ lookups r componentsPostFat)
			putStrLn $ intercalate sep $ concat [
				lookups r omega3,
				lookups r omega6]
		)
		cp


================================================
FILE: mktable.sh
================================================
#!/bin/sh
# Usage: $0 http://ndb.nal.usda.gov/ndb/foods/show/738?manu=&fgcd=
curl -s 'https://ndb.nal.usda.gov/ndb/foods/show/'`echo "$1" | sed -e 's#[^0-9]*\([0-9]*\).*#\1#'`'?format=Full&reportfmt=csv' | iconv -f cp1251 | sed -e 's#^([^)]*)##' | ./mktable.hs


================================================
FILE: muesli.cabal
================================================
Name:           muesli
Version:        0

License:        OtherLicense
License-file:   LICENSE


Build-Type:     Simple
Cabal-Version:  >= 1.2
Tested-With:    GHC == 8.10.3

Executable      Muesli
        Main-is:        Main.hs
        ghc-options:    -fno-warn-tabs
        other-modules:  Database, DatabaseTools, Types, Muesli
        Build-depends:
                        base >= 4 && < 5,
                        ansi-terminal >= 0.6.2.1 && < 0.12,
                        fixed-vector >= 1.1 && < 1.3
Download .txt
gitextract_lq3jvk9y/

├── .gitignore
├── Database.hs
├── DatabaseTools.hs
├── LICENSE
├── Main.hs
├── Muesli.hs
├── README.md
├── Setup.lhs
├── Types.hs
├── mktable.hs
├── mktable.sh
└── muesli.cabal
Condensed preview — 12 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (38K chars).
[
  {
    "path": ".gitignore",
    "chars": 22,
    "preview": "*.swp\n*.hi\n*.o\nmuesli\n"
  },
  {
    "path": "Database.hs",
    "chars": 10418,
    "preview": "{-# OPTIONS_GHC -fno-warn-tabs #-}\nmodule Database where\n\nimport qualified Data.Vector.Fixed as F\n\nimport DatabaseTools\n"
  },
  {
    "path": "DatabaseTools.hs",
    "chars": 659,
    "preview": "{-# LANGUAGE DataKinds, FlexibleContexts, TypeFamilies #-}\n{-# OPTIONS_GHC -fno-warn-tabs #-}\nmodule DatabaseTools where"
  },
  {
    "path": "LICENSE",
    "chars": 508,
    "preview": "            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE\n                    Version 2, December 2004\n\n Copyright (C) 200"
  },
  {
    "path": "Main.hs",
    "chars": 61,
    "preview": "module Main where\nimport qualified Muesli\nmain = Muesli.main\n"
  },
  {
    "path": "Muesli.hs",
    "chars": 11794,
    "preview": "#!/usr/bin/env runhaskell\n{-# LANGUAGE TemplateHaskell, DataKinds, FlexibleContexts #-}\n{-# OPTIONS_GHC -fno-warn-tabs #"
  },
  {
    "path": "README.md",
    "chars": 6483,
    "preview": "# muesli\n\nA muesli calculator. Prints a recipe and its nutritional value. Brought up because i'm not much into spreadshe"
  },
  {
    "path": "Setup.lhs",
    "chars": 77,
    "preview": "#!/usr/bin/env runhaskell\n\n> import Distribution.Simple\n> main = defaultMain\n"
  },
  {
    "path": "Types.hs",
    "chars": 688,
    "preview": "{-# LANGUAGE DataKinds, TypeFamilies, UndecidableInstances #-}\n{-# OPTIONS_GHC -fno-warn-tabs #-}\nmodule Types where\n\nim"
  },
  {
    "path": "mktable.hs",
    "chars": 2205,
    "preview": "#!/usr/bin/runhaskell\n{-# OPTIONS_GHC -fno-warn-tabs #-}\nimport Data.List\nimport Text.CSV\n\nllookup :: String -> [[String"
  },
  {
    "path": "mktable.sh",
    "chars": 261,
    "preview": "#!/bin/sh\n# Usage: $0 http://ndb.nal.usda.gov/ndb/foods/show/738?manu=&fgcd=\ncurl -s 'https://ndb.nal.usda.gov/ndb/foods"
  },
  {
    "path": "muesli.cabal",
    "chars": 509,
    "preview": "Name:           muesli\nVersion:        0\n\nLicense:        OtherLicense\nLicense-file:   LICENSE\n\n\nBuild-Type:     Simple\n"
  }
]

About this extraction

This page contains the full source code of the l29ah/muesli GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 12 files (32.9 KB), approximately 16.0k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!