Generates a human-friendly display string from a number of minutes. Approximate, if set, determines the maximum number of units to return, rounding the last unit. For example, a setting of 2 would return days and hours; or hours and minutes; but never days, hours, and minutes.

A Brauhaus object can be easily serialized and deserialized from a JSON format. Deserialization can be from a JSON string or an object (i.e. the value given by JSON.parse(...)). For example, to serialize and deserialize a recipe object:

var r, serialized;

// Serialize

r =newBrauhaus.Recipe(...);

serialized = JSON.stringify(r);

// Deserialize from JSON string

serialized ='...';

r =newBrauhaus.Recipe(serialized);

// Deserialize from parsed object

serialized = JSON.parse('...');

r =newBrauhaus.Recipe(serialized);

Note: there is also a BeerXML plugin available which can serialize / deserialize BeerXML 1.0.

Guess the price in USD per kilogram of this fermentable, based on the name. Prices are an approximation based on multiple online homebrew supply store prices. You should use toFixed(2) to display these.

A spice is some kind of substance added to flavor or protect a brew. Spices can be hops, coriander, orange peel, cinnamon, whirlfloc, Irish moss, rose hips, etc. Each spice can have the following properties:

Calculate the IBU of a spice for the given method, early OG, and batch size in liters. Available methods are 'tinseth' and 'rager'. The early OG is usually calculated as the sum of gravity values for all non-late fermentables.

Yeast are the biological workhorse that transform sugars into alcohol. Yeast can be professional strains like Wyeast 3068, harvested from bottles, harvested from the air, or other bugs like bacteria that produce acid.

An automatically generated description of the step. If the first argument is true, then use SI units (liters, kilograms, celcius). If it is false, then use quarts, pounds and fahrenheit. If a second argument is passed, then it is used as the total grain weight of the recipe to determine the exact amount of water or mash to add/remove.

A beer recipe, containing ingredients like fermentables, spices, and yeast. Calculations can be made for bitterness, alcohol content, color, and more. Many values are unset by default and will be calculated when the Recipe.prototype.calculate() method is called. The brewDayDuration, boilStartTime and boilEndTime are unset until the Recipe.prototype.timeline() method is called.

Grade this recipe's completeness. Returned is a Number, where a completely blank recipe is zero and the higher the number, the higher the recipe completeness / quality. Some items carry more weight than others.

Scale a recipe and its ingredients to a new batch size and boil size in liters. Gravity and bitterness units are preserved. This does not recalculate the recipe, it merely adjusts various weights and volumes.

Generate a brew timeline from a recipe. If siUnits is true, then generate the timeline in metric units, otherwise output imperial units. Returns a list of [duration, description] items where duration is a time in minutes from the start of the recipe and description is the step description text.

>>> r.timeline()

[

[0,'Heat 10l of water to 68C (about 20 minutes)'],

[20,'Add 1kg CaraMunich (10 GU) and steep for 20 minutes'],

[40.16,'Remove grains. This is now your wort. Top up to 10l and bring to a boil (about 12 minutes)'],

[62.52,'Add 28g of Cascade hops (30 IBU)'],

...

]

It's possible to display a human-friendly version of this information with some utility methods used in a loop. For example:

40 minutes: Remove grains. This is now your wort. Top up to 10l and bring to a boil (about 12 minutes)

63 minutes: Add 28g of Cascade hops (30 IBU)

...

It is also possible to determine the hop additions relative to the start and end of the boil. This allows you to nicely display the boil additions as relative times (e.g. -60 minutes, -45 minutes, -5 minutes to the end of the boil). Anything before the boilStartTime is the mash, steep, or heating to boil, while anything after the boilEndTime is chilling, fermentation and bottling. The brewDayDuration ends when fermentation begins. The exact point of bottling can be determined with a combination of brewDayDuration, primaryDays, secondaryDays, and tertiaryDays.

When building brauhaus.js with cake build or npm test you will see the output of CoffeeLint, a static analysis code quality tool for CoffeeScript. Please adhere to the warnings and errors to ensure your changes will build.

Before submitting a pull request, please add any relevant tests and run them via:

npm test

If you have PhantomJS installed and on your path then you can use:

CI=true npm test

Pull requests will automatically be tested by Travis CI both in Node.js 0.6/0.8/0.10 and in a headless webkit environment (PhantomJS). Changes that cause tests to fail will not be accepted. New features should be tested to be accepted.

New tests can be added in the test directory. If you add a new file there, please don't forget to update the test.html to include it!

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.