مسابقه دانش‌دخت
اسلامیکال از تاریخ ۱۵ دی تا ۲۰ بهمن، میزبان یک همایه با موضوع زنان است. شما می‌توانید در مسابقه مقاله‌نویسی دانش‌دخت، شرکت کنید و با نگارش مقاله، از جوایز آن بهره‌مند باشید. اگر به موضوعات مربوط با زنان علاقه‌مندید، این فرصت را از دست ندهید. فهرستی از مقالات پیشنهادی جهت ایجاد یا ویرایش در اینجا وجود دارد.

مدیاویکی:Gadget-Extra-Editbuttons-Functions-test.js

از اسلامیکال
نسخهٔ تاریخ ‏۱۲ ژانویهٔ ۲۰۲۳، ساعت ۱۶:۲۰ توسط Aboammar (بحث | مشارکت‌ها) (صفحه‌ای تازه حاوی «var EE_faChrs = "ءاآأإئؤبپتثجچحخدذرزژسشصضطظعغفقکگلمنوهیةيک" + "ًٌٍَُِّْ"; var EE_faNums = "۰۱۲۳۴۵۶۷۸۹"; var EE_arNums = "٠١٢٣٤٥٦٧٨٩"; //here we will list none farsi chars like ە ە which is Kurdish char instead of ه ه (Farsi) var NoneFarsi={//حروف کردی به فارسی 'ہ':'ه',//Urdu ہ > ه ه (Farsi)...» ایجاد کرد)
(تفاوت) → نسخهٔ قدیمی‌تر | نمایش نسخهٔ فعلی (تفاوت) | نسخهٔ جدیدتر ← (تفاوت)
پرش به ناوبری پرش به جستجو

نکته: پس از انتشار ممکن است برای دیدن تغییرات نیاز باشد که حافظهٔ نهانی مرورگر خود را پاک کنید.

  • فایرفاکس / سافاری: کلید Shift را نگه دارید و روی دکمهٔ Reload کلیک کنید، یا کلید‌های Ctrl-F5 یا Ctrl-R را با هم فشار دهید (در رایانه‌های اپل مکینتاش کلید‌های ⌘-R)
  • گوگل کروم: کلیدهای Ctrl+Shift+R را با هم فشار دهید (در رایانه‌های اپل مکینتاش کلید‌های ⌘-Shift-R)
  • اینترنت اکسپلورر/ Edge: کلید Ctrl را نگه‌دارید و روی دکمهٔ Refresh کلیک کنید، یا کلید‌های Ctrl-F5 را با هم فشار دهید
  • اپرا: Ctrl-F5 را بفشارید.
var EE_faChrs = "ءاآأإئؤبپتثجچحخدذرزژسشصضطظعغفقکگلمنوهیةيک" + "ًٌٍَُِّْ";
var EE_faNums = "۰۱۲۳۴۵۶۷۸۹";
var EE_arNums = "٠١٢٣٤٥٦٧٨٩";
//here we will list none farsi chars like ە ە which is Kurdish char  instead of ه ه (Farsi)
var NoneFarsi={//حروف کردی به فارسی

               'ہ':'ه',//Urdu ہ > ه ه (Farsi)
               'ى':'ی',//Urdu ى > ی
                'ې':'ی',//Uyghur ې >ی
               'ە':'ه',//Kurdish ە > ه ه (Farsi)
               'ھ':'ه',
              }

var tupN = [];
var tupO = [];

//Also it uses variables  of [[مدیاویکی:Gadget-Extra-Editbuttons-Dictionary.js]] 

/*
 * Javascript Diff Algorithm
 *  http://ejohn.org/projects/javascript-diff-algorithm/
 */

function links_underline(str, rev_type) {
    //this function is used to have better results for Diff Algorithm in wikilinks
    var falinks = str.match(/\[\[.*?\]\]/g);
    if (falinks) {
        if (rev_type == 'Start') {
            for (var i = 0; i < falinks.length; i++) {
                var item_s = falinks[i];
                var intem_u = falinks[i].replace(/\s/g, '_');
                str = str.replace(item_s, intem_u);
            }
        } else {
            for (var i = 0; i < falinks.length; i++) {
                var item_s = falinks[i].replace(/\_/g, ' ');
                var intem_u = falinks[i];
                str = str.replace(intem_u, item_s);
            }
        }
    };
    return str;
}

function escape(s) {
    //Diff Algorithm's functions
    var n = s;
    n = n.replace(/&/g, "&amp;");
    n = n.replace(/</g, "&lt;");
    n = n.replace(/>/g, "&gt;");
    n = n.replace(/"/g, "&quot;");

    return n;
};

function di_escape(s) {
    //Diff Algorithm's functions
    var n = s;
    n = n.replace(/&amp;/g, "&");
    n = n.replace(/&lt;/g, "<");
    n = n.replace(/&gt;/g, ">");
    n = n.replace(/&quot;/g, '"');

    return n;
};


function diffString(o, n) {
    //Diff Algorithm's functions
    tupN = [];
    tupO = [];
    o = o.replace(/\s+$/, '');
    n = n.replace(/\s+$/, '');
    var out = diff(o == "" ? [] : o.split(/\s+/), n == "" ? [] : n.split(/\s+/));
    var oSpace = o.match(/\s+/g);
    if (oSpace == null) {
        oSpace = ["\n"];
    } else {
        oSpace.push("\n");
    }
    var nSpace = n.match(/\s+/g);
    if (nSpace == null) {
        nSpace = ["\n"];
    } else {
        nSpace.push("\n");
    }
    if (out.n.length == 0) {
        for (var i = 0; i < out.o.length; i++) {
            tupO.push(escape(out.o[i]))
        }
    } else {
        if (out.n[0].text == null) {
            for (n = 0; n < out.o.length && out.o[n].text == null; n++) {
                tupO.push(escape(out.o[n]));
            }
        }
        for (var i = 0; i < out.n.length; i++) {
            if (out.n[i].text == null) {
                tupN.push(escape(out.n[i]));
            } else {
                for (n = out.n[i].row + 1; n < out.o.length && out.o[n].text == null; n++) {
                    tupO.push(escape(out.o[n]));
                }
            }
        }
    }
    o = '';
    n = '';
}

function diff(o, n) {
    //Diff Algorithm's functions
    var ns = new Object();
    var os = new Object();

    for (var i = 0; i < n.length; i++) {
        if (ns[n[i]] == null) ns[n[i]] = {
            rows: new Array(),
            o: null
        };
        ns[n[i]].rows.push(i);
    }

    for (var i = 0; i < o.length; i++) {
        if (os[o[i]] == null) os[o[i]] = {
            rows: new Array(),
            n: null
        };
        os[o[i]].rows.push(i);
    }

    for (var i in ns) {
        if (ns[i].rows.length == 1 && typeof (os[i]) != "undefined" && os[i].rows.length == 1) {
            n[ns[i].rows[0]] = {
                text: n[ns[i].rows[0]],
                row: os[i].rows[0]
            };
            o[os[i].rows[0]] = {
                text: o[os[i].rows[0]],
                row: ns[i].rows[0]
            };
        }
    }

    for (var i = 0; i < n.length - 1; i++) {
        if (n[i].text != null && n[i + 1].text == null && n[i].row + 1 < o.length && o[n[i].row + 1].text == null && n[i + 1] == o[n[i].row + 1]) {
            n[i + 1] = {
                text: n[i + 1],
                row: n[i].row + 1
            };
            o[n[i].row + 1] = {
                text: o[n[i].row + 1],
                row: i + 1
            };
        }
    }

    for (var i = n.length - 1; i > 0; i--) {
        if (n[i].text != null && n[i - 1].text == null && n[i].row > 0 && o[n[i].row - 1].text == null && n[i - 1] == o[n[i].row - 1]) {
            n[i - 1] = {
                text: n[i - 1],
                row: n[i].row - 1
            };
            o[n[i].row - 1] = {
                text: o[n[i].row - 1],
                row: i - 1
            };
        }
    }

    return {
        o: o,
        n: n
    };
};

function RevertBug(diffO, diffN, str) {
    //Diff Algorithm's functions + Reverting Bug's functions
    for (var i = 0; i < diffN.length; i++) {

        //Checking Interwikis' Links
        var diffN_di = di_escape(diffN[i])
        var diffO_di = di_escape(diffO[i])
        var item = diffN_di
        var regex = /\[\[([a-z]{2,3}|[a-z]{2,3}\-[a-z\-]{2,}|simple)(\s|_|)\:(.*?)(\s|_|\:.*|)\]\]/g
        var interwikis = item.match(regex);
        if (interwikis != null) {
            str = str.replace(diffN_di, diffO_di);
        };

        //Checking Files' Links
        if (item.replace(/\|/g, "") != item) {
            var regex = /\[\[ *(?:پرونده|تصویر|[Ff]ile|[Ii]mage)(\s|_|)\:(\s|_|)(.*?)\|/g
        } else {
            var regex = /\[\[ *(?:پرونده|تصویر|[Ff]ile|[Ii]mage)(\s|_|)\:(\s|_|)(.*?)\]\]/g
        };
        var filelinkN = diffN_di.match(regex);
        var filelinkO = diffO_di.match(regex);
        if (filelinkN != null) {
            str = str.replace(filelinkN, filelinkO);
        };

        //Checking User's Sign Link
        var regex = /\[\[(\s|_|)([Uu]ser|کاربر|بحث کاربر|بحث_کاربر|ویژه)(\s|_|)\:/g
        var UserSign = item.match(regex);
        if (UserSign != null) {
            str = str.replace(diffN_di, diffO_di);
        };

        //Checking URLs
        var regex = /(\[\/\/[\w\-]+?\.wiki|https?\:\/\/)(\S+)/g
        var URLlinkN = diffN_di.match(regex);
        var URLlinkO = diffO_di.match(regex);
        if (URLlinkN != null) {
            str = str.replace(URLlinkN, URLlinkO);
        };
    };
    diffO = '';
    diffN = '';
    return str;
};

/** applyOnSelection
 *
 *  Description: Applies the string functions defined below to the
 *  selected text in the edit box. If no text is selected, applies
 *  the function to the whole contents of edit box.
 *
 */
function applyOnSelection(callback) {
    if (document.getElementById("editform")) {
        var txtarea = document.getElementById("wpTextbox1");
    } else if (document.getElementById("wpNewTitleMain")) {
        var txtarea = document.getElementById("wpNewTitleMain");
    } else {
        return;
    }
    var selText;
    if (document.selection && document.selection.createRange) { // IE/Opera
        // get current selection  
        txtarea.focus();
        var range = document.selection.createRange();
        selText = range.text;
        if (selText) {
            range.text = callback.apply(this, [selText]);
            range.select();
        } else {
            txtarea.value = callback.apply(this, [txtarea.value]);
        }
    } else if (txtarea.selectionStart || txtarea.selectionStart == '0') { // Mozilla
        // get current selection
        txtarea.focus();
        var startPos = txtarea.selectionStart;
        var endPos = txtarea.selectionEnd;
        selText = txtarea.value.substring(startPos, endPos);
        //insert tags
        if (selText) {
            txtarea.value = txtarea.value.substring(0, startPos) + callback.apply(this, [selText]) + txtarea.value.substring(endPos, txtarea.value.length);
            txtarea.selectionStart = startPos + selText.length;
            txtarea.selectionEnd = txtarea.selectionStart;
        } else {
            txtarea.value = callback.apply(this, [txtarea.value]);
        }
    }
}


/** toggleDir
 *
 *  Description: Toggles the directionality of the text in the edit
 *  box textarea. It is helpful when working on wikitext that contains
 *  mixed Persian and English content, or contains commands that are
 *  in English (e.g. untranslated parser functions, etc.)
 *
 */
function toggleDir(obj) {
    var isrtl = 0;
    if (obj) {
        isrtl = obj.style.direction != 'ltr';
        if (isrtl) {
            obj.style.textAlign = "left";
            obj.style.direction = "ltr";
        } else {
            obj.style.textAlign = "right";
            obj.style.direction = "rtl";
        }
    }
}


/** fromEntityToUtf8
 *
 *  Description: Takes an HTML entitiy like &#118; and returns the
 *  Unicode equivalent of it (in this example, letter "v").
 *
 *  This is needed because older browsers sometimes turned in HTML
 *  entities instead of Unicode characters.
 *
 */
function fromEntityToUtf8(str) {
    return str.replace(/&#([0-9]+);/g, function (s, n, ofs, all) {
        return String.fromCharCode(n);
    });
}


/** fromUtf8ToEntity
 *
 *  Description: Takes a Unicode character like the letter "v" and
 *  returns the equivalent HTML entity (in this example, &#118;).
 *
 *  This is not in use anymore and is only kept for historical
 *  purposes.
 *
 */
function fromUtf8ToEntity(str) {
    return str.replace(/([^\x00-\x7f])/g, function (s, c, ofs, all) {
        c = String(c);
        return "&#" + c.charCodeAt(0) + ";";
    });
}


/** AtSignReplace
 *
 *  Description: Replaces the @ sign in the text with {{at}} to
 *  prevent spam bots from picking up email addresses. 
 *
 *  This function is not used by the default buttons.
 *
 */
function AtSignReplace(str) {
    return str.replace(/(\S+?)@(\S+?)/g, '$1{{at}}$2');
}


/** URLfix
 *
 *  Description: Finds all links to Wikipedia pages, strips the
 *  http(s) prefix (to ensure the user will not switch protocols
 *  by clicking on the link), and removes the unnecessary parts of
 *  the query string (such as the "title" attribute of a diff link)
 *  to make the URLs shorter and easier to maintain.
 *
 */
function URLfix(str) {
    // Replace every %20 with _ to protect them from decodeURI
    var old = "";
    while (old != str) {
        old = str;
        str = str.replace(/(http\S+?)\%20/g, '$1\u200c\u200c\u200c_\u200c\u200c\u200c');
    }

    // Decode URIs
    // NOTE: This would convert all %20's to _'s which could break some links
    // but we will undo that later on
    str = str.replace(/(http\S+)/g, function (s, p) {
        return decodeURI(p)
    });

    // Revive all instances of %20 to make sure no links is broken
    str = str.replace(/\u200c\u200c\u200c_\u200c\u200c\u200c/g, '%20');

    // Shorten Wikipedia diff URLs
    str = str.replace(/\[(https?\:|)\/\/([\w\-]+)\.wikipedia\.org\/w\/index\.php\?title=[^&\s]*&(diff=[^&\s]+&|)(oldid=\d+)/g, '[//$2.wikipedia.org/w/index.php?$3$4');

    // Strip the http(s) prefix
    str = str.replace(/\[(https?\:|)\/\/([\w\-]+)\.wikipedia\.org\/(\S*)/g, '[//$2.wikipedia.org/$3');

    return str;
}


/** YKarabic
 *
 *  Description: Replaces all instances of ي and ك withی and ک,
 *  respectively. It should not make any ch anges to Arabic text
 *  surrounded by appropriate templates, and to interwikis.
 *
 */
function YKarabic(str) {
    var old = "";

   /* to do: we should list all of none farsi chars (Kurdish, Urdu, Arabic which are similar to farsi but their unicode is diffrent like (Kurdish ە &#x06D5; and ه &#x0647; Farsi)
   */

    // Do not touch the text inside links, images, categories or interwikis
    while (old != str) {
        old = str;
        str = str.replace(/\[\[([^\]]*?\:[^\]]*?)ي(.*?)\]\]/g, '[[$1\u200c\u200c\u200cی\u200c\u200c\u200c$2]]');
        str = str.replace(/\[\[([^\]]*?\:[^\]]*?)ك(.*?)\]\]/g, '[[$1\u200c\u200c\u200cک\u200c\u200c\u200c$2]]');
        str = str.replace(/\[\[([^\]]*?\:[^\]]*?)ہ(.*?)\]\]/g, '[[$1؛؛؛؛ه؛؛؛؛$2]]');//&#x06D5; to &#x0647;
        str = str.replace(/\{\{(عربی|به عربی)\|(.*?)ى(.*?)\}\}/g, '{{$1|$2؛؛؛؛ڎ؛؛؛؛$3}}');// Urdu and Arabic for {{عربی
        str = str.replace(/\[\[([^\]]*?\:[^\]]*?)ى(.*?)\]\]/g, '[[$1؛؛؛؛ی؛؛؛؛$2]]');// Urdu
        str = str.replace(/\[\[([^\]]*?\:[^\]]*?)ﻲ(.*?)\]\]/g, '[[$1\u200c\u200c\u200c\u200cڎ\u200c\u200c\u200c\u200c$2]]');// Urdu-Arabic,I used char ڎ temporary and it will replace in next lines! 


        str = str.replace(/\[\[([^\]]*?\:[^\]]*?)ۍ(.*?)\]\]/g, '[[$1،،،،ڎ،،،،$2]]');// Pushtu ,I used char ڎ temporary and it will replace in next lines! 

        str = str.replace(/\[\[([^\]]*?\:[^\]]*?)ې(.*?)\]\]/g, '[[$1،،،،ی،،،،$2]]');//Uyghur

        str = str.replace(/\[\[([^\]]*?\:[^\]]*?)ە(.*?)\]\]/g, '[[$1\u200c\u200c\u200cه\u200c\u200c\u200c$2]]');//&#x06D5; to &#x0647;
        str = str.replace(/\[\[([^\]]*?\:[^\]]*?)ھ(.*?)\]\]/g, '[[$1،،،،ه،،،،$2]]');//&#x06BE; to  &#x0647;

    }

    // Replace every ي and ك with ی and ک, respectively
    // NOTE: This WILL mess with images, links, categories and interwikis
    // but we will undo it later
    str = str.replace(/ي/g, 'ی');
    str = str.replace(/ك/g, 'ک');

    //Uyghur
    str = str.replace(/ې/g, 'ی');

    //Urdu
    // Convert &#1609; to &#1740; (the latter is standard Persian Yeh)
    str = str.replace(/ى/g, 'ی');
    str = str.replace(/ﻲ/g, 'ی');
    // Convert &#x06C1; to &#x0647; // ہہہہ to ههه
    str = str.replace(/ہ/g, 'ه');

    //Pushtu 
    str = str.replace(/ۍ/g, 'ی');

    //Kurdish
    //(Kurdish ە &#x06D5; to ه &#x0647; Farsi)
    str =str.replace(/ە/g,'ه'); 
   //(Kurdish ھ &#x06BE; to ه &#x0647; Farsi)
    str =str.replace(/ھ/g,'ه'); 

    // Undo the changes to interwikis, links and images
    // NOTE: This will also undo changes to categories which is not good
    // but we will undo that later
    str = str.replace(/\u200c\u200c\u200cی\u200c\u200c\u200c/g, 'ي');
    str = str.replace(/\u200c\u200c\u200cک\u200c\u200c\u200c/g, 'ك');
    str = str.replace(/؛؛؛؛ه؛؛؛؛/g, 'ہ');//Urdu
    str = str.replace(/؛؛؛؛ی؛؛؛؛/g, 'ى');//Urdu
    str = str.replace(/\u200c\u200c\u200c\u200cڎ\u200c\u200c\u200c\u200c/g, 'ﻲ');//Urdu Arabic, this line revert previous line's replaces
    str = str.replace(/،،،،ڎ،،،،/g, 'ۍ');//Pushtu , this line revert previous line's replaces
    str = str.replace(/،،،،ی،،،،/g, 'ې');//Uyghur
    str = str.replace(/\u200c\u200c\u200cه\u200c\u200c\u200c/g, 'ە');//Kurdish
    str = str.replace(/،،،،ه،،،،/g, 'ھ');//Kurdish


    old = "";
    // Replace every ي and ك in categories with ی and ک, respectively
    while (old != str) {
        old = str;
        str = str.replace(/\[\[(رده|[Cc]ategory):(.*?)(ى|ي|ې|ۍ)(.*?)\]\]/g, '[[$1:$2ی$4]]');//Urdu and Arabic and Uyghur
        str = str.replace(/\[\[(رده|[Cc]ategory):(.*?)ك(.*?)\]\]/g, '[[$1:$2ک$3]]');
        str = str.replace(/\[\[(رده|[Cc]ategory):(.*?)(ھ|ە|ہ)(.*?)\]\]/g, '[[$1:$2ه$3]]');//Urdu and Kurdish ه
    }

    // Finally, replace every ی and ک in Arabic text with ي and ك, respectively
    old = "";
    while (old != str) {
        old = str;
        str = str.replace(/\{\{(عربی|شروع عربی|آغاز عربی)\}\}([^\}]*)ی([^\{]*)\{\{پایان\sعربی\}\}/g,'{{$1}}$2ي$3{{پایان عربی}}');
        str = str.replace(/\{\{(عربی?)\|(.*?)ی(.*?)\}\}/g, '{{عربی\|$2ي$3}}');
        str = str.replace(/\{\{(عربی?)\|(.*?)ک(.*?)\}\}/g, '{{عربی\|$2ك$3}}');
        str = str.replace(/\{\{(به عربی?)\|(.*?)ی(.*?)\}\}/g, '{{به عربی\|$2ي$3}}');
        str = str.replace(/\{\{(به عربی?)\|(.*?)ک(.*?)\}\}/g, '{{به عربی\|$2ك$3}}');
        str = str.replace(/\{\{(عربی|شروع عربی|آغاز عربی)\}\}([^\}]*)ک([^\{]*)\{\{پایان\sعربی\}\}/g, '{{$1}}$2ك$3{{پایان عربی}}');
        str = str.replace(/؛؛؛؛ڎ؛؛؛؛/g, 'ى');//Urdu and Arabic ya maghsureh
    }

    return str;
}


