<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://recipedius.com/index.php?action=history&amp;feed=atom&amp;title=Module%3ARecipedius</id>
	<title>Module:Recipedius - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://recipedius.com/index.php?action=history&amp;feed=atom&amp;title=Module%3ARecipedius"/>
	<link rel="alternate" type="text/html" href="https://recipedius.com/index.php?title=Module:Recipedius&amp;action=history"/>
	<updated>2026-11-02T20:06:05Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.11</generator>
	<entry>
		<id>https://recipedius.com/index.php?title=Module:Recipedius&amp;diff=140&amp;oldid=prev</id>
		<title>Recipedius deploy: 0.015 T013: target missing ingredients and canonicalize fractions (1b80afc)</title>
		<link rel="alternate" type="text/html" href="https://recipedius.com/index.php?title=Module:Recipedius&amp;diff=140&amp;oldid=prev"/>
		<updated>2026-09-25T14:04:05Z</updated>

		<summary type="html">&lt;p&gt;0.015 T013: target missing ingredients and canonicalize fractions (1b80afc)&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 14:04, 25 September 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l16&quot;&gt;Line 16:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 16:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;local FRACTIONS = {&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;local FRACTIONS = {&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   { 0.125, &#039;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;⅛&lt;/del&gt;&#039; }, { 0.25, &#039;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;¼&lt;/del&gt;&#039; }, { 1/3, &#039;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;⅓&lt;/del&gt;&#039; }, { 0.375, &#039;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;⅜&lt;/del&gt;&#039; }, { 0.5, &#039;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;½&lt;/del&gt;&#039; },&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   { 0.125, &#039;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;1/8&lt;/ins&gt;&#039; }, { 0.25, &#039;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;1/4&lt;/ins&gt;&#039; }, { 1/3, &#039;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;1/3&lt;/ins&gt;&#039; }, { 0.375, &#039;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;3/8&lt;/ins&gt;&#039; }, { 0.5, &#039;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;1/2&lt;/ins&gt;&#039; },&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   { 0.625, &#039;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;⅝&lt;/del&gt;&#039; }, { 2/3, &#039;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;⅔&lt;/del&gt;&#039; }, { 0.75, &#039;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;¾&lt;/del&gt;&#039; }, { 0.875, &#039;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;⅞&lt;/del&gt;&#039; },&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   { 0.625, &#039;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;5/8&lt;/ins&gt;&#039; }, { 2/3, &#039;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;2/3&lt;/ins&gt;&#039; }, { 0.75, &#039;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;3/4&lt;/ins&gt;&#039; }, { 0.875, &#039;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;7/8&lt;/ins&gt;&#039; },&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;}&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;}&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;local FRACTION_CHARS = { [&amp;#039;⅛&amp;#039;]=0.125, [&amp;#039;¼&amp;#039;]=0.25, [&amp;#039;⅓&amp;#039;]=1/3, [&amp;#039;⅜&amp;#039;]=0.375, [&amp;#039;½&amp;#039;]=0.5, [&amp;#039;⅝&amp;#039;]=0.625, [&amp;#039;⅔&amp;#039;]=2/3, [&amp;#039;¾&amp;#039;]=0.75, [&amp;#039;⅞&amp;#039;]=0.875 }&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;local FRACTION_CHARS = { [&amp;#039;⅛&amp;#039;]=0.125, [&amp;#039;¼&amp;#039;]=0.25, [&amp;#039;⅓&amp;#039;]=1/3, [&amp;#039;⅜&amp;#039;]=0.375, [&amp;#039;½&amp;#039;]=0.5, [&amp;#039;⅝&amp;#039;]=0.625, [&amp;#039;⅔&amp;#039;]=2/3, [&amp;#039;¾&amp;#039;]=0.75, [&amp;#039;⅞&amp;#039;]=0.875 }&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l31&quot;&gt;Line 31:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 31:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   local linked = s:match(&amp;#039;^%[%[([^%[%]|]+)%]%]$&amp;#039;)&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   local linked = s:match(&amp;#039;^%[%[([^%[%]|]+)%]%]$&amp;#039;)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   return linked and trim(linked) or s&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   return linked and trim(linked) or s&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;end&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;-- A missing ingredient must open its pre-targeted Page Forms editor, not&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;-- MediaWiki&#039;s generic raw editor. mw.title normalizes and encodes the target.&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;local function ingredientFormLink(name, label)&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;  local target = mw.title.new(&#039;Special:FormEdit/Ingredient/&#039; .. name)&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;  if not target then return mw.text.nowiki(label) end&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;  return &#039;[&#039; .. target:fullUrl() .. &#039; &#039; .. mw.text.nowiki(label) .. &#039;]&#039;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;end&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;end&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l254&quot;&gt;Line 254:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 262:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     local createLinks = {}&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     local createLinks = {}&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     for _, name in ipairs(missing) do&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     for _, name in ipairs(missing) do&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;       table.insert(createLinks, &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&#039;[[Special:FormEdit/Ingredient/&#039; .. &lt;/del&gt;name &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;.. &#039;|&#039; .. &lt;/del&gt;name &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;.. &#039;]]&#039;&lt;/del&gt;)&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;       table.insert(createLinks, &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;ingredientFormLink(&lt;/ins&gt;name&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;, &lt;/ins&gt;name&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;)&lt;/ins&gt;)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     end&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     end&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     add(&amp;#039;&amp;lt;div class=&amp;quot;rp-missing&amp;quot;&amp;gt;These ingredients have no record yet, so they are left out of the nutrition and substitution tables: &amp;#039; ..&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     add(&amp;#039;&amp;lt;div class=&amp;quot;rp-missing&amp;quot;&amp;gt;These ingredients have no record yet, so they are left out of the nutrition and substitution tables: &amp;#039; ..&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l268&quot;&gt;Line 268:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 276:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     local shown = countLabel(l.name, l.qty, l.unit)&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     local shown = countLabel(l.name, l.qty, l.unit)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     local isRecipe = not ing and getRecipe(l.name)&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     local isRecipe = not ing and getRecipe(l.name)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     local link = (ing or isRecipe) and (&#039;[[&#039; .. l.name .. &#039;|&#039; .. shown .. &#039;]]&#039;) or (&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&#039;[[&#039; .. &lt;/del&gt;l.name &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;.. &#039;|&#039; .. &lt;/del&gt;shown .. &#039;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;]]&lt;/del&gt;&amp;lt;sup class=&quot;rp-missing-mark&quot;&amp;gt;?&amp;lt;/sup&amp;gt;&#039;)&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     local link = (ing or isRecipe) and (&#039;[[&#039; .. l.name .. &#039;|&#039; .. shown .. &#039;]]&#039;) or&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;      (ingredientFormLink&lt;/ins&gt;(l.name&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;, &lt;/ins&gt;shown&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;) &lt;/ins&gt;.. &#039;&amp;lt;sup class=&quot;rp-missing-mark&quot;&amp;gt;?&amp;lt;/sup&amp;gt;&#039;)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     local qty = fmtQty(l.qty) .. &amp;#039; &amp;#039; .. unitLabel(l.qty, l.unit)&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     local qty = fmtQty(l.qty) .. &amp;#039; &amp;#039; .. unitLabel(l.qty, l.unit)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     local prep = l.prep ~= &amp;#039;&amp;#039; and (&amp;#039;, &amp;lt;span class=&amp;quot;rp-prep&amp;quot;&amp;gt;&amp;#039; .. l.prep .. &amp;#039;&amp;lt;/span&amp;gt;&amp;#039;) or &amp;#039;&amp;#039;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     local prep = l.prep ~= &amp;#039;&amp;#039; and (&amp;#039;, &amp;lt;span class=&amp;quot;rp-prep&amp;quot;&amp;gt;&amp;#039; .. l.prep .. &amp;#039;&amp;lt;/span&amp;gt;&amp;#039;) or &amp;#039;&amp;#039;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Recipedius deploy</name></author>
	</entry>
	<entry>
		<id>https://recipedius.com/index.php?title=Module:Recipedius&amp;diff=136&amp;oldid=prev</id>
		<title>Recipedius deploy: 0.014 T014: deploy AI-assisted Recipe import (e0496d8)</title>
		<link rel="alternate" type="text/html" href="https://recipedius.com/index.php?title=Module:Recipedius&amp;diff=136&amp;oldid=prev"/>
		<updated>2026-09-25T12:55:48Z</updated>

		<summary type="html">&lt;p&gt;0.014 T014: deploy AI-assisted Recipe import (e0496d8)&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 12:55, 25 September 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l22&quot;&gt;Line 22:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 22:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;local function trim(s) return mw.text.trim(s or &amp;#039;&amp;#039;) end&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;local function trim(s) return mw.text.trim(s or &amp;#039;&amp;#039;) end&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;-- AI-assisted recipe imports persist ingredient titles as ordinary wiki links&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;-- so the form value itself remains navigable. Keep the existing plain-title&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;-- format compatible, while resolving that narrow importer-owned syntax before&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;-- data lookup, Cargo storage, pluralization, and generated display links.&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;local function ingredientTitle(s)&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;  s = trim(s)&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;  local linked = s:match(&#039;^%[%[([^%[%]|]+)%]%]$&#039;)&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;  return linked and trim(linked) or s&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;end&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;-- &amp;quot;1 1/2&amp;quot;, &amp;quot;3/4&amp;quot;, &amp;quot;0.5&amp;quot;, &amp;quot;1 ½&amp;quot; and &amp;quot;¾&amp;quot; all parse.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;-- &amp;quot;1 1/2&amp;quot;, &amp;quot;3/4&amp;quot;, &amp;quot;0.5&amp;quot;, &amp;quot;1 ½&amp;quot; and &amp;quot;¾&amp;quot; all parse.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l165&quot;&gt;Line 165:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 175:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     if raw ~= &amp;#039;&amp;#039; and not raw:match(&amp;#039;^&amp;lt;!%-%-&amp;#039;) then&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     if raw ~= &amp;#039;&amp;#039; and not raw:match(&amp;#039;^&amp;lt;!%-%-&amp;#039;) then&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;       local parts = mw.text.split(raw, &amp;#039;;&amp;#039;, true)&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;       local parts = mw.text.split(raw, &amp;#039;;&amp;#039;, true)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;       local name = &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;trim&lt;/del&gt;(parts[1] or &#039;&#039;)&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;       local name = &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;ingredientTitle&lt;/ins&gt;(parts[1] or &#039;&#039;)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;       if name ~= &amp;#039;&amp;#039; then&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;       if name ~= &amp;#039;&amp;#039; then&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         table.insert(lines, {&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         table.insert(lines, {&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Recipedius deploy</name></author>
	</entry>
	<entry>
		<id>https://recipedius.com/index.php?title=Module:Recipedius&amp;diff=123&amp;oldid=prev</id>
		<title>Recipedius deploy: 0.012 T009: deploy working form entry points (6e8250e)</title>
		<link rel="alternate" type="text/html" href="https://recipedius.com/index.php?title=Module:Recipedius&amp;diff=123&amp;oldid=prev"/>
		<updated>2026-09-24T13:37:03Z</updated>

		<summary type="html">&lt;p&gt;0.012 T009: deploy working form entry points (6e8250e)&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 13:37, 24 September 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l238&quot;&gt;Line 238:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 238:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   if #missing &amp;gt; 0 then&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   if #missing &amp;gt; 0 then&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    -- Each name links to the ingredient form already targeted at that title, so&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    -- a contributor lands on the right form rather than being asked for a name&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    -- the page already knows. A bare Special:FormEdit link has no target and&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    -- answers &quot;No target page specified&quot;.&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    local createLinks = {}&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    for _, name in ipairs(missing) do&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;      table.insert(createLinks, &#039;[[Special:FormEdit/Ingredient/&#039; .. name .. &#039;|&#039; .. name .. &#039;]]&#039;)&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    end&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     add(&amp;#039;&amp;lt;div class=&amp;quot;rp-missing&amp;quot;&amp;gt;These ingredients have no record yet, so they are left out of the nutrition and substitution tables: &amp;#039; ..&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     add(&amp;#039;&amp;lt;div class=&amp;quot;rp-missing&amp;quot;&amp;gt;These ingredients have no record yet, so they are left out of the nutrition and substitution tables: &amp;#039; ..&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;       table.concat(&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;missing&lt;/del&gt;, &#039;, &#039;) .. &#039;. &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;[[Special:FormEdit/Ingredient|Create one]]&lt;/del&gt;.&amp;lt;/div&amp;gt;&#039;)&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;       table.concat(&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;createLinks&lt;/ins&gt;, &#039;, &#039;) .. &#039;. &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Follow a name to create its record&lt;/ins&gt;.&amp;lt;/div&amp;gt;&#039;)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   end&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   end&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Recipedius deploy</name></author>
	</entry>
	<entry>
		<id>https://recipedius.com/index.php?title=Module:Recipedius&amp;diff=95&amp;oldid=prev</id>
		<title>Recipedius deploy: Protected &quot;Module:Recipedius&quot;: 0.010 T017: configuration page, deployed from version control ([Edit=Allow only administrators] (indefinite) [Move=Allow only administrators] (indefinite))</title>
		<link rel="alternate" type="text/html" href="https://recipedius.com/index.php?title=Module:Recipedius&amp;diff=95&amp;oldid=prev"/>
		<updated>2026-09-23T19:28:23Z</updated>

		<summary type="html">&lt;p&gt;Protected &amp;quot;&lt;a href=&quot;/index.php/Module:Recipedius&quot; title=&quot;Module:Recipedius&quot;&gt;Module:Recipedius&lt;/a&gt;&amp;quot;: 0.010 T017: configuration page, deployed from version control ([Edit=Allow only administrators] (indefinite) [Move=Allow only administrators] (indefinite))&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 19:28, 23 September 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Recipedius deploy</name></author>
	</entry>
	<entry>
		<id>https://recipedius.com/index.php?title=Module:Recipedius&amp;diff=79&amp;oldid=prev</id>
		<title>Recipedius deploy: 0.010 T016: deploy 0.009 recipe and ingredient contract, 0.007 techniques, and template sandboxes (dbbad33)</title>
		<link rel="alternate" type="text/html" href="https://recipedius.com/index.php?title=Module:Recipedius&amp;diff=79&amp;oldid=prev"/>
		<updated>2026-09-23T19:25:43Z</updated>

		<summary type="html">&lt;p&gt;0.010 T016: deploy 0.009 recipe and ingredient contract, 0.007 techniques, and template sandboxes (dbbad33)&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 19:25, 23 September 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l95&quot;&gt;Line 95:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 95:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     { where = &amp;quot;_pageName=&amp;#039;&amp;quot; .. sqlEsc(name) .. &amp;quot;&amp;#039;&amp;quot;, limit = 1 })&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     { where = &amp;quot;_pageName=&amp;#039;&amp;quot; .. sqlEsc(name) .. &amp;quot;&amp;#039;&amp;quot;, limit = 1 })&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   ingredientCache[name] = rows[1] or false&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   ingredientCache[name] = rows[1] or false&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;  return rows[1]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;end&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;local recipeCache = {}&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;local function getRecipe(name)&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;  if recipeCache[name] ~= nil then return recipeCache[name] or nil end&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;  local rows = cargo.query(&#039;Recipes&#039;, &#039;_pageName=name&#039;,&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    { where = &quot;_pageName=&#039;&quot; .. sqlEsc(name) .. &quot;&#039;&quot;, limit = 1 })&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;  recipeCache[name] = rows[1] or false&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   return rows[1]&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   return rows[1]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;end&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;end&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l169&quot;&gt;Line 169:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 178:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   end&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   end&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   return lines&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   return lines&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;end&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;local function resolvedArg(args, preferred, legacy)&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;  local value = trim(args[preferred])&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;  if value ~= &#039;&#039; then return value end&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;  return trim(args[legacy])&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;end&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;end&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l182&quot;&gt;Line 182:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 197:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   local page = title.prefixedText&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   local page = title.prefixedText&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   local serves = tonumber(args.serves) or 1&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   local serves = tonumber(args.serves) or 1&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;  local description = resolvedArg(args, &#039;description&#039;, &#039;lede&#039;)&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;  local instructions = resolvedArg(args, &#039;instructions&#039;, &#039;method&#039;)&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   local lines = parseLines(args.ingredients)&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   local lines = parseLines(args.ingredients)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l193&quot;&gt;Line 193:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 210:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         if not seen[a] then seen[a] = true; table.insert(allergens, a) end&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         if not seen[a] then seen[a] = true; table.insert(allergens, a) end&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;       end&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;       end&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;else&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;elseif not getRecipe(l.name) then&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;       table.insert(missing, l.name)&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;       table.insert(missing, l.name)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     end&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     end&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l216&quot;&gt;Line 216:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 233:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   add(&amp;#039;|}&amp;#039;)&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   add(&amp;#039;|}&amp;#039;)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;if trim&lt;/del&gt;(&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;args.lede&lt;/del&gt;) ~= &#039;&#039; then add(&quot;&amp;lt;div class=\&quot;rp-lede\&quot;&amp;gt;&#039;&#039;&quot; .. &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;trim(args.lede) &lt;/del&gt;.. &quot;&#039;&#039;&amp;lt;/div&amp;gt;&quot;) end&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;add&lt;/ins&gt;(&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&#039;== Description ==&#039;&lt;/ins&gt;)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;  if description &lt;/ins&gt;~= &#039;&#039; then add(&quot;&amp;lt;div class=\&quot;rp-lede\&quot;&amp;gt;&#039;&#039;&quot; .. &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;description &lt;/ins&gt;.. &quot;&#039;&#039;&amp;lt;/div&amp;gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&quot;)&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;  else add(&quot;&#039;&#039;No description yet.&#039;&#039;&lt;/ins&gt;&quot;) end&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   if #missing &amp;gt; 0 then&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   if #missing &amp;gt; 0 then&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l230&quot;&gt;Line 230:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 249:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     local ing = getIngredient(l.name)&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     local ing = getIngredient(l.name)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     local shown = countLabel(l.name, l.qty, l.unit)&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     local shown = countLabel(l.name, l.qty, l.unit)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     local link = ing and (&#039;[[&#039; .. l.name .. &#039;|&#039; .. shown .. &#039;]]&#039;) or (&#039;[[&#039; .. l.name .. &#039;|&#039; .. shown .. &#039;]]&amp;lt;sup class=&quot;rp-missing-mark&quot;&amp;gt;?&amp;lt;/sup&amp;gt;&#039;)&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    local isRecipe = not ing and getRecipe(l.name)&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     local link = &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;(&lt;/ins&gt;ing &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;or isRecipe) &lt;/ins&gt;and (&#039;[[&#039; .. l.name .. &#039;|&#039; .. shown .. &#039;]]&#039;) or (&#039;[[&#039; .. l.name .. &#039;|&#039; .. shown .. &#039;]]&amp;lt;sup class=&quot;rp-missing-mark&quot;&amp;gt;?&amp;lt;/sup&amp;gt;&#039;)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     local qty = fmtQty(l.qty) .. &amp;#039; &amp;#039; .. unitLabel(l.qty, l.unit)&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     local qty = fmtQty(l.qty) .. &amp;#039; &amp;#039; .. unitLabel(l.qty, l.unit)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     local prep = l.prep ~= &amp;#039;&amp;#039; and (&amp;#039;, &amp;lt;span class=&amp;quot;rp-prep&amp;quot;&amp;gt;&amp;#039; .. l.prep .. &amp;#039;&amp;lt;/span&amp;gt;&amp;#039;) or &amp;#039;&amp;#039;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     local prep = l.prep ~= &amp;#039;&amp;#039; and (&amp;#039;, &amp;lt;span class=&amp;quot;rp-prep&amp;quot;&amp;gt;&amp;#039; .. l.prep .. &amp;#039;&amp;lt;/span&amp;gt;&amp;#039;) or &amp;#039;&amp;#039;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l243&quot;&gt;Line 243:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 263:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   add(&amp;#039;|}&amp;#039;)&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   add(&amp;#039;|}&amp;#039;)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;-- method&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;add(&#039;== Instructions ==&#039;)&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   if &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;trim(args.method) &lt;/del&gt;~= &#039;&#039; then&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   if &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;instructions &lt;/ins&gt;~= &#039;&#039; then add(&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;instructions&lt;/ins&gt;)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    &lt;/del&gt;add(&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&#039;== Method ==&#039;&lt;/del&gt;)&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;  else &lt;/ins&gt;add(&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&quot;&#039;&#039;No instructions yet&lt;/ins&gt;.&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&#039;&#039;&quot;&lt;/ins&gt;) end&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    &lt;/del&gt;add(&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;trim(args&lt;/del&gt;.&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;method&lt;/del&gt;)&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;)&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;  &lt;/del&gt;end&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   -- substitutions resolved for this recipe&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   -- substitutions resolved for this recipe&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l283&quot;&gt;Line 283:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 301:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     frame:callParserFunction(&amp;#039;#cargo_store&amp;#039;, {&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     frame:callParserFunction(&amp;#039;#cargo_store&amp;#039;, {&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;       &amp;#039;_table=Recipes&amp;#039;, serves = tostring(serves), time = trim(args.time), tags = trim(args.tags),&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;       &amp;#039;_table=Recipes&amp;#039;, serves = tostring(serves), time = trim(args.time), tags = trim(args.tags),&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;       contributor = trim(args.contributor), lede = &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;trim(args.lede)&lt;/del&gt;, method = &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;trim(args.method)&lt;/del&gt;,&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;       contributor = trim(args.contributor), lede = &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;description&lt;/ins&gt;, method = &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;instructions&lt;/ins&gt;,&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;       kcal_total = tostring(round(kcalTotal)), allergens = table.concat(allergens, &amp;#039;,&amp;#039;), ingredient_count = tostring(#lines),&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;       kcal_total = tostring(round(kcalTotal)), allergens = table.concat(allergens, &amp;#039;,&amp;#039;), ingredient_count = tostring(#lines),&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     })&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     })&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   end&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   end&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   local cats = { &#039;[[Category:Recipes]]&#039; }&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;-- Categories belong to real recipe pages. Without this guard a /testcases&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;  &lt;/del&gt;for _, t in ipairs(splitList(args.tags)) do table.insert(cats, &#039;[[Category:&#039; .. t .. &#039;]]&#039;) end&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;  -- page that exercises the template would file itself under Category:Recipes&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;  &lt;/del&gt;add(table.concat(cats, &#039;&#039;))&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;  -- and every tag category it demonstrates.&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;  if title.namespace == 0 then&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    &lt;/ins&gt;local cats = { &#039;[[Category:Recipes]]&#039; }&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    &lt;/ins&gt;for _, t in ipairs(splitList(args.tags)) do table.insert(cats, &#039;[[Category:&#039; .. t .. &#039;]]&#039;) end&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    &lt;/ins&gt;add(table.concat(cats, &#039;&#039;))&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;  end&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   return table.concat(out, &amp;#039;\n&amp;#039;)&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   return table.concat(out, &amp;#039;\n&amp;#039;)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;end&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;end&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Recipedius deploy</name></author>
	</entry>
	<entry>
		<id>https://recipedius.com/index.php?title=Module:Recipedius&amp;diff=3&amp;oldid=prev</id>
		<title>Janine: Recipedius seed</title>
		<link rel="alternate" type="text/html" href="https://recipedius.com/index.php?title=Module:Recipedius&amp;diff=3&amp;oldid=prev"/>
		<updated>2026-09-09T19:58:45Z</updated>

		<summary type="html">&lt;p&gt;Recipedius seed&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;--[[&lt;br /&gt;
  Module:Recipedius&lt;br /&gt;
  The computed layer of Recipedius. Reads ingredient records and substitution rules&lt;br /&gt;
  from Cargo tables and renders recipe pages, the weekly sale ranking, and cookbooks.&lt;br /&gt;
&lt;br /&gt;
  Entry points (all via {{#invoke:Recipedius|fn}} from templates):&lt;br /&gt;
    recipe    - renders a recipe from Template:Recipe args and stores its rows&lt;br /&gt;
    sale      - ranks recipes by how many of their shopping items are on sale&lt;br /&gt;
    cookbook  - renders a printable book from a list of recipe pages&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
local cargo = mw.ext.cargo&lt;br /&gt;
&lt;br /&gt;
-- ---------------------------------------------------------------- helpers&lt;br /&gt;
&lt;br /&gt;
local FRACTIONS = {&lt;br /&gt;
  { 0.125, &amp;#039;⅛&amp;#039; }, { 0.25, &amp;#039;¼&amp;#039; }, { 1/3, &amp;#039;⅓&amp;#039; }, { 0.375, &amp;#039;⅜&amp;#039; }, { 0.5, &amp;#039;½&amp;#039; },&lt;br /&gt;
  { 0.625, &amp;#039;⅝&amp;#039; }, { 2/3, &amp;#039;⅔&amp;#039; }, { 0.75, &amp;#039;¾&amp;#039; }, { 0.875, &amp;#039;⅞&amp;#039; },&lt;br /&gt;
}&lt;br /&gt;
local FRACTION_CHARS = { [&amp;#039;⅛&amp;#039;]=0.125, [&amp;#039;¼&amp;#039;]=0.25, [&amp;#039;⅓&amp;#039;]=1/3, [&amp;#039;⅜&amp;#039;]=0.375, [&amp;#039;½&amp;#039;]=0.5, [&amp;#039;⅝&amp;#039;]=0.625, [&amp;#039;⅔&amp;#039;]=2/3, [&amp;#039;¾&amp;#039;]=0.75, [&amp;#039;⅞&amp;#039;]=0.875 }&lt;br /&gt;
&lt;br /&gt;
local function trim(s) return mw.text.trim(s or &amp;#039;&amp;#039;) end&lt;br /&gt;
&lt;br /&gt;
-- &amp;quot;1 1/2&amp;quot;, &amp;quot;3/4&amp;quot;, &amp;quot;0.5&amp;quot;, &amp;quot;1 ½&amp;quot; and &amp;quot;¾&amp;quot; all parse.&lt;br /&gt;
local function parseQty(s)&lt;br /&gt;
  s = trim(s)&lt;br /&gt;
  local total, found = 0, false&lt;br /&gt;
  for tok in s:gmatch(&amp;#039;%S+&amp;#039;) do&lt;br /&gt;
    if FRACTION_CHARS[tok] then total = total + FRACTION_CHARS[tok]; found = true&lt;br /&gt;
    else&lt;br /&gt;
      local a, b = tok:match(&amp;#039;^(%d+)/(%d+)$&amp;#039;)&lt;br /&gt;
      if a then total = total + tonumber(a) / tonumber(b); found = true&lt;br /&gt;
      elseif tonumber(tok) then total = total + tonumber(tok); found = true end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  if found then return total end&lt;br /&gt;
  return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function fmtQty(q)&lt;br /&gt;
  if not q then return &amp;#039;&amp;#039; end&lt;br /&gt;
  local w = math.floor(q + 1e-6)&lt;br /&gt;
  local f = q - w&lt;br /&gt;
  if f &amp;gt; 0.94 then w = w + 1; f = 0 end&lt;br /&gt;
  local fs = &amp;#039;&amp;#039;&lt;br /&gt;
  if f &amp;gt; 0.06 then&lt;br /&gt;
    local best, bd = nil, 1&lt;br /&gt;
    for _, pair in ipairs(FRACTIONS) do&lt;br /&gt;
      local d = math.abs(pair[1] - f)&lt;br /&gt;
      if d &amp;lt; bd then bd = d; best = pair[2] end&lt;br /&gt;
    end&lt;br /&gt;
    if bd &amp;lt; 0.06 then fs = best else fs = string.format(&amp;#039;%.2f&amp;#039;, f):gsub(&amp;#039;^0&amp;#039;, &amp;#039;&amp;#039;) end&lt;br /&gt;
  end&lt;br /&gt;
  if w == 0 then return fs ~= &amp;#039;&amp;#039; and fs or &amp;#039;0&amp;#039; end&lt;br /&gt;
  if fs ~= &amp;#039;&amp;#039; then return w .. &amp;#039; &amp;#039; .. fs end&lt;br /&gt;
  return tostring(w)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local PLURALS = { [&amp;#039;Garlic&amp;#039;] = &amp;#039;Garlic cloves&amp;#039;, [&amp;#039;Whole chicken&amp;#039;] = &amp;#039;Whole chickens&amp;#039;, [&amp;#039;Russet potato&amp;#039;] = &amp;#039;Russet potatoes&amp;#039; }&lt;br /&gt;
-- Display name for a count-based ingredient: &amp;quot;2 eggs&amp;quot;, &amp;quot;3 bananas&amp;quot;, &amp;quot;6 garlic cloves&amp;quot;.&lt;br /&gt;
local function countLabel(name, q, u)&lt;br /&gt;
  if u ~= &amp;#039;each&amp;#039; or not q or q &amp;lt;= 1 then return name end&lt;br /&gt;
  if PLURALS[name] then return PLURALS[name] end&lt;br /&gt;
  if name:sub(-1) == &amp;#039;s&amp;#039; then return name end&lt;br /&gt;
  return name .. &amp;#039;s&amp;#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function unitLabel(q, u)&lt;br /&gt;
  if u == &amp;#039;each&amp;#039; or u == &amp;#039;&amp;#039; then return &amp;#039;&amp;#039; end&lt;br /&gt;
  if u == &amp;#039;cup&amp;#039; and q and q &amp;gt; 1 then return &amp;#039;cups&amp;#039; end&lt;br /&gt;
  return u&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function sqlEsc(s) return (tostring(s):gsub(&amp;quot;&amp;#039;&amp;quot;, &amp;quot;\\&amp;#039;&amp;quot;)) end&lt;br /&gt;
&lt;br /&gt;
local function splitList(s)&lt;br /&gt;
  local out = {}&lt;br /&gt;
  for item in (s or &amp;#039;&amp;#039;):gmatch(&amp;#039;[^,]+&amp;#039;) do&lt;br /&gt;
    item = trim(item)&lt;br /&gt;
    if item ~= &amp;#039;&amp;#039; then table.insert(out, item) end&lt;br /&gt;
  end&lt;br /&gt;
  return out&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function round(x) return math.floor(x + 0.5) end&lt;br /&gt;
&lt;br /&gt;
-- ---------------------------------------------------------------- data access&lt;br /&gt;
&lt;br /&gt;
local ingredientCache = {}&lt;br /&gt;
local function getIngredient(name)&lt;br /&gt;
  if ingredientCache[name] ~= nil then return ingredientCache[name] or nil end&lt;br /&gt;
  local rows = cargo.query(&amp;#039;Ingredients&amp;#039;,&lt;br /&gt;
    &amp;#039;_pageName=name,kcal100,g_tsp,g_tbsp,g_cup,g_each,allergens,pantry,price,price_per&amp;#039;,&lt;br /&gt;
    { where = &amp;quot;_pageName=&amp;#039;&amp;quot; .. sqlEsc(name) .. &amp;quot;&amp;#039;&amp;quot;, limit = 1 })&lt;br /&gt;
  ingredientCache[name] = rows[1] or false&lt;br /&gt;
  return rows[1]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function gramsPer(ing, unit)&lt;br /&gt;
  if not ing then return nil end&lt;br /&gt;
  local key = ({ tsp = &amp;#039;g_tsp&amp;#039;, tbsp = &amp;#039;g_tbsp&amp;#039;, cup = &amp;#039;g_cup&amp;#039;, each = &amp;#039;g_each&amp;#039; })[unit]&lt;br /&gt;
  if not key then return nil end&lt;br /&gt;
  return tonumber(ing[key])&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function kcalOf(ing, q, unit)&lt;br /&gt;
  local g = gramsPer(ing, unit)&lt;br /&gt;
  local k = ing and tonumber(ing.kcal100)&lt;br /&gt;
  if not (g and k and q) then return 0 end&lt;br /&gt;
  return q * g * k / 100&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Substitution rules for an ingredient, resolved for the role it plays in this recipe.&lt;br /&gt;
-- A base row (role blank) applies everywhere; a row with a role overrides the base for that role.&lt;br /&gt;
-- An override with applicable=no removes the option for that role.&lt;br /&gt;
local subsCache = {}&lt;br /&gt;
local function rulesFor(name, role)&lt;br /&gt;
  if not subsCache[name] then&lt;br /&gt;
    subsCache[name] = cargo.query(&amp;#039;Substitutions&amp;#039;,&lt;br /&gt;
      &amp;#039;sub_to,alt,role,ratio,conv,confidence,effect,warning,applicable&amp;#039;,&lt;br /&gt;
      { where = &amp;quot;sub_from=&amp;#039;&amp;quot; .. sqlEsc(name) .. &amp;quot;&amp;#039;&amp;quot;, orderBy = &amp;#039;sub_to&amp;#039;, limit = 200 })&lt;br /&gt;
  end&lt;br /&gt;
  local groups, order = {}, {}&lt;br /&gt;
  for _, r in ipairs(subsCache[name]) do&lt;br /&gt;
    local key = (r.sub_to or &amp;#039;&amp;#039;) .. &amp;#039;|&amp;#039; .. (r.alt or &amp;#039;&amp;#039;)&lt;br /&gt;
    if not groups[key] then groups[key] = {}; table.insert(order, key) end&lt;br /&gt;
    if trim(r.role) == &amp;#039;&amp;#039; then groups[key].base = r&lt;br /&gt;
    elseif trim(r.role) == role then groups[key].override = r end&lt;br /&gt;
  end&lt;br /&gt;
  local out = {}&lt;br /&gt;
  for _, key in ipairs(order) do&lt;br /&gt;
    local b, o = groups[key].base, groups[key].override&lt;br /&gt;
    local blocked = o and trim(o.applicable):lower() == &amp;#039;no&amp;#039;&lt;br /&gt;
    if (b or o) and not blocked then&lt;br /&gt;
      local m = {}&lt;br /&gt;
      for _, k in ipairs({ &amp;#039;sub_to&amp;#039;, &amp;#039;alt&amp;#039;, &amp;#039;ratio&amp;#039;, &amp;#039;conv&amp;#039;, &amp;#039;confidence&amp;#039;, &amp;#039;effect&amp;#039;, &amp;#039;warning&amp;#039; }) do&lt;br /&gt;
        local ov = o and trim(o[k]) or &amp;#039;&amp;#039;&lt;br /&gt;
        if ov ~= &amp;#039;&amp;#039; then m[k] = ov elseif b then m[k] = trim(b[k]) else m[k] = &amp;#039;&amp;#039; end&lt;br /&gt;
      end&lt;br /&gt;
      if m.warning == &amp;#039;none&amp;#039; then m.warning = &amp;#039;&amp;#039; end&lt;br /&gt;
      m.roleSpecific = o ~= nil&lt;br /&gt;
      table.insert(out, m)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  return out&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- ---------------------------------------------------------------- recipe&lt;br /&gt;
&lt;br /&gt;
-- Ingredient lines are written one per line as:  Ingredient; quantity; unit; role; preparation&lt;br /&gt;
local function parseLines(text)&lt;br /&gt;
  local lines = {}&lt;br /&gt;
  for raw in (text or &amp;#039;&amp;#039;):gmatch(&amp;#039;[^\r\n]+&amp;#039;) do&lt;br /&gt;
    raw = trim(raw)&lt;br /&gt;
    if raw ~= &amp;#039;&amp;#039; and not raw:match(&amp;#039;^&amp;lt;!%-%-&amp;#039;) then&lt;br /&gt;
      local parts = mw.text.split(raw, &amp;#039;;&amp;#039;, true)&lt;br /&gt;
      local name = trim(parts[1] or &amp;#039;&amp;#039;)&lt;br /&gt;
      if name ~= &amp;#039;&amp;#039; then&lt;br /&gt;
        table.insert(lines, {&lt;br /&gt;
          name = name,&lt;br /&gt;
          qty = parseQty(parts[2] or &amp;#039;&amp;#039;),&lt;br /&gt;
          unit = trim(parts[3] or &amp;#039;&amp;#039;),&lt;br /&gt;
          role = trim(parts[4] or &amp;#039;&amp;#039;),&lt;br /&gt;
          prep = trim(parts[5] or &amp;#039;&amp;#039;),&lt;br /&gt;
        })&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  return lines&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local CONF_DOTS = { high = &amp;#039;●●●&amp;#039;, medium = &amp;#039;●●○&amp;#039;, low = &amp;#039;●○○&amp;#039; }&lt;br /&gt;
local function confBadge(c)&lt;br /&gt;
  c = trim(c):lower()&lt;br /&gt;
  return &amp;#039;&amp;lt;span class=&amp;quot;rp-conf rp-conf-&amp;#039; .. c .. &amp;#039;&amp;quot; title=&amp;quot;confidence: &amp;#039; .. c .. &amp;#039;&amp;quot;&amp;gt;&amp;#039; .. (CONF_DOTS[c] or &amp;#039;○○○&amp;#039;) .. &amp;#039; &amp;#039; .. c .. &amp;#039;&amp;lt;/span&amp;gt;&amp;#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.recipe(frame)&lt;br /&gt;
  local args = frame:getParent().args&lt;br /&gt;
  local title = mw.title.getCurrentTitle()&lt;br /&gt;
  local page = title.prefixedText&lt;br /&gt;
  local serves = tonumber(args.serves) or 1&lt;br /&gt;
  local lines = parseLines(args.ingredients)&lt;br /&gt;
&lt;br /&gt;
  -- totals from the ingredient records&lt;br /&gt;
  local kcalTotal, allergens, seen, missing = 0, {}, {}, {}&lt;br /&gt;
  for _, l in ipairs(lines) do&lt;br /&gt;
    local ing = getIngredient(l.name)&lt;br /&gt;
    if ing then&lt;br /&gt;
      kcalTotal = kcalTotal + kcalOf(ing, l.qty, l.unit)&lt;br /&gt;
      for _, a in ipairs(splitList(ing.allergens)) do&lt;br /&gt;
        if not seen[a] then seen[a] = true; table.insert(allergens, a) end&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      table.insert(missing, l.name)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  local out = {}&lt;br /&gt;
  local function add(s) table.insert(out, s) end&lt;br /&gt;
&lt;br /&gt;
  -- infobox&lt;br /&gt;
  add(&amp;#039;{| class=&amp;quot;wikitable rp-infobox&amp;quot;\n|+ &amp;#039; .. page)&lt;br /&gt;
  add(&amp;#039;|-\n! Serves\n| &amp;#039; .. serves)&lt;br /&gt;
  if trim(args.time) ~= &amp;#039;&amp;#039; then add(&amp;#039;|-\n! Time\n| &amp;#039; .. trim(args.time)) end&lt;br /&gt;
  add(&amp;#039;|-\n! Per serving\n| &amp;lt;b&amp;gt;&amp;#039; .. round(kcalTotal / serves) .. &amp;#039; kcal&amp;lt;/b&amp;gt; &amp;lt;small&amp;gt;(&amp;#039; .. round(kcalTotal) .. &amp;#039; for the batch)&amp;lt;/small&amp;gt;&amp;#039;)&lt;br /&gt;
  add(&amp;#039;|-\n! Contains\n| &amp;#039; .. (#allergens &amp;gt; 0 and table.concat(allergens, &amp;#039;, &amp;#039;) or &amp;quot;&amp;#039;&amp;#039;nothing flagged&amp;#039;&amp;#039;&amp;quot;))&lt;br /&gt;
  if trim(args.contributor) ~= &amp;#039;&amp;#039; then add(&amp;#039;|-\n! Contributed by\n| &amp;#039; .. trim(args.contributor)) end&lt;br /&gt;
  if trim(args.tags) ~= &amp;#039;&amp;#039; then&lt;br /&gt;
    local tagLinks = {}&lt;br /&gt;
    for _, t in ipairs(splitList(args.tags)) do table.insert(tagLinks, &amp;#039;[[:Category:&amp;#039; .. t .. &amp;#039;|&amp;#039; .. t .. &amp;#039;]]&amp;#039;) end&lt;br /&gt;
    add(&amp;#039;|-\n! Tags\n| &amp;#039; .. table.concat(tagLinks, &amp;#039; · &amp;#039;))&lt;br /&gt;
  end&lt;br /&gt;
  add(&amp;#039;|-\n| colspan=&amp;quot;2&amp;quot; | &amp;lt;small&amp;gt;Calories are computed from the [[:Category:Ingredients|ingredient records]]. Approximate.&amp;lt;/small&amp;gt;&amp;#039;)&lt;br /&gt;
  add(&amp;#039;|}&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
  if trim(args.lede) ~= &amp;#039;&amp;#039; then add(&amp;quot;&amp;lt;div class=\&amp;quot;rp-lede\&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;quot; .. trim(args.lede) .. &amp;quot;&amp;#039;&amp;#039;&amp;lt;/div&amp;gt;&amp;quot;) end&lt;br /&gt;
&lt;br /&gt;
  if #missing &amp;gt; 0 then&lt;br /&gt;
    add(&amp;#039;&amp;lt;div class=&amp;quot;rp-missing&amp;quot;&amp;gt;These ingredients have no record yet, so they are left out of the nutrition and substitution tables: &amp;#039; ..&lt;br /&gt;
      table.concat(missing, &amp;#039;, &amp;#039;) .. &amp;#039;. [[Special:FormEdit/Ingredient|Create one]].&amp;lt;/div&amp;gt;&amp;#039;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  -- ingredients table&lt;br /&gt;
  add(&amp;#039;== Ingredients ==&amp;#039;)&lt;br /&gt;
  add(&amp;#039;{| class=&amp;quot;wikitable rp-ingredients&amp;quot;\n! Quantity !! Ingredient !! Its job here !! Swaps&amp;#039;)&lt;br /&gt;
  local swapSections = {}&lt;br /&gt;
  for i, l in ipairs(lines) do&lt;br /&gt;
    local ing = getIngredient(l.name)&lt;br /&gt;
    local shown = countLabel(l.name, l.qty, l.unit)&lt;br /&gt;
    local link = ing and (&amp;#039;[[&amp;#039; .. l.name .. &amp;#039;|&amp;#039; .. shown .. &amp;#039;]]&amp;#039;) or (&amp;#039;[[&amp;#039; .. l.name .. &amp;#039;|&amp;#039; .. shown .. &amp;#039;]]&amp;lt;sup class=&amp;quot;rp-missing-mark&amp;quot;&amp;gt;?&amp;lt;/sup&amp;gt;&amp;#039;)&lt;br /&gt;
    local qty = fmtQty(l.qty) .. &amp;#039; &amp;#039; .. unitLabel(l.qty, l.unit)&lt;br /&gt;
    local prep = l.prep ~= &amp;#039;&amp;#039; and (&amp;#039;, &amp;lt;span class=&amp;quot;rp-prep&amp;quot;&amp;gt;&amp;#039; .. l.prep .. &amp;#039;&amp;lt;/span&amp;gt;&amp;#039;) or &amp;#039;&amp;#039;&lt;br /&gt;
    local rules = ing and rulesFor(l.name, l.role) or {}&lt;br /&gt;
    local swapCell = &amp;quot;&amp;#039;&amp;#039;none&amp;#039;&amp;#039;&amp;quot;&lt;br /&gt;
    if #rules &amp;gt; 0 then&lt;br /&gt;
      swapCell = &amp;#039;[[#Substitutions for this recipe|&amp;#039; .. #rules .. (#rules == 1 and &amp;#039; option&amp;#039; or &amp;#039; options&amp;#039;) .. &amp;#039;]]&amp;#039;&lt;br /&gt;
      table.insert(swapSections, { line = l, rules = rules })&lt;br /&gt;
    end&lt;br /&gt;
    add(&amp;#039;|-\n| class=&amp;quot;rp-qty&amp;quot; | &amp;#039; .. trim(qty) .. &amp;#039;\n| &amp;#039; .. link .. prep .. &amp;#039;\n| class=&amp;quot;rp-role&amp;quot; | &amp;#039; .. l.role .. &amp;#039;\n| &amp;#039; .. swapCell)&lt;br /&gt;
  end&lt;br /&gt;
  add(&amp;#039;|}&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
  -- method&lt;br /&gt;
  if trim(args.method) ~= &amp;#039;&amp;#039; then&lt;br /&gt;
    add(&amp;#039;== Method ==&amp;#039;)&lt;br /&gt;
    add(trim(args.method))&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  -- substitutions resolved for this recipe&lt;br /&gt;
  if #swapSections &amp;gt; 0 then&lt;br /&gt;
    add(&amp;#039;== Substitutions for this recipe ==&amp;#039;)&lt;br /&gt;
    add(&amp;#039;&amp;lt;p class=&amp;quot;rp-note&amp;quot;&amp;gt;Rules come from each ingredient\&amp;#039;s record and are resolved for the job the ingredient does in this recipe. Confidence is the community\&amp;#039;s, not a guarantee.&amp;lt;/p&amp;gt;&amp;#039;)&lt;br /&gt;
    add(&amp;#039;{| class=&amp;quot;wikitable rp-subs&amp;quot;\n! Instead of !! Use !! How much !! What changes !! Confidence&amp;#039;)&lt;br /&gt;
    for _, s in ipairs(swapSections) do&lt;br /&gt;
      for _, r in ipairs(s.rules) do&lt;br /&gt;
        local useName = r.alt ~= &amp;#039;&amp;#039; and (r.alt .. &amp;#039; ([[&amp;#039; .. r.sub_to .. &amp;#039;]])&amp;#039;) or (&amp;#039;[[&amp;#039; .. r.sub_to .. &amp;#039;]]&amp;#039;)&lt;br /&gt;
        local howMuch&lt;br /&gt;
        if r.conv ~= &amp;#039;&amp;#039; then howMuch = r.conv&lt;br /&gt;
        else&lt;br /&gt;
          local ratio = tonumber(r.ratio) or 1&lt;br /&gt;
          local nq = s.line.qty and (s.line.qty * ratio) or nil&lt;br /&gt;
          howMuch = nq and (fmtQty(nq) .. &amp;#039; &amp;#039; .. unitLabel(nq, s.line.unit) .. &amp;#039; &amp;lt;small&amp;gt;(× &amp;#039; .. ratio .. &amp;#039;)&amp;lt;/small&amp;gt;&amp;#039;) or (&amp;#039;× &amp;#039; .. ratio)&lt;br /&gt;
        end&lt;br /&gt;
        local what = r.effect&lt;br /&gt;
        if r.warning ~= &amp;#039;&amp;#039; then what = what .. &amp;#039;&amp;lt;br /&amp;gt;&amp;lt;span class=&amp;quot;rp-warn&amp;quot;&amp;gt;⚠ &amp;#039; .. r.warning .. &amp;#039;&amp;lt;/span&amp;gt;&amp;#039; end&lt;br /&gt;
        if r.roleSpecific then what = what .. &amp;#039; &amp;lt;small class=&amp;quot;rp-role-tag&amp;quot;&amp;gt;rule for: &amp;#039; .. s.line.role .. &amp;#039;&amp;lt;/small&amp;gt;&amp;#039; end&lt;br /&gt;
        add(&amp;#039;|-\n| [[&amp;#039; .. s.line.name .. &amp;#039;]]\n| &amp;#039; .. useName .. &amp;#039;\n| class=&amp;quot;rp-qty&amp;quot; | &amp;#039; .. howMuch .. &amp;#039;\n| &amp;#039; .. what .. &amp;#039;\n| &amp;#039; .. confBadge(r.confidence))&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    add(&amp;#039;|}&amp;#039;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  -- store rows (skipped when the page is being previewed inside another page)&lt;br /&gt;
  if title.namespace == 0 then&lt;br /&gt;
    for i, l in ipairs(lines) do&lt;br /&gt;
      frame:callParserFunction(&amp;#039;#cargo_store&amp;#039;, {&lt;br /&gt;
        &amp;#039;_table=RecipeIngredients&amp;#039;, recipe = page, ingredient = l.name,&lt;br /&gt;
        qty = l.qty and tostring(l.qty) or &amp;#039;&amp;#039;, unit = l.unit, role = l.role, prep = l.prep, pos = tostring(i),&lt;br /&gt;
      })&lt;br /&gt;
    end&lt;br /&gt;
    frame:callParserFunction(&amp;#039;#cargo_store&amp;#039;, {&lt;br /&gt;
      &amp;#039;_table=Recipes&amp;#039;, serves = tostring(serves), time = trim(args.time), tags = trim(args.tags),&lt;br /&gt;
      contributor = trim(args.contributor), lede = trim(args.lede), method = trim(args.method),&lt;br /&gt;
      kcal_total = tostring(round(kcalTotal)), allergens = table.concat(allergens, &amp;#039;,&amp;#039;), ingredient_count = tostring(#lines),&lt;br /&gt;
    })&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  local cats = { &amp;#039;[[Category:Recipes]]&amp;#039; }&lt;br /&gt;
  for _, t in ipairs(splitList(args.tags)) do table.insert(cats, &amp;#039;[[Category:&amp;#039; .. t .. &amp;#039;]]&amp;#039;) end&lt;br /&gt;
  add(table.concat(cats, &amp;#039;&amp;#039;))&lt;br /&gt;
  return table.concat(out, &amp;#039;\n&amp;#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- ---------------------------------------------------------------- sale&lt;br /&gt;
&lt;br /&gt;
function p.sale(frame)&lt;br /&gt;
  local args = frame.args&lt;br /&gt;
  local store = trim(args.store)&lt;br /&gt;
  local where = store ~= &amp;#039;&amp;#039; and (&amp;quot;store=&amp;#039;&amp;quot; .. sqlEsc(store) .. &amp;quot;&amp;#039;&amp;quot;) or nil&lt;br /&gt;
  local sale = cargo.query(&amp;#039;SaleItems&amp;#039;, &amp;#039;ingredient,price,was,per,store&amp;#039;, { where = where, limit = 200 })&lt;br /&gt;
  if #sale == 0 then return &amp;quot;&amp;#039;&amp;#039;No sale items have been entered yet. Add them with [[Template:SaleItem]].&amp;#039;&amp;#039;&amp;quot; end&lt;br /&gt;
  local onSale = {}&lt;br /&gt;
  for _, s in ipairs(sale) do onSale[s.ingredient] = s end&lt;br /&gt;
&lt;br /&gt;
  local rows = cargo.query(&amp;#039;RecipeIngredients=RI,Ingredients=I&amp;#039;, &amp;#039;RI.recipe=recipe,RI.ingredient=ingredient,I.pantry=pantry&amp;#039;,&lt;br /&gt;
    { join = &amp;#039;RI.ingredient=I._pageName&amp;#039;, limit = 2000 })&lt;br /&gt;
  local recipes, order = {}, {}&lt;br /&gt;
  for _, r in ipairs(rows) do&lt;br /&gt;
    if not recipes[r.recipe] then recipes[r.recipe] = { hits = {}, toBuy = 0, save = 0 }; table.insert(order, r.recipe) end&lt;br /&gt;
    local rec = recipes[r.recipe]&lt;br /&gt;
    local pantry = trim(r.pantry):lower() == &amp;#039;yes&amp;#039;&lt;br /&gt;
    if not pantry then&lt;br /&gt;
      rec.toBuy = rec.toBuy + 1&lt;br /&gt;
      local s = onSale[r.ingredient]&lt;br /&gt;
      if s then&lt;br /&gt;
        table.insert(rec.hits, r.ingredient)&lt;br /&gt;
        rec.save = rec.save + ((tonumber(s.was) or 0) - (tonumber(s.price) or 0))&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  local ranked = {}&lt;br /&gt;
  for _, name in ipairs(order) do&lt;br /&gt;
    local rec = recipes[name]&lt;br /&gt;
    if #rec.hits &amp;gt; 0 then rec.name = name; table.insert(ranked, rec) end&lt;br /&gt;
  end&lt;br /&gt;
  table.sort(ranked, function(a, b)&lt;br /&gt;
    if #a.hits ~= #b.hits then return #a.hits &amp;gt; #b.hits end&lt;br /&gt;
    return (#a.hits / math.max(1, a.toBuy)) &amp;gt; (#b.hits / math.max(1, b.toBuy))&lt;br /&gt;
  end)&lt;br /&gt;
&lt;br /&gt;
  local out = { &amp;#039;{| class=&amp;quot;wikitable rp-sale&amp;quot;\n! Recipe !! On sale !! Shopping list !! You save&amp;#039; }&lt;br /&gt;
  for _, rec in ipairs(ranked) do&lt;br /&gt;
    local links = {}&lt;br /&gt;
    for _, h in ipairs(rec.hits) do table.insert(links, &amp;#039;[[&amp;#039; .. h .. &amp;#039;]]&amp;#039;) end&lt;br /&gt;
    table.insert(out, &amp;#039;|-\n| [[&amp;#039; .. rec.name .. &amp;#039;]]\n| &amp;#039; .. table.concat(links, &amp;#039;, &amp;#039;) .. &amp;#039;\n| &amp;#039; .. #rec.hits .. &amp;#039; of &amp;#039; .. rec.toBuy ..&lt;br /&gt;
      &amp;#039; items &amp;lt;small&amp;gt;(pantry staples excluded)&amp;lt;/small&amp;gt;\n| class=&amp;quot;rp-qty&amp;quot; | $&amp;#039; .. string.format(&amp;#039;%.2f&amp;#039;, rec.save))&lt;br /&gt;
  end&lt;br /&gt;
  table.insert(out, &amp;#039;|}&amp;#039;)&lt;br /&gt;
  return table.concat(out, &amp;#039;\n&amp;#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- ---------------------------------------------------------------- cookbook&lt;br /&gt;
&lt;br /&gt;
local function chapterFor(tags)&lt;br /&gt;
  local t = {}&lt;br /&gt;
  for _, x in ipairs(splitList(tags)) do t[x:lower()] = true end&lt;br /&gt;
  if t[&amp;#039;breakfast&amp;#039;] then return &amp;#039;Mornings&amp;#039; end&lt;br /&gt;
  if t[&amp;#039;dessert&amp;#039;] then return &amp;#039;Sweets&amp;#039; end&lt;br /&gt;
  if t[&amp;#039;dinner&amp;#039;] or t[&amp;#039;side&amp;#039;] or t[&amp;#039;soup&amp;#039;] then return &amp;#039;Suppers and sides&amp;#039; end&lt;br /&gt;
  return &amp;#039;Pantry and dressings&amp;#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.cookbook(frame)&lt;br /&gt;
  local args = frame:getParent().args&lt;br /&gt;
  local names = splitList(args.recipes)&lt;br /&gt;
  local title = trim(args.title) ~= &amp;#039;&amp;#039; and trim(args.title) or &amp;#039;Our kitchen&amp;#039;&lt;br /&gt;
  local out = {}&lt;br /&gt;
  local function add(s) table.insert(out, s) end&lt;br /&gt;
&lt;br /&gt;
  add(&amp;#039;&amp;lt;div class=&amp;quot;rp-book&amp;quot;&amp;gt;&amp;#039;)&lt;br /&gt;
  add(&amp;#039;&amp;lt;div class=&amp;quot;rp-page rp-cover&amp;quot;&amp;gt;&amp;lt;div class=&amp;quot;rp-orn&amp;quot;&amp;gt;✦&amp;lt;/div&amp;gt;&amp;lt;div class=&amp;quot;rp-cover-title&amp;quot;&amp;gt;&amp;#039; .. title .. &amp;#039;&amp;lt;/div&amp;gt;&amp;lt;div class=&amp;quot;rp-cover-sub&amp;quot;&amp;gt;&amp;#039; ..&lt;br /&gt;
    #names .. (#names == 1 and &amp;#039; recipe&amp;#039; or &amp;#039; recipes&amp;#039;) .. &amp;#039; · assembled on Recipedius&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;#039;)&lt;br /&gt;
  if trim(args.dedication) ~= &amp;#039;&amp;#039; then&lt;br /&gt;
    add(&amp;#039;&amp;lt;div class=&amp;quot;rp-page rp-dedication&amp;quot;&amp;gt;&amp;#039; .. trim(args.dedication) .. &amp;#039;&amp;lt;/div&amp;gt;&amp;#039;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  -- gather&lt;br /&gt;
  local recs, chapters, chapterOrder = {}, {}, {}&lt;br /&gt;
  for _, n in ipairs(names) do&lt;br /&gt;
    local r = cargo.query(&amp;#039;Recipes&amp;#039;, &amp;#039;_pageName=name,serves,time,tags,contributor,lede,method&amp;#039;,&lt;br /&gt;
      { where = &amp;quot;_pageName=&amp;#039;&amp;quot; .. sqlEsc(n) .. &amp;quot;&amp;#039;&amp;quot;, limit = 1 })[1]&lt;br /&gt;
    if r then&lt;br /&gt;
      r.lines = cargo.query(&amp;#039;RecipeIngredients&amp;#039;, &amp;#039;ingredient,qty,unit,prep,pos&amp;#039;,&lt;br /&gt;
        { where = &amp;quot;recipe=&amp;#039;&amp;quot; .. sqlEsc(n) .. &amp;quot;&amp;#039;&amp;quot;, orderBy = &amp;#039;pos&amp;#039;, limit = 100 })&lt;br /&gt;
      local ch = chapterFor(r.tags)&lt;br /&gt;
      if not chapters[ch] then chapters[ch] = {}; table.insert(chapterOrder, ch) end&lt;br /&gt;
      table.insert(chapters[ch], r)&lt;br /&gt;
    else&lt;br /&gt;
      add(&amp;#039;&amp;lt;div class=&amp;quot;rp-missing&amp;quot;&amp;gt;No recipe page called &amp;quot;&amp;#039; .. n .. &amp;#039;&amp;quot; was found.&amp;lt;/div&amp;gt;&amp;#039;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  -- contents&lt;br /&gt;
  add(&amp;#039;&amp;lt;div class=&amp;quot;rp-page rp-toc&amp;quot;&amp;gt;&amp;lt;div class=&amp;quot;rp-chap-label&amp;quot;&amp;gt;Contents&amp;lt;/div&amp;gt;&amp;#039;)&lt;br /&gt;
  for _, ch in ipairs(chapterOrder) do&lt;br /&gt;
    add(&amp;#039;&amp;lt;div class=&amp;quot;rp-toc-chapter&amp;quot;&amp;gt;&amp;#039; .. ch .. &amp;#039;&amp;lt;/div&amp;gt;&amp;#039;)&lt;br /&gt;
    for _, r in ipairs(chapters[ch]) do add(&amp;#039;&amp;lt;div class=&amp;quot;rp-toc-row&amp;quot;&amp;gt;&amp;lt;span&amp;gt;&amp;#039; .. r.name .. &amp;#039;&amp;lt;/span&amp;gt;&amp;lt;span&amp;gt;&amp;#039; .. r.time .. &amp;#039;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;#039;) end&lt;br /&gt;
  end&lt;br /&gt;
  add(&amp;#039;&amp;lt;/div&amp;gt;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
  for _, ch in ipairs(chapterOrder) do&lt;br /&gt;
    add(&amp;#039;&amp;lt;div class=&amp;quot;rp-page rp-chapter&amp;quot;&amp;gt;&amp;lt;div class=&amp;quot;rp-chap-label&amp;quot;&amp;gt;Chapter&amp;lt;/div&amp;gt;&amp;lt;div class=&amp;quot;rp-chapter-title&amp;quot;&amp;gt;&amp;#039; .. ch .. &amp;#039;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;#039;)&lt;br /&gt;
    for _, r in ipairs(chapters[ch]) do&lt;br /&gt;
      add(&amp;#039;&amp;lt;div class=&amp;quot;rp-page rp-recipe-page&amp;quot;&amp;gt;&amp;lt;div class=&amp;quot;rp-chap-label&amp;quot;&amp;gt;&amp;#039; .. ch .. &amp;#039;&amp;lt;/div&amp;gt;&amp;lt;div class=&amp;quot;rp-recipe-title&amp;quot;&amp;gt;&amp;#039; .. r.name .. &amp;#039;&amp;lt;/div&amp;gt;&amp;#039;)&lt;br /&gt;
      if trim(r.lede) ~= &amp;#039;&amp;#039; then add(&amp;quot;&amp;lt;div class=\&amp;quot;rp-lede\&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;quot; .. r.lede .. &amp;quot;&amp;#039;&amp;#039;&amp;lt;/div&amp;gt;&amp;quot;) end&lt;br /&gt;
      add(&amp;#039;&amp;lt;div class=&amp;quot;rp-book-cols&amp;quot;&amp;gt;&amp;lt;div class=&amp;quot;rp-book-ings&amp;quot;&amp;gt;&amp;#039;)&lt;br /&gt;
      for _, l in ipairs(r.lines) do&lt;br /&gt;
        local q = tonumber(l.qty)&lt;br /&gt;
        add(&amp;#039;&amp;lt;div class=&amp;quot;rp-book-ing&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;rp-qty&amp;quot;&amp;gt;&amp;#039; .. fmtQty(q) .. &amp;#039; &amp;#039; .. unitLabel(q, l.unit) .. &amp;#039;&amp;lt;/span&amp;gt;&amp;lt;span&amp;gt;&amp;#039; .. countLabel(l.ingredient, q, l.unit) ..&lt;br /&gt;
          (trim(l.prep) ~= &amp;#039;&amp;#039; and (&amp;#039;, &amp;#039; .. l.prep) or &amp;#039;&amp;#039;) .. &amp;#039;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;#039;)&lt;br /&gt;
      end&lt;br /&gt;
      add(&amp;#039;&amp;lt;/div&amp;gt;&amp;lt;div class=&amp;quot;rp-book-method&amp;quot;&amp;gt;\n&amp;#039; .. (r.method or &amp;#039;&amp;#039;) .. &amp;#039;\n&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;#039;)&lt;br /&gt;
      add(&amp;#039;&amp;lt;div class=&amp;quot;rp-book-foot&amp;quot;&amp;gt;Serves &amp;#039; .. r.serves .. &amp;#039; · &amp;#039; .. r.time .. (trim(r.contributor) ~= &amp;#039;&amp;#039; and (&amp;#039; · contributed by &amp;#039; .. r.contributor) or &amp;#039;&amp;#039;) .. &amp;#039;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;#039;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  add(&amp;#039;&amp;lt;/div&amp;gt;&amp;#039;)&lt;br /&gt;
  return table.concat(out, &amp;#039;\n&amp;#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Janine</name></author>
	</entry>
</feed>