MediaWiki:Gadget-wikEd.js

// // JSHint options /* jshint -W004, -W100, newcap: false, browser: true, jquery: true, sub: true, bitwise: true, curly: true, evil: true, forin: true, freeze: true, globalstrict: true, immed: true, latedef: true, loopfunc: true, quotmark: single, strict: true, undef: true */ /* global GM_getValue, GM_setValue, GM_xmlhttpRequest, console */

// turn on ECMAScript 5 strict mode 'use strict';

// define global object var wikEd; if (wikEd === undefined) { wikEd = {}; }

wikEd.Meta = function {/* // ==UserScript== // @name       wikEd // @version    0.9.148 // @date       March 20, 2017 // @namespace  https://en.wikipedia.org/wiki/User:Cacycle/ // @description A full-featured in-browser editor for Wikipedia and other MediaWikis // @include    * // @homepage   https://en.wikipedia.org/wiki/User:Cacycle/wikEd // @source     https://en.wikipedia.org/wiki/User:Cacycle/wikEd.js // @author      Cacycle (https://en.wikipedia.org/wiki/User:Cacycle) // @license    Released into the public domain // @grant      GM_getValue // @grant      GM_xmlhttpRequest // ==/UserScript==

wikEd is a full-featured edit page text editor for regular to advanced users on Wikipedia and other MediaWikis. wikEd features syntax highlighting, reference, template, and code folding, on-page Show preview and Show changes, and advanced search and replace functions. wikEd works under all web browsers except Internet Explorer. This code has to be saved as UTF-8 in your editor to preserve Unicode characters like ♥ (heart symbol).


 * /};

// define global objects var wikEdConfig; var wikEdText; var WED; var WikEdDiff;

// // start of user configurable variables //

// // wikEd.InitGlobalsConfigs: initialize user configurable variables //

wikEd.InitGlobalConfigs = function {

// user readable texts, copy changes to https://en.wikipedia.org/wiki/User:Cacycle/wikEd_international_en.js, also defined in wikEdDiff.js	if (wikEd.config.text === undefined) { wikEd.config.text = {}; }

// wikEd.InitText: define built-in user interface texts wikEd.InitText = function { wikEd.InitObject(wikEd.config.text, {

// logo 'wikEdLogo alt':              'wikEd', 'wikEdLogo title':            'wikEd {wikEdProgramVersion} ({wikEdProgramDate}) Click to disable', 'wikEdLogo error alt':        'wikEd error', 'wikEdLogo error title':      'Loading error - wikEd {wikEdProgramVersion} ({wikEdProgramDate}) Click to disable', 'wikEdLogo browser alt':      '(wikEd)', 'wikEdLogo browser title':    'Browser not supported - wikEd {wikEdProgramVersion} ({wikEdProgramDate})', 'wikEdLogo incompatible alt': '(wikEd)', 'wikEdLogo incompatible title': 'Incompatible script, gadget, or add-on: {wikEdParameter} - wikEd {wikEdProgramVersion} ({wikEdProgramDate})', 'wikEdLogo disabled alt':     '(wikEd)', 'wikEdLogo disabled title':   'Disabled - wikEd {wikEdProgramVersion} ({wikEdProgramDate}) Click to enable', 'wikEdLogo testVersion alt':  'wikEd_dev', 'wikEdLogo testVersion title': 'wikEd_dev (unstable test version) {wikEdProgramVersion} ({wikEdProgramDate}) Click to disable',

// top jumper 'wikEdScrollToEdit4 alt':     'Scroll to edit', 'wikEdScrollToEdit4 title':   'Scroll to edit field',

// button bar grip titles 'wikEdGripFormat title':      'Formatting buttons (click to hide or show)', 'wikEdGripTextify title':     'Textify and wikify buttons (click to hide or show)', 'wikEdGripCustom1 title':     'Custom buttons (click to hide or show)', 'wikEdGripFind title':        'Find buttons (click to hide or show)', 'wikEdGripFix title':         'Fixing buttons (click to hide or show)', 'wikEdGripCustom2 title':     'Custom buttons (click to hide or show)', 'wikEdGripControl title':     'wikEd control buttons (click to hide or show)',

// button bar background titles 'wikEdBarFormat title':       '', 'wikEdBarTextify title':      '', 'wikEdBarCustom1 title':      '', 'wikEdBarFind title':         '', 'wikEdBarFix title':          '', 'wikEdBarCustom2 title':      '', 'wikEdBarControl title':      'wikEd {wikEdProgramVersion} ({wikEdProgramDate})', 'wikEdBarPreview title':      '', 'wikEdBarPreview2 title':     '', 'wikEdBarJump title':         '', 'wikEdBarPasted title':       '',

// formatting buttons, top row 'wikEdUndo alt':              'Undo', 'wikEdUndo title':            'Undo', 'wikEdRedo alt':              'Redo', 'wikEdRedo title':            'Redo', 'wikEdBold alt':              'Bold', 'wikEdBold title':            'Bold text', 'wikEdItalic alt':            'Italic', 'wikEdItalic title':          'Italic text', 'wikEdUnderline alt':         'Underline', 'wikEdUnderline title':       'Underline text', 'wikEdStrikethrough alt':     'Strikethrough', 'wikEdStrikethrough title':   'Strikethrough text', 'wikEdNowiki alt':            'Nowiki', 'wikEdNowiki title':          'Nowiki markup text', 'wikEdSuperscript alt':       'Superscript', 'wikEdSuperscript title':     'Superscript text', 'wikEdSubscript alt':         'Subscript', 'wikEdSubscript title':       'Subscript text', 'wikEdRef alt':               'Ref', 'wikEdRef title':             'In-text reference (shift-click: named tag)', 'wikEdCase alt':              'Case', 'wikEdCase title':            'Toggle between lowercase, uppercase first, and uppercase', 'wikEdSort alt':              'Sort', 'wikEdSort title':            'Sort alphabetically', 'wikEdRedirect alt':          'Redirect', 'wikEdRedirect title':        'Create redirect, deletes whole text', 'wikEdUndoAll alt':           'Undo all', 'wikEdUndoAll title':         'Undo all changes', 'wikEdRedoAll alt':           'Redo all', 'wikEdRedoAll title':         'Redo all changes',

// formatting buttons, bottom row 'wikEdWikiLink alt':          'Link', 'wikEdWikiLink title':        'Wiki link', 'wikEdWebLink alt':           'Weblink', 'wikEdWebLink title':         'External weblink', 'wikEdHeading alt':           'Heading', 'wikEdHeading title':         'Increase heading levels (shift-click: decrease)', 'wikEdBulletList alt':        'Bullet list', 'wikEdBulletList title':      'Increase bulleted list level (shift-click: decrease)', 'wikEdNumberList alt':        'Number list', 'wikEdNumberList title':      'Increase numbered list level (shift-click: decrease)', 'wikEdIndentList alt':        'Indent list', 'wikEdIndentList title':      'Increase indention (shift-click: decrease)', 'wikEdDefinitionList alt':    'Def list', 'wikEdDefinitionList title':  'Definition list', 'wikEdImage alt':             'Image', 'wikEdImage title':           'Image', 'wikEdTable alt':             'Table', 'wikEdTable title':           'Table', 'wikEdReferences alt':        'References', 'wikEdReferences title':      'References location (shift-click: references section)', 'wikEdSign alt':              'Signature', 'wikEdSign title':            'Signature Mr no no (talk) 23:52, 21 August 2017 (UTC) (shift-click: name only Mr no no (talk))',

// textify buttons 'wikEdWikify alt':            'Wikify', 'wikEdWikify title':          'Convert pasted content to wiki code, update highlighting', 'wikEdTextify alt':           'Textify', 'wikEdTextify title':         'Convert pasted content to plain text, update highlighting (shift-click: forced highlighting)', 'wikEdPastedWikify alt':      'Wikify pasted', 'wikEdPastedWikify title':    'Convert pasted content to wiki code', 'wikEdPastedTextify alt':     'Textify pasted', 'wikEdPastedTextify title':   'Convert pasted content to plain text', 'wikEdPastedClose alt':       'x', 'wikEdPastedClose title':     'Close',

// find and replace buttons, top row 'wikEdFindAll alt':           'Find all', 'wikEdFindAll title':         'Find all matches', 'wikEdFindPrev alt':          'Find prev', 'wikEdFindPrev title':        'Find previous match', 'wikEdFindSelect title':      'Select a previous search or jump to a heading', 'wikEdFindNext alt':          'Find next', 'wikEdFindNext title':        'Find next match (shift-click: get selection)', 'wikEdJumpPrev alt':          'Selected prev', 'wikEdJumpPrev title':        'Find the selected text backwards', 'wikEdJumpNext alt':          'Selected next', 'wikEdJumpNext title':        'Find the selected text forwards',

// find and replace buttons, bottom row 'wikEdReplaceAll alt':        'Replace all', 'wikEdReplaceAll title':      'Replace all matches in whole text or selection', 'wikEdReplacePrev alt':       'Replace prev', 'wikEdReplacePrev title':     'Replace previous match', 'wikEdReplaceSelect title':   'Select a previous replacement', 'wikEdReplaceNext alt':       'Replace next (shift-click: get selection)', 'wikEdReplaceNext title':     'Replace next match', 'wikEdCaseSensitive alt':     'Case sensitive', 'wikEdCaseSensitive title':   'Search is case sensitive', 'wikEdRegExp alt':            'RegExp', 'wikEdRegExp title':          'Search field is a regular expression', 'wikEdFindAhead alt':         'Find ahead', 'wikEdFindAhead title':       'Find ahead as you type (case-insensitive non-regexp search)',

// fix buttons, top row 'wikEdFixBasic alt':          'Fix basic', 'wikEdFixBasic title':        'Fix blanks and empty lines, also done by other fixing functions', 'wikEdFixHtml alt':           'Fix html', 'wikEdFixHtml title':         'Fix html to wikicode', 'wikEdFixCaps alt':           'Fix caps', 'wikEdFixCaps title':         'Fix caps in headers and lists', 'wikEdFixUnicode alt':        'Fix Unicode', 'wikEdFixUnicode title':      'Fix Unicode character representations', 'wikEdFixAll alt':            'Fix all', 'wikEdFixAll title':          'Fix basic, html, capitalization, and Unicode', 'wikEdFixRedirect alt':       'Fix redirects', 'wikEdFixRedirect title':     'Fix redirects',

// fix buttons, bottom row 'wikEdFixDashes alt':         'Fix dashes', 'wikEdFixDashes title':       'Fix dashes', 'wikEdFixPunct alt':          'Fix punctuation', 'wikEdFixPunct title':        'Fix spaces before punctuation', 'wikEdFixMath alt':           'Fix math', 'wikEdFixMath title':         'Fix math', 'wikEdFixChem alt':           'Fix chem', 'wikEdFixChem title':         'Fix chemical formulas', 'wikEdFixUnits alt':          'Fix units', 'wikEdFixUnits title':        'Fix units', 'wikEdFixRegExTypo alt':      'Fix typos', 'wikEdFixRegExTypo title':    'Fix typos using the AutoWikiBrowser RegExTypoFixer rules',

// wikEd control buttons, top row 'wikEdRefHide alt':           '[REF, TEMPL]', 'wikEdRefHide title':         'Simple view: hide refs, templates, and table code', 'wikEdRefButtonTooltip':      'Click to display hidden reference', 'wikEdTemplButtonTooltip':    'Click to display hidden template', 'wikEdCharEntityButtonTooltip': 'Click to display hidden character entity', 'wikEdTableButtonTooltip':    'Click to display hidden table code', 'wikEdRefButtonShowTooltip':  'Click to hide reference', 'wikEdTemplButtonShowTooltip': 'Click to hide template', 'wikEdCharEntityButtonShowTooltip': 'Click to hide character entity', 'wikEdTableButtonShowTooltip': 'Click to hide table code', 'wikEdTextZoom alt':          'Text zoom', 'wikEdTextZoom title':        'Text zoom cycling (shift-click: reverse)', 'wikEdClearHistory alt':      'Clear history', 'wikEdClearHistory title':    'Clear the find, replace, and summary history', 'wikEdScrollToPreview alt':   'Scroll to preview', 'wikEdScrollToPreview title': 'Scroll to preview field', 'wikEdScrollToEdit alt':      'Scroll to edit', 'wikEdScrollToEdit title':    'Scroll to edit field',

// wikEd control buttons, bottom row 'wikEdUseWikEd alt':          'Use wikEd', 'wikEdUseWikEd title':        'Use wikEd instead of classic text area', 'wikEdHighlightSyntax alt':   'Syntax', 'wikEdHighlightSyntax title': 'Syntax highlighting', 'wikEdSource alt':            'Source', 'wikEdCloseToolbar title':    'Close the standard non-wikEd toolbar', 'wikEdCloseToolbar alt':      'Close toolbar', 'wikEdSource title':          'Show the source code for testing', 'wikEdUsing alt':             'Using', 'wikEdUsing title':           'Automatically add \'\'…using wikEd\'\' to summaries', 'wikEdFullScreen alt':        'Fullscreen', 'wikEdFullScreen title':      'Fullscreen mode', 'wikEdTableMode alt':         'Table as tables', 'wikEdTableMode title':       'Edit tables as tables',

// summary buttons 'wikEdClearSummary alt':      'Clear summary', 'wikEdClearSummary title':    'Clear the summary field', 'wikEdSummarySelect title':   'Select a previous summary', 'wikEdPresetSummary': [ '/* */ ', 'copyedit', 'reply', 'article created', 'intro rewrite', 'linkfix', 'fixing typos', 'removing linkspam', 'reverting test', 'reverting vandalism', 'formatting source text', '{wikEdUsing}' ],			'wikEdSummaryUsing':          '…using wikEd',

// toolbar 'wikEdCodeEditorButtonDisabled': ' (disabled by wikEd)',

// button title acceskey 'alt-shift':                  'alt-shift-',

// submit buttons 'wikEdLocalPreviewImg alt':   'Preview below', 'wikEdLocalPreview title':    'Show preview below', 'wikEdLocalDiffImg alt':      'Changes below', 'wikEdLocalDiff title':       'Show current changes below', 'wikEdHelpPageLink':          ' | wikEd help', // use full link without {wikEdHomeBaseUrl} if the page is not on the English Wikipedia

// preview and changes buttons, top 'wikEdClose alt':             'Close', 'wikEdClose title':           'Close preview box', 'wikEdClose2 alt':            'Close', 'wikEdClose2 title':          'Close preview box', 'wikEdScrollToPreview2 alt':  'Scroll to preview', 'wikEdScrollToPreview2 title': 'Scroll to preview field', 'wikEdScrollToEdit2 alt':     'Scroll to edit', 'wikEdScrollToEdit2 title':   'Scroll to edit field',

// preview and changes buttons, bottom 'wikEdScrollToPreview3 alt':  'Scroll to preview', 'wikEdScrollToPreview3 title': 'Scroll to preview field', 'wikEdScrollToEdit3 alt':     'Scroll to edit', 'wikEdScrollToEdit3 title':   'Scroll to edit field',

// preview field 'wikEdPreviewLoading':        '...', 'diffNotLoaded':              'Error: Local diff script not installed.',

// formatting functions 'image filename':             'filename', 'image width':                'width', 'table caption':              'caption', 'table heading':              'heading', 'table cell':                 'cell', 'redirect article link':      'article link',

// fixing functions 'External links':             'External links', 'See also':                   'See also', 'References':                 'References',

// language specific wiki code 'wikicode Image':             'Image', 'wikicode File':              'File', 'wikicode Media':             'Media', 'wikicode Category':          'Category', 'wikicode Template':          'Template', 'wikEdReferencesSection':     '\n== References ==\n\n

['(^|\\n)([ \xa0]+)(\\S[^\\n]*)',       'preform',       'block'], // "preformatted" text line (leading space) ['(^|\\n)([*#:;]+)([^\\n]*)',           'list',          'block'], // list line

['\x00(br|wbr)\\b[^\x00\x01]*\x01', 'void',              'block'], // , ['\x00(\\w+)[^\x00\x01]*?\\/\x01', 'htmlEmpty',          'block'], //

['\x00(\\w+)[^\x00\x01]*\x01',     'html',                'open'], // ['\x00\\/(\\w+)[^\x00\x01]*\x01',  'html',               'close'], //

['(^|\\n)(\\{\\|)',                'table',               'open'], // table start ['(^|\\n)(\\|\\}\\})',             'pipeTemplateEnd',    'multi'], // empty template parameter + template end ['(^|\\n)(\\|\\})',                'table',              'close'], // table end

['(^|\\n)(\\|\\+)',                'tableCaption',        'open'], // table caption ['(^|\\n)(\\|\\-)',                'row',                 'open'], // table row

['(^|\\n)(\\|)',                   'newlinePipe',        'block'], // table cell, wikilink separator, file parameter separator, empty template parameter ['\\|\\|',                         'doublePipe',         'block'], // table cell separator, empty file parameter separator, empty template parameters ['\\|',                            'pipe',               'block'], // table cell attribute separator, table caption parameter separator, wikilink separator, file parameter separator, redirect separator, template parameter parameter

['(^|\\n)(!)',                     'header',              'open'], // table header cell ['!!',                             'headerSep',           'open'], // table header cell separator

['\\{{2,}',                        'paramTempl',          'open'], // template or parameter start ['\\}{2,}',                        'paramTempl',         'close'], // template parameter end

['(^\\s*)#REDIRECT(?=\\s*\\[\\[)', 'redirect',           'block'], // redirect

['\\[\\[(?=(Image|File|Media|' + wikEd.config.text['wikicode Image'] + '|' + wikEd.config.text['wikicode File'] + '|' + wikEd.config.text['wikicode Media'] + ')\\s*:\\s*)', 'file', 'open'], // file link start /// add translation ['\\[\\[',                         'link', 'open'],                // wikilink, category start with interlink detection ['\\]\\]',                         'doubleCloseBracket', 'close'], // wikilink, category, file link, redirect end

['\\[((((https?:|ftp:|irc:|gopher:|)\\/\\/)|news:|mailto:)[^\\x00-\\x20\\s"\\[\\]\\x7f]+)(\\s*)', 'external', 'open'], // external link start; up?? url detected as ext link!		['\\]',                             'external',           'close'], // external link end

['(^|\\n)={1,6}',                  'heading',             'open'], // heading start - heading can contain multi-line templates and s, all single-line ['={1,6}[ \xa0\\t]*(?=(\\n|$))',   'heading',            'close'], // heading end

['\\\'{2,}',                       'boldItalic',         'multi'], // bold, italic

['__(' + wikEd.magicWords + ')__', 'magic',              'block'], // magic words ['~{3,5}',                         'signature',          'block'], // signature ['(^|\\n)\\-{4,}',                 'hr',                 'block'], // hr		['(\\n|$)',                         'newline',            'block']  // breaks: heading, lists, external link, wikilink before

];

// parse tag array into regular expression string and parenthesized substring match-to-tag info array var regExpStrings = []; for (var i = 0; i < tagArray.length; i ++) { var regExpSub = tagArray[i][0]; var tag = tagArray[i][1]; var tagClass = tagArray[i][2];

// add parenthesized sub regExp to regexp array regExpStrings.push('(' + regExpSub + ')');

// detect if a fragment starts with (^|\\n) to handle the leading newlines var tagStart = false; if (/^\(\^\|\\n\)/.test(regExpSub) === true) { tagStart = true; }

// save tag information for matched parenthesis wikEd.parseObj.matchToTag.push( [tag, tagClass, tagStart] );

// add empty entry for all sub parentheses, ignore (? and \( var pos = 0; while ( (pos = regExpSub.indexOf('(', pos) + 1) > 0) {			if (regExpSub.charAt(pos) != '?') {				if (regExpSub.charAt(pos - 2) != '\\') {					wikEd.parseObj.matchToTag.push( [] );				}			}		}	}

// create regExp from or-joined parenthesized sub regExps wikEd.parseObj.regExpTags = new RegExp(regExpStrings.join('|'), 'gi');

return; };

// // wikEd.HighlightSyntax: highlight syntax in obj.html; //  existing highlighting must have been removed using wikEd.RemoveHighlighting //  expects < > &lt; &gt; &amp;  \xa0 instead of    \n instead of // known bugs: // - templates inside elements // - fragment highlighting misses surrounding html // // this is a real wikicode parser that works as follows: //  cycle through the text with a complex regexp search for wikicode and highlighting fragments //    build an array-based tree structure of text elements //      tag info: text pos, text length, tag type (open, close, block, error) //      connectivity info: parent, firstChild, nextSibling, paired opening/closing (all array indexes) //  add actual highlighting html code to parse tree elements // /* TO DO: heading closes links valid table markup: \n :{| preformatted lines: space-only lines inside and as last allowed

wikEd.HighlightSyntax = function (obj, noTimeOut, keepComments, noBlocks) {

// start timer to cancel after wikEd.config.maxHighlightTime ms	var highlightStartDate = new Date;

// linkify raw watchlist if (wikEd.editWatchlist === true) { obj.html = obj.html.replace(/(.*)/gm,			function(p, p1) {				var ns = '';				var article = p1;				var regExp = /^(.*?:)(.*)$/;				var regExpMatch = regExp.exec(article);				if (regExpMatch !== null) {					ns = regExpMatch[1];					article = regExpMatch[2];				}				var html = '' + p + ' ';				return html;			}		); return; }

// &lt; &gt; &amp; to \x00 \x01 & obj.html = obj.html.replace(/&lt;/g, '\x00'); obj.html = obj.html.replace(/&gt;/g, '\x01'); obj.html = obj.html.replace(/&amp;/g, '&');

// trailing, leading, and multi spaces to nbsp obj.html = obj.html.replace(/^ | $/gm, '\xa0'); obj.html = obj.html.replace(/(\n|\xa0 | ) /g, '$1\xa0');

// define parse object var parseObj = {

// tree object that holds nodes to be sorted and joined for final text: // { 'tag':, 'parent': , 'firstChild': , 'nextSibling': , 'start': , 'tagLength': , 'type': , 'paired': , 'pairedPos': , 'left': , 'right': , 'index': , 'attrib': , 'newline': } 'tree': [],

// main regular expression for syntactic elements 'regExp': null,

// last match 'regExpMatch': null,

// highlight whole text or fragment 'whole': false,

// ignore leading closing tags for fragment highlighting 'addedOpenTag': false,

// quick references 'lastOpenTag': null, 'lastOpenNode': 0,

// filtered ignore p tags 'lastOpenNodeFiltered': null, 'lastOpenTagFiltered': null,

'secondlastOpenNodeFiltered': null, 'secondlastOpenTagFiltered': null, };

// add root node parseObj.tree[0] = { 'type': 'root' };

// clear array of link addresses and preview image ids if (obj.whole === true) { parseObj.whole = true; wikEd.wikiLinks = []; wikEd.referenceArray = []; wikEd.templateArray = []; wikEd.charEntityArray = []; wikEd.HighlightNamedHideButtonsStylesheet = new wikEd.StyleSheet(wikEd.frameDocument); wikEd.filePreviewNo = 0; wikEd.filePreviewIds = []; }

// take out comments and html formatting to be kept var content = ''; var from = 0; var commentsLength = 0; var regExpMatch; var regExpComments = /(\x00!--(.|\n)*?--\x01)|(<[^>]*>)/g; while ( (regExpMatch = regExpComments.exec(obj.html)) !== null) { var tag; var p1 = regExpMatch[1] || ''; var p2 = regExpMatch[2] || ''; if (p1 !== '') { tag = 'comment'; }		else if (p2 !== '') { tag = 'keep'; }		parseObj.tree.push( { 'tag': tag, 'start': regExpMatch.index - commentsLength, 'tagLength': 0, 'type': tag, 'left': regExpMatch[0] } ); content += obj.html.substring(from, regExpMatch.index); commentsLength += regExpMatch[0].length; from = regExpComments.lastIndex; }	if (parseObj.tree.length > 0) { content += obj.html.substring(from); obj.html = content; }

//// opening block tags and templates break link?

// show main parsing regExp: // WED('regExp', wikEd.parseObj.regExpTags.toString.replace(/\x00/g, '<').replace(/\x01/g, '>').replace(/\n/g, '\\n'));

// cycle through text and find tags with a regexp search wikEd.parseObj.regExpTags.lastIndex = 0; while ( (parseObj.regExpMatch = wikEd.parseObj.regExpTags.exec(obj.html)) !== null) {

// cancel highlighting after wikEd.config.maxHighlightTime ms		if (noTimeOut !== true) { var currentDate = new Date; if ( (currentDate - highlightStartDate) > wikEd.config.maxHighlightTime) { break; }		}

var tagMatch = parseObj.regExpMatch[0]; var tagFrom = parseObj.regExpMatch.index; var tagLength = tagMatch.length; var tagTo = tagFrom + tagLength; var tagProperties = []; var tagMatchParenth = 0;

// get regexp index number from first defined parenthesized submatch var tag = ''; var tagClass = ''; var tagStart = ''; for (var i = 1; i < wikEd.parseObj.matchToTag.length; i ++) { if (typeof parseObj.regExpMatch[i] != 'undefined') {

// get tag information tag = wikEd.parseObj.matchToTag[i][0]; tagClass = wikEd.parseObj.matchToTag[i][1]; tagStart = wikEd.parseObj.matchToTag[i][2]; tagMatchParenth = i;				break; }		}