/** NonStandard
 *
 *  Description: Replaces all instances of non-standard characters
 *  used for heh+yeh, with the standard form of «هٔ».
 *
 */
function NonStandard(str) {
    // The non-standard character ۀ is used in Urdu; we would like to
    // undo changes to Urdu interwikis
    var old = "";
    while (old != str) {
        old = str;
        str = str.replace(/\[\[(ur\:[^\]]*?)ۀ(.*?)\]\]/g, '[[$1\u200c\u200c\u200cهٔ\u200c\u200c\u200c$2]]');
    }

    // Replace ه followed by (space|ZWNJ|lrm) follow by ی with هٔ
    str = str.replace(/ه[\u200c\u200e\s]+ی([\s\n])/g, 'هٔ$1');

    // Replace ه followed by (space|ZWNJ|lrm|nothing) follow by ء or   ٔ with هٔ
    str = str.replace(/ه[\u200c\u200e\s]*[ءٔ]([\s\n])/g, 'هٔ$1');

    // Replace هٓ or single-character ۀ with the standard هٔ
    str = str.replace(/(ۀ|هٓ)/g, 'هٔ');

    // Replace ه followed by ئ or ی, and then by ی, with ه‌ای
    // example: خانهئی becomes خانه‌ای
    str = str.replace(/ه‌[ئی]ی/g, 'ه‌ای');

    // Revert the changes to the Urdu interwikis
    old = "";
    while (old != str) {
        old = str;
        str = str.replace(/\u200c\u200c\u200cهٔ\u200c\u200c\u200c/g, 'ۀ');
    }


    var FaGlyphs={'\u200cه':'ﻫ','ی\u200c':'ﻰﻲ','ﺃ':'ﺄﺃ','ﺁ':'ﺁﺂ','ﺇ':'ﺇﺈ','ا':'ﺎا',
            'ب':'ﺑﺐﺏﺒ','پ':'ﭙﭘﭗﭖ','ت':'ﺘﺖﺗﺖﺕ',
            'ث':'ﺜﺛﺚﺙ','ج':'ﺠﺟﺞﺝ','چ':'ﭼﭻﭺﭽ','ح':'ﺤﺣﺢﺡ','خ':'ﺥﺨﺧﺦ','د':'ﺪﺩ',
            'ذ':'ﺬﺫ','ر':'ﺮﺭ','ز':'ﺰﺯ','ژ':'ﮋﮊ','س':'ﺴﺳﺲﺱ','ش':'ﺸﺷﺶﺵ','ص':'ﺼﺻﺺﺹ',
            'ض':'ﻀﺿﺾﺽ','ط':'ﻄﻃﻂﻁ','ظ':'ﻈﻇﻆﻅ','ع':'ﻌﻋﻊﻉ','غ':'ﻍﻐﻏﻎ','ف':'ﻔﻓﻒﻑ',
            'ق':'ﻘﻗﻖﻕ','ک':'ﮑﮐﮏﮎﻜﻛﻚﻙ','گ':'ﮕﮔﮓﮒ','ل':'ﻠﻟﻞﻝ','م':'ﻡﻤﻣﻢﻣ','ن':'ﻨﻧﻦﻥ',
            'ه':'ﻩﻪﻫﻬ','هٔ':'ﮥﮤ','و':'ﻮﻭ','ﺅ':'ﺆﺅ','ی':'ﻴﻳﻲﻱﻰىىﻯ','ئ':'ﺌﺋﺊﺉ','لا':'ﻼ','ﻹ':'ﻺ','ﻷ':'ﻸ','ﻵ':'ﻶ'
            };
    for (var character in FaGlyphs) {
        var Ch1 = character ;
        var Ch2 = FaGlyphs[character];
        var old=''
        while (old != str) {
            old = str;
            var regex = new RegExp("[" + Ch2 + "]", "g");
            str = str.replace(regex, Ch1);
        }
    };
   //Function for removing incorrect ZWNJs
    str=RemoveBadZWNJ(str)
    return str;
}


