<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>http://iti-testbed.tugraz.at/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Schuschu</id>
	<title>D-Cube - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="http://iti-testbed.tugraz.at/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Schuschu"/>
	<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php/Special:Contributions/Schuschu"/>
	<updated>2026-05-04T19:16:22Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.33.1</generator>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=Topology_of_Nodes&amp;diff=675</id>
		<title>Topology of Nodes</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=Topology_of_Nodes&amp;diff=675"/>
		<updated>2023-01-22T13:38:46Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Complete Testbed Map Image.png|upright=4.0|frameless|Map of the testbed facility in Graz, Austria]]&lt;br /&gt;
&lt;br /&gt;
[[File:Complete Testbed Map.pdf|thumb|Map of the testbed facility]]&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=File:Complete_Testbed_Map_Image.png&amp;diff=674</id>
		<title>File:Complete Testbed Map Image.png</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=File:Complete_Testbed_Map_Image.png&amp;diff=674"/>
		<updated>2023-01-22T13:37:05Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Map of the testbed facility in Graz, Austria&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=Topology_of_Nodes&amp;diff=673</id>
		<title>Topology of Nodes</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=Topology_of_Nodes&amp;diff=673"/>
		<updated>2023-01-22T13:35:16Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Complete Testbed Map.pdf|thumb|Map of the testbed facility]]&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=File:Complete_Testbed_Map.pdf&amp;diff=672</id>
		<title>File:Complete Testbed Map.pdf</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=File:Complete_Testbed_Map.pdf&amp;diff=672"/>
		<updated>2023-01-22T13:35:06Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Map of the testbed facility in Graz, Austria&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=Special_Features&amp;diff=665</id>
		<title>Special Features</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=Special_Features&amp;diff=665"/>
		<updated>2021-05-23T09:21:06Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;br /&amp;gt; &lt;br /&gt;
{|&lt;br /&gt;
|&amp;lt;strong&amp;gt;Reproducible Wi-Fi interference generation.&amp;lt;/strong&amp;gt; D-Cube embeds &amp;lt;i&amp;gt;JamLab-NG&amp;lt;/i&amp;gt;, an open-source framework allowing the generation of controllable Wi-Fi interference using the off-the-shelf devices such as the Raspberry Pi 3. JamLab-NG enables the fine-grained control of individual link-layer frames sent by the BCM43430A1 Wi-Fi module embedded in the Raspberry Pi 3, avoiding the uncontrollable delays introduced by the network stack, operating system, and clear channel assessment procedure. JamLab-NG also allows generating repeatable Wi-Fi interference patterns by controlling radio settings such as the transmission speed and the packet length, which would otherwise be automatically adapted by the radio firmware at runtime. Each observer node in D-Cube can act as an interfering device using JamLab-NG in parallel to its measurement tasks. The JamLab-NG code is based on [https://github.com/seemoo-lab/nexmon NexMon] and is [http://www.iti.tugraz.at/JamLab-NG openly available] to the community. An article describing JamLab-NG in detail is available as PDF [http://www.carloalbertoboano.com/documents/schuss19jamlabng.pdf here].&lt;br /&gt;
|[[File:empty.png|left|195px]]&lt;br /&gt;
|[[File:jamlabng_architecture.png|2475px|right]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|&amp;lt;strong&amp;gt;Binary patching.&amp;lt;/strong&amp;gt; D-Cube embeds the ability to build and apply patches to binary files. This allows a large degree of freedom when testing protocol performance: binary patching allows indeed D-Cube to seamlessly benchmark the firmware under test for different sets of input parameters, such as the amount of data to be transmitted, traffic patterns and load, as well as node identity (i.e., address of the source and destination nodes). &lt;br /&gt;
In particular, D-Cube directly injects these input parameters into the firmware under test by exploiting a well-known data structure, as explained in [http://www.carloalbertoboano.com/documents/schuss18benchmark.pdf this paper] (Section IV). Essentially, the developers add a new section to their base firmware containing an instance of the well-known data structure assigning placeholder values for all its fields that will be automatically replaced by D-Cube's binary patching framework. The latter even allows developers to define user-defined protocol parameters, a useful feature to check which protocol parameters actually deliver the best performance. &lt;br /&gt;
|[[File:empty.png|left|195px]]&lt;br /&gt;
|[[File:Binary_patching.png|1475px|right]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|&amp;lt;strong&amp;gt;EEPROM mailbox. &amp;lt;/strong&amp;gt; D-Cube makes use of an EEPROM acting as a mailbox between the benchmarking infrastructure and the target nodes running the firmware under test in order to schedule the transmission and timestamp the reception of data packets. In particular, an I2C bus is shared between each D-Cube's [[Observer Nodes|observer node]] and the target nodes (Tmote Sky, nRF52840) connected to it. D-Cube signals the availability of new data to be transmitted from a given node by loading the information onto the EEPROM and by toggling a pre-defined GPIO pin. Conversely, a target node can signal the reception of new data by writing it to the EEPROM and by raising a pre-defined GPIO pin accordingly. D-Cube then verifies the correctness of the information written in the EEPROM and uses the GPIO rising edge timestamp to compute the end-to-end latency of communications in the network. For more information, please refer to [[How to Use|this page]].&lt;br /&gt;
|[[File:empty.png|left|195px]]&lt;br /&gt;
|[[File:dcube_eeprom.png|2775px|right]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=File:ZB_250k.zip&amp;diff=658</id>
		<title>File:ZB 250k.zip</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=File:ZB_250k.zip&amp;diff=658"/>
		<updated>2020-11-24T14:08:57Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: Topology for 250kBit Zigbee&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
Topology for 250kBit Zigbee&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=File:NRF_2M.zip&amp;diff=657</id>
		<title>File:NRF 2M.zip</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=File:NRF_2M.zip&amp;diff=657"/>
		<updated>2020-11-24T14:08:31Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: Topology for 2MBit nRF Prop PHY&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
Topology for 2MBit nRF Prop PHY&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=File:NRF_1M.zip&amp;diff=656</id>
		<title>File:NRF 1M.zip</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=File:NRF_1M.zip&amp;diff=656"/>
		<updated>2020-11-24T14:08:06Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: Topology for 1MBit nRF Prop PHY&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
Topology for 1MBit nRF Prop PHY&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=File:BLE_500k.zip&amp;diff=655</id>
		<title>File:BLE 500k.zip</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=File:BLE_500k.zip&amp;diff=655"/>
		<updated>2020-11-24T14:07:36Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: Topology for 500kBit Coded BLE&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
Topology for 500kBit Coded BLE&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=File:BLE_125k.zip&amp;diff=654</id>
		<title>File:BLE 125k.zip</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=File:BLE_125k.zip&amp;diff=654"/>
		<updated>2020-11-24T14:07:15Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: Topology for 125kBit Coded BLE&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
Topology for 125kBit Coded BLE&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=File:BLE_2M.zip&amp;diff=653</id>
		<title>File:BLE 2M.zip</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=File:BLE_2M.zip&amp;diff=653"/>
		<updated>2020-11-24T14:06:45Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: Topology for 2MBit BLE&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
Topology for 2MBit BLE&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=File:BLE_1M.zip&amp;diff=652</id>
		<title>File:BLE 1M.zip</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=File:BLE_1M.zip&amp;diff=652"/>
		<updated>2020-11-24T14:06:22Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: Topology for 1MBit BLE&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
Topology for 1MBit BLE&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=File:NRFDC_1.zip&amp;diff=645</id>
		<title>File:NRFDC 1.zip</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=File:NRFDC_1.zip&amp;diff=645"/>
		<updated>2019-12-19T18:47:27Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: Schuschu uploaded a new version of File:NRFDC 1.zip&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
Tested against nRF5_SDK_16.0.0_98a08e2. Place into \examples\peripheral\nRFDC_1 ARM-GCC and Segger Embedded Studio are supported.&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=Overview_of_Available_Suites&amp;diff=644</id>
		<title>Overview of Available Suites</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=Overview_of_Available_Suites&amp;diff=644"/>
		<updated>2019-12-05T13:56:07Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: updated number of source and destination nodes in several benchmark suites, replaced sink with destination to keep a common naming scheme.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
D-Cube currently supports three benchmark suites. Each suite is specified by: (i) a given hardware platform, (ii) a given application scenario, and (iii) a set of performance metrics. We describe next the benchmark suites on a high level:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;strong&amp;gt;SkyDC_1 (Tmote Sky Data Collection v1).&amp;lt;/strong&amp;gt; This benchmark resembles the first category of the [http://ewsn2019.thss.tsinghua.edu.cn/competition-scenario.html EWSN 2019 dependability competition]. &lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Hardware platform&amp;lt;/i&amp;gt;: Tmote Sky.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Application scenario&amp;lt;/i&amp;gt;: In this benchmark, a fixed number of source nodes (at most eight) communicate to a single destination node over a multi-hop network. This benchmark hence focuses on multipoint-to-point traffic. In particular, each destination node collects sensor data of different length transmitted by the different source nodes and allows out-of-order delivery.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Performance metrics&amp;lt;/i&amp;gt;: The measured performance metrics are: (i) the reliability of transmissions, i.e., the number of messages correctly reported to each intended destination, (ii) the average end-to-end latency in communicating each message to its intended destination(s), and (iii) the average energy consumption on all nodes in the network. Note that, on each run, during the first 60 seconds no data is generated and the energy consumption is not measured, so to allow the firmware under test to bootstrap the network.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
The results of this benchmark are available [https://iti-testbed.tugraz.at/leaderboard/benchmarksuite/1 here]. An example of the pre-defined config struct for binary patching for this benchmark suite is available [https://iti-testbed.tugraz.at/wiki/images/9/97/SkyDC_1.zip here].&amp;lt;/li&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;strong&amp;gt;SkyDD_1 (Tmote Sky Data Dissemination v1).&amp;lt;/strong&amp;gt; This benchmark resembles the second category of the [http://ewsn2019.thss.tsinghua.edu.cn/competition-scenario.html EWSN 2019 dependability competition]. &lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Hardware platform&amp;lt;/i&amp;gt;: Tmote Sky.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Application scenario&amp;lt;/i&amp;gt;: In this benchmark, a fixed number of source nodes (at most eight) needs to disseminate actuation commands of different length to a specific set of destination nodes over a multi-hop network. This benchmark hence focuses on point-to-multipoint traffic. In particular, each source node is associated with a specific set of destinations (at most eight), which will be injected as an input parameter into the firmware under test. A destination can receive messages from only a single source node, cannot act as a source at the same time, and allows out-of-order delivery.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Performance metrics&amp;lt;/i&amp;gt;: The measured performance metrics are: (i) the reliability of transmissions, i.e., the number of messages correctly reported to each intended destination, (ii) the average end-to-end latency in communicating each message to its intended destination(s), and (iii) the average energy consumption on all nodes in the network. Note that, on each run, during the first 60 seconds no data is generated and the energy consumption is not measured, so to allow the firmware under test to bootstrap the network. &lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
The results of this benchmark are available [https://iti-testbed.tugraz.at/leaderboard/benchmarksuite/2 here]. An example of the pre-defined config struct for binary patching for this benchmark suite is available [https://iti-testbed.tugraz.at/wiki/images/9/97/SkyDC_1.zip here].&amp;lt;/li&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;strong&amp;gt;nRFDC_1 (nRF52840 Timely Data Collection v1). &amp;lt;/strong&amp;gt; This benchmark runs on the nRF52840 platform and resembles a data collection with bounded delays within a multi-hop network. &lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Hardware platform&amp;lt;/i&amp;gt;: nRF52840.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Application scenario&amp;lt;/i&amp;gt;: This benchmark focuses on multipoint-to-point traffic: up to 48 source nodes generate raw sensor values of different lengths, which should be communicated to the same destination. The latter may be located several hops away from a given source node, even when making use of the coded PHY layers available on the nRF52. The messages containing the raw sensor values should be forwarded to the intended destination as efficiently as possible within a maximum per-message delay bound ∂, i.e., the end-to-end delay of every message from its generation to its reception at the destination should be lower than ∂ (which is fixed and applies to all messages exchanged during a test run). If a message has been received with an end-to-end delay greater than ∂, it is considered to be lost.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Performance metrics&amp;lt;/i&amp;gt;: The measured performance metrics are: (i) the reliability of transmissions, i.e., the number of messages correctly reported to each intended destination, and (ii) the average energy consumption on all nodes in the network. Note that, on each run, during the first 60 seconds no data is generated and the energy consumption is not measured, so to allow the firmware under test to bootstrap the network. &lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
The results of this benchmark are available [https://iti-testbed.tugraz.at/leaderboard/benchmarksuite/3 here]. An example of the pre-defined config struct for binary patching for this benchmark suite is available [https://iti-testbed.tugraz.at/wiki/images/d/db/NRFDC_1.zip here].&amp;lt;/li&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;strong&amp;gt;nRFDD_1 (nRF52840 Timely Data Dissemination v1). &amp;lt;/strong&amp;gt; This benchmark runs on the nRF52840 platform and resembles a data dissemination with bounded delays within a multi-hop network. &lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Hardware platform&amp;lt;/i&amp;gt;: nRF52840.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Application scenario&amp;lt;/i&amp;gt;: In this benchmark, a single source nodes needs to disseminate actuation commands of different length to a specific set of up to 48 destination nodes over a multi-hop network. This benchmark hence focuses on point-to-multipoint traffic. The identity of the source node and its associated destinations nodes be injected as an input parameter into the firmware under test. A destination cannot act as a source at the same time, but allows out-of-order delivery. The messages should be disseminated to all intended destinations as efficiently as possible within a maximum per-message delay bound ∂, i.e., the end-to-end delay of every message from its generation to its reception at the destination should be lower than ∂ (which is fixed and applies to all messages exchanged during a test run). If a message has been received with an end-to-end delay greater than ∂, it is considered to be lost.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Performance metrics&amp;lt;/i&amp;gt;: The measured performance metrics are: (i) the reliability of transmissions, i.e., the number of messages correctly reported to each intended destination, and (ii) the average energy consumption on all nodes in the network. Note that, on each run, during the first 60 seconds no data is generated and the energy consumption is not measured, so to allow the firmware under test to bootstrap the network. &lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
The results of this benchmark are available [https://iti-testbed.tugraz.at/leaderboard/benchmarksuite/4 here]. An example of the pre-defined config struct for binary patching for this benchmark suite is available [https://iti-testbed.tugraz.at/wiki/images/d/db/NRFDC_1.zip here].&amp;lt;/li&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=File:SkyDC_1.zip&amp;diff=639</id>
		<title>File:SkyDC 1.zip</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=File:SkyDC_1.zip&amp;diff=639"/>
		<updated>2019-11-28T15:39:31Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: Tested against Contiki &amp;quot;3.1&amp;quot;. Originally used during EWSN'2019 Dependability Competition.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
Tested against Contiki &amp;quot;3.1&amp;quot;. Originally used during EWSN'2019 Dependability Competition.&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=File:NRFDC_1.zip&amp;diff=636</id>
		<title>File:NRFDC 1.zip</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=File:NRFDC_1.zip&amp;diff=636"/>
		<updated>2019-11-28T13:10:25Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: Schuschu uploaded a new version of File:NRFDC 1.zip&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
Tested against nRF5_SDK_16.0.0_98a08e2. Place into \examples\peripheral\nRFDC_1 ARM-GCC and Segger Embedded Studio are supported.&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=File:NRFDC_1.zip&amp;diff=605</id>
		<title>File:NRFDC 1.zip</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=File:NRFDC_1.zip&amp;diff=605"/>
		<updated>2019-11-14T18:05:53Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: Tested against nRF5_SDK_16.0.0_98a08e2. Place into \examples\peripheral\nRFDC_1 ARM-GCC and Segger Embedded Studio are supported.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
Tested against nRF5_SDK_16.0.0_98a08e2. Place into \examples\peripheral\nRFDC_1 ARM-GCC and Segger Embedded Studio are supported.&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=File:Competition_example_2020.zip&amp;diff=601</id>
		<title>File:Competition example 2020.zip</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=File:Competition_example_2020.zip&amp;diff=601"/>
		<updated>2019-11-13T12:08:41Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: Tested against nRF5_SDK_16.0.0_98a08e2.
Place into \examples\peripheral\ewsn2020
ARM-GCC and Segger Embedded Studio are supported.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
Tested against nRF5_SDK_16.0.0_98a08e2.&lt;br /&gt;
Place into \examples\peripheral\ewsn2020&lt;br /&gt;
ARM-GCC and Segger Embedded Studio are supported.&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=Template:Documentation/doc&amp;diff=569</id>
		<title>Template:Documentation/doc</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=Template:Documentation/doc&amp;diff=569"/>
		<updated>2019-11-10T17:40:36Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TemplateBox&lt;br /&gt;
 |name = Documentation&lt;br /&gt;
 |desc-en = This template automatically displays a green documentation box like you are seeing now, and automatically loads the content from a /doc subpage. It can also load the content from other places if instructed to. It is intended for pages which are [[:en:Wikipedia:Transclusion|transcluded]] in other pages, i.e. templates, whether in the template namespace or not.&lt;br /&gt;
 |desc-td-en = This template automatically displays a green documentation box like you are seeing now, and automatically loads the content from a /doc subpage. It can also load the content from other places if instructed to. It is intended for pages which are transcluded in other pages, i.e. templates, whether in the template namespace or not.&lt;br /&gt;
 |usage-notes = This template allows any page to use any documentation page, and makes it possible to protect templates while allowing anyone to edit the template's documentation, and categories. It also reduces server resources by circumventing a [[:en:Wikipedia:Template limits|technical limitation of templates]] (see a [{{fullurl:en:Project:Village pump (technical)|diff=prev&amp;amp;oldid=69888944}} developer's explanation]).&lt;br /&gt;
&lt;br /&gt;
This code should be added at the bottom of the template code, with no extra space before &amp;quot;&amp;lt;code&amp;gt;&amp;amp;lt;noinclude&amp;amp;gt;&amp;lt;/code&amp;gt;&amp;quot; (which would cause extra space on pages where the template is used). The parameter can be used as shown above to transclude an arbitrary documentation page.&lt;br /&gt;
&lt;br /&gt;
Add categories to the documentation page inside includeonly tags.&lt;br /&gt;
&lt;br /&gt;
If the documentation page contains includeonly or noinclude tags as part of the documentation, replace the &amp;quot;&amp;lt;&amp;quot; with &amp;quot;&amp;amp;amp;lt;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 |1        = 1&lt;br /&gt;
 &amp;lt;!-- |1aliases = List of aliases, separated by / (a slash) --&amp;gt;&lt;br /&gt;
 |1label   = pagename&lt;br /&gt;
 |1d-en    = Template name (if there's no explicit namespace, the page is assumed to be in the &amp;quot;Template:&amp;quot; namespace; to specify a page in the main namespace, prefix it explicitly with &amp;quot;:&amp;quot;)&lt;br /&gt;
 |1type    = string/wiki-page-name&lt;br /&gt;
 |1def     = The current template page with the suffix /doc&lt;br /&gt;
 |1stat    = optional&lt;br /&gt;
&lt;br /&gt;
 |2        = heading&lt;br /&gt;
 |2label   = heading text&lt;br /&gt;
 |2aliases = 2&lt;br /&gt;
 |2d-td-en= Change the text of the &amp;quot;documentation&amp;quot; heading. If this is set to blank, the entire heading line (including the first [edit] link) will also disappear. If the documentation page doesn't exist, the &amp;quot;edit&amp;quot; link includes a preload parameter so that clicking it will pre-fill the edit form with the basic documentation page format.&lt;br /&gt;
 |2d-en    = Change the text of the &amp;quot;documentation&amp;quot; heading. If this is set to blank, the entire heading line (including the first [edit] link) will also disappear. If the documentation page doesn't exist, the &amp;quot;edit&amp;quot; link includes a [[mw:Manual:Creating pages with preloaded text|preload]] parameter so that clicking it will pre-fill the edit form with the basic documentation page format.&lt;br /&gt;
 |2type    = string&lt;br /&gt;
 |2def     = icon and &amp;quot;Documentation&amp;quot; text&lt;br /&gt;
 |2stat    = optional-&lt;br /&gt;
&lt;br /&gt;
 |3        = content&lt;br /&gt;
 |3label   = content&lt;br /&gt;
 |3d-en    = The content of the documentation can also be fed directly as text, instead of being specified by the name of the page containing it (parameter {{para|1}}). This option is mostly useful in a rare case where is a single documentation template is used to document many templates, with very little content change. In such a case, the {{para|content}} parameter can be used to call the documentation template with additional parameters, like &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;content = {{Any doc page/doc |parameter1 |parameter2}}&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. See &amp;quot;Usage&amp;quot; section below for more examples and [[:Category:Multi-template documentation]] for examples of template documentation pages used for more than one template.&lt;br /&gt;
 |3d-td-en = The content of the documentation can also be fed directly as text, instead of being specified by the name of the page containing it (parameter &amp;quot;1=&amp;quot;). This option is mostly useful in a rare case where is a single documentation template is used to document many templates, with very little content change. In such a case, the &amp;quot;content=&amp;quot; parameter can be used to call the documentation template with additional parameters, like &amp;quot;&amp;lt;nowiki&amp;gt;content = {{Any doc page/doc |parameter1 |parameter2}}&amp;lt;/nowiki&amp;gt;&amp;quot;. See &amp;quot;Usage&amp;quot; section below for more examples and &amp;quot;Category:Multi-template documentation&amp;quot; for examples of template documentation pages used for more than one template.&lt;br /&gt;
 |3type    = string&lt;br /&gt;
 |3def     = &lt;br /&gt;
 |3stat    = optional-&lt;br /&gt;
&lt;br /&gt;
 |namespace = template&lt;br /&gt;
 |usergroup = all&lt;br /&gt;
 |placement = bottom&lt;br /&gt;
 |type = &lt;br /&gt;
 |setscats = &lt;br /&gt;
 |lines = one&lt;br /&gt;
 |shorthand = &lt;br /&gt;
 |relieson = &lt;br /&gt;
 |mustbesubst = &lt;br /&gt;
 |useTemplateData = 1&lt;br /&gt;
 |usage-notes = &lt;br /&gt;
Normally this template is used without any parameters, placed at the bottom of the template or page being documented, within a {{tag|noinclude}} container:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!--Last line of your template code--&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{Documentation}}&lt;br /&gt;
&amp;lt;!-- Add categories to the /doc subpage --&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then this template automatically loads the content from the /doc subpage of the template it is used on.&lt;br /&gt;
&lt;br /&gt;
This template can also load the content from any other page. Like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!--Last line of your template code--&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{Documentation |Template:Other page/doc}}&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that when loading the documentation from a page other than the local /doc page it becomes tricky to handle the categories.&lt;br /&gt;
&lt;br /&gt;
The content can also be fed directly as text. Like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!--Last line of your template code--&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{Documentation&lt;br /&gt;
 | content =&lt;br /&gt;
(some documentation)&lt;br /&gt;
}}&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the {{para|content}} parameter is used, the doc box normally does not show the [edit] [purge] links in the top right corner. Note that if the /doc page exists, a link to it is still shown in the link box below the doc box.&lt;br /&gt;
&lt;br /&gt;
Parameter {{para|1}} and the {{para|content}} parameter can also be combined, like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!--Last line of your template code--&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{Documentation |1=Template:Any page/doc&lt;br /&gt;
| content = {{Any page/doc |parameters}}&lt;br /&gt;
}}&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then the pagename fed as parameter 1 is used for the [edit] [purge] links and for the /doc link in the link box below the doc box. But the '''content''' parameter is used for the content shown in the doc box. The above code means that the content is transcluded as {{tnull|Template:Any page/doc{{!}}parameters}}. In this example a parameter is also fed to the /doc page being loaded.&lt;br /&gt;
 |example = &lt;br /&gt;
 |example-value =&lt;br /&gt;
 |seealso =&lt;br /&gt;
* {{Tl|documentation subpage}}&lt;br /&gt;
* [[m:Template:Documentation]]&lt;br /&gt;
* {{Tl|Description}}&lt;br /&gt;
&lt;br /&gt;
 |i18n-method = autotranslate&lt;br /&gt;
 |i18n-desc = &lt;br /&gt;
 |i18n-mediawiki-msg = &lt;br /&gt;
 |i18n-subpage = &lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;includeonly&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Template documentation| ]]&lt;br /&gt;
[[Category:Template namespace templates]]&lt;br /&gt;
&amp;lt;/includeonly&amp;gt;&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=Module:No_globals&amp;diff=562</id>
		<title>Module:No globals</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=Module:No_globals&amp;diff=562"/>
		<updated>2019-11-10T17:37:36Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local mt = getmetatable(_G) or {}&lt;br /&gt;
function mt.__index (t, k)&lt;br /&gt;
	if k ~= 'arg' then&lt;br /&gt;
		error('Tried to read nil global ' .. tostring(k), 2)&lt;br /&gt;
	end&lt;br /&gt;
	return nil&lt;br /&gt;
end&lt;br /&gt;
function mt.__newindex(t, k, v)&lt;br /&gt;
	if k ~= 'arg' then&lt;br /&gt;
		error('Tried to write global ' .. tostring(k), 2)&lt;br /&gt;
	end&lt;br /&gt;
	rawset(t, k, v)&lt;br /&gt;
end&lt;br /&gt;
setmetatable(_G, mt)&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=Module:QuickTest&amp;diff=564</id>
		<title>Module:QuickTest</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=Module:QuickTest&amp;diff=564"/>
		<updated>2019-11-10T17:37:36Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-- Tests whether a module has a test API, and if so, runs these tests&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
function p.run(titleCurrentPage)&lt;br /&gt;
	local title = titleCurrentPage&lt;br /&gt;
	local titlesplit = mw.text.split(title, '/', true)&lt;br /&gt;
	if titlesplit[1]:find('Module:', 1, true) ~= 1 then return '' end&lt;br /&gt;
	if titlesplit[#titlesplit] == 'doc' then&lt;br /&gt;
		table.remove(titlesplit)&lt;br /&gt;
	end&lt;br /&gt;
	title = table.concat(titlesplit, '/')&lt;br /&gt;
	&lt;br /&gt;
	-- Load the module&lt;br /&gt;
	local m = require(title)&lt;br /&gt;
	local testType = 'public-member'&lt;br /&gt;
	local testFunction = ( (type(m) == 'table') and (getmetatable(m) and getmetatable(m).quickTests or m['runTests']) )&lt;br /&gt;
	local testFunctionType = type(testFunction)&lt;br /&gt;
	if ( (type(m) == 'table') and (getmetatable(m) and getmetatable(m).quickTests) ) then&lt;br /&gt;
		testType = 'meta-table'&lt;br /&gt;
	end&lt;br /&gt;
	if ( testFunctionType ~= 'function' and not ( testFunctionType == 'table' and getmetatable(testFunction).__call ) ) then&lt;br /&gt;
		return '', title, testType&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Execute the test function&lt;br /&gt;
	local ok, result = pcall(testFunction)&lt;br /&gt;
	if ok then&lt;br /&gt;
		return result, title, testType&lt;br /&gt;
	else&lt;br /&gt;
		return 'error', title, testType&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function cat(title, titleCurrentPage, cat)&lt;br /&gt;
	if titleCurrentPage == title then return cat end&lt;br /&gt;
	return ''&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.testModule(frame)&lt;br /&gt;
	local titleCurrentPage =  ( frame.args and frame.args.title ) or ( frame and frame:preprocess('{{FULLPAGENAME}}') ) or 'Frame not defined.'&lt;br /&gt;
	local testResult, title, testType = p.run(titleCurrentPage)&lt;br /&gt;
	local testCode = '=p.runTests()'&lt;br /&gt;
&lt;br /&gt;
	if testResult == true then&lt;br /&gt;
		return '[[File:Octicons-check.svg|16px|alt=Quick tests passed|Quick tests passed|link=COM:LUA/T#auto]]' .. cat(title, titleCurrentPage, '[[Category:Scribunto modules with tests passed]]')&lt;br /&gt;
	elseif testResult == false then&lt;br /&gt;
		if testType == 'meta-table' then&lt;br /&gt;
			testCode = '=getmetatable(p).quickTests()'&lt;br /&gt;
		end&lt;br /&gt;
		return '[[File:Octicons-bug.svg|16px|alt=Bug executing tests|Bug executing tests|link=COM:LUA/T#auto]] Run &amp;lt;code&amp;gt;' .. testCode .. '&amp;lt;/code&amp;gt; in the LUA console on [[' .. title .. ']] for more details.' .. cat(title, titleCurrentPage, '[[Category:Scribunto modules with tests failed]]')&lt;br /&gt;
	elseif testResult == 'error' then&lt;br /&gt;
		return '[[File:Octicons-issue-opened.svg|16px|alt=Error|link=COM:LUA/T#auto]] Error executing tests.' .. cat(title, titleCurrentPage, '[[Category:Scribunto modules with errors executing tests]]')&lt;br /&gt;
	else&lt;br /&gt;
		return '[[File:Octicons-megaphone.svg|16px|alt=No test API|link=COM:LUA/T#auto-howto]] '.. testResult .. cat(title, titleCurrentPage, '[[Category:Scribunto modules without test API]]')&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.injectResult(frame)&lt;br /&gt;
	local result = p.testModule(frame)&lt;br /&gt;
	if result == '' then return '' end&lt;br /&gt;
	&lt;br /&gt;
	return ( frame.args['pattern']:gsub('%%result%%', result) )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local mt = {&lt;br /&gt;
	quickTests = function ()&lt;br /&gt;
		return 'function' == type( p.injectResult )&lt;br /&gt;
	end&lt;br /&gt;
}&lt;br /&gt;
setmetatable(p, mt)&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=Template:Module-nav/tab3&amp;diff=546</id>
		<title>Template:Module-nav/tab3</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=Template:Module-nav/tab3&amp;diff=546"/>
		<updated>2019-11-10T17:37:35Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;onlyinclude&amp;gt;&amp;lt;span style=&amp;quot;display:inline-block; padding:0 1px 0 0; {{linear-gradient|top|#d6d4c7 0%, #c4bb8b 100%}};&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;display:inline-block;{{linear-gradient|top|#fefcea 0%, #ede3a6 100%}}; padding:.8em;&amp;quot;&amp;gt;{{{text}}}&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/onlyinclude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{documentation}}&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=Template:Module_rating&amp;diff=548</id>
		<title>Template:Module rating</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=Template:Module_rating&amp;diff=548"/>
		<updated>2019-11-10T17:37:35Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;includeonly&amp;gt;{{Module other|{{ombox&lt;br /&gt;
 | type      = notice&lt;br /&gt;
 | image     = {{#switch: {{{1|}}}&lt;br /&gt;
   | pre-alpha | prealpha | pa = [[File:Ambox warning blue construction.svg|40x40px|link=|alt=Pre-alpha]]&lt;br /&gt;
   | alpha | a                 = [[File:Alpha lowercase.svg|26x26px|link=|alt=Alpha]]&lt;br /&gt;
   | beta | b                  = [[File:Greek lc beta.svg|40x40px|link=|alt=Beta]]&lt;br /&gt;
   | release | r | general | g = [[File:Green check.svg|40x40px|link=|alt=Ready for use]]&lt;br /&gt;
   | protected | protect | p   = [[File:{{#switch:{{#invoke:Effective protection level|edit|{{#switch:{{SUBPAGENAME}}|doc|sandbox={{FULLBASEPAGENAME}}|{{FULLPAGENAME}}}}}}|autoconfirmed=Semi|extendedconfirmed=Extended|accountcreator|templateeditor=Template|#default=Full}}-protection-shackle.svg|40x40px|link=|alt=Protected]]&lt;br /&gt;
   | semiprotected | semiprotect | semi =[[File:Semi-protection-shackle.svg|40x40px|link=|alt=Semi-protected]]&lt;br /&gt;
  }}&lt;br /&gt;
 | style     = &lt;br /&gt;
 | textstyle = &lt;br /&gt;
 | text      = {{#switch: {{{1|}}}&lt;br /&gt;
   | pre-alpha | prealpha | pa = This module is rated as [[:Category:Modules in pre-alpha development|pre-alpha]]. It is unfinished, and may or may not be in active development. It should not be used from article namespace pages. Modules remain pre-alpha until the original editor (or someone who takes one over if it is abandoned for some time) is satisfied with the basic structure.&amp;lt;!--&lt;br /&gt;
   --&amp;gt;{{#switch: {{SUBPAGENAME}}|doc|sandbox=&amp;lt;!-- No category for /doc or /sandbox subpages --&amp;gt;&lt;br /&gt;
       | {{#ifeq: {{{nocat|}}} | true | &amp;lt;!-- No category if user sets nocat=true --&amp;gt; | [[Category:Modules in pre-alpha development|{{PAGENAME}}]] }}&lt;br /&gt;
      }}&lt;br /&gt;
   | alpha | a                 = This module is rated as [[:Category:Modules in alpha|alpha]]. It is ready for third-party input, and may be used on a few pages to see if problems arise, but should be watched. Suggestions for new features or changes in their input and output mechanisms are welcome.&amp;lt;!--&lt;br /&gt;
   --&amp;gt;{{#switch: {{SUBPAGENAME}}|doc|sandbox=&amp;lt;!-- No category for /doc or /sandbox subpages --&amp;gt;&lt;br /&gt;
       | {{#ifeq: {{{nocat|}}} | true | &amp;lt;!-- No category if user sets nocat=true --&amp;gt; | [[Category:Modules in alpha|{{PAGENAME}}]] }}&lt;br /&gt;
      }}&lt;br /&gt;
   | beta | b                  = This module is rated as [[:Category:Modules in beta|beta]], and is ready for widespread use. It is still new and should be used with some caution to ensure the results are as expected.&amp;lt;!--&lt;br /&gt;
   --&amp;gt;{{#switch: {{SUBPAGENAME}}|doc|sandbox=&amp;lt;!-- No category for /doc or /sandbox subpages --&amp;gt;&lt;br /&gt;
       | {{#ifeq: {{{nocat|}}} | true | &amp;lt;!-- No category if user sets nocat=true --&amp;gt; | [[Category:Modules in beta|{{PAGENAME}}]] }}&lt;br /&gt;
      }}&lt;br /&gt;
   | release | r | general | g = This module is rated as [[:Category:Modules for general use|ready for general use]]. It has reached a mature form and is thought to be bug-free and ready for use wherever appropriate. It is ready to mention on help pages and other Wikipedia resources as an option for new users to learn. To reduce server load and bad output, it should be improved by [[Wikipedia:Template sandbox and test cases|sandbox testing]] rather than repeated trial-and-error editing.&amp;lt;!--&lt;br /&gt;
   --&amp;gt;{{#switch: {{SUBPAGENAME}}|doc|sandbox=&amp;lt;!-- No category for /doc or /sandbox subpages --&amp;gt;&lt;br /&gt;
       | {{#ifeq: {{{nocat|}}} | true | &amp;lt;!-- No category if user sets nocat=true --&amp;gt; | [[Category:Modules for general use|{{PAGENAME}}]] }}&lt;br /&gt;
      }}&lt;br /&gt;
   | protected | protect | p   = This module is [[:Category:Modules subject to page protection|subject to page protection]]. It is a [[Wikipedia:High-risk templates|highly visible module]] in use by a very large number of pages, or is [[Wikipedia:Substitution|substituted]] very frequently. Because vandalism or mistakes would affect many pages, and even trivial editing might cause substantial load on the servers, it is [[Wikipedia:Protection policy|protected]] from editing.&amp;lt;!--&lt;br /&gt;
   --&amp;gt;{{#switch: {{SUBPAGENAME}}|doc|sandbox=&amp;lt;!-- No category for /doc or /sandbox subpages --&amp;gt;&lt;br /&gt;
       | {{#ifeq: {{{nocat|}}} | true | &amp;lt;!-- No category if user sets nocat=true --&amp;gt; | [[Category:Modules subject to page protection|{{PAGENAME}}]] }}&lt;br /&gt;
      }}&lt;br /&gt;
   | semiprotected | semiprotect | semi   = This module is [[:Category:Modules subject to page protection|subject to page protection]]. It is a [[Wikipedia:High-risk templates|highly visible module]] in use by a very large number of pages, or is [[Wikipedia:Substitution|substituted]] very frequently. Because vandalism or mistakes would affect many pages, and even trivial editing might cause substantial load on the servers, it is [[WP:SEMI|semi-protected]] from editing.&amp;lt;!--&lt;br /&gt;
   --&amp;gt;{{#switch: {{SUBPAGENAME}}|doc|sandbox=&amp;lt;!-- No category for /doc or /sandbox subpages --&amp;gt;&lt;br /&gt;
       | {{#ifeq: {{{nocat|}}} | true | &amp;lt;!-- No category if user sets nocat=true --&amp;gt; | [[Category:Modules subject to page protection|{{PAGENAME}}]] }}&lt;br /&gt;
      }}&lt;br /&gt;
   | #default                  = {{error|Module rating is invalid or not specified.}}&lt;br /&gt;
  }}&lt;br /&gt;
}}|{{error|Error: {{tl|Module rating}} must be placed in the Module namespace.}} [[Category:Pages with templates in the wrong namespace]]|demospace={{{demospace|&amp;lt;noinclude&amp;gt;module&amp;lt;/noinclude&amp;gt;}}}}}&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{module rating|release|nocat=true|demospace=module}}&lt;br /&gt;
{{documentation}}&lt;br /&gt;
&amp;lt;!-- Categories go on the /doc subpage, and interwikis go in Wikidata. --&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=Template:Module_rating/i18n/en&amp;diff=550</id>
		<title>Template:Module rating/i18n/en</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=Template:Module_rating/i18n/en&amp;diff=550"/>
		<updated>2019-11-10T17:37:35Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages /&amp;gt;&lt;br /&gt;
&amp;lt;onlyinclude&amp;gt;{{#switch: {{{1|}}}&lt;br /&gt;
   | pre-alpha  = This module is rated as [[:Category:Modules in pre-alpha development|pre-alpha]]. It is unfinished, and may or may not be in active development. It should not be used other than for testing. Modules remain pre-alpha until the original editor (or someone who takes one over if it is abandoned for some time) is satisfied with the basic structure.&lt;br /&gt;
 &lt;br /&gt;
   | alpha  = This module is rated as [[:Category:Modules in alpha|alpha]]. It is ready for third-party input, and may be used on a few pages to see if problems arise, but should be watched. Suggestions for new features or changes in their input and output mechanisms are welcome.&lt;br /&gt;
 &lt;br /&gt;
   | beta = This module is rated as [[:Category:Modules in beta|beta]], and is ready for widespread use. It is still new and should be used with some caution to ensure the results are as expected.&lt;br /&gt;
 &lt;br /&gt;
   | release = This module is rated as [[:Category:Modules for general use|ready for general use]]. It has reached a mature form and is thought to be bug-free and ready for use wherever appropriate. To reduce server load and bad output, it should be improved by [[:en:WP:TESTCASES|sandbox testing]] rather than repeated trial-and-error editing.&lt;br /&gt;
 &lt;br /&gt;
   | protected = This module is [[:Category:Modules subject to page protection|subject to page protection]]. It is a [[:en:Wikipedia:High-risk templates|highly visible module]] in use by a very large number of pages, or is [[:en:WP:SUBST|substituted]] very frequently. Because vandalism or mistakes would affect many pages, and even trivial editing might cause substantial load on the servers, it is [[:en:WP:PROTECT|protected]] from editing.&lt;br /&gt;
 &lt;br /&gt;
   | semiprotected  = This module is [[:Category:Modules subject to page protection|subject to page protection]]. It is a [[:en:Wikipedia:High-risk templates|highly visible module]] in use by a very large number of pages, or is [[:en:WP:SUBST|substituted]] very frequently. Because vandalism or mistakes would affect many pages, and even trivial editing might cause substantial load on the servers, it is [[:en:WP:SEMI|semi-protected]] from editing.&lt;br /&gt;
 &lt;br /&gt;
   | error = Error: {{tl|Module rating}} must be placed in the Module namespace.&lt;br /&gt;
}}&amp;lt;/onlyinclude&amp;gt;&lt;br /&gt;
{{translated tag|header}}&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=Template:Ombox&amp;diff=552</id>
		<title>Template:Ombox</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=Template:Ombox&amp;diff=552"/>
		<updated>2019-11-10T17:37:35Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{#invoke:Message box|ombox}}&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{documentation}}&lt;br /&gt;
&amp;lt;!-- Categories go on the /doc subpage, and interwikis go on Wikidata. --&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=Template:T/main&amp;diff=554</id>
		<title>Template:T/main</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=Template:T/main&amp;diff=554"/>
		<updated>2019-11-10T17:37:35Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{#ifeq:{{lc:{{{code}}}}}|tt|&amp;lt;code&amp;gt;}}&amp;lt;!--  code start&lt;br /&gt;
--&amp;gt;{{#switch:{{#switch:{{{link}}}|no|n|-=1|0}}{{#switch:+|{{{1|}}}|{{{2|}}}|{{{3|}}}|{{{4|}}}=1|0}}{{#switch:-|{{{1|}}}|{{{2|}}}|{{{3|}}}|{{{4|}}}=1|0}}&amp;lt;!--&lt;br /&gt;
 --&amp;gt;|000|010|011|100=|{{#switch:{{{case}}}|i|n={{i18n/namespace|t|link={{{case}}}o|lang={{{i18n|}}}}}|l=template|Template}}:}}&amp;lt;!--&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;{{#switch:{{{link}}}|no|n={{#switch:{{{incl|{{{i|}}}}}}|3=&amp;lt;span style=&amp;quot;font-family:monospace;{{{style|}}}&amp;quot;&amp;gt;}}&amp;lt;!-- link=no&lt;br /&gt;
   --&amp;gt;{{#switch:{{{incl|{{{i|}}}}}}|0|1|2|3|4|5|6=&amp;amp;#123;&amp;amp;#123;}}&amp;lt;!--  &lt;br /&gt;
  --&amp;gt;{{#switch:{{{2|}}}|+|-|={{#switch:{{{1|}}}|+|-|={{PAGENAME}}|{{PAGENAME:{{{1}}}}}}}|{{{2}}}}}&amp;lt;!--   when &amp;quot;link=no&amp;quot;: just display&lt;br /&gt;
  --&amp;gt;{{#if:{{{parm|}}}|&amp;amp;#124;{{{parm}}}}}&amp;lt;!-- optional parm display &lt;br /&gt;
  --&amp;gt;{{#switch:{{{incl|{{{i|}}}}}}|0|1|2|3|4|5|6=&amp;amp;#125;&amp;amp;#125;}}&amp;lt;!-- &lt;br /&gt;
   --&amp;gt;{{#switch:{{{incl|{{{i|}}}}}}|3=&amp;lt;/span&amp;gt;}}&amp;lt;!--&lt;br /&gt;
&lt;br /&gt;
 --&amp;gt;|{{#switch:+|{{{1|}}}|{{{2|}}}|{{{3|}}}|{{{4|}}}=|{{#switch:{{{incl|{{{i|}}}}}}|0|4=&amp;amp;#123;&amp;amp;#123;|1|5=&amp;amp;#123;}}}}&amp;lt;!-- when +: not outside&lt;br /&gt;
   --&amp;gt;[[:{{#switch:{{{3|}}}|+|-|=|{{trim|{{{3}}}}}&amp;amp;#58;}}&amp;lt;!--                      language code (ISO 639-1)  (and/or sisterproject prefix)&lt;br /&gt;
   --&amp;gt;Template:{{#switch:{{{1|}}}|+|-|={{PAGENAME}}|{{PAGENAME:{{{1}}}}}}}|&amp;lt;!--  =link= &lt;br /&gt;
&lt;br /&gt;
   --&amp;gt;{{#switch:+|{{{1|}}}|{{{2|}}}|{{{3|}}}|{{{4|}}}={{#switch:{{{case}}}|i|n={{i18n/namespace|t|link=no|lang={{{i18n|}}}}}|l=template|Template}}:}}&amp;lt;!--&lt;br /&gt;
   --&amp;gt;{{#switch:{{{incl|{{{i|}}}}}}|3=&amp;lt;span style=&amp;quot;font-family:monospace,monospace;{{{style|}}}&amp;quot;&amp;gt;}}&amp;lt;!-- &lt;br /&gt;
   --&amp;gt;{{#switch:{{{incl|{{{i|}}}}}}|2|3|6=&amp;amp;#123;&amp;amp;#123;|1|5=&amp;amp;#123;}}&amp;lt;!--&lt;br /&gt;
   --&amp;gt;{{#switch:+|{{{1|}}}|{{{2|}}}|{{{3|}}}|{{{4|}}}={{#switch:{{{incl|{{{i|}}}}}}|0|4=&amp;amp;#123;&amp;amp;#123;|1|5=&amp;amp;#123;}}}}&amp;lt;!-- inside&lt;br /&gt;
   --&amp;gt;{{#if:{{{code|}}}|&amp;lt;code&amp;gt;}}{{#switch:{{{incl|{{{i|}}}}}}|4|5|6|9=&amp;lt;tt&amp;gt;}}&amp;lt;!--   code/typewrite start&lt;br /&gt;
   --&amp;gt;{{#switch:{{{2|}}}|+|-|={{#switch:{{{1|}}}|+|-|={{PAGENAME}}|{{PAGENAME:{{{1}}}}}}}|{{{2}}}}}&amp;lt;!-- display name &lt;br /&gt;
   --&amp;gt;{{#if:{{{parm|}}}|{{#switch:&amp;amp;#124;|{{padleft:|1|{{{parm}}}}}|{{padleft:|6|{{{parm}}}}}=|&amp;amp;#124;}}{{{parm}}}}}&amp;lt;!-- opt. parm&lt;br /&gt;
   --&amp;gt;{{#switch:{{{incl|{{{i|}}}}}}|4|5|6|9=&amp;lt;/tt&amp;gt;}}{{#if:{{{code|}}}|&amp;lt;/code&amp;gt;}}&amp;lt;!-- typewrite/code end&lt;br /&gt;
   --&amp;gt;{{#switch:{{{incl|{{{i|}}}}}}|2|3|6=&amp;amp;#125;&amp;amp;#125;|1|5=&amp;amp;#125;}}&amp;lt;!--&lt;br /&gt;
   --&amp;gt;{{#switch:{{{incl|{{{i|}}}}}}|3=&amp;lt;/span&amp;gt;}}&amp;lt;!--&lt;br /&gt;
   --&amp;gt;{{#switch:+|{{{1|}}}|{{{2|}}}|{{{3|}}}|{{{4|}}}={{#switch:{{{incl|{{{i|}}}}}}|0|4=&amp;amp;#125;&amp;amp;#125;|1|5=&amp;amp;#125;}}}}&amp;lt;!-- inside&lt;br /&gt;
  --&amp;gt;]]{{#switch:+|{{{1|}}}|{{{2|}}}|{{{3|}}}|{{{4|}}}=|{{#switch:{{{incl|{{{i|}}}}}}|0|4=&amp;amp;#125;&amp;amp;#125;|1|5=&amp;amp;#125;}}}}}}&amp;lt;!--  not outside&lt;br /&gt;
--&amp;gt;{{#ifeq:{{lc:{{{code}}}}}|tt|&amp;lt;/code&amp;gt;}}&amp;lt;!--  code end&lt;br /&gt;
--&amp;gt;{{#if:{{{full|{{#ifeq:{{{5}}}|full|1}}}}}|&amp;lt;span class=&amp;quot;plainlinks&amp;quot;&amp;gt;&amp;lt;!--&lt;br /&gt;
  --&amp;gt;&amp;amp;#160;&amp;lt;tt&amp;gt;(&amp;lt;/tt&amp;gt;&amp;lt;small&amp;gt;[{{fullurl:Template:{{{1|{{PAGENAME}}}}}}} {{int:view}}]&amp;lt;!--&lt;br /&gt;
  --&amp;gt;&amp;amp;#160;&amp;amp;#8226;&amp;amp;#160;[{{fullurl:Template:{{{1|{{PAGENAME}}}}}|action=edit}} {{int:edit}}]&amp;lt;!--&lt;br /&gt;
  --&amp;gt;&amp;amp;#160;&amp;amp;#8226;&amp;amp;#160;[[:Template talk:{{{1|{{PAGENAME}}}}}|{{int:talk}}]]&amp;lt;!--&lt;br /&gt;
  --&amp;gt;&amp;amp;#160;&amp;amp;#8226;&amp;amp;#160;[{{fullurl:Special:Whatlinkshere/Template:{{{1|{{PAGENAME}}}}}|limit=500}} Links]&amp;lt;!-- {{int:links}}  needs fix&lt;br /&gt;
  --&amp;gt;&amp;amp;#160;&amp;amp;#8226;&amp;amp;#160;[{{fullurl:Template:{{{1|{{PAGENAME}}}}}|action=history}} History]&amp;lt;/small&amp;gt;&amp;lt;tt&amp;gt;)&amp;lt;/tt&amp;gt;&amp;lt;!--     &lt;br /&gt;
--&amp;gt;&amp;lt;/span&amp;gt;}}&amp;lt;!--&lt;br /&gt;
--&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{documentation|Template:T/doc}}&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=Template:Tl&amp;diff=556</id>
		<title>Template:Tl</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=Template:Tl&amp;diff=556"/>
		<updated>2019-11-10T17:37:35Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;amp;#123;&amp;amp;#123;[[Template:{{{1}}}|{{{1}}}]]&amp;amp;#125;&amp;amp;#125;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{documentation}}&lt;br /&gt;
&amp;lt;!-- Categories go on the /doc subpage and interwikis go on Wikidata. --&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=Module:Autotranslate/doc&amp;diff=558</id>
		<title>Module:Autotranslate/doc</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=Module:Autotranslate/doc&amp;diff=558"/>
		<updated>2019-11-10T17:37:35Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Module rating|release}}{{Module rating|protected}}&lt;br /&gt;
Code for {{tl|Autotranslate}}. Also used for {{tl|Autotranslate/clone 1}}, {{tl|Autotranslate/clone 2}}. {{tl|Autotranslate/clone 3}}, {{tl|Autotranslate/clone 4}}, {{tl|Documentation subpage}}.&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=Module:LangSwitch&amp;diff=560</id>
		<title>Module:LangSwitch</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=Module:LangSwitch&amp;diff=560"/>
		<updated>2019-11-10T17:37:35Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;--[[&lt;br /&gt;
  __  __           _       _        _                      ____          _ _       _     &lt;br /&gt;
 |  \/  | ___   __| |_   _| | ___ _| |    __ _ _ __   __ _/ ___|_      _(_) |_ ___| |__  &lt;br /&gt;
 | |\/| |/ _ \ / _` | | | | |/ _ (_) |   / _` | '_ \ / _` \___ \ \ /\ / / | __/ __| '_ \ &lt;br /&gt;
 | |  | | (_) | (_| | |_| | |  __/_| |__| (_| | | | | (_| |___) \ V  V /| | || (__| | | |&lt;br /&gt;
 |_|  |_|\___/ \__,_|\__,_|_|\___(_)_____\__,_|_| |_|\__, |____/ \_/\_/ |_|\__\___|_| |_|&lt;br /&gt;
                                                     |___/                               &lt;br /&gt;
 Authors and maintainers:&lt;br /&gt;
* User:Zolo   - original version in Module:Fallback&lt;br /&gt;
* User:Jarekt &lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
-- add optional module &lt;br /&gt;
-- used for debugging purposes as it detects cases of unintended global variables&lt;br /&gt;
require('Module:No globals') &lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
_langSwitch&lt;br /&gt;
 &lt;br /&gt;
This function is the core part of the LangSwitch template. &lt;br /&gt;
 &lt;br /&gt;
Example usage from Lua:&lt;br /&gt;
text = _langSwitch({en='text in english', pl='tekst po polsku'}, lang)&lt;br /&gt;
 &lt;br /&gt;
Parameters:&lt;br /&gt;
  args - table with translations by language&lt;br /&gt;
  lang - desired language (often user's native language)&lt;br /&gt;
&lt;br /&gt;
 Error Handling:&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
function p._langSwitch(args, lang) -- args: table of translations&lt;br /&gt;
	-- Return error if there is not default and no english version&lt;br /&gt;
	if not args.en and not args.default then&lt;br /&gt;
		local err = '&amp;lt;b class=&amp;quot;error&amp;quot;&amp;gt;LangSwitch Error: no default&amp;lt;/b&amp;gt;'&lt;br /&gt;
		if args.nocat == '1' then&lt;br /&gt;
			return err&lt;br /&gt;
		else&lt;br /&gt;
			return err .. '[[Category:LangSwitch template without default version]]'&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- To improve performance try quick switch, and load fallback chain only if needed. &lt;br /&gt;
	-- In the vast majority of cases fast switch is sufficient&lt;br /&gt;
	local val = args[lang]&lt;br /&gt;
	if val == '~' then &lt;br /&gt;
		return ''&lt;br /&gt;
	elseif val and val ~= '' then &lt;br /&gt;
		return val &lt;br /&gt;
	elseif args.quick then&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- get the list of accepetable language (lang + those in lang's fallback chain) and check their content&lt;br /&gt;
	assert(lang, 'LangSwitch Error: no lang')&lt;br /&gt;
	local langList = mw.language.getFallbacksFor(lang)&lt;br /&gt;
	table.insert(langList,1,lang)&lt;br /&gt;
	table.insert(langList,math.max(#langList,2),'default')&lt;br /&gt;
	for _, language in ipairs(langList) do &lt;br /&gt;
		val = args[language]&lt;br /&gt;
		if val == '~' then &lt;br /&gt;
			return ''&lt;br /&gt;
		elseif val and val ~= '' then &lt;br /&gt;
			return val &lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
langSwitch&lt;br /&gt;
 &lt;br /&gt;
This function is the core part of the LangSwitch template. &lt;br /&gt;
 &lt;br /&gt;
Example Usage from a template:&lt;br /&gt;
{{#invoke:fallback|langSwitch|en=text in english|pl=tekst po polsku|lang={{int:lang}} }}&lt;br /&gt;
 &lt;br /&gt;
Parameters:&lt;br /&gt;
  frame.args - table with translations by language&lt;br /&gt;
  frame.args.lang - desired language (often user's native language)&lt;br /&gt;
&lt;br /&gt;
 Error Handling:&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
function p.langSwitch(frame) -- version to be used from wikitext&lt;br /&gt;
	local args = frame.args&lt;br /&gt;
	-- if no expected args provided than check parent template/module args&lt;br /&gt;
	if args.en==nil and args.default==nil and args.nocat==nil then&lt;br /&gt;
		args = mw.getCurrentFrame():getParent().args &lt;br /&gt;
	end&lt;br /&gt;
	local lang = args.lang&lt;br /&gt;
	if not lang or not mw.language.isKnownLanguageTag(lang) then&lt;br /&gt;
		lang = frame:callParserFunction( &amp;quot;int&amp;quot;, &amp;quot;lang&amp;quot; ) -- get user's chosen language &lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Try quick switch which checks the most likely option when fallback is not needed&lt;br /&gt;
	args.quick = true;&lt;br /&gt;
	local val = p._langSwitch(args, lang)&lt;br /&gt;
	if val then&lt;br /&gt;
		return val&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Allow input in format: {{LangSwitch|de=Grün|es/it/pt=Verde|fr=Vert|en=Green |lang=en}}&lt;br /&gt;
	-- with multiple languages mapping to a single value&lt;br /&gt;
	local args1 = {}&lt;br /&gt;
	for name, value in pairs( args ) do &lt;br /&gt;
		if value ~= '' and type(name)=='string' then &lt;br /&gt;
    		for str in string.gmatch( name, &amp;quot;([^/]+)&amp;quot; ) do&lt;br /&gt;
				args1[str] = value&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return p._langSwitch(args1, lang)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=Template:LuaLogo&amp;diff=534</id>
		<title>Template:LuaLogo</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=Template:LuaLogo&amp;diff=534"/>
		<updated>2019-11-10T17:37:34Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;onlyinclude&amp;gt;&amp;lt;div style=&amp;quot;position:relative&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;width:{{#expr:{{{s|150}}}}}px;height:{{#expr:{{{s|150}}}}}px;{{border-radius|50%}};background-color:#19198A&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;position:absolute;top:{{#expr:{{{s|150}}}*0.4}}px;color:#fff;font-family:Helvetica,Arial,sans-serif;font-weight:bold;font-size:{{#expr:{{{s|150}}}*0.525}}px;line-height:{{#expr:{{{s|150}}}*0.525}}px;&amp;quot;&amp;gt;Lua&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;width:{{#expr:{{{s|150}}}*0.267}}px;height:{{#expr:{{{s|150}}}*0.267}}px;{{border-radius|50%}};background-color:#fff;position:absolute;top:{{#expr:{{{s|150}}}*0.034+( &amp;lt;!--radius--&amp;gt;( (&amp;lt;!--total_w--&amp;gt;{{{s|150}}} - &amp;lt;!--self_w--&amp;gt;{{{s|150}}}*0.267)/2 - &amp;lt;!--padding--&amp;gt;{{{s|150}}}*0.034 )*(1-0.707106781186548) )}}px;left:{{#expr:(({{{s|150}}}-({{{s|150}}}*0.267))/2)+( &amp;lt;!--radius--&amp;gt;( (&amp;lt;!--total_w--&amp;gt;{{{s|150}}} - &amp;lt;!--self_w--&amp;gt;{{{s|150}}}*0.267)/2 - &amp;lt;!--padding--&amp;gt;{{{s|150}}}*0.034 )*&amp;lt;!--rotation matrix--&amp;gt;(0.707106781186548) )}}px&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/onlyinclude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{documentation}}&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=Template:Mbox&amp;diff=536</id>
		<title>Template:Mbox</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=Template:Mbox&amp;diff=536"/>
		<updated>2019-11-10T17:37:34Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;table class=&amp;quot;messagebox plainlinks layouttemplate {{{lang|}}}&amp;quot; {{#if:{{{lang|}}}|lang=&amp;quot;{{{lang}}}&amp;quot;}} style=&amp;quot;direction:{{Dir|{{{lang|}}}}};margin:2px auto;{{#if:{{{width|}}}|width:{{{width|}}};}}{{#switch:{{{type|}}}&lt;br /&gt;
  |warning |speedy       = border:2px solid #b22222;background:#ffdbdb;&lt;br /&gt;
  |serious |delete |stop = border:2px solid #b22222;&lt;br /&gt;
  |issue |content        = border:2px solid #f28500;background:#ffe;&amp;lt;!--warn--&amp;gt;&lt;br /&gt;
  |query |style          = border:2px solid #f4c430;background:#ffe;&amp;lt;!--cleanup--&amp;gt;&lt;br /&gt;
  |shit                  = border:2px solid #960;&lt;br /&gt;
  |license               = border:2px solid #88a;&lt;br /&gt;
  |legal                 = border:2px solid #666;background:#fff;&lt;br /&gt;
  |honor                 = border:2px solid #ca3;background:#fcf4db;&lt;br /&gt;
  |growth                = border:2px solid #8d4;background:#f5fff5;&amp;lt;!--alt--&amp;gt;&lt;br /&gt;
  |move                  = border:2px solid #93c;&lt;br /&gt;
  |protection |message   = border:2px solid #aaa;&amp;lt;!--none--&amp;gt;&lt;br /&gt;
  |notice |#default      = border:2px solid #48d;background:#fbfcff;&amp;lt;!--info--&amp;gt;&lt;br /&gt;
  }}color:#222;border-{{Dir|{{{lang|}}}|right|left}}-width:8px;border-collapse:collapse;{{{style|}}}&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&lt;br /&gt;
{{#ifeq:{{{image|}}}|none&lt;br /&gt;
| &amp;lt;td class=&amp;quot;mbox-empty-cell&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;!--No image. Cell with some width or padding necessary for text cell to have 100% width.--&amp;gt;&lt;br /&gt;
| &amp;lt;td class=&amp;quot;mbox-image&amp;quot; style=&amp;quot;padding-{{Dir|{{{lang|}}}|right|left}}:.9em&amp;quot;&amp;gt;{{#if:{{{image|}}}&lt;br /&gt;
  | {{{image|}}}&lt;br /&gt;
  | [[File:{{#switch:{{{type|}}}&lt;br /&gt;
    |warning |speedy  = Commons-emblem-urgent&lt;br /&gt;
    |serious |delete  = Gnome-emblem-important&lt;br /&gt;
    |stop             = Commons-emblem-hand&lt;br /&gt;
    |move             = Go-next-purple&lt;br /&gt;
    |issue |content   = Commons-emblem-issue&lt;br /&gt;
    |query            = Commons-emblem-query&lt;br /&gt;
    |style            = Gnome-edit-clear&lt;br /&gt;
    |shit             = OpenMoji-color 1F4A9&lt;br /&gt;
    |license          = Commons-emblem-copyright&lt;br /&gt;
    |legal            = Commons-emblem-legal&lt;br /&gt;
    |honor            = Gnome-help-about&lt;br /&gt;
    |growth           = Dialog-apply&lt;br /&gt;
    |protection       = Gnome-security-medium&lt;br /&gt;
    |message          = Tango-style info icon&lt;br /&gt;
    |notice |#default = Commons-emblem-notice&lt;br /&gt;
    }}.svg|45x45px|class=noviewer|{{#ifeq:{{NAMESPACE}}|Template||link=}}]]&lt;br /&gt;
  }}&amp;lt;/td&amp;gt;&lt;br /&gt;
}}&amp;lt;td class=&amp;quot;mbox-text&amp;quot; style=&amp;quot;{{{textstyle|}}}&amp;quot;&amp;gt;{{{text|}}}&amp;lt;/td&amp;gt;{{#if:{{{imageright|}}}&lt;br /&gt;
| &amp;lt;td class=&amp;quot;mbox-imageright&amp;quot;&amp;gt;{{{imageright|}}}&amp;lt;/td&amp;gt;&lt;br /&gt;
}}&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;!--&lt;br /&gt;
Most templates made based on this template do not comply with [[Help:Authoring a license-template]]&lt;br /&gt;
--&amp;gt;{{#ifeq:{{{type|}}}|license|[[Category:Licensing templates based on Mbox]]}}&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{Pp-template}}&lt;br /&gt;
{{Documentation}}&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=Template:Module-nav&amp;diff=538</id>
		<title>Template:Module-nav</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=Template:Module-nav&amp;diff=538"/>
		<updated>2019-11-10T17:37:34Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;span class=&amp;quot;plainlinks&amp;quot;&amp;gt;&amp;lt;!--&lt;br /&gt;
&lt;br /&gt;
--&amp;gt; &amp;lt;!-- === Section # 1: Code, Discussion, Edit, history, links, Link count, QuickTest ===&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;[[Module:{{{module|File}}}#com-module-code|{{Module-nav/tab|text={{int:Syntaxhighlight-visualeditor-mwsyntaxhighlightinspector-code}} }}]]&amp;lt;!--&lt;br /&gt;
--&amp;gt;[[:Module talk:{{ROOTPAGENAME:Module:{{{module|File}}}}}|{{Module-nav/tab|text={{int:talk}}}}]]&amp;lt;!--&lt;br /&gt;
--&amp;gt;[{{fullurl:Module:{{{module|File}}}|action=edit}} {{Module-nav/tab|text={{int:vector-view-edit}}}}]&amp;lt;!--&lt;br /&gt;
--&amp;gt;[{{fullurl:Module:{{{module|File}}}|action=history}} {{Module-nav/tab|text={{int:vector-view-history}}}}]&amp;lt;!--&lt;br /&gt;
--&amp;gt;[{{fullurl:Special:WhatLinksHere/:Module:{{{module|File}}}|limit=999}} {{Module-nav/tab|text={{Ucfirst:{{Int:Wikibase-diffview-link}}}}}}]&amp;lt;!--&lt;br /&gt;
--&amp;gt;[https://tools.wmflabs.org/templatecount/index.php?lang=commons&amp;amp;namespace=828&amp;amp;name={{ROOTPAGENAMEE:Module:{{{module|File}}}}} {{Module-nav/tab|text={{Module-nav/i18n|Link count}}}}]&amp;lt;!--&lt;br /&gt;
--&amp;gt;{{#invoke:QuickTest|injectResult|pattern={{Module-nav/tab|text=%result%}}&amp;lt;noinclude&amp;gt;|title=Module:File/doc&amp;lt;/noinclude&amp;gt;}}&amp;lt;!--&lt;br /&gt;
&lt;br /&gt;
--&amp;gt; &amp;lt;!-- === Section # 2: Subpages, Documentation, tests, results, sandbox ===&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;[[Special:PrefixIndex/Module:{{ROOTPAGENAME:Module:{{{module|File}}}}}|{{Module-nav/tab2|text={{Module-nav/i18n|Subpages}}{{int:colon}}}}]]&amp;lt;!--&lt;br /&gt;
--&amp;gt;[[Special:MyLanguage/Module:{{ROOTPAGENAME:Module:{{{module|File}}}}}/doc|{{Module-nav/tab2|text={{ucfirst:{{int:Label-gadget-documentation}}}} }}]]&amp;lt;!--&lt;br /&gt;
--&amp;gt;[[Module:{{{module|File}}}/testcases|{{Module-nav/tab2|text={{Module-nav/i18n|tests}}}}]]&amp;lt;!--&lt;br /&gt;
--&amp;gt;[[Module talk:{{{module|File}}}/testcases|{{Module-nav/tab2|text={{int:Apisandbox-results}} }}]]&amp;lt;!--&lt;br /&gt;
--&amp;gt;[[Module:{{ROOTPAGENAME:Module:{{{module|File}}}}}/sandbox|{{Module-nav/tab2|text={{int:Sandboxlink-portlet-label}}}}]]&amp;lt;!--&lt;br /&gt;
--&amp;gt;[[Module:{{ROOTPAGENAME:Module:{{{module|File}}}}}|{{Module-nav/tab2|text={{Module-nav/i18n|live}} }}]]&amp;lt;!--&lt;br /&gt;
&lt;br /&gt;
--&amp;gt; &amp;lt;!-- === Section # 3: All modules ===&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;[[Special:PrefixIndex/Module:|{{Module-nav/tab3|text=All modules}}]]&amp;lt;!--&lt;br /&gt;
--&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{documentation}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=Template:Module-nav/i18n&amp;diff=540</id>
		<title>Template:Module-nav/i18n</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=Template:Module-nav/i18n&amp;diff=540"/>
		<updated>2019-11-10T17:37:34Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{#switch:{{lc:{{{1|}}}}}&lt;br /&gt;
&lt;br /&gt;
|subpages = {{LangSwitch&lt;br /&gt;
  |en=Subpages&lt;br /&gt;
  |ja=下位ページ&lt;br /&gt;
  |pl=Podstrony&lt;br /&gt;
  |pt=Subpáginas&lt;br /&gt;
  |zh-hans=子页面&lt;br /&gt;
  |zh-hant=子頁面&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
|link count= {{LangSwitch&lt;br /&gt;
  |en=Link count&lt;br /&gt;
  |ja=リンク数&lt;br /&gt;
  |pl=Liczba linków&lt;br /&gt;
  |pt=Contagem de links&lt;br /&gt;
  |zh-hans=链接计数&lt;br /&gt;
  |zh-hant=連結計數&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
|tests= {{LangSwitch&lt;br /&gt;
  |en=Tests&lt;br /&gt;
  |ja=試験&lt;br /&gt;
  |pl=Testowanie&lt;br /&gt;
  |pt=Testes&lt;br /&gt;
  |zh-hans=文字&lt;br /&gt;
  |zh-hant=文字&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
|live= {{LangSwitch&lt;br /&gt;
  |en=Live code&lt;br /&gt;
  |ja=オンラインで実行&lt;br /&gt;
  |pl=Opublikowany kod&lt;br /&gt;
  |pt=Código vivo&lt;br /&gt;
  |zh-hans=在线程序代码&lt;br /&gt;
  |zh-hant=線上程式代碼&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=Template:Module-nav/tab&amp;diff=542</id>
		<title>Template:Module-nav/tab</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=Template:Module-nav/tab&amp;diff=542"/>
		<updated>2019-11-10T17:37:34Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;onlyinclude&amp;gt;&amp;lt;span style=&amp;quot;display:inline-block; padding:0 1px 0 0; {{linear-gradient|top|#d9dcdd 0%, #bfc7cc 50%, #aab8bf 100%}};&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;display:inline-block;{{linear-gradient|top|#f2f6f8 0%, #d8e1e7 50%, #c3d4dd 100%}}; padding:.8em;&amp;quot;&amp;gt;{{{text}}}&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/onlyinclude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{documentation}}&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=Template:Module-nav/tab2&amp;diff=544</id>
		<title>Template:Module-nav/tab2</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=Template:Module-nav/tab2&amp;diff=544"/>
		<updated>2019-11-10T17:37:34Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;onlyinclude&amp;gt;&amp;lt;span style=&amp;quot;display:inline-block; padding:0 1px 0 0; {{linear-gradient|top|#c4ceb9 0%, #a8b79a 100%}};&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;display:inline-block;{{linear-gradient|top|#ebf7de 0%, #cee0bc 100%}}; padding:.8em;&amp;quot;&amp;gt;{{{text}}}&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/onlyinclude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{documentation}}&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=Module:Autotranslate&amp;diff=526</id>
		<title>Module:Autotranslate</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=Module:Autotranslate&amp;diff=526"/>
		<updated>2019-11-10T17:37:33Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;  --[[&lt;br /&gt;
  __  __           _       _           _         _        _                       _       _       &lt;br /&gt;
 |  \/  | ___   __| |_   _| | ___ _   / \  _   _| |_ ___ | |_ _ __ __ _ _ __  ___| | __ _| |_ ___ &lt;br /&gt;
 | |\/| |/ _ \ / _` | | | | |/ _ (_) / _ \| | | | __/ _ \| __| '__/ _` | '_ \/ __| |/ _` | __/ _ \&lt;br /&gt;
 | |  | | (_) | (_| | |_| | |  __/_ / ___ \ |_| | || (_) | |_| | | (_| | | | \__ \ | (_| | ||  __/&lt;br /&gt;
 |_|  |_|\___/ \__,_|\__,_|_|\___(_)_/   \_\__,_|\__\___/ \__|_|  \__,_|_| |_|___/_|\__,_|\__\___|&lt;br /&gt;
 &lt;br /&gt;
 Authors and maintainers:&lt;br /&gt;
* User:Zolo   - original version&lt;br /&gt;
* User:Jarekt &lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
-- local function to help normalize input arguments&lt;br /&gt;
local function normalize_input_args(input_args, output_args)&lt;br /&gt;
	for name, value in pairs( input_args ) do &lt;br /&gt;
		if value ~= '' then -- nuke empty strings&lt;br /&gt;
			if type(name)=='string' then name=string.lower(name) end -- convert to lower case&lt;br /&gt;
			output_args[name] = value&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return output_args&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- initialize object to be returned&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
autotranslate&lt;br /&gt;
 &lt;br /&gt;
This function is the core part of the Autotranslate template. &lt;br /&gt;
 &lt;br /&gt;
Usage from a template:&lt;br /&gt;
{{#invoke:autotranslate|autotranslate|base=|lang= }}&lt;br /&gt;
 &lt;br /&gt;
Parameters:&lt;br /&gt;
  frame.args.base - base page name&lt;br /&gt;
  frame.args.lang - desired language (often user's native language)&lt;br /&gt;
&lt;br /&gt;
 Error Handling:&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
function p.autotranslate(frame) &lt;br /&gt;
&lt;br /&gt;
	-- switch to lowercase parameters to make them case independent&lt;br /&gt;
	local args = {}&lt;br /&gt;
	args = normalize_input_args(frame:getParent().args, args)&lt;br /&gt;
	args = normalize_input_args(frame.args, args)&lt;br /&gt;
&lt;br /&gt;
	-- get language fallback list&lt;br /&gt;
	if not args.lang or not mw.language.isSupportedLanguage(args.lang) then&lt;br /&gt;
		args.lang = frame:callParserFunction( &amp;quot;int&amp;quot;, &amp;quot;lang&amp;quot; )           -- get user's chosen language &lt;br /&gt;
	end&lt;br /&gt;
	local langList = mw.language.getFallbacksFor(args.lang)&lt;br /&gt;
	table.insert(langList,1,args.lang)&lt;br /&gt;
&lt;br /&gt;
	-- find base page&lt;br /&gt;
	local base = args.base&lt;br /&gt;
	args.base = nil&lt;br /&gt;
	assert(base and  #base&amp;gt;0, 'Base page not provided for autotranslate' )&lt;br /&gt;
	if not mw.ustring.find(base,':') then   -- if base page does not indicate namespace&lt;br /&gt;
		base = 'Template:' .. base          -- than assume it is a template &lt;br /&gt;
	end&lt;br /&gt;
 &lt;br /&gt;
	-- find base template language subpage&lt;br /&gt;
	local page = args.default  -- default page if provided or nil otherwise&lt;br /&gt;
	for _, language in ipairs(langList) do&lt;br /&gt;
		if mw.title.new(base .. '/' .. language).exists then&lt;br /&gt;
			page =  base .. '/' .. language -- returns only the page&lt;br /&gt;
			break&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	assert(page, string.format('No fallback page found for autotranslate (base=[[%s]], lang=%s)', base, args.lang))&lt;br /&gt;
 &lt;br /&gt;
	-- Transclude {{page |....}} with template arguments the same as the ones passed to {{autotranslate}} template.&lt;br /&gt;
	return frame:expandTemplate{ title = page, args = args}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=Template:Border-radius&amp;diff=528</id>
		<title>Template:Border-radius</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=Template:Border-radius&amp;diff=528"/>
		<updated>2019-11-10T17:37:33Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;includeonly&amp;gt;-moz-border-radius: {{{1|8px}}}; -webkit-border-radius: {{{1|8px}}}; border-radius: {{{1|8px}}};&amp;lt;/includeonly&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>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=Template:LangSwitch&amp;diff=530</id>
		<title>Template:LangSwitch</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=Template:LangSwitch&amp;diff=530"/>
		<updated>2019-11-10T17:37:33Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;includeonly&amp;gt;{{#invoke:LangSwitch|langSwitch}}&amp;lt;/includeonly&amp;gt;&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>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=Template:Linear-gradient&amp;diff=532</id>
		<title>Template:Linear-gradient</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=Template:Linear-gradient&amp;diff=532"/>
		<updated>2019-11-10T17:37:33Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt; &amp;amp;lt;div style=&amp;quot;&lt;br /&gt;
 &amp;lt;/noinclude&amp;gt;background-image:-moz-linear-gradient({{{1|&amp;lt;noinclude&amp;gt;''start-position''&amp;lt;/noinclude&amp;gt;}}},{{{2|&amp;lt;noinclude&amp;gt;''color [stop],...''&amp;lt;/noinclude&amp;gt;}}});&amp;lt;noinclude&amp;gt;&lt;br /&gt;
 &amp;lt;/noinclude&amp;gt;background-image:o-linear-gradient({{{1|&amp;lt;noinclude&amp;gt;''start-position''&amp;lt;/noinclude&amp;gt;}}},{{{2|&amp;lt;noinclude&amp;gt;''color [stop],...''&amp;lt;/noinclude&amp;gt;}}});&amp;lt;noinclude&amp;gt;&lt;br /&gt;
 &amp;lt;/noinclude&amp;gt;background-image:-webkit-linear-gradient({{{1|&amp;lt;noinclude&amp;gt;''start-position''&amp;lt;/noinclude&amp;gt;}}},{{{2|&amp;lt;noinclude&amp;gt;''color [stop],...''&amp;lt;/noinclude&amp;gt;}}});&amp;lt;noinclude&amp;gt;&lt;br /&gt;
 &amp;lt;/noinclude&amp;gt;background-image:linear-gradient({{#switch:{{{1|&amp;lt;noinclude&amp;gt;''start-position''&amp;lt;/noinclude&amp;gt;}}}&lt;br /&gt;
|        360deg|         400grad|             1turn|0rad|&lt;br /&gt;
|-360deg|  0deg|-400grad|  0grad|   -1turn|   0turn|                   bottom = to top&lt;br /&gt;
|-315deg| 45deg|-350grad| 50grad|-.875turn|.125turn|bottom left | left bottom = to top right&lt;br /&gt;
|-270deg| 90deg|-300grad|100grad| -.75turn| .25turn|              left        = to right&lt;br /&gt;
|-225deg|135deg|-250grad|150grad|-.675turn|.375turn|   top left | left top    = to bottom right&lt;br /&gt;
|-180deg|180deg|-200grad|200grad|  -.5turn|  .5turn|                   top    = to bottom&lt;br /&gt;
|-135deg|225deg|-150grad|250grad|-.375turn|.675turn|   top right|right top    = to bottom left&lt;br /&gt;
| -90deg|270deg|-100grad|300grad| -.25turn| .75turn|             right        = to left&lt;br /&gt;
| -45deg|315deg| -50grad|350grad|-.125turn|.875turn|bottom right|right bottom = to top left&lt;br /&gt;
|#default={{{1|&amp;lt;noinclude&amp;gt;''start-position''&amp;lt;/noinclude&amp;gt;}}}&lt;br /&gt;
}},{{{2|&amp;lt;noinclude&amp;gt;''color [stop],...''&amp;lt;/noinclude&amp;gt;}}});&amp;lt;noinclude&amp;gt;&lt;br /&gt;
 &amp;quot;&amp;amp;gt;Lorem ipsum...&amp;amp;lt;/div&amp;amp;gt;&lt;br /&gt;
{{Documentation}}&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=Test_page&amp;diff=513</id>
		<title>Test page</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=Test_page&amp;diff=513"/>
		<updated>2019-11-10T17:29:46Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Clickable button 2|link=Main page|text=Link to Main Page}}&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=Module:Icon/data&amp;diff=493</id>
		<title>Module:Icon/data</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=Module:Icon/data&amp;diff=493"/>
		<updated>2019-11-10T17:28:16Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-- This module stores icon data for [[Module:Icon]].&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- Icon data&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local data = {&lt;br /&gt;
	fa = {&lt;br /&gt;
		image = &amp;quot;Featured article star.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Featured article&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	far = {&lt;br /&gt;
		image = &amp;quot;Cscr-star piece.png&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Featured article review&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	farc = {&lt;br /&gt;
		image = &amp;quot;Cscr-star piece.png&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Featured article removal candidate&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	ffa = {&lt;br /&gt;
		aliases = {&amp;quot;dfa&amp;quot;},&lt;br /&gt;
		image = &amp;quot;Featured article star - cross.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Former featured article&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	fac = {&lt;br /&gt;
		aliases = {&amp;quot;fan&amp;quot;},&lt;br /&gt;
		image = &amp;quot;Cscr-candidate.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Featured article candidate&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	ffac = {&lt;br /&gt;
		aliases = {&amp;quot;nofa&amp;quot;},&lt;br /&gt;
		image = &amp;quot;Featured article star - cross.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Failed featured article candidate&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	fl = {&lt;br /&gt;
		image = &amp;quot;Featured article star.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Featured list&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	flrc = {&lt;br /&gt;
		aliases = {&amp;quot;flr&amp;quot;},&lt;br /&gt;
		image = &amp;quot;Cscr-star piece.png&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Featured list removal candidate&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	ffl = {&lt;br /&gt;
		aliases = {&amp;quot;dfl&amp;quot;},&lt;br /&gt;
		image = &amp;quot;Cscr-featured-strike.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Former featured list&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	flc = {&lt;br /&gt;
		aliases = {&amp;quot;fln&amp;quot;},&lt;br /&gt;
		image = &amp;quot;Cscr-candidate.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Featured list candidate&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	fflc = {&lt;br /&gt;
		aliases = {&amp;quot;nofl&amp;quot;},&lt;br /&gt;
		image = &amp;quot;Cscr-former.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Failed featured list candidate&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	a = {&lt;br /&gt;
		image = &amp;quot;Symbol a class.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;A-Class article&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	dac = {&lt;br /&gt;
		aliases = {&amp;quot;daa&amp;quot;},&lt;br /&gt;
		image = &amp;quot;Symbol unsupport A vote.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Demoted A-Class article&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	acc = {&lt;br /&gt;
		aliases = {&amp;quot;acn&amp;quot;, &amp;quot;aac&amp;quot;},&lt;br /&gt;
		image = &amp;quot;A candidate.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;A-Class article candidate&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	noac = {&lt;br /&gt;
		aliases = {&amp;quot;faac&amp;quot;},&lt;br /&gt;
		image = &amp;quot;Symbol unsupport A vote.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Failed A-Class article candidate&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	ga = {&lt;br /&gt;
		image = &amp;quot;Symbol support vote.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Good article&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	gar = {&lt;br /&gt;
		image = &amp;quot;GA Candidate Neutral vote(ChaosNil).svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Good article reassessment&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	dga = {&lt;br /&gt;
		image = &amp;quot;Symbol unsupport vote.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Delisted good article&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	gan = {&lt;br /&gt;
		aliases = {&amp;quot;gac&amp;quot;},&lt;br /&gt;
		image = &amp;quot;GA candidate.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Good article nominee&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	ga2 = {&lt;br /&gt;
		image = &amp;quot;Symbol neutral vote.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Good article, 2nd opinion&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	gah = {&lt;br /&gt;
		image = &amp;quot;Symbol wait.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Good article on hold&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	fgan = {&lt;br /&gt;
		aliases = {&amp;quot;noga&amp;quot;, &amp;quot;gaf&amp;quot;, &amp;quot;gf&amp;quot;},&lt;br /&gt;
		image = &amp;quot;Symbol oppose vote.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Failed good article nominee&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	fp = {&lt;br /&gt;
		image = &amp;quot;Cscr-featured.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Featured picture&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	fpc = {&lt;br /&gt;
		aliases = {&amp;quot;fpn&amp;quot;},&lt;br /&gt;
		image = &amp;quot;Cscr-candidate.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Featured picture candidate&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	ffp = {&lt;br /&gt;
		image = &amp;quot;Cscr-former.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Former featured picture&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	vp = {&lt;br /&gt;
		image = &amp;quot;ENWP VP Logo.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Valued picture&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	vpc = {&lt;br /&gt;
		image = &amp;quot;Valued pics 1.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Valued picture candidate&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	fs = {&lt;br /&gt;
		image = &amp;quot;Cscr-featured.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Featured sound&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	ffs = {&lt;br /&gt;
		image = &amp;quot;Cscr-former.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Former featured sound&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	fsc = {&lt;br /&gt;
		image = &amp;quot;Cscr-candidate.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Featured sound candidate&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	fpo = {&lt;br /&gt;
		image = &amp;quot;Linecons big-star.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Before the featured portal process ceased in 2017, this had been designated as a featured portal.&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	fpor = {&lt;br /&gt;
		image = &amp;quot;Cscr-star piece.png&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Featured portal review&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	ffpo = {&lt;br /&gt;
		image = &amp;quot;Featured article star - cross.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Former featured portal&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	fpoc = {&lt;br /&gt;
		image = &amp;quot;Cscr-candidate.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Featured portal candidate&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	ft = {&lt;br /&gt;
		image = &amp;quot;Cscr-featuredtopic.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Featured topic&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	ftrc = {&lt;br /&gt;
		image = &amp;quot;Cscr-star piece.png&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Featured topic removal candidate&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	fft = {&lt;br /&gt;
		aliases = {&amp;quot;dft&amp;quot;},&lt;br /&gt;
		image = &amp;quot;DFT candidate_cluster.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Former featured topic&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	ftc = {&lt;br /&gt;
		aliases = {&amp;quot;ftn&amp;quot;},&lt;br /&gt;
		image = &amp;quot;FT candidate cluster.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Featured topic candidate&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	gt = {&lt;br /&gt;
		image = &amp;quot;Support cluster.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Good topic&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	gtrc = {&lt;br /&gt;
		image = &amp;quot;Symbol unsupport vote.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Good topic removal candidate&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	gtc = {&lt;br /&gt;
		aliases = {&amp;quot;gtn&amp;quot;},&lt;br /&gt;
		image = &amp;quot;GA candidate cluster.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Good topic candidate&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	bplus = {&lt;br /&gt;
		aliases = {&amp;quot;b+&amp;quot;},&lt;br /&gt;
		image = &amp;quot;Symbol bplus class.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Bplus-Class article&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	b = {&lt;br /&gt;
		image = &amp;quot;Symbol b class.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;B-Class article&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	br = {&lt;br /&gt;
		aliases = {&amp;quot;bcr&amp;quot;},&lt;br /&gt;
		image = &amp;quot;Bclass-checklist.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;B-Class review&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	c = {&lt;br /&gt;
		image = &amp;quot;Symbol c class.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;C-Class article&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	start = {&lt;br /&gt;
		image = &amp;quot;Symbol start class.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Start-Class article&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	stub = {&lt;br /&gt;
		image = &amp;quot;Symbol stub class.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Stub-Class article&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	list = {&lt;br /&gt;
		aliases = {&amp;quot;comparison&amp;quot;},&lt;br /&gt;
		image = &amp;quot;Symbol list class.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;List-Class article&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	no = {&lt;br /&gt;
		image = &amp;quot;Crystal button cancel.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Unknown-Class article&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	book = {&lt;br /&gt;
		image = &amp;quot;Symbol book class2.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Wikipedia book&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	category = {&lt;br /&gt;
		aliases = {&amp;quot;cat&amp;quot;, &amp;quot;categ&amp;quot;},&lt;br /&gt;
		image = &amp;quot;Folder Hexagonal Icon.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Category&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	disambiguation = {&lt;br /&gt;
		aliases = {&amp;quot;dab&amp;quot;, &amp;quot;disamb&amp;quot;, &amp;quot;disambig&amp;quot;},&lt;br /&gt;
		image = &amp;quot;Symbol dab class.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Disambiguation page&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	image = {&lt;br /&gt;
		aliases = {&amp;quot;file&amp;quot;},&lt;br /&gt;
		image = &amp;quot;Video-x-generic.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;File&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
    needed = {&lt;br /&gt;
        image = &amp;quot;Symbol needed class.svg&amp;quot;,&lt;br /&gt;
        tooltip = &amp;quot;Needed article&amp;quot;,&lt;br /&gt;
    },&lt;br /&gt;
	outline = {&lt;br /&gt;
		image = &amp;quot;Global thinking.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Outline&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
        portal = {&lt;br /&gt;
		image = &amp;quot;Portal-puzzle.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Portal&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	project = {&lt;br /&gt;
		image = &amp;quot;Symbol information vote.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Project page&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	redirect = {&lt;br /&gt;
		aliases = {&amp;quot;red&amp;quot;, &amp;quot;redir&amp;quot;},&lt;br /&gt;
		image = &amp;quot;Symbol redirect vote2.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Redirect&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	template = {&lt;br /&gt;
		aliases = {&amp;quot;temp&amp;quot;, &amp;quot;templ&amp;quot;},&lt;br /&gt;
		image = &amp;quot;Symbol template class.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Template&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	essay = {&lt;br /&gt;
		image = &amp;quot;Essay.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Essay&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	na = {&lt;br /&gt;
		image = &amp;quot;Symbol neutral vote.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Non-article page&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	aa = {&lt;br /&gt;
		image = &amp;quot;Yes check.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Audited article of limited subject matter&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	da = {&lt;br /&gt;
		image = &amp;quot;Symbol oppose vote.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Demoted article&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	dyk = {&lt;br /&gt;
		image = &amp;quot;Symbol question.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Did You Know?&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	dyk2 = {&lt;br /&gt;
		image = &amp;quot;DYK questionmark icon.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Did You Know?&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	pr = {&lt;br /&gt;
		image = &amp;quot;Nuvola apps kedit.png&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Peer review&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	ppr = {&lt;br /&gt;
		image = &amp;quot;Nuvola apps kedit.png&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Portal peer review&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	q = {&lt;br /&gt;
		aliases = {&amp;quot;question&amp;quot;},&lt;br /&gt;
		image = &amp;quot;Symbol question.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Question&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	qi = {&lt;br /&gt;
		image = &amp;quot;Quality images logo.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Quality image on Wikimedia Commons&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	vi = {&lt;br /&gt;
		image = &amp;quot;Valued image seal.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Valued image on Wikimedia Commons&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	tfa = {&lt;br /&gt;
		image = &amp;quot;Wikipedia-logo.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Today's Featured Article&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	tfl = {&lt;br /&gt;
		image = &amp;quot;Wikipedia-logo.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Today's Featured List&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	itn = {&lt;br /&gt;
		image = &amp;quot;Globe current.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;In The News&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	otd = {&lt;br /&gt;
		image = &amp;quot;Nuvola apps date.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;On This Day&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	wikiproject = {&lt;br /&gt;
		image = &amp;quot;People icon.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;WikiProject&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	wikipedia = {&lt;br /&gt;
		image = &amp;quot;Wikipedia-logo.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Wikipedia page&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	commons = {&lt;br /&gt;
		image = &amp;quot;Commons-logo.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Commons page&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	wikiquote = {&lt;br /&gt;
		image = &amp;quot;Wikiquote-logo.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Wikiquote page&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	wikiversity = {&lt;br /&gt;
		image = &amp;quot;Wikiversity-logo.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Wikiversity page&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	wikibooks = {&lt;br /&gt;
		image = &amp;quot;Wikibooks-logo.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Wikibooks page&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	wikisource = {&lt;br /&gt;
		image = &amp;quot;Wikisource-logo.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Wikisource page&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	wiktionary = {&lt;br /&gt;
		image = &amp;quot;Wiktionary-logo.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Wiktionary page&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	wikinews = {&lt;br /&gt;
		image = &amp;quot;Wikinews-logo.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Wikinews page&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	wikispecies = {&lt;br /&gt;
		image = &amp;quot;Wikispecies-logo.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Wikispecies page&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	wikidata = {&lt;br /&gt;
		image = &amp;quot;Wikidata-logo.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Wikidata page&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	wikivoyage = {&lt;br /&gt;
		image = &amp;quot;Wikivoyage-logo.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Wikivoyage page&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	meta = {&lt;br /&gt;
		image = &amp;quot;Wikimedia Community Logo.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Meta-wiki page&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	four = {&lt;br /&gt;
		image = &amp;quot;Four Award.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Four Award&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	million = {&lt;br /&gt;
		image = &amp;quot;Million award logo.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Million Award&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	module = {&lt;br /&gt;
		image = &amp;quot;Lua-logo-nolabel.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Module&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	vital = {&lt;br /&gt;
		image = &amp;quot;Círculos_Concéntricos.svg&amp;quot;,&lt;br /&gt;
		tooltip = &amp;quot;Vital article&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	_DEFAULT = {&lt;br /&gt;
		image = &amp;quot;Symbol question.svg&amp;quot;,&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- End icon data&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
-- Make aliases work the same as normal keys, and remove the &amp;quot;aliases&amp;quot; subtables. &lt;br /&gt;
for k, t in pairs(data) do&lt;br /&gt;
	if t.aliases then&lt;br /&gt;
		for i, alias in ipairs(t.aliases) do&lt;br /&gt;
			data[alias] = t&lt;br /&gt;
		end&lt;br /&gt;
		t.aliases = nil&lt;br /&gt;
	end&lt;br /&gt;
	data[k] = t&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return data&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=Module:List&amp;diff=495</id>
		<title>Module:List</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=Module:List&amp;diff=495"/>
		<updated>2019-11-10T17:28:16Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-- This module outputs different kinds of lists. At the moment, bulleted,&lt;br /&gt;
-- unbulleted, horizontal, ordered, and horizontal ordered lists are supported.&lt;br /&gt;
&lt;br /&gt;
local libUtil = require('libraryUtil')&lt;br /&gt;
local checkType = libUtil.checkType&lt;br /&gt;
local mTableTools = require('Module:TableTools')&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
local listTypes = {&lt;br /&gt;
	['bulleted'] = true,&lt;br /&gt;
	['unbulleted'] = true,&lt;br /&gt;
	['horizontal'] = true,&lt;br /&gt;
	['ordered'] = true,&lt;br /&gt;
	['horizontal_ordered'] = true&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function p.makeListData(listType, args)&lt;br /&gt;
	-- Constructs a data table to be passed to p.renderList.&lt;br /&gt;
	local data = {}&lt;br /&gt;
&lt;br /&gt;
	-- Classes&lt;br /&gt;
	data.classes = {}&lt;br /&gt;
	if listType == 'horizontal' or listType == 'horizontal_ordered' then&lt;br /&gt;
		table.insert(data.classes, 'hlist hlist-separated')&lt;br /&gt;
	elseif listType == 'unbulleted' then&lt;br /&gt;
		table.insert(data.classes, 'plainlist')&lt;br /&gt;
	end&lt;br /&gt;
	table.insert(data.classes, args.class)&lt;br /&gt;
&lt;br /&gt;
	-- Main div style&lt;br /&gt;
	data.style = args.style&lt;br /&gt;
&lt;br /&gt;
	-- Indent for horizontal lists&lt;br /&gt;
	if listType == 'horizontal' or listType == 'horizontal_ordered' then&lt;br /&gt;
		local indent = tonumber(args.indent)&lt;br /&gt;
		indent = indent and indent * 1.6 or 0&lt;br /&gt;
		if indent &amp;gt; 0 then&lt;br /&gt;
			data.marginLeft = indent .. 'em'&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- List style types for ordered lists&lt;br /&gt;
	-- This could be &amp;quot;1, 2, 3&amp;quot;, &amp;quot;a, b, c&amp;quot;, or a number of others. The list style&lt;br /&gt;
	-- type is either set by the &amp;quot;type&amp;quot; attribute or the &amp;quot;list-style-type&amp;quot; CSS&lt;br /&gt;
	-- property.&lt;br /&gt;
	if listType == 'ordered' or listType == 'horizontal_ordered' then &lt;br /&gt;
		data.listStyleType = args.list_style_type or args['list-style-type']&lt;br /&gt;
		data.type = args['type']&lt;br /&gt;
&lt;br /&gt;
		-- Detect invalid type attributes and attempt to convert them to&lt;br /&gt;
		-- list-style-type CSS properties.&lt;br /&gt;
		if data.type &lt;br /&gt;
			and not data.listStyleType&lt;br /&gt;
			and not tostring(data.type):find('^%s*[1AaIi]%s*$')&lt;br /&gt;
		then&lt;br /&gt;
			data.listStyleType = data.type&lt;br /&gt;
			data.type = nil&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- List tag type&lt;br /&gt;
	if listType == 'ordered' or listType == 'horizontal_ordered' then&lt;br /&gt;
		data.listTag = 'ol'&lt;br /&gt;
	else&lt;br /&gt;
		data.listTag = 'ul'&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Start number for ordered lists&lt;br /&gt;
	data.start = args.start&lt;br /&gt;
	if listType == 'horizontal_ordered' then&lt;br /&gt;
		-- Apply fix to get start numbers working with horizontal ordered lists.&lt;br /&gt;
		local startNum = tonumber(data.start)&lt;br /&gt;
		if startNum then&lt;br /&gt;
			data.counterReset = 'listitem ' .. tostring(startNum - 1)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- List style&lt;br /&gt;
	 -- ul_style and ol_style are included for backwards compatibility. No&lt;br /&gt;
	 -- distinction is made for ordered or unordered lists.&lt;br /&gt;
	data.listStyle = args.list_style&lt;br /&gt;
&lt;br /&gt;
	-- List items&lt;br /&gt;
	-- li_style is included for backwards compatibility. item_style was included&lt;br /&gt;
	-- to be easier to understand for non-coders.&lt;br /&gt;
	data.itemStyle = args.item_style or args.li_style&lt;br /&gt;
	data.items = {}&lt;br /&gt;
	for i, num in ipairs(mTableTools.numKeys(args)) do&lt;br /&gt;
		local item = {}&lt;br /&gt;
		item.content = args[num]&lt;br /&gt;
		item.style = args['item' .. tostring(num) .. '_style']&lt;br /&gt;
			or args['item_style' .. tostring(num)]&lt;br /&gt;
		item.value = args['item' .. tostring(num) .. '_value']&lt;br /&gt;
			or args['item_value' .. tostring(num)]&lt;br /&gt;
		table.insert(data.items, item)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return data&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.renderList(data)&lt;br /&gt;
	-- Renders the list HTML.&lt;br /&gt;
	&lt;br /&gt;
	-- Return the blank string if there are no list items.&lt;br /&gt;
	if type(data.items) ~= 'table' or #data.items &amp;lt; 1 then&lt;br /&gt;
		return ''&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Render the main div tag.&lt;br /&gt;
	local root = mw.html.create('div')&lt;br /&gt;
	for i, class in ipairs(data.classes or {}) do&lt;br /&gt;
		root:addClass(class)&lt;br /&gt;
	end&lt;br /&gt;
	root:css{['margin-left'] = data.marginLeft}&lt;br /&gt;
	if data.style then&lt;br /&gt;
		root:cssText(data.style)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Render the list tag.&lt;br /&gt;
	local list = root:tag(data.listTag or 'ul')&lt;br /&gt;
	list&lt;br /&gt;
		:attr{start = data.start, type = data.type}&lt;br /&gt;
		:css{&lt;br /&gt;
			['counter-reset'] = data.counterReset,&lt;br /&gt;
			['list-style-type'] = data.listStyleType&lt;br /&gt;
		}&lt;br /&gt;
	if data.listStyle then&lt;br /&gt;
		list:cssText(data.listStyle)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Render the list items&lt;br /&gt;
	for i, t in ipairs(data.items or {}) do&lt;br /&gt;
		local item = list:tag('li')&lt;br /&gt;
		if data.itemStyle then&lt;br /&gt;
			item:cssText(data.itemStyle)&lt;br /&gt;
		end&lt;br /&gt;
		if t.style then&lt;br /&gt;
			item:cssText(t.style)&lt;br /&gt;
		end&lt;br /&gt;
		item&lt;br /&gt;
			:attr{value = t.value}&lt;br /&gt;
			:wikitext(t.content)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return tostring(root)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.renderTrackingCategories(args)&lt;br /&gt;
	local isDeprecated = false -- Tracks deprecated parameters.&lt;br /&gt;
	for k, v in pairs(args) do&lt;br /&gt;
		k = tostring(k)&lt;br /&gt;
		if k:find('^item_style%d+$') or k:find('^item_value%d+$') then&lt;br /&gt;
			isDeprecated = true&lt;br /&gt;
			break&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	local ret = ''&lt;br /&gt;
	if isDeprecated then&lt;br /&gt;
		ret = ret .. '[[Category:List templates with deprecated parameters]]'&lt;br /&gt;
	end&lt;br /&gt;
	return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.makeList(listType, args)&lt;br /&gt;
	if not listType or not listTypes[listType] then&lt;br /&gt;
		error(string.format(&lt;br /&gt;
			&amp;quot;bad argument #1 to 'makeList' ('%s' is not a valid list type)&amp;quot;,&lt;br /&gt;
			tostring(listType)&lt;br /&gt;
		), 2)&lt;br /&gt;
	end&lt;br /&gt;
	checkType('makeList', 2, args, 'table')&lt;br /&gt;
	local data = p.makeListData(listType, args)&lt;br /&gt;
	local list = p.renderList(data)&lt;br /&gt;
	local trackingCategories = p.renderTrackingCategories(args)&lt;br /&gt;
	return list .. trackingCategories&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
for listType in pairs(listTypes) do&lt;br /&gt;
	p[listType] = function (frame)&lt;br /&gt;
		local mArguments = require('Module:Arguments')&lt;br /&gt;
		local origArgs = mArguments.getArgs(frame, {&lt;br /&gt;
			valueFunc = function (key, value)&lt;br /&gt;
			if not value or not mw.ustring.find(value, '%S') then return nil end&lt;br /&gt;
			if mw.ustring.find(value, '^%s*[%*#;:]') then&lt;br /&gt;
				return value&lt;br /&gt;
			else&lt;br /&gt;
				return value:match('^%s*(.-)%s*$')&lt;br /&gt;
			end&lt;br /&gt;
			return nil&lt;br /&gt;
		end&lt;br /&gt;
		})&lt;br /&gt;
		-- Copy all the arguments to a new table, for faster indexing.&lt;br /&gt;
		local args = {}&lt;br /&gt;
		for k, v in pairs(origArgs) do&lt;br /&gt;
			args[k] = v&lt;br /&gt;
		end&lt;br /&gt;
		return p.makeList(listType, args)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=Module:Lua_banner&amp;diff=497</id>
		<title>Module:Lua banner</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=Module:Lua_banner&amp;diff=497"/>
		<updated>2019-11-10T17:28:16Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-- This module implements the {{lua}} template.&lt;br /&gt;
local yesno = require('Module:Yesno')&lt;br /&gt;
local mList = require('Module:List')&lt;br /&gt;
local mTableTools = require('Module:TableTools')&lt;br /&gt;
local mMessageBox = require('Module:Message box')&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
function p.main(frame)&lt;br /&gt;
	local origArgs = frame:getParent().args&lt;br /&gt;
	local args = {}&lt;br /&gt;
	for k, v in pairs(origArgs) do&lt;br /&gt;
		v = v:match('^%s*(.-)%s*$')&lt;br /&gt;
		if v ~= '' then&lt;br /&gt;
			args[k] = v&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return p._main(args)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._main(args)&lt;br /&gt;
	local modules = mTableTools.compressSparseArray(args)&lt;br /&gt;
	local box = p.renderBox(modules)&lt;br /&gt;
	local trackingCategories = p.renderTrackingCategories(args, modules)&lt;br /&gt;
	return box .. trackingCategories&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.renderBox(modules)&lt;br /&gt;
	local boxArgs = {}&lt;br /&gt;
	if #modules &amp;lt; 1 then&lt;br /&gt;
		boxArgs.text = '&amp;lt;strong class=&amp;quot;error&amp;quot;&amp;gt;Error: no modules specified&amp;lt;/strong&amp;gt;'&lt;br /&gt;
	else&lt;br /&gt;
		local moduleLinks = {}&lt;br /&gt;
		for i, module in ipairs(modules) do&lt;br /&gt;
			moduleLinks[i] = string.format('[[:%s]]', module)&lt;br /&gt;
		end&lt;br /&gt;
		local moduleList = mList.makeList('bulleted', moduleLinks)&lt;br /&gt;
		if mw.title.getCurrentTitle().contentModel == &amp;quot;Scribunto&amp;quot; then&lt;br /&gt;
			boxArgs.text = 'This module depends on the following other modules:' .. moduleList&lt;br /&gt;
		else&lt;br /&gt;
			boxArgs.text = 'This template  uses [[Wikipedia:Lua|Lua]]:\n' .. moduleList&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	boxArgs.type = 'notice'&lt;br /&gt;
	boxArgs.small = true&lt;br /&gt;
	boxArgs.image = '[[File:Lua-logo-nolabel.svg|30px|alt=|link=]]'&lt;br /&gt;
	return mMessageBox.main('mbox', boxArgs)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.renderTrackingCategories(args, modules, titleObj)&lt;br /&gt;
	if yesno(args.nocat) then&lt;br /&gt;
		return ''&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local cats = {}&lt;br /&gt;
&lt;br /&gt;
	-- Error category&lt;br /&gt;
	if #modules &amp;lt; 1 then&lt;br /&gt;
		cats[#cats + 1] = 'Lua templates with errors'&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Lua templates category&lt;br /&gt;
	titleObj = titleObj or mw.title.getCurrentTitle()&lt;br /&gt;
	local subpageBlacklist = {&lt;br /&gt;
		doc = true,&lt;br /&gt;
		sandbox = true,&lt;br /&gt;
		sandbox2 = true,&lt;br /&gt;
		testcases = true&lt;br /&gt;
	}&lt;br /&gt;
	if titleObj.namespace == 10&lt;br /&gt;
		and not subpageBlacklist[titleObj.subpageText]&lt;br /&gt;
	then&lt;br /&gt;
		local category = args.category&lt;br /&gt;
		if not category then&lt;br /&gt;
			local categories = {&lt;br /&gt;
				['Module:String'] = 'Lua String-based templates',&lt;br /&gt;
				['Module:Math'] = 'Templates based on the Math Lua module',&lt;br /&gt;
				['Module:BaseConvert'] = 'Templates based on the BaseConvert Lua module',&lt;br /&gt;
				['Module:Citation'] = 'Lua-based citation templates'&lt;br /&gt;
			}&lt;br /&gt;
			categories['Module:Citation/CS1'] = categories['Module:Citation']&lt;br /&gt;
			category = modules[1] and categories[modules[1]]&lt;br /&gt;
			category = category or 'Lua-based templates'&lt;br /&gt;
		end&lt;br /&gt;
		cats[#cats + 1] = category&lt;br /&gt;
		local protLevels = {&lt;br /&gt;
			autoconfirmed = 1,&lt;br /&gt;
			extendedconfirmed = 2,&lt;br /&gt;
			templateeditor = 3,&lt;br /&gt;
			sysop = 4&lt;br /&gt;
		}&lt;br /&gt;
		local currentProt&lt;br /&gt;
		if titleObj.id ~= 0 then&lt;br /&gt;
			-- id is 0 (page does not exist) if am previewing before creating a template.&lt;br /&gt;
			currentProt = titleObj.protectionLevels[&amp;quot;edit&amp;quot;][1]&lt;br /&gt;
		end&lt;br /&gt;
		if currentProt == nil then currentProt = 0 else currentProt = protLevels[currentProt] end&lt;br /&gt;
		for i, module in ipairs(modules) do&lt;br /&gt;
			local moduleProt = mw.title.new(module).protectionLevels[&amp;quot;edit&amp;quot;][1]&lt;br /&gt;
			if moduleProt == nil then moduleProt = 0 else moduleProt = protLevels[moduleProt] end&lt;br /&gt;
			if moduleProt &amp;lt; currentProt then&lt;br /&gt;
				cats[#cats + 1] = &amp;quot;Templates using under-protected Lua modules&amp;quot;&lt;br /&gt;
				break&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	for i, cat in ipairs(cats) do&lt;br /&gt;
		cats[i] = string.format('[[Category:%s]]', cat)&lt;br /&gt;
	end&lt;br /&gt;
	return table.concat(cats)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=Module:Math&amp;diff=499</id>
		<title>Module:Math</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=Module:Math&amp;diff=499"/>
		<updated>2019-11-10T17:28:16Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;--[[&lt;br /&gt;
&lt;br /&gt;
This module provides a number of basic mathematical operations.&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local yesno, getArgs -- lazily initialized&lt;br /&gt;
&lt;br /&gt;
local p = {} -- Holds functions to be returned from #invoke, and functions to make available to other Lua modules.&lt;br /&gt;
local wrap = {} -- Holds wrapper functions that process arguments from #invoke. These act as intemediary between functions meant for #invoke and functions meant for Lua.&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Helper functions used to avoid redundant code.&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function err(msg)&lt;br /&gt;
	-- Generates wikitext error messages.&lt;br /&gt;
	return mw.ustring.format('&amp;lt;strong class=&amp;quot;error&amp;quot;&amp;gt;Formatting error: %s&amp;lt;/strong&amp;gt;', msg)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function unpackNumberArgs(args)&lt;br /&gt;
	-- Returns an unpacked list of arguments specified with numerical keys.&lt;br /&gt;
	local ret = {}&lt;br /&gt;
	for k, v in pairs(args) do&lt;br /&gt;
		if type(k) == 'number' then&lt;br /&gt;
			table.insert(ret, v)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return unpack(ret)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function makeArgArray(...)&lt;br /&gt;
	-- Makes an array of arguments from a list of arguments that might include nils.&lt;br /&gt;
	local args = {...} -- Table of arguments. It might contain nils or non-number values, so we can't use ipairs.&lt;br /&gt;
	local nums = {} -- Stores the numbers of valid numerical arguments.&lt;br /&gt;
	local ret = {}&lt;br /&gt;
	for k, v in pairs(args) do&lt;br /&gt;
		v = p._cleanNumber(v)&lt;br /&gt;
		if v then&lt;br /&gt;
			nums[#nums + 1] = k&lt;br /&gt;
			args[k] = v&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	table.sort(nums)&lt;br /&gt;
	for i, num in ipairs(nums) do&lt;br /&gt;
		ret[#ret + 1] = args[num]&lt;br /&gt;
	end&lt;br /&gt;
	return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function fold(func, ...)&lt;br /&gt;
	-- Use a function on all supplied arguments, and return the result. The function must accept two numbers as parameters,&lt;br /&gt;
	-- and must return a number as an output. This number is then supplied as input to the next function call.&lt;br /&gt;
	local vals = makeArgArray(...)&lt;br /&gt;
	local count = #vals -- The number of valid arguments&lt;br /&gt;
	if count == 0 then return&lt;br /&gt;
		-- Exit if we have no valid args, otherwise removing the first arg would cause an error.&lt;br /&gt;
		nil, 0&lt;br /&gt;
	end&lt;br /&gt;
	local ret = table.remove(vals, 1)&lt;br /&gt;
	for _, val in ipairs(vals) do&lt;br /&gt;
		ret = func(ret, val)&lt;br /&gt;
	end&lt;br /&gt;
	return ret, count&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Fold arguments by selectively choosing values (func should return when to choose the current &amp;quot;dominant&amp;quot; value).&lt;br /&gt;
]]&lt;br /&gt;
local function binary_fold(func, ...)&lt;br /&gt;
	local value = fold((function(a, b) if func(a, b) then return a else return b end end), ...)&lt;br /&gt;
	return value&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
random&lt;br /&gt;
&lt;br /&gt;
Generate a random number&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
{{#invoke: Math | random }}&lt;br /&gt;
{{#invoke: Math | random | maximum value }}&lt;br /&gt;
{{#invoke: Math | random | minimum value | maximum value }}&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
function wrap.random(args)&lt;br /&gt;
	local first = p._cleanNumber(args[1])&lt;br /&gt;
	local second = p._cleanNumber(args[2])&lt;br /&gt;
	return p._random(first, second)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._random(first, second)&lt;br /&gt;
	math.randomseed(mw.site.stats.edits + mw.site.stats.pages + os.time() + math.floor(os.clock() * 1000000000))&lt;br /&gt;
	-- math.random will throw an error if given an explicit nil parameter, so we need to use if statements to check the params.&lt;br /&gt;
	if first and second then&lt;br /&gt;
		if first &amp;lt;= second then -- math.random doesn't allow the first number to be greater than the second.&lt;br /&gt;
			return math.random(first, second)&lt;br /&gt;
		end&lt;br /&gt;
	elseif first then&lt;br /&gt;
		return math.random(first)&lt;br /&gt;
	else&lt;br /&gt;
		return math.random()&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
order&lt;br /&gt;
&lt;br /&gt;
Determine order of magnitude of a number&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
{{#invoke: Math | order | value }}&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
function wrap.order(args)&lt;br /&gt;
	local input_string = (args[1] or args.x or '0');&lt;br /&gt;
	local input_number = p._cleanNumber(input_string);&lt;br /&gt;
	if input_number == nil then&lt;br /&gt;
		return err('order of magnitude input appears non-numeric')&lt;br /&gt;
	else&lt;br /&gt;
		return p._order(input_number)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._order(x)&lt;br /&gt;
	if x == 0 then return 0 end&lt;br /&gt;
	return math.floor(math.log10(math.abs(x)))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
precision&lt;br /&gt;
&lt;br /&gt;
Detemines the precision of a number using the string representation&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
{{ #invoke: Math | precision | value }}&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
function wrap.precision(args)&lt;br /&gt;
	local input_string = (args[1] or args.x or '0');&lt;br /&gt;
	local trap_fraction = args.check_fraction;&lt;br /&gt;
	local input_number;&lt;br /&gt;
&lt;br /&gt;
	if not yesno then&lt;br /&gt;
		yesno = require('Module:Yesno')&lt;br /&gt;
	end&lt;br /&gt;
	if yesno(trap_fraction, true) then -- Returns true for all input except nil, false, &amp;quot;no&amp;quot;, &amp;quot;n&amp;quot;, &amp;quot;0&amp;quot; and a few others. See [[Module:Yesno]].&lt;br /&gt;
		local pos = string.find(input_string, '/', 1, true);&lt;br /&gt;
		if pos ~= nil then&lt;br /&gt;
			if string.find(input_string, '/', pos + 1, true) == nil then&lt;br /&gt;
				local denominator = string.sub(input_string, pos+1, -1);&lt;br /&gt;
				local denom_value = tonumber(denominator);&lt;br /&gt;
				if denom_value ~= nil then&lt;br /&gt;
					return math.log10(denom_value);&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	input_number, input_string = p._cleanNumber(input_string);&lt;br /&gt;
	if input_string == nil then&lt;br /&gt;
		return err('precision input appears non-numeric')&lt;br /&gt;
	else&lt;br /&gt;
		return p._precision(input_string)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._precision(x)&lt;br /&gt;
	if type(x) == 'number' then&lt;br /&gt;
		x = tostring(x)&lt;br /&gt;
	end&lt;br /&gt;
	x = string.upper(x)&lt;br /&gt;
&lt;br /&gt;
	local decimal = x:find('%.')&lt;br /&gt;
	local exponent_pos = x:find('E')&lt;br /&gt;
	local result = 0;&lt;br /&gt;
&lt;br /&gt;
	if exponent_pos ~= nil then&lt;br /&gt;
		local exponent = string.sub(x, exponent_pos + 1)&lt;br /&gt;
		x = string.sub(x, 1, exponent_pos - 1)&lt;br /&gt;
		result = result - tonumber(exponent)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if decimal ~= nil then&lt;br /&gt;
		result = result + string.len(x) - decimal&lt;br /&gt;
		return result&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local pos = string.len(x);&lt;br /&gt;
	while x:byte(pos) == string.byte('0') do&lt;br /&gt;
		pos = pos - 1&lt;br /&gt;
		result = result - 1&lt;br /&gt;
		if pos &amp;lt;= 0 then&lt;br /&gt;
			return 0&lt;br /&gt;
		end&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;
--[[&lt;br /&gt;
max&lt;br /&gt;
&lt;br /&gt;
Finds the maximum argument&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
{{#invoke:Math| max | value1 | value2 | ... }}&lt;br /&gt;
&lt;br /&gt;
Note, any values that do not evaluate to numbers are ignored.&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
function wrap.max(args)&lt;br /&gt;
	return p._max(unpackNumberArgs(args))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._max(...)&lt;br /&gt;
	local max_value = binary_fold((function(a, b) return a &amp;gt; b end), ...)&lt;br /&gt;
	if max_value then&lt;br /&gt;
		return max_value&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
median&lt;br /&gt;
&lt;br /&gt;
Find the median of set of numbers&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
{{#invoke:Math | median | number1 | number2 | ...}}&lt;br /&gt;
OR&lt;br /&gt;
{{#invoke:Math | median }}&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
function wrap.median(args)&lt;br /&gt;
	return p._median(unpackNumberArgs(args))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._median(...)&lt;br /&gt;
	local vals = makeArgArray(...)&lt;br /&gt;
	local count = #vals&lt;br /&gt;
	table.sort(vals)&lt;br /&gt;
&lt;br /&gt;
	if count == 0 then&lt;br /&gt;
		return 0&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if p._mod(count, 2) == 0 then&lt;br /&gt;
		return (vals[count/2] + vals[count/2+1])/2&lt;br /&gt;
	else&lt;br /&gt;
		return vals[math.ceil(count/2)]&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
min&lt;br /&gt;
&lt;br /&gt;
Finds the minimum argument&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
{{#invoke:Math| min | value1 | value2 | ... }}&lt;br /&gt;
OR&lt;br /&gt;
{{#invoke:Math| min }}&lt;br /&gt;
&lt;br /&gt;
When used with no arguments, it takes its input from the parent&lt;br /&gt;
frame.  Note, any values that do not evaluate to numbers are ignored.&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
function wrap.min(args)&lt;br /&gt;
	return p._min(unpackNumberArgs(args))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._min(...)&lt;br /&gt;
	local min_value = binary_fold((function(a, b) return a &amp;lt; b end), ...)&lt;br /&gt;
	if min_value then&lt;br /&gt;
		return min_value&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
sum&lt;br /&gt;
&lt;br /&gt;
Finds the sum&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
{{#invoke:Math| sum | value1 | value2 | ... }}&lt;br /&gt;
OR&lt;br /&gt;
{{#invoke:Math| sum }}&lt;br /&gt;
&lt;br /&gt;
Note, any values that do not evaluate to numbers are ignored.&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
function wrap.sum(args)&lt;br /&gt;
	return p._sum(unpackNumberArgs(args))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._sum(...)&lt;br /&gt;
	local sums, count = fold((function(a, b) return a + b end), ...)&lt;br /&gt;
	if not sums then&lt;br /&gt;
		return 0&lt;br /&gt;
	else&lt;br /&gt;
		return sums&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
average&lt;br /&gt;
&lt;br /&gt;
Finds the average&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
{{#invoke:Math| average | value1 | value2 | ... }}&lt;br /&gt;
OR&lt;br /&gt;
{{#invoke:Math| average }}&lt;br /&gt;
&lt;br /&gt;
Note, any values that do not evaluate to numbers are ignored.&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
function wrap.average(args)&lt;br /&gt;
	return p._average(unpackNumberArgs(args))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._average(...)&lt;br /&gt;
	local sum, count = fold((function(a, b) return a + b end), ...)&lt;br /&gt;
	if not sum then&lt;br /&gt;
		return 0&lt;br /&gt;
	else&lt;br /&gt;
		return sum / count&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
round&lt;br /&gt;
&lt;br /&gt;
Rounds a number to specified precision&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
{{#invoke:Math | round | value | precision }}&lt;br /&gt;
&lt;br /&gt;
--]]&lt;br /&gt;
&lt;br /&gt;
function wrap.round(args)&lt;br /&gt;
	local value = p._cleanNumber(args[1] or args.value or 0)&lt;br /&gt;
	local precision = p._cleanNumber(args[2] or args.precision or 0)&lt;br /&gt;
	if value == nil or precision == nil then&lt;br /&gt;
		return err('round input appears non-numeric')&lt;br /&gt;
	else&lt;br /&gt;
		return p._round(value, precision)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._round(value, precision)&lt;br /&gt;
	local rescale = math.pow(10, precision or 0);&lt;br /&gt;
	return math.floor(value * rescale + 0.5) / rescale;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
log10&lt;br /&gt;
&lt;br /&gt;
returns the log (base 10) of a number&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
{{#invoke:Math | log10 | x }}&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
function wrap.log10(args)&lt;br /&gt;
	return math.log10(args[1])&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
mod&lt;br /&gt;
&lt;br /&gt;
Implements the modulo operator&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
{{#invoke:Math | mod | x | y }}&lt;br /&gt;
&lt;br /&gt;
--]]&lt;br /&gt;
&lt;br /&gt;
function wrap.mod(args)&lt;br /&gt;
	local x = p._cleanNumber(args[1])&lt;br /&gt;
	local y = p._cleanNumber(args[2])&lt;br /&gt;
	if not x then&lt;br /&gt;
		return err('first argument to mod appears non-numeric')&lt;br /&gt;
	elseif not y then&lt;br /&gt;
		return err('second argument to mod appears non-numeric')&lt;br /&gt;
	else&lt;br /&gt;
		return p._mod(x, y)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._mod(x, y)&lt;br /&gt;
	local ret = x % y&lt;br /&gt;
	if not (0 &amp;lt;= ret and ret &amp;lt; y) then&lt;br /&gt;
		ret = 0&lt;br /&gt;
	end&lt;br /&gt;
	return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
gcd&lt;br /&gt;
&lt;br /&gt;
Calculates the greatest common divisor of multiple numbers&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
{{#invoke:Math | gcd | value 1 | value 2 | value 3 | ... }}&lt;br /&gt;
--]]&lt;br /&gt;
&lt;br /&gt;
function wrap.gcd(args)&lt;br /&gt;
	return p._gcd(unpackNumberArgs(args))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._gcd(...)&lt;br /&gt;
	local function findGcd(a, b)&lt;br /&gt;
		local r = b&lt;br /&gt;
		local oldr = a&lt;br /&gt;
		while r ~= 0 do&lt;br /&gt;
			local quotient = math.floor(oldr / r)&lt;br /&gt;
			oldr, r = r, oldr - quotient * r&lt;br /&gt;
		end&lt;br /&gt;
		if oldr &amp;lt; 0 then&lt;br /&gt;
			oldr = oldr * -1&lt;br /&gt;
		end&lt;br /&gt;
		return oldr&lt;br /&gt;
	end&lt;br /&gt;
	local result, count = fold(findGcd, ...)&lt;br /&gt;
	return result&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
precision_format&lt;br /&gt;
&lt;br /&gt;
Rounds a number to the specified precision and formats according to rules&lt;br /&gt;
originally used for {{template:Rnd}}.  Output is a string.&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
{{#invoke: Math | precision_format | number | precision }}&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
function wrap.precision_format(args)&lt;br /&gt;
	local value_string = args[1] or 0&lt;br /&gt;
	local precision = args[2] or 0&lt;br /&gt;
	return p._precision_format(value_string, precision)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._precision_format(value_string, precision)&lt;br /&gt;
	-- For access to Mediawiki built-in formatter.&lt;br /&gt;
	local lang = mw.getContentLanguage();&lt;br /&gt;
&lt;br /&gt;
	local value&lt;br /&gt;
	value, value_string = p._cleanNumber(value_string)&lt;br /&gt;
	precision = p._cleanNumber(precision)&lt;br /&gt;
&lt;br /&gt;
	-- Check for non-numeric input&lt;br /&gt;
	if value == nil or precision == nil then&lt;br /&gt;
		return err('invalid input when rounding')&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local current_precision = p._precision(value)&lt;br /&gt;
	local order = p._order(value)&lt;br /&gt;
&lt;br /&gt;
	-- Due to round-off effects it is neccesary to limit the returned precision under&lt;br /&gt;
	-- some circumstances because the terminal digits will be inaccurately reported.&lt;br /&gt;
	if order + precision &amp;gt;= 14 then&lt;br /&gt;
		if order + p._precision(value_string) &amp;gt;= 14 then&lt;br /&gt;
			precision = 13 - order;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- If rounding off, truncate extra digits&lt;br /&gt;
	if precision &amp;lt; current_precision then&lt;br /&gt;
		value = p._round(value, precision)&lt;br /&gt;
		current_precision = p._precision(value)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local formatted_num = lang:formatNum(math.abs(value))&lt;br /&gt;
	local sign&lt;br /&gt;
&lt;br /&gt;
	-- Use proper unary minus sign rather than ASCII default&lt;br /&gt;
	if value &amp;lt; 0 then&lt;br /&gt;
		sign = '−'&lt;br /&gt;
	else&lt;br /&gt;
		sign = ''&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Handle cases requiring scientific notation&lt;br /&gt;
	if string.find(formatted_num, 'E', 1, true) ~= nil or math.abs(order) &amp;gt;= 9 then&lt;br /&gt;
		value = value * math.pow(10, -order)&lt;br /&gt;
		current_precision = current_precision + order&lt;br /&gt;
		precision = precision + order&lt;br /&gt;
		formatted_num = lang:formatNum(math.abs(value))&lt;br /&gt;
	else&lt;br /&gt;
		order = 0;&lt;br /&gt;
	end&lt;br /&gt;
	formatted_num = sign .. formatted_num&lt;br /&gt;
&lt;br /&gt;
	-- Pad with zeros, if needed&lt;br /&gt;
	if current_precision &amp;lt; precision then&lt;br /&gt;
		local padding&lt;br /&gt;
		if current_precision &amp;lt;= 0 then&lt;br /&gt;
			if precision &amp;gt; 0 then&lt;br /&gt;
				local zero_sep = lang:formatNum(1.1)&lt;br /&gt;
				formatted_num = formatted_num .. zero_sep:sub(2,2)&lt;br /&gt;
&lt;br /&gt;
				padding = precision&lt;br /&gt;
				if padding &amp;gt; 20 then&lt;br /&gt;
					padding = 20&lt;br /&gt;
				end&lt;br /&gt;
&lt;br /&gt;
				formatted_num = formatted_num .. string.rep('0', padding)&lt;br /&gt;
			end&lt;br /&gt;
		else&lt;br /&gt;
			padding = precision - current_precision&lt;br /&gt;
			if padding &amp;gt; 20 then&lt;br /&gt;
				padding = 20&lt;br /&gt;
			end&lt;br /&gt;
			formatted_num = formatted_num .. string.rep('0', padding)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Add exponential notation, if necessary.&lt;br /&gt;
	if order ~= 0 then&lt;br /&gt;
		-- Use proper unary minus sign rather than ASCII default&lt;br /&gt;
		if order &amp;lt; 0 then&lt;br /&gt;
			order = '−' .. lang:formatNum(math.abs(order))&lt;br /&gt;
		else&lt;br /&gt;
			order = lang:formatNum(order)&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		formatted_num = formatted_num .. '&amp;lt;span style=&amp;quot;margin:0 .15em 0 .25em&amp;quot;&amp;gt;×&amp;lt;/span&amp;gt;10&amp;lt;sup&amp;gt;' .. order .. '&amp;lt;/sup&amp;gt;'&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return formatted_num&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Helper function that interprets the input numerically.  If the&lt;br /&gt;
input does not appear to be a number, attempts evaluating it as&lt;br /&gt;
a parser functions expression.&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
function p._cleanNumber(number_string)&lt;br /&gt;
	if type(number_string) == 'number' then&lt;br /&gt;
		-- We were passed a number, so we don't need to do any processing.&lt;br /&gt;
		return number_string, tostring(number_string)&lt;br /&gt;
	elseif type(number_string) ~= 'string' or not number_string:find('%S') then&lt;br /&gt;
		-- We were passed a non-string or a blank string, so exit.&lt;br /&gt;
		return nil, nil;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Attempt basic conversion&lt;br /&gt;
	local number = tonumber(number_string)&lt;br /&gt;
&lt;br /&gt;
	-- If failed, attempt to evaluate input as an expression&lt;br /&gt;
	if number == nil then&lt;br /&gt;
		local success, result = pcall(mw.ext.ParserFunctions.expr, number_string)&lt;br /&gt;
		if success then&lt;br /&gt;
			number = tonumber(result)&lt;br /&gt;
			number_string = tostring(number)&lt;br /&gt;
		else&lt;br /&gt;
			number = nil&lt;br /&gt;
			number_string = nil&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		number_string = number_string:match(&amp;quot;^%s*(.-)%s*$&amp;quot;) -- String is valid but may contain padding, clean it.&lt;br /&gt;
		number_string = number_string:match(&amp;quot;^%+(.*)$&amp;quot;) or number_string -- Trim any leading + signs.&lt;br /&gt;
		if number_string:find('^%-?0[xX]') then&lt;br /&gt;
			-- Number is using 0xnnn notation to indicate base 16; use the number that Lua detected instead.&lt;br /&gt;
			number_string = tostring(number)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return number, number_string&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Wrapper function that does basic argument processing. This ensures that all functions from #invoke can use either the current&lt;br /&gt;
frame or the parent frame, and it also trims whitespace for all arguments and removes blank arguments.&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local mt = { __index = function(t, k)&lt;br /&gt;
	return function(frame)&lt;br /&gt;
		if not getArgs then&lt;br /&gt;
			getArgs = require('Module:Arguments').getArgs&lt;br /&gt;
		end&lt;br /&gt;
		return wrap[k](getArgs(frame))  -- Argument processing is left to Module:Arguments. Whitespace is trimmed and blank arguments are removed.&lt;br /&gt;
	end&lt;br /&gt;
end }&lt;br /&gt;
&lt;br /&gt;
return setmetatable(p, mt)&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=Module:Navbar&amp;diff=501</id>
		<title>Module:Navbar</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=Module:Navbar&amp;diff=501"/>
		<updated>2019-11-10T17:28:16Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {}&lt;br /&gt;
&lt;br /&gt;
local getArgs&lt;br /&gt;
local ul&lt;br /&gt;
&lt;br /&gt;
function p.addItem (mini, full, link, descrip, args, url)&lt;br /&gt;
	local l&lt;br /&gt;
	if url then&lt;br /&gt;
		l = {'[', '', ']'}&lt;br /&gt;
	else&lt;br /&gt;
		l = {'[[', '|', ']]'}&lt;br /&gt;
	end&lt;br /&gt;
	ul:tag('li')&lt;br /&gt;
		:addClass('nv-'..full)&lt;br /&gt;
		:wikitext(l[1] .. link .. l[2])&lt;br /&gt;
		:tag(args.mini and 'abbr' or 'span')&lt;br /&gt;
			:attr('title', descrip..' this template')&lt;br /&gt;
			:cssText(args.fontstyle)&lt;br /&gt;
			:wikitext(args.mini and mini or full)&lt;br /&gt;
			:done()&lt;br /&gt;
		:wikitext(l[3])&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.brackets (position, c, args, div)&lt;br /&gt;
	if args.brackets then&lt;br /&gt;
		div&lt;br /&gt;
			:tag('span')&lt;br /&gt;
				:css('margin-'..position, '-0.125em')&lt;br /&gt;
				:cssText(args.fontstyle)&lt;br /&gt;
				:wikitext(c)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._navbar(args)&lt;br /&gt;
	local show = {true, true, true, false, false, false}&lt;br /&gt;
	local titleArg = 1&lt;br /&gt;
	&lt;br /&gt;
	if args.collapsible then&lt;br /&gt;
		titleArg = 2&lt;br /&gt;
		if not args.plain then args.mini = 1 end&lt;br /&gt;
		if args.fontcolor then&lt;br /&gt;
			args.fontstyle = 'color:' .. args.fontcolor .. ';'&lt;br /&gt;
		end&lt;br /&gt;
		args.style = 'float:left; text-align:left'&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if args.template then&lt;br /&gt;
		titleArg = 'template'&lt;br /&gt;
		show = {true, false, false, false, false, false}&lt;br /&gt;
		local index = {t = 2, d = 2, e = 3, h = 4, m = 5, w = 6, talk = 2, edit = 3, hist = 4, move = 5, watch = 6}&lt;br /&gt;
		for k,v in ipairs(require ('Module:TableTools').compressSparseArray(args)) do&lt;br /&gt;
			local num = index[v]&lt;br /&gt;
			if num then show[num] = true end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if args.noedit then show[3] = false end&lt;br /&gt;
	&lt;br /&gt;
	local titleText = args[titleArg] or (':' .. mw.getCurrentFrame():getParent():getTitle())&lt;br /&gt;
	local title = mw.title.new(mw.text.trim(titleText), 'Template')&lt;br /&gt;
	if not title then&lt;br /&gt;
		error('Invalid title ' .. titleText)&lt;br /&gt;
	end&lt;br /&gt;
	local talkpage = title.talkPageTitle and title.talkPageTitle.fullText or ''&lt;br /&gt;
	&lt;br /&gt;
	local div = mw.html.create():tag('div')&lt;br /&gt;
	div&lt;br /&gt;
		:addClass('plainlinks')&lt;br /&gt;
		:addClass('hlist')&lt;br /&gt;
		:addClass('navbar')&lt;br /&gt;
		:cssText(args.style)&lt;br /&gt;
&lt;br /&gt;
	if args.mini then div:addClass('mini') end&lt;br /&gt;
&lt;br /&gt;
	if not (args.mini or args.plain) then&lt;br /&gt;
		div&lt;br /&gt;
			:tag('span')&lt;br /&gt;
				:css('word-spacing', 0)&lt;br /&gt;
				:cssText(args.fontstyle)&lt;br /&gt;
				:wikitext(args.text or 'This box:')&lt;br /&gt;
				:wikitext(' ')&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	p.brackets('right', '&amp;amp;#91; ', args, div)&lt;br /&gt;
	&lt;br /&gt;
	ul = div:tag('ul')&lt;br /&gt;
	if show[1] then p.addItem('v', 'view', title.fullText, 'View', args) end&lt;br /&gt;
	if show[2] then p.addItem('t', 'talk', talkpage, 'Discuss', args) end&lt;br /&gt;
	if show[3] then p.addItem('e', 'edit', title:fullUrl('action=edit'), 'Edit', args, true) end&lt;br /&gt;
	if show[4] then p.addItem('h', 'hist', title:fullUrl('action=history'), 'History of', args, true) end&lt;br /&gt;
	if show[5] then&lt;br /&gt;
		local move = mw.title.new ('Special:Movepage')&lt;br /&gt;
		p.addItem('m', 'move', move:fullUrl('target='..title.fullText), 'Move', args, true) end&lt;br /&gt;
	if show[6] then p.addItem('w', 'watch', title:fullUrl('action=watch'), 'Watch', args, true) end&lt;br /&gt;
	&lt;br /&gt;
	p.brackets('left', ' &amp;amp;#93;', args, div)&lt;br /&gt;
	&lt;br /&gt;
	if args.collapsible then&lt;br /&gt;
		div&lt;br /&gt;
			:done()&lt;br /&gt;
		:tag('div')&lt;br /&gt;
			:css('font-size', '114%')&lt;br /&gt;
			:css('margin', args.mini and '0 4em' or '0 7em')&lt;br /&gt;
			:cssText(args.fontstyle)&lt;br /&gt;
			:wikitext(args[1])&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return tostring(div:done())&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.navbar(frame)&lt;br /&gt;
	if not getArgs then&lt;br /&gt;
		getArgs = require('Module:Arguments').getArgs&lt;br /&gt;
	end&lt;br /&gt;
	return p._navbar(getArgs(frame))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=Module:Navbox&amp;diff=503</id>
		<title>Module:Navbox</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=Module:Navbox&amp;diff=503"/>
		<updated>2019-11-10T17:28:16Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;--&lt;br /&gt;
-- This module implements {{Navbox}}&lt;br /&gt;
--&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
local navbar = require('Module:Navbar')._navbar&lt;br /&gt;
local getArgs -- lazily initialized&lt;br /&gt;
&lt;br /&gt;
local args&lt;br /&gt;
local border&lt;br /&gt;
local listnums&lt;br /&gt;
local ODD_EVEN_MARKER = '\127_ODDEVEN_\127'&lt;br /&gt;
local RESTART_MARKER = '\127_ODDEVEN0_\127'&lt;br /&gt;
local REGEX_MARKER = '\127_ODDEVEN(%d?)_\127'&lt;br /&gt;
&lt;br /&gt;
local function striped(wikitext)&lt;br /&gt;
	-- Return wikitext with markers replaced for odd/even striping.&lt;br /&gt;
	-- Child (subgroup) navboxes are flagged with a category that is removed&lt;br /&gt;
	-- by parent navboxes. The result is that the category shows all pages&lt;br /&gt;
	-- where a child navbox is not contained in a parent navbox.&lt;br /&gt;
	local orphanCat = '[[Category:Navbox orphans]]'&lt;br /&gt;
	if border == 'subgroup' and args.orphan ~= 'yes' then&lt;br /&gt;
		-- No change; striping occurs in outermost navbox.&lt;br /&gt;
		return wikitext .. orphanCat&lt;br /&gt;
	end&lt;br /&gt;
	local first, second = 'odd', 'even'&lt;br /&gt;
	if args.evenodd then&lt;br /&gt;
		if args.evenodd == 'swap' then&lt;br /&gt;
			first, second = second, first&lt;br /&gt;
		else&lt;br /&gt;
			first = args.evenodd&lt;br /&gt;
			second = first&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	local changer&lt;br /&gt;
	if first == second then&lt;br /&gt;
		changer = first&lt;br /&gt;
	else&lt;br /&gt;
		local index = 0&lt;br /&gt;
		changer = function (code)&lt;br /&gt;
			if code == '0' then&lt;br /&gt;
				-- Current occurrence is for a group before a nested table.&lt;br /&gt;
				-- Set it to first as a valid although pointless class.&lt;br /&gt;
				-- The next occurrence will be the first row after a title&lt;br /&gt;
				-- in a subgroup and will also be first.&lt;br /&gt;
				index = 0&lt;br /&gt;
				return first&lt;br /&gt;
			end&lt;br /&gt;
			index = index + 1&lt;br /&gt;
			return index % 2 == 1 and first or second&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	local regex = orphanCat:gsub('([%[%]])', '%%%1')&lt;br /&gt;
	return (wikitext:gsub(regex, ''):gsub(REGEX_MARKER, changer))  -- () omits gsub count&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function processItem(item, nowrapitems)&lt;br /&gt;
	if item:sub(1, 2) == '{|' then&lt;br /&gt;
		-- Applying nowrap to lines in a table does not make sense.&lt;br /&gt;
		-- Add newlines to compensate for trim of x in |parm=x in a template.&lt;br /&gt;
		return '\n' .. item ..'\n'&lt;br /&gt;
	end&lt;br /&gt;
	if nowrapitems == 'yes' then&lt;br /&gt;
		local lines = {}&lt;br /&gt;
		for line in (item .. '\n'):gmatch('([^\n]*)\n') do&lt;br /&gt;
			local prefix, content = line:match('^([*:;#]+)%s*(.*)')&lt;br /&gt;
			if prefix and not content:match('^&amp;lt;span class=&amp;quot;nowrap&amp;quot;&amp;gt;') then&lt;br /&gt;
				line = prefix .. '&amp;lt;span class=&amp;quot;nowrap&amp;quot;&amp;gt;' .. content .. '&amp;lt;/span&amp;gt;'&lt;br /&gt;
			end&lt;br /&gt;
			table.insert(lines, line)&lt;br /&gt;
		end&lt;br /&gt;
		item = table.concat(lines, '\n')&lt;br /&gt;
	end&lt;br /&gt;
	if item:match('^[*:;#]') then&lt;br /&gt;
		return '\n' .. item ..'\n'&lt;br /&gt;
	end&lt;br /&gt;
	return item&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function renderNavBar(titleCell)&lt;br /&gt;
&lt;br /&gt;
	if args.navbar ~= 'off' and args.navbar ~= 'plain' and not (not args.name and mw.getCurrentFrame():getParent():getTitle():gsub('/sandbox$', '') == 'Template:Navbox') then&lt;br /&gt;
		titleCell:wikitext(navbar{&lt;br /&gt;
			args.name,&lt;br /&gt;
			mini = 1,&lt;br /&gt;
			fontstyle = (args.basestyle or '') .. ';' .. (args.titlestyle or '') .. ';background:none transparent;border:none;-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none; padding:0;'&lt;br /&gt;
		})&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
--   Title row&lt;br /&gt;
--&lt;br /&gt;
local function renderTitleRow(tbl)&lt;br /&gt;
	if not args.title then return end&lt;br /&gt;
&lt;br /&gt;
	local titleRow = tbl:tag('tr')&lt;br /&gt;
&lt;br /&gt;
	if args.titlegroup then&lt;br /&gt;
		titleRow&lt;br /&gt;
			:tag('th')&lt;br /&gt;
				:attr('scope', 'row')&lt;br /&gt;
				:addClass('navbox-group')&lt;br /&gt;
				:addClass(args.titlegroupclass)&lt;br /&gt;
				:cssText(args.basestyle)&lt;br /&gt;
				:cssText(args.groupstyle)&lt;br /&gt;
				:cssText(args.titlegroupstyle)&lt;br /&gt;
				:wikitext(args.titlegroup)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local titleCell = titleRow:tag('th'):attr('scope', 'col')&lt;br /&gt;
&lt;br /&gt;
	if args.titlegroup then&lt;br /&gt;
		titleCell&lt;br /&gt;
			:css('border-left', '2px solid #fdfdfd')&lt;br /&gt;
			:css('width', '100%')&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local titleColspan = 2&lt;br /&gt;
	if args.imageleft then titleColspan = titleColspan + 1 end&lt;br /&gt;
	if args.image then titleColspan = titleColspan + 1 end&lt;br /&gt;
	if args.titlegroup then titleColspan = titleColspan - 1 end&lt;br /&gt;
&lt;br /&gt;
	titleCell&lt;br /&gt;
		:cssText(args.basestyle)&lt;br /&gt;
		:cssText(args.titlestyle)&lt;br /&gt;
		:addClass('navbox-title')&lt;br /&gt;
		:attr('colspan', titleColspan)&lt;br /&gt;
&lt;br /&gt;
	renderNavBar(titleCell)&lt;br /&gt;
&lt;br /&gt;
	titleCell&lt;br /&gt;
		:tag('div')&lt;br /&gt;
			-- id for aria-labelledby attribute&lt;br /&gt;
			:attr('id', mw.uri.anchorEncode(args.title))&lt;br /&gt;
			:addClass(args.titleclass)&lt;br /&gt;
			:css('font-size', '114%')&lt;br /&gt;
			:css('margin', '0 4em')&lt;br /&gt;
			:wikitext(processItem(args.title))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
--   Above/Below rows&lt;br /&gt;
--&lt;br /&gt;
&lt;br /&gt;
local function getAboveBelowColspan()&lt;br /&gt;
	local ret = 2&lt;br /&gt;
	if args.imageleft then ret = ret + 1 end&lt;br /&gt;
	if args.image then ret = ret + 1 end&lt;br /&gt;
	return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function renderAboveRow(tbl)&lt;br /&gt;
	if not args.above then return end&lt;br /&gt;
&lt;br /&gt;
	tbl:tag('tr')&lt;br /&gt;
		:tag('td')&lt;br /&gt;
			:addClass('navbox-abovebelow')&lt;br /&gt;
			:addClass(args.aboveclass)&lt;br /&gt;
			:cssText(args.basestyle)&lt;br /&gt;
			:cssText(args.abovestyle)&lt;br /&gt;
			:attr('colspan', getAboveBelowColspan())&lt;br /&gt;
			:tag('div')&lt;br /&gt;
				-- id for aria-labelledby attribute, if no title&lt;br /&gt;
				:attr('id', args.title and nil or mw.uri.anchorEncode(args.above))&lt;br /&gt;
				:wikitext(processItem(args.above, args.nowrapitems))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function renderBelowRow(tbl)&lt;br /&gt;
	if not args.below then return end&lt;br /&gt;
&lt;br /&gt;
	tbl:tag('tr')&lt;br /&gt;
		:tag('td')&lt;br /&gt;
			:addClass('navbox-abovebelow')&lt;br /&gt;
			:addClass(args.belowclass)&lt;br /&gt;
			:cssText(args.basestyle)&lt;br /&gt;
			:cssText(args.belowstyle)&lt;br /&gt;
			:attr('colspan', getAboveBelowColspan())&lt;br /&gt;
			:tag('div')&lt;br /&gt;
				:wikitext(processItem(args.below, args.nowrapitems))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
--   List rows&lt;br /&gt;
--&lt;br /&gt;
local function renderListRow(tbl, index, listnum)&lt;br /&gt;
	local row = tbl:tag('tr')&lt;br /&gt;
&lt;br /&gt;
	if index == 1 and args.imageleft then&lt;br /&gt;
		row&lt;br /&gt;
			:tag('td')&lt;br /&gt;
				:addClass('navbox-image')&lt;br /&gt;
				:addClass(args.imageclass)&lt;br /&gt;
				:css('width', '1px')               -- Minimize width&lt;br /&gt;
				:css('padding', '0px 2px 0px 0px')&lt;br /&gt;
				:cssText(args.imageleftstyle)&lt;br /&gt;
				:attr('rowspan', #listnums)&lt;br /&gt;
				:tag('div')&lt;br /&gt;
					:wikitext(processItem(args.imageleft))&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if args['group' .. listnum] then&lt;br /&gt;
		local groupCell = row:tag('th')&lt;br /&gt;
&lt;br /&gt;
		-- id for aria-labelledby attribute, if lone group with no title or above&lt;br /&gt;
		if listnum == 1 and not (args.title or args.above or args.group2) then&lt;br /&gt;
			groupCell&lt;br /&gt;
				:attr('id', mw.uri.anchorEncode(args.group1))&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		groupCell&lt;br /&gt;
			:attr('scope', 'row')&lt;br /&gt;
			:addClass('navbox-group')&lt;br /&gt;
			:addClass(args.groupclass)&lt;br /&gt;
			:cssText(args.basestyle)&lt;br /&gt;
			:css('width', args.groupwidth or '1%') -- If groupwidth not specified, minimize width&lt;br /&gt;
&lt;br /&gt;
		groupCell&lt;br /&gt;
			:cssText(args.groupstyle)&lt;br /&gt;
			:cssText(args['group' .. listnum .. 'style'])&lt;br /&gt;
			:wikitext(args['group' .. listnum])&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local listCell = row:tag('td')&lt;br /&gt;
&lt;br /&gt;
	if args['group' .. listnum] then&lt;br /&gt;
		listCell&lt;br /&gt;
			:css('text-align', 'left')&lt;br /&gt;
			:css('border-left-width', '2px')&lt;br /&gt;
			:css('border-left-style', 'solid')&lt;br /&gt;
	else&lt;br /&gt;
		listCell:attr('colspan', 2)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if not args.groupwidth then&lt;br /&gt;
		listCell:css('width', '100%')&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local rowstyle  -- usually nil so cssText(rowstyle) usually adds nothing&lt;br /&gt;
	if index % 2 == 1 then&lt;br /&gt;
		rowstyle = args.oddstyle&lt;br /&gt;
	else&lt;br /&gt;
		rowstyle = args.evenstyle&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local listText = args['list' .. listnum]&lt;br /&gt;
	local oddEven = ODD_EVEN_MARKER&lt;br /&gt;
	if listText:sub(1, 12) == '&amp;lt;/div&amp;gt;&amp;lt;table' then&lt;br /&gt;
		-- Assume list text is for a subgroup navbox so no automatic striping for this row.&lt;br /&gt;
		oddEven = listText:find('&amp;lt;th[^&amp;gt;]*&amp;quot;navbox%-title&amp;quot;') and RESTART_MARKER or 'odd'&lt;br /&gt;
	end&lt;br /&gt;
	listCell&lt;br /&gt;
		:css('padding', '0px')&lt;br /&gt;
		:cssText(args.liststyle)&lt;br /&gt;
		:cssText(rowstyle)&lt;br /&gt;
		:cssText(args['list' .. listnum .. 'style'])&lt;br /&gt;
		:addClass('navbox-list')&lt;br /&gt;
		:addClass('navbox-' .. oddEven)&lt;br /&gt;
		:addClass(args.listclass)&lt;br /&gt;
		:addClass(args['list' .. listnum .. 'class'])&lt;br /&gt;
		:tag('div')&lt;br /&gt;
			:css('padding', (index == 1 and args.list1padding) or args.listpadding or '0em 0.25em')&lt;br /&gt;
			:wikitext(processItem(listText, args.nowrapitems))&lt;br /&gt;
&lt;br /&gt;
	if index == 1 and args.image then&lt;br /&gt;
		row&lt;br /&gt;
			:tag('td')&lt;br /&gt;
				:addClass('navbox-image')&lt;br /&gt;
				:addClass(args.imageclass)&lt;br /&gt;
				:css('width', '1px')               -- Minimize width&lt;br /&gt;
				:css('padding', '0px 0px 0px 2px')&lt;br /&gt;
				:cssText(args.imagestyle)&lt;br /&gt;
				:attr('rowspan', #listnums)&lt;br /&gt;
				:tag('div')&lt;br /&gt;
					:wikitext(processItem(args.image))&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
--   Tracking categories&lt;br /&gt;
--&lt;br /&gt;
&lt;br /&gt;
local function needsHorizontalLists()&lt;br /&gt;
	if border == 'subgroup' or args.tracking == 'no' then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
	local listClasses = {&lt;br /&gt;
		['plainlist'] = true, ['hlist'] = true, ['hlist hnum'] = true,&lt;br /&gt;
		['hlist hwrap'] = true, ['hlist vcard'] = true, ['vcard hlist'] = true,&lt;br /&gt;
		['hlist vevent'] = true,&lt;br /&gt;
	}&lt;br /&gt;
	return not (listClasses[args.listclass] or listClasses[args.bodyclass])&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function hasBackgroundColors()&lt;br /&gt;
	for _, key in ipairs({'titlestyle', 'groupstyle', 'basestyle', 'abovestyle', 'belowstyle'}) do&lt;br /&gt;
		if tostring(args[key]):find('background', 1, true) then&lt;br /&gt;
			return true&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function hasBorders()&lt;br /&gt;
	for _, key in ipairs({'groupstyle', 'basestyle', 'abovestyle', 'belowstyle'}) do&lt;br /&gt;
		if tostring(args[key]):find('border', 1, true) then&lt;br /&gt;
			return true&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function isIllegible()&lt;br /&gt;
	local styleratio = require('Module:Color contrast')._styleratio&lt;br /&gt;
&lt;br /&gt;
	for key, style in pairs(args) do&lt;br /&gt;
		if tostring(key):match(&amp;quot;style$&amp;quot;) then&lt;br /&gt;
			if styleratio{mw.text.unstripNoWiki(style)} &amp;lt; 4.5 then&lt;br /&gt;
				return true&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function getTrackingCategories()&lt;br /&gt;
	local cats = {}&lt;br /&gt;
	if needsHorizontalLists() then table.insert(cats, 'Navigational boxes without horizontal lists') end&lt;br /&gt;
	if hasBackgroundColors() then table.insert(cats, 'Navboxes using background colours') end&lt;br /&gt;
	if isIllegible() then table.insert(cats, 'Potentially illegible navboxes') end&lt;br /&gt;
	if hasBorders() then table.insert(cats, 'Navboxes using borders') end&lt;br /&gt;
	return cats&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function renderTrackingCategories(builder)&lt;br /&gt;
	local title = mw.title.getCurrentTitle()&lt;br /&gt;
	if title.namespace ~= 10 then return end -- not in template space&lt;br /&gt;
	local subpage = title.subpageText&lt;br /&gt;
	if subpage == 'doc' or subpage == 'sandbox' or subpage == 'testcases' then return end&lt;br /&gt;
&lt;br /&gt;
	for _, cat in ipairs(getTrackingCategories()) do&lt;br /&gt;
		builder:wikitext('[[Category:' .. cat .. ']]')&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
--   Main navbox tables&lt;br /&gt;
--&lt;br /&gt;
local function renderMainTable()&lt;br /&gt;
	local tbl = mw.html.create('table')&lt;br /&gt;
		:addClass('nowraplinks')&lt;br /&gt;
		:addClass(args.bodyclass)&lt;br /&gt;
&lt;br /&gt;
	if args.title and (args.state ~= 'plain' and args.state ~= 'off') then&lt;br /&gt;
		if args.state == 'collapsed' then args.state = 'mw-collapsed' end&lt;br /&gt;
		tbl&lt;br /&gt;
			:addClass('mw-collapsible')&lt;br /&gt;
			:addClass(args.state or 'autocollapse')&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	tbl:css('border-spacing', 0)&lt;br /&gt;
	if border == 'subgroup' or border == 'none' then&lt;br /&gt;
		tbl&lt;br /&gt;
			:addClass('navbox-subgroup')&lt;br /&gt;
			:cssText(args.bodystyle)&lt;br /&gt;
			:cssText(args.style)&lt;br /&gt;
	else  -- regular navbox - bodystyle and style will be applied to the wrapper table&lt;br /&gt;
		tbl&lt;br /&gt;
			:addClass('navbox-inner')&lt;br /&gt;
			:css('background', 'transparent')&lt;br /&gt;
			:css('color', 'inherit')&lt;br /&gt;
	end&lt;br /&gt;
	tbl:cssText(args.innerstyle)&lt;br /&gt;
&lt;br /&gt;
	renderTitleRow(tbl)&lt;br /&gt;
	renderAboveRow(tbl)&lt;br /&gt;
	for i, listnum in ipairs(listnums) do&lt;br /&gt;
		renderListRow(tbl, i, listnum)&lt;br /&gt;
	end&lt;br /&gt;
	renderBelowRow(tbl)&lt;br /&gt;
&lt;br /&gt;
	return tbl&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._navbox(navboxArgs)&lt;br /&gt;
	args = navboxArgs&lt;br /&gt;
	listnums = {}&lt;br /&gt;
&lt;br /&gt;
	for k, _ in pairs(args) do&lt;br /&gt;
		if type(k) == 'string' then&lt;br /&gt;
			local listnum = k:match('^list(%d+)$')&lt;br /&gt;
			if listnum then table.insert(listnums, tonumber(listnum)) end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	table.sort(listnums)&lt;br /&gt;
&lt;br /&gt;
	border = mw.text.trim(args.border or args[1] or '')&lt;br /&gt;
	if border == 'child' then&lt;br /&gt;
		border = 'subgroup'&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- render the main body of the navbox&lt;br /&gt;
	local tbl = renderMainTable()&lt;br /&gt;
&lt;br /&gt;
	-- render the appropriate wrapper around the navbox, depending on the border param&lt;br /&gt;
	local res = mw.html.create()&lt;br /&gt;
	if border == 'none' then&lt;br /&gt;
		local nav = res:tag('div')&lt;br /&gt;
			:attr('role', 'navigation')&lt;br /&gt;
			:node(tbl)&lt;br /&gt;
		-- aria-labelledby title, otherwise above, otherwise lone group&lt;br /&gt;
		if args.title or args.above or (args.group1 and not args.group2) then&lt;br /&gt;
			nav:attr('aria-labelledby', mw.uri.anchorEncode(args.title or args.above or args.group1))&lt;br /&gt;
		else&lt;br /&gt;
			nav:attr('aria-label', 'Navbox')&lt;br /&gt;
		end&lt;br /&gt;
	elseif border == 'subgroup' then&lt;br /&gt;
		-- We assume that this navbox is being rendered in a list cell of a parent navbox, and is&lt;br /&gt;
		-- therefore inside a div with padding:0em 0.25em. We start with a &amp;lt;/div&amp;gt; to avoid the&lt;br /&gt;
		-- padding being applied, and at the end add a &amp;lt;div&amp;gt; to balance out the parent's &amp;lt;/div&amp;gt;&lt;br /&gt;
		res&lt;br /&gt;
			:wikitext('&amp;lt;/div&amp;gt;')&lt;br /&gt;
			:node(tbl)&lt;br /&gt;
			:wikitext('&amp;lt;div&amp;gt;')&lt;br /&gt;
	else&lt;br /&gt;
		local nav = res:tag('div')&lt;br /&gt;
			:attr('role', 'navigation')&lt;br /&gt;
			:addClass('navbox')&lt;br /&gt;
			:addClass(args.navboxclass)&lt;br /&gt;
			:cssText(args.bodystyle)&lt;br /&gt;
			:cssText(args.style)&lt;br /&gt;
			:css('padding', '3px')&lt;br /&gt;
			:node(tbl)&lt;br /&gt;
		-- aria-labelledby title, otherwise above, otherwise lone group&lt;br /&gt;
		if args.title or args.above or (args.group1 and not args.group2) then&lt;br /&gt;
			nav:attr('aria-labelledby', mw.uri.anchorEncode(args.title or args.above or args.group1))&lt;br /&gt;
		else&lt;br /&gt;
			nav:attr('aria-label', 'Navbox')&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if (args.nocat or 'false'):lower() == 'false' then&lt;br /&gt;
		renderTrackingCategories(res)&lt;br /&gt;
	end&lt;br /&gt;
	return striped(tostring(res))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.navbox(frame)&lt;br /&gt;
	if not getArgs then&lt;br /&gt;
		getArgs = require('Module:Arguments').getArgs&lt;br /&gt;
	end&lt;br /&gt;
	args = getArgs(frame, {wrappers = {'Template:Navbox', 'Template:Navbox subgroup'}})&lt;br /&gt;
	if frame.args.border then&lt;br /&gt;
		-- This allows Template:Navbox_subgroup to use {{#invoke:Navbox|navbox|border=...}}.&lt;br /&gt;
		args.border = frame.args.border&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Read the arguments in the order they'll be output in, to make references number in the right order.&lt;br /&gt;
	local _&lt;br /&gt;
	_ = args.title&lt;br /&gt;
	_ = args.above&lt;br /&gt;
	for i = 1, 20 do&lt;br /&gt;
		_ = args[&amp;quot;group&amp;quot; .. tostring(i)]&lt;br /&gt;
		_ = args[&amp;quot;list&amp;quot; .. tostring(i)]&lt;br /&gt;
	end&lt;br /&gt;
	_ = args.below&lt;br /&gt;
&lt;br /&gt;
	return p._navbox(args)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=Module:String&amp;diff=505</id>
		<title>Module:String</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=Module:String&amp;diff=505"/>
		<updated>2019-11-10T17:28:16Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: 1 revision imported&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 'true' 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 'true' 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, {'s'} )&lt;br /&gt;
	local s = new_args['s'] or ''&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, { 's', 'i', 'j' } )&lt;br /&gt;
	local s = new_args['s'] or ''&lt;br /&gt;
	local i = tonumber( new_args['i'] ) or 1&lt;br /&gt;
	local j = tonumber( new_args['j'] ) 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( 'String subset index out of range' )&lt;br /&gt;
	end&lt;br /&gt;
	if j &amp;lt; i then&lt;br /&gt;
		return str._error( 'String subset indices out of order' )&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 == '' then&lt;br /&gt;
		return str._error( 'Target string is empty' )&lt;br /&gt;
	end&lt;br /&gt;
	if pattern == '' then&lt;br /&gt;
		return str._error( 'Pattern string is empty' )&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( 'Requested start is out of range' )&lt;br /&gt;
	end&lt;br /&gt;
	if match_index == 0 then&lt;br /&gt;
		return str._error( 'Match index is out of range' )&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( 'Match not found' )&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, {'s', 'pattern', 'start', 'match', 'plain', 'nomatch'} )&lt;br /&gt;
	local s = new_args['s'] or ''&lt;br /&gt;
	local start = tonumber( new_args['start'] ) or 1&lt;br /&gt;
	local plain_flag = str._getBoolean( new_args['plain'] or false )&lt;br /&gt;
	local pattern = new_args['pattern'] or ''&lt;br /&gt;
	local match_index = math.floor( tonumber(new_args['match']) or 1 )&lt;br /&gt;
	local nomatch = new_args['nomatch']&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, {'target', 'pos'} )&lt;br /&gt;
	local target_str = new_args['target'] or ''&lt;br /&gt;
	local pos = tonumber( new_args['pos'] ) 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( 'String index out of range' )&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, {'source', 'target'} )&lt;br /&gt;
	local source_str = new_args['source'] or ''&lt;br /&gt;
	local target_str = new_args['target'] or ''&lt;br /&gt;
&lt;br /&gt;
	if target_str == '' 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, {'source', 'target', 'start', 'plain' } )&lt;br /&gt;
	local source_str = new_args['source'] or ''&lt;br /&gt;
	local pattern = new_args['target'] or ''&lt;br /&gt;
	local start_pos = tonumber(new_args['start']) or 1&lt;br /&gt;
	local plain = new_args['plain'] or true&lt;br /&gt;
&lt;br /&gt;
	if source_str == '' or pattern == '' 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, {'source', 'pattern', 'replace', 'count', 'plain' } )&lt;br /&gt;
	local source_str = new_args['source'] or ''&lt;br /&gt;
	local pattern = new_args['pattern'] or ''&lt;br /&gt;
	local replace = new_args['replace'] or ''&lt;br /&gt;
	local count = tonumber( new_args['count'] )&lt;br /&gt;
	local plain = new_args['plain'] or true&lt;br /&gt;
&lt;br /&gt;
	if source_str == '' or pattern == '' 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( 'function rep expects a number as second parameter, received &amp;quot;' .. ( frame.args[2] or '' ) .. '&amp;quot;' )&lt;br /&gt;
	end&lt;br /&gt;
	return string.rep( frame.args[1] or '', 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( 'No pattern string specified' )&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, {'source', 'pattern', 'plain'})&lt;br /&gt;
	local source = args.source or ''&lt;br /&gt;
	local pattern = args.pattern or ''&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, '')&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, {'source', 'pattern'})&lt;br /&gt;
	local source = args.source or ''&lt;br /&gt;
	local pattern = args.pattern or ''&lt;br /&gt;
	if pattern == '' 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 ~= '' 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 '' )&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 'Errors reported by Module String'&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 ''&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local error_str = '&amp;lt;strong class=&amp;quot;error&amp;quot;&amp;gt;String Module Error: ' .. error_str .. '&amp;lt;/strong&amp;gt;'&lt;br /&gt;
	if error_category ~= '' and not str._getBoolean( no_category ) then&lt;br /&gt;
		error_str = '[[Category:' .. error_category .. ']]' .. 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 ) == 'string' then&lt;br /&gt;
		boolean_str = boolean_str:lower()&lt;br /&gt;
		if boolean_str == 'false' or boolean_str == 'no' or boolean_str == '0'&lt;br /&gt;
				or boolean_str == '' 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 ) == 'boolean' then&lt;br /&gt;
		boolean_value = boolean_str&lt;br /&gt;
	else&lt;br /&gt;
		error( 'No boolean value found' )&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;
return str&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=Module:TableTools&amp;diff=507</id>
		<title>Module:TableTools</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=Module:TableTools&amp;diff=507"/>
		<updated>2019-11-10T17:28:16Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;--[[&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
--                               TableTools                                       --&lt;br /&gt;
--                                                                                --&lt;br /&gt;
-- This module includes a number of functions for dealing with Lua tables.        --&lt;br /&gt;
-- It is a meta-module, meant to be called from other Lua modules, and should     --&lt;br /&gt;
-- not be called directly from #invoke.                                           --&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
--]]&lt;br /&gt;
&lt;br /&gt;
local libraryUtil = require('libraryUtil')&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
-- Define often-used variables and functions.&lt;br /&gt;
local floor = math.floor&lt;br /&gt;
local infinity = math.huge&lt;br /&gt;
local checkType = libraryUtil.checkType&lt;br /&gt;
local checkTypeMulti = libraryUtil.checkTypeMulti&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- isPositiveInteger&lt;br /&gt;
--&lt;br /&gt;
-- This function returns true if the given value is a positive integer, and false&lt;br /&gt;
-- if not. Although it doesn't operate on tables, it is included here as it is&lt;br /&gt;
-- useful for determining whether a given table key is in the array part or the&lt;br /&gt;
-- hash part of a table.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
--]]&lt;br /&gt;
function p.isPositiveInteger(v)&lt;br /&gt;
	if type(v) == 'number' and v &amp;gt;= 1 and floor(v) == v and v &amp;lt; infinity then&lt;br /&gt;
		return true&lt;br /&gt;
	else&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- isNan&lt;br /&gt;
--&lt;br /&gt;
-- This function returns true if the given number is a NaN value, and false&lt;br /&gt;
-- if not. Although it doesn't operate on tables, it is included here as it is&lt;br /&gt;
-- useful for determining whether a value can be a valid table key. Lua will&lt;br /&gt;
-- generate an error if a NaN is used as a table key.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
--]]&lt;br /&gt;
function p.isNan(v)&lt;br /&gt;
	if type(v) == 'number' and tostring(v) == '-nan' then&lt;br /&gt;
		return true&lt;br /&gt;
	else&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- shallowClone&lt;br /&gt;
--&lt;br /&gt;
-- This returns a clone of a table. The value returned is a new table, but all&lt;br /&gt;
-- subtables and functions are shared. Metamethods are respected, but the returned&lt;br /&gt;
-- table will have no metatable of its own.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
--]]&lt;br /&gt;
function p.shallowClone(t)&lt;br /&gt;
	local ret = {}&lt;br /&gt;
	for k, v in pairs(t) do&lt;br /&gt;
		ret[k] = v&lt;br /&gt;
	end&lt;br /&gt;
	return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- removeDuplicates&lt;br /&gt;
--&lt;br /&gt;
-- This removes duplicate values from an array. Non-positive-integer keys are&lt;br /&gt;
-- ignored. The earliest value is kept, and all subsequent duplicate values are&lt;br /&gt;
-- removed, but otherwise the array order is unchanged.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
--]]&lt;br /&gt;
function p.removeDuplicates(t)&lt;br /&gt;
	checkType('removeDuplicates', 1, t, 'table')&lt;br /&gt;
	local isNan = p.isNan&lt;br /&gt;
	local ret, exists = {}, {}&lt;br /&gt;
	for i, v in ipairs(t) do&lt;br /&gt;
		if isNan(v) then&lt;br /&gt;
			-- NaNs can't be table keys, and they are also unique, so we don't need to check existence.&lt;br /&gt;
			ret[#ret + 1] = v&lt;br /&gt;
		else&lt;br /&gt;
			if not exists[v] then&lt;br /&gt;
				ret[#ret + 1] = v&lt;br /&gt;
				exists[v] = true&lt;br /&gt;
			end&lt;br /&gt;
		end	&lt;br /&gt;
	end&lt;br /&gt;
	return ret&lt;br /&gt;
end			&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- numKeys&lt;br /&gt;
--&lt;br /&gt;
-- This takes a table and returns an array containing the numbers of any numerical&lt;br /&gt;
-- keys that have non-nil values, sorted in numerical order.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
--]]&lt;br /&gt;
function p.numKeys(t)&lt;br /&gt;
	checkType('numKeys', 1, t, 'table')&lt;br /&gt;
	local isPositiveInteger = p.isPositiveInteger&lt;br /&gt;
	local nums = {}&lt;br /&gt;
	for k, v in pairs(t) do&lt;br /&gt;
		if isPositiveInteger(k) then&lt;br /&gt;
			nums[#nums + 1] = k&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	table.sort(nums)&lt;br /&gt;
	return nums&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- affixNums&lt;br /&gt;
--&lt;br /&gt;
-- This takes a table and returns an array containing the numbers of keys with the&lt;br /&gt;
-- specified prefix and suffix. For example, for the table&lt;br /&gt;
-- {a1 = 'foo', a3 = 'bar', a6 = 'baz'} and the prefix &amp;quot;a&amp;quot;, affixNums will&lt;br /&gt;
-- return {1, 3, 6}.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
--]]&lt;br /&gt;
function p.affixNums(t, prefix, suffix)&lt;br /&gt;
	checkType('affixNums', 1, t, 'table')&lt;br /&gt;
	checkType('affixNums', 2, prefix, 'string', true)&lt;br /&gt;
	checkType('affixNums', 3, suffix, 'string', true)&lt;br /&gt;
&lt;br /&gt;
	local function cleanPattern(s)&lt;br /&gt;
		-- Cleans a pattern so that the magic characters ()%.[]*+-?^$ are interpreted literally.&lt;br /&gt;
		s = s:gsub('([%(%)%%%.%[%]%*%+%-%?%^%$])', '%%%1')&lt;br /&gt;
		return s&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	prefix = prefix or ''&lt;br /&gt;
	suffix = suffix or ''&lt;br /&gt;
	prefix = cleanPattern(prefix)&lt;br /&gt;
	suffix = cleanPattern(suffix)&lt;br /&gt;
	local pattern = '^' .. prefix .. '([1-9]%d*)' .. suffix .. '$'&lt;br /&gt;
&lt;br /&gt;
	local nums = {}&lt;br /&gt;
	for k, v in pairs(t) do&lt;br /&gt;
		if type(k) == 'string' then			&lt;br /&gt;
			local num = mw.ustring.match(k, pattern)&lt;br /&gt;
			if num then&lt;br /&gt;
				nums[#nums + 1] = tonumber(num)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	table.sort(nums)&lt;br /&gt;
	return nums&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- numData&lt;br /&gt;
--&lt;br /&gt;
-- Given a table with keys like (&amp;quot;foo1&amp;quot;, &amp;quot;bar1&amp;quot;, &amp;quot;foo2&amp;quot;, &amp;quot;baz2&amp;quot;), returns a table&lt;br /&gt;
-- of subtables in the format &lt;br /&gt;
-- { [1] = {foo = 'text', bar = 'text'}, [2] = {foo = 'text', baz = 'text'} }&lt;br /&gt;
-- Keys that don't end with an integer are stored in a subtable named &amp;quot;other&amp;quot;.&lt;br /&gt;
-- The compress option compresses the table so that it can be iterated over with&lt;br /&gt;
-- ipairs.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
--]]&lt;br /&gt;
function p.numData(t, compress)&lt;br /&gt;
	checkType('numData', 1, t, 'table')&lt;br /&gt;
	checkType('numData', 2, compress, 'boolean', true)&lt;br /&gt;
	local ret = {}&lt;br /&gt;
	for k, v in pairs(t) do&lt;br /&gt;
		local prefix, num = mw.ustring.match(tostring(k), '^([^0-9]*)([1-9][0-9]*)$')&lt;br /&gt;
		if num then&lt;br /&gt;
			num = tonumber(num)&lt;br /&gt;
			local subtable = ret[num] or {}&lt;br /&gt;
			if prefix == '' then&lt;br /&gt;
				-- Positional parameters match the blank string; put them at the start of the subtable instead.&lt;br /&gt;
				prefix = 1&lt;br /&gt;
			end&lt;br /&gt;
			subtable[prefix] = v&lt;br /&gt;
			ret[num] = subtable&lt;br /&gt;
		else&lt;br /&gt;
			local subtable = ret.other or {}&lt;br /&gt;
			subtable[k] = v&lt;br /&gt;
			ret.other = subtable&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if compress then&lt;br /&gt;
		local other = ret.other&lt;br /&gt;
		ret = p.compressSparseArray(ret)&lt;br /&gt;
		ret.other = other&lt;br /&gt;
	end&lt;br /&gt;
	return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- compressSparseArray&lt;br /&gt;
--&lt;br /&gt;
-- This takes an array with one or more nil values, and removes the nil values&lt;br /&gt;
-- while preserving the order, so that the array can be safely traversed with&lt;br /&gt;
-- ipairs.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
--]]&lt;br /&gt;
function p.compressSparseArray(t)&lt;br /&gt;
	checkType('compressSparseArray', 1, t, 'table')&lt;br /&gt;
	local ret = {}&lt;br /&gt;
	local nums = p.numKeys(t)&lt;br /&gt;
	for _, num in ipairs(nums) do&lt;br /&gt;
		ret[#ret + 1] = t[num]&lt;br /&gt;
	end&lt;br /&gt;
	return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- sparseIpairs&lt;br /&gt;
--&lt;br /&gt;
-- This is an iterator for sparse arrays. It can be used like ipairs, but can&lt;br /&gt;
-- handle nil values.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
--]]&lt;br /&gt;
function p.sparseIpairs(t)&lt;br /&gt;
	checkType('sparseIpairs', 1, t, 'table')&lt;br /&gt;
	local nums = p.numKeys(t)&lt;br /&gt;
	local i = 0&lt;br /&gt;
	local lim = #nums&lt;br /&gt;
	return function ()&lt;br /&gt;
		i = i + 1&lt;br /&gt;
		if i &amp;lt;= lim then&lt;br /&gt;
			local key = nums[i]&lt;br /&gt;
			return key, t[key]&lt;br /&gt;
		else&lt;br /&gt;
			return nil, nil&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- size&lt;br /&gt;
--&lt;br /&gt;
-- This returns the size of a key/value pair table. It will also work on arrays,&lt;br /&gt;
-- but for arrays it is more efficient to use the # operator.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
--]]&lt;br /&gt;
&lt;br /&gt;
function p.size(t)&lt;br /&gt;
	checkType('size', 1, t, 'table')&lt;br /&gt;
	local i = 0&lt;br /&gt;
	for k in pairs(t) do&lt;br /&gt;
		i = i + 1&lt;br /&gt;
	end&lt;br /&gt;
	return i&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local function defaultKeySort(item1, item2)&lt;br /&gt;
	-- &amp;quot;number&amp;quot; &amp;lt; &amp;quot;string&amp;quot;, so numbers will be sorted before strings.&lt;br /&gt;
	local type1, type2 = type(item1), type(item2)&lt;br /&gt;
	if type1 ~= type2 then&lt;br /&gt;
		return type1 &amp;lt; type2&lt;br /&gt;
	else -- This will fail with table, boolean, function.&lt;br /&gt;
		return item1 &amp;lt; item2&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
	Returns a list of the keys in a table, sorted using either a default&lt;br /&gt;
	comparison function or a custom keySort function.&lt;br /&gt;
]]&lt;br /&gt;
function p.keysToList(t, keySort, checked)&lt;br /&gt;
	if not checked then&lt;br /&gt;
		checkType('keysToList', 1, t, 'table')&lt;br /&gt;
		checkTypeMulti('keysToList', 2, keySort, { 'function', 'boolean', 'nil' })&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local list = {}&lt;br /&gt;
	local index = 1&lt;br /&gt;
	for key, value in pairs(t) do&lt;br /&gt;
		list[index] = key&lt;br /&gt;
		index = index + 1&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if keySort ~= false then&lt;br /&gt;
		keySort = type(keySort) == 'function' and keySort or defaultKeySort&lt;br /&gt;
		&lt;br /&gt;
		table.sort(list, keySort)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return list&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
	Iterates through a table, with the keys sorted using the keysToList function.&lt;br /&gt;
	If there are only numerical keys, sparseIpairs is probably more efficient.&lt;br /&gt;
]]&lt;br /&gt;
function p.sortedPairs(t, keySort)&lt;br /&gt;
	checkType('sortedPairs', 1, t, 'table')&lt;br /&gt;
	checkType('sortedPairs', 2, keySort, 'function', true)&lt;br /&gt;
	&lt;br /&gt;
	local list = p.keysToList(t, keySort, true)&lt;br /&gt;
	&lt;br /&gt;
	local i = 0&lt;br /&gt;
	return function()&lt;br /&gt;
		i = i + 1&lt;br /&gt;
		local key = list[i]&lt;br /&gt;
		if key ~= nil then&lt;br /&gt;
			return key, t[key]&lt;br /&gt;
		else&lt;br /&gt;
			return nil, nil&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
	Returns true if all keys in the table are consecutive integers starting at 1.&lt;br /&gt;
--]]&lt;br /&gt;
function p.isArray(t)&lt;br /&gt;
	checkType(&amp;quot;isArray&amp;quot;, 1, t, &amp;quot;table&amp;quot;)&lt;br /&gt;
	&lt;br /&gt;
	local i = 0&lt;br /&gt;
	for k, v in pairs(t) do&lt;br /&gt;
		i = i + 1&lt;br /&gt;
		if t[i] == nil then&lt;br /&gt;
			return false&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- { &amp;quot;a&amp;quot;, &amp;quot;b&amp;quot;, &amp;quot;c&amp;quot; } -&amp;gt; { a = 1, b = 2, c = 3 }&lt;br /&gt;
function p.invert(array)&lt;br /&gt;
	checkType(&amp;quot;invert&amp;quot;, 1, array, &amp;quot;table&amp;quot;)&lt;br /&gt;
	&lt;br /&gt;
	local map = {}&lt;br /&gt;
	for i, v in ipairs(array) do&lt;br /&gt;
		map[v] = i&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return map&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
	{ &amp;quot;a&amp;quot;, &amp;quot;b&amp;quot;, &amp;quot;c&amp;quot; } -&amp;gt; { [&amp;quot;a&amp;quot;] = true, [&amp;quot;b&amp;quot;] = true, [&amp;quot;c&amp;quot;] = true }&lt;br /&gt;
--]]&lt;br /&gt;
function p.listToSet(t)&lt;br /&gt;
	checkType(&amp;quot;listToSet&amp;quot;, 1, t, &amp;quot;table&amp;quot;)&lt;br /&gt;
	&lt;br /&gt;
	local set = {}&lt;br /&gt;
	for _, item in ipairs(t) do&lt;br /&gt;
		set[item] = true&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return set&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
	Recursive deep copy function.&lt;br /&gt;
	Preserves identities of subtables.&lt;br /&gt;
	&lt;br /&gt;
]]&lt;br /&gt;
local function _deepCopy(orig, includeMetatable, already_seen)&lt;br /&gt;
	-- Stores copies of tables indexed by the original table.&lt;br /&gt;
	already_seen = already_seen or {}&lt;br /&gt;
	&lt;br /&gt;
	local copy = already_seen[orig]&lt;br /&gt;
	if copy ~= nil then&lt;br /&gt;
		return copy&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if type(orig) == 'table' then&lt;br /&gt;
		copy = {}&lt;br /&gt;
		for orig_key, orig_value in pairs(orig) do&lt;br /&gt;
			copy[deepcopy(orig_key, includeMetatable, already_seen)] = deepcopy(orig_value, includeMetatable, already_seen)&lt;br /&gt;
		end&lt;br /&gt;
		already_seen[orig] = copy&lt;br /&gt;
		&lt;br /&gt;
		if includeMetatable then&lt;br /&gt;
			local mt = getmetatable(orig)&lt;br /&gt;
			if mt ~= nil then&lt;br /&gt;
				local mt_copy = deepcopy(mt, includeMetatable, already_seen)&lt;br /&gt;
				setmetatable(copy, mt_copy)&lt;br /&gt;
				already_seen[mt] = mt_copy&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	else -- number, string, boolean, etc&lt;br /&gt;
		copy = orig&lt;br /&gt;
	end&lt;br /&gt;
	return copy&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.deepCopy(orig, noMetatable, already_seen)&lt;br /&gt;
	checkType(&amp;quot;deepCopy&amp;quot;, 3, already_seen, &amp;quot;table&amp;quot;, true)&lt;br /&gt;
	&lt;br /&gt;
	return _deepCopy(orig, not noMetatable, already_seen)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
	Concatenates all values in the table that are indexed by a number, in order.&lt;br /&gt;
	sparseConcat{ a, nil, c, d }  =&amp;gt;  &amp;quot;acd&amp;quot;&lt;br /&gt;
	sparseConcat{ nil, b, c, d }  =&amp;gt;  &amp;quot;bcd&amp;quot;&lt;br /&gt;
]]&lt;br /&gt;
function p.sparseConcat(t, sep, i, j)&lt;br /&gt;
	local list = {}&lt;br /&gt;
	&lt;br /&gt;
	local list_i = 0&lt;br /&gt;
	for _, v in p.sparseIpairs(t) do&lt;br /&gt;
		list_i = list_i + 1&lt;br /&gt;
		list[list_i] = v&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return table.concat(list, sep, i, j)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
-- This returns the length of a table, or the first integer key n counting from&lt;br /&gt;
-- 1 such that t[n + 1] is nil. It is similar to the operator #, but may return&lt;br /&gt;
-- a different value when there are gaps in the array portion of the table.&lt;br /&gt;
-- Intended to be used on data loaded with mw.loadData. For other tables, use #.&lt;br /&gt;
-- Note: #frame.args in frame object always be set to 0, regardless of &lt;br /&gt;
-- the number of unnamed template parameters, so use this function for&lt;br /&gt;
-- frame.args.&lt;br /&gt;
--]]&lt;br /&gt;
function p.length(t)&lt;br /&gt;
	local i = 1&lt;br /&gt;
	while t[i] ~= nil do&lt;br /&gt;
		i = i + 1&lt;br /&gt;
	end&lt;br /&gt;
	return i - 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.inArray(arr, valueToFind)&lt;br /&gt;
	checkType(&amp;quot;inArray&amp;quot;, 1, arr, &amp;quot;table&amp;quot;)&lt;br /&gt;
	&lt;br /&gt;
	-- if valueToFind is nil, error?&lt;br /&gt;
	&lt;br /&gt;
	for _, v in ipairs(arr) do&lt;br /&gt;
		if v == valueToFind then&lt;br /&gt;
			return true&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=Module:Color_contrast&amp;diff=486</id>
		<title>Module:Color contrast</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=Module:Color_contrast&amp;diff=486"/>
		<updated>2019-11-10T17:28:15Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;--&lt;br /&gt;
-- This module implements&lt;br /&gt;
--  {{Color contrast ratio}}&lt;br /&gt;
--  {{Greater color contrast ratio}}&lt;br /&gt;
--  {{ColorToLum}}&lt;br /&gt;
--  {{RGBColorToLum}}&lt;br /&gt;
--&lt;br /&gt;
local p = {}&lt;br /&gt;
local HTMLcolor = mw.loadData( 'Module:Color contrast/colors' )&lt;br /&gt;
&lt;br /&gt;
local function sRGB (v)&lt;br /&gt;
	if (v &amp;lt;= 0.03928) then&lt;br /&gt;
		v = v / 12.92&lt;br /&gt;
	else&lt;br /&gt;
		v = math.pow((v+0.055)/1.055, 2.4)&lt;br /&gt;
	end&lt;br /&gt;
	return v&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function rgbdec2lum(R, G, B)&lt;br /&gt;
	if ( 0 &amp;lt;= R and R &amp;lt; 256 and 0 &amp;lt;= G and G &amp;lt; 256 and 0 &amp;lt;= B and B &amp;lt; 256 ) then&lt;br /&gt;
		return 0.2126 * sRGB(R/255) + 0.7152 * sRGB(G/255) + 0.0722 * sRGB(B/255)&lt;br /&gt;
	else&lt;br /&gt;
		return ''&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function hsl2lum(h, s, l)&lt;br /&gt;
	if ( 0 &amp;lt;= h and h &amp;lt; 360 and 0 &amp;lt;= s and s &amp;lt;= 1 and 0 &amp;lt;= l and l &amp;lt;= 1 ) then&lt;br /&gt;
		local c = (1 - math.abs(2*l - 1))*s&lt;br /&gt;
		local x = c*(1 - math.abs( math.fmod(h/60, 2) - 1) )&lt;br /&gt;
		local m = l - c/2&lt;br /&gt;
&lt;br /&gt;
		local r, g, b = m, m, m&lt;br /&gt;
		if( 0 &amp;lt;= h and h &amp;lt; 60 ) then&lt;br /&gt;
			r = r + c&lt;br /&gt;
			g = g + x&lt;br /&gt;
		elseif( 60 &amp;lt;= h and h &amp;lt; 120 ) then&lt;br /&gt;
			r = r + x&lt;br /&gt;
			g = g + c&lt;br /&gt;
		elseif( 120 &amp;lt;= h and h &amp;lt; 180 ) then&lt;br /&gt;
			g = g + c&lt;br /&gt;
			b = b + x&lt;br /&gt;
		elseif( 180 &amp;lt;= h and h &amp;lt; 240 ) then&lt;br /&gt;
			g = g + x&lt;br /&gt;
			b = b + c&lt;br /&gt;
		elseif( 240 &amp;lt;= h and h &amp;lt; 300 ) then&lt;br /&gt;
			r = r + x&lt;br /&gt;
			b = b + c&lt;br /&gt;
		elseif( 300 &amp;lt;= h and h &amp;lt; 360 ) then&lt;br /&gt;
			r = r + c&lt;br /&gt;
			b = b + x&lt;br /&gt;
		end&lt;br /&gt;
		return rgbdec2lum(255*r, 255*g, 255*b)&lt;br /&gt;
	else&lt;br /&gt;
		return ''&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function color2lum(c)&lt;br /&gt;
&lt;br /&gt;
	if (c == nil) then&lt;br /&gt;
		return ''&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- html '#' entity&lt;br /&gt;
	c = c:gsub(&amp;quot;&amp;amp;#35;&amp;quot;, &amp;quot;#&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
	-- whitespace&lt;br /&gt;
	c = c:match( '^%s*(.-)[%s;]*$' )&lt;br /&gt;
&lt;br /&gt;
	-- unstrip nowiki strip markers&lt;br /&gt;
	c = mw.text.unstripNoWiki(c)&lt;br /&gt;
&lt;br /&gt;
	-- lowercase&lt;br /&gt;
	c = c:lower()&lt;br /&gt;
&lt;br /&gt;
	-- first try to look it up&lt;br /&gt;
	local L = HTMLcolor[c]&lt;br /&gt;
	if (L ~= nil) then&lt;br /&gt;
		return L&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- convert from hsl&lt;br /&gt;
	if mw.ustring.match(c,'^hsl%([%s]*[0-9][0-9%.]*[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*%)$') then&lt;br /&gt;
		local h, s, l = mw.ustring.match(c,'^hsl%([%s]*([0-9][0-9%.]*)[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*%)$')&lt;br /&gt;
		return hsl2lum(tonumber(h), tonumber(s)/100, tonumber(l)/100)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- convert from rgb&lt;br /&gt;
	if mw.ustring.match(c,'^rgb%([%s]*[0-9][0-9]*[%s]*,[%s]*[0-9][0-9]*[%s]*,[%s]*[0-9][0-9]*[%s]*%)$') then&lt;br /&gt;
		local R, G, B = mw.ustring.match(c,'^rgb%([%s]*([0-9][0-9]*)[%s]*,[%s]*([0-9][0-9]*)[%s]*,[%s]*([0-9][0-9]*)[%s]*%)$')&lt;br /&gt;
		return rgbdec2lum(tonumber(R), tonumber(G), tonumber(B))&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- convert from rgb percent&lt;br /&gt;
	if mw.ustring.match(c,'^rgb%([%s]*[0-9][0-9%.]*%%[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*%)$') then&lt;br /&gt;
		local R, G, B = mw.ustring.match(c,'^rgb%([%s]*([0-9][0-9%.]*)%%[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*%)$')&lt;br /&gt;
		return rgbdec2lum(255*tonumber(R)/100, 255*tonumber(G)/100, 255*tonumber(B)/100)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- remove leading # (if there is one) and whitespace&lt;br /&gt;
	c = mw.ustring.match(c, '^[%s#]*([a-f0-9]*)[%s]*$')&lt;br /&gt;
&lt;br /&gt;
	-- split into rgb&lt;br /&gt;
	local cs = mw.text.split(c or '', '')&lt;br /&gt;
	if( #cs == 6 ) then&lt;br /&gt;
		local R = 16*tonumber('0x' .. cs[1]) + tonumber('0x' .. cs[2])&lt;br /&gt;
		local G = 16*tonumber('0x' .. cs[3]) + tonumber('0x' .. cs[4])&lt;br /&gt;
		local B = 16*tonumber('0x' .. cs[5]) + tonumber('0x' .. cs[6])&lt;br /&gt;
&lt;br /&gt;
		return rgbdec2lum(R, G, B)&lt;br /&gt;
	elseif ( #cs == 3 ) then&lt;br /&gt;
		local R = 16*tonumber('0x' .. cs[1]) + tonumber('0x' .. cs[1])&lt;br /&gt;
		local G = 16*tonumber('0x' .. cs[2]) + tonumber('0x' .. cs[2])&lt;br /&gt;
		local B = 16*tonumber('0x' .. cs[3]) + tonumber('0x' .. cs[3])&lt;br /&gt;
&lt;br /&gt;
		return rgbdec2lum(R, G, B)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- failure, return blank&lt;br /&gt;
	return ''&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- This exports the function for use in other modules.&lt;br /&gt;
-- The colour is passed as a string.&lt;br /&gt;
function p._lum(color)&lt;br /&gt;
	return color2lum(color)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._greatercontrast(args)&lt;br /&gt;
	local bias = tonumber(args['bias'] or '0') or 0&lt;br /&gt;
	local css = (args['css'] and args['css'] ~= '') and true or false&lt;br /&gt;
	local v1 = color2lum(args[1] or '')&lt;br /&gt;
	local c2 = args[2] or '#FFFFFF'&lt;br /&gt;
	local v2 = color2lum(c2)&lt;br /&gt;
	local c3 = args[3] or '#000000'&lt;br /&gt;
	local v3 = color2lum(c3)&lt;br /&gt;
	local ratio1 = -1;&lt;br /&gt;
	local ratio2 = -1;&lt;br /&gt;
	if (type(v1) == 'number' and type(v2) == 'number') then&lt;br /&gt;
		ratio1 = (v2 + 0.05)/(v1 + 0.05)&lt;br /&gt;
		ratio1 = (ratio1 &amp;lt; 1) and 1/ratio1 or ratio1&lt;br /&gt;
	end&lt;br /&gt;
	if (type(v1) == 'number' and type(v3) == 'number') then&lt;br /&gt;
		ratio2 = (v3 + 0.05)/(v1 + 0.05)&lt;br /&gt;
		ratio2 = (ratio2 &amp;lt; 1) and 1/ratio2 or ratio2&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if css then&lt;br /&gt;
		local c1 = args[1] or ''&lt;br /&gt;
		if mw.ustring.match(c1, '^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]$') or&lt;br /&gt;
			mw.ustring.match(c1, '^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]$') then&lt;br /&gt;
				c1 = '#' .. c1&lt;br /&gt;
		end&lt;br /&gt;
		if mw.ustring.match(c2, '^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]$') or&lt;br /&gt;
			mw.ustring.match(c2, '^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]$') then&lt;br /&gt;
				c2 = '#' .. c2&lt;br /&gt;
		end&lt;br /&gt;
		if mw.ustring.match(v3, '^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]$') or&lt;br /&gt;
			mw.ustring.match(v3, '^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]$') then&lt;br /&gt;
				c3 = '#' .. c3&lt;br /&gt;
		end&lt;br /&gt;
		return 'background-color:' .. c1 .. '; color:' .. ((ratio1 &amp;gt; 0) and (ratio2 &amp;gt; 0) and ((ratio1 + bias &amp;gt; ratio2) and c2 or c3) or '') .. ';'&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return (ratio1 &amp;gt; 0) and (ratio2 &amp;gt; 0) and ((ratio1 + bias &amp;gt; ratio2) and c2 or c3) or ''&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._ratio(args)&lt;br /&gt;
	local v1 = color2lum(args[1])&lt;br /&gt;
	local v2 = color2lum(args[2])&lt;br /&gt;
	if (type(v1) == 'number' and type(v2) == 'number') then&lt;br /&gt;
		-- v1 should be the brighter of the two.&lt;br /&gt;
		if v2 &amp;gt; v1 then&lt;br /&gt;
			v1, v2 = v2, v1&lt;br /&gt;
		end&lt;br /&gt;
		return (v1 + 0.05)/(v2 + 0.05)&lt;br /&gt;
	else&lt;br /&gt;
		return args['error'] or '?'&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._styleratio(args)&lt;br /&gt;
	local style = (args[1] or ''):lower()&lt;br /&gt;
	local bg, fg = 'white', 'black'&lt;br /&gt;
	local lum_bg, lum_fg = 1, 0&lt;br /&gt;
&lt;br /&gt;
	if args[2] then&lt;br /&gt;
		local lum = color2lum(args[2])&lt;br /&gt;
		if lum ~= '' then bg, lum_bg = args[2], lum end&lt;br /&gt;
	end&lt;br /&gt;
	if args[3] then&lt;br /&gt;
		local lum = color2lum(args[3])&lt;br /&gt;
		if lum ~= '' then fg, lum_fg = args[3], lum end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local slist = mw.text.split(mw.ustring.gsub(mw.ustring.gsub(style or '', '&amp;amp;#[Xx]23;', '#'), '&amp;amp;#35;', '#'), ';')&lt;br /&gt;
	for k = 1,#slist do&lt;br /&gt;
		local s = slist[k]&lt;br /&gt;
		local k,v = s:match( '^[%s]*([^:]-):([^:]-)[%s;]*$' )&lt;br /&gt;
		k = k or ''&lt;br /&gt;
		v = v or ''&lt;br /&gt;
		if (k:match('^[%s]*(background)[%s]*$') or k:match('^[%s]*(background%-color)[%s]*$')) then&lt;br /&gt;
			local lum = color2lum(v)&lt;br /&gt;
			if( lum ~= '' ) then bg, lum_bg = v, lum end&lt;br /&gt;
		elseif (k:match('^[%s]*(color)[%s]*$')) then&lt;br /&gt;
			local lum = color2lum(v)&lt;br /&gt;
			if( lum ~= '' ) then bg, lum_fg = v, lum end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if lum_bg &amp;gt; lum_fg then&lt;br /&gt;
		return (lum_bg + 0.05)/(lum_fg + 0.05)&lt;br /&gt;
	else&lt;br /&gt;
		return (lum_fg + 0.05)/(lum_bg + 0.05)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Use {{#invoke:Color contrast|somecolor}} directly or&lt;br /&gt;
{{#invoke:Color contrast}} from a wrapper template.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
	-- |1=	— required; A color to check.&lt;br /&gt;
--]]&lt;br /&gt;
function p.lum(frame)&lt;br /&gt;
	local color = frame.args[1] or frame:getParent().args[1]&lt;br /&gt;
	return p._lum(color)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.ratio(frame)&lt;br /&gt;
	local args = frame.args[1] and frame.args or frame:getParent().args&lt;br /&gt;
	return p._ratio(args)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.styleratio(frame)&lt;br /&gt;
	local args = frame.args[1] and frame.args or frame:getParent().args&lt;br /&gt;
	return p._styleratio(args)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.greatercontrast(frame)&lt;br /&gt;
	local args = frame.args[1] and frame.args or frame:getParent().args&lt;br /&gt;
	return p._greatercontrast(args)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
	<entry>
		<id>http://iti-testbed.tugraz.at/wiki/index.php?title=Module:Color_contrast/colors&amp;diff=489</id>
		<title>Module:Color contrast/colors</title>
		<link rel="alternate" type="text/html" href="http://iti-testbed.tugraz.at/wiki/index.php?title=Module:Color_contrast/colors&amp;diff=489"/>
		<updated>2019-11-10T17:28:15Z</updated>

		<summary type="html">&lt;p&gt;Schuschu: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;return {&lt;br /&gt;
	aliceblue            = 0.92880068253475,&lt;br /&gt;
	antiquewhite         = 0.84646951707754,&lt;br /&gt;
	aqua                 = 0.7874,&lt;br /&gt;
	aquamarine           = 0.8078549208338,&lt;br /&gt;
	azure                = 0.97265264954166,&lt;br /&gt;
	beige                = 0.8988459998705,&lt;br /&gt;
	bisque               = 0.80732327372979,&lt;br /&gt;
	black                = 0,&lt;br /&gt;
	blanchedalmond       = 0.85084439608156,&lt;br /&gt;
	blue                 = 0.0722,&lt;br /&gt;
	blueviolet           = 0.12622014321946,&lt;br /&gt;
	brown                = 0.098224287876511,&lt;br /&gt;
	burlywood            = 0.51559844533893,&lt;br /&gt;
	cadetblue            = 0.29424681085422,&lt;br /&gt;
	chartreuse           = 0.76032025902623,&lt;br /&gt;
	chocolate            = 0.23898526114557,&lt;br /&gt;
	coral                = 0.37017930872924,&lt;br /&gt;
	cornflowerblue       = 0.30318641994179,&lt;br /&gt;
	cornsilk             = 0.93562110372965,&lt;br /&gt;
	crimson              = 0.16042199953026,&lt;br /&gt;
	cyan                 = 0.7874,&lt;br /&gt;
	darkblue             = 0.018640801980939,&lt;br /&gt;
	darkcyan             = 0.20329317839046,&lt;br /&gt;
	darkgoldenrod        = 0.27264703559993,&lt;br /&gt;
	darkgray             = 0.39675523072563,&lt;br /&gt;
	darkgreen            = 0.091143429047575,&lt;br /&gt;
	darkgrey             = 0.39675523072563,&lt;br /&gt;
	darkkhaki            = 0.45747326349994,&lt;br /&gt;
	darkmagenta          = 0.07353047651207,&lt;br /&gt;
	darkolivegreen       = 0.12651920884889,&lt;br /&gt;
	darkorange           = 0.40016167026524,&lt;br /&gt;
	darkorchid           = 0.13413142174857,&lt;br /&gt;
	darkred              = 0.054889674531132,&lt;br /&gt;
	darksalmon           = 0.40541471563381,&lt;br /&gt;
	darkseagreen         = 0.43789249325969,&lt;br /&gt;
	darkslateblue        = 0.065792846227988,&lt;br /&gt;
	darkslategray        = 0.067608151928044,&lt;br /&gt;
	darkslategrey        = 0.067608151928044,&lt;br /&gt;
	darkturquoise        = 0.4874606277449,&lt;br /&gt;
	darkviolet           = 0.10999048339343,&lt;br /&gt;
	deeppink             = 0.23866895828276,&lt;br /&gt;
	deepskyblue          = 0.44481603395575,&lt;br /&gt;
	dimgray              = 0.14126329114027,&lt;br /&gt;
	dimgrey              = 0.14126329114027,&lt;br /&gt;
	dodgerblue           = 0.27442536991456,&lt;br /&gt;
	firebrick            = 0.10724525535015,&lt;br /&gt;
	floralwhite          = 0.95922484825004,&lt;br /&gt;
	forestgreen          = 0.18920812076002,&lt;br /&gt;
	fuchsia              = 0.2848,&lt;br /&gt;
	gainsboro            = 0.71569350050648,&lt;br /&gt;
	ghostwhite           = 0.94311261886323,&lt;br /&gt;
	gold                 = 0.69860877428159,&lt;br /&gt;
	goldenrod            = 0.41919977809569,&lt;br /&gt;
	gray                 = 0.2158605001139,&lt;br /&gt;
	green                = 0.15438342968146,&lt;br /&gt;
	greenyellow          = 0.80609472611453,&lt;br /&gt;
	grey                 = 0.2158605001139,&lt;br /&gt;
	honeydew             = 0.96336535554782,&lt;br /&gt;
	hotpink              = 0.34658438169715,&lt;br /&gt;
	indianred            = 0.21406134963884,&lt;br /&gt;
	indigo               = 0.03107561486337,&lt;br /&gt;
	ivory                = 0.99071270600615,&lt;br /&gt;
	khaki                = 0.77012343394121,&lt;br /&gt;
	lavender             = 0.80318750514521,&lt;br /&gt;
	lavenderblush        = 0.90172748631046,&lt;br /&gt;
	lawngreen            = 0.73905893124963,&lt;br /&gt;
	lemonchiffon         = 0.94038992245622,&lt;br /&gt;
	lightblue            = 0.63709141280807,&lt;br /&gt;
	lightcoral           = 0.35522120733135,&lt;br /&gt;
	lightcyan            = 0.94587293494829,&lt;br /&gt;
	lightgoldenrodyellow = 0.93348351018297,&lt;br /&gt;
	lightgray            = 0.65140563741982,&lt;br /&gt;
	lightgreen           = 0.69091979956865,&lt;br /&gt;
	lightgrey            = 0.65140563741982,&lt;br /&gt;
	lightpink            = 0.58566152734898,&lt;br /&gt;
	lightsalmon          = 0.4780675225206,&lt;br /&gt;
	lightseagreen        = 0.35050145117042,&lt;br /&gt;
	lightskyblue         = 0.56195637618331,&lt;br /&gt;
	lightslategray       = 0.23830165007287,&lt;br /&gt;
	lightslategrey       = 0.23830165007287,&lt;br /&gt;
	lightsteelblue       = 0.53983888284666,&lt;br /&gt;
	lightyellow          = 0.98161818392882,&lt;br /&gt;
	lime                 = 0.7152,&lt;br /&gt;
	limegreen            = 0.44571042246098,&lt;br /&gt;
	linen                = 0.88357340984379,&lt;br /&gt;
	magenta              = 0.2848,&lt;br /&gt;
	maroon               = 0.045891942324215,&lt;br /&gt;
	mediumaquamarine     = 0.49389703310801,&lt;br /&gt;
	mediumblue           = 0.044077780212328,&lt;br /&gt;
	mediumorchid         = 0.21639251153773,&lt;br /&gt;
	mediumpurple         = 0.22905858091648,&lt;br /&gt;
	mediumseagreen       = 0.34393112338131,&lt;br /&gt;
	mediumslateblue      = 0.20284629471622,&lt;br /&gt;
	mediumspringgreen    = 0.70704308194184,&lt;br /&gt;
	mediumturquoise      = 0.5133827926448,&lt;br /&gt;
	mediumvioletred      = 0.14371899849357,&lt;br /&gt;
	midnightblue         = 0.02071786635086,&lt;br /&gt;
	mintcream            = 0.97834604947588,&lt;br /&gt;
	mistyrose            = 0.82183047859185,&lt;br /&gt;
	moccasin             = 0.80083000991567,&lt;br /&gt;
	navajowhite          = 0.76519682342785,&lt;br /&gt;
	navy                 = 0.015585128108224,&lt;br /&gt;
	oldlace              = 0.91900633405549,&lt;br /&gt;
	olive                = 0.20027537200568,&lt;br /&gt;
	olivedrab            = 0.22593150951929,&lt;br /&gt;
	orange               = 0.4817026703631,&lt;br /&gt;
	orangered            = 0.25516243753416,&lt;br /&gt;
	orchid               = 0.31348806761439,&lt;br /&gt;
	palegoldenrod        = 0.78792647887614,&lt;br /&gt;
	palegreen            = 0.77936759006353,&lt;br /&gt;
	paleturquoise        = 0.76436077921714,&lt;br /&gt;
	palevioletred        = 0.28754994117889,&lt;br /&gt;
	papayawhip           = 0.87797100199835,&lt;br /&gt;
	peachpuff            = 0.74905589878251,&lt;br /&gt;
	peru                 = 0.30113074877936,&lt;br /&gt;
	pink                 = 0.63271070702466,&lt;br /&gt;
	plum                 = 0.45734221587969,&lt;br /&gt;
	powderblue           = 0.68254586500605,&lt;br /&gt;
	purple               = 0.061477070432439,&lt;br /&gt;
	rebeccapurple        = 0.07492341159447,&lt;br /&gt;
	red                  = 0.2126,&lt;br /&gt;
	rosybrown            = 0.32319457649407,&lt;br /&gt;
	royalblue            = 0.16663210743188,&lt;br /&gt;
	saddlebrown          = 0.097922285020521,&lt;br /&gt;
	salmon               = 0.36977241527596,&lt;br /&gt;
	sandybrown           = 0.46628543696283,&lt;br /&gt;
	seagreen             = 0.19734199706275,&lt;br /&gt;
	seashell             = 0.92737862206922,&lt;br /&gt;
	sienna               = 0.13697631337098,&lt;br /&gt;
	silver               = 0.52711512570581,&lt;br /&gt;
	skyblue              = 0.55291668518184,&lt;br /&gt;
	slateblue            = 0.14784278062136,&lt;br /&gt;
	slategray            = 0.20896704076536,&lt;br /&gt;
	slategrey            = 0.20896704076536,&lt;br /&gt;
	snow                 = 0.96533341834849,&lt;br /&gt;
	springgreen          = 0.73052306068529,&lt;br /&gt;
	steelblue            = 0.20562642207625,&lt;br /&gt;
	tan                  = 0.48237604163921,&lt;br /&gt;
	teal                 = 0.16996855778968,&lt;br /&gt;
	thistle              = 0.56818401093733,&lt;br /&gt;
	tomato               = 0.30638612719415,&lt;br /&gt;
	turquoise            = 0.5895536427578,&lt;br /&gt;
	violet               = 0.40315452986676,&lt;br /&gt;
	wheat                = 0.74909702820482,&lt;br /&gt;
	white                = 1,&lt;br /&gt;
	whitesmoke           = 0.91309865179342,&lt;br /&gt;
	yellow               = 0.9278,&lt;br /&gt;
	yellowgreen          = 0.50762957208707,&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Schuschu</name></author>
		
	</entry>
</feed>