// handle chew-up regExp matches that massively speed up regexp search if (tagClass == 'ignore') {

// move regExp pointer back if chew-up regExp fragment has eaten into the start of an inline link if (obj.html.charAt(wikEd.parseObj.regExpTags.lastIndex) == ':') { var regExpMatch = /(https?|ftp|irc|gopher)$/.exec(tagMatch); if (regExpMatch !== null) { wikEd.parseObj.regExpTags.lastIndex = wikEd.parseObj.regExpTags.lastIndex - regExpMatch[0].length; }			}			continue; }

// detect and remove newline from leading (^|\n) in sub-regexp: table, pipeTemplateEnd, tableCaption, row, newlinePipe, header var leadingNewline = false; if (tagStart === true) { if (parseObj.regExpMatch[tagMatchParenth + 1] == '\n') { tagFrom ++; tagLength --; leadingNewline = true; tagProperties.push(['newline', true]); }		}

// newlines close or end certain tags if (leadingNewline === true) { wikEd.HighlightBuildTree('newline', 'close', tagFrom, 0, parseObj); }		var openNode = parseObj.tree[parseObj.lastOpenNodeFiltered];

// get attrib text if ( (tagClass == 'open') && ( (tag == 'table') || (tag == 'row') ) ) { var attribEnd = obj.html.indexOf('\n', tagTo); if (attribEnd == -1) { attribEnd = null; }			var attribText = obj.html.substring(tagTo, attribEnd); if (attribText !== '') { attribText = attribText.replace(/^ +| +$/g, ''); tagProperties.push(['attrib', attribText]); }		}

// no wikicode in link target, template, or parameter name if ( (parseObj.lastOpenTag == 'link') || (parseObj.lastOpenTag == 'template') || (parseObj.lastOpenTag == 'parameter') ) {