/** InterwikiSorter
 *
 *  Description: Finds all the interwiki links in the text and sorts
 *  them alphabetaically.
 *
 */
function InterwikiSorter(str) {
    var ref = /\[\[([A-Za-z][A-Za-z-]{1,20}?)\:(.*?)\]\]\r?\n?(\s*)/g

    //extract interwiki's and delete them temporarily from the string
    interwikis = str.match(ref);
    if (interwikis == null) return;
    str = str.replace(ref, "");

    //sort interwikis
    interwikis = interwikis.sort();

    //put interwiki's back
    str = str + interwikis.join("");

    return str;
}

/** SortText
 *
 *  Description: Takes a piece of text in Persian which contains
 *  several lines (separated by the newline character), and sorts
 *  the lines alphabetically, with respect to their first character.
 *
 */
function SortText(str) {
    function sortPreparation(instr) { // solve persian problem on sorting by replace characters in strings
        return instr.replace(/ی/g, "ي")
            .replace(/ک/g, "ك")
            .replace(/گ/g, "كی")
            .replace(/ژ/g, "زی")
            .replace(/چ/g, "جی")
            .replace(/پ/g, "بی");
    }
    temp = str.split('\n');
    temp.sort(function (a, b) {
        var keyA = sortPreparation(a);
        var keyB = sortPreparation(b);
        if (keyA < keyB) return -1;
        if (keyA > keyB) return 1;
        return 0;
    });
    var result = temp.join('\n');
    return result;
}


