<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://eurovision.jobogamer.xyz/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3AGadget-libExtraUtil.js</id>
	<title>MediaWiki:Gadget-libExtraUtil.js - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://eurovision.jobogamer.xyz/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3AGadget-libExtraUtil.js"/>
	<link rel="alternate" type="text/html" href="https://eurovision.jobogamer.xyz/index.php?title=MediaWiki:Gadget-libExtraUtil.js&amp;action=history"/>
	<updated>2026-07-25T10:40:11Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.45.4</generator>
	<entry>
		<id>https://eurovision.jobogamer.xyz/index.php?title=MediaWiki:Gadget-libExtraUtil.js&amp;diff=285&amp;oldid=prev</id>
		<title>Alfie: 1 revision imported</title>
		<link rel="alternate" type="text/html" href="https://eurovision.jobogamer.xyz/index.php?title=MediaWiki:Gadget-libExtraUtil.js&amp;diff=285&amp;oldid=prev"/>
		<updated>2026-03-19T09:58:34Z</updated>

		<summary type="html">&lt;p&gt;1 revision imported&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 05:58, 19 March 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Alfie</name></author>
	</entry>
	<entry>
		<id>https://eurovision.jobogamer.xyz/index.php?title=MediaWiki:Gadget-libExtraUtil.js&amp;diff=284&amp;oldid=prev</id>
		<title>en&gt;Pppery: Drop polyfills per request</title>
		<link rel="alternate" type="text/html" href="https://eurovision.jobogamer.xyz/index.php?title=MediaWiki:Gadget-libExtraUtil.js&amp;diff=284&amp;oldid=prev"/>
		<updated>2024-02-05T17:17:55Z</updated>

		<summary type="html">&lt;p&gt;Drop polyfills per request&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;/*  _____________________________________________________________________________&lt;br /&gt;
 * |                                                                             |&lt;br /&gt;
 * |                    === WARNING: GLOBAL GADGET FILE ===                      |&lt;br /&gt;
 * |                  Changes to this page affect many users.                    |&lt;br /&gt;
 * | Please discuss changes on the talk page or on [[WT:Gadget]] before editing. |&lt;br /&gt;
 * |_____________________________________________________________________________|&lt;br /&gt;
 *&lt;br /&gt;
 * ###############################################################################&lt;br /&gt;
 * #                                                                             #&lt;br /&gt;
 * #  This script has unit tests on its /testcases.js subpage. Please install    #&lt;br /&gt;
 * #  the WikiUnit script [[User:Evad37/WikiUnit]] and run tests before saving.  #&lt;br /&gt;
 * #                                                                             #&lt;br /&gt;
 * ###############################################################################&lt;br /&gt;
 * &lt;br /&gt;
 * Imported from version 924857650 as of 14 November 2019 from [[User:Evad37/extra.js]]&lt;br /&gt;
 * Common helper functions (created for XFDcloser, but may be useful for other scripts)&lt;br /&gt;
 * Author: Evad37&lt;br /&gt;
 *&lt;br /&gt;
 * Take care to load approriate resource loader modules, as specified for each function.&lt;br /&gt;
 * See &amp;lt; https://www.mediawiki.org/wiki/mw.loader &amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
/* jshint esversion: 5, laxbreak: true, undef: true, maxerr: 999*/&lt;br /&gt;
/* globals window, $, mw, OO, extraJs */&lt;br /&gt;
// &amp;lt;nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
window.extraJs = { version: &amp;#039;2.3.0&amp;#039; };&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * makeApiErrorMsg&lt;br /&gt;
 *&lt;br /&gt;
 * Makes an error message, suitable for displaying to a user, from the values&lt;br /&gt;
 * that the MediaWiki Api passes to the failure callback function, e.g.&lt;br /&gt;
 * `new mw.Api.get(queryObject}).done(successCallback).fail(failureCallback)`&lt;br /&gt;
 *&lt;br /&gt;
 * @param {string} code&lt;br /&gt;
 *  First parameter passed to failure callback function.&lt;br /&gt;
 * @param {jQuery.jqXHR} jqxhr&lt;br /&gt;
 *  Second parameter passed to failure callback function.&lt;br /&gt;
 * @return {string} Error message details, with in a format like&lt;br /&gt;
 *  &amp;quot;(API|HTTP) error: details&amp;quot;&lt;br /&gt;
 */&lt;br /&gt;
extraJs.makeErrorMsg = function(code, jqxhr) {&lt;br /&gt;
	var details = &amp;#039;&amp;#039;;&lt;br /&gt;
	if ( code === &amp;#039;http&amp;#039; &amp;amp;&amp;amp; jqxhr.textStatus === &amp;#039;error&amp;#039; ) {&lt;br /&gt;
		details = &amp;#039;HTTP error &amp;#039; + jqxhr.xhr.status;&lt;br /&gt;
	} else if ( code === &amp;#039;http&amp;#039; ) {&lt;br /&gt;
		details = &amp;#039;HTTP error: &amp;#039; + jqxhr.textStatus;&lt;br /&gt;
	} else if ( code === &amp;#039;ok-but-empty&amp;#039; ) {&lt;br /&gt;
		details = &amp;#039;Error: Got an empty response from the server&amp;#039;;&lt;br /&gt;
	} else {&lt;br /&gt;
		details = &amp;#039;API error: &amp;#039; + code;&lt;br /&gt;
	}&lt;br /&gt;
	return details;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * makeLink&lt;br /&gt;
 *&lt;br /&gt;
 * Makes a link to a en.Wikipedia page that opens in a new tab/window.&lt;br /&gt;
 * &lt;br /&gt;
 * @requires {Module} mediawiki.util&lt;br /&gt;
 * @param {string} linktarget&lt;br /&gt;
 *  The target page.&lt;br /&gt;
 * @param {string} linktext&lt;br /&gt;
 *  Text to display in the link. Optional, if not provided the target will be used.&lt;br /&gt;
 * @return {jQuery} jQuery object containing the `&amp;lt;a&amp;gt;` element.&lt;br /&gt;
 */&lt;br /&gt;
extraJs.makeLink = function(linktarget, linktext) {&lt;br /&gt;
	if ( linktext == null ) {&lt;br /&gt;
		linktext = linktarget;&lt;br /&gt;
	}&lt;br /&gt;
	return $(&amp;#039;&amp;lt;a&amp;gt;&amp;#039;).attr({&lt;br /&gt;
		&amp;#039;href&amp;#039;: mw.util.getUrl(linktarget),&lt;br /&gt;
		&amp;#039;target&amp;#039;:&amp;#039;_blank&amp;#039;&lt;br /&gt;
	}).text(linktext);&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * makeTooltip&lt;br /&gt;
 *&lt;br /&gt;
 * Make a question mark in a circle that shows a &amp;#039;tooltip&amp;#039; when hovered over&lt;br /&gt;
 * &lt;br /&gt;
 * @deprecated Use addTooltip instead.&lt;br /&gt;
 *&lt;br /&gt;
 * @param {string} tipText&lt;br /&gt;
 *  The text for the tooltip.&lt;br /&gt;
 * @return {jQuery} jQuery object containing the tooltip element&lt;br /&gt;
 */&lt;br /&gt;
extraJs.makeTooltip = function(tipText) {&lt;br /&gt;
	// Add css rule, if not already added&lt;br /&gt;
	if ( !extraJs.tooltipStyle ) {&lt;br /&gt;
		var s = mw.loader.addStyleTag(&amp;#039;.ejs-tooltip { border:1px solid #33a; border-radius:10px; &amp;#039;+&lt;br /&gt;
		&amp;#039;font-weight:bold; font-size:80%; color:#22a; padding:0px; cursor:help }&amp;#039;);&lt;br /&gt;
		extraJs.tooltipStyle = s.sheet || s.styleSheet || s;&lt;br /&gt;
	}&lt;br /&gt;
	return $(&amp;#039;&amp;lt;span&amp;gt;&amp;#039;).attr({&amp;#039;title&amp;#039;:tipText, &amp;#039;class&amp;#039;:&amp;#039;ejs-tooltip&amp;#039;}).html(&amp;#039;&amp;amp;thinsp;?&amp;amp;thinsp;&amp;#039;);&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * addTooltip&lt;br /&gt;
 *&lt;br /&gt;
 * Appends a question mark in a circle to an element, and shows a&lt;br /&gt;
 * &amp;#039;tooltip&amp;#039; when the element is hovered over&lt;br /&gt;
 *&lt;br /&gt;
 * @param {jQuery} $el jQuery element to add the tooltip to.&lt;br /&gt;
 * @param {string} tipText The text for the tooltip.&lt;br /&gt;
 * @return {jQuery} jQuery element witj the tooltip&lt;br /&gt;
 */&lt;br /&gt;
extraJs.addTooltip = function($el, tipText) {&lt;br /&gt;
	// Add css rule, if not already added&lt;br /&gt;
	if ( !extraJs.tooltipStyles ) {&lt;br /&gt;
		var s = mw.loader.addStyleTag(&lt;br /&gt;
			&amp;quot;.ejs-tooltips { display: inline-block; border-bottom: 1px dotted black; cursor:help; } &amp;quot;+&lt;br /&gt;
			&amp;quot;.ejs-tooltipstext-container { visibility: hidden; position: absolute; z-index: 2000; width:auto; max-width:500px; padding:2px 0 0 10px; white-space:normal; } &amp;quot;+&lt;br /&gt;
			&amp;quot;.ejs-tooltips:hover .ejs-tooltipstext-container { visibility: visible; } &amp;quot;+&lt;br /&gt;
			&amp;quot;.ejs-tooltips .ejs-tooltipstext { display:inline-block; background-color: #333; color: #ddd; text-align: center; border-radius: 5px; padding: 5px; } &amp;quot;+			  &lt;br /&gt;
			&amp;quot;.ejs-tooltips-symbol { border:1px solid #33a; border-radius:20px; font-weight:bold; font-size:80%; color:#22a; padding:0px; cursor:help }&amp;quot;&lt;br /&gt;
		);&lt;br /&gt;
		extraJs.tooltipStyles = s.sheet || s.styleSheet || s;&lt;br /&gt;
	}&lt;br /&gt;
	return $el.addClass(&amp;quot;ejs-tooltips&amp;quot;).append(&lt;br /&gt;
		$(&amp;quot;&amp;lt;span class=&amp;#039;ejs-tooltips-symbol&amp;#039;&amp;gt;&amp;amp;thinsp;?&amp;amp;thinsp;&amp;lt;/span&amp;gt;&amp;quot;),&lt;br /&gt;
		$(&amp;quot;&amp;lt;div class=&amp;#039;ejs-tooltipstext-container&amp;#039;&amp;gt;&amp;quot;).append(&lt;br /&gt;
			$(&amp;quot;&amp;lt;span class=&amp;#039;ejs-tooltipstext&amp;#039;&amp;gt;&amp;quot;).text(tipText)&lt;br /&gt;
		)&lt;br /&gt;
	);&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * multiButtonConfirm&lt;br /&gt;
 *&lt;br /&gt;
 * Uses OOjs UI to create a multi-button confirm dialogue.&lt;br /&gt;
 *&lt;br /&gt;
 * @requires {Modules} oojs-ui-core, oojs-ui-windows, mediawiki.util&lt;br /&gt;
 * @param {string} title&lt;br /&gt;
 *  Title for the dialogue.&lt;br /&gt;
 * @param {string} message&lt;br /&gt;
 *  Message for the dialogue. Certain HTML tags can be escaped, newline characters are ignored.&lt;br /&gt;
 * @param {object[]} buttons&lt;br /&gt;
 *  Array of objects which each represent a buttons to show at the bottom of the prompt.&lt;br /&gt;
 *  Each object can be of the form&lt;br /&gt;
 *  `{&lt;br /&gt;
 *    label: {string},&lt;br /&gt;
 *    action: {string|null},&lt;br /&gt;
 *    flags: {string|null},&lt;br /&gt;
 *   }`&lt;br /&gt;
 *  where `label` is the label to show on the button, `action` is the value passed to the callback&lt;br /&gt;
 *  function if that button is selected by the user, and `flags` is one of &amp;quot;safe&amp;quot;, &amp;quot;primary&amp;quot;,&lt;br /&gt;
 *  &amp;quot;progressive&amp;quot;, or &amp;quot;destructive&amp;quot;, per https://www.mediawiki.org/wiki/OOjs_UI/Elements/Flagged&lt;br /&gt;
 * @param {function} callback&lt;br /&gt;
 *  callback function executed after a button is selected (passed that button&amp;#039;s `action` value)&lt;br /&gt;
 * @param {object} options&lt;br /&gt;
 *  Display options:&lt;br /&gt;
 *   @param {boolean} options.verbose&lt;br /&gt;
 *    Display verbose message formatting (left- instead of center-aligned)&lt;br /&gt;
 *   @param {boolean} options.unescape&lt;br /&gt;
 *    Unescape the following simple HTML tags (no attributes) in the message:&lt;br /&gt;
 *    &amp;lt;br&amp;gt;, &amp;lt;p&amp;gt;, &amp;lt;ul&amp;gt;, &amp;lt;li&amp;gt;, &amp;lt;pre&amp;gt; (and matching closing tags or self-closed tags).&lt;br /&gt;
 *    Tags within &amp;lt;pre&amp;gt; tags will not be unescaped.&lt;br /&gt;
 *   @param {boolean} options.wikilinks&lt;br /&gt;
 *    Convert [[wikilinks]] into actual links. If `options.unescape` is set to `true`, wikilinks&lt;br /&gt;
 *    within &amp;lt;pre&amp;gt; tags will not be converted.&lt;br /&gt;
 */&lt;br /&gt;
extraJs.multiButtonConfirm = function(title, message, buttons, callback, options) {&lt;br /&gt;
	// If needed, create array of deferreds&lt;br /&gt;
	if ( !extraJs.multiButtonConfirm.dfd ) {&lt;br /&gt;
		extraJs.multiButtonConfirm.dfd = [$.Deferred().resolve()];&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	// Add Deferred, to be resoved when previous window is done&lt;br /&gt;
	var dfdIndex = extraJs.multiButtonConfirm.dfd.push($.Deferred()) - 1;&lt;br /&gt;
	&lt;br /&gt;
	// Open window when previous window&amp;#039;s Deferred is resolved&lt;br /&gt;
	extraJs.multiButtonConfirm.dfd[dfdIndex-1].done(function(){&lt;br /&gt;
		extraJs.multiButtonConfirm.windowManager = new OO.ui.WindowManager();&lt;br /&gt;
		var windowManager = extraJs.multiButtonConfirm.windowManager;&lt;br /&gt;
		var messageDialog = new OO.ui.MessageDialog();&lt;br /&gt;
		$(&amp;#039;body&amp;#039;).append( windowManager.$element );&lt;br /&gt;
		windowManager.addWindows( [ messageDialog ] );&lt;br /&gt;
		var instance = windowManager.openWindow( messageDialog, {&lt;br /&gt;
			title: title,&lt;br /&gt;
			message: message,&lt;br /&gt;
			verbose: options &amp;amp;&amp;amp; options.verbose,&lt;br /&gt;
			actions: buttons&lt;br /&gt;
		} );&lt;br /&gt;
		instance.opened.then( function() {&lt;br /&gt;
			if ( options &amp;amp;&amp;amp; ( options.unescape || options.wikilinks ) ) {&lt;br /&gt;
				// Escaped message text&lt;br /&gt;
				var msg = $(&amp;#039;label.oo-ui-messageDialog-message&amp;#039;)&lt;br /&gt;
					.filter(&amp;#039;:visible&amp;#039;)&lt;br /&gt;
					.text();&lt;br /&gt;
				&lt;br /&gt;
				// Unescape escaped html - pre tags			&lt;br /&gt;
				if ( options.unescape ) {&lt;br /&gt;
					// Process pre tags first (this way the only unescaped `&amp;lt;`s will be for pre tags)&lt;br /&gt;
					msg = msg.replace(/&amp;amp;lt;(\/?pre\s?\/?)&amp;amp;gt;/g,&amp;#039;&amp;lt;$1&amp;gt;&amp;#039;);&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				// Make wikilinks into real links&lt;br /&gt;
				if ( options.wikilinks ) {&lt;br /&gt;
					var path = &amp;#039;https:&amp;#039; + mw.config.get(&amp;#039;wgServer&amp;#039;) + &amp;#039;/wiki/&amp;#039;;&lt;br /&gt;
					// First piped links, then simple links (unless inside &amp;lt;pre&amp;gt; tags)&lt;br /&gt;
					msg = msg.replace(&lt;br /&gt;
						/\[\[([^\|\]]*?)\|([^\|\]]*?)\]\](?![^&amp;lt;]*?&amp;lt;\/pre&amp;gt;)/g,&lt;br /&gt;
						&amp;#039;&amp;lt;a href=&amp;quot;&amp;#039; + path + mw.util.wikiUrlencode(&amp;#039;$1&amp;#039;) + &amp;#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;$2&amp;lt;/a&amp;gt;&amp;#039;&lt;br /&gt;
					).replace(&lt;br /&gt;
						/\[\[([^\|\]]+?)]\](?![^&amp;lt;]*?&amp;lt;\/pre&amp;gt;)/g,&lt;br /&gt;
						&amp;#039;&amp;lt;a href=&amp;quot;&amp;#039; + path + mw.util.wikiUrlencode(&amp;#039;$1&amp;#039;) + &amp;#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;$1&amp;lt;/a&amp;gt;&amp;#039;&lt;br /&gt;
					);&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				// Unescape escaped html - other tags			&lt;br /&gt;
				if ( options.unescape ) {&lt;br /&gt;
					// Process other tags, unless inside &amp;lt;pre&amp;gt; tags&lt;br /&gt;
					msg = msg.replace(/&amp;amp;lt;(\/?(?:br|p|ul|li)\s?\/?)&amp;amp;gt;(?![^&amp;lt;]*?&amp;lt;\/pre&amp;gt;)/g,&amp;#039;&amp;lt;$1&amp;gt;&amp;#039;);&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				// Replace message&lt;br /&gt;
				$(&amp;#039;label.oo-ui-messageDialog-message&amp;#039;)&lt;br /&gt;
				.filter(&amp;#039;:visible&amp;#039;)&lt;br /&gt;
				.html(msg);&lt;br /&gt;
				&lt;br /&gt;
				// Resize dialogue to fit&lt;br /&gt;
				messageDialog.updateSize();&lt;br /&gt;
			}&lt;br /&gt;
		} );&lt;br /&gt;
		instance.closed.then( function ( data ) {&lt;br /&gt;
			if ( data &amp;amp;&amp;amp; data.action ) {&lt;br /&gt;
				callback(data.action);&lt;br /&gt;
			} else {&lt;br /&gt;
				callback(null);&lt;br /&gt;
			}&lt;br /&gt;
			windowManager.destroy();&lt;br /&gt;
			// Resolve this window&amp;#039;s Deferred&lt;br /&gt;
			extraJs.multiButtonConfirm.dfd[dfdIndex].resolve();&lt;br /&gt;
		} );&lt;br /&gt;
	});&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
/** Template&lt;br /&gt;
 *&lt;br /&gt;
 * @class&lt;br /&gt;
 * Represents the wikitext of template transclusion. Used by #parseTemplates.&lt;br /&gt;
 * @prop {String} name Name of the template&lt;br /&gt;
 * @prop {String} wikitext Full wikitext of the transclusion&lt;br /&gt;
 * @prop {Object[]} parameters Parameters used in the translcusion, in order, of form:&lt;br /&gt;
	{&lt;br /&gt;
		name: {String|Number} parameter name, or position for unnamed parameters,&lt;br /&gt;
		value: {String} Wikitext passed to the parameter (whitespace trimmed),&lt;br /&gt;
		wikitext: {String} Full wikitext (including leading pipe, parameter name/equals sign (if applicable), value, and any whitespace)&lt;br /&gt;
	}&lt;br /&gt;
 * @constructor&lt;br /&gt;
 * @param {String} wikitext Wikitext of a template transclusion, starting with &amp;#039;{{&amp;#039; and ending with &amp;#039;}}&amp;#039;.&lt;br /&gt;
 */&lt;br /&gt;
extraJs.Template = function(wikitext) {&lt;br /&gt;
	this.wikitext = wikitext;&lt;br /&gt;
	this.parameters = [];&lt;br /&gt;
};&lt;br /&gt;
extraJs.Template.constructor = extraJs.Template;&lt;br /&gt;
extraJs.Template.prototype.addParam = function(name, val, wikitext) {&lt;br /&gt;
	this.parameters.push({&lt;br /&gt;
		&amp;#039;name&amp;#039;: name,&lt;br /&gt;
		&amp;#039;value&amp;#039;: val, &lt;br /&gt;
		&amp;#039;wikitext&amp;#039;: &amp;#039;|&amp;#039; + wikitext&lt;br /&gt;
	});&lt;br /&gt;
};&lt;br /&gt;
/**&lt;br /&gt;
 * Get a parameter data by parameter name&lt;br /&gt;
 */ &lt;br /&gt;
extraJs.Template.prototype.getParam = function(paramName) {&lt;br /&gt;
	return this.parameters.find(function(p) { return p.name == paramName; });&lt;br /&gt;
};&lt;br /&gt;
extraJs.Template.prototype.setName = function(name) {&lt;br /&gt;
	this.name = name.trim();&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * parseTemplates&lt;br /&gt;
 *&lt;br /&gt;
 * Parses templates from wikitext.&lt;br /&gt;
 * Based on SD0001&amp;#039;s version at &amp;lt;https://en.wikipedia.org/wiki/User:SD0001/parseAllTemplates.js&amp;gt;.&lt;br /&gt;
 * Returns an array containing the template details:&lt;br /&gt;
 *  var templates = parseTemplates(&amp;quot;Hello {{foo |Bar|baz=qux |2=loremipsum|3=}} world&amp;quot;);&lt;br /&gt;
 *  console.log(templates[0]); // --&amp;gt; object&lt;br /&gt;
	{&lt;br /&gt;
		name: &amp;quot;foo&amp;quot;,&lt;br /&gt;
		wikitext:&amp;quot;{{foo |Bar|baz=qux | 2 = loremipsum  |3=}}&amp;quot;,&lt;br /&gt;
		parameters: [&lt;br /&gt;
			{&lt;br /&gt;
				name: 1,&lt;br /&gt;
				value: &amp;#039;Bar&amp;#039;,&lt;br /&gt;
				wikitext: &amp;#039;|Bar&amp;#039;&lt;br /&gt;
			},&lt;br /&gt;
			{&lt;br /&gt;
				name: &amp;#039;baz&amp;#039;,&lt;br /&gt;
				value: &amp;#039;qux&amp;#039;,&lt;br /&gt;
				wikitext: &amp;#039;|baz=qux &amp;#039;&lt;br /&gt;
			},&lt;br /&gt;
			{&lt;br /&gt;
				name: &amp;#039;2&amp;#039;,&lt;br /&gt;
				value: &amp;#039;loremipsum&amp;#039;,&lt;br /&gt;
				wikitext: &amp;#039;| 2 = loremipsum  &amp;#039;&lt;br /&gt;
			},&lt;br /&gt;
			{&lt;br /&gt;
				name: &amp;#039;3&amp;#039;,&lt;br /&gt;
				value: &amp;#039;&amp;#039;,&lt;br /&gt;
				wikitext: &amp;#039;|3=&amp;#039;&lt;br /&gt;
			}&lt;br /&gt;
		],&lt;br /&gt;
		getParam: function(paramName) {&lt;br /&gt;
			return this.parameters.find(function(p) { return p.name == paramName; });&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
 *    &lt;br /&gt;
 * &lt;br /&gt;
 * @param {String} wikitext&lt;br /&gt;
 * @param {Boolean} recursive Set to `true` to also parse templates that occur within other templates,&lt;br /&gt;
 *  rather than just top-level templates. &lt;br /&gt;
 * @return object[]&lt;br /&gt;
*/&lt;br /&gt;
extraJs.parseTemplates = function(wikitext, recursive) {&lt;br /&gt;
	&lt;br /&gt;
 	var strReplaceAt = function(string, index, char) {&lt;br /&gt;
		return string.slice(0,index) + char + string.slice(index + 1);&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
	var result = [];&lt;br /&gt;
	&lt;br /&gt;
	var processTemplateText = function (startIdx, endIdx) {&lt;br /&gt;
		var text = wikitext.slice(startIdx, endIdx);&lt;br /&gt;
&lt;br /&gt;
		var template = new extraJs.Template(&amp;#039;{{&amp;#039; + text.replace(/\1/g,&amp;#039;|&amp;#039;) + &amp;#039;}}&amp;#039;);&lt;br /&gt;
		&lt;br /&gt;
		// swap out pipe in links with \1 control character&lt;br /&gt;
		// [[File: ]] can have multiple pipes, so might need multiple passes&lt;br /&gt;
		while ( /(\[\[[^\]]*?)\|(.*?\]\])/g.test(text) ) {&lt;br /&gt;
			text = text.replace(/(\[\[[^\]]*?)\|(.*?\]\])/g, &amp;#039;$1\1$2&amp;#039;);&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		var chunks = text.split(&amp;#039;|&amp;#039;).map(function(chunk) {&lt;br /&gt;
			// change &amp;#039;\1&amp;#039; control characters back to pipes&lt;br /&gt;
			return chunk.replace(/\1/g,&amp;#039;|&amp;#039;); &lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
		template.setName(chunks[0]);&lt;br /&gt;
		&lt;br /&gt;
		var parameterChunks = chunks.slice(1);&lt;br /&gt;
&lt;br /&gt;
		var unnamedIdx = 1;&lt;br /&gt;
		parameterChunks.forEach(function(chunk) {&lt;br /&gt;
			var indexOfEqualTo = chunk.indexOf(&amp;#039;=&amp;#039;);&lt;br /&gt;
			var indexOfOpenBraces = chunk.indexOf(&amp;#039;{{&amp;#039;);&lt;br /&gt;
			&lt;br /&gt;
			var isWithoutEquals = !chunk.includes(&amp;#039;=&amp;#039;);&lt;br /&gt;
			var hasBracesBeforeEquals = chunk.includes(&amp;#039;{{&amp;#039;) &amp;amp;&amp;amp; indexOfOpenBraces &amp;lt; indexOfEqualTo;	&lt;br /&gt;
			var isUnnamedParam = ( isWithoutEquals || hasBracesBeforeEquals );&lt;br /&gt;
			&lt;br /&gt;
			var pName, pNum, pVal;&lt;br /&gt;
			if ( isUnnamedParam ) {&lt;br /&gt;
				// Get the next number not already used by either an unnamed parameter, or by a&lt;br /&gt;
				// named parameter like `|1=val`&lt;br /&gt;
				while ( template.getParam(unnamedIdx) ) {&lt;br /&gt;
					unnamedIdx++;&lt;br /&gt;
				}&lt;br /&gt;
				pNum = unnamedIdx;&lt;br /&gt;
				pVal = chunk.trim();&lt;br /&gt;
			} else {&lt;br /&gt;
				pName = chunk.slice(0, indexOfEqualTo).trim();&lt;br /&gt;
				pVal = chunk.slice(indexOfEqualTo + 1).trim();&lt;br /&gt;
			}&lt;br /&gt;
			template.addParam(pName || pNum, pVal, chunk);&lt;br /&gt;
		});&lt;br /&gt;
		&lt;br /&gt;
		result.push(template);&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	var n = wikitext.length;&lt;br /&gt;
	&lt;br /&gt;
	// number of unclosed braces&lt;br /&gt;
	var numUnclosed = 0;&lt;br /&gt;
&lt;br /&gt;
	// are we inside a comment, or between nowiki tags, or in a {{{parameter}}}?&lt;br /&gt;
	var inComment = false;&lt;br /&gt;
	var inNowiki = false;&lt;br /&gt;
	var inParameter = false;&lt;br /&gt;
&lt;br /&gt;
	var startIdx, endIdx;&lt;br /&gt;
	&lt;br /&gt;
	for (var i=0; i&amp;lt;n; i++) {&lt;br /&gt;
		&lt;br /&gt;
		if ( !inComment &amp;amp;&amp;amp; !inNowiki &amp;amp;&amp;amp; !inParameter ) {&lt;br /&gt;
			&lt;br /&gt;
			if (wikitext[i] === &amp;#039;{&amp;#039; &amp;amp;&amp;amp; wikitext[i+1] === &amp;#039;{&amp;#039; &amp;amp;&amp;amp; wikitext[i+2] === &amp;#039;{&amp;#039; &amp;amp;&amp;amp; wikitext[i+3] !== &amp;#039;{&amp;#039;) {&lt;br /&gt;
				inParameter = true;&lt;br /&gt;
				i += 2;&lt;br /&gt;
			} else if (wikitext[i] === &amp;#039;{&amp;#039; &amp;amp;&amp;amp; wikitext[i+1] === &amp;#039;{&amp;#039;) {&lt;br /&gt;
				if (numUnclosed === 0) {&lt;br /&gt;
					startIdx = i+2;&lt;br /&gt;
				}&lt;br /&gt;
				numUnclosed += 2;&lt;br /&gt;
				i++;&lt;br /&gt;
			} else if (wikitext[i] === &amp;#039;}&amp;#039; &amp;amp;&amp;amp; wikitext[i+1] === &amp;#039;}&amp;#039;) {&lt;br /&gt;
				if (numUnclosed === 2) {&lt;br /&gt;
					endIdx = i;&lt;br /&gt;
					processTemplateText(startIdx, endIdx);&lt;br /&gt;
				}&lt;br /&gt;
				numUnclosed -= 2;&lt;br /&gt;
				i++;&lt;br /&gt;
			} else if (wikitext[i] === &amp;#039;|&amp;#039; &amp;amp;&amp;amp; numUnclosed &amp;gt; 2) {&lt;br /&gt;
				// swap out pipes in nested templates with \1 character&lt;br /&gt;
				wikitext = strReplaceAt(wikitext, i,&amp;#039;\1&amp;#039;);&lt;br /&gt;
			} else if ( /^&amp;lt;!--/.test(wikitext.slice(i, i + 4)) ) {&lt;br /&gt;
				inComment = true;&lt;br /&gt;
				i += 3;&lt;br /&gt;
			} else if ( /^&amp;lt;nowiki ?&amp;gt;/.test(wikitext.slice(i, i + 9)) ) {&lt;br /&gt;
				inNowiki = true;&lt;br /&gt;
				i += 7;&lt;br /&gt;
			} &lt;br /&gt;
&lt;br /&gt;
		} else { // we are in a comment or nowiki or {{{parameter}}}&lt;br /&gt;
			if (wikitext[i] === &amp;#039;|&amp;#039;) {&lt;br /&gt;
				// swap out pipes with \1 character&lt;br /&gt;
				wikitext = strReplaceAt(wikitext, i,&amp;#039;\1&amp;#039;);&lt;br /&gt;
			} else if (/^--&amp;gt;/.test(wikitext.slice(i, i + 3))) {&lt;br /&gt;
				inComment = false;&lt;br /&gt;
				i += 2;&lt;br /&gt;
			} else if (/^&amp;lt;\/nowiki ?&amp;gt;/.test(wikitext.slice(i, i + 10))) {&lt;br /&gt;
				inNowiki = false;&lt;br /&gt;
				i += 8;&lt;br /&gt;
			} else if (wikitext[i] === &amp;#039;}&amp;#039; &amp;amp;&amp;amp; wikitext[i+1] === &amp;#039;}&amp;#039; &amp;amp;&amp;amp; wikitext[i+2] === &amp;#039;}&amp;#039;) {&lt;br /&gt;
				inParameter = false;&lt;br /&gt;
				i += 2;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	if ( recursive ) {&lt;br /&gt;
		var subtemplates = result.map(function(template) {&lt;br /&gt;
			return template.wikitext.slice(2,-2);&lt;br /&gt;
		})&lt;br /&gt;
		.filter(function(templateWikitext) {&lt;br /&gt;
			return /\{\{(?:.|\n)*\}\}/.test(templateWikitext);&lt;br /&gt;
		})&lt;br /&gt;
		.map(function(templateWikitext) {&lt;br /&gt;
			return extraJs.parseTemplates(templateWikitext, true);&lt;br /&gt;
		});&lt;br /&gt;
		&lt;br /&gt;
		return result.concat.apply(result, subtemplates);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	return result;&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
/**&lt;br /&gt;
 * toSentenceCase&lt;br /&gt;
 *&lt;br /&gt;
 * Capitalises the first letter of a string.&lt;br /&gt;
 *&lt;br /&gt;
 * @param {String} input&lt;br /&gt;
 *  The string to be transformed.&lt;br /&gt;
 * @param {Boolean} lc&lt;br /&gt;
 *  Transform the characters following the first character to lowercase&lt;br /&gt;
 * @returns {String} Transformed string.&lt;br /&gt;
 */&lt;br /&gt;
extraJs.toSentenceCase = function(input, lc) {&lt;br /&gt;
	return input.slice(0,1).toUpperCase() +&lt;br /&gt;
		(( lc ) ? input.slice(1).toLowerCase() : input.slice(1));&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * uniqueArray&lt;br /&gt;
 *&lt;br /&gt;
 * Filters out possible duplicate values from an array of strings.&lt;br /&gt;
 *&lt;br /&gt;
 * @param {String[]} a Array to be filtered.&lt;br /&gt;
 * @return {String[]} Filtered array.&lt;br /&gt;
 */&lt;br /&gt;
extraJs.uniqueArray = function(a) {&lt;br /&gt;
	var table = {};&lt;br /&gt;
	a.forEach(function(e) {&lt;br /&gt;
		table[e] = true;&lt;br /&gt;
	});&lt;br /&gt;
	return Object.keys(table);&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * unlink&lt;br /&gt;
 *&lt;br /&gt;
 * Function to unlink and/or remove links and file usages from a block of wikitext.&lt;br /&gt;
 * Derived from XFDcloser &amp;lt; https://en.wikipedia.org/wiki/User:Evad37/XFDcloser.js &amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
 * @requires {Module} mediawiki.util, User:SD0001/parseTemplate.js&lt;br /&gt;
 * @param {string} wikitext&lt;br /&gt;
 *  Wikitext in which to search for links or file usages.&lt;br /&gt;
 * @param {string[]} unlinkThese&lt;br /&gt;
 *  Array of page titles to be unlinked.&lt;br /&gt;
 * @param {number} ns&lt;br /&gt;
 *  Number of the namespace which the wikitext is in.&lt;br /&gt;
 * @param {boolean} isDab&lt;br /&gt;
 *  Wikitext is of a disambiguation page.&lt;br /&gt;
 * @return {string} Updated wikitext. If no links or file usages were found, this will be&lt;br /&gt;
 *  the same as the input wikitext.&lt;br /&gt;
 */&lt;br /&gt;
extraJs.unlink = function(wikitext, unlinkThese, ns, isDab) {&lt;br /&gt;
	// Remove image/file usages, if any titles are files&lt;br /&gt;
	var unlinkFiles = unlinkThese.filter(function(t){ return /^File:/i.test(t); });&lt;br /&gt;
	if ( unlinkFiles.length &amp;gt; 0 ) {&lt;br /&gt;
		// Start building regex strings&lt;br /&gt;
		var normal_regex_str = &amp;quot;(&amp;quot;;&lt;br /&gt;
		var gallery_regex_str = &amp;quot;(&amp;quot;;&lt;br /&gt;
		var free_regex_str = &amp;quot;(&amp;quot;;&lt;br /&gt;
		var filename, filename_regex_str;&lt;br /&gt;
		for ( var i=0; i&amp;lt;unlinkFiles.length; i++ ) {&lt;br /&gt;
			// Take off namespace prefix&lt;br /&gt;
			filename = unlinkFiles[i].replace(/^.*?:/, &amp;quot;&amp;quot;);&lt;br /&gt;
			// For regex matching: first character can be either upper or lower case, special&lt;br /&gt;
			// characters need to be escaped, spaces/underscores can be either spaces or underscores&lt;br /&gt;
			filename_regex_str = &amp;quot;[&amp;quot; + mw.util.escapeRegExp(filename.slice(0, 1).toUpperCase()) +&lt;br /&gt;
			mw.util.escapeRegExp(filename.slice(0, 1).toLowerCase()) + &amp;quot;]&amp;quot; +&lt;br /&gt;
			mw.util.escapeRegExp(filename.slice(1)).replace(/(?: |_)/g, &amp;quot;[ _]&amp;quot;);&lt;br /&gt;
			// Add to regex strings&lt;br /&gt;
			normal_regex_str += &amp;quot;\\[\\[\\s*(?:[Ii]mage|[Ff]ile)\\s*:\\s*&amp;quot; + filename_regex_str +&lt;br /&gt;
			&amp;quot;\\s*\\|?.*?(?:(?:\\[\\[.*?\\]\\]).*?)*\\]\\]&amp;quot;;&lt;br /&gt;
			gallery_regex_str += &amp;quot;^\\s*(?:[Ii]mage|[Ff]ile):\\s*&amp;quot; + filename_regex_str + &amp;quot;.*?$&amp;quot;;&lt;br /&gt;
			free_regex_str += &amp;quot;\\|\\s*(?:[\\w\\s]+\\=)?\\s*(?:(?:[Ii]mage|[Ff]ile):\\s*)?&amp;quot; +&lt;br /&gt;
			filename_regex_str;&lt;br /&gt;
			&lt;br /&gt;
			if ( i+1 !== unlinkFiles.length ) {&lt;br /&gt;
				normal_regex_str += &amp;quot;|&amp;quot;;&lt;br /&gt;
				gallery_regex_str += &amp;quot;|&amp;quot;;&lt;br /&gt;
				free_regex_str += &amp;quot;|&amp;quot;;				&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		// Close off regex strings&lt;br /&gt;
		normal_regex_str += &amp;quot;)(?![^&amp;lt;]*?--&amp;gt;)&amp;quot;;&lt;br /&gt;
		gallery_regex_str += &amp;quot;)(?![^&amp;lt;]*?--&amp;gt;)&amp;quot;;&lt;br /&gt;
		free_regex_str += &amp;quot;)(?![^&amp;lt;]*?--&amp;gt;)&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
		// Check for normal file usage, i.e. [[File:Foobar.png|...]]&lt;br /&gt;
		var normal_regex = new RegExp( normal_regex_str, &amp;quot;g&amp;quot;);&lt;br /&gt;
		wikitext = wikitext.replace(normal_regex, &amp;quot;&amp;quot;);&lt;br /&gt;
		&lt;br /&gt;
		// Check for gallery usage, i.e. instances that must start on a new line, eventually&lt;br /&gt;
		// preceded with some space, and must include File: or Image: prefix&lt;br /&gt;
		var gallery_regex = new RegExp( gallery_regex_str, &amp;quot;mg&amp;quot; );&lt;br /&gt;
		wikitext = wikitext.replace(gallery_regex, &amp;quot;&amp;quot;);&lt;br /&gt;
		&lt;br /&gt;
		// Check for free usages, for example as template argument, might have the File: or Image:&lt;br /&gt;
		// prefix excluded, but must be preceeded by an |&lt;br /&gt;
		var free_regex = new RegExp( free_regex_str, &amp;quot;mg&amp;quot; );&lt;br /&gt;
		wikitext = wikitext.replace(free_regex, &amp;quot;&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	// Remove portal links/templates, if there are any	&lt;br /&gt;
	var unlinkPortals = unlinkThese.filter(function(t){ return /^Portal:/i.test(t); });&lt;br /&gt;
	if ( unlinkPortals.length &amp;gt; 0 ) {&lt;br /&gt;
		// Build regex string&lt;br /&gt;
		var portal_regex_str = &amp;quot;(&amp;quot; +&lt;br /&gt;
			unlinkPortals.map(function(portal) {&lt;br /&gt;
				// Take off namespace prefix&lt;br /&gt;
				var portalname = portal.replace(&amp;quot;Portal:&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
				// For regex matching: first character can be either upper or lower case, special&lt;br /&gt;
				// characters need to be escaped, spaces/underscores can be either spaces or underscores&lt;br /&gt;
				return &amp;quot;[&amp;quot; + mw.util.escapeRegExp(portalname.slice(0, 1).toUpperCase()) +&lt;br /&gt;
					mw.util.escapeRegExp(portalname.slice(0, 1).toLowerCase()) + &amp;quot;]&amp;quot; +&lt;br /&gt;
					mw.util.escapeRegExp(portalname.slice(1)).replace(/(?: |_)/g, &amp;quot;[ _]&amp;quot;);&lt;br /&gt;
			}).join(&amp;#039;|&amp;#039;) +&lt;br /&gt;
			&amp;quot;)(?![^&amp;lt;]*?--&amp;gt;)&amp;quot;; // Close off regex string&lt;br /&gt;
		var portal_regex = new RegExp(portal_regex_str);&lt;br /&gt;
&lt;br /&gt;
		// Find templates to remove parameters from, or remove entirely&lt;br /&gt;
		var templatesInWikitext = extraJs.parseTemplates(wikitext, true);&lt;br /&gt;
		&lt;br /&gt;
		// templates using numbered/unnamed parameters, e.g.{{Portal|Foo|Bar}}&lt;br /&gt;
		var numberedParameterTemplates = [&lt;br /&gt;
			// {{Portal}} and its redirects:&lt;br /&gt;
			&amp;#039;portal&amp;#039;, &amp;#039;portalpar&amp;#039;, &amp;#039;portal box&amp;#039;, &amp;#039;ports&amp;#039;, &amp;#039;portal-2&amp;#039;,&lt;br /&gt;
			// {{Portal-inline}} and its redirects:&lt;br /&gt;
			&amp;#039;portal-inline&amp;#039;, &amp;#039;portal inline&amp;#039;, &amp;#039;portal frameless&amp;#039;, &amp;#039;portal-inline-template&amp;#039;,&lt;br /&gt;
			// {{Portal bar}} and its redirects:&lt;br /&gt;
			&amp;#039;portal bar&amp;#039;, &amp;#039;portalbar&amp;#039;&lt;br /&gt;
		];&lt;br /&gt;
		// templates using named parameters, e.g. {{Subject bar |portal=Foo |portal2=Bar}}&lt;br /&gt;
		var namedParameterTemplates = [&amp;#039;subject bar&amp;#039;];&lt;br /&gt;
		&lt;br /&gt;
		// helper functions for filtering/mapping&lt;br /&gt;
		var isNumberedParameter = function(param) {&lt;br /&gt;
			return !isNaN(Number(param.name));&lt;br /&gt;
		};&lt;br /&gt;
		var isNamedPortalParameter = function(param) {&lt;br /&gt;
			return /portal\d*/.test(param.name);&lt;br /&gt;
		};&lt;br /&gt;
&lt;br /&gt;
		/**&lt;br /&gt;
		 * @param {TemplateObject[]} existingTemplates Subset of TemplateObjects from extraJs.parseTemplates&lt;br /&gt;
		 * @param {Function(ParamObject)=&amp;gt;boolean} paramTypeFilter Function that returns `true` if&lt;br /&gt;
		 *  the passed in parameter might contain a portal, and `false` otherwise&lt;br /&gt;
		 * @param {Function(ParamObject[])=&amp;gt;boolean} keepFilter Function that returns `true` if the&lt;br /&gt;
		 *  template should be kept (and edited), or `false` if the template should just be removed&lt;br /&gt;
		 * @sideEffect modifies variable `wikitext`&lt;br /&gt;
		 */&lt;br /&gt;
		var editOrRemoveTemplates = function( existingTemplates, paramTypeFilter, keepFilter ) {&lt;br /&gt;
			existingTemplates.forEach(function(template) {&lt;br /&gt;
				var paramsToKeep = template.parameters.filter(function(param) {&lt;br /&gt;
					return !paramTypeFilter(param) || !portal_regex.test(param.value);&lt;br /&gt;
				});&lt;br /&gt;
				if ( paramsToKeep.length === template.parameters.length ) {&lt;br /&gt;
					// No changes needed&lt;br /&gt;
					return;&lt;br /&gt;
				}				&lt;br /&gt;
				if ( keepFilter(paramsToKeep) ) {&lt;br /&gt;
					var updatedTemplateWikitext = template.wikitext.replace(/\|(.|\n)*/, &amp;#039;&amp;#039;) +&lt;br /&gt;
						paramsToKeep.map(function(p) { return p.wikitext; }).join(&amp;#039;&amp;#039;) +&lt;br /&gt;
						&amp;#039;}}&amp;#039;;&lt;br /&gt;
					wikitext = wikitext.replace(template.wikitext, updatedTemplateWikitext);&lt;br /&gt;
				} else {&lt;br /&gt;
					// Remove template wikitext, including any preceding * or : characters:&lt;br /&gt;
					// - if on it&amp;#039;s own line, remove a linebreak&lt;br /&gt;
					wikitext = wikitext.replace(&lt;br /&gt;
						new RegExp(&amp;#039;\\n[\\*\\:]*[\\t ]*&amp;#039; + mw.util.escapeRegExp(template.wikitext) + &amp;#039;\\n&amp;#039;),&lt;br /&gt;
						&amp;#039;\n&amp;#039;&lt;br /&gt;
					)&lt;br /&gt;
					// - if something else is on the line, leave the linebreaks alone&lt;br /&gt;
					.replace(&lt;br /&gt;
						new RegExp(&amp;#039;[\\*\\:]*[\\t ]*&amp;#039; + mw.util.escapeRegExp(template.wikitext)),&lt;br /&gt;
						&amp;#039;&amp;#039;&lt;br /&gt;
					);&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
		};&lt;br /&gt;
&lt;br /&gt;
		// Deal with numbered-parameter templates&lt;br /&gt;
		editOrRemoveTemplates(&lt;br /&gt;
			templatesInWikitext.filter(function(template) {&lt;br /&gt;
				var name = template.name.toLowerCase().replace(/_/g, &amp;#039; &amp;#039;);&lt;br /&gt;
				return numberedParameterTemplates.includes(name);&lt;br /&gt;
			}),&lt;br /&gt;
			isNumberedParameter,&lt;br /&gt;
			function(params) { return params.some(isNumberedParameter); }&lt;br /&gt;
		);&lt;br /&gt;
		&lt;br /&gt;
		// Deal with named parameter templates&lt;br /&gt;
		editOrRemoveTemplates(&lt;br /&gt;
			templatesInWikitext.filter(function(template) {&lt;br /&gt;
				var name = template.name.toLowerCase().replace(/_/g, &amp;#039; &amp;#039;);&lt;br /&gt;
				return namedParameterTemplates.includes(name);&lt;br /&gt;
			}),&lt;br /&gt;
			isNamedPortalParameter,&lt;br /&gt;
			function(params) { return params.length &amp;gt; 0; }&lt;br /&gt;
		);&lt;br /&gt;
		&lt;br /&gt;
		// Remove any &amp;quot;See also&amp;quot; sections that are now empty&lt;br /&gt;
		var seeAlsoSection = /(==+)\s*[Ss]ee [Aa]lso\s*==+([.\n]*?)(?:(==+)|$)/g.exec(wikitext);&lt;br /&gt;
		if ( seeAlsoSection ) {&lt;br /&gt;
			var hasSubsection = seeAlsoSection[1] &amp;amp;&amp;amp; seeAlsoSection[3] &amp;amp;&amp;amp; seeAlsoSection[3].length &amp;gt; seeAlsoSection[1].length;&lt;br /&gt;
			var isEmpty = seeAlsoSection[2].trim() === &amp;#039;&amp;#039;;&lt;br /&gt;
			if ( isEmpty &amp;amp;&amp;amp; !hasSubsection ) {&lt;br /&gt;
				wikitext = wikitext.replace(seeAlsoSection[0], seeAlsoSection[3]);&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	// Remove links&lt;br /&gt;
	// Start building regex strings&lt;br /&gt;
	var simple_regex_str = &amp;quot;\\[\\[\\s*:?\\s*(&amp;quot;;&lt;br /&gt;
	var named_regex_str = &amp;quot;\\[\\[\\s*:?\\s*(?:&amp;quot;;&lt;br /&gt;
	for ( var ii=0; ii&amp;lt;unlinkThese.length; ii++ ) {&lt;br /&gt;
		// For regex matching: first character can be either upper or lower case, special&lt;br /&gt;
		// characters need to be escaped, spaces/underscores can be either spaces or underscores&lt;br /&gt;
		var unlink_regex_str = &amp;quot;[&amp;quot; + mw.util.escapeRegExp(unlinkThese[ii].slice(0, 1).toUpperCase()) +&lt;br /&gt;
			mw.util.escapeRegExp(unlinkThese[ii].slice(0, 1).toLowerCase()) + &amp;quot;]&amp;quot; +&lt;br /&gt;
			mw.util.escapeRegExp(unlinkThese[ii].slice(1)).replace(/(?: |_)/g, &amp;quot;[ _]&amp;quot;);&lt;br /&gt;
		// Add to regex strings&lt;br /&gt;
		simple_regex_str += unlink_regex_str;&lt;br /&gt;
		named_regex_str += unlink_regex_str;&lt;br /&gt;
		if ( ii+1 !== unlinkThese.length ) {&lt;br /&gt;
			simple_regex_str += &amp;quot;|&amp;quot;;&lt;br /&gt;
			named_regex_str += &amp;quot;|&amp;quot;;			&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	// Close off regex strings&lt;br /&gt;
	simple_regex_str += &amp;quot;)(?:#[^\\|\\]]*?)?\\s*\\]\\](?![^&amp;lt;]*?--&amp;gt;)&amp;quot;;&lt;br /&gt;
	named_regex_str += &amp;quot;)(?:#[^\\|\\]]*?)?\\s*\\|([^\\[\\]\\n\\r]+?)\\]\\](?![^&amp;lt;]*?--&amp;gt;)&amp;quot;;&lt;br /&gt;
	var simple_regex = new RegExp( simple_regex_str, &amp;quot;g&amp;quot; );&lt;br /&gt;
	var named_regex = new RegExp( named_regex_str, &amp;quot;g&amp;quot; );&lt;br /&gt;
	&lt;br /&gt;
	// Set index articles for names, which should be treated like disambiguation pages, will contain&lt;br /&gt;
	// one of these templates&lt;br /&gt;
	var name_set_index_regex = /\{\{\s*(?:[Gg]iven[ _]name|[Ss]urnames?|[Nn]ickname|[Ff]irst[ _]name|[Ff]orename|[Dd]isambigN(?:ame|m)?)\s*(?:\|.*?)*?\}\}/g;&lt;br /&gt;
	if ( name_set_index_regex.test(wikitext) ) {&lt;br /&gt;
		isDab = true;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	// List items removals:&lt;br /&gt;
	if ( ns === 10 ) {&lt;br /&gt;
		//Within navbox templates, remove links entirely, including the preceding *&amp;#039;s and the following newline&lt;br /&gt;
		var navbox_regex = new RegExp(&amp;quot;\\{\\{[Nn]avbox(?: with collapsible groups| with columns)?\\s*\\|&amp;quot; +&lt;br /&gt;
			&amp;quot;(?:.|\\n)*?(?:(?:\\{\\{&amp;quot; +			// accounts for templates within the navbox&lt;br /&gt;
				&amp;quot;(?:.|\\n)*?(?:(?:\\{\\{&amp;quot; +		// accounts for templates within templates within the navbox&lt;br /&gt;
					&amp;quot;(?:.|\\n)*?&amp;quot; +&lt;br /&gt;
				&amp;quot;\\}\\})(?:.|\\n)*?)*?&amp;quot; +&lt;br /&gt;
			&amp;quot;\\}\\})(?:.|\\n)*?)*&amp;quot; +&lt;br /&gt;
		&amp;quot;\\}\\}&amp;quot;, &amp;quot;g&amp;quot;);&lt;br /&gt;
		var navbox_simple_regex = new RegExp( &amp;quot;\\*+\\s*&amp;quot; + simple_regex_str + &amp;quot;[\\r\\t\\f\\v ]*\\n&amp;quot;, &amp;quot;g&amp;quot; );&lt;br /&gt;
		var navbox_named_regex = new RegExp( &amp;quot;\\*+\\s*&amp;quot; + named_regex_str + &amp;quot;[\\r\\t\\f\\v ]*\\n&amp;quot;, &amp;quot;g&amp;quot; );&lt;br /&gt;
		//Find navbox templates&lt;br /&gt;
		var navboxes = wikitext.match(navbox_regex);&lt;br /&gt;
		if ( navboxes ) {&lt;br /&gt;
			// remove regex matches from wikitext&lt;br /&gt;
			var replacement;&lt;br /&gt;
			for ( var jj=0; jj&amp;lt;navboxes.length; jj++ ) {&lt;br /&gt;
				replacement = navboxes[jj].replace(navbox_simple_regex, &amp;quot;&amp;quot;).replace(navbox_named_regex, &amp;quot;&amp;quot;);&lt;br /&gt;
				wikitext = wikitext.replace(navboxes[jj], replacement);&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	} else if ( isDab ) {&lt;br /&gt;
		// For disambiguation pages, entirely remove list items containing a backlink, including the&lt;br /&gt;
		// preceding *&amp;#039;s and the following newline (but skiping list items with multiple links)&lt;br /&gt;
		var dab_simple_regex = new RegExp( &amp;quot;\\*+[^\\[\\]\\n\\r]*&amp;quot; + simple_regex_str + &amp;quot;[^\\[\\]\\n\\r]*\\n&amp;quot;, &amp;quot;g&amp;quot; );&lt;br /&gt;
		var dab_named_regex = new RegExp( &amp;quot;\\*+[^\\[\\]\\n\\r]*&amp;quot; + named_regex_str + &amp;quot;[^\\[\\]\\n\\r]*\\n&amp;quot;, &amp;quot;g&amp;quot; );	&lt;br /&gt;
		wikitext = wikitext.replace(dab_simple_regex, &amp;quot;&amp;quot;).replace(dab_named_regex, &amp;quot;&amp;quot;);&lt;br /&gt;
	} else {&lt;br /&gt;
		// For See also sections, entirely remove list items containing a backlink, including the&lt;br /&gt;
		// preceding *&amp;#039;s and the following newline (but skiping list items with multiple links)&lt;br /&gt;
		var seealso_regex = /==+\s*[Ss]ee [Aa]lso\s*==+\n+(?:^.*\n*)*?(?:(?===+)|$)/gm;&lt;br /&gt;
		var seealso_simple_regex = new RegExp( &amp;quot;\\*+[^\\[\\]\\n\\r]*&amp;quot; + simple_regex_str + &amp;quot;[^\\[\\]\\n\\r]*\\n&amp;quot;, &amp;quot;g&amp;quot; );&lt;br /&gt;
		var seealso_named_regex = new RegExp( &amp;quot;\\*+[^\\[\\]\\n\\r]*&amp;quot; + named_regex_str + &amp;quot;[^\\[\\]\\n\\r]*\\n&amp;quot;, &amp;quot;g&amp;quot; );&lt;br /&gt;
		var seealso = wikitext.match(seealso_regex);&lt;br /&gt;
		if ( seealso ) {&lt;br /&gt;
			// remove regex matches from wikitext&lt;br /&gt;
			var replacement_seealso;&lt;br /&gt;
			for ( var kk=0; kk&amp;lt;seealso.length; kk++ ) {&lt;br /&gt;
				replacement_seealso = (seealso[kk]+&amp;quot;\n&amp;quot;).replace(seealso_simple_regex, &amp;quot;&amp;quot;).replace(seealso_named_regex, &amp;quot;&amp;quot;);&lt;br /&gt;
				wikitext = wikitext.replace(seealso[kk].trim(), replacement_seealso.trim());&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		// Other lists need manual review, in case the item should be retained unlinked (e.g. complete lists per [[WP:CSC]])&lt;br /&gt;
	}&lt;br /&gt;
	// Mark any other list items with backlinks for manual review, using {{subst:void}}&lt;br /&gt;
	var manual_review_regex = new RegExp(&lt;br /&gt;
		&amp;#039;^(\\*+.*)(&amp;#039; +&lt;br /&gt;
		simple_regex_str.replace(/([^\\])\(([^?])/g, &amp;quot;$1(?:$2&amp;quot;) + // replace capturing groups with non-capturing groups&lt;br /&gt;
		&amp;#039;|&amp;#039; +&lt;br /&gt;
		named_regex_str.replace(/([^\\])\(([^?])/g, &amp;quot;$1(?:$2&amp;quot;) + // replace capturing groups with non-capturing groups&lt;br /&gt;
		&amp;#039;)(.*)$&amp;#039;, &amp;#039;gm&amp;#039; );&lt;br /&gt;
	wikitext = wikitext.replace(manual_review_regex, &amp;#039;{{subst:void}}$1{{subst:^|&amp;lt;strong&amp;gt;}}$2{{subst:^|&amp;lt;/strong&amp;gt;}}$3&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
	// For all other links, replace with unlinked text&lt;br /&gt;
	wikitext = wikitext.replace(simple_regex, &amp;quot;$1&amp;quot;).replace(named_regex, &amp;quot;$1&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	return wikitext;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * val2key&lt;br /&gt;
 *&lt;br /&gt;
 * For an object `obj` with key:value pairs, return a value&amp;#039;s corresponding key.&lt;br /&gt;
 *&lt;br /&gt;
 * @param {string|number} val&lt;br /&gt;
 *  Value to seach for.&lt;br /&gt;
 * @param {object} obj&lt;br /&gt;
 *  Object to search in.&lt;br /&gt;
 * @return {string|number} Key corresponding to the input value.&lt;br /&gt;
 */&lt;br /&gt;
extraJs.val2key = function(val, obj) {&lt;br /&gt;
    for ( var k in obj ) {&lt;br /&gt;
        if ( obj[k] === val ) {&lt;br /&gt;
            return k;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// &amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>en&gt;Pppery</name></author>
	</entry>
</feed>