if ( (openNode !== undefined) && (openNode.firstChild === null) ) {

// allow templates and template parameters, template and link separators, and newline if (					( (tagClass == 'open') && (tag != 'paramTempl') ) ||					( (tagClass == 'block') && (tag != 'newlinePipe') && (tag != 'doublePipe') && (tag != 'pipe') && (tag != 'headerSep') && (tag != 'newline') && (tag != 'preform') ) //// preform ok?				) {

// convert opening tag to error and continue var errorText; if (parseObj.lastOpenTag == 'link') { errorText = wikEd.config.text.wikEdErrorCodeInLinkName; }					else if (parseObj.lastOpenTag == 'template') { errorText = wikEd.config.text.wikEdErrorCodeInTemplName; }					else if (parseObj.lastOpenTag == 'parameter') { errorText = wikEd.config.text.wikEdErrorCodeInParamName; }					wikEd.HighlightMarkLastOpenNode(errorText, parseObj); wikEd.HighlightGetLevel(parseObj); }			}		}

// handle current tag by dispatching infos to stack manager that builds a hierarchical tree switch (tag) {

// non-ambiguous tags case 'nowiki': case 'pre': case 'math': case 'score': case 'void': case 'file': case 'heading': case 'redirect': case 'magic': case 'signature': case 'hr': wikEd.HighlightBuildTree(tag, tagClass, tagFrom, tagLength, parseObj); break;

// bold and italic case 'boldItalic': switch (tagLength) { case 2: switch(parseObj.lastOpenTagFiltered) { case 'italic': wikEd.HighlightBuildTree('italic', 'close', tagFrom, tagLength, parseObj); break; case 'boldItalic': wikEd.HighlightTreeRedefine(parseObj.lastOpenNodeFiltered, 'italic', 3, 2, parseObj); wikEd.HighlightTreeRedefine(parseObj.secondlastOpenNodeFiltered, 'bold', 0, 3, parseObj); wikEd.HighlightGetLevel(parseObj); wikEd.HighlightBuildTree('italic', 'close', tagFrom, tagLength, parseObj); break; default: wikEd.HighlightBuildTree('italic', 'open', tagFrom, tagLength, parseObj); }						break; case 3: switch(parseObj.lastOpenTagFiltered) { case 'bold': wikEd.HighlightBuildTree('bold', 'close', tagFrom, tagLength, parseObj); break; case 'boldItalic': wikEd.HighlightTreeRedefine(parseObj.lastOpenNodeFiltered, 'bold', 2, 3, parseObj); wikEd.HighlightTreeRedefine(parseObj.secondlastOpenNodeFiltered, 'italic', 0, 2, parseObj); wikEd.HighlightGetLevel(parseObj); wikEd.HighlightBuildTree('bold', 'close', tagFrom, tagLength, parseObj); break; default: wikEd.HighlightBuildTree('bold', 'open', tagFrom, tagLength, parseObj); }						break; case 5: switch(parseObj.lastOpenTagFiltered) { case 'bold': if (parseObj.secondlastOpenTagFiltered == 'italic') { wikEd.HighlightBuildTree('bold', 'close', tagFrom, 3, parseObj); wikEd.HighlightBuildTree('italic', 'close', tagFrom + 3, 2, parseObj); }								else { wikEd.HighlightBuildTree('bold', 'close', tagFrom, 3, parseObj); wikEd.HighlightBuildTree('italic', 'open', tagFrom + 3, 2, parseObj); }								break; case 'italic': if (parseObj.secondlastOpenTagFiltered == 'bold') { wikEd.HighlightBuildTree('italic', 'close', tagFrom, 2, parseObj); wikEd.HighlightBuildTree('bold', 'close', tagFrom + 2, 3, parseObj); }								else { wikEd.HighlightBuildTree('italic', 'close', tagFrom, 2, parseObj); wikEd.HighlightBuildTree('bold', 'open', tagFrom + 2, 3, parseObj); }								break; case 'boldItalic': wikEd.HighlightTreeRedefine(parseObj.secondlastOpenNodeFiltered, 'bold', 0, 3, parseObj); wikEd.HighlightTreeRedefine(parseObj.lastOpenNodeFiltered, 'italic', 3, 2, parseObj); wikEd.HighlightGetLevel(parseObj); parseObj.lastOpenTag = 'italic'; wikEd.HighlightBuildTree('italic', 'close', tagFrom, 2, parseObj); wikEd.HighlightBuildTree('bold', 'close', tagFrom + 2, 3, parseObj); break; default: wikEd.HighlightBuildTree('boldItalic', 'open', tagFrom, tagLength, parseObj); wikEd.HighlightBuildTree('boldItalic', 'open', tagFrom, tagLength, parseObj); }						break; default: parseObj.tree.push( { 'start': tagFrom, 'tagLength': tagLength, 'type': 'error', 'left': wikEd.config.text.wikEdErrorBoldItalic } ); break; }				break;

// templParam: template or template parameter case 'paramTempl':

// template or parameter var paramTemplTag = tag; if (tagLength == 2) { paramTemplTag = 'template'; }				else if (tagLength == 3) { paramTemplTag = 'parameter'; }

// open paramTempl if (tagClass == 'open') { wikEd.HighlightBuildTree(paramTemplTag, tagClass, tagFrom, tagLength, parseObj);

// add spare elements for later disambiguation if (paramTemplTag == 'paramTempl') { for (var pos = 2; pos < tagLength - 1; pos = pos + 2) { wikEd.HighlightBuildTree(paramTemplTag, tagClass, tagFrom, tagLength, parseObj); }					}				}

// close paramTempl else {

// no opening tag, delegate error handling if ( (parseObj.lastOpenNode === 0) || (parseObj.lastOpenNode === null) ) { wikEd.HighlightBuildTree(paramTemplTag, tagClass, tagFrom, tagLength, parseObj); break; }					if (openNode === undefined) { wikEd.HighlightBuildTree(paramTemplTag, tagClass, tagFrom, tagLength, parseObj); break; }

// close template or parameter, open and close defined if (						( (paramTemplTag == 'template') && (parseObj.lastOpenTagFiltered == 'template') ) ||						( (paramTemplTag == 'parameter') && (parseObj.lastOpenTagFiltered == 'parameter') ) ||						( (paramTemplTag == 'parameter') && (parseObj.lastOpenTagFiltered == 'parameterPiped') )					) { wikEd.HighlightBuildTree(paramTemplTag, tagClass, tagFrom, tagLength, parseObj); }

// closing defines ambiguous opening else if (						( (paramTemplTag == 'template') || (paramTemplTag == 'parameter') ) &&						(parseObj.lastOpenTagFiltered == 'paramTempl') &&						(openNode.tagLength >= tagLength)					) {

// redefine ambiguous opening wikEd.HighlightTreeRedefine(parseObj.lastOpenNodeFiltered, paramTemplTag, openNode.tagLength - tagLength, tagLength, parseObj);

// adjust all ambiguous parents var redefinedTag; var redefinedLength; var nodeNo = openNode.parent; while ( (nodeNo !== 0) && (nodeNo !== null) && (nodeNo !== undefined) ) { var node = parseObj.tree[nodeNo]; if (node.tag != 'paramTempl') { break; }

if (nodeNo == openNode.parent) { redefinedTag = node.tag; redefinedLength = node.tagLength - tagLength; }

// ignore spare paramTempl opening tags like p tags if (redefinedLength === 0) { redefinedTag = 'spare'; }

// mark remaining single { as error else if (redefinedLength == 1) { parseObj.tree.push( {									'start': node.start,									'tagLength': node.tagLength,									'type': 'error',									'left': wikEd.config.text.wikEdErrorTemplParam								} ); redefinedTag = 'spare'; }

// this is a template else if (redefinedLength == 2) { node.tag = 'template'; }

// this is a parameter else if (redefinedLength == 3) { node.tag = 'parameter'; }

// redefine parent wikEd.HighlightTreeRedefine(nodeNo, redefinedTag, null, redefinedLength, parseObj);

// all further opening paramTempl tags are spare if (redefinedLength <= 3) { redefinedTag = 'spare'; redefinedLength = 0; }

// up one level nodeNo = node.parent; }						wikEd.HighlightGetLevel(parseObj);

// and close innermost tag wikEd.HighlightBuildTree(paramTemplTag, tagClass, tagFrom, tagLength, parseObj); }

// opening defines ambiguous closing else if ( ( (openNode.tag == 'template') || (openNode.tag == 'parameter') || (openNode.tag == 'parameterPiped') ) && (tagLength >= openNode.tagLength)					) { wikEd.HighlightBuildTree(openNode.tag, tagClass, tagFrom, openNode.tagLength, parseObj); wikEd.parseObj.regExpTags.lastIndex = wikEd.parseObj.regExpTags.lastIndex - tagLength + openNode.tagLength; }

// both ambiguous else if (						(paramTemplTag == 'paramTempl') &&						(openNode.tag == 'paramTempl') &&						( (openNode.tagLength > 3) && (tagLength > 3) )					) { parseObj.tree.push( {							'start': openNode.start,							'tagLength': openNode.tagLength,							'type': 'error',							'left': wikEd.config.text.wikEdErrorTemplParamAmbig						} ); parseObj.tree.push( {							'start': tagFrom,							'tagLength': tagLength,							'type': 'error',							'left': wikEd.config.text.wikEdErrorTemplParamAmbig						} ); }

// opening and closing do not match else { parseObj.tree.push( {							'start': openNode.start,							'tagLength': openNode.tagLength,							'type': 'error',							'left': wikEd.config.text.wikEdErrorTemplParam						} ); parseObj.tree.push( {							'start': tagFrom,							'tagLength': tagLength,							'type': 'error',							'left': wikEd.config.text.wikEdErrorTemplParam						} ); }				}				break;

// wikilink case 'link': wikEd.HighlightBuildTree(tag, tagClass, tagFrom, 2, parseObj); break;

// inline link block and external link case 'inlineURL': case 'external':

// trailing punctuation not part of inline links if (tag == 'inlineURL') { var regExpMatch; if (/\(/.test(tagMatch) === true) {						regExpMatch = /^(.*?)([.,:;\\!?)]+)$/.exec(tagMatch); }					else { regExpMatch = /^(.*?)([.,:;\\!?]+)$/.exec(tagMatch); }					if (regExpMatch !== null) { wikEd.parseObj.regExpTags.lastIndex = tagFrom + regExpMatch[1].length; tagMatch = regExpMatch[1]; tagLength = tagMatch.length; tagTo = tagFrom + tagLength; }				}

// urls in templates or tables are interrupted by tag strings if (tag == 'inlineURL') { var node = parseObj.tree[parseObj.lastOpenNode]; while ( (node !== undefined) && (node !== null) ) {

// urls in templates are interrupted by }} and | if ( (node.tag == 'template') || (node.tag == 'paramTempl') || (node.tag == 'parameter') || (node.tag == 'parameterPiped') ) { var regExpMatch; if ( (regExpMatch = /^(.*?)(\}\}|\|)(.*?)$/.exec(tagMatch)) !== null) { wikEd.parseObj.regExpTags.lastIndex = tagFrom + regExpMatch[1].length; tagMatch = regExpMatch[1]; tagLength = tagMatch.length; tagTo = tagFrom + tagLength; }							break; }

// urls in tables are interrupted by || else if (node.tag == 'table') { var regExpMatch; if ( (regExpMatch = /^(.*?)(\}\}|\|)(.*?)$/.exec(tagMatch)) !== null) { wikEd.parseObj.regExpTags.lastIndex = tagFrom + regExpMatch[1].length; tagMatch = regExpMatch[1]; tagLength = tagMatch.length; tagTo = tagFrom + tagLength; }							break; }						node = parseObj.tree[node.parent]; }				}

// dissect external [url text if (tag == 'external') { if (tagClass == 'open') { var url = parseObj.regExpMatch[tagMatchParenth + 1]; var spaces = parseObj.regExpMatch[tagMatchParenth + 5]; wikEd.HighlightBuildTree(tag, tagClass, tagFrom, 1, parseObj); wikEd.HighlightBuildTree('externalURL', 'block', tagFrom + 1, url.length, parseObj); wikEd.HighlightBuildTree('externalText', tagClass, tagFrom + 1 + url.length + spaces.length, 0, parseObj); }

// close ], ignore false positive non-tags that have no opening [ else { var node = parseObj.tree[parseObj.lastOpenNode]; while ( (node !== null) && (node !== undefined) ) { if (node.tag == tag) { break; }							node = parseObj.tree[node.parent]; }						if ( (node !== null) && (node !== undefined) ) { if (node.parent !== null) { wikEd.HighlightBuildTree('externalText', tagClass, tagFrom, 0, parseObj); wikEd.HighlightBuildTree(tag, tagClass, tagFrom, tagLength, parseObj); }						}					}					break; }

wikEd.HighlightBuildTree(tag, tagClass, tagFrom, tagLength, parseObj); break;

// 			case 'html': var htmlTag = parseObj.regExpMatch[tagMatchParenth + 1].toLowerCase; if (/^(ref|references|sub|sup|u|s|p|wbr)$/i.test(htmlTag) === true) { wikEd.HighlightBuildTree(htmlTag, tagClass, tagFrom, tagLength, parseObj); }				else if (/^(table|tr|td|th|col|thead|tfoot|tbody|colgroup|caption|abbr|big|blockquote|center|code|del|div|font|ins|small|span|strike|tt|rb|rp|rt|ruby|nowiki|math|score|noinclude|includeonly|onlyinclude|gallery|categorytree|charinsert|hiero|imagemap|inputbox|poem|syntaxhighlight|source|timeline)$/.test(htmlTag) === true) { wikEd.HighlightBuildTree(htmlTag, tagClass, tagFrom, tagLength, parseObj); }				else { wikEd.HighlightBuildTree('htmlUnknown', 'block', tagFrom, tagLength, parseObj); }				break;

// 			case 'htmlEmpty': var htmlTag = parseObj.regExpMatch[tagMatchParenth + 1].toLowerCase; if (/^(references|ref|br|p|wbr)$/i.test(htmlTag) === true) { wikEd.HighlightBuildTree(htmlTag, tagClass, tagFrom, tagLength, parseObj); }				else { wikEd.HighlightBuildTree(tag, tagClass, tagFrom, tagLength, parseObj); }				break;

// |}}: table end or empty template parameter + template end case 'pipeTemplateEnd': switch (parseObj.lastOpenTagFiltered) { case 'table': wikEd.HighlightBuildTree('table', 'close', tagFrom, 2, parseObj, tagProperties); break; case 'tableAttrib': wikEd.HighlightBuildTree('tableAttrib', 'close', tagFrom, 0, parseObj); wikEd.HighlightBuildTree('table', 'close', tagFrom, 2, parseObj, tagProperties); break; case 'tableCaption': wikEd.HighlightBuildTree('tableCaption', 'close', tagFrom - 1, 0, parseObj); wikEd.HighlightBuildTree('table', 'close', tagFrom, 2, parseObj, tagProperties); break; case 'captionAttrib': wikEd.HighlightBuildTree('captionAttrib', 'close', openNode.start + openNode.tagLength, 0, parseObj); wikEd.HighlightBuildTree('tableCaption', 'close', tagFrom - 1, 0, parseObj); wikEd.HighlightBuildTree('table', 'close', tagFrom, 2, parseObj, tagProperties); break; case 'row': wikEd.HighlightBuildTree('row', 'close', tagFrom - 1, 0, parseObj); wikEd.HighlightBuildTree('table', 'close', tagFrom, 2, parseObj, tagProperties); break; case 'rowAttrib': wikEd.HighlightBuildTree('rowAttrib', 'close', tagFrom - 1, 0, parseObj); wikEd.HighlightBuildTree('row', 'close', tagFrom, 2, parseObj); break; case 'header': wikEd.HighlightBuildTree('header', 'close', tagFrom - 1, 0, parseObj); wikEd.HighlightBuildTree('row', 'close', tagFrom - 1, 0, parseObj); wikEd.HighlightBuildTree('table', 'close', tagFrom, 2, parseObj, tagProperties); break; case 'cell': wikEd.HighlightBuildTree('cell', 'close', tagFrom - 1, 0, parseObj); wikEd.HighlightBuildTree('row', 'close', tagFrom - 1, 0, parseObj); wikEd.HighlightBuildTree('table', 'close', tagFrom, 2, parseObj, tagProperties); break; case 'template': wikEd.HighlightBuildTree('templateParam', 'block', tagFrom, 1, parseObj); wikEd.HighlightBuildTree('template', 'close', tagFrom + 1, 2, parseObj); break; }				break;

// {|, |}: table case 'table': if (tagClass == 'open') { switch (parseObj.lastOpenTagFiltered) { case 'tableAttrib': wikEd.HighlightBuildTree('tableAttrib', 'close', tagFrom - 1, 0, parseObj); break; case 'tableCaption': wikEd.HighlightBuildTree('tableCaption', 'close', tagFrom - 1, 0, parseObj); break; case 'captionAttrib': wikEd.HighlightBuildTree('captionAttrib', 'close', openNode.start + openNode.tagLength, 0, parseObj); wikEd.HighlightBuildTree('tableCaption', 'close', tagFrom - 1, 0, parseObj); break; case 'row': wikEd.HighlightBuildTree('row', 'close', tagFrom - 1, 0, parseObj); break; case 'rowAttrib': wikEd.HighlightBuildTree('rowAttrib', 'close', tagFrom - 1, 0, parseObj); wikEd.HighlightBuildTree('row', 'close', tagFrom - 1, 0, parseObj); break; case 'header': break; case 'headerAttrib': wikEd.HighlightBuildTree('headerAttrib', 'close', tagFrom - 1, 0, parseObj); break; case 'cell': break; case 'cellAttrib': wikEd.HighlightBuildTree('cellAttrib', 'close', tagFrom - 1, 0, parseObj); break; }					wikEd.HighlightBuildTree(tag, tagClass, tagFrom, tagLength, parseObj, tagProperties); wikEd.HighlightBuildTree('tableAttrib', 'open', tagTo, 0, parseObj); }

// close close else { switch (parseObj.lastOpenTagFiltered) { case 'tableAttrib': wikEd.HighlightBuildTree('tableAttrib', 'close', tagFrom - 1, 0, parseObj); break; case 'tableCaption': wikEd.HighlightBuildTree('tableCaption', 'close', tagFrom - 1, 0, parseObj); break; case 'captionAttrib': wikEd.HighlightBuildTree('captionAttrib', 'close', openNode.start + openNode.tagLength, 0, parseObj); wikEd.HighlightBuildTree('tableCaption', 'close', tagFrom - 1, 0, parseObj); break; case 'row': wikEd.HighlightBuildTree('row', 'close', tagFrom - 1, 0, parseObj); break; case 'rowAttrib': wikEd.HighlightBuildTree('rowAttrib', 'close', tagFrom - 1, 0, parseObj); wikEd.HighlightBuildTree('row', 'close', tagFrom - 1, 0, parseObj); break; case 'header': wikEd.HighlightBuildTree('header', 'close', tagFrom - 1, 0, parseObj); wikEd.HighlightBuildTree('row', 'close', tagFrom - 1, 0, parseObj); break; case 'headerAttrib': wikEd.HighlightBuildTree('headerAttrib', 'close', tagFrom - 1, 0, parseObj); wikEd.HighlightBuildTree('header', 'close', tagFrom - 1, 0, parseObj); wikEd.HighlightBuildTree('row', 'close', tagFrom - 1, 0, parseObj); break; case 'cell': wikEd.HighlightBuildTree('cell', 'close', tagFrom - 1, 0, parseObj); wikEd.HighlightBuildTree('row', 'close', tagFrom - 1, 0, parseObj); break; case 'cellAttrib': wikEd.HighlightBuildTree('cellAttrib', 'close', tagFrom - 1, 0, parseObj); wikEd.HighlightBuildTree('cell', 'close', tagFrom - 1, 0, parseObj); wikEd.HighlightBuildTree('row', 'close', tagFrom - 1, 0, parseObj); break; }					wikEd.HighlightBuildTree(tag, tagClass, tagFrom, tagLength, parseObj, tagProperties); }				break;

// ]]: wikilink, file link, redirect case 'doubleCloseBracket': if (parseObj.lastOpenTagFiltered == 'file') { wikEd.HighlightBuildTree(parseObj.lastOpenTagFiltered, tagClass, tagFrom, tagLength, parseObj); }				else { wikEd.HighlightBuildTree('link', tagClass, tagFrom, tagLength, parseObj); }				break;

// \n|: table cell, wikilink separator, file parameter separator, redirect separator, empty template parameter case 'newlinePipe': switch (parseObj.lastOpenTagFiltered) { case 'table': wikEd.HighlightBuildTree('row', 'open', tagFrom, 0, parseObj); break; case 'tableAttrib': wikEd.HighlightBuildTree('tableAttrib', 'close', tagFrom - 1, 0, parseObj); wikEd.HighlightBuildTree('row', 'open', tagFrom, 0, parseObj); break; case 'tableCaption': wikEd.HighlightBuildTree('tableCaption', 'close', tagFrom - 1, 0, parseObj); wikEd.HighlightBuildTree('row', 'open', tagFrom, 0, parseObj); break; case 'captionAttrib': wikEd.HighlightBuildTree('captionAttrib', 'close', tagFrom - 1, 0, parseObj); wikEd.HighlightBuildTree('tableCaption', 'close', tagFrom - 1, 0, parseObj); wikEd.HighlightBuildTree('row', 'open', tagFrom, 0, parseObj); break; case 'row': break; case 'rowAttrib': wikEd.HighlightBuildTree('rowAttrib', 'close', tagFrom - 1, 0, parseObj); break; case 'header': wikEd.HighlightBuildTree('header', 'close', tagFrom - 1, 0, parseObj); break; case 'headerAttrib': wikEd.HighlightBuildTree('headerAttrib', 'close', tagFrom - 1, 0, parseObj); wikEd.HighlightBuildTree('header', 'close', tagFrom - 1, 0, parseObj); break; case 'cell': wikEd.HighlightBuildTree('cell', 'close', tagFrom - 1, 0, parseObj); break; case 'cellAttrib': wikEd.HighlightBuildTree('cellAttrib', 'close', tagFrom - 1, 0, parseObj); wikEd.HighlightBuildTree('cell', 'close', tagFrom - 1, 0, parseObj); break; case 'link': wikEd.HighlightBuildTree('linkParam', tagClass, tagFrom, tagLength, parseObj); break; case 'file': wikEd.HighlightBuildTree('fileParam', tagClass, tagFrom, tagLength, parseObj); break; case 'template': case 'paramTempl': wikEd.HighlightBuildTree('templateParam', tagClass, tagFrom, tagLength, parseObj); break; }				switch (parseObj.lastOpenTagFiltered) { case 'table': case 'tableAttrib': case 'tableCaption': case 'captionAttrib': case 'row': case 'rowAttrib': case 'header': case 'headerAttrib': case 'cell': case 'cellAttrib': wikEd.HighlightBuildTree('cell', 'open', tagFrom, tagLength, parseObj, tagProperties); wikEd.HighlightBuildTree('cellAttrib', 'open', tagTo, 0, parseObj); }				break;

// \n!: header case 'header': switch (parseObj.lastOpenTagFiltered) { case 'table': wikEd.HighlightBuildTree('row', 'open', tagFrom, 0, parseObj); break; case 'tableAttrib': wikEd.HighlightBuildTree('tableAttrib', 'close', tagFrom - 1, 0, parseObj); wikEd.HighlightBuildTree('row', 'open', tagFrom, 0, parseObj); break; case 'tableCaption': wikEd.HighlightBuildTree('tableCaption', 'close', tagFrom - 1, 0, parseObj); wikEd.HighlightBuildTree('row', 'open', tagFrom, 0, parseObj); break; case 'captionAttrib': wikEd.HighlightBuildTree('captionAttrib', 'close', openNode.start + openNode.tagLength, 0, parseObj); wikEd.HighlightBuildTree('tableCaption', 'close', tagFrom - 1, 0, parseObj); wikEd.HighlightBuildTree('row', 'open', tagFrom, 0, parseObj); break; case 'row': break; case 'rowAttrib': wikEd.HighlightBuildTree('rowAttrib', 'close', tagFrom - 1, 0, parseObj); break; case 'header': wikEd.HighlightBuildTree('header', 'close', tagFrom - 1, 0, parseObj); break; case 'headerAttrib': wikEd.HighlightBuildTree('headerAttrib', 'close', tagFrom - 1, 0, parseObj); wikEd.HighlightBuildTree('header', 'close', tagFrom - 1, 0, parseObj); break; case 'cell': wikEd.HighlightBuildTree('cell', 'close', tagFrom - 1, 0, parseObj); break; case 'cellAttrib': wikEd.HighlightBuildTree('cellAttrib', 'close', tagFrom - 1, 0, parseObj); wikEd.HighlightBuildTree('cell', 'close', tagFrom - 1, 0, parseObj); break; }				wikEd.HighlightBuildTree(tag, tagClass, tagFrom, tagLength, parseObj, tagProperties); wikEd.HighlightBuildTree('headerAttrib', 'open', tagTo, 0, parseObj); break;

// ||: table cell separator, empty file parameter separator, empty template parameters case 'doublePipe': switch (parseObj.lastOpenTagFiltered) { case 'header': wikEd.HighlightBuildTree('header', 'close', tagFrom, 0, parseObj); wikEd.HighlightBuildTree('header', 'open', tagFrom, tagLength, parseObj); wikEd.HighlightBuildTree('headerAttrib', 'open', tagTo, 0, parseObj); break; case 'headerAttrib': wikEd.HighlightBuildTree('headerAttrib', 'close', tagFrom, 0, parseObj); wikEd.HighlightBuildTree('header', 'close', tagFrom, 0, parseObj); wikEd.HighlightBuildTree('header', 'open', tagFrom, tagLength, parseObj); wikEd.HighlightBuildTree('headerAttrib', 'open', tagTo, 0, parseObj); break; case 'cell': wikEd.HighlightBuildTree('cell', 'close', tagFrom, 0, parseObj); wikEd.HighlightBuildTree('cell', 'open', tagFrom, tagLength, parseObj); wikEd.HighlightBuildTree('cellAttrib', 'open', tagTo, 0, parseObj); break; case 'cellAttrib': wikEd.HighlightBuildTree('cellAttrib', 'close', tagFrom, 0, parseObj); wikEd.HighlightBuildTree('cell', 'close', tagFrom, 0, parseObj); wikEd.HighlightBuildTree('cell', 'open', tagFrom, tagLength, parseObj); wikEd.HighlightBuildTree('cellAttrib', 'open', tagTo, 0, parseObj); break; case 'link': wikEd.HighlightBuildTree('linkParam', tagClass, tagFrom, 1, parseObj); break; case 'file': wikEd.HighlightBuildTree('fileParam', tagClass, tagFrom, 1, parseObj); wikEd.HighlightBuildTree('fileParam', tagClass, tagFrom + 1, 1, parseObj); break; case 'template': case 'paramTempl': wikEd.HighlightBuildTree('templateParam', tagClass, tagFrom, 1, parseObj); wikEd.HighlightBuildTree('templateParam', tagClass, tagFrom + 1, 1, parseObj); break; }				break;

// !!: table header separator case 'headerSep': switch (parseObj.lastOpenTagFiltered) { case 'header': wikEd.HighlightBuildTree('header', 'close', tagFrom, 0, parseObj); wikEd.HighlightBuildTree('header', 'open', tagFrom, tagLength, parseObj); wikEd.HighlightBuildTree('headerAttrib', 'open', tagTo, 0, parseObj); break; case 'headerAttrib': wikEd.HighlightBuildTree('headerAttrib', 'close', tagFrom, 0, parseObj); wikEd.HighlightBuildTree('header', 'close', tagFrom, 0, parseObj); wikEd.HighlightBuildTree('header', 'open', tagFrom, tagLength, parseObj); wikEd.HighlightBuildTree('headerAttrib', 'open', tagTo, 0, parseObj); break; }				break;

// |-, |+: table caption, table row case 'tableCaption': case 'row': switch (parseObj.lastOpenTagFiltered) { case 'table': break; case 'tableAttrib': wikEd.HighlightBuildTree('tableAttrib', 'close', tagFrom - 1, 0, parseObj); break; case 'tableCaption': wikEd.HighlightBuildTree('tableCaption', 'close', tagFrom - 1, 0, parseObj); break; case 'captionAttrib': wikEd.HighlightBuildTree('captionAttrib', 'close', openNode.start + openNode.tagLength, 0, parseObj); wikEd.HighlightBuildTree('tableCaption', 'close', tagFrom - 1, 0, parseObj); break; case 'row': wikEd.HighlightBuildTree('row', 'close', tagFrom - 1, 0, parseObj); break; case 'rowAttrib': wikEd.HighlightBuildTree('rowAttrib', 'close', tagFrom - 1, 0, parseObj); wikEd.HighlightBuildTree('row', 'close', tagFrom - 1, 0, parseObj); break; case 'header': wikEd.HighlightBuildTree('header', 'close', tagFrom - 1, 0, parseObj); wikEd.HighlightBuildTree('row', 'close', tagFrom - 1, 0, parseObj); break; case 'headerAttrib': wikEd.HighlightBuildTree('headerAttrib', 'close', tagFrom - 1, 0, parseObj); wikEd.HighlightBuildTree('header', 'close', tagFrom - 1, 0, parseObj); wikEd.HighlightBuildTree('row', 'close', tagFrom - 1, 0, parseObj); break; case 'cell': wikEd.HighlightBuildTree('cell', 'close', tagFrom - 1, 0, parseObj); wikEd.HighlightBuildTree('row', 'close', tagFrom - 1, 0, parseObj); break; case 'cellAttrib': wikEd.HighlightBuildTree('cellAttrib', 'close', tagFrom - 1, 0, parseObj); wikEd.HighlightBuildTree('cell', 'close', tagFrom - 1, 0, parseObj); wikEd.HighlightBuildTree('row', 'close', tagFrom - 1, 0, parseObj); break; }				wikEd.HighlightBuildTree(tag, tagClass, tagFrom, tagLength, parseObj, tagProperties); if (tag == 'row') { wikEd.HighlightBuildTree('rowAttrib', 'open', tagTo, 0, parseObj); }				else if (tag == 'tableCaption') { wikEd.HighlightBuildTree('captionAttrib', 'open', tagTo, 0, parseObj); }				break;

// pipe |: table tableCaption, cell, or header attribute separator, wikilink separator, file parameter separator, template parameter, parameter default case 'pipe': switch (parseObj.lastOpenTagFiltered) { case 'captionAttrib': case 'headerAttrib': case 'cellAttrib':

// save attrib text to open tag: tableCaption, header, cell if (openNode !== undefined) { var attribText = obj.html.substring(openNode.start + openNode.tagLength, tagFrom); var attribEnd = attribText.indexOf('\n'); if (attribEnd == -1) { attribEnd = tagFrom; }							else { attribText = attribText.substr(0, attribEnd); attribEnd = openNode.start + openNode.tagLength + attribEnd - 1; }							if (attribText !== '') { attribText = attribText.replace(/^ +| +$/g, ''); }							parseObj.tree[openNode.parent].attrib = attribText; switch (parseObj.lastOpenTagFiltered) { case 'captionAttrib': wikEd.HighlightBuildTree('captionAttrib', 'close', attribEnd, tagLength, parseObj); break; case 'headerAttrib': wikEd.HighlightBuildTree('headerAttrib', 'close', attribEnd, tagLength, parseObj); break; case 'cellAttrib': wikEd.HighlightBuildTree('cellAttrib', 'close', attribEnd, tagLength, parseObj); break; }						}						break; case 'link': wikEd.HighlightBuildTree('linkParam', tagClass, tagFrom, tagLength, parseObj); break; case 'file': wikEd.HighlightBuildTree('fileParam', tagClass, tagFrom, tagLength, parseObj); break; case 'template': case 'paramTempl': //// check later for parameterPiped wikEd.HighlightBuildTree('templateParam', tagClass, tagFrom, tagLength, parseObj); break; case 'parameter': wikEd.HighlightBuildTree('parameterDefault', tagClass, tagFrom, tagLength, parseObj); break; }				break;

// list and preformatted (leading space) lines case 'preform':

// ignore template parameters preceeded with newline-spaces if (parseObj.lastOpenTagFiltered == 'template') { wikEd.parseObj.regExpTags.lastIndex = tagTo - parseObj.regExpMatch[tagMatchParenth + 3].length; break; }				// run through, no break

case 'list':

// highlight line wikEd.HighlightBuildTree(tag, tagClass, tagFrom, tagLength, parseObj);

// highlight tag wikEd.HighlightBuildTree(tag + 'Tag', tagClass, tagFrom, parseObj.regExpMatch[tagMatchParenth + 2].length, parseObj);

// move text pointer after tag wikEd.parseObj.regExpTags.lastIndex = tagTo - parseObj.regExpMatch[tagMatchParenth + 3].length; break;

// newline, old case 'newline': wikEd.HighlightBuildTree(tag, 'close', tagFrom, 0, parseObj); break;

// unrecognized tag default: parseObj.tree.push( { 'start': tagFrom, 'tagLength': tagLength, 'type': 'error', 'left': wikEd.config.text.wikEdErrorNoHandler } ); }

// quit after reaching $ 'newline' if (tagMatch === '') { break; }	}

// do not tolerate trailing opening tags for whole text highlighting if (parseObj.whole === true) {

// mark remaining unmatched opening tags while ( (parseObj.lastOpenNode !== 0) && (parseObj.lastOpenNode !== null) ) { wikEd.HighlightMarkLastOpenNode(wikEd.config.text.wikEdErrorNoClose, parseObj); }	}

// show parsing tree before // WED('parseObj.tree', parseObj.tree);

// additional block highlighting (autolinking, colors, spaces, dashed, control chars, charents) if (noBlocks !== true) {

// wiki autolinking (case sensitive, newlines are actually allowed!) var regExpMatch; var regExpAutoLink = /((PMID)[ \xa0\t]+(\d+))|((RFC)[ \xa0\t]+(\d+))|((RFC)[ \xa0\t]+(\d+))|((ISBN)[ \xa0\t]+((97(8|9)( |-)?)?(\d( |-)?){9}(\d|x)))/g; while ( (regExpMatch = regExpAutoLink.exec(obj.html) ) !== null) { wikEd.HighlightBuildTree(regExpMatch[2] || regExpMatch[5] || regExpMatch[8] || regExpMatch[11], 'block', regExpMatch.index, regExpMatch[0].length, parseObj); }

// named html colors in quotation marks var regExpColorLight = /('|")(aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|blanchedalmond|burlywood|chartreuse|coral|cornsilk|cyan|darkgray|darkgrey|darkkhaki|darkorange|darksalmon|darkseagreen|floralwhite|fuchsia|gainsboro|ghostwhite|gold|goldenrod|greenyellow|honeydew|hotpink|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightskyblue|lightsteelblue|lightyellow|lime|linen|magenta|mediumaquamarine|mediumspringgreen|mediumturquoise|mintcream|mistyrose|moccasin|navajowhite|oldlace|orange|palegoldenrod|palegreen|paleturquoise|papayawhip|peachpuff|peru|pink|plum|powderblue|salmon|sandybrown|seashell|silver|skyblue|snow|springgreen|tan|thistle|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen)(\1)/gi;		while ( (regExpMatch = regExpColorLight.exec(obj.html) ) !== null) { wikEd.HighlightBuildTree('colorLight', 'block', regExpMatch.index + regExpMatch[1].length, regExpMatch[2].length, parseObj); }		var regExpColorDark = /('|")(black|blue|blueviolet|brown|cadetblue|chocolate|cornflowerblue|crimson|darkblue|darkcyan|darkgoldenrod|darkgreen|darkmagenta|darkolivegreen|darkorchid|darkred|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|forestgreen|gray|green|grey|indianred|indigo|lightseagreen|lightslategray|lightslategrey|limegreen|maroon|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumvioletred|midnightblue|navy|olive|olivedrab|orangered|orchid|palevioletred|purple|red|rosybrown|royalblue|saddlebrown|seagreen|sienna|slateblue|slategray|slategrey|steelblue|teal|tomato)(\1)/g;		while ( (regExpMatch = regExpColorDark.exec(obj.html) ) !== null) {			wikEd.HighlightBuildTree('colorDark', 'block', regExpMatch.index + regExpMatch[1].length, regExpMatch[2].length, parseObj);		}

// RGB hex colors #ddc, exclude links and character entities starting with & var regExpColor3 = /(^|[^\/\w&])(#[0-9a-f]{3})(?=([^\d\w]|$))/gi; while ( (regExpMatch = regExpColor3.exec(obj.html) ) !== null) { wikEd.HighlightBuildTree('colorHex3', 'block', regExpMatch.index + regExpMatch[1].length, regExpMatch[2].length, parseObj); }

// RGB hex colors #d4d0cc, exclude links and character entities starting with & var regExpColor6 = /(^|[^\/\w&])(#[0-9a-f]{6})(?=([^\d\w]|$))/gi; while ( (regExpMatch = regExpColor6.exec(obj.html) ) !== null) { wikEd.HighlightBuildTree('colorHex6', 'block', regExpMatch.index + regExpMatch[1].length, regExpMatch[2].length, parseObj); }

// RGB decimal colors rgb(128,64,265) var regExpColorDec = /\brgb\(\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*\d{1,3}\s*\)/gi; while ( (regExpMatch = regExpColorDec.exec(obj.html) ) !== null) { wikEd.HighlightBuildTree('colorDec', 'block', regExpMatch.index, regExpMatch[0].length, parseObj); }

// single character highlighting: spaces, dashes var regExpCharSpaceDash = new RegExp('[' + wikEd.charHighlightingStr + ']', 'g'); while ( (regExpMatch = regExpCharSpaceDash.exec(obj.html) ) !== null) { wikEd.HighlightBuildTree('char', 'block', regExpMatch.index, regExpMatch[0].length, parseObj); }

// control character highlighting var regExpCharCtrl = new RegExp('[' + wikEd.controlCharHighlightingStr + ']', 'g'); while ( (regExpMatch = regExpCharCtrl.exec(obj.html) ) !== null) { if (regExpMatch[0].charCodeAt(0) > 2) { wikEd.HighlightBuildTree('ctrl', 'block', regExpMatch.index, regExpMatch[0].length, parseObj); }		}

// character entities var regExpCharEntities = /&(\w+);/g; while ( (regExpMatch = regExpCharEntities.exec(obj.html) ) !== null) { if (wikEd.charEntitiesByName[ regExpMatch[1] ] !== null) { wikEd.HighlightBuildTree('charEntity', 'block', regExpMatch.index, regExpMatch[0].length, parseObj); }		}	}	// merge wiki syntax in	wikEd.HighlightAddHtml(parseObj, obj);

// get file previews if ( (wikEd.config.filePreview === true) && (wikEd.filePreviewRequest !== '') ) { wikEd.AjaxPreview(wikEd.filePreviewRequest, wikEd.FilePreviewAjaxHandler); wikEd.filePreviewRequest = ''; }

// merge html and plain text wikEd.HighlightMergeHtml(parseObj, obj);

// free up array parseObj.tree = [];

// \x00 and \x01 back to &lt; and &gt; obj.html = obj.html.replace(/&/g, '&amp;'); obj.html = obj.html.replace(/\x00/g, '&lt;'); obj.html = obj.html.replace(/\x01/g, '&gt;');

// remove linebreaks in tablemode tables if (wikEd.tableMode === true) { obj.html = obj.html.replace(/\n(<(caption|tr|th|td|br)\b[^>]*?\bclass="wikEdTable\w+"[^>]*?>)/g, '$1'); obj.html = obj.html.replace(/(<\/table>?)\n/g, '$1'); }

// WED('obj.html', obj.html); // WED('wikEd.TabifyHTML(obj.html)', wikEd.TabifyHTML(obj.html));

// remove comments if ( (wikEd.config.removeHighlightComments === true) && (keepComments !== true) ) { obj.html = obj.html.replace(//g, ''); }	return; };

// // wikEd.HighlightTreeRedefine: redefine opening tag, for bold / italic and template / parameter //

wikEd.HighlightTreeRedefine = function (openNodeIndex, tag, tagFromDiff, tagLength, parseObj) {

if (typeof tag == 'string') { parseObj.tree[openNodeIndex].tag = tag; }	if (typeof tagFromDiff == 'string') { parseObj.tree[openNodeIndex].start += tagFromDiff; }	if (typeof tagLength == 'string') { parseObj.tree[openNodeIndex].tagLength = tagLength; }	return; };

// // wikEd.HighlightBuildTree: build an array based tree structure of text elements //  tag info: text pos, text length, tag type (root, open, close, block, error) //  connectivity info: parent, firstChild, nextSibling, paired opening/closing (all array indexes)

wikEd.HighlightBuildTree = function (tag, tagClass, tagFrom, tagLength, parseObj, tagProperties) {

// show parameters: // WED('tag, tagClass, tagFrom, tagLength', tag + ' ,' + tagClass + ', ' + tagFrom + ', ' + tagLength);

// single-element tags (block) var pushNode; if (tagClass == 'block') { var previousSibling = null; if ( (parseObj.lastOpenNode !== 0) && (parseObj.lastOpenNode !== null) ) { var redefinedParentTag;

// change parent link to linkPiped, only one valid separator per link if ( (tag == 'linkParam') && (parseObj.lastOpenTag == 'link') ) { redefinedParentTag = 'linkPiped'; }

// change parent link to parameterPiped, only one valid separator per link else if ( (tag == 'parameterDefault') && (parseObj.lastOpenTag == 'parameter') ) { redefinedParentTag = 'parameterPiped'; }

// redefine parent tag if (redefinedParentTag !== undefined) { parseObj.tree[parseObj.lastOpenNode].tag = redefinedParentTag; parseObj.lastOpenTagFiltered = redefinedParentTag; }

// chain blocks var newNode = parseObj.tree.length;

// first node if (parseObj.tree[parseObj.lastOpenNode].firstChild === null) { parseObj.tree[parseObj.lastOpenNode].firstChild = newNode; }

// chain to previous blocks else { previousSibling = parseObj.tree[parseObj.lastOpenNode].lastChild; var previousSiblingNode = parseObj.tree[previousSibling]; if (previousSiblingNode !== undefined) { previousSiblingNode.nextSibling = newNode; }			}			parseObj.tree[parseObj.lastOpenNode].lastChild = newNode; }

// add new block to tree pushNode = { 'tag': tag, 'start': tagFrom, 'tagLength': tagLength, 'type': 'block', 'parent': parseObj.lastOpenNode, 'previousSibling': previousSibling };		parseObj.tree.push(pushNode); }

// opening tags else if (tagClass == 'open') {

// push new open element onto tree pushNode = { 'tag': tag, 'start': tagFrom, 'tagLength': tagLength, 'type': 'open', 'parent': parseObj.lastOpenNode };		parseObj.lastOpenNode = parseObj.tree.push(pushNode) - 1;

// get new top and second-to-top nodes, ignoring unpaired p tags wikEd.HighlightGetLevel(parseObj); }

// closing tags else if (tagClass == 'close') {

// try until we find the correct opening tag after fixing the tree while (true) {

// no opening tag on stack if (parseObj.lastOpenNode === 0) {

// ignore unmatched = if (tag == 'heading') { break; }

// ignore breaking newlines if (tag != 'newline') {

// tolerate leading closing tags for fragment highlighting if ( (parseObj.whole === false) && (parseObj.addedOpenTag === false) ) {

// add new closing element to tree pushNode = { 'tag': tag, 'start': tagFrom, 'tagLength': tagLength, 'type': 'close', 'pairedPos': parseObj.tree[parseObj.lastOpenNode].start + parseObj.tree[parseObj.lastOpenNode].tagLength, };						parseObj.tree.push(pushNode); break; }

// add no open tag error to tree else { pushNode = { 'start': tagFrom, 'tagLength': tagLength, 'type': 'error', 'left': wikEd.config.text.wikEdErrorNoOpen };						parseObj.tree.push(pushNode); break; }				}			}

// ignore unpaired and spare nodes and try again with parent if ( (tag != 'p') && ( (parseObj.lastOpenTag == 'p') || (parseObj.lastOpenTag == 'spare') ) ) { if (parseObj.lastOpenNode !== null) { parseObj.lastOpenNode = parseObj.tree[parseObj.lastOpenNode].parent; parseObj.lastOpenTag = parseObj.lastOpenNode.tag; }				continue; }

// newline breaks heading or external link, remove corresponding opening tag from stack if (tag == 'newline') {

// mark broken opening tags var nodeNo = parseObj.lastOpenNode; var node = null; while ( (nodeNo !== 0) && (nodeNo !== undefined) && (nodeNo !== null) ) { node = parseObj.tree[nodeNo]; if (						(node.tag == 'heading') ||						(node.tag == 'link') ||						(node.tag == 'linkPiped') ||						(node.tag == 'externalText') ||						(node.tag == 'bold') ||						(node.tag == 'italic') ||						(node.tag == 'boldItalic')					) { wikEd.HighlightMarkLastOpenNode(wikEd.config.text.wikEdErrorNewline, parseObj); wikEd.HighlightGetLevel(parseObj); }					nodeNo = node.parent; }				break; }

// correct piped link switch (tag) { case 'link': if (parseObj.lastOpenTag == 'linkPiped') { tag = 'linkPiped'; }					break;

// correct piped parameter case 'parameter': if (parseObj.lastOpenTag == 'parameterPiped') { tag = 'parameterPiped'; }					break; }

// wrong closing element if (tag != parseObj.lastOpenTag) {

// ignore common unmatched false positive non-tags: = and ] if ( (tag == 'heading') ) { break; }

// check if there is an open tag for this close tag var nodeNo = parseObj.lastOpenNode; while ( (nodeNo !== 0) && (nodeNo !== undefined) && (nodeNo !== null) ) { if (parseObj.tree[nodeNo].tag == tag) { break; }					nodeNo = parseObj.tree[nodeNo].parent; }

// treat open tags as wrong, close tag as correct if ( (nodeNo !== 0) && (nodeNo !== undefined) && (nodeNo !== null) && (parseObj.tree[nodeNo].tag == tag) ) {

// mark remaining unmatched opening tags var nodeNo = parseObj.lastOpenNode; while ( (nodeNo !== 0) && (nodeNo !== undefined) && (nodeNo !== null) ) { var node = parseObj.tree[nodeNo]; if (node.tag == tag) { parseObj.lastOpenNode = nodeNo; break; }						nodeNo = node.parent; node.type = 'error'; node.left = wikEd.config.text.wikEdErrorNoClose; node.parent = null; }					wikEd.HighlightGetLevel(parseObj); }

// treat open tags as correct, treat close tag as wrong else {

// add wrong close tag error to tree pushNode = { 'start': tagFrom, 'tagLength': tagLength, 'type': 'error', 'left': wikEd.config.text.wikEdErrorNoOpen };					parseObj.tree.push(pushNode); break; }			}

// headings in templates are ignored but we do not want to hide that template if (tag == 'heading') {

// check for heading in template or ref var ignoreHeading = false; var nodeNo = parseObj.tree[parseObj.lastOpenNode].parent; while ( (nodeNo !== 0) && (nodeNo !== undefined) && (nodeNo !== null) ) { var node = parseObj.tree[nodeNo]; if (node.tag == 'template') { node.noHide = true; ignoreHeading = true; }					else if (node.tag == 'ref') { node.noHide = true; ignoreHeading = true; }					nodeNo = node.parent; }

// clean out opening heading if (ignoreHeading === true) {

// add headings in template errors to tree

// convert opening tag to error wikEd.HighlightMarkLastOpenNode(wikEd.config.text.wikEdErrorTemplHeading, parseObj); pushNode = { 'start': tagFrom, 'tagLength': tagLength, 'type': 'error', 'left': wikEd.config.text.wikEdErrorTemplHeading };					parseObj.tree.push(pushNode); break; }			}

// it is the correct closing element

// save element last text position to opening tag entry var pairedPos; var openNode = parseObj.tree[parseObj.lastOpenNode]; openNode.pairedPos = tagFrom; pairedPos = parseObj.tree[parseObj.lastOpenNode].start + parseObj.tree[parseObj.lastOpenNode].tagLength;

// add new closing element to tree pushNode = { 'tag': tag, 'start': tagFrom, 'tagLength': tagLength, 'type': 'close', 'paired': parseObj.lastOpenNode, 'pairedPos': pairedPos, 'parent': openNode.parent };			parseObj.tree.push(pushNode);

// up one level if ( (parseObj.lastOpenNode !== 0) && (parseObj.lastOpenNode !== null) ) { parseObj.lastOpenNode = parseObj.tree[parseObj.lastOpenNode].parent; }			break; }

// get new top and second-to-top nodes, ignoring unpaired p tags wikEd.HighlightGetLevel(parseObj); }

// add extra properties if ( (pushNode !== undefined) && (tagProperties !== undefined) ) { for (var i = 0; i < tagProperties.length; i ++) { pushNode[tagProperties[i][0]] = tagProperties[i][1]; }	}

return; };

// // wikEd.HighlightMarkLastOpenNode: redefine last open node as an error, ignore p and spare, handle pipe subnodes //

wikEd.HighlightMarkLastOpenNode = function (errorText, parseObj) {

var lastOpenNode = parseObj.lastOpenNode; var openNode = parseObj.tree[lastOpenNode]; parseObj.lastOpenNode = openNode.parent; if ( (openNode.tag != 'p') && (openNode.tag != 'spare') ) {

// mark pipes if ( (openNode.tag == 'linkPiped') || (openNode.tag == 'parameterPiped') || (openNode.tag == 'template') || (openNode.tag == 'paramTempl') ) { var childNode = parseObj.tree[openNode.firstChild]; if (childNode !== undefined) { parseObj.tree[openNode.firstChild] = { 'start': childNode.start, 'tagLength': childNode.tagLength, 'type': 'error', 'left': errorText };			}		}

// mark child nodes of error nodes with lower priority (table elements) wikEd.HighlightMarkNestedErrors(lastOpenNode, errorText, parseObj);

// mark unmatched opening tags parseObj.tree[lastOpenNode] = { 'start': openNode.start, 'tagLength': openNode.tagLength, 'type': 'error', 'left': errorText };	}	return; };

// // wikEd.HighlightMarkNestedErrors: mark child nodes of error nodes with lower priority (table elements) //

wikEd.HighlightMarkNestedErrors = function (parent, errorText, parseObj) {

var tagNesting = { 'table':  'tableCaption|row|tableAttrib', 'tableCaption': 'captionAttrib', 'row':    'header|cell|rowAttrib', 'header': 'headerAttrib', 'cell':   'cellAttrib' };

var regExp = null; if (tagNesting.hasOwnProperty(parseObj.tree[parent].tag) === true) { regExp = new RegExp('^(' + tagNesting[parseObj.tree[parent].tag ]+ ')$'); }

for (var i = 0; i < parseObj.tree.length; i ++) { var node = parseObj.tree[i]; if ( (node.parent == parent) && (regExp !== null) && (regExp.test(node.tag) === true) ) { wikEd.HighlightMarkNestedErrors(i, errorText, parseObj); node.type = 'error'; node.left = errorText; }	}	return; };

// // wikEd.HighlightGetLevel: get current innermost (top) element name from parse stack, ignoring unpaired p tags //

wikEd.HighlightGetLevel = function (parseObj) {

parseObj.lastOpenTag = null; parseObj.lastOpenNodeFiltered = null; parseObj.lastOpenTagFiltered = null; parseObj.secondlastOpenNodeFiltered = null; parseObj.secondlastOpenTagFiltered = null;

if ( (parseObj.lastOpenNode === 0) || (parseObj.lastOpenNode === null) ) { return; }

parseObj.lastOpenTag = parseObj.tree[parseObj.lastOpenNode].tag; var nodeNo = parseObj.lastOpenNode; while ( (nodeNo !== 0) && (nodeNo !== undefined) && (nodeNo !== null) ) { var node = parseObj.tree[nodeNo]; if ( (node.tag != 'p') && (node.tag != 'spare') ) { parseObj.lastOpenNodeFiltered = nodeNo; parseObj.lastOpenTagFiltered = parseObj.tree[nodeNo].tag; break; }		nodeNo = parseObj.tree[nodeNo].parent; }

if ( (nodeNo !== 0) && (nodeNo !== null) ) { nodeNo = parseObj.tree[nodeNo].parent; while ( (nodeNo !== 0) && (nodeNo !== undefined) && (nodeNo !== null) ) { var node = parseObj.tree[nodeNo]; if ( (node.tag != 'p') && (node.tag != 'spare') ) { parseObj.secondlastOpenNodeFiltered = nodeNo; parseObj.secondlastOpenTagFiltered = parseObj.tree[nodeNo].tag; break; }			nodeNo = parseObj.tree[nodeNo].parent; }	}

return; };

// // wikEd.HighlightAddCode: add actual highlighting html code to parse tree elements //

wikEd.HighlightAddHtml = function (parseObj, obj) {

// cycle through currently existing parse array var from = 0; var i = 0; var cellCount = 0; while (i < parseObj.tree.length) {

var node = parseObj.tree[i]; var tag = node.tag; var tagFrom = node.start; var tagLength = node.tagLength; var tagType = node.type; var pairedPos = node.pairedPos; var tagTo = tagFrom + tagLength; var tagMatch = ''; if (tagLength > 0) { tagMatch = obj.html.substr(tagFrom, tagLength); }

var insertLeft = ''; var insertRight = ''; var pushRight = ''; var pushRight2 = ''; var pushRightPos2; var pushLeft = '';

// get sanitized attributes var attrib = ''; if ( (node.attrib !== undefined) && (node.attrib !== '') ) { var htmlTag = ''; switch (tag) { case 'table': htmlTag = 'table'; break; case 'tableCaption': htmlTag = 'tr'; break; case 'row': htmlTag = 'tr'; break; case 'header': htmlTag = 'th'; break; case 'cell': htmlTag = 'td'; break; }			if (htmlTag !== '') { attrib = wikEd.SanitizeAttributes(htmlTag, node.attrib, true); if (attrib !== '') {

// adjust rowspan in headers and cells if ( (htmlTag == 'th') || (htmlTag == 'td') ) { attrib = attrib.replace(/\b(rowspan\s*=\s*('|"|)\s*\+?)(\d+)(\s*\2)/gi,							function (p, p1, p2, p3, p4) {								return p1 + (p3 * 2 - 1) + p4;							}						);					}					attrib = ' ' + attrib;				}			}		}

// get parent and paired var parent = null; if ( (node.parent !== undefined) && (node.parent !== null) && (node.parent > 0) ) { parent = parseObj.tree[node.parent]; }		var paired = null; if ( (node.paired !== undefined) && (node.paired > 0) ) { paired = parseObj.tree[node.paired]; }

// get linebreaks before tag var newlineClass = ''; var newlineHtml = ''; if (node.newline === true) {

// add actual linebreak after headers/cells instead for pasting of table to raw text (still adds tabs as cell separators) if ( (cellCount > 0) && (tagType == 'open') && ( (tag == 'header') || (tag == 'cell') ) ) { newlineHtml = '  '; }			else { newlineClass = 'BR'; }		}		var parentNewlineClass = ''; if ( (parent !== null) && (parent.newline === true) ) { parentNewlineClass = 'BR'; }		var pairedNewlineClass = ''; if ( (paired !== null) && (paired.newline === true) ) { pairedNewlineClass = 'BR'; }

switch (tagType) {

// tag type: open case 'open': var innerPlain = ''; if (pairedPos !== undefined) { innerPlain = obj.html.substring(tagTo, pairedPos); }				switch (tag) { case 'italic': insertLeft = ' '; insertRight = ' '; break; case 'bold': insertLeft = ' '; insertRight = ' '; break; case 'link': case 'linkPiped': var linkClass = 'wikEdLink'; var follow = ''; var interClean = ''; var nsClean = '';

// detect interlink and namespace //                1   123 inter: 3     2 45  :  5 6        namespace           64 7template 7   8  9param  98 var regExpLink = /^(\s*)(([\w\- ]+)\:\s*)?((\:\s*)?([^\:\|\[\]\{\}\n\t]*\s*\:\s*))?([^\|\n]+?)\s*(\|((.|\n)*))?\s*$/gi; regExpLink.lastIndex = 0; var regExpMatch; if ( (regExpMatch = regExpLink.exec(innerPlain)) !== null) {

// get interwiki, namespace, article, paramters var pre = regExpMatch[1] || ''; var inter = regExpMatch[2] || ''; var ns = regExpMatch[4] || ''; var article = regExpMatch[7] || ''; var param = regExpMatch[9] || '';

if (inter !== '') { interClean = inter; interClean = interClean.replace(/\s/g, ' '); interClean = interClean.replace(/ {2,}/g, ' '); interClean = interClean.replace(/: +:/, ''); interClean = interClean.replace(/^ $/, ''); }							var interStart = tagTo + regExpMatch.index + pre.length;

if (ns !== '') { nsClean = ns; nsClean = nsClean.replace(/\s/g, ' '); nsClean = nsClean.replace(/ {2,}/g, ' '); nsClean = nsClean.replace(/: :/, ''); nsClean = nsClean.replace(/^ $/, ''); }							var nsStart = interStart + ns.length;

// change interwiki into more common namespace if ambiguous if ( (interClean !== ) && (nsClean === ) ) { ns = inter; nsClean = interClean; nsStart = interStart; inter = ''; interClean = ''; }

// detect cross-namespace links linkClass = 'wikEdLink'; if (wikEd.pageNamespace !== null) { if (ns != wikEd.pageNamespace) { linkClass = 'wikEdLinkCrossNs'; }							}

// highlight interwiki and namespace if (article !== '') {

// highlight interwiki if (inter !== '') { wikEd.HighlightBuildTree('linkInter', 'block', interStart, inter.length, parseObj); }

// highlight namespace if (ns !== '') { wikEd.HighlightBuildTree('linkNamespace', 'block', nsStart, ns.length, parseObj); }

// linkify var regExpCasing = new RegExp('(^|\\:)' + wikEd.config.text['wikicode Category'] + '(\\:|$)', 'i'); nsClean = nsClean.replace(regExpCasing, '$1' + wikEd.config.text['wikicode Category'] + '$2'); if (nsClean == ':') { nsClean = ''; }								follow = ' ' + wikEd.HighlightLinkify(interClean + nsClean, article); }						}

if (nsClean.toLowerCase == wikEd.config.text['wikicode Category'].toLowerCase + ':') { insertLeft = ' '; insertRight = ' '; }						else if (tag == 'linkPiped') { insertLeft = ' '; insertRight = ' '; }						else { insertLeft = ' '; insertRight = ' '; }						break; case 'file': var previewCode = ''; var regExpFile = new RegExp('^\\s*(Image|File|Media|' + wikEd.config.text['wikicode Image'] + '|' + wikEd.config.text['wikicode File'] + '|' + wikEd.config.text['wikicode Media'] + ')\\s*:\\s*([^\\|\\n]*)', 'i'); var regExpMatch = regExpFile.exec(innerPlain); if (regExpMatch === null) { insertLeft = ' '; }

// linkify and preview else { var fileTag = regExpMatch[1]; var fileName = regExpMatch[2];

// add file preview box var filePlain = fileTag + ':' + fileName.replace(/<[^>]*>/g, ''); filePlain = filePlain.replace(/ /g,'_'); if (wikEd.config.filePreview === true) {

// get image size var filePreviewSize = wikEd.config.filePreviewSize; var regExpMatch; if ( (regExpMatch = /\|(\d+)px(\||$)/.exec(innerPlain)) !== null) { var size = parseInt(regExpMatch[1]); if ( (size > 0) && (size < wikEd.config.filePreviewSize) ) { filePreviewSize = size; }								}

// get image url and size from cache var style = ''; var fileObj = wikEd.filePreviewCache['wikEd' + filePlain + filePreviewSize]; if (fileObj !== undefined) { var filePreviewHeight = filePreviewSize; if (fileObj.height !== null) { filePreviewHeight = fileObj.height; }									var filePreviewWidth = filePreviewSize; if (fileObj.width !== null) { filePreviewWidth = fileObj.width; }									style = 'background-image: url(' + fileObj.url + '); height: ' + filePreviewHeight + 'px; width: ' + filePreviewWidth + 'px;'; }

// get image url and size through an ajax request else { style = 'display: none; height: ' + filePreviewSize + 'px; width: ' + filePreviewSize + 'px;'; var fileTagPreview = fileTag; if ( (fileTag == 'Media') || (fileTag == wikEd.config.text['wikicode Media']) ) { fileTagPreview = 'File'; }									wikEd.filePreviewRequest += '\n' + filePlain + ' ' + filePreviewSize + ' ' + filePreviewSize + 'px|' + filePreviewSize + 'x' + filePreviewSize + 'px\n'; wikEd.filePreviewIds[wikEd.filePreviewNo] = filePlain + filePreviewSize; }								previewCode = ' '; wikEd.filePreviewNo ++; }							insertLeft += ' '; }						insertRight = previewCode + ' '; break; case 'external': var url = ''; var regExpMatch; if ( (regExpMatch = /\w\S+/.exec(innerPlain)) !== null) { url = regExpMatch[0]; }						insertLeft = ' '; insertRight = ' '; break; case 'externalText': insertLeft = ' '; break; case 'template': var mod = ''; var inter = ''; var interClean = ''; var ns = ''; var nsClean = ''; var template = ''; var param = ''; var follow = '';

//                                12          mod              2  :    1 34  :    4 5        namespace                 53     6 template            6    7   89 param  98 var regExpTempl = new RegExp('^\\s*((' + wikEd.templModifier + ')\\:\\s*)?((\\:\\s*)?([^:|\\[\\]{}\\s\\x00\\x01]*\\s*\\:))?\\s*([^:\\n\\x00\\x01{}]+?)\\s*(\\|((.|\\n)*?))?\\s*$', 'gi');

// detect parser variables and functions, might slow main regexp down var regExpMatch; var isParserVar = false; if ( (regExpMatch = regExpTempl.exec(innerPlain)) !== null) {

// get modifier, namespace, template, paramters var p1 = regExpMatch[1] || ''; if (p1 !== '') { mod = p1; interClean = mod.replace(/\s+$/g, ''); interClean = inter.replace(/:$/g, ''); }

var p3 = regExpMatch[3] || ''; if (p3 !== '') { ns = p3; nsClean = ns.replace(/^\s+|\s+$/g, ''); nsClean = nsClean.replace(/\s*\:\s*/g, ':'); nsClean = nsClean.replace(/\s\s+/g, ' '); nsClean = nsClean.replace(/(.):$/g, '$1'); }

template = regExpMatch[6] || ''; param = regExpMatch[8] || ''; var parserVar = ns.substr(0, ns.length - 1);

// VARIABLE if (isParserVar === false) { if ( (template !== ) && (ns === ) && (param === '') ) { var regExpParserVar = new RegExp('^(' + wikEd.parserVariables + '|' + wikEd.parserVariablesR + ')$', ''); var regExpMatchParserVar; if ( (regExpMatchParserVar = regExpParserVar.exec(template)) !== null) { isParserVar = true; wikEd.HighlightBuildTree('templateParserFunct', 'block', tagFrom + 2, innerPlain.length, parseObj); }								}							}

// VARIABLE:R if (isParserVar === false) { if ( (ns !== '') && (template == 'R') ) { var regExpParserVar = new RegExp('^(' + wikEd.parserVariablesR + ')$', ''); var regExpMatchParserVar; if ( (regExpMatchParserVar = regExpParserVar.exec(parserVar)) !== null) { isParserVar = true; wikEd.HighlightBuildTree('templateParserFunct', 'block', tagFrom + 2, innerPlain.indexOf(':') + 1, parseObj); }								}							}

// FUNCTION:param|R if (isParserVar === false) { if ( (ns !== ) && ( (param === ) || (param == 'R') ) ) { var regExpParserVar = new RegExp('^(' + wikEd.parserFunctionsR + ')$', ''); if ( (regExpMatch = regExpParserVar.exec(parserVar)) !== null) { isParserVar = true; wikEd.HighlightBuildTree('templateParserFunct', 'block', tagFrom + 2, innerPlain.indexOf(':') + 1, parseObj); }								}							}

// function:param|param if (isParserVar === false) { if (ns !== '') { var regExpParserVar = new RegExp('^(' + wikEd.parserFunctions + ')$', 'i'); if ( (regExpMatch = regExpParserVar.exec(parserVar)) !== null) { isParserVar = true; wikEd.HighlightBuildTree('templateParserFunct', 'block', tagFrom + 2, innerPlain.indexOf(':') + 1, parseObj); }								}							}

// 							if (isParserVar === false) { if (ns !== '') { var regExpParserVar = new RegExp('^(#(' + wikEd.parserFunctionsHash + '))$', 'i'); if ( (regExpMatch = regExpParserVar.exec(parserVar)) !== null) {

// #property: linkify wikibase template (wikidata) if (parserVar == '#property') {

// item id from parameter var item = ''; var regExpMatchItem; if ( (regExpMatchItem = /(^|\|)id=([^|]+)/.exec(param)) !== null) { item = regExpMatchItem[2]; }

// item name from parameter else if ( (regExpMatchItem = /(^|\|)of=([^|]+)/.exec(param)) !== null) { item = wikEd.EncodeTitle(regExpMatchItem[2]); item = 'Special:ItemByTitle/' + wikEd.wikibase.currentSite.globalSiteId + '/' + item; }

// get item name from article name else { item = wikEd.EncodeTitle; item = 'Special:ItemByTitle/' + wikEd.wikibase.currentSite.globalSiteId + '/' + item ; }

// get wikibase repository url follow = ' ' + wikEd.HighlightLinkify(, , (wikEd.wikibase.repoUrl + wikEd.wikibase.repoArticlePath).replace(/\$1/, item)); }

// #invoke: template scripting (LUA) if (parserVar == '#invoke') { follow = ' ' + wikEd.HighlightLinkify('Module:', template); }

isParserVar = true; wikEd.HighlightBuildTree('templateParserFunct', 'block', tagFrom + 2, innerPlain.indexOf(':') + 1, parseObj); }								}							}

// highlight template if (isParserVar === false) {

// highlight modifier if (mod !== '') { wikEd.HighlightBuildTree('templateModifier', 'block', tagFrom + 2, mod.length, parseObj); }

// highlight namespace if (ns !== '') { wikEd.HighlightBuildTree('templateNamespace', 'block', tagFrom + 2 + mod.length, ns.length, parseObj); }

// add missing template namespace and linkify if (ns == ':') { ns = ''; }								else if (ns === '') {

// no Template: addition for subpage linking if (template.indexOf('/')!== 0) { ns = wikEd.config.text['wikicode Template'] + ':'; }								}								follow = ' ' + wikEd.HighlightLinkify(ns, template); }						}						var hideClass = 'wikEdTempl'; if ( (template !== '') && (isParserVar === false) ) { if (wikEd.refHide === true) {

// show first template immediately following a template or reference var hideButtonClass = 'wikEdTemplButton'; var hideButtonStyle = ''; if (parent !== null) { if ( (parent.tag == 'template') || (parent.tag == 'ref') ) { if (/^\s*$/.test(obj.html.substring(parent.start + parent.tagLength, tagFrom)) === true) { hideButtonClass = hideButtonClass.replace(/Button(Show)?/, 'ButtonShow'); hideClass = 'wikEdTemplShow'; hideButtonStyle = ' style="display: block"'; }									}								}								insertLeft = '  '; wikEd.templateArray.push( {'text': template, 'added': false} ); }						}						insertLeft += ' '; insertRight = ' '; break; case 'parameter': case 'parameterPiped': insertLeft = ' '; pushRight = ' '; break; case 'html': case 'tr': case 'td': case 'th': case 'col': case 'thead': case 'tfoot': case 'tbody': case 'colgroup': case 'abbr': case 'big': case 'blockquote': case 'center': case 'code': case 'del': case 'div': case 'font': case 'ins': case 'small': case 'span': case 'strike': case 'tt': case 'rb': case 'rp': case 'rt': case 'ruby': case 'nowiki': case 'math': case 'score': case 'noinclude': case 'includeonly': case 'onlyinclude': case 'gallery': case 'categorytree': case 'charinsert': case 'hiero': case 'imagemap': case 'inputbox': case 'poem': case 'syntaxhighlight': case 'source': case 'timeline': insertLeft = ' '; pushRight = ' '; break; case 'u': insertLeft = ' '; pushRight = ' '; break; case 's': insertLeft = ' '; pushRight = ' '; break; case 'sub': insertLeft = ' '; pushRight = ' '; break; case 'sup': insertLeft = ' '; pushRight = ' '; break; case 'p': insertLeft = ''; pushRight = ' '; break; case 'spare': break; case 'ref':

// ref no hide if (node.noHide === true) { insertLeft = ' '; }

// ref hide else { var refName = ''; var regExpMatch; if ( (regExpMatch = /(\bname\s*=\s*('|"))([^\x01]+?)\2/i.exec(tagMatch)) !== null) {								refName = regExpMatch[3] || ;								wikEd.HighlightBuildTree('refName', 'block', tagFrom + regExpMatch.index + regExpMatch[1].length, regExpMatch[3].length, parseObj);							}							else if ( (regExpMatch = /(\bname\s*=\s*)(\w+)/i.exec(tagMatch)) !== null) {								refName = regExpMatch[2];								wikEd.HighlightBuildTree('refName', 'block', tagFrom + regExpMatch.index + regExpMatch[1].length, regExpMatch[2].length, parseObj);							}							if (wikEd.refHide === true) {								if (refName !== ) {									insertLeft = '  ';									wikEd.referenceArray.push( {'text': refName, 'added': false} );								}								else {									insertLeft = '  '; }							}							insertLeft += ' '; pushRight = ' '; }						break; case 'references': insertLeft = ' '; pushRight = ' '; break; case 'heading': var heading = innerPlain.replace(/^\s+|\s+$/g, ''); if ( (heading == wikEd.config.text['See also']) || (heading == wikEd.config.text.References) || (heading == wikEd.config.text['External links']) ) { insertLeft = ' '; }						else { insertLeft = ' '; }						break;

// table open case 'table': if (wikEd.tableMode === true) { insertLeft = ' '; }						else { insertLeft = ' '; insertRight = '  '; }						break; case 'tableAttrib': if (wikEd.tableMode === true) { if (parent.attrib !== undefined) { insertRight = ' '; }							if (wikEd.refHide === true) { insertRight += ' '; }							insertRight += '  '; }						else { if (parent.attrib !== undefined) { insertRight = ' '; }						}						break; case 'tableCaption': if (wikEd.tableMode === true) { insertRight = '  '; }						else { insertRight = ' '; }						break; case 'captionAttrib': if (wikEd.tableMode === true) { if (parent.attrib !== undefined) { insertLeft = ' '; insertRight = ' '; if (wikEd.refHide === true) { insertRight += ' '; }							}							else { insertRight = ''; }						}						else { if (parent.attrib !== undefined) { insertLeft = ' '; insertRight = ' '; }						}						break; case 'row': if ( (paired !== null) && (paired.tagLength > 0) ) { insertRight = ' '; }						else { insertRight = ' '; }						break; case 'rowAttrib': var parentAttrib = parent.attrib || ''; if (parentAttrib !== '') { parentAttrib = wikEd.SanitizeAttributes('tr', parentAttrib, true); if (parentAttrib !== '') { parentAttrib = ' ' + parentAttrib; }						}						if (wikEd.tableMode === true) { if (parent.attrib !== undefined) { insertRight = ' '; }							if (wikEd.refHide === true) { insertRight += ' '; }							insertRight += '  <tr class="wikEdTableRow"' + parentAttrib + '>'; }						else { if (parent.attrib !== undefined) { insertRight = ' '; }							insertRight += ' '; }						break; case 'header': if (wikEd.tableMode === true) { insertRight = ' '; }						else { insertRight = ' '; }						break; case 'headerAttrib': if (wikEd.tableMode === true) { if (parent.attrib !== undefined) { insertLeft = ' '; insertRight = ' '; if (wikEd.refHide === true) { insertRight += ' '; }							}						}						else { if (parent.attrib !== undefined) { insertLeft = ' '; insertRight = ' '; }						}						break; case 'cell': if (wikEd.tableMode === true) { insertRight = ' '; }						else { insertRight = ' '; }						break; case 'cellAttrib': if (wikEd.tableMode === true) { if (parent.attrib !== undefined) { insertLeft = ' '; insertRight = ' '; if (wikEd.refHide === true) { insertRight += ' '; }							}						}						else { if (parent.attrib !== undefined) { insertLeft = ' '; insertRight = ' '; }						}						break; }				break;

// tag type: block case 'block': switch (tag) { case 'linkNamespace': insertLeft = ' '; pushRight = ' '; break; case 'linkInter': insertLeft = ' '; pushRight = ' '; break; case 'inlineURL': var url = ''; var regExpMatch; if ( (regExpMatch = /\w\S+/.exec(tagMatch)) !== null) { url = regExpMatch[0]; }						insertLeft = '<span class="wikEdURLName" ' + wikEd.HighlightLinkify(, , url) + '>'; pushRight = ' '; break; case 'externalURL': insertLeft = ' '; pushRight = ' '; break; case 'templateModifier': insertLeft = ' '; pushRight = ' '; break; case 'templateNamespace': insertLeft = ' '; pushRight = ' '; break; case 'templateParserFunct': insertLeft = ' '; pushRight = ' '; break; case 'PMID': var idNumber = ''; var regExpMatch; if ( (regExpMatch = /\d+/.exec(tagMatch)) !== null) { idNumber = regExpMatch[0]; }						insertLeft = '<span class="wikEdPMID" ' + wikEd.HighlightLinkify(, , '//www.ncbi.nlm.nih.gov/pubmed/' + idNumber) + '>'; insertRight = ' '; break; case 'ISBN': var idNumber = ''; var regExpMatch; if ( (regExpMatch = /\d[\s\d\-]+x?/.exec(tagMatch)) !== null) { idNumber = regExpMatch[0].replace(/\D/g, ''); }						insertLeft = '<span class="wikEdISBN" ' + wikEd.HighlightLinkify('', 'Special:BookSources/' + idNumber) + '>'; pushRight = ' '; break; case 'RFC': var idNumber = ''; var regExpMatch; if ( (regExpMatch = /\d[\s\d\-]+x?/.exec(tagMatch)) !== null) { idNumber = regExpMatch[0].replace(/\D/g, ''); }						insertLeft = '<span class="wikEdISBN" ' + wikEd.HighlightLinkify(, , '//tools.ietf.org/html/rfc' + idNumber) + '>'; pushRight = ' '; break; case 'magic': insertLeft = ' '; insertRight = ' '; break; case 'signature': var title = wikEd.config.text['wikEdSignature' + tagLength]; insertLeft = '<span class="wikEdSignature" title="' + title + '">'; insertRight = ' '; break; case 'hr': pushLeft = ' '; pushRight = ' '; break; case 'linkParam': insertLeft = ' '; insertRight = ' '; break; case 'fileParam':

// make text parameters a caption var params = ''; if (pairedPos !== undefined) { params = obj.html.substring(tagFrom + 1, parent.pairedPos - 1); }						if (/^\s*(thumb|thumbnail|frame|right|left|center|none|\d+px|\d+x\d+px|link\=.*?|upright|border)\s*(\||$)/.test(params) === true) { insertLeft = ' '; insertRight = ' '; }						else { insertLeft = ' '; insertRight = ' '; }						break; case 'redirect': insertLeft = ' '; pushRight = ' '; break; case 'templateParam': insertLeft = ' '; pushRight = ' '; break; case 'parameterDefault': insertLeft = ' '; insertRight = ' '; break; case 'void': case 'html': case 'htmlEmpty': insertLeft = ' '; pushRight = ' '; break; case 'htmlUnknown': insertLeft = '<span class="wikEdHtmlUnknown" title="' + wikEd.config.text.wikEdErrorHtmlUnknown + '">'; pushRight = ' '; break; case 'ref': var refName = ''; var regExpMatch; if ( (regExpMatch = /(\bname\s*=\s*('|"))([^\x01]+?)\2/i.exec(tagMatch)) !== null) {							refName = regExpMatch[3];							wikEd.HighlightBuildTree('refName', 'block', tagFrom + regExpMatch.index + regExpMatch[1].length, regExpMatch[3].length, parseObj);						}						else if ( (regExpMatch = /(\bname\s*=\s*)(\w+)/i.exec(tagMatch)) !== null) {							refName = regExpMatch[2];							wikEd.HighlightBuildTree('refName', 'block', tagFrom + regExpMatch.index + regExpMatch[1].length, regExpMatch[2].length, parseObj);						}						if (wikEd.refHide === true) {							if (refName !== '') {								insertLeft = ' <button class="wikEdRefButton' + wikEd.referenceArray.length + '" title="' + wikEd.config.text.wikEdRefButtonTooltip + '"> ';								wikEd.referenceArray.push( {'text': refName + ' ↑', 'added': false} );							}							else {								insertLeft = ' <button class="wikEdRefButton" title="' + wikEd.config.text.wikEdRefButtonTooltip + '"> '; }						}						insertLeft += ' '; pushRight = ' '; break; case 'references': insertLeft = ' '; pushRight = ' '; break; case 'pre': insertLeft = ' '; pushRight = ' '; break; case 'math': insertLeft = ' '; pushRight = ' '; break; case 'score': insertLeft = ' '; pushRight = ' '; break; case 'nowiki': insertLeft = ' '; pushRight = ' '; break; case 'listTag': insertLeft = ' '; insertRight = ' '; break; case 'preformTag': insertLeft = ' '; insertRight = ' '; break; case 'refName': insertLeft = ' '; pushRight = ' '; break; case 'list': pushLeft = ' '; pushRight = ' '; break; case 'preform': pushLeft = ' '; pushRight = ' '; break; case 'colorLight': insertLeft = '<span style="background: ' + tagMatch + '" class="wikEdColorsLight">'; insertRight = ' '; break; case 'colorDark': insertLeft = '<span style="background: ' + tagMatch + '" class="wikEdColorsDark">'; insertRight = ' '; break; case 'colorHex3': var regExpMatch = /([0-9a-f])([0-9a-f])([0-9a-f])/i.exec(tagMatch); if ( (regExpMatch[1] > 255) || (regExpMatch[2] > 255) || (regExpMatch[3] > 255) ) { break; }						var luminance = parseInt(regExpMatch[1], 16) * 16 * 0.299 + parseInt(regExpMatch[2], 16) * 16 * 0.587 + parseInt(regExpMatch[3], 16) * 16 * 0.114; if (luminance > 128) { insertLeft = '<span style="background: ' + tagMatch + '" class="wikEdColorsLight">'; insertRight = ' '; }						else { insertLeft = '<span style="background: ' + tagMatch + '" class="wikEdColorsDark">'; insertRight = ' '; }						break; case 'colorHex6': var regExpMatch = /([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})/i.exec(tagMatch); if ( (regExpMatch[1] > 255) || (regExpMatch[2] > 255) || (regExpMatch[3] > 255) ) { break; }						var luminance = parseInt(regExpMatch[1], 16) * 0.299 + parseInt(regExpMatch[2], 16) * 0.587 + parseInt(regExpMatch[3], 16) * 0.114; if (luminance > 128) { insertLeft = '<span style="background: ' + tagMatch + '" class="wikEdColorsLight">'; insertRight = ' '; }						else { insertLeft = '<span style="background: ' + tagMatch + '" class="wikEdColorsDark">'; insertRight = ' '; }						break; case 'colorDec': var regExpMatch = /(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/i.exec(tagMatch); if ( (regExpMatch[1] > 255) || (regExpMatch[2] > 255) || (regExpMatch[3] > 255) ) { break; }						var luminance = regExpMatch[1] * 0.299 + regExpMatch[2] * 0.587 + regExpMatch[3] * 0.114; if (luminance > 128) { insertLeft = '<span style="background: ' + tagMatch + '" class="wikEdColorsLight">'; insertRight = ' '; }						else { insertLeft = '<span style="background: ' + tagMatch + '" class="wikEdColorsDark">'; insertRight = ' '; }						break; case 'ctrl': insertLeft = '<span class="wikEdCtrl" title="' + wikEd.controlCharHighlighting[tagMatch.charCodeAt(0).toString] + '">'; insertRight = ' '; break; case 'char': var charName = wikEd.charHighlighting[tagMatch.charCodeAt(0).toString]; var charClass = 'wikEd' + charName; insertLeft = '<span class="' + charClass + '" title="' + wikEd.config.text[charName] + '">'; insertRight = ' '; break; case 'charEntity': var regExpMatch = /&(\w+);/i.exec(tagMatch); var character = wikEd.charEntitiesByName[ regExpMatch[1] ]; if (character !== undefined) { if (wikEd.refHide === true) { insertLeft = ' <button class="wikEdCharEntityButton' + wikEd.charEntityArray.length + '" title="' + wikEd.config.text.wikEdCharEntityButtonTooltip + '"> '; wikEd.charEntityArray.push( {'text': character, 'added': false} ); }							insertLeft += ' '; insertRight = ' '; }						break; }				break;

// tag type: various case 'comment': insertLeft = ' ' + node.left + ' '; break; case 'keep': insertLeft = ' ' + node.left + ' '; break; case 'error': insertLeft = '<span class="wikEdError" title="' + node.left + '">'; if (wikEd.config.highlightError === true) { insertLeft += ' ' + node.left + ' '; }				pushRight = ' '; break; case 'note': // for debugging insertLeft = ' ' + node.tagLength + ' '; break; case 'root': break; case undefined: break; }

// add left html into existing entry if (insertLeft !== '') { node.left = insertLeft; node.index = i;		}

// add left html as new array element to allow for overlapping highlighting as in hr		else if (pushLeft !== '') { parseObj.tree.push( { 'start': tagFrom, 'tagLength': 0, 'left': pushLeft, 'index': i - 0.5 } ); }

// add right html into existing entry if (insertRight !== '') { node.right = insertRight; node.index = i;		}

// add right html as new array element to allow for overlapping highlighting as in html-like tags and urls else if (pushRight !== '') { parseObj.tree.push( { 'start': tagTo, 'tagLength': 0, 'right': pushRight, 'index': i + 0.5 } ); }		if (pushRight2 !== '') { parseObj.tree.push( { 'start': pushRightPos2, 'tagLength': 0, 'right': pushRight2, 'index': i + 0.5 } ); }

from = tagTo; i ++; }

return; };

