<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://stockhub.co/index.php?action=history&amp;feed=atom&amp;title=Module%3ABuffer%2Fsandbox</id>
	<title>Module:Buffer/sandbox - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://stockhub.co/index.php?action=history&amp;feed=atom&amp;title=Module%3ABuffer%2Fsandbox"/>
	<link rel="alternate" type="text/html" href="https://stockhub.co/index.php?title=Module:Buffer/sandbox&amp;action=history"/>
	<updated>2026-04-15T17:58:07Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://stockhub.co/index.php?title=Module:Buffer/sandbox&amp;diff=135405&amp;oldid=prev</id>
		<title>imported&gt;Neils51: sp</title>
		<link rel="alternate" type="text/html" href="https://stockhub.co/index.php?title=Module:Buffer/sandbox&amp;diff=135405&amp;oldid=prev"/>
		<updated>2019-05-19T10:30:00Z</updated>

		<summary type="html">&lt;p&gt;sp&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;--[[=============================&lt;br /&gt;
This Module was written by Alexander Zhikun He, also known as, User:Codehydro on the English Wikipedia&lt;br /&gt;
&lt;br /&gt;
All methods were developed independently and any resemblance to other string buffer libraries would be coincidental.&lt;br /&gt;
Furthermore, many methods will not work when compiled by standard Lua libraries as they depend on behaviors unique to&lt;br /&gt;
the MediaMiki Scribunto mod, which, for example, has a getmetatable() method that always returns nil on non-tables.&lt;br /&gt;
https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual&lt;br /&gt;
&lt;br /&gt;
Source code comments may be thin at some points because they are intended to be supplemented by the documentation page:&lt;br /&gt;
https://en.wikipedia.org/wiki/Module:Buffer/doc&lt;br /&gt;
&lt;br /&gt;
Licensed under Creative Commons Attribution-ShareAlike 3.0 Unported License&lt;br /&gt;
https://en.wikipedia.org/wiki/Wikipedia:Text_of_Creative_Commons_Attribution-ShareAlike_3.0_Unported_License&lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Module:Buffer&lt;br /&gt;
https://en.wikipedia.org/wiki/User:Codehydro&lt;br /&gt;
============================= -- ]]&lt;br /&gt;
&lt;br /&gt;
-- Performs type validation&lt;br /&gt;
local function Valid(v)&lt;br /&gt;
	if v and v ~= true then --reject nil/boolean; faster than 2 type() comparisons&lt;br /&gt;
		local str = tostring(v) --functions not filtered since unlikely passed by accident (Scribunto does not have userdata/thread types)&lt;br /&gt;
		--tostring(string-type) returns same ref; same refs compare faster than type()&lt;br /&gt;
		if str ~= v and str == &amp;#039;table&amp;#039; then&lt;br /&gt;
			return rawget(v, 1) and table.concat(v)&lt;br /&gt;
		end&lt;br /&gt;
		--numbers are coerced to string per table.concat op; appending in string form saves ops on repeat concat&lt;br /&gt;
		if str ~= &amp;#039;&amp;#039; then&lt;br /&gt;
			return str&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local MBpairs&lt;br /&gt;