function FM(str) {
    //بن‌های ماضی
    var verbs = "(آراست|آرامید|آزرد|آزمود|آسود|آشامید|آشفت|آغازید|آغشت|آفرید|آگند|آلود|آمد|آمرزید" + "|آموخت|آمیخت|آورد|آویخت|آهیخت|ارزید|افتاد|افراشت|افروخت|افزود|افسرد|افشاند|افگند" + "|انباشت|انجامید|انداخت|اندوخت|اندود|اندیشید|انگاشت|انگیخت|اوباشت|ایستاد|باخت" + "|بارید|بافت|بالید|بایست|بخشود|بخشید|برازید|برد|برید|بست|بسود|بسیجید|بلعید|بود" + "|بوسید|بویید|بیخت|پاشید|پالود|پخت|پذیرفت|پراکند|پرداخت|پرستید|پرسید|پرورد|پرید" + "|پژمرد|پژوهید|پسندید|پلاسید|پلکید|پناهید|پنداشت|پوسید|پوشید|پویید|پیچید|پیراست" + "|پیمود|پیوست|تاخت|تافت|تپید|تراشید|تراوید|ترسید|ترشید|ترکید|تکاند|تکانید|تنید|توانست" + "|جست|جُست|جَست|جنبید|جنگید|جوشید|جوید|جهید|چاپید|چایید|چپید|چربید|چرخید|چرید|چسبید|چشید" + "|چکید|چلاند|چلانید|چمید|چید|خارید|خاست|خایید|خراشید|خرامید|خروشید|خرید|خزید|خست" + "|خشکید|خلید|خمید|خوابید|خواست|خواند|خورد|خوفید|خیسید|داد|داشت|دانست|درخشید|دروید" + "|درید|دزدید|دمید|دوخت|دوشید|دوید|دیدم|ربود|رخشید|رسید|رست|رَست|رُست|رشت|رفت|رُفت|روفت" + "|رقصید|رمید|رنجید|رندید|رویید|ریخت|رید|زارید|زایید|زد|زدود|زیست|ساخت|سپرد|سپوخت" + "|ستد|سترد|ستود|ستیزید|سرود|سرشت|سرید|سزید|سفت|سگالید|سنجید|سوخت|سود|شاشید|شایست" + "|شتافت|شد|شست|شکافت|شکست|شکفت|شکیفت|شگفت|شمرد|شناخت|شنید|شورید|طلبید|طوفید|غارتید" + "|غرید|غلطید|غنود|فرستاد|فرسود|فرمود|فروخت|فریفت|فشرد|فهمید|قاپید|قبولاند|کاست" + "|کاشت|کاوید|کرد|کشت|کشید|مکشید|کفت|کفید|کند|کوچید|کوشید|کوفت|گایید|گداخت|گذاشت" + "|گذشت|گرازید|گرایید|گردید|گرفت|گروید|گریخت|گریست|گزارد|گزید|گُزید|گَزید|گسارد|گسترد|گسست" + "|گشت|گشود|گفت|گماشت|گنجید|گندید|گوارید|گوزید|لرزید|لغزید|لمدنی|لندید|لنگید|لهید" + "|لیسید|ماسید|مالید|ماند|مرد|مکید|مولید|مویید|نازید|نالید|نامید|نشست|نکوهید|نگاشت" + "|نگریست|نمود|نواخت|نوردید|نوشت|نوشید|نهاد|نهفت|نیوشید|ورزید|وزید|هراسید|هشت" + "|یارست|یازید|یافت)";

    var re = new RegExp("(^|[^" + EE_faChrs + "])(می|نمی)\\s?" + verbs + "(م|ی|یم|ید|ند|)($|[^" + EE_faChrs + "])", "g");
    str = str.replace(re, "$1$2\u200c$3$4$5");

    //بن‌های مضارع
    verbs = "(آرای|آرام|آزار|آزمای|آسای|آشام|آشوب|آغاز|آغار|آفرین|آگن|آلای|آی|آمرز" + "|آموز|آمیز|آور|آویز|آهنج|ارز|افت|افراز|افروز|افزای|افسر|افشان|افگن" + "|انبار|انجام|انداز|اندوز|اندای|اندیش|انگار|انگیز|اوبار|ایست|باز" + "|بار|باش|باف|بال|بای|بخشای|بخش|براز|بر|بُر|بَر|بند|بساو|بسیج|بلع|بو" + "|بوس|بوی|بیز|پاش|پالای|پز|پذیر|پراکن|پرداز|پرست|پرس|پرور|پر" + "|پژمر|پژوه|پسند|پلاس|پلک|پناه|پندار|پوس|پوش|پوی|پیچ|پیرای" + "|پیمای|پیوند|تاز|تاب|تپ|توپ|تراش|تراو|ترس|ترش|ترک|تکان|تن|توان" + "|جه|جوی|جنب|جنگ|جوش|جو|چاپ|چای|چپ|چرب|چرخ|چر|چسب|چش" + "|چک|چلان|چم|چین|خار|خیز|خای|خراش|خرام|خروش|خر|خز|خست" + "|خشک|خل|خم|خواب|خواه|خوان|خور|خوف|خیس|ده|دار|درخش|درو" + "|در|دزد|دم|دوز|دوش|دو|بین|ربای|رخش|رس|ره|روی|رشت|رو|روب" + "|رقص|رم|رنج|رند|روی|ریز|رین|زار|زای|زن|زدای|زی|ساز|سپر|سپوز" + "|ستان|ستر|ستان|ستیز|سرای|سرشت|سر|سز|سنب|سگال|سنج|سوز|سای|شاش|شای" + "|شتاب|شو|شوی|شکاف|شکن|شکوف|شکیب|شمر|شناس|شنو|شور|طلب|طوف|غارت" + "|غر|غلط|غنو|فرست|فرسای|فرمای|فروش|فریب|فشر|فهم|قاپ|قبولان|کاه" + "|کار|کاو|کن|کار|کُش|کش|کِش|کَش|کف|کن|کوچ|کوش|کوب|گای|گداز|گذار" + "|گذر|گراز|گرای|گرد|گیر|گرو|گریز|گری|گزار|گز|گزین|گسار|گستر|گسل" + "|گشای|گو|گمار|گنج|گند|گوار|گوز|لرز|لغز|لم|لند|لنگ|له" + "|لیس|ماس|مال|مان|میر|مک|مول|موی|ناز|نال|نام|نشین|نکوه|نگار" + "|نگر|نمای|نواز|نورد|نویس|نوش|نه|نهنب|نیوش|ورز|وز|هراس|هل" + "|یار|یاز|یاب)";

    var re = new RegExp("(^|[^" + EE_faChrs + "])(می|نمی)\\s?" + verbs + "(م|ی|د|یم|ید|ند)($|[^" + EE_faChrs + "])", "g");
    str = str.replace(re, "$1$2\u200c$3$4$5");

    // ای «توان» ناقلا!
    str = str.replace(/(می|نمی) ?توان/g, "$1\u200cتوان");

    // چسباندن تمام «ها»ها با فاصلهٔ مجازی
    str = str.replace(/\sها([\]\.،\:»\)\s])/g, '\u200cها$1');
    str = str.replace(/\sها(ی|یی|یم|یت|یش|مان|تان|شان)([\]\.،\:»\)\s])/g, '\u200cها$1$2');

    // برای حذف علامت ستاره اضافی قبل از عنوان‌ها
    str = str.replace(/\n\*\s*(\=+.+?\=+\n)/g, "\n$1");

    // عضو علامت‌های نقل قول تکی از عنوان‌ها
    str = str.replace(/(\n=+)(.*?)(?:'+)(.*?)(?:'+)(.*?)(=+\n)/g, "$1$2$3$4$5");

    // برای حذف فاصله‌های اضافی در پیوندها
    str = str.replace(/\[\[\s*(.*?)\s*]]/g, "[[$1]]");

    // تبدیل به نویسه / یکی‌کردن فاصله‌های مجازی پشت‌سرهم
    str = str.replace(/(\{\{فم\}\}|\&zwnj\;|\u200c+)/g, '\u200c');

    // اول و آخر هم خط اگر فاصلهٔ مجازی باشد، حذف شود
    str = str.replace(/(^\u200c|\u200c$)/mg, '');

    //شناسه‌ها
    //توجه: «است» تعدماً از شناسه ها حذف شده چون به عنوان فعل مستقل هم کاربرد دارد و در آن موارد باید جدا نوشته شود
    // مثال: «این یک خانه است» که است در آن باید از خانه جدا نوشته شود
    str = str.replace(new RegExp("ه\\s+(ام|ای|ایم|اید|اند)($|[^" + EE_faChrs + "])", "g"), 'ه\u200c$1$2');

    // موارد جزئی دیگر و بی‌ربط به فاصلهٔ مجازی، باید منتقل شود
    str = str.replace(/ا\sً/g, 'اً');

   //Function for removing incorrect ZWNJs
    str=RemoveBadZWNJ(str)

    //These two lines are for reverting link's bugs!
    str = links_underline(str, 'Start')
    var old_text = str;
    // end

    //حذف فاصلهٔ مجازی پیش از حروف لاتین 
    //سجاوندی را از بخش واگردانی باگ خارج کردم
    str = str.replace(/\u200c([\w])/g, '$1');
    str = str.replace(/([\w])\u200c/g, '$1');

    //These three lines are for reverting link's bugs!
    diffString(old_text, str);
    str = RevertBug(tupO, tupN, str);
    str = links_underline(str, 'End')
    //end

    //حذف فاصلهٔ مجازی قبل و بعد از سجاوندی 
    str = str.replace(/\u200c([\n\s\[\]\.،«»\:\(\)\؛\؟\?\;\$\!\@\-\=\+\\])/g, '$1');
    str = str.replace(/([\n\s\[\]\.،«»\:\(\)\؛\؟\?\;\$\!\@\-\=\+\\])\u200c/g, '$1');

    return str;
}


