<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.runerealm.org/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3AGadget-sandbox.js</id>
	<title>MediaWiki:Gadget-sandbox.js - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.runerealm.org/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3AGadget-sandbox.js"/>
	<link rel="alternate" type="text/html" href="https://wiki.runerealm.org/index.php?title=MediaWiki:Gadget-sandbox.js&amp;action=history"/>
	<updated>2026-04-11T05:10:08Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.41.1</generator>
	<entry>
		<id>https://wiki.runerealm.org/index.php?title=MediaWiki:Gadget-sandbox.js&amp;diff=42211&amp;oldid=prev</id>
		<title>Alex at 11:06, 20 October 2024</title>
		<link rel="alternate" type="text/html" href="https://wiki.runerealm.org/index.php?title=MediaWiki:Gadget-sandbox.js&amp;diff=42211&amp;oldid=prev"/>
		<updated>2024-10-20T11:06:19Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;a href=&quot;https://wiki.runerealm.org/index.php?title=MediaWiki:Gadget-sandbox.js&amp;amp;diff=42211&amp;amp;oldid=39081&quot;&gt;Show changes&lt;/a&gt;</summary>
		<author><name>Alex</name></author>
	</entry>
	<entry>
		<id>https://wiki.runerealm.org/index.php?title=MediaWiki:Gadget-sandbox.js&amp;diff=39081&amp;oldid=prev</id>
		<title>Alex at 16:15, 17 October 2024</title>
		<link rel="alternate" type="text/html" href="https://wiki.runerealm.org/index.php?title=MediaWiki:Gadget-sandbox.js&amp;diff=39081&amp;oldid=prev"/>
		<updated>2024-10-17T16:15:24Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 18:15, 17 October 2024&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 16:&lt;/td&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 16:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt; * @todo Allow the stored data to be coupled to the table in question. Currently the data is stored&lt;/div&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt; * @todo Allow the stored data to be coupled to the table in question. Currently the data is stored&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt; *       on the page itself, so if any tables are shuffled, the highlighting doesn&#039;t follow. For&lt;/div&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt; *       on the page itself, so if any tables are shuffled, the highlighting doesn&#039;t follow. For&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt; *       the same reason tables hosted on other &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;mw.&lt;/del&gt;pages are not synchronized.&lt;/div&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt; *       the same reason tables hosted on other pages are not synchronized.&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt; */&lt;/div&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt; */&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 289:&lt;/td&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 289:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;            /*&lt;/div&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;            /*&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             * Merge the updated data for the current page into the data for other &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;mw.&lt;/del&gt;pages into local storage.&lt;/div&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             * Merge the updated data for the current page into the data for other pages into local storage.&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             *&lt;/div&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             *&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             * @param hashedPageName A hash of the current page name.&lt;/div&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             * @param hashedPageName A hash of the current page name.&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 506:&lt;/td&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 506:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             * Save highlighted rows for named tables, using the data-tableid attribute.&lt;/div&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             * Save highlighted rows for named tables, using the data-tableid attribute.&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             * Does not override values that are not present in the current table. This allows usethe use of a single&lt;/div&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             * Does not override values that are not present in the current table. This allows usethe use of a single&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             * table ID on &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;mw.&lt;/del&gt;pages like [[Music]]&lt;/div&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             * table ID on pages like [[Music]]&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             *&lt;/div&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             *&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             * @param tblid The table id for the table to initialise&lt;/div&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             * @param tblid The table id for the table to initialise&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Alex</name></author>
	</entry>
	<entry>
		<id>https://wiki.runerealm.org/index.php?title=MediaWiki:Gadget-sandbox.js&amp;diff=34657&amp;oldid=prev</id>
		<title>Alex: Created page with &quot;/**  * highlightTable.js  *  * Description:  * Adds highlighting to tables  *  * History:  * - 1.0: Row highlighting                         - Quarenon  * - 1.1: Update from pengLocations.js v1.0        - Quarenon  * - 2.0: pengLocations v2.1, Granular cookie      - Saftzie  * - 2.1: Made compatible with jquery.tablesorter  - Cqm  * - 2.2: Switch to localStorage                   - Cqm  * - 3.0: Allow cell highlighting                  - mejrs  * - 4.0: Labelled highligh...&quot;</title>
		<link rel="alternate" type="text/html" href="https://wiki.runerealm.org/index.php?title=MediaWiki:Gadget-sandbox.js&amp;diff=34657&amp;oldid=prev"/>
		<updated>2024-10-16T23:10:36Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;/**  * highlightTable.js  *  * Description:  * Adds highlighting to tables  *  * History:  * - 1.0: Row highlighting                         - Quarenon  * - 1.1: Update from pengLocations.js v1.0        - Quarenon  * - 2.0: pengLocations v2.1, Granular cookie      - Saftzie  * - 2.1: Made compatible with jquery.tablesorter  - Cqm  * - 2.2: Switch to localStorage                   - Cqm  * - 3.0: Allow cell highlighting                  - mejrs  * - 4.0: Labelled highligh...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;/**&lt;br /&gt;
 * highlightTable.js&lt;br /&gt;
 *&lt;br /&gt;
 * Description:&lt;br /&gt;
 * Adds highlighting to tables&lt;br /&gt;
 *&lt;br /&gt;
 * History:&lt;br /&gt;
 * - 1.0: Row highlighting                         - Quarenon&lt;br /&gt;
 * - 1.1: Update from pengLocations.js v1.0        - Quarenon&lt;br /&gt;
 * - 2.0: pengLocations v2.1, Granular cookie      - Saftzie&lt;br /&gt;
 * - 2.1: Made compatible with jquery.tablesorter  - Cqm&lt;br /&gt;
 * - 2.2: Switch to localStorage                   - Cqm&lt;br /&gt;
 * - 3.0: Allow cell highlighting                  - mejrs&lt;br /&gt;
 * - 4.0: Labelled highlighting, not page-specific - Joeytje50&lt;br /&gt;
 *&lt;br /&gt;
 * @todo Allow the stored data to be coupled to the table in question. Currently the data is stored&lt;br /&gt;
 *       on the page itself, so if any tables are shuffled, the highlighting doesn&amp;#039;t follow. For&lt;br /&gt;
 *       the same reason tables hosted on other mw.pages are not synchronized.&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * DATA STORAGE STRUCTURE&lt;br /&gt;
 * ----------------------&lt;br /&gt;
 *&lt;br /&gt;
 * In its raw, uncompressed format, the stored data is as follows:&lt;br /&gt;
 * {&lt;br /&gt;
 *     hashedPageName1: [&lt;br /&gt;
 *         [0, 1, 0, 1, 0, 1],&lt;br /&gt;
 *         [1, 0, 1, 0, 1, 0],&lt;br /&gt;
 *         [0, 0, 0, 0, 0, 0]&lt;br /&gt;
 *     ],&lt;br /&gt;
 *     hashedPageName2: [&lt;br /&gt;
 *         [0, 1, 0, 1, 0, 1],&lt;br /&gt;
 *         [1, 0, 1, 0, 1, 0],&lt;br /&gt;
 *         [0, 0, 0, 0, 0, 0]&lt;br /&gt;
 *     ]&lt;br /&gt;
 * }&lt;br /&gt;
 *&lt;br /&gt;
 * Where `hashedPageNameX` is the value of wgPageName passed through our `hashString` function,&lt;br /&gt;
 * the arrays of numbers representing tables on a page (from top to bottom) and the numbers&lt;br /&gt;
 * representing whether a row is highlighted or not, depending on if it is 1 or 0 respectively.&lt;br /&gt;
 *&lt;br /&gt;
 * During compression, these numbers are collected into groups of 6 and converted to base64.&lt;br /&gt;
 * For example:&lt;br /&gt;
 *&lt;br /&gt;
 *   1. [0, 1, 0, 1, 0, 1]&lt;br /&gt;
 *   2. 0x010101             (1 + 4 + 16 = 21)&lt;br /&gt;
 *   3. BASE_64_URL[21]      (U)&lt;br /&gt;
 *&lt;br /&gt;
 * Once each table&amp;#039;s rows have been compressed into strings, they are concatenated using `.` as a&lt;br /&gt;
 * delimiter. The hashed page name (which is guaranteed to be 8 characters long) is then prepended&lt;br /&gt;
 * to this string to look something like the following:&lt;br /&gt;
 *&lt;br /&gt;
 *   XXXXXXXXab.dc.ef&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * The first character of a hashed page name is then used to form the object that is actually&lt;br /&gt;
 * stored. As the hashing function uses hexadecimal, this gives us 16 possible characters (0-9A-Z).&lt;br /&gt;
 *&lt;br /&gt;
 * {&lt;br /&gt;
 *     A: ...&lt;br /&gt;
 *     B: ...&lt;br /&gt;
 *     C: ...&lt;br /&gt;
 *     // etc.&lt;br /&gt;
 * }&lt;br /&gt;
 *&lt;br /&gt;
 * The final step of compression is to merge each page&amp;#039;s data together under it&amp;#039;s respective top&lt;br /&gt;
 * level key. this is done by concatenation again, separated by a `!`.&lt;br /&gt;
 *&lt;br /&gt;
 * The resulting object is then converted to a string and persisted in local storage. When&lt;br /&gt;
 * uncompressing data, simply perform the following steps in reverse.&lt;br /&gt;
 *&lt;br /&gt;
 * For the implementation of this algorithm, see:&lt;br /&gt;
 * - `compress`&lt;br /&gt;
 * - `parse`&lt;br /&gt;
 * - `hashString`&lt;br /&gt;
 *&lt;br /&gt;
 * Note that while rows could theoretically be compressed further by using all ASCII characters,&lt;br /&gt;
 * eventually we&amp;#039;d start using characters outside printable ASCII which makes debugging painful.&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
/*jshint bitwise:false, camelcase:true, curly:true, eqeqeq:true, es3:false,&lt;br /&gt;
    forin:true, immed:true, indent:4, latedef:true, newcap:true,&lt;br /&gt;
    noarg:true, noempty:true, nonew:true, plusplus:true, quotmark:single,&lt;br /&gt;
    undef:true, unused:true, strict:true, trailing:true,&lt;br /&gt;
    browser:true, devel:false, jquery:true,&lt;br /&gt;
    onevar:true&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
(function($, mw, OO, rs) {&lt;br /&gt;
    &amp;#039;use strict&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
    // constants&lt;br /&gt;
    var STORAGE_KEY = &amp;#039;rs:lightTable&amp;#039;,&lt;br /&gt;
        TABLE_CLASS = &amp;#039;lighttable&amp;#039;,&lt;br /&gt;
        TBLID = &amp;#039;tableid&amp;#039;,&lt;br /&gt;
        ROWID = &amp;#039;rowid&amp;#039;,&lt;br /&gt;
        LIGHT_ON_CLASS = &amp;#039;highlight-on&amp;#039;,&lt;br /&gt;
        MOUSE_OVER_CLASS = &amp;#039;highlight-over&amp;#039;,&lt;br /&gt;
        BASE_64_URL = &amp;#039;ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_&amp;#039;,&lt;br /&gt;
        PAGE_SEPARATOR = &amp;#039;!&amp;#039;,&lt;br /&gt;
        TABLE_SEPARATOR = &amp;#039;.&amp;#039;,&lt;br /&gt;
        CASTAGNOLI_POLYNOMIAL = 0x04c11db7,&lt;br /&gt;
        UINT32_MAX = 0xffffffff,&lt;br /&gt;
&lt;br /&gt;
        self = {&lt;br /&gt;
            /*&lt;br /&gt;
             * Stores the current uncompressed data for the current page.&lt;br /&gt;
             */&lt;br /&gt;
            data: null,&lt;br /&gt;
