<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://commons.islamical.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Shahroudi</id>
	<title>Islamical Commons - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://commons.islamical.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Shahroudi"/>
	<link rel="alternate" type="text/html" href="https://commons.islamical.org/view/Special:Contributions/Shahroudi"/>
	<updated>2026-09-26T23:21:48Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.46.0</generator>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=Template:Own&amp;diff=3968</id>
		<title>Template:Own</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=Template:Own&amp;diff=3968"/>
		<updated>2026-09-25T08:56:36Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: Created page with &amp;quot;&amp;lt;noinclude&amp;gt;{{heavily used template}}&amp;lt;/noinclude&amp;gt;&amp;lt;span class=&amp;quot;int-own-work&amp;quot; lang=&amp;quot;{{int:lang}}&amp;quot;&amp;gt;{{int:Wm-license-own-work}}&amp;lt;/span&amp;gt;&amp;lt;noinclude&amp;gt; {{documentation}} &amp;lt;/noinclude&amp;gt;&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;{{heavily used template}}&amp;lt;/noinclude&amp;gt;&amp;lt;span class=&amp;quot;int-own-work&amp;quot; lang=&amp;quot;{{int:lang}}&amp;quot;&amp;gt;{{int:Wm-license-own-work}}&amp;lt;/span&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{documentation}}&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=Module:DTZ&amp;diff=3967</id>
		<title>Module:DTZ</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=Module:DTZ&amp;diff=3967"/>
		<updated>2026-09-25T08:52:43Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: Created page with &amp;quot;--[[     Format date/times with time zones. Input can be specified using the following subset of ISO 8601:  YYYY-MM-DDTHH:MMZ       (UTC) YYYY-MM-DDTHH:MM+HH     (hours ahead of UTC) YYYY-MM-DDTHH:MM+HH:MM  (hours and minutes ahead of UTC) YYYY-MM-DDTHH:MM-HH     (hours behind of UTC) YYYY-MM-DDTHH:MM-HH:MM  (hours and minutes behind of UTC)  and similar strings with seconds included in the time:  YYYY-MM-DDTHH:MM:SSZ YYYY-MM-DDTHH:MM:SS+HH YYYY-MM-DDTHH:MM:SS+HH:MM YYYY...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;--[[  &lt;br /&gt;
 &lt;br /&gt;
Format date/times with time zones. Input can be specified using the following&lt;br /&gt;
subset of ISO 8601:&lt;br /&gt;
&lt;br /&gt;
YYYY-MM-DDTHH:MMZ       (UTC)&lt;br /&gt;
YYYY-MM-DDTHH:MM+HH     (hours ahead of UTC)&lt;br /&gt;
YYYY-MM-DDTHH:MM+HH:MM  (hours and minutes ahead of UTC)&lt;br /&gt;
YYYY-MM-DDTHH:MM-HH     (hours behind of UTC)&lt;br /&gt;
YYYY-MM-DDTHH:MM-HH:MM  (hours and minutes behind of UTC)&lt;br /&gt;
&lt;br /&gt;
and similar strings with seconds included in the time:&lt;br /&gt;
&lt;br /&gt;
YYYY-MM-DDTHH:MM:SSZ&lt;br /&gt;
YYYY-MM-DDTHH:MM:SS+HH&lt;br /&gt;
YYYY-MM-DDTHH:MM:SS+HH:MM&lt;br /&gt;
YYYY-MM-DDTHH:MM:SS-HH&lt;br /&gt;
YYYY-MM-DDTHH:MM:SS-HH:MM&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
local Date = require(&#039;Module:DateI18n-585816189&#039;)&lt;br /&gt;
local errorcat = &amp;quot;[[Category:Incorrect use of DTZ]]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
local function format(year, month, day, hour, minute, second, tzhour, tzmin, lang)&lt;br /&gt;
    local result = Date._Date({year, month, day, hour, minute, second, tzhour, tzmin}, lang)&lt;br /&gt;
    if result == &#039;&#039; then&lt;br /&gt;
       return &amp;quot;invalid values in date/time&amp;quot; .. errorcat&lt;br /&gt;
    end&lt;br /&gt;
    return result&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.DTZ(frame)&lt;br /&gt;
       local input = mw.text.trim(frame.args[1])&lt;br /&gt;
       local lang = frame:callParserFunction(&amp;quot;int&amp;quot;, &amp;quot;lang&amp;quot;) -- user&#039;s language --&lt;br /&gt;
       local all, year, month, day, hour, minute, second = input:match(&amp;quot;^((%d%d%d%d)-(%d%d)-(%d%d)T(%d%d):(%d%d):(%d%d))&amp;quot;)&lt;br /&gt;
       if all == nil then&lt;br /&gt;
          all, year, month, day, hour, minute = input:match(&amp;quot;^((%d%d%d%d)-(%d%d)-(%d%d)T(%d%d):(%d%d))&amp;quot;)&lt;br /&gt;
         if all == nil then&lt;br /&gt;
            return &amp;quot;invalid date/time format&amp;quot; .. errorcat&lt;br /&gt;
         end&lt;br /&gt;
       end&lt;br /&gt;
       local tzhour, tzmin&lt;br /&gt;
       local rest = input:sub(all:len()+1)&lt;br /&gt;
       if rest == &#039;&#039; then&lt;br /&gt;
          return &amp;quot;missing timezone&amp;quot; .. errorcat&lt;br /&gt;
       end&lt;br /&gt;
       if rest:len() == 1 and rest:sub(1,1) == &#039;Z&#039; then&lt;br /&gt;
          return format(year, month, day, hour, minute, second, &#039;0&#039;, &#039;&#039;, lang)&lt;br /&gt;
       end&lt;br /&gt;
       local tzsign&lt;br /&gt;
       tzsign, tzhour, tzmin = rest:match(&amp;quot;^([+-])(%d%d):(%d%d)$&amp;quot;)&lt;br /&gt;
       if tzsign == nil then&lt;br /&gt;
          tzsign, tzhour = rest:match(&amp;quot;^([+-])(%d%d)$&amp;quot;)&lt;br /&gt;
          if tzsign == nil then&lt;br /&gt;
            return &amp;quot;invalid timezone&amp;quot; .. errorcat&lt;br /&gt;
          end     &lt;br /&gt;
          tzmin = &#039;00&#039; -- work around a glitch in Module:Date --&lt;br /&gt;
       end&lt;br /&gt;
       if tzsign == &#039;-&#039; then&lt;br /&gt;
          tzhour = -1 * tzhour&lt;br /&gt;
       end&lt;br /&gt;
       return format(year, month, day, hour, minute, second, tzhour, tzmin, lang)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=Module:ISOdate/sandbox/testcases&amp;diff=3966</id>
		<title>Module:ISOdate/sandbox/testcases</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=Module:ISOdate/sandbox/testcases&amp;diff=3966"/>
		<updated>2026-09-25T08:51:21Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: Created page with &amp;quot;require(&amp;#039;strict&amp;#039;) local TUT = mw.title.new(mw.getCurrentFrame():getTitle()).basePageTitle -- the title under test local p = require(TUT.prefixedText) -- the module to be tested local ScribuntoUnit = require(&amp;#039;Module:ScribuntoUnit&amp;#039;) local suite = ScribuntoUnit:new() local Date  = require(&amp;#039;Module:DateI18n&amp;#039;)._Date    local function ISOdate(datestr, lang, case, class, trim_year) 	local datestr, succeded = p._ISOdate(datestr, lang, case, class, trim_year) 	return datestr end...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;require(&#039;strict&#039;)&lt;br /&gt;
local TUT = mw.title.new(mw.getCurrentFrame():getTitle()).basePageTitle -- the title under test&lt;br /&gt;
local p = require(TUT.prefixedText) -- the module to be tested&lt;br /&gt;
local ScribuntoUnit = require(&#039;Module:ScribuntoUnit&#039;)&lt;br /&gt;
local suite = ScribuntoUnit:new()&lt;br /&gt;
local Date  = require(&#039;Module:DateI18n&#039;)._Date &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local function ISOdate(datestr, lang, case, class, trim_year)&lt;br /&gt;
	local datestr, succeded = p._ISOdate(datestr, lang, case, class, trim_year)&lt;br /&gt;
	return datestr&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function ISOdate_en(datestr)&lt;br /&gt;
	local datestr, succeded = p._ISOdate(datestr, &#039;en&#039;, &#039;&#039;, &#039;&#039;, &#039;100-999&#039;)&lt;br /&gt;
	return datestr&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function suite:test_outer()&lt;br /&gt;
	local mod = &#039;{{#invoke:&#039; .. TUT.text .. &#039;| &#039;&lt;br /&gt;
	self:assertSameResult(p._ISOyear(&#039;1999-08-18 08:15:30Z&#039;),                                 mod..&#039;ISOyear|1999-08-18 08:15:30Z}}&#039;)&lt;br /&gt;
	self:assertSameResult(p._ISOdate(&#039;1999-08-18 08:15:30Z&#039;, &#039;en&#039;, &#039;&#039;, &#039;dtstart&#039;, &#039;100-999&#039;), mod..&#039;ISOdate|1999-08-18 08:15:30Z|lang=en}}&#039;)&lt;br /&gt;
	self:assertSameResult(p._ISOdate(&#039;1999-08-18 08:15:30Z&#039;, &#039;pl&#039;, &#039;gen&#039;, &#039;test&#039;, true),      mod..&#039;ISOdate|1999-08-18 08:15:30Z|lang=pl|case=gen|class=test|trim_year=t}}&#039;)&lt;br /&gt;
end &lt;br /&gt;
 &lt;br /&gt;
function suite:test_1_ISOyear()&lt;br /&gt;
	self:assertEquals(&#039;1999&#039;, p._ISOyear(&#039;1999-08-18 08:15:30Z&#039;))&lt;br /&gt;
	self:assertEquals(&#039;1999&#039;, p._ISOyear(&#039;1999-08-18 08:15:30&#039;))&lt;br /&gt;
	self:assertEquals(&#039;1999&#039;, p._ISOyear(&#039;1999-08-18 08:15&#039;))&lt;br /&gt;
	self:assertEquals(&#039;1999&#039;, p._ISOyear(&#039;1999-08-18&#039;))&lt;br /&gt;
	self:assertEquals(&#039;1999&#039;, p._ISOyear(&#039;1999-08&#039;))&lt;br /&gt;
	self:assertEquals(&#039;1999&#039;, p._ISOyear(&#039;1999&#039;))&lt;br /&gt;
	self:assertEquals(&#039;0099&#039;, p._ISOyear(&#039;99-09&#039;))&lt;br /&gt;
	self:assertEquals(&#039;0000&#039;, p._ISOyear(&#039;0&#039;))&lt;br /&gt;
	self:assertEquals(&#039;&#039;    , p._ISOyear(&#039;qwerty&#039;))&lt;br /&gt;
	self:assertEquals(&#039;&#039;    , p._ISOyear(&#039;&#039;))&lt;br /&gt;
	self:assertEquals(&#039;&#039;    , p._ISOyear(&#039;1999/09&#039;))&lt;br /&gt;
end &lt;br /&gt;
&lt;br /&gt;
function suite:test_2_ISOdate_basic()&lt;br /&gt;
	self:assertEquals(&#039;10 August 1999, 08:15:30&#039;, ISOdate_en(&#039;1999-08-10 08:15:30Z&#039;))&lt;br /&gt;
	self:assertEquals(&#039;11 August 1999, 08:15:30&#039;, ISOdate_en(&#039;1999-08-11 08:15:30&#039;))&lt;br /&gt;
	self:assertEquals(&#039;12 August 1999, 08:15&#039;,    ISOdate_en(&#039;1999-08-12 08:15&#039;))&lt;br /&gt;
	self:assertEquals(&#039;13 August 1999&#039;,           ISOdate_en(&#039;1999-08-13&#039;))&lt;br /&gt;
	self:assertEquals(   &#039;August 1999&#039;,           ISOdate_en(&#039;1999-08&#039;))&lt;br /&gt;
	self:assertEquals(          &#039;1999&#039;,           ISOdate_en(&#039;1999&#039;))&lt;br /&gt;
	self:assertEquals(&#039;14 May 999&#039;,               ISOdate_en(&#039;999-05-14&#039;))&lt;br /&gt;
	self:assertEquals(&#039;15 July 0099&#039;,             ISOdate_en(&#039;99-07-15&#039;))&lt;br /&gt;
	self:assertEquals(&#039;16 September 0009&#039;,        ISOdate_en(&#039;9-09-16&#039;))&lt;br /&gt;
	self:assertEquals(&#039;December 1969&#039;,            ISOdate_en(&#039;1969-12&#039;))&lt;br /&gt;
	self:assertEquals(&#039;February 999&#039;,             ISOdate_en(&#039;999-02&#039;))&lt;br /&gt;
	self:assertEquals(&#039;999&#039;,                      ISOdate_en(&#039;999&#039;))&lt;br /&gt;
	self:assertEquals(&#039;0099&#039;,                     ISOdate_en(&#039;99&#039;))&lt;br /&gt;
	self:assertEquals(&#039;0009&#039;,                     ISOdate_en(&#039;9&#039;))&lt;br /&gt;
	self:assertEquals(&#039;&amp;quot;2010&amp;quot;&#039;,              &#039;&amp;quot;&#039;..ISOdate_en(&#039; 2010	&#039;)..&#039;&amp;quot;&#039;)&lt;br /&gt;
end &lt;br /&gt;
&lt;br /&gt;
function suite:test_3_ISOdate_odd_dates()&lt;br /&gt;
	self:assertEquals(&#039;1 August 1999, 08:05:03&#039;,   ISOdate_en(&#039;1999-8-1 8:5:3&#039;))         -- no 0s in front of dates or months&lt;br /&gt;
 	self:assertEquals(&#039;10 August 2010, 18:15:30&#039;,  ISOdate_en(&#039; 2010-08-10 18:15:30Z&#039;))  -- spaces in front of the date&lt;br /&gt;
	self:assertEquals(&#039;11 August 1999, 08:15&#039;,     ISOdate_en(&#039;1999-08-11T08:15&#039;))       -- dates with &amp;quot;T&amp;quot; separator&lt;br /&gt;
	self:assertEquals(&#039;12 August 1999, 08:15:30&#039;,  ISOdate_en(&#039;1999-08-12T08:15:30&#039;))    -- dates with &amp;quot;T&amp;quot; separator&lt;br /&gt;
	self:assertEquals(&#039;13 August 1999, 08:15:30&#039;,  ISOdate_en(&#039;1999-08-13T08:15:30Z&#039;))   -- parse YYYY-MM-DD HH:MM:SS format with &amp;quot;Z&amp;quot;&lt;br /&gt;
	self:assertEquals(&#039;14 August 1999, 08:15:30 (qwerty)&#039;, ISOdate_en(&#039;1999-08-14T08:15:30Z (qwerty)&#039;)) -- parse date with text behind it&lt;br /&gt;
	self:assertEquals(&#039;15 August 1999, 08:15 (qwerty)&#039;, ISOdate_en(&#039;1999-08-15T08:15 (qwerty)&#039;))&lt;br /&gt;
end &lt;br /&gt;
&lt;br /&gt;
function suite:test_4_ISOdate_not_dates()&lt;br /&gt;
	-- not proper dates will be returned as-is&lt;br /&gt;
	self:assertEquals(&#039;qwerty&#039;,      ISOdate_en(&#039;qwerty&#039;)) &lt;br /&gt;
	self:assertEquals(&#039;&#039;,            ISOdate_en(&#039; &#039;)) &lt;br /&gt;
	self:assertEquals(&#039;-2009-09&#039;,    ISOdate_en(&#039;-2009-09&#039;)) &lt;br /&gt;
	self:assertEquals(&#039;15-12-2008&#039;,  ISOdate_en(&#039;15-12-2008&#039;)) &lt;br /&gt;
	self:assertEquals(&#039;15 May 1999&#039;, ISOdate_en(&#039;15 May 1999&#039;)) &lt;br /&gt;
	self:assertEquals(&#039;1999-08-18T08 (creation date)&#039;, ISOdate_en(&#039;1999-08-18T08 (creation date)&#039;)) &lt;br /&gt;
	self:assertSameResult(&#039;{{other date|ca|1999}}&#039;, ISOdate_en(&#039;{{other date|ca|1999}}&#039;))&lt;br /&gt;
end &lt;br /&gt;
&lt;br /&gt;
function suite:test_5_ISOdate_out_or_range()&lt;br /&gt;
	self:assertEquals(&#039;18 August 1999&#039;,   ISOdate_en(&#039;1999-08-18 08:90:30&#039;)) -- minute out of range, keep only the valid date&lt;br /&gt;
	self:assertEquals(&#039;1999&#039;,             ISOdate_en(&#039;1999-18-18 08:20:30&#039;)) -- month out of range, keep only the valid year&lt;br /&gt;
	self:assertEquals(&#039;2000&#039;,             ISOdate_en(&#039;2000-13-29&#039;))          -- month out of range, keep only the valid year&lt;br /&gt;
	self:assertEquals(&#039;September 2009&#039;,   ISOdate_en(&#039;+2009-09&#039;))            -- a plus sign for the year is ignored&lt;br /&gt;
	self:assertEquals(&#039;1 March 1567&#039;,     ISOdate_en(&#039;1567-02-29&#039;))          -- leap day on non-leap year&lt;br /&gt;
	self:assertEquals(&#039;29 February 2000&#039;, ISOdate_en(&#039;2000-02-29&#039;))          -- leap day on leap year	&lt;br /&gt;
end &lt;br /&gt;
&lt;br /&gt;
function suite:test_6_ISOdate_arguments()&lt;br /&gt;
	-- many arguments are just passed into Module:DateI18n&lt;br /&gt;
	local datevec, datestr = {2010,1,9}, &#039;2010-01-09&#039;&lt;br /&gt;
	local case, class, trim_year = &#039;&#039;, &#039;&#039;, &lt;br /&gt;
	self:assertEquals( ISOdate(datestr, &#039;pl&#039;),       Date(datevec, &#039;pl&#039;))&lt;br /&gt;
	self:assertEquals( ISOdate(datestr, &#039;he&#039;),       Date(datevec, &#039;he&#039;))&lt;br /&gt;
	self:assertEquals( ISOdate(datestr, &#039;pl&#039;,&#039;nom&#039;), Date(datevec, &#039;pl&#039;,&#039;nom&#039;))&lt;br /&gt;
	self:assertEquals( ISOdate(datestr, &#039;pl&#039;,&#039;gen&#039;), Date(datevec, &#039;pl&#039;,&#039;gen&#039;))&lt;br /&gt;
	self:assertEquals( ISOdate(datestr, &#039;ru&#039;,&#039;ins&#039;), Date(datevec, &#039;ru&#039;,&#039;ins&#039;))&lt;br /&gt;
	self:assertEquals( ISOdate(datestr, &#039;ru&#039;,&#039;ins&#039;,&#039;dtstart&#039;), Date(datevec, &#039;ru&#039;,&#039;ins&#039;,&#039;dtstart&#039;))&lt;br /&gt;
&lt;br /&gt;
    datevec, datestr = {995,10,28}, &#039;995-10-28&#039;&lt;br /&gt;
	self:assertEquals( ISOdate(datestr, &#039;fr&#039;),                Date(datevec, &#039;fr&#039;))&lt;br /&gt;
	self:assertEquals( ISOdate(datestr, &#039;fr&#039;, &#039;&#039;, &#039;&#039;, true),      Date(datevec, &#039;fr&#039;, &#039;&#039;, &#039;&#039;, true))&lt;br /&gt;
	self:assertEquals( ISOdate(datestr, &#039;fr&#039;, &#039;&#039;, &#039;&#039;, false),     Date(datevec, &#039;fr&#039;, &#039;&#039;, &#039;&#039;, false))&lt;br /&gt;
	self:assertEquals( ISOdate(datestr, &#039;fr&#039;, &#039;&#039;, &#039;&#039;, &#039;100-990&#039;), Date(datevec, &#039;fr&#039;, &#039;&#039;, &#039;&#039;, &#039;100-990&#039;))&lt;br /&gt;
end &lt;br /&gt;
&lt;br /&gt;
return suite&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=Module:Date&amp;diff=3965</id>
		<title>Module:Date</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=Module:Date&amp;diff=3965"/>
		<updated>2026-09-25T08:50:08Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: Created page with &amp;quot;return require(&amp;#039;Module:DateI18n&amp;#039;)&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;return require(&#039;Module:DateI18n&#039;)&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=Module:DateI18n-585816189&amp;diff=3964</id>
		<title>Module:DateI18n-585816189</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=Module:DateI18n-585816189&amp;diff=3964"/>
		<updated>2026-09-25T08:49:20Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: Created page with &amp;quot;--[[     __  __           _       _        ____        _       ___ _  ___          |  \/  | ___   __| |_   _| | ___ _|  _ \  __ _| |_ ___|_ _/ |( _ ) _ __    | |\/| |/ _ \ / _` | | | | |/ _ (_) | | |/ _` | __/ _ \| || |/ _ \| &amp;#039;_ \   | |  | | (_) | (_| | |_| | |  __/_| |_| | (_| | ||  __/| || | (_) | | | |  |_|  |_|\___/ \__,_|\__,_|_|\___(_)____/ \__,_|\__\___|___|_|\___/|_| |_|    This module is intended for processing of date strings.  Please do not modify this code wi...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;--[[  &lt;br /&gt;
  __  __           _       _        ____        _       ___ _  ___        &lt;br /&gt;
 |  \/  | ___   __| |_   _| | ___ _|  _ \  __ _| |_ ___|_ _/ |( _ ) _ __  &lt;br /&gt;
 | |\/| |/ _ \ / _` | | | | |/ _ (_) | | |/ _` | __/ _ \| || |/ _ \| &#039;_ \ &lt;br /&gt;
 | |  | | (_) | (_| | |_| | |  __/_| |_| | (_| | ||  __/| || | (_) | | | |&lt;br /&gt;
 |_|  |_|\___/ \__,_|\__,_|_|\___(_)____/ \__,_|\__\___|___|_|\___/|_| |_|&lt;br /&gt;
  &lt;br /&gt;
This module is intended for processing of date strings.&lt;br /&gt;
&lt;br /&gt;
Please do not modify this code without applying the changes first at Module:Date/sandbox and testing &lt;br /&gt;
at Module:Date/sandbox/testcases and Module talk:Date/sandbox/testcases.&lt;br /&gt;
&lt;br /&gt;
Authors and maintainers:&lt;br /&gt;
* User:Parent5446 - original version of the function mimicking template:ISOdate&lt;br /&gt;
* User:Jarekt - original version of the functions mimicking template:Date &lt;br /&gt;
]]&lt;br /&gt;
require(&#039;strict&#039;)&lt;br /&gt;
&lt;br /&gt;
-- ==================================================&lt;br /&gt;
-- === Internal functions ===========================&lt;br /&gt;
-- ==================================================&lt;br /&gt;
&lt;br /&gt;
-- Function allowing for consistent treatment of boolean-like wikitext input.&lt;br /&gt;
-- It works similarly to Module:Yesno&lt;br /&gt;
local function yesno(val, default)&lt;br /&gt;
	if type(val) == &#039;boolean&#039; then&lt;br /&gt;
		return val&lt;br /&gt;
	elseif type(val) == &#039;number&#039; then&lt;br /&gt;
		if val==1 then &lt;br /&gt;
			return true&lt;br /&gt;
		elseif val==0 then&lt;br /&gt;
			return false&lt;br /&gt;
		end&lt;br /&gt;
	elseif type(val) == &#039;string&#039; then&lt;br /&gt;
	    val = mw.ustring.lower(val)  -- put in lower case&lt;br /&gt;
	    if val == &#039;no&#039;  or val == &#039;n&#039; or val == &#039;false&#039; or tonumber(val) == 0 then&lt;br /&gt;
	        return false&lt;br /&gt;
	    elseif val == &#039;yes&#039; or val == &#039;y&#039; or val == &#039;true&#039;  or tonumber(val) == 1 then&lt;br /&gt;
	        return true&lt;br /&gt;
	    end&lt;br /&gt;
    end&lt;br /&gt;
    return default&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---------------------------------------------------------------------------------------&lt;br /&gt;
-- String replacement that ignores part of the string in &amp;quot;...&amp;quot;&lt;br /&gt;
local function strReplace(String, old, new)&lt;br /&gt;
	if String:find(&#039;&amp;quot;&#039;) then&lt;br /&gt;
		local T={}&lt;br /&gt;
		for i, str in ipairs(mw.text.split( String, &#039;&amp;quot;&#039;, true )) do&lt;br /&gt;
			if i%2==1 then&lt;br /&gt;
				str = str:gsub(old, new)&lt;br /&gt;
			end&lt;br /&gt;
			table.insert(T, str)&lt;br /&gt;
		end&lt;br /&gt;
		return table.concat(T,&#039;&amp;quot;&#039;)&lt;br /&gt;
	else&lt;br /&gt;
		return String:gsub(old, new)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---------------------------------------------------------------------------------------&lt;br /&gt;
-- process datevec&lt;br /&gt;
-- INPUT:&lt;br /&gt;
--  * datevec - Array of {year,month,day,hour,minute,second, tzhour, tzmin} containing broken &lt;br /&gt;
--    down date-time component strings or numbers&lt;br /&gt;
-- OUTPUT:&lt;br /&gt;
--  * datecode - a code specifying content of the array where Y&#039; is year, &#039;M&#039; is month, &lt;br /&gt;
--     &#039;D&#039; is day, &#039;H&#039; is hour, &#039;M&#039; minute, &#039;S&#039; is second. output has to be one of YMDHMS, YMDHM, YMD, YM, MD, Y&lt;br /&gt;
--  * datenum - same array but holding only numbers or nuls&lt;br /&gt;
local function parserDatevec(datevec)&lt;br /&gt;
	-- if month is not a number than check if it is a month name in project&#039;s language&lt;br /&gt;
	local month = datevec[2]&lt;br /&gt;
	if month and month~=&#039;&#039; and not tonumber(month) then&lt;br /&gt;
		datevec[2] = mw.getContentLanguage():formatDate( &amp;quot;n&amp;quot;, month)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- create datecode based on which variables are provided and check for out-of-bound values&lt;br /&gt;
	local maxval = {nil, 12, 31, 23, 59, 59,  23, 59} -- max values for year, month, ...&lt;br /&gt;
	local minval = {nil,  1,  1,  0,  0,  0, -23,  0} -- min values for year, month, ...&lt;br /&gt;
	local c = {&#039;Y&#039;, &#039;M&#039;, &#039;D&#039;, &#039;H&#039;, &#039;M&#039;, &#039;S&#039;, &#039;&#039;, &#039;&#039;}&lt;br /&gt;
	local datecode = &#039;&#039; -- a string signifying which combination of variables was provided&lt;br /&gt;
	local datenum = {}  -- date-time encoded as a vector = [year, month, ... , second]&lt;br /&gt;
	for i = 1,8 do&lt;br /&gt;
		datenum[i] = tonumber(datevec[i])&lt;br /&gt;
		if datenum[i] and (i==1 or (datenum[i]&amp;gt;=minval[i] and datenum[i]&amp;lt;=maxval[i])) then&lt;br /&gt;
			datecode = datecode .. c[i]&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return datecode, datenum&lt;br /&gt;
end&lt;br /&gt;
	&lt;br /&gt;
---------------------------------------------------------------------------------------&lt;br /&gt;
-- process datevec&lt;br /&gt;
-- INPUT:&lt;br /&gt;
--  * datecode - a code specifying content of the array where Y&#039; is year, &#039;M&#039; is month, &lt;br /&gt;
--     &#039;D&#039; is day, &#039;H&#039; is hour, &#039;M&#039; minute, &#039;S&#039; is second. output has to be one of YMDHMS, YMDHM, YMD, YM, MD, Y&lt;br /&gt;
--  * datenum - Array of {year,month,day,hour,minute,second, tzhour, tzmin} as numbers or nuls&lt;br /&gt;
-- OUTPUT:&lt;br /&gt;
--  * timeStamp - date string in the format taken by mw.language:formatDate lua function and {{#time}} perser function&lt;br /&gt;
--       https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#mw.language:formatDate&lt;br /&gt;
--       https://www.mediawiki.org/wiki/Help:Extension:ParserFunctions#.23time&lt;br /&gt;
--  * datecode - with possible corrections&lt;br /&gt;
local function getTimestamp(datecode, datenum)&lt;br /&gt;
	-- create time stamp string (for example 2000-02-20 02:20:20) based on which variables were provided&lt;br /&gt;
	local timeStamp&lt;br /&gt;
	if datecode == &#039;YMDHMS&#039; then&lt;br /&gt;
		timeStamp = string.format(&#039;%04i-%02i-%02i %02i:%02i:%02i&#039;, datenum[1], datenum[2], datenum[3], datenum[4], datenum[5], datenum[6] )&lt;br /&gt;
	elseif datecode == &#039;YMDHM&#039; then&lt;br /&gt;
		timeStamp = string.format(&#039;%04i-%02i-%02i %02i:%02i&#039;, datenum[1], datenum[2], datenum[3], datenum[4], datenum[5] )&lt;br /&gt;
	elseif datecode:sub(1,3)==&#039;YMD&#039; then&lt;br /&gt;
		timeStamp = string.format(&#039;%04i-%02i-%02i&#039;, datenum[1], datenum[2], datenum[3] )&lt;br /&gt;
		datecode = &#039;YMD&#039; -- &#039;YMD&#039;, &#039;YMDHMS&#039; and &#039;YMDHM&#039; are the only supported format starting with &#039;YMD&#039;. All others will be converted to &#039;YMD&#039;&lt;br /&gt;
	elseif datecode == &#039;YM&#039; then&lt;br /&gt;
		timeStamp = string.format(&#039;%04i-%02i&#039;, datenum[1], datenum[2] )&lt;br /&gt;
	elseif datecode:sub(1,1)==&#039;Y&#039; then&lt;br /&gt;
		timeStamp = string.format(&#039;%04i&#039;, datenum[1] )&lt;br /&gt;
		datecode = &#039;Y&#039; &lt;br /&gt;
	elseif datecode == &#039;M&#039; then&lt;br /&gt;
		timeStamp = string.format(&#039;%04i-%02i-%02i&#039;, 2000, datenum[2], 1 )&lt;br /&gt;
	elseif datecode == &#039;MD&#039; then&lt;br /&gt;
		timeStamp = string.format(&#039;%04i-%02i-%02i&#039;, 2000, datenum[2], datenum[3] )&lt;br /&gt;
	else&lt;br /&gt;
		timeStamp = nil -- format not supported&lt;br /&gt;
	end&lt;br /&gt;
	return timeStamp, datecode&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---------------------------------------------------------------------------------------&lt;br /&gt;
-- trim leading zeros in years prior to year 1000&lt;br /&gt;
-- INPUT:&lt;br /&gt;
--  * datestr   - translated date string &lt;br /&gt;
--  * lang      - language of translation&lt;br /&gt;
-- OUTPUT:&lt;br /&gt;
--  * datestr - updated date string &lt;br /&gt;
&lt;br /&gt;
local function trimYear(datestr, year, lang)&lt;br /&gt;
	local yearStr0, yearStr1, yearStr2, zeroStr&lt;br /&gt;
	yearStr0 = string.format(&#039;%04i&#039;, year ) -- 4 digit year in standard form &amp;quot;0123&amp;quot;&lt;br /&gt;
	yearStr1 = mw.language.new(lang):formatDate( &#039;Y&#039;, yearStr0) -- same as calling {{#time}} parser function&lt;br /&gt;
	--yearStr1 = mw.getCurrentFrame():callParserFunction( &amp;quot;#time&amp;quot;, { &#039;Y&#039;, yearStr0, lang } ) -- translate to a language &lt;br /&gt;
	if yearStr0==yearStr1 then -- most of languages use standard form of year &lt;br /&gt;
		yearStr2 = tostring(year)&lt;br /&gt;
	else -- some languages use different characters for numbers&lt;br /&gt;
		yearStr2 = yearStr1&lt;br /&gt;
		zeroStr = mw.ustring.sub(yearStr1,1,1) -- get &amp;quot;0&amp;quot; in whatever language&lt;br /&gt;
		for i=1,3 do -- trim leading zeros&lt;br /&gt;
			if mw.ustring.sub(yearStr2,1,1)==zeroStr then&lt;br /&gt;
				yearStr2 = mw.ustring.sub(yearStr2, 2, 5-i)&lt;br /&gt;
			else&lt;br /&gt;
				break&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return string.gsub(datestr, yearStr1, yearStr2 ) -- in datestr replace long year with trimmed one&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---------------------------------------------------------------------------------------&lt;br /&gt;
-- Look up proper format string to be passed to {{#time}} parser function&lt;br /&gt;
-- INPUTS:&lt;br /&gt;
--  * datecode: YMDHMS, YMDHM, YMD, YM, MD, Y, or M&lt;br /&gt;
--  * day     : Number between 1 and 31 (not needed for most languages)&lt;br /&gt;
--  * lang    : language&lt;br /&gt;
-- OUTPUT:&lt;br /&gt;
--  * dFormat : input to {{#time}} function&lt;br /&gt;
local function getDateFormat(datecode, day, lang)&lt;br /&gt;
	local function parseFormat(dFormat, day)&lt;br /&gt;
		if dFormat:find(&#039;default&#039;) and #dFormat&amp;gt;10 then&lt;br /&gt;
			-- special (and messy) case of dFormat code depending on a day number&lt;br /&gt;
			-- then json contains a string with more json containing &amp;quot;default&amp;quot; field and 2 digit day keys&lt;br /&gt;
			-- if desired day is not in that json than use &amp;quot;default&amp;quot; case&lt;br /&gt;
			dFormat = dFormat:gsub(&#039;”&#039;,&#039;&amp;quot;&#039;) -- change fancy double quote to a straight one, used for json marking&lt;br /&gt;
			local D = mw.text.jsonDecode( dFormat )		--com = mw.dumpObject(D)&lt;br /&gt;
			day = string.format(&#039;d%02i&#039;,day) -- create day key&lt;br /&gt;
			dFormat = D[day] or D.default&lt;br /&gt;
			dFormat = dFormat:gsub(&amp;quot;&#039;&amp;quot;, &#039;&amp;quot;&#039;) -- change single quote to a double quote, used for {{#time}} marking&lt;br /&gt;
		end&lt;br /&gt;
		return dFormat&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local T = {}&lt;br /&gt;
	local tab = mw.ext.data.get(&#039;DateI18n.tab&#039;, lang)&lt;br /&gt;
	for _, row in pairs(tab.data) do -- convert the output into a dictionary table&lt;br /&gt;
		local id, _, msg = unpack(row)&lt;br /&gt;
		T[id] = msg&lt;br /&gt;
	end&lt;br /&gt;
	local dFormat = T[datecode]&lt;br /&gt;
	if dFormat==&#039;default&#039; and (datecode==&#039;YMDHMS&#039; or datecode==&#039;YMDHM&#039;)  then &lt;br /&gt;
		-- for most languages adding hour:minute:second is done by adding &amp;quot;, HH:MM:SS to the &lt;br /&gt;
		-- day precission date, those languages are skipped in DateI18n.tab and default to &lt;br /&gt;
		-- English which stores word &amp;quot;default&amp;quot;&lt;br /&gt;
		dFormat = parseFormat(T[&#039;YMD&#039;], day).. &#039;, H:i&#039;&lt;br /&gt;
		if datecode==&#039;YMDHMS&#039; then&lt;br /&gt;
			dFormat = dFormat .. &#039;:s&#039;&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		dFormat = parseFormat(dFormat, day)&lt;br /&gt;
	end&lt;br /&gt;
	return dFormat&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---------------------------------------------------------------------------------------&lt;br /&gt;
-- Look up proper format string to be passed to {{#time}} parser function&lt;br /&gt;
-- INPUTS:&lt;br /&gt;
--  * month : month number&lt;br /&gt;
--  * case  : gramatic case abbriviation, like &amp;quot;ins&amp;quot;, &amp;quot;loc&amp;quot;&lt;br /&gt;
--  * lang  : language&lt;br /&gt;
-- OUTPUT:&lt;br /&gt;
--  * dFormat : input to {{#time}} function&lt;br /&gt;
local function MonthCase(month, case, lang)&lt;br /&gt;
	local T = {{},{},{},{},{},{},{},{},{},{},{},{}}&lt;br /&gt;
	local tab = mw.ext.data.get(&#039;I18n/MonthCases.tab&#039;, lang)&lt;br /&gt;
	for _, row in pairs(tab.data) do&lt;br /&gt;
		local mth, cs, msg = unpack(row)&lt;br /&gt;
		T[mth][cs] = msg&lt;br /&gt;
	end&lt;br /&gt;
	return T[month][case]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- ==================================================&lt;br /&gt;
-- === External functions ===========================&lt;br /&gt;
-- ==================================================&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
--[[ ========================================================================================&lt;br /&gt;
Date&lt;br /&gt;
 &lt;br /&gt;
This function is the core part of the ISOdate template. &lt;br /&gt;
 &lt;br /&gt;
Usage:&lt;br /&gt;
  local Date = require(&#039;Module:DateI18n&#039;)._Date&lt;br /&gt;
  local dateStr = Date({2020, 12, 30, 12, 20, 11}, lang)&lt;br /&gt;
 &lt;br /&gt;
Parameters:&lt;br /&gt;
  * {year,month,day,hour,minute,second, tzhour, tzmin}: broken down date-time component strings or numbers&lt;br /&gt;
		tzhour, tzmin are timezone offsets from UTC, hours and minutes&lt;br /&gt;
  * lang: The language to display it in&lt;br /&gt;
  * case: Language format (genitive, etc.) for some languages&lt;br /&gt;
  * class: CSS class for the &amp;lt;time&amp;gt; node, use &amp;quot;&amp;quot; for no metadata at all&lt;br /&gt;
]]&lt;br /&gt;
function p._Date(datevec, lang, case, class, trim_year)	&lt;br /&gt;
	-- make sure inputs are in the right format&lt;br /&gt;
	if not lang or not mw.language.isValidCode( lang ) then&lt;br /&gt;
		lang = mw.getCurrentFrame():callParserFunction( &amp;quot;int&amp;quot;, &amp;quot;lang&amp;quot; ) -- get user&#039;s chosen language&lt;br /&gt;
	end&lt;br /&gt;
	if lang == &#039;be-tarsk&#039; then&lt;br /&gt;
		lang = &#039;be-x-old&#039;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- process datevec and extract timeStamp and datecode strings as well as numeric datenum array&lt;br /&gt;
	local datecode,  datenum  = parserDatevec(datevec)&lt;br /&gt;
	local year, month, day = datenum[1], datenum[2], datenum[3]&lt;br /&gt;
	local timeStamp, datecode = getTimestamp(datecode, datenum)&lt;br /&gt;
	if not timeStamp then -- something went wrong in parserDatevec&lt;br /&gt;
		return &#039;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	-- Commons [[Data:DateI18n.tab]] page stores prefered formats for diferent &lt;br /&gt;
	-- languages and datecodes (specifying year-month-day or just year of month-day, etc)&lt;br /&gt;
	-- Look up country specific format input to {{#time}} function&lt;br /&gt;
	local dFormat = getDateFormat(datecode, day, lang)&lt;br /&gt;
&lt;br /&gt;
	-- By default the gramatical case is not specified (case==&#039;&#039;) allowing the format to be specified &lt;br /&gt;
	-- in [[Data:DateI18n.tab]]. You can overwrite the default grammatical case of the month by &lt;br /&gt;
	-- specifying &amp;quot;case&amp;quot; variable. This is needed mostly by Slavic languages to create more complex &lt;br /&gt;
	-- phrases as it is done in [[c:Module:Complex date]]&lt;br /&gt;
	case = case or &#039;&#039;&lt;br /&gt;
	if (lang==&#039;qu&#039; or lang==&#039;qug&#039;) and (case==&#039;nom&#039;) then&lt;br /&gt;
		-- Special case related to Quechua and Kichwa languages. The form in the I18n is&lt;br /&gt;
		--  Genitive case with suffix &amp;quot;pi&amp;quot; added to month names provided by {#time}}&lt;br /&gt;
		-- in Nominative case that &amp;quot;pi&amp;quot; should be removed&lt;br /&gt;
		-- see https://commons.wikimedia.org/wiki/Template_talk:Date#Quechua from 2014&lt;br /&gt;
		dFormat = dFormat:gsub(&#039;F&amp;quot;pi&amp;quot;&#039;, &#039;F&#039;)&lt;br /&gt;
	elseif (case==&#039;gen&#039;) then&lt;br /&gt;
		dFormat = strReplace(dFormat, &amp;quot;F&amp;quot;, &amp;quot;xg&amp;quot;)&lt;br /&gt;
	elseif (case==&#039;nom&#039;) then&lt;br /&gt;
		dFormat = strReplace(dFormat, &amp;quot;xg&amp;quot;, &amp;quot;F&amp;quot;)&lt;br /&gt;
	elseif (case ~= &#039;&#039;) then&lt;br /&gt;
		-- see is page [[Data:I18n/MonthCases.tab]] on Commons have name of the month &lt;br /&gt;
		-- in specific gramatic case in desired language. If we have it than replace &lt;br /&gt;
		-- &amp;quot;F&amp;quot; and xg&amp;quot; in dFormat&lt;br /&gt;
		local monthMsg = MonthCase(month, case, lang)&lt;br /&gt;
		if  monthMsg and monthMsg ~= &#039;&#039; then -- make sure it exists&lt;br /&gt;
			dFormat = strReplace(dFormat, &#039;F&#039;,  &#039;&amp;quot;&#039;..monthMsg..&#039;&amp;quot;&#039;) -- replace default month with month name we already looked up&lt;br /&gt;
			dFormat = strReplace(dFormat, &#039;xg&#039;, &#039;&amp;quot;&#039;..monthMsg..&#039;&amp;quot;&#039;)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
    -- Translate the date using specified format&lt;br /&gt;
	-- See https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#mw.language:formatDate and &lt;br /&gt;
	-- https://www.mediawiki.org/wiki/Help:Extension:ParserFunctions##time for explanation of the format&lt;br /&gt;
	local langObj = mw.language.new(lang)&lt;br /&gt;
	local datestr = langObj:formatDate( dFormat, timeStamp) -- same as using {{#time}} parser function&lt;br /&gt;
	&lt;br /&gt;
	-- Special case related to Thai solar calendar: prior to 1940 new-year was at different &lt;br /&gt;
	-- time of year, so just year (datecode==&#039;Y&#039;) is ambiguous and is replaced by &amp;quot;YYYY or YYYY&amp;quot; phrase&lt;br /&gt;
	if lang==&#039;th&#039; and datecode==&#039;Y&#039; and year&amp;lt;=1940 then&lt;br /&gt;
		datestr = string.format(&#039;%04i หรือ %04i&#039;, year+542, year+543 ) &lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- If year&amp;lt;1000 than either keep the date padded to the length of 4 digits or trim it&lt;br /&gt;
	-- decide if the year will stay padded with zeros (for years in 0-999 range)&lt;br /&gt;
	if year and year&amp;lt;1000 then&lt;br /&gt;
		if type(trim_year)==&#039;nil&#039; then &lt;br /&gt;
			trim_year = &#039;100-999&#039;&lt;br /&gt;
		end&lt;br /&gt;
		local trim = yesno(trim_year,nil) -- convert to boolean&lt;br /&gt;
		if trim==nil and type(trim_year)==&#039;string&#039; then&lt;br /&gt;
			-- if &amp;quot;trim_year&amp;quot; not a simple True/False than it is range of dates&lt;br /&gt;
			-- for example &#039;100-999&#039; means to pad one and 2 digit years to be 4 digit long, while keeping 3 digit years as is&lt;br /&gt;
			local YMin, YMax = trim_year:match( &#039;(%d+)-(%d+)&#039; )&lt;br /&gt;
			trim = (YMin~=nil and year&amp;gt;=tonumber(YMin) and year&amp;lt;=tonumber(YMax)) &lt;br /&gt;
		end&lt;br /&gt;
		if trim==true then&lt;br /&gt;
			datestr = trimYear(datestr, year, lang) -- in datestr replace long year with trimmed one&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- append timezone if present&lt;br /&gt;
	if datenum[7] and (datecode == &#039;YMDHMS&#039; or datecode == &#039;YMDHM&#039;) then&lt;br /&gt;
		-- use {{#time}} parser function to create timezone string, so that we use correct character set&lt;br /&gt;
		local sign = (datenum[7]&amp;lt;0) and &#039;−&#039; or &#039;+&#039;&lt;br /&gt;
		timeStamp = string.format(&amp;quot;2000-01-01 %02i:%02i:00&amp;quot;, math.abs(datenum[7]), datenum[8] or 0)&lt;br /&gt;
		local timezone = langObj:formatDate( &#039;H:i&#039;, timeStamp) -- same as using {{#time}} parser function&lt;br /&gt;
		datestr = string.format(&amp;quot;%s %s%s&amp;quot;, datestr, sign, timezone )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- html formating and tagging of date string&lt;br /&gt;
	if class and class ~= &#039;&#039; and datecode~=&#039;M&#039; and datecode~=&#039;MD&#039;then&lt;br /&gt;
		local DateHtmlTags = &#039;&amp;lt;span style=&amp;quot;white-space:nowrap&amp;quot;&amp;gt;&amp;lt;time class=&amp;quot;%s&amp;quot; datetime=&amp;quot;%s&amp;quot; lang=&amp;quot;%s&amp;quot; dir=&amp;quot;%s&amp;quot;&amp;gt;%s&amp;lt;/time&amp;gt;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
		datestr = DateHtmlTags:format(class, timeStamp, lang, langObj:getDir(), datestr)&lt;br /&gt;
	end&lt;br /&gt;
	return datestr&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[ ========================================================================================&lt;br /&gt;
Date&lt;br /&gt;
 &lt;br /&gt;
This function is the core part of the ISOdate template. &lt;br /&gt;
 &lt;br /&gt;
Usage:&lt;br /&gt;
{{#invoke:DateI18n|Date|year=|month=|day=|hour=|minute=|second=|tzhour=|tzmin=|lang=en}}&lt;br /&gt;
 &lt;br /&gt;
Parameters:&lt;br /&gt;
  * year, month, day, hour, minute, second: broken down date-time component strings&lt;br /&gt;
  * tzhour, tzmin: timezone offset from UTC, hours and minutes&lt;br /&gt;
  * lang: The language to display it in&lt;br /&gt;
  * case: Language format (genitive, etc.) for some languages&lt;br /&gt;
  * class: CSS class for the &amp;lt;time&amp;gt; node, use &amp;quot;&amp;quot; for no metadata at all&lt;br /&gt;
]]&lt;br /&gt;
function p.Date(frame)&lt;br /&gt;
	local args = {}&lt;br /&gt;
	for name, value in pairs( frame.args ) do &lt;br /&gt;
		name = string.gsub( string.lower(name), &#039; &#039;, &#039;_&#039;)&lt;br /&gt;
		args[name] = value&lt;br /&gt;
	end&lt;br /&gt;
	return p._Date(	&lt;br /&gt;
		{ args.year, args.month, args.day, args.hour, args.minute, args.second, args.tzhour, args.tzmin },&lt;br /&gt;
		args.lang,                  -- language&lt;br /&gt;
		args.case,                  -- allows to specify grammatical case for the month for languages that use them&lt;br /&gt;
		args.class or &#039;dtstart&#039;,    -- allows to set the html class of the time node where the date is included. This is useful for microformats.&lt;br /&gt;
		args.trim_year or &#039;100-999&#039; -- by default pad one and 2 digit years to be 4 digit long, while keeping 3 digit years as is&lt;br /&gt;
	)	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=Module:DateI18n/sandbox_2&amp;diff=3963</id>
		<title>Module:DateI18n/sandbox 2</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=Module:DateI18n/sandbox_2&amp;diff=3963"/>
		<updated>2026-09-25T08:48:06Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: Created page with &amp;quot;--[[     __  __           _       _        ____        _       ___ _  ___          |  \/  | ___   __| |_   _| | ___ _|  _ \  __ _| |_ ___|_ _/ |( _ ) _ __    | |\/| |/ _ \ / _` | | | | |/ _ (_) | | |/ _` | __/ _ \| || |/ _ \| &amp;#039;_ \   | |  | | (_) | (_| | |_| | |  __/_| |_| | (_| | ||  __/| || | (_) | | | |  |_|  |_|\___/ \__,_|\__,_|_|\___(_)____/ \__,_|\__\___|___|_|\___/|_| |_|    This module is intended for processing of date strings.  Please do not modify this code wi...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;--[[  &lt;br /&gt;
  __  __           _       _        ____        _       ___ _  ___        &lt;br /&gt;
 |  \/  | ___   __| |_   _| | ___ _|  _ \  __ _| |_ ___|_ _/ |( _ ) _ __  &lt;br /&gt;
 | |\/| |/ _ \ / _` | | | | |/ _ (_) | | |/ _` | __/ _ \| || |/ _ \| &#039;_ \ &lt;br /&gt;
 | |  | | (_) | (_| | |_| | |  __/_| |_| | (_| | ||  __/| || | (_) | | | |&lt;br /&gt;
 |_|  |_|\___/ \__,_|\__,_|_|\___(_)____/ \__,_|\__\___|___|_|\___/|_| |_|&lt;br /&gt;
  &lt;br /&gt;
This module is intended for processing of date strings.&lt;br /&gt;
&lt;br /&gt;
Please do not modify this code without applying the changes first at Module:DateI18n/sandbox&lt;br /&gt;
and testing at Module:DateI18n/sandbox/testcases and Module talk:DateI18n/sandbox/testcases.&lt;br /&gt;
&lt;br /&gt;
Authors and maintainers:&lt;br /&gt;
* User:Parent5446 - original version of the function mimicking Template:ISOdate&lt;br /&gt;
* User:Jarekt - original version of the functions mimicking Template:Date &lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
-- =======================================&lt;br /&gt;
-- === Dependencies ======================&lt;br /&gt;
-- =======================================&lt;br /&gt;
&lt;br /&gt;
require(&#039;strict&#039;)&lt;br /&gt;
&lt;br /&gt;
-- =======================================&lt;br /&gt;
-- === Local Functions ===================&lt;br /&gt;
-- =======================================&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------&lt;br /&gt;
--[[ (copied from Module:Core)&lt;br /&gt;
Function allowing for consistent treatment of boolean-like wikitext input.&lt;br /&gt;
Inputs:&lt;br /&gt;
  1) val - value to be evaluated, outputs as a function of values:&lt;br /&gt;
		true  : true  (boolean), 1 (number), or strings: &amp;quot;yes&amp;quot;, &amp;quot;y&amp;quot;, &amp;quot;true&amp;quot;, &amp;quot;1&amp;quot;&lt;br /&gt;
		false : false (boolean), 0 (number), or strings: &amp;quot;no&amp;quot;, &amp;quot;n&amp;quot;, &amp;quot;false&amp;quot;, &amp;quot;0&amp;quot;&lt;br /&gt;
  2) default - value to return otherwise&lt;br /&gt;
See Also: It works similarly to Module:Yesno&lt;br /&gt;
]]&lt;br /&gt;
local function yesno(val, default)&lt;br /&gt;
	if type(val) == &#039;boolean&#039; then&lt;br /&gt;
		return val&lt;br /&gt;
	elseif type(val) == &#039;number&#039; then&lt;br /&gt;
		val = tostring(val)&lt;br /&gt;
	end&lt;br /&gt;
	if type(val) == &#039;string&#039; then&lt;br /&gt;
		local LUT = {&lt;br /&gt;
			yes=true , y=true , [&#039;true&#039;] =true , t=true , [&#039;1&#039;]=true , on =true,&lt;br /&gt;
			no =false, n=false, [&#039;false&#039;]=false, f=false, [&#039;0&#039;]=false, off=false }&lt;br /&gt;
	    val = LUT[mw.ustring.lower(val)]  -- put in lower case&lt;br /&gt;
	    if (val~=nil) then&lt;br /&gt;
			return val&lt;br /&gt;
		end&lt;br /&gt;
    end&lt;br /&gt;
    return default&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
---------------------------------------------------------------------------------------&lt;br /&gt;
-- trim leading zeros in years prior to year 1000&lt;br /&gt;
-- INPUT:&lt;br /&gt;
--  * datestr   - translated date string &lt;br /&gt;
--  * lang      - language of translation&lt;br /&gt;
-- OUTPUT:&lt;br /&gt;
--  * datestr - updated date string &lt;br /&gt;
&lt;br /&gt;
local function trimYear(datestr, year, lang)&lt;br /&gt;
	local yearStr0, yearStr1, yearStr2, zeroStr&lt;br /&gt;
	yearStr0 = string.format(&#039;%04i&#039;, year ) -- 4 digit year in standard form &amp;quot;0123&amp;quot;&lt;br /&gt;
	yearStr1 = mw.language.new(lang):formatDate( &#039;Y&#039;, yearStr0) -- same as calling {{#time}} parser function&lt;br /&gt;
	--yearStr1 = mw.getCurrentFrame():callParserFunction( &amp;quot;#time&amp;quot;, { &#039;Y&#039;, yearStr0, lang } ) -- translate to a language &lt;br /&gt;
	if yearStr0==yearStr1 then -- most of languages use standard form of year &lt;br /&gt;
		yearStr2 = tostring(year)&lt;br /&gt;
	else -- some languages use different characters for numbers&lt;br /&gt;
		yearStr2 = yearStr1&lt;br /&gt;
		zeroStr = mw.ustring.sub(yearStr1,1,1) -- get &amp;quot;0&amp;quot; in whatever language&lt;br /&gt;
		for i=1,3 do -- trim leading zeros&lt;br /&gt;
			if mw.ustring.sub(yearStr2,1,1)==zeroStr then&lt;br /&gt;
				yearStr2 = mw.ustring.sub(yearStr2, 2, 5-i)&lt;br /&gt;
			else&lt;br /&gt;
				break&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return string.gsub(datestr, yearStr1, yearStr2 ) -- in datestr replace long year with trimmed one&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---------------------------------------------------------------------------------------&lt;br /&gt;
-- Look up proper format string to be passed to {{#time}} parser function&lt;br /&gt;
-- INPUTS:&lt;br /&gt;
--  * datecode: YMDhms, YMDhm, YMD, YM, Y, MDhms, MDhm, MD, or M&lt;br /&gt;
--  * day     : Number between 1 and 31 (not needed for most languages)&lt;br /&gt;
--  * lang    : language&lt;br /&gt;
-- OUTPUT:&lt;br /&gt;
--  * dFormat : input to {{#time}} function&lt;br /&gt;
local function getDateFormat(datecode, day, lang)&lt;br /&gt;
	local function parseFormat(dFormat, day)&lt;br /&gt;
		if dFormat:find(&#039;default&#039;) and #dFormat&amp;gt;10 then&lt;br /&gt;
			-- Special (and messy) case of dFormat code depending on a day number, where data is a&lt;br /&gt;
			-- JSON-encoded table {”default”:”*”,”dDD”:”*”} including fields for specific 2-digit days.&lt;br /&gt;
			-- Change curly double quotes (possibly used for easier editing in tabular data) in dFormat&lt;br /&gt;
			-- to straight ASCII double quotes (required for parsing of this JSON-encoded table).&lt;br /&gt;
			local D = mw.text.jsonDecode(mw.ustring.gsub(dFormat, &#039;[„“‟”]&#039;, &#039;&amp;quot;&#039;)) --com = mw.dumpObject(D)&lt;br /&gt;
			-- If the desired day is not in that JSON table, then use its &amp;quot;default&amp;quot; case.&lt;br /&gt;
			dFormat = D[string.format(&#039;d%02i&#039;, day)] or D.default&lt;br /&gt;
            -- Change ASCII single quotes to ASCII double quotes used for {{#time}} marking.&lt;br /&gt;
            -- Apostrophes needed in plain-text must not use ASCII single quotes but curly apostrophe&lt;br /&gt;
            -- e.g. { ‟default”: ‟j”, ‟d01”: ‟j’&#039;o&#039;” }, not { ‟default”: ‟j”, ‟d01”: ‟j&#039;&#039;o&#039;” }.&lt;br /&gt;
		end&lt;br /&gt;
		dFormat = dFormat:gsub(&amp;quot;&#039;&amp;quot;, &#039;&amp;quot;&#039;)&lt;br /&gt;
		return dFormat&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local T = {}&lt;br /&gt;
	local tab = mw.ext.data.get(&#039;DateI18n.tab&#039;, lang)&lt;br /&gt;
	for _, row in pairs(tab.data) do -- convert the output into a dictionary table&lt;br /&gt;
		local id, _, msg = unpack(row)&lt;br /&gt;
		T[id] = msg&lt;br /&gt;
	end&lt;br /&gt;
    -- Compatibility of legacy data using &#039;HMS&#039; or &#039;HM&#039;, where &#039;M&#039; is ambiguous&lt;br /&gt;
    T.YMDhms = T.YMDhms or T.YMDHMS&lt;br /&gt;
    T.YMDhm  = T.YMDhm  or T.YMDHM&lt;br /&gt;
    datecode = datecode == &#039;YMDHMS&#039; and &#039;YMDhms&#039; or datecode == &#039;YMDHM&#039; and &#039;YMDhm&#039; or datecode&lt;br /&gt;
&lt;br /&gt;
	local dFormat = T[datecode]&lt;br /&gt;
	if dFormat == &#039;default&#039; and (datecode == &#039;YMDhms&#039; or datecode == &#039;YMDhm&#039;)  then &lt;br /&gt;
		-- For most languages adding hour:minute:second is done by adding &amp;quot;, HH:ii:ss to the &lt;br /&gt;
		-- day precission date, those languages are skipped in DateI18n.tab and default to &lt;br /&gt;
		-- English which stores word &amp;quot;default&amp;quot;&lt;br /&gt;
		dFormat = parseFormat(T[&#039;YMD&#039;], day).. &#039;, H:i&#039;&lt;br /&gt;
		if datecode == &#039;YMDhms&#039; then&lt;br /&gt;
			dFormat = dFormat .. &#039;:s&#039;&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		dFormat = parseFormat(dFormat, day)&lt;br /&gt;
	end&lt;br /&gt;
	return dFormat&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---------------------------------------------------------------------------------------&lt;br /&gt;
-- Look up proper format string to be passed to {{#time}} parser function&lt;br /&gt;
-- INPUTS:&lt;br /&gt;
--  * month : month number&lt;br /&gt;
--  * case  : gramatic case abbriviation, like &amp;quot;ins&amp;quot;, &amp;quot;loc&amp;quot;&lt;br /&gt;
--  * lang  : language&lt;br /&gt;
-- OUTPUT:&lt;br /&gt;
--  * dFormat : input to {{#time}} function&lt;br /&gt;
local function MonthCase(month, case, lang)&lt;br /&gt;
	if month == nil or case == nil then&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
	local T = {{},{},{},{},{},{},{},{},{},{},{},{}}&lt;br /&gt;
	local tab = mw.ext.data.get(&#039;I18n/MonthCases.tab&#039;, lang)&lt;br /&gt;
	for _, row in pairs(tab.data) do&lt;br /&gt;
		local mth, cs, msg = unpack(row)&lt;br /&gt;
		T[mth][cs] = msg&lt;br /&gt;
	end&lt;br /&gt;
	return T[month][case]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- ==================================================&lt;br /&gt;
-- === External functions ===========================&lt;br /&gt;
-- ==================================================&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
-- ===========================================================================&lt;br /&gt;
-- === Functions accesible from the outside to allow unit-testing&lt;br /&gt;
-- === Please do not use directly as they could change in the future&lt;br /&gt;
-- ===========================================================================&lt;br /&gt;
&lt;br /&gt;
---------------------------------------------------------------------------------------&lt;br /&gt;
-- Single string replacement that ignores part of the string in &amp;quot;...&amp;quot;&lt;br /&gt;
function p.strReplace(String, old, new)&lt;br /&gt;
	if String:find(&#039;&amp;quot;&#039;) then&lt;br /&gt;
		local T={}&lt;br /&gt;
		for i, str in ipairs(mw.text.split( String, &#039;&amp;quot;&#039;, true )) do&lt;br /&gt;
			if i%2==1 then&lt;br /&gt;
				str = str:gsub(old, new, 1)&lt;br /&gt;
			end&lt;br /&gt;
			table.insert(T, str)&lt;br /&gt;
		end&lt;br /&gt;
		return table.concat(T,&#039;&amp;quot;&#039;)&lt;br /&gt;
	else&lt;br /&gt;
		return String:gsub(old, new, 1)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---------------------------------------------------------------------------------------&lt;br /&gt;
-- process datevec&lt;br /&gt;
-- INPUT:&lt;br /&gt;
--  * datevec - Array of {year,month,day,hour,minute,second, tzhour, tzmin} containing broken &lt;br /&gt;
--    down date-time component strings or numbers&lt;br /&gt;
-- OUTPUT:&lt;br /&gt;
--  * datenum - same array but holding only numbers or nuls&lt;br /&gt;
function p.clean_datevec(datevec)&lt;br /&gt;
	-- create datecode based on which variables are provided and check for out-of-bound values&lt;br /&gt;
	&lt;br /&gt;
	-- check special case of month provided as a name&lt;br /&gt;
	local month = datevec[2]&lt;br /&gt;
	if type(month) == &#039;string&#039; and month ~= &#039;&#039; and not tonumber(month) then&lt;br /&gt;
		-- When the month is not a number, check if it&#039;s a month name in the project&#039;s language.&lt;br /&gt;
		datevec[2] = mw.getContentLanguage():formatDate(&#039;n&#039;, month)&lt;br /&gt;
	end&lt;br /&gt;
		&lt;br /&gt;
	-- check bounds&lt;br /&gt;
	local maxval = {  1/0, 12, 31, 23, 59, 59,  23, 59 } -- max values (or  1/0=+inf) for year, month, day, hour, minute, second, tzhour, tzmin&lt;br /&gt;
	local minval = { -1/0, 01, 01, 00, 00, 00, -23, 00 } -- min values (or -1/0=-inf) for year, month, ...&lt;br /&gt;
	local datenum  = {} -- date-time encoded as a vector = [year, month, ... , second, tzhour, tzmin]&lt;br /&gt;
	for i = 1, 8 do&lt;br /&gt;
        local val = tonumber(datevec[i])&lt;br /&gt;
        if val and val &amp;gt;= minval[i] and val &amp;lt;= maxval[i] then -- These tests work with infinite min/max values.&lt;br /&gt;
		    datenum[i] = val&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- leap second&lt;br /&gt;
	if tonumber(datevec[6]) == 60 then -- leap second &#039;60&#039; is valid only at end of 23:59 UTC, on 30 June or 31 December of specific years&lt;br /&gt;
--		datenum[6] = 60 &lt;br /&gt;
		local MDhm = table.concat({unpack(datenum,2,5)}, &#039;,&#039;)&lt;br /&gt;
	    if (MDhm == table.concat({6, 30, 23, 59}, &#039;,&#039;)) or (MDhm == table.concat({12, 31, 23, 59}, &#039;,&#039;)) then&lt;br /&gt;
		   datenum[6] = 60 &lt;br /&gt;
	    end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return datenum&lt;br /&gt;
end&lt;br /&gt;
	&lt;br /&gt;
---------------------------------------------------------------------------------------&lt;br /&gt;
-- process datevec&lt;br /&gt;
-- INPUT:&lt;br /&gt;
--  * datenum - Array of {year,month,day,hour,minute,second, tzhour, tzmin} as numbers or nuls&lt;br /&gt;
-- OUTPUT:&lt;br /&gt;
--  * timeStamp - date string in the format taken by mw.language:formatDate lua function and {{#time}} parser function&lt;br /&gt;
--       https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#mw.language:formatDate&lt;br /&gt;
--       https://www.mediawiki.org/wiki/Help:Extension:ParserFunctions#.23time&lt;br /&gt;
--  * datecode - a code specifying content of the array where Y&#039; is year, &#039;M&#039; is month,&lt;br /&gt;
--     &#039;D&#039; is day, &#039;h&#039; is hour, &#039;m&#039; minute, &#039;s&#039; is second.&lt;br /&gt;
--     Output has to be one of YMDhms, YMDhm, YMD, YM, Y, MDhms, MDhm, MD, M.&lt;br /&gt;
function p.getTimestamp(datenum)&lt;br /&gt;
&lt;br /&gt;
	-- create datecode based on datenum&lt;br /&gt;
	local codes  = { &#039;Y&#039;, &#039;M&#039;, &#039;D&#039;, &#039;h&#039;, &#039;m&#039;, &#039;s&#039;} &lt;br /&gt;
	local datecode = &#039;&#039; -- a string signifying which combination of variables was provided&lt;br /&gt;
	for i, c in ipairs(codes) do&lt;br /&gt;
		datecode = datecode .. (datenum[i] and c or &#039;&#039;) -- if datenum[i] than append codes[i] to datecode&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- create timestamp string (for example 2000-02-20 02:20:20) based on which variables were provided&lt;br /&gt;
	local timeStamp&lt;br /&gt;
    -- date starting by a year&lt;br /&gt;
	if datecode == &#039;YMDhms&#039; then&lt;br /&gt;
		timeStamp = string.format(&#039;%04i-%02i-%02i %02i:%02i:%02i&#039;, datenum[1], datenum[2], datenum[3], datenum[4], datenum[5], datenum[6] )&lt;br /&gt;
	elseif datecode == &#039;YMDhm&#039; then&lt;br /&gt;
		timeStamp = string.format(&#039;%04i-%02i-%02i %02i:%02i&#039;, datenum[1], datenum[2], datenum[3], datenum[4], datenum[5] )&lt;br /&gt;
	elseif datecode:sub(1,3)==&#039;YMD&#039; then&lt;br /&gt;
		timeStamp = string.format(&#039;%04i-%02i-%02i&#039;, datenum[1], datenum[2], datenum[3] )&lt;br /&gt;
		datecode  = &#039;YMD&#039; -- &#039;YMDhms&#039;, &#039;YMDhm&#039; and &#039;YMD&#039; are the only supported format starting with &#039;YMD&#039;; all others will be converted to &#039;YMD&#039;.&lt;br /&gt;
	elseif datecode:sub(1,2) == &#039;YM&#039; then&lt;br /&gt;
		timeStamp = string.format(&#039;%04i-%02i&#039;, datenum[1], datenum[2] )&lt;br /&gt;
		datecode  = &#039;YM&#039; &lt;br /&gt;
	elseif datecode:sub(1,1)==&#039;Y&#039; then&lt;br /&gt;
		timeStamp = string.format(&#039;%04i&#039;, datenum[1] )&lt;br /&gt;
		datecode  = &#039;Y&#039; &lt;br /&gt;
    -- date starting by a month (the implied year is 2000)&lt;br /&gt;
	elseif datecode== &#039;MDhms&#039; then&lt;br /&gt;
		timeStamp = string.format(&#039;%04i-%02i-%02i %02i:%02i:%02i&#039;, 2000, datenum[2], datenum[3], datenum[4], datenum[5], datenum[6] )&lt;br /&gt;
	elseif datecode == &#039;MDhm&#039; then&lt;br /&gt;
		timeStamp = string.format(&#039;%04i-%02i-%02i %02i:%02i&#039;, 2000, datenum[2], datenum[3], datenum[4], datenum[5] )&lt;br /&gt;
	elseif datecode:sub(1,2) == &#039;MD&#039; then&lt;br /&gt;
		timeStamp = string.format(&#039;%04i-%02i-%02i&#039;, 2000, datenum[2], datenum[3] )&lt;br /&gt;
		datecode = &#039;MD&#039; -- &#039;MDhms&#039;, &#039;MDhm&#039; and &#039;MD&#039; are the only supported format starting with &#039;MD&#039;; all others will be converted to &#039;MD&#039;&lt;br /&gt;
	elseif datecode:sub(1,1) == &#039;M&#039; then -- Ambiguous: could mean minutes, but here means month (when parsed as a name/abbrev, not as a number).&lt;br /&gt;
		timeStamp = string.format(&#039;%04i-%02i-%02i&#039;, 2000, datenum[2], 1 )&lt;br /&gt;
		datecode  = &#039;M&#039; &lt;br /&gt;
    -- other possible but unrecognized formats (e.g. &#039;DHis&#039;, &#039;DHi&#039;, &#039;D&#039;, &#039;His&#039;, &#039;Hi&#039;);&lt;br /&gt;
    -- note that &#039;Dh&#039;, &#039;D&#039;, &#039;h&#039;, &#039;s&#039; may eventually work, but not &#039;m&#039; for minute only, which is ambiguous with &#039;M&#039; for month only.&lt;br /&gt;
	else&lt;br /&gt;
		timeStamp = nil -- format not supported&lt;br /&gt;
	end&lt;br /&gt;
	return timeStamp, datecode&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function isValidLangCode(lang)&lt;br /&gt;
	if not lang then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
	lang = mw.text.trim(lang)&lt;br /&gt;
	return lang ~= &#039;&#039; and lang ~= &#039;⧼Lang⧽&#039; and mw.language.isValidCode(lang)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- ===========================================================================&lt;br /&gt;
-- === Version of the function to be called from other LUA codes&lt;br /&gt;
-- ===========================================================================&lt;br /&gt;
&lt;br /&gt;
--[[ ========================================================================================&lt;br /&gt;
Date&lt;br /&gt;
 &lt;br /&gt;
This function is the core part of the ISOdate template. &lt;br /&gt;
 &lt;br /&gt;
Usage:&lt;br /&gt;
  local Date = require(&#039;Module:DateI18n&#039;)._Date&lt;br /&gt;
  local dateStr = Date({2020, 12, 30, 12, 20, 11}, lang)&lt;br /&gt;
 &lt;br /&gt;
Parameters:&lt;br /&gt;
  * {year,month,day,hour,minute,second, tzhour, tzmin}: broken down date-time component strings or numbers&lt;br /&gt;
		tzhour, tzmin are timezone offsets from UTC, hours and minutes&lt;br /&gt;
  * lang: The language to display it in&lt;br /&gt;
  * case: Language format (genitive, etc.) for some languages&lt;br /&gt;
  * class: CSS class for the &amp;lt;time&amp;gt; node, use &amp;quot;&amp;quot; for no metadata at all&lt;br /&gt;
]]&lt;br /&gt;
function p._Date(datevec, lang, case, class, trim_year)&lt;br /&gt;
	-- make sure inputs are in the right format&lt;br /&gt;
	&lt;br /&gt;
	-- set language&lt;br /&gt;
	if not isValidLangCode(lang) then&lt;br /&gt;
		-- get user&#039;s chosen language&lt;br /&gt;
		-- equivalent to {{int:lang}}&lt;br /&gt;
		lang = mw.getCurrentFrame():callParserFunction(&amp;quot;int&amp;quot;, &amp;quot;lang&amp;quot;)&lt;br /&gt;
		&lt;br /&gt;
		if not isValidLangCode(lang) then&lt;br /&gt;
			-- if that doesn&#039;t work, use the project language&lt;br /&gt;
			-- this is useful on projects which import this module from Commons&lt;br /&gt;
			lang = mw.language.getContentLanguage().code&lt;br /&gt;
			&lt;br /&gt;
			if not isValidLangCode(lang) then&lt;br /&gt;
				-- if that doesn&#039;t work, use English&lt;br /&gt;
				lang = &amp;quot;en&amp;quot;&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if lang == &#039;be-tarask&#039; then&lt;br /&gt;
		lang = &#039;be-x-old&#039;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- process datevec and extract timeStamp and datecode strings as well as numeric datenum array&lt;br /&gt;
	local datenum  = p.clean_datevec(datevec)&lt;br /&gt;
	local year, month, day = datenum[1], datenum[2], datenum[3]&lt;br /&gt;
	local timeStamp, datecode = p.getTimestamp(datenum)&lt;br /&gt;
	if not timeStamp then -- something went wrong in parserDatevec&lt;br /&gt;
		return &#039;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	-- Commons [[Data:DateI18n.tab]] page stores prefered formats for diferent &lt;br /&gt;
	-- languages and datecodes (specifying year-month-day or just year of month-day, etc)&lt;br /&gt;
	-- Look up country specific format input to {{#time}} function&lt;br /&gt;
	local dFormat = getDateFormat(datecode, day, lang)&lt;br /&gt;
&lt;br /&gt;
	-- By default the gramatical case is not specified (case==&#039;&#039;) allowing the format to be specified &lt;br /&gt;
	-- in [[Data:DateI18n.tab]]. You can overwrite the default grammatical case of the month by &lt;br /&gt;
	-- specifying &amp;quot;case&amp;quot; variable. This is needed mostly by Slavic languages to create more complex &lt;br /&gt;
	-- phrases as it is done in [[c:Module:Complex date]]&lt;br /&gt;
	case = case or &#039;&#039;&lt;br /&gt;
	if (lang==&#039;qu&#039; or lang==&#039;qug&#039;) and case==&#039;nom&#039; then&lt;br /&gt;
		-- Special case related to Quechua and Kichwa languages. The form in the I18n is&lt;br /&gt;
		--  Genitive case with suffix &amp;quot;pi&amp;quot; added to month names provided by {#time}}&lt;br /&gt;
		-- in Nominative case that &amp;quot;pi&amp;quot; should be removed&lt;br /&gt;
		-- see https://commons.wikimedia.org/wiki/Template_talk:Date#Quechua from 2014&lt;br /&gt;
		dFormat = dFormat:gsub(&#039;F&amp;quot;pi&amp;quot;&#039;, &#039;F&#039;)&lt;br /&gt;
	elseif case == &#039;gen&#039; then&lt;br /&gt;
		dFormat = p.strReplace(dFormat, &amp;quot;F&amp;quot;, &amp;quot;xg&amp;quot;)&lt;br /&gt;
	elseif case == &#039;nom&#039; then&lt;br /&gt;
		dFormat = p.strReplace(dFormat, &amp;quot;xg&amp;quot;, &amp;quot;F&amp;quot;)&lt;br /&gt;
	elseif case ~= &#039;&#039; and month ~= nil then&lt;br /&gt;
		-- see is page [[Data:I18n/MonthCases.tab]] on Commons have name of the month &lt;br /&gt;
		-- in specific gramatic case in desired language. If we have it than replace &lt;br /&gt;
		-- &amp;quot;F&amp;quot; and xg&amp;quot; in dFormat&lt;br /&gt;
		local monthMsg = MonthCase(month, case, lang)&lt;br /&gt;
		if  monthMsg and monthMsg ~= &#039;&#039; then -- make sure it exists&lt;br /&gt;
			dFormat = p.strReplace(dFormat, &#039;F&#039;,  &#039;&amp;quot;&#039;..monthMsg..&#039;&amp;quot;&#039;) -- replace default month with month name we already looked up&lt;br /&gt;
			dFormat = p.strReplace(dFormat, &#039;xg&#039;, &#039;&amp;quot;&#039;..monthMsg..&#039;&amp;quot;&#039;)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
    -- Translate the date using specified format.&lt;br /&gt;
	-- See https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#mw.language:formatDate and &lt;br /&gt;
	-- https://www.mediawiki.org/wiki/Help:Extension:ParserFunctions##time for explanation of the format&lt;br /&gt;
	local langObj = mw.language.new(lang)&lt;br /&gt;
	local datestr = langObj:formatDate(dFormat, timeStamp) -- same as using {{#time}} parser function&lt;br /&gt;
	&lt;br /&gt;
	-- Special case related to Thai solar calendar: prior to 1940 new-year was at different time of year,&lt;br /&gt;
	-- so just year (datecode == &#039;Y&#039;) is ambiguous and is replaced by &amp;quot;YYYY or YYYY&amp;quot; phrase&lt;br /&gt;
	if lang==&#039;th&#039; and datecode==&#039;Y&#039; and year&amp;lt;=1940 then&lt;br /&gt;
		datestr = string.format(&#039;%04i หรือ %04i&#039;, year+542, year+543 ) &lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- If year &amp;lt; 1000 than either keep the date padded to the length of 4 digits or trim it.&lt;br /&gt;
	-- Decide if the year will stay padded with zeros (for years in 0-999 range).&lt;br /&gt;
	if year and year &amp;lt; 1000 then&lt;br /&gt;
		trim_year = yesno(trim_year, trim_year or &#039;100-999&#039;)&lt;br /&gt;
		if type(trim_year) == &#039;string&#039; then&lt;br /&gt;
			-- If `trim_year` not a simple boolean, then it&#039;s a range of dates.&lt;br /&gt;
			-- For example &#039;100-999&#039; means to pad 1-or-2-digit years to be 4-digit long, while keeping 3-digit years as is.&lt;br /&gt;
			local YMin, YMax = trim_year:match( &#039;(%d+)-(%d+)&#039; )&lt;br /&gt;
			trim_year = YMin and year &amp;gt;= tonumber(YMin) and year &amp;lt;= tonumber(YMax)&lt;br /&gt;
		end&lt;br /&gt;
		if trim_year then&lt;br /&gt;
			datestr = trimYear(datestr, year, lang) -- in datestr replace long year with trimmed one&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Append a timezone if present (after the hour and minute of the day).&lt;br /&gt;
	if datenum[7] and (datecode:sub(1, 5) == &#039;YMDhm&#039; or datecode:sub(1, 4) == &#039;MDhm&#039;) then&lt;br /&gt;
		-- Use {{#time}} parser function to create timezone string, so that we use the correct character set.&lt;br /&gt;
		local sign = (datenum[7]&amp;lt;0) and &#039;−&#039; or &#039;+&#039;&lt;br /&gt;
		timeStamp = string.format(&amp;quot;2000-01-01 %02i:%02i:00&amp;quot;, math.abs(datenum[7]), datenum[8] or 0)&lt;br /&gt;
		local timezone = langObj:formatDate(&#039;H:i&#039;, timeStamp) -- same as using {{#time}} parser function&lt;br /&gt;
		datestr = string.format(&amp;quot;%s %s%s&amp;quot;, datestr, sign, timezone )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- HTML formating of date string and tagging for microformats (only for absolute dates with a year).&lt;br /&gt;
	if class and class ~= &#039;&#039; and class ~= &#039;-&#039; and datecode:sub(1,1) == &#039;Y&#039; then &lt;br /&gt;
		local pat = &#039;&amp;lt;time class=&amp;quot;%s&amp;quot; datetime=&amp;quot;%s&amp;quot; lang=&amp;quot;%s&amp;quot; dir=&amp;quot;%s&amp;quot; style=&amp;quot;white-space:nowrap&amp;quot;&amp;gt;%s&amp;lt;/time&amp;gt;&#039;&lt;br /&gt;
		datestr = pat:format(class, timeStamp, lang, langObj:getDir(), datestr)&lt;br /&gt;
	end&lt;br /&gt;
	return datestr&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- ===========================================================================&lt;br /&gt;
-- === Version of the function to be called from template namespace&lt;br /&gt;
-- ===========================================================================&lt;br /&gt;
&lt;br /&gt;
--[[ ========================================================================================&lt;br /&gt;
Date&lt;br /&gt;
 &lt;br /&gt;
This function is the core part of the ISOdate template. &lt;br /&gt;
 &lt;br /&gt;
Usage:&lt;br /&gt;
{{#invoke:DateI18n|Date|year=|month=|day=|hour=|minute=|second=|tzhour=|tzmin=|lang=en}}&lt;br /&gt;
 &lt;br /&gt;
Parameters:&lt;br /&gt;
  * year, month, day, hour, minute, second: broken down date-time component strings&lt;br /&gt;
  * tzhour, tzmin: timezone offset from UTC, hours and minutes&lt;br /&gt;
  * lang: The language to display it in&lt;br /&gt;
  * case: Language format (genitive, etc.) for some languages&lt;br /&gt;
  * class: CSS class for the &amp;lt;time&amp;gt; node, use &amp;quot;&amp;quot; for no metadata at all&lt;br /&gt;
]]&lt;br /&gt;
function p.Date(frame)&lt;br /&gt;
	-- get args&lt;br /&gt;
	local args = {}&lt;br /&gt;
	for key, value in pairs(frame.args) do &lt;br /&gt;
		local trimmed_key = string.gsub(string.lower(mw.text.trim(key)), &#039; &#039;, &#039;_&#039;)&lt;br /&gt;
		local trimmed_value = mw.text.trim(value)&lt;br /&gt;
		if trimmed_key ~= &#039;class&#039; and trimmed_value == &#039;&#039; then&lt;br /&gt;
			trimmed_value = nil&lt;br /&gt;
		end&lt;br /&gt;
		args[trimmed_key] = trimmed_value&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- default values&lt;br /&gt;
	-- Allows to set the html class of the time node where the date is included. This is useful for microformats.&lt;br /&gt;
	args.class = args.class or &#039;-&#039;&lt;br /&gt;
	if args.class == &#039;&#039; then&lt;br /&gt;
		args.class = &#039;dtstart&#039;&lt;br /&gt;
	end&lt;br /&gt;
	-- By default, pad one- and two-digit years to be 4 digits long, while keeping three-digit years as-is.&lt;br /&gt;
	args.trim_year = args.trim_year or &#039;100-999&#039;&lt;br /&gt;
	&lt;br /&gt;
	return p._Date(	&lt;br /&gt;
		{args.year, args.month, args.day, args.hour, args.minute, args.second, args.tzhour, args.tzmin},&lt;br /&gt;
		args.lang,&lt;br /&gt;
		args.case,	&lt;br /&gt;
		args.class,&lt;br /&gt;
		args.trim_year&lt;br /&gt;
	)	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=Module:DateI18n/sandbox2&amp;diff=3962</id>
		<title>Module:DateI18n/sandbox2</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=Module:DateI18n/sandbox2&amp;diff=3962"/>
		<updated>2026-09-25T08:47:45Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: Created page with &amp;quot;--[[     __  __           _       _        ____        _       ___ _  ___          |  \/  | ___   __| |_   _| | ___ _|  _ \  __ _| |_ ___|_ _/ |( _ ) _ __    | |\/| |/ _ \ / _` | | | | |/ _ (_) | | |/ _` | __/ _ \| || |/ _ \| &amp;#039;_ \   | |  | | (_) | (_| | |_| | |  __/_| |_| | (_| | ||  __/| || | (_) | | | |  |_|  |_|\___/ \__,_|\__,_|_|\___(_)____/ \__,_|\__\___|___|_|\___/|_| |_|    This module is intended for processing of date strings.  Please do not modify this code wi...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;--[[  &lt;br /&gt;
  __  __           _       _        ____        _       ___ _  ___        &lt;br /&gt;
 |  \/  | ___   __| |_   _| | ___ _|  _ \  __ _| |_ ___|_ _/ |( _ ) _ __  &lt;br /&gt;
 | |\/| |/ _ \ / _` | | | | |/ _ (_) | | |/ _` | __/ _ \| || |/ _ \| &#039;_ \ &lt;br /&gt;
 | |  | | (_) | (_| | |_| | |  __/_| |_| | (_| | ||  __/| || | (_) | | | |&lt;br /&gt;
 |_|  |_|\___/ \__,_|\__,_|_|\___(_)____/ \__,_|\__\___|___|_|\___/|_| |_|&lt;br /&gt;
  &lt;br /&gt;
This module is intended for processing of date strings.&lt;br /&gt;
&lt;br /&gt;
Please do not modify this code without applying the changes first at Module:Date/sandbox and testing &lt;br /&gt;
at Module:Date/sandbox/testcases and Module talk:Date/sandbox/testcases.&lt;br /&gt;
&lt;br /&gt;
Authors and maintainers:&lt;br /&gt;
* User:Parent5446 - original version of the function mimicking template:ISOdate&lt;br /&gt;
* User:Jarekt - original version of the functions mimicking template:Date &lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
-- =======================================&lt;br /&gt;
-- === Dependencies ======================&lt;br /&gt;
-- =======================================&lt;br /&gt;
&lt;br /&gt;
require(&#039;strict&#039;)&lt;br /&gt;
&lt;br /&gt;
-- =======================================&lt;br /&gt;
-- === Local Functions ===================&lt;br /&gt;
-- =======================================&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------&lt;br /&gt;
--[[ (copied from Module:Core)&lt;br /&gt;
Function allowing for consistent treatment of boolean-like wikitext input.&lt;br /&gt;
Inputs:&lt;br /&gt;
  1) val - value to be evaluated, outputs as a function of values:&lt;br /&gt;
		true  : true  (boolean), 1 (number), or strings: &amp;quot;yes&amp;quot;, &amp;quot;y&amp;quot;, &amp;quot;true&amp;quot;, &amp;quot;1&amp;quot;&lt;br /&gt;
		false : false (boolean), 0 (number), or strings: &amp;quot;no&amp;quot;, &amp;quot;n&amp;quot;, &amp;quot;false&amp;quot;, &amp;quot;0&amp;quot;&lt;br /&gt;
  2) default - value to return otherwise&lt;br /&gt;
See Also: It works similarly to Module:Yesno&lt;br /&gt;
]]&lt;br /&gt;
local function yesno(val, default)&lt;br /&gt;
	if type(val) == &#039;boolean&#039; then&lt;br /&gt;
		return val&lt;br /&gt;
	elseif type(val) == &#039;number&#039; then&lt;br /&gt;
		val = tostring(val)&lt;br /&gt;
	end&lt;br /&gt;
	if type(val) == &#039;string&#039; then&lt;br /&gt;
		local LUT = {&lt;br /&gt;
			yes=true , y=true , [&#039;true&#039;] =true , t=true , [&#039;1&#039;]=true , on =true,&lt;br /&gt;
			no =false, n=false, [&#039;false&#039;]=false, f=false, [&#039;0&#039;]=false, off=false }&lt;br /&gt;
	    val = LUT[mw.ustring.lower(val)]  -- put in lower case&lt;br /&gt;
	    if (val~=nil) then&lt;br /&gt;
			return val&lt;br /&gt;
		end&lt;br /&gt;
    end&lt;br /&gt;
    return default&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
---------------------------------------------------------------------------------------&lt;br /&gt;
-- trim leading zeros in years prior to year 1000&lt;br /&gt;
-- INPUT:&lt;br /&gt;
--  * datestr   - translated date string &lt;br /&gt;
--  * lang      - language of translation&lt;br /&gt;
-- OUTPUT:&lt;br /&gt;
--  * datestr - updated date string &lt;br /&gt;
&lt;br /&gt;
local function trimYear(datestr, year, lang)&lt;br /&gt;
	local yearStr0, yearStr1, yearStr2, zeroStr&lt;br /&gt;
	yearStr0 = string.format(&#039;%04i&#039;, year ) -- 4 digit year in standard form &amp;quot;0123&amp;quot;&lt;br /&gt;
	yearStr1 = mw.language.new(lang):formatDate( &#039;Y&#039;, yearStr0) -- same as calling {{#time}} parser function&lt;br /&gt;
	--yearStr1 = mw.getCurrentFrame():callParserFunction( &amp;quot;#time&amp;quot;, { &#039;Y&#039;, yearStr0, lang } ) -- translate to a language &lt;br /&gt;
	if yearStr0==yearStr1 then -- most of languages use standard form of year &lt;br /&gt;
		yearStr2 = tostring(year)&lt;br /&gt;
	else -- some languages use different characters for numbers&lt;br /&gt;
		yearStr2 = yearStr1&lt;br /&gt;
		zeroStr = mw.ustring.sub(yearStr1,1,1) -- get &amp;quot;0&amp;quot; in whatever language&lt;br /&gt;
		for i=1,3 do -- trim leading zeros&lt;br /&gt;
			if mw.ustring.sub(yearStr2,1,1)==zeroStr then&lt;br /&gt;
				yearStr2 = mw.ustring.sub(yearStr2, 2, 5-i)&lt;br /&gt;
			else&lt;br /&gt;
				break&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return string.gsub(datestr, yearStr1, yearStr2 ) -- in datestr replace long year with trimmed one&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---------------------------------------------------------------------------------------&lt;br /&gt;
-- Look up proper format string to be passed to {{#time}} parser function&lt;br /&gt;
-- INPUTS:&lt;br /&gt;
--  * datecode: YMDhms, YMDhm, YMD, YM, Y, MDhms, MDhm, MD, or M&lt;br /&gt;
--  * day     : Number between 1 and 31 (not needed for most languages)&lt;br /&gt;
--  * lang    : language&lt;br /&gt;
-- OUTPUT:&lt;br /&gt;
--  * dFormat : input to {{#time}} function&lt;br /&gt;
local function getDateFormat(datecode, day, lang)&lt;br /&gt;
	local function parseFormat(dFormat, day)&lt;br /&gt;
		if dFormat:find(&#039;default&#039;) and #dFormat&amp;gt;10 then&lt;br /&gt;
			-- Special (and messy) case of dFormat code depending on a day number, where data is a&lt;br /&gt;
			-- JSON-encoded table {”default”:”*”,”dDD”:”*”} including fields for specific 2-digit days.&lt;br /&gt;
			-- Change curly double quotes (possibly used for easier editing in tabular data) in dFormat&lt;br /&gt;
			-- to straight ASCII double quotes (required for parsing of this JSON-encoded table).&lt;br /&gt;
			local D = mw.text.jsonDecode(mw.ustring.gsub(dFormat, &#039;[„“‟”]&#039;, &#039;&amp;quot;&#039;)) --com = mw.dumpObject(D)&lt;br /&gt;
			-- If the desired day is not in that JSON table, then use its &amp;quot;default&amp;quot; case.&lt;br /&gt;
			dFormat = D[string.format(&#039;d%02i&#039;, day)] or D.default&lt;br /&gt;
            -- Change ASCII single quotes to ASCII double quotes used for {{#time}} marking.&lt;br /&gt;
            -- Apostrophes needed in plain-text must not use ASCII single quotes but curly apostrophe&lt;br /&gt;
            -- e.g. { ‟default”: ‟j”, ‟d01”: ‟j’&#039;o&#039;” }, not { ‟default”: ‟j”, ‟d01”: ‟j&#039;&#039;o&#039;” }.&lt;br /&gt;
		end&lt;br /&gt;
		dFormat = dFormat:gsub(&amp;quot;&#039;&amp;quot;, &#039;&amp;quot;&#039;)&lt;br /&gt;
		return dFormat&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local T = {}&lt;br /&gt;
	local tab = mw.ext.data.get(&#039;DateI18n.tab&#039;, lang)&lt;br /&gt;
	for _, row in pairs(tab.data) do -- convert the output into a dictionary table&lt;br /&gt;
		local id, _, msg = unpack(row)&lt;br /&gt;
		T[id] = msg&lt;br /&gt;
	end&lt;br /&gt;
    -- Compatibility of legacy data using &#039;HMS&#039; or &#039;HM&#039;, where &#039;M&#039; is ambiguous&lt;br /&gt;
    T.YMDhms = T.YMDhms or T.YMDHMS&lt;br /&gt;
    T.YMDhm  = T.YMDhm  or T.YMDHM&lt;br /&gt;
    datecode = datecode == &#039;YMDHMS&#039; and &#039;YMDhms&#039; or datecode == &#039;YMDHM&#039; and &#039;YMDhm&#039; or datecode&lt;br /&gt;
&lt;br /&gt;
	local dFormat = T[datecode]&lt;br /&gt;
	if dFormat == &#039;default&#039; and (datecode == &#039;YMDhms&#039; or datecode == &#039;YMDhm&#039;)  then &lt;br /&gt;
		-- For most languages adding hour:minute:second is done by adding &amp;quot;, HH:ii:ss to the &lt;br /&gt;
		-- day precission date, those languages are skipped in DateI18n.tab and default to &lt;br /&gt;
		-- English which stores word &amp;quot;default&amp;quot;&lt;br /&gt;
		dFormat = parseFormat(T[&#039;YMD&#039;], day).. &#039;, H:i&#039;&lt;br /&gt;
		if datecode == &#039;YMDhms&#039; then&lt;br /&gt;
			dFormat = dFormat .. &#039;:s&#039;&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		dFormat = parseFormat(dFormat, day)&lt;br /&gt;
	end&lt;br /&gt;
	return dFormat&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---------------------------------------------------------------------------------------&lt;br /&gt;
-- Look up proper format string to be passed to {{#time}} parser function&lt;br /&gt;
-- INPUTS:&lt;br /&gt;
--  * month : month number&lt;br /&gt;
--  * case  : gramatic case abbriviation, like &amp;quot;ins&amp;quot;, &amp;quot;loc&amp;quot;&lt;br /&gt;
--  * lang  : language&lt;br /&gt;
-- OUTPUT:&lt;br /&gt;
--  * dFormat : input to {{#time}} function&lt;br /&gt;
local function MonthCase(month, case, lang)&lt;br /&gt;
	if month == nil or case == nil then&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
	local T = {{},{},{},{},{},{},{},{},{},{},{},{}}&lt;br /&gt;
	local tab = mw.ext.data.get(&#039;I18n/MonthCases.tab&#039;, lang)&lt;br /&gt;
	for _, row in pairs(tab.data) do&lt;br /&gt;
		local mth, cs, msg = unpack(row)&lt;br /&gt;
		T[mth][cs] = msg&lt;br /&gt;
	end&lt;br /&gt;
	return T[month][case]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- ==================================================&lt;br /&gt;
-- === External functions ===========================&lt;br /&gt;
-- ==================================================&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
-- ===========================================================================&lt;br /&gt;
-- === Functions accesible from the outside to allow unit-testing&lt;br /&gt;
-- === Please do not use directly as they could change in the future&lt;br /&gt;
-- ===========================================================================&lt;br /&gt;
&lt;br /&gt;
---------------------------------------------------------------------------------------&lt;br /&gt;
-- Single string replacement that ignores part of the string in &amp;quot;...&amp;quot;&lt;br /&gt;
function p.strReplace(String, old, new)&lt;br /&gt;
	if String:find(&#039;&amp;quot;&#039;) then&lt;br /&gt;
		local T={}&lt;br /&gt;
		for i, str in ipairs(mw.text.split( String, &#039;&amp;quot;&#039;, true )) do&lt;br /&gt;
			if i%2==1 then&lt;br /&gt;
				str = str:gsub(old, new, 1)&lt;br /&gt;
			end&lt;br /&gt;
			table.insert(T, str)&lt;br /&gt;
		end&lt;br /&gt;
		return table.concat(T,&#039;&amp;quot;&#039;)&lt;br /&gt;
	else&lt;br /&gt;
		return String:gsub(old, new, 1)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---------------------------------------------------------------------------------------&lt;br /&gt;
-- process datevec&lt;br /&gt;
-- INPUT:&lt;br /&gt;
--  * datevec - Array of {year,month,day,hour,minute,second, tzhour, tzmin} containing broken &lt;br /&gt;
--    down date-time component strings or numbers&lt;br /&gt;
-- OUTPUT:&lt;br /&gt;
--  * datenum - same array but holding only numbers or nuls&lt;br /&gt;
function p.clean_datevec(datevec)&lt;br /&gt;
	-- create datecode based on which variables are provided and check for out-of-bound values&lt;br /&gt;
	&lt;br /&gt;
	-- check special case of month provided as a name&lt;br /&gt;
	local month = datevec[2]&lt;br /&gt;
	if type(month) == &#039;string&#039; and month ~= &#039;&#039; and not tonumber(month) then&lt;br /&gt;
		-- When the month is not a number, check if it&#039;s a month name in the project&#039;s language.&lt;br /&gt;
		datevec[2] = mw.getContentLanguage():formatDate(&#039;n&#039;, month)&lt;br /&gt;
	end&lt;br /&gt;
		&lt;br /&gt;
	-- check bounds&lt;br /&gt;
	local maxval = {  1/0, 12, 31, 23, 59, 59,  23, 59 } -- max values (or  1/0=+inf) for year, month, day, hour, minute, second, tzhour, tzmin&lt;br /&gt;
	local minval = { -1/0, 01, 01, 00, 00, 00, -23, 00 } -- min values (or -1/0=-inf) for year, month, ...&lt;br /&gt;
	local datenum  = {} -- date-time encoded as a vector = [year, month, ... , second, tzhour, tzmin]&lt;br /&gt;
	for i = 1, 8 do&lt;br /&gt;
        local val = tonumber(datevec[i])&lt;br /&gt;
        if val and val &amp;gt;= minval[i] and val &amp;lt;= maxval[i] then -- These tests work with infinite min/max values.&lt;br /&gt;
		    datenum[i] = val&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- leap second&lt;br /&gt;
	if tonumber(datevec[6]) == 60 then -- leap second &#039;60&#039; is valid only at end of 23:59 UTC, on 30 June or 31 December of specific years&lt;br /&gt;
--		datenum[6] = 60 &lt;br /&gt;
		local MDhm = table.concat({unpack(datenum,2,5)}, &#039;,&#039;)&lt;br /&gt;
	    if (MDhm == table.concat({6, 30, 23, 59}, &#039;,&#039;)) or (MDhm == table.concat({12, 31, 23, 59}, &#039;,&#039;)) then&lt;br /&gt;
		   datenum[6] = 60 &lt;br /&gt;
	    end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return datenum&lt;br /&gt;
end&lt;br /&gt;
	&lt;br /&gt;
---------------------------------------------------------------------------------------&lt;br /&gt;
-- process datevec&lt;br /&gt;
-- INPUT:&lt;br /&gt;
--  * datenum - Array of {year,month,day,hour,minute,second, tzhour, tzmin} as numbers or nuls&lt;br /&gt;
-- OUTPUT:&lt;br /&gt;
--  * timeStamp - date string in the format taken by mw.language:formatDate lua function and {{#time}} parser function&lt;br /&gt;
--       https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#mw.language:formatDate&lt;br /&gt;
--       https://www.mediawiki.org/wiki/Help:Extension:ParserFunctions#.23time&lt;br /&gt;
--  * datecode - a code specifying content of the array where Y&#039; is year, &#039;M&#039; is month,&lt;br /&gt;
--     &#039;D&#039; is day, &#039;h&#039; is hour, &#039;m&#039; minute, &#039;s&#039; is second.&lt;br /&gt;
--     Output has to be one of YMDhms, YMDhm, YMD, YM, Y, MDhms, MDhm, MD, M.&lt;br /&gt;
function p.getTimestamp(datenum)&lt;br /&gt;
&lt;br /&gt;
	-- create datecode based on datenum&lt;br /&gt;
	local codes  = { &#039;Y&#039;, &#039;M&#039;, &#039;D&#039;, &#039;h&#039;, &#039;m&#039;, &#039;s&#039;} &lt;br /&gt;
	local datecode = &#039;&#039; -- a string signifying which combination of variables was provided&lt;br /&gt;
	for i, c in ipairs(codes) do&lt;br /&gt;
		datecode = datecode .. (datenum[i] and c or &#039;&#039;) -- if datenum[i] than append codes[i] to datecode&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- create timestamp string (for example 2000-02-20 02:20:20) based on which variables were provided&lt;br /&gt;
	local timeStamp&lt;br /&gt;
    -- date starting by a year&lt;br /&gt;
	if datecode == &#039;YMDhms&#039; then&lt;br /&gt;
		timeStamp = string.format(&#039;%04i-%02i-%02i %02i:%02i:%02i&#039;, datenum[1], datenum[2], datenum[3], datenum[4], datenum[5], datenum[6] )&lt;br /&gt;
	elseif datecode == &#039;YMDhm&#039; then&lt;br /&gt;
		timeStamp = string.format(&#039;%04i-%02i-%02i %02i:%02i&#039;, datenum[1], datenum[2], datenum[3], datenum[4], datenum[5] )&lt;br /&gt;
	elseif datecode:sub(1,3)==&#039;YMD&#039; then&lt;br /&gt;
		timeStamp = string.format(&#039;%04i-%02i-%02i&#039;, datenum[1], datenum[2], datenum[3] )&lt;br /&gt;
		datecode  = &#039;YMD&#039; -- &#039;YMDhms&#039;, &#039;YMDhm&#039; and &#039;YMD&#039; are the only supported format starting with &#039;YMD&#039;; all others will be converted to &#039;YMD&#039;.&lt;br /&gt;
	elseif datecode:sub(1,2) == &#039;YM&#039; then&lt;br /&gt;
		timeStamp = string.format(&#039;%04i-%02i&#039;, datenum[1], datenum[2] )&lt;br /&gt;
		datecode  = &#039;YM&#039; &lt;br /&gt;
	elseif datecode:sub(1,1)==&#039;Y&#039; then&lt;br /&gt;
		timeStamp = string.format(&#039;%04i&#039;, datenum[1] )&lt;br /&gt;
		datecode  = &#039;Y&#039; &lt;br /&gt;
    -- date starting by a month (the implied year is 2000)&lt;br /&gt;
	elseif datecode== &#039;MDhms&#039; then&lt;br /&gt;
		timeStamp = string.format(&#039;%04i-%02i-%02i %02i:%02i:%02i&#039;, 2000, datenum[2], datenum[3], datenum[4], datenum[5], datenum[6] )&lt;br /&gt;
	elseif datecode == &#039;MDhm&#039; then&lt;br /&gt;
		timeStamp = string.format(&#039;%04i-%02i-%02i %02i:%02i&#039;, 2000, datenum[2], datenum[3], datenum[4], datenum[5] )&lt;br /&gt;
	elseif datecode:sub(1,2) == &#039;MD&#039; then&lt;br /&gt;
		timeStamp = string.format(&#039;%04i-%02i-%02i&#039;, 2000, datenum[2], datenum[3] )&lt;br /&gt;
		datecode = &#039;MD&#039; -- &#039;MDhms&#039;, &#039;MDhm&#039; and &#039;MD&#039; are the only supported format starting with &#039;MD&#039;; all others will be converted to &#039;MD&#039;&lt;br /&gt;
	elseif datecode:sub(1,1) == &#039;M&#039; then -- Ambiguous: could mean minutes, but here means month (when parsed as a name/abbrev, not as a number).&lt;br /&gt;
		timeStamp = string.format(&#039;%04i-%02i-%02i&#039;, 2000, datenum[2], 1 )&lt;br /&gt;
		datecode  = &#039;M&#039; &lt;br /&gt;
    -- other possible but unrecognized formats (e.g. &#039;DHis&#039;, &#039;DHi&#039;, &#039;D&#039;, &#039;His&#039;, &#039;Hi&#039;);&lt;br /&gt;
    -- note that &#039;Dh&#039;, &#039;D&#039;, &#039;h&#039;, &#039;s&#039; may eventually work, but not &#039;m&#039; for minute only, which is ambiguous with &#039;M&#039; for month only.&lt;br /&gt;
	else&lt;br /&gt;
		timeStamp = nil -- format not supported&lt;br /&gt;
	end&lt;br /&gt;
	return timeStamp, datecode&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- ===========================================================================&lt;br /&gt;
-- === Version of the function to be called from other LUA codes&lt;br /&gt;
-- ===========================================================================&lt;br /&gt;
&lt;br /&gt;
--[[ ========================================================================================&lt;br /&gt;
Date&lt;br /&gt;
 &lt;br /&gt;
This function is the core part of the ISOdate template. &lt;br /&gt;
 &lt;br /&gt;
Usage:&lt;br /&gt;
  local Date = require(&#039;Module:DateI18n&#039;)._Date&lt;br /&gt;
  local dateStr = Date({2020, 12, 30, 12, 20, 11}, lang)&lt;br /&gt;
 &lt;br /&gt;
Parameters:&lt;br /&gt;
  * {year,month,day,hour,minute,second, tzhour, tzmin}: broken down date-time component strings or numbers&lt;br /&gt;
		tzhour, tzmin are timezone offsets from UTC, hours and minutes&lt;br /&gt;
  * lang: The language to display it in&lt;br /&gt;
  * case: Language format (genitive, etc.) for some languages&lt;br /&gt;
  * class: CSS class for the &amp;lt;time&amp;gt; node, use &amp;quot;&amp;quot; for no metadata at all&lt;br /&gt;
]]&lt;br /&gt;
function p._Date(datevec, lang, case, class, trim_year)	&lt;br /&gt;
	-- make sure inputs are in the right format&lt;br /&gt;
	if not lang or not mw.language.isValidCode( lang ) then&lt;br /&gt;
		lang = mw.getCurrentFrame():callParserFunction( &amp;quot;int&amp;quot;, &amp;quot;lang&amp;quot; ) -- get user&#039;s chosen language&lt;br /&gt;
	end&lt;br /&gt;
	if lang == &#039;be-tarask&#039; then&lt;br /&gt;
		lang = &#039;be-x-old&#039;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- process datevec and extract timeStamp and datecode strings as well as numeric datenum array&lt;br /&gt;
	local datenum  = p.clean_datevec(datevec)&lt;br /&gt;
	local year, month, day = datenum[1], datenum[2], datenum[3]&lt;br /&gt;
	local timeStamp, datecode = p.getTimestamp(datenum)&lt;br /&gt;
	if not timeStamp then -- something went wrong in parserDatevec&lt;br /&gt;
		return &#039;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	-- Commons [[Data:DateI18n.tab]] page stores prefered formats for diferent &lt;br /&gt;
	-- languages and datecodes (specifying year-month-day or just year of month-day, etc)&lt;br /&gt;
	-- Look up country specific format input to {{#time}} function&lt;br /&gt;
	local dFormat = getDateFormat(datecode, day, lang)&lt;br /&gt;
&lt;br /&gt;
	-- By default the gramatical case is not specified (case==&#039;&#039;) allowing the format to be specified &lt;br /&gt;
	-- in [[Data:DateI18n.tab]]. You can overwrite the default grammatical case of the month by &lt;br /&gt;
	-- specifying &amp;quot;case&amp;quot; variable. This is needed mostly by Slavic languages to create more complex &lt;br /&gt;
	-- phrases as it is done in [[c:Module:Complex date]]&lt;br /&gt;
	case = case or &#039;&#039;&lt;br /&gt;
	if (lang==&#039;qu&#039; or lang==&#039;qug&#039;) and case==&#039;nom&#039; then&lt;br /&gt;
		-- Special case related to Quechua and Kichwa languages. The form in the I18n is&lt;br /&gt;
		--  Genitive case with suffix &amp;quot;pi&amp;quot; added to month names provided by {#time}}&lt;br /&gt;
		-- in Nominative case that &amp;quot;pi&amp;quot; should be removed&lt;br /&gt;
		-- see https://commons.wikimedia.org/wiki/Template_talk:Date#Quechua from 2014&lt;br /&gt;
		dFormat = dFormat:gsub(&#039;F&amp;quot;pi&amp;quot;&#039;, &#039;F&#039;)&lt;br /&gt;
	elseif case == &#039;gen&#039; then&lt;br /&gt;
		dFormat = p.strReplace(dFormat, &amp;quot;F&amp;quot;, &amp;quot;xg&amp;quot;)&lt;br /&gt;
	elseif case == &#039;nom&#039; then&lt;br /&gt;
		dFormat = p.strReplace(dFormat, &amp;quot;xg&amp;quot;, &amp;quot;F&amp;quot;)&lt;br /&gt;
	elseif case ~= &#039;&#039; and month ~= nil then&lt;br /&gt;
		-- see is page [[Data:I18n/MonthCases.tab]] on Commons have name of the month &lt;br /&gt;
		-- in specific gramatic case in desired language. If we have it than replace &lt;br /&gt;
		-- &amp;quot;F&amp;quot; and xg&amp;quot; in dFormat&lt;br /&gt;
		local monthMsg = MonthCase(month, case, lang)&lt;br /&gt;
		if  monthMsg and monthMsg ~= &#039;&#039; then -- make sure it exists&lt;br /&gt;
			dFormat = p.strReplace(dFormat, &#039;F&#039;,  &#039;&amp;quot;&#039;..monthMsg..&#039;&amp;quot;&#039;) -- replace default month with month name we already looked up&lt;br /&gt;
			dFormat = p.strReplace(dFormat, &#039;xg&#039;, &#039;&amp;quot;&#039;..monthMsg..&#039;&amp;quot;&#039;)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
    -- Translate the date using specified format.&lt;br /&gt;
	-- See https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#mw.language:formatDate and &lt;br /&gt;
	-- https://www.mediawiki.org/wiki/Help:Extension:ParserFunctions##time for explanation of the format&lt;br /&gt;
	local langObj = mw.language.new(lang)&lt;br /&gt;
	local datestr = langObj:formatDate(dFormat, timeStamp) -- same as using {{#time}} parser function&lt;br /&gt;
	&lt;br /&gt;
	-- Special case related to Thai solar calendar: prior to 1940 new-year was at different time of year,&lt;br /&gt;
	-- so just year (datecode == &#039;Y&#039;) is ambiguous and is replaced by &amp;quot;YYYY or YYYY&amp;quot; phrase&lt;br /&gt;
	if lang==&#039;th&#039; and datecode==&#039;Y&#039; and year&amp;lt;=1940 then&lt;br /&gt;
		datestr = string.format(&#039;%04i หรือ %04i&#039;, year+542, year+543 ) &lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- If year &amp;lt; 1000 than either keep the date padded to the length of 4 digits or trim it.&lt;br /&gt;
	-- Decide if the year will stay padded with zeros (for years in 0-999 range).&lt;br /&gt;
	if year and year &amp;lt; 1000 then&lt;br /&gt;
		trim_year = yesno(trim_year, trim_year or &#039;100-999&#039;)&lt;br /&gt;
		if type(trim_year) == &#039;string&#039; then&lt;br /&gt;
			-- If `trim_year` not a simple boolean, then it&#039;s a range of dates.&lt;br /&gt;
			-- For example &#039;100-999&#039; means to pad 1-or-2-digit years to be 4-digit long, while keeping 3-digit years as is.&lt;br /&gt;
			local YMin, YMax = trim_year:match( &#039;(%d+)-(%d+)&#039; )&lt;br /&gt;
			trim_year = YMin and year &amp;gt;= tonumber(YMin) and year &amp;lt;= tonumber(YMax)&lt;br /&gt;
		end&lt;br /&gt;
		if trim_year then&lt;br /&gt;
			datestr = trimYear(datestr, year, lang) -- in datestr replace long year with trimmed one&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Append a timezone if present (after the hour and minute of the day).&lt;br /&gt;
	if datenum[7] and (datecode:sub(1, 5) == &#039;YMDhm&#039; or datecode:sub(1, 4) == &#039;MDhm&#039;) then&lt;br /&gt;
		-- Use {{#time}} parser function to create timezone string, so that we use the correct character set.&lt;br /&gt;
		local sign = (datenum[7]&amp;lt;0) and &#039;−&#039; or &#039;+&#039;&lt;br /&gt;
		timeStamp = string.format(&amp;quot;2000-01-01 %02i:%02i:00&amp;quot;, math.abs(datenum[7]), datenum[8] or 0)&lt;br /&gt;
		local timezone = langObj:formatDate(&#039;H:i&#039;, timeStamp) -- same as using {{#time}} parser function&lt;br /&gt;
		datestr = string.format(&amp;quot;%s %s%s&amp;quot;, datestr, sign, timezone )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- HTML formating of date string and tagging for microformats (only for absolute dates with a year).&lt;br /&gt;
	if class and class ~= &#039;&#039; and class ~= &#039;-&#039; and datecode:sub(1,1) == &#039;Y&#039; then &lt;br /&gt;
		local pat = &#039;&amp;lt;time class=&amp;quot;%s&amp;quot; datetime=&amp;quot;%s&amp;quot; lang=&amp;quot;%s&amp;quot; dir=&amp;quot;%s&amp;quot; style=&amp;quot;white-space:nowrap&amp;quot;&amp;gt;%s&amp;lt;/time&amp;gt;&#039;&lt;br /&gt;
		datestr = pat:format(class, timeStamp, lang, langObj:getDir(), datestr)&lt;br /&gt;
	end&lt;br /&gt;
	return datestr&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- ===========================================================================&lt;br /&gt;
-- === Versions of the function to be called from template namespace&lt;br /&gt;
-- ===========================================================================&lt;br /&gt;
&lt;br /&gt;
--[[ ========================================================================================&lt;br /&gt;
Date&lt;br /&gt;
 &lt;br /&gt;
This function is the core part of the ISOdate template. &lt;br /&gt;
 &lt;br /&gt;
Usage:&lt;br /&gt;
{{#invoke:DateI18n|Date|year=|month=|day=|hour=|minute=|second=|tzhour=|tzmin=|lang=en}}&lt;br /&gt;
 &lt;br /&gt;
Parameters:&lt;br /&gt;
  * year, month, day, hour, minute, second: broken down date-time component strings&lt;br /&gt;
  * tzhour, tzmin: timezone offset from UTC, hours and minutes&lt;br /&gt;
  * lang: The language to display it in&lt;br /&gt;
  * case: Language format (genitive, etc.) for some languages&lt;br /&gt;
  * class: CSS class for the &amp;lt;time&amp;gt; node, use &amp;quot;&amp;quot; for no metadata at all&lt;br /&gt;
]]&lt;br /&gt;
function p.Date(frame)&lt;br /&gt;
	local args = {}&lt;br /&gt;
	for name, value in pairs( frame.args ) do &lt;br /&gt;
		name = string.gsub( string.lower(name), &#039; &#039;, &#039;_&#039;)&lt;br /&gt;
		args[name] = value&lt;br /&gt;
	end&lt;br /&gt;
	return p._Date(	&lt;br /&gt;
		{ args.year, args.month, args.day, args.hour, args.minute, args.second, args.tzhour, args.tzmin },&lt;br /&gt;
		args.lang,                  -- language&lt;br /&gt;
		args.case,                  -- allows to specify grammatical case for the month for languages that use them&lt;br /&gt;
		args.class or &#039;dtstart&#039;,    -- allows to set the html class of the time node where the date is included. This is useful for microformats.&lt;br /&gt;
		args.trim_year or &#039;100-999&#039; -- by default pad one and 2 digit years to be 4 digit long, while keeping 3 digit years as is&lt;br /&gt;
	)	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=Module:DateI18n/timef_test&amp;diff=3961</id>
		<title>Module:DateI18n/timef test</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=Module:DateI18n/timef_test&amp;diff=3961"/>
		<updated>2026-09-25T08:47:13Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: Created page with &amp;quot;local p = require(&amp;#039;Module:UnitTests&amp;#039;)  function p:test_1_English_language() 	self:preprocess_equals_preprocess(&amp;#039;{{#invoke:DateI18n|Date|year=2009|month=12|day=09|hour=13|minute=20|lang=en}}&amp;#039;, &amp;#039;{{#timef:2009-12-09T13:20:17|both|en}}&amp;#039;) 	self:preprocess_equals_preprocess(&amp;#039;{{#invoke:DateI18n|Date|year=2009|month=01|day=09|lang=en}}&amp;#039;, &amp;#039;{{#timef:2009-01-09|date|en}}&amp;#039;) 	self:preprocess_equals_preprocess(&amp;#039;{{#invoke:DateI18n|Date|month=12|day=09|lang=en}}&amp;#039;, &amp;#039;{{#timef:2009-12-09|p...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = require(&#039;Module:UnitTests&#039;)&lt;br /&gt;
&lt;br /&gt;
function p:test_1_English_language()&lt;br /&gt;
	self:preprocess_equals_preprocess(&#039;{{#invoke:DateI18n|Date|year=2009|month=12|day=09|hour=13|minute=20|lang=en}}&#039;, &#039;{{#timef:2009-12-09T13:20:17|both|en}}&#039;)&lt;br /&gt;
	self:preprocess_equals_preprocess(&#039;{{#invoke:DateI18n|Date|year=2009|month=01|day=09|lang=en}}&#039;, &#039;{{#timef:2009-01-09|date|en}}&#039;)&lt;br /&gt;
	self:preprocess_equals_preprocess(&#039;{{#invoke:DateI18n|Date|month=12|day=09|lang=en}}&#039;, &#039;{{#timef:2009-12-09|pretty|en}}&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p:test_2_YMD_format()&lt;br /&gt;
	self:preprocess_equals_preprocess_many(&lt;br /&gt;
		&#039;{{#invoke:DateI18n|Date|year=2024|month=09|day=12|lang=&#039;, &#039;}}&#039;,&lt;br /&gt;
		&#039;{{#timef:2024-09-12|date|&#039;, &#039;}}&#039;, {&lt;br /&gt;
			{&#039;be&#039;},&lt;br /&gt;
			{&#039;be-x-old&#039;},&lt;br /&gt;
			{&#039;bn&#039;},&lt;br /&gt;
			{&#039;bpy&#039;},&lt;br /&gt;
			{&#039;ca&#039;},&lt;br /&gt;
			{&#039;ce&#039;},&lt;br /&gt;
			{&#039;ckb&#039;},&lt;br /&gt;
			{&#039;cs&#039;},&lt;br /&gt;
			{&#039;da&#039;},&lt;br /&gt;
			{&#039;de&#039;},&lt;br /&gt;
			{&#039;el&#039;},&lt;br /&gt;
			{&#039;en&#039;},&lt;br /&gt;
			{&#039;eo&#039;},&lt;br /&gt;
			{&#039;es&#039;},&lt;br /&gt;
			{&#039;et&#039;},&lt;br /&gt;
			{&#039;eu&#039;},&lt;br /&gt;
			{&#039;fa&#039;},&lt;br /&gt;
			{&#039;fi&#039;},&lt;br /&gt;
			{&#039;fr&#039;},&lt;br /&gt;
			{&#039;ga&#039;},&lt;br /&gt;
			{&#039;gl&#039;},&lt;br /&gt;
			{&#039;he&#039;},&lt;br /&gt;
			{&#039;hi&#039;},&lt;br /&gt;
			{&#039;hr&#039;},&lt;br /&gt;
			{&#039;hsb&#039;},&lt;br /&gt;
			{&#039;hu&#039;},&lt;br /&gt;
			{&#039;ia&#039;},&lt;br /&gt;
			{&#039;is&#039;},&lt;br /&gt;
			{&#039;it&#039;},&lt;br /&gt;
			{&#039;ja&#039;},&lt;br /&gt;
			{&#039;kn&#039;},&lt;br /&gt;
			{&#039;ko&#039;},&lt;br /&gt;
			{&#039;lt&#039;},&lt;br /&gt;
			{&#039;lv&#039;},&lt;br /&gt;
			{&#039;mk&#039;},&lt;br /&gt;
			{&#039;ml&#039;},&lt;br /&gt;
			{&#039;mr&#039;},&lt;br /&gt;
			{&#039;new&#039;},&lt;br /&gt;
			{&#039;nn&#039;},&lt;br /&gt;
			{&#039;no&#039;},&lt;br /&gt;
			{&#039;oc&#039;},&lt;br /&gt;
			{&#039;pa&#039;},&lt;br /&gt;
			{&#039;pl&#039;},&lt;br /&gt;
			{&#039;pt&#039;},&lt;br /&gt;
			{&#039;qu&#039;},&lt;br /&gt;
			{&#039;qug&#039;},&lt;br /&gt;
			{&#039;ru&#039;},&lt;br /&gt;
			{&#039;sk&#039;},&lt;br /&gt;
			{&#039;sl&#039;},&lt;br /&gt;
			{&#039;sr&#039;},&lt;br /&gt;
			{&#039;th&#039;},&lt;br /&gt;
			{&#039;uk&#039;},&lt;br /&gt;
			{&#039;vi&#039;},&lt;br /&gt;
			{&#039;yue&#039;},&lt;br /&gt;
			{&#039;zh-hans&#039;}&lt;br /&gt;
	} )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p:test_3_MD_format()&lt;br /&gt;
	self:preprocess_equals_preprocess_many(&lt;br /&gt;
		&#039;{{#invoke:DateI18n|Date|month=11|day=12|lang=&#039;, &#039;}}&#039;,&lt;br /&gt;
		&#039;{{#timef:0000-11-12|pretty|&#039;, &#039;}}&#039;, {&lt;br /&gt;
			{&#039;be&#039;},&lt;br /&gt;
			{&#039;be-x-old&#039;},&lt;br /&gt;
			{&#039;bn&#039;},&lt;br /&gt;
			{&#039;bpy&#039;},&lt;br /&gt;
			{&#039;ca&#039;},&lt;br /&gt;
			{&#039;ce&#039;},&lt;br /&gt;
			{&#039;ckb&#039;},&lt;br /&gt;
			{&#039;cs&#039;},&lt;br /&gt;
			{&#039;da&#039;},&lt;br /&gt;
			{&#039;de&#039;},&lt;br /&gt;
			{&#039;el&#039;},&lt;br /&gt;
			{&#039;en&#039;},&lt;br /&gt;
			{&#039;eo&#039;},&lt;br /&gt;
			{&#039;es&#039;},&lt;br /&gt;
			{&#039;et&#039;},&lt;br /&gt;
			{&#039;eu&#039;},&lt;br /&gt;
			{&#039;fa&#039;},&lt;br /&gt;
			{&#039;fi&#039;},&lt;br /&gt;
			{&#039;fr&#039;},&lt;br /&gt;
			{&#039;ga&#039;},&lt;br /&gt;
			{&#039;gl&#039;},&lt;br /&gt;
			{&#039;he&#039;},&lt;br /&gt;
			{&#039;hi&#039;},&lt;br /&gt;
			{&#039;hr&#039;},&lt;br /&gt;
			{&#039;hsb&#039;},&lt;br /&gt;
			{&#039;hu&#039;},&lt;br /&gt;
			{&#039;ia&#039;},&lt;br /&gt;
			{&#039;is&#039;},&lt;br /&gt;
			{&#039;it&#039;},&lt;br /&gt;
			{&#039;ja&#039;},&lt;br /&gt;
			{&#039;kn&#039;},&lt;br /&gt;
			{&#039;ko&#039;},&lt;br /&gt;
			{&#039;lt&#039;},&lt;br /&gt;
			{&#039;lv&#039;},&lt;br /&gt;
			{&#039;mk&#039;},&lt;br /&gt;
			{&#039;ml&#039;},&lt;br /&gt;
			{&#039;mr&#039;},&lt;br /&gt;
			{&#039;new&#039;},&lt;br /&gt;
			{&#039;nn&#039;},&lt;br /&gt;
			{&#039;no&#039;},&lt;br /&gt;
			{&#039;oc&#039;},&lt;br /&gt;
			{&#039;pa&#039;},&lt;br /&gt;
			{&#039;pl&#039;},&lt;br /&gt;
			{&#039;pt&#039;},&lt;br /&gt;
			{&#039;qu&#039;},&lt;br /&gt;
			{&#039;qug&#039;},&lt;br /&gt;
			{&#039;ru&#039;},&lt;br /&gt;
			{&#039;sk&#039;},&lt;br /&gt;
			{&#039;sl&#039;},&lt;br /&gt;
			{&#039;sr&#039;},&lt;br /&gt;
			{&#039;th&#039;},&lt;br /&gt;
			{&#039;uk&#039;},&lt;br /&gt;
			{&#039;vi&#039;},&lt;br /&gt;
			{&#039;yue&#039;},&lt;br /&gt;
			{&#039;zh-hans&#039;}&lt;br /&gt;
	} )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p:test_4_YMDhm_format()&lt;br /&gt;
	self:preprocess_equals_preprocess_many(&lt;br /&gt;
		&#039;{{#invoke:DateI18n|Date|year=2009|month=12|day=09|hour=13|minute=20|lang=&#039;, &#039;}}&#039;,&lt;br /&gt;
		&#039;{{#timef:2009-12-09T13:20:17|both|&#039;, &#039;}}&#039;, {&lt;br /&gt;
			{&#039;be&#039;},&lt;br /&gt;
			{&#039;be-x-old&#039;},&lt;br /&gt;
			{&#039;bn&#039;},&lt;br /&gt;
			{&#039;bpy&#039;},&lt;br /&gt;
			{&#039;ca&#039;},&lt;br /&gt;
			{&#039;ce&#039;},&lt;br /&gt;
			{&#039;ckb&#039;},&lt;br /&gt;
			{&#039;cs&#039;},&lt;br /&gt;
			{&#039;da&#039;},&lt;br /&gt;
			{&#039;de&#039;},&lt;br /&gt;
			{&#039;el&#039;},&lt;br /&gt;
			{&#039;en&#039;},&lt;br /&gt;
			{&#039;eo&#039;},&lt;br /&gt;
			{&#039;es&#039;},&lt;br /&gt;
			{&#039;et&#039;},&lt;br /&gt;
			{&#039;eu&#039;},&lt;br /&gt;
			{&#039;fa&#039;},&lt;br /&gt;
			{&#039;fi&#039;},&lt;br /&gt;
			{&#039;fr&#039;},&lt;br /&gt;
			{&#039;ga&#039;},&lt;br /&gt;
			{&#039;gl&#039;},&lt;br /&gt;
			{&#039;he&#039;},&lt;br /&gt;
			{&#039;hi&#039;},&lt;br /&gt;
			{&#039;hr&#039;},&lt;br /&gt;
			{&#039;hsb&#039;},&lt;br /&gt;
			{&#039;hu&#039;},&lt;br /&gt;
			{&#039;ia&#039;},&lt;br /&gt;
			{&#039;is&#039;},&lt;br /&gt;
			{&#039;it&#039;},&lt;br /&gt;
			{&#039;ja&#039;},&lt;br /&gt;
			{&#039;kn&#039;},&lt;br /&gt;
			{&#039;ko&#039;},&lt;br /&gt;
			{&#039;lt&#039;},&lt;br /&gt;
			{&#039;lv&#039;},&lt;br /&gt;
			{&#039;mk&#039;},&lt;br /&gt;
			{&#039;ml&#039;},&lt;br /&gt;
			{&#039;mr&#039;},&lt;br /&gt;
			{&#039;new&#039;},&lt;br /&gt;
			{&#039;nn&#039;},&lt;br /&gt;
			{&#039;no&#039;},&lt;br /&gt;
			{&#039;oc&#039;},&lt;br /&gt;
			{&#039;pa&#039;},&lt;br /&gt;
			{&#039;pl&#039;},&lt;br /&gt;
			{&#039;pt&#039;},&lt;br /&gt;
			{&#039;qu&#039;},&lt;br /&gt;
			{&#039;qug&#039;},&lt;br /&gt;
			{&#039;ru&#039;},&lt;br /&gt;
			{&#039;sk&#039;},&lt;br /&gt;
			{&#039;sl&#039;},&lt;br /&gt;
			{&#039;sr&#039;},&lt;br /&gt;
			{&#039;th&#039;},&lt;br /&gt;
			{&#039;uk&#039;},&lt;br /&gt;
			{&#039;vi&#039;},&lt;br /&gt;
			{&#039;yue&#039;},&lt;br /&gt;
			{&#039;zh-hans&#039;}&lt;br /&gt;
	} )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function p:test_6_Romance_languages()&lt;br /&gt;
	self:preprocess_equals_preprocess(&#039;{{#invoke:DateI18n|Date|year=2024|month=09|day=01|lang=fr}}&#039;, &#039;{{#timef:2024-09-01|date|fr}}&#039;)&lt;br /&gt;
	self:preprocess_equals_preprocess(&#039;{{#invoke:DateI18n|Date|year=2024|month=09|day=02|lang=fr}}&#039;, &#039;{{#timef:2024-09-02|date|fr}}&#039;)&lt;br /&gt;
	self:preprocess_equals_preprocess(&#039;{{#invoke:DateI18n|Date|month=08|day=02|lang=fr}}&#039;, &#039;{{#timef:2024-08-02|pretty|fr}}&#039;)&lt;br /&gt;
	self:preprocess_equals_preprocess(&#039;{{#invoke:DateI18n|Date|month=08|day=01|lang=fr}}&#039;, &#039;{{#timef:2024-08-01|pretty|fr}}&#039;)&lt;br /&gt;
	&lt;br /&gt;
	self:preprocess_equals_preprocess(&#039;{{#invoke:DateI18n|Date|year=2024|month=08|day=01|lang=ga}}&#039;, &#039;{{#timef:2024-08-01|date|ga}}&#039;)&lt;br /&gt;
	self:preprocess_equals_preprocess(&#039;{{#invoke:DateI18n|Date|year=2024|month=08|day=02|lang=ga}}&#039;, &#039;{{#timef:2024-08-02|date|ga}}&#039;)&lt;br /&gt;
	self:preprocess_equals_preprocess(&#039;{{#invoke:DateI18n|Date|month=07|day=02|lang=ga}}&#039;, &#039;{{#timef:2024-07-02|pretty|ga}}&#039;)&lt;br /&gt;
	self:preprocess_equals_preprocess(&#039;{{#invoke:DateI18n|Date|month=07|day=01|lang=ga}}&#039;, &#039;{{#timef:2024-07-01|pretty|ga}}&#039;)&lt;br /&gt;
	&lt;br /&gt;
	self:preprocess_equals_preprocess(&#039;{{#invoke:DateI18n|Date|year=2024|month=07|day=01|lang=ca}}&#039;, &#039;{{#timef:2024-07-01|date|ca}}&#039;)&lt;br /&gt;
	self:preprocess_equals_preprocess(&#039;{{#invoke:DateI18n|Date|year=2024|month=07|day=02|lang=ca}}&#039;, &#039;{{#timef:2024-07-02|date|ca}}&#039;)&lt;br /&gt;
	self:preprocess_equals_preprocess(&#039;{{#invoke:DateI18n|Date|month=06|day=02|lang=ca}}&#039;, &#039;{{#timef:2024-06-02|pretty|ca}}&#039;)&lt;br /&gt;
	self:preprocess_equals_preprocess(&#039;{{#invoke:DateI18n|Date|month=06|day=01|lang=ca}}&#039;, &#039;{{#timef:2024-06-01|pretty|ca}}&#039;)&lt;br /&gt;
	&lt;br /&gt;
	self:preprocess_equals_preprocess(&#039;{{#invoke:DateI18n|Date|year=2024|month=04|day=01|lang=eu}}&#039;, &#039;{{#timef:2024-04-01|date|eu}}&#039;)&lt;br /&gt;
	self:preprocess_equals_preprocess(&#039;{{#invoke:DateI18n|Date|year=2024|month=04|day=02|lang=eu}}&#039;, &#039;{{#timef:2024-04-02|date|eu}}&#039;)&lt;br /&gt;
	self:preprocess_equals_preprocess(&#039;{{#invoke:DateI18n|Date|year=2024|month=03|day=11|lang=eu}}&#039;, &#039;{{#timef:2024-03-11|date|eu}}&#039;)&lt;br /&gt;
	self:preprocess_equals_preprocess(&#039;{{#invoke:DateI18n|Date|year=2024|month=02|day=21|lang=eu}}&#039;, &#039;{{#timef:2024-02-21|date|eu}}&#039;)&lt;br /&gt;
	self:preprocess_equals_preprocess(&#039;{{#invoke:DateI18n|Date|year=2024|month=01|day=31|lang=eu}}&#039;, &#039;{{#timef:2024-01-31|date|eu}}&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p:test_7_Quechua_language()&lt;br /&gt;
	self:preprocess_equals_preprocess(&#039;{{#invoke:DateI18n|Date|year=2009|month=01|day=09|lang=qu}}&#039;, &#039;{{#timef:2009-01-09|date|qu}}&#039;)&lt;br /&gt;
	self:preprocess_equals_preprocess(&#039;{{#invoke:DateI18n|Date|month=12|day=09|lang=qu}}&#039;, &#039;{{#timef:0000-12-09|pretty|qu}}&#039;)&lt;br /&gt;
	self:preprocess_equals_preprocess(&#039;{{#invoke:DateI18n|Date|year=2009|month=01|day=09|lang=qug}}&#039;, &#039;{{#timef:2009-01-09|date|qug}}&#039;)&lt;br /&gt;
	self:preprocess_equals_preprocess(&#039;{{#invoke:DateI18n|Date|month=12|day=09|lang=qug}}&#039;, &#039;{{#timef:0000-12-09|pretty|qug}}&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p:test_8_Thai_solar_calendar()&lt;br /&gt;
	self:preprocess_equals_preprocess(&#039;{{#invoke:DateI18n|Date|year=2009|month=01|day=09|lang=th}}&#039;, &#039;{{#timef:2009-01-09|date|th}}&#039;)&lt;br /&gt;
	self:preprocess_equals_preprocess(&#039;{{#invoke:DateI18n|Date|month=12|day=09|lang=th}}&#039;, &#039;{{#timef:0000-12-09|pretty|th}}&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=Module:DateI18n/sandbox/testcases&amp;diff=3960</id>
		<title>Module:DateI18n/sandbox/testcases</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=Module:DateI18n/sandbox/testcases&amp;diff=3960"/>
		<updated>2026-09-25T08:46:46Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: Created page with &amp;quot;local TUT = mw.title.new(mw.getCurrentFrame():getTitle()).basePageTitle -- the title under test local p = require(TUT.prefixedText)-- the module to be tested local Date = p._Date local ScribuntoUnit = require(&amp;#039;Module:ScribuntoUnit&amp;#039;) local suite = ScribuntoUnit:new()  function suite:test_01_English() 	self:assertEquals( &amp;#039;20 July 1969, 20:17:40&amp;#039;, Date({1969,07,20,20,17,40},&amp;#039;en&amp;#039;)) 	self:assertEquals( &amp;#039;20 July 1969, 20:17&amp;#039;,    Date({1969,07,20,20,17},&amp;#039;en&amp;#039;)) 	self:assertEqual...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local TUT = mw.title.new(mw.getCurrentFrame():getTitle()).basePageTitle -- the title under test&lt;br /&gt;
local p = require(TUT.prefixedText)-- the module to be tested&lt;br /&gt;
local Date = p._Date&lt;br /&gt;
local ScribuntoUnit = require(&#039;Module:ScribuntoUnit&#039;)&lt;br /&gt;
local suite = ScribuntoUnit:new()&lt;br /&gt;
&lt;br /&gt;
function suite:test_01_English()&lt;br /&gt;
	self:assertEquals( &#039;20 July 1969, 20:17:40&#039;, Date({1969,07,20,20,17,40},&#039;en&#039;))&lt;br /&gt;
	self:assertEquals( &#039;20 July 1969, 20:17&#039;,    Date({1969,07,20,20,17},&#039;en&#039;))&lt;br /&gt;
	self:assertEquals( &#039;20 July 1969&#039;,           Date({1969,07,20,20},&#039;en&#039;))&lt;br /&gt;
	self:assertEquals( &#039;20 July 1969&#039;,           Date({1969,07,20},&#039;en&#039;))&lt;br /&gt;
	self:assertEquals( &#039;20 July 1969&#039;,           Date({1969,07,20,nil,17,40},&#039;en&#039;))&lt;br /&gt;
	self:assertEquals( &#039;July 1969&#039;,              Date({1969,07},&#039;en&#039;))&lt;br /&gt;
	self:assertEquals( &#039;1969&#039;,                   Date({1969},&#039;en&#039;))&lt;br /&gt;
	self:assertEquals( &#039;1969&#039;,                   Date({1969,&#039;&#039;,&#039;&#039;,&#039;&#039;,&#039;&#039;,&#039;&#039;},&#039;en&#039;))&lt;br /&gt;
	self:assertEquals( &#039;20 July&#039;,                Date({nil,07,20},&#039;en&#039;))&lt;br /&gt;
	self:assertEquals( &#039;July&#039;,                   Date({nil,07},&#039;en&#039;))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function suite:test_02_French()&lt;br /&gt;
	self:assertEquals( &#039;1&amp;lt;sup&amp;gt;er&amp;lt;/sup&amp;gt; juin 1999&#039;, Date({1999,6,1},&#039;fr&#039;))&lt;br /&gt;
	self:assertEquals( &#039;2 juin 1999&#039;,   Date({1999,6,2},&#039;fr&#039;))&lt;br /&gt;
	self:assertEquals( &#039;1&amp;lt;sup&amp;gt;er&amp;lt;/sup&amp;gt; mai&#039;, Date({&#039;&#039;,5,1},&#039;fr&#039;))&lt;br /&gt;
	self:assertEquals( &#039;2 mai&#039;, Date({&#039;&#039;,5,2},&#039;fr&#039;))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function suite:test_03_Catalan()&lt;br /&gt;
	self:assertEquals( &#039;1r de juny de 1999&#039;, Date({1999,6,1},&#039;ca&#039;))&lt;br /&gt;
	self:assertEquals( &#039;2 de juny de 1999&#039;,  Date({1999,6,2},&#039;ca&#039;))&lt;br /&gt;
	self:assertEquals( &#039;1r de maig&#039;,         Date({&#039;&#039;,5,1},&#039;ca&#039;))&lt;br /&gt;
	self:assertEquals( &#039;2 de maig&#039;,          Date({&#039;&#039;,5,2},&#039;ca&#039;))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function suite:test_04_Gallic()&lt;br /&gt;
	self:assertEquals( &#039;1&amp;lt;sup&amp;gt;ú&amp;lt;/sup&amp;gt; Meitheamh 1999&#039;, Date({1999,6,1},&#039;ga&#039;))&lt;br /&gt;
	self:assertEquals( &#039;2 Meitheamh 1999&#039;,  Date({1999,6,2},&#039;ga&#039;))&lt;br /&gt;
	self:assertEquals( &#039;1&amp;lt;sup&amp;gt;ú&amp;lt;/sup&amp;gt; Bealtaine&#039;, Date({&#039;&#039;,5,1},&#039;ga&#039;))&lt;br /&gt;
	self:assertEquals( &#039;2 Bealtaine&#039;, Date({&#039;&#039;,5,2},&#039;ga&#039;))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function suite:test_05_Basque()&lt;br /&gt;
	self:assertEquals( &#039;1999ko uztailaren 1ea&#039;,  Date({1999,7,01},&#039;eu&#039;))&lt;br /&gt;
	self:assertEquals( &#039;1999ko uztailaren 2a&#039;,   Date({1999,7,02},&#039;eu&#039;))&lt;br /&gt;
	self:assertEquals( &#039;1999ko uztailaren 11&#039;,   Date({1999,7,11},&#039;eu&#039;))&lt;br /&gt;
	self:assertEquals( &#039;1999ko uztailaren 21ea&#039;, Date({1999,7,21},&#039;eu&#039;))&lt;br /&gt;
	self:assertEquals( &#039;1999ko uztailaren 31&#039;,   Date({1999,7,31},&#039;eu&#039;))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function suite:test_06_Thai_solar_calendar()&lt;br /&gt;
	self:assertEquals( &#039;1 มกราคม พ.ศ. 2484&#039;, Date({1941,1,1},&#039;th&#039;))&lt;br /&gt;
	self:assertEquals( &#039;มกราคม พ.ศ. 2484&#039;, Date({1941,1},&#039;th&#039;))&lt;br /&gt;
	--self:assertEquals( &#039;กันยายน พ.ศ. 2483&#039;, Date({1940,12},&#039;th&#039;))&lt;br /&gt;
	self:assertEquals( &#039;กันยายน พ.ศ. 2484&#039;, Date({1941,09},&#039;th&#039;))&lt;br /&gt;
	self:assertEquals( &#039;พ.ศ. 2484&#039;, Date({1941},&#039;th&#039;))&lt;br /&gt;
	self:assertEquals( &#039;2482 หรือ 2483&#039;, Date({1940},&#039;th&#039;))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function suite:test_07_Quechua()&lt;br /&gt;
	self:assertEquals( &#039;9 ñiqin inirupi 2009 watapi&#039;, Date({2009,1,9},&#039;qu&#039;))&lt;br /&gt;
	self:assertEquals( &#039;9 ñiqin inirupi&#039;, Date({nil,1,9},&#039;qu&#039;))&lt;br /&gt;
	self:assertEquals( &#039;inirupi 2009 watapi&#039;, Date({2009,1},&#039;qu&#039;))&lt;br /&gt;
	self:assertEquals( &#039;iniru 2009 watapi&#039;, Date({2009,1},&#039;qu&#039;,&#039;nom&#039;))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function suite:test_10_YMD_in_50_languages()&lt;br /&gt;
	local datevec = {2010,1,9}&lt;br /&gt;
	self:assertEquals( &#039;9 студзеня 2010&#039;, Date(datevec,&#039;be&#039;))&lt;br /&gt;
	self:assertEquals( &#039;9 студзеня 2010&#039;, Date(datevec,&#039;be-tarask&#039;))&lt;br /&gt;
	self:assertEquals( &#039;9 студзеня 2010&#039;, Date(datevec,&#039;be-x-old&#039;))&lt;br /&gt;
	self:assertEquals( &#039;৯ জানুয়ারি ২০১০&#039;, Date(datevec,&#039;bn&#039;))&lt;br /&gt;
	self:assertEquals( &#039;জানুয়ারী ৯, মারি ২০১০&#039;, Date(datevec,&#039;bpy&#039;))&lt;br /&gt;
	self:assertEquals( &#039;9 de gener de 2010&#039;, Date(datevec,&#039;ca&#039;))&lt;br /&gt;
	self:assertEquals( &#039;2010 шеран 9 январь&#039;, Date(datevec,&#039;ce&#039;))&lt;br /&gt;
	self:assertEquals( &#039;٩ی کانوونی دووەمی ٢٠١٠&#039;, Date(datevec,&#039;ckb&#039;))&lt;br /&gt;
	self:assertEquals( &#039;9. ledna 2010&#039;, Date(datevec,&#039;cs&#039;))&lt;br /&gt;
	self:assertEquals( &#039;9. januar 2010&#039;, Date(datevec,&#039;da&#039;))&lt;br /&gt;
	self:assertEquals( &#039;9. Januar 2010&#039;, Date(datevec,&#039;de&#039;))&lt;br /&gt;
	self:assertEquals( &#039;9 Ιανουαρίου 2010&#039;, Date(datevec,&#039;el&#039;))&lt;br /&gt;
	self:assertEquals( &#039;9 January 2010&#039;, Date(datevec,&#039;en&#039;))&lt;br /&gt;
	self:assertEquals( &#039;la 9-a de januaro 2010&#039;, Date(datevec,&#039;eo&#039;))&lt;br /&gt;
	self:assertEquals( &#039;9 de enero de 2010&#039;, Date(datevec,&#039;es&#039;))&lt;br /&gt;
	self:assertEquals( &#039;9. jaanuar 2010&#039;, Date(datevec,&#039;et&#039;))&lt;br /&gt;
	self:assertEquals( &#039;2010ko urtarrilaren 9a&#039;, Date(datevec,&#039;eu&#039;))&lt;br /&gt;
	self:assertEquals( &#039;&amp;amp;rlm;۹ ژانویهٔ ۲۰۱۰&amp;amp;rlm;&#039;, Date(datevec,&#039;fa&#039;))&lt;br /&gt;
	self:assertEquals( &#039;9. tammikuuta 2010&#039;, Date(datevec,&#039;fi&#039;))&lt;br /&gt;
	self:assertEquals( &#039;9 janvier 2010&#039;, Date(datevec,&#039;fr&#039;))&lt;br /&gt;
	self:assertEquals( &#039;9 Eanáir 2010&#039;, Date(datevec,&#039;ga&#039;))&lt;br /&gt;
	self:assertEquals( &#039;9 de xaneiro de 2010&#039;, Date(datevec,&#039;gl&#039;))&lt;br /&gt;
	self:assertEquals( &#039;&amp;amp;rlm;9 בינואר 2010&amp;amp;rlm;&#039;, Date(datevec,&#039;he&#039;))&lt;br /&gt;
	self:assertEquals( &#039;९ जनवरी २०१०&#039;, Date(datevec,&#039;hi&#039;))&lt;br /&gt;
	self:assertEquals( &#039;9. siječnja 2010.&#039;, Date(datevec,&#039;hr&#039;))&lt;br /&gt;
	self:assertEquals( &#039;9. januara 2010&#039;, Date(datevec,&#039;hsb&#039;))&lt;br /&gt;
	self:assertEquals( &#039;2010. január 9.&#039;, Date(datevec,&#039;hu&#039;))&lt;br /&gt;
	self:assertEquals( &#039;9 de januario 2010&#039;, Date(datevec,&#039;ia&#039;))&lt;br /&gt;
	self:assertEquals( &#039;9. janúar 2010&#039;, Date(datevec,&#039;is&#039;))&lt;br /&gt;
	self:assertEquals( &#039;2010年1月9日&#039;, Date(datevec,&#039;ja&#039;))&lt;br /&gt;
	self:assertEquals( &#039;ಜನವರಿ ೯, ೨೦೧೦&#039;, Date(datevec,&#039;kn&#039;))&lt;br /&gt;
	self:assertEquals( &#039;2010년 1월 9일&#039;, Date(datevec,&#039;ko&#039;))&lt;br /&gt;
	self:assertEquals( &#039;2010 m. sausio 9 d.&#039;, Date(datevec,&#039;lt&#039;))&lt;br /&gt;
	self:assertEquals( &#039;2010. gada 9. janvāris&#039;, Date(datevec,&#039;lv&#039;))&lt;br /&gt;
	self:assertEquals( &#039;9 јануари 2010&#039;, Date(datevec,&#039;mk&#039;))&lt;br /&gt;
	self:assertEquals( &#039;9 ജനുവരി 2010&#039;, Date(datevec,&#039;ml&#039;))&lt;br /&gt;
	self:assertEquals( &#039;जानेवारी ९, इ.स. २०१०&#039;, Date(datevec,&#039;mr&#039;))&lt;br /&gt;
	self:assertEquals( &#039;ज्यानुवरी ९, ई सं २०१०&#039;, Date(datevec,&#039;new&#039;))&lt;br /&gt;
	self:assertEquals( &#039;9. januar 2010&#039;, Date(datevec,&#039;nn&#039;))&lt;br /&gt;
	self:assertEquals( &#039;9. januar 2010&#039;, Date(datevec,&#039;no&#039;))&lt;br /&gt;
	self:assertEquals( &#039;9 genièr de 2010&#039;, Date(datevec,&#039;oc&#039;))&lt;br /&gt;
	self:assertEquals( &#039;9 ਜਨਵਰੀ 2010&#039;, Date(datevec,&#039;pa&#039;))&lt;br /&gt;
	self:assertEquals( &#039;9 stycznia 2010&#039;, Date(datevec,&#039;pl&#039;))&lt;br /&gt;
	self:assertEquals( &#039;9 de janeiro de 2010&#039;, Date(datevec,&#039;pt&#039;))&lt;br /&gt;
	self:assertEquals( &#039;9 ñiqin inirupi 2010 watapi&#039;, Date(datevec,&#039;qu&#039;))&lt;br /&gt;
	self:assertEquals( &#039;9 niki Kamaypi 2010 watapi&#039;, Date(datevec,&#039;qug&#039;))&lt;br /&gt;
	self:assertEquals( &#039;9 января 2010&#039;, Date(datevec,&#039;ru&#039;))&lt;br /&gt;
	self:assertEquals( &#039;9. januára 2010&#039;, Date(datevec,&#039;sk&#039;))&lt;br /&gt;
	self:assertEquals( &#039;9. januarja 2010&#039;, Date(datevec,&#039;sl&#039;))&lt;br /&gt;
	self:assertEquals( &#039;9. јануар 2010.&#039;, Date(datevec,&#039;sr&#039;))&lt;br /&gt;
	self:assertEquals( &#039;9 มกราคม พ.ศ. 2553&#039;, Date(datevec,&#039;th&#039;))&lt;br /&gt;
	self:assertEquals( &#039;9 січня 2010&#039;, Date(datevec,&#039;uk&#039;))&lt;br /&gt;
	self:assertEquals( &#039;9 tháng 1 năm 2010&#039;, Date(datevec,&#039;vi&#039;))&lt;br /&gt;
	self:assertEquals( &#039;2010年1月9日&#039;, Date(datevec,&#039;zh-hans&#039;))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function suite:test_11_YMDHMS()&lt;br /&gt;
	local datevec = {1569,09,3,20,17,40}&lt;br /&gt;
	self:assertEquals( &#039;3 September 1569, 20:17:40&#039;, Date(datevec,&#039;en&#039;))&lt;br /&gt;
	self:assertEquals( &#039;1569ko irailaren 3a, 20:17:40&#039;, Date(datevec,&#039;eu&#039;))&lt;br /&gt;
	self:assertEquals( &#039;٣ی ئەیلوولی ١٥٦٩، ٢٠:١٧:٤٠&#039;, Date(datevec,&#039;ckb&#039;))&lt;br /&gt;
	self:assertEquals( &#039;3. septembra 1569 ob 20:17:40&#039;, Date(datevec,&#039;sl&#039;))&lt;br /&gt;
	self:assertEquals( &#039;3 tháng 9 năm 1569 lúc 20:17:40&#039;, Date(datevec,&#039;vi&#039;))&lt;br /&gt;
end &lt;br /&gt;
&lt;br /&gt;
function suite:test_12_YMDHM()&lt;br /&gt;
	local datevec = {1569,09,3,20,17}&lt;br /&gt;
	self:assertEquals( &#039;3 September 1569, 20:17&#039;, Date(datevec,&#039;en&#039;))&lt;br /&gt;
	self:assertEquals( &#039;1569ko irailaren 3a, 20:17&#039;, Date(datevec,&#039;eu&#039;))&lt;br /&gt;
	self:assertEquals( &#039;٣ی ئەیلوولی ١٥٦٩، ٢٠:١٧&#039;, Date(datevec,&#039;ckb&#039;))&lt;br /&gt;
	self:assertEquals( &#039;3. septembra 1569 ob 20:17&#039;, Date(datevec,&#039;sl&#039;))&lt;br /&gt;
	self:assertEquals( &#039;3 tháng 9 năm 1569 lúc 20:17&#039;, Date(datevec,&#039;vi&#039;))&lt;br /&gt;
end &lt;br /&gt;
&lt;br /&gt;
function suite:test_13_German()&lt;br /&gt;
	self:assertEquals( &#039;20. Juli 1969, 20:17:40&#039;, Date({1969,07,20,20,17,40},&#039;de&#039;))&lt;br /&gt;
	self:assertEquals( &#039;20. Juli 1969, 20:17&#039;,    Date({1969,07,20,20,17},&#039;de&#039;))&lt;br /&gt;
	self:assertEquals( &#039;20. Juli 1969&#039;,           Date({1969,07,20,20},&#039;de&#039;))&lt;br /&gt;
	self:assertEquals( &#039;20. Juli 1969&#039;,           Date({1969,07,20},&#039;de&#039;))&lt;br /&gt;
	self:assertEquals( &#039;20. Juli 1969&#039;,           Date({1969,07,20,nil,17,40},&#039;de&#039;))&lt;br /&gt;
	self:assertEquals( &#039;Juli 1969&#039;,               Date({1969,07},&#039;de&#039;))&lt;br /&gt;
	self:assertEquals( &#039;1969&#039;,                    Date({1969},&#039;de&#039;))&lt;br /&gt;
	self:assertEquals( &#039;1969&#039;,                    Date({1969,&#039;&#039;,&#039;&#039;,&#039;&#039;,&#039;&#039;,&#039;&#039;},&#039;de&#039;))&lt;br /&gt;
	self:assertEquals( &#039;20. Juli&#039;,                Date({nil,07,20},&#039;de&#039;))&lt;br /&gt;
	self:assertEquals( &#039;Juli&#039;,                    Date({nil,07},&#039;de&#039;))&lt;br /&gt;
	self:assertEquals( &#039;&#039;,                        Date({nil},&#039;de&#039;))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function suite:test_outer_function()&lt;br /&gt;
	-- rest the p.Date(frame) function accessible to template functions&lt;br /&gt;
	local mod = &#039;{{#invoke:&#039; .. TUT.text .. &#039;| Date&#039;&lt;br /&gt;
	self:assertSameResult( &#039;9 January 2009, 15:28:37 +03:30&#039;, mod..&#039;|year=2009|month=01|day=09|hour=15|minute=28|second=37|tzhour=3|tzmin=30|class=|lang=en}}&#039;)&lt;br /&gt;
	self:assertSameResult( &#039;9 January 2009, 15:28:37&#039;, mod..&#039;|year=2009|month=01|day=09|hour=15|minute=28|second=37|class=|lang=en}}&#039;)&lt;br /&gt;
	self:assertSameResult( &#039;25 mai 1943, 15:28:37&#039;,    mod..&#039;|year=1943|month=05|day=25|hour=15|minute=28|second=37|class=|lang=fr}}&#039;)	&lt;br /&gt;
	self:assertSameResult( &#039;&amp;lt;time class=&amp;quot;dtstart&amp;quot; datetime=&amp;quot;2009-01-09&amp;quot; lang=&amp;quot;pl&amp;quot; dir=&amp;quot;ltr&amp;quot; style=&amp;quot;white-space:nowrap&amp;quot;&amp;gt;9 stycznia 2009&amp;lt;/time&amp;gt;&#039;, mod..&#039;|year=2009|month=01|day=09|class=dtstart|lang=pl}}&#039;)&lt;br /&gt;
	self:assertSameResult( &#039;&amp;lt;time class=&amp;quot;dtstart&amp;quot; datetime=&amp;quot;2009-01-09&amp;quot; lang=&amp;quot;pl&amp;quot; dir=&amp;quot;ltr&amp;quot; style=&amp;quot;white-space:nowrap&amp;quot;&amp;gt;9 styczeń 2009&amp;lt;/time&amp;gt;&#039;,  mod..&#039;|year=2009|month=01|day=09|case=nom|lang=pl}}&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function suite:test_class()&lt;br /&gt;
	self:assertEquals(&#039;9 January 2009, 15:28:37&#039;, Date({2009,1,9,15,28,37}, &#039;en&#039;, &#039;&#039;, &#039;&#039;))&lt;br /&gt;
	self:assertEquals(&#039;&amp;lt;time class=&amp;quot;dtstart&amp;quot; datetime=&amp;quot;2009-01-09 15:28:37&amp;quot; lang=&amp;quot;en&amp;quot; dir=&amp;quot;ltr&amp;quot; style=&amp;quot;white-space:nowrap&amp;quot;&amp;gt;9 January 2009, 15:28:37&amp;lt;/time&amp;gt;&#039;, Date({2009,1,9,15,28,37}, &#039;en&#039;, &#039;&#039;, &#039;dtstart&#039;))&lt;br /&gt;
	self:assertEquals(&#039;9 January&#039;, Date({nil,1,9}, &#039;en&#039;, &#039;&#039;, &#039;dtstart&#039;))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function suite:test_timezones()&lt;br /&gt;
	self:assertEquals(&#039;9 January 2009, 15:28:37 +03:30&#039;, Date({2009,1,9,15,28,37,3,30}, &#039;en&#039;))&lt;br /&gt;
	self:assertEquals(&#039;9 January 2009, 15:28:37 −11:00&#039;, Date({2009,1,9,15,28,37,-11} , &#039;en&#039;))&lt;br /&gt;
	self:assertEquals(&#039;ज्यानुवरी ९, ई सं २००९, १५:२८:३७ −११:००&#039;, Date({2009,1,9,15,28,37,-11} , &#039;new&#039;))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function suite:test_gramatical_cases()&lt;br /&gt;
	self:assertEquals( &#039;20 July 1969&#039;,   Date({1969,07,20},&#039;en&#039;,&#039;&#039;))&lt;br /&gt;
	self:assertEquals( &#039;21 lipca 1969&#039;,  Date({1969,07,21},&#039;pl&#039;,&#039;&#039;))&lt;br /&gt;
	self:assertEquals( &#039;22 lipiec 1969&#039;, Date({1969,07,22},&#039;pl&#039;,&#039;nom&#039;))&lt;br /&gt;
	self:assertEquals( &#039;23 lipca 1969&#039;,  Date({1969,07,23},&#039;pl&#039;,&#039;gen&#039;))&lt;br /&gt;
	self:assertEquals( &#039;24 lipcem 1969&#039;, Date({1969,07,24},&#039;pl&#039;,&#039;ins&#039;))&lt;br /&gt;
	self:assertEquals( &#039;25 lipcu 1969&#039;,  Date({1969,07,25},&#039;pl&#039;,&#039;loc&#039;))&lt;br /&gt;
	self:assertEquals( &#039;21 июля 1969&#039;,   Date({1969,07,21},&#039;ru&#039;,&#039;&#039;))&lt;br /&gt;
	self:assertEquals( &#039;22 июль 1969&#039;,   Date({1969,07,22},&#039;ru&#039;,&#039;nom&#039;))&lt;br /&gt;
	self:assertEquals( &#039;23 июля 1969&#039;,   Date({1969,07,23},&#039;ru&#039;,&#039;gen&#039;))&lt;br /&gt;
	self:assertEquals( &#039;24 июлем 1969&#039;,  Date({1969,07,24},&#039;ru&#039;,&#039;ins&#039;))&lt;br /&gt;
	self:assertEquals( &#039;25 июле 1969&#039;,   Date({1969,07,25},&#039;ru&#039;,&#039;loc&#039;))&lt;br /&gt;
	self:assertEquals( &#039;marraskuu 1960&#039;,    Date({1960,11},&#039;fi&#039;,&#039;&#039;))&lt;br /&gt;
	self:assertEquals( &#039;marraskuu 1961&#039;,    Date({1961,11},&#039;fi&#039;,&#039;nom&#039;))&lt;br /&gt;
	self:assertEquals( &#039;marraskuun 1962&#039;,   Date({1962,11},&#039;fi&#039;,&#039;gen&#039;))&lt;br /&gt;
	self:assertEquals( &#039;marraskuuta 1963&#039;,  Date({1963,11},&#039;fi&#039;,&#039;ptv&#039;))&lt;br /&gt;
	self:assertEquals( &#039;marraskuussa 1964&#039;, Date({1964,11},&#039;fi&#039;,&#039;ine&#039;))&lt;br /&gt;
	self:assertEquals( &#039;marraskuusta 1965&#039;, Date({1965,11},&#039;fi&#039;,&#039;ela&#039;))&lt;br /&gt;
	self:assertEquals( &#039;marraskuuhun 1966&#039;, Date({1966,11},&#039;fi&#039;,&#039;ill&#039;))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function suite:test_year_trimming()&lt;br /&gt;
    self:assertEquals( &#039;1 September 999&#039;,  Date({999, 9, 1}, &#039;en&#039;, &#039;&#039;, &#039;&#039;, true))&lt;br /&gt;
    self:assertEquals( &#039;2 September 99&#039;,   Date({ 99, 9, 2}, &#039;en&#039;, &#039;&#039;, &#039;&#039;, &#039;true&#039;))&lt;br /&gt;
    self:assertEquals( &#039;3 September 9&#039;,    Date({  9, 9, 3}, &#039;en&#039;, &#039;&#039;, &#039;&#039;, 1))&lt;br /&gt;
    self:assertEquals( &#039;4 September 0999&#039;, Date({999, 9, 4}, &#039;en&#039;, &#039;&#039;, &#039;&#039;, false))&lt;br /&gt;
    self:assertEquals( &#039;5 September 0999&#039;, Date({999, 9, 5}, &#039;en&#039;, &#039;&#039;, &#039;&#039;, &#039;false&#039;))&lt;br /&gt;
    self:assertEquals( &#039;6 September 999&#039;,  Date({999, 9, 6}, &#039;en&#039;, &#039;&#039;, &#039;&#039;, &#039;100-999&#039;))&lt;br /&gt;
    self:assertEquals( &#039;7 September 0999&#039;, Date({999, 9, 7}, &#039;en&#039;, &#039;&#039;, &#039;&#039;, &#039;100-990&#039;))&lt;br /&gt;
    self:assertEquals( &#039;৮ সেপ্টেম্বর ৯৮৭&#039;,    Date({987, 9, 8}, &#039;bn&#039;, &#039;&#039;, &#039;&#039;, &#039;1&#039;))&lt;br /&gt;
    self:assertEquals( &#039;सप्टेंबर ९, इ.स. ९८७&#039;,    Date({987, 9, 9}, &#039;mr&#039;, &#039;&#039;, &#039;&#039;, &#039;1&#039;))&lt;br /&gt;
    self:assertEquals( &#039;ಸೆಪ್ಟೆಂಬರ್ ೧೦, ೯೮೭&#039;,  Date({987, 9,10}, &#039;kn&#039;, &#039;&#039;, &#039;&#039;, &#039;1&#039;))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function suite:test_out_of_range_dates()&lt;br /&gt;
	self:assertEquals( &#039;20 July 1969, 20:17:40&#039;, Date({1969,07,20,20,17,40},&#039;en&#039;)) -- correct&lt;br /&gt;
	self:assertEquals( &#039;20 July 1969, 20:17&#039;,    Date({1969,07,20,20,17,80},&#039;en&#039;)) -- bad second&lt;br /&gt;
	self:assertEquals( &#039;20 July 1969&#039;,           Date({1969,07,20,20,67,40},&#039;en&#039;)) -- bad minute&lt;br /&gt;
	self:assertEquals( &#039;20 July 1969&#039;,           Date({1969,07,20,30,17,40},&#039;en&#039;)) -- bad hour&lt;br /&gt;
	self:assertEquals( &#039;July 1969&#039;,              Date({1969,07,80,20,17,40},&#039;en&#039;)) -- bad day&lt;br /&gt;
	self:assertEquals( &#039;1969&#039;,                   Date({1969,13,20,20,17,40},&#039;en&#039;)) -- bad month&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function suite:test_strReplace()&lt;br /&gt;
	self:assertEquals( &#039;new old book&#039;, p.strReplace(&#039;old old book&#039;, &#039;old&#039;, &#039;new&#039;)) &lt;br /&gt;
	self:assertEquals( &#039;&amp;quot;old&amp;quot; new book&#039;, p.strReplace(&#039;&amp;quot;old&amp;quot; old book&#039;, &#039;old&#039;, &#039;new&#039;)) &lt;br /&gt;
	self:assertEquals( &#039;my &amp;quot;old&amp;quot; new book&#039;, p.strReplace(&#039;my &amp;quot;old&amp;quot; old book&#039;, &#039;old&#039;, &#039;new&#039;)) &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function suite:test_clean_datevec()&lt;br /&gt;
	self:assertDeepEquals( {1969,07,20,20,17,40,3,30}, p.clean_datevec({1969,07,20,20,17,40,3,30})) &lt;br /&gt;
	self:assertDeepEquals({1969,7,20,20,17,40},       p.clean_datevec({1969,07,20,20,17,40})) &lt;br /&gt;
	self:assertDeepEquals({1969,7,20,20,17,40},       p.clean_datevec({&#039;1969&#039;,&#039;07&#039;,&#039;20&#039;,&#039;20&#039;,&#039;17&#039;,&#039;40&#039;})) &lt;br /&gt;
	self:assertDeepEquals({1969,7,20,20,17,40},       p.clean_datevec({&#039;1969&#039;,&#039;July&#039;,&#039;20&#039;,&#039;20&#039;,&#039;17&#039;,&#039;40&#039;})) &lt;br /&gt;
	self:assertDeepEquals({1969,7,20,20,17},          p.clean_datevec({1969,7,20,20,17,90})) -- bad second&lt;br /&gt;
	self:assertDeepEquals({1969,7,20, 20,nil,40},     p.clean_datevec({1969,7,20,20,90,40})) -- bad minute&lt;br /&gt;
	self:assertDeepEquals({1969,7,20,nil,17,40},      p.clean_datevec({1969,7,20,24,17,40})) -- bad hour&lt;br /&gt;
	self:assertDeepEquals({1969,7,nil,20,17,40},      p.clean_datevec({1969,7,32,20,17,40})) -- bad day&lt;br /&gt;
	self:assertDeepEquals({1969,nil,20,20,17,40},     p.clean_datevec({1969,13,20,20,17,40})) -- bad month&lt;br /&gt;
	self:assertDeepEquals({1968,7,20,20,17},          p.clean_datevec({1968,7,20,20,17,60}))  -- bad second&lt;br /&gt;
	self:assertDeepEquals({1970,6,30,23,59,60},       p.clean_datevec({1970,06,30,23,59,60})) -- leap second&lt;br /&gt;
	self:assertDeepEquals({1971,12,31,23,59,60},      p.clean_datevec({1971,12,31,23,59,60})) -- leap second&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function suite:test_getTimestamp()&lt;br /&gt;
	local function get_datecode(datenum)&lt;br /&gt;
		local _, datecode = p.getTimestamp(datenum)&lt;br /&gt;
		return datecode&lt;br /&gt;
	end &lt;br /&gt;
&lt;br /&gt;
	self:assertEquals( &#039;YMDhms&#039;, get_datecode({1961,7,20,20,17,40,3,30})) &lt;br /&gt;
	self:assertEquals( &#039;YMDhms&#039;, get_datecode({1962,7,20,20,17,40})) &lt;br /&gt;
	self:assertEquals( &#039;YMDhm&#039;,  get_datecode({1963,7,20,20,17})) &lt;br /&gt;
	self:assertEquals( &#039;YMD&#039;,    get_datecode({1964,7,20,nil,17})) &lt;br /&gt;
	self:assertEquals( &#039;YMD&#039;,    get_datecode({1965,7,20,20})) &lt;br /&gt;
	self:assertEquals( &#039;YMD&#039;,    get_datecode({1966,7,20})) &lt;br /&gt;
	self:assertEquals( &#039;YM&#039;,     get_datecode({1967,7,nil,20,17})) &lt;br /&gt;
	self:assertEquals( &#039;YM&#039;,     get_datecode({1968,7,nil,20,nil})) &lt;br /&gt;
	self:assertEquals( &#039;YM&#039;,     get_datecode({1969,7,nil,nil,17})) &lt;br /&gt;
	self:assertEquals( &#039;YM&#039;,     get_datecode({1970,7})) &lt;br /&gt;
	self:assertEquals( &#039;Y&#039;,      get_datecode({1971,nil,20,20,17,40})) &lt;br /&gt;
	self:assertEquals( &#039;Y&#039;,      get_datecode({1971,nil,20,20,nil,40})) &lt;br /&gt;
	self:assertEquals( &#039;Y&#039;,      get_datecode({1971})) &lt;br /&gt;
	self:assertEquals( &#039;MDhms&#039;,  get_datecode({nil,7,20,20,17,40,3,30})) &lt;br /&gt;
	self:assertEquals( &#039;MDhms&#039;,  get_datecode({nil,7,20,20,17,40})) &lt;br /&gt;
	self:assertEquals( &#039;MDhm&#039;,   get_datecode({nil,7,20,20,17})) &lt;br /&gt;
	self:assertEquals( &#039;MD&#039;,     get_datecode({nil,7,20,nil,17})) &lt;br /&gt;
	self:assertEquals( &#039;MD&#039;,     get_datecode({nil,7,20,20})) &lt;br /&gt;
	self:assertEquals( &#039;MD&#039;,     get_datecode({nil,7,20})) &lt;br /&gt;
	self:assertEquals( &#039;M&#039;,      get_datecode({nil,7,nil,20,17})) &lt;br /&gt;
	self:assertEquals( &#039;M&#039;,      get_datecode({nil,7,nil,20,nil})) &lt;br /&gt;
	self:assertEquals( &#039;M&#039;,      get_datecode({nil,7,nil,nil,17})) &lt;br /&gt;
	self:assertEquals( &#039;M&#039;,      get_datecode({nil,7})) &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function suite:test_1()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function suite:test_checkDateValidity()&lt;br /&gt;
	local check = p.checkDateValidity&lt;br /&gt;
	self:assertEquals(true,  check({1969,2,28}))&lt;br /&gt;
	self:assertEquals(false, check({1969,2,29}))&lt;br /&gt;
	self:assertEquals(true,  check({1968,2,29}))&lt;br /&gt;
	self:assertEquals(false, check({2010,2,29}))&lt;br /&gt;
	self:assertEquals(true,  check({2400,2,29}))&lt;br /&gt;
	self:assertEquals(true,  check({-3,2,29}))&lt;br /&gt;
	self:assertEquals(true,  check({100,2,29}))&lt;br /&gt;
	self:assertEquals(false, check({1969,2,30}))&lt;br /&gt;
	self:assertEquals(false, check({1969,13,30}))&lt;br /&gt;
	self:assertEquals(false, check({1969,nil,28}))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return suite&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=Module:DateI18n/sandbox&amp;diff=3959</id>
		<title>Module:DateI18n/sandbox</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=Module:DateI18n/sandbox&amp;diff=3959"/>
		<updated>2026-09-25T08:46:12Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: Created page with &amp;quot;--[[     __  __           _       _        ____        _       ___ _  ___          |  \/  | ___   __| |_   _| | ___ _|  _ \  __ _| |_ ___|_ _/ |( _ ) _ __    | |\/| |/ _ \ / _` | | | | |/ _ (_) | | |/ _` | __/ _ \| || |/ _ \| &amp;#039;_ \   | |  | | (_) | (_| | |_| | |  __/_| |_| | (_| | ||  __/| || | (_) | | | |  |_|  |_|\___/ \__,_|\__,_|_|\___(_)____/ \__,_|\__\___|___|_|\___/|_| |_|    This module is intended for processing of date strings.  Please do not modify this code wi...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;--[[  &lt;br /&gt;
  __  __           _       _        ____        _       ___ _  ___        &lt;br /&gt;
 |  \/  | ___   __| |_   _| | ___ _|  _ \  __ _| |_ ___|_ _/ |( _ ) _ __  &lt;br /&gt;
 | |\/| |/ _ \ / _` | | | | |/ _ (_) | | |/ _` | __/ _ \| || |/ _ \| &#039;_ \ &lt;br /&gt;
 | |  | | (_) | (_| | |_| | |  __/_| |_| | (_| | ||  __/| || | (_) | | | |&lt;br /&gt;
 |_|  |_|\___/ \__,_|\__,_|_|\___(_)____/ \__,_|\__\___|___|_|\___/|_| |_|&lt;br /&gt;
  &lt;br /&gt;
This module is intended for processing of date strings.&lt;br /&gt;
&lt;br /&gt;
Please do not modify this code without applying the changes first at Module:DateI18n/sandbox&lt;br /&gt;
and testing at Module:DateI18n/sandbox/testcases and Module talk:DateI18n/sandbox/testcases.&lt;br /&gt;
&lt;br /&gt;
Authors and maintainers:&lt;br /&gt;
* User:Parent5446 - original version of the function mimicking Template:ISOdate&lt;br /&gt;
* User:Jarekt - original version of the functions mimicking Template:Date &lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
-- =======================================&lt;br /&gt;
-- === Dependencies ======================&lt;br /&gt;
-- =======================================&lt;br /&gt;
&lt;br /&gt;
require(&#039;strict&#039;)&lt;br /&gt;
&lt;br /&gt;
-- =======================================&lt;br /&gt;
-- === Local Functions ===================&lt;br /&gt;
-- =======================================&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------&lt;br /&gt;
--[[ (copied from Module:Core)&lt;br /&gt;
Function allowing for consistent treatment of boolean-like wikitext input.&lt;br /&gt;
Inputs:&lt;br /&gt;
  1) val - value to be evaluated, outputs as a function of values:&lt;br /&gt;
		true  : true  (boolean), 1 (number), or strings: &amp;quot;yes&amp;quot;, &amp;quot;y&amp;quot;, &amp;quot;true&amp;quot;, &amp;quot;1&amp;quot;&lt;br /&gt;
		false : false (boolean), 0 (number), or strings: &amp;quot;no&amp;quot;, &amp;quot;n&amp;quot;, &amp;quot;false&amp;quot;, &amp;quot;0&amp;quot;&lt;br /&gt;
  2) default - value to return otherwise&lt;br /&gt;
See Also: It works similarly to Module:Yesno&lt;br /&gt;
]]&lt;br /&gt;
local function yesno(val, default)&lt;br /&gt;
	if type(val) == &#039;boolean&#039; then&lt;br /&gt;
		return val&lt;br /&gt;
	elseif type(val) == &#039;number&#039; then&lt;br /&gt;
		val = tostring(val)&lt;br /&gt;
	end&lt;br /&gt;
	if type(val) == &#039;string&#039; then&lt;br /&gt;
		local LUT = {&lt;br /&gt;
			yes=true , y=true , [&#039;true&#039;] =true , t=true , [&#039;1&#039;]=true , on =true,&lt;br /&gt;
			no =false, n=false, [&#039;false&#039;]=false, f=false, [&#039;0&#039;]=false, off=false }&lt;br /&gt;
	    val = LUT[mw.ustring.lower(val)]  -- put in lower case&lt;br /&gt;
	    if (val~=nil) then&lt;br /&gt;
			return val&lt;br /&gt;
		end&lt;br /&gt;
    end&lt;br /&gt;
    return default&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
---------------------------------------------------------------------------------------&lt;br /&gt;
-- trim leading zeros in years prior to year 1000&lt;br /&gt;
-- INPUT:&lt;br /&gt;
--  * datestr   - translated date string &lt;br /&gt;
--  * lang      - language of translation&lt;br /&gt;
-- OUTPUT:&lt;br /&gt;
--  * datestr - updated date string &lt;br /&gt;
&lt;br /&gt;
local function trimYear(datestr, year, lang)&lt;br /&gt;
	local yearStr0, yearStr1, yearStr2, zeroStr&lt;br /&gt;
	yearStr0 = string.format(&#039;%04i&#039;, year ) -- 4 digit year in standard form &amp;quot;0123&amp;quot;&lt;br /&gt;
	yearStr1 = mw.language.new(lang):formatDate( &#039;Y&#039;, yearStr0) -- same as calling {{#time}} parser function&lt;br /&gt;
	--yearStr1 = mw.getCurrentFrame():callParserFunction( &amp;quot;#time&amp;quot;, { &#039;Y&#039;, yearStr0, lang } ) -- translate to a language &lt;br /&gt;
	if yearStr0==yearStr1 then -- most of languages use standard form of year &lt;br /&gt;
		yearStr2 = tostring(year)&lt;br /&gt;
	else -- some languages use different characters for numbers&lt;br /&gt;
		yearStr2 = yearStr1&lt;br /&gt;
		zeroStr = mw.ustring.sub(yearStr1,1,1) -- get &amp;quot;0&amp;quot; in whatever language&lt;br /&gt;
		for i=1,3 do -- trim leading zeros&lt;br /&gt;
			if mw.ustring.sub(yearStr2,1,1)==zeroStr then&lt;br /&gt;
				yearStr2 = mw.ustring.sub(yearStr2, 2, 5-i)&lt;br /&gt;
			else&lt;br /&gt;
				break&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return string.gsub(datestr, yearStr1, yearStr2 ) -- in datestr replace long year with trimmed one&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---------------------------------------------------------------------------------------&lt;br /&gt;
-- Look up proper format string to be passed to {{#time}} parser function&lt;br /&gt;
-- INPUTS:&lt;br /&gt;
--  * datecode: YMDhms, YMDhm, YMD, YM, Y, MDhms, MDhm, MD, or M&lt;br /&gt;
--  * day     : Number between 1 and 31 (not needed for most languages)&lt;br /&gt;
--  * lang    : language&lt;br /&gt;
-- OUTPUT:&lt;br /&gt;
--  * dFormat : input to {{#time}} function&lt;br /&gt;
local function getDateFormat(datecode, day, lang)&lt;br /&gt;
	local function parseFormat(dFormat, day)&lt;br /&gt;
		if dFormat:find(&#039;default&#039;) and #dFormat&amp;gt;10 then&lt;br /&gt;
			-- Special (and messy) case of dFormat code depending on a day number, where data is a&lt;br /&gt;
			-- JSON-encoded table {”default”:”*”,”dDD”:”*”} including fields for specific 2-digit days.&lt;br /&gt;
			-- Change curly double quotes (possibly used for easier editing in tabular data) in dFormat&lt;br /&gt;
			-- to straight ASCII double quotes (required for parsing of this JSON-encoded table).&lt;br /&gt;
			local D = mw.text.jsonDecode(mw.ustring.gsub(dFormat, &#039;[„“‟”]&#039;, &#039;&amp;quot;&#039;)) --com = mw.dumpObject(D)&lt;br /&gt;
			-- If the desired day is not in that JSON table, then use its &amp;quot;default&amp;quot; case.&lt;br /&gt;
			dFormat = D[string.format(&#039;d%02i&#039;, day)] or D.default&lt;br /&gt;
            -- Change ASCII single quotes to ASCII double quotes used for {{#time}} marking.&lt;br /&gt;
            -- Apostrophes needed in plain-text must not use ASCII single quotes but curly apostrophe&lt;br /&gt;
            -- e.g. { ‟default”: ‟j”, ‟d01”: ‟j’&#039;o&#039;” }, not { ‟default”: ‟j”, ‟d01”: ‟j&#039;&#039;o&#039;” }.&lt;br /&gt;
		end&lt;br /&gt;
		dFormat = dFormat:gsub(&amp;quot;&#039;&amp;quot;, &#039;&amp;quot;&#039;)&lt;br /&gt;
		return dFormat&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local T = {}&lt;br /&gt;
	local tab = mw.ext.data.get(&#039;DateI18n.tab&#039;, lang)&lt;br /&gt;
	for _, row in pairs(tab.data) do -- convert the output into a dictionary table&lt;br /&gt;
		local id, _, msg = unpack(row)&lt;br /&gt;
		T[id] = msg&lt;br /&gt;
	end&lt;br /&gt;
    -- Compatibility of legacy data using &#039;HMS&#039; or &#039;HM&#039;, where &#039;M&#039; is ambiguous&lt;br /&gt;
    T.YMDhms = T.YMDhms or T.YMDHMS&lt;br /&gt;
    T.YMDhm  = T.YMDhm  or T.YMDHM&lt;br /&gt;
    datecode = datecode == &#039;YMDHMS&#039; and &#039;YMDhms&#039; or datecode == &#039;YMDHM&#039; and &#039;YMDhm&#039; or datecode&lt;br /&gt;
&lt;br /&gt;
	local dFormat = T[datecode]&lt;br /&gt;
	if dFormat == &#039;default&#039; and (datecode == &#039;YMDhms&#039; or datecode == &#039;YMDhm&#039;)  then &lt;br /&gt;
		-- For most languages adding hour:minute:second is done by adding &amp;quot;, HH:ii:ss to the &lt;br /&gt;
		-- day precission date, those languages are skipped in DateI18n.tab and default to &lt;br /&gt;
		-- English which stores word &amp;quot;default&amp;quot;&lt;br /&gt;
		dFormat = parseFormat(T[&#039;YMD&#039;], day).. &#039;, H:i&#039;&lt;br /&gt;
		if datecode == &#039;YMDhms&#039; then&lt;br /&gt;
			dFormat = dFormat .. &#039;:s&#039;&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		dFormat = parseFormat(dFormat, day)&lt;br /&gt;
	end&lt;br /&gt;
	return dFormat&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---------------------------------------------------------------------------------------&lt;br /&gt;
-- Look up proper format string to be passed to {{#time}} parser function&lt;br /&gt;
-- INPUTS:&lt;br /&gt;
--  * month : month number&lt;br /&gt;
--  * case  : gramatic case abbriviation, like &amp;quot;ins&amp;quot;, &amp;quot;loc&amp;quot;&lt;br /&gt;
--  * lang  : language&lt;br /&gt;
-- OUTPUT:&lt;br /&gt;
--  * dFormat : input to {{#time}} function&lt;br /&gt;
local function MonthCase(month, case, lang)&lt;br /&gt;
	if month == nil or case == nil then&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
	local T = {{},{},{},{},{},{},{},{},{},{},{},{}}&lt;br /&gt;
	local tab = mw.ext.data.get(&#039;I18n/MonthCases.tab&#039;, lang)&lt;br /&gt;
	for _, row in pairs(tab.data) do&lt;br /&gt;
		local mth, cs, msg = unpack(row)&lt;br /&gt;
		T[mth][cs] = msg&lt;br /&gt;
	end&lt;br /&gt;
	return T[month][case]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- ==================================================&lt;br /&gt;
-- === External functions ===========================&lt;br /&gt;
-- ==================================================&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
-- ===========================================================================&lt;br /&gt;
-- === Functions accesible from the outside to allow unit-testing&lt;br /&gt;
-- === Please do not use directly as they could change in the future&lt;br /&gt;
-- ===========================================================================&lt;br /&gt;
&lt;br /&gt;
---------------------------------------------------------------------------------------&lt;br /&gt;
-- Single string replacement that ignores part of the string in &amp;quot;...&amp;quot;&lt;br /&gt;
function p.strReplace(String, old, new)&lt;br /&gt;
	if String:find(&#039;&amp;quot;&#039;) then&lt;br /&gt;
		local T={}&lt;br /&gt;
		for i, str in ipairs(mw.text.split( String, &#039;&amp;quot;&#039;, true )) do&lt;br /&gt;
			if i%2==1 then&lt;br /&gt;
				str = str:gsub(old, new, 1)&lt;br /&gt;
			end&lt;br /&gt;
			table.insert(T, str)&lt;br /&gt;
		end&lt;br /&gt;
		return table.concat(T,&#039;&amp;quot;&#039;)&lt;br /&gt;
	else&lt;br /&gt;
		return String:gsub(old, new, 1)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---------------------------------------------------------------------------------------&lt;br /&gt;
-- process datevec&lt;br /&gt;
-- INPUT:&lt;br /&gt;
--  * datevec - Array of {year,month,day,hour,minute,second, tzhour, tzmin} containing broken &lt;br /&gt;
--    down date-time component strings or numbers&lt;br /&gt;
-- OUTPUT:&lt;br /&gt;
--  * datenum - same array but holding only numbers or nuls&lt;br /&gt;
function p.clean_datevec(datevec)&lt;br /&gt;
	-- create datecode based on which variables are provided and check for out-of-bound values&lt;br /&gt;
	&lt;br /&gt;
	-- check special case of month provided as a name&lt;br /&gt;
	local month = datevec[2]&lt;br /&gt;
	if type(month) == &#039;string&#039; and month ~= &#039;&#039; and not tonumber(month) then&lt;br /&gt;
		-- When the month is not a number, check if it&#039;s a month name in the project&#039;s language.&lt;br /&gt;
		datevec[2] = mw.getContentLanguage():formatDate(&#039;n&#039;, month)&lt;br /&gt;
	end&lt;br /&gt;
		&lt;br /&gt;
	-- check bounds&lt;br /&gt;
	local maxval = {  1/0, 12, 31, 23, 59, 59,  23, 59 } -- max values (or  1/0=+inf) for year, month, day, hour, minute, second, tzhour, tzmin&lt;br /&gt;
	local minval = { -1/0, 01, 01, 00, 00, 00, -23, 00 } -- min values (or -1/0=-inf) for year, month, ...&lt;br /&gt;
	local datenum  = {} -- date-time encoded as a vector = [year, month, ... , second, tzhour, tzmin]&lt;br /&gt;
	for i = 1, 8 do&lt;br /&gt;
        local val = tonumber(datevec[i])&lt;br /&gt;
        if val and val &amp;gt;= minval[i] and val &amp;lt;= maxval[i] then -- These tests work with infinite min/max values.&lt;br /&gt;
		    datenum[i] = val&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- leap second&lt;br /&gt;
	if tonumber(datevec[6]) == 60 then -- leap second &#039;60&#039; is valid only at end of 23:59 UTC, on 30 June or 31 December of specific years&lt;br /&gt;
--		datenum[6] = 60 &lt;br /&gt;
		local MDhm = table.concat({unpack(datenum,2,5)}, &#039;,&#039;)&lt;br /&gt;
	    if (MDhm == table.concat({6, 30, 23, 59}, &#039;,&#039;)) or (MDhm == table.concat({12, 31, 23, 59}, &#039;,&#039;)) then&lt;br /&gt;
		   datenum[6] = 60 &lt;br /&gt;
	    end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return datenum&lt;br /&gt;
end&lt;br /&gt;
	&lt;br /&gt;
---------------------------------------------------------------------------------------&lt;br /&gt;
-- process datevec&lt;br /&gt;
-- INPUT:&lt;br /&gt;
--  * datenum - Array of {year,month,day,hour,minute,second, tzhour, tzmin} as numbers or nuls&lt;br /&gt;
-- OUTPUT:&lt;br /&gt;
--  * timeStamp - date string in the format taken by mw.language:formatDate lua function and {{#time}} parser function&lt;br /&gt;
--       https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#mw.language:formatDate&lt;br /&gt;
--       https://www.mediawiki.org/wiki/Help:Extension:ParserFunctions#.23time&lt;br /&gt;
--  * datecode - a code specifying content of the array where Y&#039; is year, &#039;M&#039; is month,&lt;br /&gt;
--     &#039;D&#039; is day, &#039;h&#039; is hour, &#039;m&#039; minute, &#039;s&#039; is second.&lt;br /&gt;
--     Output has to be one of YMDhms, YMDhm, YMD, YM, Y, MDhms, MDhm, MD, M.&lt;br /&gt;
function p.getTimestamp(datenum)&lt;br /&gt;
&lt;br /&gt;
	-- create datecode based on datenum&lt;br /&gt;
	local codes  = { &#039;Y&#039;, &#039;M&#039;, &#039;D&#039;, &#039;h&#039;, &#039;m&#039;, &#039;s&#039;} &lt;br /&gt;
	local datecode = &#039;&#039; -- a string signifying which combination of variables was provided&lt;br /&gt;
	for i, c in ipairs(codes) do&lt;br /&gt;
		datecode = datecode .. (datenum[i] and c or &#039;&#039;) -- if datenum[i] than append codes[i] to datecode&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- create timestamp string (for example 2000-02-20 02:20:20) based on which variables were provided&lt;br /&gt;
	local timeStamp&lt;br /&gt;
    -- date starting by a year&lt;br /&gt;
	if datecode == &#039;YMDhms&#039; then&lt;br /&gt;
		timeStamp = string.format(&#039;%04i-%02i-%02i %02i:%02i:%02i&#039;, datenum[1], datenum[2], datenum[3], datenum[4], datenum[5], datenum[6] )&lt;br /&gt;
	elseif datecode == &#039;YMDhm&#039; then&lt;br /&gt;
		timeStamp = string.format(&#039;%04i-%02i-%02i %02i:%02i&#039;, datenum[1], datenum[2], datenum[3], datenum[4], datenum[5] )&lt;br /&gt;
	elseif datecode:sub(1,3)==&#039;YMD&#039; then&lt;br /&gt;
		timeStamp = string.format(&#039;%04i-%02i-%02i&#039;, datenum[1], datenum[2], datenum[3] )&lt;br /&gt;
		datecode  = &#039;YMD&#039; -- &#039;YMDhms&#039;, &#039;YMDhm&#039; and &#039;YMD&#039; are the only supported format starting with &#039;YMD&#039;; all others will be converted to &#039;YMD&#039;.&lt;br /&gt;
	elseif datecode:sub(1,2) == &#039;YM&#039; then&lt;br /&gt;
		timeStamp = string.format(&#039;%04i-%02i&#039;, datenum[1], datenum[2] )&lt;br /&gt;
		datecode  = &#039;YM&#039; &lt;br /&gt;
	elseif datecode:sub(1,1)==&#039;Y&#039; then&lt;br /&gt;
		timeStamp = string.format(&#039;%04i&#039;, datenum[1] )&lt;br /&gt;
		datecode  = &#039;Y&#039; &lt;br /&gt;
    -- date starting by a month (the implied year is 2000)&lt;br /&gt;
	elseif datecode== &#039;MDhms&#039; then&lt;br /&gt;
		timeStamp = string.format(&#039;%04i-%02i-%02i %02i:%02i:%02i&#039;, 2000, datenum[2], datenum[3], datenum[4], datenum[5], datenum[6] )&lt;br /&gt;
	elseif datecode == &#039;MDhm&#039; then&lt;br /&gt;
		timeStamp = string.format(&#039;%04i-%02i-%02i %02i:%02i&#039;, 2000, datenum[2], datenum[3], datenum[4], datenum[5] )&lt;br /&gt;
	elseif datecode:sub(1,2) == &#039;MD&#039; then&lt;br /&gt;
		timeStamp = string.format(&#039;%04i-%02i-%02i&#039;, 2000, datenum[2], datenum[3] )&lt;br /&gt;
		datecode = &#039;MD&#039; -- &#039;MDhms&#039;, &#039;MDhm&#039; and &#039;MD&#039; are the only supported format starting with &#039;MD&#039;; all others will be converted to &#039;MD&#039;&lt;br /&gt;
	elseif datecode:sub(1,1) == &#039;M&#039; then -- Ambiguous: could mean minutes, but here means month (when parsed as a name/abbrev, not as a number).&lt;br /&gt;
		timeStamp = string.format(&#039;%04i-%02i-%02i&#039;, 2000, datenum[2], 1 )&lt;br /&gt;
		datecode  = &#039;M&#039; &lt;br /&gt;
    -- other possible but unrecognized formats (e.g. &#039;DHis&#039;, &#039;DHi&#039;, &#039;D&#039;, &#039;His&#039;, &#039;Hi&#039;);&lt;br /&gt;
    -- note that &#039;Dh&#039;, &#039;D&#039;, &#039;h&#039;, &#039;s&#039; may eventually work, but not &#039;m&#039; for minute only, which is ambiguous with &#039;M&#039; for month only.&lt;br /&gt;
	else&lt;br /&gt;
		timeStamp = nil -- format not supported&lt;br /&gt;
	end&lt;br /&gt;
	return timeStamp, datecode&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function isValidLangCode(lang)&lt;br /&gt;
	if not lang then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
	lang = mw.text.trim(lang)&lt;br /&gt;
	return lang ~= &#039;&#039; and lang ~= &#039;⧼Lang⧽&#039; and mw.language.isValidCode(lang)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- ===========================================================================&lt;br /&gt;
-- === Version of the function to be called from other LUA codes&lt;br /&gt;
-- ===========================================================================&lt;br /&gt;
&lt;br /&gt;
--[[ ========================================================================================&lt;br /&gt;
Date&lt;br /&gt;
 &lt;br /&gt;
This function is the core part of the ISOdate template. &lt;br /&gt;
 &lt;br /&gt;
Usage:&lt;br /&gt;
  local Date = require(&#039;Module:DateI18n&#039;)._Date&lt;br /&gt;
  local dateStr = Date({2020, 12, 30, 12, 20, 11}, lang)&lt;br /&gt;
 &lt;br /&gt;
Parameters:&lt;br /&gt;
  * {year,month,day,hour,minute,second, tzhour, tzmin}: broken down date-time component strings or numbers&lt;br /&gt;
		tzhour, tzmin are timezone offsets from UTC, hours and minutes&lt;br /&gt;
  * lang: The language to display it in&lt;br /&gt;
  * case: Language format (genitive, etc.) for some languages&lt;br /&gt;
  * class: CSS class for the &amp;lt;time&amp;gt; node, use &amp;quot;&amp;quot; for no metadata at all&lt;br /&gt;
]]&lt;br /&gt;
function p._Date(datevec, lang, case, class, trim_year)&lt;br /&gt;
	-- make sure inputs are in the right format&lt;br /&gt;
	&lt;br /&gt;
	-- set language&lt;br /&gt;
	if not isValidLangCode(lang) then&lt;br /&gt;
		-- get user&#039;s chosen language&lt;br /&gt;
		-- equivalent to {{int:lang}}&lt;br /&gt;
		lang = mw.getCurrentFrame():callParserFunction(&amp;quot;int&amp;quot;, &amp;quot;lang&amp;quot;)&lt;br /&gt;
		&lt;br /&gt;
		if not isValidLangCode(lang) then&lt;br /&gt;
			-- if that doesn&#039;t work, use the project language&lt;br /&gt;
			-- this is useful on projects which import this module from Commons&lt;br /&gt;
			lang = mw.language.getContentLanguage().code&lt;br /&gt;
			&lt;br /&gt;
			if not isValidLangCode(lang) then&lt;br /&gt;
				-- if that doesn&#039;t work, use English&lt;br /&gt;
				lang = &amp;quot;en&amp;quot;&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if lang == &#039;be-tarask&#039; then&lt;br /&gt;
		lang = &#039;be-x-old&#039;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- process datevec and extract timeStamp and datecode strings as well as numeric datenum array&lt;br /&gt;
	local datenum  = p.clean_datevec(datevec)&lt;br /&gt;
	local year, month, day = datenum[1], datenum[2], datenum[3]&lt;br /&gt;
	local timeStamp, datecode = p.getTimestamp(datenum)&lt;br /&gt;
	if not timeStamp then -- something went wrong in parserDatevec&lt;br /&gt;
		return &#039;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	-- Commons [[Data:DateI18n.tab]] page stores prefered formats for diferent &lt;br /&gt;
	-- languages and datecodes (specifying year-month-day or just year of month-day, etc)&lt;br /&gt;
	-- Look up country specific format input to {{#time}} function&lt;br /&gt;
	local dFormat = getDateFormat(datecode, day, lang)&lt;br /&gt;
&lt;br /&gt;
	-- By default the gramatical case is not specified (case==&#039;&#039;) allowing the format to be specified &lt;br /&gt;
	-- in [[Data:DateI18n.tab]]. You can overwrite the default grammatical case of the month by &lt;br /&gt;
	-- specifying &amp;quot;case&amp;quot; variable. This is needed mostly by Slavic languages to create more complex &lt;br /&gt;
	-- phrases as it is done in [[c:Module:Complex date]]&lt;br /&gt;
	case = case or &#039;&#039;&lt;br /&gt;
	if (lang==&#039;qu&#039; or lang==&#039;qug&#039;) and case==&#039;nom&#039; then&lt;br /&gt;
		-- Special case related to Quechua and Kichwa languages. The form in the I18n is&lt;br /&gt;
		--  Genitive case with suffix &amp;quot;pi&amp;quot; added to month names provided by {#time}}&lt;br /&gt;
		-- in Nominative case that &amp;quot;pi&amp;quot; should be removed&lt;br /&gt;
		-- see https://commons.wikimedia.org/wiki/Template_talk:Date#Quechua from 2014&lt;br /&gt;
		dFormat = dFormat:gsub(&#039;F&amp;quot;pi&amp;quot;&#039;, &#039;F&#039;)&lt;br /&gt;
	elseif case == &#039;gen&#039; then&lt;br /&gt;
		dFormat = p.strReplace(dFormat, &amp;quot;F&amp;quot;, &amp;quot;xg&amp;quot;)&lt;br /&gt;
	elseif case == &#039;nom&#039; then&lt;br /&gt;
		dFormat = p.strReplace(dFormat, &amp;quot;xg&amp;quot;, &amp;quot;F&amp;quot;)&lt;br /&gt;
	elseif case ~= &#039;&#039; and month ~= nil then&lt;br /&gt;
		-- see is page [[Data:I18n/MonthCases.tab]] on Commons have name of the month &lt;br /&gt;
		-- in specific gramatic case in desired language. If we have it than replace &lt;br /&gt;
		-- &amp;quot;F&amp;quot; and xg&amp;quot; in dFormat&lt;br /&gt;
		local monthMsg = MonthCase(month, case, lang)&lt;br /&gt;
		if  monthMsg and monthMsg ~= &#039;&#039; then -- make sure it exists&lt;br /&gt;
			dFormat = p.strReplace(dFormat, &#039;F&#039;,  &#039;&amp;quot;&#039;..monthMsg..&#039;&amp;quot;&#039;) -- replace default month with month name we already looked up&lt;br /&gt;
			dFormat = p.strReplace(dFormat, &#039;xg&#039;, &#039;&amp;quot;&#039;..monthMsg..&#039;&amp;quot;&#039;)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
    -- Translate the date using specified format.&lt;br /&gt;
	-- See https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#mw.language:formatDate and &lt;br /&gt;
	-- https://www.mediawiki.org/wiki/Help:Extension:ParserFunctions##time for explanation of the format&lt;br /&gt;
	local langObj = mw.language.new(lang)&lt;br /&gt;
	local datestr = langObj:formatDate(dFormat, timeStamp) -- same as using {{#time}} parser function&lt;br /&gt;
	&lt;br /&gt;
	-- Special case related to Thai solar calendar: prior to 1940 new-year was at different time of year,&lt;br /&gt;
	-- so just year (datecode == &#039;Y&#039;) is ambiguous and is replaced by &amp;quot;YYYY or YYYY&amp;quot; phrase&lt;br /&gt;
	if lang==&#039;th&#039; and datecode==&#039;Y&#039; and year&amp;lt;=1940 then&lt;br /&gt;
		datestr = string.format(&#039;%04i หรือ %04i&#039;, year+542, year+543 ) &lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- If year &amp;lt; 1000 than either keep the date padded to the length of 4 digits or trim it.&lt;br /&gt;
	-- Decide if the year will stay padded with zeros (for years in 0-999 range).&lt;br /&gt;
	if year and year &amp;lt; 1000 then&lt;br /&gt;
		trim_year = yesno(trim_year, trim_year or &#039;100-999&#039;)&lt;br /&gt;
		if type(trim_year) == &#039;string&#039; then&lt;br /&gt;
			-- If `trim_year` not a simple boolean, then it&#039;s a range of dates.&lt;br /&gt;
			-- For example &#039;100-999&#039; means to pad 1-or-2-digit years to be 4-digit long, while keeping 3-digit years as is.&lt;br /&gt;
			local YMin, YMax = trim_year:match( &#039;(%d+)-(%d+)&#039; )&lt;br /&gt;
			trim_year = YMin and year &amp;gt;= tonumber(YMin) and year &amp;lt;= tonumber(YMax)&lt;br /&gt;
		end&lt;br /&gt;
		if trim_year then&lt;br /&gt;
			datestr = trimYear(datestr, year, lang) -- in datestr replace long year with trimmed one&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Append a timezone if present (after the hour and minute of the day).&lt;br /&gt;
	if datenum[7] and (datecode:sub(1, 5) == &#039;YMDhm&#039; or datecode:sub(1, 4) == &#039;MDhm&#039;) then&lt;br /&gt;
		-- Use {{#time}} parser function to create timezone string, so that we use the correct character set.&lt;br /&gt;
		local sign = (datenum[7]&amp;lt;0) and &#039;−&#039; or &#039;+&#039;&lt;br /&gt;
		timeStamp = string.format(&amp;quot;2000-01-01 %02i:%02i:00&amp;quot;, math.abs(datenum[7]), datenum[8] or 0)&lt;br /&gt;
		local timezone = langObj:formatDate(&#039;H:i&#039;, timeStamp) -- same as using {{#time}} parser function&lt;br /&gt;
		datestr = string.format(&amp;quot;%s %s%s&amp;quot;, datestr, sign, timezone )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- HTML formating of date string and tagging for microformats (only for absolute dates with a year).&lt;br /&gt;
	if class and class ~= &#039;&#039; and class ~= &#039;-&#039; and datecode:sub(1,1) == &#039;Y&#039; then &lt;br /&gt;
		local pat = &#039;&amp;lt;time class=&amp;quot;%s&amp;quot; datetime=&amp;quot;%s&amp;quot; lang=&amp;quot;%s&amp;quot; dir=&amp;quot;%s&amp;quot; style=&amp;quot;white-space:nowrap&amp;quot;&amp;gt;%s&amp;lt;/time&amp;gt;&#039;&lt;br /&gt;
		datestr = pat:format(class, timeStamp, lang, langObj:getDir(), datestr)&lt;br /&gt;
	end&lt;br /&gt;
	return datestr&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- ===========================================================================&lt;br /&gt;
-- === Version of the function to be called from template namespace&lt;br /&gt;
-- ===========================================================================&lt;br /&gt;
&lt;br /&gt;
--[[ ========================================================================================&lt;br /&gt;
Date&lt;br /&gt;
 &lt;br /&gt;
This function is the core part of the ISOdate template. &lt;br /&gt;
 &lt;br /&gt;
Usage:&lt;br /&gt;
{{#invoke:DateI18n|Date|year=|month=|day=|hour=|minute=|second=|tzhour=|tzmin=|lang=en}}&lt;br /&gt;
 &lt;br /&gt;
Parameters:&lt;br /&gt;
  * year, month, day, hour, minute, second: broken down date-time component strings&lt;br /&gt;
  * tzhour, tzmin: timezone offset from UTC, hours and minutes&lt;br /&gt;
  * lang: The language to display it in&lt;br /&gt;
  * case: Language format (genitive, etc.) for some languages&lt;br /&gt;
  * class: CSS class for the &amp;lt;time&amp;gt; node, use &amp;quot;&amp;quot; for no metadata at all&lt;br /&gt;
]]&lt;br /&gt;
function p.Date(frame)&lt;br /&gt;
	-- get args&lt;br /&gt;
	local args = {}&lt;br /&gt;
	for key, value in pairs(frame.args) do &lt;br /&gt;
		local trimmed_key = string.gsub(string.lower(mw.text.trim(key)), &#039; &#039;, &#039;_&#039;)&lt;br /&gt;
		local trimmed_value = mw.text.trim(value)&lt;br /&gt;
		if trimmed_key ~= &#039;class&#039; and trimmed_value == &#039;&#039; then&lt;br /&gt;
			trimmed_value = nil&lt;br /&gt;
		end&lt;br /&gt;
		args[trimmed_key] = trimmed_value&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- default values&lt;br /&gt;
	-- Allows to set the html class of the time node where the date is included. This is useful for microformats.&lt;br /&gt;
	args.class = args.class or &#039;-&#039;&lt;br /&gt;
	if args.class == &#039;&#039; then&lt;br /&gt;
		args.class = &#039;dtstart&#039;&lt;br /&gt;
	end&lt;br /&gt;
	-- By default, pad one- and two-digit years to be 4 digits long, while keeping three-digit years as-is.&lt;br /&gt;
	args.trim_year = args.trim_year or &#039;100-999&#039;&lt;br /&gt;
	&lt;br /&gt;
	return p._Date(	&lt;br /&gt;
		{args.year, args.month, args.day, args.hour, args.minute, args.second, args.tzhour, args.tzmin},&lt;br /&gt;
		args.lang,&lt;br /&gt;
		args.case,	&lt;br /&gt;
		args.class,&lt;br /&gt;
		args.trim_year&lt;br /&gt;
	)	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.getDateFormat(frame)&lt;br /&gt;
	-- get args&lt;br /&gt;
	local args = {}&lt;br /&gt;
	for key, value in pairs(frame.args) do &lt;br /&gt;
		local trimmed_key = string.gsub(string.lower(mw.text.trim(key)), &#039; &#039;, &#039;_&#039;)&lt;br /&gt;
		local trimmed_value = mw.text.trim(value)&lt;br /&gt;
		if trimmed_key ~= &#039;class&#039; and trimmed_value == &#039;&#039; then&lt;br /&gt;
			trimmed_value = nil&lt;br /&gt;
		end&lt;br /&gt;
		args[trimmed_key] = trimmed_value&lt;br /&gt;
	end&lt;br /&gt;
	return getDateFormat(args.datecode, args.day, args.lang)&lt;br /&gt;
end&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=Module:Int&amp;diff=3958</id>
		<title>Module:Int</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=Module:Int&amp;diff=3958"/>
		<updated>2026-09-25T08:42:22Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: Created page with &amp;quot;-- This is a helper module for Template:Int  local trim = mw.text.trim local isValidCode = mw.language.isValidCode local messageNew = mw.message.new  local frameCurrent = mw.getCurrentFrame() local preprocess = frameCurrent.preprocess local pageLang = preprocess(frameCurrent, &amp;#039;{{PAGELANGUAGE}}&amp;#039;)  local export = {}  function export.renderIntMessage(frame) 	local args = frame.args 	local msgId = trim(args[1]) 	local pargs = (frame:getParent() or {}).args 	local msgArgs...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-- This is a helper module for [[Template:Int]]&lt;br /&gt;
&lt;br /&gt;
local trim = mw.text.trim&lt;br /&gt;
local isValidCode = mw.language.isValidCode&lt;br /&gt;
local messageNew = mw.message.new&lt;br /&gt;
&lt;br /&gt;
local frameCurrent = mw.getCurrentFrame()&lt;br /&gt;
local preprocess = frameCurrent.preprocess&lt;br /&gt;
local pageLang = preprocess(frameCurrent, &#039;{{PAGELANGUAGE}}&#039;)&lt;br /&gt;
&lt;br /&gt;
local export = {}&lt;br /&gt;
&lt;br /&gt;
function export.renderIntMessage(frame)&lt;br /&gt;
	local args = frame.args&lt;br /&gt;
	local msgId = trim(args[1])&lt;br /&gt;
	local pargs = (frame:getParent() or {}).args&lt;br /&gt;
	local msgArgs = {}&lt;br /&gt;
	for k, v in pairs(pargs) do&lt;br /&gt;
		local n = tonumber(k) or 0&lt;br /&gt;
		if n &amp;gt;= 2 then&lt;br /&gt;
			msgArgs[n - 1] = trim(v)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	local lang = args.lang&lt;br /&gt;
	if not lang or lang == &#039;&#039; or not isValidCode(lang) then&lt;br /&gt;
		lang = pageLang&lt;br /&gt;
	end&lt;br /&gt;
	local msg = messageNew(msgId, msgArgs):inLanguage(lang)&lt;br /&gt;
	if lang == &#039;qqx&#039; or msg:exists() then&lt;br /&gt;
			return msg:isDisabled() and (args.missing or &#039;&#039;) or preprocess(frameCurrent, msg:plain())&lt;br /&gt;
	else&lt;br /&gt;
		return args.missing ~= &#039;&#039; and args.missing or &#039;⧼&#039; .. msgId .. &#039;⧽&#039;&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return export&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=Template:Int&amp;diff=3957</id>
		<title>Template:Int</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=Template:Int&amp;diff=3957"/>
		<updated>2026-09-25T08:41:44Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: Created page with &amp;quot;&amp;lt;onlyinclude&amp;gt;{{&amp;lt;includeonly&amp;gt;safesubst:&amp;lt;/includeonly&amp;gt;#invoke:Int|renderIntMessage|{{{1}}}|missing={{{missing|}}}|lang={{{lang|}}}}}&amp;lt;/onlyinclude&amp;gt; {{Documentation}} &amp;lt;!-- Add categories to the /doc subpage and interwikis in Wikidata, not here! --&amp;gt;&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;onlyinclude&amp;gt;{{&amp;lt;includeonly&amp;gt;safesubst:&amp;lt;/includeonly&amp;gt;#invoke:Int|renderIntMessage|{{{1}}}|missing={{{missing|}}}|lang={{{lang|}}}}}&amp;lt;/onlyinclude&amp;gt;&lt;br /&gt;
{{Documentation}}&lt;br /&gt;
&amp;lt;!-- Add categories to the /doc subpage and interwikis in Wikidata, not here! --&amp;gt;&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=File:Button_ang.png&amp;diff=4249</id>
		<title>File:Button ang.png</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=File:Button_ang.png&amp;diff=4249"/>
		<updated>2026-09-18T14:16:47Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== اجازه‌نامه ==&lt;br /&gt;
{{Ombox&lt;br /&gt;
| type      = style&lt;br /&gt;
| image     = [[پرونده:Emblem-important.svg]]&lt;br /&gt;
| style     = width: 800px; &lt;br /&gt;
| textstyle = &lt;br /&gt;
| text      = این تصویر از &#039;&#039;انبار ویکی‌پدیا&#039;&#039; که با مجوزهای حق نشر آزاد مختلف منتشر کننده آثار است، به اینجا آمده است و انتقال دهنده مجوز دقیقی برای انتشار آن گزارش نکرده‌است. برای اطلاعات بیشتر باید به &#039;&#039;انبار ویکی‌پدیا&#039;&#039; مراجعه کنید. احتمال دارد این تصویر به دلایل &#039;&#039;&#039;نقض حق تکثیر&#039;&#039;&#039; در اینجا و حتی انبار ویکی‌پدیا حذف بشود.&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=File:Button_m.png&amp;diff=4252</id>
		<title>File:Button m.png</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=File:Button_m.png&amp;diff=4252"/>
		<updated>2026-09-18T14:16:11Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== اجازه‌نامه ==&lt;br /&gt;
{{Ombox&lt;br /&gt;
| type      = style&lt;br /&gt;
| image     = [[پرونده:Emblem-important.svg]]&lt;br /&gt;
| style     = width: 800px; &lt;br /&gt;
| textstyle = &lt;br /&gt;
| text      = این تصویر از &#039;&#039;انبار ویکی‌پدیا&#039;&#039; که با مجوزهای حق نشر آزاد مختلف منتشر کننده آثار است، به اینجا آمده است و انتقال دهنده مجوز دقیقی برای انتشار آن گزارش نکرده‌است. برای اطلاعات بیشتر باید به &#039;&#039;انبار ویکی‌پدیا&#039;&#039; مراجعه کنید. احتمال دارد این تصویر به دلایل &#039;&#039;&#039;نقض حق تکثیر&#039;&#039;&#039; در اینجا و حتی انبار ویکی‌پدیا حذف بشود.&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=File:Abdulbaha_knighting.jpg&amp;diff=4025</id>
		<title>File:Abdulbaha knighting.jpg</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=File:Abdulbaha_knighting.jpg&amp;diff=4025"/>
		<updated>2026-09-18T14:06:05Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== اجازه‌نامه ==&lt;br /&gt;
{{Ombox&lt;br /&gt;
| type      = style&lt;br /&gt;
| image     = [[پرونده:Emblem-important.svg]]&lt;br /&gt;
| style     = width: 800px; &lt;br /&gt;
| textstyle = &lt;br /&gt;
| text      = این تصویر از &#039;&#039;انبار ویکی‌پدیا&#039;&#039; که با مجوزهای حق نشر آزاد مختلف منتشر کننده آثار است، به اینجا آمده است و انتقال دهنده مجوز دقیقی برای انتشار آن گزارش نکرده‌است. برای اطلاعات بیشتر باید به &#039;&#039;انبار ویکی‌پدیا&#039;&#039; مراجعه کنید. احتمال دارد این تصویر به دلایل &#039;&#039;&#039;نقض حق تکثیر&#039;&#039;&#039; در اینجا و حتی انبار ویکی‌پدیا حذف بشود.&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=File:26473195.jpg&amp;diff=3990</id>
		<title>File:26473195.jpg</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=File:26473195.jpg&amp;diff=3990"/>
		<updated>2026-09-18T14:01:16Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== اجازه‌نامه ==&lt;br /&gt;
{{Ombox&lt;br /&gt;
| type      = style&lt;br /&gt;
| image     = [[پرونده:Emblem-important.svg]]&lt;br /&gt;
| style     = width: 800px; &lt;br /&gt;
| textstyle = &lt;br /&gt;
| text      = این تصویر از &#039;&#039;انبار ویکی‌پدیا&#039;&#039; که با مجوزهای حق نشر آزاد مختلف منتشر کننده آثار است، به اینجا آمده است و انتقال دهنده مجوز دقیقی برای انتشار آن گزارش نکرده‌است. برای اطلاعات بیشتر باید به &#039;&#039;انبار ویکی‌پدیا&#039;&#039; مراجعه کنید. احتمال دارد این تصویر به دلایل &#039;&#039;&#039;نقض حق تکثیر&#039;&#039;&#039; در اینجا و حتی انبار ویکی‌پدیا حذف بشود.&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=File:Daysam_coin.jpg&amp;diff=4366</id>
		<title>File:Daysam coin.jpg</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=File:Daysam_coin.jpg&amp;diff=4366"/>
		<updated>2026-09-18T09:22:50Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== اجازه‌نامه ==&lt;br /&gt;
{{Ombox&lt;br /&gt;
| type      = style&lt;br /&gt;
| image     = [[پرونده:Emblem-important.svg]]&lt;br /&gt;
| style     = width: 800px; &lt;br /&gt;
| textstyle = &lt;br /&gt;
| text      = این تصویر از &#039;&#039;انبار ویکی‌پدیا&#039;&#039; که با مجوزهای حق نشر آزاد مختلف منتشر کننده آثار است، به اینجا آمده است و انتقال دهنده مجوز دقیقی برای انتشار آن گزارش نکرده‌است. برای اطلاعات بیشتر باید به &#039;&#039;انبار ویکی‌پدیا&#039;&#039; مراجعه کنید. احتمال دارد این تصویر به دلایل &#039;&#039;&#039;نقض حق تکثیر&#039;&#039;&#039; در اینجا و حتی انبار ویکی‌پدیا حذف بشود.&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=File:Flag_of_Ethiopia_(1975%E2%80%931987).svg&amp;diff=4534</id>
		<title>File:Flag of Ethiopia (1975–1987).svg</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=File:Flag_of_Ethiopia_(1975%E2%80%931987).svg&amp;diff=4534"/>
		<updated>2026-09-18T09:10:07Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: Shahroudi صفحهٔ پرونده:Flag of Ethiopia (1975–1987) (1).svg را به پرونده:Flag of Ethiopia (1975–1987).svg منتقل کرد&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== خلاصه ==&lt;br /&gt;
Importing file&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=File:Aya-.png&amp;diff=4173</id>
		<title>File:Aya-.png</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=File:Aya-.png&amp;diff=4173"/>
		<updated>2026-09-18T09:02:04Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=File:Jerusalem-2013(2)-Temple_Mount-Dome_of_the_Rock_(SE_exposure).jpg&amp;diff=5042</id>
		<title>File:Jerusalem-2013(2)-Temple Mount-Dome of the Rock (SE exposure).jpg</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=File:Jerusalem-2013(2)-Temple_Mount-Dome_of_the_Rock_(SE_exposure).jpg&amp;diff=5042"/>
		<updated>2026-09-18T08:17:19Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=File:%D8%A7%D8%B3%D8%AA%D9%87%D9%84%D8%A7%D9%84_%D8%AF%D8%B1_%D9%82%D9%85.jpg&amp;diff=5863</id>
		<title>File:استهلال در قم.jpg</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=File:%D8%A7%D8%B3%D8%AA%D9%87%D9%84%D8%A7%D9%84_%D8%AF%D8%B1_%D9%82%D9%85.jpg&amp;diff=5863"/>
		<updated>2026-07-28T17:41:12Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: https://www.mehrnews.com/photo/3989581/%D8%A7%D8%B3%D8%AA%D9%87%D9%84%D8%A7%D9%84-%D9%85%D8%A7%D9%87-%D9%85%D8%A8%D8%A7%D8%B1%DA%A9-%D8%B1%D9%85%D8%B6%D8%A7%D9%86-%D8%AF%D8%B1-%D9%82%D9%85#gallery-17&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== خلاصه ==&lt;br /&gt;
https://www.mehrnews.com/photo/3989581/%D8%A7%D8%B3%D8%AA%D9%87%D9%84%D8%A7%D9%84-%D9%85%D8%A7%D9%87-%D9%85%D8%A8%D8%A7%D8%B1%DA%A9-%D8%B1%D9%85%D8%B6%D8%A7%D9%86-%D8%AF%D8%B1-%D9%82%D9%85#gallery-17&lt;br /&gt;
== اجازه‌نامه ==&lt;br /&gt;
{{خود|cc-by-4.0}}&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=File:%D8%B3%D8%AE%D9%86%DA%AF%D9%88%DB%8C_%D8%B3%D8%AA%D8%A7%D8%AF_%D8%AA%D8%B4%DB%8C%DB%8C%D8%B9_%D8%B1%D9%87%D8%A8%D8%B1_%D8%B4%D9%87%DB%8C%D8%AF.jpeg&amp;diff=5914</id>
		<title>File:سخنگوی ستاد تشییع رهبر شهید.jpeg</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=File:%D8%B3%D8%AE%D9%86%DA%AF%D9%88%DB%8C_%D8%B3%D8%AA%D8%A7%D8%AF_%D8%AA%D8%B4%DB%8C%DB%8C%D8%B9_%D8%B1%D9%87%D8%A8%D8%B1_%D8%B4%D9%87%DB%8C%D8%AF.jpeg&amp;diff=5914"/>
		<updated>2026-07-01T06:23:37Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== اجازه‌نامه ==&lt;br /&gt;
{{cc-by-sa-4.0}}&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=File:Changing_the_flag_of_the_Shrine_of_Hazrat_Masumeh.jpg&amp;diff=4275</id>
		<title>File:Changing the flag of the Shrine of Hazrat Masumeh.jpg</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=File:Changing_the_flag_of_the_Shrine_of_Hazrat_Masumeh.jpg&amp;diff=4275"/>
		<updated>2026-06-05T05:34:44Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== اجازه‌نامه ==&lt;br /&gt;
{{cc-by-sa-4.0}}&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=File:P_no.svg&amp;diff=5315</id>
		<title>File:P no.svg</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=File:P_no.svg&amp;diff=5315"/>
		<updated>2026-04-19T15:42:13Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== اجازه‌نامه ==&lt;br /&gt;
{{Ombox&lt;br /&gt;
| type      = style&lt;br /&gt;
| image     = [[پرونده:Emblem-important.svg]]&lt;br /&gt;
| style     = width: 800px; &lt;br /&gt;
| textstyle = &lt;br /&gt;
| text      = این تصویر از &#039;&#039;انبار ویکی‌پدیا&#039;&#039; که با مجوزهای حق نشر آزاد مختلف منتشر کننده آثار است، به اینجا آمده است و انتقال دهنده مجوز دقیقی برای انتشار آن گزارش نکرده‌است. برای اطلاعات بیشتر باید به &#039;&#039;انبار ویکی‌پدیا&#039;&#039; مراجعه کنید. احتمال دارد این تصویر به دلایل &#039;&#039;&#039;نقض حق تکثیر&#039;&#039;&#039; در اینجا و حتی انبار ویکی‌پدیا حذف بشود.&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=File:Logo-razndojht.jpg&amp;diff=5109</id>
		<title>File:Logo-razndojht.jpg</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=File:Logo-razndojht.jpg&amp;diff=5109"/>
		<updated>2026-04-16T11:17:51Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== اجازه‌نامه ==&lt;br /&gt;
{{خود|cc-by-sa-4.0}}&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=File:Bildnis_Johann_Ludwig_Burckhardt_HMB_1947-221.jpg&amp;diff=4219</id>
		<title>File:Bildnis Johann Ludwig Burckhardt HMB 1947-221.jpg</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=File:Bildnis_Johann_Ludwig_Burckhardt_HMB_1947-221.jpg&amp;diff=4219"/>
		<updated>2026-02-16T03:26:03Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== اجازه‌نامه ==&lt;br /&gt;
{{Ombox&lt;br /&gt;
| type      = style&lt;br /&gt;
| image     = [[پرونده:Emblem-important.svg]]&lt;br /&gt;
| style     = width: 800px; &lt;br /&gt;
| textstyle = &lt;br /&gt;
| text      = این تصویر از &#039;&#039;انبار ویکی‌پدیا&#039;&#039; که با مجوزهای حق نشر آزاد مختلف منتشر کننده آثار است، به اینجا آمده است و انتقال دهنده مجوز دقیقی برای انتشار آن گزارش نکرده‌است. برای اطلاعات بیشتر باید به &#039;&#039;انبار ویکی‌پدیا&#039;&#039; مراجعه کنید. احتمال دارد این تصویر به دلایل &#039;&#039;&#039;نقض حق تکثیر&#039;&#039;&#039; در اینجا و حتی انبار ویکی‌پدیا حذف بشود.&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=File:Burckhardt_Taufregister_Lausanne.jpg&amp;diff=4244</id>
		<title>File:Burckhardt Taufregister Lausanne.jpg</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=File:Burckhardt_Taufregister_Lausanne.jpg&amp;diff=4244"/>
		<updated>2026-02-16T03:23:40Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== اجازه‌نامه ==&lt;br /&gt;
{{Ombox&lt;br /&gt;
| type      = style&lt;br /&gt;
| image     = [[پرونده:Emblem-important.svg]]&lt;br /&gt;
| style     = width: 800px; &lt;br /&gt;
| textstyle = &lt;br /&gt;
| text      = این تصویر از &#039;&#039;انبار ویکی‌پدیا&#039;&#039; که با مجوزهای حق نشر آزاد مختلف منتشر کننده آثار است، به اینجا آمده است و انتقال دهنده مجوز دقیقی برای انتشار آن گزارش نکرده‌است. برای اطلاعات بیشتر باید به &#039;&#039;انبار ویکی‌پدیا&#039;&#039; مراجعه کنید. احتمال دارد این تصویر به دلایل &#039;&#039;&#039;نقض حق تکثیر&#039;&#039;&#039; در اینجا و حتی انبار ویکی‌پدیا حذف بشود.&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=File:Burckhardt_Taufregister_Basel.jpg&amp;diff=4243</id>
		<title>File:Burckhardt Taufregister Basel.jpg</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=File:Burckhardt_Taufregister_Basel.jpg&amp;diff=4243"/>
		<updated>2026-02-16T03:18:46Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== اجازه‌نامه ==&lt;br /&gt;
{{Ombox&lt;br /&gt;
| type      = style&lt;br /&gt;
| image     = [[پرونده:Emblem-important.svg]]&lt;br /&gt;
| style     = width: 800px; &lt;br /&gt;
| textstyle = &lt;br /&gt;
| text      = این تصویر از &#039;&#039;انبار ویکی‌پدیا&#039;&#039; که با مجوزهای حق نشر آزاد مختلف منتشر کننده آثار است، به اینجا آمده است و انتقال دهنده مجوز دقیقی برای انتشار آن گزارش نکرده‌است. برای اطلاعات بیشتر باید به &#039;&#039;انبار ویکی‌پدیا&#039;&#039; مراجعه کنید. احتمال دارد این تصویر به دلایل &#039;&#039;&#039;نقض حق تکثیر&#039;&#039;&#039; در اینجا و حتی انبار ویکی‌پدیا حذف بشود.&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=File:Kirschgarten.jpg&amp;diff=5081</id>
		<title>File:Kirschgarten.jpg</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=File:Kirschgarten.jpg&amp;diff=5081"/>
		<updated>2026-02-16T03:18:10Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== اجازه‌نامه ==&lt;br /&gt;
{{Ombox&lt;br /&gt;
| type      = style&lt;br /&gt;
| image     = [[پرونده:Emblem-important.svg]]&lt;br /&gt;
| style     = width: 800px; &lt;br /&gt;
| textstyle = &lt;br /&gt;
| text      = این تصویر از &#039;&#039;انبار ویکی‌پدیا&#039;&#039; که با مجوزهای حق نشر آزاد مختلف منتشر کننده آثار است، به اینجا آمده است و انتقال دهنده مجوز دقیقی برای انتشار آن گزارش نکرده‌است. برای اطلاعات بیشتر باید به &#039;&#039;انبار ویکی‌پدیا&#039;&#039; مراجعه کنید. احتمال دارد این تصویر به دلایل &#039;&#039;&#039;نقض حق تکثیر&#039;&#039;&#039; در اینجا و حتی انبار ویکی‌پدیا حذف بشود.&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=File:Erndhalde_Samuel_Birmann_1875.jpg&amp;diff=4429</id>
		<title>File:Erndhalde Samuel Birmann 1875.jpg</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=File:Erndhalde_Samuel_Birmann_1875.jpg&amp;diff=4429"/>
		<updated>2026-02-16T03:16:22Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== اجازه‌نامه ==&lt;br /&gt;
{{Ombox&lt;br /&gt;
| type      = style&lt;br /&gt;
| image     = [[پرونده:Emblem-important.svg]]&lt;br /&gt;
| style     = width: 800px; &lt;br /&gt;
| textstyle = &lt;br /&gt;
| text      = این تصویر از &#039;&#039;انبار ویکی‌پدیا&#039;&#039; که با مجوزهای حق نشر آزاد مختلف منتشر کننده آثار است، به اینجا آمده است و انتقال دهنده مجوز دقیقی برای انتشار آن گزارش نکرده‌است. برای اطلاعات بیشتر باید به &#039;&#039;انبار ویکی‌پدیا&#039;&#039; مراجعه کنید. احتمال دارد این تصویر به دلایل &#039;&#039;&#039;نقض حق تکثیر&#039;&#039;&#039; در اینجا و حتی انبار ویکی‌پدیا حذف بشود.&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=File:Burckhardt_3_Kinder_1795.jpg&amp;diff=4242</id>
		<title>File:Burckhardt 3 Kinder 1795.jpg</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=File:Burckhardt_3_Kinder_1795.jpg&amp;diff=4242"/>
		<updated>2026-02-16T03:15:16Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== اجازه‌نامه ==&lt;br /&gt;
{{Ombox&lt;br /&gt;
| type      = style&lt;br /&gt;
| image     = [[پرونده:Emblem-important.svg]]&lt;br /&gt;
| style     = width: 800px; &lt;br /&gt;
| textstyle = &lt;br /&gt;
| text      = این تصویر از &#039;&#039;انبار ویکی‌پدیا&#039;&#039; که با مجوزهای حق نشر آزاد مختلف منتشر کننده آثار است، به اینجا آمده است و انتقال دهنده مجوز دقیقی برای انتشار آن گزارش نکرده‌است. برای اطلاعات بیشتر باید به &#039;&#039;انبار ویکی‌پدیا&#039;&#039; مراجعه کنید. احتمال دارد این تصویر به دلایل &#039;&#039;&#039;نقض حق تکثیر&#039;&#039;&#039; در اینجا و حتی انبار ویکی‌پدیا حذف بشود.&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=File:Johann_Ludwig_Burckhardt_mit_24_Jahren.jpg&amp;diff=5045</id>
		<title>File:Johann Ludwig Burckhardt mit 24 Jahren.jpg</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=File:Johann_Ludwig_Burckhardt_mit_24_Jahren.jpg&amp;diff=5045"/>
		<updated>2026-02-16T03:14:53Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== اجازه‌نامه ==&lt;br /&gt;
{{Ombox&lt;br /&gt;
| type      = style&lt;br /&gt;
| image     = [[پرونده:Emblem-important.svg]]&lt;br /&gt;
| style     = width: 800px; &lt;br /&gt;
| textstyle = &lt;br /&gt;
| text      = این تصویر از &#039;&#039;انبار ویکی‌پدیا&#039;&#039; که با مجوزهای حق نشر آزاد مختلف منتشر کننده آثار است، به اینجا آمده است و انتقال دهنده مجوز دقیقی برای انتشار آن گزارش نکرده‌است. برای اطلاعات بیشتر باید به &#039;&#039;انبار ویکی‌پدیا&#039;&#039; مراجعه کنید. احتمال دارد این تصویر به دلایل &#039;&#039;&#039;نقض حق تکثیر&#039;&#039;&#039; در اینجا و حتی انبار ویکی‌پدیا حذف بشود.&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=File:Flickr_-_%E2%80%A6trialsanderrors_-_The_Treasury,_Petra,_Jordan,_by_the_American_Colony_Jerusalem_Photo_Department,_ca._1910.jpg&amp;diff=4795</id>
		<title>File:Flickr - …trialsanderrors - The Treasury, Petra, Jordan, by the American Colony Jerusalem Photo Department, ca. 1910.jpg</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=File:Flickr_-_%E2%80%A6trialsanderrors_-_The_Treasury,_Petra,_Jordan,_by_the_American_Colony_Jerusalem_Photo_Department,_ca._1910.jpg&amp;diff=4795"/>
		<updated>2026-02-16T03:14:37Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== اجازه‌نامه ==&lt;br /&gt;
{{Ombox&lt;br /&gt;
| type      = style&lt;br /&gt;
| image     = [[پرونده:Emblem-important.svg]]&lt;br /&gt;
| style     = width: 800px; &lt;br /&gt;
| textstyle = &lt;br /&gt;
| text      = این تصویر از &#039;&#039;انبار ویکی‌پدیا&#039;&#039; که با مجوزهای حق نشر آزاد مختلف منتشر کننده آثار است، به اینجا آمده است و انتقال دهنده مجوز دقیقی برای انتشار آن گزارش نکرده‌است. برای اطلاعات بیشتر باید به &#039;&#039;انبار ویکی‌پدیا&#039;&#039; مراجعه کنید. احتمال دارد این تصویر به دلایل &#039;&#039;&#039;نقض حق تکثیر&#039;&#039;&#039; در اینجا و حتی انبار ویکی‌پدیا حذف بشود.&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=File:PLAN_OF_MEKKA_(1814).jpg&amp;diff=5305</id>
		<title>File:PLAN OF MEKKA (1814).jpg</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=File:PLAN_OF_MEKKA_(1814).jpg&amp;diff=5305"/>
		<updated>2026-02-16T03:14:14Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== اجازه‌نامه ==&lt;br /&gt;
{{Ombox&lt;br /&gt;
| type      = style&lt;br /&gt;
| image     = [[پرونده:Emblem-important.svg]]&lt;br /&gt;
| style     = width: 800px; &lt;br /&gt;
| textstyle = &lt;br /&gt;
| text      = این تصویر از &#039;&#039;انبار ویکی‌پدیا&#039;&#039; که با مجوزهای حق نشر آزاد مختلف منتشر کننده آثار است، به اینجا آمده است و انتقال دهنده مجوز دقیقی برای انتشار آن گزارش نکرده‌است. برای اطلاعات بیشتر باید به &#039;&#039;انبار ویکی‌پدیا&#039;&#039; مراجعه کنید. احتمال دارد این تصویر به دلایل &#039;&#039;&#039;نقض حق تکثیر&#039;&#039;&#039; در اینجا و حتی انبار ویکی‌پدیا حذف بشود.&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=File:Abu_Simble_Temples_1905-1907_A.png&amp;diff=4038</id>
		<title>File:Abu Simble Temples 1905-1907 A.png</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=File:Abu_Simble_Temples_1905-1907_A.png&amp;diff=4038"/>
		<updated>2026-02-16T03:14:04Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== اجازه‌نامه ==&lt;br /&gt;
{{Ombox&lt;br /&gt;
| type      = style&lt;br /&gt;
| image     = [[پرونده:Emblem-important.svg]]&lt;br /&gt;
| style     = width: 800px; &lt;br /&gt;
| textstyle = &lt;br /&gt;
| text      = این تصویر از &#039;&#039;انبار ویکی‌پدیا&#039;&#039; که با مجوزهای حق نشر آزاد مختلف منتشر کننده آثار است، به اینجا آمده است و انتقال دهنده مجوز دقیقی برای انتشار آن گزارش نکرده‌است. برای اطلاعات بیشتر باید به &#039;&#039;انبار ویکی‌پدیا&#039;&#039; مراجعه کنید. احتمال دارد این تصویر به دلایل &#039;&#039;&#039;نقض حق تکثیر&#039;&#039;&#039; در اینجا و حتی انبار ویکی‌پدیا حذف بشود.&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=File:Haddsch-Urkunde_von_Scheich_Ibrahim.jpg&amp;diff=4867</id>
		<title>File:Haddsch-Urkunde von Scheich Ibrahim.jpg</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=File:Haddsch-Urkunde_von_Scheich_Ibrahim.jpg&amp;diff=4867"/>
		<updated>2026-02-16T03:13:27Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== اجازه‌نامه ==&lt;br /&gt;
{{Ombox&lt;br /&gt;
| type      = style&lt;br /&gt;
| image     = [[پرونده:Emblem-important.svg]]&lt;br /&gt;
| style     = width: 800px; &lt;br /&gt;
| textstyle = &lt;br /&gt;
| text      = این تصویر از &#039;&#039;انبار ویکی‌پدیا&#039;&#039; که با مجوزهای حق نشر آزاد مختلف منتشر کننده آثار است، به اینجا آمده است و انتقال دهنده مجوز دقیقی برای انتشار آن گزارش نکرده‌است. برای اطلاعات بیشتر باید به &#039;&#039;انبار ویکی‌پدیا&#039;&#039; مراجعه کنید. احتمال دارد این تصویر به دلایل &#039;&#039;&#039;نقض حق تکثیر&#039;&#039;&#039; در اینجا و حتی انبار ویکی‌پدیا حذف بشود.&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=File:Egypt-statue.jpg&amp;diff=4410</id>
		<title>File:Egypt-statue.jpg</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=File:Egypt-statue.jpg&amp;diff=4410"/>
		<updated>2026-02-16T03:12:32Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== اجازه‌نامه ==&lt;br /&gt;
{{Ombox&lt;br /&gt;
| type      = style&lt;br /&gt;
| image     = [[پرونده:Emblem-important.svg]]&lt;br /&gt;
| style     = width: 800px; &lt;br /&gt;
| textstyle = &lt;br /&gt;
| text      = این تصویر از &#039;&#039;انبار ویکی‌پدیا&#039;&#039; که با مجوزهای حق نشر آزاد مختلف منتشر کننده آثار است، به اینجا آمده است و انتقال دهنده مجوز دقیقی برای انتشار آن گزارش نکرده‌است. برای اطلاعات بیشتر باید به &#039;&#039;انبار ویکی‌پدیا&#039;&#039; مراجعه کنید. احتمال دارد این تصویر به دلایل &#039;&#039;&#039;نقض حق تکثیر&#039;&#039;&#039; در اینجا و حتی انبار ویکی‌پدیا حذف بشود.&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=File:Grabstele_von_Johann_Ludwig_Burckhardt.png&amp;diff=4856</id>
		<title>File:Grabstele von Johann Ludwig Burckhardt.png</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=File:Grabstele_von_Johann_Ludwig_Burckhardt.png&amp;diff=4856"/>
		<updated>2026-02-16T03:11:58Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== اجازه‌نامه ==&lt;br /&gt;
{{Ombox&lt;br /&gt;
| type      = style&lt;br /&gt;
| image     = [[پرونده:Emblem-important.svg]]&lt;br /&gt;
| style     = width: 800px; &lt;br /&gt;
| textstyle = &lt;br /&gt;
| text      = این تصویر از &#039;&#039;انبار ویکی‌پدیا&#039;&#039; که با مجوزهای حق نشر آزاد مختلف منتشر کننده آثار است، به اینجا آمده است و انتقال دهنده مجوز دقیقی برای انتشار آن گزارش نکرده‌است. برای اطلاعات بیشتر باید به &#039;&#039;انبار ویکی‌پدیا&#039;&#039; مراجعه کنید. احتمال دارد این تصویر به دلایل &#039;&#039;&#039;نقض حق تکثیر&#039;&#039;&#039; در اینجا و حتی انبار ویکی‌پدیا حذف بشود.&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=File:Logo-daneshdojht.png&amp;diff=5108</id>
		<title>File:Logo-daneshdojht.png</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=File:Logo-daneshdojht.png&amp;diff=5108"/>
		<updated>2026-01-05T03:44:36Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== اجازه‌نامه ==&lt;br /&gt;
{{خود|cc-by-sa-4.0|GFDL|migration=not-eligible}}&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=File:Jerusalem_Temple_Mount_Al-Aqsa_Mosque_(29324502388).jpg&amp;diff=5043</id>
		<title>File:Jerusalem Temple Mount Al-Aqsa Mosque (29324502388).jpg</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=File:Jerusalem_Temple_Mount_Al-Aqsa_Mosque_(29324502388).jpg&amp;diff=5043"/>
		<updated>2025-12-16T10:39:44Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== اجازه‌نامه ==&lt;br /&gt;
{{Ombox&lt;br /&gt;
| type      = style&lt;br /&gt;
| image     = [[پرونده:Emblem-important.svg]]&lt;br /&gt;
| style     = width: 800px; &lt;br /&gt;
| textstyle = &lt;br /&gt;
| text      = این تصویر از &#039;&#039;انبار ویکی‌پدیا&#039;&#039; که با مجوزهای حق نشر آزاد مختلف منتشر کننده آثار است، به اینجا آمده است و انتقال دهنده مجوز دقیقی برای انتشار آن گزارش نکرده‌است. برای اطلاعات بیشتر باید به &#039;&#039;انبار ویکی‌پدیا&#039;&#039; مراجعه کنید. احتمال دارد این تصویر به دلایل &#039;&#039;&#039;نقض حق تکثیر&#039;&#039;&#039; در اینجا و حتی انبار ویکی‌پدیا حذف بشود.&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=File:Dehio_10_Dome_of_the_Rock_Section.jpg&amp;diff=4369</id>
		<title>File:Dehio 10 Dome of the Rock Section.jpg</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=File:Dehio_10_Dome_of_the_Rock_Section.jpg&amp;diff=4369"/>
		<updated>2025-12-16T10:33:02Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== اجازه‌نامه ==&lt;br /&gt;
{{Ombox&lt;br /&gt;
| type      = style&lt;br /&gt;
| image     = [[پرونده:Emblem-important.svg]]&lt;br /&gt;
| style     = width: 800px; &lt;br /&gt;
| textstyle = &lt;br /&gt;
| text      = این تصویر از &#039;&#039;انبار ویکی‌پدیا&#039;&#039; که با مجوزهای حق نشر آزاد مختلف منتشر کننده آثار است، به اینجا آمده است و انتقال دهنده مجوز دقیقی برای انتشار آن گزارش نکرده‌است. برای اطلاعات بیشتر باید به &#039;&#039;انبار ویکی‌پدیا&#039;&#039; مراجعه کنید. احتمال دارد این تصویر به دلایل &#039;&#039;&#039;نقض حق تکثیر&#039;&#039;&#039; در اینجا و حتی انبار ویکی‌پدیا حذف بشود.&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=File:Exterior_of_the_Dome_of_the_Rock_06.jpg&amp;diff=4445</id>
		<title>File:Exterior of the Dome of the Rock 06.jpg</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=File:Exterior_of_the_Dome_of_the_Rock_06.jpg&amp;diff=4445"/>
		<updated>2025-12-16T10:32:25Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== اجازه‌نامه ==&lt;br /&gt;
{{Ombox&lt;br /&gt;
| type      = style&lt;br /&gt;
| image     = [[پرونده:Emblem-important.svg]]&lt;br /&gt;
| style     = width: 800px; &lt;br /&gt;
| textstyle = &lt;br /&gt;
| text      = این تصویر از &#039;&#039;انبار ویکی‌پدیا&#039;&#039; که با مجوزهای حق نشر آزاد مختلف منتشر کننده آثار است، به اینجا آمده است و انتقال دهنده مجوز دقیقی برای انتشار آن گزارش نکرده‌است. برای اطلاعات بیشتر باید به &#039;&#039;انبار ویکی‌پدیا&#039;&#039; مراجعه کنید. احتمال دارد این تصویر به دلایل &#039;&#039;&#039;نقض حق تکثیر&#039;&#039;&#039; در اینجا و حتی انبار ویکی‌پدیا حذف بشود.&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=Module:Cat_see_also&amp;diff=3949</id>
		<title>Module:Cat see also</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=Module:Cat_see_also&amp;diff=3949"/>
		<updated>2025-12-13T17:02:05Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: Created page with &amp;quot;require(&amp;#039;strict&amp;#039;)  local p = {}  function p.main(frame) 	local args = require(&amp;#039;Module:Arguments&amp;#039;).getArgs(frame) 	frame = mw.getCurrentFrame() 	-- Special case when the first given link in parameter is &amp;#039;V&amp;#039;, and 	-- the current page name starts by &amp;#039;V&amp;#039; or &amp;#039;In&amp;#039; 	if args[1] == &amp;#039;V&amp;#039; then 		local title = mw.title.getCurrentTitle().text 		local cwttb = mw.text.split( title, &amp;#039;:&amp;#039; ); 		if title:sub(1, 1) == &amp;#039;V&amp;#039; then 			args[1] = &amp;#039;In&amp;#039; .. mw.getContentLanguage():lcfirst(title) 		else...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;require(&#039;strict&#039;)&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
function p.main(frame)&lt;br /&gt;
	local args = require(&#039;Module:Arguments&#039;).getArgs(frame)&lt;br /&gt;
	frame = mw.getCurrentFrame()&lt;br /&gt;
	-- Special case when the first given link in parameter is &#039;V&#039;, and&lt;br /&gt;
	-- the current page name starts by &#039;V&#039; or &#039;In&#039;&lt;br /&gt;
	if args[1] == &#039;V&#039; then&lt;br /&gt;
		local title = mw.title.getCurrentTitle().text&lt;br /&gt;
		local cwttb = mw.text.split( title, &#039;:&#039; );&lt;br /&gt;
		if title:sub(1, 1) == &#039;V&#039; then&lt;br /&gt;
			args[1] = &#039;In&#039; .. mw.getContentLanguage():lcfirst(title)&lt;br /&gt;
		elseif title:sub(1, 1) == &#039;I&#039; then&lt;br /&gt;
			args[1] = mw.getContentLanguage():ucfirst(title:sub(3))&lt;br /&gt;
		else&lt;br /&gt;
			args[1] = nil&lt;br /&gt;
		end&lt;br /&gt;
		local cwttc = cwttb [1]&lt;br /&gt;
		if mw.ustring.sub (cwttc, -5) == &#039; code&#039; then&lt;br /&gt;
			cwttc = mw.ustring.sub (cwttc, 1, #cwttc-5)&lt;br /&gt;
		end&lt;br /&gt;
		if args[9] ~= nil&lt;br /&gt;
			then args[&#039;for&#039;] = args[9]&lt;br /&gt;
		elseif  mw.ustring.sub (cwttb[1], 1, 22) == &#039;Valid SVG created with&#039;&lt;br /&gt;
			then args[&#039;for&#039;] = &#039;[[Template:C&#039; .. mw.ustring.sub (cwttc, 12) .. &#039;|&#039; .. mw.ustring.sub (cwttc, 24) .. &#039;]]&#039;&lt;br /&gt;
		elseif mw.ustring.sub (cwttb[1], 1, 24) == &#039;Invalid SVG created with&#039;&lt;br /&gt;
			then args[&#039;for&#039;] = &#039;[[Template:C&#039; .. mw.ustring.sub (cwttc, 14) .. &#039;|&#039; .. mw.ustring.sub (cwttc, 26) .. &#039;]]&#039;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	-- filter the list of links in parameters&lt;br /&gt;
	local links = {}&lt;br /&gt;
	local linkformat = &#039;&amp;lt;span lang=&amp;quot;en&amp;quot; dir=&amp;quot;ltr&amp;quot;&amp;gt;[[:&#039; .. (args.iw or args.SISTER or &#039;&#039;) .. &#039;Category:%s|%s]]&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
	for i, v in ipairs(args) do&lt;br /&gt;
		-- discard HTML comments and opening or closing &amp;quot;nowiki&amp;quot; tags in values,&lt;br /&gt;
		-- then normalize and trim whitespaces&lt;br /&gt;
		v = v	:gsub(&#039;&amp;lt;!%-%-.-%-%-&amp;gt;&#039;, &#039;&#039;)&lt;br /&gt;
			:gsub(&#039;&amp;lt;nowiki *&amp;gt;&#039;, &#039;&#039;):gsub(&#039;&amp;lt;/nowiki *&amp;gt;&#039;, &#039;&#039;):gsub(&#039;&amp;lt;nowiki */&amp;gt;&#039;, &#039;&#039;)&lt;br /&gt;
			:gsub(&#039;_&#039;, &#039; &#039;):gsub(&#039;%s+&#039;, &#039; &#039;):gsub(&#039;^%s*(.-)%s*$&#039;, &#039;%1&#039;)&lt;br /&gt;
		-- do not insert any link for empty values&lt;br /&gt;
		if v ~= &#039;&#039; then&lt;br /&gt;
			local html = args[&amp;quot;h&amp;quot; .. tostring(i)]&lt;br /&gt;
			if html ~= nil and html ~= &#039;&#039; then&lt;br /&gt;
				table.insert(links, linkformat:format(v, &#039;&amp;lt;&#039; .. html .. &#039;&amp;gt;&#039; .. v .. &#039;&amp;lt;/&#039; .. html .. &#039;&amp;gt;&#039;))&lt;br /&gt;
			else&lt;br /&gt;
				table.insert(links, linkformat:format(v, v))&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	-- do not return any box if the filtered list of links is now empty&lt;br /&gt;
	if #links == 0 then&lt;br /&gt;
		return &#039;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	-- find the localized template to format the box and message containing the list&lt;br /&gt;
	if not args.lang or not mw.language.isSupportedLanguage(args.lang) then&lt;br /&gt;
		-- use page language instead of user language on pages translated using the Translate extension&lt;br /&gt;
		if frame:callParserFunction(&#039;#translation&#039;, &#039;&#039;) ~= &#039;&#039; then&lt;br /&gt;
			args.lang = frame:preprocess(&#039;{{PAGELANGUAGE}}&#039;)&lt;br /&gt;
		else&lt;br /&gt;
			args.lang = frame:callParserFunction(&#039;Int&#039;, &#039;Lang&#039;)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	local fallbacks = mw.language.getFallbacksFor(args.lang)&lt;br /&gt;
	table.insert(fallbacks, 1, args.lang)&lt;br /&gt;
	for _, lang in ipairs(fallbacks) do&lt;br /&gt;
		if mw.title.new(&#039;Template:Cat see also/i18n/&#039; .. lang).exists then&lt;br /&gt;
			args.lang = lang&lt;br /&gt;
			break&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	-- prepare the formating of the list according to target language&lt;br /&gt;
	args.list = require(&#039;Module:Linguistic&#039;).conj(links, args.lang, &#039;and&#039;)&lt;br /&gt;
	args.length = #links&lt;br /&gt;
	-- format the box and its message continaing the list&lt;br /&gt;
	return frame:expandTemplate{ title = &#039;Template:Cat see also/i18n/&#039; .. args.lang, args = args }&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=Template:Cat_see_also&amp;diff=3948</id>
		<title>Template:Cat see also</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=Template:Cat_see_also&amp;diff=3948"/>
		<updated>2025-12-13T17:01:37Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: Created page with &amp;quot;&amp;lt;onlyinclude&amp;gt;{{#invoke:Cat see also|main|&amp;lt;noinclude&amp;gt;Category navigational templates&amp;lt;/noinclude&amp;gt;}}&amp;lt;/onlyinclude&amp;gt;  {{Documentation}}&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;onlyinclude&amp;gt;{{#invoke:Cat see also|main|&amp;lt;noinclude&amp;gt;Category navigational templates&amp;lt;/noinclude&amp;gt;}}&amp;lt;/onlyinclude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Documentation}}&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=Template:SuperFallback&amp;diff=3947</id>
		<title>Template:SuperFallback</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=Template:SuperFallback&amp;diff=3947"/>
		<updated>2025-12-13T17:00:22Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: Created page with &amp;quot;{{#ifexist: {{{1|}}}/{{#if: {{{2|}}} |{{{2}}}|{{int:Lang}}}} | {{#if: {{{2|}}} |{{{2}}}|{{int:Lang}}}} | {{#ifexist: {{{1|}}}/{{GetFallback|{{#if: {{{2|}}} |{{{2}}}|{{int:Lang}}}}}} | {{GetFallback|{{#if: {{{2|}}} |{{{2}}}|{{int:Lang}}}}}} | {{#ifexist: {{{1|}}}/{{GetFallback2|{{#if: {{{2|}}} |{{{2}}}|{{int:Lang}}}}}} | {{GetFallback2|{{#if: {{{2|}}} |{{{2}}}|{{int:Lang}}}}}} | {{CONTENTLANGUAGE}} }} }} }}&amp;lt;noinclude&amp;gt;  {{heavily used template}} {{documentation}}  &amp;lt;/noincl...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{#ifexist: {{{1|}}}/{{#if: {{{2|}}} |{{{2}}}|{{int:Lang}}}} | {{#if: {{{2|}}} |{{{2}}}|{{int:Lang}}}} | {{#ifexist: {{{1|}}}/{{GetFallback|{{#if: {{{2|}}} |{{{2}}}|{{int:Lang}}}}}} | {{GetFallback|{{#if: {{{2|}}} |{{{2}}}|{{int:Lang}}}}}} | {{#ifexist: {{{1|}}}/{{GetFallback2|{{#if: {{{2|}}} |{{{2}}}|{{int:Lang}}}}}} | {{GetFallback2|{{#if: {{{2|}}} |{{{2}}}|{{int:Lang}}}}}} | {{CONTENTLANGUAGE}} }} }} }}&amp;lt;noinclude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{heavily used template}}&lt;br /&gt;
{{documentation}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=Template:Clear&amp;diff=3946</id>
		<title>Template:Clear</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=Template:Clear&amp;diff=3946"/>
		<updated>2025-12-13T17:00:03Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: Created page with &amp;quot;&amp;lt;div style=&amp;quot;clear:{{{1|both}}};&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;noinclude&amp;gt; {{documentation}} &amp;lt;/noinclude&amp;gt;&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;clear:{{{1|both}}};&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{documentation}}&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=Template:Wikidata_Infobox/i18n/getMsg&amp;diff=3945</id>
		<title>Template:Wikidata Infobox/i18n/getMsg</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=Template:Wikidata_Infobox/i18n/getMsg&amp;diff=3945"/>
		<updated>2025-12-13T16:59:32Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: Created page with &amp;quot;&amp;lt;onlyinclude&amp;gt;&amp;lt;includeonly&amp;gt;{{#if:{{{nowrap|}}}||&amp;lt;bdi lang=&amp;quot;{{SuperFallback|Translations:Template:Wikidata Infobox/i18n/msg-{{{1}}}}}&amp;quot;&amp;gt;}}{{Translations:Template:Wikidata Infobox/i18n/msg-{{{1}}}/{{SuperFallback|Translations:Template:Wikidata Infobox/i18n/msg-{{{1}}}}}}}{{#if:{{{nowrap|}}}||&amp;lt;/bdi&amp;gt;}}&amp;lt;/includeonly&amp;gt;&amp;lt;/onlyinclude&amp;gt; {{Documentation}} &amp;lt;!-- Add categories to the /doc subpage and interwikis in Wikidata, not here! --&amp;gt;&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;onlyinclude&amp;gt;&amp;lt;includeonly&amp;gt;{{#if:{{{nowrap|}}}||&amp;lt;bdi lang=&amp;quot;{{SuperFallback|Translations:Template:Wikidata Infobox/i18n/msg-{{{1}}}}}&amp;quot;&amp;gt;}}{{Translations:Template:Wikidata Infobox/i18n/msg-{{{1}}}/{{SuperFallback|Translations:Template:Wikidata Infobox/i18n/msg-{{{1}}}}}}}{{#if:{{{nowrap|}}}||&amp;lt;/bdi&amp;gt;}}&amp;lt;/includeonly&amp;gt;&amp;lt;/onlyinclude&amp;gt;&lt;br /&gt;
{{Documentation}}&lt;br /&gt;
&amp;lt;!-- Add categories to the /doc subpage and interwikis in Wikidata, not here! --&amp;gt;&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=Module:String&amp;diff=3944</id>
		<title>Module:String</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=Module:String&amp;diff=3944"/>
		<updated>2025-12-13T16:59:16Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: Created page with &amp;quot;--[[  This module is intended to provide access to basic string functions.  Most of the functions provided here can be invoked with named parameters, unnamed parameters, or a mixture.  If named parameters are used, Mediawiki will automatically remove any leading or trailing whitespace from the parameter. Depending on the intended use, it may be advantageous to either preserve or remove such whitespace.  Global options 	ignore_errors: If set to &amp;#039;true&amp;#039; or 1, any error cond...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;--[[&lt;br /&gt;
&lt;br /&gt;
This module is intended to provide access to basic string functions.&lt;br /&gt;
&lt;br /&gt;
Most of the functions provided here can be invoked with named parameters,&lt;br /&gt;
unnamed parameters, or a mixture.  If named parameters are used, Mediawiki will&lt;br /&gt;
automatically remove any leading or trailing whitespace from the parameter.&lt;br /&gt;
Depending on the intended use, it may be advantageous to either preserve or&lt;br /&gt;
remove such whitespace.&lt;br /&gt;
&lt;br /&gt;
Global options&lt;br /&gt;
	ignore_errors: If set to &#039;true&#039; or 1, any error condition will result in&lt;br /&gt;
		an empty string being returned rather than an error message.&lt;br /&gt;
&lt;br /&gt;
	error_category: If an error occurs, specifies the name of a category to&lt;br /&gt;
		include with the error message.  The default category is&lt;br /&gt;
		[Category:Errors reported by Module String].&lt;br /&gt;
&lt;br /&gt;
	no_category: If set to &#039;true&#039; or 1, no category will be added if an error&lt;br /&gt;
		is generated.&lt;br /&gt;
&lt;br /&gt;
Unit tests for this module are available at Module:String/tests.&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local str = {}&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
len&lt;br /&gt;
&lt;br /&gt;
This function returns the length of the target string.&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
{{#invoke:String|len|target_string|}}&lt;br /&gt;
OR&lt;br /&gt;
{{#invoke:String|len|s=target_string}}&lt;br /&gt;
&lt;br /&gt;
Parameters&lt;br /&gt;
	s: The string whose length to report&lt;br /&gt;
&lt;br /&gt;
If invoked using named parameters, Mediawiki will automatically remove any leading or&lt;br /&gt;
trailing whitespace from the target string.&lt;br /&gt;
]]&lt;br /&gt;
function str.len( frame )&lt;br /&gt;
	local new_args = str._getParameters( frame.args, {&#039;s&#039;} )&lt;br /&gt;
	local s = new_args[&#039;s&#039;] or &#039;&#039;&lt;br /&gt;
	return mw.ustring.len( s )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
sub&lt;br /&gt;
&lt;br /&gt;
This function returns a substring of the target string at specified indices.&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
{{#invoke:String|sub|target_string|start_index|end_index}}&lt;br /&gt;
OR&lt;br /&gt;
{{#invoke:String|sub|s=target_string|i=start_index|j=end_index}}&lt;br /&gt;
&lt;br /&gt;
Parameters&lt;br /&gt;
	s: The string to return a subset of&lt;br /&gt;
	i: The fist index of the substring to return, defaults to 1.&lt;br /&gt;
	j: The last index of the string to return, defaults to the last character.&lt;br /&gt;
&lt;br /&gt;
The first character of the string is assigned an index of 1.  If either i or j&lt;br /&gt;
is a negative value, it is interpreted the same as selecting a character by&lt;br /&gt;
counting from the end of the string.  Hence, a value of -1 is the same as&lt;br /&gt;
selecting the last character of the string.&lt;br /&gt;
&lt;br /&gt;
If the requested indices are out of range for the given string, an error is&lt;br /&gt;
reported.&lt;br /&gt;
]]&lt;br /&gt;
function str.sub( frame )&lt;br /&gt;
	local new_args = str._getParameters( frame.args, { &#039;s&#039;, &#039;i&#039;, &#039;j&#039; } )&lt;br /&gt;
	local s = new_args[&#039;s&#039;] or &#039;&#039;&lt;br /&gt;
	local i = tonumber( new_args[&#039;i&#039;] ) or 1&lt;br /&gt;
	local j = tonumber( new_args[&#039;j&#039;] ) or -1&lt;br /&gt;
&lt;br /&gt;
	local len = mw.ustring.len( s )&lt;br /&gt;
&lt;br /&gt;
	-- Convert negatives for range checking&lt;br /&gt;
	if i &amp;lt; 0 then&lt;br /&gt;
		i = len + i + 1&lt;br /&gt;
	end&lt;br /&gt;
	if j &amp;lt; 0 then&lt;br /&gt;
		j = len + j + 1&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if i &amp;gt; len or j &amp;gt; len or i &amp;lt; 1 or j &amp;lt; 1 then&lt;br /&gt;
		return str._error( &#039;String subset index out of range&#039; )&lt;br /&gt;
	end&lt;br /&gt;
	if j &amp;lt; i then&lt;br /&gt;
		return str._error( &#039;String subset indices out of order&#039; )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return mw.ustring.sub( s, i, j )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
This function implements that features of {{str sub old}} and is kept in order&lt;br /&gt;
to maintain these older templates.&lt;br /&gt;
]]&lt;br /&gt;
function str.sublength( frame )&lt;br /&gt;
	local i = tonumber( frame.args.i ) or 0&lt;br /&gt;
	local len = tonumber( frame.args.len )&lt;br /&gt;
	return mw.ustring.sub( frame.args.s, i + 1, len and ( i + len ) )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
match&lt;br /&gt;
&lt;br /&gt;
This function returns a substring from the source string that matches a&lt;br /&gt;
specified pattern.&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
{{#invoke:String|match|source_string|pattern_string|start_index|match_number|plain_flag|nomatch_output}}&lt;br /&gt;
OR&lt;br /&gt;
{{#invoke:String|match|s=source_string|pattern=pattern_string|start=start_index&lt;br /&gt;
	|match=match_number|plain=plain_flag|nomatch=nomatch_output}}&lt;br /&gt;
&lt;br /&gt;
Parameters&lt;br /&gt;
	s: The string to search&lt;br /&gt;
	pattern: The pattern or string to find within the string&lt;br /&gt;
	start: The index within the source string to start the search.  The first&lt;br /&gt;
		character of the string has index 1.  Defaults to 1.&lt;br /&gt;
	match: In some cases it may be possible to make multiple matches on a single&lt;br /&gt;
		string.  This specifies which match to return, where the first match is&lt;br /&gt;
		match= 1.  If a negative number is specified then a match is returned&lt;br /&gt;
		counting from the last match.  Hence match = -1 is the same as requesting&lt;br /&gt;
		the last match.  Defaults to 1.&lt;br /&gt;
	plain: A flag indicating that the pattern should be understood as plain&lt;br /&gt;
		text.  Defaults to false.&lt;br /&gt;
	nomatch: If no match is found, output the &amp;quot;nomatch&amp;quot; value rather than an error.&lt;br /&gt;
&lt;br /&gt;
If invoked using named parameters, Mediawiki will automatically remove any leading or&lt;br /&gt;
trailing whitespace from each string.  In some circumstances this is desirable, in&lt;br /&gt;
other cases one may want to preserve the whitespace.&lt;br /&gt;
&lt;br /&gt;
If the match_number or start_index are out of range for the string being queried, then&lt;br /&gt;
this function generates an error.  An error is also generated if no match is found.&lt;br /&gt;
If one adds the parameter ignore_errors=true, then the error will be suppressed and&lt;br /&gt;
an empty string will be returned on any failure.&lt;br /&gt;
&lt;br /&gt;
For information on constructing Lua patterns, a form of [regular expression], see:&lt;br /&gt;
&lt;br /&gt;
* http://www.lua.org/manual/5.1/manual.html#5.4.1&lt;br /&gt;
* http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Patterns&lt;br /&gt;
* http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Ustring_patterns&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
-- This sub-routine is exported for use in other modules&lt;br /&gt;
function str._match( s, pattern, start, match_index, plain_flag, nomatch )&lt;br /&gt;
	if s == &#039;&#039; then&lt;br /&gt;
		return str._error( &#039;Target string is empty&#039; )&lt;br /&gt;
	end&lt;br /&gt;
	if pattern == &#039;&#039; then&lt;br /&gt;
		return str._error( &#039;Pattern string is empty&#039; )&lt;br /&gt;
	end&lt;br /&gt;
	start = tonumber(start) or 1&lt;br /&gt;
	if math.abs(start) &amp;lt; 1 or math.abs(start) &amp;gt; mw.ustring.len( s ) then&lt;br /&gt;
		return str._error( &#039;Requested start is out of range&#039; )&lt;br /&gt;
	end&lt;br /&gt;
	if match_index == 0 then&lt;br /&gt;
		return str._error( &#039;Match index is out of range&#039; )&lt;br /&gt;
	end&lt;br /&gt;
	if plain_flag then&lt;br /&gt;
		pattern = str._escapePattern( pattern )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local result&lt;br /&gt;
	if match_index == 1 then&lt;br /&gt;
		-- Find first match is simple case&lt;br /&gt;
		result = mw.ustring.match( s, pattern, start )&lt;br /&gt;
	else&lt;br /&gt;
		if start &amp;gt; 1 then&lt;br /&gt;
			s = mw.ustring.sub( s, start )&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local iterator = mw.ustring.gmatch(s, pattern)&lt;br /&gt;
		if match_index &amp;gt; 0 then&lt;br /&gt;
			-- Forward search&lt;br /&gt;
			for w in iterator do&lt;br /&gt;
				match_index = match_index - 1&lt;br /&gt;
				if match_index == 0 then&lt;br /&gt;
					result = w&lt;br /&gt;
					break&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		else&lt;br /&gt;
			-- Reverse search&lt;br /&gt;
			local result_table = {}&lt;br /&gt;
			local count = 1&lt;br /&gt;
			for w in iterator do&lt;br /&gt;
				result_table[count] = w&lt;br /&gt;
				count = count + 1&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			result = result_table[ count + match_index ]&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if result == nil then&lt;br /&gt;
		if nomatch == nil then&lt;br /&gt;
			return str._error( &#039;Match not found&#039; )&lt;br /&gt;
		else&lt;br /&gt;
			return nomatch&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		return result&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
-- This is the entry point for #invoke:String|match&lt;br /&gt;
function str.match( frame )&lt;br /&gt;
	local new_args = str._getParameters( frame.args, {&#039;s&#039;, &#039;pattern&#039;, &#039;start&#039;, &#039;match&#039;, &#039;plain&#039;, &#039;nomatch&#039;} )&lt;br /&gt;
	local s = new_args[&#039;s&#039;] or &#039;&#039;&lt;br /&gt;
	local start = tonumber( new_args[&#039;start&#039;] ) or 1&lt;br /&gt;
	local plain_flag = str._getBoolean( new_args[&#039;plain&#039;] or false )&lt;br /&gt;
	local pattern = new_args[&#039;pattern&#039;] or &#039;&#039;&lt;br /&gt;
	local match_index = math.floor( tonumber(new_args[&#039;match&#039;]) or 1 )&lt;br /&gt;
	local nomatch = new_args[&#039;nomatch&#039;]&lt;br /&gt;
&lt;br /&gt;
	return str._match( s, pattern, start, match_index, plain_flag, nomatch )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
pos&lt;br /&gt;
&lt;br /&gt;
This function returns a single character from the target string at position pos.&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
{{#invoke:String|pos|target_string|index_value}}&lt;br /&gt;
OR&lt;br /&gt;
{{#invoke:String|pos|target=target_string|pos=index_value}}&lt;br /&gt;
&lt;br /&gt;
Parameters&lt;br /&gt;
	target: The string to search&lt;br /&gt;
	pos: The index for the character to return&lt;br /&gt;
&lt;br /&gt;
If invoked using named parameters, Mediawiki will automatically remove any leading or&lt;br /&gt;
trailing whitespace from the target string.  In some circumstances this is desirable, in&lt;br /&gt;
other cases one may want to preserve the whitespace.&lt;br /&gt;
&lt;br /&gt;
The first character has an index value of 1.&lt;br /&gt;
&lt;br /&gt;
If one requests a negative value, this function will select a character by counting backwards&lt;br /&gt;
from the end of the string.  In other words pos = -1 is the same as asking for the last character.&lt;br /&gt;
&lt;br /&gt;
A requested value of zero, or a value greater than the length of the string returns an error.&lt;br /&gt;
]]&lt;br /&gt;
function str.pos( frame )&lt;br /&gt;
	local new_args = str._getParameters( frame.args, {&#039;target&#039;, &#039;pos&#039;} )&lt;br /&gt;
	local target_str = new_args[&#039;target&#039;] or &#039;&#039;&lt;br /&gt;
	local pos = tonumber( new_args[&#039;pos&#039;] ) or 0&lt;br /&gt;
&lt;br /&gt;
	if pos == 0 or math.abs(pos) &amp;gt; mw.ustring.len( target_str ) then&lt;br /&gt;
		return str._error( &#039;String index out of range&#039; )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return mw.ustring.sub( target_str, pos, pos )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
str_find&lt;br /&gt;
&lt;br /&gt;
This function duplicates the behavior of {{str_find}}, including all of its quirks.&lt;br /&gt;
This is provided in order to support existing templates, but is NOT RECOMMENDED for&lt;br /&gt;
new code and templates.  New code is recommended to use the &amp;quot;find&amp;quot; function instead.&lt;br /&gt;
&lt;br /&gt;
Returns the first index in &amp;quot;source&amp;quot; that is a match to &amp;quot;target&amp;quot;.  Indexing is 1-based,&lt;br /&gt;
and the function returns -1 if the &amp;quot;target&amp;quot; string is not present in &amp;quot;source&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Important Note: If the &amp;quot;target&amp;quot; string is empty / missing, this function returns a&lt;br /&gt;
value of &amp;quot;1&amp;quot;, which is generally unexpected behavior, and must be accounted for&lt;br /&gt;
separatetly.&lt;br /&gt;
]]&lt;br /&gt;
function str.str_find( frame )&lt;br /&gt;
	local new_args = str._getParameters( frame.args, {&#039;source&#039;, &#039;target&#039;} )&lt;br /&gt;
	local source_str = new_args[&#039;source&#039;] or &#039;&#039;&lt;br /&gt;
	local target_str = new_args[&#039;target&#039;] or &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
	if target_str == &#039;&#039; then&lt;br /&gt;
		return 1&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local start = mw.ustring.find( source_str, target_str, 1, true )&lt;br /&gt;
	if start == nil then&lt;br /&gt;
		start = -1&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return start&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
find&lt;br /&gt;
&lt;br /&gt;
This function allows one to search for a target string or pattern within another&lt;br /&gt;
string.&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
{{#invoke:String|find|source_str|target_string|start_index|plain_flag}}&lt;br /&gt;
OR&lt;br /&gt;
{{#invoke:String|find|source=source_str|target=target_str|start=start_index|plain=plain_flag}}&lt;br /&gt;
&lt;br /&gt;
Parameters&lt;br /&gt;
	source: The string to search&lt;br /&gt;
	target: The string or pattern to find within source&lt;br /&gt;
	start: The index within the source string to start the search, defaults to 1&lt;br /&gt;
	plain: Boolean flag indicating that target should be understood as plain&lt;br /&gt;
		text and not as a Lua style regular expression, defaults to true&lt;br /&gt;
&lt;br /&gt;
If invoked using named parameters, Mediawiki will automatically remove any leading or&lt;br /&gt;
trailing whitespace from the parameter.  In some circumstances this is desirable, in&lt;br /&gt;
other cases one may want to preserve the whitespace.&lt;br /&gt;
&lt;br /&gt;
This function returns the first index &amp;gt;= &amp;quot;start&amp;quot; where &amp;quot;target&amp;quot; can be found&lt;br /&gt;
within &amp;quot;source&amp;quot;.  Indices are 1-based.  If &amp;quot;target&amp;quot; is not found, then this&lt;br /&gt;
function returns 0.  If either &amp;quot;source&amp;quot; or &amp;quot;target&amp;quot; are missing / empty, this&lt;br /&gt;
function also returns 0.&lt;br /&gt;
&lt;br /&gt;
This function should be safe for UTF-8 strings.&lt;br /&gt;
]]&lt;br /&gt;
function str.find( frame )&lt;br /&gt;
	local new_args = str._getParameters( frame.args, {&#039;source&#039;, &#039;target&#039;, &#039;start&#039;, &#039;plain&#039; } )&lt;br /&gt;
	local source_str = new_args[&#039;source&#039;] or &#039;&#039;&lt;br /&gt;
	local pattern = new_args[&#039;target&#039;] or &#039;&#039;&lt;br /&gt;
	local start_pos = tonumber(new_args[&#039;start&#039;]) or 1&lt;br /&gt;
	local plain = new_args[&#039;plain&#039;] or true&lt;br /&gt;
&lt;br /&gt;
	if source_str == &#039;&#039; or pattern == &#039;&#039; then&lt;br /&gt;
		return 0&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	plain = str._getBoolean( plain )&lt;br /&gt;
&lt;br /&gt;
	local start = mw.ustring.find( source_str, pattern, start_pos, plain )&lt;br /&gt;
	if start == nil then&lt;br /&gt;
		start = 0&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return start&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
replace&lt;br /&gt;
&lt;br /&gt;
This function allows one to replace a target string or pattern within another&lt;br /&gt;
string.&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
{{#invoke:String|replace|source_str|pattern_string|replace_string|replacement_count|plain_flag}}&lt;br /&gt;
OR&lt;br /&gt;
{{#invoke:String|replace|source=source_string|pattern=pattern_string|replace=replace_string|&lt;br /&gt;
   count=replacement_count|plain=plain_flag}}&lt;br /&gt;
&lt;br /&gt;
Parameters&lt;br /&gt;
	source: The string to search&lt;br /&gt;
	pattern: The string or pattern to find within source&lt;br /&gt;
	replace: The replacement text&lt;br /&gt;
	count: The number of occurences to replace, defaults to all.&lt;br /&gt;
	plain: Boolean flag indicating that pattern should be understood as plain&lt;br /&gt;
		text and not as a Lua style regular expression, defaults to true&lt;br /&gt;
]]&lt;br /&gt;
function str.replace( frame )&lt;br /&gt;
	local new_args = str._getParameters( frame.args, {&#039;source&#039;, &#039;pattern&#039;, &#039;replace&#039;, &#039;count&#039;, &#039;plain&#039; } )&lt;br /&gt;
	local source_str = new_args[&#039;source&#039;] or &#039;&#039;&lt;br /&gt;
	local pattern = new_args[&#039;pattern&#039;] or &#039;&#039;&lt;br /&gt;
	local replace = new_args[&#039;replace&#039;] or &#039;&#039;&lt;br /&gt;
	local count = tonumber( new_args[&#039;count&#039;] )&lt;br /&gt;
	local plain = new_args[&#039;plain&#039;] or true&lt;br /&gt;
&lt;br /&gt;
	if source_str == &#039;&#039; or pattern == &#039;&#039; then&lt;br /&gt;
		return source_str&lt;br /&gt;
	end&lt;br /&gt;
	plain = str._getBoolean( plain )&lt;br /&gt;
&lt;br /&gt;
	if plain then&lt;br /&gt;
		pattern = str._escapePattern( pattern )&lt;br /&gt;
		replace = mw.ustring.gsub( replace, &amp;quot;%%&amp;quot;, &amp;quot;%%%%&amp;quot; ) --Only need to escape replacement sequences.&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local result&lt;br /&gt;
&lt;br /&gt;
	if count ~= nil then&lt;br /&gt;
		result = mw.ustring.gsub( source_str, pattern, replace, count )&lt;br /&gt;
	else&lt;br /&gt;
		result = mw.ustring.gsub( source_str, pattern, replace )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return result&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
	simple function to pipe string.rep to templates.&lt;br /&gt;
]]&lt;br /&gt;
function str.rep( frame )&lt;br /&gt;
	local repetitions = tonumber( frame.args[2] )&lt;br /&gt;
	if not repetitions then&lt;br /&gt;
		return str._error( &#039;function rep expects a number as second parameter, received &amp;quot;&#039; .. ( frame.args[2] or &#039;&#039; ) .. &#039;&amp;quot;&#039; )&lt;br /&gt;
	end&lt;br /&gt;
	return string.rep( frame.args[1] or &#039;&#039;, repetitions )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
escapePattern&lt;br /&gt;
&lt;br /&gt;
This function escapes special characters from a Lua string pattern. See [1]&lt;br /&gt;
for details on how patterns work.&lt;br /&gt;
&lt;br /&gt;
[1] https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Patterns&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
{{#invoke:String|escapePattern|pattern_string}}&lt;br /&gt;
&lt;br /&gt;
Parameters&lt;br /&gt;
	pattern_string: The pattern string to escape.&lt;br /&gt;
]]&lt;br /&gt;
function str.escapePattern( frame )&lt;br /&gt;
	local pattern_str = frame.args[1]&lt;br /&gt;
	if not pattern_str then&lt;br /&gt;
		return str._error( &#039;No pattern string specified&#039; )&lt;br /&gt;
	end&lt;br /&gt;
	local result = str._escapePattern( pattern_str )&lt;br /&gt;
	return result&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
count&lt;br /&gt;
This function counts the number of occurrences of one string in another.&lt;br /&gt;
]]&lt;br /&gt;
function str.count(frame)&lt;br /&gt;
	local args = str._getParameters(frame.args, {&#039;source&#039;, &#039;pattern&#039;, &#039;plain&#039;})&lt;br /&gt;
	local source = args.source or &#039;&#039;&lt;br /&gt;
	local pattern = args.pattern or &#039;&#039;&lt;br /&gt;
	local plain = str._getBoolean(args.plain or true)&lt;br /&gt;
	if plain then&lt;br /&gt;
		pattern = str._escapePattern(pattern)&lt;br /&gt;
	end&lt;br /&gt;
	local _, count = mw.ustring.gsub(source, pattern, &#039;&#039;)&lt;br /&gt;
	return count&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
endswith&lt;br /&gt;
This function determines whether a string ends with another string.&lt;br /&gt;
]]&lt;br /&gt;
function str.endswith(frame)&lt;br /&gt;
	local args = str._getParameters(frame.args, {&#039;source&#039;, &#039;pattern&#039;})&lt;br /&gt;
	local source = args.source or &#039;&#039;&lt;br /&gt;
	local pattern = args.pattern or &#039;&#039;&lt;br /&gt;
	if pattern == &#039;&#039; then&lt;br /&gt;
		-- All strings end with the empty string.&lt;br /&gt;
		return &amp;quot;yes&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	if mw.ustring.sub(source, -mw.ustring.len(pattern), -1) == pattern then&lt;br /&gt;
		return &amp;quot;yes&amp;quot;&lt;br /&gt;
	else&lt;br /&gt;
		return &amp;quot;&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
join&lt;br /&gt;
&lt;br /&gt;
Join all non empty arguments together; the first argument is the separator.&lt;br /&gt;
Usage:&lt;br /&gt;
{{#invoke:String|join|sep|one|two|three}}&lt;br /&gt;
]]&lt;br /&gt;
function str.join(frame)&lt;br /&gt;
	local args = {}&lt;br /&gt;
	local sep&lt;br /&gt;
	for _, v in ipairs( frame.args ) do&lt;br /&gt;
		if sep then&lt;br /&gt;
			if v ~= &#039;&#039; then&lt;br /&gt;
				table.insert(args, v)&lt;br /&gt;
			end&lt;br /&gt;
		else&lt;br /&gt;
			sep = v&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return table.concat( args, sep or &#039;&#039; )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Helper function that populates the argument list given that user may need to use a mix of&lt;br /&gt;
named and unnamed parameters.  This is relevant because named parameters are not&lt;br /&gt;
identical to unnamed parameters due to string trimming, and when dealing with strings&lt;br /&gt;
we sometimes want to either preserve or remove that whitespace depending on the application.&lt;br /&gt;
]]&lt;br /&gt;
function str._getParameters( frame_args, arg_list )&lt;br /&gt;
	local new_args = {}&lt;br /&gt;
	local index = 1&lt;br /&gt;
	local value&lt;br /&gt;
&lt;br /&gt;
	for _, arg in ipairs( arg_list ) do&lt;br /&gt;
		value = frame_args[arg]&lt;br /&gt;
		if value == nil then&lt;br /&gt;
			value = frame_args[index]&lt;br /&gt;
			index = index + 1&lt;br /&gt;
		end&lt;br /&gt;
		new_args[arg] = value&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return new_args&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Helper function to handle error messages.&lt;br /&gt;
]]&lt;br /&gt;
function str._error( error_str )&lt;br /&gt;
	local frame = mw.getCurrentFrame()&lt;br /&gt;
	local error_category = frame.args.error_category or &#039;Errors reported by Module String&#039;&lt;br /&gt;
	local ignore_errors = frame.args.ignore_errors or false&lt;br /&gt;
	local no_category = frame.args.no_category or false&lt;br /&gt;
&lt;br /&gt;
	if str._getBoolean(ignore_errors) then&lt;br /&gt;
		return &#039;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local error_str = &#039;&amp;lt;strong class=&amp;quot;error&amp;quot;&amp;gt;String Module Error: &#039; .. error_str .. &#039;&amp;lt;/strong&amp;gt;&#039;&lt;br /&gt;
	if error_category ~= &#039;&#039; and not str._getBoolean( no_category ) then&lt;br /&gt;
		error_str = &#039;[[Category:&#039; .. error_category .. &#039;]]&#039; .. error_str&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return error_str&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Helper Function to interpret boolean strings&lt;br /&gt;
]]&lt;br /&gt;
function str._getBoolean( boolean_str )&lt;br /&gt;
	local boolean_value&lt;br /&gt;
&lt;br /&gt;
	if type( boolean_str ) == &#039;string&#039; then&lt;br /&gt;
		boolean_str = boolean_str:lower()&lt;br /&gt;
		if boolean_str == &#039;false&#039; or boolean_str == &#039;no&#039; or boolean_str == &#039;0&#039;&lt;br /&gt;
				or boolean_str == &#039;&#039; then&lt;br /&gt;
			boolean_value = false&lt;br /&gt;
		else&lt;br /&gt;
			boolean_value = true&lt;br /&gt;
		end&lt;br /&gt;
	elseif type( boolean_str ) == &#039;boolean&#039; then&lt;br /&gt;
		boolean_value = boolean_str&lt;br /&gt;
	else&lt;br /&gt;
		error( &#039;No boolean value found&#039; )&lt;br /&gt;
	end&lt;br /&gt;
	return boolean_value&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Helper function that escapes all pattern characters so that they will be treated&lt;br /&gt;
as plain text.&lt;br /&gt;
]]&lt;br /&gt;
function str._escapePattern( pattern_str )&lt;br /&gt;
	return mw.ustring.gsub( pattern_str, &amp;quot;([%(%)%.%%%+%-%*%?%[%^%$%]])&amp;quot;, &amp;quot;%%%1&amp;quot; )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[ &lt;br /&gt;
	check if string is a number&lt;br /&gt;
]]&lt;br /&gt;
function str.isNumber( frame )&lt;br /&gt;
	if not tonumber( frame.args[1] ) then &lt;br /&gt;
		return 0 &lt;br /&gt;
	else &lt;br /&gt;
		return 1 &lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return str&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=Template:Wikidata_Infobox/styles.css&amp;diff=3943</id>
		<title>Template:Wikidata Infobox/styles.css</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=Template:Wikidata_Infobox/styles.css&amp;diff=3943"/>
		<updated>2025-12-13T16:58:31Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: Created page with &amp;quot;/* @noflip */ #wdinfobox[dir=&amp;quot;ltr&amp;quot;] { 	float: right; /* override .infobox style: this rule is flipped (changed to “left”) on rtl pages, while MediaWiki:Common.css isn’t */ 	clear: right; /* override .infobox style: this rule is flipped (changed to “left”) on rtl pages, while MediaWiki:Common.css isn’t */ 	margin-right: 0; 	margin-left: 1em; } /* @noflip */ #wdinfobox[dir=&amp;quot;rtl&amp;quot;] { 	float: left; /* override .infobox style: this rule is flipped (changed to “le...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* @noflip */&lt;br /&gt;
#wdinfobox[dir=&amp;quot;ltr&amp;quot;] {&lt;br /&gt;
	float: right; /* override .infobox style: this rule is flipped (changed to “left”) on rtl pages, while MediaWiki:Common.css isn’t */&lt;br /&gt;
	clear: right; /* override .infobox style: this rule is flipped (changed to “left”) on rtl pages, while MediaWiki:Common.css isn’t */&lt;br /&gt;
	margin-right: 0;&lt;br /&gt;
	margin-left: 1em;&lt;br /&gt;
}&lt;br /&gt;
/* @noflip */&lt;br /&gt;
#wdinfobox[dir=&amp;quot;rtl&amp;quot;] {&lt;br /&gt;
	float: left; /* override .infobox style: this rule is flipped (changed to “left”) on rtl pages, while MediaWiki:Common.css isn’t */&lt;br /&gt;
	clear: left; /* override .infobox style: this rule is flipped (changed to “left”) on rtl pages, while MediaWiki:Common.css isn’t */&lt;br /&gt;
	margin-left: 0;&lt;br /&gt;
	margin-right: 1em;&lt;br /&gt;
}&lt;br /&gt;
#wdinfobox {&lt;br /&gt;
	width: 258px;&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
	font-size: 95%;&lt;br /&gt;
	padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#wdinfobox .image img {&lt;br /&gt;
	max-width: 250px;&lt;br /&gt;
	max-height: 250px;&lt;br /&gt;
	width: auto;&lt;br /&gt;
}&lt;br /&gt;
#wdinfoboxcaption {&lt;br /&gt;
	background: #FFF;&lt;br /&gt;
}&lt;br /&gt;
/* @noflip */&lt;br /&gt;
#wdinfobox[dir=&amp;quot;ltr&amp;quot;] #wdinfoboxcaption {&lt;br /&gt;
	margin-left: 0;&lt;br /&gt;
}&lt;br /&gt;
/* @noflip */&lt;br /&gt;
#wdinfobox[dir=&amp;quot;rtl&amp;quot;] #wdinfoboxcaption {&lt;br /&gt;
	margin-right: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#wdinfobox th, #wdinfo_taxon th {&lt;br /&gt;
	vertical-align: top;&lt;br /&gt;
	word-wrap: break-word;&lt;br /&gt;
	hyphens: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#wdinfobox td, #wdinfo_taxon td {&lt;br /&gt;
	word-wrap: break-word;&lt;br /&gt;
	hyphens: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#wdinfobox li:not(:last-child) {&lt;br /&gt;
    margin-bottom: 3px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#wdinfo_taxon {&lt;br /&gt;
	font-size: 95%;&lt;br /&gt;
	table-layout: fixed;&lt;br /&gt;
	padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.taxontree-lcell, .wikidatainfobox-lcell {&lt;br /&gt;
	background: #CFE3FF;&lt;br /&gt;
	padding-left: .4em;&lt;br /&gt;
	padding-right: .4em;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
}&lt;br /&gt;
.taxontree-rcell, .wikidatainfobox-rcell {&lt;br /&gt;
	word-wrap: break-word;&lt;br /&gt;
	hyphens: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* @noflip */&lt;br /&gt;
#wdinfobox[dir=&amp;quot;ltr&amp;quot;] .taxontree-lcell,&lt;br /&gt;
#wdinfobox[dir=&amp;quot;ltr&amp;quot;] .wikidatainfobox-lcell {&lt;br /&gt;
	text-align: right;&lt;br /&gt;
	word-wrap: break-word;&lt;br /&gt;
	hyphens: auto;&lt;br /&gt;
}&lt;br /&gt;
/* @noflip */&lt;br /&gt;
#wdinfobox[dir=&amp;quot;rtl&amp;quot;] .taxontree-lcell,&lt;br /&gt;
#wdinfobox[dir=&amp;quot;rtl&amp;quot;] .wikidatainfobox-lcell {&lt;br /&gt;
	text-align: left;&lt;br /&gt;
	word-wrap: break-word;&lt;br /&gt;
	hyphens: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.taxontree-fullcell {&lt;br /&gt;
	text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.taxontree-hdrcell {&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	background: #CFE3FF;&lt;br /&gt;
	padding-left: .4em;&lt;br /&gt;
	padding-right: .4em;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.taxontree-row {&lt;br /&gt;
	&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media screen and (max-width: 600px) {&lt;br /&gt;
  .wdinfo_nomobile {&lt;br /&gt;
  	display: none;&lt;br /&gt;
  	visibility: hidden;&lt;br /&gt;
  	height: 0;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.wdinfobox_horizontal {&lt;br /&gt;
	clear: both !important;&lt;br /&gt;
	display: block;&lt;br /&gt;
	box-sizing: border-box !important;&lt;br /&gt;
	width: 100% !important;&lt;br /&gt;
	column-width: 24em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.wdinfobox_hide {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#wdcreator {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.wdcreator_show {&lt;br /&gt;
	display: block !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#wdinfo_taxon ul {&lt;br /&gt;
	list-style: none;&lt;br /&gt;
	list-style-position: inside;&lt;br /&gt;
}&lt;br /&gt;
/* @noflip */&lt;br /&gt;
#wdinfobox[dir=&amp;quot;ltr&amp;quot;] #wdinfo_taxon ul {&lt;br /&gt;
	padding-left: 0;&lt;br /&gt;
	margin-left: 0;&lt;br /&gt;
}&lt;br /&gt;
/* @noflip */&lt;br /&gt;
#wdinfobox[dir=&amp;quot;rtl&amp;quot;] #wdinfo_taxon ul {&lt;br /&gt;
	padding-right: 0;&lt;br /&gt;
	margin-right: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.wikidatainfoboxVN ul li {&lt;br /&gt;
	list-style: none;&lt;br /&gt;
	padding: 0;&lt;br /&gt;
	margin: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
.wikidatainfoboxVN ul {&lt;br /&gt;
	margin-left: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.wikidatainfoboxVN {&lt;br /&gt;
	padding: 0;&lt;br /&gt;
	margin: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* {{Protected}} */&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
	<entry>
		<id>https://commons.islamical.org/w/index.php?title=Template:Wikidata_Infobox/core&amp;diff=3942</id>
		<title>Template:Wikidata Infobox/core</title>
		<link rel="alternate" type="text/html" href="https://commons.islamical.org/w/index.php?title=Template:Wikidata_Infobox/core&amp;diff=3942"/>
		<updated>2025-12-13T16:58:07Z</updated>

		<summary type="html">&lt;p&gt;Shahroudi: Created page with &amp;quot;&amp;lt;!-- Please test changes at https://commons.wikimedia.org/wiki/Template:Wikidata_Infobox/sandbox and test that they work before modifying this template directly! --&amp;gt;&amp;lt;templatestyles src=&amp;quot;Template:Wikidata Infobox/styles.css&amp;quot; /&amp;gt;&amp;lt;!--  Categorize working and non-working uses --&amp;gt;&amp;lt;includeonly&amp;gt;{{#ifeq:{{{trackingcats | yes}}} | yes | {{#if:{{{qid|}}} | Category:Uses of Wikidata Infobox | Category:Uses of Wikidata Infobox with no item}}}}&amp;lt;/includeonly&amp;gt;&amp;lt;!--  --&amp;gt;{{#if:{{{q...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&lt;br /&gt;
Please test changes at https://commons.wikimedia.org/wiki/Template:Wikidata_Infobox/sandbox and test that they work before modifying this template directly!&lt;br /&gt;
--&amp;gt;&amp;lt;templatestyles src=&amp;quot;Template:Wikidata Infobox/styles.css&amp;quot; /&amp;gt;&amp;lt;!--&lt;br /&gt;
&lt;br /&gt;
Categorize working and non-working uses --&amp;gt;&amp;lt;includeonly&amp;gt;{{#ifeq:{{{trackingcats | yes}}} | yes | {{#if:{{{qid|}}} | [[Category:Uses of Wikidata Infobox]] | [[Category:Uses of Wikidata Infobox with no item]]}}}}&amp;lt;/includeonly&amp;gt;&amp;lt;!--&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;{{#if:{{{qid|}}} | {{#invoke:Wikidata Infobox|main|{{{qid}}}}} |&amp;lt;!--&lt;br /&gt;
-- no qid--&amp;gt;&amp;lt;table id=&amp;quot;wdinfobox&amp;quot; class=&amp;quot;fileinfotpl-type-information vevent infobox&amp;quot; dir=&amp;quot;{{#dir}}&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td colspan=2 style=&amp;quot;text-align:center;&amp;quot;&amp;gt;&#039;&#039;&#039;{{Wikidata Infobox/i18n/getMsg|noid}}&#039;&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[https://www.wikidata.org/w/index.php?search={{PAGENAMEE}} {{Wikidata Infobox/i18n/getMsg|search}}]&#039;&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[https://www.wikidata.org/wiki/Special:NewItem?site=commonswiki&amp;amp;page={{FULLPAGENAMEE}}&amp;amp;label={{#invoke:String|replace|{{PAGENAMEE}}|_|+}} {{Wikidata Infobox/i18n/getMsg|newitem}}]&#039;&#039;&#039;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{#ifeq:{{{conf_upload|}}}|yes|&amp;lt;tr&amp;gt;&amp;lt;td colspan=2 style=&amp;quot;text-align: center&amp;quot;&amp;gt;&#039;&#039;&#039;[{{fullurl:Special:UploadWizard|categories={{PAGENAMEE}}}} {{int:Cx-contributions-upload}}]&#039;&#039;&#039;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;}}&amp;lt;/table&amp;gt;}}&amp;lt;!-- end of qid check&lt;br /&gt;
--&amp;gt;&amp;lt;noinclude&amp;gt;{{Documentation}}&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Shahroudi</name></author>
	</entry>
</feed>