/** digitsEnToFa
 *
 *  Description: Takes a string made of English digits only, and
 *  returns a string that represents the same number but with
 *  Persian digits
 *
 */
function digitsEnToFa(str) {
    for (var i = 0; i < 10; i++) {
        reEnToFa = new RegExp("" + i);
        str = str.replace(reEnToFa, EE_faNums[i]);
    }

    return str;
}


/** digitsFaToEn
 *
 *  Description: Takes a string made of English digits only, and
 *  returns a string that represents the same number but with
 *  Persian digits
 *
 */
function digitsFaToEn(str) {
    for (var i = 0; i < 10; i++) {
        reFaToEn = new RegExp(EE_faNums[i]);
        str = str.replace(reFaToEn, i);
    }

    return str;
}


/** digitsArToFa
 *
 *  Description: Takes a string that contains digits, and
 *  replaces all Arabic digits with the corresponding Persian
 *  digits
 *
 */
function digitsArToFa(str) {
    for (var i = 0; i < 10; i++) {
        reArToFa = new RegExp(EE_arNums[i]);
        str = str.replace(reArToFa, EE_faNums[i]);
    }

    return str;
}


/** digits_move
 *
 *  Description: A special flavor of digits() function that is
 *  to be used only on the move page. It is more simplistic than
 *  the digits() function itself.
 *
 */
