<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://eurovision.jobogamer.xyz/index.php?action=history&amp;feed=atom&amp;title=Module%3AWomen_in_Red_event</id>
	<title>Module:Women in Red event - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://eurovision.jobogamer.xyz/index.php?action=history&amp;feed=atom&amp;title=Module%3AWomen_in_Red_event"/>
	<link rel="alternate" type="text/html" href="https://eurovision.jobogamer.xyz/index.php?title=Module:Women_in_Red_event&amp;action=history"/>
	<updated>2026-06-10T23:47:21Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.45.3</generator>
	<entry>
		<id>https://eurovision.jobogamer.xyz/index.php?title=Module:Women_in_Red_event&amp;diff=4618&amp;oldid=prev</id>
		<title>imported&gt;MSGJ: use pairs because not all events are numbered sequentially</title>
		<link rel="alternate" type="text/html" href="https://eurovision.jobogamer.xyz/index.php?title=Module:Women_in_Red_event&amp;diff=4618&amp;oldid=prev"/>
		<updated>2025-11-26T15:05:21Z</updated>

		<summary type="html">&lt;p&gt;use pairs because not all events are numbered sequentially&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;require(&amp;#039;strict&amp;#039;)&lt;br /&gt;
local p = {}&lt;br /&gt;
local data = mw.loadJsonData(&amp;#039;Wikipedia:WikiProject Women in Red/events&amp;#039;)&lt;br /&gt;
local currentDate = os.date(&amp;#039;*t&amp;#039;)&lt;br /&gt;
local lang = mw.getContentLanguage()&lt;br /&gt;
local frame = mw.getCurrentFrame()&lt;br /&gt;
local args = frame.args&lt;br /&gt;
local yesno = require(&amp;#039;Module:Yesno&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
local format_date = function(_date)&lt;br /&gt;
	local month = _date.month and _date.month-1 or 0&lt;br /&gt;
	return _date.year*12+month&lt;br /&gt;
end&lt;br /&gt;
local currentMonth = format_date(currentDate)&lt;br /&gt;
&lt;br /&gt;
local monthName = function(month, abbrev)&lt;br /&gt;
	local monthcode = month&amp;lt;10 and (&amp;#039;0&amp;#039;..tostring(month)) or tostring(month)&lt;br /&gt;
	local timestamp = &amp;#039;2024&amp;#039; .. monthcode .. &amp;#039;01000000&amp;#039;&lt;br /&gt;
	local _format = abbrev and &amp;#039;M&amp;#039; or &amp;#039;F&amp;#039;&lt;br /&gt;
	return lang:formatDate(_format, timestamp)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local _findLatest = function()&lt;br /&gt;
	local _max = 1&lt;br /&gt;
	for n, _ in pairs(data) do&lt;br /&gt;
		local val = tonumber(n) or 0&lt;br /&gt;
		if val&amp;lt;1000 and val&amp;gt;_max then&lt;br /&gt;
			_max = val&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return _max&lt;br /&gt;
end&lt;br /&gt;
p.findLatest = function()&lt;br /&gt;
	return _findLatest() + (tonumber(args.add) or 0)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local value = function(event, field, default)&lt;br /&gt;
	local data = data[tonumber(event)]&lt;br /&gt;
	if data and data[field] then&lt;br /&gt;
		return data[field]&lt;br /&gt;
	else&lt;br /&gt;
		return default&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local makeCat = function(cat, key, test)&lt;br /&gt;
	local key2 = key and not test and (&amp;#039;|&amp;#039; .. key) or &amp;#039;&amp;#039;&lt;br /&gt;
	return &amp;#039;[[&amp;#039; .. (test and &amp;#039;:&amp;#039; or &amp;#039;&amp;#039;) .. &amp;#039;Category:&amp;#039; .. cat .. key2 .. &amp;#039;]]&amp;#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local collapse = function(title, text)&lt;br /&gt;
	return frame:expandTemplate{title = &amp;#039;Collapsed top&amp;#039;, args = {&lt;br /&gt;
			bg = &amp;#039;transparent&amp;#039;,&lt;br /&gt;
			width = &amp;#039;80%&amp;#039;,&lt;br /&gt;
			[1] = title&lt;br /&gt;
		}} ..  text .. &amp;#039;&amp;lt;/table&amp;gt;&amp;lt;/div&amp;gt;&amp;#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
p.main = function()&lt;br /&gt;
	local ret = value(args[1], args[2], args[3] or &amp;#039;&amp;#039;)&lt;br /&gt;
	if args.hash==&amp;#039;no&amp;#039; and type(ret)==&amp;#039;string&amp;#039; then&lt;br /&gt;
		ret = ret:gsub(&amp;#039;#&amp;#039;, &amp;#039;&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
	if ret and type(ret)==&amp;#039;string&amp;#039; and ret:sub(1,1)==&amp;#039;#&amp;#039; then -- prevent # character from starting a list&lt;br /&gt;
		ret = mw.text.nowiki(ret)&lt;br /&gt;
	end&lt;br /&gt;
	return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local getDates = function(event, endDefaultsToStart)&lt;br /&gt;
	local _start = value(event, &amp;#039;start&amp;#039;) or {&lt;br /&gt;
		month = value(event, &amp;#039;month&amp;#039;),&lt;br /&gt;
		year = value(event, &amp;#039;year&amp;#039;)&lt;br /&gt;
	}&lt;br /&gt;
	local _end = value(event, &amp;#039;end&amp;#039;)&lt;br /&gt;
	if not _end and endDefaultsToStart then&lt;br /&gt;
		_end = _start&lt;br /&gt;
	end&lt;br /&gt;
	return _start, _end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local _date = function(event, sentence, abbrev)&lt;br /&gt;
	local _start, _end = getDates(event)&lt;br /&gt;
	local ret = &amp;#039;&amp;#039;&lt;br /&gt;
	if sentence then&lt;br /&gt;
		ret = _end and &amp;#039;from &amp;#039; or &amp;#039;in &amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	ret = ret .. (_start.month and monthName(_start.month, abbrev) or &amp;#039;&amp;#039;)&lt;br /&gt;
	if not _end or _start.year~=_end.year then&lt;br /&gt;
		ret = ret .. (_start.month and &amp;#039; &amp;#039; or &amp;#039;&amp;#039;) .. tostring(_start.year)&lt;br /&gt;
	end&lt;br /&gt;
	if _end then&lt;br /&gt;
		local to&lt;br /&gt;
		if sentence then&lt;br /&gt;
			to = &amp;#039; to &amp;#039;&lt;br /&gt;
		else&lt;br /&gt;
			if _start.year==_end.year then&lt;br /&gt;
				to = &amp;#039;–&amp;#039; -- en dash&lt;br /&gt;
			else&lt;br /&gt;
				to = &amp;#039; – &amp;#039; -- spaced en dash&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		ret = ret .. to .. monthName(_end.month, abbrev) .. &amp;#039; &amp;#039; .. tostring(_end.year)&lt;br /&gt;
	end&lt;br /&gt;
	local sortkey = os.time{&lt;br /&gt;
		year = _start.year or 0,&lt;br /&gt;
		month = _start.month or 1,&lt;br /&gt;
		day = _start.month and 2 or 1&lt;br /&gt;
	}&lt;br /&gt;
	return ret, sortkey&lt;br /&gt;
end&lt;br /&gt;
p.date = function()&lt;br /&gt;
	local event = tonumber(args[1])&lt;br /&gt;
	if data[event] then&lt;br /&gt;
		local date, _ = _date(&lt;br /&gt;
			event,&lt;br /&gt;
			yesno(frame.args.sentence or &amp;#039;false&amp;#039;),&lt;br /&gt;
			yesno(frame.args.abbrev or &amp;#039;false&amp;#039;)&lt;br /&gt;
		)&lt;br /&gt;
		return date&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
p.invitation = function()&lt;br /&gt;
	local event = tonumber(args[1])&lt;br /&gt;
	if not event then&lt;br /&gt;
		local page = mw.title.getCurrentTitle().text&lt;br /&gt;
		event = tonumber(page:match(&amp;#039;WikiProject Women in Red/Meetup/(%d+)&amp;#039;))&lt;br /&gt;
	end&lt;br /&gt;
	if data[event] then&lt;br /&gt;
		local _start, _ = getDates(event)&lt;br /&gt;
		local anchor = _start.month and (&amp;#039;#&amp;#039; .. monthName(_start.month) .. &amp;#039; &amp;#039; .. _start.year) or &amp;#039;&amp;#039;&lt;br /&gt;
		return &amp;#039;[[Wikipedia:WikiProject Women in Red/Outreach/&amp;#039; .. _start.year &lt;br /&gt;
			.. anchor&lt;br /&gt;
			.. &amp;#039;|WikiProject Women in Red/Outreach/&amp;#039; .. _start.year&lt;br /&gt;
			.. &amp;#039;]]&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local _name = function(meetup)&lt;br /&gt;
	local series = value(meetup, &amp;#039;series&amp;#039;)&lt;br /&gt;
	local name = value(meetup, &amp;#039;name&amp;#039;)&lt;br /&gt;
	local out = series or &amp;#039;&amp;#039;&lt;br /&gt;
	if series and name then&lt;br /&gt;
		out = out .. &amp;#039;: &amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	out = out .. (name or &amp;#039;&amp;#039;)&lt;br /&gt;
	return out&lt;br /&gt;
end&lt;br /&gt;
p.name = function()&lt;br /&gt;
	return mw.text.nowiki(_name(args[1]))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
p.nested = function()&lt;br /&gt;
-- Function to produce year for nested display in project banner&lt;br /&gt;
	local year = value(args[1], &amp;#039;year&amp;#039;)&lt;br /&gt;
	if not year and value(args[1], &amp;#039;start&amp;#039;) and value(args[1], &amp;#039;start&amp;#039;).year==value(args[1], &amp;#039;end&amp;#039;).year then&lt;br /&gt;
		year = value(args[1], &amp;#039;start&amp;#039;).year&lt;br /&gt;
	end&lt;br /&gt;
	return _name(args[1]) .. (year and (&amp;#039; (&amp;#039; .. year .. &amp;#039;)&amp;#039;) or &amp;#039;&amp;#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
p.text = function()&lt;br /&gt;
	local meetup = args[1]&lt;br /&gt;
	return &amp;#039;[[Wikipedia:WikiProject Women in Red/Meetup/&amp;#039; .. meetup&lt;br /&gt;
		.. &amp;#039;|&amp;#039; .. _name(meetup) &lt;br /&gt;
		.. &amp;#039; &amp;#039; .. value(meetup, &amp;#039;type&amp;#039;, &amp;#039;edit-a-thon&amp;#039;)&lt;br /&gt;
		.. &amp;#039;]] &amp;#039;&lt;br /&gt;
		.. _date(meetup, true, false)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local link = function(n, name)&lt;br /&gt;
	local label = name and _name(n) or n&lt;br /&gt;
	return &amp;#039;[[Wikipedia:WikiProject Women in Red/Meetup/&amp;#039; .. n .. &amp;#039;|&amp;#039; .. label .. &amp;#039;]]&amp;#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local buildTable = function(option, show, _sort)&lt;br /&gt;
	local meetupCell = function(n)&lt;br /&gt;
		local background = value(n, &amp;#039;background&amp;#039;) and (&amp;#039;#&amp;#039; .. value(n, &amp;#039;background&amp;#039;)) or nil&lt;br /&gt;
		return mw.html.create(&amp;#039;th&amp;#039;)&lt;br /&gt;
			:css(&amp;#039;background-color&amp;#039;, background)&lt;br /&gt;
			:css(&amp;#039;text-align&amp;#039;, &amp;#039;center&amp;#039;)&lt;br /&gt;
			:wikitext(n)&lt;br /&gt;
	end&lt;br /&gt;
	local total = 0&lt;br /&gt;
	option.meetup = true&lt;br /&gt;
	option.name = true&lt;br /&gt;
	option.date = true&lt;br /&gt;
	local header = mw.html.create(&amp;#039;tr&amp;#039;)&lt;br /&gt;
	local cols = 0&lt;br /&gt;
	for _, col in ipairs({&amp;#039;meetup&amp;#039;, &amp;#039;icon&amp;#039;, &amp;#039;series&amp;#039;, &amp;#039;name&amp;#039;, &amp;#039;date&amp;#039;, &amp;#039;image&amp;#039;, &amp;#039;template&amp;#039;, &amp;#039;wrapper&amp;#039;, &amp;#039;contrast&amp;#039;, &amp;#039;category&amp;#039;}) do&lt;br /&gt;
		if option[col] then&lt;br /&gt;
			cols = cols + 1&lt;br /&gt;
			local col = mw.html.create(&amp;#039;th&amp;#039;):wikitext(lang:ucfirst(col))&lt;br /&gt;
			header:node(col)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	local sorted_data = {}&lt;br /&gt;
	for n, _ in pairs(data) do&lt;br /&gt;
		table.insert(sorted_data, n)&lt;br /&gt;
	end&lt;br /&gt;
	if _sort then&lt;br /&gt;
		table.sort(sorted_data, _sort)&lt;br /&gt;
	end&lt;br /&gt;
	local showDate = function(meetup)&lt;br /&gt;
		local dates, sortkey = _date(meetup, false, true)&lt;br /&gt;
		return mw.html.create(&amp;#039;td&amp;#039;):attr(&amp;#039;data-sort-value&amp;#039;, sortkey):wikitext(dates):done()&lt;br /&gt;
	end&lt;br /&gt;
	local rows = {}&lt;br /&gt;
	for _, n in ipairs(sorted_data) do&lt;br /&gt;
		local event = data[n]&lt;br /&gt;
		if not show or show(n, event) then&lt;br /&gt;
			local row = mw.html.create(&amp;#039;tr&amp;#039;):node(meetupCell(n))&lt;br /&gt;
			if option.icon then&lt;br /&gt;
				local icon = event.icon and &amp;#039;[[File:&amp;#039; .. event.icon .. &amp;#039;|center|50px]]&amp;#039;&lt;br /&gt;
				local cell = mw.html.create(&amp;#039;td&amp;#039;):wikitext(icon)&lt;br /&gt;
				row:node(cell)&lt;br /&gt;
			end&lt;br /&gt;
			if option.series then&lt;br /&gt;
				local series = event.series and &amp;#039;[[:Category:WikiProject Women in Red &amp;#039; .. event.series:gsub(&amp;#039;#&amp;#039;, &amp;#039;&amp;#039;) .. &amp;#039; articles|&amp;#039; .. event.series .. &amp;#039;]]&amp;#039; or &amp;#039;&amp;#039;&lt;br /&gt;
				local cell = mw.html.create(&amp;#039;td&amp;#039;):wikitext(series)&lt;br /&gt;
				row:node(cell)&lt;br /&gt;
			end&lt;br /&gt;
			local name = option.series and event.name or _name(n)&lt;br /&gt;
			local link = &amp;#039;[[Wikipedia:WikiProject Women in Red/Meetup/&amp;#039; .. n .. &amp;#039;|&amp;#039; .. name .. &amp;#039;]]&amp;#039;&lt;br /&gt;
			local name_cell = mw.html.create(&amp;#039;td&amp;#039;):wikitext(link)&lt;br /&gt;
			row:node(name_cell)&lt;br /&gt;
				:node(showDate(n))&lt;br /&gt;
			if option.image then&lt;br /&gt;
				local pic = event.image and &amp;#039;[[File:&amp;#039; .. event.image .. &amp;#039;|center|x50px|&amp;#039; .. (event.caption or &amp;#039;&amp;#039;) .. &amp;#039;]]&amp;#039;&lt;br /&gt;
				local cell = mw.html.create(&amp;#039;td&amp;#039;):wikitext(pic)&lt;br /&gt;
				row:node(cell)&lt;br /&gt;
			end&lt;br /&gt;
			if option.template then&lt;br /&gt;
				local template = frame:extensionTag(&amp;#039;code&amp;#039;, &amp;#039;{{WIR|&amp;#039; .. n .. &amp;#039;}}&amp;#039;)&lt;br /&gt;
				local cell = mw.html.create(&amp;#039;td&amp;#039;):css(&amp;#039;text-align&amp;#039;, &amp;#039;center&amp;#039;):wikitext(template)&lt;br /&gt;
				row:node(cell)&lt;br /&gt;
			end&lt;br /&gt;
			if option.wrapper then&lt;br /&gt;
				local wrapper = &amp;#039;{{[[:Template:WIR-&amp;#039; .. n .. &amp;#039;|WIR-&amp;#039; .. n .. &amp;#039;]]}}&amp;#039;&lt;br /&gt;
				local cell = mw.html.create(&amp;#039;td&amp;#039;):css(&amp;#039;text-align&amp;#039;, &amp;#039;center&amp;#039;):wikitext(wrapper)&lt;br /&gt;
				row:node(cell)&lt;br /&gt;
			end&lt;br /&gt;
			if option.contrast then&lt;br /&gt;
				local background = value(n, &amp;#039;background&amp;#039;)&lt;br /&gt;
				local colour, contrast&lt;br /&gt;
				if background then&lt;br /&gt;
					contrast = frame:expandTemplate{&lt;br /&gt;
						title = &amp;#039;Color contrast ratio&amp;#039;,&lt;br /&gt;
						args = {[1] = &amp;#039;#000000&amp;#039;, [2] = background}&lt;br /&gt;
					}&lt;br /&gt;
					contrast = math.floor(contrast*10)/10&lt;br /&gt;
					colour = contrast&amp;lt;4.5 and &amp;#039;FFCCCB&amp;#039; or contrast&amp;lt;=7 and &amp;#039;FFFF8F&amp;#039; or &amp;#039;D1FFBD&amp;#039;&lt;br /&gt;
				end&lt;br /&gt;
				local cell = mw.html.create(&amp;#039;td&amp;#039;)&lt;br /&gt;
					:css(&amp;#039;text-align&amp;#039;, &amp;#039;center&amp;#039;)&lt;br /&gt;
					:css(&amp;#039;background-color&amp;#039;, colour and (&amp;#039;#&amp;#039;..colour))&lt;br /&gt;
					:wikitext(contrast)&lt;br /&gt;
				row:node(cell)&lt;br /&gt;
			end&lt;br /&gt;
			if option.category then&lt;br /&gt;
				local cat = &amp;#039;WikiProject Women in Red meetup &amp;#039; .. n .. &amp;#039; articles&amp;#039;&lt;br /&gt;
				local url = mw.uri.fullUrl(&amp;#039;:Category:&amp;#039; .. cat, {&lt;br /&gt;
					action = &amp;#039;edit&amp;#039;,&lt;br /&gt;
					preload = &amp;#039;Template:WIR category/preload&amp;#039;,&lt;br /&gt;
					summary = &amp;#039;Create meetup category for Women in Red&amp;#039;&lt;br /&gt;
				})&lt;br /&gt;
				local pagesInCat = mw.site.stats.pagesInCategory(cat)&lt;br /&gt;
				total = total + pagesInCat&lt;br /&gt;
				local catText = &amp;#039;[[&amp;#039; .. &amp;#039;:Category:&amp;#039; .. cat .. &amp;#039;|&amp;#039; .. pagesInCat .. &amp;#039;]]&amp;#039;&lt;br /&gt;
				if pagesInCat==0 and not mw.title.new(&amp;#039;:Category:&amp;#039; .. cat).exists then&lt;br /&gt;
					catText = catText .. &amp;#039; ([&amp;#039; .. tostring(url) .. &amp;#039; create])&amp;#039;&lt;br /&gt;
				end&lt;br /&gt;
				local cell = mw.html.create(&amp;#039;td&amp;#039;):css(&amp;#039;text-align&amp;#039;, &amp;#039;center&amp;#039;):wikitext(catText)&lt;br /&gt;
				row:node(cell)&lt;br /&gt;
			end&lt;br /&gt;
		table.insert(rows, tostring(row))&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	local footer&lt;br /&gt;
	if option.category then&lt;br /&gt;
		footer = mw.html.create(&amp;#039;tr&amp;#039;)&lt;br /&gt;
			:tag(&amp;#039;th&amp;#039;):attr(&amp;#039;colspan&amp;#039;, cols-1):wikitext(&amp;#039;Total&amp;#039;):done()&lt;br /&gt;
			:tag(&amp;#039;th&amp;#039;):css(&amp;#039;text-align&amp;#039;, &amp;#039;center&amp;#039;):wikitext(tostring(total)):done()&lt;br /&gt;
		end&lt;br /&gt;
	return mw.html.create(&amp;#039;table&amp;#039;)&lt;br /&gt;
		:addClass(&amp;#039;wikitable&amp;#039;):addClass(&amp;#039;sortable&amp;#039;)&lt;br /&gt;
		:node(header)&lt;br /&gt;
		:node(table.concat(rows))&lt;br /&gt;
		:node(footer)&lt;br /&gt;
end&lt;br /&gt;
p.list = function()&lt;br /&gt;
	local first = tonumber(args.first) or 1&lt;br /&gt;
	local last = tonumber(args.last) or 9999&lt;br /&gt;
	if args.latest then&lt;br /&gt;
		last = _findLatest()&lt;br /&gt;
		first = last - tonumber(args.latest) + 1&lt;br /&gt;
	end&lt;br /&gt;
	local option = {}&lt;br /&gt;
	for key, value in pairs(args) do&lt;br /&gt;
		option[key] = yesno(value)&lt;br /&gt;
	end&lt;br /&gt;
	local order = function(m, n)&lt;br /&gt;
		local start1, _ = getDates(m)&lt;br /&gt;
		start1 = format_date(start1)&lt;br /&gt;
		local start2, _ = getDates(n)&lt;br /&gt;
		start2 = format_date(start2) &lt;br /&gt;
		local earlier = start1&amp;lt;start2&lt;br /&gt;
		if start1==start2 then&lt;br /&gt;
			earlier = m&amp;lt;n&lt;br /&gt;
		end&lt;br /&gt;
		return earlier&lt;br /&gt;
	end&lt;br /&gt;
	return buildTable(&lt;br /&gt;
		option,&lt;br /&gt;
		function(n, _)&lt;br /&gt;
			return n&amp;gt;=first and n&amp;lt;=last&lt;br /&gt;
		end,&lt;br /&gt;
		order&lt;br /&gt;
	)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local eventStatus = function(event, _date)&lt;br /&gt;
--function to decide whether an event is upcoming, current, ongoing, recently completed or past&lt;br /&gt;
	local month = currentMonth&lt;br /&gt;
	if _date then&lt;br /&gt;
		month = format_date(_date)&lt;br /&gt;
	end&lt;br /&gt;
	local _start = format_date(event[&amp;#039;start&amp;#039;] or {&lt;br /&gt;
		year = event.year,&lt;br /&gt;
		month = event.month or 1&lt;br /&gt;
	})&lt;br /&gt;
	local _end = format_date(event[&amp;#039;end&amp;#039;] or {&lt;br /&gt;
		year = event.year,&lt;br /&gt;
		month = event.month or 12&lt;br /&gt;
	})&lt;br /&gt;
	if _end&amp;lt;month-1 then -- event ended before previous month&lt;br /&gt;
		return &amp;#039;past&amp;#039;&lt;br /&gt;
	elseif _end==month-1 then -- event ended on previous month&lt;br /&gt;
		return &amp;#039;recent&amp;#039;&lt;br /&gt;
	elseif _start==month then -- event has started on current month&lt;br /&gt;
		return &amp;#039;current&amp;#039;&lt;br /&gt;
	elseif _start==month+1 then -- event starts after current month&lt;br /&gt;
		return &amp;#039;upcoming&amp;#039;&lt;br /&gt;
	elseif _start&amp;lt;month then -- event starts before current month&lt;br /&gt;
		return &amp;#039;ongoing&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local searchEvents = function(_date)&lt;br /&gt;
	local events = {current = {}, recent = {}, ongoing = {}, upcoming = {}, past = {}}&lt;br /&gt;
	for n, event in pairs(data) do&lt;br /&gt;
		local status = eventStatus(event, _date)&lt;br /&gt;
		if status then&lt;br /&gt;
			table.insert(events[status], n)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	table.sort(events.past, function(a, b) return a &amp;gt; b end)&lt;br /&gt;
	return events&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
p.current_events = function(frame)&lt;br /&gt;
	local _date = currentDate&lt;br /&gt;
	if frame.args[1] then&lt;br /&gt;
		_date = getDates(frame.args[1])&lt;br /&gt;
	elseif frame.args.year and frame.args.year~=&amp;#039;&amp;#039; then&lt;br /&gt;
		_date = {&lt;br /&gt;
			year = tonumber(frame.args.year),&lt;br /&gt;
			month = tonumber(frame.args.month) or 1&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
	local mClickableButton = require(&amp;#039;Module:Clickable button&amp;#039;).main&lt;br /&gt;
	local button = function(text, colour)&lt;br /&gt;
		return mClickableButton{&lt;br /&gt;
			[1] = text,&lt;br /&gt;
			color = &amp;#039;white&amp;#039;,&lt;br /&gt;
			style = colour and (&amp;#039;background-color: #&amp;#039; .. colour)&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
	local links = function(text, events, extra)&lt;br /&gt;
		local list = {}&lt;br /&gt;
		if events[1] or extra then&lt;br /&gt;
			for _, n in ipairs(events) do&lt;br /&gt;
				table.insert(list, button(&lt;br /&gt;
					&amp;#039;[[Wikipedia:WikiProject Women in Red/Meetup/&amp;#039; .. n .. &amp;#039;|&amp;#039; .. _name(n) .. &amp;#039;]]&amp;#039;,&lt;br /&gt;
					value(n, &amp;#039;background&amp;#039;)&lt;br /&gt;
				) .. &amp;#039; &amp;#039;)&lt;br /&gt;
			end&lt;br /&gt;
			if extra then&lt;br /&gt;
				table.insert(list, button(extra))&lt;br /&gt;
			end&lt;br /&gt;
			return mw.html.create(&amp;#039;tr&amp;#039;)&lt;br /&gt;
				:tag(&amp;#039;td&amp;#039;):wikitext(text .. &amp;#039;: &amp;#039;):done()&lt;br /&gt;
				:tag(&amp;#039;td&amp;#039;):wikitext(table.concat(list)):done()&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	local events = searchEvents(_date)&lt;br /&gt;
	local ret = mw.html.create(&amp;#039;table&amp;#039;)&lt;br /&gt;
		:node(links(frame.args.recent or &amp;#039;Recently completed&amp;#039;, events.recent))&lt;br /&gt;
		:node(links(frame.args.current or monthName(_date.month) .. &amp;#039; &amp;#039; .. _date.year, events.current))&lt;br /&gt;
		:node(links(frame.args.ongoing or &amp;#039;Ongoing initiatives&amp;#039;, events.ongoing))&lt;br /&gt;
		:node(links(frame.args.upcoming or &amp;#039;Upcoming events&amp;#039;, events.upcoming, &amp;#039;[[Wikipedia:WikiProject Women in Red/Ideas|Ideas]]&amp;#039;))&lt;br /&gt;
	return tostring(ret)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
p.events = function()&lt;br /&gt;
-- function to produce automated list of events on Wikipedia:WikiProject Women in Red/Events&lt;br /&gt;
	local ret = mw.html.create(&amp;#039;div&amp;#039;)&lt;br /&gt;
	local ec = searchEvents()&lt;br /&gt;
	local links = function(class)&lt;br /&gt;
		if not ec[class] or not args[class] then&lt;br /&gt;
			return nil&lt;br /&gt;
		end&lt;br /&gt;
		ret:tag(&amp;#039;h3&amp;#039;):wikitext(args[class]):done()&lt;br /&gt;
		if ec[class][1] then&lt;br /&gt;
			ret:tag(&amp;#039;ul&amp;#039;)&lt;br /&gt;
			for _, n in ipairs(ec[class]) do&lt;br /&gt;
				local date2 = _date(n, false, false)&lt;br /&gt;
				if date2==tostring(tonumber(date2)) then&lt;br /&gt;
					date2 = date2 .. &amp;#039; year-long &amp;#039; .. value(n, &amp;#039;type&amp;#039;, &amp;#039;editathon&amp;#039;)&lt;br /&gt;
				end&lt;br /&gt;
				ret:tag(&amp;#039;li&amp;#039;):wikitext(date2 .. &amp;#039;: &amp;#039; .. link(n, true)):done()&lt;br /&gt;
			end&lt;br /&gt;
		else&lt;br /&gt;
			ret:tag(&amp;#039;p&amp;#039;):css(&amp;#039;font-style&amp;#039;, &amp;#039;italic&amp;#039;):wikitext(&amp;#039;None to display.&amp;#039;):done()&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	links(&amp;#039;ongoing&amp;#039;)&lt;br /&gt;
	links(&amp;#039;current&amp;#039;)&lt;br /&gt;
	links(&amp;#039;recent&amp;#039;)&lt;br /&gt;
	links(&amp;#039;upcoming&amp;#039;)&lt;br /&gt;
	links(&amp;#039;past&amp;#039;)&lt;br /&gt;
	return tostring(ret)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
p.event_list = function()&lt;br /&gt;
-- function to produce bulleted list of events for Template:Women in Red navigation&lt;br /&gt;
	local ec = searchEvents()&lt;br /&gt;
	local class = args[1]&lt;br /&gt;
	if not ec[class] then&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
	local ret = mw.html.create(&amp;#039;ul&amp;#039;)&lt;br /&gt;
	for _, n in ipairs(ec[class]) do&lt;br /&gt;
		ret:tag(&amp;#039;li&amp;#039;):wikitext(link(n, true)):done()&lt;br /&gt;
	end&lt;br /&gt;
	return tostring(ret)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
p.event_list_by_year = function()&lt;br /&gt;
-- function to produce bulleted list of past events for Template:Women in Red navigation&lt;br /&gt;
	local ret = mw.html.create(&amp;#039;ul&amp;#039;)&lt;br /&gt;
	local year = args[1] and tonumber(args[1]) or 2023&lt;br /&gt;
	local events = {}&lt;br /&gt;
	for n, event in pairs(data) do&lt;br /&gt;
		if (event.year==year or (event.start and event.start.year==year)) and eventStatus(event)==&amp;#039;past&amp;#039; then&lt;br /&gt;
			local type = event.type or &amp;#039;edit-a-thon&amp;#039;&lt;br /&gt;
			if not events[type] then&lt;br /&gt;
				events[type] = {}&lt;br /&gt;
			end&lt;br /&gt;
			local month = value(n, &amp;#039;month&amp;#039;, 0)&lt;br /&gt;
			if not events[type][month] then&lt;br /&gt;
				events[type][month] = {}&lt;br /&gt;
			end&lt;br /&gt;
			table.insert(events[type][month], n)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	for type, eventsOfType in pairs(events) do&lt;br /&gt;
		ret:wikitext(lang:uc(type)..&amp;#039;S: &amp;#039;)&lt;br /&gt;
		for _, n in ipairs(eventsOfType[0] or {}) do&lt;br /&gt;
			ret:tag(&amp;#039;li&amp;#039;):wikitext(link(n, true)):done()&lt;br /&gt;
		end&lt;br /&gt;
		for month = 1, 12 do&lt;br /&gt;
			if eventsOfType[month] then&lt;br /&gt;
				local sublist = mw.html.create(&amp;#039;ul&amp;#039;)&lt;br /&gt;
				for _, n in ipairs(eventsOfType[month]) do&lt;br /&gt;
					sublist:tag(&amp;#039;li&amp;#039;):wikitext(link(n, true)):done()&lt;br /&gt;
				end&lt;br /&gt;
				ret:tag(&amp;#039;li&amp;#039;):wikitext(monthName(month, true) .. &amp;#039;: &amp;#039;):node(sublist):done()&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return tostring(ret)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
p.category_header = function(frame)&lt;br /&gt;
	local pargs = frame:getParent().args&lt;br /&gt;
	local test = pargs.test&lt;br /&gt;
	local page = mw.title.getCurrentTitle().text&lt;br /&gt;
	local n = test and pargs.n or page:match(&amp;#039;WikiProject Women in Red meetup (%d+) articles&amp;#039;)&lt;br /&gt;
	local year = test and pargs.year or page:match(&amp;#039;WikiProject Women in Red (%d+) articles&amp;#039;)&lt;br /&gt;
	local year2 = test and pargs.year2 or page:match(&amp;#039;WikiProject Women in Red in (%d+)&amp;#039;)&lt;br /&gt;
	local series = test and pargs.series or page:match(&amp;#039;WikiProject Women in Red (.+)&amp;#039;)&lt;br /&gt;
	local cats, text, image_right, empty, nav&lt;br /&gt;
	local image_left = &amp;#039;Women in Red logo.svg&amp;#039;&lt;br /&gt;
	local makeCatL = function(cat, key)&lt;br /&gt;
		return makeCat(cat, key, test)&lt;br /&gt;
	end&lt;br /&gt;
	if n then&lt;br /&gt;
		text = &amp;#039;This category contains talk pages of articles which were created or improved&amp;#039;&lt;br /&gt;
			.. &amp;#039; during the &amp;lt;b&amp;gt;[[Wikipedia:WikiProject Women in Red/Meetup/&amp;#039;&lt;br /&gt;
			.. n .. &amp;#039;|&amp;#039; .. _name(n) .. &amp;#039; &amp;#039; .. value(n, &amp;#039;type&amp;#039;, &amp;#039;edit-a-thon&amp;#039;) .. &amp;#039;]]&amp;lt;/b&amp;gt;&amp;#039;&lt;br /&gt;
			.. &amp;#039; hosted by the [[Wikipedia:WikiProject Women in Red|Women in Red project]] &amp;#039;&lt;br /&gt;
			.. _date(n, true, false) .. &amp;#039;.&amp;#039;&lt;br /&gt;
		cats = {makeCatL(&amp;#039;WikiProject Women in Red articles by meetup&amp;#039;, n)}&lt;br /&gt;
		local _start, _end = getDates(n, true)&lt;br /&gt;
		for year = _start.year, _end.year do&lt;br /&gt;
			table.insert(cats, makeCatL(&amp;#039;WikiProject Women in Red &amp;#039; .. year .. &amp;#039; articles&amp;#039;, n))&lt;br /&gt;
		end&lt;br /&gt;
		if value(n, &amp;#039;series&amp;#039;) then&lt;br /&gt;
			table.insert(cats, makeCatL(&amp;#039;WikiProject Women in Red &amp;#039; .. value(n, &amp;#039;series&amp;#039;):gsub(&amp;#039;#&amp;#039;, &amp;#039;&amp;#039;) .. &amp;#039; articles&amp;#039;, n))&lt;br /&gt;
		end&lt;br /&gt;
		empty = mw.site.stats.pagesInCategory(&amp;#039;WikiProject Women in Red meetup &amp;#039; .. n .. &amp;#039; articles&amp;#039;)==0&lt;br /&gt;
		local future = false&lt;br /&gt;
		if _start.year&amp;gt;currentDate.year then&lt;br /&gt;
			future = true&lt;br /&gt;
		elseif _start.year==currentDate.year then&lt;br /&gt;
			if _start.month and _start.month&amp;gt;=currentDate.month then&lt;br /&gt;
				future = true&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		image_left = value(n, &amp;#039;icon&amp;#039;, &amp;#039;Women in Red logo.svg&amp;#039;)&lt;br /&gt;
		image_right = value(n, &amp;#039;image&amp;#039;) and &amp;#039;[[File:&amp;#039; .. value(n, &amp;#039;image&amp;#039;) .. &amp;#039;|80px|&amp;#039; .. (value(n, &amp;#039;caption&amp;#039;) or &amp;#039;&amp;#039;) .. &amp;#039;]]&amp;#039;&lt;br /&gt;
		empty = empty and future&lt;br /&gt;
		nav = true&lt;br /&gt;
	elseif year then -- for categories such as Category:WikiProject Women in Red 2025 articles&lt;br /&gt;
		year = tonumber(year)&lt;br /&gt;
		local inYear = function(_, event)&lt;br /&gt;
			if event.start and event[&amp;#039;end&amp;#039;] then&lt;br /&gt;
				return event.start.year&amp;lt;=year and event[&amp;#039;end&amp;#039;].year&amp;gt;=year&lt;br /&gt;
			else&lt;br /&gt;
				return event.year==year&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		text = &amp;#039;This category contains talk pages of articles which were created or improved in &amp;#039;&lt;br /&gt;
			.. year .. &amp;#039; as part of the [[Wikipedia:WikiProject Women in Red|Women in Red project]].&amp;#039;&lt;br /&gt;
			.. collapse(&lt;br /&gt;
				&amp;#039;Articles improved during &amp;#039; .. year,&lt;br /&gt;
				tostring(buildTable({category = true}, inYear))&lt;br /&gt;
			)&lt;br /&gt;
		cats = {&lt;br /&gt;
			makeCatL(&amp;#039;WikiProject Women in Red in &amp;#039; .. year, &amp;#039;Articles&amp;#039;),&lt;br /&gt;
			makeCatL(&amp;#039;WikiProject Women in Red articles by year&amp;#039;, year)&lt;br /&gt;
		}&lt;br /&gt;
		nav = true&lt;br /&gt;
	elseif year2 then -- for categories such as Category:WikiProject Women in Red in 2025&lt;br /&gt;
		year2 = tonumber(year2)&lt;br /&gt;
		text = &amp;#039;This category contains all meetups of the [[Wikipedia:WikiProject Women in Red|Women in Red project]] in &amp;#039; .. year2 .. &amp;#039;.&amp;#039;&lt;br /&gt;
		cats = {&lt;br /&gt;
			makeCatL(&amp;#039;Wikipedia meetups in &amp;#039; .. year2, &amp;#039;Women in Red&amp;#039;),&lt;br /&gt;
			makeCatL(&amp;#039;WikiProject Women in Red by year&amp;#039;, year2)&lt;br /&gt;
		}&lt;br /&gt;
		nav = true&lt;br /&gt;
	elseif series then&lt;br /&gt;
		series = series:gsub(&amp;#039;%sarticles&amp;#039;, &amp;#039;&amp;#039;):gsub(&amp;#039;1day1woman&amp;#039;, &amp;#039;#1day1woman&amp;#039;)&lt;br /&gt;
		text = &amp;#039;This category contains talk pages of articles which were created or improved as part of the &amp;#039; .. series&lt;br /&gt;
			.. &amp;#039; series of meetups hosted by the [[Wikipedia:WikiProject Women in Red|Women in Red project]].&amp;#039;&lt;br /&gt;
			.. collapse(&lt;br /&gt;
				&amp;#039;Articles improved during &amp;#039; .. series .. &amp;#039; events&amp;#039;,&lt;br /&gt;
				tostring(buildTable(&lt;br /&gt;
					{category = true},&lt;br /&gt;
					function(_, event) return event.series==series end&lt;br /&gt;
				))&lt;br /&gt;
			)&lt;br /&gt;
		cats = {makeCatL(&amp;#039;WikiProject Women in Red articles by series&amp;#039;, series)}&lt;br /&gt;
	end&lt;br /&gt;
	local out = {frame:expandTemplate{title = &amp;#039;cmbox&amp;#039;, args = {&lt;br /&gt;
		image = &amp;#039;[[File:&amp;#039; .. image_left .. &amp;#039;|40px]]&amp;#039;,&lt;br /&gt;
		text = text or &amp;#039;&amp;#039;,&lt;br /&gt;
		imageright = image_right&lt;br /&gt;
	}}}&lt;br /&gt;
	table.insert(out, not(pargs.test) and nav and frame:expandTemplate{&lt;br /&gt;
		title = &amp;#039;Category series navigation&amp;#039;,&lt;br /&gt;
		args = {min = &amp;#039;1&amp;#039;}&lt;br /&gt;
	} or &amp;#039;&amp;#039;)&lt;br /&gt;
	table.insert(out, frame:expandTemplate{title = &amp;#039;CatAutoTOC&amp;#039;})&lt;br /&gt;
	table.insert(out, empty and frame:expandTemplate{&lt;br /&gt;
		title = &amp;#039;Possibly empty category&amp;#039;,&lt;br /&gt;
		args = {[1] = &amp;#039;This category should be populated soon.&amp;#039;}&lt;br /&gt;
	} or &amp;#039;&amp;#039;)&lt;br /&gt;
	table.insert(out, table.concat(cats or {}) or &amp;#039;&amp;#039;)&lt;br /&gt;
	return table.concat(out)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
p.addDateCategories = function()&lt;br /&gt;
	local n = tonumber(args[1])&lt;br /&gt;
	local test = yesno(args.test)&lt;br /&gt;
	local cats = {}&lt;br /&gt;
	local _start, _end = getDates(n, true)&lt;br /&gt;
	local start_id, end_id = format_date(_start), format_date(_end)&lt;br /&gt;
	for year = _start.year, _end.year do&lt;br /&gt;
		table.insert(cats, makeCat(&amp;#039;WikiProject Women in Red in &amp;#039; .. year, n, test))&lt;br /&gt;
	end&lt;br /&gt;
	if _start.month and start_id+2&amp;gt;=end_id then -- event spans at most three months&lt;br /&gt;
		for monthid = start_id, end_id do -- add monthly categories&lt;br /&gt;
			local year = math.floor(monthid/12)&lt;br /&gt;
			local month = monthid - year*12 + 1&lt;br /&gt;
			table.insert(cats, makeCat(&amp;#039;Wikipedia meetups in &amp;#039; .. monthName(month) .. &amp;#039; &amp;#039; .. year, &amp;#039;Women in Red&amp;#039;, test))&lt;br /&gt;
		end&lt;br /&gt;
	else -- event spans more than three months, just use yearly categories&lt;br /&gt;
		for year = _start.year, _end.year do&lt;br /&gt;
			table.insert(cats, makeCat(&amp;#039;Wikipedia meetups in &amp;#039; .. year, &amp;#039;Women in Red&amp;#039;, test))&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if value(n, &amp;#039;type&amp;#039;)==&amp;#039;contest&amp;#039; then&lt;br /&gt;
		table.insert(cats, makeCat(&amp;#039;Wikipedia competitions&amp;#039;, test))&lt;br /&gt;
	end&lt;br /&gt;
	return table.concat(cats)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
p.pinterest = function()&lt;br /&gt;
-- Function to generate the correct link to pinterest based on the month of the start of the event&lt;br /&gt;
	local event = tonumber(frame.args[1])&lt;br /&gt;
	if data[event] then&lt;br /&gt;
		local _start = getDates(event)&lt;br /&gt;
		local month = monthName(_start.month or 1)&lt;br /&gt;
		local label = month .. &amp;#039;-&amp;#039; .. _start.year .. &amp;#039;-editathons&amp;#039;&lt;br /&gt;
		return &amp;#039;[https://www.pinterest.com/wikiwomeninred/&amp;#039; .. label .. &amp;#039; &amp;#039; .. label .. &amp;#039;]&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>imported&gt;MSGJ</name></author>
	</entry>
</feed>