local noOp = function() end&lt;br /&gt;
do&lt;br /&gt;
	local iMap, vMap, oMap, pIter, pOther, pFast, Next --Map&lt;br /&gt;
	local function init() -- init = noOp after first run&lt;br /&gt;
		function Next(t)&lt;br /&gt;
			return next, t -- slightly faster to do this than to use select()&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		function pIter(t, k)&lt;br /&gt;
			-- don&amp;#039;t use rawget; accepting unmapped tables does not measurably affect performance.&lt;br /&gt;
			k = (iMap[t] or MBpairs(t, true) and iMap[t])[not k and 1 or vMap[t][k]]&lt;br /&gt;
			return k, t[k]&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		function pOther(t, k)&lt;br /&gt;
			-- comparison to nil because false is a valid key&lt;br /&gt;
			k = (oMap[t] or MBpairs(t, true) and oMap[t])[nil==k and 1 or vMap[t][k]]&lt;br /&gt;
			return k, t[k]&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		function pFast(t, k)&lt;br /&gt;
			-- mapless iterator; almost as fast as native ipairs; slight performance penalty when length not cached&lt;br /&gt;
			k = not k and 1 or k &amp;lt; (vMap[t] or #t) and k + 1 or nil&lt;br /&gt;
			return k, t[k]&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local mk = {__mode = &amp;#039;k&amp;#039;} -- use mode &amp;#039;k&amp;#039;; found that mode &amp;#039;kv&amp;#039; sometimes garbage collects maps mid-loop (may not error because iterators auto re-map, but that&amp;#039;s expensive)&lt;br /&gt;
		init = noOp&lt;br /&gt;
		iMap = setmetatable({}, mk) -- numeric keys&lt;br /&gt;
		vMap = setmetatable({}, mk) -- next key&lt;br /&gt;
		oMap = setmetatable({}, mk) -- non-numeric keys&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	function MBpairs(t, ...) -- pairs always iterates in order&lt;br /&gt;
		local iter, ex = ...&lt;br /&gt;
		init()&lt;br /&gt;
		iter = iter == nil&lt;br /&gt;
		if iter and not oMap[t] and ex==nil and rawget(t, 1)~=nil and next(t, #t)==nil then--while possible to miss keys, more thorough check would negate the benefit of pFast&lt;br /&gt;
			vMap[t] = #t return pFast, t, nil&lt;br /&gt;
		elseif ... or not vMap[t] or select(&amp;#039;#&amp;#039;, ...) ~= 1 then&lt;br /&gt;
			local ti, tn, to, n = {}, {}, {}, #t --reduces table lookups&lt;br /&gt;
			iMap[t], vMap[t], oMap[t] = ti, tn, to&lt;br /&gt;
			for k = 1, n do&lt;br /&gt;
				--stage one avoids number type checking op in stage two for most numeric keys&lt;br /&gt;
				ti[k], tn[k] = k, k + 1&lt;br /&gt;
			end&lt;br /&gt;
			for k in (ex or Next)(t) do&lt;br /&gt;
				if not tn[k] then&lt;br /&gt;
					table.insert(tonumber(k) ~= k and to or ti, k)&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			if #ti ~= n then&lt;br /&gt;
				table.sort(ti)&lt;br /&gt;
				for k = 1, #ti do&lt;br /&gt;
					-- somewhat wasteful, but trying to avoid overwriting can be even more expensive&lt;br /&gt;
					tn[ti[k]] = k + 1&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			for k = 1, #to do&lt;br /&gt;
				tn[to[k]] = k + 1&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		return iter and pIter or oMap[t] and pOther or noOp, t --noOp for mapless&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local parent, rawkey, spec&lt;br /&gt;
do&lt;br /&gt;
	--new scope for variables not reused outside (reduces number of var names that need to checked outside of scope)&lt;br /&gt;
	--shared meta for Buffer parent property, raw mode, and specialized functions&lt;br /&gt;
	local mkv = {&lt;br /&gt;
		__mode = &amp;#039;kv&amp;#039;,&lt;br /&gt;
		__call = function(t,k,v)&lt;br /&gt;
			t[k] = v&lt;br /&gt;
			return k&lt;br /&gt;
		end&lt;br /&gt;
	}&lt;br /&gt;
	--shared meta less memory&lt;br /&gt;
	parent = setmetatable({}, mkv)&lt;br /&gt;
	rawkey = setmetatable({}, mkv)&lt;br /&gt;
	spec = setmetatable({}, mkv)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local MB, MBi, MBmix, buffHTML, gfuncs, noCache, Element&lt;br /&gt;
do&lt;br /&gt;
	--minimize number of locals per scope to reduce time spent sifting through irrelevant variable names&lt;br /&gt;
	local _stream&lt;br /&gt;
	do&lt;br /&gt;
		local stream --keep stream near top of scope&lt;br /&gt;
&lt;br /&gt;
		local function init(f) --init = noOp after first run&lt;br /&gt;
			local function each(self, ...)&lt;br /&gt;
				for k = 1, select(&amp;#039;#&amp;#039;, ...) do&lt;br /&gt;
					k = Valid(select(k, ...)) -- slightly faster than table.insert(self, (Valid(select(k, ...))))&lt;br /&gt;
					if k then&lt;br /&gt;
						table.insert(self, k)&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				return self&lt;br /&gt;
			end&lt;br /&gt;
			init = noOp&lt;br /&gt;
			stream = {&lt;br /&gt;
				__call = function(t, v)&lt;br /&gt;
					v = v and Valid(v)&lt;br /&gt;
					--last_concat cleared before entering stream mode&lt;br /&gt;
					return v and table.insert(t, v) or t&lt;br /&gt;
				end,&lt;br /&gt;
				__index = function(t, i)&lt;br /&gt;
					--no table look up minimizes resources to retrieve the only stream function&lt;br /&gt;
					return i == &amp;#039;each&amp;#039; and each or MB.__index(t, i) and setmetatable(t, MB)[i]&lt;br /&gt;
				end,&lt;br /&gt;
				__tostring = function(t)&lt;br /&gt;
					return setmetatable(t, MB)()&lt;br /&gt;
				end&lt;br /&gt;
			}&lt;br /&gt;
			for k, v in next, MB do&lt;br /&gt;
				stream[k] = stream[k] or v&lt;br /&gt;
			end&lt;br /&gt;
			setmetatable(stream, getmetatable(MB))&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		function _stream(self, ...)&lt;br /&gt;
			init()&lt;br /&gt;
			self.last_concat = nil&lt;br /&gt;
			return setmetatable(self, stream):each(...)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- helper for :getParent()-like methods (including getBuffer which does not return a parent)&lt;br /&gt;
	local function isMBfunc(Buffer, s, ...)&lt;br /&gt;
		--eventually should figure out to make this work for :getHTML which is very similar&lt;br /&gt;
		return s and&lt;br /&gt;
			(&lt;br /&gt;
				select(&amp;#039;#&amp;#039;, ...) == 0 and&lt;br /&gt;
				(&lt;br /&gt;
					--unprefixed function names append as a string&lt;br /&gt;
					not rawkey[s] and&lt;br /&gt;
					tostring(s):match(&amp;#039;^_.*&amp;#039;) and&lt;br /&gt;
					MB.__index(Buffer, s) and&lt;br /&gt;
					MB.__index(Buffer, s)(Buffer) or&lt;br /&gt;
					MBmix(Buffer, s)&lt;br /&gt;
				) or assert( --getParent is a one-way trip so one-time assert not expensive&lt;br /&gt;
					MB.__index(Buffer, s),&lt;br /&gt;
					(&amp;#039;&amp;quot; %s &amp;quot; does not match any available Module:Buffer function&amp;#039;):format(s)&lt;br /&gt;
				)(Buffer, ...)&lt;br /&gt;
			) or Buffer&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- helper for :_out and :_str&lt;br /&gt;
	local function MBselect(n, ...)&lt;br /&gt;
		local n, seps = n - 1, {select(2, ...)}&lt;br /&gt;
		if type(seps[n])==&amp;#039;table&amp;#039; then &lt;br /&gt;
			if buffHTML and rawget(seps[n], buffHTML) then&lt;br /&gt;
				return ...&lt;br /&gt;
			end&lt;br /&gt;
			setmetatable(seps, {&lt;br /&gt;
				__index = setmetatable(seps[n], {&lt;br /&gt;
					__index = function(t)&lt;br /&gt;
						return rawget(t, 1)&lt;br /&gt;
					end&lt;br /&gt;
				})&lt;br /&gt;
			})[n] = nil&lt;br /&gt;
		end&lt;br /&gt;
		return ..., seps&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
local _inHTML&lt;br /&gt;
do&lt;br /&gt;
	local lastBuffer, lastHTML&lt;br /&gt;
	local function init(...) -- init replaced and new version called on return&lt;br /&gt;
		local create, mwFunc = mw.html.create&lt;br /&gt;
		do&lt;br /&gt;
		local mwHTMLmeta = getmetatable(create())&lt;br /&gt;
		buffHTML, mwFunc, _inHTML = setmetatable(mw.clone(mwHTMLmeta), getmetatable(MB)), mwHTMLmeta.__index -- buffHTML declared near top of module; remove _inHTML from outer scope&lt;br /&gt;
		function init(nodes, ...)&lt;br /&gt;
			local name, args, tag = select(... and type(...) == &amp;#039;table&amp;#039; and 1 or 2, nil, ...)&lt;br /&gt;
			tag = create(Valid(name), args)&lt;br /&gt;
			if nodes then&lt;br /&gt;
				table.insert(nodes, tag.parent and tag or rawset(tag, &amp;#039;parent&amp;#039;, parent[nodes]))&lt;br /&gt;
			end&lt;br /&gt;
			if args then&lt;br /&gt;
				local a, b = args.selfClosing, args.parent&lt;br /&gt;
				args.selfClosing, args.parent = nil&lt;br /&gt;
				if next(args) then&lt;br /&gt;
					Element._add(parent(tag.nodes, tag), args)&lt;br /&gt;
				end&lt;br /&gt;
				args.selfClosing, args.parent = a, b -- in case args is reused&lt;br /&gt;
			end&lt;br /&gt;
			return tag&lt;br /&gt;
		end&lt;br /&gt;
		for k, v in next, {[mw] = mwHTMLmeta,&lt;br /&gt;
			__call = function(h, v)&lt;br /&gt;
				return MBmix(spec[h.nodes] and h.nodes or spec(setmetatable(parent(h.nodes, h), MB), Element), v)&lt;br /&gt;
			end,&lt;br /&gt;
			__concat = false, -- false means take from MB&lt;br /&gt;
			__eq = false&lt;br /&gt;
		} do&lt;br /&gt;
		buffHTML[k] = v or MB[k]&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local nonSelf, BHi = {tag = true,done = true,allDone = true}, buffHTML.__index&lt;br /&gt;
do&lt;br /&gt;
	local g&lt;br /&gt;
	g = {__index = function(t, i)&lt;br /&gt;
		if gfuncs and gfuncs[i] then&lt;br /&gt;
			g.__index, gfuncs = gfuncs&lt;br /&gt;
			return g.__index[i]&lt;br /&gt;
		end&lt;br /&gt;
	end}&lt;br /&gt;
	setmetatable(nonSelf, g)&lt;br /&gt;
	setmetatable(BHi, g)&lt;br /&gt;
end&lt;br /&gt;
for k in next, nonSelf do&lt;br /&gt;
	-- any HTML objects returned by these funcs will be granted Module:Buffer enhancements&lt;br /&gt;
	local func = mwFunc[k]&lt;br /&gt;
	BHi[k] = function(t, ...)&lt;br /&gt;
		local HTML = func(t, ...)&lt;br /&gt;
		return parent[HTML] and HTML or setmetatable(parent(HTML, t), buffHTML)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
do&lt;br /&gt;
	local function joinNode(HTML, sep)&lt;br /&gt;
		local nodes, join = HTML.nodes&lt;br /&gt;
		if noCache and rawkey[sep] or Valid(sep) then&lt;br /&gt;
			join, HTML.nodes = tostring(rawset(HTML, &amp;#039;nodes&amp;#039;, {MB.__call(nodes, sep)})), nodes&lt;br /&gt;
		end&lt;br /&gt;
		return join or tostring(HTML)&lt;br /&gt;
	end&lt;br /&gt;
	for k, v in next, {&lt;br /&gt;
		getParent = function(HTML, ...)&lt;br /&gt;
			lastHTML = HTML&lt;br /&gt;
			return MBi.getParent(HTML:allDone(), ...)&lt;br /&gt;
		end, -- return to Buffer that created the HTML tree&lt;br /&gt;
		getBuffer = function(HTML, ...)&lt;br /&gt;
			lastHTML = HTML&lt;br /&gt;
			return isMBfunc(lastBuffer, ...)&lt;br /&gt;
		end, -- return to last used&lt;br /&gt;
		killParent = function(HTML, ...)&lt;br /&gt;
			MBi.killParent(HTML:allDone(), ...)&lt;br /&gt;
			return HTML&lt;br /&gt;
		end,&lt;br /&gt;
		_out = function(HTML, ...)&lt;br /&gt;
			if ... == 0 then&lt;br /&gt;
				MBi._out(HTML.nodes, ...)&lt;br /&gt;
				return HTML&lt;br /&gt;
			end&lt;br /&gt;
			lastHTML, HTML = HTML, HTML:allDone()&lt;br /&gt;
			local n, ops, seps = select(&amp;#039;#&amp;#039;, ...)&lt;br /&gt;
			if n &amp;gt; 1 then&lt;br /&gt;
				local ops, seps = MBselect(n, ...)&lt;br /&gt;
				return parent[HTML]:_in(joinNode(HTML, rawget(seps, 0))):_out(ops, rawset(seps, buffHTML, true))&lt;br /&gt;
			end&lt;br /&gt;
			return parent[HTML]:_(joinNode(HTML, ...))&lt;br /&gt;
		end,&lt;br /&gt;
		_str = function(HTML, ...)&lt;br /&gt;
			-- does not set lastHTML&lt;br /&gt;
			if ... == 0 then&lt;br /&gt;
				return joinNode(HTML, select(2, ...))&lt;br /&gt;
			end -- passing 0 strings without calling allDone()&lt;br /&gt;
			local HTML, n = HTML:allDone(), select(&amp;#039;#&amp;#039;, ...)&lt;br /&gt;
			if n &amp;gt; 1 then&lt;br /&gt;
				local ops, seps = MBselect(n, ...)&lt;br /&gt;
				return parent[HTML]:_in(joinNode(HTML, rawget(seps, 1))):_str(ops, rawset(seps, buffHTML, true))&lt;br /&gt;
			end&lt;br /&gt;
			return joinNode(HTML, ...)&lt;br /&gt;
		end,&lt;br /&gt;
		_parent = function(HTML, ...)&lt;br /&gt;
			table.insert(HTML.nodes, parent[HTML:allDone()]:_str(...))&lt;br /&gt;
			return HTML&lt;br /&gt;
		end&lt;br /&gt;
	} do&lt;br /&gt;
	BHi[k] = v&lt;br /&gt;
end&lt;br /&gt;
	end&lt;br /&gt;
	do&lt;br /&gt;
		local htmlArg, skip, outFuncs = {parent = true,selfClosing = true,tagName = true}, {}&lt;br /&gt;
		do&lt;br /&gt;
			local out local function func(nodes, ...)&lt;br /&gt;
				return out(parent[nodes], ...)&lt;br /&gt;
			end&lt;br /&gt;
			outFuncs = setmetatable({&lt;br /&gt;
				tag = function(nodes, ...)&lt;br /&gt;
					return parent(setmetatable(init(nodes, ...), buffHTML), parent[nodes])&lt;br /&gt;
				end,&lt;br /&gt;
				done = function(b, ops)&lt;br /&gt;
					b = parent[b] &lt;br /&gt;
					while b.parent and ops ~= 0 do&lt;br /&gt;
						b, ops = b.parent, ops and ops - 1 or 0&lt;br /&gt;
					end&lt;br /&gt;
					return b&lt;br /&gt;
				end&lt;br /&gt;
			}, {__index = function(nodes, i)&lt;br /&gt;
				if rawget(BHi, i) then&lt;br /&gt;
					out = BHi[i]&lt;br /&gt;
					return func&lt;br /&gt;
				end -- rawget to exclude globals&lt;br /&gt;
			end})&lt;br /&gt;
		end&lt;br /&gt;
		Element = {&lt;br /&gt;
			_add = function(nodes, t)&lt;br /&gt;
				for k, v in MBpairs(t), t, skip[t] do&lt;br /&gt;
					(v ~= true and MBmix or noOp)(nodes, v)&lt;br /&gt;
				end&lt;br /&gt;
				local HTML = parent[nodes] for k, v in MBpairs(t, false) do&lt;br /&gt;
				if htmlArg[k] then&lt;br /&gt;
					HTML[k] = v&lt;br /&gt;
				elseif v and v ~= true then&lt;br /&gt;
					if nonSelf[k] then&lt;br /&gt;
						if k == &amp;#039;tag&amp;#039; then&lt;br /&gt;
							if type(v) == &amp;#039;table&amp;#039; then&lt;br /&gt;
								skip[v], k = 1, rawset(create(Valid(v[1])), &amp;#039;parent&amp;#039;, HTML)&lt;br /&gt;
								Element._add(spec(parent(k.nodes, k, table.insert(nodes, k)), Element), v)&lt;br /&gt;
								if k.selfClosing then&lt;br /&gt;
									k.nodes = nil else spec[k.nodes], parent[k.nodes] = nil&lt;br /&gt;
								end -- free memory/reduce clutter; parent ref will auto-unset when k.nodes is nil&lt;br /&gt;
								if not k.tagName then&lt;br /&gt;
									k.styles, k.attributes = nil&lt;br /&gt;
								end&lt;br /&gt;
							else table.insert(nodes, create(v))&lt;br /&gt;
							end&lt;br /&gt;
						elseif mwFunc[k] then&lt;br /&gt;
							if k == &amp;#039;done&amp;#039; and tonumber(v) ~= v and v[1] and tonumber(v[1]) == v[1] then&lt;br /&gt;
								skip[v] = 1&lt;br /&gt;
							end&lt;br /&gt;
							MBmix(outFuncs[k](nodes, skip[v] and v[1]).nodes, v)&lt;br /&gt;
						elseif v[1] or v[2] then&lt;br /&gt;
							k = MBi[k](nodes, unpack(v, 1, rawset(skip, v, k == &amp;#039;_B&amp;#039; and 1 or 2)[v]))&lt;br /&gt;
							Element._add(getmetatable(k) and rawget(k, &amp;#039;nodes&amp;#039;) or k, v) -- if k is not a table, then v should not contain any extra keys or this may error.&lt;br /&gt;
						else MBi[k](nodes, v)&lt;br /&gt;
						end -- k probably == &amp;#039;_G&amp;#039; or &amp;#039;_R&amp;#039;&lt;br /&gt;
					elseif mwFunc[k] then&lt;br /&gt;
						if type(v) ~= &amp;#039;table&amp;#039; or rawget(v, &amp;#039;nodes&amp;#039;) then&lt;br /&gt;
							mwFunc[k](HTML, v)&lt;br /&gt;
						else&lt;br /&gt;
							local css = k == &amp;#039;css&amp;#039;&lt;br /&gt;
							for x, y in MBpairs(v, true) do&lt;br /&gt;
								(y and y ~= true and mwFunc[k] or noOp)(HTML, css and x:gsub(&amp;#039;_&amp;#039;, &amp;#039;-&amp;#039;) or x, y)&lt;br /&gt;
							end -- iterate non-numbers first&lt;br /&gt;
							for _, y in MBpairs(v, nil) do&lt;br /&gt;
								(y and y ~= true and mwFunc[k] or noOp)(HTML, y)&lt;br /&gt;
							end -- don&amp;#039;t bother with gsub since text must be quoted anyhow&lt;br /&gt;
						end&lt;br /&gt;
					elseif rawget(Element, k) or rawget(MBi, k) then&lt;br /&gt;
						if tonumber(v) == v or v[1] == nil or getmetatable(v) then&lt;br /&gt;
							(Element[k] or MBi[k])(nodes, v) -- v is probably string-able object, or a table to be handled by :_all&lt;br /&gt;
						else (Element[k] or MBi[k])(nodes, unpack(v, 1, table.maxn(v)))&lt;br /&gt;
						end -- v is definitely a table&lt;br /&gt;
					else mwFunc.css(HTML, k:gsub(&amp;#039;_&amp;#039;, &amp;#039;-&amp;#039;, 1), tostring(v))&lt;br /&gt;
					end -- oddly enough, :_add clocked its fastest runtime after adding auto-gsub as a feature&lt;br /&gt;
					skip[v] = nil&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			return nodes&lt;br /&gt;
		end&lt;br /&gt;
	}&lt;br /&gt;
	local tempMeta = {mode = &amp;#039;v&amp;#039;, copy = {styles = true,attributes = true}}&lt;br /&gt;
	function tempMeta.__index(t, i)&lt;br /&gt;
		return tempMeta.copy[i] and rawset(t, i, MBi._cc(false, 0, t.orig[i]))[i] or t.orig[i]&lt;br /&gt;
	end&lt;br /&gt;
	rawkey[setmetatable(Element, {__index = outFuncs, __concat = function(Element, v)&lt;br /&gt;
		return setmetatable({nodes = spec({}, Element),orig = parent[v]}, tempMeta)&lt;br /&gt;
	end})] = math.huge&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function MBi:getHTML(...)&lt;br /&gt;
	lastBuffer = self&lt;br /&gt;
	if ... then&lt;br /&gt;
		if select(&amp;#039;#&amp;#039;, ...) == 1 then&lt;br /&gt;
			return not rawkey[s] and tostring(...):match&amp;#039;^_&amp;#039; and BHi[...] and BHi[...](lastHTML) or lastHTML(...)&lt;br /&gt;
		else&lt;br /&gt;
			return assert(BHi[...], (&amp;#039;&amp;quot; %s &amp;quot; does not match any mw.html or Buffer-mw.html function&amp;#039;):format(tostring(...)))(lastHTML, select(2, ...))&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return lastHTML&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function MBi:_html(...)&lt;br /&gt;
	return MBi._(self, lastHTML, select(spec[self] == Element and select(&amp;#039;#&amp;#039;, ...) == 0 and 1 or 2, true, ...))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return init(...)&lt;br /&gt;
		end&lt;br /&gt;
		function _inHTML(self, ...)&lt;br /&gt;
			local HTML = init(nil, ...)&lt;br /&gt;
			if HTML.selfClosing and spec[self] == Element then&lt;br /&gt;
				self.last_concat = table.insert(self, HTML)&lt;br /&gt;
				return self&lt;br /&gt;
			end&lt;br /&gt;
			lastBuffer, lastHTML = self, setmetatable(parent(HTML, self), buffHTML) -- set after &amp;#039;args&amp;#039; table processed by :_add&lt;br /&gt;
			return HTML&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	local _var, unbuild do&lt;br /&gt;
	local prev, rebuild&lt;br /&gt;
	local function init(...) -- init replaced before return&lt;br /&gt;
		local function pick(b, v)&lt;br /&gt;
			return b and table.insert(b, v) or v&lt;br /&gt;
		end&lt;br /&gt;
		local function c(a, num)&lt;br /&gt;
			return rawset(a.a or a, 0, a[0] and a[0] + a.c or num and a[1] or a[1]:byte())[0]&lt;br /&gt;
		end&lt;br /&gt;
		local same, build, alt = {__tostring = function(a, b)&lt;br /&gt;
			return a.a[0] and pick(b, a.a.string and string.char(a.a[0]) or a.a.table and a.a[1][a.a[0]] or a.a[0])&lt;br /&gt;
		end}, {&lt;br /&gt;
		__index = {c = 1},&lt;br /&gt;
		__tostring = function(t)&lt;br /&gt;
			return t:_build()&lt;br /&gt;
		end,&lt;br /&gt;
		table = function(a, b)&lt;br /&gt;
			local i = next(a[1], a[0]) or a[0] == #a[1] and next(a[1])&lt;br /&gt;
			return pick(b, rawset(a.a or a, 0, i)[1][i])&lt;br /&gt;
		end, -- change rate (a.c) ignored since users control the table&amp;#039;s contents&lt;br /&gt;
		number = function(a, b)&lt;br /&gt;
			return pick(b, c(a, true))&lt;br /&gt;
		end,&lt;br /&gt;
		string = function(a, b)&lt;br /&gt;
			return pick(b, string.char(c(a)))&lt;br /&gt;
		end&lt;br /&gt;
	}, {__index = function(a, i)&lt;br /&gt;
		return a.a[i]&lt;br /&gt;
	end, __tostring = function(a, b)&lt;br /&gt;
	return (rawget(a, 0) and a[0] == tostring(a[0]) and rawset(a, 0, a[0]:byte()) or a).a._build(a, b) end}&lt;br /&gt;
	local function shift(t, c)&lt;br /&gt;
		t[0] = t[0] and t[0] + c or t:_build() and t[0] - t.c + c&lt;br /&gt;
		if t.table then&lt;br /&gt;
			t[0] = (t[0] - 1) % #t[1] + 1&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	function rebuild(...)&lt;br /&gt;
		local v, c = ...&lt;br /&gt;
		if v or select(&amp;#039;#&amp;#039;, ...) == 0 then&lt;br /&gt;
			if v and not c then&lt;br /&gt;
				return prev&lt;br /&gt;
			end&lt;br /&gt;
			local meta, c = select(v and 1 or 3, alt, c, same, 0)&lt;br /&gt;
			return setmetatable({a = prev, _build = meta.__tostring, c = c}, meta)&lt;br /&gt;
		elseif v == nil then&lt;br /&gt;
			-- no-op&lt;br /&gt;
		elseif c then&lt;br /&gt;
			shift(prev, c) -- v == false&lt;br /&gt;
		else prev:_build()&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	init, noCache = function(v, c)&lt;br /&gt;
		prev = setmetatable({v, c = c, _build = build[type(v)] or v, [type(v)] = true, alt = {}}, build)&lt;br /&gt;
		return prev&lt;br /&gt;
	end, true&lt;br /&gt;
	return init(...)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function unbuild(sep)&lt;br /&gt;
	for k, v in MBpairs(sep, nil) do&lt;br /&gt;
		k = getmetatable(v) if k and (k == build or k == alt) then&lt;br /&gt;
		shift(v.a or v, -v.c)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
		end&lt;br /&gt;
		function _var(self, ...)&lt;br /&gt;
			local obj if ... and ... ~= true then&lt;br /&gt;
			obj = init(...)&lt;br /&gt;
		elseif prev then&lt;br /&gt;
			if ... ~= false then&lt;br /&gt;
				obj = rebuild(...)&lt;br /&gt;
			else rebuild(...)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		return obj and MBi._(self, obj, nil, true) or self&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local lib; MBi = setmetatable({stream = _stream,&lt;br /&gt;
_inHTML = _inHTML,&lt;br /&gt;
_var = _var,&lt;br /&gt;
_ = function(self, v, ...)&lt;br /&gt;
	local at, raw = select(select(&amp;#039;#&amp;#039;, ...) == 1 and ... == true and 1 or 2, nil, ...)&lt;br /&gt;
	if raw then&lt;br /&gt;
		rawkey[self] = math.huge else v = Valid(v)&lt;br /&gt;
	end&lt;br /&gt;
	if v or raw then&lt;br /&gt;
		if at or rawkey[self] then&lt;br /&gt;
			raw = #self&lt;br /&gt;
		end -- if length increases by more than one after table.insert, then set rawkey[self] = math.huge; rawkey[self] may be equal to a previous &amp;#039;at&amp;#039;&lt;br /&gt;
		at, self.last_concat = at and (tonumber(at) ~= at and raw + at or at)&lt;br /&gt;
		table.insert(self, select(at and 1 or 2, at, v))&lt;br /&gt;
		if at and at &amp;lt; 0 or raw and #self - raw &amp;gt; 1 then&lt;br /&gt;
			rawkey[self] = math.huge elseif at and #self == raw then rawkey[self] = rawkey[self] and math.max(rawkey[self], at) or at&lt;br /&gt;
		end&lt;br /&gt;
	end -- above line looks bizarre because one table.insert op may make length jump from 0 to 8: local wtf = {[2] = 2,[4] = 4,[8] = 8}mw.log(#wtf,table.insert(wtf,1),#wtf)&lt;br /&gt;
	return self&lt;br /&gt;
end,&lt;br /&gt;
_nil = function(self, at, ...)&lt;br /&gt;
	if ... ~= true and ... ~= false then&lt;br /&gt;
		-- faster than type(...) ~= &amp;#039;boolean&amp;#039;&lt;br /&gt;
		if not at or at == &amp;#039;0&amp;#039; then&lt;br /&gt;
			self[#self] = ... if ... then&lt;br /&gt;
			rawkey[self] = math.huge&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		local n, v = tonumber(at), ...&lt;br /&gt;
		if n ~= at then&lt;br /&gt;
&lt;br /&gt;
			if n then&lt;br /&gt;
				n = #self + at&lt;br /&gt;
			elseif at ~= true and select(&amp;#039;#&amp;#039;, ...) == 0 then&lt;br /&gt;
				v, n = at, #self&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		if n then&lt;br /&gt;
&lt;br /&gt;
			if v == nil and n &amp;gt; 0 then&lt;br /&gt;
				table.remove(self, n)&lt;br /&gt;
			else self[math.floor(n)], rawkey[self] = v, math.huge&lt;br /&gt;
			end -- floor position for consistency with Table library&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	self.last_concat = nil&lt;br /&gt;
end&lt;br /&gt;
return self&lt;br /&gt;
		end,&lt;br /&gt;
		_all = function(self, t, valKey)&lt;br /&gt;
			for k, v in MBpairs(t) do&lt;br /&gt;
				MBmix(self, v, valKey)&lt;br /&gt;
			end&lt;br /&gt;
			for k, v in valKey and MBpairs(t, false) or noOp, t do&lt;br /&gt;
				if tonumber(v) then&lt;br /&gt;
					MBi._(self, k, v) -- self not always a buffer&lt;br /&gt;
				elseif rawget(MBi, k) and v and v ~= true then&lt;br /&gt;
					if v[1] == nil or getmetatable(v) then&lt;br /&gt;
						MBi[k](self, v)&lt;br /&gt;
					else MBi[k](self, unpack(v, 1, table.maxn(v)))&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			return self&lt;br /&gt;
		end,&lt;br /&gt;
		_str = function(t, ...)&lt;br /&gt;
			local n = select(&amp;#039;#&amp;#039;, ...)&lt;br /&gt;
			if n &amp;gt; 1 then&lt;br /&gt;
				local k, ops, seps, r = 2, MBselect(n, ...)&lt;br /&gt;
				r = MB(t(seps[1]))&lt;br /&gt;
				while parent[t] and ops &amp;gt; 1 and r:_(parent[t](seps[k]), 1) do&lt;br /&gt;
					t, k, ops = parent[t], k + 1, ops - 1&lt;br /&gt;
				end&lt;br /&gt;
				return table.concat(r, seps[k] or nil)&lt;br /&gt;
			end&lt;br /&gt;
			return MB.__call(t, ...)&lt;br /&gt;
		end,&lt;br /&gt;
		_in = function (self, ...)&lt;br /&gt;
			return parent(MB(...), self)&lt;br /&gt;
		end,&lt;br /&gt;
		_out = function(t, ...)&lt;br /&gt;
			if ... == 0 then&lt;br /&gt;
				return parent(t, parent[t], MBi._cc(t, t, MB.__call(t, (select(2, ...))), getmetatable(t)))&lt;br /&gt;
			end -- love how :_cc needed nothing new to implement this *self pat on back*&lt;br /&gt;
			local n = select(&amp;#039;#&amp;#039;, ...)&lt;br /&gt;
			if n &amp;gt; 1 then&lt;br /&gt;
				local k, ops, seps = 1, MBselect(n, ...)&lt;br /&gt;
				while parent[t] and ops &amp;gt; 0 do&lt;br /&gt;
					t, k, ops = parent[t]:_(t(seps[k])), k + 1, ops - 1&lt;br /&gt;
				end&lt;br /&gt;
			elseif parent[t] then&lt;br /&gt;
				return parent[t]:_(t(...))&lt;br /&gt;
			end&lt;br /&gt;
			return t&lt;br /&gt;
		end,&lt;br /&gt;
		_cc = function(self, clear, copy, meta)&lt;br /&gt;
			if clear then&lt;br /&gt;
				if rawequal(clear, copy) then&lt;br /&gt;
					return self, spec[MBi._cc] and setmetatable(spec[MBi._cc], MB) -- rawequal to avoid re-string via __eq in case both are different Buffer objects&lt;br /&gt;
				elseif copy == true then&lt;br /&gt;
					copy = self&lt;br /&gt;
				end&lt;br /&gt;
				if clear ~= 0 then&lt;br /&gt;
					assert(type(clear) == &amp;#039;table&amp;#039;, debug.traceback(&amp;#039;Buffer:_cc can only &amp;quot;clear&amp;quot; tables. Did you forget to call with a colon?&amp;#039;, 2)) -- errors can be hard to trace without this&lt;br /&gt;
					for k in self and next or noOp, clear do&lt;br /&gt;
						rawset(clear, k, nil)&lt;br /&gt;
					end&lt;br /&gt;
				else&lt;br /&gt;
					return MBi._cc(false, {unpack(copy)}, copy)&lt;br /&gt;
				end -- copy length w/o empty strings; recursion to avoid self = false causing garbage collection (non-weak child may exist)&lt;br /&gt;
				if self == false or copy and type(copy) == &amp;#039;table&amp;#039; then&lt;br /&gt;
					-- self == false means copy is a table (saves a type op for recursive calls)&lt;br /&gt;
					meta = meta or getmetatable(copy)&lt;br /&gt;
					if self and #copy &amp;gt; 1 then&lt;br /&gt;
						-- preserves length with empty strings; developed from studying http://www.lua.org/source/5.1/ltable.c.html		&lt;br /&gt;
						local n, null, i, e = #copy, {}, math.ldexp(2, select(2, math.frexp(#copy)) - 2)&lt;br /&gt;
						e, spec[MBi._cc], parent[null] = i - 1, null, clear&lt;br /&gt;
						for k = 1, e do&lt;br /&gt;
							table.insert(clear, false)&lt;br /&gt;
						end&lt;br /&gt;
						while i &amp;lt;= n do&lt;br /&gt;
							table.insert(clear, i, &amp;#039;&amp;#039;) i, null[i] = i + math.ldexp(2, select(2, math.frexp(n - i)) - 2), &amp;#039;&amp;#039;&lt;br /&gt;
						end&lt;br /&gt;
						for k = 1, e do&lt;br /&gt;
							rawset(clear, k, nil)&lt;br /&gt;
						end&lt;br /&gt;
					end&lt;br /&gt;
					for k, v in next, copy do&lt;br /&gt;
						rawset(clear, k, type(v) == &amp;#039;table&amp;#039; and MBi._cc(false, 0, v) or v)&lt;br /&gt;
					end&lt;br /&gt;
				elseif copy then&lt;br /&gt;
					rawset(clear, 1, (Valid(copy)))&lt;br /&gt;
				end&lt;br /&gt;
				rawkey[setmetatable(clear, meta)], parent[clear] = rawkey[copy], parent[copy]&lt;br /&gt;
			end&lt;br /&gt;
			return self and rawset(self, &amp;#039;last_concat&amp;#039;, nil) or clear&lt;br /&gt;
		end,&lt;br /&gt;
		_parent = function(self, ...)&lt;br /&gt;
			return parent[self] and MBi._(self, parent[self]:_str(...)) or self&lt;br /&gt;
		end,&lt;br /&gt;
		getParent = function(self, ...)&lt;br /&gt;
			return isMBfunc(parent[self] or parent[parent(self, setmetatable({}, MB))], ...)&lt;br /&gt;
		end,&lt;br /&gt;
		killParent = function(self, ...)&lt;br /&gt;
			return parent[self] and isMBfunc(parent[self], ...) and parent(self) or self&lt;br /&gt;
		end,&lt;br /&gt;
		_build = function(self, t)&lt;br /&gt;
			table.insert(t, self())&lt;br /&gt;
		end, -- for compatibility with mw.html:node()&lt;br /&gt;
		last_concat = false -- prevent library check&lt;br /&gt;
	}, {__index = function(t, i)&lt;br /&gt;
		-- import string, mw.text, and mw.ustring libraries on an as-needed basis&lt;br /&gt;
		local func = string[i] or mw.text[i] or mw.ustring[i] or type(i) == &amp;#039;string&amp;#039; and mw.ustring[i:match&amp;#039;^u(.+)&amp;#039;] if func then&lt;br /&gt;
		lib	= lib or function (s, f, ...)&lt;br /&gt;
			if parent[s] and next(s) == nil then&lt;br /&gt;
				return s:_((f(tostring(parent[Element and (spec[s] == Element and s:allDone() or spec[parent[s]] == Element and parent[s]) or s]), ...)))&lt;br /&gt;
			end&lt;br /&gt;
			return f(tostring(s), ...) -- not using ternary/logical operators here to allow multiple return values&lt;br /&gt;
		end&lt;br /&gt;
		return rawset(t, i, i:match&amp;#039;^u?gsub&amp;#039; and function(self, p, r, ...)return lib(self, func, p, r or &amp;#039;&amp;#039;, ...)end -- Why are ugsub/gsub special? because empty strings are against my religion!&lt;br /&gt;
		or function(self, ...)return lib(self, func, ...)end)[i]&lt;br /&gt;
	end&lt;br /&gt;
end})&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function MBmix(t, v, ...)&lt;br /&gt;
	return v and ((type(v) ~= &amp;#039;table&amp;#039; or getmetatable(v)) and MBi._(t, v) or (select(&amp;#039;#&amp;#039;, ...) == 0 and spec[t] and spec[t]._add or MBi._all)(t, v, ...)) or t&lt;br /&gt;
end -- :_all always passes two args&lt;br /&gt;
&lt;br /&gt;
local _G, new_G = _G -- localize _G for console testing (console _G ~= module _G)&lt;br /&gt;
return setmetatable({__index = function(t, i)&lt;br /&gt;
	return spec[t] and spec[t][i] or MBi[i]&lt;br /&gt;
end,&lt;br /&gt;
__call = function(t, ...)&lt;br /&gt;
	local rawsep, sep, i, j, raw = noCache and rawkey[...] and ..., ...&lt;br /&gt;
	if i or j or rawsep or Valid(sep) then&lt;br /&gt;
		raw, sep, i, j = rawkey[spec[t]] or rawkey[t], rawsep or Valid(sep), i and (i ~= tonumber(i) and i + #t or i), j and (j ~= tonumber(j) and j + #t or j)&lt;br /&gt;
		if rawsep or raw and (raw &amp;gt;= (j or #t) or i &amp;lt; 1) then&lt;br /&gt;
			raw, i, j = {}, i and math.floor(i), j and math.floor(j) -- floor for consistency with table.concat(t, sep, i, j), which ignores decimals&lt;br /&gt;
			raw.lc, t.last_concat = t.last_concat -- temporarily unset last_concat to prevent disqualification from mapless iteration&lt;br /&gt;
			for k, v in MBpairs(t) do&lt;br /&gt;
				if raw[1] or not i or k &amp;gt;= i then&lt;br /&gt;
					if j and k &amp;gt; j then break&lt;br /&gt;
					end&lt;br /&gt;
					if raw.s then&lt;br /&gt;
						raw.s = table.insert(raw, tostring(sep))&lt;br /&gt;
					end -- if sep contains v and v is a Buffer-variable, sep must be strung before v&lt;br /&gt;
					k = Valid(v) if k then&lt;br /&gt;
					raw.s = rawsep or sep and raw[1] and table.insert(raw, sep)&lt;br /&gt;
					table.insert(raw, k)&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		if rawsep and not raw.s then&lt;br /&gt;
			raw[#raw] = unbuild(sep)&lt;br /&gt;
		end -- unbuild rawsep if final index in t was invalid&lt;br /&gt;
		t.last_concat = raw.lc&lt;br /&gt;
		return table.concat(raw)&lt;br /&gt;
	end&lt;br /&gt;
	return table.concat(t, sep, i and math.max(i, 1), j and math.min(j, #t))&lt;br /&gt;
end&lt;br /&gt;
return MB.__tostring(t)&lt;br /&gt;
	end,&lt;br /&gt;
	__tostring = function(t)&lt;br /&gt;
		if t.last_concat then&lt;br /&gt;
			return t.last_concat&lt;br /&gt;
		end&lt;br /&gt;
		local r = rawkey[spec[t]] or rawkey[t]&lt;br /&gt;
		r = table.concat(r and r &amp;gt;= #t and MBi._all({}, t) or t)&lt;br /&gt;
		return (noCache or rawset(t, &amp;#039;last_concat&amp;#039;, r)) and r&lt;br /&gt;
	end,&lt;br /&gt;
	__concat = function(a, b)&lt;br /&gt;
		if buffHTML then&lt;br /&gt;
			for k = 1, 2 do&lt;br /&gt;
				local v = select(k, a, b) -- faster than for k, v in pairs{a, b} do&lt;br /&gt;
				if v and spec[v] and spec[v] == Element then&lt;br /&gt;
					if parent[v].selfClosing then&lt;br /&gt;
						if rawequal(a, b) then&lt;br /&gt;
							return (not noCache or parent[v].tagName) and v:_str(0):rep(2) or v:_str(0)..v:_str(0)&lt;br /&gt;
						end -- rawequal avoids premature tostring of Buffer:_var objects;&lt;br /&gt;
						b, a = select(k, b, parent[v], a)&lt;br /&gt;
					else local temp = Element .. v --helper method; returns a mirror of parent[v]&lt;br /&gt;
						MBmix(MBmix(parent(temp.nodes, temp), a), k == 1 and spec[b] == Element and parent[b] or b)&lt;br /&gt;
						return buffHTML.__tostring(setmetatable(temp, {__index = parent[v], __mode = &amp;#039;v&amp;#039;})) -- switch from tempMeta to avoid MBi._cc op of styles/attributes&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		return table.concat(MBmix(MBmix({}, a), b))&lt;br /&gt;
	end,&lt;br /&gt;
	__pairs = MBpairs,&lt;br /&gt;
	__ipairs = MBpairs,&lt;br /&gt;
	__eq = function(a, b)&lt;br /&gt;
		return tostring(a) == tostring(b)&lt;br /&gt;
	end -- avoid a == b in this module; use rawequal(a,b) when they may be different Buffers (premature tostring waste ops and is bad for Buffer:_var)&lt;br /&gt;
}, {__tostring = function()return&amp;#039;&amp;#039;end,&lt;br /&gt;
__call = function(self, ...)&lt;br /&gt;
	MB = MB or self&lt;br /&gt;
	if new_G then&lt;br /&gt;
		if ... and _G and ... == _G then new_G = ...&lt;br /&gt;
		end&lt;br /&gt;
	elseif ... and (... == _G or type(...) == &amp;#039;table&amp;#039; and (...)._G == ...) then&lt;br /&gt;
		local Nil, mG = {}, (...):getmetatable() or (...):setmetatable{}:getmetatable()&lt;br /&gt;
		new_G, _G, gfuncs = ..., ..., { -- gfuncs stored for Buffer:_inHTML; new_G is a is a Module:Buffer local declared just before the final return statement.&lt;br /&gt;
		_G = function(self, i, ...)&lt;br /&gt;
			local X, save = rawget(new_G, i), select(&amp;#039;#&amp;#039;, ...) == 0 and self or ...&lt;br /&gt;
			if i and i ~= true and not (X and save and rawequal(X, save)) and rawset(new_G, i, save) and (X ~= nil or save == nil and new_G[i] ~= nil) then&lt;br /&gt;
				-- rawequal in case X is another buffer&lt;br /&gt;
				local mG = getmetatable(new_G) or {__call = mG.__call}&lt;br /&gt;
				if mG.__index then&lt;br /&gt;
					pcall(rawset, mG.__index, i, X)&lt;br /&gt;
				else mG.__index = setmetatable(new_G, mG) and {[i] = X}&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			return self, ... -- avoiding __eq with rawequal(self,save) is overkill since buffers can self-save without being passed as save&lt;br /&gt;
		end,&lt;br /&gt;
		_R = function(self, i, v, m)&lt;br /&gt;
			if i ~= &amp;#039;new_G&amp;#039; then&lt;br /&gt;
				if i and i ~= true then rawset(new_G, i , v)&lt;br /&gt;
				end&lt;br /&gt;
			elseif not v or v == true or v._G ~= _G then&lt;br /&gt;
				new_G = setmetatable(v ~= true and v or {}, {__call = mG.__call, __index = v ~= true and m ~= true and (m or new_G) or nil})&lt;br /&gt;
			else new_G, (not m and (m ~= nil or v == new_G) and Nil or getmetatable(v)).__index = v, m ~= true and (m or new_G) or nil&lt;br /&gt;
			end -- setting Nil.__index is noOp&lt;br /&gt;
			return self&lt;br /&gt;
		end,&lt;br /&gt;
		_2 = function(self, ...)&lt;br /&gt;
			if new_G[...] ~= nil then&lt;br /&gt;
				return new_G[...]&lt;br /&gt;
			end -- higher priority so Buffer:_G(&amp;#039;new_G&amp;#039;, ...) can prevent an overwrite&lt;br /&gt;
			if ... == &amp;#039;new_G&amp;#039; then&lt;br /&gt;
				return rawset((select(&amp;#039;#&amp;#039;, ...) ~= 1 and MBi._R(new_G, ...) or new_G), &amp;#039;_G&amp;#039;, _G)&lt;br /&gt;
			end&lt;br /&gt;
			return select(select(&amp;#039;#&amp;#039;, ...) == 1 and 1 or 2, self:_G(...)) --return only one value; &amp;#039;return select(2, self:_G(...)) or self&amp;#039; doesn&amp;#039;t work for returning nil&lt;br /&gt;
		end,&lt;br /&gt;
		_B = function(self, v)&lt;br /&gt;
			return v or v == nil and Nil&lt;br /&gt;
		end&lt;br /&gt;
	} for k, v in next, gfuncs do&lt;br /&gt;
	MBi[k] = v&lt;br /&gt;
end &lt;br /&gt;
setmetatable(Nil,{__concat = MB.__concat,__newindex = noOp,__call = noOp,__tostring = noOp,__metatable = MB,__index = setmetatable({_B = MBi._B,_ = function()return Nil&lt;br /&gt;
end,last_concat = &amp;#039;&amp;#039;},&lt;br /&gt;
{__index = function(t,i)return (MBi[i] or i and not tonumber(i)) and t._ or nil&lt;br /&gt;
end})})&lt;br /&gt;
function mG.__call(G, k, ...)&lt;br /&gt;
	return (k._G or G.type(k) == &amp;#039;table&amp;#039;) and (G.select(&amp;#039;#&amp;#039;, ...) ~= 1 and G.rawset(k, ...) or G:rawset(..., k) and k) or G:rawset(k, (...)) and ...&lt;br /&gt;
end&lt;br /&gt;
		end&lt;br /&gt;
		local new = setmetatable({}, self)&lt;br /&gt;
		if ... and (...) == new_G then&lt;br /&gt;
			return select(2, ...) and MBmix(new:_G((select(2, ...))), select(3, ...)) or new&lt;br /&gt;
		end&lt;br /&gt;
		return ... and MBi._(new, ...) or new&lt;br /&gt;
	end,&lt;br /&gt;
	__index = function(t, i)&lt;br /&gt;
		MB = MB or t&lt;br /&gt;
		return MBi[i] and function(...)&lt;br /&gt;
			return MBi[i](setmetatable({}, t), select(... == t and 2 or 1,...))&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
})&lt;/div&gt;</summary>
		<author><name>imported&gt;Neils51</name></author>
	</entry>
</feed>