function digits_move(str) {
    str = fromEntityToUtf8(str, true);

    old = "";
    // Convert all English digits to Persian digits
    while (old != str) {
        old = str;
        re = new RegExp("[0-9]+");
        str = str.replace(re, digitsEnToFa);
    }

    old = "";
    // Convert all Arabic digits to Persian digits
    while (old != str) {
        old = str;
        re = new RegExp("[" + EE_arNums + "]+");
        str = str.replace(re, digitsArToFa);
    }

    return (str);
}


function digits(str) {
    // Disabled for Template namespace, due to recurring problems
    if (mw.config.get('wgNamespaceNumber') == 10) {
        return str;
    } else {
        //These two lines are for reverting link's bugs!
        str = links_underline(str, 'Start')
        var old_text = str;
        // end
        str = fromEntityToUtf8(str, true);
        var old = str;
        // فارسی به انگلیسی
        while (1 == 1) {
            for (var i = 0; i < 10; i++) {
                var reFaToEn = new RegExp("([A-Za-z0-9][^" + EE_faChrs + EE_faNums + "\\n\\{\\}\\|=]*)" + EE_faNums[i] + "([^" + EE_faNums + "\\n\\{\\}\\|=]*?[A-Za-z0-9])", "g");
                old = old.replace(reFaToEn, "$1¬!¬" + i + "$2");
                old = old.replace(/¬!¬/g, "");
                var reFaToEn = new RegExp("(^|[\\n=>])([^" + EE_faChrs + EE_faNums + "\\n\\{\\}\\|=]*)" + EE_faNums[i] + "([^" + EE_faNums + "\\n\\{\\}\\|=]*?[A-Za-z0-9])", "g");
                old = old.replace(reFaToEn, "$1$2¬!¬" + i + "$3");
                old = old.replace(/¬!¬/g, "");
                var reFaToEn = new RegExp("([A-Za-z0-9][^" + EE_faChrs + EE_faNums + "\\n\\{\\}\\|=]*)" + EE_faNums[i] + "([^" + EE_faNums + "\\n\\{\\}\\|=]*?[\\n\\{\\}\\|<$])", "g");
                old = old.replace(reFaToEn, "$1¬!¬" + i + "$2");
                old = old.replace(/¬!¬/g, "");
            }
            if (old == str) break;
            str = old;
        }
        // انگلیسی به فارسی
        while (1 == 1) {
            for (var i = 0; i < 10; i++) {
                var reEnToFa = new RegExp("([" + EE_faChrs + ">][^A-Za-z0-9\\n\\{\\}\\|=]*)" + i + "([^A-Za-z\\n\\{\\}\\|=]*?[<" + EE_faChrs + EE_faNums + "])", "g");
                old = old.replace(reEnToFa, "$1" + EE_faNums[i] + "$2");
                var reEnToFa = new RegExp("(^|[=\\n\\{\\}\\|>])([^A-Za-z0-9\\n\\{\\}\\|=]*)" + i + "([^A-Za-z\\n\\{\\}\\|=]*?[\\n\\{\\}\\|<$])", "g");
                old = old.replace(reEnToFa, "$1$2" + EE_faNums[i] + "$3");
            }
            if (old == str) break;
            str = old;
        }
        // فارسی به انگلیسی (آن‌هایی که صددرصد باید انگلیسی شوند)
        while (1 == 1) {
            for (var i = 0; i < 10; i++) {
                var reFaToEn = new RegExp('(style|colspan|rowspan|cellspacing|width|size|border|thumbtime)( *= *[^\\|\\n]*?)' + EE_faNums[i] + '(.*?\\|)', 'g');
                old = old.replace(reFaToEn, "$1$2¬!¬" + i + "$3");
                old = old.replace(/¬!¬/g, "");
                var reFaToEn = new RegExp('(<math>[^<]*?)' + EE_faNums[i] + '([^<]*<\\/math>)', 'g');
                old = old.replace(reFaToEn, "$1¬!¬" + i + "$2");
                old = old.replace(/¬!¬/g, "");
                var reFaToEn = new RegExp('(https?://[^\\s\\r\\n\\|\\}]*?)' + EE_faNums[i], 'g');
                old = old.replace(reFaToEn, "$1¬!¬" + i);
                old = old.replace(/¬!¬/g, "");
                var reFaToEn = new RegExp('(' + EE_faNums[i] + ')پیکسل', 'g');
                old = old.replace(reFaToEn, "$1¬!¬پیکسل" + i);
                old = old.replace(/¬!¬/g, "");
            }
            if (old == str) break;
            str = old;
        }

        // عربی به فارسی
        for (var i = 0; i < 10; i++) {
            str = str.replace(new RegExp(EE_arNums[i], 'g'), EE_faNums[i]);
        }

        //These three lines are for reverting link's bugs!
        diffString(old_text, str);
        str = RevertBug(tupO, tupN, str);
        str = links_underline(str, 'End')
        //end 

        // Decimal point, and thousands' separator
        str = str.replace(/([۱۲۳۴۵۶۷۸۹۰])\.([۱۲۳۴۵۶۷۸۹۰])/g, '$1٫$2');
        str = str.replace(/([۱۲۳۴۵۶۷۸۹۰]),([۱۲۳۴۵۶۷۸۹۰])/g, '$1٬$2');

        return str;
    }
};


