مدیاویکی:Gadget-Extra-Editbuttons-persiantools.js و مدیاویکی:Gadget-Extra-Editbuttons-persianwikitools.js: تفاوت میان صفحه‌ها

    از ویکی پاسخ
    (تفاوت بین صفحه‌ها)
    (صفحه‌ای تازه حاوی «// <nowiki> // DO NOT REMOVE THIS LINE EVER /** * Persian text style improvement tools * Tests: [[مدیاویکی:Gadget-Extra-Editbutto...» ایجاد کرد)
     
    (صفحه‌ای تازه حاوی «// <nowiki> // DO NOT REMOVE THIS LINE EVER /** * Wikipedia specific Persian text style improvement tools * Tests: [[مدیاویکی:Gad...» ایجاد کرد)
     
    خط ۱: خط ۱:
    // <nowiki> // DO NOT REMOVE THIS LINE EVER
    // <nowiki> // DO NOT REMOVE THIS LINE EVER
    /**
    /**
      * Persian text style improvement tools
      * Wikipedia specific Persian text style improvement tools
      * Tests: [[مدیاویکی:Gadget-Extra-Editbuttons-tests.js]] [[وپ:تست]]
      * Tests: [[مدیاویکی:Gadget-Extra-Editbuttons-tests.js]] [[وپ:تست]]
      * See also:
      * See also: [[مدیاویکی:Gadget-Extra-Editbuttons-persiantools.js]]
    * * [[مدیاویکی:Gadget-Extra-Editbuttons-persianwikitools.js]]
    * * [[مدیاویکی:Gadget-Extra-Editbuttons-dictionary.js]]
      */
      */
    var persianTools = (function () {
    /*global persianTools, persianToolsDictionary, autoEd*/
    var persianWikiTools = (function () {
    'use strict';
    'use strict';
            //http://www.entitycode.com/
    var persianGlyphs, persianDigits, arabicIndicDigits, arabicDigits,
    var htmlEntityCodes = {
    vowels, persianCharacters, persianCharactersNoVowels, persianPastVerbs,
    "&iexcl;": "¡", "&cent;": "¢", "&pound;": "£", "&curren;": "¤",
    persianPresentVerbs, persianComplexPastVerbs, persianComplexPresentVerbs, similarPersianCharacters, hamza;
    "&yen;": "¥", "&brvbar;": "¦", "&sect;": "§", "&copy;": "©",
    "&middot;": "·", "&times;": "×", "&rdquo;": "”", "&dagger;": "†",
    "&Dagger;": "‡", "&euro;": "€", "&laquo;": "«", "&reg;": "®",
    "&deg;": "°", "&plusmn;": "±", "&sup2;": "²", "&sup3;": "³",
    "&para;": "¶", "&sup1;": "¹", "&raquo;": "»", "&frac14;": "¼",
    "&frac12;": "½", "&frac34;": "¾", "&iquest;": "¿", "&divide;": "÷",
    "&ndash;": "–", "&mdash;": "—", "&lsquo;": "‘", "&rsquo;": "’",
    "&ldquo;": "“", "&trade;": "™", "&bull;": "•", "&hellip;": "…",
    "&permil;": "‰", "&lsaquo;": "‹", "&rsaquo;": "›", "&larr;": "←",
    "&uarr;": "↑", "&rarr;": "→", "&darr;": "↓", "&harr;": "↔",
    "&crarr;": "↵", "&minus;": "−", "&radic;": "√", "&infin;": "∞",
    "&loz;": "◊", "&spades;": "♠", "&rfloor;": "⌋", "&nbsp;": " ",
    "&ne;": "≠", "&ap;": "≈", "&approx;": "≈", "&asymp;": "≈",
    "&rceil;": "⌉", "&lfloor;": "⌊", "&diams;": "♦", "&auml;": "ä",
    "&ouml;": "ö", "&uuml;": "ü", "&szlig;": "ß", "&aring;": "å",
    "&oline; ": "‾ ", "&aelig;": "æ", "&ccedil;": "ç", "&ntilde;": "ñ",
    "&acirc;": "â", "&aacute;": "á", "&agrave;": "à", "&#36;": "$",
    "&clubs;": "♣", "&hearts;": "♥", "&Prime;": "″", "&prime;": "′",
    "&lceil;": "⌈", "&mldr;": "…", "&bullet;": "•", "&grave;": "`",
    "&pm;": "±", "&acute;": "´", "&centerdot;": "·", "&half;": "½",
    "&Auml;": "Ä", "&Ouml;": "Ö",  "&Uuml;": "Ü", "&rsquor;": "’",
    "&lsquor;": "‚", "&sbquo;": "‚", "&rdquor;": "”", "&bdquo;": "„",
    "&ldquor;": "„",  "&ddagger;": "‡", "&div;": "÷", "&leq;": "≤",
    "&geq;": "≥", "&le;": "≤", "&ge;": "≥"
    }; // &quot; , &amp; &lt; &gt; &#124;
    var patterns = {
    arabicDigitsEnglishContext: /[a-z]([\|a-z %"'\._:\;,\-\\\/\(\)\#\^\+\d><–\[\]&?{}](?!\|\|))*\d|(\d|[a-z])[a-z %"'\._:\;\|,\-\\\/\(\)\#\^\+\d><–\[\]&?{}]*[a-z]\d*/gi,
    arabicTagEnclosed: /\{\{(?:عربی|شروع عربی|آغاز عربی)\}\}([\s\S]*?)\{\{(?:پایان عربی)\}\}/g,
    LtRTagEnclosed: /\{\{(?:چپ چین|چپ‌چین)\}\}([\s\S]*?)\{\{(?:پایان چپ‌چین|پایان چپ چین|پایان)\}\}/g,
    argumentsBlacklist: /(?:accessdate|namespace|legend1start|image|تصویر|doi|style|شابک|عرض|bibcode|isbn|issn|pmid|arxiv|upright|upleft|padding|spacing|border|filename|نام پرونده)\s*\=\s*[^\|\}\]]*/gi,
    color: /#(?:[abcdef0-9]{8}|[abcdef0-9]{6}|[abcdef0-9]{3})/gi,
    //colorAsParameter: /\=\s*(?:[abcdef0-9]{8}|[abcdef0-9]{6}|[abcdef0-9]{3})(?:[\s\|\}]|$)/gi,
    // space, ", \t, \n, {, |, }, ... they will interfere with wiki markup
    decodeUriBlacklist: /(?:%20|%27|%5C|%5E|%60|%23|%25|%3C|%3E|%5B|%5D|%22|%09|%0A|%7B|%7C|%7D)/gi,
    diffLink: /\[\[(?:ویژه|Special):(?:تفاوت|Diff)\/[^\|\]]*/gi,
    englishDate: /\d{1,2},? [a-z]{3,} \d{2,4}/gi, // 3, May 2013
    fileNames: /(?:پرونده|File|تصویر|Image)\:.*?(?=\||\]|\n|$)/gi, // don't capture | after
    fileParameter: /\|\s*(image|تصویر)\s*\=\s*.*/g,
    ipSign: /\[\[ویژه:مشارکت\u200cها.*?\]\]/g,
    isbn: /(?:ISBN|ISSN|PMID) [\d\-]*/gi,
    galleryTag: /<gallery.*?>[\s\S]*?<\/gallery>/g,
    htmlAttributes: /(?:style|perrow|colspan|color|rowspan|cellpadding|cellspacing|height|width|size|border|thumbtime|name|perrow|upright|upleft)\s*[\=\:]\s*(?:['\"].*?['\"]|[\da-z]+)/gi,
    htmlEntity: /&#\d+;/,
    imagePixelSize: /[\|=] *[x\d]+?(px|پیکسل)[\]\|\s]/g, // means it will capture |10px| and |10x10px|
    insideQuote: /[^ا]".*?"/g,
    wikilinkTargets: /\[[^\[|\]]+/g,
    nowikiTag:/<nowiki>.+?<\/nowiki>/g,
    preTag:/<pre.*?>.*?<\/pre>/g,
    insideHtmlComment: /<\!\-\-[\s\S]*?\-\->/g,
    linksOnEnglishContext: /[a-z][\:\,\. ]*\[\[[\da-z\-\, ]*/gi,
    mathTag: /<math.*?>[\s\S]*?<\/math>/g,
    otherLanguagesInline: /\{\{(?:به .+?|پم|به انگلیسی|انگلیسی|عربی|متن عربی|عبارت عربی|حدیث|به عربی|به اردو|اردو|lang\-[au]r|پینگ|ping)[\s\S]*?\}\}/g,
    parameter: /\{\{\{\d+/gi,
    parenthesesAfterDigits: /\w\s?\([\w\s\.\-]*?\)/g,
    parenthesesHa: /\)ها/g,
    ref: /(?:<ref[^\/]*?>[\s\S]*?<\/ref>|<ref[^\/]*?\/>)/g, // inside <ref></ref> and <ref/>
    refname: /\<ref name\=.*?\>/g,
    citation:/\{\{\s*(?:[Cc]it|یادکرد).*?[_\s]*(?:\{\{.*?\}\}|[^\}])*\}\}/g,
    signatures: /\[\[(?:کاربر|User|بحث[ _]کاربر|User[_ ]talk)\:.*?\]\]/gi,
    sourceTag: /(<source.*?>[\s\S]*?<\/source>|<syntaxhighlight.*?>[\s\S]*?<\/syntaxhighlight>|<code.*?>[\s\S]*?<\/code>|<timeline.*?>[\s\S]*?<\/timeline>)/g,
    tagNames: /<\/?[a-zA-Z\d]*/g,
    templateEnglishName: /(الگو|Template):[a-z][a-z\d\-\+_]+/gi,
    templateWithEnglishName: /\{\{[ \_]*(?:(?:الگو|Template):)?(?:start\-date)[ \_]*\|.*?\}\}/gi,
    templateParameterName: /\|\s*(?=[a-z_]*\d)[a-z_\d]*\s*\=/gi,
    globalExceptionTag: /(<nowiki>.+?<\/nowiki>|<!--[\s]*ابر[\s]*-->.+?<!--[\s]*\/[\s]*ابر[\s]*-->|\{\{استثنای ابرابزار\|[\s\S]*?\}\})/gi,
    translatedUrl: /.(کام|نت|آی‌آر)/g,
    boxVar: /([a-zA-Z][۱۲۳۴۵۶۷۸۹۰]+) *\=/g,
    url: /\/\/.*?(?=[\s\n\|\}\]<]|$)/gi, // بدون https?: هم ممکن است
    mediawikiFunctions: /\{\{\#(?:\{\{.*?\}\}|[^\}])*\}\}/gi,
    articleTitleParts: new RegExp('\\s' + mw.config.get('wgTitle').split(' ').join('\\s|\\s') + '\\s', 'g'),
    catgories:/\[\[(?:رده|[Cc]ategory)\:[^\]]+\]\]/gi
    };


    arabicDigits = '0123456789';
    function escapeRE( s ) {
    arabicIndicDigits = '٠١٢٣٤٥٦٧٨٩';
    return s.replace( /([$()*+\-.?[\\\]^{|}])/g, '\\$1' );
    //نویسه\u200cهای غیرفارسی ي-ك-ە و موارد مشابه پیش از تبدیل به نویسهٔ فارسی در سایر ریجکس\u200cها باید به عنوان کاراکتر فارسی شناخته شوند.
    }
    similarPersianCharacters = '\u0643\uFB91\uFB90\uFB8F\uFB8E\uFEDC\uFEDB\uFEDA\uFED9\u0649\uFEEF\u064A\u06C1\u06D5\u06BE\uFEF0-\uFEF4';
    vowels = '\u064B-\u0650\u0652\u0670';
    persianCharacters = '\u0621-\u0655\u067E\u0686\u0698\u06AF\u06A9\u0643\u06AA\uFED9\uFEDA\u06CC\uFEF1\uFEF2' + similarPersianCharacters;
    persianCharactersNoVowels = '\u0621-\u064A\u0653-\u0655\u067E\u0686\u0698\u06AF\u06A9\u0643\u06AA\uFED9\uFEDA\u06CC\uFEF1\uFEF2' + similarPersianCharacters;
    persianDigits = '۰۱۲۳۴۵۶۷۸۹';
    hamza = '\u0654';


    function normalizeZwnj(text) {
    function descendingFromComparetor(x, y) {
    return x.from - y.from;
    }
    function removeCheckDict(text){
    // رفع مشکل [[Special:Permalink/25174868#متن هایلایت‌شده]]
    var otext = ''
    while (otext!=text){
    otext = text
    text=text.replace(/\<span[^>]+CheckDictation\-marked[^>]+\>([^<>]+)\<\/span\>/g, '$1')
    }
    return text
    return text
    // Replace LRM، RLM characters with ZWNJ and it will remove unneeded ZWNJ at next lines
    // .replace(/[\u180E\u2028\u2029\u202A\u202B\u202C\u202D\u202E\u200F¬]/g, '\u200c')
    .replace(new RegExp('([' + persianCharacters + '] *)[\u200F\u200E]+( *[' + persianCharacters + '])', 'g'), '$1\u200c$2')
    // Remove more than a ZWNJs
    .replace(/([\u200B-\u200D\uFEFF\u200E\u200F]){2,}/g, '$1')
    // Convert ¬ to zwnj in Persian context
    .replace(new RegExp('([' + persianCharacters + '])¬(?=[' + persianCharacters + '])', 'g'), '$1\u200c')
    // Clean ZWNJs after characters that don't conncet to the next letter
    .replace(/([۰-۹0-9إأةؤورزژاآدذ،؛,\:«»\\\/@#$٪×\*\(\)ـ\-=\|ء])\u200c/g, '$1')
    // Clean ZWNJs before and after English characters
    .replace(/[\u200B-\u200D\uFEFF]([\w])/g, '$1')
    .replace(/([\w])[\u200B-\u200D\uFEFF]/g, '$1')
    // Clean ZWNJs before and after Persian characters
    .replace(new RegExp('\[\\u200b\-\\u200d\\uFEFF\]([' + vowels + arabicIndicDigits + persianDigits + hamza+'])','g'), '$1')
    .replace(new RegExp('(['+arabicIndicDigits+'])\[\\u200b\-\\u200d\\uFEFF\]','g'), '$1')
    // Clean ZWNJs after and before punctuation
    .replace(/[\u200B\u200C\uFEFF]([ء\n\s\[\]\.،«»\:\(\)\؛\؟\?\;\$\!\@\-\=\+\\\|])/g, '$1')
    .replace(/([\n\s\[\.،«»\:\(\)\؛\؟\?\;\$\!\@\-\=\+\\\|])[\u200B-\u200D\uFEFF]/g, '$1')
    // Clean ZWNJs before brakets which have sapce after\before them
    .replace(/[\u200B-\u200D\uFEFF](\]\][\s\n])/g, '$1')
    .replace(/([\n\s]\[\[)[\u200B-\u200D\uFEFF]/g, '$1');
    }
    }
    function replaceExcept(text, callback, excepts) {
    var match, result = [], i, ranges, minRange, to, min, max;
    while (text !== '') {
    ranges = [];
    for (i in excepts) {
    if (excepts.hasOwnProperty(i)) {
    // a global regex should be reset before calls
    excepts[i].lastIndex = 0;
    match = excepts[i].exec(text);
    if (match !== null) {
    ranges.push({
    from: match.index,
    to: match.index + match[0].length
    });
    }
    }
    }


    persianGlyphs = {
    // so nothing is matched
    // these two are for visually available ZWNJ #visualZwnj
    if (ranges.length === 0) {
    '\u200cه': 'ﻫ',
    result.push(callback(text));
    'ی\u200c': 'ﻰﻲ',
    break;
    'أ': 'ﺄﺃﺃ',
    }
    'آ': 'ﺁﺁﺂ',
     
    'إ': 'ﺇﺈﺇ',
    minRange = ranges.sort(descendingFromComparetor)[0];
    'ا': 'ﺍﺎ',
    min = minRange.from;
    'ب': 'ﺏﺐﺑﺒ',
     
    'پ': 'ﭖﭗﭘﭙ',
    to = [];
    'ت': 'ﺕﺖﺗﺘ',
    for (i in ranges) {
    'ث': 'ﺙﺚﺛﺜ',
    if (ranges.hasOwnProperty(i)) {
    'ج': 'ﺝﺞﺟﺠ',
    if (ranges[i].from <= minRange.to) {
    'چ': 'ﭺﭻﭼﭽ',
    to.push(ranges[i].to);
    'ح': 'ﺡﺢﺣﺤ',
    }
    'خ': 'ﺥﺦﺧﺨ',
    }
    'د': 'ﺩﺪ',
    }
    'ذ': 'ﺫﺬ',
    max = Math.max.apply(null, to);
    'ر': 'ﺭﺮ',
     
    'ز': 'ﺯﺰ',
    result.push(callback(text.substr(0, min)));
    'ژ': 'ﮊﮋ',
    result.push(text.substr(min, max - min));
    'س': 'ﺱﺲﺳﺴ',
    // console.log('Excepted: "' + text.substr(min, max - min) + '"');
    ': 'ﺵﺶﺷﺸ',
    text = text.substr(max);
    'ص': 'ﺹﺺﺻﺼ',
    }
    'ض': 'ﺽﺾﺿﻀ',
    return result.join('');
    'ط': 'ﻁﻂﻃﻄ',
    }
    'ظ': 'ﻅﻆﻇﻈ',
     
    'ع': 'ﻉﻊﻋﻌ',
    function wikiConvertToPersianCharacters(text) {
    'غ': 'ﻍﻎﻏﻐ',
    return replaceExcept(
    'ف': 'ﻑﻒﻓﻔ',
    text,
    'ق': 'ﻕﻖﻗﻘ',
    persianTools.toStandardPersianCharacters,
    'ک': 'ﮎﮏﮐﮑﻙﻚﻛﻜ',
    [patterns.globalExceptionTag, patterns.otherLanguagesInline, patterns.arabicTagEnclosed, patterns.fileNames, patterns.signatures, patterns.url]
    'گ': 'ﮒﮓﮔﮕ',
    );
    'ل': 'ﻝﻞﻟﻠ',
    }
    'م': 'ﻡﻢﻣﻤ',
     
    'ن': 'ﻥﻦﻧﻨ',
    if (!String.prototype.trim) { // if is not available currently
    'ه': 'ﻩﻪﻫﻬ',
    String.prototype.trim = function () {
    'هٔ': 'ﮤﮥ',
    return this.replace(/^\s+|\s+$/g, '');
    'و': 'ﻭﻮ',
    };
    'ؤ': 'ﺅﺅﺆ',
    }
    'ی': 'ﯼﯽﯾﯿﻯﻰﻱﻲﻳﻴ',
    'ئ': 'ﺉﺊﺋﺌ',
    'لا': 'ﻻﻼ',
    'لإ': 'ﻹﻺ',
    'لأ': 'ﻸﻷ',
    'لآ': 'ﻵﻶ'
    };


    function toStandardPersianCharacters(text) {
    function autoFormatCleanReferences ( str ) {
    var i;
    // تمیزکاری autoFormater.js > cleanReferences
    for (i in persianGlyphs) {
    str = str.replace(
    if (persianGlyphs.hasOwnProperty(i)) {
    /<\s*references\s*(\s\b[^<>]*?)?\s*(?:\/|>\s*<\s*\/\s*references)\s*>/gi,
    text = text.replace(new RegExp('[' + persianGlyphs[i] + ']', 'g'), i);
    '<references$1/>'
    );
    if (mw.config.get('wgNamespaceNumber') === 0){
    //ویکی‌پدیای فارسی منبع برای ارجاع نیست 
    str = str.replace(/\<ref[^>]*\>\[?(?:https?:)?\/\/fa.(?:m\.)?wikipedia.org\/[^\<\n\}\]\[]+\]?\<\/ref\>/gi, '')
    };
    str = str.replace( /<\s*references\s*(\s\b[^<\/>]*?)?\s*>/gi, '<references$1>' );
    str = str.replace( /<\s*\/\s*references\s*>/gi, '<\/references>' );
    var re = /(<references[^<\/>]*)>/g, m;
    while ( m = re.exec( str ) ) {
    if ( str.indexOf( '<\/references>', m.index ) < 0 ) {
    str = str.slice( 0, m.index ) + m[1] + '/>' + str.slice( m.index + m[0].length );
    }
    }
    }
    }
    return normalizeZwnj(text) // needed because of #visualZwnj
    str = str.replace( /< *ref\s*(\s\b[^<>]*?)\s*(?:\/+|>\s*<\s*\/+\s*ref) *>/gi, '<ref$1/>' );
    .replace(/ك/g, 'ک') // Arabic
     
    .replace(/ڪ/g, 'ک') // Urdu
    /* remove line breaks with assays only the top of the article */
    .replace(/ﻙ/g, 'ک') // Pushtu
    var i = str.indexOf( '<references' ),
    .replace(//g, 'ک') // Uyghur
    slice;
    .replace(/ي/g, 'ی') // Arabic
    if ( i > 0 ) {
    .replace(/ى/g, 'ی') // Urdu
    slice = str.slice( i );
    .replace(/ے/g, 'ی') // Urdu
    slice = slice.replace( /< *ref\s*(\s\b[^<\/>]*?)?\s*>[\t ]*/gi, '<ref$1>' );
    .replace(/ۍ/g, 'ی') // Pushtu
    slice = slice.replace( /(?:(\n[\t ]*)|[\t ]*)<\s*\/+\s*ref\s*>/gi, '$1<\/ref>' );
    .replace(/ې/g, 'ی') // Uyghur
    str = str.slice( 0, i );
    .replace(/ہ/g, 'ه') // Convert &#x06C1; to &#x0647; ہہہہ to ههه
    }
    .replace(/ە/g, 'ه\u200c') // Kurdish
    str = str.replace( /< *ref\s*(\s\b[^<\/>]*?)?\s*>\s*/gi, '<ref$1>' );
    .replace(/ھ/g, 'ه'); // Kurdish
    str = str.replace( /\s*<\s*\/+\s*ref\s*>/gi, '<\/ref>' );
    if ( slice ) {
    str += slice;
    }
     
    /* Space between the end of block and remove <ref> or two <ref> */
    str = str.replace( /([!,.;?]|<ref\b[^<>]*(?:\/|>[^<>]*<\/ref)>) +(?=<ref[ >])/gi, '$1' );
    /* Two identical punctuation before and cut after a <ref> on one */
    str = str.replace( /([!,.:;?])(<ref\b[^<>]*(?:\/|>[^<>]*<\/ref)>)\1/gi, '$1$2' );
    /* ref inside small */
    return str.replace( /\<small\> *(\<ref[^\<]+\<\/ref\>)<\/small\>/gi, '$1' );
    }
    }


    function toPersianDigits(text) {
    function autoFormatCleanTags(str) {
    var i = 0;
    str = str.replace( /(<\/?s)trike\b/gi, '$1' );
    for (i = 0; i <= 9; i = i + 1) {
    str = str.replace(
    text = text.replace(new RegExp('[' + arabicIndicDigits[i] + arabicDigits[i] + ']', 'g'), persianDigits[i]);
    /\<u\>([^\<]+)\<\/u\>/gi,
    "''$1''"
    );
    str = str.replace(
    /\<center\>/gi,
    "{{وسط‌چین}}"
    );
    str = str.replace(
    /\<\/center\>/gi,
    "{{پایان}}"
    );
    str = str.replace(
    /<sub\s*(>[^<>]*<)\s*(?:su[bp]\s*[.\/\\]+|[.\/\\]+\s*su[bp])\s*>/gi,
    '<sub$1/sub>'
    );
    str = str.replace(
    /<sup\s*(>[^<>]*<)\s*(?:su[bp]\s*[.\/\\]+|[.\/\\]+\s*su[bp])\s*>/gi,
    '<sup$1/sup>'
    );
     
    /* Drop default font attributes */
    str = str.replace(
    /(<font\b[^<>]*?)\s+fa\w+(?:[\s"',=]*(?:Arial|Helvetica(?:\W?N\w*)?|sans\W?serif)\b)+[\s"';]*(?=\s\w+\s*=|>)/gi,
    '$1'
    );
    str = str.replace(
    /(<font\b[^<>]*?)\s+size[\s"',=]*(?:-1\b|2\b|100\b[ ,.]*\d*%|1(?:\.0*)?em\b)["';]*/gi,
    '$1'
    );
    /* Remove inline elements with no attributes */
    while ( /<(font|span)\s*>\s*(?:<(?!\1)|[^<])*?\s*<\/\1[^<>]*>/i.test( str ) ) {
    str = str.replace( /<(font|span)\s*>[ \n]*((?:<(?!\1)|[^<])*?)[ \n]*<\/\1[^<>]*>/gi, '$2' );
    }
    str = str.replace(
    /<font\s+color[\s"',=]*(#[\dA-F]{3,6}|[a-z]{3,20})[\s"';]*>((?:<(?!font)|[^<])*?)<\/font[^<>]*>/gi,
    '<span style="color:$1;">$2<\/span>'
    );
    str = str.replace(
    /<font\s+size[\s"',=]*(?:-[2-9]|[01])[\s"';]*>((?:<(?!font)|[^<])*?)<\/font[^<>]*>/gi,
    '<small>$1<\/small>'
    );
    str = str.replace(
    /<font\s+size[\s"',=]*(?:[+-]0|3)[\s"';]*>((?:<(?!font)|[^<])*?)<\/font[^<>]*>/gi,
    '<span style="font-size:larger;">$1<\/span>'
    );
    /* Merge nested inline tags */
    str = str.replace(
    /<(abbr|cite|mark|q|s|small|u)\s*><(font|span)\s+style\s*=\s*["']?([^\n"<>]*?);?["']?\s*>([^<>]*)<\/\2\s*>\s*(?=<\/\1\s*>)/gi,
    '<$1 style="$3;">$4'
    );
    str = str.replace(
    /(<span\b[^<>]*?)\s+style\s*=\s*["']?([^\n"<>]*?);?["']?\s*><span\s+style\s*=\s*["']?([^\n"<>]*?);?["']?\s*>([^<>]*)<\/span\s*>\s*(?=<\/span\s*>)/gi,
    '$1 style="$2; $3;">$4'
    );
     
    /* Verschiedenste Formen von HTML-Zeilenumbrüchen durch einheitliche ersetzen */
    str = str.replace( /<(?:[\s\/\\]*br\b)+\s*(\s\w[^<>]*?)?[\s.\/\\]*>/gi, '<br$1/>' );
    /* Unnötige HTML-Zeilenumbrüche entfernen, wenn sowieso ein Absatz folgt */
    str = str.replace( / *(?:{{سخ}}|<br \/>)(?=[\r\n][\n#*:;\|}\]])/gi, '' );
    str = str.replace(
    /<(ref|small|su[bp])\b\s*(\s\w[^<>]*?)?\s*><small\s*>([^<>]*)<\/small\s*><\/\1\s*>/gi,
    '<$1$2>$3<\/$1>'
    );
    str = str.replace(
    /<small\s*><(ref|small|su[bp])\b\s*(\s\w[^<>]*?)?\s*?( ?\/|>[^<>]*<\/\1)\s*><\/small\s*>/gi,
    '<$1$2$3>'
    );
    /* Drop old navigation bar wrapper, see [[Template:NaviBlock]] */
    return str.replace(
    /<div\s+class[^<>\w]*BoxenVerschmelzen[^<>\w]*>\s*(\{\{[^#:<>{}]*\}\})\s*<\/div>/gi,
    '$1'
    );
    }
     
    function autoFormatCleanDuplicateLinks(str) {
    /* Exclude files and infoboxes from the start of the article */
    var m = /^(?:\s*\[\[\w+:(?:\[\[[^\n\]]*\]\]|[^\n\]])*\]\])*(?:\s*\{\{(?:\{\{[^}]*\}\}|[^}])*\}\})+/.exec( str ),
    start = m ? m[0].length : 0,
    found = [],
    a = [];
    /* Unlink years that are linked more than one time */
    var re = /\[\[ *([۱۲][۱۲۳۴۵۶۷۸۹۰]{3}|[۱۲][۱۲۳۴۵۶۷۸۹۰]{3} \((میلادی|قمری)\)) *\]\]/g;
    /* In each case the first discovery of a year noted entlinken thereafter */
    while ( m = re.exec( str ) ) {
    if ( m.index >= start ) {
    found[m[1]] ? a.push( m ) : found[m[1]] = true;
    }
    }
    var r = '',
    p = 0;
    for ( var i = 0; i < a.length; i++ ) {
    r += str.slice( p, a[i].index ) + a[i][1];
    p = a[i].index + a[i][0].length;
    }
    }
    return text
    return p ? r + str.slice( p ) : str;
    .replace(new RegExp('([' + persianDigits + ']) ?%', 'g'), '$1٪')
    .replace(new RegExp('٪([' + persianDigits + ']+(?:[.٬٫][' + persianDigits + ']*)*)', 'g'), '$1٪')
    //.replace(new RegExp('([' + persianDigits + '])\\.(?=[' + persianDigits + '])', 'g'), '$1٫') // persian decimal separator
    .replace(new RegExp('([' + persianDigits + '])\\،(?=[' + persianDigits + '])', 'g'), '$1٬'); // جایگزینی جداکننده هزاگان به جای ویرگول در میان اعداد
    }
    }


    function applyOrthography(text) {
    function autoFormatCleanDates(str){
    return text
    var months = ["ژانویه", "فوریه", "مارس", "آوریل", "مه", "ژوئن", "ژوئیه", "اوت", "سپتامبر", "اکتبر", "نوامبر", "دسامبر", 'فروردین', 'اردیبهشت', 'خرداد', 'تیر',
    .replace(/\r/g, '')
    'مرداد', 'شهریور', 'مهر', 'آبان', 'آذر', 'دی', 'بهمن', 'اسفند',"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
    //تمیزکاری autoFormatter.js
     
    .replace( /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x9F\uFEFF\u00AD]+/g, '' )
    /* Add missing space between day and month */
    .replace(/[ \xA0\xAD\u1680\u180E\u2000-\u200D\u2028\u2029\u202F\u205F\u2060\u3000]+\n/g,'\n')
    str = str.replace( new RegExp( '([\\s!\'(>|„](?:3[01]|[12]\\d|0?[1-9])\\.?)(?=(?:' +
    //تبدیل تب و فاصله نشکن اول خط به هیچ چون مدیاویکی آن را در نظر نمی‌گیرد
    months.join( '|' ) + ')\\b)', 'g' ), '$1 ' );
    .replace(/\n[\t\u00A0]+/g, '\n')
    /* No non-breaking space between month and year */
    //تبدیل انواع فاصله‌ها به فاصله ساده
    str = str.replace( new RegExp( '(\\b(?:3[01]|[12]\\d|0?[1-9])\\.?(?:[\\s\\xA0]|&nbsp;)+(?:' +
    .replace(/[\u0020\u0085\u00A0\u180E\u2000-\u200A\u202F\u205F\u3000]/g, ' ')
    months.join( '|' ) + '))(?:\xA0|&nbsp;)(?=[12]\\d{3}\\b)', 'g' ), '$1 ' );
    .replace(/[\u0085]/g, '')
    /* Missverständliches deutsches Datumsformat durch Langform ersetzen */
    //http://kb.mozillazine.org/Network.IDN.blacklist_chars
    var separator= ' ';
    .replace(/[\u01C3\uFE15]/g, '!')
    str = str.replace(
    .replace(/[\u0589\u05C3\uA789]/g, ':')
    /([\s'(>„])(3[01]|[12]\d|0?[1-9])\. *(1[012]|0?[1-9])\. *(?=[12]\d{3}[!,.:;?]?[\s')<\]“])/g,
    .replace(/[\u0338\u2044\u2215\u2571\u29F8\u3033\uFF0F]/g, '/')
    function( $0, $1, $2, $3 ) {
    .replace(/[\u05F4]/g, '"')
    return $1 + ( $2 | 0 ) + separator + months[$3 | 0] + ' ';
    .replace(/[\u06D4\u0701\uFF0E\uFF61]/g, '.')
    }
    .replace(/\u3014/g, '(')
    );
    .replace(/\u3015/g, ')')
    // عدد فارسی
    // جایگزینی ۀ غیراستاندار+حرف بعدی بدون فاصله به ه+همزه+فاصله
    str = str.replace( new RegExp( '([\\s!\'(>|„](?:۳[۰۱]|[۱۲][۱۲۳۴۵۶۷۸۹]|۰?[۱۲۳۴۵۶۷۸۹])\\.?)(?=(?:' +
    .replace(/[ۂۀ](?![\s\n])/g, 'هٔ ')
    months.join( '|' ) + ')[\\s\')<\\]»}|])', 'g' ), '$1 ' );
    // Replace ه followed by (space|ZWNJ|lrm) follow by ی with هٔ
    /* No non-breaking space between month and year */
    .replace([\u200c\u200e\s]+ی([\s\n])/g, 'هٔ$1')
    str = str.replace( new RegExp( '([\\s\'(>«](?:۳[۰۱]|[۱۲][۱۲۳۴۵۶۷۸۹]|۰?[۱۲۳۴۵۶۷۸۹])\\.?(?:[\\s\\xA0]|&nbsp;)+(?:' +
    // Replace ه followed by (space|ZWNJ|lrm|nothing) follow by ء or with هٔ
    months.join( '|' ) + '))(?:\xA0|&nbsp;)(?=[۱۲][۱۲۳۴۵۶۷۸۹]{3}[\\s\')<\\]»}|])', 'g' ), '$1 ' );
    .replace([\u200c\u200e\s]*[ءٔ]([\s\n])/g, 'هٔ$1')
    /* Missverständliches deutsches Datumsformat durch Langform ersetzen */
    // Replace هٓ or single-character ۀ with the standard هٔ
    var separator= ' ';
    .replace(/(ۀ|هٓ)/g, 'هٔ')
    str = str.replace(
    // Replace ه followed by ئ or ی, and then by ی, with ه\u200cای, example: خانهئی becomes خانه\u200cای
    /([\s'(>«])(۳[۰۱]|[۱۲][۱۲۳۴۵۶۷۸۹]|۰?[۱۲۳۴۵۶۷۸۹])\. *(۱[۰۱۲]|۰?[۱۲۳۴۵۶۷۸۹])\. *(?=[۱۲][۱۲۳۴۵۶۷۸۹]{3}[!,.:;?]?[\s')<\]»}|])/g,
    .replace(/ه\u200c[ئی]ی/g, 'ه\u200cای')
    function( $0, $1, $2, $3 ) {
    // Function for removing incorrect ZWNJs
    return $1 + ( $2 | 0 ) + separator + months[$3 | 0] + ' ';
    .replace(/([\u200c\u200e])([\s\n])/g, '$2')
    }
    .replace(/([\s\n])([\u200c\u200e])/g, '$1')
    );
    //فاصلهٔ پیش از واکه\u200cهای کوتاه اشتباه است و برای جلوگیر از به هم چسبیدن کلمات فاصله و واکه جابجا باید گردند.
    return str
    .replace(new RegExp('([' + persianCharacters + vowels + hamza + '])(\\s)([' + vowels + hamza + '])', 'g'), '$1$3$2')
    //واکه\u200cهای کوتاه پشت سرهم نمی\u200cآیند و یک حرف باید بینشان فاصله باشد
    .replace(new RegExp('([' + vowels + hamza + ']){2,}', 'g'), '$1')
    .replace(/ئء/g, 'یء') //two hamzes after each other
    .replace(/أء/g, 'اء') //two hamzes after each other
    .replace(/ؤء/g, 'ؤ') //two hamzes after each other
    //.replace(/وء/g, 'ؤ')//bug on  سوء
    .replace(/سؤ ?استفاده/g, 'سوءاستفاده')//bug on سوءاستفاده و سوء
    .replace(/ و یا /g, ' یا ')// replace «و یا» with «یا»
    //افزودن همزه
    //.replace(/درباره (ام|ات|اش|مان|تان|شان|ای)(\s|$)/g, 'درباره‌$1$2')//i برای جلوگیری از باگ احتمالی برای افزودن همزه به درباره
    //.replace(/درباره /g, 'دربارهٔ ')
    //.replace(new RegExp('صفحه(\\s|)(['+persianDigits+']+)(\\n|\\.|\\,|\\||\\<)', 'g'), 'صفحهٔ $2$3');//[[Special:PermaLink/15326391#افزودن همزه]]
    }
    }


    function quotation(text) {
    // این تابع زمانی گیومه را به فارسی تیدیل می‌کند که در پاراگراف مورد نظر تعداد گیومهٔ لاتین زوج باشد.
    var lines = text.split(/\n\n/);
    var result = [];
    for (var i = 0; i < lines.length; ++i) {
    var line = lines[i];
    if ((line.match(/"/g) || []).length % 2 === 0) { // count of quote marks
    // تبدیل گیومهٔ لاتین به فارسی
    // این دستور در ابتدا باشد تا فاصله‌های قبل و بعد گیومه هم اصلاح شود
    line = line.replace(
    new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.\\)]+)"((?:\\[\\[|).*?[' + persianTools.persianCharacters + '؛\\n،]+?(?:\\]\\]|\\.|\\<|\\:|…|))"([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{\\(]|$)', 'g'),
    '$1«$2»$3'
    );
    // if some of quote marks are remained from conversion, something might wrong, revert
    var testline=line.replace(/(?:<ref[^\/]*?>[\s\S]*?<\/ref>|<ref[^\/]*?\/>)/g,'')
    if (testline.match(/"/g)) {
    line = lines[i];
    }
    }
    // رفع مشکل استفاده از ـً به جای گیومه لاتین در متن فارسی
    line=line.replace(new RegExp('ا\\"([ ]*[' +persianTools.persianCharacters + '])', 'g'), 'اً$1')
    line=line.replace(new RegExp('ا\\”([ ]*[' +persianTools.persianCharacters + '])', 'g'), 'اً$1')
    // ”“ تبدیل
    line = line.replace(
    new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.]+)“((?:\\[\\[|).*?[' + persianTools.persianCharacters + '\\n]+?(?:\\]\\]|\\.|\\<|\\:|\\{|\\[|…|))”([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{]|$)', 'g'),
    '$1«$2»$3'
    );
    //وارونه ”“ تبدیل
    line = line.replace(
    new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.]+)”((?:\\[\\[|).*?[' + persianTools.persianCharacters + '\\n]+?(?:\\]\\]|\\.|\\<|\\:|\\{|\\[|…|))“([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{]|$)', 'g'),
    '$1«$2»$3'
    );
    // ‘’ تبدیل
    line = line.replace(
    new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.]+)‘((?:\\[\\[|).*?[' + persianTools.persianCharacters + '\\n]+?(?:\\]\\]|\\.|\\<|\\:|\\{|\\[|…|))’([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{]|$)', 'g'),
    '$1«$2»$3'
    );
    //وارونه ‘’ تبدیل
    line = line.replace(
    new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.]+)’((?:\\[\\[|).*?[' + persianTools.persianCharacters + '\\n]+?(?:\\]\\]|\\.|\\<|\\:|\\{|\\[|…|))‘([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{]|$)', 'g'),
    '$1«$2»$3'
    );
    // ‚’ تبدیل
    line = line.replace(
    new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.]+)‚((?:\\[\\[|).*?[' + persianTools.persianCharacters + '\\n]+?(?:\\]\\]|\\.|\\<|\\:|\\{|\\[|…|))’([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{]|$)', 'g'),
    '$1«$2»$3'
    );
    // „” تبدیل
    line = line.replace(
    new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.]+)„((?:\\[\\[|).*?[' + persianTools.persianCharacters + '\\n]+?(?:\\]\\]|\\.|\\<|\\:|\\{|\\[|…|))”([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{]|$)', 'g'),
    '$1«$2»$3'
    );
    // << >> تبدیل
    line = line.replace(
    new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.]+)\\<\\<((?:\\[\\[|).*?[' + persianTools.persianCharacters + '\\n]+?(?:\\]\\]|\\.|\\<|\\:|\\{|\\[|…|))\\>\\>([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{]|$)', 'g'),
    '$1«$2»$3'
    );
    // (()) تبدیل
    line = line.replace(
    new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.]+)\\(\\(((?:\\[\\[|).*?[' + persianTools.persianCharacters + '\\n]+?(?:\\]\\]|\\.|\\<|\\:|\\{|\\[|…|))\\)\\)([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{]|$)', 'g'),
    '$1«$2»$3'
    );
    result.push(line);
    }
    return result.join('\n\n');
    }
    /**
    /**
    * Replaces Persian characters with Arabic's ones so an Arabic sorter can sort Persian lines
    * افزودن ستون به الگوی پانویس
    * @param {string} text محتوا
    */
    function addColumnToRefTemplate(text) {
    /* var refTemplate = /\{\{پانویس([^\}\{]+)?\}\}/i.exec(text), needChange = false;
    if (refTemplate) {
    if ((text.match(/<ref/gi) || []).length >= 6) {
    if (refTemplate[1] !== undefined) {
    var refParams = refTemplate[1].split('|');
    for (var i = refParams.length - 1; i >= 0; i--) {
    // اگر از پیش ستون یا پارامتر عرض تعریف شده‌باشد تغییری ایجاد نمی‌شود.
    if (refParams[i].length == 1 || refParams[i].indexOf('عرض') > -1) {
    needChange = true;
    break;
    }
    }
    }
    if (refTemplate[1] === undefined || !needChange) {
    return text.replace(refTemplate[0], refTemplate[0].replace('}}', '|۲}}'));
    }
    }
    }else{
    if ((mw.config.get('wgNamespaceNumber') === 0 && mw.config.get("wgEditMessage")==='editing')||mw.config.get('wgPageName') ==="ویکی‌پدیا:ویکی‌پروژه_ابزارها/آزمایش_واحد") {
    if ((text.match(/<ref/gi) || []).length > 0 &&  /\{\{پانویس([^\}\{]+)?\}\}/i.exec(text) !=null) {
    var text2 = text.replace ('== منابع ==','== منابع ==\n{{پانویس}}')
    if (text2==text){
    text2 = text.replace ('== پانویس ==','== پانویس ==\n{{پانویس}}')
    }
    if (text2==text){
    text2 = text.replace ('[[رده:','== منابع ==\n{{پانویس}}\n\n[[رده:')
    }
    if (text2==text){
    text2 = text + '\n== منابع ==\n{{پانویس}}'
    }
    text=text2
    }
    }
    }*/
    return text;
    }
    /**
    * اصلاح پیوندها
    * @param  {string} text محتوا
    * @return {string}
    */
    */
    function dePersian(text) {
    function fixBadLinks(text) {
    // حذف متن جایگزین پیوند اگر با نشانی پیوند برابر باشد؛ مانند [[سلام|سلام]]
    text = text.replace(/\[{2}([^\|]+)\|\1\]{2}/gi, '[[$1]]');
     
    // حذف پیوند سال و روز ماه
    text = text.replace(/\[{2}([۰-۹]+|[۰-۹]+ [\)\(\u0621-\u0655\u067E\u0686\u0698\u06AF\u06A9\u0643\u06AA\uFED9\uFEDA\u06CC\uFEF1\uFEF2]+)(?:\|([^\]\|\[]+))?\]{2}/g, function (match, p1, p2) {
    // اگر فقط سال پیوند شده‌باشد یا به شکل [[سال|همان سال]] باشد فقط سال را می‌گرداند.
    if (p1 !== p2 && p1.replace(/ \((میلادی|قمری|خورشیدی|شمسی|پیش از میلاد|قبل از میلاد)\)/g,'') === p2){
    return p2;
    }//[[Special:Permalink/19908981#حذف پیوند تاریخ‌ها]]
    if (p2 === undefined || p1 === p2) {
    // اگر پیوند به روز و ماه بود، برای جلوگیری از اشتباه و تداخل، بررسی می‌شوند که حتما یکی از ماه‌ها داخل رشته باشد.
    if (p1.indexOf(" ") > -1) {
    var
    months = ["فروردین", "اردیبهشت", "خرداد", "تیر", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی", "بهمن", "اسفند",
    "ژانویه", "فوریه", "مارس", "آوریل", "مه", "ژوئن", "ژوئیه", "اوت", "سپتامبر", "اکتبر", "نوامبر", "دسامبر",
    "محرم", "صفر", "ربیع‌الاول", "ربیع‌الثانی", "جمادی‌الاول", "جمادی‌الثانی", "رجب", "شعبان", "رمضان", "شوال", "ذیقعده", "ذیحجه"],
    i;
    for (i = months.length - 1; i >= 0; i--) {
    if (p1.indexOf(months[i]) > -1) {
    return p1.replace(/ \((میلادی|قمری|خورشیدی|شمسی|پیش از میلاد|قبل از میلاد)\)/g,'');
    }
    }
    return "[[" + p1 + "]]";
    }
    return p1;
    }
    // اگر متن جایگزین پیوند مخالف پیوند سال بود، متن جایگزین را برمی‌گرداند.
    return p2;
    });
     
    return text;
    }
     
    function wikiPunctuation(text) {
    text = autoFormatCleanReferences (text)
    text = autoFormatCleanTags(text)
    text = autoFormatCleanDuplicateLinks(text)
    text = replaceExcept(
    text,
    function (text) {
    return quotation(text);
    },
    [patterns.ref]
    );
    if (mw.config.get('wgNamespaceNumber') === 0){
    var old_text=text.replace(/\=\=/g, '')
    if (old_text==text){//در صورتی که در مقاله بخش‌بندی وجود نداشته باشد
    text=text.replace(/(\n\{\{سخ\}\}|\n\n)(\s|_|)\'\'\'(.*?)\'\'\'(\s|_|)(\{\{سخ\}\}|\n)([\n\#\*])/g, '\n\n== $3 ==\n$6')
    }
    }
    text = replaceExcept(
    text,
    function (text) {
    text = text.replace(
    new RegExp('([' + persianTools.persianCharactersNoVowels + '])ـ+([' + persianTools.persianCharactersNoVowels + '])', 'g'),
    '$1$2'
    );
    return text.replace(new RegExp('([' + persianTools.persianCharacters + '])(\\]\\]|), (\\[\\[|)?(?=[' + persianTools.persianCharacters + "])", 'g'), '$1$2، $3');
    },
    [patterns.globalExceptionTag, patterns.fileNames, patterns.url, patterns.galleryTag, patterns.sourceTag, patterns.translatedUrl, patterns.parenthesesHa]
    );
    text = replaceExcept(
    text,
    function (text) {
    return text.replace(/(<\/ref>)\s+(<ref)/g, '$1$2').replace(/([^=])\s+<ref(?!erences)/g, '$1<ref');
    },
    [/\{\{(پانویس|پانویس‌ها|پی‌نوشت)\s*\|[\s\S]*/]
    );
    return replaceExcept(
    text,
    function (text) {
    return persianTools.punctuation(text)
    .replace(/^([*#]+)([^*#\:\s])/mg, '$1 $2') // Adds a space after the # or * for lists
    .replace(/^([*#]+) {2,}([^*#\:\s])/mg, '$1 $2'); // Trim more that one space after the # or * for lists
    },
    [patterns.globalExceptionTag, patterns.mathTag, patterns.fileNames, patterns.url, patterns.wikilinkTargets,
    patterns.galleryTag, patterns.sourceTag, patterns.translatedUrl, patterns.parenthesesHa]
    )
    .replace(/\u00A0/g, ' ') // convert implicit nbsp to space, probably is being added by some bug on ContentTranslation
    .replace(/٬ /g, '، ')
    .replace(new RegExp('([' + persianTools.persianCharacters + '\]])٬', 'g'), '$1،')
    .replace(new RegExp('([' + persianTools.persianCharacters + '])(\]\]|»|)[ ]*[,]', 'g'), '$1$2، ')
    .replace(/\[\[([^\|\]]+)\|(\'{2,3})\1'{2,3}\]\]/g,'$2[[$1]]$2') // for [[foo|'''foo''']] > '''[[foo]]'''
    .replace(new RegExp('\\[\\[(' + escapeRE(mw.config.get('wgPageName')) + ')\\]\\]', 'g'), '$1') // پیوندزدایی از خود صفحه
    //برگرفته از https://tools.wmflabs.org/checkwiki/cgi-bin/checkwikin.cgi?project=fawiki&view=project
    .replace(/\[\[([^\|\]]+)\|\1([\u200c ]*(های?))\]\]/g, '[[$1]]$2')//[[Special:Diff/17515365/17865938]]
    .replace(/([\S]*)[\s\u200c]*-[\s\u200c]*(تاکنون)(?![ ]+)/g, '$1-اکنون')//[[Special:Diff/17515365/17865938]]
    //مشکل در نشانی اینترنتی
    .replace(/(\<ref.*?\>) *(\[|)\www(6|3|)\./gi, '$1$2http://www$3.')
    .replace(/\[\[ *(https?\:\/\/.*?) *\]\]/g, '[$1]')
    .replace(/\[\[ *(\/\/.*?) *\]\]/g, '[$1]')
    .replace(/(https?:\/?\/?){2,}/g, '$1')
    // تمیزکاری autoFormatter.js > cleanExternalLinks
    .replace(/\b(?:http(s?)(?::+\/*|\/\/+:*)\b)+/gi, 'http$1://')
    // repair links with vertical stroke
    .replace(/(\[https?:\/\/[^\s[\]|]*?) *\| *(?=[^\s=[\]|]+\])/gi, '$1 ')
    // supplement slashes at the end easier Domains
    .replace(/(\[https?:\/\/\w[\w.-]*\w\.\w+) +/gi, '$1/ ')
    // Domains lowercase, whether labeled or not
    .replace(/\bhttps?:\/\/\b[0-9a-z.-]*[A-Z][\w.-]*/g, function ($0) {
    return $0.toLowerCase();
    })
    // پیوند به بیرون‌هایی که در میان پیوند نویسهٔ رفتن به خط بعد، وجود داشته باشد
    .replace(/\[(?:https?\:|)\/\/[^\]\[]+\]/g, function (x) {
    x = x.replace(/[\n\r]/g,'');
    return x
    })
    // فاصله اول زیربخش
    .replace(/پیوند\n\=/,'پیوند=')// [[Special:Diff/20238012/20244702]]
    .replace(/^ +(\=+[^\=]+\=+)/mg, '$1')
    .replace(/\[\[\|/g, '[[')
    .replace(/(\< *\/ *br *\>|\< *br *\\ *\>|\< *br *\. *\>)/g, '<br/>')
    .replace(/(\<br *\/\>|\{\{سخ\}\})([\r\n])(\*|\#|\=\=)/g, '$2$3')
    .replace(/(\<br *\/\>|\{\{سخ\}\}) *\]\]/g, ']]')
    .replace(/\[\[ *(\<br *\/\>|\{\{سخ\}\})/g, '[[')
    .replace(/(\< *span *\/ *\>|\< *\/ *span *\/ *\>)/gi, '</span>')
    .replace(/(\< *center *\/ *\>|\< *\/ *center *\/ *\>)/gi, '</center>')
    .replace(/(\< *b *\/ *\>|\< *\/ *b *\/ *\>)/gi, '</b>')
    .replace(/(\< *div *\/ *\>|\< *\/ *div *\/ *\>)/gi, '</div>')
    .replace(/(\< *p *\/ *\>|\< *\/ *p *\/ *\>)/gi, '</p>')
    .replace(/(\< *td *\/ *\>|\< *\/ *td *\/ *\>)/gi, '</td>')
    .replace(/(\< *small *\/ *\>|\< *\/ *small *\/ *\>)/gi, '</small>')
    .replace(/\[\[([^\]]+)\{\{\!\}\}([^\]]+)\]\]/g, '[[$1|$2]]')//وجود {{!}} درون پیوند
    .replace(/\[{2}([^\|]+)\|\1\]{2}/gi, '[[$1]]')//زمانی که بخش هدف و نمایه پیوند یکی باشند
    .replace(/\[\[(.+)\|('+)(.+\b)('+)\]\]/gi, '$2[[$1|$3]]$4')// انتقال ''' به بیرون پیوند
    // تمیزکاری autoFormatter.js > CleanGalleries
    .replace(/<gallery\b([^<>]*)>([^<>]+)<\/gallery\b[^<>]*>/gi,
    function( $0, $1, $2 ) {
    return '<gallery' + $1 + '>' + $2
    .replace( /^(\s*)\[+([^[\]]*)\]\]?\s*$/gm, '$1$2' )
    .replace( /^(\s*)\[+/gm, '$1' ) + '<\/gallery>';
    }
    )
    // تمیزکاری پرونده‌ها
    // زمانی که برچسب کوچک در توضیحات تصویر می‌آید برای دستگاه‌های با مانیتور کوچک خواندن متن مشکل می‌شود
    //https://tools.wmflabs.org/checkwiki/cgi-bin/checkwiki.cgi?project=fawiki&view=only&id=77
    .replace(/\[\[(پرونده|[Ff]ile)\:((?:\[\[.*?\]\]|[^\]])*)\]\]/g, function ($0, $1, $2) {
    $2 = $2.replace(/\<\/?(big|center|small)>/g,'');
    return '[['+$1+':'+$2+']]'
    })
    .replace( /\[\[ *تصو[يی]ر\:/gi, '[[پرونده:' )
    // تمیزکاری الگو autoFormater.js > cleanTemplates
    .replace( /\{\{\s*:?\s*(?:الگو|Template)\s*:\s*/gi, '{\{' )
    // حذف خط زیر از عنوان الگو
    .replace(/(?:^|[^{])\{\{[ 0-9a-z\xC0-\u024F-]*_[ \w\xC0-\u024F-]*/gi,
    function( $0 ) {
    return $0.replace( /_+$/, '' ).replace( /[ _]+/g, ' ' ).replace( /\{ +/, '{' );
    }
    )
    //سایر موارد
    .replace(/\[\[(رده|الگو|ویکی\u200cپدیا)\: +/g, '[[$1:')
    .replace(/\{\{\*\}\}/g, '{{•}}')
    .replace(/[\n\s]*\{\{[•·ن](w?)\}\}\s*/g, '{{•$1}} ')
    .replace(/\=\{\{[•·ن](w?)\}\}\s*/g, '=\n{{•$1}} ')//رفع باگ [[Special:Diff/14799178/16387261]] در خط بالا
    .replace(/ *(<\/? ?br ?\/?>|\{\{بر\}\}) */g, '{{سخ}}')
    .replace(/\{\{سخ\}\}\n\n/g, '\n\n')
    .replace(/\n\n\{\{سخ\}\}/g, '\n\n')
    .replace(/\{\{سخ\}\}\]/g, ']')
    .replace(/\[\{\{سخ\}\}/g, '[')
    .replace(/\n\n(\*|\#)/g,'\n$1')
    .replace(/\n(\#|\*)( |)\n/g,'\n$1')
    .replace(/\n(\*|\#)( |)(\={2,})/g,'\n$3')
    .replace(/(\n?)\s+?<\/ref>/g, '$1</ref>')
    .replace(/\{ *\|/g, '{|')
    .replace(/\| *\}/g, '|}')
    .replace(/\{\| *\{\|/g, '{|')
    .replace(/\|\} *\|\}/g, '|}')
    .replace( /^=.*&nbsp;.*=$/gim, function( $0 ) {
    return $0.replace( /(?:&nbsp;|\s)+/gi, ' ' );
    })
    .replace(/([^=])\n+(\=.*?\=\n+)/g, '$1\n\n$2')
    .replace(/^(=+([^=].*?)=+)[\t\s]{1,}\n/g, '$1\n')
    .replace(/^(\={2,}) +[\:,;>&\^#@•→←↔↑↓—–…~٫،؛ٔ]/mg, '$1') // Cleanup headers
    .replace(/[\:,;<&\^#@•→←↔↑↓—–…~٫،؛ٔ] +(\={2,})$/mg, '$1')
    .replace(/^(\={2,}\s*)(«)([^\n«»]*?)(»)(\s*\={2,})/mg, '$1 $3 $5')
    .replace(/^(\={2,}) *'+(.*?)'+ *(\={2,})/mg, '$1 $2 $3')
    .replace(/^[•●⚫⬤]/mg, '*') // Wikify bullets in start of lines
    .replace(/^#\s*(REDIRECT|تغییر[ _]?مسیر)/gi, '#تغییرمسیر')
    .replace(/^#تغییرمسیر(?=\S)/g, '#تغییرمسیر ') // Adds a space after #REDIRECT
    .replace(/(\={2,}) *([^\n\r]*?) *(\={2,})/g, '$1 $2 $3') // Format headings level 2 and above
    // زیربخش نیازی به برچسب بزرگ و کوچک ندارد
    .replace(/(\=+) \<(?:small|big)\>([^\=\n\r]+)\<\/(?:small|big)\> (\=+)/g, '$1 $2 $3')
    // فاصله‌های اضافی را از داخل پیوند به بیرون منتقل کند تا اگر اضافه بودند در کدهای دیگر حذف شوند
    .replace(/\[\[(\s*)(.*?)(\s*)\]\]/g, '$1[[$2]]$3')
    //حذف فاصلهٔ اضافی درون {{}}
    .replace(/\{\{(\s*)(.*?)(\s*)\}\}/g, '{{$2}}')
    // تبدیل به نویسه / یکی کردن فاصله های مجازی پشت سرهم
    .replace(/(\{\{فم\}\}|\&zwnj\;|\u200c+)/g, '\u200c')
    // Full stop and comma should be before citation. See en:WP:REFPUNC
    .replace(/ *((?:<ref[^\/]*?>.*?<\/ref>)+)([\.،,:])?/g, '$2$1')
    .replace(/([^.])([\.،,:]){2}((?:<ref[^\/]*?>.*?<\/ref>)+)/g, '$1$2$3')
    .replace(/ *((?:<ref[^\/]*?\/>)+)([\.،,:])/g, '$2$1')
    .replace(/([^.])([\.،,:]){2}(((?:<ref[^\/]*?\/>)+)+)/g, '$1$2$3')
    /* هر رده در یک خط */
    .replace( /([^\s>-]) *(\[\[رده:[^\n[\]]*\]\])/gi, '$1\n$2' )
    .replace( /(\[\[رده:[^\n[\]]*\]\]) *(?![\s<-]|$)/gi, '$1\n' )
    .replace( /(\[\[رده:[^\n[\]]*\]\]\n) *(?!\[\[رده:|[\s<-]|$)/gi,'$1\n')
    //ترتیب‌پیش‌فرض
    .replace(/\{\{(?:DEFAULTSORT|[Dd]efaultsort|ترتیب|ترتیب[‌ ]پیش[‌ ]?فرض) *[|:] *(?=.*?}})/g, '{{ترتیب‌پیش‌فرض:')
    .replace(/\{\{(ترتیب‌پیش‌فرض|DEFAULTSORT)\:[-\w,\s\(\)]+\}\}\n?/g, '')
    .replace(/(\{\{(?:ترتیب‌پیش‌فرض|DEFAULT\w*SORT\w*):[^\n{}]*\}\})\s*(?=\[\[رده:)/gi,'$1\n')
    .replace(/(\{\{ترتیب‌پیش‌فرض\:)\s/g, '$1')
    .replace( /(==\n)\n+(?=<references[^\n<>]*\/>\n\n)/gi, '$1' )
    //نچسبیدن و+فاصله به براکت که محصول اشتباه در تایپ کردن است
    .replace(/\]\]و /g, ']] و ')
    .replace(/(\s|^)\'\'\'(\s|)(.*?)(\s|)\'\'\'(\s)/g, "$1'''$3'''$5") // حذف فاصلهٔ اضافی درون ویکی کد
    .replace(/'''\{\{به /g, "''' {{به ")
    .replace(/\*(\s+|\n)?\{\{پانویس/g, "{{پانویس")
    .replace(/((?:^|\n\s)\=+\s+\=+(?:\s+|)\n)/g, "\n\n")
    .replace(/\n{3,}/g, '\n\n')
    .replace(/(\[{1,2})([^\[\]\n]+) +(\]{1,2})/g, "$1$2$3")
    .replace(/(\[{1,2}) +([^\[\]\n]+)(\]{1,2})/g, "$1$2$3")
    //تبدیل بندهای ترتیبی به قالب‌بندی ویکی [[Special:Permalink/19923598#تبدیل بندهای ترتیبی به قالب‌بندی ویکی]]
    .replace(/(?:(?:^(?:\* ?)?[۱۲۳۴۵۶۷۸۹۰0-9]{1,2} ?[\.\-\)]) ?[^۱۲۳۴۵۶۷۸۹۰0-9\n]+\n+){2,}/gm, function (x) {
    var x2=x.replace(/((?:\* ?)?[۱۲۳۴۵۶۷۸۹۰0-9]{1,2} ?[\.\-\)]) ?([^۱۲۳۴۵۶۷۸۹۰0-9\n]+)\n+/gm,'# $2\n')
    if (x2.replace(/[۱۲۳۴۵۶۷۸۹۰0-9]/g, '')===x2){
    return x2;
    }
    return x;
    })
    .trim();
    }
     
    function wikiSubsection(text) {
    return text.replace(/\<(?:\s*)references?(?:\s*\/|\s*\/\s*)\>/g, '{{پانویس}}')
      .replace(/\{\{(?:[Rr]eflist|[Rr]eferences?|پانویس[‌ ]?ها)(?=\||\})/g, '{{پانویس')
      .replace(/\{\{راست(| |‌)چین\}\}\s*\{\{پانویس(.*?)\}\}\s*\{\{(پایان راست(| |‌)چین|پایان)\}\}/g, '{{پانویس$2}}')
      .replace(/\{\{چپ(| |‌)چین\}\}\s*\{\{پانویس(.*?)\}\}\s*\{\{(پایان چپ(| |‌)چین|پایان)\}\}/g, '{{پانویس$2|چپ‌چین=بله}}')
      .replace(/\<small\>\s*\{\{پانویس(.*?)\}\}\s*\<\/small\>/g, '{{پانویس$1|اندازه=کوچک}}')
      .replace(/(({\{پانویس.*?\}\})(\n|)){1,}/g, '$1')
      .replace(/\=\s*لیست\s*\=/g, '= فهرست =')
      .replace(/\=\s*(?:[gG]allery|نگارستان|گالری (تصویر|عکس|))\s*\=/g, '= نگارخانه =')
      .replace(/\=\s*(?:بیوگرافی|زندگینامه)\s*\=/g, '= زندگی‌نامه =')
      .replace(/\=\s*(?:[eE]xternal links|لینک‌?های بیرونی|پیوندهای خارجی|لینک‌?های خارجی|پیوندهای بیرونی)\s*\=/g, '= پیوند به بیرون =')
      .replace(/\=\s*(?:[nN]otes|[fF]ootnotes?|پاورقی|پاورقی‌ها|پانوشت|پانویس‌ها)\s*\=/g, '= پانویس =')
      .replace(/\=\s*(?:[Ss]ee [Aa]lso|همچنین ببینی[مد]|بیشتر ببینی[مد]|همچنین نگاه کنید|بیشتر بدانی[مد]|مراجعات مرتبط|جستار وابسته|مطلب مرتبط|مطالب مرتبط|جستارهای مشابه|جستارهای دیگر)\s*\=/g, '= جستارهای وابسته =')
      .replace(/\=\s*(?:منبع|منبع[‌ ]?ها|رفرنس|رفرنس[‌ ]?ها|ارجاع[‌ ]?ها|ارجاع|مرجع[‌ ]?ها|رفرنس|برگرفته از|مراجع|منابع و یادداشت[‌ ]?ها|منبع|مرجع|م[آا]خذ|منابع و م[آا]خذ|منابع و پانویس‌ها|فهرست مراجع|لیست مراجع|فهرست ارجاع[‌ ]?ها|فهرست ارجاع|[rR]eferences)\s*\=/g, '= منابع =')
      //.replace(/\=\s*(?:مطالعه بیشتر|بیشتر بخوانی[مد])\s*\=/g, '= برای مطالعهٔ بیشتر =')
      .replace(/^\={3,}\s*(جستارهای وابسته|پانویس|منابع)\s*\={3,}$/g, '== $1 ==');
    }
    function wikiUrlMinifier(text) {
    return text
    .replace(patterns.url, function (x) {
    return replaceExcept(
    x,
    function (x) {
    try {
    x = decodeURI(x);
    } catch (e) {
    try {
    x = decodeURIComponent(unescape(x));
    } catch (e) {mw.notify(e); }
    }
    return x;
    },
    [patterns.globalExceptionTag, patterns.decodeUriBlacklist, patterns.refname]
    );
    })
     
    // Strip the http(s) prefix
    .replace(/\[(https?\:)(?=\/\/(?:[\w\-]+)\.(?:m\.)?(wiki(pedia|media|data|source|news|oyage|quote)|wiktionary)\.org\/[^\s\]]*)/g, '[')
    .replace(/[\[\=](?:https?\:|)\/\/[\w\-]{2,}\.(?:m\.)?wikipedia\.org\/w(?:iki)?\/([^\n?]*?)[\]\|]/g, function (x) {
    x = x.replace(/\[(?:https?\:|)\/\/([\w\-]{2,})\.(?:m\.)?wikipedia\.org\/w(?:iki)?\/(.*?) (.*?)\]/g,'[[:$1:$2|$3]]')
    x = x.replace(/\[(?:https?\:|)\/\/([\w\-]{2,})\.(?:m\.)?wikipedia\.org\/w(?:iki)?\/(.*?)\]/g,'[[:$1:$2]]')
    //x = x.replace(/\=(?:https?\:|)\/\/([\w\-]{2,})\.(?:m\.)?wikipedia\.org\/w(?:iki)?\/(.*?)\|/g,'=[[:$1:$2]]|') // در الگو یادکرد مشکل ایجاد می‌کند
    x = x.replace(/\[\[\:fa\:/g,'[[').replace(/\%20/g,' ').replace(/٪۲۰/g,' ').replace(/\[\[[a-zA-Z\'0-9 ]+\|/g,'[[')
    x = x.replace(/\[\[.*?\]\]/g, function (y) {
    y = y.replace(/\_/g,' ')
    return y
    })
    return x
    }).replace(/\[{2}([^\|]+)\|\1\]{2}/gi, '[[$1]]');
    }
    function SubSectionLeveling (text) {
    // تنظیم سطح زیربخش‌ها
    text=text.replace(/^(\={2,}) *(.*?) *(\={2,})/mg, '$1 $2 $3')
    if ((mw.config.get('wgNamespaceNumber') === 0 && mw.config.get("wgEditMessage")==='editing')||mw.config.get('wgPageName') ==="ویکی‌پدیا:ویکی‌پروژه_ابزارها/آزمایش_واحد") {
    //مقاله‌ای که فقط زیربخش سطح ۱ دارد
    if (text.replace(/\=\=/g,'')===text){
    var text2 = text.replace(new RegExp('^\=([^\=\r\n]+)\=$', 'gm'), "== $1 ==")
    if (text!==text2){
    text=text2.replace(/\n\=  /g,'\n= ').replace(/  \=\n/g,' =\n')
    };
    };
    //مقاله‌ای که فقط زیربخش سطح ۳ یا ۴ دارد
    var text_test=text.replace(/^\=+ (منابع|جستارهای وابسته|پیوند به بیرون|پانویس|نگارخانه) \=+\n/gm,'')
    if (text_test.replace(/^\=\= /gm,'')===text_test){
    if (text_test.replace(/^\=\=\= /gm,'')!==text_test){
    //سطح ۳
    text = text.replace(new RegExp('^\=\=\=([^\=\r\n]+)\=\=\=$', 'gm'), "== $1 ==")
    text = text.replace(new RegExp('^\=\=\=\=([^\=\r\n]+)\=\=\=\=$', 'gm'), "=== $1 ===")
    } else if (text_test.replace(/^\=\=\=\= /gm,'')!==text_test) {
    //سطح ۴
    text = text.replace(new RegExp('^\=\=\=\=([^\=\r\n]+)\=\=\=\=$', 'gm'), "== $1 ==")
    }else{
    text=text.replace(/===/g,'==')
    };
    };
    text=text.replace(/==  /g,'== ').replace(/  ==/g,' ==')
    };
    return text;
    };
    function decimalPointToPersian(text) {
    //Decimal point [[Special:Permalink/25438370#جمع‌بندی_بدون_رسیدگی]]
    return text.replace(new RegExp('([۰۱۲۳۴۵۶۷۸۹])\\.(?=[۰۱۲۳۴۵۶۷۸۹])', 'g'), '$1٫')
    };
    function wikiTextDigitsToPersian(text) {
    text = replaceExcept(
    text,
    toEnglishDigits,
    [patterns.argumentsBlacklist, patterns.fileNames, patterns.fileParameter]);
    text = replaceExcept(
    text,
    persianTools.toPersianDigits,
    [patterns.globalExceptionTag, patterns.url, patterns.argumentsBlacklist, patterns.mathTag, patterns.imagePixelSize, patterns.fileNames, patterns.ref,
    patterns.sourceTag, patterns.arabicDigitsEnglishContext, patterns.signatures, patterns.htmlEntity, patterns.diffLink,
    patterns.htmlAttributes, patterns.fileParameter, patterns.templateParameterName, patterns.ipSign,
    patterns.parenthesesAfterDigits, patterns.otherLanguagesInline, patterns.preTag , patterns.isbn, patterns.englishDate,
    patterns.parameter, patterns.color, patterns.templateEnglishName, patterns.linksOnEnglishContext, patterns.citation, patterns.refname,
    patterns.LtRTagEnclosed, patterns.boxVar, patterns.mediawikiFunctions]
    );
    text = replaceExcept(
    text,
    decimalPointToPersian,
    [patterns.catgories]
    );
    return text
    return text
    .replace(/ی/g, 'ي')
    //  thousands' separator
    .replace(/ک/g, 'ك')
    .replace(/([۱۲۳۴۵۶۷۸۹۰]),([۱۲۳۴۵۶۷۸۹۰])/g, '$1٬$2')
    .replace(/گ/g, 'كی')
    .replace(/([۱۲۳۴۵۶۷۸۹۰])( |)\u0652/g, '$1°')//تبدیل نویسه سکون+عدد فارسی به نویسه درجه و عدد فارسی
    .replace(/ژ/g, 'زی')
    .replace(/\u0652( |)([۱۲۳۴۵۶۷۸۹۰])/g, '°$2')
    .replace(/چ/g, 'جی')
    //فاصله بین نویسه درجه و حروف الفبای فارسی به جز عدد فارسی
    .replace(/پ/g, 'بی');
    .replace(/([\u0621-\u064A\u0653-\u0655\u067E\u0686\u0698\u06AF\u06A9\u0643\u06AA\uFED9\uFEDA\u06CC\uFEF1\uFEF2])°/g, '$1 °');
    }
     
    function dictationReplace(x, y, extensions, text) {
    return text.replace(
    new RegExp(
    '(^|[^' + persianTools.persianCharacters + '])(\\s|\u200c|_|)(' + x + ')(\\s|_)(' + y + ')(\\s|\u200c|_|)(' +
    extensions + ')($|[^' + persianTools.persianCharacters + '])',
    'g'
    ),
    '$1$2$3\u200c$5$6$7$8'
    );
    }
    }


    function persianSortText(text) {
    // it has dependency to MediaWiki:Gadget-Extra-Editbuttons-Dictionary.js
    return text.split('\n').sort(function (x, y) {
    function dictation(text) {
    var keyX = dePersian(x),
    var i,
    keyY = dePersian(y);
    dictionary = persianToolsDictionary,
    if (keyX < keyY) {
    NASB = '\u064b', // ًـ
    return -1;
    ZAMM = '\u064c'; // ُـ
    for (i in dictionary.complexes) {
    if (dictionary.complexes.hasOwnProperty(i)) {
    text = dictationReplace(
    i,
    dictionary.complexes[i],
    'ی|یی|ها|های|هایی|هایم|هایت|هایش|هایمان|هایتان|هایشان|',
    text
    );
    }
    }
    if (keyX > keyY) {
    }
    return 1;
    // for last name
    text = dictationReplace(
    dictionary.personNames,
    'ی|یی|زاده|نیا|گان|فر|نژاد|یان|ی\u200cها|یها',
    'ی|',
    text
    );
    // for 'آباد's
    text = dictationReplace(
    dictionary.personNames + '|' + dictionary.addToAbad,
    'آباد',
    'زاده|نیا|پور|گان|فر|نژاد|ی|یان|ها|های|یی|هایی|ی\u200cها|یها|',
    text
    );
    // for first names
    for (i in dictionary.firstNameComplex) {
    if (dictionary.firstNameComplex.hasOwnProperty(i)) {
    text = text.replace(
    new RegExp(
    '(^|[^' + persianTools.persianCharacters + ']|\\s|_)(' + i + ')(\\s|_)(' +
    dictionary.firstNameComplex[i] + ')(\\s|_)($|[^' + persianTools.persianCharacters + ']|[^' +
    persianTools.persianCharacters + '])',
    'g'
    ),
    '$1$2\u200c$4$5$6'
    );
    }
    }
    // for colors
    text = dictationReplace(
    dictionary.colorsNames,
    'فام|گون',
    'زاده|نیا|پور|گان|فر|نژاد|ی|یی|ها|های|هایی|ی\u200cها|یها|هایم|هایت|هایش|هایمان|هایتان|هایشان|',
    text
    );
    // for numbers
    text = dictationReplace(
    dictionary.persianNumbers,
    'گانه|ماهه',
    'زاده|نیا|پور|گان|فر|نژاد|ی|یی|ها|های|هایی|هایم|هایت|هایش|هایمان|هایتان|هایشان|',
    text
    );
    // wrong dictation
    for (i in dictionary.forReplace) {
    if (dictionary.forReplace.hasOwnProperty(i)) {
    text = text.replace(
    new RegExp(
    '(^|[^' + persianTools.persianCharacters + '])(\\s|\\(|\u200c|_|)(' + i + ')(\\s|\\)|\u200c|_|)($|[^' +
    persianTools.persianCharacters + '])',
    'g'
    ),
    '$1$2' + dictionary.forReplace[i] + '$4$5'
    );
    }
    }
    return 0;
    }
    }).join('\n');
     
    }
    // کلماتی که آ دارند
    text = text.replace(
    new RegExp("(^|\\s|_|«|»|\\[|\\(|\\<|\\>|\\')(" + dictionary.wordsWithA + ")(ی|ئی|یی|ٔ|)(?= |«|»|\\.|،|_|\\]|\\s|\\:|\\)|\\<|\\>|؟|\\'|\\!|$)", 'g'),
    function (x) { return x.replace(/ا/i, 'آ'); } // 'i' is just to trick bidi algorithm on code view
    );
    // بن مضارع که آ دارند
    text = text.replace(
    new RegExp("(^|\u200c|\\s|_|«|»|\\[|\\(|\\<|\\>|\\')(" + dictionary.PresentVerbsWithA + ")(م|ی|د|یم|ید|ند)(?= |«|»|\\.|،|_|\\s|\\]|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)", 'g'),
    function (x) { return x.replace(/ا/i, 'آ'); } // 'i' is just to trick bidi algorithm on code view
    );
     
    // بن ماضی که آ دارند
    text = text.replace(
    new RegExp("(^|\u200c|\\s|_|«|»|\\[|\\(|\\<|\\>|\\')(" + dictionary.PastVerbsWithA + ")(م|ی|یم|ید|ند|ه|)(?= |«|»|\\.|،|_|\\s|\\]|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)", 'g'),
    function (x) { return x.replace(/ا/i, 'آ'); } // 'i' is just to trick bidi algorithm on code view
    );
     
    // همزه ضم
    text = text.replace(
    new RegExp("(^|\\s|_|«|»|\\[|\\(|\\<|\\>|\\')(" + dictionary.HamzehZam + ")(‌ها|ها|ین|ان|ی|ئی|یی|ٔ|)(?= |«|»|\\.|،|_|\\s|\\]|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)", 'g'),
    function (x) { return x.replace(/وء/, 'ؤ').replace(/و/i, 'ؤ'); } // 'i' is just to trick bidi algorithm on code view
    );
    //همزه نصب
    text = text.replace(
    new RegExp("(^|\\s|_|«|»|\\[|\\(|\\<|\\>|\\')(" + dictionary.HamzehNasb + ")(ی|ئی|یی|ٔ|)(?= |«|»|\\.|،|_|\\s|\\]|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)", 'g'),
    function (x) { return x.replace(/ا/i, 'أ'); } // 'i' is just to trick bidi algorithm on code view
    );
     
    //همزه وسط کلمه
    for (i in dictionary.HamzehAtInside) {
    text = text.replace(new RegExp(
    "(^|\\s|_|«|»|\\[|\\(|\\<|\\>|\\')(" + i + ')(| )(' + dictionary.HamzehAtInside[i] + ")(?= |«|»|\\.|،|_|\\s|\\]|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)",
    'g'
    ), '$1$2ء$4');
    }
     
    // در مورد افزودن یا حذف همزهٔ پایانی اجماعی وجود ندارد.
    /* text = text.replace(new RegExp("(^|\\s|_|«|»|\\[|\\(|\\<|\\>|\\')(" + dictionary.HamzehAtEnd + ")(?= |«|»|\\.|،|_|\\s|\\]|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)", 'g'),'$1$2ء'); */


    persianPastVerbs = '(' +
    //الف مقصوره
    'ارزید|افتاد|افراشت|افروخت|افزود|افسرد|افشاند|افکند|انباشت|انجامید|انداخت|اندوخت|اندود|اندیشید|انگاشت|انگیخت|انگیزاند|اوباشت|ایستاد' +
    text = text.replace(
    '|آراست|آراماند|آرامید|آرمید|آزرد|آزمود|آسود|آشامید|آشفت|آشوبید|آغازید|آغشت|آفرید|آکند|آگند|آلود|آمد|آمرزید|آموخت|آموزاند' +
    new RegExp("(^|\\s|_|«|»|\\[|\\(|\\<|\\>|\\')(" + dictionary.AlefMaghsooreh + ")(?= |«|»|\\.|،|_|\\s|\\]|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)", 'g'),
    '|آمیخت|آهیخت|آورد|آویخت|باخت|باراند|بارید|بافت|بالید|باوراند|بایست|بخشود|بخشید|برازید|برد|برید|بست|بسود|بسیجید|بلعید' +
    function (x) { return x.replace(/ا/i, 'ی'); } // 'i' is just to trick bidi algorithm on code view
    '|بود|بوسید|بویید|بیخت|پاشاند|پاشید|پالود|پایید|پخت|پذیراند|پذیرفت|پراکند|پراند|پرداخت|پرستید|پرسید|پرهیزید|پروراند|پرورد|پرید' +
    );
    '|پژمرد|پژوهید|پسندید|پلاسید|پلکید|پناهید|پنداشت|پوسید|پوشاند|پوشید|پویید|پیچاند|پیچانید|پیچید|پیراست|پیمود|پیوست|تاباند|تابید|تاخت' +
    '|تاراند|تازاند|تازید|تافت|تپاند|تپید|تراشاند|تراشید|تراوید|ترساند|ترسید|ترشید|ترکاند|ترکید|تکاند|تکانید|تنید|توانست|جَست|جُست' +
    '|جست|جنباند|جنبید|جنگید|جهاند|جهید|جوشاند|جوشید|جوید|چاپید|چایید|چپاند|چپید|چراند|چربید|چرخاند|چرخید|چرید|چسباند|چسبید' +
    '|چشاند|چشید|چکاند|چکید|چلاند|چلانید|چمید|چید|خاراند|خارید|خاست|خایید|خراشاند|خراشید|خرامید|خروشید|خرید|خزید|خشکاند' +
    '|خشکید|خفت|خلید|خمید|خنداند|خندانید|خندید|خواباند|خوابانید|خوابید|خواست|خواند|خوراند|خورد|خوفید|خیساند|خیسید|داد|داشت|دانست' +
    '|درخشانید|درخشید|دروید|درید|دزدید|دمید|دواند|دوخت|دوشید|دوید|دید|دیدم|راند|ربود|رخشید|رساند|رسانید|رست|رَست|رُست' +
    '|رسید|رشت|رفت|رُفت|رقصاند|رقصید|رمید|رنجاند|رنجید|رندید|رهاند|رهانید|رهید|روبید|روفت|رویاند|رویید|ریخت|رید|ریسید' +
    '|زاد|زارید|زایید|زد|زدود|زیست|سابید|ساخت|سپارد|سپرد|سپوخت|ستاند|ستد|سترد|ستود|ستیزید|سرایید|سرشت|سرود|سرید' +
    '|سزید|سفت|سگالید|سنجید|سوخت|سود|سوزاند|شاشید|شایست|شتافت|شد|شست|شکافت|شکست|شکفت|شکیفت|شگفت|شمارد|شمرد|شناخت' +
    '|شناساند|شنید|شوراند|شورید|طپید|طلبید|طوفید|غارتید|غرید|غلتاند|غلتانید|غلتید|غلطاند|غلطانید|غلطید|غنود|فرستاد|فرسود|فرمود|فروخت' +
    '|فریفت|فشاند|فشرد|فهماند|فهمید|قاپید|قبولاند|کاست|کاشت|کاوید|کرد|کشاند|کشانید|کشت|کشید|کفت|کفید|کند|کوبید|کوچید' +
    '|کوشید|کوفت|گَزید|گُزید|گایید|گداخت|گذارد|گذاشت|گذراند|گذشت|گرازید|گرایید|گرداند|گردانید|گردید|گرفت|گروید|گریاند|گریخت|گریست' +
    '|گزارد|گزید|گسارد|گستراند|گسترد|گسست|گسیخت|گشت|گشود|گفت|گمارد|گماشت|گنجاند|گنجانید|گنجید|گندید|گوارید|گوزید|لرزاند|لرزید' +
    '|لغزاند|لغزید|لمباند|لمدنی|لمید|لندید|لنگید|لهید|لولید|لیسید|ماسید|مالاند|مالید|ماند|مانست|مرد|مکشید|مکید|مولید|مویید' +
    '|نازید|نالید|نامید|نشاند|نشست|نکوهید|نگاشت|نگریست|نمایاند|نمود|نهاد|نهفت|نواخت|نوردید|نوشاند|نوشت|نوشید|نیوشید|هراسید|هشت' +
    '|ورزید|وزاند|وزید|یارست|یازید|یافت' +
    ')';


    persianPresentVerbs = '(' +
    // صفت+تر
    'ارز|افت|افراز|افروز|افزا|افزای|افسر|افشان|افکن|انبار|انباز|انجام|انداز|اندای|اندوز|اندیش|انگار|انگیز|انگیزان' +
    text = text.replace(new RegExp("(^|\\s|_|«|»|\\]|\\[|\\(|\\<|\\>|\\')(" + dictionary.adjective + ")( |_)تر(?= |«|»|\\.|\\[|\\]|،|_|\\s|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)", 'g'),'$1$2\u200cتر');
    '|اوبار|ایست|آرا|آرام|آرامان|آرای|آزار|آزما|آزمای|آسا|آسای|آشام|آشوب|آغار|آغاز|آفرین|آکن|آگن|آلا|آلای' +
    '|آمرز|آموز|آموزان|آمیز|آهنج|آور|آویز|آی|بار|باران|باز|باش|باف|بال|باوران|بای|باید|بخش|بخشا|بخشای' +
    // اسامی رنگ‌ها (به‌عنوان صفت)+تر
    '|بر|بَر|بُر|براز|بساو|بسیج|بلع|بند|بو|بوس|بوی|بیز|بین|پا|پاش|پاشان|پالا|پالای|پذیر|پذیران' +
    text = text.replace(new RegExp("(^|\\s|_|«|»|\\]|\\[|\\(|\\<|\\>|\\')(" + dictionary.colorsNames + ")( |_)تر(?= |«|»|\\.|\\[|\\]|،|_|\\s|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)", 'g'),'$1$2\u200cتر');
    '|پر|پراکن|پران|پرداز|پرس|پرست|پرهیز|پرور|پروران|پز|پژمر|پژوه|پسند|پلاس|پلک|پناه|پندار|پوس|پوش|پوشان' +
    '|پوی|پیچ|پیچان|پیرا|پیرای|پیما|پیمای|پیوند|تاب|تابان|تاران|تاز|تازان|تپ|تپان|تراش|تراشان|تراو|ترس|ترسان' +
    text = text.replace(/به دست\u200cآورد/g, 'به دست آورد'); // Solving a bug!
    '|ترش|ترک|ترکان|تکان|تن|توان|توپ|جنب|جنبان|جنگ|جه|جهان|جو|جوش|جوشان|جوی|چاپ|چای|چپ|چپان' +
    text = persianTools.normalizeZwnj(text);
    '|چر|چران|چرب|چرخ|چرخان|چسب|چسبان|چش|چشان|چک|چکان|چل|چلان|چم|چین|خار|خاران|خای|خر|خراش' +
    return text.replace(new RegExp("(^|[؛\\s\\n\\.،«»\'\\<\\>؟])(" + dictionary.needsNasb + ')[' + NASB + ZAMM + ']?([؛؟\\s\\n\\.،«»\'"\\<\\>]|$)', 'g'), function (match) {
    '|خراشان|خرام|خروش|خز|خشک|خشکان|خل|خم|خند|خندان|خواب|خوابان|خوان|خواه|خور|خوران|خوف|خیز|خیس' +
    return match
    '|خیسان|دار|درخش|درخشان|درو|دزد|دم|ده|دو|دوان|دوز|دوش|ران|ربا|ربای|رخش|رس|رسان' +
    .replace(new RegExp('ا([\\s\\n\\.،«»؟؛"\'\\>\\<' + ZAMM + '])', 'i'), 'ا' + NASB + '$1')
    '|رشت|رقص|رقصان|رم|رنج|رنجان|رند|ره|رهان|رو|روب|روی|رویان|ریز|ریس|رین|زا|زار|زای|زدا' +
    .replace(new RegExp(NASB + '["' + NASB + ZAMM + ']'), NASB);
    '|زدای|زن|زی|ساب|ساز|سای|سپار|سپر|سپوز|ستا|ستان|ستر|ستیز|سر|سرا|سرای|سرشت|سز|سگال|سنب' +
    });
    '|سنج|سوز|سوزان|شاش|شای|شتاب|شکاف|شکف|شکن|شکوف|شکیب|شمار|شمر|شناس|شناسان|شنو|شو|شور|شوران|شوی' +
    }
    '|طپ|طلب|طوف|غارت|غر|غلت|غلتان|غلط|غلطان|غنو|فرسا|فرسای|فرست|فرما|فرمای|فروش|فریب|فشار|فشان|فشر' +
    '|فهم|فهمان|قاپ|قبولان|کار|کاه|کاو|کش|کَش|کُش|کِش|کشان|کف|کن|کوب|کوچ|کوش|گا|گای|گداز' +
    '|گذار|گذر|گذران|گرا|گراز|گرای|گرد|گردان|گرو|گری|گریان|گریز|گز|گزار|گزین|گسار|گستر|گستران|گسل|گشا' +
    '|گشای|گمار|گنج|گنجان|گند|گو|گوار|گوز|گوی|گیر|لرز|لرزان|لغز|لغزان|لم|لمبان|لند|لنگ|له|لول' +
    '|لیس|ماس|مال|مان|مک|مول|موی|میر|ناز|نال|نام|نشان|نشین|نکوه|نگار|نگر|نما|نمای|نمایان|نه' +
    '|نهنب|نواز|نورد|نوش|نوشان|نویس|نیوش|هراس|هست|هل|ورز|وز|وزان|یاب|یار|یاز' +
    ')';


    persianComplexPastVerbs={
    function wikiDictation(text) {
    'باز':'آفرید|آمد|آموخت|آورد|ایستاد|تابید|جست|خواند|داشت|رساند|ستاند|شمرد|ماند|نمایاند|نهاد|نگریست|پرسید|گذارد'+
    return replaceExcept(
    '|گرداند|گردید|گرفت|گشت|گشود|گفت|یافت',
    text,
    'در':'بر ?داشت|بر ?گرفت|آمد|آمیخت|آورد|آویخت|افتاد|افکند|انداخت|رفت|ماند|نوردید|کشید|گرفت',//bug: در گذشته
    dictation,
    'بر':'آشفت|آمد|آورد|افتاد|افراشت|افروخت|افشاند|افکند|انداخت|انگیخت|تاباند|تابید|تافت|تنید|جهید|خاست|خواست|خورد'+
    [patterns.globalExceptionTag, patterns.fileNames, patterns.signatures, patterns.url, patterns.galleryTag, patterns.insideQuote, patterns.argumentsBlacklist, patterns.articleTitleParts]
    '|داشت|دمید|شمرد|نهاد|چید|کرد|کشید|گرداند|گردانید|گردید|گزید|گشت|گشود|گمارد|گماشت',
    );
    'فرو':'آمد|خورد|داد|رفت|نشاند|کرد|گذارد|گذاشت',
    'وا':'داشت|رهاند|ماند|نهاد|کرد',
    'ور':'آمد|افتاد|رفت',
    'یاد':'گرفت',
    'پدید':'آورد',
    'پراکنده':'ساخت',
    'زمین':'خورد',
    'گول':'زد',
    'لخت':'کرد'
    }
    }
    function wikiApplyOrthography(text) {
    text=text //en:Wikipedia:HTML5
    //big
    .replace(/((?:\<big\>){5})([^<]+)((?:\<\/big\>){5})/g,'<span style="font-size: 56px;">$2</span>')
    .replace(/((?:\<big\>){4})([^<]+)((?:\<\/big\>){4})/g,'<span style="font-size: 38px;">$2</span>')
    .replace(/((?:\<big\>){3})([^<]+)((?:\<\/big\>){3})/g,'{{خیلی بزرگ|$2}}')
    .replace(/((?:\<big\>){2})([^<]+)((?:\<\/big\>){2})/g,'{{بزرگ|$2}}')
    .replace(/((?:\<big\>){1})([^<]+|[\s\S]+)((?:\<\/big\>){1})/g,'{{درشت|$2}}')
    //center
    .replace(/<center><gallery>([\S\s]+?)\<\/gallery><\/center>/g,'<gallery class="center">$1</gallery>')
    //.replace(/<center>([\S\s]+?)<\/center>/g,'{{وسط|$1}}')
    //empty tag
    .replace(/<span style="font-size: [^>]+"><\/span>/g,'')
    .replace(/{{(?:درشت|خیلی بزرگ|بزرگ|وسط)\|}}/g,'')


    persianComplexPresentVerbs={
    //حذف برچسب‌های خالی نرم‌افزار مدیاویکی
    'باز':'آفرین|آموز|آور|ایست|تاب|جو|خوان|دار|رس|ستان|شمار|مان|نمایان|نه|نگر|پرس|گذار|گردان|گرد|گشا|گو|گیر|یاب',
    var tags = ['math', 'div', 'grammarly\\-btn','code', 'nowiki', 'pre', 'syntaxhighlight' ,'source', 's', 'noinclude', 'includeonly', 'big', 'small','gallery'];// has bug for sub , sup [[Special:Diff/19450140/19490903]]
    'در':'بر ?دار|بر ?گیر|آمیز|آور|آویز|افت|افکن|انداز|مان|نورد|کش|گذر|گیر',//مشکل با: در روم باستان، در ده
    text = replaceExcept(
    'بر':'آشوب|آور|افت|افراز|افروز|افشان|افکن|انداز|انگیز|تابان|تاب|تن|جه|خواه|خور|خیز|دار|دم|شمار|نه|چین|کش|کن'+
      text,
    '|گردان|گزین|گشا|گمار',
      function (text) {
    //مشکل با : بر گردن
    for (var i = 0; i < tags.length; ++i) {
    'فرو':'خور|ده|رو|نشین|کن|گذار',
    for (var b = 0; b < 5; ++b) {//خیلی از برچسب‌های خالی تو در تو هستند مانند [[Special:PermaLink/19223877]]
    'وا':'دار|رهان|مان|نه|کن',
      text = text.replace(new RegExp('\<' + tags[i] + '[^\>]*\>(\\n|\\s|\u200c)*?\<\\/' + tags[i] + '\>', 'g'), '');
    'ور':'افت|رو',
    }
    'یاد':'گیر',
      // remove the tags if they occurred multiple times consequently
    'پدید':'آور',
      if (mw.config.get('wgNamespaceNumber') === 0 || mw.config.get('wgNamespaceNumber') === 4) {
    'پراکنده':'ساز',
    text = text.replace(new RegExp('(\<' + tags[i] + '\>){2,}', 'g'), '$1')
    'زمین':'خور',
      .replace(new RegExp('(\<\\/' + tags[i] + '\>){2,}', 'g'), '$1');
    'گول':'زن',
      }
    'لخت':'کن'
    }
    if (mw.config.get('wgNamespaceNumber') === 0) {
    text=text.replace(/\<ref\>[\s\n]*\<\/ref\>/g,'').replace(/\<ref\>[\s\n]*\<ref\>/g,'<ref>').replace(/\<\/ref\>[\s\n]*\<\/ref\>/g,'</ref>').replace(/\<ref\/\>/g,'</ref>');
    };
    return text
      },
      [patterns.insideHtmlComment]
    );
    return replaceExcept(
    text,
    persianTools.applyOrthography,
    [patterns.globalExceptionTag, patterns.fileNames, patterns.signatures, patterns.url, patterns.galleryTag, patterns.wikilinkTargets]
    ).replace(patterns.galleryTag, function (gallery) {
    // apply `applyOrthography` on gallery descriptions separately
    return gallery.replace(/^([^\|]*?\|)(.*)$/mg, function (x, y, z) {
    return y + persianTools.applyOrthography(z);
    });
    });
    }
    // probably should be exactly same above but for applyZwnj
    function wikiApplyZwnj(text) {
    return replaceExcept(
    text,
    persianTools.applyZwnj,
    [patterns.globalExceptionTag, patterns.fileNames, patterns.signatures, patterns.url, patterns.galleryTag]
    ).replace(patterns.galleryTag, function (gallery) {
    // apply `applyOrthography` on gallery descriptions separatly
    return gallery.replace(/^([^\|]*?\|)(.*)$/mg, function (x, y, z) {
    return y + persianTools.applyZwnj(z);
    });
    });
    }
    }


    function complexVerbsApplyZwnj(text) {
    function replaceEnMonth(text) {
    for (var x in persianComplexPastVerbs) {
    var enMonth = {
    var y = persianComplexPastVerbs[x]
    'آگست':'اوت',
    text = text.replace(new RegExp(
    'آگوست':'اوت',
      '(^|[^' + persianCharacters + '])(' + x + ') ?(می|نمی|)( |\u200c|)(ن|)('
    'جولای':'ژوئیه',
    + y + ')(م|ی|یم|ید|ند|ه|ن|)($|[^' + persianCharacters + '])', 'g'),
    'مارچ':'مارس',
    '$1$2\u200c$3\u200c$5$6$7$8');
    'آپریل':'آوریل',
    'فوریوری':'فوریه',
    'january': 'ژانویه',
    'jan': 'ژانویه',
    'february': 'فوریه',
    'feb': 'فوریه',
    'march': 'مارس',
    'mar': 'مارس',
    'april': 'آوریل',
    'apr': 'آوریل',
    'may': 'مه',
    'june': 'ژوئن',
    'jun': 'ژوئن',
    'july': 'ژوئیه',
    'august': 'اوت',
    'aug': 'اوت',
    'september': 'سپتامبر',
    'sept': 'سپتامبر',
    'sep': 'سپتامبر',
    'october': 'اکتبر',
    'oct': 'اکتبر',
    'november': 'نوامبر',
    'nov': 'نوامبر',
    'december': 'دسامبر',
    'dec': 'دسامبر'
    };
    for (var i in enMonth) {
    var text_new = text.replace(new RegExp(i, 'ig'), enMonth[i])
    if (text_new != text) {
    return text_new
    }
    }
    }
    for (var x in persianComplexPresentVerbs) {
    return text
    var y = persianComplexPresentVerbs[x]
    };
    text = text.replace(new RegExp(
    function autoFormatCleanDatesException (text) {
      '(^|[^' + persianCharacters + '])(' + x + ') ?(می|نمی|)( |\u200c|)(ن|)('
    return replaceExcept(
    + y + ')(م|ی|د|یم|ید|ند|ن)($|[^' + persianCharacters + '])', 'g'),
    text,
    '$1$2\u200c$3\u200c$5$6$7$8');
    autoFormatCleanDates,
    [patterns.globalExceptionTag, patterns.fileNames, patterns.galleryTag, patterns.mathTag, patterns.sourceTag, patterns.templateWithEnglishName, patterns.citation, patterns.argumentsBlacklist, patterns.ref]
    )
    }
    function wikitranslateEnMonth(text) {
    text=autoFormatCleanDatesException(text)
    return replaceExcept(
    text,
    function translateEnMonth(text) {
    var enMonthRegex = '(آگست|آگوست|جولای|مارچ|آپریل|january|jan|february|feb|march|mar|april|apr|may|jun|june|july|august|aug|sep|sept|september|oct|october|nov|november|december|dec)';
    return text.replace(new RegExp('([^a-zA-Z])(\^|\\||\\s|\\=|\\n|\\(|«|\\:)' + enMonthRegex + ' (\\d{1,2}|[۱۲۳۴۵۶۷۸۹۰]{1,2})\\, (\\d{3,4}|[۱۲۳۴۵۶۷۸۹۰]{3,4})(\\||\\s|\\n|\$|\\)|\\}|»)([\^a\-zA\-Z])', 'ig'),
    function (x) {
    x=x.replace(new RegExp('([\^a\-zA\-Z])(\^|\\||\\s|\\=|\\n|\\(|«|\\:)' + enMonthRegex + ' (\\d{1,2}|[۱۲۳۴۵۶۷۸۹۰]{1,2})\\, (\\d{3,4}|[۱۲۳۴۵۶۷۸۹۰]{3,4})(\\||\\s|\\n|\$|\\)|\\}||»)([^a-zA-Z])', 'ig'),
    '$1$2$4 $3 $5$6$7')
    x = persianTools.toPersianDigits(x);
    x = replaceEnMonth(x);
    return x;
    })
    .replace(new RegExp('([\^a\-zA\-Z])(\^|\\||\\s|\\=|\\n|\\(|«)((\\d{1,2}|[۱۲۳۴۵۶۷۸۹۰]{1,2}) |)' + enMonthRegex + ' (\\d{3,4}|[۱۲۳۴۵۶۷۸۹۰]{3,4})(\\||\\s|\\n|$|\\)|\\}|»|\\:)([\^a\-zA\-Z])', 'ig'),
    function(x) {
    x = persianTools.toPersianDigits(x);
    x = replaceEnMonth(x);
    return x;
    }
    );
    }, [patterns.globalExceptionTag, patterns.fileNames, patterns.ref, patterns.fileParameter, patterns.galleryTag, patterns.mathTag, patterns.sourceTag, patterns.templateWithEnglishName, patterns.citation, patterns.argumentsBlacklist]
    )
    }
    var arabicDigits = '0123456789', persianDigits = '۰۱۲۳۴۵۶۷۸۹', arabicIndicDigits = '٠١٢٣٤٥٦٧٨٩';
    function robustToEnglishDigits(text) {
    var i = 0;
    for (i = 0; i <= 9; i = i + 1) {
    text = text.replace(new RegExp('[' + persianDigits[i] + arabicIndicDigits[i]+']', 'g'), arabicDigits[i]);
    }
    }
    return text;
    return text;
    }
    }
    function toEnglishDigits(text) {
    text = text.replace(/[a-zA-Z]([\_\s\:\.\,\;\]\[\"\'\)\(\}\{\/\\ ]+|)([۱۲۳۴۵۶۷۸۹۰٪\.٫\-\—\–°÷×\+\,\s\_\:،»«؛]+)([\_\s\:\.\,\;\]\[\"\'\)\(\}\{\/\\\<\> ]+|)([a-zA-Z\>]|$)/g, function (x) {
    var i = 0;
    for (i = 0; i <= 9; i = i + 1) {
    x = x.replace(new RegExp('[' + persianDigits[i] + arabicIndicDigits[i]+ ']', 'g'), arabicDigits[i]);
    }
    return x.replace(/،/g,',').replace(/»/g,'"').replace(/«/g,'"').replace(/؛/g,';');
    });
    // bug [[Special:Diff/17760890/17760898]]
    text = text.replace(/([a-zA-Z][۱۲۳۴۵۶۷۸۹۰]+) *\=/g, function (x) {
    var i = 0;
    for (i = 0; i <= 9; i = i + 1) {
    x = x.replace(new RegExp('[' + persianDigits[i] + arabicIndicDigits[i]+ ']', 'g'), arabicDigits[i]);
    }
    return x;
    });
    // ISBN, ISSN and PMID's numbers should in english
    text = text.replace(/\b(ISBN|ISSN|PMID|PubMed) *:? *([۱۲۳۴۵۶۷۸۹۰0-9–—−ـ_\-]+)([^۱۲۳۴۵۶۷۸۹۰0-9–—−ـ_\-]|$)/gi, function (x) {
    x=x.replace(/[–—−ـ_\-]+/g,'-')
    var i = 0;
    for (i = 0; i <= 9; i = i + 1) {
    x = x.replace(new RegExp('[' + persianDigits[i] + arabicIndicDigits[i]+ ']', 'g'), arabicDigits[i]);
    }
    x = x.replace(/\b(ISBN|ISSN|PMID|PubMed) *:? *([۱۲۳۴۵۶۷۸۹۰\-0-9]+)([^۱۲۳۴۵۶۷۸۹۰\-0-9]|$)/gi,'$1 $2$3')
    x = x.replace('PubMed','PMID')
    return x;
    });
    text = text.replace(/ISBN \-note/g,'ISBN-note');
    // تبدیل عددهای فارسی در عدد ترتیبی انگلیسی
    text = text.replace(/(?:^|["\'\s_«\(\[\{])([۱۲۳۴۵۶۷۸۹۰]+)(st|nd|rd|th)[\s_\.,»"\'\)\]\}]/g, function (x) {
    var i = 0;
    for (i = 0; i <= 9; i = i + 1) {
    x = x.replace(new RegExp('[' + persianDigits[i]+ arabicIndicDigits[i] + ']', 'g'), arabicDigits[i]);
    }
    return x;
    });
    return text
    .replace(new RegExp('([' + arabicDigits + ']) ?٪', 'g'), '$1%')
    .replace(new RegExp('([' + arabicDigits + '])٫(?=[' + arabicDigits + '])', 'g'), '$1.') // English decimal separator
    }
    function cleanTemplateBracesFromArticle (text) {// like [[Special:Diff/18828723]]
                if (mw.config.get('wgNamespaceNumber') !== 0) {
                      return text
                }
                var i =0
                for (i = 0; i <= 5; i = i + 1) {
    text = text.replace(/\{\{\{[^\|\}]+\|([^\}]+)\}\}\}/g, '$1')
              .replace(/\{\{\{[^\|\}]+\| *\}\}\}/g, '')
    }


    function applyZwnj(text) {
                return text.replace(/\{\{\#/g, '{{جا:#')
    text=complexVerbsApplyZwnj(text);
                          .replace(/\{\{ *(PAGENAME|FULLPAGENAMEE|SITENAME|NAMESPACE) *\}\}/g, '{{جا:$1}}')
    return normalizeZwnj(text)
                          .replace('{{ترتیب‌پیش‌فرض:}}', '');
    .replace(
    }
    new RegExp('(^|[^' + persianCharacters + '])(می|نمی) ?' + persianPastVerbs +
    function decodeHTMLSymbolEntitiesCodes (text) {
    '(م|ی|یم|ید|ند|ه|)($|[^' + persianCharacters + '])', 'g'),
    //&copy; > ©
    '$1$2\u200c$3$4$5'
    return replaceExcept(
    )
    text,
    .replace(
    function decodeEntitiesCodes (text) {
    new RegExp('(^|[^' + persianCharacters + '])(می|نمی) ?' + persianPresentVerbs +
    for (var i in htmlEntityCodes) {
    '(م|ی|د|یم|ید|ند)($|[^' + persianCharacters + '])', 'g'),
    var entityInput = i;
    '$1$2\u200c$3$4$5'
    var entityoutput = htmlEntityCodes[i];
    )
    text=text.replace(new RegExp(entityInput, 'g'), entityoutput);
    // ماضی نقلی (است حذف شد)
    }
    .replace(
    return text;
    new RegExp('(^|[^' + persianCharacters + '])(ن|)' + persianPastVerbs +
    }, [patterns.globalExceptionTag, patterns.fileNames, patterns.ref, patterns.fileParameter,
    (ام|ای|ایم|اید|اند)($|[^' + persianCharacters + '])', 'g'),
    patterns.galleryTag, patterns.mathTag, patterns.sourceTag, patterns.templateWithEnglishName,
    '$1$2$3ه\u200c$4$5'
    patterns.citation, patterns.url]
    )
    )
    }
    // بن فعل مضارع «دان» جدا آمد چون پسوند «ی» با عبارت «میدانی» تداخل داشت
    function removeWikiSigne (text) {
    .replace(
    return replaceExcept(
    new RegExp('(^|[^' + persianCharacters + '])(می|نمی) ?(دان)(م|د|یم|ید|ند)($|[^' + persianCharacters + '])', 'g'),
    text,
    '$1$2\u200c$3$4$5'
    function (text) {
    )
    text=text.replace(/\[\[([^\|\]]+)\|([^\]]+)\]\]/g, '$2');
    // ای «توان» ناقلا!
    text=text.replace(/\[\[([^\|\]]+)\]\]/g, '$1');
    .replace(/(\s)(می|نمی) ?توان/g, '$1$2\u200cتوان')
    return text;
    // چسباندن تمام «ها»ها با فاصلهٔ مجازی
    }, [patterns.globalExceptionTag, patterns.fileNames, patterns.fileParameter,
    .replace(/ ها([\]\.،\:»\)\s]|\'{2,3}|\={2,})/g, '\u200cها$1')
    patterns.mathTag, patterns.sourceTag, patterns.templateWithEnglishName, patterns.nowikiTag, patterns.preTag,
    .replace(/ ها(ی|یی|یم|یت|یش|ی?مان|ی?تان|ی?شان)([\]\.،\:»\)\s])/g, '\u200cها$1$2')
    patterns.insideHtmlComment]
    .replace(/هها/g, 'ه‌ها')
    )
    // چسباندن تمام «ترین»ها با فاصلهٔ مجازی
    }
    .replace(/ ترین([\]\.،\:»\)\s]|\'{2,3}|\={2,})/g, '\u200cترین$1')
    function autoEdHTMLtoWikitextWikiTools (text) {
    // چسباندن تمام «تبار»ها با فاصلهٔ مجازی
    return replaceExcept(
    .replace(
    text,
    new RegExp('([' + persianCharacters + ']ی) تبار([^' + persianCharacters + '])', 'g'),
    autoEd.autoEdHTMLtoWikitext,
    '$1\u200cتبار$2'
    [patterns.fileParameter, patterns.mathTag, patterns.sourceTag]
    )
    )
    // چسباندن تمام «شناس»ها با فاصلهٔ مجازی
    }
    .replace(
    function superTool(text) {
    new RegExp('([' + persianCharacters + ']) شناس(ی?[^' + persianCharacters + '])', 'g'),
    text = decodeHTMLSymbolEntitiesCodes (text);
    '$1\u200cشناس$2'
    text = cleanTemplateBracesFromArticle (text);
    )
    text = persianWikiTools.wikiConvertToPersianCharacters(text);
    // چسباندن تمام «گیر»ها با فاصلهٔ مجازی
    text = persianWikiTools.wikiApplyZwnj(text);
    .replace(
    text = persianWikiTools.wikiApplyOrthography(text);
    new RegExp('([' + persianCharacters + ']) گیری([^' + persianCharacters + '])', 'g'),
    text = persianWikiTools.wikitranslateEnMonth(text);
    '$1\u200cگیری$2'
    if (mw.config.get('wgNamespaceNumber') !== 10) {
    )
    text = persianWikiTools.wikiTextDigitsToPersian(text);
    // برای حذف علامت ستاره اضافی قبل از عنوان ها
    }
    .replace(/\n\*\s*(\=+.+?\=+\n)/g, '\n$1')
    text = persianWikiTools.wikiUrlMinifier(text);
    // عضو علامت های نقل قول تکی از عنوان ها
    text = persianWikiTools.wikiDictation(text);
    .replace(/(\n=+)(.*?)(?:'+)(.*?)(?:'+)(.*?)(=+\n)/g, '$1$2$3$4$5')
    text = persianWikiTools.wikiPunctuation(text);
    // اول و آخر هم خط اگر فاصلهٔ مجازی باشد، حذف شود
    text = persianWikiTools.wikiSubsection(text);
    .replace(/(^\u200c|\u200c$)/mg, '')
    text = persianWikiTools.SubSectionLeveling (text)
    // شناسه ها
    //ابزارهای بیشتر برگرفته از ویکی‌پدیای انگلیسی [[Mediawiki:Gadget-Extra-Editbuttons-autoed.js]]
    // توجه: «است» تعدماً از شناسه ها حذف شده چون به عنوان فعل مستقل هم کاربرد دارد و در آن موارد باید جدا نوشته شود
    text = autoEd.autoEdISBN(text);
    // مثال: «این یک خانه است» که است در آن باید از خانه جدا نوشته شود
    text = autoEd.autoEdWhitespace(text);
    // حروف «ام» و «ای» هم به دلیل تشابه با حرف ندا «اِی» و ام انگلیسی و ای انگلیسی حذف شدند.
    text = autoEdHTMLtoWikitextWikiTools(text);
    //.replace(new RegExp('ه +(ایم|اید|اند)($|[^' + persianCharacters + '\u200c])', 'g'), 'ه\u200c$1$2')// به بخش ماضی نقلی منتقل شد
    text = autoEd.autoEdHeadlines(text);
    // موارد جزئی دیگر و بی ربط به فاصلهٔ مجازی، باید منتقل شود
    text = autoEd.autoEdTablestoWikitext(text);
    .replace(/ا\sً/g, 'اً')
    text = autoEd.autoEdExtraBreaks(text);
    // رفع اشکال که\u200cای
    text = persianWikiTools.addColumnToRefTemplate(text);
    .replace(/ که\u200cای /g, ' که ای ')
    text = persianWikiTools.removeCheckDict(text);
    //رفع اشکال میستری (Mystery)
    return text;
    .replace(/می\u200cستری/g, 'میستری')
    }
    .replace(/ویکیپدیا/g, 'ویکی‌پدیا')
    .replace(new RegExp('می\u200cگوی($|[^' + persianCharacters + '\u200c])', 'g'), 'میگوی$1') // for میگوی دریایی
    function superToolMove(text) {
    .replace(new RegExp('می\u200cدوی($|[^' + persianCharacters + '\u200c])', 'g'), 'میدوی$1');// for [[میدوی (ابهام‌زدایی)]]
    text = ' ' + text + ' '; // بعضی از کدها اگر فاصله در انتها یا اول نباشد عمل نمی‌کنند مانند افزودن تنوین به کلمه بعدا
    text = persianWikiTools.wikiConvertToPersianCharacters(text);
    text = persianTools.applyZwnj(text);
    text = persianWikiTools.wikiApplyOrthography(text);
    text = persianWikiTools.wikiTextDigitsToPersian(text);
    text = persianWikiTools.wikiUrlMinifier(text);
    text = persianWikiTools.wikiDictation(text);
    text = persianWikiTools.wikiPunctuation(text);
    return text.trim();
    }
    }


    function punctuation(text) {
    return text
    /// سجاوندی غیرفارسی
    .replace(/ː/g, ':') // Replace incorrect : character
    // استفاده از ؟ فارسی
    .replace(new RegExp('([' + persianCharacters + '])[ ]*[?]', 'g'), '$1؟')
    // استفاده از ; فارسی
    .replace(new RegExp('([' + persianCharacters + '])[ ]*[;]', 'g'), '$1؛ ')
    // استفاده از ، فارسی
    .replace(new RegExp('([' + persianCharacters + '])(\]\]|»|)[ ]*[,]', 'g'), '$1$2، ')
    //حذف دو فاصله بعد از سجاوندی
    .replace(/(،|؛|؟|\.)  /g, '$1 ')
    .replace(/\r/g, '')
    // افزودن یا حذف فاصله
    // حذف فاصله‌های تکراری میان واژه‌ها، به جز بین نام پارامتر و علامت مساوی
    .replace(/(. ) +(?=[^= ])/g, '$1')
    //فاصله بعد از سجاوندی به جز ! به دلیل (<!-- و !! در بالای جدول‌ها)
    .replace(/([،\.\؛\؟»])([^\s\.\(\)«»\"\[\]<>\d\w\{\}\|۰۱۲۳۴۵۶۷۸۹\'])/g, '$1 $2')
    // افزودن فاصله به بعد از سجاوندی
    .replace(new RegExp('([' + persianCharacters + ']+|\\]|\\)|»)([؟،؛\\!\\.])([' + persianCharacters +persianDigits + ']+|\\[|\\(|«)', 'g'), '$1$2 $3')
    // حذف فاصله بعد از گیومه، پرانتز، براکت باز
    .replace(/([\(«\[]) /g, '$1')
    // حذف فاصله قبل از گیومه، پرانتز، براکت بسته
    .replace(/ ([\)»\]])/g, '$1')
    // افزودن فاصله قبل از گیومه باز
    .replace(/([^ \(\[\|\r\n>'])(«)/g, '$1 $2')
    .replace(/ +\( +/g, ' (')
    .replace(new RegExp('([' + persianCharacters + ']|\\]|») *\\( *(?=[' + persianCharacters + '])(?!ها\\)|ان\\))', 'g'), '$1 (')
    .replace(new RegExp('([' + persianCharacters + ']) *\\) *(?=[' + persianCharacters + ']|\\[|«)', 'g'), '$1) ')
    // خط جدید
    .replace(/\n\s{1,}\n/g, '\n\n')
    // Removes extra line between two items list
    .replace(/(\n\*.*?)\n+(?=\n\*)/g, '$1')
    // Removes extra line between two items list
    .replace(/(\n#.*?)\n+(?=\n#)/g, '$1')
    // Convert , to ، if there are Persian characters on both sides of it
    .replace(new RegExp('([' + persianCharacters + ']), ?(?=[' + persianCharacters + "])", 'g'), '$1$2، ')
    // بعد از نقطه‌ویرگول فارسی علامتی قرار نمی‌گیرد
    .replace(/(؛)(([\s]+)?[\.،؛:!؟\-…])/g, '$1')
    // در انتهای پاراگراف نقطه‌ویرگول فارسی نمی‌آید
    .replace(/(؛)(\s|)\n\n/g, '.\n\n')
    // سجاوندی در ابتدای علامت باز قرار نمی‌گیرد
    .replace(/([\(«])[\s]([؛\.،])/g, '$1')
    // ویرگول فارسی
    // بعد از ویرگول فارسی این علامت‌ها قرار نمی‌گیرد
    .replace(/(،)([\s]+)?([،؛!؟\-][\.،؛!؟\-]*|\.(?!\.))/g, '$1')
    // نقطه
    // باید سه نقطه باشد
    .replace(new RegExp('([' + persianCharacters + '])( *)(\\.{3,})', 'g'), '$1$2…')
    .replace(/ \.\.\. /g, ' … ')
    // بعد از نقطه این علایم نمی‌آیند
    .replace(new RegExp('([' + persianCharacters + '])\\.( *[،؛:!؟\\?]+)', 'g'), '$1.')
    // سجاوندی در ابتدای پرانتز و گیومه باز قرار نمی‌گیرد
    .replace(new RegExp('(\\(|«)[\\.،؛](\\s|)([' + persianCharacters + '])', 'g'), '$1$3')
    // سجاوندی در داخل پرانتز
    .replace(new RegExp('([' + persianCharacters + '])(\\s|)[\\.،؛](\\s|)(\\))', 'g'), '$1$2$3$4')
    // در صورت وابستگی معنی جملات بهتر است نقطه‌ویرگول فارسی قرار گیرد
    .replace(new RegExp('([' + persianCharacters + '])(\\s|)(\\.)(\\s|)(ولی|که\\s|و\\s|بنابراین|لذا)', 'g'), '$1؛ $5')
    /// Question & exclamation mark
    // علامت تعجب تکراری به دلیل وجود !! در عنوان جدول‌های مدیاویکی نباید اصلاح شود.
    // تكرار علامت سوال فارسی
    .replace(/(؟(\s|)){2,}/g, '؟')
    // علامت‌گذاری نادرست
    .replace('؟ !', '؟!').replace('! ؟', '!؟')
    // Remove space preceding punctuation, except for ellipses
    .replace(/([^ \.]) +([؟،\:؛!\.])(\s[^ \.]|<|$)/g, '$1$2$3')
    // تبدیل نیم‌خط به تمام خط بین اعداد فارسی (وپ:خط تیره)
    .replace(new RegExp('([' + persianDigits + ']+\\s?(?:\\_\\_|\\-|ـ+)\\s?)*([' + persianDigits + ']+)\\s?(?:\\_\\_|\\-|ـ+)\\s?([' + persianDigits + ']+)(?!\\s?(?:\\_\\_|\\-|ـ+)\\s?[' + persianDigits + ']+)', 'g'), function ($0, $1, $2, $3) { return ($1 ? $0 : $2 + '–' + $3) })
    // عبارت «ها» درون پرانتز می‌تواند به کلمه قبلی خود بچسبد
    .replace(/ \(ها\)/g, '(ها)')
    .replace(/(\(|)ه‍\. (ق|خ|ش)([\n\/ ]|\))/g, 'ه‍.$2$3')//iاصلاح تاریخ هجری
    // حذف فاصلهٔ میان دو عبارت مختصر که دارای نقطهٔ اختصار باشند
    .replace(new RegExp('(\^|\\||\\(|«|\\}|"|\\s|\\*|\\#)(([' + persianCharacters + ']\{1,2\})\\. \?)\{2,6\}', 'g'), function (m) { return m.replace(/\. (.)/g, '.$1'); });
    }
    return {
    return {
    applyOrthography: applyOrthography,
    removeWikiSigne: removeWikiSigne,
    applyZwnj: applyZwnj,
    superTool: superTool,
    normalizeZwnj: normalizeZwnj,
    superToolMove: superToolMove,
    persianSortText: persianSortText,
    dictation: dictation,
    punctuation: punctuation,
    wikiApplyOrthography: wikiApplyOrthography,
    toPersianDigits: toPersianDigits,
    wikiApplyZwnj: wikiApplyZwnj,
    toStandardPersianCharacters: toStandardPersianCharacters,
    wikiConvertToPersianCharacters: wikiConvertToPersianCharacters,
    vowels: vowels,
    wikiDictation: wikiDictation,
    persianCharacters: persianCharacters,
    wikiPunctuation: wikiPunctuation,
    persianCharactersNoVowels: persianCharactersNoVowels
    wikiSubsection:wikiSubsection,
    SubSectionLeveling:SubSectionLeveling,
    wikiUrlMinifier: wikiUrlMinifier,
    wikiTextDigitsToPersian: wikiTextDigitsToPersian,
    wikitranslateEnMonth: wikitranslateEnMonth,
    addColumnToRefTemplate: addColumnToRefTemplate,
    fixBadLinks: fixBadLinks,
    robustToEnglishDigits: robustToEnglishDigits,
    toEnglishDigits: toEnglishDigits,
    removeCheckDict:removeCheckDict
    };
    };
    }());
    }());
    if (typeof window !== 'undefined') {
    if (typeof window !== "undefined") {
    window.persianTools = persianTools;
    window.persianWikiTools = persianWikiTools;
    }
    }
    // </nowiki>
    // </nowiki>

    نسخهٔ ‏۲۰ سپتامبر ۲۰۲۰، ساعت ۱۲:۰۰

    // <nowiki> // DO NOT REMOVE THIS LINE EVER
    /**
     * Wikipedia specific Persian text style improvement tools
     * Tests: [[مدیاویکی:Gadget-Extra-Editbuttons-tests.js]] [[وپ:تست]]
     * See also: [[مدیاویکی:Gadget-Extra-Editbuttons-persiantools.js]]
     */
    /*global persianTools, persianToolsDictionary, autoEd*/
    var persianWikiTools = (function () {
    	'use strict';
            //http://www.entitycode.com/
    	var htmlEntityCodes = {
    		"&iexcl;": "¡", "&cent;": "¢", "&pound;": "£", "&curren;": "¤",
    		"&yen;": "¥", "&brvbar;": "¦", "&sect;": "§", "&copy;": "©",
    		"&middot;": "·", "&times;": "×", "&rdquo;": "”", "&dagger;": "†",
    		"&Dagger;": "‡", "&euro;": "€", "&laquo;": "«", "&reg;": "®",
    		"&deg;": "°", "&plusmn;": "±", "&sup2;": "²", "&sup3;": "³",
    		"&para;": "¶", "&sup1;": "¹", "&raquo;": "»", "&frac14;": "¼",
    		"&frac12;": "½", "&frac34;": "¾", "&iquest;": "¿", "&divide;": "÷",
    		"&ndash;": "–", "&mdash;": "—", "&lsquo;": "‘", "&rsquo;": "’",
    		"&ldquo;": "“", "&trade;": "™", "&bull;": "•", "&hellip;": "…",
    		"&permil;": "‰", "&lsaquo;": "‹", "&rsaquo;": "›", "&larr;": "←",
    		"&uarr;": "↑", "&rarr;": "→", "&darr;": "↓", "&harr;": "↔",
    		"&crarr;": "↵", "&minus;": "−", "&radic;": "√", "&infin;": "∞",
    		"&loz;": "◊", "&spades;": "♠", "&rfloor;": "⌋", "&nbsp;": " ",
    		"&ne;": "≠", "&ap;": "≈", "&approx;": "≈", "&asymp;": "≈",
    		"&rceil;": "⌉", "&lfloor;": "⌊", "&diams;": "♦", "&auml;": "ä",
    		"&ouml;": "ö", "&uuml;": "ü", "&szlig;": "ß", "&aring;": "å",
    		"&oline; ": "‾ ", "&aelig;": "æ", "&ccedil;": "ç", "&ntilde;": "ñ",
    		"&acirc;": "â", "&aacute;": "á", "&agrave;": "à", "&#36;": "$",
    		"&clubs;": "♣", "&hearts;": "♥", "&Prime;": "″", "&prime;": "′",
    		"&lceil;": "⌈", "&mldr;": "…", "&bullet;": "•", "&grave;": "`",
    		"&pm;": "±", "&acute;": "´", "&centerdot;": "·", "&half;": "½",
    		"&Auml;": "Ä", "&Ouml;": "Ö",  "&Uuml;": "Ü", "&rsquor;": "’",
    		"&lsquor;": "‚", "&sbquo;": "‚", "&rdquor;": "”", "&bdquo;": "„",
    		"&ldquor;": "„",  "&ddagger;": "‡", "&div;": "÷", "&leq;": "≤",
    		"&geq;": "≥", "&le;": "≤", "&ge;": "≥"
    	}; // &quot; , &amp; &lt; &gt; &#124;
    	var patterns = {
    		arabicDigitsEnglishContext: /[a-z]([\|a-z %"'\._:\;,\-\\\/\(\)\#\^\+\d><–\[\]&?{}](?!\|\|))*\d|(\d|[a-z])[a-z %"'\._:\;\|,\-\\\/\(\)\#\^\+\d><–\[\]&?{}]*[a-z]\d*/gi,
    		arabicTagEnclosed: /\{\{(?:عربی|شروع عربی|آغاز عربی)\}\}([\s\S]*?)\{\{(?:پایان عربی)\}\}/g,
    		LtRTagEnclosed: /\{\{(?:چپ چین|چپ‌چین)\}\}([\s\S]*?)\{\{(?:پایان چپ‌چین|پایان چپ چین|پایان)\}\}/g,
    		argumentsBlacklist: /(?:accessdate|namespace|legend1start|image|تصویر|doi|style|شابک|عرض|bibcode|isbn|issn|pmid|arxiv|upright|upleft|padding|spacing|border|filename|نام پرونده)\s*\=\s*[^\|\}\]]*/gi,
    		color: /#(?:[abcdef0-9]{8}|[abcdef0-9]{6}|[abcdef0-9]{3})/gi,
    		//colorAsParameter: /\=\s*(?:[abcdef0-9]{8}|[abcdef0-9]{6}|[abcdef0-9]{3})(?:[\s\|\}]|$)/gi,
    		// space, ", \t, \n, {, |, }, ... they will interfere with wiki markup
    		decodeUriBlacklist: /(?:%20|%27|%5C|%5E|%60|%23|%25|%3C|%3E|%5B|%5D|%22|%09|%0A|%7B|%7C|%7D)/gi,
    		diffLink: /\[\[(?:ویژه|Special):(?:تفاوت|Diff)\/[^\|\]]*/gi,
    		englishDate: /\d{1,2},? [a-z]{3,} \d{2,4}/gi, // 3, May 2013
    		fileNames: /(?:پرونده|File|تصویر|Image)\:.*?(?=\||\]|\n|$)/gi, // don't capture | after
    		fileParameter: /\|\s*(image|تصویر)\s*\=\s*.*/g,
    		ipSign: /\[\[ویژه:مشارکت\u200cها.*?\]\]/g,
    		isbn: /(?:ISBN|ISSN|PMID) [\d\-]*/gi,
    		galleryTag: /<gallery.*?>[\s\S]*?<\/gallery>/g,
    		htmlAttributes: /(?:style|perrow|colspan|color|rowspan|cellpadding|cellspacing|height|width|size|border|thumbtime|name|perrow|upright|upleft)\s*[\=\:]\s*(?:['\"].*?['\"]|[\da-z]+)/gi,
    		htmlEntity: /&#\d+;/,
    		imagePixelSize: /[\|=] *[x\d]+?(px|پیکسل)[\]\|\s]/g, // means it will capture |10px| and |10x10px|
    		insideQuote: /[^ا]".*?"/g,
    		wikilinkTargets: /\[[^\[|\]]+/g,
    		nowikiTag:/<nowiki>.+?<\/nowiki>/g,
    		preTag:/<pre.*?>.*?<\/pre>/g,
    		insideHtmlComment: /<\!\-\-[\s\S]*?\-\->/g,
    		linksOnEnglishContext: /[a-z][\:\,\. ]*\[\[[\da-z\-\, ]*/gi,
    		mathTag: /<math.*?>[\s\S]*?<\/math>/g,
    		otherLanguagesInline: /\{\{(?:به .+?|پم|به انگلیسی|انگلیسی|عربی|متن عربی|عبارت عربی|حدیث|به عربی|به اردو|اردو|lang\-[au]r|پینگ|ping)[\s\S]*?\}\}/g,
    		parameter: /\{\{\{\d+/gi,
    		parenthesesAfterDigits: /\w\s?\([\w\s\.\-]*?\)/g,
    		parenthesesHa: /\)ها/g,
    		ref: /(?:<ref[^\/]*?>[\s\S]*?<\/ref>|<ref[^\/]*?\/>)/g, // inside <ref></ref> and <ref/>
    		refname: /\<ref name\=.*?\>/g,
    		citation:/\{\{\s*(?:[Cc]it|یادکرد).*?[_\s]*(?:\{\{.*?\}\}|[^\}])*\}\}/g,
    		signatures: /\[\[(?:کاربر|User|بحث[ _]کاربر|User[_ ]talk)\:.*?\]\]/gi,
    		sourceTag: /(<source.*?>[\s\S]*?<\/source>|<syntaxhighlight.*?>[\s\S]*?<\/syntaxhighlight>|<code.*?>[\s\S]*?<\/code>|<timeline.*?>[\s\S]*?<\/timeline>)/g,
    		tagNames: /<\/?[a-zA-Z\d]*/g,
    		templateEnglishName: /(الگو|Template):[a-z][a-z\d\-\+_]+/gi,
    		templateWithEnglishName: /\{\{[ \_]*(?:(?:الگو|Template):)?(?:start\-date)[ \_]*\|.*?\}\}/gi,
    		templateParameterName: /\|\s*(?=[a-z_]*\d)[a-z_\d]*\s*\=/gi,
    		globalExceptionTag: /(<nowiki>.+?<\/nowiki>|<!--[\s]*ابر[\s]*-->.+?<!--[\s]*\/[\s]*ابر[\s]*-->|\{\{استثنای ابرابزار\|[\s\S]*?\}\})/gi,
    		translatedUrl: /.(کام|نت|آی‌آر)/g,
    		boxVar: /([a-zA-Z][۱۲۳۴۵۶۷۸۹۰]+) *\=/g,
    		url: /\/\/.*?(?=[\s\n\|\}\]<]|$)/gi,	 // بدون https?: هم ممکن است
    		mediawikiFunctions: /\{\{\#(?:\{\{.*?\}\}|[^\}])*\}\}/gi,
    		articleTitleParts: new RegExp('\\s' + mw.config.get('wgTitle').split(' ').join('\\s|\\s') + '\\s', 'g'),
    		catgories:/\[\[(?:رده|[Cc]ategory)\:[^\]]+\]\]/gi
    	};
    
    	function escapeRE( s ) {
    		return s.replace( /([$()*+\-.?[\\\]^{|}])/g, '\\$1' );
    	}
    
    	function descendingFromComparetor(x, y) {
    		return x.from - y.from;
    	}
    	function removeCheckDict(text){
    		// رفع مشکل [[Special:Permalink/25174868#متن هایلایت‌شده]]
    		var otext = ''
    		while (otext!=text){
    			otext = text
    			text=text.replace(/\<span[^>]+CheckDictation\-marked[^>]+\>([^<>]+)\<\/span\>/g, '$1')
    		}
    		return text
    	}
    	function replaceExcept(text, callback, excepts) {
    		var match, result = [], i, ranges, minRange, to, min, max;
    		while (text !== '') {
    			ranges = [];
    
    			for (i in excepts) {
    				if (excepts.hasOwnProperty(i)) {
    					// a global regex should be reset before calls
    					excepts[i].lastIndex = 0;
    					match = excepts[i].exec(text);
    					if (match !== null) {
    						ranges.push({
    							from: match.index,
    							to: match.index + match[0].length
    						});
    					}
    				}
    			}
    
    			// so nothing is matched
    			if (ranges.length === 0) {
    				result.push(callback(text));
    				break;
    			}
    
    			minRange = ranges.sort(descendingFromComparetor)[0];
    			min = minRange.from;
    
    			to = [];
    			for (i in ranges) {
    				if (ranges.hasOwnProperty(i)) {
    					if (ranges[i].from <= minRange.to) {
    						to.push(ranges[i].to);
    					}
    				}
    			}
    			max = Math.max.apply(null, to);
    
    			result.push(callback(text.substr(0, min)));
    			result.push(text.substr(min, max - min));
    			// console.log('Excepted: "' + text.substr(min, max - min) + '"');
    			text = text.substr(max);
    		}
    		return result.join('');
    	}
    
    	function wikiConvertToPersianCharacters(text) {
    		return replaceExcept(
    			text,
    			persianTools.toStandardPersianCharacters,
    			[patterns.globalExceptionTag, patterns.otherLanguagesInline, patterns.arabicTagEnclosed, patterns.fileNames, patterns.signatures, patterns.url]
    		);
    	}
    
    	if (!String.prototype.trim) { // if is not available currently
    		String.prototype.trim = function () {
    			return this.replace(/^\s+|\s+$/g, '');
    		};
    	}
    
    	function autoFormatCleanReferences ( str ) {
    		// تمیزکاری autoFormater.js > cleanReferences
    		str = str.replace(
    			/<\s*references\s*(\s\b[^<>]*?)?\s*(?:\/|>\s*<\s*\/\s*references)\s*>/gi,
    			'<references$1/>'
    		);
    		if (mw.config.get('wgNamespaceNumber') === 0){
    			//ویکی‌پدیای فارسی منبع برای ارجاع نیست  
    			str = str.replace(/\<ref[^>]*\>\[?(?:https?:)?\/\/fa.(?:m\.)?wikipedia.org\/[^\<\n\}\]\[]+\]?\<\/ref\>/gi, '')
    		};
    		str = str.replace( /<\s*references\s*(\s\b[^<\/>]*?)?\s*>/gi, '<references$1>' );
    		str = str.replace( /<\s*\/\s*references\s*>/gi, '<\/references>' );
    		var re = /(<references[^<\/>]*)>/g, m;
    		while ( m = re.exec( str ) ) {
    			if ( str.indexOf( '<\/references>', m.index ) < 0 ) {
    				str = str.slice( 0, m.index ) + m[1] + '/>' + str.slice( m.index + m[0].length );
    			}
    		}
    		str = str.replace( /< *ref\s*(\s\b[^<>]*?)\s*(?:\/+|>\s*<\s*\/+\s*ref) *>/gi, '<ref$1/>' );
    
    		/* remove line breaks with assays only the top of the article */
    		var i = str.indexOf( '<references' ),
    			slice;
    		if ( i > 0 ) {
    			slice = str.slice( i );
    			slice = slice.replace( /< *ref\s*(\s\b[^<\/>]*?)?\s*>[\t ]*/gi, '<ref$1>' );
    			slice = slice.replace( /(?:(\n[\t ]*)|[\t ]*)<\s*\/+\s*ref\s*>/gi, '$1<\/ref>' );
    			str = str.slice( 0, i );
    		}
    		str = str.replace( /< *ref\s*(\s\b[^<\/>]*?)?\s*>\s*/gi, '<ref$1>' );
    		str = str.replace( /\s*<\s*\/+\s*ref\s*>/gi, '<\/ref>' );
    		if ( slice ) {
    			str += slice;
    		}
    
    		/* Space between the end of block and remove <ref> or two <ref> */
    		str = str.replace( /([!,.;?]|<ref\b[^<>]*(?:\/|>[^<>]*<\/ref)>) +(?=<ref[ >])/gi, '$1' );
    		/* Two identical punctuation before and cut after a <ref> on one */
    		str = str.replace( /([!,.:;?])(<ref\b[^<>]*(?:\/|>[^<>]*<\/ref)>)\1/gi, '$1$2' );
    		/* ref inside small */
    		return str.replace( /\<small\> *(\<ref[^\<]+\<\/ref\>)<\/small\>/gi, '$1' );
    	}
    
    	function autoFormatCleanTags(str) {
    		str = str.replace( /(<\/?s)trike\b/gi, '$1' );
    		str = str.replace(
    			/\<u\>([^\<]+)\<\/u\>/gi,
    			"''$1''"
    		);
    		str = str.replace(
    			/\<center\>/gi,
    			"{{وسط‌چین}}"
    		);
    		str = str.replace(
    			/\<\/center\>/gi,
    			"{{پایان}}"
    		);
    		str = str.replace(
    			/<sub\s*(>[^<>]*<)\s*(?:su[bp]\s*[.\/\\]+|[.\/\\]+\s*su[bp])\s*>/gi,
    			'<sub$1/sub>'
    		);
    		str = str.replace(
    			/<sup\s*(>[^<>]*<)\s*(?:su[bp]\s*[.\/\\]+|[.\/\\]+\s*su[bp])\s*>/gi,
    			'<sup$1/sup>'
    		);
    
    		/* Drop default font attributes */
    		str = str.replace(
    			/(<font\b[^<>]*?)\s+fa\w+(?:[\s"',=]*(?:Arial|Helvetica(?:\W?N\w*)?|sans\W?serif)\b)+[\s"';]*(?=\s\w+\s*=|>)/gi,
    			'$1'
    		);
    		str = str.replace(
    			/(<font\b[^<>]*?)\s+size[\s"',=]*(?:-1\b|2\b|100\b[ ,.]*\d*%|1(?:\.0*)?em\b)["';]*/gi,
    			'$1'
    		);
    		/* Remove inline elements with no attributes */
    		while ( /<(font|span)\s*>\s*(?:<(?!\1)|[^<])*?\s*<\/\1[^<>]*>/i.test( str ) ) {
    			str = str.replace( /<(font|span)\s*>[ \n]*((?:<(?!\1)|[^<])*?)[ \n]*<\/\1[^<>]*>/gi, '$2' );
    		}
    		str = str.replace(
    			/<font\s+color[\s"',=]*(#[\dA-F]{3,6}|[a-z]{3,20})[\s"';]*>((?:<(?!font)|[^<])*?)<\/font[^<>]*>/gi,
    			'<span style="color:$1;">$2<\/span>'
    		);
    		str = str.replace(
    			/<font\s+size[\s"',=]*(?:-[2-9]|[01])[\s"';]*>((?:<(?!font)|[^<])*?)<\/font[^<>]*>/gi,
    			'<small>$1<\/small>'
    		);
    		str = str.replace(
    			/<font\s+size[\s"',=]*(?:[+-]0|3)[\s"';]*>((?:<(?!font)|[^<])*?)<\/font[^<>]*>/gi,
    			'<span style="font-size:larger;">$1<\/span>'
    		);
    		/* Merge nested inline tags */
    		str = str.replace(
    			/<(abbr|cite|mark|q|s|small|u)\s*><(font|span)\s+style\s*=\s*["']?([^\n"<>]*?);?["']?\s*>([^<>]*)<\/\2\s*>\s*(?=<\/\1\s*>)/gi,
    			'<$1 style="$3;">$4'
    		);
    		str = str.replace(
    			/(<span\b[^<>]*?)\s+style\s*=\s*["']?([^\n"<>]*?);?["']?\s*><span\s+style\s*=\s*["']?([^\n"<>]*?);?["']?\s*>([^<>]*)<\/span\s*>\s*(?=<\/span\s*>)/gi,
    			'$1 style="$2; $3;">$4'
    		);
    
    		/* Verschiedenste Formen von HTML-Zeilenumbrüchen durch einheitliche ersetzen */
    		str = str.replace( /<(?:[\s\/\\]*br\b)+\s*(\s\w[^<>]*?)?[\s.\/\\]*>/gi, '<br$1/>' );
    		/* Unnötige HTML-Zeilenumbrüche entfernen, wenn sowieso ein Absatz folgt */
    		str = str.replace( / *(?:{{سخ}}|<br \/>)(?=[\r\n][\n#*:;\|}\]])/gi, '' );
    		str = str.replace(
    			/<(ref|small|su[bp])\b\s*(\s\w[^<>]*?)?\s*><small\s*>([^<>]*)<\/small\s*><\/\1\s*>/gi,
    			'<$1$2>$3<\/$1>'
    		);
    		str = str.replace(
    			/<small\s*><(ref|small|su[bp])\b\s*(\s\w[^<>]*?)?\s*?( ?\/|>[^<>]*<\/\1)\s*><\/small\s*>/gi,
    			'<$1$2$3>'
    		);
    		/* Drop old navigation bar wrapper, see [[Template:NaviBlock]] */
    		return str.replace(
    			/<div\s+class[^<>\w]*BoxenVerschmelzen[^<>\w]*>\s*(\{\{[^#:<>{}]*\}\})\s*<\/div>/gi,
    			'$1'
    		);
    	}
    
    	function autoFormatCleanDuplicateLinks(str) {
    		/* Exclude files and infoboxes from the start of the article */
    		var m = /^(?:\s*\[\[\w+:(?:\[\[[^\n\]]*\]\]|[^\n\]])*\]\])*(?:\s*\{\{(?:\{\{[^}]*\}\}|[^}])*\}\})+/.exec( str ),
    			start = m ? m[0].length : 0,
    			found = [],
    			a = [];
    		/* Unlink years that are linked more than one time */
    		var re = /\[\[ *([۱۲][۱۲۳۴۵۶۷۸۹۰]{3}|[۱۲][۱۲۳۴۵۶۷۸۹۰]{3} \((میلادی|قمری)\)) *\]\]/g;
    		/* In each case the first discovery of a year noted entlinken thereafter */
    		while ( m = re.exec( str ) ) {
    			if ( m.index >= start ) {
    				found[m[1]] ? a.push( m ) : found[m[1]] = true;
    			}
    		}
    		var r = '',
    			p = 0;
    		for ( var i = 0; i < a.length; i++ ) {
    			r += str.slice( p, a[i].index ) + a[i][1];
    			p = a[i].index + a[i][0].length;
    		}
    		return p ? r + str.slice( p ) : str;
    	}
    
    	function autoFormatCleanDates(str){
    		var months = ["ژانویه", "فوریه", "مارس", "آوریل", "مه", "ژوئن", "ژوئیه", "اوت", "سپتامبر", "اکتبر", "نوامبر", "دسامبر", 'فروردین', 'اردیبهشت', 'خرداد', 'تیر',
    			'مرداد', 'شهریور', 'مهر', 'آبان', 'آذر', 'دی', 'بهمن', 'اسفند',"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
    
    		/* Add missing space between day and month */
    		str = str.replace( new RegExp( '([\\s!\'(>|„](?:3[01]|[12]\\d|0?[1-9])\\.?)(?=(?:' +
    			months.join( '|' ) + ')\\b)', 'g' ), '$1 ' );
    		/* No non-breaking space between month and year */
    		str = str.replace( new RegExp( '(\\b(?:3[01]|[12]\\d|0?[1-9])\\.?(?:[\\s\\xA0]|&nbsp;)+(?:' +
    			months.join( '|' ) + '))(?:\xA0|&nbsp;)(?=[12]\\d{3}\\b)', 'g' ), '$1 ' );
    		/* Missverständliches deutsches Datumsformat durch Langform ersetzen */
    		var separator= ' ';
    		str = str.replace(
    			/([\s'(>„])(3[01]|[12]\d|0?[1-9])\. *(1[012]|0?[1-9])\. *(?=[12]\d{3}[!,.:;?]?[\s')<\]“])/g,
    			function( $0, $1, $2, $3 ) {
    				return $1 + ( $2 | 0 ) + separator + months[$3 | 0] + ' ';
    			}
    		);
    		// عدد فارسی
    		str = str.replace( new RegExp( '([\\s!\'(>|„](?:۳[۰۱]|[۱۲][۱۲۳۴۵۶۷۸۹]|۰?[۱۲۳۴۵۶۷۸۹])\\.?)(?=(?:' +
    			months.join( '|' ) + ')[\\s\')<\\]»}|])', 'g' ), '$1 ' );
    		/* No non-breaking space between month and year */
    		str = str.replace( new RegExp( '([\\s\'(>«](?:۳[۰۱]|[۱۲][۱۲۳۴۵۶۷۸۹]|۰?[۱۲۳۴۵۶۷۸۹])\\.?(?:[\\s\\xA0]|&nbsp;)+(?:' +
    			months.join( '|' ) + '))(?:\xA0|&nbsp;)(?=[۱۲][۱۲۳۴۵۶۷۸۹]{3}[\\s\')<\\]»}|])', 'g' ), '$1 ' );
    		/* Missverständliches deutsches Datumsformat durch Langform ersetzen */
    		var separator= ' ';
    		str = str.replace(
    			/([\s'(>«])(۳[۰۱]|[۱۲][۱۲۳۴۵۶۷۸۹]|۰?[۱۲۳۴۵۶۷۸۹])\. *(۱[۰۱۲]|۰?[۱۲۳۴۵۶۷۸۹])\. *(?=[۱۲][۱۲۳۴۵۶۷۸۹]{3}[!,.:;?]?[\s')<\]»}|])/g,
    			function( $0, $1, $2, $3 ) {
    				return $1 + ( $2 | 0 ) + separator + months[$3 | 0] + ' ';
    			}
    		);
    		return str
    	}
    
    	function quotation(text) {
    		// این تابع زمانی گیومه را به فارسی تیدیل می‌کند که در پاراگراف مورد نظر تعداد گیومهٔ لاتین زوج باشد.
    		var lines = text.split(/\n\n/);
    		var result = [];
    		for (var i = 0; i < lines.length; ++i) {
    			var line = lines[i];
    			if ((line.match(/"/g) || []).length % 2 === 0) { // count of quote marks
    				// تبدیل گیومهٔ لاتین به فارسی
    				// این دستور در ابتدا باشد تا فاصله‌های قبل و بعد گیومه هم اصلاح شود
    				line = line.replace(
    					new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.\\)]+)"((?:\\[\\[|).*?[' + persianTools.persianCharacters + '؛\\n،]+?(?:\\]\\]|\\.|\\<|\\:|…|))"([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{\\(]|$)', 'g'),
    					'$1«$2»$3'
    				);
    				// if some of quote marks are remained from conversion, something might wrong, revert
    				var testline=line.replace(/(?:<ref[^\/]*?>[\s\S]*?<\/ref>|<ref[^\/]*?\/>)/g,'')
    
    				if (testline.match(/"/g)) {
    					line = lines[i];
    				}
    			}
    			// رفع مشکل استفاده از ـً به جای گیومه لاتین در متن فارسی
    			line=line.replace(new RegExp('ا\\"([ ]*[' +persianTools.persianCharacters + '])', 'g'), 'اً$1')
    			line=line.replace(new RegExp('ا\\”([ ]*[' +persianTools.persianCharacters + '])', 'g'), 'اً$1')
    			// ”“ تبدیل 
    			line = line.replace(
    				new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.]+)“((?:\\[\\[|).*?[' + persianTools.persianCharacters + '\\n]+?(?:\\]\\]|\\.|\\<|\\:|\\{|\\[|…|))”([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{]|$)', 'g'),
    				'$1«$2»$3'
    			);
    			//وارونه ”“ تبدیل 
    			line = line.replace(
    				new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.]+)”((?:\\[\\[|).*?[' + persianTools.persianCharacters + '\\n]+?(?:\\]\\]|\\.|\\<|\\:|\\{|\\[|…|))“([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{]|$)', 'g'),
    				'$1«$2»$3'
    			);
    			// ‘’ تبدیل 
    			line = line.replace(
    				new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.]+)‘((?:\\[\\[|).*?[' + persianTools.persianCharacters + '\\n]+?(?:\\]\\]|\\.|\\<|\\:|\\{|\\[|…|))’([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{]|$)', 'g'),
    				'$1«$2»$3'
    			);
    			//وارونه ‘’ تبدیل 
    			line = line.replace(
    				new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.]+)’((?:\\[\\[|).*?[' + persianTools.persianCharacters + '\\n]+?(?:\\]\\]|\\.|\\<|\\:|\\{|\\[|…|))‘([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{]|$)', 'g'),
    				'$1«$2»$3'
    			);
    			// ‚’ تبدیل 
    			line = line.replace(
    				new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.]+)‚((?:\\[\\[|).*?[' + persianTools.persianCharacters + '\\n]+?(?:\\]\\]|\\.|\\<|\\:|\\{|\\[|…|))’([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{]|$)', 'g'),
    				'$1«$2»$3'
    			);
    			// „” تبدیل 
    			line = line.replace(
    				new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.]+)„((?:\\[\\[|).*?[' + persianTools.persianCharacters + '\\n]+?(?:\\]\\]|\\.|\\<|\\:|\\{|\\[|…|))”([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{]|$)', 'g'),
    				'$1«$2»$3'
    			);
    			// << >> تبدیل 
    			line = line.replace(
    				new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.]+)\\<\\<((?:\\[\\[|).*?[' + persianTools.persianCharacters + '\\n]+?(?:\\]\\]|\\.|\\<|\\:|\\{|\\[|…|))\\>\\>([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{]|$)', 'g'),
    				'$1«$2»$3'
    			);
    			// (()) تبدیل 
    			line = line.replace(
    				new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.]+)\\(\\(((?:\\[\\[|).*?[' + persianTools.persianCharacters + '\\n]+?(?:\\]\\]|\\.|\\<|\\:|\\{|\\[|…|))\\)\\)([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{]|$)', 'g'),
    				'$1«$2»$3'
    			);
    			result.push(line);
    		}
    		return result.join('\n\n');
    	}
    	/**
    	 * افزودن ستون به الگوی پانویس
    	 * @param {string} text محتوا
    	*/
    	 function addColumnToRefTemplate(text) {
    	/*	var refTemplate = /\{\{پانویس([^\}\{]+)?\}\}/i.exec(text), needChange = false;
    		if (refTemplate) {
    			if ((text.match(/<ref/gi) || []).length >= 6) {
    				if (refTemplate[1] !== undefined) {
    					var refParams = refTemplate[1].split('|');
    					for (var i = refParams.length - 1; i >= 0; i--) {
    						// اگر از پیش ستون یا پارامتر عرض تعریف شده‌باشد تغییری ایجاد نمی‌شود.
    						if (refParams[i].length == 1 || refParams[i].indexOf('عرض') > -1) {
    							needChange = true;
    							break;
    						}
    					}
    				}
    				if (refTemplate[1] === undefined || !needChange) {
    					return text.replace(refTemplate[0], refTemplate[0].replace('}}', '|۲}}'));
    				}
    			}
    		}else{
    			if ((mw.config.get('wgNamespaceNumber') === 0 && mw.config.get("wgEditMessage")==='editing')||mw.config.get('wgPageName') ==="ویکی‌پدیا:ویکی‌پروژه_ابزارها/آزمایش_واحد") {
    				if ((text.match(/<ref/gi) || []).length > 0 &&  /\{\{پانویس([^\}\{]+)?\}\}/i.exec(text) !=null) {
    					var text2 = text.replace ('== منابع ==','== منابع ==\n{{پانویس}}')
    					if (text2==text){
    						text2 = text.replace ('== پانویس ==','== پانویس ==\n{{پانویس}}')
    					}
    					if (text2==text){
    						text2 = text.replace ('[[رده:','== منابع ==\n{{پانویس}}\n\n[[رده:')
    					}
    					if (text2==text){
    						text2 = text + '\n== منابع ==\n{{پانویس}}'
    					}
    					text=text2
    				}
    			}
    		}*/
    		return text;
    	}
    	/**
    	 * اصلاح پیوندها
    	 * @param  {string} text محتوا
    	 * @return {string}
    	 */
    	function fixBadLinks(text) {
    		// حذف متن جایگزین پیوند اگر با نشانی پیوند برابر باشد؛ مانند [[سلام|سلام]]
    		text = text.replace(/\[{2}([^\|]+)\|\1\]{2}/gi, '[[$1]]');
    
    		// حذف پیوند سال و روز ماه
    		text = text.replace(/\[{2}([۰-۹]+|[۰-۹]+ [\)\(\u0621-\u0655\u067E\u0686\u0698\u06AF\u06A9\u0643\u06AA\uFED9\uFEDA\u06CC\uFEF1\uFEF2]+)(?:\|([^\]\|\[]+))?\]{2}/g, function (match, p1, p2) {
    		// اگر فقط سال پیوند شده‌باشد یا به شکل [[سال|همان سال]] باشد فقط سال را می‌گرداند.
    		if (p1 !== p2 && p1.replace(/ \((میلادی|قمری|خورشیدی|شمسی|پیش از میلاد|قبل از میلاد)\)/g,'') === p2){
    			return p2;
    		}//[[Special:Permalink/19908981#حذف پیوند تاریخ‌ها]]
    		if (p2 === undefined || p1 === p2) {
    			// اگر پیوند به روز و ماه بود، برای جلوگیری از اشتباه و تداخل، بررسی می‌شوند که حتما یکی از ماه‌ها داخل رشته باشد.
    			if (p1.indexOf(" ") > -1) {
    				var
    					months = ["فروردین", "اردیبهشت", "خرداد", "تیر", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی", "بهمن", "اسفند",
    	"ژانویه", "فوریه", "مارس", "آوریل", "مه", "ژوئن", "ژوئیه", "اوت", "سپتامبر", "اکتبر", "نوامبر", "دسامبر",
    	"محرم", "صفر", "ربیع‌الاول", "ربیع‌الثانی", "جمادی‌الاول", "جمادی‌الثانی", "رجب", "شعبان", "رمضان", "شوال", "ذیقعده", "ذیحجه"],
    					i;
    				for (i = months.length - 1; i >= 0; i--) {
    					if (p1.indexOf(months[i]) > -1) {
    						return p1.replace(/ \((میلادی|قمری|خورشیدی|شمسی|پیش از میلاد|قبل از میلاد)\)/g,'');
    					}
    				}
    				return "[[" + p1 + "]]";
    			}
    			return p1;
    		}
    		// اگر متن جایگزین پیوند مخالف پیوند سال بود، متن جایگزین را برمی‌گرداند.
    		return p2;
    	});
    
    	return text;
    }
    
    	function wikiPunctuation(text) {
    		text = autoFormatCleanReferences (text)
    		text = autoFormatCleanTags(text)
    		text = autoFormatCleanDuplicateLinks(text)
    		text = replaceExcept(
    			text,
    			function (text) {
    				return quotation(text);
    			},
    			[patterns.ref]
    		);
    		if (mw.config.get('wgNamespaceNumber') === 0){
    			var old_text=text.replace(/\=\=/g, '')
    			if (old_text==text){//در صورتی که در مقاله بخش‌بندی وجود نداشته باشد
    				text=text.replace(/(\n\{\{سخ\}\}|\n\n)(\s|_|)\'\'\'(.*?)\'\'\'(\s|_|)(\{\{سخ\}\}|\n)([\n\#\*])/g, '\n\n== $3 ==\n$6')
    			}
    		}
    		text = replaceExcept(
    			text,
    			function (text) {
    				text = text.replace(
    					new RegExp('([' + persianTools.persianCharactersNoVowels + '])ـ+([' + persianTools.persianCharactersNoVowels + '])', 'g'),
    					'$1$2'
    				);
    				return text.replace(new RegExp('([' + persianTools.persianCharacters + '])(\\]\\]|), (\\[\\[|)?(?=[' + persianTools.persianCharacters + "])", 'g'), '$1$2، $3');
    			},
    			[patterns.globalExceptionTag, patterns.fileNames, patterns.url, patterns.galleryTag, patterns.sourceTag, patterns.translatedUrl, patterns.parenthesesHa]
    		);
    		text = replaceExcept(
    			text,
    			function (text) {
    				return text.replace(/(<\/ref>)\s+(<ref)/g, '$1$2').replace(/([^=])\s+<ref(?!erences)/g, '$1<ref');
    			},
    			[/\{\{(پانویس|پانویس‌ها|پی‌نوشت)\s*\|[\s\S]*/]
    		);
    		return replaceExcept(
    			text,
    			function (text) {
    				return persianTools.punctuation(text)
    					.replace(/^([*#]+)([^*#\:\s])/mg, '$1 $2') // Adds a space after the # or * for lists
    					.replace(/^([*#]+) {2,}([^*#\:\s])/mg, '$1 $2'); // Trim more that one space after the # or * for lists
    			},
    			[patterns.globalExceptionTag, patterns.mathTag, patterns.fileNames, patterns.url, patterns.wikilinkTargets,
    				patterns.galleryTag, patterns.sourceTag, patterns.translatedUrl, patterns.parenthesesHa]
    		)
    			.replace(/\u00A0/g, ' ') // convert implicit nbsp to space, probably is being added by some bug on ContentTranslation
    			.replace(/٬ /g, '، ')
    			.replace(new RegExp('([' + persianTools.persianCharacters + '\]])٬', 'g'), '$1،')
    			.replace(new RegExp('([' + persianTools.persianCharacters + '])(\]\]|»|)[ ]*[,]', 'g'), '$1$2، ')
    			.replace(/\[\[([^\|\]]+)\|(\'{2,3})\1'{2,3}\]\]/g,'$2[[$1]]$2') // for [[foo|'''foo''']] > '''[[foo]]'''
    			.replace(new RegExp('\\[\\[(' + escapeRE(mw.config.get('wgPageName')) + ')\\]\\]', 'g'), '$1') // پیوندزدایی از خود صفحه
    			//برگرفته از https://tools.wmflabs.org/checkwiki/cgi-bin/checkwikin.cgi?project=fawiki&view=project
    			.replace(/\[\[([^\|\]]+)\|\1([\u200c ]*(های?))\]\]/g, '[[$1]]$2')//[[Special:Diff/17515365/17865938]]
    			.replace(/([\S]*)[\s\u200c]*-[\s\u200c]*(تاکنون)(?![ ]+)/g, '$1-اکنون')//[[Special:Diff/17515365/17865938]]
    			//مشکل در نشانی اینترنتی
    			.replace(/(\<ref.*?\>) *(\[|)\www(6|3|)\./gi, '$1$2http://www$3.')
    			.replace(/\[\[ *(https?\:\/\/.*?) *\]\]/g, '[$1]')
    			.replace(/\[\[ *(\/\/.*?) *\]\]/g, '[$1]')
    			.replace(/(https?:\/?\/?){2,}/g, '$1')
    			// تمیزکاری autoFormatter.js > cleanExternalLinks
    			.replace(/\b(?:http(s?)(?::+\/*|\/\/+:*)\b)+/gi, 'http$1://')
    			// repair links with vertical stroke
    			.replace(/(\[https?:\/\/[^\s[\]|]*?) *\| *(?=[^\s=[\]|]+\])/gi, '$1 ')
    			// supplement slashes at the end easier Domains
    			.replace(/(\[https?:\/\/\w[\w.-]*\w\.\w+) +/gi, '$1/ ')
    			// Domains lowercase, whether labeled or not
    			.replace(/\bhttps?:\/\/\b[0-9a-z.-]*[A-Z][\w.-]*/g, function ($0) {
    				return $0.toLowerCase();
    			})
    			// پیوند به بیرون‌هایی که در میان پیوند نویسهٔ رفتن به خط بعد، وجود داشته باشد
    			.replace(/\[(?:https?\:|)\/\/[^\]\[]+\]/g, function (x) {
    				x = x.replace(/[\n\r]/g,'');
    				return x
    			})
    			// فاصله اول زیربخش
    			.replace(/پیوند\n\=/,'پیوند=')// [[Special:Diff/20238012/20244702]]
    			.replace(/^ +(\=+[^\=]+\=+)/mg, '$1')
    			.replace(/\[\[\|/g, '[[')
    			.replace(/(\< *\/ *br *\>|\< *br *\\ *\>|\< *br *\. *\>)/g, '<br/>')
    			.replace(/(\<br *\/\>|\{\{سخ\}\})([\r\n])(\*|\#|\=\=)/g, '$2$3')
    			.replace(/(\<br *\/\>|\{\{سخ\}\}) *\]\]/g, ']]')
    			.replace(/\[\[ *(\<br *\/\>|\{\{سخ\}\})/g, '[[')
    			.replace(/(\< *span *\/ *\>|\< *\/ *span *\/ *\>)/gi, '</span>')
    			.replace(/(\< *center *\/ *\>|\< *\/ *center *\/ *\>)/gi, '</center>')
    			.replace(/(\< *b *\/ *\>|\< *\/ *b *\/ *\>)/gi, '</b>')
    			.replace(/(\< *div *\/ *\>|\< *\/ *div *\/ *\>)/gi, '</div>')
    			.replace(/(\< *p *\/ *\>|\< *\/ *p *\/ *\>)/gi, '</p>')
    			.replace(/(\< *td *\/ *\>|\< *\/ *td *\/ *\>)/gi, '</td>')
    			.replace(/(\< *small *\/ *\>|\< *\/ *small *\/ *\>)/gi, '</small>')
    			.replace(/\[\[([^\]]+)\{\{\!\}\}([^\]]+)\]\]/g, '[[$1|$2]]')//وجود {{!}} درون پیوند
    			.replace(/\[{2}([^\|]+)\|\1\]{2}/gi, '[[$1]]')//زمانی که بخش هدف و نمایه پیوند یکی باشند
    			.replace(/\[\[(.+)\|('+)(.+\b)('+)\]\]/gi, '$2[[$1|$3]]$4')// انتقال ''' به بیرون پیوند
    			// تمیزکاری autoFormatter.js > CleanGalleries
    			.replace(/<gallery\b([^<>]*)>([^<>]+)<\/gallery\b[^<>]*>/gi,
    				function( $0, $1, $2 ) {
    					return '<gallery' + $1 + '>' + $2
    						.replace( /^(\s*)\[+([^[\]]*)\]\]?\s*$/gm, '$1$2' )
    						.replace( /^(\s*)\[+/gm, '$1' ) + '<\/gallery>';
    				}
    			)
    			// تمیزکاری پرونده‌ها
    			// زمانی که برچسب کوچک در توضیحات تصویر می‌آید برای دستگاه‌های با مانیتور کوچک خواندن متن مشکل می‌شود
    			//https://tools.wmflabs.org/checkwiki/cgi-bin/checkwiki.cgi?project=fawiki&view=only&id=77
    			.replace(/\[\[(پرونده|[Ff]ile)\:((?:\[\[.*?\]\]|[^\]])*)\]\]/g, function ($0, $1, $2) {
    				$2 = $2.replace(/\<\/?(big|center|small)>/g,'');
    				return '[['+$1+':'+$2+']]'
    			})
    			.replace( /\[\[ *تصو[يی]ر\:/gi, '[[پرونده:' )
    			// تمیزکاری الگو autoFormater.js > cleanTemplates
    			.replace( /\{\{\s*:?\s*(?:الگو|Template)\s*:\s*/gi, '{\{' )
    			// حذف خط زیر از عنوان الگو
    			.replace(/(?:^|[^{])\{\{[ 0-9a-z\xC0-\u024F-]*_[ \w\xC0-\u024F-]*/gi,
    				function( $0 ) {
    					return $0.replace( /_+$/, '' ).replace( /[ _]+/g, ' ' ).replace( /\{ +/, '{' );
    				}
    			)
    			//سایر موارد
    			.replace(/\[\[(رده|الگو|ویکی\u200cپدیا)\: +/g, '[[$1:')
    			.replace(/\{\{\*\}\}/g, '{{•}}')
    			.replace(/[\n\s]*\{\{[•·ن](w?)\}\}\s*/g, '{{•$1}} ')
    			.replace(/\=\{\{[•·ن](w?)\}\}\s*/g, '=\n{{•$1}} ')//رفع باگ [[Special:Diff/14799178/16387261]] در خط بالا 
    			.replace(/ *(<\/? ?br ?\/?>|\{\{بر\}\}) */g, '{{سخ}}')
    			.replace(/\{\{سخ\}\}\n\n/g, '\n\n')
    			.replace(/\n\n\{\{سخ\}\}/g, '\n\n')
    			.replace(/\{\{سخ\}\}\]/g, ']')
    			.replace(/\[\{\{سخ\}\}/g, '[')
    			.replace(/\n\n(\*|\#)/g,'\n$1')
    			.replace(/\n(\#|\*)( |)\n/g,'\n$1')
    			.replace(/\n(\*|\#)( |)(\={2,})/g,'\n$3')
    			.replace(/(\n?)\s+?<\/ref>/g, '$1</ref>')
    			.replace(/\{ *\|/g, '{|')
    			.replace(/\| *\}/g, '|}')
    			.replace(/\{\| *\{\|/g, '{|')
    			.replace(/\|\} *\|\}/g, '|}')
    			.replace( /^=.*&nbsp;.*=$/gim, function( $0 ) {
    						return $0.replace( /(?:&nbsp;|\s)+/gi, ' ' );
    			})
    			.replace(/([^=])\n+(\=.*?\=\n+)/g, '$1\n\n$2')
    			.replace(/^(=+([^=].*?)=+)[\t\s]{1,}\n/g, '$1\n')
    			.replace(/^(\={2,}) +[\:,;>&\^#@•→←↔↑↓—–…~٫،؛ٔ]/mg, '$1') // Cleanup headers
    			.replace(/[\:,;<&\^#@•→←↔↑↓—–…~٫،؛ٔ] +(\={2,})$/mg, '$1')
    			.replace(/^(\={2,}\s*)(«)([^\n«»]*?)(»)(\s*\={2,})/mg, '$1 $3 $5')
    			.replace(/^(\={2,}) *'+(.*?)'+ *(\={2,})/mg, '$1 $2 $3')
    			.replace(/^[•●⚫⬤]/mg, '*') // Wikify bullets in start of lines
    			.replace(/^#\s*(REDIRECT|تغییر[ _]?مسیر)/gi, '#تغییرمسیر')
    			.replace(/^#تغییرمسیر(?=\S)/g, '#تغییرمسیر ') // Adds a space after #REDIRECT
    			.replace(/(\={2,}) *([^\n\r]*?) *(\={2,})/g, '$1 $2 $3') // Format headings level 2 and above
    			// زیربخش نیازی به برچسب بزرگ و کوچک ندارد
    			.replace(/(\=+) \<(?:small|big)\>([^\=\n\r]+)\<\/(?:small|big)\> (\=+)/g, '$1 $2 $3') 
    			// فاصله‌های اضافی را از داخل پیوند به بیرون منتقل کند تا اگر اضافه بودند در کدهای دیگر حذف شوند
    			.replace(/\[\[(\s*)(.*?)(\s*)\]\]/g, '$1[[$2]]$3')
    			//حذف فاصلهٔ اضافی درون {{}}
    			.replace(/\{\{(\s*)(.*?)(\s*)\}\}/g, '{{$2}}')
    			// تبدیل به نویسه / یکی کردن فاصله های مجازی پشت سرهم
    			.replace(/(\{\{فم\}\}|\&zwnj\;|\u200c+)/g, '\u200c')
    			// Full stop and comma should be before citation. See en:WP:REFPUNC
    			.replace(/ *((?:<ref[^\/]*?>.*?<\/ref>)+)([\.،,:])?/g, '$2$1')
    			.replace(/([^.])([\.،,:]){2}((?:<ref[^\/]*?>.*?<\/ref>)+)/g, '$1$2$3')
    			.replace(/ *((?:<ref[^\/]*?\/>)+)([\.،,:])/g, '$2$1')
    			.replace(/([^.])([\.،,:]){2}(((?:<ref[^\/]*?\/>)+)+)/g, '$1$2$3')
    			/* هر رده در یک خط */
    			.replace( /([^\s>-]) *(\[\[رده:[^\n[\]]*\]\])/gi, '$1\n$2' )
    			.replace( /(\[\[رده:[^\n[\]]*\]\]) *(?![\s<-]|$)/gi, '$1\n' )
    			.replace( /(\[\[رده:[^\n[\]]*\]\]\n) *(?!\[\[رده:|[\s<-]|$)/gi,'$1\n')
    			//ترتیب‌پیش‌فرض
    			.replace(/\{\{(?:DEFAULTSORT|[Dd]efaultsort|ترتیب|ترتیب[‌ ]پیش[‌ ]?فرض) *[|:] *(?=.*?}})/g, '{{ترتیب‌پیش‌فرض:')
    			.replace(/\{\{(ترتیب‌پیش‌فرض|DEFAULTSORT)\:[-\w,\s\(\)]+\}\}\n?/g, '')
    			.replace(/(\{\{(?:ترتیب‌پیش‌فرض|DEFAULT\w*SORT\w*):[^\n{}]*\}\})\s*(?=\[\[رده:)/gi,'$1\n')
    			.replace(/(\{\{ترتیب‌پیش‌فرض\:)\s/g, '$1')
    			.replace( /(==\n)\n+(?=<references[^\n<>]*\/>\n\n)/gi, '$1' )
    			//نچسبیدن و+فاصله به براکت که محصول اشتباه در تایپ کردن است
    			.replace(/\]\]و /g, ']] و ')
    			.replace(/(\s|^)\'\'\'(\s|)(.*?)(\s|)\'\'\'(\s)/g, "$1'''$3'''$5") // حذف فاصلهٔ اضافی درون ویکی کد
    			.replace(/'''\{\{به /g, "''' {{به ")
    			.replace(/\*(\s+|\n)?\{\{پانویس/g, "{{پانویس")
    			.replace(/((?:^|\n\s)\=+\s+\=+(?:\s+|)\n)/g, "\n\n")
    			.replace(/\n{3,}/g, '\n\n')
    			.replace(/(\[{1,2})([^\[\]\n]+) +(\]{1,2})/g, "$1$2$3")
    			.replace(/(\[{1,2}) +([^\[\]\n]+)(\]{1,2})/g, "$1$2$3")
    			//تبدیل بندهای ترتیبی به قالب‌بندی ویکی [[Special:Permalink/19923598#تبدیل بندهای ترتیبی به قالب‌بندی ویکی]]
    			.replace(/(?:(?:^(?:\* ?)?[۱۲۳۴۵۶۷۸۹۰0-9]{1,2} ?[\.\-\)]) ?[^۱۲۳۴۵۶۷۸۹۰0-9\n]+\n+){2,}/gm, function (x) {
    				var x2=x.replace(/((?:\* ?)?[۱۲۳۴۵۶۷۸۹۰0-9]{1,2} ?[\.\-\)]) ?([^۱۲۳۴۵۶۷۸۹۰0-9\n]+)\n+/gm,'# $2\n')
    				if (x2.replace(/[۱۲۳۴۵۶۷۸۹۰0-9]/g, '')===x2){
    					return x2;
    				}
    				return x;
    			})
    			.trim();
    	}
    
    	function wikiSubsection(text) {
    		return text.replace(/\<(?:\s*)references?(?:\s*\/|\s*\/\s*)\>/g, '{{پانویس}}')
    			   .replace(/\{\{(?:[Rr]eflist|[Rr]eferences?|پانویس[‌ ]?ها)(?=\||\})/g, '{{پانویس')
    			   .replace(/\{\{راست(| |‌)چین\}\}\s*\{\{پانویس(.*?)\}\}\s*\{\{(پایان راست(| |‌)چین|پایان)\}\}/g, '{{پانویس$2}}')
    			   .replace(/\{\{چپ(| |‌)چین\}\}\s*\{\{پانویس(.*?)\}\}\s*\{\{(پایان چپ(| |‌)چین|پایان)\}\}/g, '{{پانویس$2|چپ‌چین=بله}}')
    			   .replace(/\<small\>\s*\{\{پانویس(.*?)\}\}\s*\<\/small\>/g, '{{پانویس$1|اندازه=کوچک}}')
    			   .replace(/(({\{پانویس.*?\}\})(\n|)){1,}/g, '$1')
    			   .replace(/\=\s*لیست\s*\=/g, '= فهرست =')
    			   .replace(/\=\s*(?:[gG]allery|نگارستان|گالری (تصویر|عکس|))\s*\=/g, '= نگارخانه =')
    			   .replace(/\=\s*(?:بیوگرافی|زندگینامه)\s*\=/g, '= زندگی‌نامه =')
    			   .replace(/\=\s*(?:[eE]xternal links|لینک‌?های بیرونی|پیوندهای خارجی|لینک‌?های خارجی|پیوندهای بیرونی)\s*\=/g, '= پیوند به بیرون =')
    			   .replace(/\=\s*(?:[nN]otes|[fF]ootnotes?|پاورقی|پاورقی‌ها|پانوشت|پانویس‌ها)\s*\=/g, '= پانویس =')
    			   .replace(/\=\s*(?:[Ss]ee [Aa]lso|همچنین ببینی[مد]|بیشتر ببینی[مد]|همچنین نگاه کنید|بیشتر بدانی[مد]|مراجعات مرتبط|جستار وابسته|مطلب مرتبط|مطالب مرتبط|جستارهای مشابه|جستارهای دیگر)\s*\=/g, '= جستارهای وابسته =')
    			   .replace(/\=\s*(?:منبع|منبع[‌ ]?ها|رفرنس|رفرنس[‌ ]?ها|ارجاع[‌ ]?ها|ارجاع|مرجع[‌ ]?ها|رفرنس|برگرفته از|مراجع|منابع و یادداشت[‌ ]?ها|منبع|مرجع|م[آا]خذ|منابع و م[آا]خذ|منابع و پانویس‌ها|فهرست مراجع|لیست مراجع|فهرست ارجاع[‌ ]?ها|فهرست ارجاع|[rR]eferences)\s*\=/g, '= منابع =')
    			   //.replace(/\=\s*(?:مطالعه بیشتر|بیشتر بخوانی[مد])\s*\=/g, '= برای مطالعهٔ بیشتر =')
    			   .replace(/^\={3,}\s*(جستارهای وابسته|پانویس|منابع)\s*\={3,}$/g, '== $1 ==');
    	}
    	function wikiUrlMinifier(text) {
    		return text
    			.replace(patterns.url, function (x) {
    				return replaceExcept(
    					x,
    					function (x) {
    						try {
    							x = decodeURI(x);
    						} catch (e) {
    							try {
    								x = decodeURIComponent(unescape(x));
    							} catch (e) {mw.notify(e); }
    						}
    						return x;
    					},
    					[patterns.globalExceptionTag, patterns.decodeUriBlacklist, patterns.refname]
    				);
    			})
    
    			// Strip the http(s) prefix
    			.replace(/\[(https?\:)(?=\/\/(?:[\w\-]+)\.(?:m\.)?(wiki(pedia|media|data|source|news|oyage|quote)|wiktionary)\.org\/[^\s\]]*)/g, '[')
    			.replace(/[\[\=](?:https?\:|)\/\/[\w\-]{2,}\.(?:m\.)?wikipedia\.org\/w(?:iki)?\/([^\n?]*?)[\]\|]/g, function (x) {
    				x = x.replace(/\[(?:https?\:|)\/\/([\w\-]{2,})\.(?:m\.)?wikipedia\.org\/w(?:iki)?\/(.*?) (.*?)\]/g,'[[:$1:$2|$3]]')
    				x = x.replace(/\[(?:https?\:|)\/\/([\w\-]{2,})\.(?:m\.)?wikipedia\.org\/w(?:iki)?\/(.*?)\]/g,'[[:$1:$2]]')
    				//x = x.replace(/\=(?:https?\:|)\/\/([\w\-]{2,})\.(?:m\.)?wikipedia\.org\/w(?:iki)?\/(.*?)\|/g,'=[[:$1:$2]]|') // در الگو یادکرد مشکل ایجاد می‌کند
    				x = x.replace(/\[\[\:fa\:/g,'[[').replace(/\%20/g,' ').replace(/٪۲۰/g,' ').replace(/\[\[[a-zA-Z\'0-9 ]+\|/g,'[[')
    				x = x.replace(/\[\[.*?\]\]/g, function (y) {
    					y = y.replace(/\_/g,' ')
    					return y
    				})
    				return x
    			}).replace(/\[{2}([^\|]+)\|\1\]{2}/gi, '[[$1]]');
    	}
    	function SubSectionLeveling (text) {
    		// تنظیم سطح زیربخش‌ها
    		text=text.replace(/^(\={2,}) *(.*?) *(\={2,})/mg, '$1 $2 $3')
    		if ((mw.config.get('wgNamespaceNumber') === 0 && mw.config.get("wgEditMessage")==='editing')||mw.config.get('wgPageName') ==="ویکی‌پدیا:ویکی‌پروژه_ابزارها/آزمایش_واحد") {
    			//مقاله‌ای که فقط زیربخش سطح ۱ دارد
    			if (text.replace(/\=\=/g,'')===text){
    				var text2 = text.replace(new RegExp('^\=([^\=\r\n]+)\=$', 'gm'), "== $1 ==")
    				if (text!==text2){
    					text=text2.replace(/\n\=  /g,'\n= ').replace(/  \=\n/g,' =\n')
    				};
    			};
    			//مقاله‌ای که فقط زیربخش سطح ۳ یا ۴ دارد
    			var text_test=text.replace(/^\=+ (منابع|جستارهای وابسته|پیوند به بیرون|پانویس|نگارخانه) \=+\n/gm,'')
    			if (text_test.replace(/^\=\= /gm,'')===text_test){
    				if (text_test.replace(/^\=\=\= /gm,'')!==text_test){
    					//سطح ۳
    					text = text.replace(new RegExp('^\=\=\=([^\=\r\n]+)\=\=\=$', 'gm'), "== $1 ==")
    					text = text.replace(new RegExp('^\=\=\=\=([^\=\r\n]+)\=\=\=\=$', 'gm'), "=== $1 ===")
    				} else if (text_test.replace(/^\=\=\=\= /gm,'')!==text_test) {
    					//سطح ۴
    					text = text.replace(new RegExp('^\=\=\=\=([^\=\r\n]+)\=\=\=\=$', 'gm'), "== $1 ==")
    				}else{
    					text=text.replace(/===/g,'==')
    				};
    			};
    			text=text.replace(/==  /g,'== ').replace(/  ==/g,' ==')
    		};
    		return text;
    	};
    	function decimalPointToPersian(text) {
    		//Decimal point [[Special:Permalink/25438370#جمع‌بندی_بدون_رسیدگی]]
    		return text.replace(new RegExp('([۰۱۲۳۴۵۶۷۸۹])\\.(?=[۰۱۲۳۴۵۶۷۸۹])', 'g'), '$1٫')
    	};
    	function wikiTextDigitsToPersian(text) {
    		text = replaceExcept(
    			text,
    			toEnglishDigits,
    			[patterns.argumentsBlacklist, patterns.fileNames, patterns.fileParameter]);
    		text = replaceExcept(
    			text,
    			persianTools.toPersianDigits,
    			[patterns.globalExceptionTag, patterns.url, patterns.argumentsBlacklist, patterns.mathTag, patterns.imagePixelSize, patterns.fileNames, patterns.ref,
    				patterns.sourceTag, patterns.arabicDigitsEnglishContext, patterns.signatures, patterns.htmlEntity, patterns.diffLink,
    				patterns.htmlAttributes, patterns.fileParameter, patterns.templateParameterName, patterns.ipSign,
    				patterns.parenthesesAfterDigits, patterns.otherLanguagesInline, patterns.preTag , patterns.isbn, patterns.englishDate,
    				patterns.parameter, patterns.color, patterns.templateEnglishName, patterns.linksOnEnglishContext, patterns.citation, patterns.refname,
    				patterns.LtRTagEnclosed, patterns.boxVar, patterns.mediawikiFunctions]
    		);
    		text = replaceExcept(
    			text,
    			decimalPointToPersian,
    			[patterns.catgories]
    		);
    		return text
    			//  thousands' separator
    			.replace(/([۱۲۳۴۵۶۷۸۹۰]),([۱۲۳۴۵۶۷۸۹۰])/g, '$1٬$2')
    			.replace(/([۱۲۳۴۵۶۷۸۹۰])( |)\u0652/g, '$1°')//تبدیل نویسه سکون+عدد فارسی به نویسه درجه و عدد فارسی
    			.replace(/\u0652( |)([۱۲۳۴۵۶۷۸۹۰])/g, '°$2')
    			//فاصله بین نویسه درجه و حروف الفبای فارسی به جز عدد فارسی
    			.replace(/([\u0621-\u064A\u0653-\u0655\u067E\u0686\u0698\u06AF\u06A9\u0643\u06AA\uFED9\uFEDA\u06CC\uFEF1\uFEF2])°/g, '$1 °');
    	}
    
    	function dictationReplace(x, y, extensions, text) {
    		return text.replace(
    			new RegExp(
    				'(^|[^' + persianTools.persianCharacters + '])(\\s|\u200c|_|)(' + x + ')(\\s|_)(' + y + ')(\\s|\u200c|_|)(' +
    					extensions + ')($|[^' + persianTools.persianCharacters + '])',
    				'g'
    			),
    			'$1$2$3\u200c$5$6$7$8'
    		);
    	}
    
    	// it has dependency to MediaWiki:Gadget-Extra-Editbuttons-Dictionary.js
    	function dictation(text) {
    		var i,
    			dictionary = persianToolsDictionary,
    			NASB = '\u064b', // ًـ
    			ZAMM = '\u064c'; // ُـ
    		for (i in dictionary.complexes) {
    			if (dictionary.complexes.hasOwnProperty(i)) {
    				text = dictationReplace(
    					i,
    					dictionary.complexes[i],
    					'ی|یی|ها|های|هایی|هایم|هایت|هایش|هایمان|هایتان|هایشان|',
    					text
    				);
    			}
    		}
    		// for last name
    		text = dictationReplace(
    			dictionary.personNames,
    			'ی|یی|زاده|نیا|گان|فر|نژاد|یان|ی\u200cها|یها',
    			'ی|',
    			text
    		);
    		// for 'آباد's
    		text = dictationReplace(
    			dictionary.personNames + '|' + dictionary.addToAbad,
    			'آباد',
    			'زاده|نیا|پور|گان|فر|نژاد|ی|یان|ها|های|یی|هایی|ی\u200cها|یها|',
    			text
    		);
    		// for first names
    		for (i in dictionary.firstNameComplex) {
    			if (dictionary.firstNameComplex.hasOwnProperty(i)) {
    				text = text.replace(
    					new RegExp(
    						'(^|[^' + persianTools.persianCharacters + ']|\\s|_)(' + i + ')(\\s|_)(' +
    							dictionary.firstNameComplex[i] + ')(\\s|_)($|[^' + persianTools.persianCharacters + ']|[^' +
    							persianTools.persianCharacters + '])',
    						'g'
    					),
    					'$1$2\u200c$4$5$6'
    				);
    			}
    		}
    		// for colors
    		text = dictationReplace(
    			dictionary.colorsNames,
    			'فام|گون',
    			'زاده|نیا|پور|گان|فر|نژاد|ی|یی|ها|های|هایی|ی\u200cها|یها|هایم|هایت|هایش|هایمان|هایتان|هایشان|',
    			text
    		);
    		// for numbers
    		text = dictationReplace(
    			dictionary.persianNumbers,
    			'گانه|ماهه',
    			'زاده|نیا|پور|گان|فر|نژاد|ی|یی|ها|های|هایی|هایم|هایت|هایش|هایمان|هایتان|هایشان|',
    			text
    		);
    		// wrong dictation
    		for (i in dictionary.forReplace) {
    			if (dictionary.forReplace.hasOwnProperty(i)) {
    				text = text.replace(
    					new RegExp(
    						'(^|[^' + persianTools.persianCharacters + '])(\\s|\\(|\u200c|_|)(' + i + ')(\\s|\\)|\u200c|_|)($|[^' +
    							persianTools.persianCharacters + '])',
    						'g'
    					),
    					'$1$2' + dictionary.forReplace[i] + '$4$5'
    				);
    			}
    		}
    
    		// کلماتی که آ دارند
    		text = text.replace(
    			new RegExp("(^|\\s|_|«|»|\\[|\\(|\\<|\\>|\\')(" + dictionary.wordsWithA + ")(ی|ئی|یی|ٔ|)(?= |«|»|\\.|،|_|\\]|\\s|\\:|\\)|\\<|\\>|؟|\\'|\\!|$)", 'g'),
    			function (x) { return x.replace(/ا/i, 'آ'); } // 'i' is just to trick bidi algorithm on code view
    		);
    		// بن مضارع که آ دارند
    		text = text.replace(
    			new RegExp("(^|\u200c|\\s|_|«|»|\\[|\\(|\\<|\\>|\\')(" + dictionary.PresentVerbsWithA + ")(م|ی|د|یم|ید|ند)(?= |«|»|\\.|،|_|\\s|\\]|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)", 'g'),
    			function (x) { return x.replace(/ا/i, 'آ'); } // 'i' is just to trick bidi algorithm on code view
    		);
    
    		// بن ماضی که آ دارند
    		text = text.replace(
    			new RegExp("(^|\u200c|\\s|_|«|»|\\[|\\(|\\<|\\>|\\')(" + dictionary.PastVerbsWithA + ")(م|ی|یم|ید|ند|ه|)(?= |«|»|\\.|،|_|\\s|\\]|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)", 'g'),
    			function (x) { return x.replace(/ا/i, 'آ'); } // 'i' is just to trick bidi algorithm on code view
    		);
    
    		// همزه ضم
    		text = text.replace(
    			new RegExp("(^|\\s|_|«|»|\\[|\\(|\\<|\\>|\\')(" + dictionary.HamzehZam + ")(‌ها|ها|ین|ان|ی|ئی|یی|ٔ|)(?= |«|»|\\.|،|_|\\s|\\]|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)", 'g'),
    			function (x) { return x.replace(/وء/, 'ؤ').replace(/و/i, 'ؤ'); } // 'i' is just to trick bidi algorithm on code view
    		);
    		//همزه نصب
    		text = text.replace(
    			new RegExp("(^|\\s|_|«|»|\\[|\\(|\\<|\\>|\\')(" + dictionary.HamzehNasb + ")(ی|ئی|یی|ٔ|)(?= |«|»|\\.|،|_|\\s|\\]|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)", 'g'),
    			function (x) { return x.replace(/ا/i, 'أ'); } // 'i' is just to trick bidi algorithm on code view
    		);
    
    		//همزه وسط کلمه
    		for (i in dictionary.HamzehAtInside) {
    			text = text.replace(new RegExp(
    				"(^|\\s|_|«|»|\\[|\\(|\\<|\\>|\\')(" + i + ')(| )(' + dictionary.HamzehAtInside[i] + ")(?= |«|»|\\.|،|_|\\s|\\]|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)",
    				'g'
    			), '$1$2ء$4');
    		}
    
    		// در مورد افزودن یا حذف همزهٔ پایانی اجماعی وجود ندارد.
    		/* text = text.replace(new RegExp("(^|\\s|_|«|»|\\[|\\(|\\<|\\>|\\')(" + dictionary.HamzehAtEnd + ")(?= |«|»|\\.|،|_|\\s|\\]|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)", 'g'),'$1$2ء'); */
    
    		//الف مقصوره
    		text = text.replace(
    			new RegExp("(^|\\s|_|«|»|\\[|\\(|\\<|\\>|\\')(" + dictionary.AlefMaghsooreh + ")(?= |«|»|\\.|،|_|\\s|\\]|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)", 'g'),
    			function (x) { return x.replace(/ا/i, 'ی'); } // 'i' is just to trick bidi algorithm on code view
    		);
    
    		// صفت+تر
    		text = text.replace(new RegExp("(^|\\s|_|«|»|\\]|\\[|\\(|\\<|\\>|\\')(" + dictionary.adjective + ")( |_)تر(?= |«|»|\\.|\\[|\\]|،|_|\\s|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)", 'g'),'$1$2\u200cتر');
    		
    		// اسامی رنگ‌ها (به‌عنوان صفت)+تر
    		text = text.replace(new RegExp("(^|\\s|_|«|»|\\]|\\[|\\(|\\<|\\>|\\')(" + dictionary.colorsNames + ")( |_)تر(?= |«|»|\\.|\\[|\\]|،|_|\\s|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)", 'g'),'$1$2\u200cتر');
    		
    		text = text.replace(/به دست\u200cآورد/g, 'به دست آورد'); // Solving a bug!
    		text = persianTools.normalizeZwnj(text);
    		return text.replace(new RegExp("(^|[؛\\s\\n\\.،«»\'\\<\\>؟])(" + dictionary.needsNasb + ')[' + NASB + ZAMM + ']?([؛؟\\s\\n\\.،«»\'"\\<\\>]|$)', 'g'), function (match) {
    			return match
    				.replace(new RegExp('ا([\\s\\n\\.،«»؟؛"\'\\>\\<' + ZAMM + '])', 'i'), 'ا' + NASB + '$1')
    				.replace(new RegExp(NASB + '["' + NASB + ZAMM + ']'), NASB);
    		});
    	}
    
    	function wikiDictation(text) {
    		return replaceExcept(
    			text,
    			dictation,
    			[patterns.globalExceptionTag, patterns.fileNames, patterns.signatures, patterns.url, patterns.galleryTag, patterns.insideQuote, patterns.argumentsBlacklist, patterns.articleTitleParts]
    		);
    	}
    	function wikiApplyOrthography(text) {
    		text=text //en:Wikipedia:HTML5
    				//big
    				.replace(/((?:\<big\>){5})([^<]+)((?:\<\/big\>){5})/g,'<span style="font-size: 56px;">$2</span>')
    				.replace(/((?:\<big\>){4})([^<]+)((?:\<\/big\>){4})/g,'<span style="font-size: 38px;">$2</span>')
    				.replace(/((?:\<big\>){3})([^<]+)((?:\<\/big\>){3})/g,'{{خیلی بزرگ|$2}}')
    				.replace(/((?:\<big\>){2})([^<]+)((?:\<\/big\>){2})/g,'{{بزرگ|$2}}')
    				.replace(/((?:\<big\>){1})([^<]+|[\s\S]+)((?:\<\/big\>){1})/g,'{{درشت|$2}}')
    				//center
    				.replace(/<center><gallery>([\S\s]+?)\<\/gallery><\/center>/g,'<gallery class="center">$1</gallery>')
    				//.replace(/<center>([\S\s]+?)<\/center>/g,'{{وسط|$1}}')
    				//empty tag
    				.replace(/<span style="font-size: [^>]+"><\/span>/g,'')
    				.replace(/{{(?:درشت|خیلی بزرگ|بزرگ|وسط)\|}}/g,'')
    
    		//حذف برچسب‌های خالی نرم‌افزار مدیاویکی
    		var tags = ['math', 'div', 'grammarly\\-btn','code', 'nowiki', 'pre', 'syntaxhighlight' ,'source', 's', 'noinclude', 'includeonly', 'big', 'small','gallery'];// has bug for sub , sup [[Special:Diff/19450140/19490903]]
    		text = replaceExcept(
    		  text,
    		  function (text) {
    			for (var i = 0; i < tags.length; ++i) {
    				for (var b = 0; b < 5; ++b) {//خیلی از برچسب‌های خالی تو در تو هستند مانند [[Special:PermaLink/19223877]]
    			  	text = text.replace(new RegExp('\<' + tags[i] + '[^\>]*\>(\\n|\\s|\u200c)*?\<\\/' + tags[i] + '\>', 'g'), '');
    				}
    			  // remove the tags if they occurred multiple times consequently
    			  if (mw.config.get('wgNamespaceNumber') === 0 || mw.config.get('wgNamespaceNumber') === 4) {
    				text = text.replace(new RegExp('(\<' + tags[i] + '\>){2,}', 'g'), '$1')
    				  .replace(new RegExp('(\<\\/' + tags[i] + '\>){2,}', 'g'), '$1');
    			  }
    			}
    			if (mw.config.get('wgNamespaceNumber') === 0) {
    				 text=text.replace(/\<ref\>[\s\n]*\<\/ref\>/g,'').replace(/\<ref\>[\s\n]*\<ref\>/g,'<ref>').replace(/\<\/ref\>[\s\n]*\<\/ref\>/g,'</ref>').replace(/\<ref\/\>/g,'</ref>');
    			};
    			return text
    		  },
    		  [patterns.insideHtmlComment]
    		);
    		return replaceExcept(
    			text,
    			persianTools.applyOrthography,
    			[patterns.globalExceptionTag, patterns.fileNames, patterns.signatures, patterns.url, patterns.galleryTag, patterns.wikilinkTargets]
    		).replace(patterns.galleryTag, function (gallery) {
    			// apply `applyOrthography` on gallery descriptions separately
    			return gallery.replace(/^([^\|]*?\|)(.*)$/mg, function (x, y, z) {
    				return y + persianTools.applyOrthography(z);
    			});
    		});
    	}
    	
    	// probably should be exactly same above but for applyZwnj
    	function wikiApplyZwnj(text) {
    		return replaceExcept(
    			text,
    			persianTools.applyZwnj,
    			[patterns.globalExceptionTag, patterns.fileNames, patterns.signatures, patterns.url, patterns.galleryTag]
    		).replace(patterns.galleryTag, function (gallery) {
    			// apply `applyOrthography` on gallery descriptions separatly
    			return gallery.replace(/^([^\|]*?\|)(.*)$/mg, function (x, y, z) {
    				return y + persianTools.applyZwnj(z);
    			});
    		});
    	}
    
    	function replaceEnMonth(text) {
    		var enMonth = {
    			'آگست':'اوت',
    			'آگوست':'اوت',
    			'جولای':'ژوئیه',
    			'مارچ':'مارس',
    			'آپریل':'آوریل',
    			'فوریوری':'فوریه',
    			'january': 'ژانویه',
    			'jan': 'ژانویه',
    			'february': 'فوریه',
    			'feb': 'فوریه',
    			'march': 'مارس',
    			'mar': 'مارس',
    			'april': 'آوریل',
    			'apr': 'آوریل',
    			'may': 'مه',
    			'june': 'ژوئن',
    			'jun': 'ژوئن',
    			'july': 'ژوئیه',
    			'august': 'اوت',
    			'aug': 'اوت',
    			'september': 'سپتامبر',
    			'sept': 'سپتامبر',
    			'sep': 'سپتامبر',
    			'october': 'اکتبر',
    			'oct': 'اکتبر',
    			'november': 'نوامبر',
    			'nov': 'نوامبر',
    			'december': 'دسامبر',
    			'dec': 'دسامبر'
    		};
    		for (var i in enMonth) {
    			var text_new = text.replace(new RegExp(i, 'ig'), enMonth[i])
    			if (text_new != text) {
    				return text_new
    			}
    		}
    		return text
    	};
    	function autoFormatCleanDatesException (text) {
    		return replaceExcept(
    			text,
    			autoFormatCleanDates,
    			[patterns.globalExceptionTag, patterns.fileNames, patterns.galleryTag, patterns.mathTag, patterns.sourceTag, patterns.templateWithEnglishName, patterns.citation, patterns.argumentsBlacklist, patterns.ref]
    		)
    	}
    	function wikitranslateEnMonth(text) {
    		text=autoFormatCleanDatesException(text)
    		return replaceExcept(
    			text,
    			function translateEnMonth(text) {
    				var enMonthRegex = '(آگست|آگوست|جولای|مارچ|آپریل|january|jan|february|feb|march|mar|april|apr|may|jun|june|july|august|aug|sep|sept|september|oct|october|nov|november|december|dec)';
    				return text.replace(new RegExp('([^a-zA-Z])(\^|\\||\\s|\\=|\\n|\\(|«|\\:)' + enMonthRegex + ' (\\d{1,2}|[۱۲۳۴۵۶۷۸۹۰]{1,2})\\, (\\d{3,4}|[۱۲۳۴۵۶۷۸۹۰]{3,4})(\\||\\s|\\n|\$|\\)|\\}|»)([\^a\-zA\-Z])', 'ig'),
    						function (x) {
    							x=x.replace(new RegExp('([\^a\-zA\-Z])(\^|\\||\\s|\\=|\\n|\\(|«|\\:)' + enMonthRegex + ' (\\d{1,2}|[۱۲۳۴۵۶۷۸۹۰]{1,2})\\, (\\d{3,4}|[۱۲۳۴۵۶۷۸۹۰]{3,4})(\\||\\s|\\n|\$|\\)|\\}||»)([^a-zA-Z])', 'ig'),
    							'$1$2$4 $3 $5$6$7')
    							x = persianTools.toPersianDigits(x);
    							x = replaceEnMonth(x);
    							return x;
    						})
    					.replace(new RegExp('([\^a\-zA\-Z])(\^|\\||\\s|\\=|\\n|\\(|«)((\\d{1,2}|[۱۲۳۴۵۶۷۸۹۰]{1,2}) |)' + enMonthRegex + ' (\\d{3,4}|[۱۲۳۴۵۶۷۸۹۰]{3,4})(\\||\\s|\\n|$|\\)|\\}|»|\\:)([\^a\-zA\-Z])', 'ig'),
    						function(x) {
    							x = persianTools.toPersianDigits(x);
    							x = replaceEnMonth(x);
    							return x;
    						}
    					);
    			}, [patterns.globalExceptionTag, patterns.fileNames, patterns.ref, patterns.fileParameter, patterns.galleryTag, patterns.mathTag, patterns.sourceTag, patterns.templateWithEnglishName, patterns.citation, patterns.argumentsBlacklist]
    		)
    	}
    	
    	var arabicDigits = '0123456789', persianDigits = '۰۱۲۳۴۵۶۷۸۹', arabicIndicDigits = '٠١٢٣٤٥٦٧٨٩';
    	function robustToEnglishDigits(text) {
    		var i = 0;
    		for (i = 0; i <= 9; i = i + 1) {
    			text = text.replace(new RegExp('[' + persianDigits[i] + arabicIndicDigits[i]+']', 'g'), arabicDigits[i]);
    		}
    		return text;
    	}
    		
    	function toEnglishDigits(text) {
    		text = text.replace(/[a-zA-Z]([\_\s\:\.\,\;\]\[\"\'\)\(\}\{\/\\ ]+|)([۱۲۳۴۵۶۷۸۹۰٪\.٫\-\—\–°÷×\+\,\s\_\:،»«؛]+)([\_\s\:\.\,\;\]\[\"\'\)\(\}\{\/\\\<\> ]+|)([a-zA-Z\>]|$)/g, function (x) {
    			var i = 0;
    			for (i = 0; i <= 9; i = i + 1) {
    				x = x.replace(new RegExp('[' + persianDigits[i] + arabicIndicDigits[i]+ ']', 'g'), arabicDigits[i]);
    			}
    			return x.replace(/،/g,',').replace(/»/g,'"').replace(/«/g,'"').replace(/؛/g,';');
    		});
    		// bug [[Special:Diff/17760890/17760898]]
    		text = text.replace(/([a-zA-Z][۱۲۳۴۵۶۷۸۹۰]+) *\=/g, function (x) {
    			var i = 0;
    			for (i = 0; i <= 9; i = i + 1) {
    				x = x.replace(new RegExp('[' + persianDigits[i] + arabicIndicDigits[i]+ ']', 'g'), arabicDigits[i]);
    			}
    			return x;
    		});
    		// ISBN, ISSN and PMID's numbers should in english
    		text = text.replace(/\b(ISBN|ISSN|PMID|PubMed) *:? *([۱۲۳۴۵۶۷۸۹۰0-9–—−ـ_\-]+)([^۱۲۳۴۵۶۷۸۹۰0-9–—−ـ_\-]|$)/gi, function (x) {
    			x=x.replace(/[–—−ـ_\-]+/g,'-')
    			var i = 0;
    			for (i = 0; i <= 9; i = i + 1) {
    				x = x.replace(new RegExp('[' + persianDigits[i] + arabicIndicDigits[i]+ ']', 'g'), arabicDigits[i]);
    			}
    			x = x.replace(/\b(ISBN|ISSN|PMID|PubMed) *:? *([۱۲۳۴۵۶۷۸۹۰\-0-9]+)([^۱۲۳۴۵۶۷۸۹۰\-0-9]|$)/gi,'$1 $2$3')
    			x = x.replace('PubMed','PMID')
    			return x;
    		});
    		text = text.replace(/ISBN \-note/g,'ISBN-note');
    		// تبدیل عددهای فارسی در عدد ترتیبی انگلیسی
    		text = text.replace(/(?:^|["\'\s_«\(\[\{])([۱۲۳۴۵۶۷۸۹۰]+)(st|nd|rd|th)[\s_\.,»"\'\)\]\}]/g, function (x) {
    			var i = 0;
    			for (i = 0; i <= 9; i = i + 1) {
    				x = x.replace(new RegExp('[' + persianDigits[i]+ arabicIndicDigits[i] + ']', 'g'), arabicDigits[i]);
    			}
    			return x;
    		});
    		return text
    			.replace(new RegExp('([' + arabicDigits + ']) ?٪', 'g'), '$1%')
    			.replace(new RegExp('([' + arabicDigits + '])٫(?=[' + arabicDigits + '])', 'g'), '$1.') // English decimal separator
    	}
    	function cleanTemplateBracesFromArticle (text) {// like [[Special:Diff/18828723]]
                if (mw.config.get('wgNamespaceNumber') !== 0) {
                      return text
                }
                var i =0
                for (i = 0; i <= 5; i = i + 1) {
    				text = text.replace(/\{\{\{[^\|\}]+\|([^\}]+)\}\}\}/g, '$1')
    				           .replace(/\{\{\{[^\|\}]+\| *\}\}\}/g, '')
    			}
    
                return text.replace(/\{\{\#/g, '{{جا:#')
                           .replace(/\{\{ *(PAGENAME|FULLPAGENAMEE|SITENAME|NAMESPACE) *\}\}/g, '{{جا:$1}}')
                           .replace('{{ترتیب‌پیش‌فرض:}}', '');
    	}
    	function decodeHTMLSymbolEntitiesCodes (text) {
    		//&copy; > ©
    		return replaceExcept(
    			text,
    			function decodeEntitiesCodes (text) {
    				for (var i in htmlEntityCodes) {
    					var entityInput = i;
    					var entityoutput = htmlEntityCodes[i];
    					text=text.replace(new RegExp(entityInput, 'g'), entityoutput);
    				}
    				return text;
    			}, [patterns.globalExceptionTag, patterns.fileNames, patterns.ref, patterns.fileParameter,
    			patterns.galleryTag, patterns.mathTag, patterns.sourceTag, patterns.templateWithEnglishName,
    			patterns.citation, patterns.url]
    		)
    	}
    	function removeWikiSigne (text) {
    		return replaceExcept(
    			text,
    			function (text) {
    				text=text.replace(/\[\[([^\|\]]+)\|([^\]]+)\]\]/g, '$2');
    				text=text.replace(/\[\[([^\|\]]+)\]\]/g, '$1');
    				return text;
    			}, [patterns.globalExceptionTag, patterns.fileNames, patterns.fileParameter,
    		 patterns.mathTag, patterns.sourceTag, patterns.templateWithEnglishName, patterns.nowikiTag, patterns.preTag,
    		 patterns.insideHtmlComment]
    		)
    	}
    	function autoEdHTMLtoWikitextWikiTools (text) {
    		return replaceExcept(
    			text,
    			autoEd.autoEdHTMLtoWikitext,
    			[patterns.fileParameter, patterns.mathTag, patterns.sourceTag]
    		)
    	}
    	function superTool(text) {
    		text = decodeHTMLSymbolEntitiesCodes (text);
    		text = cleanTemplateBracesFromArticle (text);
    		text = persianWikiTools.wikiConvertToPersianCharacters(text);
    		text = persianWikiTools.wikiApplyZwnj(text);
    		text = persianWikiTools.wikiApplyOrthography(text);
    		text = persianWikiTools.wikitranslateEnMonth(text);
    		if (mw.config.get('wgNamespaceNumber') !== 10) {
    			text = persianWikiTools.wikiTextDigitsToPersian(text);
    		}
    		text = persianWikiTools.wikiUrlMinifier(text);
    		text = persianWikiTools.wikiDictation(text);
    		text = persianWikiTools.wikiPunctuation(text);
    		text = persianWikiTools.wikiSubsection(text);
    		text = persianWikiTools.SubSectionLeveling (text)
    		//ابزارهای بیشتر برگرفته از ویکی‌پدیای انگلیسی [[Mediawiki:Gadget-Extra-Editbuttons-autoed.js]]
    		text = autoEd.autoEdISBN(text);
    		text = autoEd.autoEdWhitespace(text);
    		text = autoEdHTMLtoWikitextWikiTools(text);
    		text = autoEd.autoEdHeadlines(text);
    		text = autoEd.autoEdTablestoWikitext(text);
    		text = autoEd.autoEdExtraBreaks(text);
    		text = persianWikiTools.addColumnToRefTemplate(text);
    		text = persianWikiTools.removeCheckDict(text);
    		return text;
    	}
    	
    	function superToolMove(text) {
    		text = ' ' + text + ' '; // بعضی از کدها اگر فاصله در انتها یا اول نباشد عمل نمی‌کنند مانند افزودن تنوین به کلمه بعدا
    		text = persianWikiTools.wikiConvertToPersianCharacters(text);
    		text = persianTools.applyZwnj(text);
    		text = persianWikiTools.wikiApplyOrthography(text);
    		text = persianWikiTools.wikiTextDigitsToPersian(text);
    		text = persianWikiTools.wikiUrlMinifier(text);
    		text = persianWikiTools.wikiDictation(text);
    		text = persianWikiTools.wikiPunctuation(text);
    		return text.trim();
    	}
    
    	return {
    		removeWikiSigne: removeWikiSigne,
    		superTool: superTool,
    		superToolMove: superToolMove,
    		dictation: dictation,
    		wikiApplyOrthography: wikiApplyOrthography,
    		wikiApplyZwnj: wikiApplyZwnj,
    		wikiConvertToPersianCharacters: wikiConvertToPersianCharacters,
    		wikiDictation: wikiDictation,
    		wikiPunctuation: wikiPunctuation,
    		wikiSubsection:wikiSubsection,
    		SubSectionLeveling:SubSectionLeveling,
    		wikiUrlMinifier: wikiUrlMinifier,
    		wikiTextDigitsToPersian: wikiTextDigitsToPersian,
    		wikitranslateEnMonth: wikitranslateEnMonth,
    		addColumnToRefTemplate: addColumnToRefTemplate,
    		fixBadLinks: fixBadLinks,
    		robustToEnglishDigits: robustToEnglishDigits,
    		toEnglishDigits: toEnglishDigits,
    		removeCheckDict:removeCheckDict
    	};
    }());
    if (typeof window !== "undefined") {
    	window.persianWikiTools = persianWikiTools;
    }
    // </nowiki>