bjs_menu_nutrition 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +61 -0
- data/exe/bjs-menu-nutrition +50 -0
- data/lib/bjs_menu_nutrition/menu.json +1 -0
- data/lib/bjs_menu_nutrition/version.rb +3 -0
- data/lib/bjs_menu_nutrition.rb +100 -0
- metadata +52 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 9732f63e3723045673c173c559a3082193aa1bb85389660c5ef258275f844374
|
|
4
|
+
data.tar.gz: 16cc32f8fd7c117a9e95fd5b8733f4c49dfa92497357287c54ae3daa3ee4c4e4
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 8485271855454ac4377c6f345005e846c1665ea7beb94a23eb48b98ded13500ef5a2d64712877a9014df62759bc636d201aaf3f312a862017e1f484853e48f6a
|
|
7
|
+
data.tar.gz: 614a54dc6576f5a1bf65f3c2557dadfe78609a3310ede1afcf455a48468a00f03c98535aeef29c30f8a85e94fcd937a6db1f2262801e8f1986b1f3f9820a8aae
|
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 BJ's Menus
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# bjs_menu_nutrition
|
|
2
|
+
|
|
3
|
+
Total the calories, protein, carbs, fat and sodium of a BJ's Restaurant & Brewhouse meal, offline. Pick a main, sides, drinks and desserts (with quantities) and get meal totals, the allergens in the meal, and a clear flag on every item that has no published value, so a total is never silently low.
|
|
4
|
+
|
|
5
|
+
The bundled menu has 183 items (132 with published nutrition). Items listed only per slice, and items with no published value, are not added to a total; the total is shown with a `+` and the items are named. Unknown allergen info never passes an allergen filter.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
gem install bjs_menu_nutrition
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## CLI
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
bjs-menu-nutrition total "BJ's Wagyu Burger" "2x Avocado Egg Rolls"
|
|
17
|
+
bjs-menu-nutrition search pizookie
|
|
18
|
+
bjs-menu-nutrition filter --max-cal 600 --min-protein 30 --without Milk --role main
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
1 x BJ's Wagyu Burger
|
|
23
|
+
2 x Avocado Egg Rolls
|
|
24
|
+
|
|
25
|
+
Calories 3,210 cal
|
|
26
|
+
Protein 68 g
|
|
27
|
+
Carbs 322 g
|
|
28
|
+
Fat 186 g
|
|
29
|
+
Sodium 5,669 mg
|
|
30
|
+
Allergens: Eggs, Fish, Milk, Other Gluten, Soy, Sulfites, Tree Nuts, Wheat
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Library
|
|
34
|
+
|
|
35
|
+
```ruby
|
|
36
|
+
require "bjs_menu_nutrition"
|
|
37
|
+
|
|
38
|
+
meal = BjsMenuNutrition.total(["BJ's Wagyu Burger", "2x Avocado Egg Rolls"])
|
|
39
|
+
puts BjsMenuNutrition.format_total(meal["totals"]["cal"]) # 3,210 cal
|
|
40
|
+
BjsMenuNutrition.filter(max_cal: 600, without: ["Milk"], role: "main")
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## How totals work
|
|
44
|
+
|
|
45
|
+
- `2x Name` sets a quantity (1-99).
|
|
46
|
+
- A name can be the item id, the exact name, or words that match exactly one item; an ambiguous query such as `burger` is an error that lists the matches.
|
|
47
|
+
- A nutrient with no published value, or an item listed per slice, is skipped and named in `missing`; the formatted total ends with `+`. If no item in the meal has the value, it reads `Not listed`.
|
|
48
|
+
|
|
49
|
+
## Links
|
|
50
|
+
|
|
51
|
+
- Full menu with prices, photos and per-item nutrition: [BJ's menu](https://bjsmenus.com/)
|
|
52
|
+
- Source: https://github.com/nbkdevs/bjs-menu
|
|
53
|
+
- Issues: https://github.com/nbkdevs/bjs-menu/issues
|
|
54
|
+
|
|
55
|
+
## Notes
|
|
56
|
+
|
|
57
|
+
Values are as published by the restaurant and can change; check with your server about allergies. Unofficial; not affiliated with BJ's Restaurants, Inc.
|
|
58
|
+
|
|
59
|
+
## Licence
|
|
60
|
+
|
|
61
|
+
MIT
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "json"
|
|
5
|
+
require_relative "../lib/bjs_menu_nutrition"
|
|
6
|
+
|
|
7
|
+
M = BjsMenuNutrition
|
|
8
|
+
HELP = <<~TXT
|
|
9
|
+
bjs-menu-nutrition - BJ's Restaurant meal nutrition totals (offline)
|
|
10
|
+
|
|
11
|
+
Usage:
|
|
12
|
+
bjs-menu-nutrition total "BJ's Wagyu Burger" "2x Avocado Egg Rolls" [--json]
|
|
13
|
+
bjs-menu-nutrition search <words>
|
|
14
|
+
bjs-menu-nutrition filter [--max-cal N] [--min-protein N] [--max-sodium N] [--without Milk,Wheat] [--role main]
|
|
15
|
+
bjs-menu-nutrition categories
|
|
16
|
+
TXT
|
|
17
|
+
LABELS = { "cal" => "Calories", "protein" => "Protein", "carbs" => "Carbs", "fat" => "Fat", "sodium" => "Sodium" }.freeze
|
|
18
|
+
|
|
19
|
+
args = ARGV.dup
|
|
20
|
+
json = !args.delete("--json").nil?
|
|
21
|
+
cmd = args.shift
|
|
22
|
+
opt = ->(n) { (i = args.index(n)) ? args[i + 1] : nil }
|
|
23
|
+
begin
|
|
24
|
+
case cmd
|
|
25
|
+
when "total"
|
|
26
|
+
r = M.total(args)
|
|
27
|
+
if json
|
|
28
|
+
puts JSON.pretty_generate(r)
|
|
29
|
+
else
|
|
30
|
+
r["lines"].each { |l| puts "#{l["qty"]} x #{l["name"]}" }
|
|
31
|
+
puts
|
|
32
|
+
M::NUTRIENTS.each { |k| puts LABELS[k].ljust(9) + M.format_total(r["totals"][k]) }
|
|
33
|
+
missing = M::NUTRIENTS.flat_map { |k| r["totals"][k]["missing"] }.uniq
|
|
34
|
+
puts "\n+ partial: no published value (or per-slice only) for #{missing.join("; ")}" unless missing.empty?
|
|
35
|
+
puts "Allergens: #{r["allergens"].join(", ")}" unless r["allergens"].empty?
|
|
36
|
+
end
|
|
37
|
+
when "search" then M.search(args.join(" ")).each { |i| puts M.row(i) }
|
|
38
|
+
when "filter"
|
|
39
|
+
num = ->(n) { opt.(n)&.to_i }
|
|
40
|
+
M.filter(max_cal: num.("--max-cal"), min_protein: num.("--min-protein"), max_sodium: num.("--max-sodium"),
|
|
41
|
+
without: (opt.("--without") || "").split(","), role: opt.("--role")).each { |i| puts M.row(i) }
|
|
42
|
+
when "categories" then puts M.categories
|
|
43
|
+
else
|
|
44
|
+
puts HELP
|
|
45
|
+
exit(cmd.nil? || %w[-h --help].include?(cmd) ? 0 : 1)
|
|
46
|
+
end
|
|
47
|
+
rescue BjsMenuNutrition::Error => e
|
|
48
|
+
warn e.message
|
|
49
|
+
exit 1
|
|
50
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"source":"https://bjsmenus.com/","updated":"2026-10-30","note":"Published BJ's Restaurant nutrition figures as collected by bjsmenus.com. null = not published.","items":[{"id":"bjs-0001","name":"Brewhouse Bites Sampler","category":"New and Popular","role":"main","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0002","name":"Pizza, Pizookie and Pepsi Bundle","category":"New and Popular","role":"main","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0003","name":"BJ's Wagyu Burger","category":"New and Popular","role":"main","cal":1230,"protein":40,"carbs":90,"fat":78,"sodium":3049,"calText":null,"perSlice":false,"allergens":["Eggs","Fish","Milk","Other Gluten","Soy","Tree Nuts","Wheat"]},{"id":"bjs-0004","name":"Korean Sweet & Spicy Chicken Sandwich","category":"New and Popular","role":"main","cal":1200,"protein":48,"carbs":155,"fat":45,"sodium":4277,"calText":null,"perSlice":false,"allergens":["Eggs","Milk","Other Gluten","Soy","Sulfites","Wheat","Sesame Seeds"]},{"id":"bjs-0005","name":"Avocado Egg Rolls","category":"New and Popular","role":"main","cal":990,"protein":14,"carbs":116,"fat":54,"sodium":1310,"calText":null,"perSlice":false,"allergens":["Eggs","Soy","Sulfites","Wheat"]},{"id":"bjs-0006","name":"Boneless Wings","category":"New and Popular","role":"main","cal":870,"protein":65,"carbs":59,"fat":41,"sodium":3522,"calText":null,"perSlice":false,"allergens":["Eggs","Milk","Other Gluten","Wheat"]},{"id":"bjs-0007","name":"Chicken Alfredo","category":"New and Popular","role":"main","cal":1220,"protein":69,"carbs":113,"fat":52,"sodium":2366,"calText":null,"perSlice":false,"allergens":["Milk","Other Gluten","Soy","Wheat","Sesame Seeds"]},{"id":"bjs-0008","name":"Bone-In Wings","category":"New and Popular","role":"main","cal":810,"protein":51,"carbs":31,"fat":54,"sodium":2754,"calText":null,"perSlice":false,"allergens":["Eggs","Milk","Wheat"]},{"id":"bjs-0009","name":"Parmesan-Crusted Chicken","category":"New and Popular","role":"main","cal":1330,"protein":94,"carbs":79,"fat":76,"sodium":2716,"calText":null,"perSlice":false,"allergens":["Eggs","Other Gluten","Shellfish","Soy","Sulfites","Wheat"]},{"id":"bjs-0010","name":"Garlic Shrimp with Parmesan Toast Appetizer","category":"Shareable Appetizers","role":"main","cal":740,"protein":45,"carbs":53,"fat":39,"sodium":1706,"calText":null,"perSlice":false,"allergens":["Milk","Other Gluten","Shellfish","Soy","Sulfites","Wheat"]},{"id":"bjs-0011","name":"BJ's Original Wings","category":"Shareable Appetizers","role":"main","cal":880,"protein":52,"carbs":34,"fat":60,"sodium":4885,"calText":null,"perSlice":false,"allergens":["Eggs","Milk","Other Gluten","Wheat"]},{"id":"bjs-0012","name":"Fried Couscous Mac & Cheese Balls","category":"Shareable Appetizers","role":"main","cal":790,"protein":27,"carbs":72,"fat":45,"sodium":2526,"calText":null,"perSlice":false,"allergens":["Eggs","Milk","Soy","Sulfites","Wheat"]},{"id":"bjs-0013","name":"Mozzarella Sticks","category":"Shareable Appetizers","role":"main","cal":820,"protein":33,"carbs":78,"fat":39,"sodium":2041,"calText":null,"perSlice":false,"allergens":["Eggs","Milk","Wheat"]},{"id":"bjs-0014","name":"Deep Dish Nachos","category":"Shareable Appetizers","role":"main","cal":1860,"protein":104,"carbs":125,"fat":106,"sodium":4533,"calText":null,"perSlice":false,"allergens":["Milk","Soy","Sulfites","Wheat"]},{"id":"bjs-0015","name":"Honey Sriracha Brussels Sprouts","category":"Shareable Appetizers","role":"main","cal":220,"protein":11,"carbs":31,"fat":6,"sodium":1346,"calText":null,"perSlice":false,"allergens":[]},{"id":"bjs-0016","name":"Burger Sliders","category":"Shareable Appetizers","role":"main","cal":800,"protein":48,"carbs":81,"fat":32,"sodium":1634,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0017","name":"Burger Sliders with Fries","category":"Shareable Appetizers","role":"main","cal":1150,"protein":52,"carbs":121,"fat":51,"sodium":2555,"calText":null,"perSlice":false,"allergens":["Milk","Wheat"]},{"id":"bjs-0018","name":"Crispy Calamari","category":"Shareable Appetizers","role":"main","cal":650,"protein":48,"carbs":66,"fat":22,"sodium":2063,"calText":null,"perSlice":false,"allergens":["Eggs","Milk","Shellfish","Soy","Wheat"]},{"id":"bjs-0019","name":"Chicken Pot Stickers","category":"Shareable Appetizers","role":"main","cal":510,"protein":22,"carbs":81,"fat":11,"sodium":4094,"calText":null,"perSlice":false,"allergens":["Eggs","Milk","Soy","Wheat"]},{"id":"bjs-0020","name":"Ahi Poke","category":"Shareable Appetizers","role":"main","cal":500,"protein":34,"carbs":44,"fat":20,"sodium":1773,"calText":null,"perSlice":false,"allergens":["Eggs","Fish","Soy","Sulfites","Wheat","Sesame Seeds"]},{"id":"bjs-0021","name":"Spinach and Artichoke Dip","category":"Shareable Appetizers","role":"main","cal":1050,"protein":34,"carbs":111,"fat":54,"sodium":1771,"calText":null,"perSlice":false,"allergens":["Milk","Soy","Wheat"]},{"id":"bjs-0022","name":"Big Twist Pretzel with Beer Cheese","category":"Shareable Appetizers","role":"main","cal":1220,"protein":41,"carbs":179,"fat":34,"sodium":4341,"calText":null,"perSlice":false,"allergens":["Milk","Wheat"]},{"id":"bjs-0023","name":"California Club Flatbread","category":"Shareable Appetizers","role":"main","cal":null,"protein":5,"carbs":10,"fat":5,"sodium":231,"calText":"110 per slice","perSlice":true,"allergens":["Eggs","Milk","Soy","Wheat","Sesame Seeds"]},{"id":"bjs-0024","name":"Pepperoni Extreme Flatbread","category":"Shareable Appetizers","role":"main","cal":null,"protein":4,"carbs":10,"fat":8,"sodium":325,"calText":"130 per slice","perSlice":true,"allergens":["Milk","Wheat"]},{"id":"bjs-0025","name":"Chips & Housemade Guacamole + Salsa","category":"Shareable Appetizers","role":"main","cal":810,"protein":24,"carbs":118,"fat":28,"sodium":1922,"calText":null,"perSlice":false,"allergens":["Wheat"]},{"id":"bjs-0026","name":"Soup and Salad Combo","category":"Soups and Salads","role":"main","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0027","name":"Chicken Tortilla Soup","category":"Soups and Salads","role":"main","cal":280,"protein":12,"carbs":30,"fat":12,"sodium":1853,"calText":null,"perSlice":false,"allergens":["Milk","Wheat"]},{"id":"bjs-0028","name":"Broccoli Cheddar Soup","category":"Soups and Salads","role":"main","cal":390,"protein":19,"carbs":23,"fat":26,"sodium":1845,"calText":null,"perSlice":false,"allergens":["Milk","Wheat"]},{"id":"bjs-0029","name":"Clam Chowder","category":"Soups and Salads","role":"main","cal":380,"protein":14,"carbs":36,"fat":20,"sodium":1196,"calText":null,"perSlice":false,"allergens":["Fish","Milk","Other Gluten","Shellfish","Soy","Sulfites","Wheat"]},{"id":"bjs-0030","name":"House Salad","category":"Soups and Salads","role":"main","cal":null,"protein":5,"carbs":8,"fat":4,"sodium":205,"calText":"80 plain / 240-320 with dressing","perSlice":false,"allergens":null},{"id":"bjs-0031","name":"House Wedge Salad","category":"Soups and Salads","role":"main","cal":320,"protein":6,"carbs":7,"fat":31,"sodium":630,"calText":null,"perSlice":false,"allergens":["Soy","Wheat"]},{"id":"bjs-0032","name":"House Caesar Salad","category":"Soups and Salads","role":"main","cal":340,"protein":10,"carbs":21,"fat":25,"sodium":892,"calText":null,"perSlice":false,"allergens":["Eggs","Fish","Milk","Other Gluten","Soy","Wheat"]},{"id":"bjs-0033","name":"Fresh Mozzarella and Tomato Salad","category":"Soups and Salads","role":"main","cal":260,"protein":14,"carbs":11,"fat":18,"sodium":322,"calText":null,"perSlice":false,"allergens":["Milk","Soy"]},{"id":"bjs-0034","name":"Steakhouse Wedge","category":"Entree Salads","role":"main","cal":1350,"protein":53,"carbs":62,"fat":97,"sodium":3550,"calText":null,"perSlice":false,"allergens":["Eggs","Fish","Milk","Other Gluten","Soy","Tree Nuts","Wheat"]},{"id":"bjs-0035","name":"Enlightened Strawberry Fields Salad","category":"Entree Salads","role":"main","cal":480,"protein":45,"carbs":16,"fat":26,"sodium":1242,"calText":null,"perSlice":false,"allergens":["Soy","Sulfites","Tree Nuts","Wheat"]},{"id":"bjs-0036","name":"Enlightened Seared Ahi Salad","category":"Entree Salads","role":"main","cal":560,"protein":30,"carbs":42,"fat":30,"sodium":1316,"calText":null,"perSlice":false,"allergens":["Eggs","Fish","Soy","Tree Nuts","Wheat"]},{"id":"bjs-0037","name":"Santa Fe Salad","category":"Entree Salads","role":"main","cal":1030,"protein":55,"carbs":56,"fat":61,"sodium":2361,"calText":null,"perSlice":false,"allergens":["Eggs","Milk","Soy","Wheat"]},{"id":"bjs-0038","name":"Enlightened Asian Chopped Salad","category":"Entree Salads","role":"main","cal":510,"protein":25,"carbs":31,"fat":21,"sodium":1382,"calText":null,"perSlice":false,"allergens":["Eggs","Soy","Tree Nuts","Wheat"]},{"id":"bjs-0039","name":"Chicken Caesar Salad","category":"Entree Salads","role":"main","cal":1030,"protein":62,"carbs":44,"fat":70,"sodium":3022,"calText":null,"perSlice":false,"allergens":["Eggs","Fish","Milk","Other Gluten","Soy","Wheat"]},{"id":"bjs-0040","name":"Build Your Own Pizza (Large)","category":"Pizzas","role":"main","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":true,"allergens":null},{"id":"bjs-0041","name":"Half & Half Deep Dish","category":"Pizzas","role":"main","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0042","name":"BJ's Favorite Pizza","category":"Pizzas","role":"main","cal":360,"protein":15,"carbs":38,"fat":15,"sodium":755,"calText":null,"perSlice":true,"allergens":["Milk","Wheat"]},{"id":"bjs-0043","name":"Pepperoni Extreme Pizza","category":"Pizzas","role":"main","cal":400,"protein":14,"carbs":35,"fat":21,"sodium":921,"calText":null,"perSlice":true,"allergens":["Milk","Wheat"]},{"id":"bjs-0044","name":"Mikes Hot Honey Pizza","category":"Pizzas","role":"main","cal":390,"protein":14,"carbs":47,"fat":14,"sodium":823,"calText":null,"perSlice":true,"allergens":["Milk","Wheat","Sesame Seeds"]},{"id":"bjs-0045","name":"Epic Five Meat Pizza","category":"Pizzas","role":"main","cal":410,"protein":19,"carbs":35,"fat":18,"sodium":970,"calText":null,"perSlice":true,"allergens":["Milk","Wheat"]},{"id":"bjs-0046","name":"Barbeque Chicken Pizza","category":"Pizzas","role":"main","cal":350,"protein":19,"carbs":44,"fat":9,"sodium":825,"calText":null,"perSlice":true,"allergens":["Milk","Wheat","Sesame Seeds"]},{"id":"bjs-0047","name":"Chicken Bacon Ranch Pizza","category":"Pizzas","role":"main","cal":450,"protein":23,"carbs":37,"fat":22,"sodium":908,"calText":null,"perSlice":true,"allergens":["Eggs","Milk","Shellfish","Wheat"]},{"id":"bjs-0048","name":"Vegetarian Pizza","category":"Pizzas","role":"main","cal":280,"protein":11,"carbs":36,"fat":9,"sodium":524,"calText":null,"perSlice":true,"allergens":["Milk","Wheat"]},{"id":"bjs-0049","name":"BJ's Classic Combo Pizza","category":"Pizzas","role":"main","cal":350,"protein":16,"carbs":36,"fat":15,"sodium":841,"calText":null,"perSlice":true,"allergens":["Milk","Wheat"]},{"id":"bjs-0050","name":"BJ's Brewhouse Classic Pizza","category":"Pizzas","role":"main","cal":90,"protein":4,"carbs":9,"fat":5,"sodium":247,"calText":null,"perSlice":true,"allergens":["Milk","Wheat"]},{"id":"bjs-0051","name":"Spicy Pig Pizza","category":"Pizzas","role":"main","cal":90,"protein":4,"carbs":9,"fat":4,"sodium":250,"calText":null,"perSlice":true,"allergens":["Milk","Wheat"]},{"id":"bjs-0052","name":"Build Your Own Pizza (Tavern-Cut)","category":"Pizzas","role":"main","cal":60,"protein":2,"carbs":8,"fat":2,"sodium":117,"calText":null,"perSlice":true,"allergens":["Milk"]},{"id":"bjs-0053","name":"Gluten-Free Thin Crust Cheese Pizza","category":"Pizzas","role":"main","cal":130,"protein":4,"carbs":14,"fat":6,"sodium":198,"calText":null,"perSlice":true,"allergens":["Milk"]},{"id":"bjs-0054","name":"Gluten-Free Pepperoni Extreme","category":"Pizzas","role":"main","cal":210,"protein":6,"carbs":14,"fat":15,"sodium":503,"calText":null,"perSlice":true,"allergens":["Milk","Wheat"]},{"id":"bjs-0055","name":"Gluten-Free Vegetarian","category":"Pizzas","role":"main","cal":140,"protein":4,"carbs":15,"fat":7,"sodium":240,"calText":null,"perSlice":true,"allergens":["Milk"]},{"id":"bjs-0056","name":"Gluten-Free BJ's Classic Combo","category":"Pizzas","role":"main","cal":190,"protein":7,"carbs":15,"fat":11,"sodium":450,"calText":null,"perSlice":true,"allergens":["Milk"]},{"id":"bjs-0057","name":"Gluten-Free Chicken Bacon Ranch","category":"Pizzas","role":"main","cal":250,"protein":12,"carbs":15,"fat":15,"sodium":520,"calText":null,"perSlice":true,"allergens":["Eggs","Milk","Wheat"]},{"id":"bjs-0058","name":"Gluten-Free Barbeque Chicken","category":"Pizzas","role":"main","cal":200,"protein":10,"carbs":22,"fat":8,"sodium":517,"calText":null,"perSlice":true,"allergens":["Milk","Sesame Seeds"]},{"id":"bjs-0059","name":"Shrimp Scampi","category":"Pastas","role":"main","cal":1370,"protein":48,"carbs":112,"fat":76,"sodium":1923,"calText":null,"perSlice":false,"allergens":["Fish","Milk","Shellfish","Sulfites","Wheat"]},{"id":"bjs-0060","name":"Deep Dish Ziti","category":"Pastas","role":"main","cal":1220,"protein":43,"carbs":102,"fat":71,"sodium":2741,"calText":null,"perSlice":false,"allergens":["Eggs","Milk","Wheat"]},{"id":"bjs-0061","name":"Jumbo Spaghetti and Meatballs","category":"Pastas","role":"main","cal":1280,"protein":53,"carbs":135,"fat":59,"sodium":1903,"calText":null,"perSlice":false,"allergens":["Eggs","Milk","Wheat"]},{"id":"bjs-0062","name":"Italian Chicken Parmigiana Pasta","category":"Pastas","role":"main","cal":1440,"protein":99,"carbs":118,"fat":66,"sodium":2623,"calText":null,"perSlice":false,"allergens":["Eggs","Milk","Wheat"]},{"id":"bjs-0063","name":"California Chicken Club Sandwich","category":"Sandwiches & Tacos","role":"main","cal":1310,"protein":73,"carbs":91,"fat":69,"sodium":2986,"calText":null,"perSlice":false,"allergens":["Eggs","Milk","Other Gluten","Soy","Wheat"]},{"id":"bjs-0064","name":"BJ's Classic Crispy Chicken Sandwich","category":"Sandwiches & Tacos","role":"main","cal":1220,"protein":45,"carbs":116,"fat":63,"sodium":2756,"calText":null,"perSlice":false,"allergens":["Eggs","Other Gluten","Wheat"]},{"id":"bjs-0065","name":"Enlightened Mediterranean Chicken Pita Tacos","category":"Sandwiches & Tacos","role":"main","cal":660,"protein":38,"carbs":45,"fat":22,"sodium":1427,"calText":null,"perSlice":false,"allergens":["Milk","Other Gluten","Soy","Wheat"]},{"id":"bjs-0066","name":"BJ's Slow-Roasted Tri-Tip Beef Dip","category":"Sandwiches & Tacos","role":"main","cal":1690,"protein":71,"carbs":114,"fat":107,"sodium":4650,"calText":null,"perSlice":false,"allergens":["Milk","Other Gluten","Soy","Sulfites","Wheat"]},{"id":"bjs-0067","name":"Bacon Cheeseburger","category":"Burgers","role":"main","cal":1250,"protein":56,"carbs":90,"fat":73,"sodium":3792,"calText":null,"perSlice":false,"allergens":["Eggs","Fish","Milk","Other Gluten","Soy","Wheat"]},{"id":"bjs-0068","name":"All-American Smash Burger","category":"Burgers","role":"main","cal":1190,"protein":40,"carbs":88,"fat":73,"sodium":4416,"calText":null,"perSlice":false,"allergens":["Eggs","Fish","Milk","Other Gluten","Soy","Wheat"]},{"id":"bjs-0069","name":"Bacon Guacamole Deluxe Burger","category":"Burgers","role":"main","cal":1320,"protein":57,"carbs":94,"fat":78,"sodium":3560,"calText":null,"perSlice":false,"allergens":["Eggs","Fish","Milk","Other Gluten","Soy","Wheat"]},{"id":"bjs-0070","name":"Steakhouse Burger","category":"Burgers","role":"main","cal":1760,"protein":81,"carbs":94,"fat":117,"sodium":4515,"calText":null,"perSlice":false,"allergens":["Eggs","Milk","Other Gluten","Soy","Wheat"]},{"id":"bjs-0071","name":"BJ's Smokehouse Burger","category":"Burgers","role":"main","cal":1270,"protein":57,"carbs":106,"fat":67,"sodium":3660,"calText":null,"perSlice":false,"allergens":["Eggs","Fish","Milk","Other Gluten","Soy","Wheat"]},{"id":"bjs-0072","name":"Hatch Green Chile Smash Burger","category":"Burgers","role":"main","cal":1140,"protein":45,"carbs":91,"fat":66,"sodium":3534,"calText":null,"perSlice":false,"allergens":["Eggs","Milk","Other Gluten","Shellfish","Soy","Wheat"]},{"id":"bjs-0073","name":"New Orleans Jambalaya+","category":"Specialty Entrees","role":"main","cal":1320,"protein":69,"carbs":99,"fat":70,"sodium":3623,"calText":null,"perSlice":false,"allergens":["Fish","Milk","Other Gluten","Shellfish","Soy","Sulfites","Wheat"]},{"id":"bjs-0074","name":"Atlantic Salmon","category":"Specialty Entrees","role":"main","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0075","name":"BJ's Brewhouse Blonde® Fish 'N' Chips","category":"Specialty Entrees","role":"main","cal":1120,"protein":57,"carbs":141,"fat":36,"sodium":4196,"calText":null,"perSlice":false,"allergens":["Eggs","Fish","Milk","Other Gluten","Soy","Sulfites","Wheat"]},{"id":"bjs-0076","name":"Sal's Brewhouse Chicken","category":"Specialty Entrees","role":"main","cal":1000,"protein":54,"carbs":45,"fat":67,"sodium":3014,"calText":null,"perSlice":false,"allergens":["Eggs","Other Gluten","Shellfish","Soy","Sulfites","Wheat"]},{"id":"bjs-0077","name":"Enlightened Cherry Chipotle Glazed Salmon","category":"Specialty Entrees","role":"main","cal":580,"protein":47,"carbs":40,"fat":26,"sodium":576,"calText":null,"perSlice":false,"allergens":["Fish","Soy","Sulfites","Wheat"]},{"id":"bjs-0078","name":"BJ's Brewhouse Bowl","category":"Specialty Entrees","role":"main","cal":480,"protein":14,"carbs":58,"fat":21,"sodium":2036,"calText":null,"perSlice":false,"allergens":["Soy","Sulfites","Wheat"]},{"id":"bjs-0079","name":"BJ's Brewhouse Bowl with Salmon","category":"Specialty Entrees","role":"main","cal":870,"protein":55,"carbs":61,"fat":46,"sodium":3248,"calText":null,"perSlice":false,"allergens":["Fish","Milk","Soy","Sulfites","Wheat"]},{"id":"bjs-0080","name":"BJ's Brewhouse Bowl with Shrimp","category":"Specialty Entrees","role":"main","cal":730,"protein":49,"carbs":61,"fat":31,"sodium":2858,"calText":null,"perSlice":false,"allergens":["Milk","Shellfish","Soy","Sulfites","Wheat"]},{"id":"bjs-0081","name":"BJ's Brewhouse Bowl with Chicken","category":"Specialty Entrees","role":"main","cal":710,"protein":54,"carbs":60,"fat":27,"sodium":3047,"calText":null,"perSlice":false,"allergens":["Milk","Soy","Sulfites","Wheat"]},{"id":"bjs-0082","name":"BJ's Brewhouse Bowl with Tri-Tip","category":"Specialty Entrees","role":"main","cal":850,"protein":50,"carbs":61,"fat":39,"sodium":3212,"calText":null,"perSlice":false,"allergens":["Milk","Soy","Sulfites","Wheat"]},{"id":"bjs-0083","name":"Prime Rib","category":"Steaks & Slow-Roasted Entrees","role":"main","cal":1310,"protein":80,"carbs":7,"fat":106,"sodium":2246,"calText":null,"perSlice":false,"allergens":["Eggs","Fish","Milk","Soy","Sulfites"]},{"id":"bjs-0084","name":"Double Bone-In Pork Chop Weekend Special","category":"Steaks & Slow-Roasted Entrees","role":"main","cal":650,"protein":55,"carbs":17,"fat":40,"sodium":2434,"calText":null,"perSlice":false,"allergens":["Eggs","Soy","Sulfites"]},{"id":"bjs-0086","name":"Slow-Roasted Tri-Tip","category":"Steaks & Slow-Roasted Entrees","role":"main","cal":660,"protein":48,"carbs":47,"fat":30,"sodium":2582,"calText":null,"perSlice":false,"allergens":["Soy","Sulfites","Wheat"]},{"id":"bjs-0087","name":"Baby Back Pork Ribs - Full Rack","category":"Steaks & Slow-Roasted Entrees","role":"main","cal":1540,"protein":50,"carbs":179,"fat":68,"sodium":9190,"calText":null,"perSlice":false,"allergens":["Soy","Sulfites","Wheat"]},{"id":"bjs-0088","name":"Baby Back Pork Ribs - Half Rack","category":"Steaks & Slow-Roasted Entrees","role":"main","cal":830,"protein":25,"carbs":104,"fat":34,"sodium":4932,"calText":null,"perSlice":false,"allergens":["Soy","Sulfites","Wheat"]},{"id":"bjs-0089","name":"Slow-Roasted Tri-Tip and Baby Back Ribs","category":"Steaks & Slow-Roasted Entrees","role":"main","cal":1240,"protein":61,"carbs":120,"fat":56,"sodium":6333,"calText":null,"perSlice":false,"allergens":["Soy","Sulfites","Wheat"]},{"id":"bjs-0090","name":"Slow-Roasted Tri-tip and Shrimp Scampi","category":"Steaks & Slow-Roasted Entrees","role":"main","cal":1080,"protein":48,"carbs":82,"fat":54,"sodium":3574,"calText":null,"perSlice":false,"allergens":["Fish","Shellfish","Soy","Sulfites","Wheat"]},{"id":"bjs-0091","name":"Slow-Roasted Tri-Tip and Chicken","category":"Steaks & Slow-Roasted Entrees","role":"main","cal":880,"protein":61,"carbs":76,"fat":29,"sodium":3601,"calText":null,"perSlice":false,"allergens":["Soy","Sulfites","Wheat"]},{"id":"bjs-0092","name":"BJ's Original Crispy Chicken Sandwich","category":"$13 Pizookie Meal Deal","role":"main","cal":1120,"protein":54,"carbs":110,"fat":45,"sodium":2277,"calText":null,"perSlice":false,"allergens":["Eggs","Milk","Other Gluten","Soy","Wheat"]},{"id":"bjs-0093","name":"Italian Chicken Parmigiana Pasta Lunch Sized","category":"$13 Pizookie Meal Deal","role":"main","cal":860,"protein":53,"carbs":80,"fat":39,"sodium":1538,"calText":null,"perSlice":false,"allergens":["Eggs","Milk","Wheat"]},{"id":"bjs-0095","name":"Southern Fried Chicken","category":"$13 Pizookie Meal Deal","role":"main","cal":1140,"protein":52,"carbs":70,"fat":66,"sodium":1928,"calText":null,"perSlice":false,"allergens":["Eggs","Milk","Soy","Sulfites","Wheat"]},{"id":"bjs-0096","name":"Personal Deep-Dish Pizza & House Salad Combo","category":"$13 Pizookie Meal Deal","role":"main","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0097","name":"Enlightened Mediterranean Chicken Bowl","category":"$13 Pizookie Meal Deal","role":"main","cal":590,"protein":50,"carbs":40,"fat":24,"sodium":1449,"calText":null,"perSlice":false,"allergens":["Milk","Soy","Sulfites","Sesame Seeds"]},{"id":"bjs-0099","name":"Strawberry Fields Salad With Chicken","category":"$13 Pizookie Meal Deal","role":"main","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0100","name":"Kids' Create-Your-Own-Pasta","category":"Kids' Menu","role":"main","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0101","name":"Kids' Chicken Tenders","category":"Kids' Menu","role":"main","cal":null,"protein":27,"carbs":30,"fat":26,"sodium":1708,"calText":"470 (with ranch dressing)","perSlice":false,"allergens":["Eggs","Milk","Other Gluten","Soy","Wheat"]},{"id":"bjs-0102","name":"Kids' Mini Corn Dogs","category":"Kids' Menu","role":"main","cal":470,"protein":14,"carbs":36,"fat":29,"sodium":1059,"calText":null,"perSlice":false,"allergens":["Eggs","Milk","Other Gluten","Soy","Wheat"]},{"id":"bjs-0103","name":"Chicken Breast","category":"Kids' Menu","role":"main","cal":220,"protein":39,"carbs":0,"fat":6,"sodium":851,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0104","name":"Kids' Mini Burgers","category":"Kids' Menu","role":"main","cal":380,"protein":24,"carbs":36,"fat":16,"sodium":663,"calText":null,"perSlice":false,"allergens":["Eggs","Fish","Milk","Other Gluten","Soy","Wheat"]},{"id":"bjs-0105","name":"Kids' Mac 'N' Cheese","category":"Kids' Menu","role":"main","cal":340,"protein":12,"carbs":48,"fat":11,"sodium":833,"calText":null,"perSlice":false,"allergens":["Eggs","Milk","Wheat"]},{"id":"bjs-0106","name":"Kids' Deep Dish Pizza","category":"Kids' Menu","role":"main","cal":560,"protein":23,"carbs":66,"fat":23,"sodium":1423,"calText":null,"perSlice":false,"allergens":["Milk","Shellfish","Wheat"]},{"id":"bjs-0107","name":"Kids' Boneless Wings","category":"Kids' Menu","role":"main","cal":650,"protein":33,"carbs":56,"fat":31,"sodium":2431,"calText":null,"perSlice":false,"allergens":["Eggs","Milk","Other Gluten","Soy","Wheat"]},{"id":"bjs-0108","name":"Kids' Mini Pizookie®","category":"Kids' Menu","role":"main","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0109","name":"Kids' Sundae","category":"Kids' Menu","role":"main","cal":390,"protein":4,"carbs":45,"fat":22,"sodium":74,"calText":null,"perSlice":false,"allergens":["Eggs","Milk","Soy","Tree Nuts","Wheat"]},{"id":"bjs-0110","name":"Pizookie® Trio","category":"Desserts","role":"dessert","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":"1,740-2,180 depending on flavors chosen","perSlice":false,"allergens":null},{"id":"bjs-0111","name":"Ice Cream Cup","category":"Desserts","role":"dessert","cal":null,"protein":7,"carbs":null,"fat":null,"sodium":null,"calText":"210-220 depending on scoop count","perSlice":false,"allergens":["Eggs","Milk","Soy"]},{"id":"bjs-0112","name":"BJ's Handcrafted Root Beer Float","category":"Desserts","role":"dessert","cal":550,"protein":0,"carbs":90,"fat":19,"sodium":95,"calText":null,"perSlice":false,"allergens":["Milk","Sulfites"]},{"id":"bjs-0113","name":"BJ's Handcrafted Black Cherry Float","category":"Desserts","role":"dessert","cal":530,"protein":0,"carbs":82,"fat":19,"sodium":105,"calText":null,"perSlice":false,"allergens":["Eggs","Milk","Soy"]},{"id":"bjs-0114","name":"BJ's Handcrafted Orange Cream Float","category":"Desserts","role":"dessert","cal":540,"protein":0,"carbs":85,"fat":19,"sodium":106,"calText":null,"perSlice":false,"allergens":["Milk","Soy"]},{"id":"bjs-0115","name":"BJ's Handcrafted Vanilla Cream Float","category":"Desserts","role":"dessert","cal":530,"protein":0,"carbs":83,"fat":19,"sodium":105,"calText":null,"perSlice":false,"allergens":["Eggs","Milk","Soy"]},{"id":"bjs-0116","name":"BJ's Handcrafted Root Beer","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":240,"protein":0,"carbs":60,"fat":0,"sodium":14,"calText":null,"perSlice":false,"allergens":[]},{"id":"bjs-0117","name":"BJ's Handcrafted Vanilla Cream Soda","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":190,"protein":0,"carbs":47,"fat":0,"sodium":32,"calText":null,"perSlice":false,"allergens":[]},{"id":"bjs-0118","name":"BJ's Handcrafted Orange Cream Soda","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":210,"protein":0,"carbs":51,"fat":0,"sodium":34,"calText":null,"perSlice":false,"allergens":[]},{"id":"bjs-0119","name":"BJ's Handcrafted Black Cherry Soda","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":190,"protein":0,"carbs":47,"fat":0,"sodium":32,"calText":null,"perSlice":false,"allergens":[]},{"id":"bjs-0120","name":"BJ's Handcrafted Ginger Beer","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":130,"protein":0,"carbs":31,"fat":0,"sodium":22,"calText":null,"perSlice":false,"allergens":[]},{"id":"bjs-0121","name":"BJ's Root Beer- 6 Pack","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0122","name":"BJ's Ginger Beer - 4 Pack","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0123","name":"BJ's Root Beer - Single Can","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0124","name":"BJ's Ginger Beer - Single Can","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0125","name":"Pepsi","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":null,"protein":0,"carbs":34,"fat":0,"sodium":31,"calText":"130 (10 oz)","perSlice":false,"allergens":[]},{"id":"bjs-0126","name":"Diet Pepsi","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":null,"protein":0,"carbs":0,"fat":0,"sodium":38,"calText":"0 (10 oz)","perSlice":false,"allergens":[]},{"id":"bjs-0127","name":"Pepsi Zero Sugar","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0128","name":"Dr Pepper","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":null,"protein":0,"carbs":34,"fat":0,"sodium":44,"calText":"140 (10 oz)","perSlice":false,"allergens":[]},{"id":"bjs-0129","name":"Diet Dr Pepper","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":null,"protein":0,"carbs":0,"fat":0,"sodium":44,"calText":"0 (10 oz)","perSlice":false,"allergens":[]},{"id":"bjs-0130","name":"Starry","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":null,"protein":0,"carbs":32,"fat":0,"sodium":30,"calText":"120 (10 oz)","perSlice":false,"allergens":[]},{"id":"bjs-0131","name":"Mountain Dew","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":null,"protein":0,"carbs":39,"fat":0,"sodium":63,"calText":"140 (10 oz)","perSlice":false,"allergens":[]},{"id":"bjs-0132","name":"Shirley Temple","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":210,"protein":0,"carbs":53,"fat":0,"sodium":36,"calText":null,"perSlice":false,"allergens":[]},{"id":"bjs-0133","name":"Club Soda","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0134","name":"Bottled Water","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0135","name":"Strawberry Lemonade","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":190,"protein":0,"carbs":47,"fat":0,"sodium":15,"calText":null,"perSlice":false,"allergens":[]},{"id":"bjs-0136","name":"Lemonade","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":180,"protein":0,"carbs":44,"fat":0,"sodium":17,"calText":null,"perSlice":false,"allergens":[]},{"id":"bjs-0137","name":"San Pellegrino","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0138","name":"Red Bull Sugarfree","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0139","name":"Unsweetened Black Iced Tea","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0140","name":"Sweet Tea","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":190,"protein":0,"carbs":48,"fat":0,"sodium":7,"calText":null,"perSlice":false,"allergens":[]},{"id":"bjs-0141","name":"Arnold Palmer","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0142","name":"Hot Chocolate","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":160,"protein":1,"carbs":25,"fat":6,"sodium":174,"calText":null,"perSlice":false,"allergens":["Milk"]},{"id":"bjs-0143","name":"Chocolate Milk","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":450,"protein":18,"carbs":73,"fat":9,"sodium":293,"calText":null,"perSlice":false,"allergens":["Milk"]},{"id":"bjs-0144","name":"Milk","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":280,"protein":20,"carbs":28,"fat":10,"sodium":300,"calText":null,"perSlice":false,"allergens":["Milk"]},{"id":"bjs-0145","name":"Pineapple Juice","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0146","name":"Orange Juice","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0147","name":"Cranberry Juice","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0148","name":"Apple Juice","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0149","name":"Grapefruit Juice","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0150","name":"BJ's Handcrafted Root Beer 64 oz","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0151","name":"BJ's Handcrafted Vanilla Cream Soda 64 oz","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0152","name":"BJ's Handcrafted Orange Cream Soda 64 oz","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0153","name":"BJ's Handcrafted Black Cherry Soda 64 oz","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0154","name":"Lemonade 64 oz","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0155","name":"Strawberry Lemonade 64 oz","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0156","name":"Unsweetened Black Iced Tea 64 oz","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0157","name":"Arnold Palmer 64 oz","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0187","name":"Fries","category":"Sides","role":"side","cal":350,"protein":4,"carbs":40,"fat":19,"sodium":921,"calText":null,"perSlice":false,"allergens":["Wheat"]},{"id":"bjs-0188","name":"Sweet Potato Fries","category":"Sides","role":"side","cal":330,"protein":2,"carbs":52,"fat":12,"sodium":230,"calText":null,"perSlice":false,"allergens":[]},{"id":"bjs-0190","name":"Loaded Mashed Potatoes","category":"Sides","role":"side","cal":930,"protein":32,"carbs":37,"fat":70,"sodium":2122,"calText":null,"perSlice":false,"allergens":["Milk","Shellfish"]},{"id":"bjs-0191","name":"Baked Potato","category":"Sides","role":"side","cal":590,"protein":9,"carbs":70,"fat":28,"sodium":207,"calText":null,"perSlice":false,"allergens":[]},{"id":"bjs-0192","name":"Loaded Baked Potato","category":"Sides","role":"side","cal":990,"protein":33,"carbs":72,"fat":60,"sodium":1107,"calText":null,"perSlice":false,"allergens":["Milk","Shellfish"]},{"id":"bjs-0193","name":"Broccoli","category":"Sides","role":"side","cal":40,"protein":3,"carbs":6,"fat":0,"sodium":30,"calText":null,"perSlice":false,"allergens":[]},{"id":"bjs-0194","name":"Rice Pilaf","category":"Sides","role":"side","cal":230,"protein":5,"carbs":39,"fat":6,"sodium":621,"calText":null,"perSlice":false,"allergens":[]},{"id":"bjs-0195","name":"Honey Sriracha Brussels Sprouts","category":"Sides","role":"side","cal":160,"protein":9,"carbs":23,"fat":4,"sodium":940,"calText":null,"perSlice":false,"allergens":["Milk","Shellfish","Wheat","Sesame Seeds"]},{"id":"bjs-0196","name":"Asparagus","category":"Sides","role":"side","cal":25,"protein":2,"carbs":3,"fat":0,"sodium":2,"calText":null,"perSlice":false,"allergens":[]},{"id":"bjs-0197","name":"Garlic-Roasted Vegetables","category":"Sides","role":"side","cal":250,"protein":4,"carbs":11,"fat":21,"sodium":531,"calText":null,"perSlice":false,"allergens":["Sesame Seeds"]},{"id":"bjs-0198","name":"Gluten-Sensitive Spinach and Artichoke Dip","category":"Gluten Sensitive Options","role":"main","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0201","name":"Gluten-Sensitive House Salad","category":"Gluten Sensitive Options","role":"main","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0202","name":"Gluten-Sensitive House Caesar Salad","category":"Gluten Sensitive Options","role":"main","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0203","name":"Gluten-Sensitive Santa Fe Salad","category":"Gluten Sensitive Options","role":"main","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0204","name":"Gluten-Sensitive Chicken Caesar Salad","category":"Gluten Sensitive Options","role":"main","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0205","name":"BJ's Classic Rib-Eye","category":"Gluten Sensitive Options","role":"main","cal":1080,"protein":106,"carbs":5,"fat":67,"sodium":2272,"calText":null,"perSlice":false,"allergens":["Soy","Sulfites","Wheat"]},{"id":"bjs-0206","name":"Gluten-Sensitive Fresh Atlantic Salmon","category":"Gluten Sensitive Options","role":"main","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0211","name":"Gluten-Sensitive BJ's Wagyu Burger","category":"Gluten Sensitive Options","role":"main","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0213","name":"Gluten-Sensitive Bacon Guacamole Deluxe Burger","category":"Gluten Sensitive Options","role":"main","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0215","name":"White Cheddar Mashed Potatoes","category":"Gluten Sensitive Options","role":"main","cal":330,"protein":7,"carbs":33,"fat":18,"sodium":1097,"calText":null,"perSlice":false,"allergens":["Milk"]},{"id":"bjs-0226","name":"Chocolate Chunk Pizookie","category":"New and Popular","role":"main","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0228","name":"Strawberry Shortcake Pizookie","category":"Desserts","role":"dessert","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0230","name":"Triple Chocolate Pizookie Made With Ghirardelli","category":"Desserts","role":"dessert","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0231","name":"Salted Caramel Pizookie","category":"Desserts","role":"dessert","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0233","name":"Gluten-Free Chocolate Chip Pizookie","category":"Desserts","role":"dessert","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0234","name":"Red Bull","category":"Non-Alcoholic Beverages To Go","role":"drink","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0254","name":"Gluten-Sensitive Hickory Brisket and Bacon Burger","category":"Gluten Sensitive Options","role":"main","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0255","name":"Gluten-Sensitive Bacon Cheeseburger","category":"Gluten Sensitive Options","role":"main","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null},{"id":"bjs-0256","name":"Gluten-Sensitive Classic Burger","category":"Gluten Sensitive Options","role":"main","cal":null,"protein":null,"carbs":null,"fat":null,"sodium":null,"calText":null,"perSlice":false,"allergens":null}]}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
require_relative "bjs_menu_nutrition/version"
|
|
5
|
+
|
|
6
|
+
# Offline BJ's Restaurant meal builder: nutrition totals, missing-value flags,
|
|
7
|
+
# search and calorie/allergen filters. Data collected by https://bjsmenus.com/.
|
|
8
|
+
module BjsMenuNutrition
|
|
9
|
+
NUTRIENTS = %w[cal protein carbs fat sodium].freeze
|
|
10
|
+
UNITS = { "cal" => "cal", "protein" => "g", "carbs" => "g", "fat" => "g", "sodium" => "mg" }.freeze
|
|
11
|
+
DATA = JSON.parse(File.read(File.join(__dir__, "bjs_menu_nutrition", "menu.json"), encoding: "utf-8")).freeze
|
|
12
|
+
ITEMS = DATA["items"].freeze
|
|
13
|
+
|
|
14
|
+
class Error < StandardError; end
|
|
15
|
+
|
|
16
|
+
module_function
|
|
17
|
+
|
|
18
|
+
def norm(str)
|
|
19
|
+
str.to_s.downcase.delete("'\u2018\u2019").gsub(/[^a-z0-9]+/, " ").strip
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def items = ITEMS
|
|
23
|
+
|
|
24
|
+
def categories = ITEMS.map { |i| i["category"] }.uniq
|
|
25
|
+
|
|
26
|
+
def search(query)
|
|
27
|
+
q = norm(query)
|
|
28
|
+
return [] if q.empty?
|
|
29
|
+
|
|
30
|
+
words = q.split(" ")
|
|
31
|
+
ITEMS.select { |i| n = norm(i["name"]); words.all? { |w| n.include?(w) } }
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Find by id, exact name, or a query that matches exactly one item.
|
|
35
|
+
def find(ref)
|
|
36
|
+
hit = ITEMS.find { |i| i["id"] == ref } || ITEMS.find { |i| norm(i["name"]) == norm(ref) }
|
|
37
|
+
return hit if hit
|
|
38
|
+
|
|
39
|
+
hits = search(ref)
|
|
40
|
+
return hits.first if hits.size == 1
|
|
41
|
+
raise Error, %(No menu item matches "#{ref}") if hits.empty?
|
|
42
|
+
|
|
43
|
+
raise Error, %("#{ref}" matches #{hits.size} items: #{hits.first(5).map { |h| h["name"] }.join("; ")})
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# "2x Avocado Egg Rolls" => ["Avocado Egg Rolls", 2]
|
|
47
|
+
def parse_line(text)
|
|
48
|
+
m = /\A\s*(\d+)\s*[xX\u00d7]\s+(.+)\z/.match(text)
|
|
49
|
+
m ? [m[2].strip, m[1].to_i] : [text.strip, 1]
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Total a meal. Items with no published value for a nutrient, or listed per slice,
|
|
53
|
+
# are not added and are named in "missing"; the total is then partial.
|
|
54
|
+
def total(lines)
|
|
55
|
+
resolved = lines.map do |l|
|
|
56
|
+
ref, qty = l.is_a?(String) ? parse_line(l) : l
|
|
57
|
+
item = find(ref)
|
|
58
|
+
raise Error, "Quantity for #{item["name"]} must be 1-99" unless qty.is_a?(Integer) && qty.between?(1, 99)
|
|
59
|
+
|
|
60
|
+
[item, qty]
|
|
61
|
+
end
|
|
62
|
+
totals = NUTRIENTS.to_h do |k|
|
|
63
|
+
sum = 0
|
|
64
|
+
missing = []
|
|
65
|
+
resolved.each { |item, qty| item[k].nil? || item["perSlice"] ? missing << item["name"] : sum += item[k] * qty }
|
|
66
|
+
[k, { "sum" => sum, "unit" => UNITS[k], "missing" => missing, "partial" => !missing.empty?,
|
|
67
|
+
"listed" => !resolved.empty? && missing.size < resolved.size }]
|
|
68
|
+
end
|
|
69
|
+
known = resolved.reject { |i, _| i["allergens"].nil? }
|
|
70
|
+
{ "lines" => resolved.map { |i, q| { "name" => i["name"], "qty" => q } }, "totals" => totals,
|
|
71
|
+
"allergens" => known.flat_map { |i, _| i["allergens"] }.uniq.sort,
|
|
72
|
+
"allergen_unknown" => resolved.select { |i, _| i["allergens"].nil? }.map { |i, _| i["name"] } }
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Items matching every limit. Unknown allergen info never passes a without: filter.
|
|
76
|
+
def filter(max_cal: nil, min_protein: nil, max_sodium: nil, without: [], role: nil)
|
|
77
|
+
wo = without.map { |w| norm(w) }.reject(&:empty?)
|
|
78
|
+
ITEMS.select do |i|
|
|
79
|
+
next false if role && i["role"] != role
|
|
80
|
+
next false if max_cal && (i["cal"].nil? || i["perSlice"] || i["cal"] > max_cal)
|
|
81
|
+
next false if min_protein && (i["protein"].nil? || i["protein"] < min_protein)
|
|
82
|
+
next false if max_sodium && (i["sodium"].nil? || i["sodium"] > max_sodium)
|
|
83
|
+
next false if !wo.empty? && (i["allergens"].nil? || i["allergens"].any? { |a| wo.include?(norm(a)) })
|
|
84
|
+
|
|
85
|
+
true
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def format_total(tot)
|
|
90
|
+
return "Not listed" unless tot["listed"]
|
|
91
|
+
|
|
92
|
+
n = tot["sum"].round.to_s.reverse.scan(/\d{1,3}/).join(",").reverse
|
|
93
|
+
"#{n} #{tot["unit"]}#{"+" if tot["partial"]}"
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def row(item)
|
|
97
|
+
cal = item["calText"] ? "#{item["calText"]} cal" : (item["cal"] ? "#{item["cal"]} cal" : "calories not listed")
|
|
98
|
+
"#{item["name"]} (#{item["category"]}) - #{cal}"
|
|
99
|
+
end
|
|
100
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: bjs_menu_nutrition
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- BJ's Menus
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies: []
|
|
12
|
+
description: Total calories, protein, carbs, fat and sodium for a BJ's Restaurant
|
|
13
|
+
meal, see which items have no published value, and filter the menu by calories,
|
|
14
|
+
protein, sodium and allergens. Library and CLI.
|
|
15
|
+
executables:
|
|
16
|
+
- bjs-menu-nutrition
|
|
17
|
+
extensions: []
|
|
18
|
+
extra_rdoc_files: []
|
|
19
|
+
files:
|
|
20
|
+
- LICENSE
|
|
21
|
+
- README.md
|
|
22
|
+
- exe/bjs-menu-nutrition
|
|
23
|
+
- lib/bjs_menu_nutrition.rb
|
|
24
|
+
- lib/bjs_menu_nutrition/menu.json
|
|
25
|
+
- lib/bjs_menu_nutrition/version.rb
|
|
26
|
+
homepage: https://bjsmenus.com/
|
|
27
|
+
licenses:
|
|
28
|
+
- MIT
|
|
29
|
+
metadata:
|
|
30
|
+
homepage_uri: https://bjsmenus.com/
|
|
31
|
+
source_code_uri: https://github.com/nbkdevs/bjs-menu/tree/main/packages/rubygems
|
|
32
|
+
bug_tracker_uri: https://github.com/nbkdevs/bjs-menu/issues
|
|
33
|
+
rubygems_mfa_required: 'true'
|
|
34
|
+
rdoc_options: []
|
|
35
|
+
require_paths:
|
|
36
|
+
- lib
|
|
37
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
38
|
+
requirements:
|
|
39
|
+
- - ">="
|
|
40
|
+
- !ruby/object:Gem::Version
|
|
41
|
+
version: 3.0.0
|
|
42
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - ">="
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '0'
|
|
47
|
+
requirements: []
|
|
48
|
+
rubygems_version: 4.0.20
|
|
49
|
+
specification_version: 4
|
|
50
|
+
summary: 'Offline BJ''s Restaurant meal builder: nutrition totals, missing-value flags
|
|
51
|
+
and allergen filters.'
|
|
52
|
+
test_files: []
|