function concatRegexp(reg, exp) {
  let flags = reg.flags + exp.flags;
  flags = Array.from(new Set(flags.split(''))).join();
  return new RegExp(reg.source + exp.source, 'gi');
}

function editPage( info ) {
	$.ajax({
		url: mw.util.wikiScript( 'api' ),
		type: 'POST',
		dataType: 'json',
		data: {
			format: 'json',
			action: 'edit',
			title: info.title,
			text: info.text,
			bot: true, 
			summary: info.summary,
			token: mw.user.tokens.get( 'csrfToken' )
		}
	})
	.then (function( data ) {
		if ( data && data.edit && data.edit.result && data.edit.result == 'Success' ) {
			//alert( 'Page edited!' );
		} else {
			console.log( 'The edit query returned an error. =(' );
		}
	})
	.catch ( function() {
		console.log( 'The ajax request failed.' );
	});
}

function removeFromListedPage(text) {
  editPage({
	title: "User:Qwerfjkl/UScounties",
	text: text.replace("* [["+title+"]]", ""),
	summary: 'Removed "'+title+'" - fixed'
});
}

function getListPageContentAndRemove() {
(new mw.Api()).get( {
	prop: 'revisions',
	rvprop: 'content',
	rvlimit: 1,
	indexpageids: true,
	titles: "User:Qwerfjkl/UScounties"
} )
.then( function ( data ) {
	var q = data.query,
		id = q && q.pageids && q.pageids[0],
		pg = id && q.pages && q.pages[ id ],
		rv = pg && pg.revisions;
	if ( rv && rv[0] && rv[0]['*'] ) {
		removeFromListedPage( rv[0]['*'] );
	}
} )
.catch( console.log("Error removing: "+title));
}
function sleep(ms) {
    var unixtime_ms = new Date().getTime();
    while(new Date().getTime() < unixtime_ms + ms) {}
}
if (/\{\{Pres(Head|Row|Foot)/i.test(oldText)) {
  getListPageContentAndRemove() // remove from list
  sleep(1000)
  return {text: false} // skip
}

headerRegexp = /\{\| *.+\s*\|\+.+\n\|\-.*\n(?:\|-\n)?\! *(?:scope="col"\|)? *Year\n\! *(?:scope="col"\|)? *(?:''')?\[\[Republican Party \(United States\)\|(?:Republican|GOP)\]\](?:''')?\n\! *(?:scope="col"\|)? *(?:''')?\[\[Democratic Party \(United States\)\|(?:Dem(?:ocrati?c?)?|DEM)\]\](?:''')?(?:\n\! *.+?)?\s*\|\-.*/i

rowRegexp = /\| *(?:style="text\-align:center;")? *\{\{Party shading\/(.+)\}\} *\| *''' *(?:\[\[(?:\d{4} )?United States presidential election(?:(?: in (.+?))?(?:, .+)?)?\|)?(\d{4})(?:\]\])? *'''\s*\| *(?:(?:style="text-align:center;")? *\{\{Party shading\/Republican\}\} *\| *(?:''')? *.+? *(?:''')? ''(.+?)'')?\s*\| *(?:(?:style="text-align:center;")? *\{\{Party shading\/Democratic\}\} *\| *(?:''')? *.+? *(?:''')? *'' *(.+?) *'')?\s*(?:\s*\| *)?(?:style="text\-align:center;(?: background:honeyDew;)?"?)?\|?(?:(?:''')? *.+? *(?:''')? * '' *(.+?) *'' *(.*))?\s*\|/gi

bottomRegexp = /(?:-\s*\| colspan="4" style="text-align:center; colspan= ?" ?4"\s*\|County \[\[CPVI\]\]:.+\n\|)?\}(?:\s*\{\{Hidden end\}\})?/

state= title.replace(/.*?, (.+)/, '$1') // get state

presRegexp = new RegExp('('+ headerRegexp.source+'[\\s\\S]*'+rowRegexp.source+bottomRegexp.source+')', 'i')
// isolate table
presTableText = oldText.match(presRegexp)
if (presTableText === null) {
  console.log(title) // log for checkup later
  return {text: false} // Incorrectly formatted, skip
}
else {
  presTableText = presTableText[1]
}
const refRegexp = /\<ref[^\>]*\>(?:[\s\S]+?\<\/ref\>)?/gi
refs = presTableText.match(refRegexp); // gets refs

newPresTableText = presTableText.replace(refRegexp, '') // remove refs
newPresTableText = presTableText.replace(/\{\{ ?efn ?\|[^\}]+\}\}/gi, '') // remove efn's

reflessPresTable = newPresTableText
var refText = ''

if (refs != null) {
for (var i = 0; i < refs.length; i++) {
refText = refText.concat('|source'+(i+1)+'='+refs[i])
} };

newPresTableText = newPresTableText.replace(concatRegexp(rowRegexp, /\-(?:\n\|\-)?/), function(match, p1, p2, p3, p4, p5, p6) {

if (p2 != undefined) {
return '{{PresRow|'+p3+'|'+p1+'|'+p4+'|'+p5+'|'+p6+'|'+p2+'}}';
}
else {
return '{{PresRow|'+p3+'|'+p1+'|'+p4+'|'+p5+'|'+p6+'|'+state+'}}';
} })

newPresTableText = newPresTableText.replace(concatRegexp(rowRegexp, bottomRegexp), function(match, p1, p2, p3, p4, p5, p6) {
if (parseInt(p3) <= 1856) { // Whig parameter?
window.Whig = 'yes'
} else {
window.Whig = 'no'
}

if (p2 != undefined) {
return '{{PresFoot|'+p3+'|'+p1+'|'+p4+'|'+p5+'|'+p6+'|'+p2+'}}';
}
else {
return '{{PresFoot|'+p3+'|'+p1+'|'+p4+'|'+p5+'|'+p6+'|'+state+'}}';
} }) // handle end

newPresTableText = newPresTableText.replace(headerRegexp, `{{PresHead|place=`+title+`|whig=`+window.Whig+refText+`}}
<!-- PresRow should be {{PresRow|Year|Winning party|GOP/Whig vote #|Dem vote #|3rd party vote #|State}} -->`)

newPresTableText = newPresTableText.replace(/\{\{Pres((?:Row|Foot)\|[^\}]*?)\|undefined\|([^}]*\}\})/gi, '{{Pres$1|0|$2') // Fix empty 3/4/5 parameter error - set to 0
oldText = oldText.replace(presTableText, newPresTableText)
if (newPresTableText.match(/\{\{PresHead[\s\S]+?\}\}\n\<!-- PresRow should be \{\{PresRow\|Year\|Winning party\|GOP\/Whig vote #\|Dem vote #\|3rd party vote #\|State\}\} --\>(\s+\{\{PresRow[^\}]+\}\})+\s+\{\{PresFoot[^\}]+\}\}/i) === null) { // sanity check
  console.log(title) // log for checkup later
  return {text: false} // Incorrectly formatted, skip
}

oldText = oldText.replace(/\{\{Hidden begin\s*(?:\|\s*titlestyle *= *background:#ccccff;?\s*\|\s*title *= *Presidential elections? results?\s*)?\}\}\s*\{\{PresHead/gi, '{{PresHead') // Fix error
if (reflessPresTable == newPresTableText) { // only refs stripped
  return {text: false}
}
getListPageContentAndRemove() // remove from list
return {text: oldText, summary: "Template-ify United States election table"};