میڈیاویکی:Gadget-Peshkar-functions.js

تفصیل کے لیے کھولیں کے بٹن پر کلک کریں یاددہانی: محفوظ کرنے کے بعد تازہ ترین تبدیلیوں کو دیکھنے کے لیے آپ کو اپنے براؤزر کا کیش صاف کرنا ہوگا۔

  • فائرفاکس/ سفاری: جب Reload پر کلک کریں تو Shift دبا کر رکھیں، یا Ctrl-F5 یا Ctrl-R دبائیں (Mac پر R- )
  • گوگل کروم: Ctrl-Shift-R دبائیں (Mac پر Shift-R-⌘)
  • انٹرنیٹ ایکسپلورر: جب Refresh پر کلک کریں تو Ctrl یا Ctrl-F5 دبائیں
  • اوپیرا: Tools → Preferences میں جائیں اور کیش صاف کریں

// اس فائل کا بڑا حصہ [[:fa:مدیاویکی:Gadget-Extra-Editbuttons-persianwikitools.js]] سے ماخوذ ہے

var peshkarFunctions = (function() {

    var urduHuroof = [
        'آ', 'ا', 'ب', 'پ', 'ت', 'ٹ', 'ث', 'ج', 'چ', 'ح', 'خ', 'د', 'ڈ', 'ذ', 'ر', 'ڑ', 'ز', 'ژ', 'س', 'ش', 'ص', 'ض', 'ط', 'ظ', 'ع', 'غ', 'ف', 'ق', 'ک', 'گ', 'ل', 'م', 'ن', 'و', 'ہ', 'ی', 'ے',
        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
        'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
    ];

    var urduMonths = ["جنوری", "فروری", "مارچ", "اپریل", "مئی", "جون", "جولائی", "اگست", "ستمبر", "اکتوبر", "نومبر", "دسمبر"];
    var arabicMonths = ["محرم", "صفر", "ربیع الاول", "ربیع الثانی", "جمادی الاول", "جمادی الثانی", "رجب", "شعبان", "رمضان", "شوال", "ذو القعدہ", "ذی قعدہ", "ذو الحجہ", "ذی حجہ"];

    //http://www.entitycode.com/
    var htmlEntityCodes = {
        "¡": "¡",
        "¢": "¢",
        "£": "£",
        "¤": "¤",
        "¥": "¥",
        "¦": "¦",
        "§": "§",
        "©": "©",
        "·": "·",
        "×": "×",
        "”": "”",
        "†": "†",
        "‡": "‡",
        "€": "€",
        "«": "«",
        "®": "®",
        "°": "°",
        "±": "±",
        "²": "²",
        "³": "³",
        "¶": "¶",
        "¹": "¹",
        "»": "»",
        "¼": "¼",
        "½": "½",
        "¾": "¾",
        "¿": "¿",
        "÷": "÷",
        "–": "–",
        "—": "—",
        "‘": "‘",
        "’": "’",
        "“": "“",
        "™": "™",
        "•": "•",
        "…": "…",
        "‰": "‰",
        "‹": "‹",
        "›": "›",
        "←": "←",
        "↑": "↑",
        "→": "→",
        "↓": "↓",
        "↔": "↔",
        "↵": "↵",
        "−": "−",
        "√": "√",
        "∞": "∞",
        "◊": "◊",
        "♠": "♠",
        "⌋": "⌋",
        " ": " ",
        "≠": "≠",
        "≈": "≈",
        "≈": "≈",
        "≈": "≈",
        "⌉": "⌉",
        "⌊": "⌊",
        "♦": "♦",
        "ä": "ä",
        "ö": "ö",
        "ü": "ü",
        "ß": "ß",
        "å": "å",
        "‾ ": "‾ ",
        "æ": "æ",
        "ç": "ç",
        "ñ": "ñ",
        "â": "â",
        "á": "á",
        "à": "à",
        "$": "$",
        "♣": "♣",
        "♥": "♥",
        "″": "″",
        "′": "′",
        "⌈": "⌈",
        "…": "…",
        "•": "•",
        "`": "`",
        "±": "±",
        "´": "´",
        "·": "·",
        "½": "½",
        "Ä": "Ä",
        "Ö": "Ö",
        "Ü": "Ü",
        "’": "’",
        "‚": "‚",
        "‚": "‚",
        "”": "”",
        "„": "„",
        "„": "„",
        "‡": "‡",
        "÷": "÷",
        "≤": "≤",
        "≥": "≥",
        "≤": "≤",
        "≥": "≥"
    }; // " , & < > |
    var patterns = {
        arabicDigitsEnglishContext: /[a-z]([\|a-z %"'\._:\;,\-\\\/\(\)\#\^\+\d><–\[\]&?{}](?!\|\|))*\d|(\d|[a-z])[a-z %"'\._:\;\|,\-\\\/\(\)\#\^\+\d><–\[\]&?{}]*[a-z]\d*/gi,
        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|%C2|%A0)/gi,
        diffLink: /\[\[(?:خاص|Special):(?:فرق|Diff)\/[^\|\]]*/gi,
        englishDate: /\d{1,2},? [a-z]{3,} \d{2,4}/gi, // 3, May 2013
        fileNames: /(?:فائل|File|تصوہر|Image)\:.*?(?=\||\]|\n|$)|=.*\.(?:flac|gif|jpeg|jpg|mid|mp3|mpeg|mpg|ogg|pdf|png|svg|wav|webm)$/mgi, // don't capture | after
        fileParameter: /\|\s*(image|تصویر|فائل)\s*\=\s*.*/g,
        ipSign: /\[\[خاص:شراکتیں.*?\]\]/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|
        pageNumber: /page\s*=\s*\d+/g,
        insideQuote: /[^ا]".*?"/g,
        wikilinkTargets: /\[[^\[|\]]+/g,
        nowikiTag: /<nowiki>.+?<\/nowiki>/g,
        preTag: /<pre.*?>.*?<\/pre>/g,
        insideHtmlComment: /<\!\-\-[\s\S]*?\-\->/g,
        linksOnEnglishContext: /[a-z][\:\,\. ]*\[\[[\da-z\-\, ]*/gi,
        mapFrameTag: /<mapframe.*?>[\s\S]*?<\/mapframe>/g,
        mathTag: /<math.*?>[\s\S]*?<\/math>/g,
        parameter: /\{\{\{\d+/gi,
        parenthesesAfterDigits: /\w\s?\([\w\s\.\-]*?\)/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,
        graphTemplate: /(?:\\<div[^\>]+>)?\{\{[ \_]*(?:سانچہ|Template)?(?:[Gg]raph\:?[^\|\}]+).*?[_\s\n]*(?:\{\{.*?\}\}|[^\}])*\}\}(?:\\<\/div\>)?/g,
        templateEnglishName: /(سانچہ|Template):[a-z][a-z\d\-\+_]+/gi,
        templateWithEnglishName: /\{\{[ \_]*(?:سانچہ|Template)?[\x00-\x7a~]*\|.*?\}\}/gi,
        templateParameterName: /\|\s*(?=[a-z_]*\d)[a-z_\d]*\s*\=/gi,
        globalExceptionTag: /(<nowiki>.+?<\/nowiki>|[\s\S]*?\}\})/gi,
        translatedUrl: /.(کوم|کام|اورگ|آرگ|نیٹ|ڈاٹ نیٹ|ڈاٹ آرگ|ڈاٹ کام|ڈاٹ کوم)/g,
        boxVar: /([a-zA-Z][0-9]+) *\=/g,
        url: /\/\/.*?(?=[\s\n\|\}\]<]|$)/gi,
        url2: /\/\/.*?(?:[\s\n\|\}\]<]|$)/gi,
        urlArchive: /\/\/web\.archive\.org[^\|\}\n\\<\>]+/gi,
        mediawikiFunctions: /\{\{\#(?:\{\{.*?\}\}|[^\}])*\}\}/gi,
        articleTitleParts: new RegExp('\\s' + escapeRegExp(mw.config.get('wgTitle')).split(' ').join('\\s|\\s') + '\\s', 'g'),
        catgories: /\[\[(?:زمرہ|[Cc]ategory)\:[^\]]+\]\]/gi,
        rfd: /\{\{مضمون برائے حذف.*\}\}/g
    };

    function escapeRegExp(string) {
        return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
    }

    function escapeRE(s) {
        return s.replace(/([$()*+\-.?[\\\]^{|}])/g, '\\$1');
    }

    function descendingFromComparator(x, y) {
        return x.from - y.from;
    }

    function removeCheckDict(text) {
        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(descendingFromComparator)[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 autoFormatCleanReferences(str) {
        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?:)?\/\/ur.(?: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(
            /<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+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 = /\[\[ *([12][0-9]{3}|[12][0-9]{3}\s*\((عیسوی|ء|ھ|ہجری)\)) *\]\]/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"].concat(urduMonths, arabicMonths);

        /* 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] + ' ';
            }
        );

        /* Missverständliches deutsches Datumsformat durch Langform ersetzen */
        str = str.replace(
            /([\s'(>«])(3[01]|[12][1-9]|0?[1-9])\. *(1[012]|0?[1-9])\. *(?=[12][1-9]{3}[!,.:;?]?[\s')<\]»}|])/g,
            function($0, $1, $2, $3) {
                return $1 + ($2 | 0) + separator + months[$3 | 0] + ' ';
            }
        );
        return str;
    }

    function addColumnToRefTemplate(text) {
        var refTemplate = /\{\{حوالہ\sجات([^\}\{]+)?\}\}/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)) {
                if ((text.match(/<ref/gi) || []).length > 0 && /\{\{حوالہ\sجات([^\}\{]+)?\}\}/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;
    }

    function fixBadLinks(text) {
        text = text.replace(/\[{2}([^\|]+)\|\1\]{2}/gi, '[[$1]]');

        // سنہ اور دنوں کے روابط کو حذف کرنے کے لیے
        text = text.replace(/\[{2}([0-9]+|[0-9]+ [\)\(\u0621-\u0655\u067E\u0686\u0698\u06AF\u06A9\u0643\u06AA\uFED9\uFEDA\u06CC\uFEF1\uFEF2]+)(?:\|([^\]\|\[]+))?\]{2}/g, function(match, p1, p2) {
            var calendar_type = / \((عیسوی|ہجری|ق م|قبل مسیح|ھ|ء)\)/g;
            if (p1 !== p2 && p1.replace(calendar_type, '') === p2) {
                return p2;
            }
            if (p2 === undefined || p1 === p2) {
                if (p1.indexOf(" ") > -1) {
                    var months = [urduMonths, arabicMonths],
                        i;
                    for (i = months.length - 1; i >= 0; i--) {
                        if (p1.indexOf(months[i]) > -1) {
                            return p1.replace(calendar_type, '');
                        }
                    }
                    return "[[" + p1 + "]]";
                }
                return p1;
            }
            return p2;
        });
        return text;
    }

    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, patterns.urlArchive]
                );
            })

            // 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(/\[\[\: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 wikiSubsection(text) {
        return text.replace(/\\<(?:\s*)references?(?:\s*\/|\s*\/\s*)\>/g, '{{حوالہ جات}}')
            .replace(/\{\{(?:[Rr]eflist|[Rr]eferences?|حوالہ[‌ ]?جات)(?=\||\})/g, '{{حوالہ جات')
            .replace(/\=\s*لسٹ\s*\=/g, '= فہرست =')
            .replace(/\=\s*(?:[gG]allery|نگارخانہ|نگار خانہ|(تصاویر|فائلوں|فائل) کی گیلری)\s*\=/g, '= نگارخانہ =')
            .replace(/\=\s*(?:بایوگرافی|بائیوگرافی)\s*\=/g, '= سوانح =')
            .replace(/\=\s*(?:[eE]xternal links|بیرونی لنکس|بیرونی لنک|خارجی روابط|بیرونی روابط)\s*\=/g, '= بیرونی روابط =')
            .replace(/\=\s*(?:[bB]ibliography)\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*(?:[Ff]urther [Rr]eading|مزید پڑھیں|اور پڑھیں|اور پڑھیے|نیز پڑھیے|نیز پڑھیں|مطالعہ بیشتر|مزید مطالعہ)\s*\=/g, '= مزید پڑھیے =')
            .replace(/^\={3,}\s*(مزید دیکھیے|حوالہ جات|بیرونی روابط|مزید پڑھیے|حواشی)\s*\={3,}$/g, '== $1 ==');
    }

    function SubSectionLeveling(text) {
        // ذیلی سرخیوں کی ترتیب
        text = text.replace(/^(\={2,}) *(.*?) *(\={2,})/mg, '$1 $2 $3');
        if ((mw.config.get('wgNamespaceNumber') === 0)) {
            // مضامین جن میں فقط درجۂ اول کی سرخی ہے
            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 autoFormatCleanDatesException(text) {
        return replaceExcept(
            text,
            autoFormatCleanDates,
            [patterns.globalExceptionTag, patterns.fileNames, patterns.galleryTag, patterns.mapFrameTag, patterns.mathTag, patterns.sourceTag, patterns.templateWithEnglishName, patterns.citation, patterns.argumentsBlacklist, patterns.ref]
        );
    }

    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 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}|[0-9]{1,2})\\, (\\d{3,4}|[0-9]{3,4})(\\||\\s|\\n|\$|\\)|\\}|»)([\^a\-zA\-Z])', 'ig'),
                        function(x) {
                            x = x.replace(new RegExp('([\^a\-zA\-Z])(\^|\\||\\s|\\=|\\n|\\(|«|\\:)' + enMonthRegex + ' (\\d{1,2}|[0-9]{1,2})\\, (\\d{3,4}|[0-9]{3,4})(\\||\\s|\\n|\$|\\)|\\}||»)([^a-zA-Z])', 'ig'),
                                '$1$2$4 $3 $5$6$7');
                            x = replaceEnMonth(x);
                            return x;
                        })
                    .replace(new RegExp('([\^a\-zA\-Z])(\^|\\||\\s|\\=|\\n|\\(|«)((\\d{1,2}|[0-9]{1,2}) |)' + enMonthRegex + ' (\\d{3,4}|[0-9]{3,4})(\\||\\s|\\n|$|\\)|\\}|»|\\:)([\^a\-zA\-Z])', 'ig'),
                        function(x) {
                            x = replaceEnMonth(x);
                            return x;
                        }
                    );
            }, [patterns.globalExceptionTag, patterns.fileNames, patterns.ref, patterns.fileParameter, patterns.galleryTag, patterns.mapFrameTag, 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 [[:fa: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%');
    }

    function cleanTemplateBracesFromArticle(text, alwaysRun) { // like [[fa:Special:Diff/18828723]]
        if (mw.config.get('wgNamespaceNumber') !== 0 && !alwaysRun) {
            return text;
        }
        var i = 0;
        for (i = 0; i <= 5; i = i + 1) {
            text = text.replace(/\{\{\{[^\|\}]+\|([^\}]+)\}\}\}/g, '$1')
                .replace(/\{\{\{[^\|\}]+\| *\}\}\}/g, '');
        }

        return text.replace(/\{\{\#(?!invoke)/ig, '{{جا:#')
            .replace(/\{\{ *(PAGENAME|FULLPAGENAMEE|SITENAME|NAMESPACE) *\}\}/g, '{{جا:$1}}');
    }

    function decodeHTMLSymbolEntitiesCodes(text) {
        //&copy; > ©
        return replaceExcept(
            text,
            function decodeEntitiesCodes(text) {
                if (!text) return '';
                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.mapFrameTag, patterns.mathTag, patterns.sourceTag, patterns.templateWithEnglishName, patterns.citation, patterns.url
            ]
        );
    }

    //Selected from [[:en:WP:AutoEd]] script
    function autoEdISBN(str) { //MAIN FUNCTION describes list of fixes

        //Allows WikiMagic to work with ISBNs
        str = str.replace(/ISBN *\-10:|ISBN *\-13:|ISBN *\-10|ISBN *\-13|ISBN:/gi, "ISBN");
        //ISSN regexs from [[:en:Wikipedia:AutoWikiBrowser/Settings/ISSN]]
        str = str.replace(/ISSN\s*(\d)/gi, "ISSN $1");
        str = str.replace(/ISSN (\d)(\d)(\d)(\d)[\.\: ~\=]*(\d)(\d)(\d)([\dx])/gi, "ISSN $1$2$3$4-$5$6$7$8 ");
        str = str.replace(/ISSN (\d)(\d)(\d)(\d)\-(\d)(\d)(\d)x/gi, "ISSN $1$2$3$4-$5$6$7X");
        str = str.replace(/ISSN (\d)(\d)(\d)(\d)\-(\d)(\d)(\d)x/gi, "ISSN $1$2$3$4-$5$6$7X");

        //ISBN regexs from [[:Wikipedia:AutoWikiBrowser/Settings/ISBN-hyph]]
        str = str.replace(/ISBN(\d)/gi, "ISBN $1");
        str = str.replace(/\[\[ *(ISBN [\d\-x]{10,13}) *\]\]/gi, "$1");
        str = str.replace(/\[\[ISBN\|(ISBN\s*[^\]]*)\]\]/gi, "$1");
        str = str.replace(/\[*ISBN\]*\:*[ \t]+([0-9X\-]+)/gi, "ISBN $1");
        str = str.replace(/ISBN +([\d-]{1,9}) (\d+|X\W)/gi, "ISBN $1$2");
        str = str.replace(/\[*ISBN\]*\:* *\[\[Special\:Booksources\/\d*\|([\dxX\- ]+)\]\]/gi, "ISBN $1");
        str = str.replace(/\[isbn\]\:* *(\d)/gi, "ISBN $1");
        str = str.replace(/ISBN (\d{10,10}) - *(\d)/gi, "ISBN $1 ,$2");
        var loopcount = 0;
        while (loopcount < 10) { //'
            str = str.replace(/ISBN (\d{1,9}) (\d|x)/gi, "ISBN $1$2");
            loopcount++;
        }
        str = str.replace(/ISBN (\d{1,9})(x)/gi, "ISBN $1X");
        str = str.replace(/ISBN (\d\d\d\d\d\d\d\d\d(\d|x)) +(\d)/gi, "ISBN $1, $3");
        str = str.replace(/ISBN ([\d-]{12,12}) (\d|x)/gi, "ISBN $1-$2");
        /* broken ISBNs with hyphens */
        // autoFormatter.js > cleanISBNs 
        str = str.replace(
            /(^|[\s#'(*>|])(?:(ISBN\d?\s*=\s*)|ISBN(?:-?1[03]\b| *1[03]:)?:?\s*)(9-?7-?[89]-?)?([013][\d\u2010-\u2012\u2212-]{8,}[\dX]\b)/gim,
            function($0, $1, $2, $3, $4) {
                return $1 + ($2 || 'ISBN ') + ($3 || '').replace(/^9\D*7\D*(\d)\D*/, '97$1-') + $4
                    /* Remove all dashes */
                    .replace(/[^\dX]+/gi, '')
                    /* Group 0 for English books */
                    .replace(/^0([01]\d)(\d{6})\B/, '0$1-$2-')
                    .replace(/^0([2-6]\d\d)(\d{5})\B/, '0$1-$2-')
                    .replace(/^0(7\d{3}|8[0-4]\d\d)(\d{4})\B/, '0$1-$2-')
                    .replace(/^0(8[5-9]\d{3})(\d{3})\B/, '0$1-$2-')
                    .replace(/^0(9[0-4]\d{4})(\d\d)\B/, '0$1-$2-')
                    .replace(/^0(9[5-9]\d{5})(\d)\B/, '0$1-$2-')
                    /* Group 1 for English books */
                    .replace(/^1(0\d)(\d{6})\B/, '1$1-$2-')
                    .replace(/^1([1-3]\d\d)(\d{5})\B/, '1$1-$2-')
                    .replace(/^1(4\d{3}|5[0-4]\d\d)(\d{4})\B/, '1$1-$2-')
                    .replace(/^1(5[5-9]\d{3}|[67]\d{4}|8[0-5]\d{3}|86[0-8]\d\d|869[0-7]\d)(\d{3})\B/, '1$1-$2-')
                    .replace(/^1(869[89]\d\d|8[7-9]\d{4}|9[0-8]\d{4}|99[0-8]\d{3})(\d\d)\B/, '1$1-$2-')
                    .replace(/^1(999\d{4})(\d)\B/, '1$1-$2-')
                    /* Group 3 for German books */
                    .replace(/^3(0[0-24-9]|1\d)(\d{6})\B/, '3$1-$2-')
                    .replace(/^3(03[0-3]|[2-6]\d\d)(\d{5})\B/, '3$1-$2-')
                    .replace(/^3(03[4-6]\d|7\d{3}|8[0-4]\d\d)(\d{4})\B/, '3$1-$2-')
                    .replace(/^3(03[7-9]\d\d|8[5-9]\d{3}|95[4-9]\d\d|9[69]\d{3})(\d{3})\B/, '3$1-$2-')
                    .replace(/^3(9[0-4]\d{4})(\d\d)\B/, '3$1-$2-')
                    .replace(/^3(95[0-3]\d{4}|9[78]\d{5})(\d)\B/, '3$1-$2-')
                    /* Add missing dash after group */
                    .replace(/^([0-57]|6\d\d|8\d|9[0-4]|9[5-8]\d|99[0-8]\d|999\d\d)\B/, '$1-');
            }
        );
        return str;
    }

    //---------------------whitespace.js--------------------------------
    function autoEdWhitespace(str) { //MAIN FUNCTION describes list of fixes

        str = str.replace(/\t/g, " ");

        str = str.replace(/^ ? ? \n/gm, "\n");
        str = str.replace(/(\n\n)\n+/g, "$1");
        str = str.replace(/== ? ?\n\n==/g, "==\n==");
        str = str.replace(/\n\n(\* ?\[?http)/g, "\n$1");

        str = str.replace(/^ ? ? \n/gm, "\n");
        str = str.replace(/\n\n\*/g, "\n*");
        //  str = str.replace(/[ \t][ \t]+/g, " ");
        str = str.replace(/([=\n]\n)\n+/g, "$1");
        str = str.replace(/ \n/g, "\n");

        //==Headings==
        str = str.replace(/^(={1,4} )[ ]*([^= ][^=]*[^= ])[ ]*( ={1,4})$/gm, "$1$2$3");
        str = str.replace(/^(={1,4})([^= ][^=]*[^= ])[ ]+(={1,4})$/gm, "$1$2$3");
        str = str.replace(/^(={1,4})[ ]+([^= ][^=]*[^= ])(={1,4})$/gm, "$1$2$3");

        return str;
    }

    //---------------------htmltowikitext.js--------------------------------
    //Convert HTML to wikitext
    function autoEdHTMLtoWikitext(str) {
        // <b>, <strong>, <i>, and <em> tags
        str = str.replace(/<(B|STRONG)[ ]*>((?:[^<>]|<[a-z][^<>]*\/>|<([a-z]+)(?:| [^<>]*)>[^<>]*<\/\3>)*?)<\/\1[ ]*>/gi, "'''$2'''");
        str = str.replace(/<(I|EM)[ ]*>((?:[^<>]|<[a-z][^<>]*\/>|<([a-z]+)(?:| [^<>]*)>[^<>]*<\/\3>)*?)<\/\1[ ]*>/gi, "''$2''");
        // </br>, <\br>, <br\>, <BR />, ...
        str = str.replace(/<[\\\/]+BR[\\\/\s]*>/gim, "<br />");
        str = str.replace(/<[\\\/\s]*BR[\s]*[\\\/]+[\s]*>/gim, "<br />");
        // <.br>, <br.>, <Br>, ...
        str = str.replace(/<[\s\.]*BR[\s\.]*>/gim, "<br>");
        // <br>>, <<br />, <<br >> ...
        str = str.replace(/<[\s]*(<br[\s\/]*>)/gim, "$1");
        str = str.replace(/(<br[\s\/]*>)[\s]*>/gim, "$1");

        str = str.replace(/<[\\\/\s]*REFERENCES[\\\/\s]*>/gim, "<references />");
        // Repeated references tag
        str = str.replace(/(<references \/>)[\s]*\1/gim, "$1");
        // Make sure <H1>, ..., <H6> is after a newline
        str = str.replace(/([^\r\n ])[\t ]*(<H[1-6][^<>]*>)/gim, "$1\n$2");
        // Make sure </H1>, ..., </H6> is before a newline
        str = str.replace(/(<\/H[1-6][^<>]*>)[\t ]*([^\r\n ])/gim, "$1\n$2");
        // Remove newlines from inside <H1>, ..., <H6>
        var loopcount = 0;
        while (str.search(/<H([1-6])[^<>]*>(?:[^<>]|<\/?[^\/h\r\n][^<>]*>)*?<\/H\1[^<>]*>/gim) >= 0 && loopcount <= 10) {
            str = str.replace(/(<H)([1-6])([^<>]*>(?:[^<>]|<\/?[^\/h\r\n][^<>]*>)*?)[\r\n]((?:[^<>]|<\/?[^\/h\r\n][^<>]*>)*?<\/H)\2([^<>]*>)/gim, "$1$2$3 $4$2$5");
            loopcount++;
        }
        // Replace <H1>, ..., <H6> with wikified section headings
        str = str.replace(/(^|[\r\n])[\t ]*<H1[^<>]*>([^\r\n]*?)<\/H1[\r\n\t ]*>[\t ]*([\r\n]|$)/gim, '$1=$2=$3');
        str = str.replace(/(^|[\r\n])[\t ]*<H2[^<>]*>([^\r\n]*?)<\/H2[\r\n\t ]*>[\t ]*([\r\n]|$)/gim, '$1==$2==$3');
        str = str.replace(/(^|[\r\n])[\t ]*<H3[^<>]*>([^\r\n]*?)<\/H3[\r\n\t ]*>[\t ]*([\r\n]|$)/gim, '$1===$2===$3');
        str = str.replace(/(^|[\r\n])[\t ]*<H4[^<>]*>([^\r\n]*?)<\/H4[\r\n\t ]*>[\t ]*([\r\n]|$)/gim, '$1====$2====$3');
        str = str.replace(/(^|[\r\n])[\t ]*<H5[^<>]*>([^\r\n]*?)<\/H5[\r\n\t ]*>[\t ]*([\r\n]|$)/gim, '$1=====$2=====$3');
        str = str.replace(/(^|[\r\n])[\t ]*<H6[^<>]*>([^\r\n]*?)<\/H6[\r\n\t ]*>[\t ]*([\r\n]|$)/gim, '$1======$2======$3');
        //Replace <ol><li> with #
        str = str.replace(
            /(\\<ol\>[\s\S]+\\<\/ol\>)/g,
            function($1) {
                return $1.replace(/[\r\n] *\\<li\>/g, '\n# ').replace(/\\<\/li\>/g, '');
            }
        ).replace(/\n\\<\/?ol\>/g, '');
        //Replace <ul><li> with *
        str = str.replace(
            /(\\<ul\>[\s\S]+\\<\/ul\>)/g,
            function($1) {
                return $1.replace(/[\r\n] *\\<li\>/g, '\n* ').replace(/\\<\/li\>/g, '');
            }
        ).replace(/\n\\<\/?ul\>/g, '');

        return str;
    }

    //---------------------headlines.js--------------------------------
    function autoEdHeadlines(str) { //MAIN FUNCTION describes list of fixes

        // Remove bold from section headings
        var loopcount = 0;
        while (str.search(/^[=]{1,5}[^=\r\n]*'''[^=\r\n]*[=]{1,5}/gim) >= 0 && loopcount <= 10) { //'
            str = str.replace(/(^[=]{1,5}[^=\r\n]*)'''([^=\r\n]*[=]{1,5})[\t ]*/gim, "$1$2"); //'
            loopcount++;
        }

        // Remove trailing colon from section headings
        str = str.replace(/(^[=]{1,5}[^=\r\n]*)[:]([\t ]*[=]{1,5})[\t ]*/gim, "$1$2");

        // Correct caps in "See also" section
        str = str.replace(/(==[\t ]*)see also([\t ]*==)/gi, "$1See also$2");

        // Change common synonyms for "See also" to "See also", but only if "See also" doesn't exist
        if (!str.match(/=[\t ]*See also[\t ]*=/gi)) {
            str = str.replace(/(==[\t ]*)(?:related topics|related articles|internal links|also see)([\t ]*==)/gi, "$1See also$2");
        }
        // Common synonyms for "External links"
        str = str.replace(/(==[\t ]*)(?:external links?|outside links?|web ?links?|exterior links?)([\t ]*==)/gi, "$1External links$2");

        // Capitalization and/or plural of "References", "Sources", "Further reading"
        str = str.replace(/(==[\t ]*)references([\t ]*==)/gi, "$1References$2");
        str = str.replace(/(==[\t ]*)sources([\t ]*==)/gi, "$1Sources$2");
        str = str.replace(/(==[\t ]*)further readings?([\t ]*==)/gi, "$1Further reading$2");

        return str;
    }


    //---------------------tablestowikitext.js--------------------------------
    function autoEdTablestoWikitext(str) { //MAIN FUNCTION describes list of fixes

        // Remove newlines from inside table specific tags
        var loopcount = 0;
        while (str.search(/(?:<\/?table|<\/?tr|<\/?td|<\/?th)[^<>]*[\r\n]/gi) >= 0 && loopcount <= 10) {
            str = str.replace(/((?:<\/?table|<\/?tr|<\/?td|<\/?th)[^<>]*)[\r\n]/gi, "$1 ");
            loopcount++;
        }
        // Remove extra whitespace from inside table specific tags
        str = str.replace(/(<table|<tr|<td|<th)([^<>]*?)[\s]+(>)/gim, "$1$2$3");
        str = str.replace(/(<table|<tr|<td|<th)([^<>]*?)[\s][\s]+/gim, "$1$2 ");
        // Remove any extra junk </tr>, </td>, </th>, </table>
        str = str.replace(/(<\/table|<\/tr|<\/td|<\/th)[^<>]+(>)/gim, "$1$2");
        // Remove space whitespace after </tr>, </td>, </th>, <table>
        str = str.replace(/(<\/tr>|<\/td>|<\/th>|<table[^<>]*>)[\s]+/gim, "$1");
        // Remove space before <tr>, <td>, <th>, </table>
        str = str.replace(/[\s]+(<\/table>|<tr[^<>]*>|<td[^<>]*>|<th[^<>]*>)/gim, "$1");
        // Replace '<table>' with '{|'
        str = str.replace(/<table( [^<>]*|)>[\s]*/gim, "{|$1\n");
        // Replace '</table>' with '|}'
        str = str.replace(/[\s]*<\/table>/gi, "\n|}");
        // Replace '</td><td>' with '||'
        str = str.replace(/<\/td[\s]*>[\s]*<td[\s]*>/gim, "||");
        str = str.replace(/<\/td[\s]*>[\s]*<td ([^<>]+)>/gim, "|| $1 |");
        // Replace '</th><th>' with '!!'
        str = str.replace(/<\/th[\s]*>[\s]*<th[\s]*>/gim, "!!");
        str = str.replace(/<\/th[\s]*>[\s]*<th ([^<>]+)>/gim, "!! $1 |");
        // Replace '</td></tr>' and '</th></tr>' with EOL
        str = str.replace(/<\/(?:td|th)>[\s]*<\/tr>[\s]/gim, "\n");
        // Replace '</td>', '</th>', '</tr>' with EOL
        str = str.replace(/<\/(?:td|th|tr)>[\s]*/gim, "\n");
        // Replace '<tr>' with '|-'
        str = str.replace(/[\s]*<tr>[\s]*/gim, "\n|-\n");
        str = str.replace(/[\s]*<tr ([^<>]*)>[\s]*/gim, "\n|- $1\n");
        // Replace '<td>' with "|"
        str = str.replace(/[\s]*<td>([^\s])/gim, "\n| $1");
        str = str.replace(/[\s]*<td>([\s])/gim, "\n|$1");
        str = str.replace(/[\s]*<td[\s]*([^<>]*?)[\s]*>([^\s])/gim, "\n| $1 | $2");
        str = str.replace(/[\s]*<td[\s]*([^<>]*?)[\s]*>([\s])/gim, "\n| $1 |$2");
        // Replace '<th>' with '!'
        str = str.replace(/[\s]*<th>([^\s])/gim, "\n! $1");
        str = str.replace(/[\s]*<th>([\s])/gim, "\n!$1");
        str = str.replace(/[\s]*<th[\s]*([^<>]*?)[\s]*>([^\s])/gim, "\n! $1 | $2");
        str = str.replace(/[\s]*<th[\s]*([^<>]*?)[\s]*>([^\s])/gim, "\n! $1 |$2");

        return str;
    }

    //---------------------extrabreaks.js--------------------------------
    function autoEdExtraBreaks(str) { //MAIN FUNCTION describes list of fixes

        //Usually unneeded BR tags from ends of image descriptions and wikilinks (]]), templates (}}), template parameters (|)
        str = str.replace(/[\t ]*<[\s\/\.]*br[\s\/\.]*>[\t ]*([\t\n ]*?)(\]\]|}}|\|)/gim, "$1$2");
        //BR tag before a list item
        str = str.replace(/[\t ]*<[\s\/\.]*br[\s\/\.]*>[\t ]*([\s]*?[\n]\*)/gim, "$1");
        //BR tag followed by at least two newlines
        str = str.replace(/[\t ]*<[\s\/\.]*br[\s\/\.]*>[\t ]*([\n])[\t ]*([\n])/gim, "$1$2");

        return str;
    }

    function sortUrdu(a, b) {
        let i = 0;
        while (i < Math.min(a.length, b.length) && a[i] === b[i]) {
            i++;
        }
        if (i < Math.min(a.length, b.length)) {
            return urduHuroof.indexOf(a[i]) - urduHuroof.indexOf(b[i]);
        }
        return a.length - b.length;
    }

    function sortCategories(content) {
        return content.replace(/((?:\n\[\[زمرہ:.+\]\])+)/, function(categories) {
            var categoryLines = categories.trim().split('\n');
            var sortedCategories = categoryLines.sort(sortUrdu);
            return '\n' + sortedCategories.map(function(line, i) {
                // Check if the category matches the page title and adjust the sorting index
                if (line.indexOf('[[زمرہ:' + mw.config.get('wgPageName') + ']]') === 0) {
                    line = '[[زمرہ:' + mw.config.get('wgPageName') + '| ]]';
                    i = -1; // Place this category at the top
                }
                return {
                    index: i,
                    content: line
                };
            }).sort(function(x, y) {
                return x.index - y.index;
            }).map(function(x) {
                return x.content;
            }).join('\n');
        });
    }

    // بعض الفاظ کے آخر میں دو زبر لگانے کے لیے
    function addDoZabar(words, text) {
        words.forEach(word => {
            const DOZABAR = '\u064B';
            const regex = new RegExp('(?<!\\S)' + word + '(?!\\S)(?!' + DOZABAR + ')', 'g');
            text = text.replace(regex, word + DOZABAR);
        });
        return text;
    }

    // چند ضروری فارمیٹنگ کا نفاذ
    function formatText(text) {
        text = text.replace(/(\۔)(?![\s\d\[\]\{\}\(\)<>»﴾\'\"\%])/g, '$1 ')
            .replace(/(\،)(?![\s\d\[\]\{\}\(\)<>»﴾\'\"\%])/g, '$1 ')
            .replace(/\s+(\،)/g, '$1')
            .replace(/\s+(\۔)/g, '$1')
            .replace(/\n\*\s*(\=+.+?\=+\n)/g, '\n$1')
            .replace(/(\n=+)(.*?)(?:'+)(.*?)(?:'+)(.*?)(=+\n)/g, '$1$2$3$4$5')
            .replace(/<ref>([\s\S]*?)<\/ref>\s*([،۔])/g, '$2<ref>$1</ref>')
            .replace(/(\s)?<ref>/g, '<ref>')
            .replace(/<\/ref>(\s)?(?=[\w\u0600-\u06FF])/g, '</ref> ');

        if (mw.config.get('wgNamespaceNumber') === 0) {
            text = text.replace(/(?<=\n|^)\=\s*([^=]+?)\s*\=(?=\r?\n|$)/gm, '== $1 ==');
        }

        return text;
    }

    // خانۂ معلومات کے سانچوں کے کلیدی الفاظ
    const keywords = ['infobox', 'Infobox', 'Geobox', 'geobox', 'Taxobox', 'taxobox', 'Drugbox', 'drugbox', 'Chembox', 'chembox', 'Japanese city', 'japanese city', 'india districts', 'India Districts', 'خانہ معلومات', 'خانۂ معلومات'];
    // خانۂ معلومات کی ترتیب و تنظیم کے لیے
    function formatInfoboxContent(content) {
        if (/^\|\s*[^|\s]/gm.test(content)) {
            return content;
        }
        return content.replace(/\|(?![^[]*\]\])(?![^<]*>)/g, '\n|');
    }

    // خانۂ معلومات کو اخذ کرنے کے لیے
    function extractTemplates(text, keywords) {
        const templates = [];
        let templateStart = -1;
        let level = 0;
        let inTemplate = false;

        for (let i = 0; i < text.length; i++) {
            if (text[i] === '{' && text[i + 1] === '{') {
                if (!inTemplate) {
                    inTemplate = true;
                    templateStart = i;
                }
                level++;
                i++;
            } else if (text[i] === '}' && text[i + 1] === '}') {
                level--;
                if (level === 0 && inTemplate) {
                    const templateEnd = i + 1;
                    let templateText = text.substring(templateStart, templateEnd + 1);
                    const keyword = templateText.substring(2).split('|')[0].trim();
                    if (new RegExp(`^(${keywords.join('|')})`, 'i').test(keyword)) {
                        // خانۂ معلومات کے مندرجات کی ترتیب کے لیے
                        templateText = '{{' + formatInfoboxContent(templateText.slice(2, -2));
                        if (templateText[templateText.length - 1] !== '\n') {
                            templateText += '\n';
                        }
                        templateText += '}}';
                        if (text.substring(templateEnd + 1).charAt(0) !== '\n') {
                            templateText += '\n';
                        }
                        templates.push({
                            original: text.substring(templateStart, templateEnd + 1),
                            formatted: templateText
                        });
                    }
                    inTemplate = false;
                    templateStart = -1;
                }
                i++;
            }
        }
        templates.forEach(({
            original,
            formatted
        }) => {
            text = text.replace(original, formatted);
        });
        return text;
    }

    // کیفیت نامہ کے اینی میشن کے لیے
    function showStatusAnimation() {
        const statusBox = document.createElement('div');
        statusBox.id = 'statusBox';
        document.body.appendChild(statusBox);

        const header = document.createElement('div');
        header.className = 'status-header';
        header.textContent = 'براہ کرم کچھ توقف کیجیے';
        statusBox.appendChild(header);

        const dotsContainer = document.createElement('div');
        dotsContainer.style.display = 'flex';
        dotsContainer.style.justifyContent = 'center';

        for (let i = 1; i <= 9; i++) {
            const dot = document.createElement('span');
            dot.className = 'dot';
            dotsContainer.appendChild(dot);
        }

        statusBox.appendChild(dotsContainer);

        const dots = statusBox.querySelectorAll('.dot');
        let currentDot = 0;
        const intervalId = setInterval(() => {
            dots.forEach(dot => {
                dot.style.transform = 'scale(1)';
                dot.style.backgroundColor = '#4a5969';
            });

            dots[currentDot].style.transform = 'scale(2)';
            dots[currentDot].style.backgroundColor = '#88d646';

            currentDot = (currentDot + 1) % dots.length;
        }, 200);

        setTimeout(() => {
            clearInterval(intervalId);
            statusBox.remove();
        }, 300000);
    }

    function removeStatusAnimation() {
        const statusBox = document.getElementById('statusBox');
        if (statusBox) {
            statusBox.remove();
        }
    }

    // فرق صفحہ کھولنے کے لیے
    function openDiffPage(page) {
        const diffUrl = mw.util.getUrl(page, {
            diff: 'cur',
            oldid: 'prev'
        });
        window.location.href = diffUrl;
    }

    function replaceMand(text) {
        const pattern = /(ب|پ|ت|ٹ|ث|چ|ح|خ|ش|ص|ض|ط|ظ|ع|غ|ف|ق|ل|م|ن|ہ|ی)(مند)( |وں|ی|اں|ان|،|۔|\n)/g;
        text = text.replace(pattern, '$1 $2$3');
        return text;
    }

    function replaceBey(text) {
        const urduWords = [
            'بیشرم',
            'بیضرر',
            'بیقابو',
            'بیعزتی',
            'بیشک',
            'بیترتیب',
            'بیایمان',
            'بیکار',
            'بیتحاشا',
            'بینامی',
            'بیخبری',
            'بیقدر',
            'بیاتفاقی',
            'بیوفا',
            'بیروزگاری',
            'بیگھر',
            'بیہودگی',
            'بیہودہ',
            'بیقرار',
            'بیوفائی',
            'بیوجہ',
            'بیگناہ',
            'بیدوا',
            'بیگانہ',
            'بیگانگی',
            'بیوقوف',
            'بیمزہ',
            'بیسائز',
            'بیمیل',
            'بیروحی',
            'بیعقل',
            'بیحد',
            'بیحال',
            'بیغیرت',
            'بیسبب',
            'بیمقصد',
            'بیتحاشا',
            'بیداغ',
            'بیلاگ',
            'بیلوث',
            'بینوا',
            'بیزبان',
            'بیزار',
            'بیآبرو',
            'بیآسرا',
            'بیسہارا',
            'بیسہاروں',
            'بیمثال'
        ];

    const regexPattern = /(\[\[.*?\]\]|\{\{.*?\}\}|بی(\S*))/g;

    urduWords.forEach(function(word) {
        var baseWord = word.slice(2);
        text = text.replace(regexPattern, function(match, p1, p2) {
            if (match.startsWith('[[') || match.startsWith('{{')) {
                return match;
            }
            if (p2 && p2.startsWith(baseWord)) {
                return 'بے ' + p2;
            }
            return match;
        });
    });
    
    text = text.replace(/بے([^\s،\.۔'"(){}[\]\|])/g, 'بے $1');
    return text;
}

    return {
        autoEdISBN: autoEdISBN,
        autoEdWhitespace: autoEdWhitespace,
        autoEdHTMLtoWikitext: autoEdHTMLtoWikitext,
        autoEdHeadlines: autoEdHeadlines,
        autoEdTablestoWikitext: autoEdTablestoWikitext,
        autoEdExtraBreaks: autoEdExtraBreaks,
        decodeHTMLSymbolEntitiesCodes: decodeHTMLSymbolEntitiesCodes,
        extractTemplates: extractTemplates,
        formatText: formatText,
        addDoZabar: addDoZabar,
        wikiSubsection: wikiSubsection,
        SubSectionLeveling: SubSectionLeveling,
        wikiUrlMinifier: wikiUrlMinifier,
        wikitranslateEnMonth: wikitranslateEnMonth,
        autoFormatCleanReferences: autoFormatCleanReferences,
        autoFormatCleanTags: autoFormatCleanTags,
        autoFormatCleanDuplicateLinks: autoFormatCleanDuplicateLinks,
        addColumnToRefTemplate: addColumnToRefTemplate,
        fixBadLinks: fixBadLinks,
        robustToEnglishDigits: robustToEnglishDigits,
        toEnglishDigits: toEnglishDigits,
        cleanTemplateBracesFromArticle: cleanTemplateBracesFromArticle,
        removeCheckDict: removeCheckDict,
        showStatusAnimation: showStatusAnimation,
        removeStatusAnimation: removeStatusAnimation,
        openDiffPage: openDiffPage,
        replaceBey: replaceBey,
        replaceMand: replaceMand,
        sortCategories: sortCategories
    };
}());

if (typeof window !== "undefined") {
    window.peshkarFunctions = peshkarFunctions;
}