// // wikEd.HighlightMergeHtml: merge parse tree highlighting html code with article text //

wikEd.HighlightMergeHtml = function (parseObj, obj) {

if (parseObj.tree.length <= 1) { return; }

// sort parse array by position, length, and index parseObj.tree.sort(		function(a, b) {

// by start position if (a.start != b.start) { return a.start - b.start; }

// by length if (a.tagLength != b.tagLength) { return a.tagLength - b.tagLength; }

// by index return a.index - b.index; }	);

// add comments and highlighting var from = 0; var htmlArray = [];

// cycle through parse array and assemble html array for (var i = 0; i < parseObj.tree.length; i ++) { var node = parseObj.tree[i]; var tagFrom = node.start; var tagLength = node.tagLength; var htmlLeft = node.left; var htmlRight = node.right; var tagTo = tagFrom + tagLength;

// drop overlapping highlighting //// |- in tables?! if (tagFrom < from) { continue; }

// ignore root if (tagFrom === undefined) { continue; }

// push leading plain text htmlArray.push(obj.html.substring(from, tagFrom));

// push left html if (htmlLeft !== undefined) { htmlArray.push(htmlLeft); }

// push right html if (htmlRight !== undefined) { htmlArray.push(obj.html.substring(tagFrom, tagTo)); htmlArray.push(htmlRight); from = tagTo; }		else { from = tagFrom; }	}	htmlArray.push(obj.html.substring(from));

// join html array obj.html = htmlArray.join('');

// display highlighted html: // WED(obj.html.replace(/\x00/g, '&lt;').replace(/\x01/g, '&gt;'));

return; };

