local kbdPrefix =
	'<kbd class=' ..
	'"keyboard-key nowrap" ' ..
	'style="border: 1px solid #aaa; ' ..
	-- The following is an expansion of 
	'-moz-border-radius: 0.2em; -webkit-border-radius: 0.2em; border-radius: 0.2em; ' ..
	-- The following is an expansion of 
	'-moz-box-shadow: 0.1em 0.1em 0.2em rgba; -webkit-box-shadow: 0.1em 0.1em 0.2em rgba; box-shadow: 0.1em 0.1em 0.2em rgba; ' ..
	'background-color: #f9f9f9; ' ..
	-- The following is an expansion of 
	'background-image: -moz-linear-gradient; background-image: -o-linear-gradient; background-image: -webkit-linear-gradient; background-image: linear-gradient; ' ..
	'padding: 0.1em 0.3em; ' ..
	'font-family: inherit; ' ..
	'font-size: 0.85em;">'

local kbdSuffix = ''

local keyText = {
	['caps lock'] = '⇪ Caps Lock',
	['캡스 락'] = '⇪ Caps Lock',
	['캡스 락'] = '⇪ Caps Lock',
	['shift'] = '⇧ Shift',
	['시프트'] = '⇧ Shift',
	['shift'] = '⇧ Shift',
	['enter'] = '↵ Enter',
	['엔터'] = '↵ Enter',
	['enter'] = '↵ Enter',
	['cmd'] = '⌘ Cmd',
	['cmd'] = '⌘ Cmd',
	['command'] = '⌘ Command',
	['커맨드'] = '⌘ Command',
	['Command'] = '⌘ Command',
	['opt'] = '⌥ Opt',
	['opt'] = '⌥ Opt',
	['option'] = '⌥ Option',
	['Option'] = '⌥ Option',
	['tab'] = 'Tab ↹',
	['탭'] = 'Tab ↹',
	['tab'] = 'Tab ↹',
	['backspace'] = '← Backspace',
	['백스페이스'] = '← Backspace',
	['백스페이스'] = '← Backspace',
	['win'] = '⊞ Win',
	['윈도'] = '⊞ Win',
	['윈도우'] = '⊞ Win',
	['win'] = '⊞ Win',
	['menu'] = '≣ Menu',
	['메뉴'] = '≣ Menu',
	['menu'] = '≣ Menu',
	['up'] = '↑',
	['위'] = '↑',
	['위'] = '↑',
	['down'] = '↓',
	['아래'] = '↓',
	['down'] = '↓',
	['left'] = '←',
	['왼쪽'] = '←',
	['left'] = '←',
	['right'] = '→',
	['오른쪽'] = '→',
	['right'] = '→',
	['asterisk'] = '&#42;',
	['별표'] = '&#42;',
	['hash'] = '&#35;',
	['해시'] = '&#35;',
	['#'] = '#',
	['colon'] = '&#58;',
	['콜론'] = '&#58;',
	[':'] = ':',
	['pipe'] = '&#124;',
	['파이프'] = '&#124;',
	['|'] = '&#124;',
	['semicolon'] = '&#59;',
	['세미콜론'] = '&#59;',
	[';'] = '&#59;',
	['equals'] = '&#61;',
	['등호'] = '&#61;',

	-- Left & right analog sticks.
	['l up'] = 'L↑',
	['l down'] = 'L↓',
	['l left'] = 'L←',
	['l right'] = 'L→',
	['l ne'] = 'L↗',
	['l se'] = 'L↘',
	['l nw'] = 'L↖',
	['l sw'] = 'L↙',

	['r up'] = 'R↑',
	['r down'] = 'R↓',
	['r left'] = 'R←',
	['r right'] = 'R→',
	['r ne'] = 'R↗',
	['r se'] = 'R↘',
	['r nw'] = 'R↖',
	['r sw'] = 'R↙',

	-- PlayStation.
	['ex'] = '×',
	['circle'] = '○',
	['square'] = '□',
	['triangle'] = '△',

	-- Nintendo 64 and GameCube.
	['c up'] = 'C↑',
	['c down'] = 'C↓',
	['c left'] = 'C←',
	['c right'] = 'C→',
	['c ne'] = 'C↗',
	['c se'] = 'C↘',
	['c nw'] = 'C↖',
	['c sw'] = 'C↙',

local keyAlias = {
	-- ['alternate name for key (alias)'] = 'name for key used in key table'
	['cmd'] = 'cmd',
	['command'] = 'command',
	['opt'] = 'opt',
	['옵션 키'] = 'option',
	['option'] = 'option',
	['win'] = 'win',
	['*'] = 'asterisk',
	['#'] = 'hash',
	[':'] = 'colon',
	[';'] = 'semicolon',
	['l-up'] = 'l up',
	['l-down'] = 'l down',
	['l-left'] = 'l left',
	['l-right'] = 'l right',
	['l-ne'] = 'l ne',
	['l-se'] = 'l se',
	['l-nw'] = 'l nw',
	['l-sw'] = 'l sw',
	['r-up'] = 'r up',
	['r-down'] = 'r down',
	['r-left'] = 'r left',
	['r-right'] = 'r right',
	['r-ne'] = 'r ne',
	['r-se'] = 'r se',
	['r-nw'] = 'r nw',
	['r-sw'] = 'r sw',
	['ps x'] = 'ex',
	['ps c'] = 'circle',
	['ps s'] = 'square',
	['ps t'] = 'triangle',
	['c-up'] = 'c up',
	['c-down'] = 'c down',
	['c-left'] = 'c left',
	['c-right'] = 'c right',
	['c-ne'] = 'c ne',
	['c-se'] = 'c se',
	['c-nw'] = 'c nw',
	['c-sw'] = 'c sw',

local Collection = {}
Collection.__index = Collection
do
	function Collection:add(item)
		if item ~= nil then
			self.n = self.n + 1
			self[self.n] = item
		end
	end
	function Collection:join(sep)
		return table.concat
	end
	function Collection:sort(comp)
		table.sort
	end
	function Collection.new
		return setmetatable
	end
end

local function keyPress(args)
	local chainNames = {
		'chain first',
		'chain second',
		'chain third',
		'chain fourth',
		'chain fifth',
		'chain sixth',
		'chain seventh',
		'chain eighth',
		'chain ninth',
	local result = Collection.new
	local chainDefault = args.chain or '+'
	for i, id in ipairs(args) do
		if i > 1 then
			result:add(args[chainNames[i - 1]] or chainDefault)
		end
		local lc = id:lower
		local text = keyText[lc] or keyText[keyAlias[lc]] or id
		result:add(kbdPrefix .. text .. kbdSuffix)
	end
	return result:join
end

local function keypress(frame)
	-- Called by "".
	-- Using the template doubles the post‐expand include size.
	return keyPress(frame:getParent.args)
end

local function press(frame)
	-- Called by "".
	return keyPress(frame.args)
end

return {
	keypress = keypress,
	press = press,