&lt;br /&gt;
            /*&lt;br /&gt;
             * Perform initial checks on the page and browser.&lt;br /&gt;
             */&lt;br /&gt;
            init: function() {&lt;br /&gt;
                var $tables = $(&amp;#039;table.&amp;#039; + TABLE_CLASS),&lt;br /&gt;
                    hashedPageName = self.hashString(mw.config.get(&amp;#039;wgPageName&amp;#039;));&lt;br /&gt;
&lt;br /&gt;
                // check we have some tables to interact with&lt;br /&gt;
                if (!$tables.length) {&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
                // check the browser supports local storage&lt;br /&gt;
                if (!rs.hasLocalStorage()) {&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                self.data = self.load(hashedPageName, $tables.length);&lt;br /&gt;
                self.initTables(hashedPageName, $tables);&lt;br /&gt;
            },&lt;br /&gt;
&lt;br /&gt;
            /*&lt;br /&gt;
             * Initialise table highlighting.&lt;br /&gt;
             *&lt;br /&gt;
             * @param hashedPageName The current page name as a hash.&lt;br /&gt;
             * @param $tables A list of highlightable tables on the current page.&lt;br /&gt;
             */&lt;br /&gt;
            initTables: function(hashedPageName, $tables) {&lt;br /&gt;
                $tables.each(function(tIndex) {&lt;br /&gt;
                    var $this = $(this),&lt;br /&gt;
                        $table = $this,&lt;br /&gt;
                        tblid = $this.data(TBLID),&lt;br /&gt;
                        // data cells&lt;br /&gt;
                        $cells = $this.find(&amp;#039;td&amp;#039;),&lt;br /&gt;
                        $rows = $this.find(&amp;#039;tr:has(td)&amp;#039;),&lt;br /&gt;
                        // don&amp;#039;t rely on headers to find number of columns      &lt;br /&gt;
                        // count them dynamically&lt;br /&gt;
                        columns = 1,&lt;br /&gt;
                        tableData = self.data[tIndex],&lt;br /&gt;
                        mode = &amp;#039;cells&amp;#039;,&lt;br /&gt;
                        initialised = false;&lt;br /&gt;
                        &lt;br /&gt;
                    if (tblid) {&lt;br /&gt;
                    	initialised = self.initNamed(tblid);&lt;br /&gt;
                    }&lt;br /&gt;
&lt;br /&gt;
                    // Switching between either highlighting rows or cells&lt;br /&gt;
                    if (!$this.hasClass(&amp;#039;individual&amp;#039;)) {&lt;br /&gt;
                        mode = &amp;#039;rows&amp;#039;;&lt;br /&gt;
                        $cells = $rows;&lt;br /&gt;
                    }&lt;br /&gt;
&lt;br /&gt;
                    // initialise rows if necessary&lt;br /&gt;
                    while ($cells.length &amp;gt; tableData.length) {&lt;br /&gt;
                        tableData.push(0);&lt;br /&gt;
                    }&lt;br /&gt;
&lt;br /&gt;
                    // counting the column count&lt;br /&gt;
                    // necessary to determine colspan of reset button&lt;br /&gt;
                    $rows.each(function() {&lt;br /&gt;
                        var $this = $(this);&lt;br /&gt;
                        columns = Math.max(columns, $this.children(&amp;#039;th,td&amp;#039;).length);&lt;br /&gt;
                    });&lt;br /&gt;
&lt;br /&gt;
                    $cells.each(function(cIndex) {&lt;br /&gt;
                        var $this = $(this),&lt;br /&gt;
                            cellData = tableData[cIndex];&lt;br /&gt;
&lt;br /&gt;
                        // forbid highlighting any cells/rows that have class nohighlight&lt;br /&gt;
                        if (!$this.hasClass(&amp;#039;nohighlight&amp;#039;)) {&lt;br /&gt;
                            // initialize highlighting based on localStorage, unless namedInit already did that&lt;br /&gt;
                            if (!initialised) {&lt;br /&gt;
                                self.setHighlight($this, cellData);&lt;br /&gt;
                            }&lt;br /&gt;
&lt;br /&gt;
                            // set mouse events&lt;br /&gt;
                            $this&lt;br /&gt;
                                .mouseover(function() {&lt;br /&gt;
                                    self.setHighlight($this, 2);&lt;br /&gt;
                                })&lt;br /&gt;
                                .mouseout(function() {&lt;br /&gt;
                                    self.setHighlight($this, 3);&lt;br /&gt;
                                })&lt;br /&gt;
                                .click(function(e) {&lt;br /&gt;
                                    // don&amp;#039;t toggle highlight when clicking links&lt;br /&gt;
                                    if ((e.target.tagName !== &amp;#039;A&amp;#039;) &amp;amp;&amp;amp; (e.target.tagName !== &amp;#039;IMG&amp;#039;)) {&lt;br /&gt;
                                        // 1 -&amp;gt; 0&lt;br /&gt;
                                        // 0 -&amp;gt; 1&lt;br /&gt;
                                        tableData[cIndex] = 1 - tableData[cIndex];&lt;br /&gt;
&lt;br /&gt;
                                        self.setHighlight($this, tableData[cIndex]);&lt;br /&gt;
                                        &lt;br /&gt;
                                        if (tblid) {&lt;br /&gt;
                                            self.saveNamed($table.data(TBLID));&lt;br /&gt;
                                        } else {&lt;br /&gt;
                                            self.save(hashedPageName);&lt;br /&gt;
                                        }&lt;br /&gt;
                                        &lt;br /&gt;
                                        e.stopPropagation();&lt;br /&gt;
                                    }&lt;br /&gt;
                                });&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                    &lt;br /&gt;
                    // if this is a named table, which wasn&amp;#039;t initialised yet, make sure to save data to the named system&lt;br /&gt;
                    if (tblid &amp;amp;&amp;amp; !initialised) {&lt;br /&gt;
                        self.saveNamed($table.data(TBLID));&lt;br /&gt;
                    }&lt;br /&gt;
&lt;br /&gt;
                    // add a button for reset&lt;br /&gt;
                    var button = new OO.ui.ButtonWidget({&lt;br /&gt;
                        label: &amp;#039;Clear selection&amp;#039;,&lt;br /&gt;
                        icon: &amp;#039;clear&amp;#039;,&lt;br /&gt;
                        title: &amp;#039;Removes all highlights from the table&amp;#039;,&lt;br /&gt;
                        classes: [&amp;#039;ht-reset&amp;#039;] // this class is targeted by other gadgets, be careful removing it&lt;br /&gt;
                    });&lt;br /&gt;
&lt;br /&gt;
                    button.$element.click(function() {&lt;br /&gt;
                        $cells.each(function(cIndex) {&lt;br /&gt;
                            tableData[cIndex] = 0;&lt;br /&gt;
                            self.setHighlight($(this), 0);&lt;br /&gt;
                        });&lt;br /&gt;
&lt;br /&gt;
                        if (tblid) {&lt;br /&gt;
                            self.saveNamed($table.data(TBLID));&lt;br /&gt;
                        } else {&lt;br /&gt;
                            self.save(hashedPageName, $tables.length);&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
&lt;br /&gt;
                    $this.append(&lt;br /&gt;
                        $(&amp;#039;&amp;lt;tfoot&amp;gt;&amp;#039;)&lt;br /&gt;
                            .append(&lt;br /&gt;
                                $(&amp;#039;&amp;lt;tr&amp;gt;&amp;#039;)&lt;br /&gt;
                                    .append(&lt;br /&gt;
                                        $(&amp;#039;&amp;lt;th&amp;gt;&amp;#039;)&lt;br /&gt;
                                            .attr(&amp;#039;colspan&amp;#039;, columns)&lt;br /&gt;
                                            .append(button.$element)&lt;br /&gt;
                                    )&lt;br /&gt;
                            )&lt;br /&gt;
                    );&lt;br /&gt;
                });&lt;br /&gt;
            },&lt;br /&gt;
&lt;br /&gt;
            /*&lt;br /&gt;
             * Change the cell background color based on mouse events.&lt;br /&gt;
             *&lt;br /&gt;
             * @param $cell The cell element.&lt;br /&gt;
             * @param val The value to control what class to add (if any).&lt;br /&gt;
             *            0 -&amp;gt; light off (no class)&lt;br /&gt;
             *            1 -&amp;gt; light on without hover&lt;br /&gt;
             *            2 -&amp;gt; mouse over&lt;br /&gt;
             */&lt;br /&gt;
            setHighlight: function($cell, val) {&lt;br /&gt;
                switch (val) {&lt;br /&gt;
                    // no highlighting&lt;br /&gt;
                    case 0:&lt;br /&gt;
                        $cell.removeClass(MOUSE_OVER_CLASS);&lt;br /&gt;
                        $cell.removeClass(LIGHT_ON_CLASS);&lt;br /&gt;
                        break;&lt;br /&gt;
&lt;br /&gt;
                    // light on&lt;br /&gt;
                    case 1:&lt;br /&gt;
                        $cell.removeClass(MOUSE_OVER_CLASS);&lt;br /&gt;
                        $cell.addClass(LIGHT_ON_CLASS);&lt;br /&gt;
                        break;&lt;br /&gt;
&lt;br /&gt;
                    // mouse-over&lt;br /&gt;
                    case 2:&lt;br /&gt;
                        $cell.addClass(MOUSE_OVER_CLASS);&lt;br /&gt;
                        break;&lt;br /&gt;
                        &lt;br /&gt;
                    // mouse-out without affecting highlights&lt;br /&gt;
                    case 3:&lt;br /&gt;
                    	$cell.removeClass(MOUSE_OVER_CLASS);&lt;br /&gt;
                    	break;&lt;br /&gt;
                }&lt;br /&gt;
            },&lt;br /&gt;
&lt;br /&gt;
            /*&lt;br /&gt;
             * Merge the updated data for the current page into the data for other mw.pages into local storage.&lt;br /&gt;
             *&lt;br /&gt;
             * @param hashedPageName A hash of the current page name.&lt;br /&gt;
             */&lt;br /&gt;
            save: function(hashedPageName) {&lt;br /&gt;
                // load the existing data so we know where to save it&lt;br /&gt;
                var curData = localStorage.getItem(STORAGE_KEY),&lt;br /&gt;
                    compressedData;&lt;br /&gt;
&lt;br /&gt;
                if (curData === null) {&lt;br /&gt;
                    curData = {};&lt;br /&gt;
                } else {&lt;br /&gt;
                    curData = JSON.parse(curData);&lt;br /&gt;
                    curData = self.parse(curData);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                // merge in our updated data and compress it&lt;br /&gt;
                curData[hashedPageName] = self.data;&lt;br /&gt;
                compressedData = self.compress(curData);&lt;br /&gt;
&lt;br /&gt;
                // convert to a string and save to localStorage&lt;br /&gt;
                compressedData = JSON.stringify(compressedData);&lt;br /&gt;
                localStorage.setItem(STORAGE_KEY, compressedData);&lt;br /&gt;
            },&lt;br /&gt;
&lt;br /&gt;
            /*&lt;br /&gt;
             * Compress the entire data set using tha algoritm documented at the top of the page.&lt;br /&gt;
             *&lt;br /&gt;
             * @param data The data to compress.&lt;br /&gt;
             *&lt;br /&gt;
             * @return the compressed data.&lt;br /&gt;
             */&lt;br /&gt;
            compress: function(data) {&lt;br /&gt;
                var ret = {};&lt;br /&gt;
&lt;br /&gt;
                Object.keys(data).forEach(function(hashedPageName) {&lt;br /&gt;
                    var pageData = data[hashedPageName],&lt;br /&gt;
                        pageKey = hashedPageName.charAt(0);&lt;br /&gt;
&lt;br /&gt;
                    if (!ret.hasOwnProperty(pageKey)) {&lt;br /&gt;
                        ret[pageKey] = {};&lt;br /&gt;
                    }&lt;br /&gt;
&lt;br /&gt;
                    ret[pageKey][hashedPageName] = [];&lt;br /&gt;
&lt;br /&gt;
                    pageData.forEach(function(tableData) {&lt;br /&gt;
                        var compressedTableData = &amp;#039;&amp;#039;,&lt;br /&gt;
                            i, j, k;&lt;br /&gt;
&lt;br /&gt;
                        for (i = 0; i &amp;lt; Math.ceil(tableData.length / 6); i += 1) {&lt;br /&gt;
                            k = tableData[6 * i];&lt;br /&gt;
&lt;br /&gt;
                            for (j = 1; j &amp;lt; 6; j += 1) {&lt;br /&gt;
                                k = 2 * k + ((6 * i + j &amp;lt; tableData.length) ? tableData[6 * i + j] : 0);&lt;br /&gt;
                            }&lt;br /&gt;
&lt;br /&gt;
                            compressedTableData += BASE_64_URL.charAt(k);&lt;br /&gt;
                        }&lt;br /&gt;
&lt;br /&gt;
                        ret[pageKey][hashedPageName].push(compressedTableData);&lt;br /&gt;
                    });&lt;br /&gt;
&lt;br /&gt;
                    ret[pageKey][hashedPageName] = ret[pageKey][hashedPageName].join(TABLE_SEPARATOR);&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                Object.keys(ret).forEach(function(pageKey) {&lt;br /&gt;
                    var hashKeys = Object.keys(ret[pageKey]),&lt;br /&gt;
                        hashedData = [];&lt;br /&gt;
&lt;br /&gt;
                    hashKeys.forEach(function(key) {&lt;br /&gt;
                        var pageData = ret[pageKey][key];&lt;br /&gt;
                        hashedData.push(key + pageData);&lt;br /&gt;
                    });&lt;br /&gt;
&lt;br /&gt;
                    hashedData = hashedData.join(PAGE_SEPARATOR);&lt;br /&gt;
                    ret[pageKey] = hashedData;&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                return ret;&lt;br /&gt;
            },&lt;br /&gt;
&lt;br /&gt;
            /*&lt;br /&gt;
             * Get the existing data for the current page.&lt;br /&gt;
             *&lt;br /&gt;
             * @param hashedPageName A hash of the current page name.&lt;br /&gt;
             * @param numTables The number of tables on the current page. Used to ensure the loaded&lt;br /&gt;
             *                  data matches the number of tables on the page thus handling cases&lt;br /&gt;
             *                  where tables have been added or removed. This does not check the&lt;br /&gt;
             *                  amount of rows in the given tables.&lt;br /&gt;
             *&lt;br /&gt;
             * @return The data for the current page.&lt;br /&gt;
             */&lt;br /&gt;
            load: function(hashedPageName, numTables) {&lt;br /&gt;
                var data = localStorage.getItem(STORAGE_KEY),&lt;br /&gt;
                    pageData;&lt;br /&gt;
&lt;br /&gt;
                if (data === null) {&lt;br /&gt;
                    pageData = [];&lt;br /&gt;
                } else {&lt;br /&gt;
                    data = JSON.parse(data);&lt;br /&gt;
                    data = self.parse(data);&lt;br /&gt;
&lt;br /&gt;
                    if (data.hasOwnProperty(hashedPageName)) {&lt;br /&gt;
                        pageData = data[hashedPageName];&lt;br /&gt;
                    } else {&lt;br /&gt;
                        pageData = [];&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                // if more tables were added&lt;br /&gt;
                // add extra arrays to store the data in&lt;br /&gt;
                // also populates if no existing data was found&lt;br /&gt;
                while (numTables &amp;gt; pageData.length) {&lt;br /&gt;
                    pageData.push([]);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                // if tables were removed, remove data from the end of the list&lt;br /&gt;
                // as there&amp;#039;s no way to tell which was removed&lt;br /&gt;
                while (numTables &amp;lt; pageData.length) {&lt;br /&gt;
                    pageData.pop();&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                return pageData;&lt;br /&gt;
            },&lt;br /&gt;
&lt;br /&gt;
            /*&lt;br /&gt;
             * Parse the compressed data as loaded from local storage using the algorithm desribed&lt;br /&gt;
             * at the top of the page.&lt;br /&gt;
             *&lt;br /&gt;
             * @param data The data to parse.&lt;br /&gt;
             *&lt;br /&gt;
             * @return the parsed data.&lt;br /&gt;
             */&lt;br /&gt;
            parse: function(data) {&lt;br /&gt;
                var ret = {};&lt;br /&gt;
&lt;br /&gt;
                Object.keys(data).forEach(function(pageKey) {&lt;br /&gt;
                    var pageData = data[pageKey].split(PAGE_SEPARATOR);&lt;br /&gt;
&lt;br /&gt;
                    pageData.forEach(function(tableData) {&lt;br /&gt;
                        var hashedPageName = tableData.substr(0, 8);&lt;br /&gt;
&lt;br /&gt;
                        tableData = tableData.substr(8).split(TABLE_SEPARATOR);&lt;br /&gt;
                        ret[hashedPageName] = [];&lt;br /&gt;
&lt;br /&gt;
                        tableData.forEach(function(rowData, index) {&lt;br /&gt;
                            var i, j, k;&lt;br /&gt;
&lt;br /&gt;
                            ret[hashedPageName].push([]);&lt;br /&gt;
&lt;br /&gt;
                            for (i = 0; i &amp;lt; rowData.length; i += 1) {&lt;br /&gt;
                                k = BASE_64_URL.indexOf(rowData.charAt(i));&lt;br /&gt;
&lt;br /&gt;
                                // input validation&lt;br /&gt;
                                if (k &amp;lt; 0) {&lt;br /&gt;
                                    k = 0;&lt;br /&gt;
                                }&lt;br /&gt;
&lt;br /&gt;
                                for (j = 5; j &amp;gt;= 0; j -= 1) {&lt;br /&gt;
                                    ret[hashedPageName][index][6 * i + j] = (k &amp;amp; 0x1);&lt;br /&gt;
                                    k &amp;gt;&amp;gt;= 1;&lt;br /&gt;
                                }&lt;br /&gt;
                            }&lt;br /&gt;
                        });&lt;br /&gt;
                    });&lt;br /&gt;
&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                return ret;&lt;br /&gt;
            },&lt;br /&gt;
&lt;br /&gt;
            /*&lt;br /&gt;
             * Hash a string into a big endian 32 bit hex string. Used to hash page names.&lt;br /&gt;
             *&lt;br /&gt;
             * @param input The string to hash.&lt;br /&gt;
             *&lt;br /&gt;
             * @return the result of the hash.&lt;br /&gt;
             */&lt;br /&gt;
            hashString: function(input) {&lt;br /&gt;
                var ret = 0,&lt;br /&gt;
                    table = [],&lt;br /&gt;
                    i, j, k;&lt;br /&gt;
&lt;br /&gt;
                // guarantee 8-bit chars&lt;br /&gt;
                input = window.unescape(window.encodeURI(input));&lt;br /&gt;
&lt;br /&gt;
                // calculate the crc (cyclic redundancy check) for all 8-bit data&lt;br /&gt;
                // bit-wise operations discard anything left of bit 31&lt;br /&gt;
                for (i = 0; i &amp;lt; 256; i += 1) {&lt;br /&gt;
                    k = (i &amp;lt;&amp;lt; 24);&lt;br /&gt;
&lt;br /&gt;
                    for (j = 0; j &amp;lt; 8; j += 1) {&lt;br /&gt;
                        k = (k &amp;lt;&amp;lt; 1) ^ ((k &amp;gt;&amp;gt;&amp;gt; 31) * CASTAGNOLI_POLYNOMIAL);&lt;br /&gt;
                    }&lt;br /&gt;
                    table[i] = k;&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                // the actual calculation&lt;br /&gt;
                for (i = 0; i &amp;lt; input.length; i += 1) {&lt;br /&gt;
                    ret = (ret &amp;lt;&amp;lt; 8) ^ table[(ret &amp;gt;&amp;gt;&amp;gt; 24) ^ input.charCodeAt(i)];&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                // make negative numbers unsigned&lt;br /&gt;
                if (ret &amp;lt; 0) {&lt;br /&gt;
                    ret += UINT32_MAX;&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                // 32-bit hex string, padded on the left&lt;br /&gt;
                ret = &amp;#039;0000000&amp;#039; + ret.toString(16).toUpperCase();&lt;br /&gt;
                ret = ret.substr(ret.length - 8);&lt;br /&gt;
&lt;br /&gt;
                return ret;&lt;br /&gt;
            },&lt;br /&gt;
            &lt;br /&gt;
            /*&lt;br /&gt;
             * Save highlighted rows for named tables, using the data-tableid attribute.&lt;br /&gt;
             * Does not override values that are not present in the current table. This allows usethe use of a single&lt;br /&gt;
             * table ID on mw.pages like [[Music]]&lt;br /&gt;
             *&lt;br /&gt;
             * @param tblid The table id for the table to initialise&lt;br /&gt;
             */&lt;br /&gt;
            saveNamed: function(tblid) {&lt;br /&gt;
                // local storage key is prefixed by the generic storage key, to avoid local storage naming conflicts.&lt;br /&gt;
                var lsKey = STORAGE_KEY + &amp;#039;:&amp;#039; + tblid,&lt;br /&gt;
                    data = localStorage.getItem(lsKey);&lt;br /&gt;
                var $tbls = $(&amp;#039;table.lighttable[data-tableid=&amp;quot;&amp;#039;+tblid+&amp;#039;&amp;quot;]&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
                if (data === null) {&lt;br /&gt;
                    data = {};&lt;br /&gt;
                } else {&lt;br /&gt;
                    data = JSON.parse(data);&lt;br /&gt;
                }&lt;br /&gt;
                &lt;br /&gt;
                $tbls.find(&amp;#039;[data-rowid]&amp;#039;).each(function() {&lt;br /&gt;
                    var id = $(this).data(&amp;#039;rowid&amp;#039;);&lt;br /&gt;
                    if (!id) return;&lt;br /&gt;
                    data[id] = Number($(this).hasClass(LIGHT_ON_CLASS));&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                localStorage.setItem(lsKey, JSON.stringify(data));&lt;br /&gt;
                console.log(data);&lt;br /&gt;
            },&lt;br /&gt;
            &lt;br /&gt;
            /*&lt;br /&gt;
             * Initialise a named table that uses data-tableid&lt;br /&gt;
             *&lt;br /&gt;
             * @param tblid The table id for the table to initialise&lt;br /&gt;
             * @return Boolean true if successfully initialised, false if no named highlight data was available&lt;br /&gt;
             */&lt;br /&gt;
            initNamed: function(tblid) {&lt;br /&gt;
                var lsKey = STORAGE_KEY + &amp;#039;:&amp;#039; + tblid;&lt;br /&gt;
                var data = localStorage.getItem(lsKey);&lt;br /&gt;
                var $tbls = $(&amp;#039;table.lighttable[data-tableid=&amp;quot;&amp;#039;+tblid+&amp;#039;&amp;quot;]&amp;#039;)&lt;br /&gt;
                if (data === null) {&lt;br /&gt;
                    // no data stored yet, so fall back to unnamed init&lt;br /&gt;
                    return false;&lt;br /&gt;
                }&lt;br /&gt;
                var data = JSON.parse(data);&lt;br /&gt;
&lt;br /&gt;
                $tbls.find(&amp;#039;[data-rowid]&amp;#039;).each(function() {&lt;br /&gt;
                    var id = $(this).data(&amp;#039;rowid&amp;#039;)&lt;br /&gt;
                    if (!id) return;&lt;br /&gt;
                    if ($(&amp;#039;[data-rowid=&amp;quot;&amp;#039;+id+&amp;#039;&amp;quot;]&amp;#039;).length &amp;gt; 1) {&lt;br /&gt;
                    	mw.log.warn(&amp;#039;Reused rowid detected in named lighttable:&amp;#039;, id, $(&amp;#039;[data-rowid=&amp;quot;&amp;#039;+id+&amp;#039;&amp;quot;]&amp;#039;));&lt;br /&gt;
                    }&lt;br /&gt;
                    self.setHighlight($(this), Number(data[id]))&lt;br /&gt;
                });&lt;br /&gt;
                return true;&lt;br /&gt;
            }&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
    $(self.init);&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
    // sample data for testing the algorithm used&lt;br /&gt;
    var data = {&lt;br /&gt;
        // page1&lt;br /&gt;
        &amp;#039;0FF47C63&amp;#039;: [&lt;br /&gt;
            [0, 1, 1, 0, 1, 0],&lt;br /&gt;
            [0, 1, 1, 0, 1, 0, 1, 1, 1],&lt;br /&gt;
            [0, 0, 0, 0, 1, 1, 0, 0]&lt;br /&gt;
        ],&lt;br /&gt;
        // page2&lt;br /&gt;
        &amp;#039;02B75ABA&amp;#039;: [&lt;br /&gt;
            [0, 1, 0, 1, 1, 0],&lt;br /&gt;
            [1, 1, 1, 0, 1, 0, 1, 1, 0],&lt;br /&gt;
            [0, 0, 1, 1, 0, 0, 0, 0]&lt;br /&gt;
        ],&lt;br /&gt;
        // page3&lt;br /&gt;
        &amp;#039;0676470D&amp;#039;: [&lt;br /&gt;
            [1, 0, 0, 1, 0, 1],&lt;br /&gt;
            [1, 0, 0, 1, 0, 1, 0, 0, 0],&lt;br /&gt;
            [1, 1, 1, 1, 0, 0, 1, 1]&lt;br /&gt;
        ]&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    console.log(&amp;#039;input&amp;#039;, data);&lt;br /&gt;
&lt;br /&gt;
    var compressedData = self.compress(data);&lt;br /&gt;
    console.log(&amp;#039;compressed&amp;#039;, compressedData);&lt;br /&gt;
&lt;br /&gt;
    var parsedData = self.parse(compressedData);&lt;br /&gt;
    console.log(parsedData);&lt;br /&gt;
    */&lt;br /&gt;
&lt;br /&gt;
}(this.jQuery, this.mediaWiki, this.OO, this.rswiki));&lt;/div&gt;</summary>
		<author><name>Alex</name></author>
	</entry>
</feed>