<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.pokemonrevolution.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Cae</id>
	<title>Pokemon Revolution Online Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.pokemonrevolution.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Cae"/>
	<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Special:Contributions/Cae"/>
	<updated>2026-08-20T21:52:55Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.45.3</generator>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Inteleon&amp;diff=41086</id>
		<title>Inteleon</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Inteleon&amp;diff=41086"/>
		<updated>2026-08-09T17:45:14Z</updated>

		<summary type="html">&lt;p&gt;Cae: created page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{PokemonInfoAndNav}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;{{PAGENAME}}&#039;&#039;&#039; is the [[Water (type)|Water]]-type starter of Galar, the 8th Region in the franchise. Though, that region is not available to explore in PRO. It evolves from [[Drizzile]] as early as level 35 and is the final evolution of [[Sobble]].&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obtainability==&lt;br /&gt;
{{PokemonSpawnData}}&lt;br /&gt;
The primary way of obtaining a {{PAGENAME}} is by evolving a [[Grookey]].&lt;br /&gt;
&lt;br /&gt;
{{Learnsets|{{PAGENAME}}}}&lt;br /&gt;
&lt;br /&gt;
==Type Effectiveness==&lt;br /&gt;
{{PokemonTypeEffectiveness}}&lt;br /&gt;
&lt;br /&gt;
==Special Counterparts==&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Shiny_Inteleon.png|Shiny Inteleon&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Drizzile&amp;diff=41085</id>
		<title>Drizzile</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Drizzile&amp;diff=41085"/>
		<updated>2026-08-09T17:45:10Z</updated>

		<summary type="html">&lt;p&gt;Cae: created page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{PokemonInfoAndNav}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;{{PAGENAME}}&#039;&#039;&#039; is the [[Water (type)|Water]]-type starter of Galar, the 8th Region in the franchise. Though, that region is not available to explore in PRO. It evolves from [[Sobble]] as early as level 16 and evolves into [[Inteleon]] at level 35.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obtainability==&lt;br /&gt;
{{PokemonSpawnData}}&lt;br /&gt;
The primary way of obtaining a {{PAGENAME}} is by evolving a [[Grookey]].&lt;br /&gt;
&lt;br /&gt;
{{Learnsets|{{PAGENAME}}}}&lt;br /&gt;
&lt;br /&gt;
==Type Effectiveness==&lt;br /&gt;
{{PokemonTypeEffectiveness}}&lt;br /&gt;
&lt;br /&gt;
==Special Counterparts==&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Shiny_Drizzile.png|Shiny Drizzile&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Sobble&amp;diff=41084</id>
		<title>Sobble</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Sobble&amp;diff=41084"/>
		<updated>2026-08-09T17:45:06Z</updated>

		<summary type="html">&lt;p&gt;Cae: created page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{PokemonInfoAndNav}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;{{PAGENAME}}&#039;&#039;&#039; is the [[Water (type)|Water]]-type starter of Galar, the 8th Region in the franchise. Though, that region is not available to explore in PRO. It evolves into [[Drizzile]] as early as level 16.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obtainability==&lt;br /&gt;
{{PokemonSpawnData}}&lt;br /&gt;
&lt;br /&gt;
{{Learnsets|{{PAGENAME}}}}&lt;br /&gt;
&lt;br /&gt;
==Type Effectiveness==&lt;br /&gt;
{{PokemonTypeEffectiveness}}&lt;br /&gt;
&lt;br /&gt;
==Special Counterparts==&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Shiny_Sobble.png|Shiny Sobble&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Cinderace&amp;diff=41083</id>
		<title>Cinderace</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Cinderace&amp;diff=41083"/>
		<updated>2026-08-09T17:45:02Z</updated>

		<summary type="html">&lt;p&gt;Cae: created page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{PokemonInfoAndNav}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;{{PAGENAME}}&#039;&#039;&#039; is the [[Fire (type)|Fire ]]-type starter of Galar, the 8th Region in the franchise. Though, that region is not available to explore in PRO. It evolves from [[Raboot]] as early as level 35 and is the final evolution of [[Scorbunny]].&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obtainability==&lt;br /&gt;
{{PokemonSpawnData}}&lt;br /&gt;
The primary way of obtaining a {{PAGENAME}} is by evolving a [[Scorbunny]].&lt;br /&gt;
&lt;br /&gt;
{{Learnsets|{{PAGENAME}}}}&lt;br /&gt;
&lt;br /&gt;
==Type Effectiveness==&lt;br /&gt;
{{PokemonTypeEffectiveness}}&lt;br /&gt;
&lt;br /&gt;
==Special Counterparts==&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Shiny_Cinderace.png|Shiny Cinderace&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Raboot&amp;diff=41082</id>
		<title>Raboot</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Raboot&amp;diff=41082"/>
		<updated>2026-08-09T17:44:59Z</updated>

		<summary type="html">&lt;p&gt;Cae: created page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{PokemonInfoAndNav}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;{{PAGENAME}}&#039;&#039;&#039; is the [[Fire (type)|Fire ]]-type starter of Galar, the 8th Region in the franchise. Though, that region is not available to explore in PRO. It evolves from [[Scorbunny]] as early as level 16 and evolves into [[Cinderace]] at level 35.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obtainability==&lt;br /&gt;
{{PokemonSpawnData}}&lt;br /&gt;
The primary way of obtaining a {{PAGENAME}} is by evolving a [[Scorbunny]].&lt;br /&gt;
&lt;br /&gt;
{{Learnsets|{{PAGENAME}}}}&lt;br /&gt;
&lt;br /&gt;
==Type Effectiveness==&lt;br /&gt;
{{PokemonTypeEffectiveness}}&lt;br /&gt;
&lt;br /&gt;
==Special Counterparts==&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Shiny_Raboot.png|Shiny Raboot&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Scorbunny&amp;diff=41081</id>
		<title>Scorbunny</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Scorbunny&amp;diff=41081"/>
		<updated>2026-08-09T17:44:57Z</updated>

		<summary type="html">&lt;p&gt;Cae: created page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{PokemonInfoAndNav}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;{{PAGENAME}}&#039;&#039;&#039; is the [[Fire (type)|Fire ]]-type starter of Galar, the 8th Region in the franchise. Though, that region is not available to explore in PRO. It evolves into [[Raboot]] as early as level 16.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obtainability==&lt;br /&gt;
{{PokemonSpawnData}}&lt;br /&gt;
&lt;br /&gt;
{{Learnsets|{{PAGENAME}}}}&lt;br /&gt;
&lt;br /&gt;
==Type Effectiveness==&lt;br /&gt;
{{PokemonTypeEffectiveness}}&lt;br /&gt;
&lt;br /&gt;
==Special Counterparts==&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Shiny_Scorbunny.png|Shiny Scorbunny&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Rillaboom&amp;diff=41080</id>
		<title>Rillaboom</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Rillaboom&amp;diff=41080"/>
		<updated>2026-08-09T17:44:51Z</updated>

		<summary type="html">&lt;p&gt;Cae: created page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{PokemonInfoAndNav}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;{{PAGENAME}}&#039;&#039;&#039; is the [[Grass (type)|Grass]]-type starter of Galar, the 8th Region in the franchise. Though, that region is not available to explore in PRO. It evolves from [[Thwackey]] as early as level 35 and is the final evolution of [[Grookey]].&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obtainability==&lt;br /&gt;
{{PokemonSpawnData}}&lt;br /&gt;
The primary way of obtaining a {{PAGENAME}} is by evolving a [[Grookey]].&lt;br /&gt;
&lt;br /&gt;
{{Learnsets|{{PAGENAME}}}}&lt;br /&gt;
&lt;br /&gt;
==Type Effectiveness==&lt;br /&gt;
{{PokemonTypeEffectiveness}}&lt;br /&gt;
&lt;br /&gt;
==Special Counterparts==&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Shiny_Rillaboom.png|Shiny Rillaboom&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Thwackey&amp;diff=41079</id>
		<title>Thwackey</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Thwackey&amp;diff=41079"/>
		<updated>2026-08-09T17:44:44Z</updated>

		<summary type="html">&lt;p&gt;Cae: created page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{PokemonInfoAndNav}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;{{PAGENAME}}&#039;&#039;&#039; is the [[Grass (type)|Grass]]-type starter of Galar, the 8th Region in the franchise. Though, that region is not available to explore in PRO. It evolves from [[Grookey]] as early as level 16 and evolves into [[Rillaboom]] at level 35.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obtainability==&lt;br /&gt;
{{PokemonSpawnData}}&lt;br /&gt;
The primary way of obtaining a {{PAGENAME}} is by evolving a [[Grookey]].&lt;br /&gt;
&lt;br /&gt;
{{Learnsets|{{PAGENAME}}}}&lt;br /&gt;
&lt;br /&gt;
==Type Effectiveness==&lt;br /&gt;
{{PokemonTypeEffectiveness}}&lt;br /&gt;
&lt;br /&gt;
==Special Counterparts==&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Shiny_Thwackey.png|Shiny Thwackey&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Grookey&amp;diff=41078</id>
		<title>Grookey</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Grookey&amp;diff=41078"/>
		<updated>2026-08-09T17:44:31Z</updated>

		<summary type="html">&lt;p&gt;Cae: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{PokemonInfoAndNav}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;{{PAGENAME}}&#039;&#039;&#039; is the [[Grass (type)|Grass]]-type starter of Galar, the 8th Region in the franchise. Though, that region is not available to explore in PRO. It evolves into [[Thwackey]] as early as level 16.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obtainability==&lt;br /&gt;
{{PokemonSpawnData}}&lt;br /&gt;
&lt;br /&gt;
{{Learnsets|{{PAGENAME}}}}&lt;br /&gt;
&lt;br /&gt;
==Type Effectiveness==&lt;br /&gt;
{{PokemonTypeEffectiveness}}&lt;br /&gt;
&lt;br /&gt;
==Special Counterparts==&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Shiny_Grookey.png|Shiny Grookey&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Module:Pokemon&amp;diff=41077</id>
		<title>Module:Pokemon</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Module:Pokemon&amp;diff=41077"/>
		<updated>2026-08-09T13:39:45Z</updated>

		<summary type="html">&lt;p&gt;Cae: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {}&lt;br /&gt;
&lt;br /&gt;
local DATA_FORMAT = &#039;CSV with header&#039;&lt;br /&gt;
&lt;br /&gt;
local COLUMNS = {&lt;br /&gt;
	number = &#039;Pokedex Number&#039;,&lt;br /&gt;
	name = &#039;Name&#039;,&lt;br /&gt;
	type1 = &#039;Type1&#039;,&lt;br /&gt;
	type2 = &#039;Type2&#039;,&lt;br /&gt;
	ability1 = &#039;Ability 1&#039;,&lt;br /&gt;
	ability2 = &#039;Ability 2&#039;,&lt;br /&gt;
	ha = &#039;Hidden Ability&#039;,&lt;br /&gt;
	generation = &#039;Generation&#039;,&lt;br /&gt;
	hp = &#039;HP&#039;,&lt;br /&gt;
	atk = &#039;Attack&#039;,&lt;br /&gt;
	def = &#039;Defense&#039;,&lt;br /&gt;
	spatk = &#039;Special Attack&#039;,&lt;br /&gt;
	spdef = &#039;Special Defense&#039;,&lt;br /&gt;
	spd = &#039;Speed&#039;,&lt;br /&gt;
	catch = &#039;Catch Rate&#039;,&lt;br /&gt;
	evhp = &#039;EVHP&#039;,&lt;br /&gt;
	evatk = &#039;EVATK&#039;,&lt;br /&gt;
	evdef = &#039;EVDEF&#039;,&lt;br /&gt;
	evspa = &#039;EVSPA&#039;,&lt;br /&gt;
	evspd = &#039;EVSPD&#039;,&lt;br /&gt;
	evsp = &#039;EVSP&#039;,&lt;br /&gt;
	male = &#039;Male Ratio&#039;,&lt;br /&gt;
	height = &#039;Height&#039;,&lt;br /&gt;
	weight = &#039;Weight&#039;,&lt;br /&gt;
	npc = &#039;NPC&#039;,&lt;br /&gt;
	exp = &#039;Base Experience&#039;,&lt;br /&gt;
	rarity = &#039;Tier&#039;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local GEN_NUMERALS = { &#039;I&#039;, &#039;II&#039;, &#039;III&#039;, &#039;IV&#039;, &#039;V&#039;, &#039;VI&#039;, &#039;VII&#039;, &#039;VIII&#039;, &#039;IX&#039; }&lt;br /&gt;
&lt;br /&gt;
local STATS = {&lt;br /&gt;
	{ key = &#039;hp&#039;, label = &#039;HP&#039;, template = &#039;HP&#039; },&lt;br /&gt;
	{ key = &#039;atk&#039;, label = &#039;Atk&#039;, template = &#039;Attack&#039; },&lt;br /&gt;
	{ key = &#039;def&#039;, label = &#039;Def&#039;, template = &#039;Defense&#039; },&lt;br /&gt;
	{ key = &#039;spatk&#039;, label = &#039;Sp.Atk&#039;, template = &#039;Special Attack&#039; },&lt;br /&gt;
	{ key = &#039;spdef&#039;, label = &#039;Sp.Def&#039;, template = &#039;Special Defense&#039; },&lt;br /&gt;
	{ key = &#039;spd&#039;, label = &#039;Spd&#039;, template = &#039;Speed&#039; },&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local EV_KEYS = { &#039;evhp&#039;, &#039;evatk&#039;, &#039;evdef&#039;, &#039;evspa&#039;, &#039;evspd&#039;, &#039;evsp&#039; }&lt;br /&gt;
&lt;br /&gt;
local function nonEmpty(s)&lt;br /&gt;
	if s == nil then return nil end&lt;br /&gt;
	s = mw.text.trim(tostring(s))&lt;br /&gt;
	if s == &#039;&#039; then return nil end&lt;br /&gt;
	return s&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function templateArgs(frame)&lt;br /&gt;
	local parent = frame:getParent()&lt;br /&gt;
	return (parent and parent.args) or frame.args&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function padNumber(n)&lt;br /&gt;
	n = tonumber(n) or 0&lt;br /&gt;
	return string.format(&#039;%03d&#039;, n)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local PokemonForms = require(&#039;Module:PokemonForms&#039;)&lt;br /&gt;
local FORM_SUFFIXES = PokemonForms.FORM_SUFFIXES&lt;br /&gt;
local STRIP_SUFFIXES = PokemonForms.STRIP_SUFFIXES&lt;br /&gt;
local MEGA_VARIANTS = PokemonForms.MEGA_VARIANTS or { &#039;&#039;, &#039; X&#039;, &#039; Y&#039; }&lt;br /&gt;
&lt;br /&gt;
-- The single data fetch: the whole raw list is loaded once per page render&lt;br /&gt;
-- and every lookup (by name, by number, form probing) reads from it.&lt;br /&gt;
local allRowsCache = nil&lt;br /&gt;
local numberIndexCache = nil&lt;br /&gt;
&lt;br /&gt;
local function loadAllRows()&lt;br /&gt;
	if allRowsCache then&lt;br /&gt;
		return allRowsCache&lt;br /&gt;
	end&lt;br /&gt;
	local csvData = mw.ext.externalData.getExternalData{&lt;br /&gt;
		url = &#039;https://wiki.pokemonrevolution.net/index.php?title=Special:GetData/PokemonRawList&#039;,&lt;br /&gt;
		format = DATA_FORMAT,&lt;br /&gt;
		data = COLUMNS,&lt;br /&gt;
	}&lt;br /&gt;
	allRowsCache = {}&lt;br /&gt;
	numberIndexCache = {}&lt;br /&gt;
	if csvData then&lt;br /&gt;
		for _, row in ipairs(csvData) do&lt;br /&gt;
			if nonEmpty(row.name) then&lt;br /&gt;
				allRowsCache[row.name] = row&lt;br /&gt;
				local num = nonEmpty(row.number)&lt;br /&gt;
				-- First occurrence wins so base forms beat Megas sharing a number.&lt;br /&gt;
				if num and numberIndexCache[num] == nil then&lt;br /&gt;
					numberIndexCache[num] = row&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return allRowsCache&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function hyphenSpaceVariant(s)&lt;br /&gt;
	if mw.ustring.find(s, &#039;-&#039;, 1, true) then&lt;br /&gt;
		return (mw.ustring.gsub(s, &#039;%-&#039;, &#039; &#039;))&lt;br /&gt;
	end&lt;br /&gt;
	return (mw.ustring.gsub(s, &#039; &#039;, &#039;-&#039;))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function byName(name)&lt;br /&gt;
	local rows = loadAllRows()&lt;br /&gt;
	return rows[name] or rows[hyphenSpaceVariant(name)]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function byNumber(number)&lt;br /&gt;
	loadAllRows()&lt;br /&gt;
	return numberIndexCache[tostring(number)]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local MEGA_COLUMNS = {&lt;br /&gt;
	number = &#039;Pokedex Number&#039;,&lt;br /&gt;
	name = &#039;Name&#039;,&lt;br /&gt;
	type1 = &#039;Type1&#039;,&lt;br /&gt;
	type2 = &#039;Type2&#039;,&lt;br /&gt;
	ability1 = &#039;Ability 1&#039;,&lt;br /&gt;
	ability2 = &#039;Ability 2&#039;,&lt;br /&gt;
	ha = &#039;Hidden Ability&#039;,&lt;br /&gt;
	generation = &#039;Generation&#039;,&lt;br /&gt;
	hp = &#039;HP&#039;,&lt;br /&gt;
	atk = &#039;Attack&#039;,&lt;br /&gt;
	def = &#039;Defense&#039;,&lt;br /&gt;
	spatk = &#039;Special Attack&#039;,&lt;br /&gt;
	spdef = &#039;Special Defense&#039;,&lt;br /&gt;
	spd = &#039;Speed&#039;,&lt;br /&gt;
	evhp = &#039;EVHP&#039;,&lt;br /&gt;
	evatk = &#039;EVATK&#039;,&lt;br /&gt;
	evdef = &#039;EVDEF&#039;,&lt;br /&gt;
	evspa = &#039;EVSPA&#039;,&lt;br /&gt;
	evspd = &#039;EVSPD&#039;,&lt;br /&gt;
	evsp = &#039;EVSP&#039;,&lt;br /&gt;
	height = &#039;Height&#039;,&lt;br /&gt;
	weight = &#039;Weight&#039;,&lt;br /&gt;
	stone = &#039;Stone&#039;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local MEGA_SPEC&lt;br /&gt;
do&lt;br /&gt;
	local parts = {}&lt;br /&gt;
	for key, header in pairs(MEGA_COLUMNS) do&lt;br /&gt;
		parts[#parts + 1] = key .. &#039;=&#039; .. header&lt;br /&gt;
	end&lt;br /&gt;
	MEGA_SPEC = table.concat(parts, &#039;,&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local megaCache = {}&lt;br /&gt;
&lt;br /&gt;
local function megaByName(name)&lt;br /&gt;
	if megaCache[name] == nil then&lt;br /&gt;
		local ok, values = pcall(function()&lt;br /&gt;
			return mw.ext.externalData.getFileData{&lt;br /&gt;
				source = &#039;data&#039;,&lt;br /&gt;
				[&#039;file name&#039;] = &#039;RawMegaPokemonList.csv&#039;,&lt;br /&gt;
				format = DATA_FORMAT,&lt;br /&gt;
				filters = &#039;Name=&#039; .. name,&lt;br /&gt;
				data = MEGA_SPEC,&lt;br /&gt;
			}&lt;br /&gt;
		end)&lt;br /&gt;
		if ok and values and values.name ~= nil then&lt;br /&gt;
			megaCache[name] = values&lt;br /&gt;
		else&lt;br /&gt;
			megaCache[name] = false&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return megaCache[name] or nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- formStem/rawListFormName now live in Module:PokemonForms, shared with&lt;br /&gt;
-- Module:Learnsets, so both resolve a form&#039;s raw-list name identically.&lt;br /&gt;
local formStem = PokemonForms.formStem&lt;br /&gt;
local rawListFormName = PokemonForms.rawListFormName&lt;br /&gt;
&lt;br /&gt;
local typeColorsCache = {}&lt;br /&gt;
local function typeColors(frame, pokeType)&lt;br /&gt;
	if not typeColorsCache[pokeType] then&lt;br /&gt;
		typeColorsCache[pokeType] = {&lt;br /&gt;
			light = frame:expandTemplate{ title = pokeType .. &#039; color light&#039; },&lt;br /&gt;
			base = frame:expandTemplate{ title = pokeType .. &#039; color&#039; },&lt;br /&gt;
			dark = frame:expandTemplate{ title = pokeType .. &#039; color dark&#039; },&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
	return typeColorsCache[pokeType]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local statColorCache = {}&lt;br /&gt;
local function statColors(frame, statTemplate)&lt;br /&gt;
	if not statColorCache[statTemplate] then&lt;br /&gt;
		statColorCache[statTemplate] = {&lt;br /&gt;
			base = frame:expandTemplate{ title = statTemplate .. &#039; color&#039; },&lt;br /&gt;
			dark = frame:expandTemplate{ title = statTemplate .. &#039; color dark&#039; },&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
	return statColorCache[statTemplate]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function navTableHtml(frame, data, colors, pageName, widthPercent)&lt;br /&gt;
	widthPercent = widthPercent or 65&lt;br /&gt;
	local number = tonumber(data.number)&lt;br /&gt;
&lt;br /&gt;
	local prevCell = &#039;&#039;&lt;br /&gt;
	if number and number &amp;gt; 1 then&lt;br /&gt;
		local prev = byNumber(number - 1)&lt;br /&gt;
		if prev then&lt;br /&gt;
			prevCell = &#039;&amp;amp;nbsp;[[File:&#039; .. prev.number .. &#039;Icon.png|&#039; .. prev.name .. &#039;|link=&#039; .. prev.name ..&lt;br /&gt;
				&#039;]]&amp;amp;nbsp;&amp;amp;nbsp;#&#039; .. padNumber(prev.number) .. &#039;&amp;amp;nbsp;[[&#039; .. prev.name .. &#039;]]&#039;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local nextCell = &#039;&#039;&lt;br /&gt;
	if number then&lt;br /&gt;
		local nxt = byNumber(number + 1)&lt;br /&gt;
		if nxt then&lt;br /&gt;
			nextCell = &#039;[[&#039; .. nxt.name .. &#039;]]&amp;amp;nbsp;#&#039; .. padNumber(nxt.number) .. &#039;&amp;amp;nbsp;&amp;amp;nbsp;[[File:&#039; ..&lt;br /&gt;
				nxt.number .. &#039;Icon.png|&#039; .. nxt.name .. &#039;|link=&#039; .. nxt.name .. &#039;]]&#039;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return &#039;&amp;lt;table style=&amp;quot;margin-left: auto; margin-right: auto; margin-bottom: 15px; height: 60px; &#039; ..&lt;br /&gt;
		&#039;border: 4px #&#039; .. colors.dark .. &#039; solid; font-weight: bold; width: &#039; .. widthPercent .. &#039;%; color: #&#039; ..&lt;br /&gt;
		colors.dark .. &#039;; border-radius: 20px; padding: 3px; background: #&#039; .. colors.base .. &#039;;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;text-align: left; width: 36%; background: #&#039; .. colors.light ..&lt;br /&gt;
		&#039;; border-radius: 15px 1px 1px 15px; border: 1px solid #&#039; .. colors.dark .. &#039;;&amp;quot;&amp;gt;&#039; .. prevCell .. &#039;&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;text-align: center; width: 28%; background: #&#039; .. colors.light ..&lt;br /&gt;
		&#039;; border: 1px solid #&#039; .. colors.dark .. &#039;;&amp;quot;&amp;gt;#&#039; .. padNumber(number) .. &#039;&amp;amp;nbsp;&amp;amp;nbsp;-&amp;amp;nbsp;&amp;amp;nbsp;&#039; ..&lt;br /&gt;
		pageName .. &#039;&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;text-align: right; width: 36%; padding-right: 10px; background: #&#039; .. colors.light ..&lt;br /&gt;
		&#039;; border: 1px solid #&#039; .. colors.dark .. &#039;; border-radius: 1px 15px 15px 1px;&amp;quot;&amp;gt;&#039; .. nextCell .. &#039;&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.navTable(frame)&lt;br /&gt;
	local args = templateArgs(frame)&lt;br /&gt;
	local pageName = mw.title.getCurrentTitle().text&lt;br /&gt;
	local name = nonEmpty(args.Name) or pageName&lt;br /&gt;
&lt;br /&gt;
	local data = byName(name)&lt;br /&gt;
	if not data then&lt;br /&gt;
		return &#039;&amp;lt;strong class=&amp;quot;error&amp;quot;&amp;gt;PokeNavTable: no data found for &amp;quot;&#039; .. name .. &#039;&amp;quot;&amp;lt;/strong&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return navTableHtml(frame, data, typeColors(frame, data.type1), pageName, 65)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function infoCell(colors, labelHtml, valueHtml)&lt;br /&gt;
	return &#039;&amp;lt;td colspan=&amp;quot;3&amp;quot; style=&amp;quot;width: 50%; border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; .. colors.light ..&lt;br /&gt;
		&#039;; border-radius: 15px; padding: 5px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;p style=&amp;quot;margin-bottom: 7px; font-weight: bold; color: #&#039; .. colors.dark .. &#039;;&amp;quot;&amp;gt;&#039; .. labelHtml .. &#039;&amp;lt;/p&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;span style=&amp;quot;border-radius: 12px; padding: 4px 10px; border: 1px solid #&#039; .. colors.dark ..&lt;br /&gt;
		&#039;; background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&#039; .. valueHtml .. &#039;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/span&amp;gt;&amp;lt;/td&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function abilityCell(colors, label, ability, widthPercent)&lt;br /&gt;
	if not ability then return &#039;&#039; end&lt;br /&gt;
	local style = &#039;border-radius: 12px; padding: 4px 10px; border: 1px solid #&#039; .. colors.dark ..&lt;br /&gt;
		&#039;; background-color: #FFFFFF;&#039;&lt;br /&gt;
	if widthPercent then&lt;br /&gt;
		style = &#039;width: &#039; .. widthPercent .. &#039;%; &#039; .. style&lt;br /&gt;
	end&lt;br /&gt;
	return &#039;&amp;lt;td style=&amp;quot;&#039; .. style .. &#039;&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&#039; .. label .. &#039;&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;[[&#039; .. ability .. &#039;_(ability)|&#039; .. ability ..&lt;br /&gt;
		&#039;]]&amp;lt;/td&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function abilitiesRow(colors, data)&lt;br /&gt;
	local entries = {&lt;br /&gt;
		{ &#039;Ability 1&#039;, nonEmpty(data.ability1) },&lt;br /&gt;
		{ &#039;Ability 2&#039;, nonEmpty(data.ability2) },&lt;br /&gt;
		{ &#039;Hidden Ability&#039;, nonEmpty(data.ha) },&lt;br /&gt;
	}&lt;br /&gt;
	local present = {}&lt;br /&gt;
	for _, entry in ipairs(entries) do&lt;br /&gt;
		if entry[2] then present[#present + 1] = entry end&lt;br /&gt;
	end&lt;br /&gt;
	local widthPercent = (#present &amp;gt; 0) and string.format(&#039;%.2f&#039;, 100 / #present) or nil&lt;br /&gt;
	local cells = {}&lt;br /&gt;
	for _, entry in ipairs(present) do&lt;br /&gt;
		cells[#cells + 1] = abilityCell(colors, entry[1], entry[2], widthPercent)&lt;br /&gt;
	end&lt;br /&gt;
	return table.concat(cells)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function statValueCell(frame, stat, value)&lt;br /&gt;
	local colors = statColors(frame, stat.template)&lt;br /&gt;
	return &#039;&amp;lt;td style=&amp;quot;width: 16.66%; border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; .. colors.base ..&lt;br /&gt;
		&#039;; border-radius: 12px; padding: 4px; font-size: 11px;&amp;quot;&amp;gt;\&#039;\&#039;\&#039;&#039; .. stat.label .. &#039;\&#039;\&#039;\&#039;&amp;lt;br&amp;gt;&#039; ..&lt;br /&gt;
		value .. &#039;&amp;lt;/td&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function statBarRow(frame, stat, value)&lt;br /&gt;
	local labelColors = statColors(frame, stat.template)&lt;br /&gt;
	local pct = math.floor(value / 255 * 100 + 0.5)&lt;br /&gt;
	if pct &amp;lt; 2 then pct = 2 end&lt;br /&gt;
	if pct &amp;gt; 100 then pct = 100 end&lt;br /&gt;
	local hue = math.floor(math.max(0, math.min(180, value * 180 / 255)) + 0.5)&lt;br /&gt;
	local fill = &#039;hsl(&#039; .. hue .. &#039;, 85%, 45%)&#039;&lt;br /&gt;
	return &#039;&amp;lt;tr&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;text-align: right; padding: 2px 8px 2px 4px; font-weight: bold; font-size: 12px; &#039; ..&lt;br /&gt;
		&#039;color: #&#039; .. labelColors.dark .. &#039;; white-space: nowrap;&amp;quot;&amp;gt;&#039; .. stat.label .. &#039;&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;width: 100%; padding: 2px 0;&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;background-color: #FFFFFF; border: 1px solid &#039; ..&lt;br /&gt;
		&#039;#999999; border-radius: 8px; height: 13px; overflow: hidden;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;div style=&amp;quot;width: &#039; .. pct .. &#039;%; height: 100%; background-color: &#039; .. fill .. &#039;;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;text-align: left; padding: 2px 4px 2px 8px; font-weight: bold; font-size: 12px; &#039; ..&lt;br /&gt;
		&#039;width: 34px;&amp;quot;&amp;gt;&#039; .. value .. &#039;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local MALE_COLOR = &#039;3B6BF5&#039;&lt;br /&gt;
local FEMALE_COLOR = &#039;F5629C&#039;&lt;br /&gt;
&lt;br /&gt;
local function genderRatioHtml(male)&lt;br /&gt;
	if male == &#039;Genderless&#039; then&lt;br /&gt;
		return &#039;&amp;lt;span style=&amp;quot;display: inline-block; color: #000000; background-color: #FFFFFF; &#039; ..&lt;br /&gt;
			&#039;border-radius: 12px; border: 1px solid #000000; padding: 3px 12px; font-weight: bold;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
			&#039;Genderless&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	local m = tonumber(male)&lt;br /&gt;
	if m == nil then&lt;br /&gt;
		m = nonEmpty(male) and 100 or 0&lt;br /&gt;
	end&lt;br /&gt;
	if m &amp;lt; 0 then m = 0 end&lt;br /&gt;
	if m &amp;gt; 100 then m = 100 end&lt;br /&gt;
	local f = 100 - m&lt;br /&gt;
&lt;br /&gt;
	local segments = &#039;&#039;&lt;br /&gt;
	if m &amp;gt; 0 then&lt;br /&gt;
		segments = segments .. &#039;&amp;lt;div style=&amp;quot;width: &#039; .. m .. &#039;%; background-color: #&#039; .. MALE_COLOR .. &#039;;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	if f &amp;gt; 0 then&lt;br /&gt;
		segments = segments .. &#039;&amp;lt;div style=&amp;quot;width: &#039; .. f .. &#039;%; background-color: #&#039; .. FEMALE_COLOR .. &#039;;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local labels = {}&lt;br /&gt;
	if m &amp;gt; 0 then&lt;br /&gt;
		labels[#labels + 1] = &#039;&amp;lt;span style=&amp;quot;color: #&#039; .. MALE_COLOR .. &#039;; font-weight: bold;&amp;quot;&amp;gt;&#039; .. m .. &#039;% ♂&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	if f &amp;gt; 0 then&lt;br /&gt;
		labels[#labels + 1] = &#039;&amp;lt;span style=&amp;quot;color: #&#039; .. FEMALE_COLOR .. &#039;; font-weight: bold;&amp;quot;&amp;gt;&#039; .. f .. &#039;% ♀&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return &#039;&amp;lt;div style=&amp;quot;width: 85%; margin: 4px auto 0;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;div style=&amp;quot;display: flex; height: 12px; border-radius: 8px; overflow: hidden; &#039; ..&lt;br /&gt;
		&#039;border: 1px solid #555555; background-color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. segments .. &#039;&amp;lt;/div&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;div style=&amp;quot;margin-top: 4px; font-size: 12px;&amp;quot;&amp;gt;&#039; .. table.concat(labels, &#039; &amp;amp;nbsp;·&amp;amp;nbsp; &#039;) ..&lt;br /&gt;
		&#039;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function categories(data, gen, bstCategory, args)&lt;br /&gt;
	local cats = { &#039;[[Category:Pokémon species]]&#039; }&lt;br /&gt;
	if gen then&lt;br /&gt;
		cats[#cats + 1] = &#039;[[Category:Generation &#039; .. gen .. &#039; Pokémon]]&#039;&lt;br /&gt;
	end&lt;br /&gt;
	cats[#cats + 1] = &#039;[[Category:&#039; .. data.type1 .. &#039;-type Pokémon]]&#039;&lt;br /&gt;
	if nonEmpty(data.type2) then&lt;br /&gt;
		cats[#cats + 1] = &#039;[[Category:&#039; .. data.type2 .. &#039;-type Pokémon]]&#039;&lt;br /&gt;
	end&lt;br /&gt;
	cats[#cats + 1] = &#039;[[Category:&#039; .. data.rarity .. &#039; Pokémon]]&#039;&lt;br /&gt;
	if nonEmpty(data.npc) then&lt;br /&gt;
		cats[#cats + 1] = &#039;[[Category:NPC-obtainable Pokémon]]&#039;&lt;br /&gt;
	end&lt;br /&gt;
	if not nonEmpty(args.EvolvesFrom) then&lt;br /&gt;
		cats[#cats + 1] = &#039;[[Category:Base-stage Pokémon]]&#039;&lt;br /&gt;
	end&lt;br /&gt;
	cats[#cats + 1] = &#039;[[Category:&#039; .. bstCategory .. &#039;-plus-BST Pokémon]]&#039;&lt;br /&gt;
	return table.concat(cats, &#039; &#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function infoboxHtml(frame, args, data, displayName, width, pageName, includeNav)&lt;br /&gt;
	local colors = typeColors(frame, data.type1)&lt;br /&gt;
	-- Regional forms carry values like &#039;1A&#039;/&#039;5A&#039;; use the leading digits.&lt;br /&gt;
	local gen = GEN_NUMERALS[tonumber(mw.ustring.match(tostring(data.generation or &#039;&#039;), &#039;^%d+&#039;) or &#039;&#039;)]&lt;br /&gt;
&lt;br /&gt;
	-- Types pill(s).&lt;br /&gt;
	local typesHtml&lt;br /&gt;
	if nonEmpty(data.type2) then&lt;br /&gt;
		local type2Colors = typeColors(frame, data.type2)&lt;br /&gt;
		typesHtml =&lt;br /&gt;
			&#039;&amp;lt;td style=&amp;quot;width: 50%; background-color: #&#039; .. colors.dark .. &#039;; border-radius: 25px 1px 1px 25px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
			&#039;[[&#039; .. data.type1 .. &#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. data.type1 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
			&#039;&amp;lt;td style=&amp;quot;width: 50%; background-color: #&#039; .. type2Colors.dark .. &#039;; border-radius: 1px 25px 25px 1px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
			&#039;[[&#039; .. data.type2 .. &#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. data.type2 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&#039;&lt;br /&gt;
	else&lt;br /&gt;
		typesHtml =&lt;br /&gt;
			&#039;&amp;lt;td style=&amp;quot;width:100%; background-color: #&#039; .. colors.dark .. &#039;; border-radius: 25px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
			&#039;[[&#039; .. data.type1 .. &#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. data.type1 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Base stats&lt;br /&gt;
	local statRows, bst = {}, 0&lt;br /&gt;
	for _, stat in ipairs(STATS) do&lt;br /&gt;
		local value = tonumber(data[stat.key]) or 0&lt;br /&gt;
		bst = bst + value&lt;br /&gt;
		statRows[#statRows + 1] = statBarRow(frame, stat, value)&lt;br /&gt;
	end&lt;br /&gt;
	local bstCategory = math.floor(bst / 100 + 0.5) * 100&lt;br /&gt;
&lt;br /&gt;
	-- EV yield.&lt;br /&gt;
	local evCells, evTotal = {}, 0&lt;br /&gt;
	for i, stat in ipairs(STATS) do&lt;br /&gt;
		local ev = tonumber(data[EV_KEYS[i]]) or 0&lt;br /&gt;
		evTotal = evTotal + ev&lt;br /&gt;
		evCells[#evCells + 1] = statValueCell(frame, stat, ev)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Catch rate.&lt;br /&gt;
	local catchRaw = tonumber(data.catch) or 0&lt;br /&gt;
	local catchPercent = string.format(&#039;%.2f&#039;, catchRaw / 255 / 3 * 100)&lt;br /&gt;
&lt;br /&gt;
	local buf = {}&lt;br /&gt;
	if includeNav then&lt;br /&gt;
		buf[#buf + 1] = navTableHtml(frame, data, colors, pageName)&lt;br /&gt;
	end&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;table align=&amp;quot;right&amp;quot; class=&amp;quot;informational-box&amp;quot; cellpadding=&amp;quot;4&amp;quot; cellspacing=&amp;quot;4&amp;quot; &#039; ..&lt;br /&gt;
		&#039;style=&amp;quot;width: &#039; .. width .. &#039;%; border: 4px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.base .. &#039;; padding: 4px; border-radius: 15px;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Header: dex number + icon, name.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;3&amp;quot; style=&amp;quot;width: 50%; border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; border-radius: 15px;&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;margin-bottom: 7px; font-weight: bold; color:#&#039; ..&lt;br /&gt;
		colors.dark .. &#039;;&amp;quot;&amp;gt;#&#039; .. padNumber(data.number) .. &#039;&amp;lt;/span&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;[[File:&#039; .. data.number ..&lt;br /&gt;
		&#039;Icon.png]]&amp;lt;/td&amp;gt;&amp;lt;td colspan=&amp;quot;3&amp;quot; style=&amp;quot;width: 50%; border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; border-radius: 15px;&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;margin-bottom: 7px; font-weight: bold; color:#&#039; ..&lt;br /&gt;
		colors.dark .. &#039;;&amp;quot;&amp;gt;&#039; .. displayName .. &#039;&amp;lt;/span&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Artwork.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;6&amp;quot; style=&amp;quot;border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; border-radius: 15px; padding: 5px;&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;border-radius: 15px; &#039; ..&lt;br /&gt;
		&#039;text-align: center; padding: 5px; background-color: #FFFFFF;&amp;quot;&amp;gt;[[File:&#039; .. data.number .. data.name ..&lt;br /&gt;
		&#039;.png|150px]]&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Types + Generation.&lt;br /&gt;
	local genHtml = &#039;—&#039;&lt;br /&gt;
	if gen then&lt;br /&gt;
		genHtml = &#039;[[:Category:Generation &#039; .. gen .. &#039; Pokémon|&amp;lt;span style=&amp;quot;color:#&#039; ..&lt;br /&gt;
			colors.dark .. &#039;;&amp;quot;&amp;gt;&#039; .. gen .. &#039;&amp;lt;/span&amp;gt;]]&#039;&lt;br /&gt;
	end&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;3&amp;quot; style=&amp;quot;width: 50%; border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; padding: 11px; border-radius: 15px;&amp;quot;&amp;gt;&amp;lt;p style=&amp;quot;margin-bottom: 7px; font-weight: bold; &#039; ..&lt;br /&gt;
		&#039;color: #&#039; .. colors.dark .. &#039;;&amp;quot;&amp;gt;Types&amp;lt;/p&amp;gt;&amp;lt;table align=&amp;quot;center&amp;quot; style=&amp;quot;width: 75%; font-weight: bold; &#039; ..&lt;br /&gt;
		&#039;padding: 3px;&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&#039; .. typesHtml .. &#039;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td colspan=&amp;quot;3&amp;quot; style=&amp;quot;width: 50%; border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; .. colors.light ..&lt;br /&gt;
		&#039;; border-radius: 15px;&amp;quot;&amp;gt;&amp;lt;p style=&amp;quot;margin-bottom: 7px; font-weight: bold; color: #&#039; .. colors.dark ..&lt;br /&gt;
		&#039;;&amp;quot;&amp;gt;Generation&amp;lt;/p&amp;gt;&amp;lt;span style=&amp;quot;border-radius: 12px; padding: 4px 10px; border: 1px solid #&#039; .. colors.dark ..&lt;br /&gt;
		&#039;; background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&#039; .. genHtml .. &#039;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/span&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Abilities.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;6&amp;quot; style=&amp;quot;border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; padding: 11px; border-radius: 15px; width: 100%;&amp;quot;&amp;gt;&amp;lt;table width=&amp;quot;100%&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&amp;lt;th colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;p style=&amp;quot;margin-bottom: 7px; font-weight: bold; color:#&#039; .. colors.dark ..&lt;br /&gt;
		&#039;;&amp;quot;&amp;gt;[[Abilities|&amp;lt;span style=&amp;quot;color:#&#039; .. colors.dark .. &#039;;&amp;quot;&amp;gt;Abilities&amp;lt;/span&amp;gt;]]&amp;lt;/p&amp;gt;&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&#039; .. abilitiesRow(colors, data) .. &#039;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Rarity + Catch rate.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&#039; ..&lt;br /&gt;
		infoCell(colors, &#039;[[List of Pokémon by Rarity Tier|&amp;lt;span style=&amp;quot;color:#&#039; .. colors.dark ..&lt;br /&gt;
			&#039;;&amp;quot;&amp;gt;Rarity Tier&amp;lt;/span&amp;gt;]]&#039;, &#039;[[:Category:&#039; .. data.rarity .. &#039; Pokémon|&amp;lt;span style=&amp;quot;color:#&#039; ..&lt;br /&gt;
			colors.dark .. &#039;;&amp;quot;&amp;gt;&#039; .. data.rarity .. &#039;&amp;lt;/span&amp;gt;]]&#039;) ..&lt;br /&gt;
		infoCell(colors, &#039;[[Catch Rates|&amp;lt;span style=&amp;quot;color:#&#039; .. colors.dark .. &#039;;&amp;quot;&amp;gt;Catch rate&amp;lt;/span&amp;gt;]]&#039;,&lt;br /&gt;
			data.catch .. &#039;/255 (&#039; .. catchPercent .. &#039;%)&#039;) ..&lt;br /&gt;
		&#039;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Base stats.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;6&amp;quot; style=&amp;quot;border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; border-radius: 15px; padding: 8px; width: 100%&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;table width=&amp;quot;100%&amp;quot; style=&amp;quot;border-collapse: collapse;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&amp;lt;th colspan=&amp;quot;3&amp;quot;&amp;gt;&amp;lt;p style=&amp;quot;margin-bottom: 7px; font-weight: bold; color: #&#039; .. colors.dark ..&lt;br /&gt;
		&#039;;&amp;quot;&amp;gt;[[Base stats|&amp;lt;span style=&amp;quot;color: #&#039; .. colors.dark .. &#039;;&amp;quot;&amp;gt;Base stats&amp;lt;/span&amp;gt;]]&amp;lt;/p&amp;gt;&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&#039; ..&lt;br /&gt;
		table.concat(statRows) ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;3&amp;quot; style=&amp;quot;text-align: center; padding-top: 6px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;div style=&amp;quot;display: inline-block; background-color: #FFFFFF; border: 1px solid #&#039; .. colors.dark ..&lt;br /&gt;
		&#039;; padding: 4px 14px; border-radius: 12px;&amp;quot;&amp;gt;Base-stat total: &#039; .. bst .. &#039;&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;/table&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- EV yield.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;6&amp;quot; style=&amp;quot;border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; border-radius: 15px; padding: 5px; width: 100%&amp;quot;&amp;gt;&amp;lt;table width=&amp;quot;100%&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&amp;lt;th colspan=&amp;quot;6&amp;quot;&amp;gt;[[EVs|&amp;lt;span style=&amp;quot;margin-bottom: 7px; font-weight: bold; color: #&#039; .. colors.dark ..&lt;br /&gt;
		&#039;;&amp;quot;&amp;gt;EV Yield&amp;lt;/span&amp;gt;]]&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&#039; .. table.concat(evCells) .. &#039;&amp;lt;/tr&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;margin: auto; background-color:#FFFFFF; border: 1px solid #&#039; ..&lt;br /&gt;
		colors.dark .. &#039;; padding: 4px 14px; border-radius: 12px; margin-bottom: 5px; width: 50%;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;EV-yield total: &#039; .. evTotal .. &#039;&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Base experience + Gender ratio.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&#039; ..&lt;br /&gt;
		infoCell(colors, &#039;[[Experience System#Base Experience|&amp;lt;span style=&amp;quot;color:#&#039; .. colors.dark ..&lt;br /&gt;
			&#039;;&amp;quot;&amp;gt;Base Experience&amp;lt;/span&amp;gt;]]&#039;, data.exp) ..&lt;br /&gt;
		&#039;&amp;lt;td colspan=&amp;quot;3&amp;quot; style=&amp;quot;width: 50%; border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; .. colors.light ..&lt;br /&gt;
		&#039;; border-radius: 15px; padding: 5px;&amp;quot;&amp;gt;&amp;lt;p style=&amp;quot;margin-bottom: 7px; font-weight: bold; color: #&#039; ..&lt;br /&gt;
		colors.dark .. &#039;;&amp;quot;&amp;gt;Gender Ratio&amp;lt;/p&amp;gt;&#039; .. genderRatioHtml(data.male) .. &#039;&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Height + Weight.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&#039; ..&lt;br /&gt;
		infoCell(colors, &#039;Height&#039;, data.height .. &#039;m&#039;) ..&lt;br /&gt;
		infoCell(colors, &#039;Weight&#039;, data.weight .. &#039;kg&#039;) ..&lt;br /&gt;
		&#039;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;/table&amp;gt;&#039;&lt;br /&gt;
	buf[#buf + 1] = categories(data, gen, bstCategory, args)&lt;br /&gt;
&lt;br /&gt;
	return table.concat(buf)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function megaInfoboxHtml(frame, data, width)&lt;br /&gt;
	local colors = typeColors(frame, data.type1)&lt;br /&gt;
	local gen = GEN_NUMERALS[tonumber(mw.ustring.match(tostring(data.generation or &#039;&#039;), &#039;^%d+&#039;) or &#039;&#039;)]&lt;br /&gt;
	local displayName = &#039;Mega &#039; .. (data.name or &#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
	local typesHtml&lt;br /&gt;
	if nonEmpty(data.type2) then&lt;br /&gt;
		local type2Colors = typeColors(frame, data.type2)&lt;br /&gt;
		typesHtml =&lt;br /&gt;
			&#039;&amp;lt;td style=&amp;quot;width: 50%; background-color: #&#039; .. colors.dark .. &#039;; border-radius: 25px 1px 1px 25px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
			&#039;[[&#039; .. data.type1 .. &#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. data.type1 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
			&#039;&amp;lt;td style=&amp;quot;width: 50%; background-color: #&#039; .. type2Colors.dark .. &#039;; border-radius: 1px 25px 25px 1px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
			&#039;[[&#039; .. data.type2 .. &#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. data.type2 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&#039;&lt;br /&gt;
	else&lt;br /&gt;
		typesHtml =&lt;br /&gt;
			&#039;&amp;lt;td style=&amp;quot;width:100%; background-color: #&#039; .. colors.dark .. &#039;; border-radius: 25px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
			&#039;[[&#039; .. data.type1 .. &#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. data.type1 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local statRows, bst = {}, 0&lt;br /&gt;
	for _, stat in ipairs(STATS) do&lt;br /&gt;
		local value = tonumber(data[stat.key]) or 0&lt;br /&gt;
		bst = bst + value&lt;br /&gt;
		statRows[#statRows + 1] = statBarRow(frame, stat, value)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local evCells, evTotal = {}, 0&lt;br /&gt;
	for i, stat in ipairs(STATS) do&lt;br /&gt;
		local ev = tonumber(data[EV_KEYS[i]]) or 0&lt;br /&gt;
		evTotal = evTotal + ev&lt;br /&gt;
		evCells[#evCells + 1] = statValueCell(frame, stat, ev)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local buf = {}&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;table align=&amp;quot;right&amp;quot; class=&amp;quot;informational-box&amp;quot; cellpadding=&amp;quot;4&amp;quot; cellspacing=&amp;quot;4&amp;quot; &#039; ..&lt;br /&gt;
		&#039;style=&amp;quot;width: &#039; .. width .. &#039;%; border: 4px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.base .. &#039;; padding: 4px; border-radius: 15px;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Header: name across the whole top line.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;6&amp;quot; style=&amp;quot;border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; border-radius: 15px;&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;margin-bottom: 7px; font-weight: bold; color:#&#039; ..&lt;br /&gt;
		colors.dark .. &#039;;&amp;quot;&amp;gt;&#039; .. displayName .. &#039;&amp;lt;/span&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Artwork.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;6&amp;quot; style=&amp;quot;border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; border-radius: 15px; padding: 5px;&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;border-radius: 15px; &#039; ..&lt;br /&gt;
		&#039;text-align: center; padding: 5px; background-color: #FFFFFF;&amp;quot;&amp;gt;[[File:&#039; .. (data.number or &#039;&#039;) .. (data.name or &#039;&#039;) ..&lt;br /&gt;
		&#039;-Mega.png|150px]]&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Types + Generation.&lt;br /&gt;
	local genHtml = &#039;—&#039;&lt;br /&gt;
	if gen then&lt;br /&gt;
		genHtml = &#039;[[:Category:Generation &#039; .. gen .. &#039; Pokémon|&amp;lt;span style=&amp;quot;color:#&#039; ..&lt;br /&gt;
			colors.dark .. &#039;;&amp;quot;&amp;gt;&#039; .. gen .. &#039;&amp;lt;/span&amp;gt;]]&#039;&lt;br /&gt;
	end&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;3&amp;quot; style=&amp;quot;width: 50%; border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; padding: 11px; border-radius: 15px;&amp;quot;&amp;gt;&amp;lt;p style=&amp;quot;margin-bottom: 7px; font-weight: bold; &#039; ..&lt;br /&gt;
		&#039;color: #&#039; .. colors.dark .. &#039;;&amp;quot;&amp;gt;Types&amp;lt;/p&amp;gt;&amp;lt;table align=&amp;quot;center&amp;quot; style=&amp;quot;width: 75%; font-weight: bold; &#039; ..&lt;br /&gt;
		&#039;padding: 3px;&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&#039; .. typesHtml .. &#039;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td colspan=&amp;quot;3&amp;quot; style=&amp;quot;width: 50%; border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; .. colors.light ..&lt;br /&gt;
		&#039;; border-radius: 15px;&amp;quot;&amp;gt;&amp;lt;p style=&amp;quot;margin-bottom: 7px; font-weight: bold; color: #&#039; .. colors.dark ..&lt;br /&gt;
		&#039;;&amp;quot;&amp;gt;Generation&amp;lt;/p&amp;gt;&amp;lt;span style=&amp;quot;border-radius: 12px; padding: 4px 10px; border: 1px solid #&#039; .. colors.dark ..&lt;br /&gt;
		&#039;; background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&#039; .. genHtml .. &#039;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/span&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Abilities.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;6&amp;quot; style=&amp;quot;border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; padding: 11px; border-radius: 15px; width: 100%;&amp;quot;&amp;gt;&amp;lt;table width=&amp;quot;100%&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&amp;lt;th colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;p style=&amp;quot;margin-bottom: 7px; font-weight: bold; color:#&#039; .. colors.dark ..&lt;br /&gt;
		&#039;;&amp;quot;&amp;gt;[[Abilities|&amp;lt;span style=&amp;quot;color:#&#039; .. colors.dark .. &#039;;&amp;quot;&amp;gt;Abilities&amp;lt;/span&amp;gt;]]&amp;lt;/p&amp;gt;&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&#039; .. abilitiesRow(colors, data) .. &#039;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Mega Stone, linked to its quest page (&amp;quot;Venusaurite (quest)&amp;quot;).&lt;br /&gt;
	local stone = nonEmpty(data.stone)&lt;br /&gt;
	local stoneHtml = &#039;—&#039;&lt;br /&gt;
	if stone then&lt;br /&gt;
		stoneHtml = &#039;[[&#039; .. stone .. &#039; (quest)|&amp;lt;span style=&amp;quot;color:#&#039; .. colors.dark .. &#039;;&amp;quot;&amp;gt;&#039; .. stone .. &#039;&amp;lt;/span&amp;gt;]]&#039;&lt;br /&gt;
	end&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;6&amp;quot; style=&amp;quot;border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; border-radius: 15px; padding: 5px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;p style=&amp;quot;margin-bottom: 7px; font-weight: bold; color: #&#039; .. colors.dark .. &#039;;&amp;quot;&amp;gt;Mega Stone&amp;lt;/p&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;span style=&amp;quot;border-radius: 12px; padding: 4px 10px; border: 1px solid #&#039; .. colors.dark ..&lt;br /&gt;
		&#039;; background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&#039; .. stoneHtml .. &#039;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/span&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Base stats.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;6&amp;quot; style=&amp;quot;border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; border-radius: 15px; padding: 8px; width: 100%&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;table width=&amp;quot;100%&amp;quot; style=&amp;quot;border-collapse: collapse;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&amp;lt;th colspan=&amp;quot;3&amp;quot;&amp;gt;&amp;lt;p style=&amp;quot;margin-bottom: 7px; font-weight: bold; color: #&#039; .. colors.dark ..&lt;br /&gt;
		&#039;;&amp;quot;&amp;gt;[[Base stats|&amp;lt;span style=&amp;quot;color: #&#039; .. colors.dark .. &#039;;&amp;quot;&amp;gt;Base stats&amp;lt;/span&amp;gt;]]&amp;lt;/p&amp;gt;&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&#039; ..&lt;br /&gt;
		table.concat(statRows) ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;3&amp;quot; style=&amp;quot;text-align: center; padding-top: 6px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;div style=&amp;quot;display: inline-block; background-color: #FFFFFF; border: 1px solid #&#039; .. colors.dark ..&lt;br /&gt;
		&#039;; padding: 4px 14px; border-radius: 12px;&amp;quot;&amp;gt;Base-stat total: &#039; .. bst .. &#039;&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;/table&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- EV yield.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;6&amp;quot; style=&amp;quot;border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; border-radius: 15px; padding: 5px; width: 100%&amp;quot;&amp;gt;&amp;lt;table width=&amp;quot;100%&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&amp;lt;th colspan=&amp;quot;6&amp;quot;&amp;gt;[[EVs|&amp;lt;span style=&amp;quot;margin-bottom: 7px; font-weight: bold; color: #&#039; .. colors.dark ..&lt;br /&gt;
		&#039;;&amp;quot;&amp;gt;EV Yield&amp;lt;/span&amp;gt;]]&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&#039; .. table.concat(evCells) .. &#039;&amp;lt;/tr&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;margin: auto; background-color:#FFFFFF; border: 1px solid #&#039; ..&lt;br /&gt;
		colors.dark .. &#039;; padding: 4px 14px; border-radius: 12px; margin-bottom: 5px; width: 50%;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;EV-yield total: &#039; .. evTotal .. &#039;&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Height + Weight.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&#039; ..&lt;br /&gt;
		infoCell(colors, &#039;Height&#039;, (data.height or &#039;—&#039;) .. &#039;m&#039;) ..&lt;br /&gt;
		infoCell(colors, &#039;Weight&#039;, (data.weight or &#039;—&#039;) .. &#039;kg&#039;) ..&lt;br /&gt;
		&#039;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;/table&amp;gt;&#039;&lt;br /&gt;
	buf[#buf + 1] = &#039;[[Category:Mega-Evolvable Pokémon]]&#039;&lt;br /&gt;
&lt;br /&gt;
	return table.concat(buf)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.infobox(frame)&lt;br /&gt;
	local args = templateArgs(frame)&lt;br /&gt;
	local pageName = mw.title.getCurrentTitle().text&lt;br /&gt;
	local name = nonEmpty(args.Name) or pageName&lt;br /&gt;
	local width = nonEmpty(args.Width) or &#039;45&#039;&lt;br /&gt;
&lt;br /&gt;
	local data = byName(name)&lt;br /&gt;
	if not data then&lt;br /&gt;
		return &#039;&amp;lt;strong class=&amp;quot;error&amp;quot;&amp;gt;PokemonInfo: no data found for &amp;quot;&#039; .. name .. &#039;&amp;quot;&amp;lt;/strong&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	frame:callParserFunction(&#039;#vardefine&#039;, &#039;type&#039;, data.type1 or &#039;Normal&#039;)&lt;br /&gt;
&lt;br /&gt;
	return infoboxHtml(frame, args, data, name, width, pageName, true)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.primaryType(frame)&lt;br /&gt;
	local args = templateArgs(frame)&lt;br /&gt;
	local name = nonEmpty(args.Name) or mw.title.getCurrentTitle().text&lt;br /&gt;
	local data = byName(name) or byName(formStem(name))&lt;br /&gt;
	return (data and nonEmpty(data.type1)) or &#039;Normal&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function requestedName(frame)&lt;br /&gt;
	local parent = frame:getParent()&lt;br /&gt;
	return nonEmpty(frame.args.Name)&lt;br /&gt;
		or (parent and nonEmpty(parent.args.Name))&lt;br /&gt;
		or mw.title.getCurrentTitle().text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local participantsCache = {}&lt;br /&gt;
&lt;br /&gt;
local function computeParticipants(frame, name)&lt;br /&gt;
	if participantsCache[name] ~= nil then&lt;br /&gt;
		return participantsCache[name] or nil&lt;br /&gt;
	end&lt;br /&gt;
	local rows = loadAllRows()&lt;br /&gt;
	local function rowFor(n)&lt;br /&gt;
		return rows[n] or rows[hyphenSpaceVariant(n)]&lt;br /&gt;
	end&lt;br /&gt;
	local stem = formStem(name)&lt;br /&gt;
	local baseData = rowFor(stem) or rowFor(name)&lt;br /&gt;
	if not baseData then&lt;br /&gt;
		participantsCache[name] = false&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
	local baseDexNumber = mw.ustring.match(tostring(baseData.number or &#039;&#039;), &#039;^%d+&#039;)&lt;br /&gt;
&lt;br /&gt;
	local parts = { { data = baseData, label = &#039;Normal&#039; } }&lt;br /&gt;
	local seen = { [baseData.name] = true }&lt;br /&gt;
	for _, form in ipairs(FORM_SUFFIXES) do&lt;br /&gt;
		local row = rowFor(rawListFormName(form, stem))&lt;br /&gt;
		-- A candidate must share the same base dex number to be a real form of&lt;br /&gt;
		-- this Pokémon. Without this check, stripping &amp;quot;Nidoran Male&amp;quot; down to&lt;br /&gt;
		-- the stem &amp;quot;Nidoran&amp;quot; (done because &amp;quot;Male&amp;quot; is a real form suffix for&lt;br /&gt;
		-- Indeedee/Meowstic-style species) lets &amp;quot;Nidoran&amp;quot; + &amp;quot; Female&amp;quot; happen to&lt;br /&gt;
		-- match the raw list&#039;s &amp;quot;Nidoran Female&amp;quot; row — a wholly different&lt;br /&gt;
		-- species (dex #29 vs Male&#039;s #32), not this one&#039;s gender form.&lt;br /&gt;
		local rowDexNumber = row and mw.ustring.match(tostring(row.number or &#039;&#039;), &#039;^%d+&#039;)&lt;br /&gt;
		if row and not seen[row.name] and rowDexNumber == baseDexNumber then&lt;br /&gt;
			seen[row.name] = true&lt;br /&gt;
			parts[#parts + 1] = { data = row, label = form.label }&lt;br /&gt;
			if form.baseLabel then&lt;br /&gt;
				parts[1].label = form.baseLabel&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	for _, variant in ipairs(MEGA_VARIANTS) do&lt;br /&gt;
		local row = megaByName(stem .. variant)&lt;br /&gt;
		if row then&lt;br /&gt;
			parts[#parts + 1] = { data = row, label = &#039;Mega&#039; .. variant, mega = true }&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	participantsCache[name] = parts&lt;br /&gt;
	return parts&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.formLabel(frame)&lt;br /&gt;
	local idx = tonumber(frame.args[1]) or 0&lt;br /&gt;
	local parts = computeParticipants(frame, requestedName(frame))&lt;br /&gt;
	if not parts then&lt;br /&gt;
		return &#039;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	local part = parts[idx + 1]&lt;br /&gt;
	return part and part.label or &#039;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.rawName(frame)&lt;br /&gt;
	local name = requestedName(frame)&lt;br /&gt;
	local parts = computeParticipants(frame, name)&lt;br /&gt;
	return (parts and parts[1].data.name) or name&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Per-form tab-button colors (index-based, same convention as formLabel):&lt;br /&gt;
-- Tabs:MultiformTab only ever had one shared color for the whole button row&lt;br /&gt;
-- (set once via TabbedInfoBoxes&#039; own {{Trichrome}} call), so no button could&lt;br /&gt;
-- ever reflect its own form. These feed Border=/Cell= overrides added to&lt;br /&gt;
-- Tabs:MultiformTab so each button is colored to the form it actually opens.&lt;br /&gt;
function p.formBorder(frame)&lt;br /&gt;
	local idx = tonumber(frame.args[1]) or 0&lt;br /&gt;
	local parts = computeParticipants(frame, requestedName(frame))&lt;br /&gt;
	local part = parts and parts[idx + 1]&lt;br /&gt;
	if not part then return &#039;&#039; end&lt;br /&gt;
	return &#039;#&#039; .. typeColors(frame, part.data.type1).dark&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.formCell(frame)&lt;br /&gt;
	local idx = tonumber(frame.args[1]) or 0&lt;br /&gt;
	local parts = computeParticipants(frame, requestedName(frame))&lt;br /&gt;
	local part = parts and parts[idx + 1]&lt;br /&gt;
	if not part then return &#039;&#039; end&lt;br /&gt;
	return &#039;#&#039; .. typeColors(frame, part.data.type1).light&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Nav bar duplicated per form (index-based) so it can be embedded inside&lt;br /&gt;
-- each tab&#039;s own content instead of once above the whole tab shell, which&lt;br /&gt;
-- is what made it structurally unable to react to which tab is active.&lt;br /&gt;
-- Prev/next always come from the base species&#039; own dex number (form dex&lt;br /&gt;
-- strings like &amp;quot;52A&amp;quot; aren&#039;t a meaningful sequence to navigate by) -- only&lt;br /&gt;
-- the color changes per form.&lt;br /&gt;
function p.formNavTable(frame)&lt;br /&gt;
	local pageName = mw.title.getCurrentTitle().text&lt;br /&gt;
	local idx = tonumber(frame.args[1]) or 0&lt;br /&gt;
	local parts = computeParticipants(frame, requestedName(frame))&lt;br /&gt;
	if not parts then&lt;br /&gt;
		return &#039;&amp;lt;strong class=&amp;quot;error&amp;quot;&amp;gt;PokeNavTable: no data found for &amp;quot;&#039; .. pageName .. &#039;&amp;quot;&amp;lt;/strong&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	local basePart = parts[1]&lt;br /&gt;
	local activePart = parts[idx + 1] or basePart&lt;br /&gt;
	-- Fills the tab shell&#039;s own width (100%) rather than the 65% that made&lt;br /&gt;
	-- sense for navTable&#039;s unconstrained, page-wide context -- this nav bar&lt;br /&gt;
	-- sits inside the same width-45%-of-page tab content as the infobox&lt;br /&gt;
	-- card now, so 65% of *that* would look small and off-center.&lt;br /&gt;
	return navTableHtml(frame, basePart.data, typeColors(frame, activePart.data.type1), pageName, 100)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.formBox(frame)&lt;br /&gt;
	local idx = tonumber(frame.args[1]) or 0&lt;br /&gt;
	local width = nonEmpty(frame.args.Width) or &#039;100&#039;&lt;br /&gt;
	local name = requestedName(frame)&lt;br /&gt;
	local parts = computeParticipants(frame, name)&lt;br /&gt;
	if not parts then&lt;br /&gt;
		return &#039;&amp;lt;strong class=&amp;quot;error&amp;quot;&amp;gt;PokemonInfo: no data found for &amp;quot;&#039; .. name .. &#039;&amp;quot;&amp;lt;/strong&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	local part = parts[idx + 1]&lt;br /&gt;
	if not part then&lt;br /&gt;
		return &#039;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	if part.mega then&lt;br /&gt;
		return megaInfoboxHtml(frame, part.data, width)&lt;br /&gt;
	end&lt;br /&gt;
	local parent = frame:getParent()&lt;br /&gt;
	local args = (parent and parent.args) or frame.args&lt;br /&gt;
	return infoboxHtml(frame, args, part.data, part.data.name, width, mw.title.getCurrentTitle().text, false)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Module:Pokemon&amp;diff=41076</id>
		<title>Module:Pokemon</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Module:Pokemon&amp;diff=41076"/>
		<updated>2026-08-09T13:35:57Z</updated>

		<summary type="html">&lt;p&gt;Cae: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {}&lt;br /&gt;
&lt;br /&gt;
local DATA_FORMAT = &#039;CSV with header&#039;&lt;br /&gt;
&lt;br /&gt;
local COLUMNS = {&lt;br /&gt;
	number = &#039;Pokedex Number&#039;,&lt;br /&gt;
	name = &#039;Name&#039;,&lt;br /&gt;
	type1 = &#039;Type1&#039;,&lt;br /&gt;
	type2 = &#039;Type2&#039;,&lt;br /&gt;
	ability1 = &#039;Ability 1&#039;,&lt;br /&gt;
	ability2 = &#039;Ability 2&#039;,&lt;br /&gt;
	ha = &#039;Hidden Ability&#039;,&lt;br /&gt;
	generation = &#039;Generation&#039;,&lt;br /&gt;
	hp = &#039;HP&#039;,&lt;br /&gt;
	atk = &#039;Attack&#039;,&lt;br /&gt;
	def = &#039;Defense&#039;,&lt;br /&gt;
	spatk = &#039;Special Attack&#039;,&lt;br /&gt;
	spdef = &#039;Special Defense&#039;,&lt;br /&gt;
	spd = &#039;Speed&#039;,&lt;br /&gt;
	catch = &#039;Catch Rate&#039;,&lt;br /&gt;
	evhp = &#039;EVHP&#039;,&lt;br /&gt;
	evatk = &#039;EVATK&#039;,&lt;br /&gt;
	evdef = &#039;EVDEF&#039;,&lt;br /&gt;
	evspa = &#039;EVSPA&#039;,&lt;br /&gt;
	evspd = &#039;EVSPD&#039;,&lt;br /&gt;
	evsp = &#039;EVSP&#039;,&lt;br /&gt;
	male = &#039;Male Ratio&#039;,&lt;br /&gt;
	height = &#039;Height&#039;,&lt;br /&gt;
	weight = &#039;Weight&#039;,&lt;br /&gt;
	npc = &#039;NPC&#039;,&lt;br /&gt;
	exp = &#039;Base Experience&#039;,&lt;br /&gt;
	rarity = &#039;Tier&#039;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local GEN_NUMERALS = { &#039;I&#039;, &#039;II&#039;, &#039;III&#039;, &#039;IV&#039;, &#039;V&#039;, &#039;VI&#039;, &#039;VII&#039;, &#039;VIII&#039;, &#039;IX&#039; }&lt;br /&gt;
&lt;br /&gt;
local STATS = {&lt;br /&gt;
	{ key = &#039;hp&#039;, label = &#039;HP&#039;, template = &#039;HP&#039; },&lt;br /&gt;
	{ key = &#039;atk&#039;, label = &#039;Atk&#039;, template = &#039;Attack&#039; },&lt;br /&gt;
	{ key = &#039;def&#039;, label = &#039;Def&#039;, template = &#039;Defense&#039; },&lt;br /&gt;
	{ key = &#039;spatk&#039;, label = &#039;Sp.Atk&#039;, template = &#039;Special Attack&#039; },&lt;br /&gt;
	{ key = &#039;spdef&#039;, label = &#039;Sp.Def&#039;, template = &#039;Special Defense&#039; },&lt;br /&gt;
	{ key = &#039;spd&#039;, label = &#039;Spd&#039;, template = &#039;Speed&#039; },&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local EV_KEYS = { &#039;evhp&#039;, &#039;evatk&#039;, &#039;evdef&#039;, &#039;evspa&#039;, &#039;evspd&#039;, &#039;evsp&#039; }&lt;br /&gt;
&lt;br /&gt;
local function nonEmpty(s)&lt;br /&gt;
	if s == nil then return nil end&lt;br /&gt;
	s = mw.text.trim(tostring(s))&lt;br /&gt;
	if s == &#039;&#039; then return nil end&lt;br /&gt;
	return s&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function templateArgs(frame)&lt;br /&gt;
	local parent = frame:getParent()&lt;br /&gt;
	return (parent and parent.args) or frame.args&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function padNumber(n)&lt;br /&gt;
	n = tonumber(n) or 0&lt;br /&gt;
	return string.format(&#039;%03d&#039;, n)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local PokemonForms = require(&#039;Module:PokemonForms&#039;)&lt;br /&gt;
local FORM_SUFFIXES = PokemonForms.FORM_SUFFIXES&lt;br /&gt;
local STRIP_SUFFIXES = PokemonForms.STRIP_SUFFIXES&lt;br /&gt;
local MEGA_VARIANTS = PokemonForms.MEGA_VARIANTS or { &#039;&#039;, &#039; X&#039;, &#039; Y&#039; }&lt;br /&gt;
&lt;br /&gt;
-- The single data fetch: the whole raw list is loaded once per page render&lt;br /&gt;
-- and every lookup (by name, by number, form probing) reads from it.&lt;br /&gt;
local allRowsCache = nil&lt;br /&gt;
local numberIndexCache = nil&lt;br /&gt;
&lt;br /&gt;
local function loadAllRows()&lt;br /&gt;
	if allRowsCache then&lt;br /&gt;
		return allRowsCache&lt;br /&gt;
	end&lt;br /&gt;
	local csvData = mw.ext.externalData.getExternalData{&lt;br /&gt;
		url = &#039;https://wiki.pokemonrevolution.net/index.php?title=Special:GetData/PokemonRawList&#039;,&lt;br /&gt;
		format = DATA_FORMAT,&lt;br /&gt;
		data = COLUMNS,&lt;br /&gt;
	}&lt;br /&gt;
	allRowsCache = {}&lt;br /&gt;
	numberIndexCache = {}&lt;br /&gt;
	if csvData then&lt;br /&gt;
		for _, row in ipairs(csvData) do&lt;br /&gt;
			if nonEmpty(row.name) then&lt;br /&gt;
				allRowsCache[row.name] = row&lt;br /&gt;
				local num = nonEmpty(row.number)&lt;br /&gt;
				-- First occurrence wins so base forms beat Megas sharing a number.&lt;br /&gt;
				if num and numberIndexCache[num] == nil then&lt;br /&gt;
					numberIndexCache[num] = row&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return allRowsCache&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function hyphenSpaceVariant(s)&lt;br /&gt;
	if mw.ustring.find(s, &#039;-&#039;, 1, true) then&lt;br /&gt;
		return (mw.ustring.gsub(s, &#039;%-&#039;, &#039; &#039;))&lt;br /&gt;
	end&lt;br /&gt;
	return (mw.ustring.gsub(s, &#039; &#039;, &#039;-&#039;))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function byName(name)&lt;br /&gt;
	local rows = loadAllRows()&lt;br /&gt;
	return rows[name] or rows[hyphenSpaceVariant(name)]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function byNumber(number)&lt;br /&gt;
	loadAllRows()&lt;br /&gt;
	return numberIndexCache[tostring(number)]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local MEGA_COLUMNS = {&lt;br /&gt;
	number = &#039;Pokedex Number&#039;,&lt;br /&gt;
	name = &#039;Name&#039;,&lt;br /&gt;
	type1 = &#039;Type1&#039;,&lt;br /&gt;
	type2 = &#039;Type2&#039;,&lt;br /&gt;
	ability1 = &#039;Ability 1&#039;,&lt;br /&gt;
	ability2 = &#039;Ability 2&#039;,&lt;br /&gt;
	ha = &#039;Hidden Ability&#039;,&lt;br /&gt;
	generation = &#039;Generation&#039;,&lt;br /&gt;
	hp = &#039;HP&#039;,&lt;br /&gt;
	atk = &#039;Attack&#039;,&lt;br /&gt;
	def = &#039;Defense&#039;,&lt;br /&gt;
	spatk = &#039;Special Attack&#039;,&lt;br /&gt;
	spdef = &#039;Special Defense&#039;,&lt;br /&gt;
	spd = &#039;Speed&#039;,&lt;br /&gt;
	evhp = &#039;EVHP&#039;,&lt;br /&gt;
	evatk = &#039;EVATK&#039;,&lt;br /&gt;
	evdef = &#039;EVDEF&#039;,&lt;br /&gt;
	evspa = &#039;EVSPA&#039;,&lt;br /&gt;
	evspd = &#039;EVSPD&#039;,&lt;br /&gt;
	evsp = &#039;EVSP&#039;,&lt;br /&gt;
	height = &#039;Height&#039;,&lt;br /&gt;
	weight = &#039;Weight&#039;,&lt;br /&gt;
	stone = &#039;Stone&#039;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local MEGA_SPEC&lt;br /&gt;
do&lt;br /&gt;
	local parts = {}&lt;br /&gt;
	for key, header in pairs(MEGA_COLUMNS) do&lt;br /&gt;
		parts[#parts + 1] = key .. &#039;=&#039; .. header&lt;br /&gt;
	end&lt;br /&gt;
	MEGA_SPEC = table.concat(parts, &#039;,&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local megaCache = {}&lt;br /&gt;
&lt;br /&gt;
local function megaByName(name)&lt;br /&gt;
	if megaCache[name] == nil then&lt;br /&gt;
		local ok, values = pcall(function()&lt;br /&gt;
			return mw.ext.externalData.getFileData{&lt;br /&gt;
				source = &#039;data&#039;,&lt;br /&gt;
				[&#039;file name&#039;] = &#039;RawMegaPokemonList.csv&#039;,&lt;br /&gt;
				format = DATA_FORMAT,&lt;br /&gt;
				filters = &#039;Name=&#039; .. name,&lt;br /&gt;
				data = MEGA_SPEC,&lt;br /&gt;
			}&lt;br /&gt;
		end)&lt;br /&gt;
		if ok and values and values.name ~= nil then&lt;br /&gt;
			megaCache[name] = values&lt;br /&gt;
		else&lt;br /&gt;
			megaCache[name] = false&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return megaCache[name] or nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- formStem/rawListFormName now live in Module:PokemonForms, shared with&lt;br /&gt;
-- Module:Learnsets, so both resolve a form&#039;s raw-list name identically.&lt;br /&gt;
local formStem = PokemonForms.formStem&lt;br /&gt;
local rawListFormName = PokemonForms.rawListFormName&lt;br /&gt;
&lt;br /&gt;
local typeColorsCache = {}&lt;br /&gt;
local function typeColors(frame, pokeType)&lt;br /&gt;
	if not typeColorsCache[pokeType] then&lt;br /&gt;
		typeColorsCache[pokeType] = {&lt;br /&gt;
			light = frame:expandTemplate{ title = pokeType .. &#039; color light&#039; },&lt;br /&gt;
			base = frame:expandTemplate{ title = pokeType .. &#039; color&#039; },&lt;br /&gt;
			dark = frame:expandTemplate{ title = pokeType .. &#039; color dark&#039; },&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
	return typeColorsCache[pokeType]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local statColorCache = {}&lt;br /&gt;
local function statColors(frame, statTemplate)&lt;br /&gt;
	if not statColorCache[statTemplate] then&lt;br /&gt;
		statColorCache[statTemplate] = {&lt;br /&gt;
			base = frame:expandTemplate{ title = statTemplate .. &#039; color&#039; },&lt;br /&gt;
			dark = frame:expandTemplate{ title = statTemplate .. &#039; color dark&#039; },&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
	return statColorCache[statTemplate]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function navTableHtml(frame, data, colors, pageName)&lt;br /&gt;
	local number = tonumber(data.number)&lt;br /&gt;
&lt;br /&gt;
	local prevCell = &#039;&#039;&lt;br /&gt;
	if number and number &amp;gt; 1 then&lt;br /&gt;
		local prev = byNumber(number - 1)&lt;br /&gt;
		if prev then&lt;br /&gt;
			prevCell = &#039;&amp;amp;nbsp;[[File:&#039; .. prev.number .. &#039;Icon.png|&#039; .. prev.name .. &#039;|link=&#039; .. prev.name ..&lt;br /&gt;
				&#039;]]&amp;amp;nbsp;&amp;amp;nbsp;#&#039; .. padNumber(prev.number) .. &#039;&amp;amp;nbsp;[[&#039; .. prev.name .. &#039;]]&#039;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local nextCell = &#039;&#039;&lt;br /&gt;
	if number then&lt;br /&gt;
		local nxt = byNumber(number + 1)&lt;br /&gt;
		if nxt then&lt;br /&gt;
			nextCell = &#039;[[&#039; .. nxt.name .. &#039;]]&amp;amp;nbsp;#&#039; .. padNumber(nxt.number) .. &#039;&amp;amp;nbsp;&amp;amp;nbsp;[[File:&#039; ..&lt;br /&gt;
				nxt.number .. &#039;Icon.png|&#039; .. nxt.name .. &#039;|link=&#039; .. nxt.name .. &#039;]]&#039;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return &#039;&amp;lt;table style=&amp;quot;margin-left: auto; margin-right: auto; margin-bottom: 15px; height: 60px; &#039; ..&lt;br /&gt;
		&#039;border: 4px #&#039; .. colors.dark .. &#039; solid; font-weight: bold; width: 65%; color: #&#039; .. colors.dark ..&lt;br /&gt;
		&#039;; border-radius: 20px; padding: 3px; background: #&#039; .. colors.base .. &#039;;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;text-align: left; width: 36%; background: #&#039; .. colors.light ..&lt;br /&gt;
		&#039;; border-radius: 15px 1px 1px 15px; border: 1px solid #&#039; .. colors.dark .. &#039;;&amp;quot;&amp;gt;&#039; .. prevCell .. &#039;&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;text-align: center; width: 28%; background: #&#039; .. colors.light ..&lt;br /&gt;
		&#039;; border: 1px solid #&#039; .. colors.dark .. &#039;;&amp;quot;&amp;gt;#&#039; .. padNumber(number) .. &#039;&amp;amp;nbsp;&amp;amp;nbsp;-&amp;amp;nbsp;&amp;amp;nbsp;&#039; ..&lt;br /&gt;
		pageName .. &#039;&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;text-align: right; width: 36%; padding-right: 10px; background: #&#039; .. colors.light ..&lt;br /&gt;
		&#039;; border: 1px solid #&#039; .. colors.dark .. &#039;; border-radius: 1px 15px 15px 1px;&amp;quot;&amp;gt;&#039; .. nextCell .. &#039;&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.navTable(frame)&lt;br /&gt;
	local args = templateArgs(frame)&lt;br /&gt;
	local pageName = mw.title.getCurrentTitle().text&lt;br /&gt;
	local name = nonEmpty(args.Name) or pageName&lt;br /&gt;
&lt;br /&gt;
	local data = byName(name)&lt;br /&gt;
	if not data then&lt;br /&gt;
		return &#039;&amp;lt;strong class=&amp;quot;error&amp;quot;&amp;gt;PokeNavTable: no data found for &amp;quot;&#039; .. name .. &#039;&amp;quot;&amp;lt;/strong&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return navTableHtml(frame, data, typeColors(frame, data.type1), pageName)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function infoCell(colors, labelHtml, valueHtml)&lt;br /&gt;
	return &#039;&amp;lt;td colspan=&amp;quot;3&amp;quot; style=&amp;quot;width: 50%; border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; .. colors.light ..&lt;br /&gt;
		&#039;; border-radius: 15px; padding: 5px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;p style=&amp;quot;margin-bottom: 7px; font-weight: bold; color: #&#039; .. colors.dark .. &#039;;&amp;quot;&amp;gt;&#039; .. labelHtml .. &#039;&amp;lt;/p&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;span style=&amp;quot;border-radius: 12px; padding: 4px 10px; border: 1px solid #&#039; .. colors.dark ..&lt;br /&gt;
		&#039;; background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&#039; .. valueHtml .. &#039;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/span&amp;gt;&amp;lt;/td&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function abilityCell(colors, label, ability, widthPercent)&lt;br /&gt;
	if not ability then return &#039;&#039; end&lt;br /&gt;
	local style = &#039;border-radius: 12px; padding: 4px 10px; border: 1px solid #&#039; .. colors.dark ..&lt;br /&gt;
		&#039;; background-color: #FFFFFF;&#039;&lt;br /&gt;
	if widthPercent then&lt;br /&gt;
		style = &#039;width: &#039; .. widthPercent .. &#039;%; &#039; .. style&lt;br /&gt;
	end&lt;br /&gt;
	return &#039;&amp;lt;td style=&amp;quot;&#039; .. style .. &#039;&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&#039; .. label .. &#039;&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;[[&#039; .. ability .. &#039;_(ability)|&#039; .. ability ..&lt;br /&gt;
		&#039;]]&amp;lt;/td&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function abilitiesRow(colors, data)&lt;br /&gt;
	local entries = {&lt;br /&gt;
		{ &#039;Ability 1&#039;, nonEmpty(data.ability1) },&lt;br /&gt;
		{ &#039;Ability 2&#039;, nonEmpty(data.ability2) },&lt;br /&gt;
		{ &#039;Hidden Ability&#039;, nonEmpty(data.ha) },&lt;br /&gt;
	}&lt;br /&gt;
	local present = {}&lt;br /&gt;
	for _, entry in ipairs(entries) do&lt;br /&gt;
		if entry[2] then present[#present + 1] = entry end&lt;br /&gt;
	end&lt;br /&gt;
	local widthPercent = (#present &amp;gt; 0) and string.format(&#039;%.2f&#039;, 100 / #present) or nil&lt;br /&gt;
	local cells = {}&lt;br /&gt;
	for _, entry in ipairs(present) do&lt;br /&gt;
		cells[#cells + 1] = abilityCell(colors, entry[1], entry[2], widthPercent)&lt;br /&gt;
	end&lt;br /&gt;
	return table.concat(cells)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function statValueCell(frame, stat, value)&lt;br /&gt;
	local colors = statColors(frame, stat.template)&lt;br /&gt;
	return &#039;&amp;lt;td style=&amp;quot;width: 16.66%; border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; .. colors.base ..&lt;br /&gt;
		&#039;; border-radius: 12px; padding: 4px; font-size: 11px;&amp;quot;&amp;gt;\&#039;\&#039;\&#039;&#039; .. stat.label .. &#039;\&#039;\&#039;\&#039;&amp;lt;br&amp;gt;&#039; ..&lt;br /&gt;
		value .. &#039;&amp;lt;/td&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function statBarRow(frame, stat, value)&lt;br /&gt;
	local labelColors = statColors(frame, stat.template)&lt;br /&gt;
	local pct = math.floor(value / 255 * 100 + 0.5)&lt;br /&gt;
	if pct &amp;lt; 2 then pct = 2 end&lt;br /&gt;
	if pct &amp;gt; 100 then pct = 100 end&lt;br /&gt;
	local hue = math.floor(math.max(0, math.min(180, value * 180 / 255)) + 0.5)&lt;br /&gt;
	local fill = &#039;hsl(&#039; .. hue .. &#039;, 85%, 45%)&#039;&lt;br /&gt;
	return &#039;&amp;lt;tr&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;text-align: right; padding: 2px 8px 2px 4px; font-weight: bold; font-size: 12px; &#039; ..&lt;br /&gt;
		&#039;color: #&#039; .. labelColors.dark .. &#039;; white-space: nowrap;&amp;quot;&amp;gt;&#039; .. stat.label .. &#039;&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;width: 100%; padding: 2px 0;&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;background-color: #FFFFFF; border: 1px solid &#039; ..&lt;br /&gt;
		&#039;#999999; border-radius: 8px; height: 13px; overflow: hidden;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;div style=&amp;quot;width: &#039; .. pct .. &#039;%; height: 100%; background-color: &#039; .. fill .. &#039;;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;text-align: left; padding: 2px 4px 2px 8px; font-weight: bold; font-size: 12px; &#039; ..&lt;br /&gt;
		&#039;width: 34px;&amp;quot;&amp;gt;&#039; .. value .. &#039;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local MALE_COLOR = &#039;3B6BF5&#039;&lt;br /&gt;
local FEMALE_COLOR = &#039;F5629C&#039;&lt;br /&gt;
&lt;br /&gt;
local function genderRatioHtml(male)&lt;br /&gt;
	if male == &#039;Genderless&#039; then&lt;br /&gt;
		return &#039;&amp;lt;span style=&amp;quot;display: inline-block; color: #000000; background-color: #FFFFFF; &#039; ..&lt;br /&gt;
			&#039;border-radius: 12px; border: 1px solid #000000; padding: 3px 12px; font-weight: bold;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
			&#039;Genderless&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	local m = tonumber(male)&lt;br /&gt;
	if m == nil then&lt;br /&gt;
		m = nonEmpty(male) and 100 or 0&lt;br /&gt;
	end&lt;br /&gt;
	if m &amp;lt; 0 then m = 0 end&lt;br /&gt;
	if m &amp;gt; 100 then m = 100 end&lt;br /&gt;
	local f = 100 - m&lt;br /&gt;
&lt;br /&gt;
	local segments = &#039;&#039;&lt;br /&gt;
	if m &amp;gt; 0 then&lt;br /&gt;
		segments = segments .. &#039;&amp;lt;div style=&amp;quot;width: &#039; .. m .. &#039;%; background-color: #&#039; .. MALE_COLOR .. &#039;;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	if f &amp;gt; 0 then&lt;br /&gt;
		segments = segments .. &#039;&amp;lt;div style=&amp;quot;width: &#039; .. f .. &#039;%; background-color: #&#039; .. FEMALE_COLOR .. &#039;;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local labels = {}&lt;br /&gt;
	if m &amp;gt; 0 then&lt;br /&gt;
		labels[#labels + 1] = &#039;&amp;lt;span style=&amp;quot;color: #&#039; .. MALE_COLOR .. &#039;; font-weight: bold;&amp;quot;&amp;gt;&#039; .. m .. &#039;% ♂&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	if f &amp;gt; 0 then&lt;br /&gt;
		labels[#labels + 1] = &#039;&amp;lt;span style=&amp;quot;color: #&#039; .. FEMALE_COLOR .. &#039;; font-weight: bold;&amp;quot;&amp;gt;&#039; .. f .. &#039;% ♀&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return &#039;&amp;lt;div style=&amp;quot;width: 85%; margin: 4px auto 0;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;div style=&amp;quot;display: flex; height: 12px; border-radius: 8px; overflow: hidden; &#039; ..&lt;br /&gt;
		&#039;border: 1px solid #555555; background-color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. segments .. &#039;&amp;lt;/div&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;div style=&amp;quot;margin-top: 4px; font-size: 12px;&amp;quot;&amp;gt;&#039; .. table.concat(labels, &#039; &amp;amp;nbsp;·&amp;amp;nbsp; &#039;) ..&lt;br /&gt;
		&#039;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function categories(data, gen, bstCategory, args)&lt;br /&gt;
	local cats = { &#039;[[Category:Pokémon species]]&#039; }&lt;br /&gt;
	if gen then&lt;br /&gt;
		cats[#cats + 1] = &#039;[[Category:Generation &#039; .. gen .. &#039; Pokémon]]&#039;&lt;br /&gt;
	end&lt;br /&gt;
	cats[#cats + 1] = &#039;[[Category:&#039; .. data.type1 .. &#039;-type Pokémon]]&#039;&lt;br /&gt;
	if nonEmpty(data.type2) then&lt;br /&gt;
		cats[#cats + 1] = &#039;[[Category:&#039; .. data.type2 .. &#039;-type Pokémon]]&#039;&lt;br /&gt;
	end&lt;br /&gt;
	cats[#cats + 1] = &#039;[[Category:&#039; .. data.rarity .. &#039; Pokémon]]&#039;&lt;br /&gt;
	if nonEmpty(data.npc) then&lt;br /&gt;
		cats[#cats + 1] = &#039;[[Category:NPC-obtainable Pokémon]]&#039;&lt;br /&gt;
	end&lt;br /&gt;
	if not nonEmpty(args.EvolvesFrom) then&lt;br /&gt;
		cats[#cats + 1] = &#039;[[Category:Base-stage Pokémon]]&#039;&lt;br /&gt;
	end&lt;br /&gt;
	cats[#cats + 1] = &#039;[[Category:&#039; .. bstCategory .. &#039;-plus-BST Pokémon]]&#039;&lt;br /&gt;
	return table.concat(cats, &#039; &#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function infoboxHtml(frame, args, data, displayName, width, pageName, includeNav)&lt;br /&gt;
	local colors = typeColors(frame, data.type1)&lt;br /&gt;
	-- Regional forms carry values like &#039;1A&#039;/&#039;5A&#039;; use the leading digits.&lt;br /&gt;
	local gen = GEN_NUMERALS[tonumber(mw.ustring.match(tostring(data.generation or &#039;&#039;), &#039;^%d+&#039;) or &#039;&#039;)]&lt;br /&gt;
&lt;br /&gt;
	-- Types pill(s).&lt;br /&gt;
	local typesHtml&lt;br /&gt;
	if nonEmpty(data.type2) then&lt;br /&gt;
		local type2Colors = typeColors(frame, data.type2)&lt;br /&gt;
		typesHtml =&lt;br /&gt;
			&#039;&amp;lt;td style=&amp;quot;width: 50%; background-color: #&#039; .. colors.dark .. &#039;; border-radius: 25px 1px 1px 25px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
			&#039;[[&#039; .. data.type1 .. &#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. data.type1 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
			&#039;&amp;lt;td style=&amp;quot;width: 50%; background-color: #&#039; .. type2Colors.dark .. &#039;; border-radius: 1px 25px 25px 1px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
			&#039;[[&#039; .. data.type2 .. &#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. data.type2 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&#039;&lt;br /&gt;
	else&lt;br /&gt;
		typesHtml =&lt;br /&gt;
			&#039;&amp;lt;td style=&amp;quot;width:100%; background-color: #&#039; .. colors.dark .. &#039;; border-radius: 25px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
			&#039;[[&#039; .. data.type1 .. &#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. data.type1 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Base stats&lt;br /&gt;
	local statRows, bst = {}, 0&lt;br /&gt;
	for _, stat in ipairs(STATS) do&lt;br /&gt;
		local value = tonumber(data[stat.key]) or 0&lt;br /&gt;
		bst = bst + value&lt;br /&gt;
		statRows[#statRows + 1] = statBarRow(frame, stat, value)&lt;br /&gt;
	end&lt;br /&gt;
	local bstCategory = math.floor(bst / 100 + 0.5) * 100&lt;br /&gt;
&lt;br /&gt;
	-- EV yield.&lt;br /&gt;
	local evCells, evTotal = {}, 0&lt;br /&gt;
	for i, stat in ipairs(STATS) do&lt;br /&gt;
		local ev = tonumber(data[EV_KEYS[i]]) or 0&lt;br /&gt;
		evTotal = evTotal + ev&lt;br /&gt;
		evCells[#evCells + 1] = statValueCell(frame, stat, ev)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Catch rate.&lt;br /&gt;
	local catchRaw = tonumber(data.catch) or 0&lt;br /&gt;
	local catchPercent = string.format(&#039;%.2f&#039;, catchRaw / 255 / 3 * 100)&lt;br /&gt;
&lt;br /&gt;
	local buf = {}&lt;br /&gt;
	if includeNav then&lt;br /&gt;
		buf[#buf + 1] = navTableHtml(frame, data, colors, pageName)&lt;br /&gt;
	end&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;table align=&amp;quot;right&amp;quot; class=&amp;quot;informational-box&amp;quot; cellpadding=&amp;quot;4&amp;quot; cellspacing=&amp;quot;4&amp;quot; &#039; ..&lt;br /&gt;
		&#039;style=&amp;quot;width: &#039; .. width .. &#039;%; border: 4px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.base .. &#039;; padding: 4px; border-radius: 15px;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Header: dex number + icon, name.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;3&amp;quot; style=&amp;quot;width: 50%; border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; border-radius: 15px;&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;margin-bottom: 7px; font-weight: bold; color:#&#039; ..&lt;br /&gt;
		colors.dark .. &#039;;&amp;quot;&amp;gt;#&#039; .. padNumber(data.number) .. &#039;&amp;lt;/span&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;[[File:&#039; .. data.number ..&lt;br /&gt;
		&#039;Icon.png]]&amp;lt;/td&amp;gt;&amp;lt;td colspan=&amp;quot;3&amp;quot; style=&amp;quot;width: 50%; border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; border-radius: 15px;&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;margin-bottom: 7px; font-weight: bold; color:#&#039; ..&lt;br /&gt;
		colors.dark .. &#039;;&amp;quot;&amp;gt;&#039; .. displayName .. &#039;&amp;lt;/span&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Artwork.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;6&amp;quot; style=&amp;quot;border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; border-radius: 15px; padding: 5px;&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;border-radius: 15px; &#039; ..&lt;br /&gt;
		&#039;text-align: center; padding: 5px; background-color: #FFFFFF;&amp;quot;&amp;gt;[[File:&#039; .. data.number .. data.name ..&lt;br /&gt;
		&#039;.png|150px]]&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Types + Generation.&lt;br /&gt;
	local genHtml = &#039;—&#039;&lt;br /&gt;
	if gen then&lt;br /&gt;
		genHtml = &#039;[[:Category:Generation &#039; .. gen .. &#039; Pokémon|&amp;lt;span style=&amp;quot;color:#&#039; ..&lt;br /&gt;
			colors.dark .. &#039;;&amp;quot;&amp;gt;&#039; .. gen .. &#039;&amp;lt;/span&amp;gt;]]&#039;&lt;br /&gt;
	end&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;3&amp;quot; style=&amp;quot;width: 50%; border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; padding: 11px; border-radius: 15px;&amp;quot;&amp;gt;&amp;lt;p style=&amp;quot;margin-bottom: 7px; font-weight: bold; &#039; ..&lt;br /&gt;
		&#039;color: #&#039; .. colors.dark .. &#039;;&amp;quot;&amp;gt;Types&amp;lt;/p&amp;gt;&amp;lt;table align=&amp;quot;center&amp;quot; style=&amp;quot;width: 75%; font-weight: bold; &#039; ..&lt;br /&gt;
		&#039;padding: 3px;&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&#039; .. typesHtml .. &#039;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td colspan=&amp;quot;3&amp;quot; style=&amp;quot;width: 50%; border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; .. colors.light ..&lt;br /&gt;
		&#039;; border-radius: 15px;&amp;quot;&amp;gt;&amp;lt;p style=&amp;quot;margin-bottom: 7px; font-weight: bold; color: #&#039; .. colors.dark ..&lt;br /&gt;
		&#039;;&amp;quot;&amp;gt;Generation&amp;lt;/p&amp;gt;&amp;lt;span style=&amp;quot;border-radius: 12px; padding: 4px 10px; border: 1px solid #&#039; .. colors.dark ..&lt;br /&gt;
		&#039;; background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&#039; .. genHtml .. &#039;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/span&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Abilities.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;6&amp;quot; style=&amp;quot;border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; padding: 11px; border-radius: 15px; width: 100%;&amp;quot;&amp;gt;&amp;lt;table width=&amp;quot;100%&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&amp;lt;th colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;p style=&amp;quot;margin-bottom: 7px; font-weight: bold; color:#&#039; .. colors.dark ..&lt;br /&gt;
		&#039;;&amp;quot;&amp;gt;[[Abilities|&amp;lt;span style=&amp;quot;color:#&#039; .. colors.dark .. &#039;;&amp;quot;&amp;gt;Abilities&amp;lt;/span&amp;gt;]]&amp;lt;/p&amp;gt;&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&#039; .. abilitiesRow(colors, data) .. &#039;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Rarity + Catch rate.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&#039; ..&lt;br /&gt;
		infoCell(colors, &#039;[[List of Pokémon by Rarity Tier|&amp;lt;span style=&amp;quot;color:#&#039; .. colors.dark ..&lt;br /&gt;
			&#039;;&amp;quot;&amp;gt;Rarity Tier&amp;lt;/span&amp;gt;]]&#039;, &#039;[[:Category:&#039; .. data.rarity .. &#039; Pokémon|&amp;lt;span style=&amp;quot;color:#&#039; ..&lt;br /&gt;
			colors.dark .. &#039;;&amp;quot;&amp;gt;&#039; .. data.rarity .. &#039;&amp;lt;/span&amp;gt;]]&#039;) ..&lt;br /&gt;
		infoCell(colors, &#039;[[Catch Rates|&amp;lt;span style=&amp;quot;color:#&#039; .. colors.dark .. &#039;;&amp;quot;&amp;gt;Catch rate&amp;lt;/span&amp;gt;]]&#039;,&lt;br /&gt;
			data.catch .. &#039;/255 (&#039; .. catchPercent .. &#039;%)&#039;) ..&lt;br /&gt;
		&#039;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Base stats.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;6&amp;quot; style=&amp;quot;border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; border-radius: 15px; padding: 8px; width: 100%&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;table width=&amp;quot;100%&amp;quot; style=&amp;quot;border-collapse: collapse;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&amp;lt;th colspan=&amp;quot;3&amp;quot;&amp;gt;&amp;lt;p style=&amp;quot;margin-bottom: 7px; font-weight: bold; color: #&#039; .. colors.dark ..&lt;br /&gt;
		&#039;;&amp;quot;&amp;gt;[[Base stats|&amp;lt;span style=&amp;quot;color: #&#039; .. colors.dark .. &#039;;&amp;quot;&amp;gt;Base stats&amp;lt;/span&amp;gt;]]&amp;lt;/p&amp;gt;&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&#039; ..&lt;br /&gt;
		table.concat(statRows) ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;3&amp;quot; style=&amp;quot;text-align: center; padding-top: 6px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;div style=&amp;quot;display: inline-block; background-color: #FFFFFF; border: 1px solid #&#039; .. colors.dark ..&lt;br /&gt;
		&#039;; padding: 4px 14px; border-radius: 12px;&amp;quot;&amp;gt;Base-stat total: &#039; .. bst .. &#039;&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;/table&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- EV yield.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;6&amp;quot; style=&amp;quot;border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; border-radius: 15px; padding: 5px; width: 100%&amp;quot;&amp;gt;&amp;lt;table width=&amp;quot;100%&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&amp;lt;th colspan=&amp;quot;6&amp;quot;&amp;gt;[[EVs|&amp;lt;span style=&amp;quot;margin-bottom: 7px; font-weight: bold; color: #&#039; .. colors.dark ..&lt;br /&gt;
		&#039;;&amp;quot;&amp;gt;EV Yield&amp;lt;/span&amp;gt;]]&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&#039; .. table.concat(evCells) .. &#039;&amp;lt;/tr&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;margin: auto; background-color:#FFFFFF; border: 1px solid #&#039; ..&lt;br /&gt;
		colors.dark .. &#039;; padding: 4px 14px; border-radius: 12px; margin-bottom: 5px; width: 50%;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;EV-yield total: &#039; .. evTotal .. &#039;&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Base experience + Gender ratio.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&#039; ..&lt;br /&gt;
		infoCell(colors, &#039;[[Experience System#Base Experience|&amp;lt;span style=&amp;quot;color:#&#039; .. colors.dark ..&lt;br /&gt;
			&#039;;&amp;quot;&amp;gt;Base Experience&amp;lt;/span&amp;gt;]]&#039;, data.exp) ..&lt;br /&gt;
		&#039;&amp;lt;td colspan=&amp;quot;3&amp;quot; style=&amp;quot;width: 50%; border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; .. colors.light ..&lt;br /&gt;
		&#039;; border-radius: 15px; padding: 5px;&amp;quot;&amp;gt;&amp;lt;p style=&amp;quot;margin-bottom: 7px; font-weight: bold; color: #&#039; ..&lt;br /&gt;
		colors.dark .. &#039;;&amp;quot;&amp;gt;Gender Ratio&amp;lt;/p&amp;gt;&#039; .. genderRatioHtml(data.male) .. &#039;&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Height + Weight.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&#039; ..&lt;br /&gt;
		infoCell(colors, &#039;Height&#039;, data.height .. &#039;m&#039;) ..&lt;br /&gt;
		infoCell(colors, &#039;Weight&#039;, data.weight .. &#039;kg&#039;) ..&lt;br /&gt;
		&#039;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;/table&amp;gt;&#039;&lt;br /&gt;
	buf[#buf + 1] = categories(data, gen, bstCategory, args)&lt;br /&gt;
&lt;br /&gt;
	return table.concat(buf)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function megaInfoboxHtml(frame, data, width)&lt;br /&gt;
	local colors = typeColors(frame, data.type1)&lt;br /&gt;
	local gen = GEN_NUMERALS[tonumber(mw.ustring.match(tostring(data.generation or &#039;&#039;), &#039;^%d+&#039;) or &#039;&#039;)]&lt;br /&gt;
	local displayName = &#039;Mega &#039; .. (data.name or &#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
	local typesHtml&lt;br /&gt;
	if nonEmpty(data.type2) then&lt;br /&gt;
		local type2Colors = typeColors(frame, data.type2)&lt;br /&gt;
		typesHtml =&lt;br /&gt;
			&#039;&amp;lt;td style=&amp;quot;width: 50%; background-color: #&#039; .. colors.dark .. &#039;; border-radius: 25px 1px 1px 25px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
			&#039;[[&#039; .. data.type1 .. &#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. data.type1 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
			&#039;&amp;lt;td style=&amp;quot;width: 50%; background-color: #&#039; .. type2Colors.dark .. &#039;; border-radius: 1px 25px 25px 1px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
			&#039;[[&#039; .. data.type2 .. &#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. data.type2 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&#039;&lt;br /&gt;
	else&lt;br /&gt;
		typesHtml =&lt;br /&gt;
			&#039;&amp;lt;td style=&amp;quot;width:100%; background-color: #&#039; .. colors.dark .. &#039;; border-radius: 25px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
			&#039;[[&#039; .. data.type1 .. &#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. data.type1 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local statRows, bst = {}, 0&lt;br /&gt;
	for _, stat in ipairs(STATS) do&lt;br /&gt;
		local value = tonumber(data[stat.key]) or 0&lt;br /&gt;
		bst = bst + value&lt;br /&gt;
		statRows[#statRows + 1] = statBarRow(frame, stat, value)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local evCells, evTotal = {}, 0&lt;br /&gt;
	for i, stat in ipairs(STATS) do&lt;br /&gt;
		local ev = tonumber(data[EV_KEYS[i]]) or 0&lt;br /&gt;
		evTotal = evTotal + ev&lt;br /&gt;
		evCells[#evCells + 1] = statValueCell(frame, stat, ev)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local buf = {}&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;table align=&amp;quot;right&amp;quot; class=&amp;quot;informational-box&amp;quot; cellpadding=&amp;quot;4&amp;quot; cellspacing=&amp;quot;4&amp;quot; &#039; ..&lt;br /&gt;
		&#039;style=&amp;quot;width: &#039; .. width .. &#039;%; border: 4px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.base .. &#039;; padding: 4px; border-radius: 15px;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Header: name across the whole top line.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;6&amp;quot; style=&amp;quot;border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; border-radius: 15px;&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;margin-bottom: 7px; font-weight: bold; color:#&#039; ..&lt;br /&gt;
		colors.dark .. &#039;;&amp;quot;&amp;gt;&#039; .. displayName .. &#039;&amp;lt;/span&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Artwork.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;6&amp;quot; style=&amp;quot;border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; border-radius: 15px; padding: 5px;&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;border-radius: 15px; &#039; ..&lt;br /&gt;
		&#039;text-align: center; padding: 5px; background-color: #FFFFFF;&amp;quot;&amp;gt;[[File:&#039; .. (data.number or &#039;&#039;) .. (data.name or &#039;&#039;) ..&lt;br /&gt;
		&#039;-Mega.png|150px]]&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Types + Generation.&lt;br /&gt;
	local genHtml = &#039;—&#039;&lt;br /&gt;
	if gen then&lt;br /&gt;
		genHtml = &#039;[[:Category:Generation &#039; .. gen .. &#039; Pokémon|&amp;lt;span style=&amp;quot;color:#&#039; ..&lt;br /&gt;
			colors.dark .. &#039;;&amp;quot;&amp;gt;&#039; .. gen .. &#039;&amp;lt;/span&amp;gt;]]&#039;&lt;br /&gt;
	end&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;3&amp;quot; style=&amp;quot;width: 50%; border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; padding: 11px; border-radius: 15px;&amp;quot;&amp;gt;&amp;lt;p style=&amp;quot;margin-bottom: 7px; font-weight: bold; &#039; ..&lt;br /&gt;
		&#039;color: #&#039; .. colors.dark .. &#039;;&amp;quot;&amp;gt;Types&amp;lt;/p&amp;gt;&amp;lt;table align=&amp;quot;center&amp;quot; style=&amp;quot;width: 75%; font-weight: bold; &#039; ..&lt;br /&gt;
		&#039;padding: 3px;&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&#039; .. typesHtml .. &#039;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td colspan=&amp;quot;3&amp;quot; style=&amp;quot;width: 50%; border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; .. colors.light ..&lt;br /&gt;
		&#039;; border-radius: 15px;&amp;quot;&amp;gt;&amp;lt;p style=&amp;quot;margin-bottom: 7px; font-weight: bold; color: #&#039; .. colors.dark ..&lt;br /&gt;
		&#039;;&amp;quot;&amp;gt;Generation&amp;lt;/p&amp;gt;&amp;lt;span style=&amp;quot;border-radius: 12px; padding: 4px 10px; border: 1px solid #&#039; .. colors.dark ..&lt;br /&gt;
		&#039;; background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&#039; .. genHtml .. &#039;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/span&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Abilities.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;6&amp;quot; style=&amp;quot;border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; padding: 11px; border-radius: 15px; width: 100%;&amp;quot;&amp;gt;&amp;lt;table width=&amp;quot;100%&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&amp;lt;th colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;p style=&amp;quot;margin-bottom: 7px; font-weight: bold; color:#&#039; .. colors.dark ..&lt;br /&gt;
		&#039;;&amp;quot;&amp;gt;[[Abilities|&amp;lt;span style=&amp;quot;color:#&#039; .. colors.dark .. &#039;;&amp;quot;&amp;gt;Abilities&amp;lt;/span&amp;gt;]]&amp;lt;/p&amp;gt;&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&#039; .. abilitiesRow(colors, data) .. &#039;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Mega Stone, linked to its quest page (&amp;quot;Venusaurite (quest)&amp;quot;).&lt;br /&gt;
	local stone = nonEmpty(data.stone)&lt;br /&gt;
	local stoneHtml = &#039;—&#039;&lt;br /&gt;
	if stone then&lt;br /&gt;
		stoneHtml = &#039;[[&#039; .. stone .. &#039; (quest)|&amp;lt;span style=&amp;quot;color:#&#039; .. colors.dark .. &#039;;&amp;quot;&amp;gt;&#039; .. stone .. &#039;&amp;lt;/span&amp;gt;]]&#039;&lt;br /&gt;
	end&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;6&amp;quot; style=&amp;quot;border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; border-radius: 15px; padding: 5px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;p style=&amp;quot;margin-bottom: 7px; font-weight: bold; color: #&#039; .. colors.dark .. &#039;;&amp;quot;&amp;gt;Mega Stone&amp;lt;/p&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;span style=&amp;quot;border-radius: 12px; padding: 4px 10px; border: 1px solid #&#039; .. colors.dark ..&lt;br /&gt;
		&#039;; background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&#039; .. stoneHtml .. &#039;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/span&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Base stats.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;6&amp;quot; style=&amp;quot;border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; border-radius: 15px; padding: 8px; width: 100%&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;table width=&amp;quot;100%&amp;quot; style=&amp;quot;border-collapse: collapse;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&amp;lt;th colspan=&amp;quot;3&amp;quot;&amp;gt;&amp;lt;p style=&amp;quot;margin-bottom: 7px; font-weight: bold; color: #&#039; .. colors.dark ..&lt;br /&gt;
		&#039;;&amp;quot;&amp;gt;[[Base stats|&amp;lt;span style=&amp;quot;color: #&#039; .. colors.dark .. &#039;;&amp;quot;&amp;gt;Base stats&amp;lt;/span&amp;gt;]]&amp;lt;/p&amp;gt;&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&#039; ..&lt;br /&gt;
		table.concat(statRows) ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;3&amp;quot; style=&amp;quot;text-align: center; padding-top: 6px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;div style=&amp;quot;display: inline-block; background-color: #FFFFFF; border: 1px solid #&#039; .. colors.dark ..&lt;br /&gt;
		&#039;; padding: 4px 14px; border-radius: 12px;&amp;quot;&amp;gt;Base-stat total: &#039; .. bst .. &#039;&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;/table&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- EV yield.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;6&amp;quot; style=&amp;quot;border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; border-radius: 15px; padding: 5px; width: 100%&amp;quot;&amp;gt;&amp;lt;table width=&amp;quot;100%&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&amp;lt;th colspan=&amp;quot;6&amp;quot;&amp;gt;[[EVs|&amp;lt;span style=&amp;quot;margin-bottom: 7px; font-weight: bold; color: #&#039; .. colors.dark ..&lt;br /&gt;
		&#039;;&amp;quot;&amp;gt;EV Yield&amp;lt;/span&amp;gt;]]&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&#039; .. table.concat(evCells) .. &#039;&amp;lt;/tr&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;margin: auto; background-color:#FFFFFF; border: 1px solid #&#039; ..&lt;br /&gt;
		colors.dark .. &#039;; padding: 4px 14px; border-radius: 12px; margin-bottom: 5px; width: 50%;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;EV-yield total: &#039; .. evTotal .. &#039;&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Height + Weight.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&#039; ..&lt;br /&gt;
		infoCell(colors, &#039;Height&#039;, (data.height or &#039;—&#039;) .. &#039;m&#039;) ..&lt;br /&gt;
		infoCell(colors, &#039;Weight&#039;, (data.weight or &#039;—&#039;) .. &#039;kg&#039;) ..&lt;br /&gt;
		&#039;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;/table&amp;gt;&#039;&lt;br /&gt;
	buf[#buf + 1] = &#039;[[Category:Mega-Evolvable Pokémon]]&#039;&lt;br /&gt;
&lt;br /&gt;
	return table.concat(buf)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.infobox(frame)&lt;br /&gt;
	local args = templateArgs(frame)&lt;br /&gt;
	local pageName = mw.title.getCurrentTitle().text&lt;br /&gt;
	local name = nonEmpty(args.Name) or pageName&lt;br /&gt;
	local width = nonEmpty(args.Width) or &#039;45&#039;&lt;br /&gt;
&lt;br /&gt;
	local data = byName(name)&lt;br /&gt;
	if not data then&lt;br /&gt;
		return &#039;&amp;lt;strong class=&amp;quot;error&amp;quot;&amp;gt;PokemonInfo: no data found for &amp;quot;&#039; .. name .. &#039;&amp;quot;&amp;lt;/strong&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	frame:callParserFunction(&#039;#vardefine&#039;, &#039;type&#039;, data.type1 or &#039;Normal&#039;)&lt;br /&gt;
&lt;br /&gt;
	return infoboxHtml(frame, args, data, name, width, pageName, true)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.primaryType(frame)&lt;br /&gt;
	local args = templateArgs(frame)&lt;br /&gt;
	local name = nonEmpty(args.Name) or mw.title.getCurrentTitle().text&lt;br /&gt;
	local data = byName(name) or byName(formStem(name))&lt;br /&gt;
	return (data and nonEmpty(data.type1)) or &#039;Normal&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function requestedName(frame)&lt;br /&gt;
	local parent = frame:getParent()&lt;br /&gt;
	return nonEmpty(frame.args.Name)&lt;br /&gt;
		or (parent and nonEmpty(parent.args.Name))&lt;br /&gt;
		or mw.title.getCurrentTitle().text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local participantsCache = {}&lt;br /&gt;
&lt;br /&gt;
local function computeParticipants(frame, name)&lt;br /&gt;
	if participantsCache[name] ~= nil then&lt;br /&gt;
		return participantsCache[name] or nil&lt;br /&gt;
	end&lt;br /&gt;
	local rows = loadAllRows()&lt;br /&gt;
	local function rowFor(n)&lt;br /&gt;
		return rows[n] or rows[hyphenSpaceVariant(n)]&lt;br /&gt;
	end&lt;br /&gt;
	local stem = formStem(name)&lt;br /&gt;
	local baseData = rowFor(stem) or rowFor(name)&lt;br /&gt;
	if not baseData then&lt;br /&gt;
		participantsCache[name] = false&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
	local baseDexNumber = mw.ustring.match(tostring(baseData.number or &#039;&#039;), &#039;^%d+&#039;)&lt;br /&gt;
&lt;br /&gt;
	local parts = { { data = baseData, label = &#039;Normal&#039; } }&lt;br /&gt;
	local seen = { [baseData.name] = true }&lt;br /&gt;
	for _, form in ipairs(FORM_SUFFIXES) do&lt;br /&gt;
		local row = rowFor(rawListFormName(form, stem))&lt;br /&gt;
		-- A candidate must share the same base dex number to be a real form of&lt;br /&gt;
		-- this Pokémon. Without this check, stripping &amp;quot;Nidoran Male&amp;quot; down to&lt;br /&gt;
		-- the stem &amp;quot;Nidoran&amp;quot; (done because &amp;quot;Male&amp;quot; is a real form suffix for&lt;br /&gt;
		-- Indeedee/Meowstic-style species) lets &amp;quot;Nidoran&amp;quot; + &amp;quot; Female&amp;quot; happen to&lt;br /&gt;
		-- match the raw list&#039;s &amp;quot;Nidoran Female&amp;quot; row — a wholly different&lt;br /&gt;
		-- species (dex #29 vs Male&#039;s #32), not this one&#039;s gender form.&lt;br /&gt;
		local rowDexNumber = row and mw.ustring.match(tostring(row.number or &#039;&#039;), &#039;^%d+&#039;)&lt;br /&gt;
		if row and not seen[row.name] and rowDexNumber == baseDexNumber then&lt;br /&gt;
			seen[row.name] = true&lt;br /&gt;
			parts[#parts + 1] = { data = row, label = form.label }&lt;br /&gt;
			if form.baseLabel then&lt;br /&gt;
				parts[1].label = form.baseLabel&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	for _, variant in ipairs(MEGA_VARIANTS) do&lt;br /&gt;
		local row = megaByName(stem .. variant)&lt;br /&gt;
		if row then&lt;br /&gt;
			parts[#parts + 1] = { data = row, label = &#039;Mega&#039; .. variant, mega = true }&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	participantsCache[name] = parts&lt;br /&gt;
	return parts&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.formLabel(frame)&lt;br /&gt;
	local idx = tonumber(frame.args[1]) or 0&lt;br /&gt;
	local parts = computeParticipants(frame, requestedName(frame))&lt;br /&gt;
	if not parts then&lt;br /&gt;
		return &#039;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	local part = parts[idx + 1]&lt;br /&gt;
	return part and part.label or &#039;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.rawName(frame)&lt;br /&gt;
	local name = requestedName(frame)&lt;br /&gt;
	local parts = computeParticipants(frame, name)&lt;br /&gt;
	return (parts and parts[1].data.name) or name&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Per-form tab-button colors (index-based, same convention as formLabel):&lt;br /&gt;
-- Tabs:MultiformTab only ever had one shared color for the whole button row&lt;br /&gt;
-- (set once via TabbedInfoBoxes&#039; own {{Trichrome}} call), so no button could&lt;br /&gt;
-- ever reflect its own form. These feed Border=/Cell= overrides added to&lt;br /&gt;
-- Tabs:MultiformTab so each button is colored to the form it actually opens.&lt;br /&gt;
function p.formBorder(frame)&lt;br /&gt;
	local idx = tonumber(frame.args[1]) or 0&lt;br /&gt;
	local parts = computeParticipants(frame, requestedName(frame))&lt;br /&gt;
	local part = parts and parts[idx + 1]&lt;br /&gt;
	if not part then return &#039;&#039; end&lt;br /&gt;
	return &#039;#&#039; .. typeColors(frame, part.data.type1).dark&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.formCell(frame)&lt;br /&gt;
	local idx = tonumber(frame.args[1]) or 0&lt;br /&gt;
	local parts = computeParticipants(frame, requestedName(frame))&lt;br /&gt;
	local part = parts and parts[idx + 1]&lt;br /&gt;
	if not part then return &#039;&#039; end&lt;br /&gt;
	return &#039;#&#039; .. typeColors(frame, part.data.type1).light&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Nav bar duplicated per form (index-based) so it can be embedded inside&lt;br /&gt;
-- each tab&#039;s own content instead of once above the whole tab shell, which&lt;br /&gt;
-- is what made it structurally unable to react to which tab is active.&lt;br /&gt;
-- Prev/next always come from the base species&#039; own dex number (form dex&lt;br /&gt;
-- strings like &amp;quot;52A&amp;quot; aren&#039;t a meaningful sequence to navigate by) -- only&lt;br /&gt;
-- the color changes per form.&lt;br /&gt;
function p.formNavTable(frame)&lt;br /&gt;
	local pageName = mw.title.getCurrentTitle().text&lt;br /&gt;
	local idx = tonumber(frame.args[1]) or 0&lt;br /&gt;
	local parts = computeParticipants(frame, requestedName(frame))&lt;br /&gt;
	if not parts then&lt;br /&gt;
		return &#039;&amp;lt;strong class=&amp;quot;error&amp;quot;&amp;gt;PokeNavTable: no data found for &amp;quot;&#039; .. pageName .. &#039;&amp;quot;&amp;lt;/strong&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	local basePart = parts[1]&lt;br /&gt;
	local activePart = parts[idx + 1] or basePart&lt;br /&gt;
	return navTableHtml(frame, basePart.data, typeColors(frame, activePart.data.type1), pageName)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.formBox(frame)&lt;br /&gt;
	local idx = tonumber(frame.args[1]) or 0&lt;br /&gt;
	local width = nonEmpty(frame.args.Width) or &#039;100&#039;&lt;br /&gt;
	local name = requestedName(frame)&lt;br /&gt;
	local parts = computeParticipants(frame, name)&lt;br /&gt;
	if not parts then&lt;br /&gt;
		return &#039;&amp;lt;strong class=&amp;quot;error&amp;quot;&amp;gt;PokemonInfo: no data found for &amp;quot;&#039; .. name .. &#039;&amp;quot;&amp;lt;/strong&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	local part = parts[idx + 1]&lt;br /&gt;
	if not part then&lt;br /&gt;
		return &#039;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	if part.mega then&lt;br /&gt;
		return megaInfoboxHtml(frame, part.data, width)&lt;br /&gt;
	end&lt;br /&gt;
	local parent = frame:getParent()&lt;br /&gt;
	local args = (parent and parent.args) or frame.args&lt;br /&gt;
	return infoboxHtml(frame, args, part.data, part.data.name, width, mw.title.getCurrentTitle().text, false)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Castform&amp;diff=41075</id>
		<title>Castform</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Castform&amp;diff=41075"/>
		<updated>2026-08-09T13:22:13Z</updated>

		<summary type="html">&lt;p&gt;Cae: new nav and info&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{PokemonInfoAndNav}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;{{PAGENAME}}&#039;&#039;&#039; is a [[Normal (type)|Normal]] type Pokémon. &lt;br /&gt;
&lt;br /&gt;
It has 4 different forms that vary depending on the weather.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obtainability==&lt;br /&gt;
{{PokemonSpawnData}}&lt;br /&gt;
&lt;br /&gt;
{{Learnsets|{{PAGENAME}}}}&lt;br /&gt;
&lt;br /&gt;
==Type Effectiveness==&lt;br /&gt;
{{PokemonTypeEffectiveness}}&lt;br /&gt;
&lt;br /&gt;
==Special Counterparts==&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Shiny_Castform.png|Shiny Castform&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Module:Pokemon&amp;diff=41074</id>
		<title>Module:Pokemon</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Module:Pokemon&amp;diff=41074"/>
		<updated>2026-08-09T12:37:41Z</updated>

		<summary type="html">&lt;p&gt;Cae: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {}&lt;br /&gt;
&lt;br /&gt;
local DATA_FORMAT = &#039;CSV with header&#039;&lt;br /&gt;
&lt;br /&gt;
local COLUMNS = {&lt;br /&gt;
	number = &#039;Pokedex Number&#039;,&lt;br /&gt;
	name = &#039;Name&#039;,&lt;br /&gt;
	type1 = &#039;Type1&#039;,&lt;br /&gt;
	type2 = &#039;Type2&#039;,&lt;br /&gt;
	ability1 = &#039;Ability 1&#039;,&lt;br /&gt;
	ability2 = &#039;Ability 2&#039;,&lt;br /&gt;
	ha = &#039;Hidden Ability&#039;,&lt;br /&gt;
	generation = &#039;Generation&#039;,&lt;br /&gt;
	hp = &#039;HP&#039;,&lt;br /&gt;
	atk = &#039;Attack&#039;,&lt;br /&gt;
	def = &#039;Defense&#039;,&lt;br /&gt;
	spatk = &#039;Special Attack&#039;,&lt;br /&gt;
	spdef = &#039;Special Defense&#039;,&lt;br /&gt;
	spd = &#039;Speed&#039;,&lt;br /&gt;
	catch = &#039;Catch Rate&#039;,&lt;br /&gt;
	evhp = &#039;EVHP&#039;,&lt;br /&gt;
	evatk = &#039;EVATK&#039;,&lt;br /&gt;
	evdef = &#039;EVDEF&#039;,&lt;br /&gt;
	evspa = &#039;EVSPA&#039;,&lt;br /&gt;
	evspd = &#039;EVSPD&#039;,&lt;br /&gt;
	evsp = &#039;EVSP&#039;,&lt;br /&gt;
	male = &#039;Male Ratio&#039;,&lt;br /&gt;
	height = &#039;Height&#039;,&lt;br /&gt;
	weight = &#039;Weight&#039;,&lt;br /&gt;
	npc = &#039;NPC&#039;,&lt;br /&gt;
	exp = &#039;Base Experience&#039;,&lt;br /&gt;
	rarity = &#039;Tier&#039;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local GEN_NUMERALS = { &#039;I&#039;, &#039;II&#039;, &#039;III&#039;, &#039;IV&#039;, &#039;V&#039;, &#039;VI&#039;, &#039;VII&#039;, &#039;VIII&#039;, &#039;IX&#039; }&lt;br /&gt;
&lt;br /&gt;
local STATS = {&lt;br /&gt;
	{ key = &#039;hp&#039;, label = &#039;HP&#039;, template = &#039;HP&#039; },&lt;br /&gt;
	{ key = &#039;atk&#039;, label = &#039;Atk&#039;, template = &#039;Attack&#039; },&lt;br /&gt;
	{ key = &#039;def&#039;, label = &#039;Def&#039;, template = &#039;Defense&#039; },&lt;br /&gt;
	{ key = &#039;spatk&#039;, label = &#039;Sp.Atk&#039;, template = &#039;Special Attack&#039; },&lt;br /&gt;
	{ key = &#039;spdef&#039;, label = &#039;Sp.Def&#039;, template = &#039;Special Defense&#039; },&lt;br /&gt;
	{ key = &#039;spd&#039;, label = &#039;Spd&#039;, template = &#039;Speed&#039; },&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local EV_KEYS = { &#039;evhp&#039;, &#039;evatk&#039;, &#039;evdef&#039;, &#039;evspa&#039;, &#039;evspd&#039;, &#039;evsp&#039; }&lt;br /&gt;
&lt;br /&gt;
local function nonEmpty(s)&lt;br /&gt;
	if s == nil then return nil end&lt;br /&gt;
	s = mw.text.trim(tostring(s))&lt;br /&gt;
	if s == &#039;&#039; then return nil end&lt;br /&gt;
	return s&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function templateArgs(frame)&lt;br /&gt;
	local parent = frame:getParent()&lt;br /&gt;
	return (parent and parent.args) or frame.args&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function padNumber(n)&lt;br /&gt;
	n = tonumber(n) or 0&lt;br /&gt;
	return string.format(&#039;%03d&#039;, n)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local PokemonForms = require(&#039;Module:PokemonForms&#039;)&lt;br /&gt;
local FORM_SUFFIXES = PokemonForms.FORM_SUFFIXES&lt;br /&gt;
local STRIP_SUFFIXES = PokemonForms.STRIP_SUFFIXES&lt;br /&gt;
local MEGA_VARIANTS = PokemonForms.MEGA_VARIANTS or { &#039;&#039;, &#039; X&#039;, &#039; Y&#039; }&lt;br /&gt;
&lt;br /&gt;
-- The single data fetch: the whole raw list is loaded once per page render&lt;br /&gt;
-- and every lookup (by name, by number, form probing) reads from it.&lt;br /&gt;
local allRowsCache = nil&lt;br /&gt;
local numberIndexCache = nil&lt;br /&gt;
&lt;br /&gt;
local function loadAllRows()&lt;br /&gt;
	if allRowsCache then&lt;br /&gt;
		return allRowsCache&lt;br /&gt;
	end&lt;br /&gt;
	local csvData = mw.ext.externalData.getExternalData{&lt;br /&gt;
		url = &#039;https://wiki.pokemonrevolution.net/index.php?title=Special:GetData/PokemonRawList&#039;,&lt;br /&gt;
		format = DATA_FORMAT,&lt;br /&gt;
		data = COLUMNS,&lt;br /&gt;
	}&lt;br /&gt;
	allRowsCache = {}&lt;br /&gt;
	numberIndexCache = {}&lt;br /&gt;
	if csvData then&lt;br /&gt;
		for _, row in ipairs(csvData) do&lt;br /&gt;
			if nonEmpty(row.name) then&lt;br /&gt;
				allRowsCache[row.name] = row&lt;br /&gt;
				local num = nonEmpty(row.number)&lt;br /&gt;
				-- First occurrence wins so base forms beat Megas sharing a number.&lt;br /&gt;
				if num and numberIndexCache[num] == nil then&lt;br /&gt;
					numberIndexCache[num] = row&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return allRowsCache&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function hyphenSpaceVariant(s)&lt;br /&gt;
	if mw.ustring.find(s, &#039;-&#039;, 1, true) then&lt;br /&gt;
		return (mw.ustring.gsub(s, &#039;%-&#039;, &#039; &#039;))&lt;br /&gt;
	end&lt;br /&gt;
	return (mw.ustring.gsub(s, &#039; &#039;, &#039;-&#039;))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function byName(name)&lt;br /&gt;
	local rows = loadAllRows()&lt;br /&gt;
	return rows[name] or rows[hyphenSpaceVariant(name)]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function byNumber(number)&lt;br /&gt;
	loadAllRows()&lt;br /&gt;
	return numberIndexCache[tostring(number)]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local MEGA_COLUMNS = {&lt;br /&gt;
	number = &#039;Pokedex Number&#039;,&lt;br /&gt;
	name = &#039;Name&#039;,&lt;br /&gt;
	type1 = &#039;Type1&#039;,&lt;br /&gt;
	type2 = &#039;Type2&#039;,&lt;br /&gt;
	ability1 = &#039;Ability 1&#039;,&lt;br /&gt;
	ability2 = &#039;Ability 2&#039;,&lt;br /&gt;
	ha = &#039;Hidden Ability&#039;,&lt;br /&gt;
	generation = &#039;Generation&#039;,&lt;br /&gt;
	hp = &#039;HP&#039;,&lt;br /&gt;
	atk = &#039;Attack&#039;,&lt;br /&gt;
	def = &#039;Defense&#039;,&lt;br /&gt;
	spatk = &#039;Special Attack&#039;,&lt;br /&gt;
	spdef = &#039;Special Defense&#039;,&lt;br /&gt;
	spd = &#039;Speed&#039;,&lt;br /&gt;
	evhp = &#039;EVHP&#039;,&lt;br /&gt;
	evatk = &#039;EVATK&#039;,&lt;br /&gt;
	evdef = &#039;EVDEF&#039;,&lt;br /&gt;
	evspa = &#039;EVSPA&#039;,&lt;br /&gt;
	evspd = &#039;EVSPD&#039;,&lt;br /&gt;
	evsp = &#039;EVSP&#039;,&lt;br /&gt;
	height = &#039;Height&#039;,&lt;br /&gt;
	weight = &#039;Weight&#039;,&lt;br /&gt;
	stone = &#039;Stone&#039;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local MEGA_SPEC&lt;br /&gt;
do&lt;br /&gt;
	local parts = {}&lt;br /&gt;
	for key, header in pairs(MEGA_COLUMNS) do&lt;br /&gt;
		parts[#parts + 1] = key .. &#039;=&#039; .. header&lt;br /&gt;
	end&lt;br /&gt;
	MEGA_SPEC = table.concat(parts, &#039;,&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local megaCache = {}&lt;br /&gt;
&lt;br /&gt;
local function megaByName(name)&lt;br /&gt;
	if megaCache[name] == nil then&lt;br /&gt;
		local ok, values = pcall(function()&lt;br /&gt;
			return mw.ext.externalData.getFileData{&lt;br /&gt;
				source = &#039;data&#039;,&lt;br /&gt;
				[&#039;file name&#039;] = &#039;RawMegaPokemonList.csv&#039;,&lt;br /&gt;
				format = DATA_FORMAT,&lt;br /&gt;
				filters = &#039;Name=&#039; .. name,&lt;br /&gt;
				data = MEGA_SPEC,&lt;br /&gt;
			}&lt;br /&gt;
		end)&lt;br /&gt;
		if ok and values and values.name ~= nil then&lt;br /&gt;
			megaCache[name] = values&lt;br /&gt;
		else&lt;br /&gt;
			megaCache[name] = false&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return megaCache[name] or nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- formStem/rawListFormName now live in Module:PokemonForms, shared with&lt;br /&gt;
-- Module:Learnsets, so both resolve a form&#039;s raw-list name identically.&lt;br /&gt;
local formStem = PokemonForms.formStem&lt;br /&gt;
local rawListFormName = PokemonForms.rawListFormName&lt;br /&gt;
&lt;br /&gt;
local function typeColors(frame, pokeType)&lt;br /&gt;
	return {&lt;br /&gt;
		light = frame:expandTemplate{ title = pokeType .. &#039; color light&#039; },&lt;br /&gt;
		base = frame:expandTemplate{ title = pokeType .. &#039; color&#039; },&lt;br /&gt;
		dark = frame:expandTemplate{ title = pokeType .. &#039; color dark&#039; },&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local statColorCache = {}&lt;br /&gt;
local function statColors(frame, statTemplate)&lt;br /&gt;
	if not statColorCache[statTemplate] then&lt;br /&gt;
		statColorCache[statTemplate] = {&lt;br /&gt;
			base = frame:expandTemplate{ title = statTemplate .. &#039; color&#039; },&lt;br /&gt;
			dark = frame:expandTemplate{ title = statTemplate .. &#039; color dark&#039; },&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
	return statColorCache[statTemplate]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function navTableHtml(frame, data, colors, pageName)&lt;br /&gt;
	local number = tonumber(data.number)&lt;br /&gt;
&lt;br /&gt;
	local prevCell = &#039;&#039;&lt;br /&gt;
	if number and number &amp;gt; 1 then&lt;br /&gt;
		local prev = byNumber(number - 1)&lt;br /&gt;
		if prev then&lt;br /&gt;
			prevCell = &#039;&amp;amp;nbsp;[[File:&#039; .. prev.number .. &#039;Icon.png|&#039; .. prev.name .. &#039;|link=&#039; .. prev.name ..&lt;br /&gt;
				&#039;]]&amp;amp;nbsp;&amp;amp;nbsp;#&#039; .. padNumber(prev.number) .. &#039;&amp;amp;nbsp;[[&#039; .. prev.name .. &#039;]]&#039;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local nextCell = &#039;&#039;&lt;br /&gt;
	if number then&lt;br /&gt;
		local nxt = byNumber(number + 1)&lt;br /&gt;
		if nxt then&lt;br /&gt;
			nextCell = &#039;[[&#039; .. nxt.name .. &#039;]]&amp;amp;nbsp;#&#039; .. padNumber(nxt.number) .. &#039;&amp;amp;nbsp;&amp;amp;nbsp;[[File:&#039; ..&lt;br /&gt;
				nxt.number .. &#039;Icon.png|&#039; .. nxt.name .. &#039;|link=&#039; .. nxt.name .. &#039;]]&#039;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return &#039;&amp;lt;table style=&amp;quot;margin-left: auto; margin-right: auto; margin-bottom: 15px; height: 60px; &#039; ..&lt;br /&gt;
		&#039;border: 4px #&#039; .. colors.dark .. &#039; solid; font-weight: bold; width: 65%; color: #&#039; .. colors.dark ..&lt;br /&gt;
		&#039;; border-radius: 20px; padding: 3px; background: #&#039; .. colors.base .. &#039;;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;text-align: left; width: 36%; background: #&#039; .. colors.light ..&lt;br /&gt;
		&#039;; border-radius: 15px 1px 1px 15px; border: 1px solid #&#039; .. colors.dark .. &#039;;&amp;quot;&amp;gt;&#039; .. prevCell .. &#039;&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;text-align: center; width: 28%; background: #&#039; .. colors.light ..&lt;br /&gt;
		&#039;; border: 1px solid #&#039; .. colors.dark .. &#039;;&amp;quot;&amp;gt;#&#039; .. padNumber(number) .. &#039;&amp;amp;nbsp;&amp;amp;nbsp;-&amp;amp;nbsp;&amp;amp;nbsp;&#039; ..&lt;br /&gt;
		pageName .. &#039;&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;text-align: right; width: 36%; padding-right: 10px; background: #&#039; .. colors.light ..&lt;br /&gt;
		&#039;; border: 1px solid #&#039; .. colors.dark .. &#039;; border-radius: 1px 15px 15px 1px;&amp;quot;&amp;gt;&#039; .. nextCell .. &#039;&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.navTable(frame)&lt;br /&gt;
	local args = templateArgs(frame)&lt;br /&gt;
	local pageName = mw.title.getCurrentTitle().text&lt;br /&gt;
	local name = nonEmpty(args.Name) or pageName&lt;br /&gt;
&lt;br /&gt;
	local data = byName(name)&lt;br /&gt;
	if not data then&lt;br /&gt;
		return &#039;&amp;lt;strong class=&amp;quot;error&amp;quot;&amp;gt;PokeNavTable: no data found for &amp;quot;&#039; .. name .. &#039;&amp;quot;&amp;lt;/strong&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return navTableHtml(frame, data, typeColors(frame, data.type1), pageName)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function infoCell(colors, labelHtml, valueHtml)&lt;br /&gt;
	return &#039;&amp;lt;td colspan=&amp;quot;3&amp;quot; style=&amp;quot;width: 50%; border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; .. colors.light ..&lt;br /&gt;
		&#039;; border-radius: 15px; padding: 5px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;p style=&amp;quot;margin-bottom: 7px; font-weight: bold; color: #&#039; .. colors.dark .. &#039;;&amp;quot;&amp;gt;&#039; .. labelHtml .. &#039;&amp;lt;/p&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;span style=&amp;quot;border-radius: 12px; padding: 4px 10px; border: 1px solid #&#039; .. colors.dark ..&lt;br /&gt;
		&#039;; background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&#039; .. valueHtml .. &#039;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/span&amp;gt;&amp;lt;/td&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function abilityCell(colors, label, ability, widthPercent)&lt;br /&gt;
	if not ability then return &#039;&#039; end&lt;br /&gt;
	local style = &#039;border-radius: 12px; padding: 4px 10px; border: 1px solid #&#039; .. colors.dark ..&lt;br /&gt;
		&#039;; background-color: #FFFFFF;&#039;&lt;br /&gt;
	if widthPercent then&lt;br /&gt;
		style = &#039;width: &#039; .. widthPercent .. &#039;%; &#039; .. style&lt;br /&gt;
	end&lt;br /&gt;
	return &#039;&amp;lt;td style=&amp;quot;&#039; .. style .. &#039;&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&#039; .. label .. &#039;&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;[[&#039; .. ability .. &#039;_(ability)|&#039; .. ability ..&lt;br /&gt;
		&#039;]]&amp;lt;/td&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function abilitiesRow(colors, data)&lt;br /&gt;
	local entries = {&lt;br /&gt;
		{ &#039;Ability 1&#039;, nonEmpty(data.ability1) },&lt;br /&gt;
		{ &#039;Ability 2&#039;, nonEmpty(data.ability2) },&lt;br /&gt;
		{ &#039;Hidden Ability&#039;, nonEmpty(data.ha) },&lt;br /&gt;
	}&lt;br /&gt;
	local present = {}&lt;br /&gt;
	for _, entry in ipairs(entries) do&lt;br /&gt;
		if entry[2] then present[#present + 1] = entry end&lt;br /&gt;
	end&lt;br /&gt;
	local widthPercent = (#present &amp;gt; 0) and string.format(&#039;%.2f&#039;, 100 / #present) or nil&lt;br /&gt;
	local cells = {}&lt;br /&gt;
	for _, entry in ipairs(present) do&lt;br /&gt;
		cells[#cells + 1] = abilityCell(colors, entry[1], entry[2], widthPercent)&lt;br /&gt;
	end&lt;br /&gt;
	return table.concat(cells)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function statValueCell(frame, stat, value)&lt;br /&gt;
	local colors = statColors(frame, stat.template)&lt;br /&gt;
	return &#039;&amp;lt;td style=&amp;quot;width: 16.66%; border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; .. colors.base ..&lt;br /&gt;
		&#039;; border-radius: 12px; padding: 4px; font-size: 11px;&amp;quot;&amp;gt;\&#039;\&#039;\&#039;&#039; .. stat.label .. &#039;\&#039;\&#039;\&#039;&amp;lt;br&amp;gt;&#039; ..&lt;br /&gt;
		value .. &#039;&amp;lt;/td&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function statBarRow(frame, stat, value)&lt;br /&gt;
	local labelColors = statColors(frame, stat.template)&lt;br /&gt;
	local pct = math.floor(value / 255 * 100 + 0.5)&lt;br /&gt;
	if pct &amp;lt; 2 then pct = 2 end&lt;br /&gt;
	if pct &amp;gt; 100 then pct = 100 end&lt;br /&gt;
	local hue = math.floor(math.max(0, math.min(180, value * 180 / 255)) + 0.5)&lt;br /&gt;
	local fill = &#039;hsl(&#039; .. hue .. &#039;, 85%, 45%)&#039;&lt;br /&gt;
	return &#039;&amp;lt;tr&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;text-align: right; padding: 2px 8px 2px 4px; font-weight: bold; font-size: 12px; &#039; ..&lt;br /&gt;
		&#039;color: #&#039; .. labelColors.dark .. &#039;; white-space: nowrap;&amp;quot;&amp;gt;&#039; .. stat.label .. &#039;&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;width: 100%; padding: 2px 0;&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;background-color: #FFFFFF; border: 1px solid &#039; ..&lt;br /&gt;
		&#039;#999999; border-radius: 8px; height: 13px; overflow: hidden;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;div style=&amp;quot;width: &#039; .. pct .. &#039;%; height: 100%; background-color: &#039; .. fill .. &#039;;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;text-align: left; padding: 2px 4px 2px 8px; font-weight: bold; font-size: 12px; &#039; ..&lt;br /&gt;
		&#039;width: 34px;&amp;quot;&amp;gt;&#039; .. value .. &#039;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local MALE_COLOR = &#039;3B6BF5&#039;&lt;br /&gt;
local FEMALE_COLOR = &#039;F5629C&#039;&lt;br /&gt;
&lt;br /&gt;
local function genderRatioHtml(male)&lt;br /&gt;
	if male == &#039;Genderless&#039; then&lt;br /&gt;
		return &#039;&amp;lt;span style=&amp;quot;display: inline-block; color: #000000; background-color: #FFFFFF; &#039; ..&lt;br /&gt;
			&#039;border-radius: 12px; border: 1px solid #000000; padding: 3px 12px; font-weight: bold;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
			&#039;Genderless&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	local m = tonumber(male)&lt;br /&gt;
	if m == nil then&lt;br /&gt;
		m = nonEmpty(male) and 100 or 0&lt;br /&gt;
	end&lt;br /&gt;
	if m &amp;lt; 0 then m = 0 end&lt;br /&gt;
	if m &amp;gt; 100 then m = 100 end&lt;br /&gt;
	local f = 100 - m&lt;br /&gt;
&lt;br /&gt;
	local segments = &#039;&#039;&lt;br /&gt;
	if m &amp;gt; 0 then&lt;br /&gt;
		segments = segments .. &#039;&amp;lt;div style=&amp;quot;width: &#039; .. m .. &#039;%; background-color: #&#039; .. MALE_COLOR .. &#039;;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	if f &amp;gt; 0 then&lt;br /&gt;
		segments = segments .. &#039;&amp;lt;div style=&amp;quot;width: &#039; .. f .. &#039;%; background-color: #&#039; .. FEMALE_COLOR .. &#039;;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local labels = {}&lt;br /&gt;
	if m &amp;gt; 0 then&lt;br /&gt;
		labels[#labels + 1] = &#039;&amp;lt;span style=&amp;quot;color: #&#039; .. MALE_COLOR .. &#039;; font-weight: bold;&amp;quot;&amp;gt;&#039; .. m .. &#039;% ♂&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	if f &amp;gt; 0 then&lt;br /&gt;
		labels[#labels + 1] = &#039;&amp;lt;span style=&amp;quot;color: #&#039; .. FEMALE_COLOR .. &#039;; font-weight: bold;&amp;quot;&amp;gt;&#039; .. f .. &#039;% ♀&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return &#039;&amp;lt;div style=&amp;quot;width: 85%; margin: 4px auto 0;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;div style=&amp;quot;display: flex; height: 12px; border-radius: 8px; overflow: hidden; &#039; ..&lt;br /&gt;
		&#039;border: 1px solid #555555; background-color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. segments .. &#039;&amp;lt;/div&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;div style=&amp;quot;margin-top: 4px; font-size: 12px;&amp;quot;&amp;gt;&#039; .. table.concat(labels, &#039; &amp;amp;nbsp;·&amp;amp;nbsp; &#039;) ..&lt;br /&gt;
		&#039;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function categories(data, gen, bstCategory, args)&lt;br /&gt;
	local cats = { &#039;[[Category:Pokémon species]]&#039; }&lt;br /&gt;
	if gen then&lt;br /&gt;
		cats[#cats + 1] = &#039;[[Category:Generation &#039; .. gen .. &#039; Pokémon]]&#039;&lt;br /&gt;
	end&lt;br /&gt;
	cats[#cats + 1] = &#039;[[Category:&#039; .. data.type1 .. &#039;-type Pokémon]]&#039;&lt;br /&gt;
	if nonEmpty(data.type2) then&lt;br /&gt;
		cats[#cats + 1] = &#039;[[Category:&#039; .. data.type2 .. &#039;-type Pokémon]]&#039;&lt;br /&gt;
	end&lt;br /&gt;
	cats[#cats + 1] = &#039;[[Category:&#039; .. data.rarity .. &#039; Pokémon]]&#039;&lt;br /&gt;
	if nonEmpty(data.npc) then&lt;br /&gt;
		cats[#cats + 1] = &#039;[[Category:NPC-obtainable Pokémon]]&#039;&lt;br /&gt;
	end&lt;br /&gt;
	if not nonEmpty(args.EvolvesFrom) then&lt;br /&gt;
		cats[#cats + 1] = &#039;[[Category:Base-stage Pokémon]]&#039;&lt;br /&gt;
	end&lt;br /&gt;
	cats[#cats + 1] = &#039;[[Category:&#039; .. bstCategory .. &#039;-plus-BST Pokémon]]&#039;&lt;br /&gt;
	return table.concat(cats, &#039; &#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function infoboxHtml(frame, args, data, displayName, width, pageName, includeNav)&lt;br /&gt;
	local colors = typeColors(frame, data.type1)&lt;br /&gt;
	-- Regional forms carry values like &#039;1A&#039;/&#039;5A&#039;; use the leading digits.&lt;br /&gt;
	local gen = GEN_NUMERALS[tonumber(mw.ustring.match(tostring(data.generation or &#039;&#039;), &#039;^%d+&#039;) or &#039;&#039;)]&lt;br /&gt;
&lt;br /&gt;
	-- Types pill(s).&lt;br /&gt;
	local typesHtml&lt;br /&gt;
	if nonEmpty(data.type2) then&lt;br /&gt;
		local type2Colors = typeColors(frame, data.type2)&lt;br /&gt;
		typesHtml =&lt;br /&gt;
			&#039;&amp;lt;td style=&amp;quot;width: 50%; background-color: #&#039; .. colors.dark .. &#039;; border-radius: 25px 1px 1px 25px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
			&#039;[[&#039; .. data.type1 .. &#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. data.type1 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
			&#039;&amp;lt;td style=&amp;quot;width: 50%; background-color: #&#039; .. type2Colors.dark .. &#039;; border-radius: 1px 25px 25px 1px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
			&#039;[[&#039; .. data.type2 .. &#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. data.type2 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&#039;&lt;br /&gt;
	else&lt;br /&gt;
		typesHtml =&lt;br /&gt;
			&#039;&amp;lt;td style=&amp;quot;width:100%; background-color: #&#039; .. colors.dark .. &#039;; border-radius: 25px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
			&#039;[[&#039; .. data.type1 .. &#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. data.type1 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Base stats&lt;br /&gt;
	local statRows, bst = {}, 0&lt;br /&gt;
	for _, stat in ipairs(STATS) do&lt;br /&gt;
		local value = tonumber(data[stat.key]) or 0&lt;br /&gt;
		bst = bst + value&lt;br /&gt;
		statRows[#statRows + 1] = statBarRow(frame, stat, value)&lt;br /&gt;
	end&lt;br /&gt;
	local bstCategory = math.floor(bst / 100 + 0.5) * 100&lt;br /&gt;
&lt;br /&gt;
	-- EV yield.&lt;br /&gt;
	local evCells, evTotal = {}, 0&lt;br /&gt;
	for i, stat in ipairs(STATS) do&lt;br /&gt;
		local ev = tonumber(data[EV_KEYS[i]]) or 0&lt;br /&gt;
		evTotal = evTotal + ev&lt;br /&gt;
		evCells[#evCells + 1] = statValueCell(frame, stat, ev)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Catch rate.&lt;br /&gt;
	local catchRaw = tonumber(data.catch) or 0&lt;br /&gt;
	local catchPercent = string.format(&#039;%.2f&#039;, catchRaw / 255 / 3 * 100)&lt;br /&gt;
&lt;br /&gt;
	local buf = {}&lt;br /&gt;
	if includeNav then&lt;br /&gt;
		buf[#buf + 1] = navTableHtml(frame, data, colors, pageName)&lt;br /&gt;
	end&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;table align=&amp;quot;right&amp;quot; class=&amp;quot;informational-box&amp;quot; cellpadding=&amp;quot;4&amp;quot; cellspacing=&amp;quot;4&amp;quot; &#039; ..&lt;br /&gt;
		&#039;style=&amp;quot;width: &#039; .. width .. &#039;%; border: 4px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.base .. &#039;; padding: 4px; border-radius: 15px;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Header: dex number + icon, name.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;3&amp;quot; style=&amp;quot;width: 50%; border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; border-radius: 15px;&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;margin-bottom: 7px; font-weight: bold; color:#&#039; ..&lt;br /&gt;
		colors.dark .. &#039;;&amp;quot;&amp;gt;#&#039; .. padNumber(data.number) .. &#039;&amp;lt;/span&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;[[File:&#039; .. data.number ..&lt;br /&gt;
		&#039;Icon.png]]&amp;lt;/td&amp;gt;&amp;lt;td colspan=&amp;quot;3&amp;quot; style=&amp;quot;width: 50%; border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; border-radius: 15px;&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;margin-bottom: 7px; font-weight: bold; color:#&#039; ..&lt;br /&gt;
		colors.dark .. &#039;;&amp;quot;&amp;gt;&#039; .. displayName .. &#039;&amp;lt;/span&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Artwork.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;6&amp;quot; style=&amp;quot;border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; border-radius: 15px; padding: 5px;&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;border-radius: 15px; &#039; ..&lt;br /&gt;
		&#039;text-align: center; padding: 5px; background-color: #FFFFFF;&amp;quot;&amp;gt;[[File:&#039; .. data.number .. data.name ..&lt;br /&gt;
		&#039;.png|150px]]&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Types + Generation.&lt;br /&gt;
	local genHtml = &#039;—&#039;&lt;br /&gt;
	if gen then&lt;br /&gt;
		genHtml = &#039;[[:Category:Generation &#039; .. gen .. &#039; Pokémon|&amp;lt;span style=&amp;quot;color:#&#039; ..&lt;br /&gt;
			colors.dark .. &#039;;&amp;quot;&amp;gt;&#039; .. gen .. &#039;&amp;lt;/span&amp;gt;]]&#039;&lt;br /&gt;
	end&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;3&amp;quot; style=&amp;quot;width: 50%; border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; padding: 11px; border-radius: 15px;&amp;quot;&amp;gt;&amp;lt;p style=&amp;quot;margin-bottom: 7px; font-weight: bold; &#039; ..&lt;br /&gt;
		&#039;color: #&#039; .. colors.dark .. &#039;;&amp;quot;&amp;gt;Types&amp;lt;/p&amp;gt;&amp;lt;table align=&amp;quot;center&amp;quot; style=&amp;quot;width: 75%; font-weight: bold; &#039; ..&lt;br /&gt;
		&#039;padding: 3px;&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&#039; .. typesHtml .. &#039;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td colspan=&amp;quot;3&amp;quot; style=&amp;quot;width: 50%; border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; .. colors.light ..&lt;br /&gt;
		&#039;; border-radius: 15px;&amp;quot;&amp;gt;&amp;lt;p style=&amp;quot;margin-bottom: 7px; font-weight: bold; color: #&#039; .. colors.dark ..&lt;br /&gt;
		&#039;;&amp;quot;&amp;gt;Generation&amp;lt;/p&amp;gt;&amp;lt;span style=&amp;quot;border-radius: 12px; padding: 4px 10px; border: 1px solid #&#039; .. colors.dark ..&lt;br /&gt;
		&#039;; background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&#039; .. genHtml .. &#039;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/span&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Abilities.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;6&amp;quot; style=&amp;quot;border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; padding: 11px; border-radius: 15px; width: 100%;&amp;quot;&amp;gt;&amp;lt;table width=&amp;quot;100%&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&amp;lt;th colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;p style=&amp;quot;margin-bottom: 7px; font-weight: bold; color:#&#039; .. colors.dark ..&lt;br /&gt;
		&#039;;&amp;quot;&amp;gt;[[Abilities|&amp;lt;span style=&amp;quot;color:#&#039; .. colors.dark .. &#039;;&amp;quot;&amp;gt;Abilities&amp;lt;/span&amp;gt;]]&amp;lt;/p&amp;gt;&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&#039; .. abilitiesRow(colors, data) .. &#039;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Rarity + Catch rate.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&#039; ..&lt;br /&gt;
		infoCell(colors, &#039;[[List of Pokémon by Rarity Tier|&amp;lt;span style=&amp;quot;color:#&#039; .. colors.dark ..&lt;br /&gt;
			&#039;;&amp;quot;&amp;gt;Rarity Tier&amp;lt;/span&amp;gt;]]&#039;, &#039;[[:Category:&#039; .. data.rarity .. &#039; Pokémon|&amp;lt;span style=&amp;quot;color:#&#039; ..&lt;br /&gt;
			colors.dark .. &#039;;&amp;quot;&amp;gt;&#039; .. data.rarity .. &#039;&amp;lt;/span&amp;gt;]]&#039;) ..&lt;br /&gt;
		infoCell(colors, &#039;[[Catch Rates|&amp;lt;span style=&amp;quot;color:#&#039; .. colors.dark .. &#039;;&amp;quot;&amp;gt;Catch rate&amp;lt;/span&amp;gt;]]&#039;,&lt;br /&gt;
			data.catch .. &#039;/255 (&#039; .. catchPercent .. &#039;%)&#039;) ..&lt;br /&gt;
		&#039;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Base stats.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;6&amp;quot; style=&amp;quot;border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; border-radius: 15px; padding: 8px; width: 100%&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;table width=&amp;quot;100%&amp;quot; style=&amp;quot;border-collapse: collapse;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&amp;lt;th colspan=&amp;quot;3&amp;quot;&amp;gt;&amp;lt;p style=&amp;quot;margin-bottom: 7px; font-weight: bold; color: #&#039; .. colors.dark ..&lt;br /&gt;
		&#039;;&amp;quot;&amp;gt;[[Base stats|&amp;lt;span style=&amp;quot;color: #&#039; .. colors.dark .. &#039;;&amp;quot;&amp;gt;Base stats&amp;lt;/span&amp;gt;]]&amp;lt;/p&amp;gt;&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&#039; ..&lt;br /&gt;
		table.concat(statRows) ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;3&amp;quot; style=&amp;quot;text-align: center; padding-top: 6px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;div style=&amp;quot;display: inline-block; background-color: #FFFFFF; border: 1px solid #&#039; .. colors.dark ..&lt;br /&gt;
		&#039;; padding: 4px 14px; border-radius: 12px;&amp;quot;&amp;gt;Base-stat total: &#039; .. bst .. &#039;&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;/table&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- EV yield.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;6&amp;quot; style=&amp;quot;border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; border-radius: 15px; padding: 5px; width: 100%&amp;quot;&amp;gt;&amp;lt;table width=&amp;quot;100%&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&amp;lt;th colspan=&amp;quot;6&amp;quot;&amp;gt;[[EVs|&amp;lt;span style=&amp;quot;margin-bottom: 7px; font-weight: bold; color: #&#039; .. colors.dark ..&lt;br /&gt;
		&#039;;&amp;quot;&amp;gt;EV Yield&amp;lt;/span&amp;gt;]]&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&#039; .. table.concat(evCells) .. &#039;&amp;lt;/tr&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;margin: auto; background-color:#FFFFFF; border: 1px solid #&#039; ..&lt;br /&gt;
		colors.dark .. &#039;; padding: 4px 14px; border-radius: 12px; margin-bottom: 5px; width: 50%;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;EV-yield total: &#039; .. evTotal .. &#039;&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Base experience + Gender ratio.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&#039; ..&lt;br /&gt;
		infoCell(colors, &#039;[[Experience System#Base Experience|&amp;lt;span style=&amp;quot;color:#&#039; .. colors.dark ..&lt;br /&gt;
			&#039;;&amp;quot;&amp;gt;Base Experience&amp;lt;/span&amp;gt;]]&#039;, data.exp) ..&lt;br /&gt;
		&#039;&amp;lt;td colspan=&amp;quot;3&amp;quot; style=&amp;quot;width: 50%; border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; .. colors.light ..&lt;br /&gt;
		&#039;; border-radius: 15px; padding: 5px;&amp;quot;&amp;gt;&amp;lt;p style=&amp;quot;margin-bottom: 7px; font-weight: bold; color: #&#039; ..&lt;br /&gt;
		colors.dark .. &#039;;&amp;quot;&amp;gt;Gender Ratio&amp;lt;/p&amp;gt;&#039; .. genderRatioHtml(data.male) .. &#039;&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Height + Weight.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&#039; ..&lt;br /&gt;
		infoCell(colors, &#039;Height&#039;, data.height .. &#039;m&#039;) ..&lt;br /&gt;
		infoCell(colors, &#039;Weight&#039;, data.weight .. &#039;kg&#039;) ..&lt;br /&gt;
		&#039;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;/table&amp;gt;&#039;&lt;br /&gt;
	buf[#buf + 1] = categories(data, gen, bstCategory, args)&lt;br /&gt;
&lt;br /&gt;
	return table.concat(buf)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function megaInfoboxHtml(frame, data, width)&lt;br /&gt;
	local colors = typeColors(frame, data.type1)&lt;br /&gt;
	local gen = GEN_NUMERALS[tonumber(mw.ustring.match(tostring(data.generation or &#039;&#039;), &#039;^%d+&#039;) or &#039;&#039;)]&lt;br /&gt;
	local displayName = &#039;Mega &#039; .. (data.name or &#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
	local typesHtml&lt;br /&gt;
	if nonEmpty(data.type2) then&lt;br /&gt;
		local type2Colors = typeColors(frame, data.type2)&lt;br /&gt;
		typesHtml =&lt;br /&gt;
			&#039;&amp;lt;td style=&amp;quot;width: 50%; background-color: #&#039; .. colors.dark .. &#039;; border-radius: 25px 1px 1px 25px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
			&#039;[[&#039; .. data.type1 .. &#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. data.type1 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
			&#039;&amp;lt;td style=&amp;quot;width: 50%; background-color: #&#039; .. type2Colors.dark .. &#039;; border-radius: 1px 25px 25px 1px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
			&#039;[[&#039; .. data.type2 .. &#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. data.type2 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&#039;&lt;br /&gt;
	else&lt;br /&gt;
		typesHtml =&lt;br /&gt;
			&#039;&amp;lt;td style=&amp;quot;width:100%; background-color: #&#039; .. colors.dark .. &#039;; border-radius: 25px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
			&#039;[[&#039; .. data.type1 .. &#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. data.type1 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local statRows, bst = {}, 0&lt;br /&gt;
	for _, stat in ipairs(STATS) do&lt;br /&gt;
		local value = tonumber(data[stat.key]) or 0&lt;br /&gt;
		bst = bst + value&lt;br /&gt;
		statRows[#statRows + 1] = statBarRow(frame, stat, value)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local evCells, evTotal = {}, 0&lt;br /&gt;
	for i, stat in ipairs(STATS) do&lt;br /&gt;
		local ev = tonumber(data[EV_KEYS[i]]) or 0&lt;br /&gt;
		evTotal = evTotal + ev&lt;br /&gt;
		evCells[#evCells + 1] = statValueCell(frame, stat, ev)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local buf = {}&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;table align=&amp;quot;right&amp;quot; class=&amp;quot;informational-box&amp;quot; cellpadding=&amp;quot;4&amp;quot; cellspacing=&amp;quot;4&amp;quot; &#039; ..&lt;br /&gt;
		&#039;style=&amp;quot;width: &#039; .. width .. &#039;%; border: 4px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.base .. &#039;; padding: 4px; border-radius: 15px;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Header: name across the whole top line.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;6&amp;quot; style=&amp;quot;border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; border-radius: 15px;&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;margin-bottom: 7px; font-weight: bold; color:#&#039; ..&lt;br /&gt;
		colors.dark .. &#039;;&amp;quot;&amp;gt;&#039; .. displayName .. &#039;&amp;lt;/span&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Artwork.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;6&amp;quot; style=&amp;quot;border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; border-radius: 15px; padding: 5px;&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;border-radius: 15px; &#039; ..&lt;br /&gt;
		&#039;text-align: center; padding: 5px; background-color: #FFFFFF;&amp;quot;&amp;gt;[[File:&#039; .. (data.number or &#039;&#039;) .. (data.name or &#039;&#039;) ..&lt;br /&gt;
		&#039;-Mega.png|150px]]&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Types + Generation.&lt;br /&gt;
	local genHtml = &#039;—&#039;&lt;br /&gt;
	if gen then&lt;br /&gt;
		genHtml = &#039;[[:Category:Generation &#039; .. gen .. &#039; Pokémon|&amp;lt;span style=&amp;quot;color:#&#039; ..&lt;br /&gt;
			colors.dark .. &#039;;&amp;quot;&amp;gt;&#039; .. gen .. &#039;&amp;lt;/span&amp;gt;]]&#039;&lt;br /&gt;
	end&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;3&amp;quot; style=&amp;quot;width: 50%; border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; padding: 11px; border-radius: 15px;&amp;quot;&amp;gt;&amp;lt;p style=&amp;quot;margin-bottom: 7px; font-weight: bold; &#039; ..&lt;br /&gt;
		&#039;color: #&#039; .. colors.dark .. &#039;;&amp;quot;&amp;gt;Types&amp;lt;/p&amp;gt;&amp;lt;table align=&amp;quot;center&amp;quot; style=&amp;quot;width: 75%; font-weight: bold; &#039; ..&lt;br /&gt;
		&#039;padding: 3px;&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&#039; .. typesHtml .. &#039;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td colspan=&amp;quot;3&amp;quot; style=&amp;quot;width: 50%; border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; .. colors.light ..&lt;br /&gt;
		&#039;; border-radius: 15px;&amp;quot;&amp;gt;&amp;lt;p style=&amp;quot;margin-bottom: 7px; font-weight: bold; color: #&#039; .. colors.dark ..&lt;br /&gt;
		&#039;;&amp;quot;&amp;gt;Generation&amp;lt;/p&amp;gt;&amp;lt;span style=&amp;quot;border-radius: 12px; padding: 4px 10px; border: 1px solid #&#039; .. colors.dark ..&lt;br /&gt;
		&#039;; background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&#039; .. genHtml .. &#039;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/span&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Abilities.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;6&amp;quot; style=&amp;quot;border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; padding: 11px; border-radius: 15px; width: 100%;&amp;quot;&amp;gt;&amp;lt;table width=&amp;quot;100%&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&amp;lt;th colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;p style=&amp;quot;margin-bottom: 7px; font-weight: bold; color:#&#039; .. colors.dark ..&lt;br /&gt;
		&#039;;&amp;quot;&amp;gt;[[Abilities|&amp;lt;span style=&amp;quot;color:#&#039; .. colors.dark .. &#039;;&amp;quot;&amp;gt;Abilities&amp;lt;/span&amp;gt;]]&amp;lt;/p&amp;gt;&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&#039; .. abilitiesRow(colors, data) .. &#039;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Mega Stone, linked to its quest page (&amp;quot;Venusaurite (quest)&amp;quot;).&lt;br /&gt;
	local stone = nonEmpty(data.stone)&lt;br /&gt;
	local stoneHtml = &#039;—&#039;&lt;br /&gt;
	if stone then&lt;br /&gt;
		stoneHtml = &#039;[[&#039; .. stone .. &#039; (quest)|&amp;lt;span style=&amp;quot;color:#&#039; .. colors.dark .. &#039;;&amp;quot;&amp;gt;&#039; .. stone .. &#039;&amp;lt;/span&amp;gt;]]&#039;&lt;br /&gt;
	end&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;6&amp;quot; style=&amp;quot;border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; border-radius: 15px; padding: 5px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;p style=&amp;quot;margin-bottom: 7px; font-weight: bold; color: #&#039; .. colors.dark .. &#039;;&amp;quot;&amp;gt;Mega Stone&amp;lt;/p&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;span style=&amp;quot;border-radius: 12px; padding: 4px 10px; border: 1px solid #&#039; .. colors.dark ..&lt;br /&gt;
		&#039;; background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&#039; .. stoneHtml .. &#039;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/span&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Base stats.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;6&amp;quot; style=&amp;quot;border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; border-radius: 15px; padding: 8px; width: 100%&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;table width=&amp;quot;100%&amp;quot; style=&amp;quot;border-collapse: collapse;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&amp;lt;th colspan=&amp;quot;3&amp;quot;&amp;gt;&amp;lt;p style=&amp;quot;margin-bottom: 7px; font-weight: bold; color: #&#039; .. colors.dark ..&lt;br /&gt;
		&#039;;&amp;quot;&amp;gt;[[Base stats|&amp;lt;span style=&amp;quot;color: #&#039; .. colors.dark .. &#039;;&amp;quot;&amp;gt;Base stats&amp;lt;/span&amp;gt;]]&amp;lt;/p&amp;gt;&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&#039; ..&lt;br /&gt;
		table.concat(statRows) ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;3&amp;quot; style=&amp;quot;text-align: center; padding-top: 6px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;div style=&amp;quot;display: inline-block; background-color: #FFFFFF; border: 1px solid #&#039; .. colors.dark ..&lt;br /&gt;
		&#039;; padding: 4px 14px; border-radius: 12px;&amp;quot;&amp;gt;Base-stat total: &#039; .. bst .. &#039;&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;/table&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- EV yield.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;6&amp;quot; style=&amp;quot;border: 1px solid #&#039; .. colors.dark .. &#039;; background-color: #&#039; ..&lt;br /&gt;
		colors.light .. &#039;; border-radius: 15px; padding: 5px; width: 100%&amp;quot;&amp;gt;&amp;lt;table width=&amp;quot;100%&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&amp;lt;th colspan=&amp;quot;6&amp;quot;&amp;gt;[[EVs|&amp;lt;span style=&amp;quot;margin-bottom: 7px; font-weight: bold; color: #&#039; .. colors.dark ..&lt;br /&gt;
		&#039;;&amp;quot;&amp;gt;EV Yield&amp;lt;/span&amp;gt;]]&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&#039; .. table.concat(evCells) .. &#039;&amp;lt;/tr&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;margin: auto; background-color:#FFFFFF; border: 1px solid #&#039; ..&lt;br /&gt;
		colors.dark .. &#039;; padding: 4px 14px; border-radius: 12px; margin-bottom: 5px; width: 50%;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;EV-yield total: &#039; .. evTotal .. &#039;&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Height + Weight.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;tr&amp;gt;&#039; ..&lt;br /&gt;
		infoCell(colors, &#039;Height&#039;, (data.height or &#039;—&#039;) .. &#039;m&#039;) ..&lt;br /&gt;
		infoCell(colors, &#039;Weight&#039;, (data.weight or &#039;—&#039;) .. &#039;kg&#039;) ..&lt;br /&gt;
		&#039;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;/table&amp;gt;&#039;&lt;br /&gt;
	buf[#buf + 1] = &#039;[[Category:Mega-Evolvable Pokémon]]&#039;&lt;br /&gt;
&lt;br /&gt;
	return table.concat(buf)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.infobox(frame)&lt;br /&gt;
	local args = templateArgs(frame)&lt;br /&gt;
	local pageName = mw.title.getCurrentTitle().text&lt;br /&gt;
	local name = nonEmpty(args.Name) or pageName&lt;br /&gt;
	local width = nonEmpty(args.Width) or &#039;45&#039;&lt;br /&gt;
&lt;br /&gt;
	local data = byName(name)&lt;br /&gt;
	if not data then&lt;br /&gt;
		return &#039;&amp;lt;strong class=&amp;quot;error&amp;quot;&amp;gt;PokemonInfo: no data found for &amp;quot;&#039; .. name .. &#039;&amp;quot;&amp;lt;/strong&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	frame:callParserFunction(&#039;#vardefine&#039;, &#039;type&#039;, data.type1 or &#039;Normal&#039;)&lt;br /&gt;
&lt;br /&gt;
	return infoboxHtml(frame, args, data, name, width, pageName, true)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.primaryType(frame)&lt;br /&gt;
	local args = templateArgs(frame)&lt;br /&gt;
	local name = nonEmpty(args.Name) or mw.title.getCurrentTitle().text&lt;br /&gt;
	local data = byName(name) or byName(formStem(name))&lt;br /&gt;
	return (data and nonEmpty(data.type1)) or &#039;Normal&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function requestedName(frame)&lt;br /&gt;
	local parent = frame:getParent()&lt;br /&gt;
	return nonEmpty(frame.args.Name)&lt;br /&gt;
		or (parent and nonEmpty(parent.args.Name))&lt;br /&gt;
		or mw.title.getCurrentTitle().text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local participantsCache = {}&lt;br /&gt;
&lt;br /&gt;
local function computeParticipants(frame, name)&lt;br /&gt;
	if participantsCache[name] ~= nil then&lt;br /&gt;
		return participantsCache[name] or nil&lt;br /&gt;
	end&lt;br /&gt;
	local rows = loadAllRows()&lt;br /&gt;
	local function rowFor(n)&lt;br /&gt;
		return rows[n] or rows[hyphenSpaceVariant(n)]&lt;br /&gt;
	end&lt;br /&gt;
	local stem = formStem(name)&lt;br /&gt;
	local baseData = rowFor(stem) or rowFor(name)&lt;br /&gt;
	if not baseData then&lt;br /&gt;
		participantsCache[name] = false&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
	local baseDexNumber = mw.ustring.match(tostring(baseData.number or &#039;&#039;), &#039;^%d+&#039;)&lt;br /&gt;
&lt;br /&gt;
	local parts = { { data = baseData, label = &#039;Normal&#039; } }&lt;br /&gt;
	local seen = { [baseData.name] = true }&lt;br /&gt;
	for _, form in ipairs(FORM_SUFFIXES) do&lt;br /&gt;
		local row = rowFor(rawListFormName(form, stem))&lt;br /&gt;
		-- A candidate must share the same base dex number to be a real form of&lt;br /&gt;
		-- this Pokémon. Without this check, stripping &amp;quot;Nidoran Male&amp;quot; down to&lt;br /&gt;
		-- the stem &amp;quot;Nidoran&amp;quot; (done because &amp;quot;Male&amp;quot; is a real form suffix for&lt;br /&gt;
		-- Indeedee/Meowstic-style species) lets &amp;quot;Nidoran&amp;quot; + &amp;quot; Female&amp;quot; happen to&lt;br /&gt;
		-- match the raw list&#039;s &amp;quot;Nidoran Female&amp;quot; row — a wholly different&lt;br /&gt;
		-- species (dex #29 vs Male&#039;s #32), not this one&#039;s gender form.&lt;br /&gt;
		local rowDexNumber = row and mw.ustring.match(tostring(row.number or &#039;&#039;), &#039;^%d+&#039;)&lt;br /&gt;
		if row and not seen[row.name] and rowDexNumber == baseDexNumber then&lt;br /&gt;
			seen[row.name] = true&lt;br /&gt;
			parts[#parts + 1] = { data = row, label = form.label }&lt;br /&gt;
			if form.baseLabel then&lt;br /&gt;
				parts[1].label = form.baseLabel&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	for _, variant in ipairs(MEGA_VARIANTS) do&lt;br /&gt;
		local row = megaByName(stem .. variant)&lt;br /&gt;
		if row then&lt;br /&gt;
			parts[#parts + 1] = { data = row, label = &#039;Mega&#039; .. variant, mega = true }&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	participantsCache[name] = parts&lt;br /&gt;
	return parts&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.formLabel(frame)&lt;br /&gt;
	local idx = tonumber(frame.args[1]) or 0&lt;br /&gt;
	local parts = computeParticipants(frame, requestedName(frame))&lt;br /&gt;
	if not parts then&lt;br /&gt;
		return &#039;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	local part = parts[idx + 1]&lt;br /&gt;
	return part and part.label or &#039;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.rawName(frame)&lt;br /&gt;
	local name = requestedName(frame)&lt;br /&gt;
	local parts = computeParticipants(frame, name)&lt;br /&gt;
	return (parts and parts[1].data.name) or name&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.formBox(frame)&lt;br /&gt;
	local idx = tonumber(frame.args[1]) or 0&lt;br /&gt;
	local width = nonEmpty(frame.args.Width) or &#039;100&#039;&lt;br /&gt;
	local name = requestedName(frame)&lt;br /&gt;
	local parts = computeParticipants(frame, name)&lt;br /&gt;
	if not parts then&lt;br /&gt;
		return &#039;&amp;lt;strong class=&amp;quot;error&amp;quot;&amp;gt;PokemonInfo: no data found for &amp;quot;&#039; .. name .. &#039;&amp;quot;&amp;lt;/strong&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	local part = parts[idx + 1]&lt;br /&gt;
	if not part then&lt;br /&gt;
		return &#039;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	if part.mega then&lt;br /&gt;
		return megaInfoboxHtml(frame, part.data, width)&lt;br /&gt;
	end&lt;br /&gt;
	local parent = frame:getParent()&lt;br /&gt;
	local args = (parent and parent.args) or frame.args&lt;br /&gt;
	return infoboxHtml(frame, args, part.data, part.data.name, width, mw.title.getCurrentTitle().text, false)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Module:Learnsets&amp;diff=41073</id>
		<title>Module:Learnsets</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Module:Learnsets&amp;diff=41073"/>
		<updated>2026-08-09T12:36:08Z</updated>

		<summary type="html">&lt;p&gt;Cae: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {}&lt;br /&gt;
&lt;br /&gt;
local function getArgs(frame)&lt;br /&gt;
    local args = {}&lt;br /&gt;
    local parent = frame:getParent()&lt;br /&gt;
    &lt;br /&gt;
    if parent then&lt;br /&gt;
        for k, v in pairs(parent.args) do&lt;br /&gt;
            if v ~= &#039;&#039; then&lt;br /&gt;
                args[k] = v&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    for k, v in pairs(frame.args) do&lt;br /&gt;
        if v ~= &#039;&#039; then&lt;br /&gt;
            args[k] = v&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    return args&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local moveDataCache = nil&lt;br /&gt;
&lt;br /&gt;
local function blankToNil(v)&lt;br /&gt;
    if v == nil or v == &#039;&#039; then&lt;br /&gt;
        return nil&lt;br /&gt;
    end&lt;br /&gt;
    return v&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function loadMoveData()&lt;br /&gt;
    if moveDataCache then&lt;br /&gt;
        return moveDataCache&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    local csvData = mw.ext.externalData.getExternalData({&lt;br /&gt;
        url = &#039;https://wiki.pokemonrevolution.net/index.php?title=Special:GetData/RawMovesList&#039;,&lt;br /&gt;
        format = &#039;CSV with header&#039;,&lt;br /&gt;
        data = {&lt;br /&gt;
            Name = &#039;Name&#039;,&lt;br /&gt;
            Type = &#039;Type&#039;,&lt;br /&gt;
            Category = &#039;Category&#039;,&lt;br /&gt;
            Power = &#039;Power&#039;,&lt;br /&gt;
            Accuracy = &#039;Accuracy&#039;,&lt;br /&gt;
            PP = &#039;PP&#039;,&lt;br /&gt;
            Broken = &#039;Broken&#039;,&lt;br /&gt;
            Typeless = &#039;Typeless&#039;,&lt;br /&gt;
            Priority = &#039;Priority&#039;,&lt;br /&gt;
            TM = &#039;TM&#039;,&lt;br /&gt;
            [&#039;Move Tutor&#039;] = &#039;Move Tutor&#039;,&lt;br /&gt;
            Egg = &#039;Egg&#039;,&lt;br /&gt;
        },&lt;br /&gt;
    })&lt;br /&gt;
&lt;br /&gt;
    moveDataCache = {}&lt;br /&gt;
    if csvData then&lt;br /&gt;
        for _, row in ipairs(csvData) do&lt;br /&gt;
            moveDataCache[row.Name] = {&lt;br /&gt;
                type = blankToNil(row.Type) or &#039;Normal&#039;,&lt;br /&gt;
                category = blankToNil(row.Category) or &#039;Status&#039;,&lt;br /&gt;
                power = blankToNil(row.Power),&lt;br /&gt;
                accuracy = blankToNil(row.Accuracy),&lt;br /&gt;
                pp = blankToNil(row.PP),&lt;br /&gt;
                broken = row.Broken or &#039;N&#039;,&lt;br /&gt;
                typeless = row.Typeless or &#039;N&#039;,&lt;br /&gt;
                priority = blankToNil(row.Priority) or &#039;0&#039;,&lt;br /&gt;
                tm = blankToNil(row.TM),&lt;br /&gt;
                move_tutor = blankToNil(row[&#039;Move Tutor&#039;]),&lt;br /&gt;
                egg = blankToNil(row.Egg)&lt;br /&gt;
            }&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return moveDataCache&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function loadLearnset(pokemonName)&lt;br /&gt;
    local jsonPath = &#039;$[&#039; .. mw.text.jsonEncode(pokemonName) .. &#039;]&#039;&lt;br /&gt;
    local ok, result, errors = pcall(function()&lt;br /&gt;
        return mw.ext.externalData.getFileData({&lt;br /&gt;
            source = &#039;data&#039;,&lt;br /&gt;
            [&#039;file name&#039;] = &#039;Learnsets.json&#039;,&lt;br /&gt;
            format = &#039;JSON&#039;,&lt;br /&gt;
            [&#039;use jsonpath&#039;] = true,&lt;br /&gt;
            data = { poke = jsonPath },&lt;br /&gt;
        })&lt;br /&gt;
    end)&lt;br /&gt;
    if not ok then&lt;br /&gt;
        return nil, &#039;Lua error: &#039; .. tostring(result)&lt;br /&gt;
    end&lt;br /&gt;
    if errors and #errors &amp;gt; 0 then&lt;br /&gt;
        return nil, &#039;ExternalData error: &#039; .. table.concat(errors, &#039; | &#039;)&lt;br /&gt;
    end&lt;br /&gt;
    local raw = result and result.poke&lt;br /&gt;
    if type(raw) ~= &#039;table&#039; then&lt;br /&gt;
        return nil, &#039;No learnset data found for &#039; .. pokemonName&lt;br /&gt;
    end&lt;br /&gt;
    return raw, nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function sentenceCase(s)&lt;br /&gt;
    local first = mw.ustring.sub(s, 1, 1)&lt;br /&gt;
    local rest = mw.ustring.sub(s, 2)&lt;br /&gt;
    return mw.ustring.upper(first) .. mw.ustring.lower(rest)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local PokemonForms = require(&#039;Module:PokemonForms&#039;)&lt;br /&gt;
local FORM_SUFFIXES = PokemonForms.FORM_SUFFIXES&lt;br /&gt;
local STRIP_SUFFIXES = PokemonForms.STRIP_SUFFIXES&lt;br /&gt;
&lt;br /&gt;
local function stripKnownFormSuffix(name)&lt;br /&gt;
    for _, suffix in ipairs(STRIP_SUFFIXES) do&lt;br /&gt;
        for _, sep in ipairs({ &#039;-&#039;, &#039; &#039; }) do&lt;br /&gt;
            local tail = sep .. suffix&lt;br /&gt;
            if mw.ustring.sub(name, -mw.ustring.len(tail)) == tail then&lt;br /&gt;
                return mw.ustring.sub(name, 1, -mw.ustring.len(tail) - 1)&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local learnsetCache = {}&lt;br /&gt;
local learnsetErrorCache = {}&lt;br /&gt;
&lt;br /&gt;
local function primeLearnsetCache(names)&lt;br /&gt;
    local uniqueNames, seen = {}, {}&lt;br /&gt;
    for _, name in ipairs(names) do&lt;br /&gt;
        if not seen[name] and learnsetCache[name] == nil and learnsetErrorCache[name] == nil then&lt;br /&gt;
            seen[name] = true&lt;br /&gt;
            table.insert(uniqueNames, name)&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    if #uniqueNames == 0 then&lt;br /&gt;
        return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local dataSpec = {}&lt;br /&gt;
    local keyToName = {}&lt;br /&gt;
    for i, name in ipairs(uniqueNames) do&lt;br /&gt;
        local key = &#039;k&#039; .. i&lt;br /&gt;
        dataSpec[key] = &#039;$[&#039; .. mw.text.jsonEncode(name) .. &#039;]&#039;&lt;br /&gt;
        keyToName[key] = name&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local ok, result, errors = pcall(function()&lt;br /&gt;
        return mw.ext.externalData.getFileData({&lt;br /&gt;
            source = &#039;data&#039;,&lt;br /&gt;
            [&#039;file name&#039;] = &#039;Learnsets.json&#039;,&lt;br /&gt;
            format = &#039;JSON&#039;,&lt;br /&gt;
            [&#039;use jsonpath&#039;] = true,&lt;br /&gt;
            data = dataSpec,&lt;br /&gt;
        })&lt;br /&gt;
    end)&lt;br /&gt;
&lt;br /&gt;
    if not ok then&lt;br /&gt;
        local msg = &#039;Lua error: &#039; .. tostring(result)&lt;br /&gt;
        for _, name in ipairs(uniqueNames) do&lt;br /&gt;
            learnsetErrorCache[name] = msg&lt;br /&gt;
        end&lt;br /&gt;
        return&lt;br /&gt;
    end&lt;br /&gt;
    if errors and #errors &amp;gt; 0 then&lt;br /&gt;
        local msg = &#039;ExternalData error: &#039; .. table.concat(errors, &#039; | &#039;)&lt;br /&gt;
        for _, name in ipairs(uniqueNames) do&lt;br /&gt;
            learnsetErrorCache[name] = msg&lt;br /&gt;
        end&lt;br /&gt;
        return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    for key, name in pairs(keyToName) do&lt;br /&gt;
        local val = result and result[key]&lt;br /&gt;
        if type(val) == &#039;table&#039; then&lt;br /&gt;
            learnsetCache[name] = val&lt;br /&gt;
        else&lt;br /&gt;
            learnsetErrorCache[name] = &#039;No learnset data found for &#039; .. name&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function getCachedLearnset(pokemonName)&lt;br /&gt;
    if learnsetCache[pokemonName] == nil and learnsetErrorCache[pokemonName] == nil then&lt;br /&gt;
        local poke, err = loadLearnset(pokemonName)&lt;br /&gt;
&lt;br /&gt;
        if not poke then&lt;br /&gt;
            local altName = sentenceCase(pokemonName)&lt;br /&gt;
            if altName ~= pokemonName then&lt;br /&gt;
                local altPoke = loadLearnset(altName)&lt;br /&gt;
                if altPoke then&lt;br /&gt;
                    poke, err = altPoke, nil&lt;br /&gt;
                end&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
        learnsetCache[pokemonName], learnsetErrorCache[pokemonName] = poke, err&lt;br /&gt;
    end&lt;br /&gt;
    return learnsetCache[pokemonName], learnsetErrorCache[pokemonName]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function resolvePagePokemon(pokemonName)&lt;br /&gt;
    local poke, err = getCachedLearnset(pokemonName)&lt;br /&gt;
    if poke then&lt;br /&gt;
        return poke, nil, pokemonName&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    -- Direct page/raw-list name -&amp;gt; Learnsets-key alias, for names that aren&#039;t&lt;br /&gt;
    -- a shared-base form suffix at all (e.g. &amp;quot;Nidoran Male&amp;quot;/&amp;quot;Nidoran Female&amp;quot;&lt;br /&gt;
    -- are two separate species lines, stored as &amp;quot;Nidoran M&amp;quot;/&amp;quot;Nidoran F&amp;quot;).&lt;br /&gt;
    local aliasName = PokemonForms.LEARNSET_ALIASES and PokemonForms.LEARNSET_ALIASES[pokemonName]&lt;br /&gt;
    if aliasName then&lt;br /&gt;
        local aliasPoke = getCachedLearnset(aliasName)&lt;br /&gt;
        if aliasPoke then&lt;br /&gt;
            return aliasPoke, nil, aliasName&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local baseName = stripKnownFormSuffix(pokemonName)&lt;br /&gt;
    if baseName then&lt;br /&gt;
        local basePoke, baseErr = getCachedLearnset(baseName)&lt;br /&gt;
        if basePoke then&lt;br /&gt;
            return basePoke, nil, baseName&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return nil, err, pokemonName&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local pokemonTypeCache = nil&lt;br /&gt;
&lt;br /&gt;
local function loadPokemonTypes()&lt;br /&gt;
    if pokemonTypeCache then return pokemonTypeCache end&lt;br /&gt;
&lt;br /&gt;
    local csvData = mw.ext.externalData.getExternalData({&lt;br /&gt;
        url    = &#039;https://wiki.pokemonrevolution.net/index.php?title=Special:GetData/PokemonRawList&#039;,&lt;br /&gt;
        format = &#039;CSV with header&#039;,&lt;br /&gt;
        data = {&lt;br /&gt;
            Name = &#039;Name&#039;,&lt;br /&gt;
            Type1 = &#039;Type1&#039;,&lt;br /&gt;
            Type2 = &#039;Type2&#039;,&lt;br /&gt;
        },&lt;br /&gt;
    })&lt;br /&gt;
&lt;br /&gt;
    pokemonTypeCache = {}&lt;br /&gt;
    if csvData then&lt;br /&gt;
        for _, row in ipairs(csvData) do&lt;br /&gt;
            pokemonTypeCache[row.Name] = {&lt;br /&gt;
                type1 = row.Type1 or &#039;&#039;,&lt;br /&gt;
                type2 = row.Type2 or &#039;&#039;,&lt;br /&gt;
            }&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    return pokemonTypeCache&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local typeColorCache = {}&lt;br /&gt;
local function typeColor(frame, pokeType)&lt;br /&gt;
    pokeType = (pokeType and pokeType ~= &#039;&#039;) and pokeType or &#039;Normal&#039;&lt;br /&gt;
    if not typeColorCache[pokeType] then&lt;br /&gt;
        typeColorCache[pokeType] = {&lt;br /&gt;
            light = frame:expandTemplate{ title = pokeType .. &#039; color light&#039; },&lt;br /&gt;
            base = frame:expandTemplate{ title = pokeType .. &#039; color&#039; },&lt;br /&gt;
            dark = frame:expandTemplate{ title = pokeType .. &#039; color dark&#039; },&lt;br /&gt;
        }&lt;br /&gt;
    end&lt;br /&gt;
    return typeColorCache[pokeType]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local categoryColorCache = {}&lt;br /&gt;
local function categoryColor(frame, category)&lt;br /&gt;
    category = (category and category ~= &#039;&#039;) and category or &#039;Status&#039;&lt;br /&gt;
    if not categoryColorCache[category] then&lt;br /&gt;
        categoryColorCache[category] = {&lt;br /&gt;
            base = frame:expandTemplate{ title = category .. &#039; color&#039; },&lt;br /&gt;
            dark = frame:expandTemplate{ title = category .. &#039; color dark&#039; },&lt;br /&gt;
        }&lt;br /&gt;
    end&lt;br /&gt;
    return categoryColorCache[category]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function isSTAB(moveType, primaryType, secondaryType)&lt;br /&gt;
    return moveType == primaryType or moveType == secondaryType&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function formatItemNumber(label, num)&lt;br /&gt;
    num = tonumber(num)&lt;br /&gt;
    if not num then&lt;br /&gt;
        return &#039;—&#039;&lt;br /&gt;
    end&lt;br /&gt;
    return label .. string.format(&#039;%02d&#039;, num)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.renderLevelUp(frame)&lt;br /&gt;
    local args = getArgs(frame)&lt;br /&gt;
    local pokemonName = args[1] or args.pokemon&lt;br /&gt;
    local primaryType = args.type1 or &amp;quot;&amp;quot;&lt;br /&gt;
    local secondaryType = args.type2 or &amp;quot;&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
    local pokemon, lsErr = getCachedLearnset(pokemonName)&lt;br /&gt;
    local moveData = loadMoveData()&lt;br /&gt;
&lt;br /&gt;
    if not pokemon then&lt;br /&gt;
        return &amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;Data load error: &amp;quot; .. (lsErr or &#039;unknown&#039;) .. &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local moves = pokemon.level_up or {}&lt;br /&gt;
    local colors = typeColor(frame, primaryType)&lt;br /&gt;
&lt;br /&gt;
    local html = mw.html.create(&#039;div&#039;)&lt;br /&gt;
        :css(&#039;width&#039;, &#039;77%&#039;)&lt;br /&gt;
        :css(&#039;margin&#039;, &#039;auto&#039;)&lt;br /&gt;
    local table = html:tag(&#039;table&#039;)&lt;br /&gt;
        :addClass(&#039;sortable&#039;)&lt;br /&gt;
        :css(&#039;width&#039;, &#039;100%&#039;)&lt;br /&gt;
        :css(&#039;text-align&#039;, &#039;center&#039;)&lt;br /&gt;
        :css(&#039;border-radius&#039;, &#039;15px 15px 0 0&#039;)&lt;br /&gt;
        :css(&#039;border&#039;, &#039;3px solid #&#039; .. colors.dark)&lt;br /&gt;
        :css(&#039;border-bottom&#039;, &#039;none&#039;)&lt;br /&gt;
        :css(&#039;background-color&#039;, &#039;#&#039; .. colors.base)&lt;br /&gt;
        :css(&#039;padding&#039;, &#039;7px&#039;)&lt;br /&gt;
&lt;br /&gt;
        local header = table:tag(&#039;tr&#039;)&lt;br /&gt;
        :css(&#039;background-color&#039;, &#039;#&#039; .. colors.light)&lt;br /&gt;
        :css(&#039;color&#039;, &#039;#&#039; .. colors.dark)&lt;br /&gt;
    header:tag(&#039;th&#039;):wikitext(&#039;Level&#039;):css(&#039;width&#039;, &#039;10%&#039;):css(&#039;border-radius&#039;, &#039;15px 1px 1px 1px&#039;)&lt;br /&gt;
    header:tag(&#039;th&#039;):wikitext(&#039;Move&#039;):css(&#039;width&#039;, &#039;15%&#039;)&lt;br /&gt;
    header:tag(&#039;th&#039;):wikitext(&#039;Type&#039;):css(&#039;width&#039;, &#039;17%&#039;)&lt;br /&gt;
    header:tag(&#039;th&#039;):wikitext(&#039;Category&#039;):css(&#039;width&#039;, &#039;16%&#039;)&lt;br /&gt;
    header:tag(&#039;th&#039;):wikitext(&#039;Base Power&#039;):css(&#039;width&#039;, &#039;17%&#039;)&lt;br /&gt;
    header:tag(&#039;th&#039;):wikitext(&#039;Accuracy&#039;):css(&#039;width&#039;, &#039;15%&#039;)&lt;br /&gt;
    header:tag(&#039;th&#039;):wikitext(&#039;PP&#039;):css(&#039;width&#039;, &#039;10%&#039;):css(&#039;border-radius&#039;, &#039;1px 15px 1px 1px&#039;)&lt;br /&gt;
&lt;br /&gt;
        for _, move in ipairs(moves) do&lt;br /&gt;
        local moveName = move.move&lt;br /&gt;
        local level = move.level&lt;br /&gt;
        local moveInfo = moveData[moveName] or {}&lt;br /&gt;
&lt;br /&gt;
        local row = table:tag(&#039;tr&#039;):css(&#039;background-color&#039;, &#039;#FFFFFF&#039;)&lt;br /&gt;
        row:tag(&#039;td&#039;):wikitext(tostring(level))&lt;br /&gt;
&lt;br /&gt;
        local moveLink = &#039;[[&#039; .. moveName .. &#039;]]&#039;&lt;br /&gt;
        if isSTAB(moveInfo.type, primaryType, secondaryType) and moveInfo.category ~= &amp;quot;Status&amp;quot; then&lt;br /&gt;
            moveLink = &amp;quot;&#039;&#039;&#039;&amp;quot; .. moveLink .. &amp;quot;&#039;&#039;&#039;&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        if moveInfo.broken == &amp;quot;Y&amp;quot; then&lt;br /&gt;
            moveLink = &amp;quot;&#039;&#039;&amp;quot; .. moveLink .. &amp;quot;&#039;&#039;&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        row:tag(&#039;td&#039;):wikitext(moveLink)&lt;br /&gt;
&lt;br /&gt;
        local moveTypeColors = typeColor(frame, moveInfo.type)&lt;br /&gt;
        row:tag(&#039;td&#039;)&lt;br /&gt;
            :css(&#039;background-color&#039;, &#039;#&#039; .. moveTypeColors.base)&lt;br /&gt;
            :css(&#039;border&#039;, &#039;2px solid #&#039; .. moveTypeColors.dark)&lt;br /&gt;
            :wikitext(&#039;[[&#039; .. (moveInfo.type or &#039;Normal&#039;) .. &#039;_(type)|&amp;lt;span style=&amp;quot;color:#FFFFFF;&amp;quot;&amp;gt;&#039; .. (moveInfo.type or &#039;Normal&#039;) .. &#039;&amp;lt;/span&amp;gt;]]&#039;)&lt;br /&gt;
&lt;br /&gt;
        local moveCatColors = categoryColor(frame, moveInfo.category)&lt;br /&gt;
        row:tag(&#039;td&#039;)&lt;br /&gt;
            :css(&#039;background-color&#039;, &#039;#&#039; .. moveCatColors.base)&lt;br /&gt;
            :css(&#039;border&#039;, &#039;2px solid #&#039; .. moveCatColors.dark)&lt;br /&gt;
            :wikitext(&#039;[[&#039; .. (moveInfo.category or &#039;Status&#039;) .. &#039; moves|&amp;lt;span style=&amp;quot;color:#FFFFFF;&amp;quot;&amp;gt;&#039; .. (moveInfo.category or &#039;Status&#039;) .. &#039;&amp;lt;/span&amp;gt;]]&#039;)&lt;br /&gt;
&lt;br /&gt;
        row:tag(&#039;td&#039;):wikitext(moveInfo.power or &#039;—&#039;)&lt;br /&gt;
        row:tag(&#039;td&#039;):wikitext(moveInfo.accuracy or &#039;—&#039;)&lt;br /&gt;
        row:tag(&#039;td&#039;):wikitext(moveInfo.pp or &#039;—&#039;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    html:tag(&#039;div&#039;)&lt;br /&gt;
        :css(&#039;text-align&#039;, &#039;left&#039;)&lt;br /&gt;
        :css(&#039;background-color&#039;, &#039;#&#039; .. colors.light)&lt;br /&gt;
        :css(&#039;padding&#039;, &#039;10px&#039;)&lt;br /&gt;
        :css(&#039;border&#039;, &#039;3px solid #&#039; .. colors.dark)&lt;br /&gt;
        :css(&#039;border-top&#039;, &#039;none&#039;)&lt;br /&gt;
        :css(&#039;border-radius&#039;, &#039;0 0 15px 15px&#039;)&lt;br /&gt;
        :wikitext([=[&lt;br /&gt;
* &#039;&#039;&#039;Emboldened&#039;&#039;&#039; moves denote this Pokémon avails from a STAB bonus for it.&lt;br /&gt;
* &#039;&#039;Italicized&#039;&#039; moves are [[Broken_Moves_%26_Abilities|broken]]; see their individual pages for more information.&lt;br /&gt;
* All moves subsumed on this list are relearnable via the [[Move Relearner]]s if lost.&lt;br /&gt;
]=])&lt;br /&gt;
    &lt;br /&gt;
    return tostring(html) .. &#039;&amp;lt;br clear=&amp;quot;all&amp;quot;&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.renderTMsHMs(frame)&lt;br /&gt;
    local args = getArgs(frame)&lt;br /&gt;
    local pokemonName = args[1] or args.pokemon&lt;br /&gt;
    local primaryType = args.type1 or &amp;quot;&amp;quot;&lt;br /&gt;
    local secondaryType = args.type2 or &amp;quot;&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
    local pokemon = getCachedLearnset(pokemonName)&lt;br /&gt;
    local moveData = loadMoveData()&lt;br /&gt;
&lt;br /&gt;
    if not pokemon then return &#039;&#039; end&lt;br /&gt;
&lt;br /&gt;
    local tms = pokemon.tms or {}&lt;br /&gt;
    local hms = pokemon.hms or {}&lt;br /&gt;
    local colors = typeColor(frame, primaryType)&lt;br /&gt;
&lt;br /&gt;
    local html = mw.html.create(&#039;div&#039;)&lt;br /&gt;
        :css(&#039;width&#039;, &#039;77%&#039;)&lt;br /&gt;
        :css(&#039;margin&#039;, &#039;auto&#039;)&lt;br /&gt;
    local table = html:tag(&#039;table&#039;)&lt;br /&gt;
        :addClass(&#039;sortable&#039;)&lt;br /&gt;
        :css(&#039;width&#039;, &#039;100%&#039;)&lt;br /&gt;
        :css(&#039;text-align&#039;, &#039;center&#039;)&lt;br /&gt;
        :css(&#039;border-radius&#039;, &#039;25px 25px 0 0&#039;)&lt;br /&gt;
        :css(&#039;border&#039;, &#039;3px solid #&#039; .. colors.dark)&lt;br /&gt;
        :css(&#039;border-bottom&#039;, &#039;none&#039;)&lt;br /&gt;
        :css(&#039;background-color&#039;, &#039;#&#039; .. colors.base)&lt;br /&gt;
        :css(&#039;padding&#039;, &#039;7px&#039;)&lt;br /&gt;
&lt;br /&gt;
    local header = table:tag(&#039;tr&#039;)&lt;br /&gt;
        :css(&#039;background-color&#039;, &#039;#&#039; .. colors.light)&lt;br /&gt;
        :css(&#039;color&#039;, &#039;#&#039; .. colors.dark)&lt;br /&gt;
    header:tag(&#039;th&#039;):attr(&#039;colspan&#039;, &#039;2&#039;):wikitext(&#039;TM&#039;):css(&#039;width&#039;, &#039;10%&#039;):css(&#039;border-top-left-radius&#039;, &#039;25px&#039;)&lt;br /&gt;
    header:tag(&#039;th&#039;):wikitext(&#039;Move&#039;):css(&#039;width&#039;, &#039;15%&#039;)&lt;br /&gt;
    header:tag(&#039;th&#039;):wikitext(&#039;Type&#039;):css(&#039;width&#039;, &#039;17%&#039;)&lt;br /&gt;
    header:tag(&#039;th&#039;):wikitext(&#039;Category&#039;):css(&#039;width&#039;, &#039;16%&#039;)&lt;br /&gt;
    header:tag(&#039;th&#039;):wikitext(&#039;Base Power&#039;):css(&#039;width&#039;, &#039;17%&#039;)&lt;br /&gt;
    header:tag(&#039;th&#039;):wikitext(&#039;Accuracy&#039;):css(&#039;width&#039;, &#039;15%&#039;)&lt;br /&gt;
    header:tag(&#039;th&#039;):wikitext(&#039;PP&#039;):css(&#039;width&#039;, &#039;10%&#039;):css(&#039;border-top-right-radius&#039;, &#039;25px&#039;)&lt;br /&gt;
&lt;br /&gt;
    for _, moveName in ipairs(tms) do&lt;br /&gt;
        local moveInfo = moveData[moveName] or {}&lt;br /&gt;
        local row = table:tag(&#039;tr&#039;):css(&#039;background-color&#039;, &#039;#FFFFFF&#039;)&lt;br /&gt;
&lt;br /&gt;
        row:tag(&#039;td&#039;):attr(&#039;colspan&#039;, &#039;2&#039;):wikitext(formatItemNumber(&#039;TM&#039;, moveInfo.tm))&lt;br /&gt;
&lt;br /&gt;
        local moveLink = &#039;[[&#039; .. moveName .. &#039;]]&#039;&lt;br /&gt;
        if isSTAB(moveInfo.type, primaryType, secondaryType) and moveInfo.category ~= &amp;quot;Status&amp;quot; then&lt;br /&gt;
            moveLink = &amp;quot;&#039;&#039;&#039;&amp;quot; .. moveLink .. &amp;quot;&#039;&#039;&#039;&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        if moveInfo.broken == &amp;quot;Y&amp;quot; then&lt;br /&gt;
            moveLink = &amp;quot;&#039;&#039;&amp;quot; .. moveLink .. &amp;quot;&#039;&#039;&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        row:tag(&#039;td&#039;):wikitext(moveLink)&lt;br /&gt;
&lt;br /&gt;
        local moveTypeColors = typeColor(frame, moveInfo.type)&lt;br /&gt;
        row:tag(&#039;td&#039;)&lt;br /&gt;
            :css(&#039;background-color&#039;, &#039;#&#039; .. moveTypeColors.base)&lt;br /&gt;
            :css(&#039;border&#039;, &#039;2px solid #&#039; .. moveTypeColors.dark)&lt;br /&gt;
            :wikitext(&#039;[[&#039; .. (moveInfo.type or &#039;Normal&#039;) .. &#039;_(type)|&amp;lt;span style=&amp;quot;color:#FFFFFF;&amp;quot;&amp;gt;&#039; .. (moveInfo.type or &#039;Normal&#039;) .. &#039;&amp;lt;/span&amp;gt;]]&#039;)&lt;br /&gt;
&lt;br /&gt;
        local moveCatColors = categoryColor(frame, moveInfo.category)&lt;br /&gt;
        row:tag(&#039;td&#039;)&lt;br /&gt;
            :css(&#039;background-color&#039;, &#039;#&#039; .. moveCatColors.base)&lt;br /&gt;
            :css(&#039;border&#039;, &#039;2px solid #&#039; .. moveCatColors.dark)&lt;br /&gt;
            :wikitext(&#039;[[&#039; .. (moveInfo.category or &#039;Status&#039;) .. &#039; moves|&amp;lt;span style=&amp;quot;color:#FFFFFF;&amp;quot;&amp;gt;&#039; .. (moveInfo.category or &#039;Status&#039;) .. &#039;&amp;lt;/span&amp;gt;]]&#039;)&lt;br /&gt;
&lt;br /&gt;
        row:tag(&#039;td&#039;):wikitext(moveInfo.power or &#039;—&#039;)&lt;br /&gt;
        row:tag(&#039;td&#039;):wikitext(moveInfo.accuracy or &#039;—&#039;)&lt;br /&gt;
        row:tag(&#039;td&#039;):wikitext(moveInfo.pp or &#039;—&#039;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    for _, moveName in ipairs(hms) do&lt;br /&gt;
        local moveInfo = moveData[moveName] or {}&lt;br /&gt;
        local row = table:tag(&#039;tr&#039;):css(&#039;background-color&#039;, &#039;#FFFFCC&#039;)&lt;br /&gt;
&lt;br /&gt;
        row:tag(&#039;td&#039;):attr(&#039;colspan&#039;, &#039;2&#039;):wikitext(formatItemNumber(&#039;HM&#039;, moveInfo.tm)):css(&#039;font-weight&#039;, &#039;bold&#039;)&lt;br /&gt;
&lt;br /&gt;
        local moveLink = &#039;[[&#039; .. moveName .. &#039;]]&#039;&lt;br /&gt;
        if isSTAB(moveInfo.type, primaryType, secondaryType) and moveInfo.category ~= &amp;quot;Status&amp;quot; then&lt;br /&gt;
            moveLink = &amp;quot;&#039;&#039;&#039;&amp;quot; .. moveLink .. &amp;quot;&#039;&#039;&#039;&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        if moveInfo.broken == &amp;quot;Y&amp;quot; then&lt;br /&gt;
            moveLink = &amp;quot;&#039;&#039;&amp;quot; .. moveLink .. &amp;quot;&#039;&#039;&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        row:tag(&#039;td&#039;):wikitext(moveLink)&lt;br /&gt;
&lt;br /&gt;
        local moveTypeColors = typeColor(frame, moveInfo.type)&lt;br /&gt;
        row:tag(&#039;td&#039;)&lt;br /&gt;
            :css(&#039;background-color&#039;, &#039;#&#039; .. moveTypeColors.base)&lt;br /&gt;
            :css(&#039;border&#039;, &#039;2px solid #&#039; .. moveTypeColors.dark)&lt;br /&gt;
            :wikitext(&#039;[[&#039; .. (moveInfo.type or &#039;Normal&#039;) .. &#039;_(type)|&amp;lt;span style=&amp;quot;color:#FFFFFF;&amp;quot;&amp;gt;&#039; .. (moveInfo.type or &#039;Normal&#039;) .. &#039;&amp;lt;/span&amp;gt;]]&#039;)&lt;br /&gt;
&lt;br /&gt;
        local moveCatColors = categoryColor(frame, moveInfo.category)&lt;br /&gt;
        row:tag(&#039;td&#039;)&lt;br /&gt;
            :css(&#039;background-color&#039;, &#039;#&#039; .. moveCatColors.base)&lt;br /&gt;
            :css(&#039;border&#039;, &#039;2px solid #&#039; .. moveCatColors.dark)&lt;br /&gt;
            :wikitext(&#039;[[&#039; .. (moveInfo.category or &#039;Status&#039;) .. &#039; moves|&amp;lt;span style=&amp;quot;color:#FFFFFF;&amp;quot;&amp;gt;&#039; .. (moveInfo.category or &#039;Status&#039;) .. &#039;&amp;lt;/span&amp;gt;]]&#039;)&lt;br /&gt;
&lt;br /&gt;
        row:tag(&#039;td&#039;):wikitext(moveInfo.power or &#039;—&#039;)&lt;br /&gt;
        row:tag(&#039;td&#039;):wikitext(moveInfo.accuracy or &#039;—&#039;)&lt;br /&gt;
        row:tag(&#039;td&#039;):wikitext(moveInfo.pp or &#039;—&#039;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    html:tag(&#039;div&#039;)&lt;br /&gt;
        :css(&#039;text-align&#039;, &#039;left&#039;)&lt;br /&gt;
        :css(&#039;background-color&#039;, &#039;#&#039; .. colors.light)&lt;br /&gt;
        :css(&#039;padding&#039;, &#039;10px&#039;)&lt;br /&gt;
        :css(&#039;border&#039;, &#039;3px solid #&#039; .. colors.dark)&lt;br /&gt;
        :css(&#039;border-top&#039;, &#039;none&#039;)&lt;br /&gt;
        :css(&#039;border-radius&#039;, &#039;0 0 25px 25px&#039;)&lt;br /&gt;
        :wikitext([=[&lt;br /&gt;
* &#039;&#039;&#039;Emboldened&#039;&#039;&#039; moves denote that this Pokémon avails from a STAB bonus for it.&lt;br /&gt;
* &#039;&#039;Italicized&#039;&#039; moves are [[Broken_Moves_%26_Abilities|broken]]; see their individual pages for more information.&lt;br /&gt;
* Refer to [[TMs and HMs]] for information on each move&#039;s obtainability.&lt;br /&gt;
]=])&lt;br /&gt;
    &lt;br /&gt;
    return tostring(html) .. &#039;&amp;lt;br clear=&amp;quot;all&amp;quot;&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.renderMoveTutors(frame)&lt;br /&gt;
    local args = getArgs(frame)&lt;br /&gt;
    local pokemonName = args[1] or args.pokemon&lt;br /&gt;
    local primaryType = args.type1 or &amp;quot;&amp;quot;&lt;br /&gt;
    local secondaryType = args.type2 or &amp;quot;&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
    local pokemon = getCachedLearnset(pokemonName)&lt;br /&gt;
    local moveData = loadMoveData()&lt;br /&gt;
&lt;br /&gt;
    if not pokemon then return &#039;&#039; end&lt;br /&gt;
&lt;br /&gt;
    local moves = pokemon.move_tutors or {}&lt;br /&gt;
    &lt;br /&gt;
    if #moves == 0 then&lt;br /&gt;
        return &amp;quot;&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    local colors = typeColor(frame, primaryType)&lt;br /&gt;
&lt;br /&gt;
    local html = mw.html.create(&#039;div&#039;)&lt;br /&gt;
        :css(&#039;width&#039;, &#039;77%&#039;)&lt;br /&gt;
        :css(&#039;margin&#039;, &#039;auto&#039;)&lt;br /&gt;
    local table = html:tag(&#039;table&#039;)&lt;br /&gt;
        :addClass(&#039;sortable&#039;)&lt;br /&gt;
        :css(&#039;width&#039;, &#039;100%&#039;)&lt;br /&gt;
        :css(&#039;text-align&#039;, &#039;center&#039;)&lt;br /&gt;
        :css(&#039;border-radius&#039;, &#039;25px 25px 0 0&#039;)&lt;br /&gt;
        :css(&#039;border&#039;, &#039;3px solid #&#039; .. colors.dark)&lt;br /&gt;
        :css(&#039;border-bottom&#039;, &#039;none&#039;)&lt;br /&gt;
        :css(&#039;background-color&#039;, &#039;#&#039; .. colors.base)&lt;br /&gt;
        :css(&#039;padding&#039;, &#039;7px&#039;)&lt;br /&gt;
&lt;br /&gt;
    local header = table:tag(&#039;tr&#039;)&lt;br /&gt;
        :css(&#039;background-color&#039;, &#039;#&#039; .. colors.light)&lt;br /&gt;
        :css(&#039;color&#039;, &#039;#&#039; .. colors.dark)&lt;br /&gt;
    header:tag(&#039;th&#039;):wikitext(&#039;Move&#039;):css(&#039;width&#039;, &#039;20%&#039;):css(&#039;border-top-left-radius&#039;, &#039;25px&#039;)&lt;br /&gt;
    header:tag(&#039;th&#039;):wikitext(&#039;Type&#039;):css(&#039;width&#039;, &#039;17%&#039;)&lt;br /&gt;
    header:tag(&#039;th&#039;):wikitext(&#039;Category&#039;):css(&#039;width&#039;, &#039;16%&#039;)&lt;br /&gt;
    header:tag(&#039;th&#039;):wikitext(&#039;Base Power&#039;):css(&#039;width&#039;, &#039;17%&#039;)&lt;br /&gt;
    header:tag(&#039;th&#039;):wikitext(&#039;Accuracy&#039;):css(&#039;width&#039;, &#039;15%&#039;)&lt;br /&gt;
    header:tag(&#039;th&#039;):wikitext(&#039;PP&#039;):css(&#039;width&#039;, &#039;15%&#039;):css(&#039;border-top-right-radius&#039;, &#039;25px&#039;)&lt;br /&gt;
&lt;br /&gt;
    for _, moveName in ipairs(moves) do&lt;br /&gt;
        local moveInfo = moveData[moveName] or {}&lt;br /&gt;
        local row = table:tag(&#039;tr&#039;):css(&#039;background-color&#039;, &#039;#FFFFFF&#039;)&lt;br /&gt;
&lt;br /&gt;
        local moveLink = &#039;[[&#039; .. moveName .. &#039;]]&#039;&lt;br /&gt;
        if isSTAB(moveInfo.type, primaryType, secondaryType) and moveInfo.category ~= &amp;quot;Status&amp;quot; then&lt;br /&gt;
            moveLink = &amp;quot;&#039;&#039;&#039;&amp;quot; .. moveLink .. &amp;quot;&#039;&#039;&#039;&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        if moveInfo.broken == &amp;quot;Y&amp;quot; then&lt;br /&gt;
            moveLink = &amp;quot;&#039;&#039;&amp;quot; .. moveLink .. &amp;quot;&#039;&#039;&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        row:tag(&#039;td&#039;):wikitext(moveLink)&lt;br /&gt;
&lt;br /&gt;
        local moveTypeColors = typeColor(frame, moveInfo.type)&lt;br /&gt;
        row:tag(&#039;td&#039;)&lt;br /&gt;
            :css(&#039;background-color&#039;, &#039;#&#039; .. moveTypeColors.base)&lt;br /&gt;
            :css(&#039;border&#039;, &#039;2px solid #&#039; .. moveTypeColors.dark)&lt;br /&gt;
            :wikitext(&#039;[[&#039; .. (moveInfo.type or &#039;Normal&#039;) .. &#039;_(type)|&amp;lt;span style=&amp;quot;color:#FFFFFF;&amp;quot;&amp;gt;&#039; .. (moveInfo.type or &#039;Normal&#039;) .. &#039;&amp;lt;/span&amp;gt;]]&#039;)&lt;br /&gt;
&lt;br /&gt;
        local moveCatColors = categoryColor(frame, moveInfo.category)&lt;br /&gt;
        row:tag(&#039;td&#039;)&lt;br /&gt;
            :css(&#039;background-color&#039;, &#039;#&#039; .. moveCatColors.base)&lt;br /&gt;
            :css(&#039;border&#039;, &#039;2px solid #&#039; .. moveCatColors.dark)&lt;br /&gt;
            :wikitext(&#039;[[&#039; .. (moveInfo.category or &#039;Status&#039;) .. &#039; moves|&amp;lt;span style=&amp;quot;color:#FFFFFF;&amp;quot;&amp;gt;&#039; .. (moveInfo.category or &#039;Status&#039;) .. &#039;&amp;lt;/span&amp;gt;]]&#039;)&lt;br /&gt;
&lt;br /&gt;
        row:tag(&#039;td&#039;):wikitext(moveInfo.power or &#039;—&#039;)&lt;br /&gt;
        row:tag(&#039;td&#039;):wikitext(moveInfo.accuracy or &#039;—&#039;)&lt;br /&gt;
        row:tag(&#039;td&#039;):wikitext(moveInfo.pp or &#039;—&#039;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    html:tag(&#039;div&#039;)&lt;br /&gt;
        :css(&#039;text-align&#039;, &#039;left&#039;)&lt;br /&gt;
        :css(&#039;background-color&#039;, &#039;#&#039; .. colors.light)&lt;br /&gt;
        :css(&#039;padding&#039;, &#039;10px&#039;)&lt;br /&gt;
        :css(&#039;border&#039;, &#039;3px solid #&#039; .. colors.dark)&lt;br /&gt;
        :css(&#039;border-top&#039;, &#039;none&#039;)&lt;br /&gt;
        :css(&#039;border-radius&#039;, &#039;0 0 25px 25px&#039;)&lt;br /&gt;
        :wikitext([=[&lt;br /&gt;
* &#039;&#039;&#039;Emboldened&#039;&#039;&#039; moves denote that this Pokémon avails from a STAB bonus for it.&lt;br /&gt;
* &#039;&#039;Italicized&#039;&#039; moves are [[Broken_Moves_%26_Abilities|broken]]; see their individual pages for more information.&lt;br /&gt;
* Refer to the [[Move Tutors]] article for tutorship information for all moves hereon.&lt;br /&gt;
]=])&lt;br /&gt;
&lt;br /&gt;
    return tostring(html) .. &#039;&amp;lt;br clear=&amp;quot;all&amp;quot;&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.renderEggMoves(frame)&lt;br /&gt;
    local args = getArgs(frame)&lt;br /&gt;
    local pokemonName = args[1] or args.pokemon&lt;br /&gt;
    local primaryType = args.type1 or &amp;quot;&amp;quot;&lt;br /&gt;
    local secondaryType = args.type2 or &amp;quot;&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
    local pokemon = getCachedLearnset(pokemonName)&lt;br /&gt;
    local moveData = loadMoveData()&lt;br /&gt;
&lt;br /&gt;
    if not pokemon then return &#039;&#039; end&lt;br /&gt;
&lt;br /&gt;
    local moves = pokemon.egg_moves or {}&lt;br /&gt;
    &lt;br /&gt;
    if #moves == 0 then&lt;br /&gt;
        return &amp;quot;&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    local colors = typeColor(frame, primaryType)&lt;br /&gt;
&lt;br /&gt;
    local html = mw.html.create(&#039;div&#039;)&lt;br /&gt;
        :css(&#039;width&#039;, &#039;77%&#039;)&lt;br /&gt;
        :css(&#039;margin&#039;, &#039;auto&#039;)&lt;br /&gt;
    local table = html:tag(&#039;table&#039;)&lt;br /&gt;
        :addClass(&#039;sortable&#039;)&lt;br /&gt;
        :css(&#039;width&#039;, &#039;100%&#039;)&lt;br /&gt;
        :css(&#039;text-align&#039;, &#039;center&#039;)&lt;br /&gt;
        :css(&#039;border-radius&#039;, &#039;25px 25px 0 0&#039;)&lt;br /&gt;
        :css(&#039;border&#039;, &#039;3px solid #&#039; .. colors.dark)&lt;br /&gt;
        :css(&#039;border-bottom&#039;, &#039;none&#039;)&lt;br /&gt;
        :css(&#039;background-color&#039;, &#039;#&#039; .. colors.base)&lt;br /&gt;
        :css(&#039;padding&#039;, &#039;7px&#039;)&lt;br /&gt;
&lt;br /&gt;
    local header = table:tag(&#039;tr&#039;)&lt;br /&gt;
        :css(&#039;background-color&#039;, &#039;#&#039; .. colors.light)&lt;br /&gt;
        :css(&#039;color&#039;, &#039;#&#039; .. colors.dark)&lt;br /&gt;
    header:tag(&#039;th&#039;):wikitext(&#039;Move&#039;):css(&#039;width&#039;, &#039;20%&#039;):css(&#039;border-top-left-radius&#039;, &#039;25px&#039;)&lt;br /&gt;
    header:tag(&#039;th&#039;):wikitext(&#039;Type&#039;):css(&#039;width&#039;, &#039;17%&#039;)&lt;br /&gt;
    header:tag(&#039;th&#039;):wikitext(&#039;Category&#039;):css(&#039;width&#039;, &#039;16%&#039;)&lt;br /&gt;
    header:tag(&#039;th&#039;):wikitext(&#039;Base Power&#039;):css(&#039;width&#039;, &#039;17%&#039;)&lt;br /&gt;
    header:tag(&#039;th&#039;):wikitext(&#039;Accuracy&#039;):css(&#039;width&#039;, &#039;15%&#039;)&lt;br /&gt;
    header:tag(&#039;th&#039;):wikitext(&#039;PP&#039;):css(&#039;width&#039;, &#039;15%&#039;):css(&#039;border-top-right-radius&#039;, &#039;25px&#039;)&lt;br /&gt;
&lt;br /&gt;
    for _, moveName in ipairs(moves) do&lt;br /&gt;
        local moveInfo = moveData[moveName] or {}&lt;br /&gt;
        local row = table:tag(&#039;tr&#039;):css(&#039;background-color&#039;, &#039;#FFFFFF&#039;)&lt;br /&gt;
&lt;br /&gt;
        local moveLink = &#039;[[&#039; .. moveName .. &#039;]]&#039;&lt;br /&gt;
        if isSTAB(moveInfo.type, primaryType, secondaryType) and moveInfo.category ~= &amp;quot;Status&amp;quot; then&lt;br /&gt;
            moveLink = &amp;quot;&#039;&#039;&#039;&amp;quot; .. moveLink .. &amp;quot;&#039;&#039;&#039;&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        if moveInfo.broken == &amp;quot;Y&amp;quot; then&lt;br /&gt;
            moveLink = &amp;quot;&#039;&#039;&amp;quot; .. moveLink .. &amp;quot;&#039;&#039;&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        row:tag(&#039;td&#039;):wikitext(moveLink)&lt;br /&gt;
&lt;br /&gt;
        local moveTypeColors = typeColor(frame, moveInfo.type)&lt;br /&gt;
        row:tag(&#039;td&#039;)&lt;br /&gt;
            :css(&#039;background-color&#039;, &#039;#&#039; .. moveTypeColors.base)&lt;br /&gt;
            :css(&#039;border&#039;, &#039;2px solid #&#039; .. moveTypeColors.dark)&lt;br /&gt;
            :wikitext(&#039;[[&#039; .. (moveInfo.type or &#039;Normal&#039;) .. &#039;_(type)|&amp;lt;span style=&amp;quot;color:#FFFFFF;&amp;quot;&amp;gt;&#039; .. (moveInfo.type or &#039;Normal&#039;) .. &#039;&amp;lt;/span&amp;gt;]]&#039;)&lt;br /&gt;
&lt;br /&gt;
        local moveCatColors = categoryColor(frame, moveInfo.category)&lt;br /&gt;
        row:tag(&#039;td&#039;)&lt;br /&gt;
            :css(&#039;background-color&#039;, &#039;#&#039; .. moveCatColors.base)&lt;br /&gt;
            :css(&#039;border&#039;, &#039;2px solid #&#039; .. moveCatColors.dark)&lt;br /&gt;
            :wikitext(&#039;[[&#039; .. (moveInfo.category or &#039;Status&#039;) .. &#039; moves|&amp;lt;span style=&amp;quot;color:#FFFFFF;&amp;quot;&amp;gt;&#039; .. (moveInfo.category or &#039;Status&#039;) .. &#039;&amp;lt;/span&amp;gt;]]&#039;)&lt;br /&gt;
&lt;br /&gt;
        row:tag(&#039;td&#039;):wikitext(moveInfo.power or &#039;—&#039;)&lt;br /&gt;
        row:tag(&#039;td&#039;):wikitext(moveInfo.accuracy or &#039;—&#039;)&lt;br /&gt;
        row:tag(&#039;td&#039;):wikitext(moveInfo.pp or &#039;—&#039;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    html:tag(&#039;div&#039;)&lt;br /&gt;
        :css(&#039;text-align&#039;, &#039;left&#039;)&lt;br /&gt;
        :css(&#039;background-color&#039;, &#039;#&#039; .. colors.light)&lt;br /&gt;
        :css(&#039;padding&#039;, &#039;10px&#039;)&lt;br /&gt;
        :css(&#039;border&#039;, &#039;3px solid #&#039; .. colors.dark)&lt;br /&gt;
        :css(&#039;border-top&#039;, &#039;none&#039;)&lt;br /&gt;
        :css(&#039;border-radius&#039;, &#039;0 0 25px 25px&#039;)&lt;br /&gt;
        :wikitext([=[&lt;br /&gt;
* &#039;&#039;&#039;Emboldened&#039;&#039;&#039; moves denote that this Pokémon avails from a STAB bonus for it.&lt;br /&gt;
* &#039;&#039;Italicized&#039;&#039; moves are [[Broken_Moves_%26_Abilities|broken]]; see their individual pages for more information.&lt;br /&gt;
* For more information on egg-move-tutors, refer to: [[Egg Moves]].&lt;br /&gt;
]=])&lt;br /&gt;
    &lt;br /&gt;
    return tostring(html) .. &#039;&amp;lt;br clear=&amp;quot;all&amp;quot;&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function renderEmptyNotice(frame, primaryType, radius, message)&lt;br /&gt;
    local colors = typeColor(frame, primaryType)&lt;br /&gt;
    local html = mw.html.create(&#039;div&#039;)&lt;br /&gt;
        :css(&#039;width&#039;, &#039;77%&#039;)&lt;br /&gt;
        :css(&#039;margin&#039;, &#039;auto&#039;)&lt;br /&gt;
        :css(&#039;text-align&#039;, &#039;center&#039;)&lt;br /&gt;
        :css(&#039;background-color&#039;, &#039;#&#039; .. colors.light)&lt;br /&gt;
        :css(&#039;padding&#039;, &#039;20px 10px&#039;)&lt;br /&gt;
        :css(&#039;border&#039;, &#039;3px solid #&#039; .. colors.dark)&lt;br /&gt;
        :css(&#039;border-radius&#039;, radius)&lt;br /&gt;
        :wikitext(&amp;quot;&#039;&#039;&amp;quot; .. message .. &amp;quot;&#039;&#039;&amp;quot;)&lt;br /&gt;
    return tostring(html) .. &#039;&amp;lt;br clear=&amp;quot;all&amp;quot;&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function hyphenSpaceVariant(s)&lt;br /&gt;
    if mw.ustring.find(s, &#039;-&#039;, 1, true) then&lt;br /&gt;
        return (mw.ustring.gsub(s, &#039;%-&#039;, &#039; &#039;))&lt;br /&gt;
    end&lt;br /&gt;
    return (mw.ustring.gsub(s, &#039; &#039;, &#039;-&#039;))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function resolveType(pokemonName, type1Override, type2Override)&lt;br /&gt;
    if type1Override ~= &#039;&#039; then&lt;br /&gt;
        return type1Override, type2Override&lt;br /&gt;
    end&lt;br /&gt;
    local typeData = loadPokemonTypes()&lt;br /&gt;
    local pt = typeData[pokemonName]&lt;br /&gt;
        or typeData[sentenceCase(pokemonName)]&lt;br /&gt;
        or typeData[hyphenSpaceVariant(pokemonName)]&lt;br /&gt;
    if pt then&lt;br /&gt;
        return pt.type1 or &#039;&#039;, pt.type2 or &#039;&#039;&lt;br /&gt;
    end&lt;br /&gt;
    return &#039;&#039;, &#039;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.main(frame)&lt;br /&gt;
    local args        = getArgs(frame)&lt;br /&gt;
    local pokemonName = args[1] or args.pokemon or &#039;&#039;&lt;br /&gt;
    local originalName = pokemonName&lt;br /&gt;
&lt;br /&gt;
    if pokemonName == &#039;&#039; then&lt;br /&gt;
        return &amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;Usage: {{Learnsets|PokemonName}}&amp;lt;/span&amp;gt;&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    primeLearnsetCache({ pokemonName })&lt;br /&gt;
&lt;br /&gt;
    local poke, lsErr, resolvedName = resolvePagePokemon(pokemonName)&lt;br /&gt;
    if not poke then&lt;br /&gt;
        return &amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;Data load error: &amp;quot; .. (lsErr or &#039;unknown&#039;) .. &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    pokemonName = resolvedName&lt;br /&gt;
&lt;br /&gt;
    local primaryType, secondaryType = resolveType(originalName, args.type1 or &#039;&#039;, args.type2 or &#039;&#039;)&lt;br /&gt;
    if primaryType == &#039;&#039; and originalName ~= pokemonName then&lt;br /&gt;
        primaryType, secondaryType = resolveType(pokemonName, &#039;&#039;, &#039;&#039;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local function callRender(fn, name, type1, type2)&lt;br /&gt;
        return fn(frame:newChild({&lt;br /&gt;
            title = frame:getTitle(),&lt;br /&gt;
            args  = { name, type1 = type1, type2 = type2 },&lt;br /&gt;
        }))&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local formCandidates = {}&lt;br /&gt;
    for _, form in ipairs(FORM_SUFFIXES) do&lt;br /&gt;
        local candidateName&lt;br /&gt;
        if form.learnsetStyle == &#039;prefix-space&#039; then&lt;br /&gt;
            candidateName = form.suffix .. &#039; &#039; .. pokemonName&lt;br /&gt;
        else&lt;br /&gt;
            candidateName = pokemonName .. &#039;-&#039; .. form.suffix&lt;br /&gt;
        end&lt;br /&gt;
        table.insert(formCandidates, { form = form, candidateName = candidateName })&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    do&lt;br /&gt;
        local names = {}&lt;br /&gt;
        for _, fc in ipairs(formCandidates) do&lt;br /&gt;
            table.insert(names, fc.candidateName)&lt;br /&gt;
        end&lt;br /&gt;
        primeLearnsetCache(names)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local forms = {}&lt;br /&gt;
    for _, fc in ipairs(formCandidates) do&lt;br /&gt;
        local form, candidateName = fc.form, fc.candidateName&lt;br /&gt;
&lt;br /&gt;
        local candidatePoke = getCachedLearnset(candidateName)&lt;br /&gt;
        if candidatePoke then&lt;br /&gt;
            -- Shared with Module:Pokemon (Module:PokemonForms.rawListFormName)&lt;br /&gt;
            -- instead of a separately-hand-duplicated copy of the same branching.&lt;br /&gt;
            local rawListName = PokemonForms.rawListFormName(form, pokemonName)&lt;br /&gt;
            local t1, t2 = resolveType(rawListName, &#039;&#039;, &#039;&#039;)&lt;br /&gt;
            table.insert(forms, {&lt;br /&gt;
                name = form.label,&lt;br /&gt;
                fullName = candidateName,&lt;br /&gt;
                displayName = rawListName,&lt;br /&gt;
                poke = candidatePoke,&lt;br /&gt;
                type1 = t1,&lt;br /&gt;
                type2 = t2,&lt;br /&gt;
                baseLabel = form.baseLabel,&lt;br /&gt;
            })&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local sectionDefs = {&lt;br /&gt;
        { heading = &#039;Level-up&#039;, plain = &#039;Level-up&#039;, radius = &#039;15px&#039;, render = p.renderLevelUp,&lt;br /&gt;
          hasData = function(pk) return #(pk.level_up or {}) &amp;gt; 0 end },&lt;br /&gt;
        { heading = &#039;[[TMs and HMs]]&#039;, plain = &#039;TMs and HMs&#039;, radius = &#039;25px&#039;, render = p.renderTMsHMs,&lt;br /&gt;
          hasData = function(pk) return #(pk.tms or {}) &amp;gt; 0 or #(pk.hms or {}) &amp;gt; 0 end },&lt;br /&gt;
        { heading = &#039;[[Move Tutors]]&#039;, plain = &#039;Move Tutors&#039;, radius = &#039;25px&#039;, render = p.renderMoveTutors,&lt;br /&gt;
          hasData = function(pk) return #(pk.move_tutors or {}) &amp;gt; 0 end },&lt;br /&gt;
        { heading = &#039;[[Egg Moves]]&#039;, plain = &#039;Egg Moves&#039;, radius = &#039;25px&#039;, render = p.renderEggMoves,&lt;br /&gt;
          hasData = function(pk) return #(pk.egg_moves or {}) &amp;gt; 0 end },&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    local baseLabel = &#039;Normal&#039;&lt;br /&gt;
    for _, f in ipairs(forms) do&lt;br /&gt;
        if f.baseLabel then&lt;br /&gt;
            baseLabel = f.baseLabel&lt;br /&gt;
            break&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    local baseDisplayName = (baseLabel ~= &#039;Normal&#039;) and (pokemonName .. &#039; &#039; .. baseLabel) or pokemonName&lt;br /&gt;
&lt;br /&gt;
    local allParticipants = { { label = baseLabel, name = pokemonName, displayName = baseDisplayName, type1 = primaryType, type2 = secondaryType, poke = poke, isBase = true } }&lt;br /&gt;
    for _, f in ipairs(forms) do&lt;br /&gt;
        table.insert(allParticipants, { label = f.name, name = f.fullName, displayName = f.displayName, type1 = f.type1, type2 = f.type2, poke = f.poke })&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local sections = {}&lt;br /&gt;
    local usedTabs = false&lt;br /&gt;
&lt;br /&gt;
    for _, def in ipairs(sectionDefs) do&lt;br /&gt;
        local anyHasData = false&lt;br /&gt;
        for _, part in ipairs(allParticipants) do&lt;br /&gt;
            if def.hasData(part.poke) then&lt;br /&gt;
                anyHasData = true&lt;br /&gt;
                break&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
        if anyHasData then&lt;br /&gt;
            table.insert(sections, &amp;quot;===&amp;quot; .. def.heading .. &amp;quot;===&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
            if #allParticipants == 1 then&lt;br /&gt;
                local part = allParticipants[1]&lt;br /&gt;
                table.insert(sections, callRender(def.render, part.name, part.type1, part.type2))&lt;br /&gt;
            else&lt;br /&gt;
                usedTabs = true&lt;br /&gt;
&lt;br /&gt;
                local tabHeaders, infoBoxes = &#039;&#039;, &#039;&#039;&lt;br /&gt;
                for _, part in ipairs(allParticipants) do&lt;br /&gt;
                    tabHeaders = tabHeaders .. &amp;quot;{{Tabs:MultiformTab|Form=&amp;quot; .. part.label .. &amp;quot;}}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
                    local box&lt;br /&gt;
                    if def.hasData(part.poke) then&lt;br /&gt;
                        box = callRender(def.render, part.name, part.type1, part.type2)&lt;br /&gt;
                    else&lt;br /&gt;
                        box = renderEmptyNotice(frame, part.type1, def.radius,&lt;br /&gt;
                            &#039;No &#039; .. def.plain .. &#039; data for &#039; .. (part.displayName or part.label) .. &#039;.&#039;)&lt;br /&gt;
                    end&lt;br /&gt;
&lt;br /&gt;
                    if part.isBase then&lt;br /&gt;
                        infoBoxes = infoBoxes .. &amp;quot;{{Tabs:MultiformTableAdditional|Table=&amp;quot; .. box .. &amp;quot;}}&amp;quot;&lt;br /&gt;
                    else&lt;br /&gt;
                        infoBoxes = infoBoxes .. &amp;quot;{{Tabs:MultiformTableAdditional|Form=&amp;quot; .. part.label .. &amp;quot;|Table=&amp;quot; .. box .. &amp;quot;}}&amp;quot;&lt;br /&gt;
                    end&lt;br /&gt;
                end&lt;br /&gt;
&lt;br /&gt;
                -- Type= is required here: TabbedInfoBoxes only sets the tab&lt;br /&gt;
                -- buttons&#039; border/background color once via {{Trichrome}},&lt;br /&gt;
                -- falling back to a stale leftover {{#external_value:type}}&lt;br /&gt;
                -- when Type= is omitted -- which it always was before this.&lt;br /&gt;
                table.insert(sections,&lt;br /&gt;
                    &amp;quot;{{TabbedInfoBoxes|Width=85|Class=|Type=&amp;quot; .. primaryType .. &amp;quot;|TabHeaders=&amp;quot; .. tabHeaders ..&lt;br /&gt;
                    &amp;quot;|InfoBoxes=\n&amp;quot; .. infoBoxes .. &amp;quot;\n}}&amp;quot;)&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if #sections == 0 then&lt;br /&gt;
        return &#039;&#039;&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local output = &amp;quot;==Moves==\n&amp;quot; .. table.concat(sections, &#039;\n&#039;)&lt;br /&gt;
&lt;br /&gt;
    if usedTabs then&lt;br /&gt;
        return frame:preprocess(output)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return output&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Module:PokemonForms&amp;diff=41072</id>
		<title>Module:PokemonForms</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Module:PokemonForms&amp;diff=41072"/>
		<updated>2026-08-09T12:36:07Z</updated>

		<summary type="html">&lt;p&gt;Cae: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {}&lt;br /&gt;
&lt;br /&gt;
p.FORM_SUFFIXES = {&lt;br /&gt;
    { suffix = &#039;Alolan&#039;, label = &#039;Alolan&#039;, rawList = &#039;prefix&#039; },&lt;br /&gt;
    { suffix = &#039;Galar&#039;, label = &#039;Galarian&#039;, rawList = &#039;prefix&#039; },&lt;br /&gt;
    { suffix = &#039;Hisui&#039;, label = &#039;Hisuian&#039;, rawList = &#039;prefix&#039; },&lt;br /&gt;
    { suffix = &#039;Paldea&#039;, label = &#039;Paldean&#039;, rawList = &#039;prefix&#039; },&lt;br /&gt;
    { suffix = &#039;Sandy&#039;, label = &#039;Sandy&#039;, rawList = &#039;suffix&#039; },&lt;br /&gt;
    { suffix = &#039;Trash&#039;, label = &#039;Trash&#039;, rawList = &#039;suffix&#039; },&lt;br /&gt;
    { suffix = &#039;Sky&#039;, label = &#039;Sky&#039;, rawList = &#039;suffix&#039; },&lt;br /&gt;
    { suffix = &#039;Fan&#039;, label = &#039;Fan&#039;, rawList = &#039;suffix&#039; },&lt;br /&gt;
    { suffix = &#039;Frost&#039;, label = &#039;Frost&#039;, rawList = &#039;suffix&#039; },&lt;br /&gt;
    { suffix = &#039;Heat&#039;, label = &#039;Heat&#039;, rawList = &#039;suffix&#039; },&lt;br /&gt;
    { suffix = &#039;Mow&#039;, label = &#039;Mow&#039;, rawList = &#039;suffix&#039; },&lt;br /&gt;
    { suffix = &#039;Wash&#039;, label = &#039;Wash&#039;, rawList = &#039;suffix&#039; },&lt;br /&gt;
    { suffix = &#039;Ash&#039;, label = &#039;Ash&#039;, learnsetStyle = &#039;prefix-space&#039;, rawList = &#039;prefix-hyphen&#039; },&lt;br /&gt;
    { suffix = &#039;Bloodmoon&#039;, label = &#039;Bloodmoon&#039;, rawList = &#039;suffix&#039; },&lt;br /&gt;
    { suffix = &#039;Low-Key&#039;, label = &#039;Low Key&#039;, rawList = &#039;suffix-label&#039; },&lt;br /&gt;
    { suffix = &#039;F&#039;, label = &#039;Female&#039;, rawList = &#039;suffix-space&#039;, baseLabel = &#039;Male&#039; },&lt;br /&gt;
    { suffix = &#039;Blue-Striped&#039;, label = &#039;Blue-Striped&#039;, rawList = &#039;suffix-label&#039; },&lt;br /&gt;
    { suffix = &#039;White-Striped&#039;, label = &#039;White-Striped&#039;, rawList = &#039;suffix-label&#039; },&lt;br /&gt;
    { suffix = &#039;Rainy&#039;, label = &#039;Rainy&#039;, rawList = &#039;suffix-label&#039; },&lt;br /&gt;
    { suffix = &#039;Snowy&#039;, label = &#039;Snowy&#039;, rawList = &#039;suffix-label&#039; },&lt;br /&gt;
    { suffix = &#039;Sunny&#039;, label = &#039;Sunny&#039;, rawList = &#039;suffix-label&#039; },&lt;br /&gt;
    { suffix = &#039;Sunshine&#039;, label = &#039;Sunshine&#039;, rawList = &#039;suffix-label&#039; },&lt;br /&gt;
    { suffix = &#039;Attack&#039;, label = &#039;Attack&#039;, rawList = &#039;suffix-label&#039; },&lt;br /&gt;
    { suffix = &#039;Defense&#039;, label = &#039;Defense&#039;, rawList = &#039;suffix-label&#039; },&lt;br /&gt;
    { suffix = &#039;Speed&#039;, label = &#039;Speed&#039;, rawList = &#039;suffix-label&#039; },&lt;br /&gt;
    { suffix = &#039;Unbound&#039;, label = &#039;Unbound&#039;, rawList = &#039;suffix-label&#039; },&lt;br /&gt;
    { suffix = &#039;Black&#039;, label = &#039;Black&#039;, rawList = &#039;suffix-label&#039; },&lt;br /&gt;
    { suffix = &#039;White&#039;, label = &#039;White&#039;, rawList = &#039;suffix-label&#039; },&lt;br /&gt;
    { suffix = &#039;Dusk&#039;, label = &#039;Dusk&#039;, rawList = &#039;suffix-label&#039; },&lt;br /&gt;
    { suffix = &#039;Midnight&#039;, label = &#039;Midnight&#039;, rawList = &#039;suffix-label&#039; },&lt;br /&gt;
    { suffix = &#039;Pirouette&#039;, label = &#039;Pirouette&#039;, rawList = &#039;suffix-label&#039; },&lt;br /&gt;
    { suffix = &#039;Yellow&#039;, label = &#039;Yellow&#039;, rawList = &#039;suffix-label&#039; },&lt;br /&gt;
    { suffix = &#039;School&#039;, label = &#039;School&#039;, rawList = &#039;suffix-label&#039; },&lt;br /&gt;
    { suffix = &#039;Crowned&#039;, label = &#039;Crowned&#039;, rawList = &#039;suffix-label&#039; },&lt;br /&gt;
    { suffix = &#039;Noice-Face&#039;, label = &#039;Noice Face&#039;, rawList = &#039;suffix-label&#039; },&lt;br /&gt;
    { suffix = &#039;Dusk-Mane&#039;, label = &#039;Dusk Mane&#039;, rawList = &#039;prefix&#039; },&lt;br /&gt;
    { suffix = &#039;Dawn-Wings&#039;, label = &#039;Dawn Wings&#039;, rawList = &#039;prefix&#039; },&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
p.STRIP_SUFFIXES = {&lt;br /&gt;
    &#039;Alolan&#039;, &#039;Galar&#039;, &#039;Hisui&#039;, &#039;Paldea&#039;, &#039;Sandy&#039;, &#039;Trash&#039;, &#039;Plant&#039;, &#039;Amped&#039;, &#039;Male&#039;,&lt;br /&gt;
    &#039;Ice Face&#039;, &#039;Noice Face&#039;, &#039;Midday&#039;, &#039;Solo&#039;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
p.RAW_LIST_ALIASES = {&lt;br /&gt;
    [&#039;Nidoran M&#039;] = &#039;Nidoran Male&#039;,&lt;br /&gt;
    [&#039;Nidoran F&#039;] = &#039;Nidoran Female&#039;,&lt;br /&gt;
    [&#039;Farfetchd&#039;] = &amp;quot;Farfetch&#039;d&amp;quot;,&lt;br /&gt;
    [&#039;Sirfetchd&#039;] = &amp;quot;Sirfetch&#039;d&amp;quot;,&lt;br /&gt;
    [&#039;Ho-oh&#039;] = &#039;Ho-Oh&#039;,&lt;br /&gt;
    [&#039;Porygon-z&#039;] = &#039;Porygon-Z&#039;,&lt;br /&gt;
    [&#039;Eiscue&#039;] = &#039;Eiscue-Ice Face&#039;,&lt;br /&gt;
    [&#039;Indeedee&#039;] = &#039;Indeedee Male&#039;,&lt;br /&gt;
    [&#039;Meowstic&#039;] = &#039;Meowstic Male&#039;,&lt;br /&gt;
    [&#039;Basculegion&#039;] = &#039;Basculegion-Male&#039;,&lt;br /&gt;
    [&#039;Oinkologne&#039;] = &#039;Oinkologne-Male&#039;,&lt;br /&gt;
    [&#039;Calyrex-Ice-Rider&#039;] = &#039;Calyrex-Ice Rider&#039;,&lt;br /&gt;
    [&#039;Calyrex-Shadow-Rider&#039;] = &#039;Calyrex-Shadow Rider&#039;,&lt;br /&gt;
    [&#039;Necrozma-Dusk-Mane&#039;] = &#039;Dusk Mane Necrozma&#039;,&lt;br /&gt;
    [&#039;Necrozma-Dawn-Wings&#039;] = &#039;Dawn Wings Necrozma&#039;,&lt;br /&gt;
    [&#039;Ogerpon&#039;] = &#039;Ogerpon-Teal Mask&#039;,&lt;br /&gt;
    [&#039;Ogerpon-Wellspring&#039;] = &#039;Ogerpon-Wellspring Mask&#039;,&lt;br /&gt;
    [&#039;Ogerpon-Hearthflame&#039;] = &#039;Ogerpon-Hearthflame Mask&#039;,&lt;br /&gt;
    [&#039;Ogerpon-Cornerstone&#039;] = &#039;Ogerpon-Cornerstone Mask&#039;,&lt;br /&gt;
    [&#039;Ogerpon-Wellspring-Tera&#039;] = &#039;Ogerpon-Wellspring Mask&#039;,&lt;br /&gt;
    [&#039;Ogerpon-Hearthflame-Tera&#039;] = &#039;Ogerpon-Hearthflame Mask&#039;,&lt;br /&gt;
    [&#039;Ogerpon-Cornerstone-Tera&#039;] = &#039;Ogerpon-Cornerstone Mask&#039;,&lt;br /&gt;
    [&#039;Oricorio&#039;] = &#039;Oricorio Baile&#039;,&lt;br /&gt;
    [&#039;Oricorio-Pom-Pom&#039;] = &#039;Oricorio Pom-Pom&#039;,&lt;br /&gt;
    [&#039;Oricorio-Pau&#039;] = &amp;quot;Oricorio Pa&#039;u&amp;quot;,&lt;br /&gt;
    [&#039;Tauros-Paldea-Combat&#039;] = &#039;Paldean Tauros-Combat&#039;,&lt;br /&gt;
    [&#039;Tauros-Paldea-Blaze&#039;] = &#039;Paldean Tauros-Blaze&#039;,&lt;br /&gt;
    [&#039;Tauros-Paldea-Aqua&#039;] = &#039;Paldean Tauros-Aqua&#039;,&lt;br /&gt;
    [&#039;Toxtricity&#039;] = &#039;Toxtricity-Amped&#039;,&lt;br /&gt;
    [&#039;Urshifu&#039;] = &#039;Urshifu-Single Strike&#039;,&lt;br /&gt;
    [&#039;Urshifu-Rapid-Strike&#039;] = &#039;Urshifu-Rapid Strike&#039;,&lt;br /&gt;
    [&#039;Wishiwashi&#039;] = &#039;Wishiwashi Solo&#039;,&lt;br /&gt;
    [&#039;Wormadam&#039;] = &#039;Wormadam-Plant&#039;,&lt;br /&gt;
    [&#039;Lycanroc&#039;] = &#039;Lycanroc-Midday&#039;,&lt;br /&gt;
    [&#039;Terapagos-Terastal&#039;] = &#039;Terapagos-Terestal&#039;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
-- Shared by Module:Pokemon and Module:Learnsets so both resolve a form&#039;s raw-list&lt;br /&gt;
-- (PokemonRawList) name identically -- previously each kept its own copy of this&lt;br /&gt;
-- logic, which is exactly the kind of duplication that quietly drifts out of sync.&lt;br /&gt;
function p.formStem(name)&lt;br /&gt;
    for _, form in ipairs(p.FORM_SUFFIXES) do&lt;br /&gt;
        local head = form.label .. &#039; &#039;&lt;br /&gt;
        if mw.ustring.sub(name, 1, mw.ustring.len(head)) == head then&lt;br /&gt;
            return mw.ustring.sub(name, mw.ustring.len(head) + 1)&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    for _, suffix in ipairs(p.STRIP_SUFFIXES) do&lt;br /&gt;
        for _, sep in ipairs({ &#039;-&#039;, &#039; &#039; }) do&lt;br /&gt;
            local tail = sep .. suffix&lt;br /&gt;
            if mw.ustring.sub(name, -mw.ustring.len(tail)) == tail then&lt;br /&gt;
                return mw.ustring.sub(name, 1, -mw.ustring.len(tail) - 1)&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    return name&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.rawListFormName(form, stem)&lt;br /&gt;
    if form.rawList == &#039;suffix&#039; then&lt;br /&gt;
        return stem .. &#039;-&#039; .. form.suffix&lt;br /&gt;
    elseif form.rawList == &#039;prefix-hyphen&#039; then&lt;br /&gt;
        return form.label .. &#039;-&#039; .. stem&lt;br /&gt;
    elseif form.rawList == &#039;suffix-label&#039; then&lt;br /&gt;
        return stem .. &#039;-&#039; .. form.label&lt;br /&gt;
    elseif form.rawList == &#039;suffix-space&#039; then&lt;br /&gt;
        return stem .. &#039; &#039; .. form.label&lt;br /&gt;
    end&lt;br /&gt;
    return form.label .. &#039; &#039; .. stem&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
p.MOB_PREFIXES = { &#039;Baby&#039;, &#039;Crystal&#039;, &#039;Shadow&#039; }&lt;br /&gt;
&lt;br /&gt;
p.MEGA_VARIANTS = { &#039;&#039;, &#039; X&#039;, &#039; Y&#039; }&lt;br /&gt;
&lt;br /&gt;
p.LEARNSET_ALIASES = {}&lt;br /&gt;
for learnsetName, rawListName in pairs(p.RAW_LIST_ALIASES) do&lt;br /&gt;
    p.LEARNSET_ALIASES[rawListName] = learnsetName&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Runerigus&amp;diff=41066</id>
		<title>Runerigus</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Runerigus&amp;diff=41066"/>
		<updated>2026-08-09T07:48:18Z</updated>

		<summary type="html">&lt;p&gt;Cae: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{PokemonInfoAndNav}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;{{PAGENAME}}&#039;&#039;&#039; is a [[Ground (type)|Ground]]- and [[Ghost (type)|Ghost]]-type Pokémon.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obtainability==&lt;br /&gt;
{{PokemonSpawnData}}&lt;br /&gt;
The primary way of obtaining a {{PAGENAME}} is by evolving a [[Galarian Yamask]].&lt;br /&gt;
&lt;br /&gt;
{{Learnsets|{{PAGENAME}}}}&lt;br /&gt;
&lt;br /&gt;
==Type Effectiveness==&lt;br /&gt;
{{PokemonTypeEffectiveness}}&lt;br /&gt;
&lt;br /&gt;
==Special Counterparts==&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Shiny_Runeriguss.png|Shiny Runerigus&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Runerigus&amp;diff=41065</id>
		<title>Runerigus</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Runerigus&amp;diff=41065"/>
		<updated>2026-08-09T07:46:51Z</updated>

		<summary type="html">&lt;p&gt;Cae: created page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{PokemonInfoAndNav}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;{{PAGENAME}}&#039;&#039;&#039; is a [[Ghost (type)|Ghost]] type Pokémon.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obtainability==&lt;br /&gt;
{{PokemonSpawnData}}&lt;br /&gt;
The primary way of obtaining a {{PAGENAME}} is by evolving a [[Galarian Yamask]].&lt;br /&gt;
&lt;br /&gt;
{{Learnsets|{{PAGENAME}}}}&lt;br /&gt;
&lt;br /&gt;
==Type Effectiveness==&lt;br /&gt;
{{PokemonTypeEffectiveness}}&lt;br /&gt;
&lt;br /&gt;
==Special Counterparts==&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Shiny_Runeriguss.png|Shiny Runerigus&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Cofagrigus&amp;diff=41064</id>
		<title>Cofagrigus</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Cofagrigus&amp;diff=41064"/>
		<updated>2026-08-09T07:44:02Z</updated>

		<summary type="html">&lt;p&gt;Cae: new nav and info&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{PokemonInfoAndNav}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;{{PAGENAME}}&#039;&#039;&#039; is a [[Ghost (type)|Ghost]] type Pokémon.&lt;br /&gt;
&lt;br /&gt;
It evolves from [[Yamask]] starting at level 34.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obtainability==&lt;br /&gt;
{{PokemonSpawnData}}&lt;br /&gt;
The primary way of obtaining a {{PAGENAME}} is by evolving a [[Yamask]].&lt;br /&gt;
&lt;br /&gt;
{{Learnsets|{{PAGENAME}}}}&lt;br /&gt;
&lt;br /&gt;
==Type Effectiveness==&lt;br /&gt;
{{PokemonTypeEffectiveness}}&lt;br /&gt;
&lt;br /&gt;
==Special Counterparts==&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Shiny_Cofagrigus.png|Shiny Cofragigus&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Wandering_Spirit_(ability)&amp;diff=41063</id>
		<title>Wandering Spirit (ability)</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Wandering_Spirit_(ability)&amp;diff=41063"/>
		<updated>2026-08-09T07:41:55Z</updated>

		<summary type="html">&lt;p&gt;Cae: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Wandering Spirit&#039;&#039;&#039; is one of the many [[Ability|abilities]] that are inheritable by Pokémon.&amp;lt;br&amp;gt;&lt;br /&gt;
It is the signature ability of [[Galarian Yamask]].&lt;br /&gt;
&lt;br /&gt;
==Function==&lt;br /&gt;
When a Pokémon with Wandering Spirit is hit by a contact move, it exchanges Abilities with the attacker. If a Pokémon affected by Wandering Spirit is switched out, it regains its original Ability.&lt;br /&gt;
&lt;br /&gt;
The Ability will trigger even if the Pokémon with Wandering Spirit faints from the attacking move.&lt;br /&gt;
&lt;br /&gt;
Wandering Spirit does not work on the following Abilities: As One, Battle Bond, Comatose, Commander, Disguise, Flower Gift, Forecast, Gulp Missile, Hunger Switch, Ice Face, Illusion, Imposter, Multitype, Neutralizing Gas, Power of Alchemy, Receiver, RKS System, Schooling, Shields Down, Stance Change, Wonder Guard, Zen Mode, and Zero to Hero. &lt;br /&gt;
&lt;br /&gt;
==Inheritable Pokémon==&lt;br /&gt;
===Predominant ability===&lt;br /&gt;
====Primary====&lt;br /&gt;
{{PrimaryAbilityList|Wandering Spirit|Theme=Ghost}}&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Wandering_Spirit_(ability)&amp;diff=41062</id>
		<title>Wandering Spirit (ability)</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Wandering_Spirit_(ability)&amp;diff=41062"/>
		<updated>2026-08-09T07:41:47Z</updated>

		<summary type="html">&lt;p&gt;Cae: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Wandering Spirit&#039;&#039;&#039; is one of the many [[Ability|abilities]] that are inheritable by Pokémon.&amp;lt;br&amp;gt;&lt;br /&gt;
It is the signature ability of [[Galarian Yamask]].&lt;br /&gt;
&lt;br /&gt;
==Function==&lt;br /&gt;
When a Pokémon with Wandering Spirit is hit by a contact move, it exchanges Abilities with the attacker. If a Pokémon affected by Wandering Spirit is switched out, it regains its original Ability.&lt;br /&gt;
&lt;br /&gt;
The Ability will trigger even if the Pokémon with Wandering Spirit faints from the attacking move.&lt;br /&gt;
&lt;br /&gt;
Wandering Spirit does not work on the following Abilities: As One, Battle Bond, Comatose, Commander, Disguise, Flower Gift, Forecast, Gulp Missile, Hunger Switch, Ice Face, Illusion, Imposter, Multitype, Neutralizing Gas, Power of Alchemy, Receiver, RKS System, Schooling, Shields Down, Stance Change, Wonder Guard, Zen Mode, and Zero to Hero. &lt;br /&gt;
&lt;br /&gt;
==Inheritable Pokémon==&lt;br /&gt;
===Predominant ability===&lt;br /&gt;
====Primary====&lt;br /&gt;
{{PrimaryAbilityList|Wandering Spirit|Theme=steel}}&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Galarian_Yamask&amp;diff=41061</id>
		<title>Galarian Yamask</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Galarian_Yamask&amp;diff=41061"/>
		<updated>2026-08-09T07:41:25Z</updated>

		<summary type="html">&lt;p&gt;Cae: created redirect&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT[[Yamask]]&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Wandering_Spirit_(ability)&amp;diff=41060</id>
		<title>Wandering Spirit (ability)</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Wandering_Spirit_(ability)&amp;diff=41060"/>
		<updated>2026-08-09T07:40:41Z</updated>

		<summary type="html">&lt;p&gt;Cae: created page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Wandering Spirit&#039;&#039;&#039; is one of the many [[Ability|abilities]] that are inheritable by Pokémon.&amp;lt;br&amp;gt;&lt;br /&gt;
It is the signature ability of [[Yamask|Galarian Yamask]].&lt;br /&gt;
&lt;br /&gt;
==Function==&lt;br /&gt;
When a Pokémon with Wandering Spirit is hit by a contact move, it exchanges Abilities with the attacker. If a Pokémon affected by Wandering Spirit is switched out, it regains its original Ability.&lt;br /&gt;
&lt;br /&gt;
The Ability will trigger even if the Pokémon with Wandering Spirit faints from the attacking move.&lt;br /&gt;
&lt;br /&gt;
Wandering Spirit does not work on the following Abilities: As One, Battle Bond, Comatose, Commander, Disguise, Flower Gift, Forecast, Gulp Missile, Hunger Switch, Ice Face, Illusion, Imposter, Multitype, Neutralizing Gas, Power of Alchemy, Receiver, RKS System, Schooling, Shields Down, Stance Change, Wonder Guard, Zen Mode, and Zero to Hero. &lt;br /&gt;
&lt;br /&gt;
==Inheritable Pokémon==&lt;br /&gt;
===Predominant ability===&lt;br /&gt;
====Primary====&lt;br /&gt;
{{PrimaryAbilityList|Wandering Spirit|Theme=steel}}&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Yamask&amp;diff=41059</id>
		<title>Yamask</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Yamask&amp;diff=41059"/>
		<updated>2026-08-09T07:36:47Z</updated>

		<summary type="html">&lt;p&gt;Cae: new nav and info&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{PokemonInfoAndNav}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;{{PAGENAME}}&#039;&#039;&#039; is a [[Ghost (type)|Ghost]] type Pokémon.&lt;br /&gt;
&lt;br /&gt;
It evolves into [[Cofagrigus]] upon reaching level 34.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obtainability==&lt;br /&gt;
{{PokemonSpawnData}}&lt;br /&gt;
&lt;br /&gt;
===[[Excavation]]===&lt;br /&gt;
{{PokemonExcavationSites|Contents=&lt;br /&gt;
{{PokemonExcavation|Site=Haunted|Levels=15-25|Rarity=Rare|Experience=2,000}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===[[Bosses]]===&lt;br /&gt;
*Possible reward from [[Morty (boss)|Morty]]&lt;br /&gt;
&lt;br /&gt;
{{Learnsets|{{PAGENAME}}}}&lt;br /&gt;
&lt;br /&gt;
==Type Effectiveness==&lt;br /&gt;
{{PokemonTypeEffectiveness}}&lt;br /&gt;
&lt;br /&gt;
==Special Counterparts==&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Shiny_Yamask.png|Shiny Yamask&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Pok%C3%A9mon_Counterparts&amp;diff=41058</id>
		<title>Pokémon Counterparts</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Pok%C3%A9mon_Counterparts&amp;diff=41058"/>
		<updated>2026-08-09T07:05:05Z</updated>

		<summary type="html">&lt;p&gt;Cae: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Pokémon counterparts are specially themed versions of Pokémon that can be encountered in the wild during special events. The only exception are Pink Forms which can be encountered on Pinkan Island during the entire year.&lt;br /&gt;
&lt;br /&gt;
Exactly like [[Chromas]], these counterparts do not improve the stats of the Pokemon; the differences are purely aesthetic.&lt;br /&gt;
&lt;br /&gt;
Shiny Pokémon are the only special counterparts available for every Pokémon. Event-specific counterparts are limited to certain Pokémon that are listed below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Shiny Pokémon==&lt;br /&gt;
[[File:Shiny_Pokemon_pip.png|right|thumb|400px|[[Golem]]&#039;s shiny-counterpart sprite in the Pokémon-card overlay.]]&lt;br /&gt;
&#039;&#039;&#039;Shiny Pokémon&#039;&#039;&#039;, also known by the &#039;&#039;&#039;shiny/shinies&#039;&#039;&#039; shortening, are the most prevalent counterpart in PRO. They are identifiable by their distinctive coloration in addition to the golden S emblem; see the image to the right for a pictorial illustration.&lt;br /&gt;
===Wild Encounters===&lt;br /&gt;
&lt;br /&gt;
For wild-Pokémon encounters, their odds are fractionally identical to those in the handheld games at 1/8192 (0.01220703125%).&lt;br /&gt;
&lt;br /&gt;
When hotlinked in the [[In-Game Chat|chat]], their link is purple-colored to differentiate it from their regular counterparts; for example, a shiny [[Pikachu]] would appear as &amp;lt;span style=&amp;quot;color: #b26ab7; font-weight: bold;&amp;quot;&amp;gt;&amp;lt;Pikachu&amp;gt;&amp;lt;/span&amp;gt; when hotlinked.&lt;br /&gt;
&lt;br /&gt;
Any wild-Pokémon battle initiated by an NPC script will &#039;&#039;&#039;not&#039;&#039;&#039; have a shiny chance; this includes even catchable Pokémon encountered via [[Headbutt Trees]], [[Diggable Patches]], [[Excavation Sites]](with the exception of the Shiny rock), and overworld-interactable Pokémon (such as the occlusive [[Snorlax]] on [[Route 12#Roadblocking Snorlax|Route 12]]).&lt;br /&gt;
&lt;br /&gt;
===NPC-Given Pokémon===&lt;br /&gt;
While the wild-battle-initiator used by NPC scripts has no shininess chance, Pokémon that are directly given by NPCs can still have chances if the RNGs are configured within the scripts for it; examples include [[fossilized Pokémon]] regenerated by the fossil-reanimators, some [[Boss NPCs|boss-prize]] Pokémon, and [[abandoned Pokémon]].&lt;br /&gt;
&lt;br /&gt;
Because these Pokémon are given much more infrequently than wild Pokémon are encountered, they tend to have varyingly lower shiny-chance odds than the standard 1/8192 rate of wild Pokémon.&lt;br /&gt;
&lt;br /&gt;
===Legendary Pokémon===&lt;br /&gt;
&lt;br /&gt;
Contemporaneously, all of the obtainable legendary Pokémon are shiny locked. Thus, legendary Pokémon would not be viewable in their shiny forms.&lt;br /&gt;
&lt;br /&gt;
==Pink Pokémon==&lt;br /&gt;
{{Main|Pinkan Island}}&lt;br /&gt;
&lt;br /&gt;
With the advent of [[Pinkan Island]]—one of the [[Orange Islands]] that was released as a standalone content addition—a bevy of Pokémon were pinkified new counterparts as a nod to those who inhabited the [http://bulbapedia.bulbagarden.net/wiki/Pinkan_Island aforementioned area in the anime].&lt;br /&gt;
&lt;br /&gt;
Every Pokémon inhabitant on the island and evolutions thereof has a pink counterpart; there is a 1/1,500 chance of encountering them in the wild. All of such inhabitants are assorted in the collage below, among a few others that have not yet been made huntable.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Pink_Caterpie.png|[[Caterpie]]&lt;br /&gt;
File:Pink_Metapod.png|[[Metapod]]&lt;br /&gt;
File:Pink_Butterfree.png|[[Butterfree]]&lt;br /&gt;
File:Pink_Weedle.png|[[Weedle]]&lt;br /&gt;
File:Pink_Kakuna.png|[[Kakuna]]&lt;br /&gt;
File:Pink_Beedrill.png|[[Beedrill]]&lt;br /&gt;
File:PinkanBeedrill_Mega.png|Pinkan Mega [[Beedrill]]&lt;br /&gt;
File:Pink_Pidgey.png|[[Pidgey]]&lt;br /&gt;
File:Pink_Pidgeotto.png|[[Pidgeotto]]&lt;br /&gt;
File:Pink_Pidgeot.png|[[Pidgeot]]&lt;br /&gt;
File:PinkanPidgeot_Mega.png|Pinkan Mega [[Pidgeot]]&lt;br /&gt;
File:Pink_Rattata.png|[[Rattata]]&lt;br /&gt;
File:Pink_Raticate.png|[[Raticate]]&lt;br /&gt;
File:Pink_Pichu.png|[[Pichu]]&lt;br /&gt;
File:Pink_Pikachu.png|[[Pikachu]]&lt;br /&gt;
File:Pink_Raichu.png|[[Raichu]]&lt;br /&gt;
File:Pink_Nidoran Female.png|[[Nidoran Female]]&lt;br /&gt;
File:Pink_Nidorina.png|[[Nidorina]]&lt;br /&gt;
File:Pink_Nidoqueen.png|[[Nidoqueen]]&lt;br /&gt;
File:Pink_Nidoran_Male.png|[[Nidoran Male]]&lt;br /&gt;
File:Pink_Nidorino.png|[[Nidorino]]&lt;br /&gt;
File:Pink_Nidoking.png|[[Nidoking]]&lt;br /&gt;
File:Pink_Vulpix.png|[[Vulpix]]&lt;br /&gt;
File:Pink_Ninetales.png|[[Ninetales]]&lt;br /&gt;
File:Pink_Oddish.png|[[Oddish]]&lt;br /&gt;
File:Pink_Gloom.png|[[Gloom]]&lt;br /&gt;
File:Pink_Vileplume.png|[[Vileplume]]&lt;br /&gt;
File:Pink_Bellossom.png|[[Bellossom]]&lt;br /&gt;
File:Pink_Paras.png|[[Paras]]&lt;br /&gt;
File:Pink_Parasect.png|[[Parasect]]&lt;br /&gt;
File:Pink_Venonat.png|[[Venonat]]&lt;br /&gt;
File:Pink_Venomoth.png|[[Venomoth]]&lt;br /&gt;
File:Pink_Diglett.png|[[Diglett]]&lt;br /&gt;
File:Pink_Dugtrio.png|[[Dugtrio]]&lt;br /&gt;
File:Pink_Psyduck.png|[[Psyduck]]&lt;br /&gt;
File:Pink_Golduck.png|[[Golduck]]&lt;br /&gt;
File:Pink_Mankey.png|[[Mankey]]&lt;br /&gt;
File:Pink_Primeape.png|[[Primeape]]&lt;br /&gt;
File:979_1.png|[[Annihilape]]&lt;br /&gt;
File:Pink_Poliwag.png|[[Poliwag]]&lt;br /&gt;
File:Pink_Poliwhirl.png|[[Poliwhirl]]&lt;br /&gt;
File:Pink_Poliwrath.png|[[Poliwrath]]&lt;br /&gt;
File:Pink_Politoed.png|[[Politoed]]&lt;br /&gt;
File:Pink_Bellsprout.png|[[Bellsprout]]&lt;br /&gt;
File:Pink_Weepinbell.png|[[Weepinbell]]&lt;br /&gt;
File:Pink_Victreebel.png|[[Victreebel]]&lt;br /&gt;
File:Pink_Doduo.png|[[Doduo]]&lt;br /&gt;
File:Pink_Dodrio.png|[[Dodrio]]&lt;br /&gt;
File:Pink_Seel.png|[[Seel]]&lt;br /&gt;
File:Pink_Dewgong.png|[[Dewgong]]&lt;br /&gt;
File:Pink_Shellder.png|[[Shellder]]&lt;br /&gt;
File:Pink_Cloyster.png|[[Cloyster]]&lt;br /&gt;
File:Pink_Krabby.png|[[Krabby]]&lt;br /&gt;
File:Pink_Kingler.png|[[Kingler]]&lt;br /&gt;
File:Pink_Exeggcute.png|[[Exeggcute]]&lt;br /&gt;
File:Pink_Exeggutor.png|[[Exeggutor]]&lt;br /&gt;
File:Pink_Rhyhorn.png|[[Rhyhorn]]&lt;br /&gt;
File:Pink_Rhydon.png|[[Rhydon]]&lt;br /&gt;
File:Pink_Rhyperior.png|[[Rhyperior]]&lt;br /&gt;
File:Pink_Tangela.png|[[Tangela]]&lt;br /&gt;
File:Pink_Tangrowth.png|[[Tangrowth]]&lt;br /&gt;
File:Pink_Staryu.png|[[Staryu]]&lt;br /&gt;
File:Pink_Starmie.png|[[Starmie]]&lt;br /&gt;
File:Pink_Scyther.png|[[Scyther]]&lt;br /&gt;
File:Pink_Scizor.png|[[Scizor]]&lt;br /&gt;
File:Pinkan_Mega_Scizor.png| Mega [[Scizor]]&lt;br /&gt;
File:900_1.png|[[Kleavor]]&lt;br /&gt;
File:Pink_Elekid.png|[[Elekid]]&lt;br /&gt;
File:Pink_Electabuzz.png|[[Electabuzz]]&lt;br /&gt;
File:Pink_Electivire.png|[[Electivire]]&lt;br /&gt;
File:Pink_Magikarp.png|[[Magikarp]]&lt;br /&gt;
File:Pink_Gyarados.png|[[Gyarados]]&lt;br /&gt;
File:PinkanGyarados_Mega.png|Pinkan Mega [[Gyarados]]&lt;br /&gt;
File:Pink_Lapras.png|[[Lapras]]&lt;br /&gt;
File:Pink_Munchlax.png|[[Munchlax]]&lt;br /&gt;
File:Pink_Snorlax.png|[[Snorlax]]&lt;br /&gt;
File:Pink_Chikorita.png|[[Chikorita]]&lt;br /&gt;
File:Pink_Bayleef.png|[[Bayleef]]&lt;br /&gt;
File:Pink_Meganium.png|[[Meganium]]&lt;br /&gt;
File:Pink_Totodile.png|[[Totodile]]&lt;br /&gt;
File:Pink_Croconaw.png|[[Croconaw]]&lt;br /&gt;
File:Pink_Feraligatr.png|[[Feraligatr]]&lt;br /&gt;
File:Pink_Natu.png|[[Natu]]&lt;br /&gt;
File:Pink_Xatu.png|[[Xatu]]&lt;br /&gt;
File:Pink_Azurill.png|[[Azurill]]&lt;br /&gt;
File:Pink_Marill.png|[[Marill]]&lt;br /&gt;
File:Pink_Azumarill.png|[[Azumarill]]&lt;br /&gt;
File:Pink_Phanpy.png|[[Phanpy]]&lt;br /&gt;
File:Pink_Donphan.png|[[Donphan]]&lt;br /&gt;
File:Pink_Smeargle.png|[[Smeargle]]&lt;br /&gt;
File:Pink_Wingull.png|[[Wingull]]&lt;br /&gt;
File:Pink_Pelipper.png|[[Pelipper]]&lt;br /&gt;
File:Pink_Ralts.png|[[Ralts]]&lt;br /&gt;
File:Pink_Kirlia.png|[[Kirlia]]&lt;br /&gt;
File:Pink_Gardevoir.png|[[Gardevoir]]&lt;br /&gt;
File:PinkanGardevoir_Mega.png|Pinkan Mega [[Gardevoir]] &lt;br /&gt;
File:Pink_Gallade.png|[[Gallade]]&lt;br /&gt;
File:PinkanGallade_Mega.png|Pinkan Mega [[Gallade]] &lt;br /&gt;
File:Pink_Plusle.png|[[Plusle]]&lt;br /&gt;
File:Pink_Minun.png|[[Minun]]&lt;br /&gt;
File:Pink_Zangoose.png|[[Zangoose]]&lt;br /&gt;
File:Pink_Barboach.png|[[Barboach]]&lt;br /&gt;
File:Pink_Whiscash.png|[[Whiscash]]&lt;br /&gt;
File:Pink_Tropius.png|[[Tropius]]&lt;br /&gt;
File:Pink_Cottonee.png|[[Cottonee]]&lt;br /&gt;
File:Pink_Whimsicott.png|[[Whimsicott]]&lt;br /&gt;
File:Pink_Pancham.png|[[Pancham]]&lt;br /&gt;
File:Pink_Pangoro.png|[[Pangoro]]&lt;br /&gt;
File:Pink_Hawlucha.png|[[Hawlucha]]&lt;br /&gt;
File:981_1.png|[[Farigiraf]]&lt;br /&gt;
File:3228_2.png|Hisuian [[Typhlosion]]&lt;br /&gt;
File:3231_3.png|Hisuian [[Samurott]]&lt;br /&gt;
File:3232_4.png|[[Lilligant]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Shadow Pokémon==&lt;br /&gt;
{{Main|Dungeons}}&lt;br /&gt;
&lt;br /&gt;
Dungeons are co-op style areas designed to be cleared by a group of players. The PVE Ladder&#039;s Top 3 guild get access to the Dungeon Nesting Grounds for a limited time to hunt Shadow Pokémon:&lt;br /&gt;
* [[Forlorn Nesting Grounds]]&lt;br /&gt;
* [[Ruins of the Vale Nesting Grounds]]&lt;br /&gt;
* [[Crux of Melody Nesting Grounds]]&lt;br /&gt;
* [[Scattered Realm Nesting Grounds]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Ekans_shadow.png|Shadow [[Ekans]]&lt;br /&gt;
File:Arbok_shadow.png|Shadow [[Arbok]]&lt;br /&gt;
File:Abra_shadow.png|Shadow [[Abra]]&lt;br /&gt;
File:Kadabra_shadow.png|Shadow [[Kadabra]]&lt;br /&gt;
File:Alakazam_shadow.png|Shadow [[Alakazam]]&lt;br /&gt;
File:Alakazam_mega_shadow.png|Shadow Mega [[Alakazam]]&lt;br /&gt;
File:Slowpoke_shadow.png|Shadow [[Slowpoke]]&lt;br /&gt;
File:Slowbro_shadow.png|Shadow [[Slowbro]]&lt;br /&gt;
File:Slowbro_mega_shadow.png|Shadow Mega [[Slowbro]]&lt;br /&gt;
File:Slowking_shadow.png|Shadow [[Slowking]]&lt;br /&gt;
File:Houndour_shadow.png|Shadow [[Houndour]]&lt;br /&gt;
File:Houndoom_shadow.png|Shadow [[Houndoom]]&lt;br /&gt;
File:Houndoom_mega_shadow.png|Shadow Mega [[Houndoom]]&lt;br /&gt;
File:Treecko_shadow.png|Shadow [[Treecko]]&lt;br /&gt;
File:Grovyle_shadow.png|Shadow [[Grovyle]]&lt;br /&gt;
File:Sceptile_shadow.png|Shadow [[Sceptile]]&lt;br /&gt;
File:Sceptile_mega_shadow.png|Shadow Mega [[Sceptile]]&lt;br /&gt;
File:Taillow_shadow.png|Shadow [[Taillow]]&lt;br /&gt;
File:Swellow_shadow.png|Shadow [[Swellow]]&lt;br /&gt;
File:Carvanha_shadow.png|Shadow [[Carvanha]]&lt;br /&gt;
File:Sharpedo_shadow.png|Shadow [[Sharpedo]]&lt;br /&gt;
File:Sharpedo_mega_shadow.png|Shadow Mega [[Sharpedo]]&lt;br /&gt;
File:Numel_shadow.png|Shadow [[Numel]]&lt;br /&gt;
File:Camerupt_shadow.png|Shadow [[Camerupt]]&lt;br /&gt;
File:Camerupt_mega_shadow.png|Shadow Mega [[Camerupt]]&lt;br /&gt;
File:Swablu_shadow.png|Shadow [[Swablu]]&lt;br /&gt;
File:Altaria_shadow.png|Shadow [[Altaria]]&lt;br /&gt;
File:Altaria_mega_shadow.png|Shadow Mega [[Altaria]]&lt;br /&gt;
File:Bagon_shadow.png|Shadow [[Bagon]]&lt;br /&gt;
File:Shelgon_shadow.png|Shadow [[Shelgon]]&lt;br /&gt;
File:Salamence_shadow.png|Shadow [[Salamence]]&lt;br /&gt;
File:Salamence_mega_shadow.png|Shadow Mega [[Salamence]]&lt;br /&gt;
File:Beldum_shadow.png|Shadow [[Beldum]]&lt;br /&gt;
File:Metang_shadow.png|Shadow [[Metang]]&lt;br /&gt;
File:Metagross_shadow.png|Shadow [[Metagross]]&lt;br /&gt;
File:Metagross_mega_shadow.png|Shadow Mega [[Metagross]]&lt;br /&gt;
File:Budew_shadow.png|Shadow [[Budew]]&lt;br /&gt;
File:Roselia_shadow.png|Shadow [[Roselia]]&lt;br /&gt;
File:Roserade_shadow.png|Shadow [[Roserade]]&lt;br /&gt;
File:Axew_shadow.png|Shadow [[Axew]]&lt;br /&gt;
File:Fraxure_shadow.png|Shadow [[Fraxure]]&lt;br /&gt;
File:Haxorus_shadow.png|Shadow [[Haxorus]]&lt;br /&gt;
File:Deino_shadow.png|Shadow [[Deino]]&lt;br /&gt;
File:Zweilous_shadow.png|Shadow [[Zweilous]]&lt;br /&gt;
File:Hydreigon_shadow.png|Shadow [[Hydreigon]]&lt;br /&gt;
File:Larvesta_shadow.png|Shadow [[Larvesta]]&lt;br /&gt;
File:Larvesta_shadow2.png|Green Shadow [[Larvesta]]&lt;br /&gt;
File:Volcarona_shadow.png|Shadow [[Volcarona]]&lt;br /&gt;
File:Volcarona_shadow2.png|Green Shadow [[Volcarona]]&lt;br /&gt;
File:Noibat_shadow.png|Shadow [[Noibat]]&lt;br /&gt;
File:Noivern_shadow.png|Shadow [[Noivern]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Event-Temporary Pokémon==&lt;br /&gt;
Occasionally, specially themed counterparts have been made available for Pokémon to help saturate event-exclusive Pokémon—typically for a select assortment of Pokémon that tally to the nature of the event. While they have never been made encounterable outside of the event, all Pokémon obtained during them were retainable by the players and thus those that remained in circulation were considered collectible commodities among traders.&lt;br /&gt;
&lt;br /&gt;
Do note that these versions have &#039;&#039;&#039;no&#039;&#039;&#039; shiny-counterpart versions; shininess is a discrete chance from these versions in the RNG calculations and thus they are mutually exclusive. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Starter Clones===&lt;br /&gt;
In August of 2016, starter-clone counterparts were introduced for each Pokémon in the evolutionary line of [[Bulbasaur]], [[Charmander]], and [[Squirtle]] as an anniversary-commemoratory event—approximately one year removed from its release into the Beta stage on August 14, 2016. While the event was abruptly discontinued later that month due to various technical difficulties, it was reintroduced on November 14, 2016, as a consolatory event due to the Halloween event&#039;s cancellation that year.&lt;br /&gt;
&lt;br /&gt;
Clone Pokémon are colorated in accordance to those that were created and deployed in the [http://bulbapedia.bulbagarden.net/wiki/M01 Pokémon: The First Movie - Mewtwo Strikes Back].&lt;br /&gt;
&lt;br /&gt;
There was a 1/20 (5%) chance of encountering these counterparts of wild [[starter Pokémon]]. Do note that this is &#039;&#039;&#039;not&#039;&#039;&#039; applicable to starter Pokémon given to regional newcomers in the lab; they have no special-counterpart chances altogether. Nowadays, Clone Pokémon are bundled into the Halloween event.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Clone_Bulbasaur.png|Clone [[Bulbasaur]]&lt;br /&gt;
File:Clone_Ivysaur.png|Clone [[Ivysaur]]&lt;br /&gt;
File:Clone_Venusaur.png|Clone [[Venusaur]]&lt;br /&gt;
File:CloneVenusaur_Mega.png|Clone Mega [[Venusaur]]&lt;br /&gt;
File:Clone_Charmander.png|Clone [[Charmander]]&lt;br /&gt;
File:Clone_Charmeleon.png|Clone [[Charmeleon]]&lt;br /&gt;
File:Clone_Charizard.png|Clone [[Charizard]]&lt;br /&gt;
File:CloneCharizardX_Mega.png|Clone Mega [[Charizard]] X&lt;br /&gt;
File:CloneCharizardY_Mega.png|Clone Mega [[Charizard]] Y&lt;br /&gt;
File:Clone_Squirtle.png|Clone [[Squirtle]]&lt;br /&gt;
File:Clone_Wartortle.png|Clone [[Wartortle]]&lt;br /&gt;
File:Clone_Blastoise.png|Clone [[Blastoise]]&lt;br /&gt;
File:CloneBlastoise_Mega.png|Clone Mega [[Blastoise]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Valentine&#039;s Day-themed Pokémon===&lt;br /&gt;
====Valentine&#039;s Day Event 2018====&lt;br /&gt;
For the 2018 Valentine&#039;s Day event, specially accessorized and/or colorated Pokémon versions were released for [[Nidoran Male]], [[Nidoran Female]], [[Illumise]] and [[Volbeat]]. There was a 1/550 chance of encountering these counterparts in the wild.&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Valentine_NidoranF.png|Valentine [[Nidoran Female]]&lt;br /&gt;
File:Valentine_Nidorina.png|Valentine [[Nidorina]]&lt;br /&gt;
File:Valentine_Nidoqueen.png|Valentine [[Nidoqueen]]&lt;br /&gt;
File:Valentine_NidoranM.png|Valentine [[Nidoran Male]]&lt;br /&gt;
File:Valentine_Nidorino.png|Valentine [[Nidorino]]&lt;br /&gt;
File:Valentine_Nidoking.png|Valentine [[Nidoking]]&lt;br /&gt;
File:Valentine_Illumise.png|Valentine [[Illumise]]&lt;br /&gt;
File:Valentine_Volbeat.png|Valentine [[Volbeat]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Valentine&#039;s Day Event 2019====&lt;br /&gt;
For the [https://pokemonrevolution.net/forum/index.php?threads/love-is-fickle.118452/ 2019 Valentine&#039;s Day Event], specially accessorized and/or colorated Pokémon versions were released for [[Alomomola]], [[Frillish]], [[Jellicent]], [[Luvdisc]], [[Minun]], [[Plusle]], [[Sawk]], [[Throh]], [[Budew]], [[Roselia]] and [[Roserade]]. There was a 1/550 chance of encountering these counterparts in the wild. &lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Valentine Pikachu.png|Valentine [[Pikachu]]&lt;br /&gt;
File:Valentine Raichu.png|Valentine [[Raichu]]&lt;br /&gt;
File:Valentine Spearow.png|Valentine [[Spearow]]&lt;br /&gt;
File:Valentine Fearow.png|Valentine [[Fearow]]&lt;br /&gt;
File:Valentine Plusle.png|Valentine [[Plusle]]&lt;br /&gt;
File:Valentine Minun.png|Valentine [[Minun]]&lt;br /&gt;
File:Valentine Luvdisc.png|Valentine [[Luvdisc]]&lt;br /&gt;
File:Valentine Budew.png|Valentine [[Budew]]&lt;br /&gt;
File:Valentine Roselia.png|Valentine [[Roselia]]&lt;br /&gt;
File:Valentine Roserade.png|Valentine [[Roserade]]&lt;br /&gt;
File:Valentine Throh.png|Valentine [[Throh]]&lt;br /&gt;
File:Valentine Throh 2.png|Valentine [[Throh]]&lt;br /&gt;
File:Valentine Throh 3.png|Valentine [[Throh]]&lt;br /&gt;
File:Valentine Sawk.png|Valentine [[Sawk]]&lt;br /&gt;
File:Valentine Sawk 2.png|Valentine [[Sawk]]&lt;br /&gt;
File:Valentine Sawk 3.png|Valentine [[Sawk]]&lt;br /&gt;
File:Valentine Alomomola.png|Valentine [[Alomomola]]&lt;br /&gt;
File:Valentine Female Frillish.png|Valentine [[Frillish]] Female&lt;br /&gt;
File:Valentine Female Jellicent.png|Valentine [[Jellicent]] Female&lt;br /&gt;
File:Valentine Male Frillish.png|Valentine [[Frillish]] Male&lt;br /&gt;
File:Valentine Male Jellicent.png|Valentine [[Jellicent]] Male&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Valentine&#039;s Day Event 2020====&lt;br /&gt;
For the 2020 Valentine&#039;s Day event, specially accessorized and/or colorated Pokémon versions were released for [[Cleffa]], [[Clefairy]] and [[Clefable]] and the other Valentine&#039;s Day sprites from previous years were also huntable. The chance of encountering these counterparts in the wild was not revealed.&lt;br /&gt;
The form was redesigned for the 2026 Valentine’s Event.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:173_1.png|Valentine [[Cleffa]]&lt;br /&gt;
File:35_1.png|Valentine [[Clefairy]]&lt;br /&gt;
File:36_1.png|Valentine [[Clefable]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Valentine&#039;s Day Event 2021====&lt;br /&gt;
For the 2021 Valentine&#039;s Day event, specially accessorized and/or colorated Pokémon versions were released for 25 different Pokémon and the other Valentine&#039;s Day sprites from previous years were also huntable. The chance of encountering these counterparts in the wild was not revealed.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Valentine Vulpix.png|Valentine [[Vulpix]]&lt;br /&gt;
File:Valentine Ninetales.png|Valentine [[Ninetales]]&lt;br /&gt;
File:Valentine Vulpix Alolan.png|Valentine [[Alolan Vulpix]]&lt;br /&gt;
File:Valentine Ninetales Alolan.png|Valentine [[Alolan Ninetales]]&lt;br /&gt;
File:Valentine Poliwag.png|Valentine [[Poliwag]]&lt;br /&gt;
File:Valentine Poliwhirl.png|Valentine [[Poliwhirl]]&lt;br /&gt;
File:Valentine Poliwrath.png|Valentine [[Poliwrath]]&lt;br /&gt;
File:Valentine Politoed.png|Valentine [[Politoed]]&lt;br /&gt;
File:Valentine Slowpoke.png|Valentine [[Slowpoke]]&lt;br /&gt;
File:Valentine Slowbro.png|Valentine [[Slowbro]]&lt;br /&gt;
File:ValentineSlowbro_Mega.png|Valentine Mega [[Slowbro]]&lt;br /&gt;
File:Valentine Seel.png|Valentine [[Seel]]&lt;br /&gt;
File:Valentine Dewgong.png|Valentine [[Dewgong]]&lt;br /&gt;
File:Valentine Lapras.png|Valentine [[Lapras]]&lt;br /&gt;
File:Valentine Slowking.png|Valentine [[Slowking]]&lt;br /&gt;
File:Valentine Lotad.png|Valentine [[Lotad]]&lt;br /&gt;
File:Valentine Lombre.png|Valentine [[Lombre]]&lt;br /&gt;
File:Valentine Ludicolo.png|Valentine [[Ludicolo]]&lt;br /&gt;
File:Valentine Bagon.png|Valentine [[Bagon]]&lt;br /&gt;
File:Valentine Shelgon.png|Valentine [[Shelgon]]&lt;br /&gt;
File:Valentine Salamence.png|Valentine [[Salamence]]&lt;br /&gt;
File:ValentineSalamence_Mega.png|Valentine Mega [[Salamence]]&lt;br /&gt;
File:Valentine Drifloon.png|Valentine [[Drifloon]]&lt;br /&gt;
File:Valentine Drifblim.png|Valentine [[Drifblim]]&lt;br /&gt;
File:Valentine Komala.png|Valentine [[Komala]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Valentine&#039;s Day Event 2022====&lt;br /&gt;
2022&#039;s batch of new Valentine&#039;s-themed Pokémon included 26 new forms of the [[Ralts]] family (including [[Kirlia]], [[Gallade]], [[Gardevoir]], and Mega Evolutions thereof), which were altered by what [[Pokéball]]s the trainer used to capture it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:495_2.png|Valentine [[Snivy]]&lt;br /&gt;
File:496_2.png|Valentine [[Servine]]&lt;br /&gt;
File:497_2.png|Valentine [[Serperior]]&lt;br /&gt;
File:Valentine Shuckle.png|Valentine [[Shuckle]]&lt;br /&gt;
File:Valentine Magnemite.png|Valentine [[Magnemite]]&lt;br /&gt;
File:Valentine Magneton.png|Valentine [[Magneton]]&lt;br /&gt;
File:Valentine Magnezone.png|Valentine [[Magnezone]]&lt;br /&gt;
File:Valentine Corsola.png|Valentine [[Corsola]]&lt;br /&gt;
File:Valentine Chinchou.png|Valentine [[Chinchou]]&lt;br /&gt;
File:Valentine Lanturn.png|Valentine [[Lanturn]]&lt;br /&gt;
File:Valentine God.png|Valentine [[Bidoof]]&lt;br /&gt;
File:Valentine Bibarel.png|Valentine [[Bibarel]]&lt;br /&gt;
File:Valentine Ralts.png|Valentine [[Ralts]]&lt;br /&gt;
File:Valentine Kirlia.png|Valentine [[Kirlia]]&lt;br /&gt;
File:Valentine Gallade.png|Valentine [[Gallade]]&lt;br /&gt;
File:Valentine&#039;s_Day_Mega_Gallade.png|Valentine Mega [[Gallade]]&lt;br /&gt;
File:Valentine Gardevoir.png|Valentine [[Gardevoir]]&lt;br /&gt;
File:Valentine&#039;s_Day_Mega_Gardevoir.png|Valentine Mega [[Gardevoir]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Valentine&#039;s Day Event 2023====&lt;br /&gt;
2023’s iteration of the Valentine’s Day event included new forms for [[Starly]], [[Shroomish]], [[Goomy]] and their evolutions.&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Valentine Starly.png|Valentine [[Starly]]&lt;br /&gt;
File:Valentine Staravia.png|Valentine [[Staravia]]&lt;br /&gt;
File:Valentine Staraptor.png|Valentine [[Staraptor]]&lt;br /&gt;
File:Valentine Shroomish.png|Valentine [[Shroomish]]&lt;br /&gt;
File:Valentine Breloom.png|Valentine [[Breloom]]&lt;br /&gt;
File:Valentine Goomy.png|Valentine [[Goomy]]&lt;br /&gt;
File:Valentine Sliggoo.png|Valentine [[Sliggoo]]&lt;br /&gt;
File:Valentine Goodra.png|Valentine [[Goodra]]&lt;br /&gt;
File:3236_2.png|Valentine Hisuian [[Sliggoo]]&lt;br /&gt;
File:3237_2.png|Valentine Hisuian [[Goodra]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Valentine&#039;s Day Event 2024====&lt;br /&gt;
During Valentine 2024, a total of &#039;&#039;&#039;96&#039;&#039;&#039; Pokémon were given a Valentine counterpart and 3 Pokémon family&#039;s sprites were reworked. Those being: [[Bagon]], [[Goomy]], [[Magnemite]], and all their evolutions.&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:54 3.png|Valentine [[Psyduck]]&lt;br /&gt;
File:55_3.png|Valentine [[Golduck]]&lt;br /&gt;
File:440_2.png|Valentine [[Happiny]]&lt;br /&gt;
File:113_2.png|Valentine [[Chansey]]&lt;br /&gt;
File:242_2.png|Valentine [[Blissey]]&lt;br /&gt;
File:133_4.png|Valentine [[Eevee]]&lt;br /&gt;
File:134_4.png|Valentine [[Vaporeon]]&lt;br /&gt;
File:135_4.png|Valentine [[Jolteon]]&lt;br /&gt;
File:136_4.png|Valentine [[Flareon]]&lt;br /&gt;
File:196_4.png|Valentine [[Espeon]]&lt;br /&gt;
File:197_4.png|Valentine [[Umbreon]]&lt;br /&gt;
File:470_4.png|Valentine [[Leafeon]]&lt;br /&gt;
File:471_4.png|Valentine [[Glaceon]]&lt;br /&gt;
File:700_4.png|Valentine [[Sylveon]]&lt;br /&gt;
File:147_2.png|Valentine [[Dratini]]&lt;br /&gt;
File:148_2.png|Valentine [[Dragonair]]&lt;br /&gt;
File:149_2.png|Valentine [[Dragonite]]&lt;br /&gt;
File:149_2f.png|Valentine Female [[Dragonite]]&lt;br /&gt;
File:177_3.png|Valentine [[Natu]]&lt;br /&gt;
File:178_3.png|Valentine [[Xatu]]&lt;br /&gt;
File:177_3f.png|Valentine Female [[Natu]]&lt;br /&gt;
File:178_3f.png|Valentine Female [[Xatu]]&lt;br /&gt;
File:191_1.png|Valentine [[Sunkern]]&lt;br /&gt;
File:192_1.png|Valentine [[Sunflora]]&lt;br /&gt;
File:198_1.png|Valentine [[Murkrow]]&lt;br /&gt;
File:430_1.png|Valentine [[Honchkrow]]&lt;br /&gt;
File:198_1f.png|Valentine Female [[Murkrow]]&lt;br /&gt;
File:430_1f.png|Valentine Female [[Honchkrow]]&lt;br /&gt;
File:214_1.png|Valentine [[Heracross]]&lt;br /&gt;
File:3014_1.png|Valentine Mega [[Heracross]]&lt;br /&gt;
File:214_1f.png|Valentine Female [[Heracross]]&lt;br /&gt;
File:3014_1f.png|Valentine Female Mega [[Heracross]]&lt;br /&gt;
File:216_3.png|Valentine [[Teddiursa]]&lt;br /&gt;
File:216_4.png|Valentine [[Teddiursa]]&lt;br /&gt;
File:216_5.png|Valentine [[Teddiursa]]&lt;br /&gt;
File:216_6.png|Valentine [[Teddiursa]]&lt;br /&gt;
File:216_7.png|Valentine [[Teddiursa]]&lt;br /&gt;
File:216_8.png|Valentine [[Teddiursa]]&lt;br /&gt;
File:216_9.png|Valentine [[Teddiursa]]&lt;br /&gt;
File:216_10.png|Valentine [[Teddiursa]]&lt;br /&gt;
File:216_11.png|Valentine [[Teddiursa]]&lt;br /&gt;
File:216_12.png|Valentine [[Teddiursa]]&lt;br /&gt;
File:231_2.png|Valentine [[Phanpy]]&lt;br /&gt;
File:232_2.png|Valentine [[Donphan]]&lt;br /&gt;
File:232_2f.png|Valentine Female [[Donphan]]&lt;br /&gt;
File:235_5.png|Valentine [[Smeargle]]&lt;br /&gt;
File:255_2.png|Valentine [[Torchic]]&lt;br /&gt;
File:256_2.png|Valentine [[Combusken]]&lt;br /&gt;
File:257_2.png|Valentine [[Blaziken]]&lt;br /&gt;
File:3017_2.png|Valentine Mega [[Blaziken]]&lt;br /&gt;
File:255_2f.png|Valentine Female [[Torchic]]&lt;br /&gt;
File:256_2f.png|Valentine Female [[Combusken]]&lt;br /&gt;
File:257_2f.png|Valentine Female [[Blaziken]]&lt;br /&gt;
File:3017_2f.png|Valentine Female Mega [[Blaziken]]&lt;br /&gt;
File:258_2.png|Valentine [[Mudkip]]&lt;br /&gt;
File:259_2.png|Valentine [[Marshtomp]]&lt;br /&gt;
File:260_2.png|Valentine [[Swampert]]&lt;br /&gt;
File:3033_2.png|Valentine Mega [[Swampert]]&lt;br /&gt;
File:328_1.png|Valentine [[Trapinch]]&lt;br /&gt;
File:329_1.png|Valentine [[Vibrava]]&lt;br /&gt;
File:330_1.png|Valentine [[Flygon]]&lt;br /&gt;
File:353_1.png|Valentine [[Shuppet]]&lt;br /&gt;
File:354_1.png|Valentine [[Banette]]&lt;br /&gt;
File:3023_1.png|Valentine Mega [[Banette]]&lt;br /&gt;
File:433Front.png|Valentine [[Chingling]]&lt;br /&gt;
File:358Front.png|Valentine [[Chimecho]]&lt;br /&gt;
File:403_1.png|Valentine [[Shinx]]&lt;br /&gt;
File:404_1.png|Valentine [[Luxio]]&lt;br /&gt;
File:405_1.png|Valentine [[Luxray]]&lt;br /&gt;
File:403_1f.png|Valentine Female [[Shinx]]&lt;br /&gt;
File:404_1f.png|Valentine Female [[Luxio]]&lt;br /&gt;
File:405_1f.png|Valentine Female [[Luxray]]&lt;br /&gt;
File:449_1.png|Valentine [[Hippopotas]]&lt;br /&gt;
File:450_1.png|Valentine [[Hippowdon]]&lt;br /&gt;
File:449_1f.png|Valentine Female [[Hippopotas]]&lt;br /&gt;
File:450_1f.png|Valentine Female [[Hippowdon]]&lt;br /&gt;
File:517_1.png|Valentine [[Munna]]&lt;br /&gt;
File:518_1.png|Valentine [[Musharna]]&lt;br /&gt;
File:517_1f.png|Valentine Female [[Munna]]&lt;br /&gt;
File:518_1f.png|Valentine Female [[Musharna]]&lt;br /&gt;
File:540_2.png|Valentine [[Sewaddle]]&lt;br /&gt;
File:541_2.png|Valentine [[Swadloon]]&lt;br /&gt;
File:542_2.png|Valentine [[Leavanny]]&lt;br /&gt;
File:577_4.png|Valentine [[Solosis]]&lt;br /&gt;
File:578_4.png|Valentine [[Duosion]]&lt;br /&gt;
File:579_4.png|Valentine [[Reuniclus]]&lt;br /&gt;
File:627_1.png|Valentine [[Rufflet]]&lt;br /&gt;
File:628_1new.png|Valentine [[Braviary]]&lt;br /&gt;
File:3235_1.png|Valentine Hisuian [[Braviary]]&lt;br /&gt;
File:667_1.png|Valentine [[Litleo]]&lt;br /&gt;
File:667_1f.png|Valentine Female [[Litleo]]&lt;br /&gt;
File:668_1.png|Valentine [[Pyroar]]&lt;br /&gt;
File:668_1f.png|Valentine Female [[Pyroar]]&lt;br /&gt;
File:684_1.png|Valentine [[Swirlix]]&lt;br /&gt;
File:685_1.png|Valentine [[Slurpuff]]&lt;br /&gt;
File:702_2.png|Valentine [[Dedenne]]&lt;br /&gt;
File:702_2f.png|Valentine Female [[Dedenne]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Valentine&#039;s Day Event 2025====&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:92_4.png|Valentine [[Gastly]]&lt;br /&gt;
File:93_4.png|Valentine [[Haunter]]&lt;br /&gt;
File:94_4.png|Valentine [[Gengar]]&lt;br /&gt;
File:3005_4.png|Valentine Mega [[Gengar]]&lt;br /&gt;
File:3261_4.png|Valentine Gigantamax [[Gengar]]&lt;br /&gt;
File:92_5.png|Valentine [[Gastly]]&lt;br /&gt;
File:93_5.png|Valentine [[Haunter]]&lt;br /&gt;
File:94_5.png|Valentine [[Gengar]]&lt;br /&gt;
File:3005_5.png|Valentine Mega [[Gengar]]&lt;br /&gt;
File:3261 5.png|Valentine Gigantamax [[Gengar]]&lt;br /&gt;
File:203_2.png|Valentine [[Girafarig]]&lt;br /&gt;
File:258_5.png|Valentine [[Mudkip]]&lt;br /&gt;
File:259_5.png|Valentine [[Marshtomp]]&lt;br /&gt;
File:260_5.png|Valentine [[Swampert]]&lt;br /&gt;
File:3033_5.png|Valentine Mega [[Swampert]]&lt;br /&gt;
File:316_1.png|Valentine [[Gulpin]]&lt;br /&gt;
File:317_1.png|Valentine [[Swalot]]&lt;br /&gt;
File:349_2.png|Valentine [[Feebas]]&lt;br /&gt;
File:350_2.png|Valentine [[Milotic]]&lt;br /&gt;
File:359_2.png|Valentine [[Absol]]&lt;br /&gt;
File:3024_2.png|Valentine Mega [[Absol]]&lt;br /&gt;
File:415_1.png|Valentine [[Combee]]&lt;br /&gt;
File:415_1f.png|Valentine Female [[Combee]]&lt;br /&gt;
File:415_2.png|Valentine [[Combee]]&lt;br /&gt;
File:416_1.png|Valentine [[Vespiquen]]&lt;br /&gt;
File:417_2.png|Valentine [[Pachirisu]]&lt;br /&gt;
File:607_2.png|Valentine [[Litwick]]&lt;br /&gt;
File:608_2.png|Valentine [[Lampent]]&lt;br /&gt;
File:609_2.png|Valentine [[Chandelure]]&lt;br /&gt;
File:679_1.png|Valentine [[Honedge]]&lt;br /&gt;
File:680_1.png|Valentine [[Doublade]]&lt;br /&gt;
File:681_1.png|Valentine [[Aegislash]]&lt;br /&gt;
File:3104_1.png|Valentine Blade Form [[Aegislash]]&lt;br /&gt;
File:981_2.png|Valentine [[Farigiraf]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Valentine&#039;s Day Event 2026====&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:280_8.png|Valentine [[Ralts]]&lt;br /&gt;
File:281_8.png|Valentine [[Kirlia]]&lt;br /&gt;
File:282_8.png|Valentine [[Gardevoir]]&lt;br /&gt;
File:3018_8.png|Valentine Mega [[Gardevoir]]&lt;br /&gt;
File:475_8.png|Valentine [[Gallade]]&lt;br /&gt;
File:3046_8.png|Valentine Mega [[Gallade]]&lt;br /&gt;
File:324_3.png|Valentine [[Torkoal]]&lt;br /&gt;
File:336_2.png|Valentine [[Seviper]]&lt;br /&gt;
File:846_1.png|Valentine [[Arrokuda]]&lt;br /&gt;
File:847_1.png|Valentine [[Barraskewda]]&lt;br /&gt;
File:848_1.png|Valentine [[Toxel]]&lt;br /&gt;
File:849_1.png|Valentine [[Toxtricity-Amped]]&lt;br /&gt;
File:3274_1.png|Valentine Gigantamax [[Toxtricity-Amped]]&lt;br /&gt;
File:3127_1.png|Valentine [[Toxtricity-Low Key]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Valtentine&#039;s Day 2026 Hunting Contest=====&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:778_701.png|Valentine [[Mimikyu]]&lt;br /&gt;
File:3186_701.png|Valentine [[Mimikyu]] (Broken Disguise)&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===April Fools event 2023===&lt;br /&gt;
In 2023, a new subset of event forms were added. These were the April Fools forms. As the name implies, it is themed around fooling and pranks.&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:AFArticuno.png|April Fools Articuno (Fearow)&lt;br /&gt;
File:AFZapdos.png|April Fools Zapdos(Fearow)&lt;br /&gt;
File:AFMoltres.png|April Fools Moltres(Fearow)&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===April Fools event 2024===&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:17_4.png|April Fools Yveltal (Pidgeotto)&lt;br /&gt;
File:24_3.png|April Fools Zygarde 50% (Arbok)&lt;br /&gt;
File:234_4.png|April Fools Xerneas (Stantler)&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Easter-themed Pokémon===&lt;br /&gt;
====Easter Event 2018====&lt;br /&gt;
For the 2018 Easter Event, specially accessorized and/or colorated forms of [[Togepi]], [[Togetic]], and [[Togekiss]] were pioneered. There was a 1/550 chance of encountering these counterparts in the wild.&lt;br /&gt;
&lt;br /&gt;
[[File:EasterTogeForms.png]]&lt;br /&gt;
&lt;br /&gt;
====Easter Event 2019====&lt;br /&gt;
For the 2019 Easter Event, specially accessorized and/or colorated Pokémon versions were released for [[Exeggcute]], [[Kangaskhan]], [[Azurill]], [[Feebas]], [[Munchlax]], [[Larvesta]] and their evolutions. There was a 1/550 chance of encountering these counterparts in the wild, as well as the [[Togepi]] Easter forms released in 2018.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Easter Exeggcute.png|Easter [[Exeggcute]]&lt;br /&gt;
File:Easter Exeggutor.png|Easter [[Exeggutor]]&lt;br /&gt;
File:Easter Kangaskhan.png|Easter [[Kangaskhan]]&lt;br /&gt;
File:EasterKangaskhan_Mega.png|Easter Mega [[Kangaskhan]]&lt;br /&gt;
File:Easter Munchlax.png|Easter [[Munchlax]]&lt;br /&gt;
File:Easter Snorlax.png|Easter [[Snorlax]]&lt;br /&gt;
File:Easter Azurill.png|Easter [[Azurill]]&lt;br /&gt;
File:Easter Marill.png|Easter [[Marill]]&lt;br /&gt;
File:Easter Azumarill.png|Easter [[Azumarill]]&lt;br /&gt;
File:Easter Feebas.png|Easter [[Feebas]]&lt;br /&gt;
File:Easter Milotic.png|Easter [[Milotic]]&lt;br /&gt;
File:Easter Larvesta.png|Easter [[Larvesta]]&lt;br /&gt;
File:637_1v2.png|Easter [[Volcarona]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Easter Event 2020====&lt;br /&gt;
For the 2020 Easter event, [[Happiny]], [[Bunnelby]], and their evolutions were given specially accessorized and/or colorized forms. Additionally, any Pokémon which had an Easter form in previous years was also made available to hunt. Furthermore, [[Shaymin]] and its Sky-form were given event forms. This was obtainable via completing the [[Breezy Town|Easter Quest]] that year. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Easter Happiny.png|Easter [[Happiny]]&lt;br /&gt;
File:Easter Chansey.png|Easter [[Chansey]]&lt;br /&gt;
File:Easter Blissey.png|Easter [[Blissey]]&lt;br /&gt;
File:Easter Bunnelby.png|Easter [[Bunnelby]]&lt;br /&gt;
File:Easter Diggersby.png|Easter [[Diggersby]]&lt;br /&gt;
File:Easter Shaymin.png|Easter [[Shaymin]]&lt;br /&gt;
File:Easter Shaymin-Sky.png|Easter [[Shaymin]] Sky Form&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Easter Event 2021====&lt;br /&gt;
For the 2021 Easter event, [[Bellsprout]], [[Wooper]], [[Mantyke]], and their evolutions were given specially accessorized and/or colorized forms. Additionally, [[Diancie]] received several Easter forms.&lt;br /&gt;
Any Pokémon which had an Easter form in previous years was also made available to hunt.&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Easter Bellsprout.png|Easter [[Bellsprout]]&lt;br /&gt;
File:Easter Weepinbell.png|Easter [[Weepinbell]]&lt;br /&gt;
File:Easter Victreebel.png|Easter [[Victreebel]]&lt;br /&gt;
File:Easter Wooper.png|Easter [[Wooper]]&lt;br /&gt;
File:Easter Quagsire.png|Easter [[Quagsire]]&lt;br /&gt;
File:Easter Mantine.png|Easter [[Mantine]]&lt;br /&gt;
File:Easter Mantyke.png|Easter [[Mantyke]]&lt;br /&gt;
File:Easter_Diancie_Amber.png|Easter Diancie Amber&lt;br /&gt;
File:Easter_Diancie_Aquamarine.png|Easter Diancie Aquamarine&lt;br /&gt;
File:Easter_Diancie_Emerald.png|Easter Diancie Emerald&lt;br /&gt;
File:Easter_Diancie_Ruby.png|Easter Diancie Ruby&lt;br /&gt;
File:Easter_Diancie_Quartz.png|Easter Diancie Quartz&lt;br /&gt;
File:EasterDiancieAmber_Mega.png|Easter Mega Diancie Amber&lt;br /&gt;
File:EasterDiancieAquamarine_Mega.png|Easter Mega Diancie Aquamarine&lt;br /&gt;
File:EasterDiancieEmerald_Mega.png|Easter Diancie Emerald&lt;br /&gt;
File:EasterDiancieRuby_Mega.png|Easter Mega Diancie Ruby&lt;br /&gt;
File:EasterDiancieQuartz_Mega.png|Easter Mega Diancie Quartz&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Easter Event 2022====&lt;br /&gt;
For the 2022 Easter event, the [[Sinnoh#Starter_Pok.C3.A9mon|Generation 4]] starters [[Piplup]], [[Turtwig]], [[Chimchar]], and their evolutions were given specially accessorized and/or colorized forms.&lt;br /&gt;
&amp;lt;br&amp;gt;Any Pokémon which had an Easter form in previous years was also made available to hunt.&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Easter Piplup.png|Easter [[Piplup]]&lt;br /&gt;
File:Easter Prinplup.png|Easter [[Prinplup]]&lt;br /&gt;
File:Easter Empoleon.png|Easter [[Empoleon]]&lt;br /&gt;
File:Easter Chimchar.png|Easter [[Chimchar]]&lt;br /&gt;
File:Easter Monferno.png|Easter [[Monferno]]&lt;br /&gt;
File:Easter Infernape.png|Easter [[Infernape]]&lt;br /&gt;
File:Easter Turtwig.png|Easter [[Turtwig]]&lt;br /&gt;
File:Easter Grotle.png|Easter [[Grotle]]&lt;br /&gt;
File:Easter Torterra.png|Easter [[Torterra]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Easter Event 2023====&lt;br /&gt;
For the 2023 Easter event, [[Klefki]] and the [[Rotom]] appliances were given specially accessorized and/or colorized forms.&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Easter Klefki.png|Easter [[Klefki]]&lt;br /&gt;
File:Easter Rotom.png|Easter [[Rotom]]&lt;br /&gt;
File:Easter Rotom-Fan.png|Easter Rotom Fan&lt;br /&gt;
File:Easter Rotom-Frost.png|Easter Rotom Frost&lt;br /&gt;
File:Easter Rotom-Heat.png|Easter Rotom Heat&lt;br /&gt;
File:Easter Rotom-Mow.png|Easter Rotom Mow&lt;br /&gt;
File:Easter Rotom-Wash.png|Easter Rotom Wash&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Easter Event 2024====&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:16_2.png|Easter [[Pidgey]]&lt;br /&gt;
File:17_2.png|Easter [[Pidgeotto]]&lt;br /&gt;
File:18_2.png|Easter [[Pidgeot]]&lt;br /&gt;
File:3029_2.png|Easter Mega [[Pidgeot]]&lt;br /&gt;
File:25_23.png|Easter [[Pikachu]]&lt;br /&gt;
File:25_23f.png|Easter Female [[Pikachu]]&lt;br /&gt;
File:56_2.png|Easter [[Mankey]]&lt;br /&gt;
File:57_2.png|Easter [[Primeape]]&lt;br /&gt;
File:979_2.png|Easter [[Annihilape]]&lt;br /&gt;
File:108_1.png|Easter [[Lickitung]]&lt;br /&gt;
File:463_1.png|Easter [[Lickilicky]]&lt;br /&gt;
File:114_3.png|Easter [[Tangela]]&lt;br /&gt;
File:465_3.png|Easter [[Tangrowth]]&lt;br /&gt;
File:209_1.png|Easter [[Snubbull]]&lt;br /&gt;
File:210_1.png|Easter [[Granbull]]&lt;br /&gt;
File:302_3.png|Easter [[Sableye]]&lt;br /&gt;
File:3034_3.png|Easter Mega [[Sableye]]&lt;br /&gt;
File:303_5.png|Easter [[Mawile]]&lt;br /&gt;
File:3019_5.png|Easter Mega [[Mawile]]&lt;br /&gt;
File:335_2.png|Easter [[Zangoose]]&lt;br /&gt;
File:336_1.png|Easter [[Seviper]]&lt;br /&gt;
File:492_2.png|Easter [[Shaymin]]&lt;br /&gt;
File:674.png|Easter [[Pancham]]&lt;br /&gt;
File:675.png|Easter [[Pangoro]]&lt;br /&gt;
File:3080_2.png|Easter [[Shaymin-Sky]]&lt;br /&gt;
File:778_3.png|Easter [[Mimikyu]]&lt;br /&gt;
File:3186_3.png|Easter Busted [[Mimikyu]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Easter Event 2025====&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Easter Pikachu_2025.png|Easter [[Pikachu]]&lt;br /&gt;
File:Easter Treecko.png|Easter [[Treecko]]&lt;br /&gt;
File:Easter Grovyle.png|Easter [[Grovyle]]&lt;br /&gt;
File:Easter Sceptile.png|Easter [[Sceptile]]&lt;br /&gt;
File:Easter Sceptile_Mega.png|Easter Mega [[Sceptile]]&lt;br /&gt;
File:Easter Torchic.png|Easter [[Torchic]]&lt;br /&gt;
File:Easter Combusken.png|Easter [[Combusken]]&lt;br /&gt;
File:Easter Blaziken.png|Easter [[Blaziken]]&lt;br /&gt;
File:Easter Blaziken_Mega.png|Easter Mega [[Blaziken]]&lt;br /&gt;
File:Easter Mudkip.png|Easter [[Mudkip]]&lt;br /&gt;
File:Easter Marshtomp.png|Easter [[Marshtomp]]&lt;br /&gt;
File:Easter Swampert.png|Easter [[Swampert]]&lt;br /&gt;
File:Easter Swampert_Mega.png|Easter Mega [[Swampert]]&lt;br /&gt;
File:Easter Seedot.png|Easter [[Seedot]]&lt;br /&gt;
File:Easter Nuzleaf.png|Easter [[Nuzleaf]]&lt;br /&gt;
File:Easter Shiftry.png|Easter [[Shiftry]]&lt;br /&gt;
File:Easter Meditite.png|Easter [[Meditite]]&lt;br /&gt;
File:Easter Medicham.png|Easter [[Medicham]]&lt;br /&gt;
File:Easter Medicham_Mega.png|Easter Mega [[Medicham]]&lt;br /&gt;
File:Easter Spinda.png|Easter [[Spinda]]&lt;br /&gt;
File:Easter Shellos.png|Easter [[Shellos]]&lt;br /&gt;
File:Easter Gastrodon.png|Easter [[Gastrodon]]&lt;br /&gt;
File:Easter Buneary.png|Easter [[Buneary]]&lt;br /&gt;
File:Easter Lopunny.png|Easter [[Lopunny]]&lt;br /&gt;
File:Easter Lopunny_Mega.png|Easter Mega [[Lopunny]]&lt;br /&gt;
File:Easter Bronzor.png|Easter [[Bronzor]]&lt;br /&gt;
File:Easter Bronzong.png|Easter [[Bronzong]]&lt;br /&gt;
File:Easter Petilil.png|Easter [[Petilil]]&lt;br /&gt;
File:Easter Lilligant.png|Easter [[Lilligant]]&lt;br /&gt;
File:Easter Lilligant_Hisui.png|Easter Hisuian [[Lilligant]]&lt;br /&gt;
File:Easter Minccino.png|Easter [[Minccino]]&lt;br /&gt;
File:Easter Cinccino.png|Easter [[Cinccino]]&lt;br /&gt;
File:Easter Emolga.png|Easter [[Emolga]]&lt;br /&gt;
File:Easter Inkay.png|Easter [[Inkay]]&lt;br /&gt;
File:Easter Malamar.png|Easter [[Malamar]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Easter Event 2026====&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:13_2.png|Easter [[Weedle]]&lt;br /&gt;
File:14_2.png|Easter [[Kakuna]]&lt;br /&gt;
File:15_2.png|Easter [[Beedrill]]&lt;br /&gt;
File:3028_2.png|Easter Mega [[Beedrill]]&lt;br /&gt;
File:58_4.png|Easter [[Growlithe]]&lt;br /&gt;
File:59_4.png|Easter [[Arcanine]]&lt;br /&gt;
File:165_1.png|Easter [[Ledyba]]&lt;br /&gt;
File:166_1.png|Easter [[Ledian]]&lt;br /&gt;
File:207_2.png|Easter [[Gligar]]&lt;br /&gt;
File:472_2.png|Easter [[Gliscor]]&lt;br /&gt;
File:285_5.png|Easter [[Shroomish]]&lt;br /&gt;
File:286_5.png|Easter [[Breloom]]&lt;br /&gt;
File:674_5.png|Easter [[Pancham]]&lt;br /&gt;
File:675_5.png|Easter [[Pangoro]]&lt;br /&gt;
File:546_5.png|Easter [[Cottonee]]&lt;br /&gt;
File:547_5.png|Easter [[Whimsicott]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===May 4th Star Wars Event===&lt;br /&gt;
====May 4th 2019====&lt;br /&gt;
During May 2019, Darth Vader-looking versions of [[Pawniard]] and [[Bisharp]] were released. They were released on May 4th as a commemoration to the famous Star Wars quote &amp;quot;May the force be with you.&amp;quot; They were released for a limited amount of time.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Darth Pawniard.png|Darth [[Pawniard]]&lt;br /&gt;
File:Darth Bisharp.png|Darth [[Bisharp]]&lt;br /&gt;
File:983_1.png|Darth [[Kingambit]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====May 4th 2021====&lt;br /&gt;
This iteration saw the addition of [[Machop]], [[Machoke]], and [[Machamp]] wielding their own lightsabers, with Machamp resembling General Grievous. [[Meditite]] and [[Medicham]], along with its mega, also saw their own sprite added, looking like Yoda. The last family added was [[Grimer]] and [[Muk]], who look like Jabba the Hutt. These forms were released for a limited time.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Grievous Machop.png|Grievous [[Machop]]&lt;br /&gt;
File:Grievous Machoke.png|Grievous [[Machoke]]&lt;br /&gt;
File:Grievous Machamp.png|Grievous [[Machamp]]&lt;br /&gt;
File:Jabba Grimer.png|Jabba the [[Grimer]]&lt;br /&gt;
File:Jabba Muk.png|Jabba the [[Muk]]&lt;br /&gt;
File:Yoda Meditite.png|Yoda [[Meditite]]&lt;br /&gt;
File:Yoda Medicham.png|Yoda [[Medicham]]&lt;br /&gt;
File:Yoda M Medicham.png|Yoda Mega [[Medicham]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====May 4th 2022====&lt;br /&gt;
Though late, 2022 did feature a new addition to the Star Wars skins: Alolan-Marowak. In the midst of the 2022 Summer Event, May 4th version of Alolan-Marowak was released.&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File: Darth Maul Alolan Marowak.png| Darth Maul [[Alolan Marowak]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====May 4th 2023====&lt;br /&gt;
In 2023’s version of the Star Wars event, new releases included [[Voltorb]], [[Munchlax]], [[Mimikyu]], [[Abra]], and their evolutions.&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Grievous_Abra.png|Grevious [[Abra]]&lt;br /&gt;
File:Grievous_Kadabra.png|Grevious [[Kadabra]]&lt;br /&gt;
File:Grievous_Alakazam.png|Grevious [[Alakazam]]&lt;br /&gt;
File:Grievous Mega Alakazam.png|Grevious Mega [[Alakazam]]&lt;br /&gt;
File:BB8 Voltorb.png|BB-8 [[Voltorb]]&lt;br /&gt;
File:BB8 Electrode.png|BB-8 [[Electrode]]&lt;br /&gt;
File:Mandalorian Munchlax.png|Mandalorian [[Munchlax]]&lt;br /&gt;
File:Mandalorian Snorlax.png|Mandalorian [[Snorlax]]&lt;br /&gt;
File:Jawa Mimikyu.png|Jawa [[Mimikyu]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====May 4th 2024====&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:360_1.png|Boba Fett [[Wynaut]]&lt;br /&gt;
File:202_1.png|Boba Fett [[Wobbuffet]]&lt;br /&gt;
File:214_2.png|Darth Vader [[Heracross]]&lt;br /&gt;
File:3014_2.png|Darth Vader Mega [[Heracross]]&lt;br /&gt;
File:280_7.png|Padawan [[Ralts]]&lt;br /&gt;
File:281_7.png|Anakin [[Kirlia]]&lt;br /&gt;
File:281_7f.png|Padme Female [[Kirlia]]&lt;br /&gt;
File:282_7.png|Padme [[Gardevoir]]&lt;br /&gt;
File:3018_7.png|Padme Mega [[Gardevoir]]&lt;br /&gt;
File:475_7.png|Anakin  [[Gallade]]&lt;br /&gt;
File:3046_7.png|Anakin Mega [[Gallade]]&lt;br /&gt;
File:703_1.png|Baby Yoda [[Carbink]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====May 4th 2025====&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:50_14.png|Storm Trooper [[Diglett]]&lt;br /&gt;
File:51_14.png|Storm Trooper [[Dugtrio]]&lt;br /&gt;
File:215_3.png|Ahsoka Tano [[Sneasel]]&lt;br /&gt;
File:461_3.png|Ahsoka Tano [[Weavile]]&lt;br /&gt;
File:285_4.png| [[Shroomish]]&lt;br /&gt;
File:286_4.png| [[Breloom]]&lt;br /&gt;
File:559_1.png| [[Scraggy]]&lt;br /&gt;
File:560_1.png| [[Scrafty]]&lt;br /&gt;
File:704_3.png|Hera Syndulla [[Goomy]]&lt;br /&gt;
File:705_3.png|Hera Syndulla [[Sliggoo]]&lt;br /&gt;
File:706_3.png|Hera Syndulla [[Goodra]]&lt;br /&gt;
File:3236_3.png|Hera Syndulla Hisuian [[Sliggoo]]&lt;br /&gt;
File:3237_3.png|Hera Syndulla Hisuian [[Goodra]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Bidoof Day 2023===&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:399_3.png|April Fools Suicune (Bidoof)&lt;br /&gt;
File:399_4.png|April Fools Entei (Bidoof)&lt;br /&gt;
File:399_5.png|April Fools Raikou (Bidoof)&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Summer-themed Pokémon===&lt;br /&gt;
====Summer Event 2020====&lt;br /&gt;
During  2020&#039;s summer event, specially accessorized and/or colorated Pokémon versions were released for the Unova Starters, along with a few other Pokémon. The chance for these Pokémon were not revealed. Additionally, a summer form for [[Volcanion]] was released and obtainable by completing the quest that year.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Summer_Horsea.png|Summer [[Horsea]]&lt;br /&gt;
File:Summer_Seadra.png|Summer [[Seadra]]&lt;br /&gt;
File:Summer_Kingdra.png|Summer [[Kingdra]]&lt;br /&gt;
File:Summer_Wingull.png|Summer [[Wingull]]&lt;br /&gt;
File:Summer_Pelipper.png|Summer [[Pelipper]]&lt;br /&gt;
File:Summer_Gible.png|Summer [[Gible]]&lt;br /&gt;
File:Summer_Gabite.png|Summer [[Gabite]]&lt;br /&gt;
File:Summer_Garchomp.png|Summer [[Garchomp]]&lt;br /&gt;
File:SummerGarchomp_Mega.png|Summer Mega [[Garchomp]]&lt;br /&gt;
File:Summer_Snivy.png|Summer [[Snivy]]&lt;br /&gt;
File:Summer_Servine.png|Summer [[Servine]]&lt;br /&gt;
File:Summer_Serperior.png|Summer [[Serperior]]&lt;br /&gt;
File:Summer_Tepig.png|Summer [[Tepig]]&lt;br /&gt;
File:Summer_Pignite.png|Summer [[Pignite]]&lt;br /&gt;
File:Summer_Emboar.png|Summer [[Emboar]]&lt;br /&gt;
File:Summer_Oshawott.png|Summer [[Oshawott]]&lt;br /&gt;
File:Summer_Dewott.png|Summer [[Dewott]]&lt;br /&gt;
File:Summer_Samurott.png|Summer [[Samurott]]&lt;br /&gt;
File:3231_1.png|Summer Hisuian [[Samurott]]&lt;br /&gt;
File:Summer_Volcanion.png|Summer [[Volcanion]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Summer Event 2021====&lt;br /&gt;
During  2021&#039;s summer event, specially accessorized and/or colorated Pokémon versions were released for [[Squirtle]], [[Darumaka]], and their evolutions. Along with these counterparts, summer themed versions were released for [[Latios]] and [[Latias]] as a reward for having completed the Summer 2021 Quest in [[Alto Mare]]. The chances for these Pokémon were not revealed. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Summer_Darumaka.png|Summer [[Darumaka]]&lt;br /&gt;
File:Summer_Darmanitan.png|Summer [[Darmanitan]]&lt;br /&gt;
File:Summer_Squirtle.png|Summer [[Squirtle]]&lt;br /&gt;
File:Summer_Wartortle.png|Summer [[Wartortle]]&lt;br /&gt;
File:Summer_Blastoise.png|Summer [[Blastoise]]&lt;br /&gt;
File:SummerBlastoise_Mega.png|Summer Mega [[Blastoise]]&lt;br /&gt;
File:Summer_Latias.png|Summer [[Latias]]&lt;br /&gt;
File:SummerLatias_Mega.png|Summer Mega [[Latias]]&lt;br /&gt;
File:Summer_Latios.png|Summer [[Latios]]&lt;br /&gt;
File:SummerLatios_Mega.png|Summer Mega [[Latios]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Summer Event 2022====&lt;br /&gt;
During 2022&#039;s summer event, specially accessorized and/or colorated Pokémon versions were released for several popular pokemon, including the likes of the [[Scyther]] family, along with our not so friendly looking rodents. Along with these variations, a summer rendition of [[Victini]] was also added in. The chances of encountering one of these variants is not open to the public.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Summer_Rattata.png|Summer [[Rattata]]&lt;br /&gt;
File:Summer_Raticate.png|Summer [[Raticate]]&lt;br /&gt;
File:Summer_Scyther.png|Summer [[Scyther]]&lt;br /&gt;
File:Summer_Scizor.png|Summer [[Scizor]]&lt;br /&gt;
File:Summer_Mega_Scizor.png|Summer Mega [[Scizor]]&lt;br /&gt;
File:900_2.png|Summer [[Kleavor]]&lt;br /&gt;
File:Summer_Farfetchd.png|Summer [[Farfetch&#039;d]]&lt;br /&gt;
File:Summer_Victini.png|Summer [[Victini]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
[[Category:Pokémon]] [[Category:Gameplay features]]&lt;br /&gt;
&lt;br /&gt;
====Summer Event 2023====&lt;br /&gt;
For the 2023 edition of the summer event, several families were given new forms, including some fan-favorites such as [[Gardevoir]], [[Snorlax]], and [[Bisharp]].&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Summer Pikachu (Surfing).png|Surfing [[Pikachu]]&lt;br /&gt;
File:Summer Pikachu (Flying).png|Flying [[Pikachu]]&lt;br /&gt;
File:Summer Vulpix.png|Summer [[Vulpix]]&lt;br /&gt;
File:Summer Ninetales.png|Summer [[Ninetales]]&lt;br /&gt;
File:Summer Abra.png|Summer [[Abra]]&lt;br /&gt;
File:Summer Kadabra.png|Summer [[Kadabra]]&lt;br /&gt;
File:Summer Alakazam.png|Summer [[Alakazam]]&lt;br /&gt;
File:Summer Mega Alakazam.png|Summer Mega [[Alakazam]]&lt;br /&gt;
File:Summer Ponyta.png|Summer [[Ponyta]]&lt;br /&gt;
File:Summer Rapidash.png|Summer [[Rapidash]]&lt;br /&gt;
File:Summer Lapras.png|Summer [[Lapras]]&lt;br /&gt;
File:Summer Munchlax.png|Summer [[Munchlax]]&lt;br /&gt;
File:Summer Snorlax.png|Summer [[Snorlax]]&lt;br /&gt;
File:Summer Azurill.png|Summer [[Azurill]]&lt;br /&gt;
File:Summer Marill.png|Summer [[Marill]]&lt;br /&gt;
File:Summer Azumarill.png|Summer [[Azumarill]]&lt;br /&gt;
File:Summer Bonsly.png|Summer [[Bonsly]]&lt;br /&gt;
File:Summer Sudowoodo.png|Summer [[Sudowoodo]]&lt;br /&gt;
File:Summer Pineco.png|Summer [[Pineco]]&lt;br /&gt;
File:Summer Forretress.png|Summer [[Forretress]]&lt;br /&gt;
File:Summer Remoraid.png|Summer [[Remoraid]]&lt;br /&gt;
File:Summer Octillery.png|Summer [[Octillery]]&lt;br /&gt;
File:Summer Ralts.png|Summer [[Ralts]]&lt;br /&gt;
File:Summer Kirlia.png|Summer [[Kirlia]]&lt;br /&gt;
File:Summer Gardevoir(Female).png|Summer [[Gardevoir]] (Female)&lt;br /&gt;
File:Summer Gardevoir(Male).png|Summer [[Gardevoir]] (Male)&lt;br /&gt;
File:Summer Mega Gardevoir(Female).png|Summer Mega [[Gardevoir]] (Female)&lt;br /&gt;
File:Summer Mega Gardevoir(Male).png|Summer Mega [[Gardevoir]] (Male)&lt;br /&gt;
File:Summer Gallade.png|Summer [[Gallade]]&lt;br /&gt;
File:Summer Mega Gallade.png|Summer Mega [[Gallade]]&lt;br /&gt;
File:Summer Pansage.png|Summer [[Pansage]]&lt;br /&gt;
File:Summer Simisage.png|Summer [[Simisage]]&lt;br /&gt;
File:Summer Pansear.png|Summer [[Pansear]]&lt;br /&gt;
File:Summer Simisear.png|Summer [[Simisear]]&lt;br /&gt;
File:Summer Panpour.png|Summer [[Panpour]]&lt;br /&gt;
File:Summer Simipour.png|Summer [[Simipour]]&lt;br /&gt;
File:Summer Petilil.png|Summer [[Petilil]]&lt;br /&gt;
File:Summer Lilligant.png|Summer [[Lilligant]]&lt;br /&gt;
File:3232_2.png|Summer Hisuian [[Lilligant]]&lt;br /&gt;
File:Summer Vanillite.png|Summer [[Vanillite]]&lt;br /&gt;
File:Summer Vanillish.png|Summer [[Vanillish]]&lt;br /&gt;
File:Summer Vanilluxe.png|Summer [[Vanilluxe]]&lt;br /&gt;
File:Summer Pawniard.png|Summer [[Pawniard]]&lt;br /&gt;
File:Summer Bisharp.png|Summer [[Bisharp]]&lt;br /&gt;
File:983_2.png|Summer [[Kingambit]]&lt;br /&gt;
File:Summer Espurr.png|Summer [[Espurr]]&lt;br /&gt;
File:Summer Meowstic M.png|Summer [[Meowstic Male]]&lt;br /&gt;
File:Summer Meowstic F.png|Summer [[Meowstic Female]]&lt;br /&gt;
File:Summer Clauncher.png|Summer [[Clauncher]]&lt;br /&gt;
File:Summer Clawitzer.png|Summer [[Clawitzer]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Summer Event 2024====&lt;br /&gt;
In 2024, a [https://pokemonrevolution.net/forum/topic/240472-summer-greninja-event-2024/ Summer Event]  was held where the reward was a SHINY Summer Froakie. &#039;&#039;&#039;This form is not obtainable in the wild&#039;&#039;&#039; and can only be obtained by winning the event.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:120_3.png|Summer [[Staryu]]&lt;br /&gt;
File:121_3.png|Summer [[Starmie]]&lt;br /&gt;
File:161_2.png|Summer [[Sentret]]&lt;br /&gt;
File:162_2.png|Summer [[Furret]]&lt;br /&gt;
File:285_3.png|Summer [[Shroomish]]&lt;br /&gt;
File:286_3.png|Summer [[Breloom]]&lt;br /&gt;
File:324_2.png|Summer [[Torkoal]]&lt;br /&gt;
File:650_2.png|Summer [[Chespin]]&lt;br /&gt;
File:651_2.png|Summer [[Quilladin]]&lt;br /&gt;
File:652_2.png|Summer [[Chesnaught]]&lt;br /&gt;
File:653_2.png|Summer [[Fennekin]]&lt;br /&gt;
File:654_2.png|Summer [[Braixen]]&lt;br /&gt;
File:655_2.png|Summer [[Delphox]]&lt;br /&gt;
File:656_1.png|Shiny Summer [[Froakie]]&lt;br /&gt;
File:657_1.png|Shiny Summer [[Frogadier]]&lt;br /&gt;
File:658_1.png|Shiny Summer [[Greninja]]&lt;br /&gt;
File:3044_1.png|Shiny Summer Ash [[Greninja]]&lt;br /&gt;
File:656_2.png|Summer [[Froakie]]&lt;br /&gt;
File:657_2.png|Summer [[Frogadier]]&lt;br /&gt;
File:658_2.png|Summer [[Greninja]]&lt;br /&gt;
File:3044_2.png|Summer Ash [[Greninja]]&lt;br /&gt;
File:661_1.png|Summer [[Fletchling]]&lt;br /&gt;
File:662_1.png|Summer [[Fletchinder]]&lt;br /&gt;
File:663_1.png|Summer [[Talonflame]]&lt;br /&gt;
File:742_1.png|Summer [[Cutiefly]]&lt;br /&gt;
File:743_1.png|Summer [[Ribombee]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Summer Event 2025/2026====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:92_6.png|Summer [[Gastly]]&lt;br /&gt;
File:93_6.png|Summer [[Haunter]]&lt;br /&gt;
File:94_6.png|Summer [[Gengar]]&lt;br /&gt;
File:3005_6.png|Summer Mega [[Gengar]]&lt;br /&gt;
File:440_3.png|Summer [[Happiny]]&lt;br /&gt;
File:113_3.png|Summer [[Chansey]]&lt;br /&gt;
File:242_3.png|Summer [[Blissey]]&lt;br /&gt;
File:258_7.png|Summer [[Mudkip]]&lt;br /&gt;
File:259_7.png|Summer [[Marshtomp]]&lt;br /&gt;
File:260_7.png|Summer [[Swampert]]&lt;br /&gt;
File:3033_7.png|Summer Mega [[Swampert]]&lt;br /&gt;
File:443_4.png|Summer [[Gible]]&lt;br /&gt;
File:444_4.png|Summer [[Gabite]]&lt;br /&gt;
File:445_4.png|Summer [[Garchomp]]&lt;br /&gt;
File:3025_4.png|Summer Mega [[Garchomp]]&lt;br /&gt;
File:568_1.png|Summer [[Trubbish]]&lt;br /&gt;
File:569_1.png|Summer [[Garbodor]]&lt;br /&gt;
File:580_1.png|Summer [[Ducklett]]&lt;br /&gt;
File:581_1.png|Summer [[Swanna]]&lt;br /&gt;
File:594_2.png|Summer [[Alomomola]]&lt;br /&gt;
File:597_2.png|Summer [[Ferroseed]]&lt;br /&gt;
File:598_2.png|Summer [[Ferrothorn]]&lt;br /&gt;
File:679_2.png|Summer [[Honedge]]&lt;br /&gt;
File:680_2.png|Summer [[Doublade]]&lt;br /&gt;
File:681_2.png|Summer [[Aegislash]]&lt;br /&gt;
File:3104_2.png|Summer Blade Form [[Aegislash]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Halloween-themed Pokémon===&lt;br /&gt;
====Halloween Event 2017====&lt;br /&gt;
On October 18th, 2017, Halloween-themed counterparts of [[Pikachu]] and [[Raichu]] were ushered in for the contemporaneous Halloween event , randomized at a 1/20 (5%) rate of huntability. [[Darkrai]] was also first made available this year.&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Halloween_Pikachu.png|Halloween [[Pikachu]]&lt;br /&gt;
File:Halloween_Raichu.png|Halloween [[Raichu]]&lt;br /&gt;
File:Pumpkin_Darkrai.png|Halloween [[Darkrai]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Halloween Event 2018====&lt;br /&gt;
During 2018&#039;s Halloween, all three Kanto starters were also given an Halloween counterpart. &lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Halloween_Bulbasaur.png|Halloween [[Bulbasaur]]&lt;br /&gt;
File:Halloween_Ivysaur.png|Halloween [[Ivysaur]]&lt;br /&gt;
File:Halloween_Venusaur.png|Halloween [[Venusaur]]&lt;br /&gt;
File:HalloweenVenusaur_Mega.png|Halloween Mega [[Venusaur]]&lt;br /&gt;
File:Halloween_Charmander.png|Halloween [[Charmander]]&lt;br /&gt;
File:Halloween_Charmeleon.png|Halloween [[Charmeleon]]&lt;br /&gt;
File:Halloween_Charizard.png|Halloween [[Charizard]]&lt;br /&gt;
File:HalloweenCharizardX_Mega.png|Halloween Mega [[Charizard]] X&lt;br /&gt;
File:HalloweenCharizardY_Mega.png|Halloween Mega [[Charizard]] Y&lt;br /&gt;
File:Halloween_Squirtle.png|Halloween [[Squirtle]]&lt;br /&gt;
File:Halloween_Wartortle.png|Halloween [[Wartortle]]&lt;br /&gt;
File:Halloween_Blastoise.png|Halloween [[Blastoise]]&lt;br /&gt;
File:3003 2.png|Halloween Mega [[Blastoise]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Halloween Event 2019====&lt;br /&gt;
On October 22nd, 2019 new Halloween sprites were released mainly focusing on the Kalos starters, as well as a few other Pokémon. Additionally, we were able to catch previous Halloween themed counterparts. The rate to catch the forms this year was 1/50 (2%). [[Darkrai]] returned this year, with an unprecedented &#039;&#039;&#039;two&#039;&#039;&#039; forms. The original form was given to those who completed the quest, however, those who had previously caught Darkrai in 2017 were given the choice for the Pumpkin Form. &lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Halloween_Ponyta.png|Halloween [[Ponyta]]&lt;br /&gt;
File:Halloween_Rapidash.png|Halloween [[Rapidash]]&lt;br /&gt;
File:Halloween_Togepi.png|Halloween [[Togepi]]&lt;br /&gt;
File:Halloween_Togetic.png|Halloween [[Togetic]]&lt;br /&gt;
File:Halloween_Togekiss.png|Halloween [[Togekiss]]&lt;br /&gt;
File:Halloween_Sneasel.png|Halloween [[Sneasel]]&lt;br /&gt;
File:Halloween_Weavile.png|Halloween [[Weavile]]&lt;br /&gt;
File:Halloween_Larvitar.png|Halloween [[Larvitar]]&lt;br /&gt;
File:Halloween_Pupitar.png|Halloween [[Pupitar]]&lt;br /&gt;
File:Halloween_Tyranitar.png|Halloween [[Tyranitar]]&lt;br /&gt;
File:HalloweenTyranitar_Mega.png|Halloween Mega[[Tyranitar]]&lt;br /&gt;
File:Halloween_Ralts.png|Halloween [[Ralts]]&lt;br /&gt;
File:Halloween_Kirlia.png|Halloween [[Kirlia]]&lt;br /&gt;
File:Halloween_Gardevoir.png|Halloween [[Gardevoir]]&lt;br /&gt;
File:HalloweenGardevoir_Mega.png|Halloween Mega [[Gardevoir]]&lt;br /&gt;
File:Halloween_Gallade.png|Halloween [[Gallade]]&lt;br /&gt;
File:HalloweenGallade_Mega.png|Halloween Mega [[Gallade]] &lt;br /&gt;
File:Halloween_Torkoal.png|Halloween [[Torkoal]]&lt;br /&gt;
File:Fancy_Darkrai.png|Halloween [[Darkrai]]&lt;br /&gt;
File:Halloween_Chespin.png|Halloween [[Chespin]]&lt;br /&gt;
File:Halloween_Quilladin.png|Halloween [[Quilladin]]&lt;br /&gt;
File:Halloween_Chesnaught.png|Halloween [[Chesnaught]]&lt;br /&gt;
File:Halloween_Fennekin.png|Halloween [[Fennekin]]&lt;br /&gt;
File:Halloween_Braixen.png|Halloween [[Braixen]]&lt;br /&gt;
File:Halloween_Delphox.png|Halloween [[Delphox]]&lt;br /&gt;
File:Halloween_Froakie.png|Halloween [[Froakie]]&lt;br /&gt;
File:Halloween_Frogadier.png|Halloween [[Frogadier]]&lt;br /&gt;
File:Halloween_Greninja.png|Halloween [[Greninja]]&lt;br /&gt;
File:Greninja_Ash.png|Halloween Ash [[Greninja]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Halloween Event 2020====&lt;br /&gt;
More Halloween-themed Pokémon were released in 2020, mainly focusing on the Johto starters. Additionally, forms from previous years could be hunted again. &lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Halloween_Gastly.png|Halloween [[Gastly]]&lt;br /&gt;
File:Halloween_Haunter.png|Halloween [[Haunter]]&lt;br /&gt;
File:Halloween_Gengar.png|Halloween [[Gengar]]&lt;br /&gt;
File:HalloweenGengar_Mega.png|Halloween Mega [[Gengar]]&lt;br /&gt;
File:Halloween_Chikorita.png|Halloween [[Chikorita]]&lt;br /&gt;
File:Halloween_Bayleef.png|Halloween [[Bayleef]]&lt;br /&gt;
File:Halloween_Meganium.png|Halloween [[Meganium]]&lt;br /&gt;
File:Halloween_Cyndaquil.png|Halloween [[Cyndaquil]]&lt;br /&gt;
File:Halloween_Quilava.png|Halloween [[Quilava]]&lt;br /&gt;
File:Halloween_Typhlosion.png|Halloween [[Typhlosion]]&lt;br /&gt;
File:3228_1.png|Halloween Hisuian [[Typhlosion]]&lt;br /&gt;
File:Halloween_Totodile.png|Halloween [[Totodile]]&lt;br /&gt;
File:Halloween_Croconaw.png|Halloween [[Croconaw]]&lt;br /&gt;
File:Halloween_Feraligatr.png|Halloween [[Feraligatr]]&lt;br /&gt;
File:Halloween_Seedot.png|Halloween [[Seedot]]&lt;br /&gt;
File:Halloween_Nuzleaf.png|Halloween [[Nuzleaf]]&lt;br /&gt;
File:Halloween_Shiftry.png|Halloween [[Shiftry]]&lt;br /&gt;
File:Halloween_Gible.png|Halloween [[Gible]]&lt;br /&gt;
File:Halloween_Gabite.png|Halloween [[Gabite]]&lt;br /&gt;
File:Halloween_Garchomp.png|Halloween [[Garchomp]]&lt;br /&gt;
File:Halloween_Mega_Garchomp.png|Halloween Mega [[Garchomp]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Halloween Event 2021====&lt;br /&gt;
With the advent of 2021&#039;s event, new Halloween counterparts featured [[Growlithe]], [[Arcanine]], [[Koffing]], [[Weezing]], and [[Absol]].&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Halloween_Growlithe.png|Halloween [[Growlithe]]&lt;br /&gt;
File:Halloween_Arcanine.png|Halloween [[Arcanine]]&lt;br /&gt;
File:Halloween_Koffing1.png|Halloween [[Koffing]]&lt;br /&gt;
File:Halloween_Weezing.png|Halloween [[Weezing]]&lt;br /&gt;
File:3113_1.png|Halloween Galarian [[Weezing]]&lt;br /&gt;
File:Halloween_Absol.png|Halloween [[Absol]]&lt;br /&gt;
File:HalloweenAbsol_Mega.png|Halloween Mega [[Absol]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Halloween Event 2022====&lt;br /&gt;
2022&#039;s iteration of the Halloween event introduced new Halloween counterparts featuring [[Larvesta]], [[Magikarp]], [[Komala]], [[Diglett]], [[Smeargle]], [[Gligar]], [[Hawlucha]], [[Vivillon]], and their evolutions. Though, [[Scatterbug]] and [[Spewpa]] did not receive a form. Later on during the event, a second wave of Halloween-themed Pokémon were released. Those being [[Eevee]] [[Ekans]], [[Drilbur]], [[Mimikyu]], [[Buneary]], and their evolutions.&lt;br /&gt;
&#039;&#039;&#039;Part 1&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Halloween Diglett.png|Halloween [[Diglett]]&lt;br /&gt;
File:Halloween Dugtrio.png|Halloween [[Dugtrio]]&lt;br /&gt;
File:Halloween Magikarp.png|Halloween [[Magikarp]]&lt;br /&gt;
File:Halloween Gyarados.png|Halloween [[Gyarados]]&lt;br /&gt;
File:HalloweenGyarados_Mega.png|Halloween Mega [[Gyarados]]&lt;br /&gt;
File:Halloween Gligar.png|Halloween [[Gligar]]&lt;br /&gt;
File:Halloween Gliscor.png|Halloween [[Gliscor]]&lt;br /&gt;
File:Halloween Smeargle.png|Halloween [[Smeargle]]&lt;br /&gt;
File:Halloween Larvesta.png|Halloween [[Larvesta]]&lt;br /&gt;
File:Halloween Volcarona.png|Halloween [[Volcarona]]&lt;br /&gt;
File:Halloween Vivillon.png|Halloween [[Vivillon]]&lt;br /&gt;
File:Halloween Hawlucha.png|Halloween [[Hawlucha]]&lt;br /&gt;
File:Halloween Komala.png|Halloween [[Komala]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Part 2&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Halloween Ekans.png|Halloween Ekans&lt;br /&gt;
File:Halloween Arbok.png|Halloween Arbok&lt;br /&gt;
File:Halloween Eevee.png|Halloween Eevee&lt;br /&gt;
File:Halloween Vaporeon.png|Halloween Vaporeon&lt;br /&gt;
File:Halloween Jolteon.png|Halloween Jolteon&lt;br /&gt;
File:Halloween Flareon.png|Halloween Flareon&lt;br /&gt;
File:Halloween Espeon.png|Halloween Espeon&lt;br /&gt;
File:Halloween Umbreon.png|Halloween Umbreon&lt;br /&gt;
File:Halloween Buneary.png|Halloween Buneary&lt;br /&gt;
File:Halloween Lopunny.png|Halloween Lopunny&lt;br /&gt;
File:Halloween_Mega_Lopunny.png|Halloween Mega [[Lopunny]]&lt;br /&gt;
File:Halloween Leafeon.png|Halloween Leafeon&lt;br /&gt;
File:Halloween Glaceon.png|Halloween Glaceon&lt;br /&gt;
File:Halloween Drilbur.png|Halloween Drilbur&lt;br /&gt;
File:Halloween Excadrill.png|Halloween Excadrill&lt;br /&gt;
File:Halloween Sylveon.png|Halloween Sylveon&lt;br /&gt;
File:Halloween Mimikyu.png|Halloween Mimikyu&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Halloween Event 2023====&lt;br /&gt;
For the 2023 edition of the Halloween event, an unprecedented amount of forms were added. The most so far from any single event. Some of them include [[Scyther]], [[Riolu]], [[Solosis]], and [[Noibat]]. Notably, the Lake Trio([[Azelf]], [[Uxie]], [[Mesprit]]) also received forms during this event.&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:25_22.png|Halloween [[Pikachu]]&lt;br /&gt;
File:52_2.png|Halloween [[Meowth]]&lt;br /&gt;
File:53_2.png|Halloween [[Persian]]&lt;br /&gt;
File:63_3.png|Halloween [[Abra]]&lt;br /&gt;
File:64_3.png|Halloween [[Kadabra]]&lt;br /&gt;
File:65_3.png|Halloween [[Alakazam]]&lt;br /&gt;
File:3004_3.png|Halloween Mega [[Alakazam]]&lt;br /&gt;
File:66_2.png|Halloween [[Machop]]&lt;br /&gt;
File:67_2.png|Halloween [[Machoke]]&lt;br /&gt;
File:68_2.png|Halloween [[Machamp]]&lt;br /&gt;
File:Halloween Farfetch&#039;d.png|Halloween [[Farfetch&#039;d]]&lt;br /&gt;
File:Halloween Tangela.png|Halloween [[Tangela]]&lt;br /&gt;
File:Halloween Tangrowth.png|Halloween [[Tangrowth]]&lt;br /&gt;
File:439_1.png|Halloween [[Mime Jr.]]&lt;br /&gt;
File:122_1.png|Halloween [[Mr. Mime]]&lt;br /&gt;
File:3114_1.png|Halloween Galar [[Mime Jr.]]&lt;br /&gt;
File:866_1.png|Halloween [[Mr. Rime]]&lt;br /&gt;
File:Halloween Scyther.png|Halloween [[Scyther]]&lt;br /&gt;
File:Halloween Scizor.png|Halloween [[Scizor]]&lt;br /&gt;
File:Halloween Mega Scizor.png|Halloween Mega [[Scizor]]&lt;br /&gt;
File:900_3.png|Halloween [[Kleavor]]&lt;br /&gt;
File:Halloween Pinsir.png|Halloween [[Pinsir]]&lt;br /&gt;
File:Halloween Mega Pinsir.png|Halloween Mega [[Pinsir]]&lt;br /&gt;
File:Halloween Tauros.png|Halloween [[Tauros]]&lt;br /&gt;
File:446_7.png|Halloween [[Munchlax]]&lt;br /&gt;
File:143_7.png|Halloween [[Snorlax]]&lt;br /&gt;
File:Halloween Munchlax.png|Halloween [[Munchlax]]&lt;br /&gt;
File:Halloween Snorlax.png|Halloween [[Snorlax]]&lt;br /&gt;
File:Halloween Spinarak.png|Halloween [[Spinarak]]&lt;br /&gt;
File:Halloween Ariados.png|Halloween [[Ariados]]&lt;br /&gt;
File:Halloween Azurill.png|Halloween [[Azurill]]&lt;br /&gt;
File:Halloween Marill.png|Halloween [[Marill]]&lt;br /&gt;
File:Halloween Azumarill.png|Halloween [[Azumarill]]&lt;br /&gt;
File:215_2.png|Halloween [[Sneasel]]&lt;br /&gt;
File:461_2.png|Halloween [[Weavile]]&lt;br /&gt;
File:Halloween Teddiursa.png|Halloween [[Teddiursa]]&lt;br /&gt;
File:Halloween Ursaring.png|Halloween [[Ursaring]]&lt;br /&gt;
File:901_2.png|Halloween [[Ursaluna]]&lt;br /&gt;
File:3203_2.png|Halloween Bloodmoon [[Ursaluna]]&lt;br /&gt;
File:Halloween Slugma.png|Halloween [[Slugma]]&lt;br /&gt;
File:Halloween Magcargo.png|Halloween [[Magcargo]]&lt;br /&gt;
File:Halloween Swinub.png|Halloween [[Swinub]]&lt;br /&gt;
File:Halloween Piloswine.png|Halloween [[Piloswine]]&lt;br /&gt;
File:Halloween Mamoswine.png|Halloween [[Mamoswine]]&lt;br /&gt;
File:Halloween Skarmory.png|Halloween [[Skarmory]]&lt;br /&gt;
File:235_4.png|Halloween [[Smeargle]]&lt;br /&gt;
File:252_2.png|Halloween [[Treecko]]&lt;br /&gt;
File:253_2.png|Halloween [[Grovyle]]&lt;br /&gt;
File:254_2.png|Halloween [[Sceptile]]&lt;br /&gt;
File:3032_2.png|Halloween Mega [[Sceptile]]&lt;br /&gt;
File:Halloween Poochyena.png|Halloween [[Poochyena]]&lt;br /&gt;
File:Halloween Mightyena.png|Halloween [[Mightyena]]&lt;br /&gt;
File:Halloween Ralts(2023).png|Halloween [[Ralts]]&lt;br /&gt;
File:Halloween Kirlia(2023).png|Halloween [[Kirlia]]&lt;br /&gt;
File:Halloween Gardevoir(2023).png|Halloween [[Gardevoir]]&lt;br /&gt;
File:Halloween Mega Gardevoir(2023).png|Halloween Mega [[Gardevoir]]&lt;br /&gt;
File:Halloween Gallade(2023).png|Halloween [[Gallade]]&lt;br /&gt;
File:Halloween Mega Gallade(2023).png|Halloween Mega [[Gallade]]&lt;br /&gt;
File:287_1.png|Halloween [[Slakoth]]&lt;br /&gt;
File:288_1.png|Halloween [[Vigoroth]]&lt;br /&gt;
File:289_1.png|Halloween [[Slaking]]&lt;br /&gt;
File:Halloween Nincada.png|Halloween [[Nincada]]&lt;br /&gt;
File:Halloween Ninjask.png|Halloween [[Ninjask]]&lt;br /&gt;
File:Halloween Shedinja.png|Halloween [[Shedinja]]&lt;br /&gt;
File:299_1.png|Halloween [[Nosepass]]&lt;br /&gt;
File:476_1.png|Halloween [[Probopass]]&lt;br /&gt;
File:299_1f.png|Halloween Female  [[Nosepass]]&lt;br /&gt;
File:476_1f.png|Halloween Female [[Probopass]]&lt;br /&gt;
File:303_2.png|Halloween [[Mawile]]&lt;br /&gt;
File:3019_2.png|Halloween Mega [[Mawile]]&lt;br /&gt;
File:303_3.png|Halloween [[Mawile]]&lt;br /&gt;
File:3019_3.png|Halloween Mega [[Mawile]]&lt;br /&gt;
File:Halloween Aron.png|Halloween [[Aron]]&lt;br /&gt;
File:Halloween Lairon.png|Halloween [[Lairon]]&lt;br /&gt;
File:Halloween Aggron.png|Halloween [[Aggron]]&lt;br /&gt;
File:HalloweenAggron Mega.png|Halloween Mega [[Aggron]]&lt;br /&gt;
File:Halloween Plusle(Robot).png|Halloween Robot [[Plusle]]&lt;br /&gt;
File:Halloween Plusle(Devil).png|Halloween Devil [[Plusle]]&lt;br /&gt;
File:Halloween Minun(Robot).png|Halloween Robot [[Minun]]&lt;br /&gt;
File:Halloween Minun(Angel).png|Halloween Angel [[Minun]]&lt;br /&gt;
File:Halloween Cacnea.png|Halloween [[Cacnea]]&lt;br /&gt;
File:Halloween Cacturne.png|Halloween [[Cacturne]]&lt;br /&gt;
File:Halloween Lunatone.png|Halloween [[Lunatone]]&lt;br /&gt;
File:Halloween Solrock.png|Halloween [[Solrock]]&lt;br /&gt;
File:Halloween Baltoy.png|Halloween [[Baltoy]]&lt;br /&gt;
File:Halloween Claydol.png|Halloween [[Claydol]]&lt;br /&gt;
File:Halloween Kecleon(Standing).png|Halloween [[Kecleon]](Standing)&lt;br /&gt;
File:Halloween Kecleon(Riding).png|Halloween [[Kecleon]](Riding)&lt;br /&gt;
File:355_1.png|Halloween [[Duskull]]&lt;br /&gt;
File:356_1.png |Halloween [[Dusclops]]&lt;br /&gt;
File:477_1.png|Halloween [[Dusknoir]]&lt;br /&gt;
File:Halloween Chingling.png|Halloween [[Chingling]]&lt;br /&gt;
File:Halloween Chimecho.png|Halloween [[Chimecho]]&lt;br /&gt;
File:Halloween Spheal.png|Halloween [[Spheal]]&lt;br /&gt;
File:Halloween Sealeo.png|Halloween [[Sealeo]]&lt;br /&gt;
File:Halloween Walrein.png|Halloween [[Walrein]]&lt;br /&gt;
File:374_2.png|Halloween [[Beldum]]&lt;br /&gt;
File:375_2.png|Halloween [[Metang]]&lt;br /&gt;
File:376_2.png|Halloween [[Metagross]]&lt;br /&gt;
File:3040_2.png|Halloween Mega [[Metagross]]&lt;br /&gt;
File:390_2.png|Halloween [[Chimchar]]&lt;br /&gt;
File:391_2.png|Halloween [[Monferno]]&lt;br /&gt;
File:392_2.png|Halloween [[Infernape]]&lt;br /&gt;
File:Halloween Buneary(2023).png|Halloween [[Buneary]](2023)&lt;br /&gt;
File:Halloween Lopunny(2023).png|Halloween [[Lopunny]](2023)&lt;br /&gt;
File:Halloween Mega Lopunny(2023).png|Halloween Mega [[Lopunny]](2023)&lt;br /&gt;
File:Halloween Bronzor.png|Halloween [[Bronzor]]&lt;br /&gt;
File:Halloween Bronzong.png|Halloween [[Bronzong]]&lt;br /&gt;
File:Halloween Riolu.png|Halloween [[Riolu]]&lt;br /&gt;
File:Halloween Lucario.png|Halloween [[Lucario]]&lt;br /&gt;
File:Halloween Mega Lucario.png|Halloween Mega [[Lucario]]&lt;br /&gt;
File:Halloween Uxie.png|Halloween [[Uxie]]&lt;br /&gt;
File:Halloween Mesprit.png|Halloween [[Mesprit]]&lt;br /&gt;
File:Halloween Azelf.png|Halloween [[Azelf]]&lt;br /&gt;
File:501_2.png|Halloween [[Oshawott]]&lt;br /&gt;
File:502_2.png|Halloween [[Dewott]]&lt;br /&gt;
File:503_2.png |Halloween [[Samurott]]&lt;br /&gt;
File:3231_2.png|Halloween Hisuian [[Samurott]]&lt;br /&gt;
File:Halloween Throh.png|Halloween [[Throh]]&lt;br /&gt;
File:Halloween Sawk.png|Halloween [[Sawk]]&lt;br /&gt;
File:548_2.png|Halloween [[Petilil]]&lt;br /&gt;
File:549_2.png|Halloween [[Lilligant]]&lt;br /&gt;
File:3232_3.png|Halloween Hisuian [[Lilligant]]&lt;br /&gt;
File:Halloween Sandile.png|Halloween [[Sandile]]&lt;br /&gt;
File:Halloween Krokorok.png|Halloween [[Krokorok]]&lt;br /&gt;
File:Halloween Krookodile.png|Halloween [[Krookodile]]&lt;br /&gt;
File:556_1.png|Halloween [[Maractus]]&lt;br /&gt;
File:574_1.png|Halloween [[Gothita]]&lt;br /&gt;
File:575_1.png|Halloween [[Gothorita]]&lt;br /&gt;
File:576_1.png|Halloween [[Gothitelle]]&lt;br /&gt;
File:574_2.png|Halloween [[Gothita]]&lt;br /&gt;
File:575_2.png|Halloween [[Gothorita]]&lt;br /&gt;
File:576_2.png|Halloween [[Gothitelle]]&lt;br /&gt;
File:Halloween SolosisG.png|Halloween [[Solosis]] (Green)&lt;br /&gt;
File:Halloween SolosisY.png|Halloween [[Solosis]] (Yellow)&lt;br /&gt;
File:Halloween SolosisR.png|Halloween [[Solosis]] (Red)&lt;br /&gt;
File:Halloween DuosionG.png|Halloween [[Duosion]] (Green)&lt;br /&gt;
File:Halloween DuosionY.png|Halloween [[Duosion]] (Yellow)&lt;br /&gt;
File:Halloween DuosionR.png|Halloween [[Duosion]] (Red)&lt;br /&gt;
File:Halloween ReuniclusG.png|Halloween [[Reuniclus]] (Green)&lt;br /&gt;
File:Halloween ReuniclusY.png|Halloween [[Reuniclus]] (Yellow)&lt;br /&gt;
File:Halloween ReuniclusR.png|Halloween [[Reuniclus]] (Red)&lt;br /&gt;
File:Halloween Foongus.png|Halloween [[Foongus]]&lt;br /&gt;
File:Halloween Foongus 2.png|Halloween [[Foongus]]&lt;br /&gt;
File:Halloween Amoonguss.png|Halloween [[Amoonguss]]&lt;br /&gt;
File:Halloween Amoonguss 2.png|Halloween [[Amoonguss]]&lt;br /&gt;
File:Halloween Joltik.png|Halloween [[Joltik]]&lt;br /&gt;
File:Halloween Galvantula.png|Halloween [[Galvantula]]&lt;br /&gt;
File:Halloween Golett 1.png|Halloween [[Golett]]&lt;br /&gt;
File:Halloween Golett 2.png|Halloween [[Golett]]&lt;br /&gt;
File:Halloween Golurk 1.png|Halloween [[Golurk]]&lt;br /&gt;
File:Halloween Golurk 2.png|Halloween [[Golurk]]&lt;br /&gt;
File:Halloween Pawniard.png|Halloween [[Pawniard]]&lt;br /&gt;
File:Halloween Bisharp.png|Halloween [[Bisharp]]&lt;br /&gt;
File:983_3.png|Halloween [[Kingambit]]&lt;br /&gt;
File:Halloween Durant.png|Halloween [[Durant]]&lt;br /&gt;
File:Halloween Pancham.png|Halloween [[Pancham]]&lt;br /&gt;
File:Halloween Pangoro.png|Halloween [[Pangoro]]&lt;br /&gt;
File:676_1.png|Halloween Heart Trim [[Furfrou]]&lt;br /&gt;
File:676_2.png|Halloween Kabuki Trim [[Furfrou]]&lt;br /&gt;
File:676_3.png|Halloween La Reine Trim [[Furfrou]]&lt;br /&gt;
File:676_4.png|Halloween Matrom Trim [[Furfrou]]&lt;br /&gt;
File:676_5.png|Halloween Star Trim [[Furfrou]]&lt;br /&gt;
File:676_6.png|Halloween Dandy Trim [[Furfrou]]&lt;br /&gt;
File:676_7.png|Halloween Pharaoh Trim [[Furfrou]]&lt;br /&gt;
File:676_8.png|Halloween Debutante Trim [[Furfrou]]&lt;br /&gt;
File:676_9.png|Halloween Diamond Trim [[Furfrou]]&lt;br /&gt;
File:Halloween Hawlucha(2023).png|Halloween [[Hawlucha]](2023)&lt;br /&gt;
File:Halloween Noibat.png|Halloween [[Noibat]]&lt;br /&gt;
File:Halloween Noivern.png|Halloween [[Noivern]]&lt;br /&gt;
File:782_1.png|Halloween [[Jangmo-o]]&lt;br /&gt;
File:783_1.png|Halloween [[Hakamo-o]]&lt;br /&gt;
File:784_1.png|Halloween [[Kommo-o]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Halloween Event 2024====&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:4_4.png|Halloween [[Charmander]]  &lt;br /&gt;
File:5_4.png|Halloween [[Charmeleon]]  &lt;br /&gt;
File:6_4.png|Halloween [[Charizard]]&lt;br /&gt;
File:3001_4.png|Halloween Mega [[Charizard X]]&lt;br /&gt;
File:3002_4.png|Halloween Mega [[Charizard Y]]&lt;br /&gt;
File:46_2.png|Halloween [[Paras]]  &lt;br /&gt;
File:47_2.png|Halloween [[Parasect]]  &lt;br /&gt;
File:58_3.png|Halloween [[Growlithe]]  &lt;br /&gt;
File:59_3.png|Halloween [[Arcanine]]  &lt;br /&gt;
File:72_2.png|Halloween [[Tentacool]]  &lt;br /&gt;
File:73_2.png|Halloween [[Tentacruel]]  &lt;br /&gt;
File:79_2.png|Halloween [[Slowpoke]]  &lt;br /&gt;
File:80_2.png|Halloween [[Slowbro]]  &lt;br /&gt;
File:199_2.png|Halloween [[Slowking]]&lt;br /&gt;
File:3030_2.png|Halloween Mega [[Slowbro]]  &lt;br /&gt;
File:92_3.png|Halloween [[Gastly]]  &lt;br /&gt;
File:93_3.png|Halloween [[Haunter]]  &lt;br /&gt;
File:94_3.png|Halloween [[Gengar]]&lt;br /&gt;
File:3005_3.png|Halloween Mega [[Gengar]]&lt;br /&gt;
File:96_1.png|Halloween [[Drowzee]]  &lt;br /&gt;
File:97_1.png|Halloween [[Hypno]]&lt;br /&gt;
File:170_2.png|Halloween [[Chinchou]]  &lt;br /&gt;
File:171_2.png|Halloween [[Lanturn]]  &lt;br /&gt;
File:213_3.png|Halloween [[Shuckle]]  &lt;br /&gt;
File:258_3.png|Halloween [[Mudkip]]  &lt;br /&gt;
File:259_3.png|Halloween [[Marshtomp]]  &lt;br /&gt;
File:260_3.png|Halloween [[Swampert]]&lt;br /&gt;
File:3033_3.png|Halloween Mega [[Swampert]]&lt;br /&gt;
File:302_4.png|Halloween [[Sableye]]  &lt;br /&gt;
File:3034_4.png|Halloween Mega [[Sableye]]&lt;br /&gt;
File:309_2.png|Halloween [[Electrike]]  &lt;br /&gt;
File:310_2.png|Halloween [[Manectric]]&lt;br /&gt;
File:3022_2.png|Halloween Mega [[Manectric]]&lt;br /&gt;
File:322_2.png|Halloween [[Numel]]  &lt;br /&gt;
File:323_2.png|Halloween [[Camerupt]]  &lt;br /&gt;
File:3036_2.png|Halloween Mega [[Camerupt]]  &lt;br /&gt;
File:328_3.png|Halloween [[Trapinch]]  &lt;br /&gt;
File:329_3.png|Halloween [[Vibrava]]  &lt;br /&gt;
File:330_3.png|Halloween [[Flygon]]  &lt;br /&gt;
File:351_1.png|Halloween [[Castform]]&lt;br /&gt;
File:3085_1.png|Halloween Sunny [[Castform]]&lt;br /&gt;
File:3086_1.png|Halloween Rainy [[Castform]]  &lt;br /&gt;
File:3087_1.png|Halloween Snowy [[Castform]]&lt;br /&gt;
File:403_2.png|Halloween [[Shinx]]  &lt;br /&gt;
File:404_2.png|Halloween [[Luxio]]  &lt;br /&gt;
File:405_2.png|Halloween [[Luxray]]  &lt;br /&gt;
File:442_2.png|Halloween [[Spiritomb]]  &lt;br /&gt;
File:447_4.png|Halloween [[Riolu]]  &lt;br /&gt;
File:448_4.png|Halloween [[Lucario]]&lt;br /&gt;
File:3026_4.png|Halloween Mega [[Lucario]]&lt;br /&gt;
&lt;br /&gt;
File:529_2.png|Halloween [[Drilbur]]  &lt;br /&gt;
File:530_2.png|Halloween [[Excadrill]]  &lt;br /&gt;
File:532_2.png|Halloween [[Timburr]]  &lt;br /&gt;
File:533_2.png|Halloween [[Gurdurr]]  &lt;br /&gt;
File:534_2.png|Halloween [[Conkeldurr]]  &lt;br /&gt;
File:546_3.png|Halloween [[Cottonee]]  &lt;br /&gt;
File:547_3.png|Halloween [[Whimsicott]]  &lt;br /&gt;
File:587_2.png|Halloween [[Emolga]]  &lt;br /&gt;
File:702_3.png|Halloween [[Dedenne]]  &lt;br /&gt;
File:708_2.png|Halloween [[Phantump]]  &lt;br /&gt;
File:709_2.png|Halloween [[Trevenant]]  &lt;br /&gt;
File:778_4.png|Halloween [[Mimikyu]]  &lt;br /&gt;
File:3186_4.png|Halloween Busted [[Mimikyu]]  &lt;br /&gt;
File:778_4f.png|Halloween Female [[Mimikyu]]&lt;br /&gt;
File:3186_4f.png|Halloween Female Busted [[Mimikyu]]&lt;br /&gt;
File:3074_2.png|Halloween [[Alolan-Marowak]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Halloween Event 2025====&lt;br /&gt;
The 2025 Halloween event featured brand new Pokémon to PRO, such as Paldean Wooper and Hisuian Sneasel.&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Halloween Mankey.png|Halloween [[Mankey]]&lt;br /&gt;
File:Halloween Primeape.png|Halloween [[Primeape]]&lt;br /&gt;
File:Halloween Annihilape.png|Halloween [[Annihilape]]&lt;br /&gt;
File:Halloween Magnemite.png|Halloween [[Magnemite]]&lt;br /&gt;
File:Halloween Magneton.png|Halloween [[Magneton]]&lt;br /&gt;
File:Halloween Magnezone.png|Halloween [[Magnezone]]&lt;br /&gt;
File:Halloween Gastly 3.png|Halloween [[Gastly]]&lt;br /&gt;
File:Halloween Haunter 3.png|Halloween [[Haunter]]&lt;br /&gt;
File:Halloween Gengar 3.png|Halloween [[Gengar]]&lt;br /&gt;
File:Halloween Mega Gengar 3.png|Halloween Mega [[Gengar]]&lt;br /&gt;
File:Halloween Alolan Marowak 2.png|Halloween [[Alolan Marowak]]&lt;br /&gt;
File:Halloween Cyndaquil 2.png|Halloween [[Cyndaquil]]&lt;br /&gt;
File:Halloween Quilava 2.png|Halloween [[Quilava]]&lt;br /&gt;
File:Halloween Typhlosion 2.png|Halloween [[Typhlosion]]&lt;br /&gt;
File:Halloween Hisuian Typhlosion.png|Halloween Hisuian [[Typhlosion]]&lt;br /&gt;
File:Halloween Paldean Wooper.png|Halloween [[Paldean Wooper]]&lt;br /&gt;
File:Halloween Clodsire.png|Halloween [[Clodsire]]&lt;br /&gt;
File:Halloween Hisuian Sneasel.png|Halloween [[Hisuian Sneasel]]&lt;br /&gt;
File:Halloween Sneasler.png|Halloween [[Sneasler]]&lt;br /&gt;
File:Halloween Smeargle 3.png|Halloween [[Smeargle]]&lt;br /&gt;
File:Halloween Mudkip 2.png|Halloween [[Mudkip]]&lt;br /&gt;
File:Halloween Marshtomp 2.png|Halloween [[Marshtomp]]&lt;br /&gt;
File:Halloween Swampert 2.png|Halloween [[Swampert]]&lt;br /&gt;
File:Halloween Mega Swampert 2.png|Halloween Mega [[Swampert]]&lt;br /&gt;
File:Halloween Sableye 2.png|Halloween [[Sableye]]&lt;br /&gt;
File:Halloween Mega Sableye 2.png|Halloween Mega [[Sableye]]&lt;br /&gt;
File:Halloween Zangoose.png|Halloween [[Zangoose]]&lt;br /&gt;
File:Halloween Zangoose 2.png|Halloween [[Zangoose]]&lt;br /&gt;
File:Halloween Zangoose 3.png|Halloween [[Zangoose]]&lt;br /&gt;
File:Halloween Piplup.png|Halloween [[Piplup]]&lt;br /&gt;
File:Halloween Prinplup.png|Halloween [[Prinplup]]&lt;br /&gt;
File:Halloween Empoleon.png|Halloween [[Empoleon]]&lt;br /&gt;
File:Halloween Piplup 2.png|Halloween [[Piplup]]&lt;br /&gt;
File:Halloween Prinplup 2.png|Halloween [[Prinplup]]&lt;br /&gt;
File:Halloween Empoleon 2.png|Halloween [[Empoleon]]&lt;br /&gt;
File:Halloween Gible 2.png|Halloween [[Gible]]&lt;br /&gt;
File:Halloween Gabite 2.png|Halloween [[Gabite]]&lt;br /&gt;
File:Halloween Garchomp 2.png|Halloween [[Garchomp]]&lt;br /&gt;
File:Halloween Mega Garchomp 2.png|Halloween Mega [[Garchomp]]&lt;br /&gt;
File:Halloween Croagunk.png|Halloween [[Croagunk]]&lt;br /&gt;
File:Halloween Toxicroak.png|Halloween [[Toxicroak]]&lt;br /&gt;
File:Halloween Sandile 2.png|Halloween [[Sandile]]&lt;br /&gt;
File:Halloween Krokorok 2.png|Halloween [[Krokorok]]&lt;br /&gt;
File:Halloween Krookodile 2.png|Halloween [[Krookodile]]&lt;br /&gt;
File:Halloween Scraggy.png|Halloween [[Scraggy]]&lt;br /&gt;
File:Halloween Scrafty.png|Halloween [[Scrafty]]&lt;br /&gt;
File:Halloween_Golett 3.png|Halloween [[Golett]]&lt;br /&gt;
File:Halloween_Golurk 3.png|Halloween [[Golurk]]&lt;br /&gt;
File:Halloween Pancham 2.png|Halloween [[Pancham]]&lt;br /&gt;
File:Halloween Pangoro 2.png|Halloween [[Pangoro]]&lt;br /&gt;
File:Halloween Mimikyu 4.png|Halloween [[Mimikyu]]&lt;br /&gt;
File:Halloween Mimikyu Busted 4.png|Halloween [[Mimikyu]]&lt;br /&gt;
File:Halloween Guzzlord.png|Halloween [[Guzzlord]]&lt;br /&gt;
File:Halloween Blacephalon.png|Halloween [[Blacephalon]]&lt;br /&gt;
File:&lt;br /&gt;
File:&lt;br /&gt;
File:&lt;br /&gt;
File:&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Christmas-themed Pokémon===&lt;br /&gt;
For the [[2016 Christmas Event]], specially accessorized and/or colorated Pokémon versions were released for a select bevy of Pokémon. There was a 1/750 chance of encountering these counterparts in the wild. In addition to the gamut of previous-year counterparts, a new batch of them was added to the spriteset for the [[2017 Christmas Event]].&lt;br /&gt;
&lt;br /&gt;
All of the these Pokémon and their Christmas-themed sprites are shown in the alphabetized collage below.&lt;br /&gt;
&lt;br /&gt;
====Pre-2018 Christmas====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Christmas_Pikachu.png|Christmas [[Pikachu]]&lt;br /&gt;
File:Christmas_Raichu.png|Christmas [[Raichu]]&lt;br /&gt;
File:Christmas_Sandshrew.png|Christmas [[Sandshrew]]&lt;br /&gt;
File:Christmas_Sandslash.png|Christmas [[Sandslash]]&lt;br /&gt;
File:Christmas_Farfetch&#039;d.png|Christmas [[Farfetch&#039;d]]&lt;br /&gt;
File:Christmas_Sentret.png|Christmas [[Sentret]]&lt;br /&gt;
File:Christmas_Furret.png|Christmas [[Furret]]&lt;br /&gt;
File:Christmas_Stantler_2016.png|Christmas [[Stantler]] (2016)&lt;br /&gt;
File:Christmas_Stantler_2017.png|Christmas [[Stantler]] (2017)&lt;br /&gt;
File:899_1.png|Christmas [[Wyrdeer]] (2024)&lt;br /&gt;
File:899_2.png|Christmas [[Wyrdeer]] (2024)&lt;br /&gt;
File:Christmas_Skitty.png|Christmas [[Skitty]]&lt;br /&gt;
File:Christmas_Delcatty.png|Christmas [[Delcatty]]&lt;br /&gt;
File:Christmas_Swablu.png|Christmas [[Swablu]]&lt;br /&gt;
File:Christmas_Altaria.png|Christmas [[Altaria]]&lt;br /&gt;
File:XmasAltaria_Mega.png|Christmas Mega [[Altaria]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Christmas Event 2018====&lt;br /&gt;
During Christmas 2018, a total of 9 Pokémon families were given a Christmas counterpart while certain other Pokémon were not made available as Christmas Pokémon again. The chances to find one were 1/1000. Additionally, Christmas themed [[Manaphy]] was a reward from the main quest that year. &lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Christmas_Vulpix.png|Christmas [[Vulpix]]&lt;br /&gt;
File:Christmas_Ninetales.png|Christmas [[Ninetales]]&lt;br /&gt;
File:Christmas_Eevee.png|Christmas [[Eevee]]&lt;br /&gt;
File:Christmas_Vaporeon.png|Christmas [[Vaporeon]]&lt;br /&gt;
File:Christmas_Jolteon.png|Christmas [[Jolteon]]&lt;br /&gt;
File:Christmas_Flareon.png|Christmas [[Flareon]]&lt;br /&gt;
File:Christmas_Espeon.png|Christmas [[Espeon]]&lt;br /&gt;
File:Christmas_Umbreon.png|Christmas [[Umbreon]]&lt;br /&gt;
File:Christmas_Leafeon.png|Christmas [[Leafeon]]&lt;br /&gt;
File:Christmas_Glaceon.png|Christmas [[Glaceon]]&lt;br /&gt;
File:Christmas_Sylveon.png|Christmas [[Sylveon]]&lt;br /&gt;
File:Christmas_Dratini.png|Christmas [[Dratini]]&lt;br /&gt;
File:Christmas_Dragonair.png|Christmas [[Dragonair]]&lt;br /&gt;
File:Christmas_Dragonite.png|Christmas [[Dragonite]]&lt;br /&gt;
File:Christmas_Mareep.png|Christmas [[Mareep]]&lt;br /&gt;
File:Christmas_Flaaffy.png|Christmas [[Flaaffy]]&lt;br /&gt;
File:Christmas_Ampharos.png|Christmas [[Ampharos]]&lt;br /&gt;
File:XmasAmpharos_Mega.png|Christmas Mega [[Ampharos]]&lt;br /&gt;
File:Christmas_Treecko.png|Christmas [[Treecko]]&lt;br /&gt;
File:Christmas_Grovyle.png|Christmas [[Grovyle]]&lt;br /&gt;
File:Christmas_Sceptile.png|Christmas [[Sceptile]]&lt;br /&gt;
File:XmasSceptile_Mega.png|Christmas Mega [[Sceptile]]&lt;br /&gt;
File:Christmas_Torchic.png|Christmas [[Torchic]]&lt;br /&gt;
File:Christmas_Combusken.png|Christmas [[Combusken]]&lt;br /&gt;
File:Christmas_Blaziken.png|Christmas [[Blaziken]]&lt;br /&gt;
File:3017_1.png|Christmas Mega [[Blaziken]]&lt;br /&gt;
File:Christmas_Mudkip.png|Christmas [[Mudkip]]&lt;br /&gt;
File:Christmas_Marshtomp.png|Christmas [[Marshtomp]]&lt;br /&gt;
File:Christmas_Swampert.png|Christmas [[Swampert]]&lt;br /&gt;
File:XmasSwampert_Mega.png|Christmas Mega [[Swampert]]&lt;br /&gt;
File:Christmas_Ralts.png|Christmas [[Ralts]]&lt;br /&gt;
File:Christmas_Kirlia.png|Christmas [[Kirlia]]&lt;br /&gt;
File:Christmas_Gardevoir.png|Christmas [[Gardevoir]]&lt;br /&gt;
File:XmasGardevoir_Mega.png|Christmas Mega [[Gardevoir]]&lt;br /&gt;
File:Christmas_Gallade.png|Christmas [[Gallade]]&lt;br /&gt;
File:XmasGallade_Mega.png|Christmas Mega [[Gallade]]&lt;br /&gt;
File:Christmas_Snorunt.png|Christmas [[Snorunt]]&lt;br /&gt;
File:Christmas_Glalie.png|Christmas [[Glalie]]&lt;br /&gt;
File:XmasGlalie_Mega.png|Christmas Mega [[Glalie]]&lt;br /&gt;
File:Christmas_Froslass.png|Christmas [[Froslass]]&lt;br /&gt;
File:Christmas_Manaphy.png|Christmas [[Manaphy]]&lt;br /&gt;
File:Christmas_Litwick.png|Christmas [[Litwick]]&lt;br /&gt;
File:Christmas_Lampent.png|Christmas [[Lampent]]&lt;br /&gt;
File:Christmas_Chandelure.png|Christmas [[Chandelure]]&lt;br /&gt;
File:Christmas_Axew.png|Christmas [[Axew]]&lt;br /&gt;
File:Christmas_Fraxure.png|Christmas [[Fraxure]]&lt;br /&gt;
File:Christmas_Haxorus.png|Christmas [[Haxorus]]&lt;br /&gt;
File:Christmas_Dedenne.png|Christmas [[Dedenne]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Christmas Event 2019====&lt;br /&gt;
During Christmas 2019, a total of 7 Pokémon families were given a Christmas counterpart and 5 Pokémon family&#039;s sprites were reworked. Those being: [[Riolu]], [[Munchlax]], [[Buneary]], [[Snover]], [[Teddiursa]], and all their evolutions. The Christmas form chance was 1/750. Additionally, a Christmas themed version of [[Kyurem]] was obtainable by completing the main quest that year.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Christmas_Psyduck.png|Christmas [[Psyduck]]&lt;br /&gt;
File:Christmas_Golduck.png|Christmas [[Golduck]]&lt;br /&gt;
File:Christmas_Tentacool.png|Christmas [[Tentacool]]&lt;br /&gt;
File:Christmas_Tentacruel.png|Christmas [[Tentacruel]]&lt;br /&gt;
File:Christmas_Munchlax2019.png|Christmas [[Munchlax]] 2019&lt;br /&gt;
File:Christmas_Snorlax2019.png|Christmas [[Snorlax]] 2019&lt;br /&gt;
File:Christmas_Smoochum.png|Christmas [[Smoochum]]&lt;br /&gt;
File:Christmas_Jynx.png|Christmas [[Jynx]]&lt;br /&gt;
File:Christmas_Elekid.png|Christmas [[Elekid]]&lt;br /&gt;
File:Christmas_Electabuzz.png|Christmas [[Electabuzz]]&lt;br /&gt;
File:Christmas_Electivire.png|Christmas [[Electivire]]&lt;br /&gt;
File:Christmas_Magby.png|Christmas [[Magby]]&lt;br /&gt;
File:Christmas_Magmar.png|Christmas [[Magmar]]&lt;br /&gt;
File:Christmas_Magmortar.png|Christmas [[Magmortar]]&lt;br /&gt;
File:Christmas_Teddiursa2019.png|Christmas [[Teddiursa]] 2019&lt;br /&gt;
File:Christmas_Ursaring2019.png|Christmas [[Ursaring]] 2019&lt;br /&gt;
File:901_1.png|Christmas [[Ursaluna]]&lt;br /&gt;
File:3203_1.png|Christmas Bloodmoon [[Ursaluna]]&lt;br /&gt;
File:Christmas_Houndour.png|Christmas [[Houndour]]&lt;br /&gt;
File:Christmas_Houndoom.png|Christmas [[Houndoom]]&lt;br /&gt;
File:XmasHoundoom_Mega.png|Christmas Mega [[Houndoom]]&lt;br /&gt;
File:Christmas_Azurill.png|Christmas [[Azurill]]&lt;br /&gt;
File:Christmas_Marill.png|Christmas [[Marill]]&lt;br /&gt;
File:Christmas_Azumarill.png|Christmas [[Azumarill]]&lt;br /&gt;
File:Christmas_Sableye.png|Christmas [[Sableye]]&lt;br /&gt;
File:SableyeChristmasMega.png|Christmas Mega [[Sableye]]&lt;br /&gt;
File:Christmas_Buneary2019.png|Christmas [[Buneary]] 2019&lt;br /&gt;
File:Christmas_Lopunny2019.png|Christmas [[Lopunny]] 2019&lt;br /&gt;
File:XmasLopunny_Mega.png|Christmas Mega [[Lopunny]]&lt;br /&gt;
File:Christmas_Riolu2019.png|Christmas [[Riolu]] 2019&lt;br /&gt;
File:Christmas_Lucario2019.png|Christmas [[Lucario]] 2019&lt;br /&gt;
File:XmasLucario_Mega.png|Christmast Mega [[Lucario]]&lt;br /&gt;
File:Christmas_Snover2019.png|Christmas [[Snover]] 2019&lt;br /&gt;
File:Christmas_Abomasnow2019.png|Christmas [[Abomasnow]] 2019&lt;br /&gt;
File:XmasAbomasnow_Mega.png|Christmas Mega [[Abomasnow]]&lt;br /&gt;
File:Christmas_Kyurem.png|Christmas [[Kyurem]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Christmas Event 2020====&lt;br /&gt;
During Christmas 2020, 2 new Pokémon families were given a Christmas counterpart [[Ferroseed]], [[Numel]], and their evolutions. The Christmas form chance was not revealed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Christmas_Numel.png|Christmas [[Numel]]&lt;br /&gt;
File:Christmas_Camerupt.png|Christmas [[Camerupt]]&lt;br /&gt;
File:Christmas_Camerupt_Mega.png|Christmas Mega [[Camerupt]]&lt;br /&gt;
File:Christmas_Ferroseed.png|Christmas [[Ferroseed]]&lt;br /&gt;
File:Christmas_Ferrothorn.png|Christmas [[Ferrothorn]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Christmas Event 2021====&lt;br /&gt;
During Christmas 2021, several Pokémon families were given a Christmas counterparts, along with the rework of Christmas [[Sableye]]. The Christmas form chance was not revealed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Christmas_Staryu.png|Christmas [[Staryu]]&lt;br /&gt;
File:Christmas_Starmie.png|Christmas [[Starmie]]&lt;br /&gt;
File:Christmas_Spheal.png|Christmas [[Spheal]]&lt;br /&gt;
File:Christmas_Sealeo.png|Christmas [[Sealeo]]&lt;br /&gt;
File:Christmas_Walrein.png|Christmas [[Walrein]]&lt;br /&gt;
File:Christmas_Smeargle.png|Christmas [[Smeargle]]&lt;br /&gt;
File:Christmas_Mawile.png|Christmas [[Mawile]]&lt;br /&gt;
File:XmasMawile_Mega.png|Christmas Mega [[Mawile]]&lt;br /&gt;
File:Christmas_Sableye2021.png|Christmas [[Sableye]] 2021&lt;br /&gt;
File:Christmas_Mega_Sableye.png|Christmas Mega [[Sableye]]&lt;br /&gt;
File:Christmas_Pachirisu.png|Christmas [[Pachirisu]]&lt;br /&gt;
File:Christmas_Emolga.png|Christmas [[Emolga]]&lt;br /&gt;
File:Christmas_Cottonee.png|Christmas [[Cottonee]]&lt;br /&gt;
File:Christmas_Whimsicott.png|Christmas [[Whimsicott]]&lt;br /&gt;
File:Christmas_Lillipup.png|Christmas [[Lillipup]]&lt;br /&gt;
File:Christmas_Herdier.png|Christmas [[Herdier]]&lt;br /&gt;
File:Christmas_Stoutland.png|Christmas [[Stoutland]]&lt;br /&gt;
File:Christmas_Deerling.png|Christmas [[Deerling]]&lt;br /&gt;
File:Christmas_Sawsbuck.png|Christmas [[Sawsbuck]]&lt;br /&gt;
File:Christmas_Petilil.png|Christmas [[Petilil]]&lt;br /&gt;
File:Christmas_Lilligant.png|Christmas [[Lilligant]]&lt;br /&gt;
File:3232_1.png|Christmas Hisuian [[Lilligant]]&lt;br /&gt;
File:Christmas_Cubchoo.png|Christmas [[Cubchoo]]&lt;br /&gt;
File:Christmas_Beartic.png|Christmas [[Beartic]]&lt;br /&gt;
File:Reshiram_Christmas_Sprite.png|Christmas [[Reshiram]]&lt;br /&gt;
File:Zekrom_Christmas_Sprite.png|Christmas [[Zekrom]]&lt;br /&gt;
File:Christmas_Goomy.png|Christmas [[Goomy]]&lt;br /&gt;
File:Christmas_Sliggoo.png|Christmas [[Sliggoo]]&lt;br /&gt;
File:Christmas_Goodra.png|Christmas [[Goodra]]&lt;br /&gt;
File:3236_1.png|Christmas Hisuian [[Sliggoo]]&lt;br /&gt;
File:3237_1.png|Christmas Hisuian [[Goodra]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Christmas Event 2022====&lt;br /&gt;
For the 2022 edition of the Christmas event, many Pokémon were given a form, including: [[Dunsparce]], [[Delibird]], [[Wailmer]], [[Beldum]], [[Espurr]], and their evolutions.&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:XmasDunsparce.png|Christmas [[Dunsparce]]&lt;br /&gt;
File:982_1.png|Christmas 2 Segment [[Dudunsparce]]&lt;br /&gt;
File:3292_1.png|Christmas 3 Segment [[Dudunsparce]]&lt;br /&gt;
File:ChristmasDelibird.png|Christmas [[Delibird]]&lt;br /&gt;
File:ChristmasWailmer.png|Christmas [[Wailmer]]&lt;br /&gt;
File:ChristmasWailord.png|Christmas [[Wailord]]&lt;br /&gt;
File:ChristmasBeldum.png|Christmas [[Beldum]]&lt;br /&gt;
File:ChristmasMetang.png|Christmas [[Metang]]&lt;br /&gt;
File:ChristmasMetagross.png|Christmas [[Metagross]]&lt;br /&gt;
File:Christmas_Mega_Metagross.png|Christmas Mega [[Metagross]]&lt;br /&gt;
File:ChristmasEspurr.png|Christmas [[Espurr]]&lt;br /&gt;
File:ChristmasMeowstic-F.png|Christmas [[Meowstic]]-F&lt;br /&gt;
File:ChristmasMeowstic-M.png|Christmas [[Meowstic]]-M&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Christmas Event 2023====&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:1_3.png|Christmas [[Bulbasaur]]&lt;br /&gt;
File:2_3.png|Christmas [[Ivysaur]]&lt;br /&gt;
File:3_3.png|Christmas [[Venusaur]]&lt;br /&gt;
File:3000_3.png|Christmas Mega [[Venusaur]]&lt;br /&gt;
File:4_3.png|Christmas [[Charmander]]&lt;br /&gt;
File:5_3.png|Christmas [[Charmeleon]]&lt;br /&gt;
File:6_3.png|Christmas [[Charizard]]&lt;br /&gt;
File:3001_3.png|Christmas Mega [[Charizard]] X&lt;br /&gt;
File:3002_3.png|Christmas Mega [[Charizard]] Y&lt;br /&gt;
File:7_4.png|Christmas [[Squirtle]]&lt;br /&gt;
File:8_4.png|Christmas [[Wartortle]]&lt;br /&gt;
File:9_4.png|Christmas [[Blastoise]]&lt;br /&gt;
File:3003_4.png|Christmas Mega [[Blastoise]]&lt;br /&gt;
File:41_1.png|Christmas [[Zubat]]&lt;br /&gt;
File:42_1.png|Christmas [[Golbat]]&lt;br /&gt;
File:169_1.png|Christmas [[Crobat]]&lt;br /&gt;
File:58_2.png|Christmas [[Growlithe]]&lt;br /&gt;
File:59_2.png|Christmas [[Arcanine]]&lt;br /&gt;
File:63_4.png|Christmas [[Abra]]&lt;br /&gt;
File:64_4.png|Christmas [[Kadabra]]&lt;br /&gt;
File:65_4.png|Christmas [[Alakazam]]&lt;br /&gt;
File:3004_4.png|Christmas Mega [[Alakazam]]&lt;br /&gt;
File:133_3.png|Christmas [[Eevee]]&lt;br /&gt;
File:134_3.png|Christmas [[Vaporeon]]&lt;br /&gt;
File:135_3.png|Christmas [[Jolteon]]&lt;br /&gt;
File:136_3.png|Christmas [[Flareon]]&lt;br /&gt;
File:196_3.png|Christmas [[Espeon]]&lt;br /&gt;
File:197_3.png|Christmas [[Umbreon]]&lt;br /&gt;
File:470_3.png|Christmas [[Leafeon]]&lt;br /&gt;
File:471_3.png|Christmas [[Glaceon]]&lt;br /&gt;
File:700_3.png|Christmas [[Sylveon]]&lt;br /&gt;
File:177_2.png|Christmas [[Natu]]&lt;br /&gt;
File:178_2.png|Christmas [[Xatu]]&lt;br /&gt;
File:201_28.png|Christmas [[Unown]] A&lt;br /&gt;
File:201_29.png|Christmas [[Unown]] B&lt;br /&gt;
File:201_30.png|Christmas [[Unown]] C&lt;br /&gt;
File:201_31.png|Christmas [[Unown]] D&lt;br /&gt;
File:201_32.png|Christmas [[Unown]] E&lt;br /&gt;
File:201_33.png|Christmas [[Unown]] F&lt;br /&gt;
File:201_34.png|Christmas [[Unown]] G&lt;br /&gt;
File:201_35.png|Christmas [[Unown]] H&lt;br /&gt;
File:201_36.png|Christmas [[Unown]] I&lt;br /&gt;
File:201_37.png|Christmas [[Unown]] J&lt;br /&gt;
File:201_38.png|Christmas [[Unown]] K&lt;br /&gt;
File:201_39.png|Christmas [[Unown]] L&lt;br /&gt;
File:201_40.png|Christmas [[Unown]] M&lt;br /&gt;
File:201_41.png|Christmas [[Unown]] N&lt;br /&gt;
File:201_42.png|Christmas [[Unown]] O&lt;br /&gt;
File:201_43.png|Christmas [[Unown]] P&lt;br /&gt;
File:201_44.png|Christmas [[Unown]] Q&lt;br /&gt;
File:201_45.png|Christmas [[Unown]] R&lt;br /&gt;
File:201_46.png|Christmas [[Unown]] S&lt;br /&gt;
File:201_47.png|Christmas [[Unown]] T&lt;br /&gt;
File:201_48.png|Christmas [[Unown]] U&lt;br /&gt;
File:201_49.png|Christmas [[Unown]] V&lt;br /&gt;
File:201_50.png|Christmas [[Unown]] W&lt;br /&gt;
File:201_51.png|Christmas [[Unown]] X&lt;br /&gt;
File:201_52.png|Christmas [[Unown]] Y&lt;br /&gt;
File:201_53.png|Christmas [[Unown]] Z&lt;br /&gt;
File:201_54.png|Christmas [[Unown]] !&lt;br /&gt;
File:201_55.png|Christmas [[Unown]] ?&lt;br /&gt;
File:213_2.png|Christmas [[Shuckle]] &lt;br /&gt;
File:220_1.png|Christmas [[Swinub]] &lt;br /&gt;
File:221_1.png|Christmas [[Piloswine]] &lt;br /&gt;
File:473_1.png|Christmas [[Mamoswine]] &lt;br /&gt;
File:431_1.png|Christmas [[Glameow]] &lt;br /&gt;
File:432_1.png|Christmas [[Purugly]] &lt;br /&gt;
File:441_1.png|Christmas [[Chatot]] &lt;br /&gt;
File:442_1.png|Christmas [[Spiritomb]] &lt;br /&gt;
File:443_3.png|Christmas [[Gible]] &lt;br /&gt;
File:444_3.png|Christmas [[Gabite]] &lt;br /&gt;
File:445_3.png|Christmas [[Garchomp]] &lt;br /&gt;
File:3025_3.png|Christmas Mega [[Garchomp]] &lt;br /&gt;
File:455_1.png|Christmas [[Carnivine]] &lt;br /&gt;
File:531_1.png|Christmas [[Audino]] &lt;br /&gt;
File:3047_1.png|Christmas Mega [[Audino]] &lt;br /&gt;
File:532_1.png|Christmas [[Timburr]] &lt;br /&gt;
File:533_1.png|Christmas [[Gurdurr]] &lt;br /&gt;
File:534_1.png|Christmas [[Conkeldurr]] &lt;br /&gt;
File:570_1.png|Christmas [[Zorua]] &lt;br /&gt;
File:571_1.png|Christmas [[Zoroark]] &lt;br /&gt;
File:624_4.png|Christmas [[Pawniard]] &lt;br /&gt;
File:625_4.png|Christmas [[Bisharp]] &lt;br /&gt;
File:983_4.png|Christmas [[Kingambit]]&lt;br /&gt;
File:633_1.png|Christmas [[Deino]] &lt;br /&gt;
File:634_1.png|Christmas [[Zweilous]] &lt;br /&gt;
File:635_1.png|Christmas [[Hydreigon]] &lt;br /&gt;
File:708_1.png|Christmas [[Phantump]] &lt;br /&gt;
File:709_1.png|Christmas [[Trevenant]] &lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Christmas Event 2024====&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:131_4.png|Christmas [[Lapras]]  &lt;br /&gt;
File:132_1.png|Christmas [[Ditto]]   &lt;br /&gt;
File:174_1.png|Christmas [[Igglybuff]]&lt;br /&gt;
File:39_1.png|Christmas [[Jigglypuff]]  &lt;br /&gt;
File:40_1.png|Christmas [[Wigglytuff]]  &lt;br /&gt;
File:258_4.png|Christmas [[Mudkip]]  &lt;br /&gt;
File:259_4.png|Christmas [[Marshtomp]]  &lt;br /&gt;
File:260_4.png|Christmas [[Swampert]]&lt;br /&gt;
File:3033_4.png|Christmas Mega [[Swampert]]   &lt;br /&gt;
File:335_3.png|Christmas [[Zangoose]]  &lt;br /&gt;
File:341_1.png|Christmas [[Corphish]]  &lt;br /&gt;
File:342_1.png|Christmas [[Crawdaunt]]    &lt;br /&gt;
File:418_1.png|Christmas [[Buizel]]  &lt;br /&gt;
File:418_1f.png|Christmas Female [[Buizel]]  &lt;br /&gt;
File:419_1.png|Christmas [[Floatzel]]  &lt;br /&gt;
File:419_1f.png|Christmas Female [[Floatzel]]  &lt;br /&gt;
File:451_1.png|Christmas [[Skorupi]]  &lt;br /&gt;
File:452_1.png|Christmas [[Drapion]]  &lt;br /&gt;
File:495_3.png|Christmas [[Snivy]]  &lt;br /&gt;
File:496_3.png|Christmas [[Servine]]&lt;br /&gt;
File:497_3.png|Christmas [[Serperior]]  &lt;br /&gt;
File:495_4.png|Christmas Shiny [[Snivy]]    &lt;br /&gt;
File:496_4.png|Christmas Shiny [[Servine]]  &lt;br /&gt;
File:497_4.png|Christmas Shiny [[Serperior]]  &lt;br /&gt;
File:546_4.png|Christmas [[Cottonee]]  &lt;br /&gt;
File:547_4.png|Christmas [[Whimsicott]]  &lt;br /&gt;
File:619_1.png|Christmas [[Mienfoo]]  &lt;br /&gt;
File:619_1f.png|Christmas Female [[Mienfoo]]  &lt;br /&gt;
File:620_1.png|Christmas [[Mienshao]]  &lt;br /&gt;
File:620_1f.png|Christmas Female [[Mienshao]]  &lt;br /&gt;
File:636_3.png|Christmas [[Larvesta]]  &lt;br /&gt;
File:637_3.png|Christmas [[Volcarona]]  &lt;br /&gt;
File:744_1.png|Christmas [[Rockruff]]  &lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Christmas Event 2025====&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:10_2.png|Christmas [[Caterpie]]&lt;br /&gt;
File:11_2.png|Christmas [[Metapod]]&lt;br /&gt;
File:12_2.png|Christmas  [[Butterfree]]&lt;br /&gt;
File:3257_2.png|Christmas Gigantamax [[Butterfree]]&lt;br /&gt;
File:23_2.png|Christmas  [[Ekans]]&lt;br /&gt;
File:24_2.png|Christmas  [[Arbok]]&lt;br /&gt;
File:90_2.png|Christmas  [[Shellder]]&lt;br /&gt;
File:91_2.png|Christmas  [[Cloyster]]&lt;br /&gt;
File:155_4.png|Christmas  [[Cyndaquil]]&lt;br /&gt;
File:156_4.png|Christmas  [[Quilava]]&lt;br /&gt;
File:157_4.png|Christmas  [[Typhlosion]]&lt;br /&gt;
File:3228_4.png|Christmas Hisui [[Typhlosion]]&lt;br /&gt;
File:241_1.png|Christmas [[Miltank]]&lt;br /&gt;
File:270_2.png|Christmas  [[Lotad]]&lt;br /&gt;
File:271_2.png|Christmas  [[Lombre]]&lt;br /&gt;
File:272_2.png|Christmas  [[Ludicolo]]&lt;br /&gt;
File:561_1.png|Christmas  [[Sigilyph]]&lt;br /&gt;
File:624_5.png|Christmas  [[Pawniard]]&lt;br /&gt;
File:625_5.png|Christmas  [[Bisharp]]&lt;br /&gt;
File:983_5.png|Christmas  [[Kingambit]]&lt;br /&gt;
File:656_3.png|Christmas  [[Froakie]]&lt;br /&gt;
File:657_3.png|Christmas  [[Frogadier]]&lt;br /&gt;
File:658_3.png|Christmas  [[Greninja]]&lt;br /&gt;
File:3044_3.png|Christmas Ash [[Greninja]]&lt;br /&gt;
File:3303_3.png|Christmas Mega [[Greninja]]&lt;br /&gt;
File:714_2.png|Christmas  [[Noibat]]&lt;br /&gt;
File:715_2.png|Christmas  [[Noivern]]&lt;br /&gt;
File:821_1.png|Christmas  [[Rookidee]]&lt;br /&gt;
File:822_1.png|Christmas  [[Corvisquire]]&lt;br /&gt;
File:823_1.png|Christmas  [[Corviknight]]&lt;br /&gt;
File:3268_1.png|Christmas Gigantamax [[Corviknight]]&lt;br /&gt;
File:856_1.png|Christmas  [[Hatenna]]&lt;br /&gt;
File:857_1.png|Christmas  [[Hattrem]]&lt;br /&gt;
File:858_1.png|Christmas  [[Hatterene]]&lt;br /&gt;
File:957_1.png|Christmas  [[Tinkatink]]&lt;br /&gt;
File:958_1.png|Christmas  [[Tinkatuff]]&lt;br /&gt;
File:959_1.png|Christmas  [[Tinkaton]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Pikachu World Quest event form===&lt;br /&gt;
During the 2020 Christmas event, 2 [[World Quest]]s were held which required the user to hunt Pikachu. During this sub-event [[Pikachu]] received 12 new huntable forms.&amp;lt;br&amp;gt;&lt;br /&gt;
During the 2021 Christmas event, the same 12 [[Pikachu]] forms were released for a pair of [[World Quest]]s.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Pikachu 1.png&lt;br /&gt;
File:Pikachu 2.png&lt;br /&gt;
File:Pikachu 3.png&lt;br /&gt;
File:Pikachu 4.png&lt;br /&gt;
File:Pikachu 5.png&lt;br /&gt;
File:Pikachu 6.png&lt;br /&gt;
File:Pikachu 7.png&lt;br /&gt;
File:Pikachu 8.png&lt;br /&gt;
File:Pikachu 9.png&lt;br /&gt;
File:Pikachu 10.png&lt;br /&gt;
File:Pikachu 11.png&lt;br /&gt;
File:Pikachu 12.png&lt;br /&gt;
File:25_16.png&lt;br /&gt;
File:25_17.png&lt;br /&gt;
File:25_24.png&lt;br /&gt;
File:25_25.png&lt;br /&gt;
File:25_26.png&lt;br /&gt;
File:25_27.png&lt;br /&gt;
File:25_28.png&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Unobtainable Forms===&lt;br /&gt;
The following forms are not obtainable at this time.&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:151_1.png|Halloween [[Mew]]&lt;br /&gt;
File:Christmas_Arceus.png|Christmas [[Arceus]]&lt;br /&gt;
File:745_1.png|Christmas [[Lycanroc]]&lt;br /&gt;
File:3091_1.png|Christmas Dusk [[Lycanroc]]&lt;br /&gt;
File:3092_1.png|Christmas Midnight [[Lycanroc]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Halloween Druddigons are part of the 2024 Halloween questline but were never made available to players.&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:621_1.png|Halloween Infernal [[Druddigon]]  &lt;br /&gt;
File:621_2.png|Halloween Cloud [[Druddigon]]  &lt;br /&gt;
File:621_3.png|Halloween Mountain [[Druddigon]]  &lt;br /&gt;
File:621_4.png|Halloween Ocean [[Druddigon]]  &lt;br /&gt;
File:621_5.png|Halloween Chemtech [[Druddigon]]  &lt;br /&gt;
File:621_6.png|Halloween Hextech [[Druddigon]]  &lt;br /&gt;
File:621_7.png|Halloween Elder [[Druddigon]]  &lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Mega Pokémon==&lt;br /&gt;
{{Main|Mega Pokémon#Gallery|Mega Pokémon}}&lt;br /&gt;
&lt;br /&gt;
Mega Evolutions are temporary in-battle metamorphoses available to some Pokémon. In addition to greater base stats and a reassigned Ability, Mega Evolutions transform the Pokémon&#039;s appearance, typically into a bigger, maturer form.&lt;br /&gt;
&lt;br /&gt;
Following their implementation in 2020, Mega Pokémon were retroactively added to event-themed spritesets where applicable. For example, the Mega Evolutions of [[Venusaur]], [[Charizard]], and [[Blastoise]] were given clone counterparts to coalesce with the rest of their respective evolutionary trees.&lt;br /&gt;
&lt;br /&gt;
For a comprehensive showcase of all Mega Pokémon sprites, refer to the such-named article aforelinked.&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Bug_Catching_Contest_(Multiplayer)&amp;diff=41057</id>
		<title>Bug Catching Contest (Multiplayer)</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Bug_Catching_Contest_(Multiplayer)&amp;diff=41057"/>
		<updated>2026-08-08T18:42:00Z</updated>

		<summary type="html">&lt;p&gt;Cae: added grubin and dewpider&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Area|Type=Forest|Region=Johto|Location=National Park}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;{{PAGENAME}}&#039;&#039;&#039; is a [[Johto]] area exclusive to the Bug Catching Contest in [[National Park]]. Due to the contest&#039;s cooldown, the multiplayer version of the Bug Catching Contest can only be accessed for 60 minutes every Saturday, making it difficult to hunt for a specific Pokémon. However, the rewards from the contest makes coming back worthwhile. &#039;&#039;&#039;This mini-event takes place every Saturday at either 10:00 GMT+0 or 22:00 GMT+0&#039;&#039;&#039;. Additionally, based on your location and the time of the year, this time may be shifted one hour ahead due to DST. Furthermore, 30 minutes before the contest begins, there will be an in-game system message informing players that it will begin soon.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==[[Bug Catching Contest]]==&lt;br /&gt;
Not to be confused with the [[Bug Catching Area|Bug Catching Contest (Single)]], the Multiplayer Bug Catching Contest is a weekly activity where the player is given 60 minutes to hunt and submit [[Bug (type)|Bug]] type Pokémon found within the [[Bug Catching Area]]. They must be of the correct nature and ability, else they will not be accepted and scored. The winners are determined by the submissions of the highest scores. Scores are determined by rarity and [[IVs]]. To submit a Pokémon, you simply have to speak with the Bug Catching Expert and show your Pokémon. He will tell you the score of your Pokémon and its current placement in the leaderboard. You can submit as many Pokémon as you&#039;d like, but only your highest score will be used. Below is a table that denotes the acceptable natures and ability combinations for each Pokémon that can be submitted to the Expert Bug Catcher:&lt;br /&gt;
{{PokemonTableAbNat|Contents=&lt;br /&gt;
{{PTANRow|Pokemon=Burmy|Ab=Overcoat,Shed Skin|Nat=Adamant,Calm,Careful,Impish,Mild,Modest,Rash,Relaxed,Sassy,Timid}}&lt;br /&gt;
{{PTANRow|Pokemon=Caterpie|Ab=Run Away,Shield Dust|Nat=Timid}}&lt;br /&gt;
{{PTANRow|Pokemon=Combee|Ab=Honey Gather|Nat=Bold,Calm,Careful,Impish,Relaxed,Sassy,Timid}}&lt;br /&gt;
{{PTANRow|Pokemon=Cutiefly|Ab=Shield Dust|Nat=Timid}}&lt;br /&gt;
{{PTANRow|Pokemon=Dwebble|Ab=Sturdy,Weak Armor|Nat=Adamant,Hasty,Jolly,Lonely,Naive,Naughty}}&lt;br /&gt;
{{PTANRow|Pokemon=Heracross|Ab=Guts,Moxie,Swarm|Nat=Adamant,Brave,Jolly}}&lt;br /&gt;
{{PTANRow|Pokemon=Illumise|Ab=Prankster,Tinted Lens|Nat=Bold,Impish,Modest,Relaxed,Timid}}&lt;br /&gt;
{{PTANRow|Pokemon=Joltik|Ab=Compound Eyes|Nat=Timid}}&lt;br /&gt;
{{PTANRow|Pokemon=Kricketot|Ab=Run Away,Shed Skin|Nat=Jolly}}&lt;br /&gt;
{{PTANRow|Pokemon=Larvesta|Ab=Flame Body,Swarm|Nat=Bold,Modest,Timid}}&lt;br /&gt;
{{PTANRow|Pokemon=Ledyba|Ab=Early Bird,Rattled,Swarm|Nat=Adamant,Jolly}}&lt;br /&gt;
{{PTANRow|Pokemon=Nincada|Ab=Compound Eyes|Nat=Adamant,Hasty,Jolly,Lonely,Naive,Naughty}}&lt;br /&gt;
{{PTANRow|Pokemon=Paras|Ab=Dry Skin|Nat=Careful,Impish}}&lt;br /&gt;
{{PTANRow|Pokemon=Pinsir|Ab=Hyper Cutter,Mold Breaker,Moxie|Nat=Adamant,Jolly}}&lt;br /&gt;
{{PTANRow|Pokemon=Scatterbug|Ab=Compound Eyes|Nat=Modest,Timid}}&lt;br /&gt;
{{PTANRow|Pokemon=Scyther|Ab=Steadfast,Swarm,Technician|Nat=Adamant,Careful,Impish,Jolly,Relaxed,Sassy}}&lt;br /&gt;
{{PTANRow|Pokemon=Spinarak|Ab=Insomnia,Swarm|Nat=Adamant,Jolly}}&lt;br /&gt;
{{PTANRow|Pokemon=Venonat|Ab=Tinted Lens|Nat=Bold,Modest,Timid}}&lt;br /&gt;
{{PTANRow|Pokemon=Volbeat|Ab=Prankster|Nat=Bold,Impish,Relaxed}}&lt;br /&gt;
{{PTANRow|Pokemon=Weedle|Ab=Run Away,Shield Dust|Nat=Adamant,Jolly}}&lt;br /&gt;
{{PTANRow|Pokemon=Wurmple|Ab=Run Away,Shield Dust|Nat=Bold,Calm,Careful,Timid}}&lt;br /&gt;
{{PTANRow|Pokemon=Yanma|Ab=Compound Eyes,Speed Boost|Nat=Modest,Timid}}&lt;br /&gt;
{{PTANRow|Pokemon=Grubbin|Ab=Swarm|Nat=Modest, Quiet}}&lt;br /&gt;
{{PTANRow|Pokemon=Dewpider|Ab=Water Bubble|Nat=Adamant, Modest, Quiet, Impish}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Once the competition is over, scores will be tallied and the Bug Catching Expert will give you your results along with the corresponding rewards.&lt;br /&gt;
&lt;br /&gt;
==Prizes==&lt;br /&gt;
Below are the prizes that are handed out after the contest ends. If you did not submit any bug with a correct nature or ability, you will not be eligible for any rewards. If you submitted a bug, but did not place in the Top 25, you will be rewarded with 3 [[PvE Coins]].&lt;br /&gt;
===Top 3===&lt;br /&gt;
Players that finish in the top 3 will receive the following rewards:&lt;br /&gt;
*50 [[PvE Coins]]&lt;br /&gt;
*20 [[Rare Candy]]&lt;br /&gt;
*10 [[PP Up]]&lt;br /&gt;
*3 bundles of x10 [[Berries]] from the following assortment: Babiri Berry, Charti Berry, Chilan Berry, Chople Berry, Coba Berry, Colbur Berry, Haban Berry, Kasib Berry, Kebia Berry, Occa Berry, Passho Berry, Payapa Berry, Rindo Berry, Roseli Berry, Shuca Berry, Tanga Berry, Wacan Berry, Yache Berry, Apicot Berry, Ganlon Berry, Liechi Berry, Petaya Berry, Starf Berry&lt;br /&gt;
*An instantly-used 7-day [[Transit Pass]]&lt;br /&gt;
*An untradeable 24-hour [[Safari Pass]]&lt;br /&gt;
*A chance at one of three cosmetics: Combee, Scizor Mask, Pinsir Horns, or Shedinja Halo&lt;br /&gt;
*An exclusive [[Jirachi]] form&lt;br /&gt;
===Top 10===&lt;br /&gt;
Players that finish in the top 10 will receive the following rewards:&lt;br /&gt;
*35 [[PvE Coins]]&lt;br /&gt;
*20 [[Rare Candy]]&lt;br /&gt;
*10 [[PP Up]]&lt;br /&gt;
*An instantly-used 7-day [[Transit Pass]]&lt;br /&gt;
*3 bundles of x10 [[Berries]] from the following assortment: Babiri Berry, Charti Berry, Chilan Berry, Chople Berry, Coba Berry, Colbur Berry, Haban Berry, Kasib Berry, Kebia Berry, Occa Berry, Passho Berry, Payapa Berry, Rindo Berry, Roseli Berry, Shuca Berry, Tanga Berry, Wacan Berry, Yache Berry, Apicot Berry, Ganlon Berry, Liechi Berry, Petaya Berry, Starf Berry&lt;br /&gt;
&lt;br /&gt;
===Top 15===&lt;br /&gt;
Players that finish in the top 15 will receive the following rewards:&lt;br /&gt;
*20 [[PvE Coins]]&lt;br /&gt;
*20 [[Rare Candy]]&lt;br /&gt;
*10 [[PP Up]]&lt;br /&gt;
*An untradeable 24-hour [[Safari Pass]]&lt;br /&gt;
*3 bundles of x10 [[Berries]] from the following assortment: Babiri Berry, Charti Berry, Chilan Berry, Chople Berry, Coba Berry, Colbur Berry, Haban Berry, Kasib Berry, Kebia Berry, Occa Berry, Passho Berry, Payapa Berry, Rindo Berry, Roseli Berry, Shuca Berry, Tanga Berry, Wacan Berry, Yache Berry, Apicot Berry, Ganlon Berry, Liechi Berry, Petaya Berry, Starf Berry&lt;br /&gt;
===Top 25===&lt;br /&gt;
Players that finish in the top 25 will receive the following rewards:&lt;br /&gt;
*10 [[PvE Coins]]&lt;br /&gt;
*20 [[Rare Candy]]&lt;br /&gt;
*10 [[PP Up]]&lt;br /&gt;
*3 bundles of x10 [[Berries]] from the following assortment: Babiri Berry, Charti Berry, Chilan Berry, Chople Berry, Coba Berry, Colbur Berry, Haban Berry, Kasib Berry, Kebia Berry, Occa Berry, Passho Berry, Payapa Berry, Rindo Berry, Roseli Berry, Shuca Berry, Tanga Berry, Wacan Berry, Yache Berry, Apicot Berry, Ganlon Berry, Liechi Berry, Petaya Berry, Starf Berry&lt;br /&gt;
&lt;br /&gt;
==Spawns==&lt;br /&gt;
===Land===&lt;br /&gt;
{{AreaLandSpawns|Location=Bug Catching Area}}&lt;br /&gt;
[[Category:Repeatable tasks]]&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Legendary_Pok%C3%A9mon&amp;diff=41048</id>
		<title>Legendary Pokémon</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Legendary_Pok%C3%A9mon&amp;diff=41048"/>
		<updated>2026-08-04T18:48:51Z</updated>

		<summary type="html">&lt;p&gt;Cae: new Legendary Template + Module&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;b&amp;gt;Legendary Pokémon&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;Mythical Pokémon&amp;lt;/b&amp;gt; are groups of Pokémon which are unique, existentially rare, and transcendently powerful. These Pokémon are mostly only catchable once and entail special requirements for their catchability. &lt;br /&gt;
&lt;br /&gt;
Legendary and Mythical Pokémon in [[Pokémon_Revolution_Online|PRO]] are not as distinctly differentiable as they are in the official games, and Mythical Pokémon are often colloquially termed as Legendaries. &lt;br /&gt;
&lt;br /&gt;
=Fundamental Facts=&lt;br /&gt;
&lt;br /&gt;
• Legendary Pokémon are shiny-locked at their spawns.&lt;br /&gt;
&lt;br /&gt;
• They are only catchable once with the exception of [[Phione]] and [[Birth Island]] spawns&lt;br /&gt;
&lt;br /&gt;
• These Pokémon are the only type of Pokémon whose [[Individual_Values|Individual Values]] and [[Nature]] can be rerolled with the help of [[Reroll_Ticket|Reroll Tickets]] and [[Natures#Nature_Reroll_Ticket|Nature Reroll Tickets]].&lt;br /&gt;
&lt;br /&gt;
• Unlike other Pokémon, Legendary and Mythical Pokémon can not be traded to other players.&lt;br /&gt;
&lt;br /&gt;
=Typologies=&lt;br /&gt;
==Legendary Pokémon==&lt;br /&gt;
===Individuals===&lt;br /&gt;
{{LegendaryPokemon|Name=Mewtwo|Requirements=Mewtwo is currently uncatchable. However, it can still be battled to register its seen-data and rebattled to register its caught-data entry on the [[Pokédex]]}}&lt;br /&gt;
{{LegendaryPokemon|Name=Regigigas|Requirements=Regigigas is currently uncatchable; however, it can still be battled to register its seen-data entry on the [[Pokédex]].}}&lt;br /&gt;
{{LegendaryPokemon|Name=Heatran|Requirements=Trainers can catchably battle Heatran upon defeating Commander Mars within [[Stark Mountain]], which entails penultimate completion of the [[Heatran (quest)]].}}&lt;br /&gt;
{{LegendaryPokemon|Name=Cresselia|Requirements=Trainers can catchably battle Cresselia upon completion of the [[Cresselia (quest)]].}}&lt;br /&gt;
===Duos===&lt;br /&gt;
The term &#039;&#039;&#039;Legendary duos&#039;&#039;&#039; refers to a diptych of intragenerational Pokémon. Members of each pair have either a diametrical or complementary relationship.&lt;br /&gt;
{{LegendaryPokemon|Name=Tower duo|Requirements=They are currently uncatchable. However, they can still be battled to register their seen-data and rebattled to register their caught-data entry on the [[Pokédex]].|Pokemon=Lugia\Ho-Oh}}&lt;br /&gt;
&lt;br /&gt;
{{LegendaryPokemon|Name=Eon Pokémon|Requirements=Completion of the [[Latios &amp;amp; Latias (quest)]] or access to [[Birth Island]] (where they&#039;re extremely rare spawns).|Pokemon=Latias\Latios}}&lt;br /&gt;
&lt;br /&gt;
{{LegendaryPokemon|Name=Hero of Many Battles|Requirements=They are currently uncatchable.|Pokemon=Zacian\Zamazenta}}&lt;br /&gt;
===Trios===&lt;br /&gt;
The term &#039;&#039;&#039;Legendary trios&#039;&#039;&#039; refers to a triptych of intragenerational Pokémon. Members of each trio share an equal BST of 580, have a different type, and entail the same quest for their catchability.&lt;br /&gt;
Only one of the members of each trio is catchable during their quest, with the exception of the Legendary Birds and the Forces of Nature. The remaining members of each trio can be encountered and caught on [[Birth Island]].&lt;br /&gt;
&lt;br /&gt;
{{LegendaryPokemon|Name=Legendary Birds|Requirements=All three of the Birds are catchable upon completion of the [[Legendary Birds (quest)|Legendary Birds quest]].|Pokemon=Articuno\Zapdos\Moltres}}&lt;br /&gt;
&lt;br /&gt;
{{LegendaryPokemon|Name=Legendary Beasts|Requirements=One of the Beasts is catchable upon defeating a [[Legendary Guardians|Legendary Guardian]] after obtention of the required Beast Bell, with a 16.6% chance (100% upon the third-consecutive defeat) of encountering the corresponding Legendary Beast. Beast Bells are selectable partway through the [[Legendary Beasts (quest)]] and are changeable contingent that the trainer hasn&#039;t encountered any of the Beasts yet. The remaining two are a possible spawn at [[Birth Island]].|Pokemon=Raikou\Entei\Suicune}}&lt;br /&gt;
&lt;br /&gt;
{{LegendaryPokemon|Name=Legendary Titans|Requirements=One of the Titans is selectably catchable once upon unlocking the Ancient Tomb, which entails completion of the [[Legendary Titans (quest)|Legendary Titans quest]] and the respective Titan Key (obtained during the quest). The remaining two are a possible spawn at [[Birth Island]].|Pokemon=Regirock\Regice\Registeel}}&lt;br /&gt;
&lt;br /&gt;
{{LegendaryPokemon|Name=Weather Trio|Requirements=They are currently uncatchable. However, they can still be battled to register their seen-data and rebattled to register their caught-data entry on the [[Pokédex]].|Pokemon=Kyogre\Groudon\Rayquaza}}&lt;br /&gt;
&lt;br /&gt;
{{LegendaryPokemon|Name=Lake Guardians|Requirements=One of the Guardians is catchable upon completion of the [[Lake Trio (quest)|Lake Trio quest]]. The remaining two are a possible spawn at [[Birth Island]].|Pokemon=Uxie\Mesprit\Azelf}}&lt;br /&gt;
&lt;br /&gt;
{{LegendaryPokemon|Name=Creation Trio|Requirements=They are currently uncatchable.|Pokemon=Dialga\Palkia\Giratina}}&lt;br /&gt;
&lt;br /&gt;
{{LegendaryPokemon|Name=Swords of Justice|Requirements=One of them is catchable upon completion of the [[Swords of Justice (quest)]].|Pokemon=Cobalion\Terrakion\Virizion}}&lt;br /&gt;
&lt;br /&gt;
{{LegendaryPokemon|Name=Forces of Nature|Requirements=Completion of the [[Forces of Nature (quest)|Forces of Nature quest]].|Pokemon=Tornadus\Thundurus\Landorus}}&lt;br /&gt;
&lt;br /&gt;
{{LegendaryPokemon|Name=Tao Trio|Requirements=Completion of the [[Kyurem (quest)]]. Zekrom and Reshiram are both obtainable via the [[Zekrom and Reshiram (quest)|Zekrom and Reshiram quest]].|Pokemon=Zekrom\Reshiram\Kyurem}}&lt;br /&gt;
&lt;br /&gt;
{{LegendaryPokemon|Name=Light Trio|Requirements=Lunala &amp;amp; Solgaleo are both catchable through [[Birth Island]]. Necrozma is currently not catchable.|Pokemon=Lunala\Solgaleo\Necrozma}}&lt;br /&gt;
&lt;br /&gt;
===Quartets===&lt;br /&gt;
{{LegendaryPokemon|Name=Tapu Guardians|Requirements=Currently not catchable|Pokemon=Tapu Koko\Tapu Lele\Tapu Bulu\Tapu Fini}}&lt;br /&gt;
==Mythical Pokémon==&lt;br /&gt;
{{LegendaryPokemon|Name=Mew|Requirements=Catchable upon completion of the [[Mew (quest)]].}}&lt;br /&gt;
{{LegendaryPokemon|Name=Baby XD001|Requirements=Catchable upon completion of the [[Baby XD001 (quest)]]}}&lt;br /&gt;
{{LegendaryPokemon|Name=Celebi|Requirements=Catchable upon completion of the [[Celebi (quest)]].}}&lt;br /&gt;
{{LegendaryPokemon|Name=Jirachi|Requirements=Catchable upon completion of the [[Jirachi (quest)]].}}&lt;br /&gt;
{{LegendaryPokemon|Name=Deoxys|Requirements=Currently uncatchable.}}&lt;br /&gt;
{{LegendaryPokemon|Name=Phione|Requirements=25% chance of spawning after defeating [[BattleBot (boss)|BattleBot]].}}&lt;br /&gt;
{{LegendaryPokemon|Name=Manaphy|Requirements=Catchable upon completion of the [[Manaphy (quest)]].}}&lt;br /&gt;
{{LegendaryPokemon|Name=Darkrai|Requirements=Catchable upon completion of the [[Darkrai (quest)]] during the Halloween event.}}&lt;br /&gt;
{{LegendaryPokemon|Name=Shaymin|Requirements=Catchable upon completion of the [[Shaymin (quest)]] during the Easter event.}}&lt;br /&gt;
{{LegendaryPokemon|Name=Arceus|Requirements=Currently uncatchable.}}&lt;br /&gt;
{{LegendaryPokemon|Name=Victini|Requirements={{PAGENAME}} is obtainable through a dungeon quest ([[Crater Town]]).}}&lt;br /&gt;
{{LegendaryPokemon|Name=Keldeo|Requirements=Catchable upon completion of the [[Keldeo (quest)]]}}&lt;br /&gt;
{{LegendaryPokemon|Name=Meloetta|Requirements=Catchable after clearing the [[Crux of Melody (Dungeon)]].}}&lt;br /&gt;
{{LegendaryPokemon|Name=Genesect|Requirements=Catchable upon completion of the [[Genesect (quest)]].}}&lt;br /&gt;
{{LegendaryPokemon|Name=Diancie|Requirements=Catchable upon completion of the [[Diancie (quest)]].}}&lt;br /&gt;
{{LegendaryPokemon|Name=Hoopa|Requirements=Catchable after clearing the [[Scattered Realm (Dungeon)]].}}&lt;br /&gt;
{{LegendaryPokemon|Name=Volcanion|Requirements=Catchable upon completion of the [[Volcanion (quest)]].}}&lt;br /&gt;
&lt;br /&gt;
==Pseudo-Legendary Pokémon==&lt;br /&gt;
Pseudo-Legendary Pokémon are comparably powerful but heterotypic to conventional Legendary Pokémon. Pseudo-Legends have a triphasic evolutionary line, a 600 BST when fully evolved, and are limitlessly obtainable.&lt;br /&gt;
&lt;br /&gt;
=See also=&lt;br /&gt;
*[[Birth Island]]&lt;br /&gt;
&lt;br /&gt;
=External Links=&lt;br /&gt;
*[https://bulbapedia.bulbagarden.net/wiki/Mythical_Pok%C3%A9mon Bulbapedia]&lt;br /&gt;
*[https://pokemonrevolution.net/forum/topic/261642-legendary-megathread// Legendary Megathread]&lt;br /&gt;
[[Category:Pokémon]] [[Category:Legendary Pokémon]]&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Template:LegendaryPokemon&amp;diff=41047</id>
		<title>Template:LegendaryPokemon</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Template:LegendaryPokemon&amp;diff=41047"/>
		<updated>2026-08-04T18:47:38Z</updated>

		<summary type="html">&lt;p&gt;Cae: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;Unified template for Legendary/Mythical Pokémon cards — handles both a single Pokémon and a group of up to 5 (duo/trio/quartet/quintet) with one call.&lt;br /&gt;
===Individuals===&lt;br /&gt;
{{LegendaryPokemon|Name=Mewtwo|Requirements=Mewtwo is currently uncatchable. However, it can still be battled to register its seen-data and rebattled to register its caught-data entry on the [[Pokédex]]}}&lt;br /&gt;
===Duos===&lt;br /&gt;
{{LegendaryPokemon|Name=Tower duo|Requirements=They are currently uncatchable. However, they can still be battled to register their seen-data and rebattled to register their caught-data entry on the [[Pokédex]].|Pokemon=Lugia\Ho-Oh}}&lt;br /&gt;
===Trios===&lt;br /&gt;
{{LegendaryPokemon|Name=Legendary Birds|Requirements=All three of the Birds are catchable upon completion of the [[Legendary Birds (quest)|Legendary Birds quest]].|Pokemon=Articuno\Zapdos\Moltres}}&lt;br /&gt;
===Quartets===&lt;br /&gt;
{{LegendaryPokemon|Name=Tapu Guardians|Requirements=Currently not catchable|Pokemon=Tapu Koko\Tapu Lele\Tapu Bulu\Tapu Fini}}&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Raw Data Lists]]&lt;br /&gt;
&amp;lt;includeonly&amp;gt;{{#invoke:LegendaryPokemon|card}}&amp;lt;/includeonly&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Module:LegendaryPokemon&amp;diff=41046</id>
		<title>Module:LegendaryPokemon</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Module:LegendaryPokemon&amp;diff=41046"/>
		<updated>2026-08-04T18:45:59Z</updated>

		<summary type="html">&lt;p&gt;Cae: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {}&lt;br /&gt;
&lt;br /&gt;
local DATA_FORMAT = &#039;CSV with header&#039;&lt;br /&gt;
local STAT_MAX = 255&lt;br /&gt;
local ROMAN = { &#039;I&#039;, &#039;II&#039;, &#039;III&#039;, &#039;IV&#039;, &#039;V&#039;, &#039;VI&#039;, &#039;VII&#039;, &#039;VIII&#039;, &#039;IX&#039; }&lt;br /&gt;
&lt;br /&gt;
local function nonEmpty(s)&lt;br /&gt;
	if s == nil then return nil end&lt;br /&gt;
	s = mw.text.trim(tostring(s))&lt;br /&gt;
	if s == &#039;&#039; then return nil end&lt;br /&gt;
	return s&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local pokemonRowsCache = nil&lt;br /&gt;
local function pokemonByName()&lt;br /&gt;
	if pokemonRowsCache then return pokemonRowsCache end&lt;br /&gt;
	local csvData = mw.ext.externalData.getExternalData{&lt;br /&gt;
		url = &#039;https://wiki.pokemonrevolution.net/index.php?title=Special:GetData/PokemonRawList&#039;,&lt;br /&gt;
		format = DATA_FORMAT,&lt;br /&gt;
		data = {&lt;br /&gt;
			number = &#039;Pokedex Number&#039;, name = &#039;Name&#039;, type1 = &#039;Type1&#039;, type2 = &#039;Type2&#039;, generation = &#039;Generation&#039;,&lt;br /&gt;
			hp = &#039;HP&#039;, atk = &#039;Attack&#039;, def = &#039;Defense&#039;, spatk = &#039;Special Attack&#039;, spdef = &#039;Special Defense&#039;,&lt;br /&gt;
			spd = &#039;Speed&#039;,&lt;br /&gt;
		},&lt;br /&gt;
	}&lt;br /&gt;
	pokemonRowsCache = {}&lt;br /&gt;
	if csvData then&lt;br /&gt;
		for _, row in ipairs(csvData) do&lt;br /&gt;
			if nonEmpty(row.name) then&lt;br /&gt;
				pokemonRowsCache[row.name] = row&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return pokemonRowsCache&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local typeColorCache = {}&lt;br /&gt;
local function typeColor(frame, pokeType)&lt;br /&gt;
	pokeType = nonEmpty(pokeType) or &#039;Normal&#039;&lt;br /&gt;
	if not typeColorCache[pokeType] then&lt;br /&gt;
		typeColorCache[pokeType] = {&lt;br /&gt;
			light = frame:expandTemplate{ title = pokeType .. &#039; color light&#039; },&lt;br /&gt;
			base = frame:expandTemplate{ title = pokeType .. &#039; color&#039; },&lt;br /&gt;
			dark = frame:expandTemplate{ title = pokeType .. &#039; color dark&#039; },&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
	return typeColorCache[pokeType]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local regionNameCache = {}&lt;br /&gt;
local function regionForGen(frame, genRoman)&lt;br /&gt;
	if not regionNameCache[genRoman] then&lt;br /&gt;
		regionNameCache[genRoman] = frame:expandTemplate{ title = &#039;LegendaryRegionFromGen&#039;, args = { genRoman } }&lt;br /&gt;
	end&lt;br /&gt;
	return regionNameCache[genRoman]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local regionColorCache = {}&lt;br /&gt;
local function regionColor(frame, regionName)&lt;br /&gt;
	if not regionColorCache[regionName] then&lt;br /&gt;
		regionColorCache[regionName] = {&lt;br /&gt;
			light = frame:expandTemplate{ title = regionName .. &#039; color light&#039; },&lt;br /&gt;
			base = frame:expandTemplate{ title = regionName .. &#039; color&#039; },&lt;br /&gt;
			dark = frame:expandTemplate{ title = regionName .. &#039; color dark&#039; },&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
	return regionColorCache[regionName]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function genToRoman(genValue)&lt;br /&gt;
	local digits = mw.ustring.match(tostring(genValue or &#039;&#039;), &#039;^%d+&#039;)&lt;br /&gt;
	local n = digits and tonumber(digits)&lt;br /&gt;
	return (n and ROMAN[n]) or tostring(genValue or &#039;&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Same 3-column shape as Module:Pokemon&#039;s statBarRow: a nowrap label that&lt;br /&gt;
-- only takes the width its own text needs, a bar column pinned to width:&lt;br /&gt;
-- 100% that soaks up all the leftover space, and a small fixed-width value&lt;br /&gt;
-- column after it -- rather than forcing the label into a fixed 40%, which&lt;br /&gt;
-- is what was crowding the bar and making the whole row look right-heavy.&lt;br /&gt;
local function statBar(frame, label, value, dark)&lt;br /&gt;
	value = tonumber(value) or 0&lt;br /&gt;
	local pct = math.floor(value / STAT_MAX * 100 + 0.5)&lt;br /&gt;
	if pct &amp;lt; 2 then pct = 2 end&lt;br /&gt;
	if pct &amp;gt; 100 then pct = 100 end&lt;br /&gt;
	local hue = math.floor(math.max(0, math.min(180, value * 180 / STAT_MAX)) + 0.5) -- red (low) -&amp;gt; teal (high)&lt;br /&gt;
	local fill = &#039;hsl(&#039; .. hue .. &#039;, 85%, 45%)&#039;&lt;br /&gt;
	return &#039;&amp;lt;tr&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;text-align: right; padding: 2px 6px 2px 2px; font-weight: bold; font-size: 10px; &#039; ..&lt;br /&gt;
		&#039;color: #&#039; .. dark .. &#039;; white-space: nowrap;&amp;quot;&amp;gt;&#039; .. label .. &#039;&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;width: 100%; padding: 2px 0;&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;background-color: #FFFFFF; border: 1px solid &#039; ..&lt;br /&gt;
		&#039;#999999; border-radius: 8px; height: 12px; overflow: hidden;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;div style=&amp;quot;width: &#039; .. pct .. &#039;%; height: 100%; background-color: &#039; .. fill .. &#039;;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;text-align: left; padding: 2px 2px 2px 6px; font-weight: bold; font-size: 10px; &#039; ..&lt;br /&gt;
		&#039;width: 28px;&amp;quot;&amp;gt;&#039; .. value .. &#039;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Cells are forced to an even 50/50 split (rather than sizing to content) so&lt;br /&gt;
-- a longer type name -- &amp;quot;Fighting&amp;quot; next to &amp;quot;Psychic&amp;quot;, say -- can&#039;t crowd the&lt;br /&gt;
-- other cell into overflowing; text is still free to wrap onto a second&lt;br /&gt;
-- line at that width rather than being clipped. border: none resets both&lt;br /&gt;
-- tables below to kill a default wiki-skin table border that was otherwise&lt;br /&gt;
-- showing through as an unstyled brownish line around this part of the card.&lt;br /&gt;
local function typeBadges(frame, row)&lt;br /&gt;
	local t1 = nonEmpty(row.type1)&lt;br /&gt;
	local t2 = nonEmpty(row.type2)&lt;br /&gt;
	local c1 = typeColor(frame, t1)&lt;br /&gt;
	if not t2 then&lt;br /&gt;
		return &#039;&amp;lt;table align=&amp;quot;center&amp;quot; style=&amp;quot;width: 80%; border: none; border-collapse: collapse; &#039; ..&lt;br /&gt;
			&#039;font-weight: bold; font-size: 12px;&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&#039; ..&lt;br /&gt;
			&#039;&amp;lt;td style=&amp;quot;background-color: #&#039; .. c1.dark .. &#039;; border-radius: 15px; padding: 2px;&amp;quot;&amp;gt;[[&#039; .. t1 ..&lt;br /&gt;
			&#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. t1 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	local c2 = typeColor(frame, t2)&lt;br /&gt;
	return &#039;&amp;lt;table align=&amp;quot;center&amp;quot; style=&amp;quot;width: 80%; table-layout: fixed; border: none; border-collapse: collapse; &#039; ..&lt;br /&gt;
		&#039;font-weight: bold; font-size: 12px;&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;width: 50%; box-sizing: border-box; background-color: #&#039; .. c1.dark ..&lt;br /&gt;
		&#039;; border-radius: 15px 1px 1px 15px; padding: 2px; overflow-wrap: break-word;&amp;quot;&amp;gt;[[&#039; ..&lt;br /&gt;
		t1 .. &#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. t1 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;width: 50%; box-sizing: border-box; background-color: #&#039; .. c2.dark ..&lt;br /&gt;
		&#039;; border-radius: 1px 15px 15px 1px; padding: 2px; overflow-wrap: break-word;&amp;quot;&amp;gt;[[&#039; ..&lt;br /&gt;
		t2 .. &#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. t2 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function memberCard(frame, name, showGeneration)&lt;br /&gt;
	local row = pokemonByName()[name]&lt;br /&gt;
	if not row then&lt;br /&gt;
		return &#039;&amp;lt;div style=&amp;quot;flex: 1 1 220px; width: 100%; box-sizing: border-box; margin: 4px; color: red;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
			&#039;Data load error: No Pokémon data found for &#039; .. name .. &#039;&amp;lt;/div&amp;gt;&#039;, nil&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local c = typeColor(frame, row.type1)&lt;br /&gt;
	local bst = (tonumber(row.hp) or 0) + (tonumber(row.atk) or 0) + (tonumber(row.def) or 0) +&lt;br /&gt;
		(tonumber(row.spatk) or 0) + (tonumber(row.spdef) or 0) + (tonumber(row.spd) or 0)&lt;br /&gt;
&lt;br /&gt;
	local genLine = &#039;&#039;&lt;br /&gt;
	if showGeneration then&lt;br /&gt;
		local genRoman = genToRoman(row.generation)&lt;br /&gt;
		genLine = &#039;&amp;lt;br&amp;gt;&amp;lt;span style=&amp;quot;font-size: 11px;&amp;quot;&amp;gt;[[:Category:Generation &#039; .. genRoman ..&lt;br /&gt;
			&#039; Pokémon|&amp;lt;span style=&amp;quot;color: #&#039; .. c.dark .. &#039;;&amp;quot;&amp;gt;Generation &#039; .. genRoman .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- flex: grows/shrinks within a group&#039;s flex row (220px basis); width:&lt;br /&gt;
	-- 100% takes over instead when this card is the sole content of a&lt;br /&gt;
	-- block-level parent (a single-Pokémon entry) -- flex properties are&lt;br /&gt;
	-- simply inert outside of a flex container, so both rules can coexist.&lt;br /&gt;
	local buf = {}&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;flex: 1 1 220px; width: 100%; min-width: 0; box-sizing: border-box; margin: 4px; &#039; ..&lt;br /&gt;
		&#039;background-color: #&#039; .. c.base .. &#039;; border: 3px solid #&#039; .. c.dark ..&lt;br /&gt;
		&#039;; border-radius: 20px; padding: 6px; text-align: center; color: #&#039; .. c.dark .. &#039;; font-weight: bold;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;background-color: #&#039; .. c.light .. &#039;; border-radius: 15px; padding: 5px; &#039; ..&lt;br /&gt;
		&#039;margin-bottom: 6px;&amp;quot;&amp;gt;#&#039; .. (row.number or &#039;&#039;) .. &#039;&amp;amp;nbsp;&amp;lt;span style=&amp;quot;font-size: 16px;&amp;quot;&amp;gt;[[&#039; .. name ..&lt;br /&gt;
		&#039;|&amp;lt;span style=&amp;quot;color: #&#039; .. c.dark .. &#039;;&amp;quot;&amp;gt;&#039; .. name .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/span&amp;gt;&#039; .. genLine .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- 150x150px (not just 150px) fits the sprite *within* a 150x150 box on&lt;br /&gt;
	-- whichever dimension is the constraint, instead of only fixing width&lt;br /&gt;
	-- and leaving height to the image&#039;s own aspect ratio -- a tall/narrow&lt;br /&gt;
	-- sprite was overflowing the fixed-height box under the old |150px form.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;background-color: #FFFFFF; border-radius: 15px; height: 150px; overflow: hidden; &#039; ..&lt;br /&gt;
		&#039;display: flex; align-items: center; justify-content: center; margin-bottom: 6px;&amp;quot;&amp;gt;[[File:&#039; ..&lt;br /&gt;
		(row.number or &#039;&#039;) .. name .. &#039;.png|150x150px]]&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = typeBadges(frame, row)&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;table style=&amp;quot;width: 100%; border: none; border-collapse: collapse; margin-top: 6px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		statBar(frame, &#039;HP&#039;, row.hp, c.dark) ..&lt;br /&gt;
		statBar(frame, &#039;Attack&#039;, row.atk, c.dark) ..&lt;br /&gt;
		statBar(frame, &#039;Defense&#039;, row.def, c.dark) ..&lt;br /&gt;
		statBar(frame, &#039;Sp. Atk&#039;, row.spatk, c.dark) ..&lt;br /&gt;
		statBar(frame, &#039;Sp. Def&#039;, row.spdef, c.dark) ..&lt;br /&gt;
		statBar(frame, &#039;Speed&#039;, row.spd, c.dark) ..&lt;br /&gt;
		&#039;&amp;lt;/table&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;text-align: center; margin-top: 4px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;div style=&amp;quot;display: inline-block; background-color: #FFFFFF; border: 1px solid #&#039; .. c.dark ..&lt;br /&gt;
		&#039;; padding: 2px 10px; border-radius: 10px; font-size: 11px;&amp;quot;&amp;gt;Total: &#039; .. bst .. &#039;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
	return table.concat(buf), row&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- width: 100% + border-box is the actual fix here: without a constrained&lt;br /&gt;
-- width, a long Requirements sentence has no wrap point to size against, so&lt;br /&gt;
-- the inline-block ancestor&#039;s shrink-to-fit layout stretches the *whole&lt;br /&gt;
-- card* to fit that one line instead of wrapping text inside a fixed box.&lt;br /&gt;
local function requirementsBox(dark, requirements)&lt;br /&gt;
	return &#039;&amp;lt;div style=&amp;quot;width: 100%; box-sizing: border-box; background-color: #FFFFFF; color: #000000; &#039; ..&lt;br /&gt;
		&#039;border-radius: 15px; font-weight: normal; text-align: left; border: 1px solid #&#039; .. dark ..&lt;br /&gt;
		&#039;; padding: 8px; margin-top: 4px; overflow-wrap: break-word;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		(requirements or &#039;&#039;) .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.card(frame)&lt;br /&gt;
	local parent = frame:getParent()&lt;br /&gt;
	local args = (parent and parent.args) or frame.args&lt;br /&gt;
&lt;br /&gt;
	local name = nonEmpty(args.Name)&lt;br /&gt;
	if not name then&lt;br /&gt;
		return &amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;Usage: {{LegendaryPokemon|Name=...|Requirements=...|&amp;quot; ..&lt;br /&gt;
			&amp;quot;Pokemon=Name1\\Name2 (omit Pokemon= for a single-species entry)}}&amp;lt;/span&amp;gt;&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local pokemonArg = nonEmpty(args.Pokemon)&lt;br /&gt;
	local members = {}&lt;br /&gt;
	if pokemonArg then&lt;br /&gt;
		for _, part in ipairs(mw.text.split(pokemonArg, &#039;\\&#039;, true)) do&lt;br /&gt;
			local trimmed = mw.text.trim(part)&lt;br /&gt;
			if trimmed ~= &#039;&#039; then&lt;br /&gt;
				members[#members + 1] = trimmed&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		members = { name }&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local requirements = args.Requirements or &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
	if #members == 1 then&lt;br /&gt;
		local cardHtml, row = memberCard(frame, members[1], true)&lt;br /&gt;
		if not row then&lt;br /&gt;
			return cardHtml&lt;br /&gt;
		end&lt;br /&gt;
		local c = typeColor(frame, row.type1)&lt;br /&gt;
		-- 50% width, matching the original single-Pokémon template&#039;s own&lt;br /&gt;
		-- width: 50% -- two of these sit side by side and together span&lt;br /&gt;
		-- the full row. calc() leaves room for this wrapper&#039;s own margin&lt;br /&gt;
		-- (and the small whitespace gap browsers render between adjacent&lt;br /&gt;
		-- inline-block elements from separate template calls) so two&lt;br /&gt;
		-- actually fit per row at true 50/50 instead of the second one&lt;br /&gt;
		-- wrapping early. Still immune to the Requirements-text sizing bug:&lt;br /&gt;
		-- width is a definite percentage of the page column, not&lt;br /&gt;
		-- shrink-to-fit, so a long sentence just wraps instead of stretching it.&lt;br /&gt;
		return &#039;&amp;lt;div style=&amp;quot;display: inline-block; vertical-align: top; box-sizing: border-box; &#039; ..&lt;br /&gt;
			&#039;width: calc(50% - 10px); background-color: #&#039; .. c.base .. &#039;; border: 1px solid #&#039; .. c.dark ..&lt;br /&gt;
			&#039;; border-radius: 22px; padding: 4px; margin: 5px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
			cardHtml .. requirementsBox(c.dark, requirements) .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local firstRow = pokemonByName()[members[1]]&lt;br /&gt;
	local genRoman = nonEmpty(args.Gen) or (firstRow and genToRoman(firstRow.generation)) or &#039;?&#039;&lt;br /&gt;
	local regionName = regionForGen(frame, genRoman)&lt;br /&gt;
	local rc = regionColor(frame, regionName)&lt;br /&gt;
&lt;br /&gt;
	local cardsHtml = {}&lt;br /&gt;
	for _, member in ipairs(members) do&lt;br /&gt;
		local cardHtml = memberCard(frame, member, false)&lt;br /&gt;
		cardsHtml[#cardsHtml + 1] = cardHtml&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Full width, block-level -- matches the original group template&#039;s own&lt;br /&gt;
	-- width: 100%, so a group always takes the whole page width and stacks&lt;br /&gt;
	-- one per row, same as before. width: 100% is a definite size relative&lt;br /&gt;
	-- to the page column rather than shrink-to-fit, so it&#039;s still immune to&lt;br /&gt;
	-- the long-Requirements-text sizing bug; member cards flex to fill it.&lt;br /&gt;
	local buf = {}&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;box-sizing: border-box; width: 100%; background-color: #&#039; .. rc.base ..&lt;br /&gt;
		&#039;; border: 3px solid #&#039; .. rc.dark .. &#039;; border-radius: 25px; padding: 6px; margin: 8px 0; &#039; ..&lt;br /&gt;
		&#039;text-align: center;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;background-color: #&#039; .. rc.light .. &#039;; border-radius: 20px; padding: 8px; &#039; ..&lt;br /&gt;
		&#039;color: #&#039; .. rc.dark .. &#039;; font-weight: bold;&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;font-size: 18px;&amp;quot;&amp;gt;&#039; .. name ..&lt;br /&gt;
		&#039;&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&amp;lt;span style=&amp;quot;font-size: 12px;&amp;quot;&amp;gt;[[:Category:Generation &#039; .. genRoman ..&lt;br /&gt;
		&#039; Pokémon|&amp;lt;span style=&amp;quot;color: #&#039; .. rc.dark .. &#039;;&amp;quot;&amp;gt;Generation &#039; .. genRoman .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;display: flex; flex-wrap: wrap; justify-content: center; margin-top: 6px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		table.concat(cardsHtml) .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;background-color: #&#039; .. rc.light .. &#039;; border-radius: 20px; padding: 6px; &#039; ..&lt;br /&gt;
		&#039;margin-top: 6px; color: #&#039; .. rc.dark .. &#039;; font-weight: bold; text-align: left;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;div style=&amp;quot;text-align: center;&amp;quot;&amp;gt;Availability&amp;lt;/div&amp;gt;&#039; .. requirementsBox(rc.dark, requirements) .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
	return table.concat(buf)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Module:LegendaryPokemon&amp;diff=41045</id>
		<title>Module:LegendaryPokemon</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Module:LegendaryPokemon&amp;diff=41045"/>
		<updated>2026-08-04T18:39:13Z</updated>

		<summary type="html">&lt;p&gt;Cae: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {}&lt;br /&gt;
&lt;br /&gt;
local DATA_FORMAT = &#039;CSV with header&#039;&lt;br /&gt;
local STAT_MAX = 255&lt;br /&gt;
local ROMAN = { &#039;I&#039;, &#039;II&#039;, &#039;III&#039;, &#039;IV&#039;, &#039;V&#039;, &#039;VI&#039;, &#039;VII&#039;, &#039;VIII&#039;, &#039;IX&#039; }&lt;br /&gt;
&lt;br /&gt;
local function nonEmpty(s)&lt;br /&gt;
	if s == nil then return nil end&lt;br /&gt;
	s = mw.text.trim(tostring(s))&lt;br /&gt;
	if s == &#039;&#039; then return nil end&lt;br /&gt;
	return s&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local pokemonRowsCache = nil&lt;br /&gt;
local function pokemonByName()&lt;br /&gt;
	if pokemonRowsCache then return pokemonRowsCache end&lt;br /&gt;
	local csvData = mw.ext.externalData.getExternalData{&lt;br /&gt;
		url = &#039;https://wiki.pokemonrevolution.net/index.php?title=Special:GetData/PokemonRawList&#039;,&lt;br /&gt;
		format = DATA_FORMAT,&lt;br /&gt;
		data = {&lt;br /&gt;
			number = &#039;Pokedex Number&#039;, name = &#039;Name&#039;, type1 = &#039;Type1&#039;, type2 = &#039;Type2&#039;, generation = &#039;Generation&#039;,&lt;br /&gt;
			hp = &#039;HP&#039;, atk = &#039;Attack&#039;, def = &#039;Defense&#039;, spatk = &#039;Special Attack&#039;, spdef = &#039;Special Defense&#039;,&lt;br /&gt;
			spd = &#039;Speed&#039;,&lt;br /&gt;
		},&lt;br /&gt;
	}&lt;br /&gt;
	pokemonRowsCache = {}&lt;br /&gt;
	if csvData then&lt;br /&gt;
		for _, row in ipairs(csvData) do&lt;br /&gt;
			if nonEmpty(row.name) then&lt;br /&gt;
				pokemonRowsCache[row.name] = row&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return pokemonRowsCache&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local typeColorCache = {}&lt;br /&gt;
local function typeColor(frame, pokeType)&lt;br /&gt;
	pokeType = nonEmpty(pokeType) or &#039;Normal&#039;&lt;br /&gt;
	if not typeColorCache[pokeType] then&lt;br /&gt;
		typeColorCache[pokeType] = {&lt;br /&gt;
			light = frame:expandTemplate{ title = pokeType .. &#039; color light&#039; },&lt;br /&gt;
			base = frame:expandTemplate{ title = pokeType .. &#039; color&#039; },&lt;br /&gt;
			dark = frame:expandTemplate{ title = pokeType .. &#039; color dark&#039; },&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
	return typeColorCache[pokeType]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local regionNameCache = {}&lt;br /&gt;
local function regionForGen(frame, genRoman)&lt;br /&gt;
	if not regionNameCache[genRoman] then&lt;br /&gt;
		regionNameCache[genRoman] = frame:expandTemplate{ title = &#039;LegendaryRegionFromGen&#039;, args = { genRoman } }&lt;br /&gt;
	end&lt;br /&gt;
	return regionNameCache[genRoman]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local regionColorCache = {}&lt;br /&gt;
local function regionColor(frame, regionName)&lt;br /&gt;
	if not regionColorCache[regionName] then&lt;br /&gt;
		regionColorCache[regionName] = {&lt;br /&gt;
			light = frame:expandTemplate{ title = regionName .. &#039; color light&#039; },&lt;br /&gt;
			base = frame:expandTemplate{ title = regionName .. &#039; color&#039; },&lt;br /&gt;
			dark = frame:expandTemplate{ title = regionName .. &#039; color dark&#039; },&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
	return regionColorCache[regionName]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function genToRoman(genValue)&lt;br /&gt;
	local digits = mw.ustring.match(tostring(genValue or &#039;&#039;), &#039;^%d+&#039;)&lt;br /&gt;
	local n = digits and tonumber(digits)&lt;br /&gt;
	return (n and ROMAN[n]) or tostring(genValue or &#039;&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function statBar(frame, label, value, dark)&lt;br /&gt;
	value = tonumber(value) or 0&lt;br /&gt;
	local pct = math.max(0, math.min(100, (value / STAT_MAX) * 100))&lt;br /&gt;
	local hue = math.floor((math.max(0, math.min(STAT_MAX, value)) / STAT_MAX) * 130) -- red (low) -&amp;gt; teal (high)&lt;br /&gt;
	-- box-sizing here matters because width is a percentage of a&lt;br /&gt;
	-- table-layout: fixed column: without it, this td&#039;s own padding would&lt;br /&gt;
	-- add on top of that 60%, throwing the bar past the column&#039;s actual box.&lt;br /&gt;
	return &#039;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;width: 40%; box-sizing: border-box; text-align: left; padding: 2px 4px; &#039; ..&lt;br /&gt;
		&#039;font-size: 11px; color: #&#039; .. dark .. &#039;;&amp;quot;&amp;gt;&#039; .. label .. &#039;&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;width: 60%; box-sizing: border-box; text-align: left; padding: 2px 4px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;div style=&amp;quot;background: #FFFFFF; border: 1px solid #&#039; .. dark .. &#039;; border-radius: 8px; overflow: hidden;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;div style=&amp;quot;width: &#039; .. pct .. &#039;%; background: hsl(&#039; .. hue ..&lt;br /&gt;
		&#039;, 65%, 45%); color: #FFFFFF; font-size: 10px; font-weight: normal; text-align: left; padding: 1px 4px; &#039; ..&lt;br /&gt;
		&#039;white-space: nowrap;&amp;quot;&amp;gt;&#039; .. value .. &#039;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Cells are forced to an even 50/50 split (rather than sizing to content) so&lt;br /&gt;
-- a longer type name -- &amp;quot;Fighting&amp;quot; next to &amp;quot;Psychic&amp;quot;, say -- can&#039;t crowd the&lt;br /&gt;
-- other cell into overflowing; text is still free to wrap onto a second&lt;br /&gt;
-- line at that width rather than being clipped. border: none resets both&lt;br /&gt;
-- tables below to kill a default wiki-skin table border that was otherwise&lt;br /&gt;
-- showing through as an unstyled brownish line around this part of the card.&lt;br /&gt;
local function typeBadges(frame, row)&lt;br /&gt;
	local t1 = nonEmpty(row.type1)&lt;br /&gt;
	local t2 = nonEmpty(row.type2)&lt;br /&gt;
	local c1 = typeColor(frame, t1)&lt;br /&gt;
	if not t2 then&lt;br /&gt;
		return &#039;&amp;lt;table align=&amp;quot;center&amp;quot; style=&amp;quot;width: 80%; border: none; border-collapse: collapse; &#039; ..&lt;br /&gt;
			&#039;font-weight: bold; font-size: 12px;&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&#039; ..&lt;br /&gt;
			&#039;&amp;lt;td style=&amp;quot;background-color: #&#039; .. c1.dark .. &#039;; border-radius: 15px; padding: 2px;&amp;quot;&amp;gt;[[&#039; .. t1 ..&lt;br /&gt;
			&#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. t1 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	local c2 = typeColor(frame, t2)&lt;br /&gt;
	return &#039;&amp;lt;table align=&amp;quot;center&amp;quot; style=&amp;quot;width: 80%; table-layout: fixed; border: none; border-collapse: collapse; &#039; ..&lt;br /&gt;
		&#039;font-weight: bold; font-size: 12px;&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;width: 50%; box-sizing: border-box; background-color: #&#039; .. c1.dark ..&lt;br /&gt;
		&#039;; border-radius: 15px 1px 1px 15px; padding: 2px; overflow-wrap: break-word;&amp;quot;&amp;gt;[[&#039; ..&lt;br /&gt;
		t1 .. &#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. t1 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;width: 50%; box-sizing: border-box; background-color: #&#039; .. c2.dark ..&lt;br /&gt;
		&#039;; border-radius: 1px 15px 15px 1px; padding: 2px; overflow-wrap: break-word;&amp;quot;&amp;gt;[[&#039; ..&lt;br /&gt;
		t2 .. &#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. t2 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function memberCard(frame, name, showGeneration)&lt;br /&gt;
	local row = pokemonByName()[name]&lt;br /&gt;
	if not row then&lt;br /&gt;
		return &#039;&amp;lt;div style=&amp;quot;flex: 1 1 220px; width: 100%; box-sizing: border-box; margin: 4px; color: red;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
			&#039;Data load error: No Pokémon data found for &#039; .. name .. &#039;&amp;lt;/div&amp;gt;&#039;, nil&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local c = typeColor(frame, row.type1)&lt;br /&gt;
	local bst = (tonumber(row.hp) or 0) + (tonumber(row.atk) or 0) + (tonumber(row.def) or 0) +&lt;br /&gt;
		(tonumber(row.spatk) or 0) + (tonumber(row.spdef) or 0) + (tonumber(row.spd) or 0)&lt;br /&gt;
&lt;br /&gt;
	local genLine = &#039;&#039;&lt;br /&gt;
	if showGeneration then&lt;br /&gt;
		local genRoman = genToRoman(row.generation)&lt;br /&gt;
		genLine = &#039;&amp;lt;br&amp;gt;&amp;lt;span style=&amp;quot;font-size: 11px;&amp;quot;&amp;gt;[[:Category:Generation &#039; .. genRoman ..&lt;br /&gt;
			&#039; Pokémon|&amp;lt;span style=&amp;quot;color: #&#039; .. c.dark .. &#039;;&amp;quot;&amp;gt;Generation &#039; .. genRoman .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- flex: grows/shrinks within a group&#039;s flex row (220px basis); width:&lt;br /&gt;
	-- 100% takes over instead when this card is the sole content of a&lt;br /&gt;
	-- block-level parent (a single-Pokémon entry) -- flex properties are&lt;br /&gt;
	-- simply inert outside of a flex container, so both rules can coexist.&lt;br /&gt;
	local buf = {}&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;flex: 1 1 220px; width: 100%; min-width: 0; box-sizing: border-box; margin: 4px; &#039; ..&lt;br /&gt;
		&#039;background-color: #&#039; .. c.base .. &#039;; border: 3px solid #&#039; .. c.dark ..&lt;br /&gt;
		&#039;; border-radius: 20px; padding: 6px; text-align: center; color: #&#039; .. c.dark .. &#039;; font-weight: bold;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;background-color: #&#039; .. c.light .. &#039;; border-radius: 15px; padding: 5px; &#039; ..&lt;br /&gt;
		&#039;margin-bottom: 6px;&amp;quot;&amp;gt;#&#039; .. (row.number or &#039;&#039;) .. &#039;&amp;amp;nbsp;&amp;lt;span style=&amp;quot;font-size: 16px;&amp;quot;&amp;gt;[[&#039; .. name ..&lt;br /&gt;
		&#039;|&amp;lt;span style=&amp;quot;color: #&#039; .. c.dark .. &#039;;&amp;quot;&amp;gt;&#039; .. name .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/span&amp;gt;&#039; .. genLine .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- 150x150px (not just 150px) fits the sprite *within* a 150x150 box on&lt;br /&gt;
	-- whichever dimension is the constraint, instead of only fixing width&lt;br /&gt;
	-- and leaving height to the image&#039;s own aspect ratio -- a tall/narrow&lt;br /&gt;
	-- sprite was overflowing the fixed-height box under the old |150px form.&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;background-color: #FFFFFF; border-radius: 15px; height: 150px; overflow: hidden; &#039; ..&lt;br /&gt;
		&#039;display: flex; align-items: center; justify-content: center; margin-bottom: 6px;&amp;quot;&amp;gt;[[File:&#039; ..&lt;br /&gt;
		(row.number or &#039;&#039;) .. name .. &#039;.png|150x150px]]&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = typeBadges(frame, row)&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;table style=&amp;quot;width: 100%; table-layout: fixed; border: none; border-collapse: collapse; &#039; ..&lt;br /&gt;
		&#039;margin-top: 6px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		statBar(frame, &#039;HP&#039;, row.hp, c.dark) ..&lt;br /&gt;
		statBar(frame, &#039;Attack&#039;, row.atk, c.dark) ..&lt;br /&gt;
		statBar(frame, &#039;Defense&#039;, row.def, c.dark) ..&lt;br /&gt;
		statBar(frame, &#039;Sp. Atk&#039;, row.spatk, c.dark) ..&lt;br /&gt;
		statBar(frame, &#039;Sp. Def&#039;, row.spdef, c.dark) ..&lt;br /&gt;
		statBar(frame, &#039;Speed&#039;, row.spd, c.dark) ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;text-align: left; padding: 3px 4px; font-size: 11px;&amp;quot;&amp;gt;Total&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;padding: 3px 4px; font-size: 11px;&amp;quot;&amp;gt;&#039; .. bst .. &#039;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
	return table.concat(buf), row&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- width: 100% + border-box is the actual fix here: without a constrained&lt;br /&gt;
-- width, a long Requirements sentence has no wrap point to size against, so&lt;br /&gt;
-- the inline-block ancestor&#039;s shrink-to-fit layout stretches the *whole&lt;br /&gt;
-- card* to fit that one line instead of wrapping text inside a fixed box.&lt;br /&gt;
local function requirementsBox(dark, requirements)&lt;br /&gt;
	return &#039;&amp;lt;div style=&amp;quot;width: 100%; box-sizing: border-box; background-color: #FFFFFF; color: #000000; &#039; ..&lt;br /&gt;
		&#039;border-radius: 15px; font-weight: normal; text-align: left; border: 1px solid #&#039; .. dark ..&lt;br /&gt;
		&#039;; padding: 8px; margin-top: 4px; overflow-wrap: break-word;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		(requirements or &#039;&#039;) .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.card(frame)&lt;br /&gt;
	local parent = frame:getParent()&lt;br /&gt;
	local args = (parent and parent.args) or frame.args&lt;br /&gt;
&lt;br /&gt;
	local name = nonEmpty(args.Name)&lt;br /&gt;
	if not name then&lt;br /&gt;
		return &amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;Usage: {{LegendaryPokemon|Name=...|Requirements=...|&amp;quot; ..&lt;br /&gt;
			&amp;quot;Pokemon=Name1\\Name2 (omit Pokemon= for a single-species entry)}}&amp;lt;/span&amp;gt;&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local pokemonArg = nonEmpty(args.Pokemon)&lt;br /&gt;
	local members = {}&lt;br /&gt;
	if pokemonArg then&lt;br /&gt;
		for _, part in ipairs(mw.text.split(pokemonArg, &#039;\\&#039;, true)) do&lt;br /&gt;
			local trimmed = mw.text.trim(part)&lt;br /&gt;
			if trimmed ~= &#039;&#039; then&lt;br /&gt;
				members[#members + 1] = trimmed&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		members = { name }&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local requirements = args.Requirements or &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
	if #members == 1 then&lt;br /&gt;
		local cardHtml, row = memberCard(frame, members[1], true)&lt;br /&gt;
		if not row then&lt;br /&gt;
			return cardHtml&lt;br /&gt;
		end&lt;br /&gt;
		local c = typeColor(frame, row.type1)&lt;br /&gt;
		-- 50% width, matching the original single-Pokémon template&#039;s own&lt;br /&gt;
		-- width: 50% -- two of these sit side by side and together span&lt;br /&gt;
		-- the full row. calc() leaves room for this wrapper&#039;s own margin&lt;br /&gt;
		-- (and the small whitespace gap browsers render between adjacent&lt;br /&gt;
		-- inline-block elements from separate template calls) so two&lt;br /&gt;
		-- actually fit per row at true 50/50 instead of the second one&lt;br /&gt;
		-- wrapping early. Still immune to the Requirements-text sizing bug:&lt;br /&gt;
		-- width is a definite percentage of the page column, not&lt;br /&gt;
		-- shrink-to-fit, so a long sentence just wraps instead of stretching it.&lt;br /&gt;
		return &#039;&amp;lt;div style=&amp;quot;display: inline-block; vertical-align: top; box-sizing: border-box; &#039; ..&lt;br /&gt;
			&#039;width: calc(50% - 10px); background-color: #&#039; .. c.base .. &#039;; border: 1px solid #&#039; .. c.dark ..&lt;br /&gt;
			&#039;; border-radius: 22px; padding: 4px; margin: 5px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
			cardHtml .. requirementsBox(c.dark, requirements) .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local firstRow = pokemonByName()[members[1]]&lt;br /&gt;
	local genRoman = nonEmpty(args.Gen) or (firstRow and genToRoman(firstRow.generation)) or &#039;?&#039;&lt;br /&gt;
	local regionName = regionForGen(frame, genRoman)&lt;br /&gt;
	local rc = regionColor(frame, regionName)&lt;br /&gt;
&lt;br /&gt;
	local cardsHtml = {}&lt;br /&gt;
	for _, member in ipairs(members) do&lt;br /&gt;
		local cardHtml = memberCard(frame, member, false)&lt;br /&gt;
		cardsHtml[#cardsHtml + 1] = cardHtml&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Full width, block-level -- matches the original group template&#039;s own&lt;br /&gt;
	-- width: 100%, so a group always takes the whole page width and stacks&lt;br /&gt;
	-- one per row, same as before. width: 100% is a definite size relative&lt;br /&gt;
	-- to the page column rather than shrink-to-fit, so it&#039;s still immune to&lt;br /&gt;
	-- the long-Requirements-text sizing bug; member cards flex to fill it.&lt;br /&gt;
	local buf = {}&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;box-sizing: border-box; width: 100%; background-color: #&#039; .. rc.base ..&lt;br /&gt;
		&#039;; border: 3px solid #&#039; .. rc.dark .. &#039;; border-radius: 25px; padding: 6px; margin: 8px 0; &#039; ..&lt;br /&gt;
		&#039;text-align: center;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;background-color: #&#039; .. rc.light .. &#039;; border-radius: 20px; padding: 8px; &#039; ..&lt;br /&gt;
		&#039;color: #&#039; .. rc.dark .. &#039;; font-weight: bold;&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;font-size: 18px;&amp;quot;&amp;gt;&#039; .. name ..&lt;br /&gt;
		&#039;&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&amp;lt;span style=&amp;quot;font-size: 12px;&amp;quot;&amp;gt;[[:Category:Generation &#039; .. genRoman ..&lt;br /&gt;
		&#039; Pokémon|&amp;lt;span style=&amp;quot;color: #&#039; .. rc.dark .. &#039;;&amp;quot;&amp;gt;Generation &#039; .. genRoman .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;display: flex; flex-wrap: wrap; justify-content: center; margin-top: 6px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		table.concat(cardsHtml) .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;background-color: #&#039; .. rc.light .. &#039;; border-radius: 20px; padding: 6px; &#039; ..&lt;br /&gt;
		&#039;margin-top: 6px; color: #&#039; .. rc.dark .. &#039;; font-weight: bold; text-align: left;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;div style=&amp;quot;text-align: center;&amp;quot;&amp;gt;Availability&amp;lt;/div&amp;gt;&#039; .. requirementsBox(rc.dark, requirements) .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
	return table.concat(buf)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Module:LegendaryPokemon&amp;diff=41044</id>
		<title>Module:LegendaryPokemon</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Module:LegendaryPokemon&amp;diff=41044"/>
		<updated>2026-08-04T18:22:47Z</updated>

		<summary type="html">&lt;p&gt;Cae: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {}&lt;br /&gt;
&lt;br /&gt;
local DATA_FORMAT = &#039;CSV with header&#039;&lt;br /&gt;
local STAT_MAX = 255&lt;br /&gt;
local ROMAN = { &#039;I&#039;, &#039;II&#039;, &#039;III&#039;, &#039;IV&#039;, &#039;V&#039;, &#039;VI&#039;, &#039;VII&#039;, &#039;VIII&#039;, &#039;IX&#039; }&lt;br /&gt;
&lt;br /&gt;
local function nonEmpty(s)&lt;br /&gt;
	if s == nil then return nil end&lt;br /&gt;
	s = mw.text.trim(tostring(s))&lt;br /&gt;
	if s == &#039;&#039; then return nil end&lt;br /&gt;
	return s&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local pokemonRowsCache = nil&lt;br /&gt;
local function pokemonByName()&lt;br /&gt;
	if pokemonRowsCache then return pokemonRowsCache end&lt;br /&gt;
	local csvData = mw.ext.externalData.getExternalData{&lt;br /&gt;
		url = &#039;https://wiki.pokemonrevolution.net/index.php?title=Special:GetData/PokemonRawList&#039;,&lt;br /&gt;
		format = DATA_FORMAT,&lt;br /&gt;
		data = {&lt;br /&gt;
			number = &#039;Pokedex Number&#039;, name = &#039;Name&#039;, type1 = &#039;Type1&#039;, type2 = &#039;Type2&#039;, generation = &#039;Generation&#039;,&lt;br /&gt;
			hp = &#039;HP&#039;, atk = &#039;Attack&#039;, def = &#039;Defense&#039;, spatk = &#039;Special Attack&#039;, spdef = &#039;Special Defense&#039;,&lt;br /&gt;
			spd = &#039;Speed&#039;,&lt;br /&gt;
		},&lt;br /&gt;
	}&lt;br /&gt;
	pokemonRowsCache = {}&lt;br /&gt;
	if csvData then&lt;br /&gt;
		for _, row in ipairs(csvData) do&lt;br /&gt;
			if nonEmpty(row.name) then&lt;br /&gt;
				pokemonRowsCache[row.name] = row&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return pokemonRowsCache&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local typeColorCache = {}&lt;br /&gt;
local function typeColor(frame, pokeType)&lt;br /&gt;
	pokeType = nonEmpty(pokeType) or &#039;Normal&#039;&lt;br /&gt;
	if not typeColorCache[pokeType] then&lt;br /&gt;
		typeColorCache[pokeType] = {&lt;br /&gt;
			light = frame:expandTemplate{ title = pokeType .. &#039; color light&#039; },&lt;br /&gt;
			base = frame:expandTemplate{ title = pokeType .. &#039; color&#039; },&lt;br /&gt;
			dark = frame:expandTemplate{ title = pokeType .. &#039; color dark&#039; },&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
	return typeColorCache[pokeType]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local regionNameCache = {}&lt;br /&gt;
local function regionForGen(frame, genRoman)&lt;br /&gt;
	if not regionNameCache[genRoman] then&lt;br /&gt;
		regionNameCache[genRoman] = frame:expandTemplate{ title = &#039;LegendaryRegionFromGen&#039;, args = { genRoman } }&lt;br /&gt;
	end&lt;br /&gt;
	return regionNameCache[genRoman]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local regionColorCache = {}&lt;br /&gt;
local function regionColor(frame, regionName)&lt;br /&gt;
	if not regionColorCache[regionName] then&lt;br /&gt;
		regionColorCache[regionName] = {&lt;br /&gt;
			light = frame:expandTemplate{ title = regionName .. &#039; color light&#039; },&lt;br /&gt;
			base = frame:expandTemplate{ title = regionName .. &#039; color&#039; },&lt;br /&gt;
			dark = frame:expandTemplate{ title = regionName .. &#039; color dark&#039; },&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
	return regionColorCache[regionName]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function genToRoman(genValue)&lt;br /&gt;
	local digits = mw.ustring.match(tostring(genValue or &#039;&#039;), &#039;^%d+&#039;)&lt;br /&gt;
	local n = digits and tonumber(digits)&lt;br /&gt;
	return (n and ROMAN[n]) or tostring(genValue or &#039;&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function statBar(frame, label, value, dark)&lt;br /&gt;
	value = tonumber(value) or 0&lt;br /&gt;
	local pct = math.max(0, math.min(100, (value / STAT_MAX) * 100))&lt;br /&gt;
	local hue = math.floor((math.max(0, math.min(STAT_MAX, value)) / STAT_MAX) * 130) -- red (low) -&amp;gt; teal (high)&lt;br /&gt;
	return &#039;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;width: 40%; text-align: left; padding: 2px 4px; font-size: 11px; color: #&#039; .. dark ..&lt;br /&gt;
		&#039;;&amp;quot;&amp;gt;&#039; .. label .. &#039;&amp;lt;/td&amp;gt;&amp;lt;td style=&amp;quot;padding: 2px 4px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;div style=&amp;quot;background: #FFFFFF; border: 1px solid #&#039; .. dark .. &#039;; border-radius: 8px; overflow: hidden;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;div style=&amp;quot;width: &#039; .. pct .. &#039;%; background: hsl(&#039; .. hue ..&lt;br /&gt;
		&#039;, 65%, 45%); color: #FFFFFF; font-size: 10px; font-weight: normal; padding: 1px 4px; &#039; ..&lt;br /&gt;
		&#039;white-space: nowrap;&amp;quot;&amp;gt;&#039; .. value .. &#039;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Cells are forced to an even 50/50 split (rather than sizing to content) so&lt;br /&gt;
-- a longer type name -- &amp;quot;Fighting&amp;quot; next to &amp;quot;Psychic&amp;quot;, say -- can&#039;t crowd the&lt;br /&gt;
-- other cell into overflowing; text is still free to wrap onto a second&lt;br /&gt;
-- line at that width rather than being clipped. border: none resets both&lt;br /&gt;
-- tables below to kill a default wiki-skin table border that was otherwise&lt;br /&gt;
-- showing through as an unstyled brownish line around this part of the card.&lt;br /&gt;
local function typeBadges(frame, row)&lt;br /&gt;
	local t1 = nonEmpty(row.type1)&lt;br /&gt;
	local t2 = nonEmpty(row.type2)&lt;br /&gt;
	local c1 = typeColor(frame, t1)&lt;br /&gt;
	if not t2 then&lt;br /&gt;
		return &#039;&amp;lt;table align=&amp;quot;center&amp;quot; style=&amp;quot;width: 80%; border: none; border-collapse: collapse; &#039; ..&lt;br /&gt;
			&#039;font-weight: bold; font-size: 12px;&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&#039; ..&lt;br /&gt;
			&#039;&amp;lt;td style=&amp;quot;background-color: #&#039; .. c1.dark .. &#039;; border-radius: 15px; padding: 2px;&amp;quot;&amp;gt;[[&#039; .. t1 ..&lt;br /&gt;
			&#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. t1 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	local c2 = typeColor(frame, t2)&lt;br /&gt;
	return &#039;&amp;lt;table align=&amp;quot;center&amp;quot; style=&amp;quot;width: 80%; table-layout: fixed; border: none; border-collapse: collapse; &#039; ..&lt;br /&gt;
		&#039;font-weight: bold; font-size: 12px;&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;width: 50%; box-sizing: border-box; background-color: #&#039; .. c1.dark ..&lt;br /&gt;
		&#039;; border-radius: 15px 1px 1px 15px; padding: 2px; overflow-wrap: break-word;&amp;quot;&amp;gt;[[&#039; ..&lt;br /&gt;
		t1 .. &#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. t1 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;width: 50%; box-sizing: border-box; background-color: #&#039; .. c2.dark ..&lt;br /&gt;
		&#039;; border-radius: 1px 15px 15px 1px; padding: 2px; overflow-wrap: break-word;&amp;quot;&amp;gt;[[&#039; ..&lt;br /&gt;
		t2 .. &#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. t2 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function memberCard(frame, name, showGeneration)&lt;br /&gt;
	local row = pokemonByName()[name]&lt;br /&gt;
	if not row then&lt;br /&gt;
		return &#039;&amp;lt;div style=&amp;quot;flex: 1 1 220px; width: 100%; box-sizing: border-box; margin: 4px; color: red;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
			&#039;Data load error: No Pokémon data found for &#039; .. name .. &#039;&amp;lt;/div&amp;gt;&#039;, nil&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local c = typeColor(frame, row.type1)&lt;br /&gt;
	local bst = (tonumber(row.hp) or 0) + (tonumber(row.atk) or 0) + (tonumber(row.def) or 0) +&lt;br /&gt;
		(tonumber(row.spatk) or 0) + (tonumber(row.spdef) or 0) + (tonumber(row.spd) or 0)&lt;br /&gt;
&lt;br /&gt;
	local genLine = &#039;&#039;&lt;br /&gt;
	if showGeneration then&lt;br /&gt;
		local genRoman = genToRoman(row.generation)&lt;br /&gt;
		genLine = &#039;&amp;lt;br&amp;gt;&amp;lt;span style=&amp;quot;font-size: 11px;&amp;quot;&amp;gt;[[:Category:Generation &#039; .. genRoman ..&lt;br /&gt;
			&#039; Pokémon|&amp;lt;span style=&amp;quot;color: #&#039; .. c.dark .. &#039;;&amp;quot;&amp;gt;Generation &#039; .. genRoman .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- flex: grows/shrinks within a group&#039;s flex row (220px basis); width:&lt;br /&gt;
	-- 100% takes over instead when this card is the sole content of a&lt;br /&gt;
	-- block-level parent (a single-Pokémon entry) -- flex properties are&lt;br /&gt;
	-- simply inert outside of a flex container, so both rules can coexist.&lt;br /&gt;
	local buf = {}&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;flex: 1 1 220px; width: 100%; min-width: 0; box-sizing: border-box; margin: 4px; &#039; ..&lt;br /&gt;
		&#039;background-color: #&#039; .. c.base .. &#039;; border: 3px solid #&#039; .. c.dark ..&lt;br /&gt;
		&#039;; border-radius: 20px; padding: 6px; text-align: center; color: #&#039; .. c.dark .. &#039;; font-weight: bold;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;background-color: #&#039; .. c.light .. &#039;; border-radius: 15px; padding: 5px; &#039; ..&lt;br /&gt;
		&#039;margin-bottom: 6px;&amp;quot;&amp;gt;#&#039; .. (row.number or &#039;&#039;) .. &#039;&amp;amp;nbsp;&amp;lt;span style=&amp;quot;font-size: 16px;&amp;quot;&amp;gt;[[&#039; .. name ..&lt;br /&gt;
		&#039;|&amp;lt;span style=&amp;quot;color: #&#039; .. c.dark .. &#039;;&amp;quot;&amp;gt;&#039; .. name .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/span&amp;gt;&#039; .. genLine .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;background-color: #FFFFFF; border-radius: 15px; height: 150px; display: flex; &#039; ..&lt;br /&gt;
		&#039;align-items: center; justify-content: center; margin-bottom: 6px;&amp;quot;&amp;gt;[[File:&#039; .. (row.number or &#039;&#039;) ..&lt;br /&gt;
		name .. &#039;.png|150px]]&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = typeBadges(frame, row)&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;table style=&amp;quot;width: 100%; border: none; border-collapse: collapse; margin-top: 6px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		statBar(frame, &#039;HP&#039;, row.hp, c.dark) ..&lt;br /&gt;
		statBar(frame, &#039;Attack&#039;, row.atk, c.dark) ..&lt;br /&gt;
		statBar(frame, &#039;Defense&#039;, row.def, c.dark) ..&lt;br /&gt;
		statBar(frame, &#039;Sp. Atk&#039;, row.spatk, c.dark) ..&lt;br /&gt;
		statBar(frame, &#039;Sp. Def&#039;, row.spdef, c.dark) ..&lt;br /&gt;
		statBar(frame, &#039;Speed&#039;, row.spd, c.dark) ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;text-align: left; padding: 3px 4px; font-size: 11px;&amp;quot;&amp;gt;Total&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;padding: 3px 4px; font-size: 11px;&amp;quot;&amp;gt;&#039; .. bst .. &#039;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
	return table.concat(buf), row&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- width: 100% + border-box is the actual fix here: without a constrained&lt;br /&gt;
-- width, a long Requirements sentence has no wrap point to size against, so&lt;br /&gt;
-- the inline-block ancestor&#039;s shrink-to-fit layout stretches the *whole&lt;br /&gt;
-- card* to fit that one line instead of wrapping text inside a fixed box.&lt;br /&gt;
local function requirementsBox(dark, requirements)&lt;br /&gt;
	return &#039;&amp;lt;div style=&amp;quot;width: 100%; box-sizing: border-box; background-color: #FFFFFF; color: #000000; &#039; ..&lt;br /&gt;
		&#039;border-radius: 15px; font-weight: normal; text-align: left; border: 1px solid #&#039; .. dark ..&lt;br /&gt;
		&#039;; padding: 8px; margin-top: 4px; overflow-wrap: break-word;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		(requirements or &#039;&#039;) .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.card(frame)&lt;br /&gt;
	local parent = frame:getParent()&lt;br /&gt;
	local args = (parent and parent.args) or frame.args&lt;br /&gt;
&lt;br /&gt;
	local name = nonEmpty(args.Name)&lt;br /&gt;
	if not name then&lt;br /&gt;
		return &amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;Usage: {{LegendaryPokemon|Name=...|Requirements=...|&amp;quot; ..&lt;br /&gt;
			&amp;quot;Pokemon=Name1\\Name2 (omit Pokemon= for a single-species entry)}}&amp;lt;/span&amp;gt;&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local pokemonArg = nonEmpty(args.Pokemon)&lt;br /&gt;
	local members = {}&lt;br /&gt;
	if pokemonArg then&lt;br /&gt;
		for _, part in ipairs(mw.text.split(pokemonArg, &#039;\\&#039;, true)) do&lt;br /&gt;
			local trimmed = mw.text.trim(part)&lt;br /&gt;
			if trimmed ~= &#039;&#039; then&lt;br /&gt;
				members[#members + 1] = trimmed&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		members = { name }&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local requirements = args.Requirements or &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
	if #members == 1 then&lt;br /&gt;
		local cardHtml, row = memberCard(frame, members[1], true)&lt;br /&gt;
		if not row then&lt;br /&gt;
			return cardHtml&lt;br /&gt;
		end&lt;br /&gt;
		local c = typeColor(frame, row.type1)&lt;br /&gt;
		-- 50% width, matching the original single-Pokémon template&#039;s own&lt;br /&gt;
		-- width: 50% -- two of these sit side by side and together span&lt;br /&gt;
		-- the full row. calc() leaves room for this wrapper&#039;s own margin&lt;br /&gt;
		-- (and the small whitespace gap browsers render between adjacent&lt;br /&gt;
		-- inline-block elements from separate template calls) so two&lt;br /&gt;
		-- actually fit per row at true 50/50 instead of the second one&lt;br /&gt;
		-- wrapping early. Still immune to the Requirements-text sizing bug:&lt;br /&gt;
		-- width is a definite percentage of the page column, not&lt;br /&gt;
		-- shrink-to-fit, so a long sentence just wraps instead of stretching it.&lt;br /&gt;
		return &#039;&amp;lt;div style=&amp;quot;display: inline-block; vertical-align: top; box-sizing: border-box; &#039; ..&lt;br /&gt;
			&#039;width: calc(50% - 10px); background-color: #&#039; .. c.base .. &#039;; border: 1px solid #&#039; .. c.dark ..&lt;br /&gt;
			&#039;; border-radius: 22px; padding: 4px; margin: 5px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
			cardHtml .. requirementsBox(c.dark, requirements) .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local firstRow = pokemonByName()[members[1]]&lt;br /&gt;
	local genRoman = nonEmpty(args.Gen) or (firstRow and genToRoman(firstRow.generation)) or &#039;?&#039;&lt;br /&gt;
	local regionName = regionForGen(frame, genRoman)&lt;br /&gt;
	local rc = regionColor(frame, regionName)&lt;br /&gt;
&lt;br /&gt;
	local cardsHtml = {}&lt;br /&gt;
	for _, member in ipairs(members) do&lt;br /&gt;
		local cardHtml = memberCard(frame, member, false)&lt;br /&gt;
		cardsHtml[#cardsHtml + 1] = cardHtml&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Full width, block-level -- matches the original group template&#039;s own&lt;br /&gt;
	-- width: 100%, so a group always takes the whole page width and stacks&lt;br /&gt;
	-- one per row, same as before. width: 100% is a definite size relative&lt;br /&gt;
	-- to the page column rather than shrink-to-fit, so it&#039;s still immune to&lt;br /&gt;
	-- the long-Requirements-text sizing bug; member cards flex to fill it.&lt;br /&gt;
	local buf = {}&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;box-sizing: border-box; width: 100%; background-color: #&#039; .. rc.base ..&lt;br /&gt;
		&#039;; border: 3px solid #&#039; .. rc.dark .. &#039;; border-radius: 25px; padding: 6px; margin: 8px 0; &#039; ..&lt;br /&gt;
		&#039;text-align: center;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;background-color: #&#039; .. rc.light .. &#039;; border-radius: 20px; padding: 8px; &#039; ..&lt;br /&gt;
		&#039;color: #&#039; .. rc.dark .. &#039;; font-weight: bold;&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;font-size: 18px;&amp;quot;&amp;gt;&#039; .. name ..&lt;br /&gt;
		&#039;&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&amp;lt;span style=&amp;quot;font-size: 12px;&amp;quot;&amp;gt;[[:Category:Generation &#039; .. genRoman ..&lt;br /&gt;
		&#039; Pokémon|&amp;lt;span style=&amp;quot;color: #&#039; .. rc.dark .. &#039;;&amp;quot;&amp;gt;Generation &#039; .. genRoman .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;display: flex; flex-wrap: wrap; justify-content: center; margin-top: 6px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		table.concat(cardsHtml) .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;background-color: #&#039; .. rc.light .. &#039;; border-radius: 20px; padding: 6px; &#039; ..&lt;br /&gt;
		&#039;margin-top: 6px; color: #&#039; .. rc.dark .. &#039;; font-weight: bold; text-align: left;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;div style=&amp;quot;text-align: center;&amp;quot;&amp;gt;Availability&amp;lt;/div&amp;gt;&#039; .. requirementsBox(rc.dark, requirements) .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
	return table.concat(buf)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Module:LegendaryPokemon&amp;diff=41043</id>
		<title>Module:LegendaryPokemon</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Module:LegendaryPokemon&amp;diff=41043"/>
		<updated>2026-08-04T18:12:25Z</updated>

		<summary type="html">&lt;p&gt;Cae: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {}&lt;br /&gt;
&lt;br /&gt;
local DATA_FORMAT = &#039;CSV with header&#039;&lt;br /&gt;
local STAT_MAX = 255&lt;br /&gt;
local ROMAN = { &#039;I&#039;, &#039;II&#039;, &#039;III&#039;, &#039;IV&#039;, &#039;V&#039;, &#039;VI&#039;, &#039;VII&#039;, &#039;VIII&#039;, &#039;IX&#039; }&lt;br /&gt;
&lt;br /&gt;
local function nonEmpty(s)&lt;br /&gt;
	if s == nil then return nil end&lt;br /&gt;
	s = mw.text.trim(tostring(s))&lt;br /&gt;
	if s == &#039;&#039; then return nil end&lt;br /&gt;
	return s&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local pokemonRowsCache = nil&lt;br /&gt;
local function pokemonByName()&lt;br /&gt;
	if pokemonRowsCache then return pokemonRowsCache end&lt;br /&gt;
	local csvData = mw.ext.externalData.getExternalData{&lt;br /&gt;
		url = &#039;https://wiki.pokemonrevolution.net/index.php?title=Special:GetData/PokemonRawList&#039;,&lt;br /&gt;
		format = DATA_FORMAT,&lt;br /&gt;
		data = {&lt;br /&gt;
			number = &#039;Pokedex Number&#039;, name = &#039;Name&#039;, type1 = &#039;Type1&#039;, type2 = &#039;Type2&#039;, generation = &#039;Generation&#039;,&lt;br /&gt;
			hp = &#039;HP&#039;, atk = &#039;Attack&#039;, def = &#039;Defense&#039;, spatk = &#039;Special Attack&#039;, spdef = &#039;Special Defense&#039;,&lt;br /&gt;
			spd = &#039;Speed&#039;,&lt;br /&gt;
		},&lt;br /&gt;
	}&lt;br /&gt;
	pokemonRowsCache = {}&lt;br /&gt;
	if csvData then&lt;br /&gt;
		for _, row in ipairs(csvData) do&lt;br /&gt;
			if nonEmpty(row.name) then&lt;br /&gt;
				pokemonRowsCache[row.name] = row&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return pokemonRowsCache&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local typeColorCache = {}&lt;br /&gt;
local function typeColor(frame, pokeType)&lt;br /&gt;
	pokeType = nonEmpty(pokeType) or &#039;Normal&#039;&lt;br /&gt;
	if not typeColorCache[pokeType] then&lt;br /&gt;
		typeColorCache[pokeType] = {&lt;br /&gt;
			light = frame:expandTemplate{ title = pokeType .. &#039; color light&#039; },&lt;br /&gt;
			base = frame:expandTemplate{ title = pokeType .. &#039; color&#039; },&lt;br /&gt;
			dark = frame:expandTemplate{ title = pokeType .. &#039; color dark&#039; },&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
	return typeColorCache[pokeType]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local regionNameCache = {}&lt;br /&gt;
local function regionForGen(frame, genRoman)&lt;br /&gt;
	if not regionNameCache[genRoman] then&lt;br /&gt;
		regionNameCache[genRoman] = frame:expandTemplate{ title = &#039;LegendaryRegionFromGen&#039;, args = { genRoman } }&lt;br /&gt;
	end&lt;br /&gt;
	return regionNameCache[genRoman]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local regionColorCache = {}&lt;br /&gt;
local function regionColor(frame, regionName)&lt;br /&gt;
	if not regionColorCache[regionName] then&lt;br /&gt;
		regionColorCache[regionName] = {&lt;br /&gt;
			light = frame:expandTemplate{ title = regionName .. &#039; color light&#039; },&lt;br /&gt;
			base = frame:expandTemplate{ title = regionName .. &#039; color&#039; },&lt;br /&gt;
			dark = frame:expandTemplate{ title = regionName .. &#039; color dark&#039; },&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
	return regionColorCache[regionName]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function genToRoman(genValue)&lt;br /&gt;
	local digits = mw.ustring.match(tostring(genValue or &#039;&#039;), &#039;^%d+&#039;)&lt;br /&gt;
	local n = digits and tonumber(digits)&lt;br /&gt;
	return (n and ROMAN[n]) or tostring(genValue or &#039;&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function statBar(frame, label, value, dark)&lt;br /&gt;
	value = tonumber(value) or 0&lt;br /&gt;
	local pct = math.max(0, math.min(100, (value / STAT_MAX) * 100))&lt;br /&gt;
	local hue = math.floor((math.max(0, math.min(STAT_MAX, value)) / STAT_MAX) * 130) -- red (low) -&amp;gt; teal (high)&lt;br /&gt;
	return &#039;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;width: 40%; text-align: left; padding: 2px 4px; font-size: 11px; color: #&#039; .. dark ..&lt;br /&gt;
		&#039;;&amp;quot;&amp;gt;&#039; .. label .. &#039;&amp;lt;/td&amp;gt;&amp;lt;td style=&amp;quot;padding: 2px 4px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;div style=&amp;quot;background: #FFFFFF; border: 1px solid #&#039; .. dark .. &#039;; border-radius: 8px; overflow: hidden;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;div style=&amp;quot;width: &#039; .. pct .. &#039;%; background: hsl(&#039; .. hue ..&lt;br /&gt;
		&#039;, 65%, 45%); color: #FFFFFF; font-size: 10px; font-weight: normal; padding: 1px 4px; &#039; ..&lt;br /&gt;
		&#039;white-space: nowrap;&amp;quot;&amp;gt;&#039; .. value .. &#039;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Cells are forced to an even 50/50 split (rather than sizing to content) so&lt;br /&gt;
-- a longer type name -- &amp;quot;Fighting&amp;quot; next to &amp;quot;Psychic&amp;quot;, say -- can&#039;t crowd the&lt;br /&gt;
-- other cell into overflowing; text is still free to wrap onto a second&lt;br /&gt;
-- line at that width rather than being clipped. border: none resets both&lt;br /&gt;
-- tables below to kill a default wiki-skin table border that was otherwise&lt;br /&gt;
-- showing through as an unstyled brownish line around this part of the card.&lt;br /&gt;
local function typeBadges(frame, row)&lt;br /&gt;
	local t1 = nonEmpty(row.type1)&lt;br /&gt;
	local t2 = nonEmpty(row.type2)&lt;br /&gt;
	local c1 = typeColor(frame, t1)&lt;br /&gt;
	if not t2 then&lt;br /&gt;
		return &#039;&amp;lt;table align=&amp;quot;center&amp;quot; style=&amp;quot;width: 80%; border: none; border-collapse: collapse; &#039; ..&lt;br /&gt;
			&#039;font-weight: bold; font-size: 12px;&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&#039; ..&lt;br /&gt;
			&#039;&amp;lt;td style=&amp;quot;background-color: #&#039; .. c1.dark .. &#039;; border-radius: 15px; padding: 2px;&amp;quot;&amp;gt;[[&#039; .. t1 ..&lt;br /&gt;
			&#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. t1 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	local c2 = typeColor(frame, t2)&lt;br /&gt;
	return &#039;&amp;lt;table align=&amp;quot;center&amp;quot; style=&amp;quot;width: 80%; table-layout: fixed; border: none; border-collapse: collapse; &#039; ..&lt;br /&gt;
		&#039;font-weight: bold; font-size: 12px;&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;width: 50%; box-sizing: border-box; background-color: #&#039; .. c1.dark ..&lt;br /&gt;
		&#039;; border-radius: 15px 1px 1px 15px; padding: 2px; overflow-wrap: break-word;&amp;quot;&amp;gt;[[&#039; ..&lt;br /&gt;
		t1 .. &#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. t1 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;width: 50%; box-sizing: border-box; background-color: #&#039; .. c2.dark ..&lt;br /&gt;
		&#039;; border-radius: 1px 15px 15px 1px; padding: 2px; overflow-wrap: break-word;&amp;quot;&amp;gt;[[&#039; ..&lt;br /&gt;
		t2 .. &#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. t2 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function memberCard(frame, name, showGeneration)&lt;br /&gt;
	local row = pokemonByName()[name]&lt;br /&gt;
	if not row then&lt;br /&gt;
		return &#039;&amp;lt;div style=&amp;quot;flex: 1 1 220px; width: 100%; box-sizing: border-box; margin: 4px; color: red;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
			&#039;Data load error: No Pokémon data found for &#039; .. name .. &#039;&amp;lt;/div&amp;gt;&#039;, nil&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local c = typeColor(frame, row.type1)&lt;br /&gt;
	local bst = (tonumber(row.hp) or 0) + (tonumber(row.atk) or 0) + (tonumber(row.def) or 0) +&lt;br /&gt;
		(tonumber(row.spatk) or 0) + (tonumber(row.spdef) or 0) + (tonumber(row.spd) or 0)&lt;br /&gt;
&lt;br /&gt;
	local genLine = &#039;&#039;&lt;br /&gt;
	if showGeneration then&lt;br /&gt;
		local genRoman = genToRoman(row.generation)&lt;br /&gt;
		genLine = &#039;&amp;lt;br&amp;gt;&amp;lt;span style=&amp;quot;font-size: 11px;&amp;quot;&amp;gt;[[:Category:Generation &#039; .. genRoman ..&lt;br /&gt;
			&#039; Pokémon|&amp;lt;span style=&amp;quot;color: #&#039; .. c.dark .. &#039;;&amp;quot;&amp;gt;Generation &#039; .. genRoman .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- flex: grows/shrinks within a group&#039;s flex row (220px basis); width:&lt;br /&gt;
	-- 100% takes over instead when this card is the sole content of a&lt;br /&gt;
	-- block-level parent (a single-Pokémon entry) -- flex properties are&lt;br /&gt;
	-- simply inert outside of a flex container, so both rules can coexist.&lt;br /&gt;
	local buf = {}&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;flex: 1 1 220px; width: 100%; min-width: 0; box-sizing: border-box; margin: 4px; &#039; ..&lt;br /&gt;
		&#039;background-color: #&#039; .. c.base .. &#039;; border: 3px solid #&#039; .. c.dark ..&lt;br /&gt;
		&#039;; border-radius: 20px; padding: 6px; text-align: center; color: #&#039; .. c.dark .. &#039;; font-weight: bold;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;background-color: #&#039; .. c.light .. &#039;; border-radius: 15px; padding: 5px; &#039; ..&lt;br /&gt;
		&#039;margin-bottom: 6px;&amp;quot;&amp;gt;#&#039; .. (row.number or &#039;&#039;) .. &#039;&amp;amp;nbsp;&amp;lt;span style=&amp;quot;font-size: 16px;&amp;quot;&amp;gt;[[&#039; .. name ..&lt;br /&gt;
		&#039;|&amp;lt;span style=&amp;quot;color: #&#039; .. c.dark .. &#039;;&amp;quot;&amp;gt;&#039; .. name .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/span&amp;gt;&#039; .. genLine .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;background-color: #FFFFFF; border-radius: 15px; height: 150px; display: flex; &#039; ..&lt;br /&gt;
		&#039;align-items: center; justify-content: center; margin-bottom: 6px;&amp;quot;&amp;gt;[[File:&#039; .. (row.number or &#039;&#039;) ..&lt;br /&gt;
		name .. &#039;.png|150px]]&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = typeBadges(frame, row)&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;table style=&amp;quot;width: 100%; border: none; border-collapse: collapse; margin-top: 6px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		statBar(frame, &#039;HP&#039;, row.hp, c.dark) ..&lt;br /&gt;
		statBar(frame, &#039;Attack&#039;, row.atk, c.dark) ..&lt;br /&gt;
		statBar(frame, &#039;Defense&#039;, row.def, c.dark) ..&lt;br /&gt;
		statBar(frame, &#039;Sp. Atk&#039;, row.spatk, c.dark) ..&lt;br /&gt;
		statBar(frame, &#039;Sp. Def&#039;, row.spdef, c.dark) ..&lt;br /&gt;
		statBar(frame, &#039;Speed&#039;, row.spd, c.dark) ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;text-align: left; padding: 3px 4px; font-size: 11px;&amp;quot;&amp;gt;Total&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;padding: 3px 4px; font-size: 11px;&amp;quot;&amp;gt;&#039; .. bst .. &#039;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
	return table.concat(buf), row&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- width: 100% + border-box is the actual fix here: without a constrained&lt;br /&gt;
-- width, a long Requirements sentence has no wrap point to size against, so&lt;br /&gt;
-- the inline-block ancestor&#039;s shrink-to-fit layout stretches the *whole&lt;br /&gt;
-- card* to fit that one line instead of wrapping text inside a fixed box.&lt;br /&gt;
local function requirementsBox(dark, requirements)&lt;br /&gt;
	return &#039;&amp;lt;div style=&amp;quot;width: 100%; box-sizing: border-box; background-color: #FFFFFF; color: #000000; &#039; ..&lt;br /&gt;
		&#039;border-radius: 15px; font-weight: normal; text-align: left; border: 1px solid #&#039; .. dark ..&lt;br /&gt;
		&#039;; padding: 8px; margin-top: 4px; overflow-wrap: break-word;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		(requirements or &#039;&#039;) .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.card(frame)&lt;br /&gt;
	local parent = frame:getParent()&lt;br /&gt;
	local args = (parent and parent.args) or frame.args&lt;br /&gt;
&lt;br /&gt;
	local name = nonEmpty(args.Name)&lt;br /&gt;
	if not name then&lt;br /&gt;
		return &amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;Usage: {{LegendaryPokemon|Name=...|Requirements=...|&amp;quot; ..&lt;br /&gt;
			&amp;quot;Pokemon=Name1\\Name2 (omit Pokemon= for a single-species entry)}}&amp;lt;/span&amp;gt;&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local pokemonArg = nonEmpty(args.Pokemon)&lt;br /&gt;
	local members = {}&lt;br /&gt;
	if pokemonArg then&lt;br /&gt;
		for _, part in ipairs(mw.text.split(pokemonArg, &#039;\\&#039;, true)) do&lt;br /&gt;
			local trimmed = mw.text.trim(part)&lt;br /&gt;
			if trimmed ~= &#039;&#039; then&lt;br /&gt;
				members[#members + 1] = trimmed&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		members = { name }&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local requirements = args.Requirements or &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
	if #members == 1 then&lt;br /&gt;
		local cardHtml, row = memberCard(frame, members[1], true)&lt;br /&gt;
		if not row then&lt;br /&gt;
			return cardHtml&lt;br /&gt;
		end&lt;br /&gt;
		local c = typeColor(frame, row.type1)&lt;br /&gt;
		-- 50% width, matching the original single-Pokémon template&#039;s own&lt;br /&gt;
		-- width: 50% -- two of these sit side by side and together span&lt;br /&gt;
		-- the full row. calc() leaves room for this wrapper&#039;s own margin&lt;br /&gt;
		-- (and the small whitespace gap browsers render between adjacent&lt;br /&gt;
		-- inline-block elements from separate template calls) so two&lt;br /&gt;
		-- actually fit per row at true 50/50 instead of the second one&lt;br /&gt;
		-- wrapping early. Still immune to the Requirements-text sizing bug:&lt;br /&gt;
		-- width is a definite percentage of the page column, not&lt;br /&gt;
		-- shrink-to-fit, so a long sentence just wraps instead of stretching it.&lt;br /&gt;
		return &#039;&amp;lt;div style=&amp;quot;display: inline-block; vertical-align: top; box-sizing: border-box; &#039; ..&lt;br /&gt;
			&#039;width: calc(50% - 10px); border: 1px solid #&#039; .. c.dark ..&lt;br /&gt;
			&#039;; border-radius: 22px; padding: 4px; margin: 5px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
			cardHtml .. requirementsBox(c.dark, requirements) .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local firstRow = pokemonByName()[members[1]]&lt;br /&gt;
	local genRoman = nonEmpty(args.Gen) or (firstRow and genToRoman(firstRow.generation)) or &#039;?&#039;&lt;br /&gt;
	local regionName = regionForGen(frame, genRoman)&lt;br /&gt;
	local rc = regionColor(frame, regionName)&lt;br /&gt;
&lt;br /&gt;
	local cardsHtml = {}&lt;br /&gt;
	for _, member in ipairs(members) do&lt;br /&gt;
		local cardHtml = memberCard(frame, member, false)&lt;br /&gt;
		cardsHtml[#cardsHtml + 1] = cardHtml&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Full width, block-level -- matches the original group template&#039;s own&lt;br /&gt;
	-- width: 100%, so a group always takes the whole page width and stacks&lt;br /&gt;
	-- one per row, same as before. width: 100% is a definite size relative&lt;br /&gt;
	-- to the page column rather than shrink-to-fit, so it&#039;s still immune to&lt;br /&gt;
	-- the long-Requirements-text sizing bug; member cards flex to fill it.&lt;br /&gt;
	local buf = {}&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;box-sizing: border-box; width: 100%; background-color: #&#039; .. rc.base ..&lt;br /&gt;
		&#039;; border: 3px solid #&#039; .. rc.dark .. &#039;; border-radius: 25px; padding: 6px; margin: 8px 0; &#039; ..&lt;br /&gt;
		&#039;text-align: center;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;background-color: #&#039; .. rc.light .. &#039;; border-radius: 20px; padding: 8px; &#039; ..&lt;br /&gt;
		&#039;color: #&#039; .. rc.dark .. &#039;; font-weight: bold;&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;font-size: 18px;&amp;quot;&amp;gt;&#039; .. name ..&lt;br /&gt;
		&#039;&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&amp;lt;span style=&amp;quot;font-size: 12px;&amp;quot;&amp;gt;[[:Category:Generation &#039; .. genRoman ..&lt;br /&gt;
		&#039; Pokémon|&amp;lt;span style=&amp;quot;color: #&#039; .. rc.dark .. &#039;;&amp;quot;&amp;gt;Generation &#039; .. genRoman .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;display: flex; flex-wrap: wrap; justify-content: center; margin-top: 6px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		table.concat(cardsHtml) .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;background-color: #&#039; .. rc.light .. &#039;; border-radius: 20px; padding: 6px; &#039; ..&lt;br /&gt;
		&#039;margin-top: 6px; color: #&#039; .. rc.dark .. &#039;; font-weight: bold; text-align: left;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;div style=&amp;quot;text-align: center;&amp;quot;&amp;gt;Availability&amp;lt;/div&amp;gt;&#039; .. requirementsBox(rc.dark, requirements) .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
	return table.concat(buf)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Module:LegendaryPokemon&amp;diff=41042</id>
		<title>Module:LegendaryPokemon</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Module:LegendaryPokemon&amp;diff=41042"/>
		<updated>2026-08-04T18:01:00Z</updated>

		<summary type="html">&lt;p&gt;Cae: Undo revision 41041 by Cae (talk)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {}&lt;br /&gt;
&lt;br /&gt;
local DATA_FORMAT = &#039;CSV with header&#039;&lt;br /&gt;
local STAT_MAX = 255&lt;br /&gt;
local ROMAN = { &#039;I&#039;, &#039;II&#039;, &#039;III&#039;, &#039;IV&#039;, &#039;V&#039;, &#039;VI&#039;, &#039;VII&#039;, &#039;VIII&#039;, &#039;IX&#039; }&lt;br /&gt;
&lt;br /&gt;
local function nonEmpty(s)&lt;br /&gt;
	if s == nil then return nil end&lt;br /&gt;
	s = mw.text.trim(tostring(s))&lt;br /&gt;
	if s == &#039;&#039; then return nil end&lt;br /&gt;
	return s&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local pokemonRowsCache = nil&lt;br /&gt;
local function pokemonByName()&lt;br /&gt;
	if pokemonRowsCache then return pokemonRowsCache end&lt;br /&gt;
	local csvData = mw.ext.externalData.getExternalData{&lt;br /&gt;
		url = &#039;https://wiki.pokemonrevolution.net/index.php?title=Special:GetData/PokemonRawList&#039;,&lt;br /&gt;
		format = DATA_FORMAT,&lt;br /&gt;
		data = {&lt;br /&gt;
			number = &#039;Pokedex Number&#039;, name = &#039;Name&#039;, type1 = &#039;Type1&#039;, type2 = &#039;Type2&#039;, generation = &#039;Generation&#039;,&lt;br /&gt;
			hp = &#039;HP&#039;, atk = &#039;Attack&#039;, def = &#039;Defense&#039;, spatk = &#039;Special Attack&#039;, spdef = &#039;Special Defense&#039;,&lt;br /&gt;
			spd = &#039;Speed&#039;,&lt;br /&gt;
		},&lt;br /&gt;
	}&lt;br /&gt;
	pokemonRowsCache = {}&lt;br /&gt;
	if csvData then&lt;br /&gt;
		for _, row in ipairs(csvData) do&lt;br /&gt;
			if nonEmpty(row.name) then&lt;br /&gt;
				pokemonRowsCache[row.name] = row&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return pokemonRowsCache&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local typeColorCache = {}&lt;br /&gt;
local function typeColor(frame, pokeType)&lt;br /&gt;
	pokeType = nonEmpty(pokeType) or &#039;Normal&#039;&lt;br /&gt;
	if not typeColorCache[pokeType] then&lt;br /&gt;
		typeColorCache[pokeType] = {&lt;br /&gt;
			light = frame:expandTemplate{ title = pokeType .. &#039; color light&#039; },&lt;br /&gt;
			base = frame:expandTemplate{ title = pokeType .. &#039; color&#039; },&lt;br /&gt;
			dark = frame:expandTemplate{ title = pokeType .. &#039; color dark&#039; },&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
	return typeColorCache[pokeType]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local regionNameCache = {}&lt;br /&gt;
local function regionForGen(frame, genRoman)&lt;br /&gt;
	if not regionNameCache[genRoman] then&lt;br /&gt;
		regionNameCache[genRoman] = frame:expandTemplate{ title = &#039;LegendaryRegionFromGen&#039;, args = { genRoman } }&lt;br /&gt;
	end&lt;br /&gt;
	return regionNameCache[genRoman]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local regionColorCache = {}&lt;br /&gt;
local function regionColor(frame, regionName)&lt;br /&gt;
	if not regionColorCache[regionName] then&lt;br /&gt;
		regionColorCache[regionName] = {&lt;br /&gt;
			light = frame:expandTemplate{ title = regionName .. &#039; color light&#039; },&lt;br /&gt;
			base = frame:expandTemplate{ title = regionName .. &#039; color&#039; },&lt;br /&gt;
			dark = frame:expandTemplate{ title = regionName .. &#039; color dark&#039; },&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
	return regionColorCache[regionName]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function genToRoman(genValue)&lt;br /&gt;
	local digits = mw.ustring.match(tostring(genValue or &#039;&#039;), &#039;^%d+&#039;)&lt;br /&gt;
	local n = digits and tonumber(digits)&lt;br /&gt;
	return (n and ROMAN[n]) or tostring(genValue or &#039;&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function statBar(frame, label, value, dark)&lt;br /&gt;
	value = tonumber(value) or 0&lt;br /&gt;
	local pct = math.max(0, math.min(100, (value / STAT_MAX) * 100))&lt;br /&gt;
	local hue = math.floor((math.max(0, math.min(STAT_MAX, value)) / STAT_MAX) * 130) -- red (low) -&amp;gt; teal (high)&lt;br /&gt;
	return &#039;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;width: 40%; text-align: left; padding: 2px 4px; font-size: 11px; color: #&#039; .. dark ..&lt;br /&gt;
		&#039;;&amp;quot;&amp;gt;&#039; .. label .. &#039;&amp;lt;/td&amp;gt;&amp;lt;td style=&amp;quot;padding: 2px 4px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;div style=&amp;quot;background: #FFFFFF; border: 1px solid #&#039; .. dark .. &#039;; border-radius: 8px; overflow: hidden;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;div style=&amp;quot;width: &#039; .. pct .. &#039;%; background: hsl(&#039; .. hue ..&lt;br /&gt;
		&#039;, 65%, 45%); color: #FFFFFF; font-size: 10px; font-weight: normal; padding: 1px 4px; &#039; ..&lt;br /&gt;
		&#039;white-space: nowrap;&amp;quot;&amp;gt;&#039; .. value .. &#039;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function typeBadges(frame, row)&lt;br /&gt;
	local t1 = nonEmpty(row.type1)&lt;br /&gt;
	local t2 = nonEmpty(row.type2)&lt;br /&gt;
	local c1 = typeColor(frame, t1)&lt;br /&gt;
	if not t2 then&lt;br /&gt;
		return &#039;&amp;lt;table align=&amp;quot;center&amp;quot; style=&amp;quot;width: 80%; font-weight: bold; font-size: 12px;&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&#039; ..&lt;br /&gt;
			&#039;&amp;lt;td style=&amp;quot;background-color: #&#039; .. c1.dark .. &#039;; border-radius: 15px; padding: 2px;&amp;quot;&amp;gt;[[&#039; .. t1 ..&lt;br /&gt;
			&#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. t1 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	local c2 = typeColor(frame, t2)&lt;br /&gt;
	return &#039;&amp;lt;table align=&amp;quot;center&amp;quot; style=&amp;quot;width: 80%; font-weight: bold; font-size: 12px;&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;background-color: #&#039; .. c1.dark .. &#039;; border-radius: 15px 1px 1px 15px; padding: 2px;&amp;quot;&amp;gt;[[&#039; ..&lt;br /&gt;
		t1 .. &#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. t1 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;background-color: #&#039; .. c2.dark .. &#039;; border-radius: 1px 15px 15px 1px; padding: 2px;&amp;quot;&amp;gt;[[&#039; ..&lt;br /&gt;
		t2 .. &#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. t2 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function memberCard(frame, name, showGeneration)&lt;br /&gt;
	local row = pokemonByName()[name]&lt;br /&gt;
	if not row then&lt;br /&gt;
		return &#039;&amp;lt;div style=&amp;quot;display: inline-block; vertical-align: top; box-sizing: border-box; width: 240px; &#039; ..&lt;br /&gt;
			&#039;margin: 4px; color: red;&amp;quot;&amp;gt;Data load error: No Pokémon data found for &#039; .. name .. &#039;&amp;lt;/div&amp;gt;&#039;, nil&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local c = typeColor(frame, row.type1)&lt;br /&gt;
	local bst = (tonumber(row.hp) or 0) + (tonumber(row.atk) or 0) + (tonumber(row.def) or 0) +&lt;br /&gt;
		(tonumber(row.spatk) or 0) + (tonumber(row.spdef) or 0) + (tonumber(row.spd) or 0)&lt;br /&gt;
&lt;br /&gt;
	local genLine = &#039;&#039;&lt;br /&gt;
	if showGeneration then&lt;br /&gt;
		local genRoman = genToRoman(row.generation)&lt;br /&gt;
		genLine = &#039;&amp;lt;br&amp;gt;&amp;lt;span style=&amp;quot;font-size: 11px;&amp;quot;&amp;gt;[[:Category:Generation &#039; .. genRoman ..&lt;br /&gt;
			&#039; Pokémon|&amp;lt;span style=&amp;quot;color: #&#039; .. c.dark .. &#039;;&amp;quot;&amp;gt;Generation &#039; .. genRoman .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local buf = {}&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;display: inline-block; vertical-align: top; box-sizing: border-box; &#039; ..&lt;br /&gt;
		&#039;width: 240px; margin: 4px; background-color: #&#039; .. c.base .. &#039;; border: 3px solid #&#039; .. c.dark ..&lt;br /&gt;
		&#039;; border-radius: 20px; padding: 6px; text-align: center; color: #&#039; .. c.dark .. &#039;; font-weight: bold;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;background-color: #&#039; .. c.light .. &#039;; border-radius: 15px; padding: 5px; &#039; ..&lt;br /&gt;
		&#039;margin-bottom: 6px;&amp;quot;&amp;gt;#&#039; .. (row.number or &#039;&#039;) .. &#039;&amp;amp;nbsp;&amp;lt;span style=&amp;quot;font-size: 16px;&amp;quot;&amp;gt;[[&#039; .. name ..&lt;br /&gt;
		&#039;|&amp;lt;span style=&amp;quot;color: #&#039; .. c.dark .. &#039;;&amp;quot;&amp;gt;&#039; .. name .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/span&amp;gt;&#039; .. genLine .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;background-color: #FFFFFF; border-radius: 15px; height: 150px; display: flex; &#039; ..&lt;br /&gt;
		&#039;align-items: center; justify-content: center; margin-bottom: 6px;&amp;quot;&amp;gt;[[File:&#039; .. (row.number or &#039;&#039;) ..&lt;br /&gt;
		name .. &#039;.png|150px]]&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = typeBadges(frame, row)&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;table style=&amp;quot;width: 100%; margin-top: 6px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		statBar(frame, &#039;HP&#039;, row.hp, c.dark) ..&lt;br /&gt;
		statBar(frame, &#039;Attack&#039;, row.atk, c.dark) ..&lt;br /&gt;
		statBar(frame, &#039;Defense&#039;, row.def, c.dark) ..&lt;br /&gt;
		statBar(frame, &#039;Sp. Atk&#039;, row.spatk, c.dark) ..&lt;br /&gt;
		statBar(frame, &#039;Sp. Def&#039;, row.spdef, c.dark) ..&lt;br /&gt;
		statBar(frame, &#039;Speed&#039;, row.spd, c.dark) ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;text-align: left; padding: 3px 4px; font-size: 11px;&amp;quot;&amp;gt;Total&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;padding: 3px 4px; font-size: 11px;&amp;quot;&amp;gt;&#039; .. bst .. &#039;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
	return table.concat(buf), row&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- width: 100% + border-box is the actual fix here: without a constrained&lt;br /&gt;
-- width, a long Requirements sentence has no wrap point to size against, so&lt;br /&gt;
-- the inline-block ancestor&#039;s shrink-to-fit layout stretches the *whole&lt;br /&gt;
-- card* to fit that one line instead of wrapping text inside a fixed box.&lt;br /&gt;
local function requirementsBox(dark, requirements)&lt;br /&gt;
	return &#039;&amp;lt;div style=&amp;quot;width: 100%; box-sizing: border-box; background-color: #FFFFFF; color: #000000; &#039; ..&lt;br /&gt;
		&#039;border-radius: 15px; font-weight: normal; text-align: left; border: 1px solid #&#039; .. dark ..&lt;br /&gt;
		&#039;; padding: 8px; margin-top: 4px; overflow-wrap: break-word;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		(requirements or &#039;&#039;) .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.card(frame)&lt;br /&gt;
	local parent = frame:getParent()&lt;br /&gt;
	local args = (parent and parent.args) or frame.args&lt;br /&gt;
&lt;br /&gt;
	local name = nonEmpty(args.Name)&lt;br /&gt;
	if not name then&lt;br /&gt;
		return &amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;Usage: {{LegendaryPokemon|Name=...|Requirements=...|&amp;quot; ..&lt;br /&gt;
			&amp;quot;Pokemon=Name1\\Name2 (omit Pokemon= for a single-species entry)}}&amp;lt;/span&amp;gt;&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local pokemonArg = nonEmpty(args.Pokemon)&lt;br /&gt;
	local members = {}&lt;br /&gt;
	if pokemonArg then&lt;br /&gt;
		for _, part in ipairs(mw.text.split(pokemonArg, &#039;\\&#039;, true)) do&lt;br /&gt;
			local trimmed = mw.text.trim(part)&lt;br /&gt;
			if trimmed ~= &#039;&#039; then&lt;br /&gt;
				members[#members + 1] = trimmed&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		members = { name }&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local requirements = args.Requirements or &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
	if #members == 1 then&lt;br /&gt;
		local cardHtml, row = memberCard(frame, members[1], true)&lt;br /&gt;
		if not row then&lt;br /&gt;
			return cardHtml&lt;br /&gt;
		end&lt;br /&gt;
		local c = typeColor(frame, row.type1)&lt;br /&gt;
		-- Explicit width (matching the 240px member card plus this wrapper&#039;s&lt;br /&gt;
		-- own padding/border) instead of shrink-to-fit, so the card&#039;s size&lt;br /&gt;
		-- is driven by its fixed layout, not by how long Requirements is.&lt;br /&gt;
		return &#039;&amp;lt;div style=&amp;quot;display: inline-block; vertical-align: top; box-sizing: border-box; width: 250px; &#039; ..&lt;br /&gt;
			&#039;background-color: #&#039; .. c.base .. &#039;; border: 1px solid #&#039; .. c.dark ..&lt;br /&gt;
			&#039;; border-radius: 22px; padding: 4px; margin: 4px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
			cardHtml .. requirementsBox(c.dark, requirements) .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local firstRow = pokemonByName()[members[1]]&lt;br /&gt;
	local genRoman = nonEmpty(args.Gen) or (firstRow and genToRoman(firstRow.generation)) or &#039;?&#039;&lt;br /&gt;
	local regionName = regionForGen(frame, genRoman)&lt;br /&gt;
	local rc = regionColor(frame, regionName)&lt;br /&gt;
&lt;br /&gt;
	local cardsHtml = {}&lt;br /&gt;
	for _, member in ipairs(members) do&lt;br /&gt;
		local cardHtml = memberCard(frame, member, false)&lt;br /&gt;
		cardsHtml[#cardsHtml + 1] = cardHtml&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Explicit width sized to the member-card row (240px card + 8px margin&lt;br /&gt;
	-- each, plus this wrapper&#039;s own padding/border) instead of shrink-to-fit&lt;br /&gt;
	-- -- same reasoning as the single-card case, otherwise a long&lt;br /&gt;
	-- Requirements sentence inflates the whole band far past its cards.&lt;br /&gt;
	local groupWidth = (#members * 248) + 20&lt;br /&gt;
&lt;br /&gt;
	local buf = {}&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;display: inline-block; vertical-align: top; box-sizing: border-box; width: &#039; ..&lt;br /&gt;
		groupWidth .. &#039;px; max-width: 100%; background-color: #&#039; .. rc.base .. &#039;; border: 3px solid #&#039; .. rc.dark ..&lt;br /&gt;
		&#039;; border-radius: 25px; padding: 6px; margin: 4px; text-align: center;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;width: 100%; box-sizing: border-box; background-color: #&#039; .. rc.light ..&lt;br /&gt;
		&#039;; border-radius: 20px; padding: 8px; color: #&#039; .. rc.dark .. &#039;; font-weight: bold;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;span style=&amp;quot;font-size: 18px;&amp;quot;&amp;gt;&#039; .. name .. &#039;&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&amp;lt;span style=&amp;quot;font-size: 12px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;[[:Category:Generation &#039; .. genRoman .. &#039; Pokémon|&amp;lt;span style=&amp;quot;color: #&#039; .. rc.dark ..&lt;br /&gt;
		&#039;;&amp;quot;&amp;gt;Generation &#039; .. genRoman .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;display: flex; flex-wrap: wrap; justify-content: center; margin-top: 6px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		table.concat(cardsHtml) .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;width: 100%; box-sizing: border-box; background-color: #&#039; .. rc.light ..&lt;br /&gt;
		&#039;; border-radius: 20px; padding: 6px; margin-top: 6px; color: #&#039; .. rc.dark ..&lt;br /&gt;
		&#039;; font-weight: bold; text-align: left;&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;text-align: center;&amp;quot;&amp;gt;Availability&amp;lt;/div&amp;gt;&#039; ..&lt;br /&gt;
		requirementsBox(rc.dark, requirements) .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
	return table.concat(buf)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Module:LegendaryPokemon&amp;diff=41041</id>
		<title>Module:LegendaryPokemon</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Module:LegendaryPokemon&amp;diff=41041"/>
		<updated>2026-08-04T17:59:27Z</updated>

		<summary type="html">&lt;p&gt;Cae: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {}&lt;br /&gt;
&lt;br /&gt;
local DATA_FORMAT = &#039;CSV with header&#039;&lt;br /&gt;
local STAT_MAX = 255&lt;br /&gt;
local ROMAN = { &#039;I&#039;, &#039;II&#039;, &#039;III&#039;, &#039;IV&#039;, &#039;V&#039;, &#039;VI&#039;, &#039;VII&#039;, &#039;VIII&#039;, &#039;IX&#039; }&lt;br /&gt;
&lt;br /&gt;
local function nonEmpty(s)&lt;br /&gt;
	if s == nil then return nil end&lt;br /&gt;
	s = mw.text.trim(tostring(s))&lt;br /&gt;
	if s == &#039;&#039; then return nil end&lt;br /&gt;
	return s&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local pokemonRowsCache = nil&lt;br /&gt;
local function pokemonByName()&lt;br /&gt;
	if pokemonRowsCache then return pokemonRowsCache end&lt;br /&gt;
	local csvData = mw.ext.externalData.getExternalData{&lt;br /&gt;
		url = &#039;https://wiki.pokemonrevolution.net/index.php?title=Special:GetData/PokemonRawList&#039;,&lt;br /&gt;
		format = DATA_FORMAT,&lt;br /&gt;
		data = {&lt;br /&gt;
			number = &#039;Pokedex Number&#039;, name = &#039;Name&#039;, type1 = &#039;Type1&#039;, type2 = &#039;Type2&#039;, generation = &#039;Generation&#039;,&lt;br /&gt;
			hp = &#039;HP&#039;, atk = &#039;Attack&#039;, def = &#039;Defense&#039;, spatk = &#039;Special Attack&#039;, spdef = &#039;Special Defense&#039;,&lt;br /&gt;
			spd = &#039;Speed&#039;,&lt;br /&gt;
		},&lt;br /&gt;
	}&lt;br /&gt;
	pokemonRowsCache = {}&lt;br /&gt;
	if csvData then&lt;br /&gt;
		for _, row in ipairs(csvData) do&lt;br /&gt;
			if nonEmpty(row.name) then&lt;br /&gt;
				pokemonRowsCache[row.name] = row&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return pokemonRowsCache&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local typeColorCache = {}&lt;br /&gt;
local function typeColor(frame, pokeType)&lt;br /&gt;
	pokeType = nonEmpty(pokeType) or &#039;Normal&#039;&lt;br /&gt;
	if not typeColorCache[pokeType] then&lt;br /&gt;
		typeColorCache[pokeType] = {&lt;br /&gt;
			light = frame:expandTemplate{ title = pokeType .. &#039; color light&#039; },&lt;br /&gt;
			base = frame:expandTemplate{ title = pokeType .. &#039; color&#039; },&lt;br /&gt;
			dark = frame:expandTemplate{ title = pokeType .. &#039; color dark&#039; },&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
	return typeColorCache[pokeType]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local regionNameCache = {}&lt;br /&gt;
local function regionForGen(frame, genRoman)&lt;br /&gt;
	if not regionNameCache[genRoman] then&lt;br /&gt;
		regionNameCache[genRoman] = frame:expandTemplate{ title = &#039;LegendaryRegionFromGen&#039;, args = { genRoman } }&lt;br /&gt;
	end&lt;br /&gt;
	return regionNameCache[genRoman]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local regionColorCache = {}&lt;br /&gt;
local function regionColor(frame, regionName)&lt;br /&gt;
	if not regionColorCache[regionName] then&lt;br /&gt;
		regionColorCache[regionName] = {&lt;br /&gt;
			light = frame:expandTemplate{ title = regionName .. &#039; color light&#039; },&lt;br /&gt;
			base = frame:expandTemplate{ title = regionName .. &#039; color&#039; },&lt;br /&gt;
			dark = frame:expandTemplate{ title = regionName .. &#039; color dark&#039; },&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
	return regionColorCache[regionName]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function genToRoman(genValue)&lt;br /&gt;
	local digits = mw.ustring.match(tostring(genValue or &#039;&#039;), &#039;^%d+&#039;)&lt;br /&gt;
	local n = digits and tonumber(digits)&lt;br /&gt;
	return (n and ROMAN[n]) or tostring(genValue or &#039;&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function statBar(frame, label, value, dark)&lt;br /&gt;
	value = tonumber(value) or 0&lt;br /&gt;
	local pct = math.max(0, math.min(100, (value / STAT_MAX) * 100))&lt;br /&gt;
	local hue = math.floor((math.max(0, math.min(STAT_MAX, value)) / STAT_MAX) * 130) -- red (low) -&amp;gt; teal (high)&lt;br /&gt;
	return &#039;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;width: 38%; text-align: left; padding: 1px 4px; font-size: 10px; color: #&#039; .. dark ..&lt;br /&gt;
		&#039;;&amp;quot;&amp;gt;&#039; .. label .. &#039;&amp;lt;/td&amp;gt;&amp;lt;td style=&amp;quot;padding: 1px 4px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;div style=&amp;quot;background: #FFFFFF; border: 1px solid #&#039; .. dark .. &#039;; border-radius: 7px; overflow: hidden;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;div style=&amp;quot;width: &#039; .. pct .. &#039;%; background: hsl(&#039; .. hue ..&lt;br /&gt;
		&#039;, 65%, 45%); color: #FFFFFF; font-size: 9px; font-weight: normal; padding: 1px 4px; &#039; ..&lt;br /&gt;
		&#039;white-space: nowrap;&amp;quot;&amp;gt;&#039; .. value .. &#039;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Cells are forced to an even 50/50 split (rather than sizing to content) so&lt;br /&gt;
-- a longer type name -- &amp;quot;Fighting&amp;quot; next to &amp;quot;Psychic&amp;quot;, say -- can&#039;t crowd the&lt;br /&gt;
-- other cell into overflowing; text is still free to wrap onto a second&lt;br /&gt;
-- line at that width rather than being clipped.&lt;br /&gt;
local function typeBadges(frame, row)&lt;br /&gt;
	local t1 = nonEmpty(row.type1)&lt;br /&gt;
	local t2 = nonEmpty(row.type2)&lt;br /&gt;
	local c1 = typeColor(frame, t1)&lt;br /&gt;
	if not t2 then&lt;br /&gt;
		return &#039;&amp;lt;table align=&amp;quot;center&amp;quot; style=&amp;quot;width: 85%; font-weight: bold; font-size: 11px;&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&#039; ..&lt;br /&gt;
			&#039;&amp;lt;td style=&amp;quot;background-color: #&#039; .. c1.dark .. &#039;; border-radius: 12px; padding: 3px;&amp;quot;&amp;gt;[[&#039; .. t1 ..&lt;br /&gt;
			&#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. t1 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	local c2 = typeColor(frame, t2)&lt;br /&gt;
	return &#039;&amp;lt;table align=&amp;quot;center&amp;quot; style=&amp;quot;width: 85%; table-layout: fixed; font-weight: bold; font-size: 11px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;width: 50%; box-sizing: border-box; background-color: #&#039; .. c1.dark ..&lt;br /&gt;
		&#039;; border-radius: 12px 1px 1px 12px; padding: 3px; overflow-wrap: break-word;&amp;quot;&amp;gt;[[&#039; ..&lt;br /&gt;
		t1 .. &#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. t1 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;width: 50%; box-sizing: border-box; background-color: #&#039; .. c2.dark ..&lt;br /&gt;
		&#039;; border-radius: 1px 12px 12px 1px; padding: 3px; overflow-wrap: break-word;&amp;quot;&amp;gt;[[&#039; ..&lt;br /&gt;
		t2 .. &#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. t2 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function memberCard(frame, name, showGeneration)&lt;br /&gt;
	local row = pokemonByName()[name]&lt;br /&gt;
	if not row then&lt;br /&gt;
		return &#039;&amp;lt;div style=&amp;quot;display: inline-block; vertical-align: top; box-sizing: border-box; width: 240px; &#039; ..&lt;br /&gt;
			&#039;margin: 4px; color: red;&amp;quot;&amp;gt;Data load error: No Pokémon data found for &#039; .. name .. &#039;&amp;lt;/div&amp;gt;&#039;, nil&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local c = typeColor(frame, row.type1)&lt;br /&gt;
	local bst = (tonumber(row.hp) or 0) + (tonumber(row.atk) or 0) + (tonumber(row.def) or 0) +&lt;br /&gt;
		(tonumber(row.spatk) or 0) + (tonumber(row.spdef) or 0) + (tonumber(row.spd) or 0)&lt;br /&gt;
&lt;br /&gt;
	local genLine = &#039;&#039;&lt;br /&gt;
	if showGeneration then&lt;br /&gt;
		local genRoman = genToRoman(row.generation)&lt;br /&gt;
		genLine = &#039;&amp;lt;br&amp;gt;&amp;lt;span style=&amp;quot;font-size: 11px;&amp;quot;&amp;gt;[[:Category:Generation &#039; .. genRoman ..&lt;br /&gt;
			&#039; Pokémon|&amp;lt;span style=&amp;quot;color: #&#039; .. c.dark .. &#039;;&amp;quot;&amp;gt;Generation &#039; .. genRoman .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local buf = {}&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;display: inline-block; vertical-align: top; box-sizing: border-box; &#039; ..&lt;br /&gt;
		&#039;width: 240px; margin: 4px; background-color: #&#039; .. c.base .. &#039;; border: 2px solid #&#039; .. c.dark ..&lt;br /&gt;
		&#039;; border-radius: 18px; padding: 6px; text-align: center; color: #&#039; .. c.dark .. &#039;; font-weight: bold;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;background-color: #&#039; .. c.light .. &#039;; border-radius: 15px; padding: 5px; &#039; ..&lt;br /&gt;
		&#039;margin-bottom: 6px;&amp;quot;&amp;gt;#&#039; .. (row.number or &#039;&#039;) .. &#039;&amp;amp;nbsp;&amp;lt;span style=&amp;quot;font-size: 16px;&amp;quot;&amp;gt;[[&#039; .. name ..&lt;br /&gt;
		&#039;|&amp;lt;span style=&amp;quot;color: #&#039; .. c.dark .. &#039;;&amp;quot;&amp;gt;&#039; .. name .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/span&amp;gt;&#039; .. genLine .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;background-color: #FFFFFF; border-radius: 15px; height: 150px; display: flex; &#039; ..&lt;br /&gt;
		&#039;align-items: center; justify-content: center; margin-bottom: 6px;&amp;quot;&amp;gt;[[File:&#039; .. (row.number or &#039;&#039;) ..&lt;br /&gt;
		name .. &#039;.png|150px]]&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = typeBadges(frame, row)&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;table style=&amp;quot;width: 100%; margin-top: 6px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		statBar(frame, &#039;HP&#039;, row.hp, c.dark) ..&lt;br /&gt;
		statBar(frame, &#039;Attack&#039;, row.atk, c.dark) ..&lt;br /&gt;
		statBar(frame, &#039;Defense&#039;, row.def, c.dark) ..&lt;br /&gt;
		statBar(frame, &#039;Sp. Atk&#039;, row.spatk, c.dark) ..&lt;br /&gt;
		statBar(frame, &#039;Sp. Def&#039;, row.spdef, c.dark) ..&lt;br /&gt;
		statBar(frame, &#039;Speed&#039;, row.spd, c.dark) ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;text-align: left; padding: 3px 4px; font-size: 11px;&amp;quot;&amp;gt;Total&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;padding: 3px 4px; font-size: 11px;&amp;quot;&amp;gt;&#039; .. bst .. &#039;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
	return table.concat(buf), row&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- width: 100% + border-box is the actual fix here: without a constrained&lt;br /&gt;
-- width, a long Requirements sentence has no wrap point to size against, so&lt;br /&gt;
-- the inline-block ancestor&#039;s shrink-to-fit layout stretches the *whole&lt;br /&gt;
-- card* to fit that one line instead of wrapping text inside a fixed box.&lt;br /&gt;
local function requirementsBox(dark, requirements)&lt;br /&gt;
	return &#039;&amp;lt;div style=&amp;quot;width: 100%; box-sizing: border-box; background-color: #FFFFFF; color: #000000; &#039; ..&lt;br /&gt;
		&#039;border-radius: 15px; font-weight: normal; text-align: left; border: 1px solid #&#039; .. dark ..&lt;br /&gt;
		&#039;; padding: 8px; margin-top: 4px; overflow-wrap: break-word;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		(requirements or &#039;&#039;) .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.card(frame)&lt;br /&gt;
	local parent = frame:getParent()&lt;br /&gt;
	local args = (parent and parent.args) or frame.args&lt;br /&gt;
&lt;br /&gt;
	local name = nonEmpty(args.Name)&lt;br /&gt;
	if not name then&lt;br /&gt;
		return &amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;Usage: {{LegendaryPokemon|Name=...|Requirements=...|&amp;quot; ..&lt;br /&gt;
			&amp;quot;Pokemon=Name1\\Name2 (omit Pokemon= for a single-species entry)}}&amp;lt;/span&amp;gt;&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local pokemonArg = nonEmpty(args.Pokemon)&lt;br /&gt;
	local members = {}&lt;br /&gt;
	if pokemonArg then&lt;br /&gt;
		for _, part in ipairs(mw.text.split(pokemonArg, &#039;\\&#039;, true)) do&lt;br /&gt;
			local trimmed = mw.text.trim(part)&lt;br /&gt;
			if trimmed ~= &#039;&#039; then&lt;br /&gt;
				members[#members + 1] = trimmed&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		members = { name }&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local requirements = args.Requirements or &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
	if #members == 1 then&lt;br /&gt;
		local cardHtml, row = memberCard(frame, members[1], true)&lt;br /&gt;
		if not row then&lt;br /&gt;
			return cardHtml&lt;br /&gt;
		end&lt;br /&gt;
		local c = typeColor(frame, row.type1)&lt;br /&gt;
		-- Explicit width (matching the 240px member card plus this wrapper&#039;s&lt;br /&gt;
		-- own padding/border) instead of shrink-to-fit, so the card&#039;s size&lt;br /&gt;
		-- is driven by its fixed layout, not by how long Requirements is.&lt;br /&gt;
		-- No background fill here -- the member card underneath is already&lt;br /&gt;
		-- fully colored, so this wrapper stays a plain thin frame instead of&lt;br /&gt;
		-- doubling the same color behind it.&lt;br /&gt;
		return &#039;&amp;lt;div style=&amp;quot;display: inline-block; vertical-align: top; box-sizing: border-box; width: 250px; &#039; ..&lt;br /&gt;
			&#039;border: 1px solid #&#039; .. c.dark .. &#039;; border-radius: 20px; padding: 4px; margin: 4px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
			cardHtml .. requirementsBox(c.dark, requirements) .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local firstRow = pokemonByName()[members[1]]&lt;br /&gt;
	local genRoman = nonEmpty(args.Gen) or (firstRow and genToRoman(firstRow.generation)) or &#039;?&#039;&lt;br /&gt;
	local regionName = regionForGen(frame, genRoman)&lt;br /&gt;
	local rc = regionColor(frame, regionName)&lt;br /&gt;
&lt;br /&gt;
	local cardsHtml = {}&lt;br /&gt;
	for _, member in ipairs(members) do&lt;br /&gt;
		local cardHtml = memberCard(frame, member, false)&lt;br /&gt;
		cardsHtml[#cardsHtml + 1] = cardHtml&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Explicit width sized to the member-card row (240px card + 8px margin&lt;br /&gt;
	-- each, plus this wrapper&#039;s own padding/border) instead of shrink-to-fit&lt;br /&gt;
	-- -- same reasoning as the single-card case, otherwise a long&lt;br /&gt;
	-- Requirements sentence inflates the whole band far past its cards.&lt;br /&gt;
	local groupWidth = (#members * 248) + 20&lt;br /&gt;
&lt;br /&gt;
	-- The band itself stays a light neutral tint with just a thin colored&lt;br /&gt;
	-- border -- the member cards underneath are already fully colored in&lt;br /&gt;
	-- their own type, so filling the band behind them with a second solid&lt;br /&gt;
	-- region color doubled up the saturation instead of adding information.&lt;br /&gt;
	-- The region color still reads clearly via the title pill and border.&lt;br /&gt;
	local buf = {}&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;display: inline-block; vertical-align: top; box-sizing: border-box; width: &#039; ..&lt;br /&gt;
		groupWidth .. &#039;px; max-width: 100%; background-color: #F7F7F7; border: 2px solid #&#039; .. rc.dark ..&lt;br /&gt;
		&#039;; border-radius: 22px; padding: 6px; margin: 4px; text-align: center;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;width: 100%; box-sizing: border-box; background-color: #&#039; .. rc.light ..&lt;br /&gt;
		&#039;; border-radius: 18px; padding: 8px; color: #&#039; .. rc.dark .. &#039;; font-weight: bold;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;span style=&amp;quot;font-size: 18px;&amp;quot;&amp;gt;&#039; .. name .. &#039;&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&amp;lt;span style=&amp;quot;font-size: 12px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;[[:Category:Generation &#039; .. genRoman .. &#039; Pokémon|&amp;lt;span style=&amp;quot;color: #&#039; .. rc.dark ..&lt;br /&gt;
		&#039;;&amp;quot;&amp;gt;Generation &#039; .. genRoman .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;display: flex; flex-wrap: wrap; justify-content: center; margin-top: 6px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		table.concat(cardsHtml) .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;width: 100%; box-sizing: border-box; background-color: #&#039; .. rc.light ..&lt;br /&gt;
		&#039;; border-radius: 18px; padding: 6px; margin-top: 6px; color: #&#039; .. rc.dark ..&lt;br /&gt;
		&#039;; font-weight: bold; text-align: left;&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;text-align: center;&amp;quot;&amp;gt;Availability&amp;lt;/div&amp;gt;&#039; ..&lt;br /&gt;
		requirementsBox(rc.dark, requirements) .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
	return table.concat(buf)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Module:LegendaryPokemon&amp;diff=41040</id>
		<title>Module:LegendaryPokemon</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Module:LegendaryPokemon&amp;diff=41040"/>
		<updated>2026-08-04T17:42:27Z</updated>

		<summary type="html">&lt;p&gt;Cae: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {}&lt;br /&gt;
&lt;br /&gt;
local DATA_FORMAT = &#039;CSV with header&#039;&lt;br /&gt;
local STAT_MAX = 255&lt;br /&gt;
local ROMAN = { &#039;I&#039;, &#039;II&#039;, &#039;III&#039;, &#039;IV&#039;, &#039;V&#039;, &#039;VI&#039;, &#039;VII&#039;, &#039;VIII&#039;, &#039;IX&#039; }&lt;br /&gt;
&lt;br /&gt;
local function nonEmpty(s)&lt;br /&gt;
	if s == nil then return nil end&lt;br /&gt;
	s = mw.text.trim(tostring(s))&lt;br /&gt;
	if s == &#039;&#039; then return nil end&lt;br /&gt;
	return s&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local pokemonRowsCache = nil&lt;br /&gt;
local function pokemonByName()&lt;br /&gt;
	if pokemonRowsCache then return pokemonRowsCache end&lt;br /&gt;
	local csvData = mw.ext.externalData.getExternalData{&lt;br /&gt;
		url = &#039;https://wiki.pokemonrevolution.net/index.php?title=Special:GetData/PokemonRawList&#039;,&lt;br /&gt;
		format = DATA_FORMAT,&lt;br /&gt;
		data = {&lt;br /&gt;
			number = &#039;Pokedex Number&#039;, name = &#039;Name&#039;, type1 = &#039;Type1&#039;, type2 = &#039;Type2&#039;, generation = &#039;Generation&#039;,&lt;br /&gt;
			hp = &#039;HP&#039;, atk = &#039;Attack&#039;, def = &#039;Defense&#039;, spatk = &#039;Special Attack&#039;, spdef = &#039;Special Defense&#039;,&lt;br /&gt;
			spd = &#039;Speed&#039;,&lt;br /&gt;
		},&lt;br /&gt;
	}&lt;br /&gt;
	pokemonRowsCache = {}&lt;br /&gt;
	if csvData then&lt;br /&gt;
		for _, row in ipairs(csvData) do&lt;br /&gt;
			if nonEmpty(row.name) then&lt;br /&gt;
				pokemonRowsCache[row.name] = row&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return pokemonRowsCache&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local typeColorCache = {}&lt;br /&gt;
local function typeColor(frame, pokeType)&lt;br /&gt;
	pokeType = nonEmpty(pokeType) or &#039;Normal&#039;&lt;br /&gt;
	if not typeColorCache[pokeType] then&lt;br /&gt;
		typeColorCache[pokeType] = {&lt;br /&gt;
			light = frame:expandTemplate{ title = pokeType .. &#039; color light&#039; },&lt;br /&gt;
			base = frame:expandTemplate{ title = pokeType .. &#039; color&#039; },&lt;br /&gt;
			dark = frame:expandTemplate{ title = pokeType .. &#039; color dark&#039; },&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
	return typeColorCache[pokeType]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local regionNameCache = {}&lt;br /&gt;
local function regionForGen(frame, genRoman)&lt;br /&gt;
	if not regionNameCache[genRoman] then&lt;br /&gt;
		regionNameCache[genRoman] = frame:expandTemplate{ title = &#039;LegendaryRegionFromGen&#039;, args = { genRoman } }&lt;br /&gt;
	end&lt;br /&gt;
	return regionNameCache[genRoman]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local regionColorCache = {}&lt;br /&gt;
local function regionColor(frame, regionName)&lt;br /&gt;
	if not regionColorCache[regionName] then&lt;br /&gt;
		regionColorCache[regionName] = {&lt;br /&gt;
			light = frame:expandTemplate{ title = regionName .. &#039; color light&#039; },&lt;br /&gt;
			base = frame:expandTemplate{ title = regionName .. &#039; color&#039; },&lt;br /&gt;
			dark = frame:expandTemplate{ title = regionName .. &#039; color dark&#039; },&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
	return regionColorCache[regionName]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function genToRoman(genValue)&lt;br /&gt;
	local digits = mw.ustring.match(tostring(genValue or &#039;&#039;), &#039;^%d+&#039;)&lt;br /&gt;
	local n = digits and tonumber(digits)&lt;br /&gt;
	return (n and ROMAN[n]) or tostring(genValue or &#039;&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function statBar(frame, label, value, dark)&lt;br /&gt;
	value = tonumber(value) or 0&lt;br /&gt;
	local pct = math.max(0, math.min(100, (value / STAT_MAX) * 100))&lt;br /&gt;
	local hue = math.floor((math.max(0, math.min(STAT_MAX, value)) / STAT_MAX) * 130) -- red (low) -&amp;gt; teal (high)&lt;br /&gt;
	return &#039;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;width: 40%; text-align: left; padding: 2px 4px; font-size: 11px; color: #&#039; .. dark ..&lt;br /&gt;
		&#039;;&amp;quot;&amp;gt;&#039; .. label .. &#039;&amp;lt;/td&amp;gt;&amp;lt;td style=&amp;quot;padding: 2px 4px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;div style=&amp;quot;background: #FFFFFF; border: 1px solid #&#039; .. dark .. &#039;; border-radius: 8px; overflow: hidden;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;div style=&amp;quot;width: &#039; .. pct .. &#039;%; background: hsl(&#039; .. hue ..&lt;br /&gt;
		&#039;, 65%, 45%); color: #FFFFFF; font-size: 10px; font-weight: normal; padding: 1px 4px; &#039; ..&lt;br /&gt;
		&#039;white-space: nowrap;&amp;quot;&amp;gt;&#039; .. value .. &#039;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function typeBadges(frame, row)&lt;br /&gt;
	local t1 = nonEmpty(row.type1)&lt;br /&gt;
	local t2 = nonEmpty(row.type2)&lt;br /&gt;
	local c1 = typeColor(frame, t1)&lt;br /&gt;
	if not t2 then&lt;br /&gt;
		return &#039;&amp;lt;table align=&amp;quot;center&amp;quot; style=&amp;quot;width: 80%; font-weight: bold; font-size: 12px;&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&#039; ..&lt;br /&gt;
			&#039;&amp;lt;td style=&amp;quot;background-color: #&#039; .. c1.dark .. &#039;; border-radius: 15px; padding: 2px;&amp;quot;&amp;gt;[[&#039; .. t1 ..&lt;br /&gt;
			&#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. t1 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	local c2 = typeColor(frame, t2)&lt;br /&gt;
	return &#039;&amp;lt;table align=&amp;quot;center&amp;quot; style=&amp;quot;width: 80%; font-weight: bold; font-size: 12px;&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;background-color: #&#039; .. c1.dark .. &#039;; border-radius: 15px 1px 1px 15px; padding: 2px;&amp;quot;&amp;gt;[[&#039; ..&lt;br /&gt;
		t1 .. &#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. t1 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;background-color: #&#039; .. c2.dark .. &#039;; border-radius: 1px 15px 15px 1px; padding: 2px;&amp;quot;&amp;gt;[[&#039; ..&lt;br /&gt;
		t2 .. &#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. t2 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function memberCard(frame, name, showGeneration)&lt;br /&gt;
	local row = pokemonByName()[name]&lt;br /&gt;
	if not row then&lt;br /&gt;
		return &#039;&amp;lt;div style=&amp;quot;display: inline-block; vertical-align: top; box-sizing: border-box; width: 240px; &#039; ..&lt;br /&gt;
			&#039;margin: 4px; color: red;&amp;quot;&amp;gt;Data load error: No Pokémon data found for &#039; .. name .. &#039;&amp;lt;/div&amp;gt;&#039;, nil&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local c = typeColor(frame, row.type1)&lt;br /&gt;
	local bst = (tonumber(row.hp) or 0) + (tonumber(row.atk) or 0) + (tonumber(row.def) or 0) +&lt;br /&gt;
		(tonumber(row.spatk) or 0) + (tonumber(row.spdef) or 0) + (tonumber(row.spd) or 0)&lt;br /&gt;
&lt;br /&gt;
	local genLine = &#039;&#039;&lt;br /&gt;
	if showGeneration then&lt;br /&gt;
		local genRoman = genToRoman(row.generation)&lt;br /&gt;
		genLine = &#039;&amp;lt;br&amp;gt;&amp;lt;span style=&amp;quot;font-size: 11px;&amp;quot;&amp;gt;[[:Category:Generation &#039; .. genRoman ..&lt;br /&gt;
			&#039; Pokémon|&amp;lt;span style=&amp;quot;color: #&#039; .. c.dark .. &#039;;&amp;quot;&amp;gt;Generation &#039; .. genRoman .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local buf = {}&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;display: inline-block; vertical-align: top; box-sizing: border-box; &#039; ..&lt;br /&gt;
		&#039;width: 240px; margin: 4px; background-color: #&#039; .. c.base .. &#039;; border: 3px solid #&#039; .. c.dark ..&lt;br /&gt;
		&#039;; border-radius: 20px; padding: 6px; text-align: center; color: #&#039; .. c.dark .. &#039;; font-weight: bold;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;background-color: #&#039; .. c.light .. &#039;; border-radius: 15px; padding: 5px; &#039; ..&lt;br /&gt;
		&#039;margin-bottom: 6px;&amp;quot;&amp;gt;#&#039; .. (row.number or &#039;&#039;) .. &#039;&amp;amp;nbsp;&amp;lt;span style=&amp;quot;font-size: 16px;&amp;quot;&amp;gt;[[&#039; .. name ..&lt;br /&gt;
		&#039;|&amp;lt;span style=&amp;quot;color: #&#039; .. c.dark .. &#039;;&amp;quot;&amp;gt;&#039; .. name .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/span&amp;gt;&#039; .. genLine .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;background-color: #FFFFFF; border-radius: 15px; height: 150px; display: flex; &#039; ..&lt;br /&gt;
		&#039;align-items: center; justify-content: center; margin-bottom: 6px;&amp;quot;&amp;gt;[[File:&#039; .. (row.number or &#039;&#039;) ..&lt;br /&gt;
		name .. &#039;.png|150px]]&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = typeBadges(frame, row)&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;table style=&amp;quot;width: 100%; margin-top: 6px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		statBar(frame, &#039;HP&#039;, row.hp, c.dark) ..&lt;br /&gt;
		statBar(frame, &#039;Attack&#039;, row.atk, c.dark) ..&lt;br /&gt;
		statBar(frame, &#039;Defense&#039;, row.def, c.dark) ..&lt;br /&gt;
		statBar(frame, &#039;Sp. Atk&#039;, row.spatk, c.dark) ..&lt;br /&gt;
		statBar(frame, &#039;Sp. Def&#039;, row.spdef, c.dark) ..&lt;br /&gt;
		statBar(frame, &#039;Speed&#039;, row.spd, c.dark) ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;text-align: left; padding: 3px 4px; font-size: 11px;&amp;quot;&amp;gt;Total&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;padding: 3px 4px; font-size: 11px;&amp;quot;&amp;gt;&#039; .. bst .. &#039;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
	return table.concat(buf), row&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- width: 100% + border-box is the actual fix here: without a constrained&lt;br /&gt;
-- width, a long Requirements sentence has no wrap point to size against, so&lt;br /&gt;
-- the inline-block ancestor&#039;s shrink-to-fit layout stretches the *whole&lt;br /&gt;
-- card* to fit that one line instead of wrapping text inside a fixed box.&lt;br /&gt;
local function requirementsBox(dark, requirements)&lt;br /&gt;
	return &#039;&amp;lt;div style=&amp;quot;width: 100%; box-sizing: border-box; background-color: #FFFFFF; color: #000000; &#039; ..&lt;br /&gt;
		&#039;border-radius: 15px; font-weight: normal; text-align: left; border: 1px solid #&#039; .. dark ..&lt;br /&gt;
		&#039;; padding: 8px; margin-top: 4px; overflow-wrap: break-word;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		(requirements or &#039;&#039;) .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.card(frame)&lt;br /&gt;
	local parent = frame:getParent()&lt;br /&gt;
	local args = (parent and parent.args) or frame.args&lt;br /&gt;
&lt;br /&gt;
	local name = nonEmpty(args.Name)&lt;br /&gt;
	if not name then&lt;br /&gt;
		return &amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;Usage: {{LegendaryPokemon|Name=...|Requirements=...|&amp;quot; ..&lt;br /&gt;
			&amp;quot;Pokemon=Name1\\Name2 (omit Pokemon= for a single-species entry)}}&amp;lt;/span&amp;gt;&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local pokemonArg = nonEmpty(args.Pokemon)&lt;br /&gt;
	local members = {}&lt;br /&gt;
	if pokemonArg then&lt;br /&gt;
		for _, part in ipairs(mw.text.split(pokemonArg, &#039;\\&#039;, true)) do&lt;br /&gt;
			local trimmed = mw.text.trim(part)&lt;br /&gt;
			if trimmed ~= &#039;&#039; then&lt;br /&gt;
				members[#members + 1] = trimmed&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		members = { name }&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local requirements = args.Requirements or &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
	if #members == 1 then&lt;br /&gt;
		local cardHtml, row = memberCard(frame, members[1], true)&lt;br /&gt;
		if not row then&lt;br /&gt;
			return cardHtml&lt;br /&gt;
		end&lt;br /&gt;
		local c = typeColor(frame, row.type1)&lt;br /&gt;
		-- Explicit width (matching the 240px member card plus this wrapper&#039;s&lt;br /&gt;
		-- own padding/border) instead of shrink-to-fit, so the card&#039;s size&lt;br /&gt;
		-- is driven by its fixed layout, not by how long Requirements is.&lt;br /&gt;
		return &#039;&amp;lt;div style=&amp;quot;display: inline-block; vertical-align: top; box-sizing: border-box; width: 250px; &#039; ..&lt;br /&gt;
			&#039;background-color: #&#039; .. c.base .. &#039;; border: 1px solid #&#039; .. c.dark ..&lt;br /&gt;
			&#039;; border-radius: 22px; padding: 4px; margin: 4px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
			cardHtml .. requirementsBox(c.dark, requirements) .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local firstRow = pokemonByName()[members[1]]&lt;br /&gt;
	local genRoman = nonEmpty(args.Gen) or (firstRow and genToRoman(firstRow.generation)) or &#039;?&#039;&lt;br /&gt;
	local regionName = regionForGen(frame, genRoman)&lt;br /&gt;
	local rc = regionColor(frame, regionName)&lt;br /&gt;
&lt;br /&gt;
	local cardsHtml = {}&lt;br /&gt;
	for _, member in ipairs(members) do&lt;br /&gt;
		local cardHtml = memberCard(frame, member, false)&lt;br /&gt;
		cardsHtml[#cardsHtml + 1] = cardHtml&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Explicit width sized to the member-card row (240px card + 8px margin&lt;br /&gt;
	-- each, plus this wrapper&#039;s own padding/border) instead of shrink-to-fit&lt;br /&gt;
	-- -- same reasoning as the single-card case, otherwise a long&lt;br /&gt;
	-- Requirements sentence inflates the whole band far past its cards.&lt;br /&gt;
	local groupWidth = (#members * 248) + 20&lt;br /&gt;
&lt;br /&gt;
	local buf = {}&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;display: inline-block; vertical-align: top; box-sizing: border-box; width: &#039; ..&lt;br /&gt;
		groupWidth .. &#039;px; max-width: 100%; background-color: #&#039; .. rc.base .. &#039;; border: 3px solid #&#039; .. rc.dark ..&lt;br /&gt;
		&#039;; border-radius: 25px; padding: 6px; margin: 4px; text-align: center;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;width: 100%; box-sizing: border-box; background-color: #&#039; .. rc.light ..&lt;br /&gt;
		&#039;; border-radius: 20px; padding: 8px; color: #&#039; .. rc.dark .. &#039;; font-weight: bold;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;span style=&amp;quot;font-size: 18px;&amp;quot;&amp;gt;&#039; .. name .. &#039;&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&amp;lt;span style=&amp;quot;font-size: 12px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;[[:Category:Generation &#039; .. genRoman .. &#039; Pokémon|&amp;lt;span style=&amp;quot;color: #&#039; .. rc.dark ..&lt;br /&gt;
		&#039;;&amp;quot;&amp;gt;Generation &#039; .. genRoman .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;display: flex; flex-wrap: wrap; justify-content: center; margin-top: 6px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		table.concat(cardsHtml) .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;width: 100%; box-sizing: border-box; background-color: #&#039; .. rc.light ..&lt;br /&gt;
		&#039;; border-radius: 20px; padding: 6px; margin-top: 6px; color: #&#039; .. rc.dark ..&lt;br /&gt;
		&#039;; font-weight: bold; text-align: left;&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;text-align: center;&amp;quot;&amp;gt;Availability&amp;lt;/div&amp;gt;&#039; ..&lt;br /&gt;
		requirementsBox(rc.dark, requirements) .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
	return table.concat(buf)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Module:LegendaryPokemon&amp;diff=41039</id>
		<title>Module:LegendaryPokemon</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Module:LegendaryPokemon&amp;diff=41039"/>
		<updated>2026-08-04T17:33:16Z</updated>

		<summary type="html">&lt;p&gt;Cae: created module&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {}&lt;br /&gt;
&lt;br /&gt;
local DATA_FORMAT = &#039;CSV with header&#039;&lt;br /&gt;
local STAT_MAX = 255&lt;br /&gt;
local ROMAN = { &#039;I&#039;, &#039;II&#039;, &#039;III&#039;, &#039;IV&#039;, &#039;V&#039;, &#039;VI&#039;, &#039;VII&#039;, &#039;VIII&#039;, &#039;IX&#039; }&lt;br /&gt;
&lt;br /&gt;
local function nonEmpty(s)&lt;br /&gt;
	if s == nil then return nil end&lt;br /&gt;
	s = mw.text.trim(tostring(s))&lt;br /&gt;
	if s == &#039;&#039; then return nil end&lt;br /&gt;
	return s&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local pokemonRowsCache = nil&lt;br /&gt;
local function pokemonByName()&lt;br /&gt;
	if pokemonRowsCache then return pokemonRowsCache end&lt;br /&gt;
	local csvData = mw.ext.externalData.getExternalData{&lt;br /&gt;
		url = &#039;https://wiki.pokemonrevolution.net/index.php?title=Special:GetData/PokemonRawList&#039;,&lt;br /&gt;
		format = DATA_FORMAT,&lt;br /&gt;
		data = {&lt;br /&gt;
			number = &#039;Pokedex Number&#039;, name = &#039;Name&#039;, type1 = &#039;Type1&#039;, type2 = &#039;Type2&#039;, generation = &#039;Generation&#039;,&lt;br /&gt;
			hp = &#039;HP&#039;, atk = &#039;Attack&#039;, def = &#039;Defense&#039;, spatk = &#039;Special Attack&#039;, spdef = &#039;Special Defense&#039;,&lt;br /&gt;
			spd = &#039;Speed&#039;,&lt;br /&gt;
		},&lt;br /&gt;
	}&lt;br /&gt;
	pokemonRowsCache = {}&lt;br /&gt;
	if csvData then&lt;br /&gt;
		for _, row in ipairs(csvData) do&lt;br /&gt;
			if nonEmpty(row.name) then&lt;br /&gt;
				pokemonRowsCache[row.name] = row&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return pokemonRowsCache&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local typeColorCache = {}&lt;br /&gt;
local function typeColor(frame, pokeType)&lt;br /&gt;
	pokeType = nonEmpty(pokeType) or &#039;Normal&#039;&lt;br /&gt;
	if not typeColorCache[pokeType] then&lt;br /&gt;
		typeColorCache[pokeType] = {&lt;br /&gt;
			light = frame:expandTemplate{ title = pokeType .. &#039; color light&#039; },&lt;br /&gt;
			base = frame:expandTemplate{ title = pokeType .. &#039; color&#039; },&lt;br /&gt;
			dark = frame:expandTemplate{ title = pokeType .. &#039; color dark&#039; },&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
	return typeColorCache[pokeType]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local regionNameCache = {}&lt;br /&gt;
local function regionForGen(frame, genRoman)&lt;br /&gt;
	if not regionNameCache[genRoman] then&lt;br /&gt;
		regionNameCache[genRoman] = frame:expandTemplate{ title = &#039;LegendaryRegionFromGen&#039;, args = { genRoman } }&lt;br /&gt;
	end&lt;br /&gt;
	return regionNameCache[genRoman]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local regionColorCache = {}&lt;br /&gt;
local function regionColor(frame, regionName)&lt;br /&gt;
	if not regionColorCache[regionName] then&lt;br /&gt;
		regionColorCache[regionName] = {&lt;br /&gt;
			light = frame:expandTemplate{ title = regionName .. &#039; color light&#039; },&lt;br /&gt;
			base = frame:expandTemplate{ title = regionName .. &#039; color&#039; },&lt;br /&gt;
			dark = frame:expandTemplate{ title = regionName .. &#039; color dark&#039; },&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
	return regionColorCache[regionName]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function genToRoman(genValue)&lt;br /&gt;
	local digits = mw.ustring.match(tostring(genValue or &#039;&#039;), &#039;^%d+&#039;)&lt;br /&gt;
	local n = digits and tonumber(digits)&lt;br /&gt;
	return (n and ROMAN[n]) or tostring(genValue or &#039;&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function statBar(frame, label, value, dark)&lt;br /&gt;
	value = tonumber(value) or 0&lt;br /&gt;
	local pct = math.max(0, math.min(100, (value / STAT_MAX) * 100))&lt;br /&gt;
	local hue = math.floor((math.max(0, math.min(STAT_MAX, value)) / STAT_MAX) * 130) -- red (low) -&amp;gt; teal (high)&lt;br /&gt;
	return &#039;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;width: 40%; text-align: left; padding: 2px 4px; font-size: 11px; color: #&#039; .. dark ..&lt;br /&gt;
		&#039;;&amp;quot;&amp;gt;&#039; .. label .. &#039;&amp;lt;/td&amp;gt;&amp;lt;td style=&amp;quot;padding: 2px 4px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;div style=&amp;quot;background: #FFFFFF; border: 1px solid #&#039; .. dark .. &#039;; border-radius: 8px; overflow: hidden;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;div style=&amp;quot;width: &#039; .. pct .. &#039;%; background: hsl(&#039; .. hue ..&lt;br /&gt;
		&#039;, 65%, 45%); color: #FFFFFF; font-size: 10px; font-weight: normal; padding: 1px 4px; &#039; ..&lt;br /&gt;
		&#039;white-space: nowrap;&amp;quot;&amp;gt;&#039; .. value .. &#039;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function typeBadges(frame, row)&lt;br /&gt;
	local t1 = nonEmpty(row.type1)&lt;br /&gt;
	local t2 = nonEmpty(row.type2)&lt;br /&gt;
	local c1 = typeColor(frame, t1)&lt;br /&gt;
	if not t2 then&lt;br /&gt;
		return &#039;&amp;lt;table align=&amp;quot;center&amp;quot; style=&amp;quot;width: 80%; font-weight: bold; font-size: 12px;&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&#039; ..&lt;br /&gt;
			&#039;&amp;lt;td style=&amp;quot;background-color: #&#039; .. c1.dark .. &#039;; border-radius: 15px; padding: 2px;&amp;quot;&amp;gt;[[&#039; .. t1 ..&lt;br /&gt;
			&#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. t1 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	local c2 = typeColor(frame, t2)&lt;br /&gt;
	return &#039;&amp;lt;table align=&amp;quot;center&amp;quot; style=&amp;quot;width: 80%; font-weight: bold; font-size: 12px;&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;background-color: #&#039; .. c1.dark .. &#039;; border-radius: 15px 1px 1px 15px; padding: 2px;&amp;quot;&amp;gt;[[&#039; ..&lt;br /&gt;
		t1 .. &#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. t1 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;background-color: #&#039; .. c2.dark .. &#039;; border-radius: 1px 15px 15px 1px; padding: 2px;&amp;quot;&amp;gt;[[&#039; ..&lt;br /&gt;
		t2 .. &#039;_(type)|&amp;lt;span style=&amp;quot;color: #FFFFFF;&amp;quot;&amp;gt;&#039; .. t2 .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function memberCard(frame, name, showGeneration)&lt;br /&gt;
	local row = pokemonByName()[name]&lt;br /&gt;
	if not row then&lt;br /&gt;
		return &#039;&amp;lt;div style=&amp;quot;display: inline-block; vertical-align: top; width: 240px; margin: 4px; &#039; ..&lt;br /&gt;
			&#039;color: red;&amp;quot;&amp;gt;Data load error: No Pokémon data found for &#039; .. name .. &#039;&amp;lt;/div&amp;gt;&#039;, nil&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local c = typeColor(frame, row.type1)&lt;br /&gt;
	local bst = (tonumber(row.hp) or 0) + (tonumber(row.atk) or 0) + (tonumber(row.def) or 0) +&lt;br /&gt;
		(tonumber(row.spatk) or 0) + (tonumber(row.spdef) or 0) + (tonumber(row.spd) or 0)&lt;br /&gt;
&lt;br /&gt;
	local genLine = &#039;&#039;&lt;br /&gt;
	if showGeneration then&lt;br /&gt;
		local genRoman = genToRoman(row.generation)&lt;br /&gt;
		genLine = &#039;&amp;lt;br&amp;gt;&amp;lt;span style=&amp;quot;font-size: 11px;&amp;quot;&amp;gt;[[:Category:Generation &#039; .. genRoman ..&lt;br /&gt;
			&#039; Pokémon|&amp;lt;span style=&amp;quot;color: #&#039; .. c.dark .. &#039;;&amp;quot;&amp;gt;Generation &#039; .. genRoman .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local buf = {}&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;display: inline-block; vertical-align: top; width: 240px; margin: 4px; &#039; ..&lt;br /&gt;
		&#039;background-color: #&#039; .. c.base .. &#039;; border: 3px solid #&#039; .. c.dark ..&lt;br /&gt;
		&#039;; border-radius: 20px; padding: 6px; text-align: center; color: #&#039; .. c.dark .. &#039;; font-weight: bold;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;background-color: #&#039; .. c.light .. &#039;; border-radius: 15px; padding: 5px; &#039; ..&lt;br /&gt;
		&#039;margin-bottom: 6px;&amp;quot;&amp;gt;#&#039; .. (row.number or &#039;&#039;) .. &#039;&amp;amp;nbsp;&amp;lt;span style=&amp;quot;font-size: 16px;&amp;quot;&amp;gt;[[&#039; .. name ..&lt;br /&gt;
		&#039;|&amp;lt;span style=&amp;quot;color: #&#039; .. c.dark .. &#039;;&amp;quot;&amp;gt;&#039; .. name .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/span&amp;gt;&#039; .. genLine .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;background-color: #FFFFFF; border-radius: 15px; height: 150px; display: flex; &#039; ..&lt;br /&gt;
		&#039;align-items: center; justify-content: center; margin-bottom: 6px;&amp;quot;&amp;gt;[[File:&#039; .. (row.number or &#039;&#039;) ..&lt;br /&gt;
		name .. &#039;.png|150px]]&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = typeBadges(frame, row)&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;table style=&amp;quot;width: 100%; margin-top: 6px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		statBar(frame, &#039;HP&#039;, row.hp, c.dark) ..&lt;br /&gt;
		statBar(frame, &#039;Attack&#039;, row.atk, c.dark) ..&lt;br /&gt;
		statBar(frame, &#039;Defense&#039;, row.def, c.dark) ..&lt;br /&gt;
		statBar(frame, &#039;Sp. Atk&#039;, row.spatk, c.dark) ..&lt;br /&gt;
		statBar(frame, &#039;Sp. Def&#039;, row.spdef, c.dark) ..&lt;br /&gt;
		statBar(frame, &#039;Speed&#039;, row.spd, c.dark) ..&lt;br /&gt;
		&#039;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;text-align: left; padding: 3px 4px; font-size: 11px;&amp;quot;&amp;gt;Total&amp;lt;/td&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;td style=&amp;quot;padding: 3px 4px; font-size: 11px;&amp;quot;&amp;gt;&#039; .. bst .. &#039;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
	return table.concat(buf), row&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function requirementsBox(dark, requirements)&lt;br /&gt;
	return &#039;&amp;lt;div style=&amp;quot;background-color: #FFFFFF; color: #000000; border-radius: 15px; font-weight: normal; &#039; ..&lt;br /&gt;
		&#039;text-align: left; border: 1px solid #&#039; .. dark .. &#039;; padding: 8px; margin-top: 4px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		(requirements or &#039;&#039;) .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.card(frame)&lt;br /&gt;
	local parent = frame:getParent()&lt;br /&gt;
	local args = (parent and parent.args) or frame.args&lt;br /&gt;
&lt;br /&gt;
	local name = nonEmpty(args.Name)&lt;br /&gt;
	if not name then&lt;br /&gt;
		return &amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;Usage: {{LegendaryPokemon|Name=...|Requirements=...|&amp;quot; ..&lt;br /&gt;
			&amp;quot;Pokemon=Name1\\Name2 (omit Pokemon= for a single-species entry)}}&amp;lt;/span&amp;gt;&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local pokemonArg = nonEmpty(args.Pokemon)&lt;br /&gt;
	local members = {}&lt;br /&gt;
	if pokemonArg then&lt;br /&gt;
		for _, part in ipairs(mw.text.split(pokemonArg, &#039;\\&#039;, true)) do&lt;br /&gt;
			local trimmed = mw.text.trim(part)&lt;br /&gt;
			if trimmed ~= &#039;&#039; then&lt;br /&gt;
				members[#members + 1] = trimmed&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		members = { name }&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local requirements = args.Requirements or &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
	if #members == 1 then&lt;br /&gt;
		local cardHtml, row = memberCard(frame, members[1], true)&lt;br /&gt;
		if not row then&lt;br /&gt;
			return cardHtml&lt;br /&gt;
		end&lt;br /&gt;
		local c = typeColor(frame, row.type1)&lt;br /&gt;
		return &#039;&amp;lt;div style=&amp;quot;display: inline-block; vertical-align: top; background-color: #&#039; .. c.base ..&lt;br /&gt;
			&#039;; border: 1px solid #&#039; .. c.dark .. &#039;; border-radius: 22px; padding: 4px; margin: 4px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
			cardHtml .. requirementsBox(c.dark, requirements) .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local firstRow = pokemonByName()[members[1]]&lt;br /&gt;
	local genRoman = nonEmpty(args.Gen) or (firstRow and genToRoman(firstRow.generation)) or &#039;?&#039;&lt;br /&gt;
	local regionName = regionForGen(frame, genRoman)&lt;br /&gt;
	local rc = regionColor(frame, regionName)&lt;br /&gt;
&lt;br /&gt;
	local cardsHtml = {}&lt;br /&gt;
	for _, member in ipairs(members) do&lt;br /&gt;
		local cardHtml = memberCard(frame, member, false)&lt;br /&gt;
		cardsHtml[#cardsHtml + 1] = cardHtml&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local buf = {}&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;display: inline-block; vertical-align: top; background-color: #&#039; .. rc.base ..&lt;br /&gt;
		&#039;; border: 3px solid #&#039; .. rc.dark .. &#039;; border-radius: 25px; padding: 6px; margin: 4px; &#039; ..&lt;br /&gt;
		&#039;text-align: center; max-width: 100%;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;background-color: #&#039; .. rc.light .. &#039;; border-radius: 20px; padding: 8px; &#039; ..&lt;br /&gt;
		&#039;color: #&#039; .. rc.dark .. &#039;; font-weight: bold;&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;font-size: 18px;&amp;quot;&amp;gt;&#039; .. name ..&lt;br /&gt;
		&#039;&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&amp;lt;span style=&amp;quot;font-size: 12px;&amp;quot;&amp;gt;[[:Category:Generation &#039; .. genRoman ..&lt;br /&gt;
		&#039; Pokémon|&amp;lt;span style=&amp;quot;color: #&#039; .. rc.dark .. &#039;;&amp;quot;&amp;gt;Generation &#039; .. genRoman .. &#039;&amp;lt;/span&amp;gt;]]&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;display: flex; flex-wrap: wrap; justify-content: center; margin-top: 6px;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		table.concat(cardsHtml) .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;div style=&amp;quot;background-color: #&#039; .. rc.light .. &#039;; border-radius: 20px; padding: 6px; &#039; ..&lt;br /&gt;
		&#039;margin-top: 6px; color: #&#039; .. rc.dark .. &#039;; font-weight: bold; text-align: left;&amp;quot;&amp;gt;&#039; ..&lt;br /&gt;
		&#039;&amp;lt;div style=&amp;quot;text-align: center;&amp;quot;&amp;gt;Availability&amp;lt;/div&amp;gt;&#039; .. requirementsBox(rc.dark, requirements) .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	buf[#buf + 1] = &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
	return table.concat(buf)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Victory_Road_Hoenn&amp;diff=41028</id>
		<title>Victory Road Hoenn</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Victory_Road_Hoenn&amp;diff=41028"/>
		<updated>2026-08-02T14:49:13Z</updated>

		<summary type="html">&lt;p&gt;Cae: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Area|Location=Hoenn|Maps=Victory Road Hoenn 1F,Victory Road Hoenn B1F,Victory Road Hoenn B2F|Type=Cave|Region=Hoenn|North=Ever Grande City|South=Ever Grande City|LandLevels=45|LandTier9=2|LandMembers=2|WaterLevels=45|Items=4|BattleNPCs=12}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;{{PAGENAME}}&#039;&#039;&#039; is a [[Hoenn]] located in the middle of [[Ever Grande City]]. Leading to the Pokémon League, it can only be accessed after obtaining all 8 regional badges. However, other than being the final cave with high level trainers and Pokémons, there isn&#039;t anything interesting inside the cave.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Notable miscellanies==&lt;br /&gt;
===Rachel&#039;s Friends Quest (Basuki)===&lt;br /&gt;
Two of the locations the seventh friend of Rachel can be found in is in Victory Road Hoenn. The first location is in B1F&#039;s north-east corner, which requires to take the north-eastmost ladder of B2F. The second location is in B2F, near its north-west corner. He will trade the player&#039;s [[Pokeball]] for a [[Potion]].&lt;br /&gt;
&lt;br /&gt;
The next friend to find will be Bambang, who can be found either in [[Cave of Origin]], [[Jagged Pass]] or [[Fiery Path]].&lt;br /&gt;
&lt;br /&gt;
==Wild Pokémon==&lt;br /&gt;
===Victory Road Hoenn 1F===&lt;br /&gt;
{{AreaLandSpawns|Location=Victory Road Hoenn 1F}}&lt;br /&gt;
&lt;br /&gt;
===Victory Road Hoenn B1F===&lt;br /&gt;
{{AreaLandSpawns|Location=Victory Road Hoenn B1F}}&lt;br /&gt;
&lt;br /&gt;
===Victory Road Hoenn B2F===&lt;br /&gt;
====Land====&lt;br /&gt;
{{AreaLandSpawns|Location=Victory Road Hoenn B2F}}&lt;br /&gt;
====Water====&lt;br /&gt;
{{AreaSurfSpawns|Location=Victory Road Hoenn B2F}}&lt;br /&gt;
&lt;br /&gt;
==Items==&lt;br /&gt;
{{AreaItems|Contents=&lt;br /&gt;
{{AIR|Item=Ultra Ball|Quantity=2|Cooldown=Not respawnable|Location=In the south-east corner of 1F. Requires to use a ladder of B1F}}&lt;br /&gt;
{{AIR|Item=PP Up|Quantity=1|Cooldown=Not respawnable|Location=At the west side of B1F. Right after you took the ladder of 1F}}&lt;br /&gt;
{{AIR|Item=Max Potion|Quantity=1|Cooldown=Not respawnable|Location=North of the south-westmost ladder of B1F}}&lt;br /&gt;
{{AIR|Item=Max Repel|Quantity=1|Cooldown=Not respawnable|Location=In the center north ground of B2F. Requires Surf}}&lt;br /&gt;
{{AIR|Item=Iron|Quantity=3|Cooldown=Not respawnable|Location=Hidden item. On the closest rock up the stairs in the southeast corner of B2F}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==NPC Battlables==&lt;br /&gt;
===Victory Road Hoenn 1F===&lt;br /&gt;
{{NPCTable|Location={{PAGENAME}} 1F|Contents=&lt;br /&gt;
{{NPCTrainer|Class=Ace Trainer|Name=Albert|Gender=boy|Lineup=&lt;br /&gt;
{{NPCLineup|Pokemon=Sigilyph,Rhyperior|Levels=63,64}}&lt;br /&gt;
}}&lt;br /&gt;
{{NPCTrainer|Class=Ace Trainer|Name=Hope|Gender=shaman|Lineup=&lt;br /&gt;
{{NPCLineup|Pokemon=Froslass|Levels=65}}&lt;br /&gt;
}}&lt;br /&gt;
{{NPCTrainer|Class=Street Thug|Name=Regan|Lineup=&lt;br /&gt;
{{NPCLineup|Pokemon=Houndoom,Shiftry|Levels=65,65}}&lt;br /&gt;
}}&lt;br /&gt;
{{NPCTrainer|Class=Ace Trainer|Name=Edgar|Gender=boy|Lineup=&lt;br /&gt;
{{NPCLineup|Pokemon=Mawile|Levels=65}}&lt;br /&gt;
}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Victory Road Hoenn B1F===&lt;br /&gt;
{{NPCTable|Location={{PAGENAME}} B1F|Contents=&lt;br /&gt;
{{NPCTrainer|Class=Ace Trainer|Name=Rory|Gender=boy|Lineup=&lt;br /&gt;
{{NPCLineup|Pokemon=Armaldo|Levels=65}}&lt;br /&gt;
}}&lt;br /&gt;
{{NPCTrainer|Class=Ace Trainer|Name=Jude|Gender=girl|Lineup=&lt;br /&gt;
{{NPCLineup|Pokemon=Cradily|Levels=65}}&lt;br /&gt;
}}&lt;br /&gt;
{{NPCTrainer|Class=Blackbelt|Name=Aden|Lineup=&lt;br /&gt;
{{NPCLineup|Pokemon=Primeape|Levels=63}}&lt;br /&gt;
}}&lt;br /&gt;
{{NPCTrainer|Class=Battle Girl|Name=Finn|Lineup=&lt;br /&gt;
{{NPCLineup|Pokemon=Musharna|Levels=65}}&lt;br /&gt;
}}&lt;br /&gt;
{{NPCTrainer|Class=Expert|Name=Bryn|Lineup=&lt;br /&gt;
{{NPCLineup|Pokemon=Hitmontop,Throh|Levels=64,65}}&lt;br /&gt;
}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Victory Road Hoenn B2F===&lt;br /&gt;
{{NPCTable|Location={{PAGENAME}} B2F|Contents=&lt;br /&gt;
{{NPCTrainer|Class=Expert|Name=Theodore|Lineup=&lt;br /&gt;
{{NPCLineup|Pokemon=Sawk|Levels=63}}&lt;br /&gt;
}}&lt;br /&gt;
{{NPCTrainer|Class=Dragon Tamer|Name=Egon|Lineup=&lt;br /&gt;
{{NPCLineup|Pokemon=Kingdra|Levels=64}}&lt;br /&gt;
}}&lt;br /&gt;
{{NPCTrainer|Class=Ace Trainer|Name=Vito|Gender=boy|Lineup=&lt;br /&gt;
{{NPCLineup|Pokemon=Electrode,Darmanitan,Swalot|Levels=63,64,65}}&lt;br /&gt;
}}&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Victory_Road_Hoenn&amp;diff=41027</id>
		<title>Victory Road Hoenn</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Victory_Road_Hoenn&amp;diff=41027"/>
		<updated>2026-08-02T14:49:03Z</updated>

		<summary type="html">&lt;p&gt;Cae: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Area|Location=Hoenn|Maps=Victory Road Hoenn 1F,Victory Road Hoenn B1F,Victory Road Hoenn B2F|Type=Cave|Region=Hoenn|North=Ever Grande City|South=Ever Grande City|LandLevels=45|LandTier9=2|LandMembers=2|WaterLevels=45|Items=4|BattleNPCs=12}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;{{PAGENAME}}&#039;&#039;&#039; is a [[Hoenn]] located in the middle of [[Ever Grande City]]. Leading to the Pokémon League, it can only be accessed after obtaining all 8 regional badges. However, other than being the final cave with high level trainers and Pokémons, there isn&#039;t anything interesting inside the cave.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Notable miscellanies==&lt;br /&gt;
===Rachel&#039;s Friends Quest (Basuki)===&lt;br /&gt;
Two of the locations the seventh friend of Rachel can be found in is in Victory Road Hoenn. The first location is in B1F&#039;s north-east corner, which requires to take the north-eastmost ladder of B2F. The second location is in B2F, near its north-west corner. He will trade the player&#039;s [[Pokeball]] for a [[Potion]].&lt;br /&gt;
&lt;br /&gt;
The next friend to find will be Bambang, who can be found either in [[Cave of Origin]], [[Jagged Pass]] or [[Fiery Path]].&lt;br /&gt;
&lt;br /&gt;
==Wild Pokémon==&lt;br /&gt;
===Victory Road Hoenn 1F===&lt;br /&gt;
{{EVTable|Contents=&lt;br /&gt;
{{EVRow|Morning=Morning|Day=Day|Night=Night|Speed=0.94|HP=0.35}}&lt;br /&gt;
}}&lt;br /&gt;
{{AreaLandSpawns|Location=Victory Road Hoenn 1F}}&lt;br /&gt;
&lt;br /&gt;
===Victory Road Hoenn B1F===&lt;br /&gt;
{{AreaLandSpawns|Location=Victory Road Hoenn B1F}}&lt;br /&gt;
&lt;br /&gt;
===Victory Road Hoenn B2F===&lt;br /&gt;
====Land====&lt;br /&gt;
{{AreaLandSpawns|Location=Victory Road Hoenn B2F}}&lt;br /&gt;
====Water====&lt;br /&gt;
{{AreaSurfSpawns|Location=Victory Road Hoenn B2F}}&lt;br /&gt;
&lt;br /&gt;
==Items==&lt;br /&gt;
{{AreaItems|Contents=&lt;br /&gt;
{{AIR|Item=Ultra Ball|Quantity=2|Cooldown=Not respawnable|Location=In the south-east corner of 1F. Requires to use a ladder of B1F}}&lt;br /&gt;
{{AIR|Item=PP Up|Quantity=1|Cooldown=Not respawnable|Location=At the west side of B1F. Right after you took the ladder of 1F}}&lt;br /&gt;
{{AIR|Item=Max Potion|Quantity=1|Cooldown=Not respawnable|Location=North of the south-westmost ladder of B1F}}&lt;br /&gt;
{{AIR|Item=Max Repel|Quantity=1|Cooldown=Not respawnable|Location=In the center north ground of B2F. Requires Surf}}&lt;br /&gt;
{{AIR|Item=Iron|Quantity=3|Cooldown=Not respawnable|Location=Hidden item. On the closest rock up the stairs in the southeast corner of B2F}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==NPC Battlables==&lt;br /&gt;
===Victory Road Hoenn 1F===&lt;br /&gt;
{{NPCTable|Location={{PAGENAME}} 1F|Contents=&lt;br /&gt;
{{NPCTrainer|Class=Ace Trainer|Name=Albert|Gender=boy|Lineup=&lt;br /&gt;
{{NPCLineup|Pokemon=Sigilyph,Rhyperior|Levels=63,64}}&lt;br /&gt;
}}&lt;br /&gt;
{{NPCTrainer|Class=Ace Trainer|Name=Hope|Gender=shaman|Lineup=&lt;br /&gt;
{{NPCLineup|Pokemon=Froslass|Levels=65}}&lt;br /&gt;
}}&lt;br /&gt;
{{NPCTrainer|Class=Street Thug|Name=Regan|Lineup=&lt;br /&gt;
{{NPCLineup|Pokemon=Houndoom,Shiftry|Levels=65,65}}&lt;br /&gt;
}}&lt;br /&gt;
{{NPCTrainer|Class=Ace Trainer|Name=Edgar|Gender=boy|Lineup=&lt;br /&gt;
{{NPCLineup|Pokemon=Mawile|Levels=65}}&lt;br /&gt;
}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Victory Road Hoenn B1F===&lt;br /&gt;
{{NPCTable|Location={{PAGENAME}} B1F|Contents=&lt;br /&gt;
{{NPCTrainer|Class=Ace Trainer|Name=Rory|Gender=boy|Lineup=&lt;br /&gt;
{{NPCLineup|Pokemon=Armaldo|Levels=65}}&lt;br /&gt;
}}&lt;br /&gt;
{{NPCTrainer|Class=Ace Trainer|Name=Jude|Gender=girl|Lineup=&lt;br /&gt;
{{NPCLineup|Pokemon=Cradily|Levels=65}}&lt;br /&gt;
}}&lt;br /&gt;
{{NPCTrainer|Class=Blackbelt|Name=Aden|Lineup=&lt;br /&gt;
{{NPCLineup|Pokemon=Primeape|Levels=63}}&lt;br /&gt;
}}&lt;br /&gt;
{{NPCTrainer|Class=Battle Girl|Name=Finn|Lineup=&lt;br /&gt;
{{NPCLineup|Pokemon=Musharna|Levels=65}}&lt;br /&gt;
}}&lt;br /&gt;
{{NPCTrainer|Class=Expert|Name=Bryn|Lineup=&lt;br /&gt;
{{NPCLineup|Pokemon=Hitmontop,Throh|Levels=64,65}}&lt;br /&gt;
}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Victory Road Hoenn B2F===&lt;br /&gt;
{{NPCTable|Location={{PAGENAME}} B2F|Contents=&lt;br /&gt;
{{NPCTrainer|Class=Expert|Name=Theodore|Lineup=&lt;br /&gt;
{{NPCLineup|Pokemon=Sawk|Levels=63}}&lt;br /&gt;
}}&lt;br /&gt;
{{NPCTrainer|Class=Dragon Tamer|Name=Egon|Lineup=&lt;br /&gt;
{{NPCLineup|Pokemon=Kingdra|Levels=64}}&lt;br /&gt;
}}&lt;br /&gt;
{{NPCTrainer|Class=Ace Trainer|Name=Vito|Gender=boy|Lineup=&lt;br /&gt;
{{NPCLineup|Pokemon=Electrode,Darmanitan,Swalot|Levels=63,64,65}}&lt;br /&gt;
}}&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Steelworker_(ability)&amp;diff=41026</id>
		<title>Steelworker (ability)</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Steelworker_(ability)&amp;diff=41026"/>
		<updated>2026-08-02T14:46:30Z</updated>

		<summary type="html">&lt;p&gt;Cae: created page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Steelworker&#039;&#039;&#039; is one of the many [[Ability|abilities]] that are inheritable by Pokémon.&lt;br /&gt;
&lt;br /&gt;
==Function==&lt;br /&gt;
If a Steel-type move is used by a Pokémon with this Ability, its Attack or Special Attack stat is multiplied by 1.5 during damage calculation, effectively increasing damage dealt by 50%. &lt;br /&gt;
&lt;br /&gt;
==Inheritable Pokémon==&lt;br /&gt;
===Predominant ability===&lt;br /&gt;
====Primary====&lt;br /&gt;
{{PrimaryAbilityList|Gulp Missile|Theme=Water}}&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=File:881Arctozolt.png&amp;diff=41025</id>
		<title>File:881Arctozolt.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=File:881Arctozolt.png&amp;diff=41025"/>
		<updated>2026-08-02T14:42:30Z</updated>

		<summary type="html">&lt;p&gt;Cae: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Fossilized_Bird&amp;diff=41024</id>
		<title>Fossilized Bird</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Fossilized_Bird&amp;diff=41024"/>
		<updated>2026-08-02T14:41:33Z</updated>

		<summary type="html">&lt;p&gt;Cae: added redirect&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT[[Fossils]]&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Fossilized_Dino&amp;diff=41023</id>
		<title>Fossilized Dino</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Fossilized_Dino&amp;diff=41023"/>
		<updated>2026-08-02T14:41:16Z</updated>

		<summary type="html">&lt;p&gt;Cae: added redirect&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT[[Fossils]]&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Fossilized_Drake&amp;diff=41022</id>
		<title>Fossilized Drake</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Fossilized_Drake&amp;diff=41022"/>
		<updated>2026-08-02T14:40:44Z</updated>

		<summary type="html">&lt;p&gt;Cae: added redirect&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT[[Fossils]]&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Fossilized_Fish&amp;diff=41021</id>
		<title>Fossilized Fish</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Fossilized_Fish&amp;diff=41021"/>
		<updated>2026-08-02T14:40:44Z</updated>

		<summary type="html">&lt;p&gt;Cae: added redirect&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT[[Fossils]]&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Fossils&amp;diff=41020</id>
		<title>Fossils</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Fossils&amp;diff=41020"/>
		<updated>2026-08-02T14:38:39Z</updated>

		<summary type="html">&lt;p&gt;Cae: added the new Fossil Mons from Gen 8&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Fossils&#039;&#039;&#039;, phrasally referred to as &#039;&#039;&#039;Pokémon Fossils&#039;&#039;&#039;, are physiological vestiges of prehistoric Pokémon that can be biogenerated into fossilized Pokémon.&lt;br /&gt;
&lt;br /&gt;
Fossilized Pokémon tend to be scarcer than more organic Pokémon, as they are only originatively obtainable by obtaining a Fossil—a rarity in its own right—and reanimated into the living version of the Pokémon.&lt;br /&gt;
&lt;br /&gt;
They are most commonly obtained by unearthing them; the two systems available for doing so are [[diggable patches]] and [[Excavation|Excavation Sites]]. Additionally, all fossils but the Jaw Fossil and Sail Fossil are subsumed under [[Brock_(boss)|Brock]]&#039;s prizeset.&lt;br /&gt;
&lt;br /&gt;
==Reanimating Fossils==&lt;br /&gt;
Fossils can be reanimated by turning them in to bioscentists; one cadre of them is stationed in each region, as explained below.&lt;br /&gt;
&lt;br /&gt;
All fossilized Pokémon that are reanimated in the labs will be initialized at level 25, and there is a 1/1,000 chance of [[Pokémon Counterparts#Shiny Pokémon|shininess]]. Those that are reanimated by bioscientists in [[Excavation|Excavation Sites]] will be initialized at level 10; and as is the case with all NPC-initiated wild-Pokémon battles, they have no shiny chance.&lt;br /&gt;
===[[Kanto]]===&lt;br /&gt;
The Dome Fossil, Helix Fossil, Old Amber, Sail Fossil, and Jaw Fossil can be reanimated in [[Cinnabar Island]]&#039;s lab in room 3 of the lab; this also requires that you have defeated Blaine in [[Cinnabar Gym]], first, since the room will be inaccessible before then.&lt;br /&gt;
===[[Johto]]===&lt;br /&gt;
Contingent that the evolved-data entries of [[Omastar]] and [[Kabutops]] and the caught-data entry of [[Aerodactyl]] has been registered in your [[Pokédex]], the bioscientist in the [[Ruins of Alph]] research center will reanimate any Claw Fossil and Root Fossil turned in to him.&lt;br /&gt;
===[[Hoenn]]===&lt;br /&gt;
====Devon Corporation====&lt;br /&gt;
Upon completing the [[Rustboro City#Devon Corporation Building|Devon Corp quest]], one of the employees in Devon Corporation 2F ([[Rustboro City]]) will offer to the Dome Fossil, Helix Fossil, Old Amber, Root Fossil, and Claw Fossil.&lt;br /&gt;
====Historical Site====&lt;br /&gt;
With an accrual of at least 6,000 Discovery Points, all-seven of the available fossils can be reanimated by Gingery Jones in the [[Historical Site]].&lt;br /&gt;
&lt;br /&gt;
While this also stipulates a fee of {{Pdollar}}10,000 to do so, you will also have a wild encounter of the fossilized Pokémon; this allows you to [[Synchronize_(ability)|synchronize]] your Pokémon&#039;s Nature with the fossilized Pokémon upon catching it if your lead Pokémon possesses that ability.&lt;br /&gt;
===[[Sinnoh]]===&lt;br /&gt;
The Armor Fossil and Skull Fossil—Sinnoh&#039;s generationally respective subset of fossils—are reanimable at [[Oreburgh City#Fossil Revival|Oreburgh Mining Museum]], stipulating that [[Cradily]] and [[Armaldo]]&#039;s evolved-data entries are registered on your Pokédex—the fully evolved biogenerations of the Root Fossil and Claw Fossil, respectively.&lt;br /&gt;
&lt;br /&gt;
==Available Fossils==&lt;br /&gt;
{{Fossil|Fossil=Helix Fossil|Pokemon=Omanyte|Locations=One-off claimable in [[Mt. Moon]] after defeating Super Nerd Quinn. The other option is the Dome Fossil\[[Diggable patches]]\Potential prize for defeating [[Brock_(boss)|Brock&#039;s boss NPC]]\[[Excavation Sites]]\Selectable mid-quest reward from Scientist Alexander in the [[G.S. Ball (quest)|G.S. Ball quest]]\7th day reward for [[Celadon Daily (task system)]]}}&lt;br /&gt;
&lt;br /&gt;
{{Fossil|Fossil=Dome Fossil|Pokemon=Kabuto|Locations=One-off claimable in [[Mt. Moon]] after defeating Super Nerd Quinn. The other option is the Helix Fossil\[[Diggable patches]]\Potential prize for defeating [[Brock_(boss)|Brock&#039;s boss NPC]]\[[Excavation Sites]]\Selectable mid-quest reward from Scientist Alexander in the [[G.S. Ball (quest)|G.S. Ball quest]]\7th day reward for [[Celadon Daily (task system)]]}}&lt;br /&gt;
&lt;br /&gt;
{{Fossil|Fossil=Old Amber|Pokemon=Aerodactyl|Locations=[[Diggable patches]]\7th day reward for [[Celadon Daily (task system)]]\Potential prize for defeating [[Brock_(boss)|Brock&#039;s boss NPC]])\[[Excavation Sites]]\[[Historical Site]] for 200 artifact pieces}}&lt;br /&gt;
&lt;br /&gt;
{{Fossil|Fossil=Root Fossil|Pokemon=Lileep|Locations=[[Diggable patches]]\Potential prize for defeating [[Brock_(boss)|Brock&#039;s boss NPC]]\[[Excavation Sites]]\Selectable mid-quest reward from Scientist Alexander in the [[G.S. Ball (quest)|G.S. Ball quest]]\[[Historical Site]] for 100 artifact pieces\Held by [[Lileep]] in [[Mirage Island#Mirage Island Cave|Mirage Island Cave]]}}&lt;br /&gt;
&lt;br /&gt;
{{Fossil|Fossil=Claw Fossil|Pokemon=Anorith|Locations=[[Diggable patches]]\Potential prize for defeating [[Brock_(boss)|Brock&#039;s boss NPC]]\[[Excavation Sites]]\Selectable mid-quest reward from Scientist Alexander in the [[G.S. Ball (quest)|G.S. Ball quest]]\[[Historical Site]] for 100 artifact pieces\Held by [[Anorith]] in [[Mirage Island#Mirage Island Cave|Mirage Island Cave]]}}&lt;br /&gt;
&lt;br /&gt;
{{Fossil|Fossil=Jaw Fossil|Pokemon=Tyrunt|Locations=[[Diggable Patches]]\[[Excavation Sites]]\Potential prize for defeating [[Gingery Jones_(boss)|Gingery Jones]] in the [[Feral Site]]\[[Historical Site]] for 350 artifact pieces\Held by [[Tyrunt]] in [[Mirage Island#Mirage Island Cave|Mirage Island Cave]]}}&lt;br /&gt;
&lt;br /&gt;
{{Fossil|Fossil=Sail Fossil|Pokemon=Amaura|Locations=[[Diggable Patches]]\[[Excavation Sites]]\Potential prize for defeating [[Gingery Jones_(boss)|Gingery Jones]] in the [[Feral Site]]\[[Historical Site]] for 350 artifact pieces\Held by [[Amaura]] in [[Mirage Island#Mirage Island Cave|Mirage Island Cave]]}}&lt;br /&gt;
&lt;br /&gt;
{{Fossil|Fossil=Armor Fossil|Pokemon=Shieldon|Locations=[[Historical Site]] in exchange for 500 artifact pieces\Held by [[Shieldon]] in [[Mirage Island#Mirage Island Cave|Mirage Island Cave]]}}&lt;br /&gt;
&lt;br /&gt;
{{Fossil|Fossil=Skull Fossil|Pokemon=Cranidos|Locations=[[Historical Site]] in exchange for 500 artifact pieces\Held by [[Cranidos]] in [[Mirage Island#Mirage Island Cave|Mirage Island Cave]]}}&lt;br /&gt;
&lt;br /&gt;
{{FossilCombo|Fossil1=Fossilized Bird|Fossil2=Fossilized Drake|Pokemon=Dracozolt|Locations=Excavation}}&lt;br /&gt;
&lt;br /&gt;
{{FossilCombo|Fossil1=Fossilized Bird|Fossil2=Fossilized Dino|Pokemon=Arctozolt|Locations=Excavation}}&lt;br /&gt;
&lt;br /&gt;
{{FossilCombo|Fossil1=Fossilized Fish|Fossil2=Fossilized Drake|Pokemon=Dracovish|Locations=Excavation}}&lt;br /&gt;
&lt;br /&gt;
{{FossilCombo|Fossil1=Fossilized Fish|Fossil2=Fossilized Dino|Pokemon=Arctovish|Locations=Excavation}}&lt;br /&gt;
&lt;br /&gt;
==Other usages==&lt;br /&gt;
===Pewter Museum===&lt;br /&gt;
They can also be donated to [[Pewter Museum]]; after doing so, you will see the Fossil visibly on the pedestal north of the Curator.&lt;br /&gt;
&lt;br /&gt;
After donating three discrete Fossils, you will have access to the [[Ancient Power]]-[[Move tutors|tutor]] in [[Ruins of Alph]] Research Center for {{Pdollar}}3,500 per tutee.&lt;br /&gt;
&lt;br /&gt;
After donating five fossils, you will receive a [[Reroll Ticket]].&lt;br /&gt;
&lt;br /&gt;
===Artifact Maniac Hastor===&lt;br /&gt;
You are able to sell Fossils to Artifact Maniac Hastor for 20 Artifact Pieces each. He can be found inside [[Historical Site]].&lt;br /&gt;
[[Category:Items]] [[Category:Pokémon]]&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=File:Fossilized_Fish.png&amp;diff=41019</id>
		<title>File:Fossilized Fish.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=File:Fossilized_Fish.png&amp;diff=41019"/>
		<updated>2026-08-02T14:38:28Z</updated>

		<summary type="html">&lt;p&gt;Cae: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=File:Fossilized_Dino.png&amp;diff=41018</id>
		<title>File:Fossilized Dino.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=File:Fossilized_Dino.png&amp;diff=41018"/>
		<updated>2026-08-02T14:38:21Z</updated>

		<summary type="html">&lt;p&gt;Cae: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=File:Fossilized_Drake.png&amp;diff=41017</id>
		<title>File:Fossilized Drake.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=File:Fossilized_Drake.png&amp;diff=41017"/>
		<updated>2026-08-02T14:38:13Z</updated>

		<summary type="html">&lt;p&gt;Cae: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=File:Fossilized_Bird.png&amp;diff=41016</id>
		<title>File:Fossilized Bird.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=File:Fossilized_Bird.png&amp;diff=41016"/>
		<updated>2026-08-02T14:38:05Z</updated>

		<summary type="html">&lt;p&gt;Cae: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Template:FossilCombo&amp;diff=41015</id>
		<title>Template:FossilCombo</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Template:FossilCombo&amp;diff=41015"/>
		<updated>2026-08-02T14:28:52Z</updated>

		<summary type="html">&lt;p&gt;Cae: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;To be used to tabulate Pokémon-fossil data for Pokémon that are revived from two combined fossils (Dracozolt, Arctozolt, Dracovish, Arctovish), for applicative usage on the page of its namesake in [[fossils]]. For single-fossil Pokémon, use [[Template:Fossil]] instead.&lt;br /&gt;
&lt;br /&gt;
It accepts the following-four modular arguments: {{{Fossil1}}} and {{{Fossil2}}} for the two fossil names, {{{Pokemon}}} for the name of the Pokemon they combine into, and {{{Locations}}} for a list of areas where they&#039;re obtainable (using \ as the delimiter between discrete locations).&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&lt;br /&gt;
{{FossilCombo|Fossil1=Fossilized Bird|Fossil2=Fossilized Drake|Pokemon=Dracozolt|Locations=Excavation}}&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
&amp;lt;includeonly&amp;gt;{{#invoke:Fossil|combo}}&amp;lt;/includeonly&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
	<entry>
		<id>https://wiki.pokemonrevolution.net/index.php?title=Template:FossilCombo&amp;diff=41014</id>
		<title>Template:FossilCombo</title>
		<link rel="alternate" type="text/html" href="https://wiki.pokemonrevolution.net/index.php?title=Template:FossilCombo&amp;diff=41014"/>
		<updated>2026-08-02T14:27:49Z</updated>

		<summary type="html">&lt;p&gt;Cae: created page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;To be used to tabulate Pokémon-fossil data for Pokémon that are revived from two combined fossils (Dracozolt, Arctozolt, Dracovish, Arctovish), for applicative usage on the page of its namesake in [[fossils]]. For single-fossil Pokémon, use [[Template:Fossil]] instead.&lt;br /&gt;
&lt;br /&gt;
It accepts the following-four modular arguments: {{{Fossil1}}} and {{{Fossil2}}} for the two fossil names, {{{Pokemon}}} for the name of the Pokemon they combine into, and {{{Locations}}} for a list of areas where they&#039;re obtainable (using \ as the delimiter between discrete locations).&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&lt;br /&gt;
{{FossilCombo|Fossil1=Fossilized Bird|Fossil2=Fossilized Drake|Pokemon=Dracozolt|Locations=Location one\Location two}}&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
&amp;lt;includeonly&amp;gt;{{#invoke:Fossil|combo}}&amp;lt;/includeonly&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cae</name></author>
	</entry>
</feed>