function Punctuation(str) {
    str = str.replace(/ *(\<\/? ?br ?\/?\>|\{\{بر\}\}) */g, "{{سخ}}");

    str = str.replace(/([،\.])([^\s\.\(\)«»\"\[\]\<\>\d\w\{\}\|۰-۹])/g, "$1 $2");

    str = str.replace(/([\(«])\s/g, '$1');
    str = str.replace(/\s([\)»])/g, '$1');
    str = str.replace(/٬\s/g, "، ");

    str = str.replace(/(\<\/ref\>)\s+(\<ref)/g, "$1$2");

    // Format headings level 2 and above
    str = str.replace(/(\={2,})\s*([^\=]*?)\s*(\={2,})/g, "$1 $2 $3");
    // TODO: remove extra lines AFTER this part

    // تغییرات جزئی که برای ربات‌ها تعریف شده بود
    str = str.replace(/[\r\n]{3,}/g, "\n\n");
    str = str.replace(/[\r\n]\s{1,}[\r\n]/g, "\n\n");
    str = str.replace(/([^=])[\r\n]+(\=.*?\=[\r\n]+)/g, "$1\n\n$2");
    str = str.replace(/[\s\r\n]+\<ref/g, "<ref");
    str = str.replace(/([\r\n]?)[\s\r\n]+?\<\/ref\>/g, "$1</ref>");

    // Add a space after the # or * for lists
    str = str.replace(/^([*#]+)([^*#:\s])/mg, "$1 $2");

    // Remove extra newlines between two list lines
    old = "";
    while (str != old) {
        old = str;
        str = str.replace(/(^|\n)(#+[^\n]*)\n\n+([#])/mg, "$1$2\n$3");
        str = str.replace(/(^|\n)(\*+[^\n]*)\n\n+([\*])/mg, "$1$2\n$3");
    }

    //برداشتن حروف نالازم در ابتدا و انتهای عنوان زیر بخش‌های سطح ۲ به بالا
    var notneededs = ":,;'<>»«&^#@•→←↔↑↓—–…~٫،؛ٔ"
    for (var i = 0; i < 27; i++) {
        str = str.replace(new RegExp('((\=+){2,}) ' + notneededs[i], 'g'), "== ");
        str = str.replace(new RegExp(notneededs[i] + ' ((\=+){2,})', 'g'), " $1");
    }

    // Redirect pages must start with #تغییرمسیر with no extra spaces
    // before or inside the تغییرمسیر part, and one space after it but
    // before the link
    str = str.replace(/^#\s*(REDIRECT|تغییر[ _]?مسیر)/ig, '#تغییرمسیر');
    str = str.replace(/^#تغییرمسیر(\S)/g, '#تغییرمسیر $1');

    // Remove extra newline between two lines both starting with a *
    str = str.replace(/(\n\*.*?)\n+(?=\n\*)/g, '$1');

    // فاصله را از آخر خط پاک می‌کند
    str = str.replace(/([^=]) *$/mg, "$1");


    // اصلاح {{•}}
    str = str.replace(/[\n\s]*\{\{[•·ن](w?)\}\}\s*/g, "{{•$1}} ");

    // برای گذاشتن گیومه برای خاصیت‌های برچسب طبق اکس‌ام‌ال
    // اشکال مشخصی که دارد این است که همهٔ نویسه‌های قابل قبول برای اکس‌ام‌ال را نمی‌پذیرد، چه نویسه‌هایی لازم است؟
    var old = "";
    while (old != str) {
        old = str;
        str = str.replace(/(\<\w*(?:\s\w*=['"\w\d]+)*\s+\w*=)([\w\d_]+)((?:\s\w*=['"\w\d]+)*\s?\/?\>)/g, "$1\"$2\"$3")
        // first version: .replace(/\<(\w*\s+\w*=)(\w+[\w\d]*)\>/, "<$1\"$2\">");
    }

    // Remove spaces preceding the }} closing tag for templates
    str = str.replace(/\s+\}\}/g, '}}');

    // Remove space after ( and before ) if there are Persian characters
    // on both sides; also, add a space before ( and after ) in the same
    // situation
    re = new RegExp("([" + EE_faChrs + "]+)\\s*\\(\\s*([" + EE_faChrs + "]+)", "g");
    str = str.replace(re, "$1 ($2");
    re = new RegExp("([" + EE_faChrs + "]+)\\s*\\)\\s*([" + EE_faChrs + "]+)", "g");
    str = str.replace(re, "$1) $2");

    // Full stop and comma should be before citation.
    old = "";
    while (old != str) {
        old = str;
        str = str.replace(/\.? ?(<ref>[^<]*<\/ref>) ?\./g, '.$1');
        str = str.replace(/\،? ?(<ref>[^<]*<\/ref>) ?\،/g, '،$1');
    }

    old = "";
    while (old != str) {
        old = str;
        // Convert , to ، if there are Persian characters on both sides of it
        // and also remove any spaces between the words on each side and the
        // Persian comma itself.
        // NOTE: we will add a space after the comma later on
        var re = new RegExp(" ([ " + EE_faChrs + "]+),([ " + EE_faChrs + "]+)", "g");
        str = str.replace(re, "$1،$2");

        // Remove space preceding puncations
        str = str.replace(/ ([؟،:؛!\.])/g, "$1");


        // Add space after punctuations
        // NOTE: Adds a space after :, which affects internal links (categories, images, etc)
        re = new RegExp("([" + EE_faChrs + "]+)([؟،؛!\.])([" + EE_faChrs + "]+)", "g");
        str = str.replace(re, "$1$2 $3");
    }

    // Remove unnecessary space caused by last line in category links (it had bug for پرونده:)
    re = new RegExp("\\[\\[(رده|الگو|ویکی\u200cپدیا)\\:\\s+", "g");
    str = str.replace(re, "[[$1\:");

    str = str.trim(); //Removing \n and \r from first and end of pages
    return str;
};


/** Dictation Tool
 *
 *  Description: Correcting ZWNJ and diction mistakes
 *  it uses [[مدیاویکی:Gadget-Extra-Editbuttons-Dictionary.js]] as dictionary.
 *
 */
function Regex_Replace(W1, W2, Extensions, str) {
    var regex = new RegExp("(^|[^" + EE_faChrs + "])(\\s|\u200c|\_|)(" + W1 + ")(\\s|\_)(" + W2 + ")(\\s|\u200c|\_|)(" + Extensions + ")($|[^" + EE_faChrs + "])", "g");
    str = str.replace(regex, "$1$2$3\u200c$5$6$7$8");
    return str;
};
function ZWNJ_Dictation(str) {

    //These two lines are for reverting link's bugs!
    str = links_underline(str, 'Start')
    var old_text = str;
    // end
    //for Complexes
    for (var word in Complexes) {
        var W1 = word;
        var W2 = Complexes[word];
        var Extensions = "ی|ها|های|هایی|هایم|هایت|هایش|هایمان|هایتان|هایشان|";
        str = Regex_Replace(W1, W2, Extensions, str)
    };

    //for last name 
    var W1 = Person_Name;
    var W2 = "ی|زاده|نیا|پور|گان|فر|نژاد|یان|ی‌ها|یها";
    var Extensions = "ی|";
    str = Regex_Replace(W1, W2, Extensions, str)
    //for Abad 
    var W1 = Person_Name + "|" + Add2Abad;
    var W2 = "آباد";
    var Extensions = "زاده|نیا|پور|گان|فر|نژاد|ی|یان|ها|های|هایی|ی‌ها|یها|";
    str = Regex_Replace(W1, W2, Extensions, str)
    //for First name 
    for (var word in FirstNameComplex) {
        var W1 = word;
        var W2 = FirstNameComplex[word];
    var regex = new RegExp("(^|[^" + EE_faChrs + "]|\\s|\_)(" + W1 + ")(\\s|\_)(" + W2 + ")(\\s|\_)($|[^" + EE_faChrs + "]|[^+ EE_faChrs +])", "g");
    str = str.replace(regex, "$1$2\u200c$4$5$6");
    };
    //for colors
    var W1 = Color_Name;
    var W2 = "فام|گون";
    var Extensions = "زاده|نیا|پور|گان|فر|نژاد|ی|ها|های|هایی|ی‌ها|یها|هایم|هایت|هایش|هایمان|هایتان|هایشان|";
    str = Regex_Replace(W1, W2, Extensions, str)
    //for Numbers
    var W1 = Farsi_Numbers;
    var W2 = "گانه|ماهه";
    var Extensions = "زاده|نیا|پور|گان|فر|نژاد|ی|ها|های|هایی|هایم|هایت|هایش|هایمان|هایتان|هایشان|";
    str = Regex_Replace(W1, W2, Extensions, str)
    //wrong dictation
    for (var word in ForReplace) {
        var W1 = word;
        var W2 = ForReplace[word];
        var regex = new RegExp("(^|[^" + EE_faChrs + "])(\\s|\u200c|_|)(" + W1 + ")(\\s|\u200c|_|)($|[^" + EE_faChrs + "])", "g");
        str = str.replace(regex, "$1$2" + W2 + "$4$5");
    };

   //Function for removing incorrect ZWNJs
    str=RemoveBadZWNJ(str)

    //حذف فاصلهٔ مجازی قبل و بعد از سجاوندی 
    str = str.replace(/\u200c([\n\s\.،«»\:\(\)\؛\؟\?\;\$\!\@\-\=\+\\])/g, '$1');
    str = str.replace(/([\n\s\.،«»\:\(\)\؛\؟\?\;\$\!\@\-\=\+\\])\u200c/g, '$1');
    //These three lines are for reverting link's bugs!
    diffString(old_text, str);
    str = RevertBug(tupO, tupN, str);
    str = links_underline(str, 'End')
    //end 

    return str;
};
function RemoveBadZWNJ(str) {
    var old=''
    while (old != str) {
        old = str;
		// Remove ZWNJ after characters that don't conncet to the next letter
		re = new RegExp("([" + EE_faNums +
			"0-9" +
			"إأةؤورزژاآدذ" +
			"،؛,\\:" +
			"«»\\/@#$٪×\\*\\(\\)ـ\\-=\\|" +
			"])" + "\u200c");
		str = str.replace(re, "$1");

		// Remove ZWNJ before characters that don't conncet to the previous letter
		re = new RegExp("([" + EE_faNums +
			"0-9" +
			"،؛,\\:" +
			"«»\\/@#$٪×\\*\\(\\)ـ\\-=\\|" +
			"])" + "\u200c");
		str = str.replace(re, "$1"); 
    };
    return str;
};
/** SuperTool
 *
 *  Description: Applies all of YKarabic, FM, NonStandard and digits
 *  functions to the text.
 *
 */
function SuperTool(str) {
    str = YKarabic(str);
    str = FM(str);
    str = NonStandard(str);
    str = digits(str);
    str = Punctuation(str);
    str = URLfix(str);
    return str;
};

/** SuperTool_move
 *
 *  Description: A special flavor of the SuperTool() function
 *  that should only be used on the move page.
 *
 */
function SuperTool_move(str) {
    str = YKarabic(str);
    str = FM(str);
    str = NonStandard(str);
    str = digits_move(str);
    str = Punctuation(str);
    return str;
};