// // wikEd.HighlightLinkify: prepare the span tag parameters for ctrl-click opening of highlighted links, addding redirect info, and highlighting redlinks //

wikEd.HighlightLinkify = function (linkPrefix, linkTitle, linkUrl) {

var linkName = ''; var subpage = false; var link = ''; var info = '';

// generate url from interlanguage or namespace prefix and title if (typeof linkUrl != 'string') {

// test for illegal characters if (/[\{\|\}\[\]<>#]/.test(linkPrefix) === true) { return ''; }

// clean prefix and title linkPrefix = wikEd.CleanLink(linkPrefix); linkTitle = wikEd.CleanLink(linkTitle); linkName = linkPrefix + linkTitle; link = linkName;

// character accentuation for Esperanto, see Help:Special_characters if (wikEd.wikiGlobals.wgContentLanguage == 'eo') { linkTitle = linkTitle.replace(/([cghjsu])(x+)/gi,				function(p, p1, p2) {					var accentChar = p1;					var xString = p2;					var xLength = xString.length;					var xCount = Math.floor(xLength / 2);					if ( (xLength / 2 - xCount) > 0) {						var pos = 'CGHJSUcghjsu'.indexOf(accentChar);						accentChar = 'ĈĜĤĴŜŬĉĝĥĵŝŭ'.substr(pos, 1);						xString = xString.replace(/^x|(x)x/gi, '$1');					}					else {						xString = xString.replace(/(x)x/gi, '$1');					}					return accentChar + xString;				}			); }

// /subpage refers to a subpage of the current page, to a section of the current page if ( (linkPrefix === '') && ( (linkTitle.indexOf('/')=== 0) || (linkTitle.indexOf('#')=== 0) ) ) { subpage = true; }

// Wiktionary differentiates between lower and uppercased titles, interwiki should not be uppercased if (subpage === true) { linkUrl = linkPrefix + wikEd.pageName + linkTitle; }		else { linkUrl = linkPrefix + linkTitle; }		linkUrl = wikEd.EncodeTitle(linkUrl); if (typeof wikEd.config.linkifyArticlePath == 'string') { linkUrl = wikEd.config.linkifyArticlePath.replace(/\$1/, linkUrl); }		else if (typeof wikEd.wikiGlobals.wgArticlePath == 'string') { linkUrl = wikEd.wikiGlobals.wgArticlePath.replace(/\$1/, linkUrl); }		else { linkUrl = ''; }

// detect redirect and redlink info if ( (Object.prototype.hasOwnProperty.call(wikEd.linkInfo, link) === true) && (wikEd.linkInfo[link].updated === true) ) {

// redirect if (wikEd.linkInfo[link].redirect === true) { var target = wikEd.linkInfo[link].target; if ( (target !== undefined) && (target !== null) ) { info += wikEd.config.text.redirect + ' ' + target; }			}

// redlinks if (wikEd.linkInfo[link].missing === true) { info += wikEd.config.text.redlink; }		}

// collect new links else { wikEd.linkInfo[link] = { update: true, updated: false, };		}	}

// url provided else {

// test for illegal characters if (/[<>]/.test(linkUrl) === true) { return ''; }

// test for templates if (/\{|\}/.test(linkUrl) === true) { return ''; }		linkName = wikEd.EncodeTitle(linkUrl); }

var linkPopup = linkName; if (subpage === true) { linkPopup = wikEd.pageName + linkPopup; }	linkPopup = linkPopup.replace(/\t/g, ' '); linkPopup = wikEd.EscapeHtml(linkPopup); linkPopup = linkPopup.replace(/"/g, '&quot;');	var linkParam = '';

if (linkUrl !== '') { var titleClick; if (wikEd.platform == 'mac') { titleClick = wikEd.config.text.followLinkMac; }		else { titleClick = wikEd.config.text.followLink; }		var id = 'wikEdWikiLink' + Object.getOwnPropertyNames(wikEd.wikiLinks).length; var linkify = linkPopup + ' ' + titleClick; linkParam += 'id="' + id + '" title="' + linkify + info + '"';

// save link infos for linkification and redlinking wikEd.wikiLinks[id] = { url: linkUrl, link: link, linkify: linkify, info: info }; }	return linkParam; };

// // wikEd.CleanLink: clean and normalize article title //

wikEd.CleanLink = function (link) {

// remove highlighting code link = link.replace(/<[^>]*>/g, '');

// remove control chars var regExp = new RegExp('[' + wikEd.controlCharHighlightingStr + '\t\n\r]', 'g'); link = link.replace(regExp, '');

// fix strange white spaces, leading colons link = link.replace(/\s/g, ' '); link = link.replace(/^ +/, ''); link = link.replace(/^:+ */, ''); link = link.replace(/ +/g, '_');

// quotes and ampersand link = link.replace(/&amp;quot;/g, '"');	link = link.replace(/&amp;apos;/g, '\'');	link = link.replace(/&amp;/g, '&');

return link; };

// // wikEd.EncodeTitle: encode article title for use in url (code copied to wikEdDiff.js) //

wikEd.EncodeTitle = function (title) {

if (title === undefined) { title = wikEd.wikiGlobals.wgTitle; }

// characters not supported title = title.replace(/[<>\[\]|{}]/g, '');

title = title.replace(/ /g, '_'); title = encodeURI(title); title = title.replace(/%25(\d\d)/g, '%$1'); title = title.replace(/&/g, '%26'); title = title.replace(/#/g, '%23'); title = title.replace(/'/g, '%27'); title = title.replace(/\?/g, '%3F'); title = title.replace(/\+/g, '%2B'); return title; };

// // wikEd.EscapeHtml: escape html code, &<> to character entities //

wikEd.EscapeHtml = function (html) {

html = html.replace(/&/g, '&amp;'); html = html.replace(/</g, '&lt;'); html = html.replace(/>/g, '&gt;'); return html; };

// // wikEd.UpdateTextarea: copy frame content or provided text to textarea //

wikEd.UpdateTextarea = function (text) {

var obj = {}; if (text !== undefined) { obj.html = text; }

// get frame content, remove dynamically inserted nodes by other scripts else { wikEd.CleanNodes(wikEd.frameDocument); obj.html = wikEd.frameBody.innerHTML; }

// remove trailing blanks and newlines at end of text obj.html = obj.html.replace(/((<br\b[^>]*>)|\s)+$/g, '');

// remove leading spaces in lines obj.html = obj.html.replace(/(<br\b[^>]*>)[\n\r]* */g, '$1');

// textify so that no html formatting is submitted wikEd.Textify(obj); obj.plain = obj.plain.replace(/ |&#160;|\xa0/g, ' '); obj.plain = obj.plain.replace(/&lt;/g, '<'); obj.plain = obj.plain.replace(/&gt;/g, '>'); obj.plain = obj.plain.replace(/&amp;/g, '&');

// convert all  char entitities to actual characters (customization option only) if (wikEd.config.nbspToChar === true) { obj.plain = obj.plain.replace(/ /g, '\xa0'); }

// copy to textarea wikEd.textarea.value = obj.plain;

// remember frame scroll position wikEd.frameScrollTop = wikEd.frameBody.scrollTop;

return; };

// // wikEd.UpdateFrame: copy textarea content or provided html to frame //

wikEd.UpdateFrame = function (html) {

// get textarea content var obj = {}; if (html !== undefined) { obj.html = html; }	else { obj.html = wikEd.textarea.value; obj.html = wikEd.EscapeHtml(obj.html);

// convert \xa (nbsp) to character entities so they do not get converted to blanks obj.html = obj.html.replace(/\xa0/g, '&amp;nbsp;'); }

// highlight the syntax if (wikEd.highlightSyntax === true) { obj.whole = true; wikEd.HighlightSyntax(obj); }

// at least display tabs else { obj.html = obj.html.replace(/(\t)/g, ' $1 '); }

// multiple blanks to blank- obj.html = obj.html.replace(/(^|\n) /g, '$1 '); obj.html = obj.html.replace(/ (\n|$)/g, ' $1'); obj.html = obj.html.replace(/ {2}/g, ' '); obj.html = obj.html.replace(/ {2}/g, ' ');

// newlines to 	obj.html = obj.html.replace(/\n/g, ' ');

// insert content into empty frame if ( (wikEd.readOnly === true) || (wikEd.frameBody.firstChild === null) || (/^<br[^>]*>\s*$/.test(wikEd.frameBody.innerHTML) === true) ) { wikEd.frameBody.innerHTML = obj.html; }

// insert content into frame, preserve history else { obj.sel = wikEd.GetSelection; obj.sel.removeAllRanges; var range = wikEd.frameDocument.createRange; range.setStartBefore(wikEd.frameBody.firstChild); range.setEndAfter(wikEd.frameBody.lastChild); obj.sel.addRange(range);

// replace the frame content with the new text, do not scroll var scrollOffset = window.pageYOffset || document.body.scrollTop; if (obj.html !== '') { wikEd.frameDocument.execCommand('inserthtml', false, obj.html); }		else { wikEd.frameDocument.execCommand('delete'); }		window.scroll(0, scrollOffset); obj.sel.removeAllRanges;

// scroll to previous position if (wikEd.frameScrollTop !== null) { wikEd.frameBody.scrollTop = wikEd.frameScrollTop; }	}	wikEd.frameScrollTop = null;

// add event handlers and labels if (wikEd.highlightSyntax === true) {

// name ref and template buttons wikEd.HighlightNamedHideButtons;

// add event handlers to unhide refs and templates wikEd.HideAddHandlers;

// add event handlers to make highlighted frame links ctrl-clickable wikEd.LinkifyLinks;

// get link infos from server (redirects, redlinks) wikEd.LinkInfoCall; }	return; };

// // wikEd.HtmlToPlain: convert html to plain text, called from wikEd.GetText //

wikEd.HtmlToPlain = function (obj) {

obj.plain = obj.html.replace(/[\n ]{2,}/g, ' '); obj.plain = obj.plain.replace(/<br\b[^>]*>/g, '\n'); obj.plain = obj.plain.replace(/\xa0/g, ' ');

return; };

// // wikEd.KeyHandler: event handler for keydown events in main document and frame //  detects emulated accesskey and traps enter in find/replace input elements //

wikEd.KeyHandler = function (event) {

// trap enter in find/replace input elements if ( (event.type == 'keydown') && (event.keyCode == 13) ) { if (event.target.id == 'wikEdFindText') { event.preventDefault; event.stopPropagation; if (event.shiftKey === true) { wikEd.EditButton(null, 'wikEdFindPrev'); }			else if (event.ctrlKey === true) { wikEd.EditButton(null, 'wikEdFindAll'); }			else { wikEd.EditButton(null, 'wikEdFindNext'); }		}		else if (event.target.id == 'wikEdReplaceText') { event.preventDefault; event.stopPropagation; if (event.shiftKey === true) { wikEd.EditButton(null, 'wikEdReplacePrev'); }			else if (event.ctrlKey === true) { wikEd.EditButton(null, 'wikEdReplaceAll'); }			else { wikEd.EditButton(null, 'wikEdReplaceNext'); }		}	}

// detect emulated accesskeys else if ( (event.shiftKey === true) && (event.ctrlKey === false) && (event.altKey === true) && (event.metaKey === false) ) {

// get wikEd button id from keycode var buttonId = wikEd.buttonKeyCode[event.keyCode]; if (buttonId !== undefined) { event.preventDefault; event.stopPropagation;

// execute the button click handler code, obj required for eval var obj = document.getElementById(buttonId); eval(wikEd.editButtonHandler[buttonId]); return; }	}	return; };

// // wikEd.FindAhead: find-as-you-type, event handler for find field, supports insensitive and regexp settings //

wikEd.FindAhead = function {

if (wikEd.findAhead.getAttribute('checked') == 'true') {

// get the find text var findText = wikEd.findText.value; if (findText === '') { return; }

// remember input field selection var findTextSelectionStart = wikEd.findText.selectionStart; var findTextSelectionEnd = wikEd.findText.selectionEnd;

// remember frame selection var sel = wikEd.GetSelection; var range = sel.getRangeAt(0).cloneRange; var rangeClone = range.cloneRange; var scrollTop = wikEd.frameBody.scrollTop;

// collapse selection to the left sel.removeAllRanges; range.collapse(true); range = sel.addRange(range);

// create obj for regexp search var obj = {};

// get insensitive and regexp button states var regExpChecked = wikEd.regExp.getAttribute('checked'); var caseSensitiveChecked = wikEd.caseSensitive.getAttribute('checked');

// get case sensitive setting var caseSensitive = false; if (caseSensitiveChecked == 'true') { caseSensitive = true; }

// get regexp setting var useRegExp = false; if (regExpChecked == 'true') { useRegExp = true; }

// parameters: obj, findText, caseSensitive, backwards, wrap, useRegExp var found = wikEd.Find(obj, findText, caseSensitive, false, true, useRegExp);

// restore original frame selection if (found === false) { wikEd.frameBody.scrollTop = scrollTop; sel.removeAllRanges; sel.addRange(rangeClone); }		else { obj.sel.removeAllRanges; obj.sel.addRange(obj.changed.range);

// scroll to selection wikEd.ScrollToSelection; }

// restore input field selection (needed for FF 3.6) wikEd.findText.select; wikEd.findText.setSelectionRange(findTextSelectionStart, findTextSelectionEnd); }	return; };

// // wikEd.DebugInfo: click handler for ctrl-click of logo buttons, pastes debug info into edit field or popup; shift-ctrl-click: extended info with resource loader modules //

wikEd.DebugInfo = function (event) {

// ctrl-click if (event.ctrlKey !== true) { return; }

// get debug infos var debug = wikEd.GetDebugInfo(event.shiftKey); debug = debug.replace(/(^|\n(?=.))/g, '$1* '); debug = '=== wikEd bug report: ____ (Please add short title) === \n\n' + debug; debug += '* Error console: ____ (Firefox: Tools → Web Developer → Browser console; push clear and reload the page. Chrome: Control button → Tools → JavaScript console. Copy and paste error messages related to wikEd.js)\n'; debug += '* Problem description: ____ (Please be as specific as possible about what is wrong, including when it happens, what happens, what is broken, and what still works)\n'; debug += '* Steps to reproduce: ____ (Please include what happens at each step. Your problems cannot be fixed without reproducing them first!)\n';

// print to iframe, textarea, debug area, or alert if (event.target == wikEd.logo) { window.alert(debug); }	else if (wikEd.useWikEd === true) { debug = wikEd.EscapeHtml('\n' + debug).replace(/\n/g, ' '); wikEd.frameDocument.execCommand('inserthtml', false, debug); }	else if (wikEd.textarea !== null) { wikEd.textarea.value += '\n' + debug; }	else { wikEd.Debug(debug, undefined, true); }	return; };

// // wikEd.GetDebugInfo: compiles debug info into string //

wikEd.GetDebugInfo = function (extended) {

var loader = ''; var mediawiki = ''; var gadgets = ''; var scripts = '';

// cycle through script urls var pageScripts = document.getElementsByTagName('script'); for (var i = 0; i < pageScripts.length; i ++) { var src = pageScripts[i].src; if (src !== '') {

// resource loader modules var regExpMatch = /load.php\?(|.*?&)modules=(.*?)(&|$)/.exec(src); if (regExpMatch !== null) { loader += decodeURIComponent(regExpMatch[2]).replace(/\|/g, '; ') + '; '; }

// mediawiki: scripts else { var regExpMatch = /index.php\?(|.*?&)title=(.*?)(&|$)/.exec(src); if (regExpMatch !== null) { var script = regExpMatch[2]; if (/^MediaWiki:Gadget/.test(script) === true) { gadgets += script.replace(/^MediaWiki:/, '') + ', '; }					else if (/^MediaWiki:/.test(script) === true) { mediawiki += script.replace(/^MediaWiki:/, '') + ', '; }					else { scripts += script + ', '; }				}

// other scripts else { var regExpScript = new RegExp(wikEd.wikiGlobals.wgServer + '(' + wikEd.wikiGlobals.wgScriptPath + ')?'); scripts += src.replace(regExpScript, ).replace(/\?.*/, ) + ', '; }			}		}	}

// get date var date = new Date; var time = (date.getUTCFullYear + '-' + (date.getUTCMonth + 1) + '-' + date.getUTCDate + ' ' + date.getUTCHours + ':' + date.getUTCMinutes + ':' + date.getUTCSeconds + ' UTC').replace(/\b(\d)\b/g, '0$1');

// get user subpages var protocol = document.location.href.replace(/\/\/.*/, ''); var subPages = wikEd.wikiGlobals.wgServer + wikEd.wikiGlobals.wgArticlePath.replace(/\$1/, 'Special:PrefixIndex/' + wikEd.wikiGlobals.wgFormattedNamespaces[2] + ':' + wikEd.EncodeTitle(wikEd.wikiGlobals.wgUserName) + '/'); if (/^\/\//.test(subPages) === true) { subPages = protocol + subPages; }

// get user js pages var userPage = wikEd.wikiGlobals.wgServer + wikEd.wikiGlobals.wgArticlePath.replace(/\$1/, wikEd.wikiGlobals.wgFormattedNamespaces[2] + ':' + wikEd.EncodeTitle(wikEd.wikiGlobals.wgUserName)); if (/^\/\//.test(userPage) === true) { userPage = protocol + userPage; }	var skinJs = userPage + '/' + wikEd.wikiGlobals.skin + '.js'; var commonJs = userPage + '/common.js';

// remove trailing separators loader = loader.replace(/; $/, ''); mediawiki = mediawiki.replace(/, $/, ''); gadgets = gadgets.replace(/, $/, ''); scripts = scripts.replace(/, $/, '');

var debug = ''; debug += 'Date: ' + time + '\n'; debug += 'wikEd version: ' + wikEd.programVersion + wikEd.installationType + ' (' + wikEd.programDate + ')\n'; debug += 'Browser: ' + window.navigator.userAgent + ' (' + window.navigator.platform + ')\n'; debug += 'Skin: ' + wikEd.wikiGlobals.skin + ' (detected: ' + wikEd.skin + ')\n'; debug += 'MediaWiki: ' + wikEd.wikiGlobals.wgVersion + '\n'; debug += 'Gadgets: ' + gadgets + '\n'; debug += 'MediaWiki scripts: ' + mediawiki + '\n'; debug += 'Scripts: ' + scripts + '\n'; if (extended === true) { debug += 'Loader: ' + loader + '\n'; }	debug += 'URL: ' + window.location.href + '\n'; debug += 'User subpages: ' + subPages + '\n'; debug += 'User/skin.js: ' + skinJs + '\n'; debug += 'User/common.js: ' + commonJs + '\n';

return debug; };

// // wikEd.MainSwitch: click handler for program logo //

wikEd.MainSwitch = function (event) {

// ctrl-click for debug info if (event.ctrlKey === true) { return; }

// disable function if browser is incompatible if (wikEd.browserNotSupported === true) { return; }

// enable wikEd if (wikEd.disabled === true) {

// check for active code editor wikEd.CodeEditorCheck;

// do not turn on when code editor is active if (wikEd.useCodeEditor === true) { wikEd.disabled = true; wikEd.SetLogo('incompatible', 'Code Editor'); return; }

wikEd.disabled = false; wikEd.SetPersistent('wikEdDisabled', '0', 0, '/');

// turn rich text frame on		if (wikEd.turnedOn === false) {

// setup wikEd wikEd.TurnOn(false); }		else { wikEd.SetLogo; var useWikEd = false; if (document.getElementById('wikEdUseWikEd').getAttribute('checked') == 'true') { useWikEd = true; }			wikEd.SetEditArea(useWikEd); wikEd.useWikEd = useWikEd; window.wikEdUseWikEd = wikEd.useWikEd; if (wikEd.useWikEd === true) { wikEd.UpdateFrame; }			wikEd.buttonBarWrapper.style.display = 'block'; wikEd.buttonBarPreview.style.display = 'block'; if (wikEd.buttonBarJump !== null) { wikEd.buttonBarJump.style.display = 'block'; }

// run scheduled custom functions wikEd.ExecuteHook(wikEd.config.onHook); }	}

// disable wikEd else { wikEd.SetPersistent('wikEdDisabled', '1', 0, '/'); if (wikEd.turnedOn === false) { wikEd.useWikEd = false; window.wikEdUseWikEd = wikEd.useWikEd; wikEd.disabled = true; wikEd.SetLogo; }		else {

// interrupt fullscreen mode if (wikEd.fullscreen === true) { wikEd.FullScreen(false); }

// turn classic textarea on			if (wikEd.useWikEd === true) { wikEd.UpdateTextarea; }			wikEd.SetEditArea(false);

// reset textarea dimensions wikEd.textarea.style.height = (wikEd.textareaOffsetHeightInitial - wikEd.frameBorderHeight) + 'px'; wikEd.textarea.style.width = '100%';

wikEd.frameHeight = (wikEd.textareaOffsetHeightInitial - wikEd.frameBorderHeight) + 'px'; wikEd.frameWidth = (wikEd.editorWrapper.clientWidth - wikEd.frameBorderWidth) + 'px'; wikEd.frame.style.height = wikEd.frameHeight; wikEd.frame.style.width = wikEd.frameWidth;

wikEd.buttonBarWrapper.style.display = 'none'; wikEd.buttonBarPreview.style.display = 'none';

wikEd.previewArticle.style.display = 'none'; wikEd.previewDiff.style.display = 'none'; wikEd.localPrevWrapper.style.display = 'none'; wikEd.localPrevWrapper.style.height = 'auto';

if (wikEd.buttonBarJump !== null) { wikEd.buttonBarJump.style.display = 'none'; }

wikEd.useWikEd = false; window.wikEdUseWikEd = wikEd.useWikEd; wikEd.disabled = true; wikEd.SetLogo;

// run scheduled custom functions wikEd.ExecuteHook(wikEd.config.offHook); }	}	return; };

// // wikEd.FullScreen: change to fullscreen edit area or back to normal view //

wikEd.FullScreen = function (fullscreen, updateButton) {

// resize only if (fullscreen === undefined) { fullscreen = wikEd.fullscreen; }

// no fullscreen for special edit pages if (wikEd.editArticle === false) { fullscreen = false; updateButton = false; }

// no fullscreen for textarea view if (wikEd.useWikEd === false) { fullscreen = false; updateButton = false; }

// skip for repeat calls if (fullscreen != wikEd.fullscreen) {

// disable frame resizing if ( (wikEd.fullscreen === false) && (wikEd.frameDocument !== null) ) { wikEd.ResizeStopHandler; }

// setup fullscreen if (fullscreen === true) { document.body.classList.add('wikEdFullscreen');

// inactivate scroll-to buttons document.getElementById('wikEdScrollToPreview').className = 'wikEdButtonInactive'; document.getElementById('wikEdScrollToEdit').className = 'wikEdButtonInactive'; }

// back to normal else { document.body.classList.remove('wikEdFullscreen');

// activate scroll-to buttons document.getElementById('wikEdScrollToPreview').className = 'wikEdButton'; document.getElementById('wikEdScrollToEdit').className = 'wikEdButton'; }	}	var switched = (fullscreen != wikEd.fullscreen); if (switched === true) { wikEd.fullscreen = fullscreen;

// set the fullscreen button state if (updateButton === true) { wikEd.Button(document.getElementById('wikEdFullScreen'), 'wikEdFullScreen', null, fullscreen); wikEd.fullScreenMode = fullscreen; }	}

// resize and scroll to edit-frame wikEd.ResizeWindowHandler; if ( (switched === true) && (fullscreen === false) ) { window.scroll(0, wikEd.GetOffsetTop(wikEd.inputWrapper) - 2); }

// grey out fullscreen button var button = document.getElementById('wikEdFullScreen'); if ( (wikEd.editArticle === false) || (wikEd.useWikEd === false) ) { button.className = 'wikEdButtonInactive'; }	else if (wikEd.fullScreenMode === true) { button.className = 'wikEdButtonChecked'; }	else { button.className = 'wikEdButtonUnchecked'; }

return; };

// // wikEd.ResizeSummary: recalculate the summary width after resizing the window //

wikEd.ResizeSummary = function {

// check if combo field exists if (wikEd.summarySelect === null) { return; }

wikEd.summaryText.style.width = ''; wikEd.summarySelect.style.width = '';

wikEd.summaryTextWidth = wikEd.summaryWrapper.clientWidth - ( wikEd.GetOffsetLeft(wikEd.summaryText) - wikEd.GetOffsetLeft(wikEd.summaryWrapper) ); if (wikEd.summaryTextWidth < 150) { wikEd.summaryTextWidth = 150; }	wikEd.summaryText.style.width = wikEd.summaryTextWidth + 'px'; wikEd.ResizeComboInput('summary'); return; };

// // wikEd.ResizeComboInput: set the size of input and select fields so that only the select button is visible behind the input field //

wikEd.ResizeComboInput = function (field) {

// check if combo field exists if (wikEd.selectElement[field] === undefined) { return; }

// short names var input = wikEd.inputElement[field]; var select = wikEd.selectElement[field];

// save select options and empty select var selectInnerHTML = select.innerHTML; select.innerHTML = '';

// set measuring styles select.style.fontFamily = 'sans-serif'; input.style.margin = '0'; select.style.margin = '0'; select.style.width = 'auto';

// get button width from small empty select box var inputWidth = input.offsetWidth; var selectWidth = select.offsetWidth; var selectBorder = parseInt(wikEd.GetStyle(select, 'borderTopWidth'), 10); var buttonWidth = selectWidth - selectBorder - 8;

// delete measuring styles select.style.margin = null; input.style.fontFamily = null; select.style.fontFamily = null;

// for long fields shorten input width if (inputWidth + buttonWidth > 150) { input.style.width = (inputWidth - buttonWidth) + 'px'; select.style.width = inputWidth + 'px'; }

// otherwise increase select width else { select.style.width = (inputWidth + buttonWidth) + 'px'; }

// restore select options select.innerHTML = selectInnerHTML;

return; };

// // wikEd.ChangeComboInput: sets the input value to selected option; onchange event handler for select boxes //

wikEd.ChangeComboInput = function (field) {

// get selection index (-1 for unselected) var selected = wikEd.selectElement[field].selectedIndex; if (selected >= 0) { wikEd.selectElement[field].selectedIndex = -1;

// get selected option var option = wikEd.selectElement[field].options[selected]; if (option.text !== '') {

// jump to heading if ( (field == 'find') && (/^=.*?=$/.test(option.value) === true) ) { var obj = {}; var findText = option.value.replace(/([\\^$*+?.\[\]{}:=!|,\-])/g, '\\$1'); findText = '^' + findText + '$';

// find and select heading text wikEd.Find(obj, findText, true, false, true, true); obj.sel.removeAllRanges; obj.sel.addRange(obj.changed.range);

// and scroll it into the viewport wikEd.ScrollToSelection; return; }

// update input field else {

// add a tag to the summary box if (field == 'summary') { wikEd.inputElement[field].value = wikEd.AppendToSummary(wikEd.inputElement[field].value, option.text); }

// add case and regexp checkboxes to find / replace fields else if (option.value == 'setcheck') { wikEd.Button(document.getElementById('wikEdCaseSensitive'), 'wikEdCaseSensitive', null, (option.text.charAt(0) == wikEd.checkMarker[true]) ); wikEd.Button(document.getElementById('wikEdRegExp'), 'wikEdRegExp', null, (option.text.charAt(1) == wikEd.checkMarker[true]) ); wikEd.inputElement[field].value = option.text.substr(3); }

// add option text else { wikEd.inputElement[field].value = option.text; }

// find the new text if ( (field == 'find') && (wikEd.findAhead.getAttribute('checked') == 'true') ) { wikEd.FindAhead; }			}		}	}	wikEd.inputElement[field].focus;

return; };

// // wikEd.AppendToSummary: append a phrase to the summary text //

wikEd.AppendToSummary = function (summary, append) {

summary = summary.replace(/^[, ]+/, ''); summary = summary.replace(/[, ]+$/, ''); if (summary !== '') { if (/ \*\/$/.test(summary) === true) { summary += ' '; }		else if (/[.;:]$/.test(summary) === true) { summary += ' '; }		else { var regExp = new RegExp('^[' + wikEd.letters + '_0-9"\'+\\-]', '');			if (regExp.test(summary) === false) {				summary += ' ';			}			else {				summary += ', ';			}		}	}	summary += append;

return summary; };

// // wikEd.AddToHistory: add an input value to the saved history //

wikEd.AddToHistory = function (field) {

if (wikEd.inputElement[field].value !== '') {

// load history from saved settings wikEd.LoadHistoryFromSettings(field);

// add current value to history wikEd.fieldHist[field].unshift(wikEd.inputElement[field].value);

// add case and regexp checkboxes to find / replace value if ( (field == 'find') || (field == 'replace') ) { wikEd.fieldHist[field][0] = wikEd.checkMarker[ (wikEd.caseSensitive.getAttribute('checked') == 'true') ] + wikEd.checkMarker[ (wikEd.regExp.getAttribute('checked') == 'true') ] + ' ' + wikEd.fieldHist[field][0]; }

// remove paragraph names from summary if (field == 'summary') { wikEd.fieldHist[field][0] = wikEd.fieldHist[field][0].replace(/^\/\* .*? \*\/ */, ''); }

// remove multiple old copies from history var i = 1; while (i < wikEd.fieldHist[field].length) { if (wikEd.fieldHist[field][i] == wikEd.fieldHist[field][0]) { wikEd.fieldHist[field].splice(i, 1); }			else { i ++; }		}

// remove new value if it is a preset value if (wikEd.config.comboPresetOptions[field] !== undefined) { var i = 0; while (i < wikEd.config.comboPresetOptions[field].length) { if (wikEd.config.comboPresetOptions[field][i] == wikEd.fieldHist[field][0]) { wikEd.fieldHist[field].shift; break; }				else { i ++; }			}		}

// cut history number to maximal history length wikEd.fieldHist[field] = wikEd.fieldHist[field].slice(0, wikEd.config.historyLength[field]);

// save history to settings if (wikEd.fieldHist[field][0] !== '') { wikEd.SaveHistoryToSetting(field); }	}	return; };

// // wikEd.SetComboOptions: generate the select options from saved history; onfocus handler for select box //

wikEd.SetComboOptions = function (field) {

// load history from saved settings wikEd.LoadHistoryFromSettings(field);

var option = {}; var selectedOption = null;

// delete options var options = wikEd.selectElement[field].options; for (var i = 0; i < options.length; i ++) { wikEd.selectElement[field].remove(i); }

// delete optgroup option = document.getElementById(field + 'Optgroup'); if (option !== null) { wikEd.selectElement[field].removeChild(option); }

// workaround for onchange not firing when selecting first option from unselected dropdown option = document.createElement('option'); option.style.display = 'none'; var j = 0; wikEd.selectElement[field].options[j++] = option;

// add history entries for (var i = 0; i < wikEd.fieldHist[field].length; i ++) { if (wikEd.fieldHist[field][i] !== undefined) { if (wikEd.fieldHist[field][i] == wikEd.inputElement[field].value) { selectedOption = j;			} option = document.createElement('option');

// replace spaces with nbsp to allow for multiple, leading, and trailing spaces option.text = wikEd.fieldHist[field][i].replace(/ /g, '\xa0'); if ( (field == 'find') || (field == 'replace') ) { option.value = 'setcheck'; }			wikEd.selectElement[field].options[j++] = option; }	}

// add preset entries var startPreset = 0; if (wikEd.config.comboPresetOptions[field] !== undefined) { startPreset = j;		for (var i = 0; i < wikEd.config.comboPresetOptions[field].length; i ++) { if (wikEd.config.comboPresetOptions[field][i] !== undefined) {

// replace spaces with nbsp to allow for multiple, leading, and trailing spaces wikEd.config.comboPresetOptions[field][i] = wikEd.config.comboPresetOptions[field][i].replace(/ /g, '\xa0');

// select a dropdown value if (wikEd.config.comboPresetOptions[field][i] == wikEd.inputElement[field].value) { selectedOption = j;				}

option = document.createElement('option'); option.text = wikEd.config.comboPresetOptions[field][i].replace(/ /g, '\xa0'); if (field == 'summary') { option.text = option.text.replace(/\{wikEdUsing\}/g, wikEd.config.summaryUsing); }				wikEd.selectElement[field].options[j++] = option; }		}	}

// set the selection wikEd.selectElement[field].selectedIndex = selectedOption;

// add a blank preset separator if ( (startPreset > 1) && (startPreset < j) ) { option = document.createElement('optgroup'); option.label = '\xa0'; option.id = field + 'Optgroup'; wikEd.selectElement[field].insertBefore(option, wikEd.selectElement[field].options[startPreset]); }

// add the TOC jumper to the find field var startTOC = 0; if (field == 'find') { startTOC = j;

// get the whole plain text var plain = wikEd.frameBody.innerHTML; plain = plain.replace(/<br\b[^>]*>/g, '\n'); plain = plain.replace(/<[^>]*>/g, ''); plain = plain.replace(/ /g, '\xa0'); plain = plain.replace(/&gt;/g, '>'); plain = plain.replace(/&lt;/g, '<'); plain = plain.replace(/&amp;/g, '&');

// cycle through the headings var regExpMatchHeading = plain.match(/(^|\n)=+.+?=+[^\n=]*[ =\t]*(?=(\n|$))/g); if (regExpMatchHeading !== null) { for (var i = 0; i < regExpMatchHeading.length; i ++) { var headingMatch = regExpMatchHeading[i].match(/\n?((=+) *(.+?)( *\2))/); var headingIndent = headingMatch[2]; headingIndent = headingIndent.replace(/^=/g, ''); headingIndent = headingIndent.replace(/\=/g, '\xa0');

// add headings to the select element option = document.createElement('option'); option.text = '\u21d2' + headingIndent + headingMatch[3]; option.value = headingMatch[1]; wikEd.selectElement[field].options[j++] = option; }		}	}

// add a blank TOC separator if ( (startTOC > 1) && (startTOC < j) ) { option = document.createElement('optgroup'); option.label = '\xa0'; option.id = field + 'Optgroup'; wikEd.selectElement[field].insertBefore(option, wikEd.selectElement[field].options[startTOC]); }

return; };

// // wikEd.ClearHistory: clear the history of combo input fields //

wikEd.ClearHistory = function (field) {

wikEd.SetPersistent(wikEd.savedName[field], '', 0, '/'); wikEd.SetComboOptions(field); return; };

// // wikEd.LoadHistoryFromSettings: get the input box history from the respective saved settings //

wikEd.LoadHistoryFromSettings = function (field) {

var setting = wikEd.GetPersistent(wikEd.savedName[field]); if ( (setting !== null) && (setting !== '') ) { setting = decodeURIComponent(setting); wikEd.fieldHist[field] = setting.split('\n'); }	else { wikEd.fieldHist[field] = []; }	return; };

// // wikEd.SaveHistoryToSetting: save the input box history to the respective saved settings //

wikEd.SaveHistoryToSetting = function (field) {

var setting = ''; setting = wikEd.fieldHist[field].join('\n'); setting = setting.replace(/\n$/, ''); setting = encodeURIComponent(setting); wikEd.SetPersistent(wikEd.savedName[field], setting, 0, '/'); return; };

// // wikEd.GetSelection: get the current iframe selection //

wikEd.GetSelection = function {

var sel = wikEd.frameWindow.getSelection;

// make sure there is at least an empty range if ( (sel !== null) && (sel.rangeCount === 0) ) { sel.collapse(wikEd.frameBody, 0); }	return sel; };

// // wikEd.SetRange: set a range, control for non-text nodes //

wikEd.SetRange = function (range, startNode, startOffset, endNode, endOffset) {

wikEd.SetRangeStart(range, startNode, startOffset); wikEd.SetRangeEnd(range, endNode, endOffset); return; };

// // wikEd.SetRangeStart: set range start //

wikEd.SetRangeStart = function (range, startNode, startOffset) {

if ( (startNode.childNodes.length > 0) && (startOffset < startNode.childNodes.length) ) { startNode = startNode.childNodes.item(startOffset); startOffset = 0; }	if (startNode.nodeName == '#text') { range.setStart(startNode, startOffset); }	else if (startNode.childNodes.length === 0) { range.setStart(startNode, 0); }	else { range.setStartAfter(startNode); }	return; };

// // wikEd.SetRangeEnd: set range end //

wikEd.SetRangeEnd = function (range, endNode, endOffset) {

if ( (endNode.childNodes.length > 0) && (endOffset < endNode.childNodes.length) ) { endNode = endNode.childNodes.item(endOffset); endOffset = 0; }	if (endNode.nodeName == '#text') { range.setEnd(endNode, endOffset); }	else if (endNode.childNodes.length === 0) { range.setEndBefore(endNode); }	else { range.setEndBefore(endNode); }	return; };

// // wikEd.GetSavedSetting: get a wikEd setting, returns boolean //

wikEd.GetSavedSetting = function (settingName, preset) {

var setting = wikEd.GetPersistent(settingName); if (setting == '1') { setting = true; }	else { if ( (setting === null) || (setting === '') ) { setting = preset; }		if (typeof setting !== 'boolean') { setting = false; }	}	return setting; };

// // wikEd.GetPersistent: get a cookie or a Greasemonkey persistent value (code copied to wikEdDiff.js) //

wikEd.GetPersistent = function ( name ) {

var getStr;

// check for web storage wikEd.DetectWebStorage;

// get a value from web storage if ( wikEd.webStorage === true ) { try { getStr = window.localStorage.getItem( name ); }		catch ( exception ) { wikEd.webStorage = false; }	}	if ( wikEd.webStorage === false ) {

// else get a Greasemonkey persistent value if ( wikEd.greasemonkey === true ) { getStr = GM_getValue( name, '' ); }

// else get a cookie value else { getStr = wikEd.GetCookie( name ); }	}

// return string if ( typeof getStr != 'string' ) { getStr = ''; }	return getStr; };

// // wikEd.SetPersistent: set a cookie or a Greasemonkey persistent value, deletes the value for expire = -1 //

wikEd.SetPersistent = function ( name, value, expires, path, domain, secure ) {

// check for web storage wikEd.DetectWebStorage;

// set a value in web storage if ( wikEd.webStorage === true ) { if ( expires == -1 ) { value = ''; }		try { window.localStorage.setItem( name, value ); }		catch ( exception ) { wikEd.webStorage = false; }	}	if ( wikEd.webStorage === false ) {

// else set a Greasemonkey persistent value if ( wikEd.greasemonkey === true ) { if ( expires == -1 ) { value = ''; }

// see http://wiki.greasespot.net/Greasemonkey_access_violation window.setTimeout( function {				GM_setValue( name, value );			}, 0 ); }

// else set a cookie value else { wikEd.SetCookie( name, value, expires, path, domain, secure ); }	}	return; };

// // wikEd.DetectWebStorage: detect if local storage is available (code copied to wikEdDiff.js) //

wikEd.DetectWebStorage = function {

if (wikEd.webStorage === null) { wikEd.webStorage = false;

// https://bugzilla.mozilla.org/show_bug.cgi?id=748620 try { if (typeof window.localStorage == 'object') {

// web storage does not persist between local html page loads in firefox if (/^file:\/\//.test(wikEd.pageOrigin) === false) { wikEd.webStorage = true; }			}		}		catch (exception) { }	}	return; };

// // wikEd.GetCookie: get a cookie (code copied to wikEdDiff.js) //

wikEd.GetCookie = function (cookieName) {

var cookie = ' ' + document.cookie; var search = ' ' + cookieName + '='; var cookieValue = ''; var offset = 0; var end = 0; offset = cookie.indexOf(search); if (offset != -1) { offset += search.length; end = cookie.indexOf(';', offset); if (end == -1) { end = cookie.length; }		cookieValue = cookie.substring(offset, end); cookieValue = cookieValue.replace(/\\+/g, ' '); cookieValue = decodeURIComponent(cookieValue); }	return cookieValue; };

// // wikEd.SetCookie: set a cookie, deletes a cookie for expire = -1 (code copied to wikEdDiff.js) //

wikEd.SetCookie = function (name, value, expires, path, domain, secure) {

var cookie = name + '=' + encodeURIComponent(value);

if ( (expires !== undefined) && (expires !== null) ) {

// generate a date 1 hour ago to delete the cookie if (expires == -1) { var cookieExpire = new Date; expires = cookieExpire.setTime(cookieExpire.getTime - 60 * 60 * 1000); expires = cookieExpire.toUTCString; }

// get date from expiration preset else if (expires === 0) { var cookieExpire = new Date; expires = cookieExpire.setTime(cookieExpire.getTime + wikEd.config.cookieExpireSec * 1000); expires = cookieExpire.toUTCString; }		cookie += '; expires=' + expires; }	if (typeof path == 'string') { cookie += '; path=' + path; }	if (typeof domain == 'string') { cookie += '; domain=' + domain; }	if (secure === true) { cookie += '; secure'; }	document.cookie = cookie; return; };

// // wikEd.GetOffsetTop: get element offset relative to window top (code copied to wikEdDiff.js) //

wikEd.GetOffsetTop = function (element) {

var offset = 0; do { offset += element.offsetTop; } while ( (element = element.offsetParent) !== null ); return offset; };

// // wikEd.GetOffsetLeft: get element offset relative to left window border //

wikEd.GetOffsetLeft = function (element) {

var offset = 0; do { offset += element.offsetLeft; } while ( (element = element.offsetParent) !== null ); return offset; };

// // wikEd.AppendScript: append script to head //

wikEd.AppendScript = function (scriptUrl, onLoadFunction) {

var script = document.createElement('script'); script.setAttribute('type', 'text/javascript'); script.setAttribute('src', scriptUrl); wikEd.head.appendChild(script); if (onLoadFunction !== undefined) { script.addEventListener('load', onLoadFunction, false); }	return script; };

// // wikEd.CleanNodes: remove DOM elements dynamically inserted by other scripts //

wikEd.CleanNodes = function (node) {

if (wikEd.cleanNodes === false) { return; }

// remove Web of Trust (WOT) tags var divs = node.getElementsByTagName('div'); for (var i = 0; i < divs.length; i ++) { var div = divs[i];

// test for WOT class names var divClass = div.className; if (/^wot-/.test(divClass) === true) { var divParent = div.parentNode; if (divParent !== null) { divParent.removeChild(div); }			continue; }

// test for WOT attributes var divAttrs = div.attributes; for (var j = 0; j < divAttrs.length; ++ j) { var attr = divAttrs.item(j); if ( (attr.nodeName == 'wottarget') || (/^link[0-9a-f]{30,}/.test(attr.nodeName) === true) ) { var divParent = div.parentNode; if (divParent !== null) { divParent.removeChild(div); }				break; }		}	}	return; };

// // wikEd.ParseDOM: parses a DOM subtree into a linear array of plain text fragments //

wikEd.ParseDOM = function (obj, topNode) {

obj.plainLength = 0; obj.plainArray = []; obj.plainNode = []; obj.plainStart = []; obj.plainPos = [];

var anchorNode = obj.sel.anchorNode; var focusNode = obj.sel.focusNode; var anchorOffset = obj.sel.anchorOffset; var focusOffset = obj.sel.focusOffset;

wikEd.ParseDOMRecursive(obj, topNode, anchorNode, anchorOffset, focusNode, focusOffset); obj.plain = obj.plainArray.join(''); obj.plain = obj.plain.replace(/\xa0/g, ' '); return; };

// // wikEd.ParseDOMRecursive: parses a DOM subtree into a linear array of plain text fragments //

wikEd.ParseDOMRecursive = function (obj, currentNode, anchorNode, anchorOffset, focusNode, focusOffset) {

// cycle through the child nodes of currentNode var childNodes = currentNode.childNodes; for (var i = 0; i < childNodes.length; i ++) { var childNode = childNodes.item(i);

// check for selection, non-text nodes if ( (currentNode == anchorNode) && (i == anchorOffset) ) { obj.plainAnchor = obj.plainLength; }		if ( (currentNode == focusNode) && (i == focusOffset) ) { obj.plainFocus = obj.plainLength; }

// check for selection, text nodes if (childNode == obj.sel.anchorNode) { obj.plainAnchor = obj.plainLength + obj.sel.anchorOffset; }		if (childNode == obj.sel.focusNode) { obj.plainFocus = obj.plainLength + obj.sel.focusOffset; }

// get text of child node var value = null; switch (childNode.nodeType) { case childNode.ELEMENT_NODE:

// skip hidden elements if (wikEd.GetStyle(childNode, 'display') == 'none') { continue; }				if ( (childNode.childNodes.length === 0) && (wikEd.leafElements[childNode.nodeName] === true) ) { if (childNode.nodeName == 'BR') { value = '\n'; }				}				else { wikEd.ParseDOMRecursive(obj, childNode, anchorNode, anchorOffset, focusNode, focusOffset); }				break; case childNode.TEXT_NODE: value = childNode.nodeValue; value = value.replace(/\n/g, ' '); break; case childNode.ENTITY_REFERENCE_NODE: value = '&' + childNode.nodeName + ';'; break; }

// add text to text object if (value !== null) {

// array of text fragments obj.plainArray.push(value);

// array of text fragment node references obj.plainNode.push(childNode);

// array of text fragment text positions obj.plainStart.push(obj.plainLength);

// node references containing text positions obj.plainPos[childNode] = obj.plainLength;

// current text length obj.plainLength += value.length; }	}	return; };

// // wikEd.GetInnerHTML: get the innerHTML of a document fragment //

wikEd.GetInnerHTML = function (obj, currentNode) {

// initialize string if (obj.html === undefined) { obj.html = ''; }	if (obj.plain === undefined) { obj.plain = ''; }	if (obj.plainArray === undefined) { obj.plainArray = []; obj.plainNode = []; obj.plainStart = []; }

var childNodes = currentNode.childNodes; for (var i = 0; i < childNodes.length; i ++) { var childNode = childNodes.item(i); switch (childNode.nodeType) { case childNode.ELEMENT_NODE: obj.html += '<' + childNode.nodeName.toLowerCase; for (var j = 0; j < childNode.attributes.length; j ++) { if (childNode.attributes.item(j).value !== null) { obj.html += ' ' + childNode.attributes.item(j).nodeName + '="' + childNode.attributes.item(j).value.replace(/</g, '&lt;').replace(/>/g, '&gt;') + '"'; }				}				if ( (childNode.childNodes.length === 0) && (wikEd.leafElements[childNode.nodeName] === true) ) { obj.html += '>'; if (childNode.nodeName == 'BR') { obj.plainArray.push('\n'); obj.plainNode.push(childNode); obj.plainStart.push(obj.plain.length); obj.plain += '\n'; }				}				else { obj.html += '>'; wikEd.GetInnerHTML(obj, childNode); obj.html += '</' + childNode.nodeName.toLowerCase + '>'; }				break; case childNode.TEXT_NODE: var value = childNode.nodeValue;

// newline handling important for pasted page content if (currentNode.nodeName != 'PRE') { value = value.replace(/[ \r]*\n[ \r\n]*/g, ' '); }

// plain array contains & < > instead of &amp; &lt; &gt; obj.plainArray.push(value); obj.plainNode.push(childNode); obj.plainStart.push(obj.plain.length); value = wikEd.EscapeHtml(value);

if (currentNode.nodeName == 'PRE') { obj.html += value.replace(/\n/g, ' '); }				else { obj.html += value; }				obj.plain += value; break; case childNode.CDATA_SECTION_NODE: obj.html += '<![CDATA[' + childNode.nodeValue + ']]>'; break; case childNode.ENTITY_REFERENCE_NODE: var value = '&' + childNode.nodeName + ';'; obj.plainArray.push(value); obj.plainNode.push(childNode); obj.plainStart.push(obj.plain.length); value = value.replace(/&/g, '&amp;'); obj.html += value; obj.plain += value; break; case childNode.COMMENT_NODE: obj.html += ''; break; }	}	return; };

// // wikEd.GetNextNode: recurse through DOM to next text-like node for anti-highlight bleeding //

wikEd.GetNextTextNode = function (obj, currentNode, currentLevel) {

// ascend until there is a sibling while (currentNode != wikEd.frameBody) {

// check for sibling var nextNode = null; if ( (obj.backwards === true) && (currentNode.previousSibling !== null) ) { nextNode = currentNode.previousSibling; }		else if ( (obj.backwards !== true) && (currentNode.nextSibling !== null) ) { nextNode = currentNode.nextSibling; }

// found sibling if (nextNode !== null) { currentNode = nextNode;

// skip hidden nodes if (				( (wikEd.refHide === true) && (/^((wikEd(Ref|Templ|CharEntity|Table))|(wikEdTableBR))$/.test(currentNode.className) === true) ) ||				(/^(wikEdScroll(Before|After))$/.test(currentNode.className) === true)			) { continue; }

// found text-like node if (				(currentNode.nodeName == '#text') ||				(currentNode.nodeType == currentNode.ENTITY_REFERENCE_NODE) ||				(wikEd.leafElements[currentNode.nodeName] === true)			) { obj.foundNode = currentNode; obj.foundLevel = currentLevel; return; }

// recurse into child nodes if (currentNode.nodeType == currentNode.ELEMENT_NODE) { wikEd.GetNextTextNodeChilds(obj, currentNode, currentLevel - 1); if (obj.foundNode !== undefined) { return; }			}		}

// no sibling, ascend to parent else { currentNode = currentNode.parentNode; currentLevel ++; }	}	return; };

// // wikEd.GetNextTextNodeChilds: recurse through child nodes to next text-like node for anti-highlight bleeding //

wikEd.GetNextTextNodeChilds = function (obj, currentNode, currentLevel) {

// set direction var childNodes = currentNode.childNodes; if (childNodes.length === 0) { return; }	var start = 0; var add = 1; if (obj.backwards === true) { start = childNodes.length - 1; add = -1; }

// cycle through child nodes (left or right) for (var i = start; ( (obj.backwards === true) && (i >= 0) ) || ( (obj.backwards !== true) && (i < childNodes.length) ); i = i + add) { var currentNode = childNodes.item(i);

// skip hidden nodes if (			( (wikEd.refHide === true) && (/^((wikEd(Ref|Templ|CharEntity|Table))|(wikEdTableBR))$/.test(currentNode.className) === true) ) ||			(/^(wikEdScroll(Before|After))$/.test(currentNode.className) === true)		) { continue; }

// found text-like node if (			(currentNode.nodeName == '#text') ||			(currentNode.nodeType == currentNode.ENTITY_REFERENCE_NODE) ||			(wikEd.leafElements[currentNode.nodeName] === true)		) { obj.foundNode = currentNode; obj.foundLevel = currentLevel; return; }

// recurse into child nodes if (currentNode.nodeType == currentNode.ELEMENT_NODE) { wikEd.GetNextTextNodeChilds(obj, currentNode, currentLevel - 1); if (obj.foundNode !== undefined) { return; }		}	}	return; };

// // wikEd.ApplyCSS: Attach css rules to document //

wikEd.ApplyCSS = function (cssDocument, cssRules) {

var stylesheet = new wikEd.StyleSheet(cssDocument); var rules = ''; for (var ruleName in cssRules) { if (Object.prototype.hasOwnProperty.call(cssRules, ruleName) === true) { var ruleStyle = cssRules[ruleName];

// replace {wikedImage:image} in css rules with image path ruleStyle = ruleStyle.replace(/\{wikEdImage:(\w+)\}/g,				function(p, p1) {					return wikEd.config.image[p1];				}			);

// replace {wikedText:text} in css rules with translation ruleStyle = ruleStyle.replace(/\{wikEdText:(\w+)\}/g,				function(p, p1) {					return wikEd.config.text[p1];				}			);

rules += ruleName + ' {' + ruleStyle + '}\n'; }	}	stylesheet.AddCSSRules(rules); return; };

// // wikEd.StyleSheet: create a new style sheet object //

wikEd.StyleSheet = function (contextObj) {

if (contextObj === undefined) { contextObj = document; }	this.styleElement = null;

this.styleElement = contextObj.createElement('style'); this.styleElement.from = 'text/css'; var insert = contextObj.getElementsByTagName('head')[0]; if (insert !== undefined) { insert.appendChild(this.styleElement); }

// // wikEd.StyleSheet.AddCSSRules: add or replace all rules at once //

this.AddCSSRules = function (rules) {

this.styleElement.appendChild(contextObj.createTextNode(rules)); return; }; };

// // wikEd.GetStyle: get computed style properties for non-inline css definitions //

wikEd.GetStyle = function (element, styleProperty) {

var styleDocument = element.ownerDocument;

var style; if (element !== null) { style = styleDocument.defaultView.getComputedStyle(element)[styleProperty]; }	return style; };

// // wikEd.AjaxPreview: get rendered page text using an Ajax non-API POST call //

wikEd.AjaxPreview = function (textValue, ResponseHandler, livePreview) {

// API request if ( (	wikEd.wikiGlobals.wgEnableAPI === true || wikEd.wikiGlobals.wgEnableAPI === 'true' ) && livePreview === true ) { var postFields = { 'format': 'xml', 'action': 'parse', 'title': wikEd.pageName, 'text': textValue };		var requestUrl = wikEd.scriptURL + 'api.php';

// AJAX API request wikEd.AjaxRequest( 'POST', requestUrl, postFields, 'text/plain', ResponseHandler ); }

// legacy support: non-API request, use Live preview if possible else {

// prepare the url var requestUrl; if ( wikEd.editForm !== null && wikEd.editUpload !== true && wikEd.editWatchlist !== true && wikEd.viewDeleted !== true ) { requestUrl = wikEd.editForm.action.replace( /\?.*/, '' ); if ( /:\/\//.test(requestUrl) === false ) { requestUrl = window.location.protocol + '//' + window.location.host + requestUrl; }		}		else if ( wikEd.wikiGlobals.wgScriptPath !== undefined ) { requestUrl = wikEd.wikiGlobals.wgScriptPath + '/index.php'; }		else { requestUrl = window.location.href; requestUrl = requestUrl.replace( /\?.*/, '' ); requestUrl = requestUrl.replace( /\/[\w\.]*$/, '/index.php' ); }

// prepare the form fields var postFields = {}; if ( wikEd.pageName !== null && wikEd.wikiGlobals.wgCanonicalNamespace != 'Special' ) { postFields['title'] = wikEd.pageName; }		else { postFields['title'] = 'wikEd_preview'; }		postFields['action'] = 'submit'; postFields['wpTextbox1'] = textValue; if ( wikEd.starttime !== null ) { postFields['wpStarttime'] = wikEd.starttime; }		if ( wikEd.edittime !== null ) { postFields['wpEdittime'] = wikEd.edittime; }		if ( wikEd.editToken !== null ) { postFields['wpEditToken'] = wikEd.editToken; }		if ( wikEd.autoSummary !== null ) { postFields['wpAutoSummary'] = wikEd.autoSummary; }		postFields['wpPreview'] = 'true'; if (livePreview !== false) { postFields['live'] = 'true'; }

// AJAX non-API request wikEd.AjaxRequest( 'POST', requestUrl, postFields, 'text/plain', ResponseHandler ); }	return; };

// // wikEd.AjaxRequest: wrapper for Ajax requests //

wikEd.AjaxRequest = function (requestMethod, requestUrl, postFields, overrideMimeType, ResponseHandler, origin) {

var request; var headers = {}; var formData;

// prepare POST request if (requestMethod == 'POST') {

// assemble string body if (typeof FormData != 'function') {

// create boundary var boundary = wikEd.CreateRandomString(12);

// POST header, charset: WebKit workaround http://aautar.digital-radiation.com/blog/?p=1645 headers['Content-Type'] = 'multipart/form-data; charset=UTF-8; boundary=' + boundary;

// assemble body data formData = ''; for (var fieldName in postFields) { if (Object.prototype.hasOwnProperty.call(postFields, fieldName) === true) { formData += '--' + boundary + '\r\n'; formData += 'Content-Disposition: form-data; name="' + fieldName + '"\r\n\r\n' + postFields[fieldName] + '\r\n'; }			}			formData += '--' + boundary + '--\r\n'; }

// use FormData object else { formData = new window.FormData; for (var fieldName in postFields) { if (Object.prototype.hasOwnProperty.call(postFields, fieldName) === true) { formData.append(fieldName, postFields[fieldName]); }			}		}	}

// send the request using Greasemonkey GM_xmlhttpRequest if (wikEd.greasemonkey === true) { headers['User-Agent'] = window.navigator.userAgent; if (origin === true) { headers['Origin'] = window.location.origin; }

// workaround for Error: Greasemonkey access violation: unsafeWindow cannot call GM_xmlhttpRequest. // see http://wiki.greasespot.net/Greasemonkey_access_violation window.setTimeout(function {			new GM_xmlhttpRequest({ 'method': requestMethod, 'url':    requestUrl, 'overrideMimeType': overrideMimeType, 'headers': headers, 'data':   formData, 'onreadystatechange': function(ajax) { if (ajax.readyState != 4) { return; }						ResponseHandler(ajax); return; }			});		}, 0);	}

// use standard XMLHttpRequest else {

// create new XMLHttpRequest object request = new window.XMLHttpRequest;

// open the request request.open(requestMethod, requestUrl, true);

// set the headers for (var headerName in headers) { if (Object.prototype.hasOwnProperty.call(headers, headerName) === true) { request.setRequestHeader(headerName, headers[headerName]); }		}

// set the mime type if ( (request.overrideMimeType !== undefined) && (typeof overrideMimeType == 'string') ) { request.overrideMimeType(overrideMimeType); }

// send the request, catch security violations Opera 0.9.51 try { request.send(formData); }		catch (exception) { return; }

// wait for the data request.onreadystatechange = function { if (request.readyState != 4) { return; }			ResponseHandler(request); return; };	}	return; };

// // wikEd.GetGlobals: parse global context variables (code copied to wikEdDiff.js) //  uses postMessage, head script, and JSON encoding for Greasemonkey global to GM context access

wikEd.GetGlobals = function (names, gotGlobalsHook) {

if (gotGlobalsHook !== undefined) { wikEd.gotGlobalsHook.push(gotGlobalsHook); }

// code already running in global context if (wikEd.greasemonkey !== true) { var globalScopeCode = ''; for (var i = 0; i < names.length; i ++) { globalScopeCode += '' + 'if (typeof ' + names[i] + ' != \'undefined\') {' + ' wikEd.wikiGlobals.' + names[i] + ' = ' + names[i] + ';' + '}';		}		if (gotGlobalsHook !== undefined) { globalScopeCode += 'wikEd.ExecuteHook(wikEd.gotGlobalsHook[' + (wikEd.gotGlobalsHook.length - 1) + '], true);'; }		eval(globalScopeCode); return; }

// prepare code to be executed in global context for Greasemonkey if ( (window.postMessage === undefined) || (typeof JSON != 'object') ) { return; }	var globalScopeCode = 'var globalObj = {};'; if (gotGlobalsHook !== undefined) { wikEd.gotGlobalsHook.push(gotGlobalsHook); globalScopeCode += 'globalObj.hookNumber = ' + (wikEd.gotGlobalsHook.length - 1) + ';'; }	globalScopeCode += 'globalObj.scriptId = \'wikEdGetGlobalScript' + wikEd.getGlobalsCounter + '\';'; globalScopeCode += 'globalObj.wikEdGetGlobals = {};';

// add global scope variables for (var i = 0; i < names.length; i ++) { globalScopeCode += '' + 'if (typeof ' + names[i] + ' != \'undefined\') {' + ' globalObj.wikEdGetGlobals[\'' + names[i] + '\'] = ' + names[i] + ';' + '}';	}	globalScopeCode += 'var globalObjStr = \'wikEd:\' + JSON.stringify(globalObj);'; var origin = wikEd.pageOrigin; if (origin == 'file://') { origin = '*'; }	globalScopeCode += 'window.postMessage(globalObjStr, \'' + origin + '\');';

// create head script to execute the code var script = document.createElement('script'); script.id = 'wikEdGetGlobalScript' + wikEd.getGlobalsCounter; wikEd.getGlobalsCounter ++; if (script.innerText !== undefined) { script.innerText = globalScopeCode; }	else { script.textContent = globalScopeCode; }	wikEd.head.appendChild(script); return; };

// // wikEd.GetGlobalsReceiver: event handler for wikEd.GetGlobals postMessage (code copied to wikEdDiff.js) //

wikEd.GetGlobalsReceiver = function (event) {

if (event.source != window) { return; }	if ( (event.origin != 'null') && (event.origin != wikEd.pageOrigin) ) { return; }	if (event.data !== '') {

// test if sent by wikEd if (/^wikEd:/.test(event.data) === false) { return; }		event.stopPropagation; var data = event.data.replace(/wikEd:/, ''); var globalObj = JSON.parse(data); var globals = globalObj.wikEdGetGlobals; if (globals !== null) { for (var key in globals) { if (Object.prototype.hasOwnProperty.call(globals, key) === true) { wikEd.wikiGlobals[key] = globals[key]; }			}

// get MediaWiki file paths from wikiGlobals wikEd.GetPaths;

// run scheduled functions only once if ( (globalObj.hookNumber !== undefined) && (wikEd.gotGlobalsHook[globalObj.hookNumber] !== undefined) ) { wikEd.ExecuteHook(wikEd.gotGlobalsHook[globalObj.hookNumber], true); }

// clean up head script var script = document.getElementById(globalObj.scriptId); if (script !== null) { wikEd.head.removeChild(script); }		}	}	return; };

// // wikEd.GetPreviousSiblingNode: getPreviousSibling, ignore non-element nodes such as comments //

wikEd.GetPreviousSiblingNode = function (node) {

while (node !== null) { node = node.previousSibling; if ( (node === null) || (node.nodeType == node.ELEMENT_NODE) ) { break; }	}	return node; };

// // wikEd.GetNextSiblingNode: getNextSibling, ignore non-element nodes such as comments //

wikEd.GetNextSiblingNode = function (node) {

while (node !== null) { node = node.nextSibling; if ( (node === null) || (node.nodeType == node.ELEMENT_NODE) ) { break; }	}	return node; };

// // wikEd.GetFirstChildNode: getFirstChild, ignore non-element nodes such as comments //

wikEd.GetFirstChildNode = function (node) {

if (node !== null) { node = node.firstChild; if ( (node !== null) && (node.nodeType != node.ELEMENT_NODE) ) { node = wikEd.GetNextSiblingNode(node); }	}	return node; };

// // wikEd.GetLastChildNode: getLastChild, ignore non-element nodes such as comments //

wikEd.GetLastChildNode = function (node) {

if (node !== null) { node = node.lastChild; if ( (node !== null) && (node.nodeType != node.ELEMENT_NODE) ) { node = wikEd.GetPreviousSiblingNode(node); }	}	return node; };

// // wikEd.CreateRandomString: create random string of specified length and character set (code copied to wikEdDiff.js) //

wikEd.CreateRandomString = function (strLength, charSet) {

if (charSet === undefined) { charSet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789'; }	var str = ''; for (var i = 0; i < strLength; i ++) { str += charSet.charAt(Math.floor(Math.random * charSet.length)); }	return str; };

// // wikEd.TabifyHTML: indent html for debugging //

wikEd.TabifyHTML = function (html) {

var indent = ''; var html = html.replace(/((<(\/)?(\w+)[^>]*>)?)([^<]*)/g,		function(p, p1, p2, p3, p4, p5, p6, p7) {			var html = ;			var code = p1;			var slash = p3;			var tag = p4;			var text = p7;			if ( (slash == '/') && (indent === ) ) {				html += '\n### Missing opening tag ###';			}			if ( (slash == '/') && (indent.length > 0) ) {				indent = indent.substr(0, indent.length - 1);			}			if ( (slash === ) && (tag.toLowerCase == 'tr') ) {				html += '\n';			}			html += '\n' + indent + code;			if ( (slash === ) && (tag.toLowerCase != 'br') ) {				indent += '\t';			}			if (text !== '') {				text = text.replace(/\n(?!($))/g, '\n' + indent);				html += '\n' + indent + text;			}			return html;		}	); return html; };

// // wikEd.Debug: print the value of variables //  use either a single value or a description followed by a value //  popup = true: use alert popup if debug textarea is not yet setup //

wikEd.Debug = function (objectName, object, usePopup) {

// string var value = ''; if (typeof object == 'string') { value = ': ' + '"' + object + '"'; }

// objects else if (typeof object == 'object') {

// null if (object === null) { value = ': [null]'; }

// whole highlighting parse tree array // { 'tag':, 'parent': , 'firstChild': , 'nextSibling': , 'start': , 'tagLength': , 'type': , 'paired': , 'pairedPos': , 'left': , 'right': , 'index': , 'attrib': , 'newline': } else if ( (typeof object[0] == 'object') && (typeof object[0].type == 'string') ) { value = ': Parse tree full:\n'; for (var i = 0; i < object.length; i ++) { value += i + ': '; var node = object[i]; if (node === null) { value += '(null)\n'; }				else { if (node.type == 'root') { value += '[type: "' + node.type + '"]\n'; }					else { value += '[type: "' + node.type + '", tag: "' + node.tag + '", start: ' + node.start + ', tagLength: ' + node.tagLength + ', parent: ' + node.parent; if (typeof node.left == 'string') { value += ', left: "' + node.left + '", right: "' + node.right + '"'; }						value += '],\n'; }				}			}		}

// whole highlighting parse tree up		else if ( (typeof object.tree == 'object') && (typeof object.lastOpenNode == 'number') ) { value = ': Parse tree upwards:\n'; var parseTreeIndex = object.lastOpenNode; var node = object.tree[parseTreeIndex]; while (node !== undefined) { if (node.type == 'root') { value += parseTreeIndex + ': [type: "' + node.type + '"]\n'; }				else { value += parseTreeIndex + ': [type: "' + node.type + '", tag: "' + node.tag + '", start: ' + node.start + ', tagLength: ' + node.tagLength + ', parent: ' + node.parent; if (typeof node.left == 'string') { value += ', left: "' + node.left + '", right: "' + node.right + '"'; }					value += '],\n'; }				if (node.parent == parseTreeIndex) { value += '(circular reference, break)'; break; }				parseTreeIndex = node.parent; node = object.tree[node.parent]; }		}

// highlighting parse tree node // { 'tag':, 'parent': , 'firstChild': , 'nextSibling': , 'start': , 'tagLength': , 'type': , 'paired': , 'pairedPos': , 'left': , 'right': , 'index': } else if (typeof object.tag == 'string') { var node = object; if (node.type == 'root') { value = ': [type: "' + node.type + '"]'; }			else { value = ': [tag: "' + node.tag + '", type: "' + node.type + '", start: ' + node.start + ', tagLength: ' + node.tagLength + ', parent: ' + node.parent + ']'; }		}

// DOM nodes else if (typeof object.nodeName == 'string') { value = ': [node; nodeName: ' + object.nodeName; if (typeof object.id == 'string') { if (object.id !== '') { value += ', id: "' + object.id + '"'; }			}			if (typeof object.className == 'string') { if (object.className !== '') { value += ', class: "' + object.className + '"'; }			}			if (typeof object.nodeValue == 'string') { value += ', nodeValue: "' + object.nodeValue + '"'; }			if ( (typeof object.innerHTML == 'string') && (object.innerHTML !== '') ) { var html = object.innerHTML; if (html.length > wikEd.config.debugInnerHtmlLength) { html = html.substr(0, wikEd.config.debugInnerHtmlLength - 3) + '...'; }				value += ', innerHTML: "' + html + '"'; }			value += ']'; }

// default else { value = ': [' + object + ']'; }	}

// undefined else if (object === undefined) { value = ''; }

// default else { value = ': ' + object; }

// use debug textarea var useDebug = false; if (wikEd.debug !== null) { useDebug = true; }	if (useDebug === true) { if (wikEd.debugOpen === false) { wikEd.debugWrapper.style.display = 'block';

// resize fullscreen frame if (wikEd.fullscreen === true) { wikEd.ResizeWindowHandler; }			else { window.scroll(0, wikEd.GetOffsetTop(wikEd.debug)); }			wikEd.debugOpen = true; }

// cut text if having reached maximum length value = objectName + value + '\n'; if (wikEd.debug.value.length > wikEd.config.debugMaxLength) { wikEd.debug.value = value + wikEd.debug.value.substr(0, wikEd.config.debugMaxLength * 2 / 3); }		else { wikEd.debug.value = value + wikEd.debug.value; }	}

// use popup alert else if (usePopup === true) { if (object === null) { window.alert(objectName); }		else { window.alert(objectName + ': ' + value); }	}

// use error console else { var msg; if (object === null) { msg = objectName; }		else { msg = objectName + ' ' + value; }		wikEd.ConsoleLog(msg); }	return; };

// // wikEd.ConsoleLog: log message to console // mw.log no longer works

wikEd.ConsoleLog = function (msg) {

if ( (typeof console == 'object') && (typeof console.error == 'function') ) { console.error('[wikEd debug]', msg); }	else { msg = msg.replace(/\n/g, '\\n'); msg = msg.replace(/([\'\"\\])/g, '\\$1');		window.setTimeout('throw new Error(\'[wikEd debug] ' + msg + '\')', 0);	}	return; };

// // wikEd.DebugTimer: show all measured timepoints //  add a new time measurement: wikEd.debugTimer.push([1234, new Date]);

wikEd.DebugTimer = function {

var times = ''; var start = wikEd.debugTimer[0][1].getTime; var prev = 0; for (var i = 0; i < wikEd.debugTimer.length; i ++) { var curr = wikEd.debugTimer[i][1].getTime - start; var diff = curr - prev; prev = curr; times += wikEd.debugTimer[i][0] + ': ' + curr + ' ms (+ ' + diff + ' ms)\n'; }	wikEd.Debug(times); wikEd.debugTimer = []; };

// // wikEd.InsertTags: overrides the insertTags function in wikibits.js used by the standard button toolbar and the editpage special chars //

wikEd.InsertTags = function (openTag, closeTag, sampleText) {

if (wikEd.useWikEd === true) { wikEd.EditButton(document.getElementById('wikEdInsertTags'), 'wikEdInsertTags', [openTag, closeTag, sampleText]); }	else if (wikEd.InsertTagsOriginal !== null) { wikEd.InsertTagsOriginal(openTag, closeTag, sampleText); }	return; };

// // wikEd.InsertAtCursor: overrides the insertAtCursor function in wikia.com MediaWiki:Functions.js //

wikEd.InsertAtCursor = function (myField, myValue) {

if (wikEd.useWikEd === true) { if (myField == wikEd.textarea) { wikEd.EditButton(document.getElementById('wikEdInsertTags'), 'wikEdInsertTags', [ myValue ]); }	}	else if (wikEd.InsertAtCursorOriginal !== null) { wikEd.InsertAtCursorOriginal(myField, myValue); }	return; };

// // wikEd.ExecuteHook: executes scheduled custom functions from functionsHook array (code copied to wikEdDiff.js) //

wikEd.ExecuteHook = function (functionsHook, onlyOnce) {

if (functionsHook === null) { return; }	for (var i = 0; i < functionsHook.length; i ++) { if (typeof functionsHook[i] == 'function') { functionsHook[i]; }	}	if (onlyOnce === true) { functionsHook = []; }	return; };

// // wikEd.InitUnicode: define character tables used in wikEd.FixUnicode //  see http://kmi.open.ac.uk/projects/ceryle/doc/docs/NOTE-charents.html

wikEd.InitUnicode = function {

// define only once if (wikEd.supportedChars !== null) { return; }

// supported chars in Mozilla and IE	wikEd.supportedChars = [ [ 'a1', 'iexcl'],  // ¡ [ 'a2', 'cent'],   // ¢ [ 'a3', 'pound'],  // £ [ 'a4', 'curren'], // ¤ [ 'a5', 'yen'],    // ¥ [ 'a6', 'brvbar'], // ¦ [ 'a7', 'sect'],   // § [ 'a8', 'uml'],    // ¨ [ 'a9', 'copy'],   // © [ 'aa', 'ordf'],   // ª [ 'ab', 'laquo'],  // « [ 'ac', 'not'],    // ¬ [ 'ae', 'reg'],    // ® [ 'af', 'macr'],   // ¯ [ 'b0', 'deg'],    // ° [ 'b1', 'plusmn'], // ± [ 'b2', 'sup2'],   // ² [ 'b3', 'sup3'],   // ³ [ 'b4', 'acute'],  // ´ [ 'b5', 'micro'],  // µ [ 'b6', 'para'],   // ¶ [ 'b7', 'middot'], // · [ 'b8', 'cedil'],  // ¸ [ 'b9', 'sup1'],   // ¹ [ 'ba', 'ordm'],   // º [ 'bb', 'raquo'],  // » [ 'bc', 'frac14'], // ¼ [ 'bd', 'frac12'], // ½ [ 'be', 'frac34'], // ¾ [ 'bf', 'iquest'], // ¿ [ 'c0', 'Agrave'], // À [ 'c1', 'Aacute'], // Á [ 'c2', 'Acirc'],  // Â [ 'c3', 'Atilde'], // Ã [ 'c4', 'Auml'],   // Ä [ 'c5', 'Aring'],  // Å [ 'c6', 'AElig'],  // Æ [ 'c7', 'Ccedil'], // Ç [ 'c8', 'Egrave'], // È [ 'c9', 'Eacute'], // É [ 'ca', 'Ecirc'],  // Ê [ 'cb', 'Euml'],   // Ë [ 'cc', 'Igrave'], // Ì [ 'cd', 'Iacute'], // Í [ 'ce', 'Icirc'],  // Î [ 'cf', 'Iuml'],   // Ï [ 'd0', 'ETH'],    // Ð [ 'd1', 'Ntilde'], // Ñ [ 'd2', 'Ograve'], // Ò [ 'd3', 'Oacute'], // Ó [ 'd4', 'Ocirc'],  // Ô [ 'd5', 'Otilde'], // Õ [ 'd6', 'Ouml'],   // Ö [ 'd7', 'times'],  // × [ 'd8', 'Oslash'], // Ø [ 'd9', 'Ugrave'], // Ù [ 'da', 'Uacute'], // Ú [ 'db', 'Ucirc'],  // Û [ 'dc', 'Uuml'],   // Ü [ 'dd', 'Yacute'], // Ý [ 'de', 'THORN'],  // Þ [ 'df', 'szlig'],  // ß [ 'e0', 'agrave'], // à [ 'e1', 'aacute'], // á [ 'e2', 'acirc'],  // â [ 'e3', 'atilde'], // ã [ 'e4', 'auml'],   // ä [ 'e5', 'aring'],  // å [ 'e6', 'aelig'],  // æ [ 'e7', 'ccedil'], // ç [ 'e8', 'egrave'], // è [ 'e9', 'eacute'], // é [ 'ea', 'ecirc'],  // ê [ 'eb', 'euml'],   // ë [ 'ec', 'igrave'], // ì [ 'ed', 'iacute'], // í [ 'ee', 'icirc'],  // î [ 'ef', 'iuml'],   // ï [ 'f0', 'eth'],    // ð [ 'f1', 'ntilde'], // ñ [ 'f2', 'ograve'], // ò [ 'f3', 'oacute'], // ó [ 'f4', 'ocirc'],  // ô [ 'f5', 'otilde'], // õ [ 'f6', 'ouml'],   // ö [ 'f7', 'divide'], // ÷ [ 'f8', 'oslash'], // ø [ 'f9', 'ugrave'], // ù [ 'fa', 'uacute'], // ú [ 'fb', 'ucirc'],  // û [ 'fc', 'uuml'],   // ü [ 'fd', 'yacute'], // ý [ 'fe', 'thorn'],  // þ [ 'ff', 'yuml'],   // ÿ [ '27', 'apos'],   // ' [ '22', 'quot'],   // "		[ '152', 'OElig'],  // Œ		[ '153', 'oelig'],  // œ		[ '160', 'Scaron'], // Š		[ '161', 'scaron'], // š		[ '178', 'Yuml'],   // Ÿ		[ '2c6', 'circ'],   // ˆ		[ '2dc', 'tilde'],  // ˜		['2013', 'ndash'],  // –		['2014', 'mdash'],  // —		['2018', 'lsquo'],  // ‘		['2019', 'rsquo'],  // ’		['201a', 'sbquo'],  // ‚		['201c', 'ldquo'],  // “		['201d', 'rdquo'],  // ”		['201e', 'bdquo'],  // „		['2020', 'dagger'], // †		['2021', 'Dagger'], // ‡		['2030', 'permil'], // ‰		['2039', 'lsaquo'], // ‹		['203a', 'rsaquo'], // ›		['20ac', 'euro'],   // €		[ '192', 'fnof'],   // ƒ		[ '391', 'Alpha'],  // Α		[ '392', 'Beta'],   // Β		[ '393', 'Gamma'],  // Γ		[ '394', 'Delta'],  // Δ		[ '395', 'Epsilon'],// Ε		[ '396', 'Zeta'],   // Ζ		[ '397', 'Eta'],    // Η		[ '398', 'Theta'],  // Θ		[ '399', 'Iota'],   // Ι		[ '39a', 'Kappa'],  // Κ		[ '39b', 'Lambda'], // Λ		[ '39c', 'Mu'],     // Μ [ '39d', 'Nu'],    // Ν [ '39e', 'Xi'],    // Ξ [ '39f', 'Omicron'],// Ο [ '3a0', 'Pi'],    // Π [ '3a1', 'Rho'],   // Ρ [ '3a3', 'Sigma'], // Σ [ '3a4', 'Tau'],   // Τ [ '3a5', 'Upsilon'],// Υ [ '3a6', 'Phi'],   // Φ [ '3a7', 'Chi'],   // Χ [ '3a8', 'Psi'],   // Ψ [ '3a9', 'Omega'], // Ω [ '3b1', 'alpha'], // α [ '3b2', 'beta'],  // β [ '3b3', 'gamma'], // γ [ '3b4', 'delta'], // δ [ '3b5', 'epsilon'],// ε [ '3b6', 'zeta'],  // ζ [ '3b7', 'eta'],   // η [ '3b8', 'theta'], // θ [ '3b9', 'iota'],  // ι [ '3ba', 'kappa'], // κ [ '3bb', 'lambda'], // λ [ '3bc', 'mu'],    // μ [ '3bd', 'nu'],    // ν [ '3be', 'xi'],    // ξ [ '3bf', 'omicron'],// ο [ '3c0', 'pi'],    // π [ '3c1', 'rho'],   // ρ [ '3c2', 'sigmaf'], // ς [ '3c3', 'sigma'], // σ [ '3c4', 'tau'],   // τ [ '3c5', 'upsilon'],// υ [ '3c6', 'phi'],   // φ [ '3c7', 'chi'],   // χ [ '3c8', 'psi'],   // ψ [ '3c9', 'omega'], // ω ['2022', 'bull'],  // • ['2026', 'hellip'], // … ['2032', 'prime'], // ′ ['2033', 'Prime'], // ″ ['203e', 'oline'], // ‾ ['2044', 'frasl'], // ⁄ ['2122', 'trade'], // ™ ['2190', 'larr'],  // ← ['2191', 'uarr'],  // ↑ ['2192', 'rarr'],  // → ['2193', 'darr'],  // ↓ ['2194', 'harr'],  // ↔ ['21d2', 'rArr'],  // ⇒ ['21d4', 'hArr'],  // ⇔ ['2200', 'forall'], // ∀ ['2202', 'part'],  // ∂ ['2203', 'exist'], // ∃ ['2207', 'nabla'], // ∇ ['2208', 'isin'],  // ∈ ['220b', 'ni'],    // ∋ ['220f', 'prod'],  // ∏ ['2211', 'sum'],   // ∑ ['2212', 'minus'], // − ['221a', 'radic'], // √ ['221d', 'prop'],  // ∝ ['221e', 'infin'], // ∞ ['2220', 'ang'],   // ∠ ['2227', 'and'],   // ∧ ['2228', 'or'],    // ∨ ['2229', 'cap'],   // ∩ ['222a', 'cup'],   // ∪ ['222b', 'int'],   // ∫ ['2234', 'there4'], // ∴ ['223c', 'sim'],   // ∼ ['2248', 'asymp'], // ≈ ['2260', 'ne'],    // ≠ ['2261', 'equiv'], // ≡ ['2264', 'le'],    // ≤ ['2265', 'ge'],    // ≥ ['2282', 'sub'],   // ⊂ ['2283', 'sup'],   // ⊃ ['2286', 'sube'],  // ⊆ ['2287', 'supe'],  // ⊇ ['2295', 'oplus'], // ⊕ ['25ca', 'loz'],   // ◊ ['2660', 'spades'], // ♠ ['2663', 'clubs'], // ♣ ['2665', 'hearts'], // ♥ ['2666', 'diams']  // ♦ ];

// reserved for internal wikEd use wikEd.reservedChars = [ [ '26', 'amp'],    // & [ '3c', 'lt'],     // < [ '3e', 'gt'],     // > [ 'a0', 'nbsp']    // ];

// special chars (spaces and invisible characters) wikEd.specialChars = [ ['2002', 'ensp'],  //   en space [ 'ad', 'shy'],    // ­ soft hyphen ['2003', 'emsp'],  //   em space ['2009', 'thinsp'], //   thin space ['200c', 'zwnj'],  // ‌ zero width non-joiner ['200d', 'zwj'],   // ‍ zero width joiner ['200e', 'lrm'],   // ‎ left-to-right mark ['200f', 'rlm']    // ‏ right-to-left mark ];

// unsupported chars in IE6 wikEd.problemChars = [ [ '3d1', 'thetasym'], // ϑ [ '3d2', 'upsih'],   // ϒ [ '3d6', 'piv'],     // ϖ ['2118', 'weierp'],  // ℘ ['2111', 'image'],   // ℑ ['211c', 'real'],    // ℜ ['2135', 'alefsym'], // ℵ ['21b5', 'crarr'],   // ↵ ['21d0', 'lArr'],    // ⇐ ['21d1', 'uArr'],    // ⇑ ['21d3', 'dArr'],    // ⇓ ['2205', 'empty'],   // ∅ ['2209', 'notin'],   // ∉ ['2217', 'lowast'],  // ∗ ['2245', 'cong'],    // ≅ ['2284', 'nsub'],    // ⊄ ['22a5', 'perp'],    // ⊥ ['2297', 'otimes'],  // ⊗ ['22c5', 'sdot'],    // ⋅ ['2308', 'lceil'],   // ⌈ ['2309', 'rceil'],   // ⌉ ['230a', 'lfloor'],  // ⌊ ['230b', 'rfloor'],  // ⌋ ['2329', 'lang'],    // 〈 ['232a', 'rang']     // 〉 ];

// index to all existing 253 HTML/XHTML character entities var allCharEntities = wikEd.supportedChars.concat(wikEd.reservedChars, wikEd.specialChars, wikEd.problemChars); for (var i = 0; i < allCharEntities.length; i ++) { wikEd.charEntitiesByName[ allCharEntities[i][1] ] = String.fromCharCode(parseInt(allCharEntities[i][0], 16)); }

// syntax highlighting of ASCII control characters and invisibles (decimal value, title) wikEd.controlCharHighlighting = { '0': 'null', '1': 'start of heading', '2': 'start of text', '3': 'end of text', '4': 'end of transmission', '5': 'enquiry', '6': 'acknowledge', '7': 'bell', '8': 'backspace', '11': 'vertical tab', '12': 'form feed, new page', '14': 'shift out', '15': 'shift in', '16': 'data link escape', '17': 'device control 1', '18': 'device control 2', '19': 'device control 3', '20': 'device control 4', '21': 'negative acknowledge', '22': 'synchronous idle', '23': 'end of trans. block', '24': 'cancel', '25': 'end of medium', '26': 'substitute', '27': 'escape', '28': 'file separator', '29': 'group separator', '30': 'record separator', '31': 'unit separator', '8204': 'zero width non-joiner', // \u200c '8205': 'zero width joiner',    // \u200d '8206': 'left-to-right mark',   // \u200e '8207': 'right-to-left mark',   // \u200f '8232': 'line separator',       // \u2028 '8233': 'paragraph separator'   // \u2028 };	for (var decimalValue in wikEd.controlCharHighlighting) { if (Object.prototype.hasOwnProperty.call(wikEd.controlCharHighlighting, decimalValue) === true) { wikEd.controlCharHighlightingStr += '\\' + String.fromCharCode(decimalValue); }	}

// character syntax highlighting: strange spaces, hyphens, and dashes (decimal value, class = title) wikEd.charHighlighting = { '9':    'tab',        // \u0009 '	' '8194': 'enSpace',    // \u2002 ' ' '8195': 'emSpace',    // \u2003 ' ' '8201': 'thinSpace',  // \u2009 ' ' '12288': 'ideographicSpace', // \u3000 '　' '45':   'hyphenDash', // \u00a0 '-' '173':  'softHyphen', // \u00ad '­' '8210': 'figureDash', // \u2012 '‒' '8211': 'enDash',     // \u2013 '–' '8212': 'emDash',     // \u2014 '—' '8213': 'barDash',    // \u2015 '―' '8722': 'minusDash'   // \u2212 '−' };	for (var decimalValue in wikEd.charHighlighting) { if (Object.prototype.hasOwnProperty.call(wikEd.charHighlighting, decimalValue) === true) { wikEd.charHighlightingStr += '\\' + String.fromCharCode(decimalValue); }	}

// UniCode support for regexps, without _0-9, from http://xregexp.com/addons/unicode/unicode-base.js v1.0.0 wikEd.letters = '0041-005A0061-007A00AA00B500BA00C0-00D600D8-00F600F8-02C102C6-02D102E0-02E402EC02EE0370-037403760377037A-037D03860388-038A038C038E-03A103A3-03F503F7-0481048A-05270531-055605590561-058705D0-05EA05F0-05F20620-064A066E066F0671-06D306D506E506E606EE06EF06FA-06FC06FF07100712-072F074D-07A507B107CA-07EA07F407F507FA0800-0815081A082408280840-085808A008A2-08AC0904-0939093D09500958-09610971-09770979-097F0985-098C098F09900993-09A809AA-09B009B209B6-09B909BD09CE09DC09DD09DF-09E109F009F10A05-0A0A0A0F0A100A13-0A280A2A-0A300A320A330A350A360A380A390A59-0A5C0A5E0A72-0A740A85-0A8D0A8F-0A910A93-0AA80AAA-0AB00AB20AB30AB5-0AB90ABD0AD00AE00AE10B05-0B0C0B0F0B100B13-0B280B2A-0B300B320B330B35-0B390B3D0B5C0B5D0B5F-0B610B710B830B85-0B8A0B8E-0B900B92-0B950B990B9A0B9C0B9E0B9F0BA30BA40BA8-0BAA0BAE-0BB90BD00C05-0C0C0C0E-0C100C12-0C280C2A-0C330C35-0C390C3D0C580C590C600C610C85-0C8C0C8E-0C900C92-0CA80CAA-0CB30CB5-0CB90CBD0CDE0CE00CE10CF10CF20D05-0D0C0D0E-0D100D12-0D3A0D3D0D4E0D600D610D7A-0D7F0D85-0D960D9A-0DB10DB3-0DBB0DBD0DC0-0DC60E01-0E300E320E330E40-0E460E810E820E840E870E880E8A0E8D0E94-0E970E99-0E9F0EA1-0EA30EA50EA70EAA0EAB0EAD-0EB00EB20EB30EBD0EC0-0EC40EC60EDC-0EDF0F000F40-0F470F49-0F6C0F88-0F8C1000-102A103F1050-1055105A-105D106110651066106E-10701075-1081108E10A0-10C510C710CD10D0-10FA10FC-1248124A-124D1250-12561258125A-125D1260-1288128A-128D1290-12B012B2-12B512B8-12BE12C012C2-12C512C8-12D612D8-13101312-13151318-135A1380-138F13A0-13F41401-166C166F-167F1681-169A16A0-16EA1700-170C170E-17111720-17311740-17511760-176C176E-17701780-17B317D717DC1820-18771880-18A818AA18B0-18F51900-191C1950-196D1970-19741980-19AB19C1-19C71A00-1A161A20-1A541AA71B05-1B331B45-1B4B1B83-1BA01BAE1BAF1BBA-1BE51C00-1C231C4D-1C4F1C5A-1C7D1CE9-1CEC1CEE-1CF11CF51CF61D00-1DBF1E00-1F151F18-1F1D1F20-1F451F48-1F4D1F50-1F571F591F5B1F5D1F5F-1F7D1F80-1FB41FB6-1FBC1FBE1FC2-1FC41FC6-1FCC1FD0-1FD31FD6-1FDB1FE0-1FEC1FF2-1FF41FF6-1FFC2071207F2090-209C21022107210A-211321152119-211D212421262128212A-212D212F-2139213C-213F2145-2149214E218321842C00-2C2E2C30-2C5E2C60-2CE42CEB-2CEE2CF22CF32D00-2D252D272D2D2D30-2D672D6F2D80-2D962DA0-2DA62DA8-2DAE2DB0-2DB62DB8-2DBE2DC0-2DC62DC8-2DCE2DD0-2DD62DD8-2DDE2E2F300530063031-3035303B303C3041-3096309D-309F30A1-30FA30FC-30FF3105-312D3131-318E31A0-31BA31F0-31FF3400-4DB54E00-9FCCA000-A48CA4D0-A4FDA500-A60CA610-A61FA62AA62BA640-A66EA67F-A697A6A0-A6E5A717-A71FA722-A788A78B-A78EA790-A793A7A0-A7AAA7F8-A801A803-A805A807-A80AA80C-A822A840-A873A882-A8B3A8F2-A8F7A8FBA90A-A925A930-A946A960-A97CA984-A9B2A9CFAA00-AA28AA40-AA42AA44-AA4BAA60-AA76AA7AAA80-AAAFAAB1AAB5AAB6AAB9-AABDAAC0AAC2AADB-AADDAAE0-AAEAAAF2-AAF4AB01-AB06AB09-AB0EAB11-AB16AB20-AB26AB28-AB2EABC0-ABE2AC00-D7A3D7B0-D7C6D7CB-D7FBF900-FA6DFA70-FAD9FB00-FB06FB13-FB17FB1DFB1F-FB28FB2A-FB36FB38-FB3CFB3EFB40FB41FB43FB44FB46-FBB1FBD3-FD3DFD50-FD8FFD92-FDC7FDF0-FDFBFE70-FE74FE76-FEFCFF21-FF3AFF41-FF5AFF66-FFBEFFC2-FFC7FFCA-FFCFFFD2-FFD7FFDA-FFDC'.replace(/(\w{4})/g, '\\u$1');

return; };

// call startup wikEd.Startup; //