सदस्य:Siddhartha Ghai/pagecreator.js

विक्षनरी से

ध्यान दें: प्रकाशित करने के बाद बदलाव देखने के लिए आपको अपने ब्राउज़र के कैश को हटाना पड़ सकता है।

  • Firefox/Safari: Reload क्लिक समय Shift दबाएँ, या फिर Ctrl-F5 या Ctrl-R दबाएँ (Mac पर ⌘-R)
  • Google Chrome: Ctrl-Shift-R दबाएँ (Mac पर ⌘-Shift-R)
  • Internet Explorer/Edge: Refresh पर क्लिक करते समय Ctrl दबाएँ, या Ctrl-F5 दबाएँ
  • Opera: Ctrl-F5 दबाएँ।
//<nowiki>
/**
* Page Creator: A userscript for semi-automated
* creation of entries on the hindi wiktionary.
* 
* Author: Siddhartha Ghai, 2014
* 
* License: CC-BY-SA 3.0
* 
* Documentation:
* https://hi.wiktionary.org/wiki/User:Siddhartha_Ghai/pagecreator
* 
* Version 0.1 alpha - 8 March 2014
*/
( function ( window, document, $, undefined ) { // Wrap with anonymous function
$( document ).ready(function () {

	var edittoken = mw.user.tokens.get( 'editToken' ),
	msg = {
		en : {
			'af': 'Afrikaans',
			'am': 'Amharic',
			'an': 'Aragonese',
			'ang': 'Old English',
			'ar': 'Arabic',
			'ast': 'Asturian',
			'ay': 'Aymara',
			'az': 'Azerbaijani',
			'be': 'Belarusian',
			'bg': 'Bulgarian',
			'bn': 'Bengali',
			'br': 'Breton',
			'bs': 'Bosnian',
			'ca': 'Catalan',
			'chr': 'Cherokee',
			'co': 'Corsican',
			'cs': 'Czech',
			'csb': 'Kashubian',
			'cy': 'Welsh',
			'da': 'Danish',
			'de': 'German',
			'dv': 'Divehi',
			'el': 'Greek',
			'en': 'English',
			'eo': 'Esperanto',
			'es': 'Spanish',
			'et': 'Estonian',
			'eu': 'Basque',
			'fa': 'Persian',
			'fi': 'Finnish',
			'fj': 'Fijian',
			'fo': 'Faroese',
			'fr': 'French',
			'fy': 'Western Frisian',
			'ga': 'Irish',
			'gd': 'Scottish Gaelic',
			'gl': 'Galician',
			'gn': 'Guarani',
			'gu': 'Gujarati',
			'gv': 'Manx',
			'ha': 'Hausa',
			'he': 'Hebrew',
			'hi': 'Hindi',
			'hr': 'Croatian',
			'hsb': 'Upper Sorbian',
			'ht': 'Haitian',
			'hu': 'Hungarian',
			'hy': 'Armenian',
			'ia': 'Interlingua',
			'id': 'Indonesian',
			'ie': 'Interlingue',
			'io': 'Ido',
			'is': 'Icelandic',
			'it': 'Italian',
			'iu': 'Inuktitut',
			'ja': 'Japanese',
			'jbo': 'Lojban',
			'jv': 'Javanese',
			'ka': 'Georgian',
			'kk': 'Kazakh',
			'kl': 'Kalaallisut',
			'km': 'Khmer',
			'kn': 'Kannada',
			'ko': 'Korean',
			'ks': 'Kashmiri',
			'ku': 'Kurdish',
			'kw': 'Cornish',
			'ky': 'Kyrgyz',
			'la': 'Latin',
			'lb': 'Luxembourgish',
			'li': 'Limburgish',
			'ln': 'Lingala',
			'lo': 'Lao',
			'lt': 'Lithuanian',
			'lv': 'Latvian',
			'mg': 'Malagasy',
			'mi': 'Maori',
			'mk': 'Macedonian',
			'ml': 'Malayalam',
			'mn': 'Mongolian',
			'mr': 'Marathi',
			'ms': 'Malay',
			'mt': 'Maltese',
			'my': 'Burmese',
			'na': 'Nauru',
			'nah': 'Nahuatl',
			'nds': 'Low German',
			'ne': 'Nepali',
			'nl': 'Dutch',
			'nn': 'Norwegian Nynorsk',
			'no': 'Norwegian',
			'oc': 'Occitan',
			'om': 'Oromo',
			'or': 'Oriya',
			'pa': 'Punjabi',
			'pl': 'Polish',
			'pnb': 'Western Punjabi',
			'ps': 'Pashto',
			'pt': 'Portuguese',
			'qu': 'Quechua',
			'ro': 'Romanian',
			'roa-rup': 'Aromanian',
			'ru': 'Russian',
			'rw': 'Kinyarwanda',
			'sa': 'Sanskrit',
			'scn': 'Sicilian',
			'sd': 'Sindhi',
			'sg': 'Sango',
			'sh': 'Serbo-Croatian',
			'si': 'Sinhala',
			'simple': 'Simple English',
			'sk': 'Slovak',
			'sl': 'Slovenian',
			'sm': 'Samoan',
			'so': 'Somali',
			'sq': 'Albanian',
			'sr': 'Serbian',
			'ss': 'Swati',
			'st': 'Southern Sotho',
			'su': 'Sundanese',
			'sv': 'Swedish',
			'sw': 'Swahili',
			'ta': 'Tamil',
			'te': 'Telugu',
			'tg': 'Tajik',
			'th': 'Thai',
			'ti': 'Tigrinya',
			'tk': 'Turkmen',
			'tl': 'Tagalog',
			'tn': 'Tswana',
			'tpi': 'Tok Pisin',
			'tr': 'Turkish',
			'ts': 'Tsonga',
			'tt': 'Tatar',
			'ug': 'Uyghur',
			'uk': 'Ukrainian',
			'ur': 'Urdu',
			'uz': 'Uzbek',
			'vec': 'Venetian',
			'vi': 'Vietnamese',
			'vo': 'Volapük',
			'wa': 'Walloon',
			'wo': 'Wolof',
			'yi': 'Yiddish',
			'zh': 'Chinese',
			'zh-min-nan': 'Min Nan',
			'zu': 'Zulu',
			'n-0': '0',
			'n-1': '1',
			'n-2': '2',
			'n-3': '3',
			'n-4': '4',
			'n-5': '5',
			'n-6': '6',
			'n-7': '7',
			'n-8': '8',
			'n-9': '9',
			'n-plus': '+',
			'name': 'Page Creator',
			'error-login': 'Error!\nPlease login to use the Page Creator script',
			'error-maxtabs': 'Error!\nThe maximum number of tabs is nine',
			'addLang': 'Add Language',
			'lang': 'Language',
			'meaning': 'Meaning',
			'type': 'Type',
			'noun': 'Noun',
			'pronoun': 'Pronoun',
			'verb': 'Verb',
			'adjective': 'Adjective',
			'adverb': 'Adverb',
			'adposition': 'Adposition',
			'conjunction': 'Conjunction',
			'interjection': 'Interjection',
			'synonyms': 'Synonyms',
			'antonyms': 'Antonyms',
			'translations': 'Translation(s)',
			'preview-header': 'Preview',
			'preview-toptext': 'Remember that this is only a preview. Your changes have not yet been saved!',
			'button-addMeaning': 'Add Meaning',
			'button-preview': 'Preview',
			'button-save': 'Save',
			'button-addTrans': 'Add Translation',
			'optgroup-pref': 'Preferred',
			'optgroup-all': 'All'
			},
		hi : {
			'af': 'अफ़्रीकी',
			'am': 'अम्हेरी',
			'an': 'अर्गोनी',
			'ang': 'पुरानी अंग्रेज़ी',
			'ar': 'अरबी',
			'ast': 'अस्तुरियन',
			'ay': 'आयमारा',
			'az': 'अज़रबैजानी',
			'be': 'बेलारूसी',
			'bg': 'बल्गेरियाई',
			'bn': 'बंगाली',
			'br': 'ब्रेटन',
			'bs': 'बोस्नियाई',
			'ca': 'कातालान',
			'chr': 'चेरोकी',
			'co': 'कोर्सीकन',
			'cs': 'चेक',
			'csb': 'काशुबियन',
			'cy': 'वेल्श',
			'da': 'डेनिश',
			'de': 'जर्मन',
			'dv': 'दिवेही',
			'el': 'यूनानी',
			'en': 'अंग्रेज़ी',
			'eo': 'एस्पेरेंतो',
			'es': 'स्पेनिश',
			'et': 'एस्तोनियाई',
			'eu': 'बास्क',
			'fa': 'फ़ारसी',
			'fi': 'फीनिश',
			'fj': 'फ़ीजी',
			'fo': 'फ़ैरोइज़',
			'fr': 'फ्रेंच',
			'fy': 'पश्चिमी फ़्रिसियाई',
			'ga': 'आयरिश',
			'gd': 'स्काट्स् गायेलिक्',
			'gl': 'गैलिशियन',
			'gn': 'गुआरानी',
			'gu': 'गुजराती',
			'gv': 'मैंक्स',
			'ha': 'हौसा',
			'he': 'हिब्रू',
			'hi': 'हिंदी',
			'hr': 'क्रोएशियाई',
			'hsb': 'ऊपरी सॉर्बियन',
			'ht': 'हैतियाई',
			'hu': 'हंगेरियाई',
			'hy': 'आर्मेनियाई',
			'ia': 'ईन्टरलिंगुआ',
			'id': 'इंडोनेशियाई',
			'ie': 'ईन्टरलिंगुइ',
			'io': 'इडौ',
			'is': 'आइसलैंडी',
			'it': 'इतालवी',
			'iu': 'इनूकीटूत्',
			'ja': 'जापानी',
			'jbo': 'लोज्बान',
			'jv': 'जावानीस',
			'ka': 'जॉर्जियाई',
			'kk': 'कज़ाख़',
			'kl': 'ग्रीनलैंडिक',
			'km': 'खमेर',
			'kn': 'कन्नड़',
			'ko': 'कोरियाई',
			'ks': 'कश्मीरी',
			'ku': 'कुर्दी',
			'kw': 'कोर्निश',
			'ky': 'किर्गीज़',
			'la': 'लातिनी',
			'lb': 'लग्ज़मबर्गी',
			'li': 'लिंबर्गिश',
			'ln': 'लिंगाला',
			'lo': 'लाओ',
			'lt': 'लिथुआनियाई',
			'lv': 'लातवियाई',
			'mg': 'मालागासी',
			'mi': 'माओरी',
			'mk': 'मैसिडोनियाई',
			'ml': 'मलयालम',
			'mn': 'मंगोलीयाई',
			'mr': 'मराठी',
			'ms': 'मलय',
			'mt': 'माल्टीज़',
			'my': 'बर्मीज़',
			'na': 'नाउरू',
			'nah': 'नहुआत्ल',
			'nds': 'निचला जर्मन',
			'ne': 'नेपाली',
			'nl': 'डच',
			'nn': 'नॉर्वेजियाई नॉयनॉर्स्क',
			'no': 'नॉर्वेजियाई',
			'oc': 'ओसीटान',
			'om': 'ओरोमो',
			'or': 'उड़िया',
			'pa': 'पंजाबी',
			'pl': 'पोलिश',
			'pnb': 'पश्चिमी पंजाबी',
			'ps': 'पश्तो',
			'pt': 'पुर्तगाली',
			'qu': 'क्वेचुआ',
			'ro': 'रोमानियाई',
			'roa-rup': 'अरोमानियन',
			'ru': 'रूसी',
			'rw': 'किन्यारवाण्डा',
			'sa': 'संस्कृत',
			'scn': 'सिसिलियन',
			'sd': 'सिंधी',
			'sg': 'सांगो',
			'sh': 'सेर्बो-क्रोएशन्',
			'si': 'सिंहली',
			'simple': 'सरल अंग्रेज़ी',
			'sk': 'स्लोवाक',
			'sl': 'स्लोवेनियाई',
			'sm': 'सामोन',
			'so': 'सोमाली',
			'sq': 'अल्बानियाई',
			'sr': 'सर्बियाई',
			'ss': 'स्वाती',
			'st': 'सेसोथो',
			'su': 'सुंडानी',
			'sv': 'स्वीडिश',
			'sw': 'स्वाहिली',
			'ta': 'तमिल',
			'te': 'तेलुगू',
			'tg': 'ताजिक',
			'th': 'थाई',
			'ti': 'तिग्रीन्या',
			'tk': 'तुर्कमेन',
			'tl': 'तागालोग',
			'tn': 'सेत्स्वाना',
			'tpi': 'टोक पिसिन',
			'tr': 'तुर्की',
			'ts': 'सोंगा',
			'tt': 'तातार',
			'ug': 'विघुर',
			'uk': 'यूक्रेनियाई',
			'ur': 'उर्दू',
			'uz': 'उज़्बेक',
			'vec': 'वेनीशियाई',
			'vi': 'वियतनामी',
			'vo': 'वोलापुक',
			'wa': 'वाल्लून',
			'wo': 'वोलोफ़',
			'yi': 'येहुदी',
			'zh': 'चीनी',
			'zh-min-nan': 'मिन नान',
			'zu': 'ज़ुलू',
			'n-0': '०',
			'n-1': '१',
			'n-2': '२',
			'n-3': '३',
			'n-4': '४',
			'n-5': '५',
			'n-6': '६',
			'n-7': '७',
			'n-8': '८',
			'n-9': '९',
			'n-plus': '+',
			'name': 'पृष्ठ निर्माता',
			'error-login': 'त्रुटि!\nपृष्ठ निर्माता स्क्रिप्ट का प्रयोग करने के लिए कृपया लॉगिन करें',
			'error-maxtabs': 'त्रुटि!\nटैबों की अधिकतम संख्या नौ है',
			'addLang': 'भाषा जोड़ें',
			'lang': 'भाषा',
			'meaning': 'अर्थ',
			'type': 'प्रकार',
			'noun': 'संज्ञा',
			'pronoun': 'सर्वनाम',
			'verb': 'क्रिया',
			'adjective': 'विशेषण',
			'adverb': 'क्रिया विशेषण',
			'adposition': 'संबंध बोधक',
			'conjunction': 'समुच्चय बोधक',
			'interjection': 'विस्मयादि बोधक',
			'synonyms': 'पर्यायवाची',
			'antonyms': 'विलोम',
			'translations': 'अनुवाद',
			'preview-header': 'झलक',
			'preview-toptext': 'याद रखें, यह केवल एक झलक है और अभी तक सुरक्षित नहीं किया गया है!',
			'button-addMeaning': 'अर्थ जोड़ें',
			'button-preview': 'पूर्वावलोकन',
			'button-save': 'सहेजें',
			'button-addTrans': 'अनुवाद जोड़ें',
			'optgroup-pref': 'पसंदीदा',
			'optgroup-all': 'सभी'
			}
	},
	lang = mw.config.get( 'wgUserLanguage' ),
	langcodes = ["af", "am", "an", "ang", "ar", "ast", "ay", "az", "be", "bg", "bn", "br", "bs", "ca", "chr", "co", "cs", "csb", "cy", "da", "de", "dv", "el", "en", "eo", "es", "et", "eu", "fa", "fi", "fj", "fo", "fr", "fy", "ga", "gd", "gl", "gn", "gu", "gv", "ha", "he", "hi", "hr", "hsb", "hu", "hy", "ia", "id", "ie", "io", "is", "it", "iu", "ja", "jbo", "jv", "ka", "kk", "kl", "km", "kn", "ko", "ks", "ku", "kw", "ky", "la", "lb", "li", "ln", "lo", "lt", "lv", "mg", "mi", "mk", "ml", "mn", "mr", "ms", "mt", "my", "na", "nah", "nds", "ne", "nl", "nn", "no", "oc", "om", "or", "pa", "pl", "pnb", "ps", "pt", "qu", "ro", "roa-rup", "ru", "rw", "sa", "scn", "sd", "sg", "sh", "si", "simple", "sk", "sl", "sm", "so", "sq", "sr", "ss", "st", "su", "sv", "sw", "ta", "te", "tg", "th", "ti", "tk", "tl", "tn", "tpi", "tr", "ts", "tt", "ug", "uk", "ur", "uz", "vec", "vi", "vo", "wa", "wo", "yi", "zh", "zh-min-nan", "zu"],
	tabcount = 0, appendAddTabButton, appendAddMeaningButton, appendAddTranslationButton, pc={},
	defaultprefs = {
		langs: ['hi', 'en'],
		summary: 'पृष्ठ निर्माण',
		summaryAd: ' ([[User:Siddhartha Ghai/pagecreator|पृष्ठ निर्माता]] द्वारा)'
	}, globalTemplatePrefix = 'User:Siddhartha Ghai/pagecreator/templates/';

	/**
	* ui(): Function to get UI messages
	* from the msg object in the user
	* interface language. If the message
	* is not present in the interface
	* language, defaults to hi.
	*
	* @param key : The key of the message
	* to be retrieved.
	*
	* @return : String, interface message
	*/
	function ui( key ) {
		return msg[lang][key] || msg.hi[key];
	}
	
	/**
	* getPrefs(): function to get the
	* preferences.
	*
	* @param key: the key of the
	* preference
	*
	* @return the preference, type
	* depends on the type of pref
	*/
	function getPrefs( key ) {
		if ( typeof pagecreatorPrefs !== 'undefined' ) {
			console.log(typeof pagecreatorPrefs);
			console.log(typeof pagecreatorPrefs !== undefined);
			return pagecreatorPrefs[key] || defaultprefs[key];
		}
		return defaultprefs[key];
	}

	/**
	* getVals(): function to get
	* the values from the form.
	*
	* @returns Object containing
	* the form values. This object
	* is to be parsed by valsToWikitext()
	*
	* Return Object format:
	*
	* { //MAIN OBJECT BEGINS
	*	{ //SUBOBJECT BEGINS
	*		lang: 'hi' //Two-letter lang code
	*		meanings: [ //MEANINGS ARRAY BEGINS
	*			{ //MEANING OBJECT BEGINS
	*				type: 'संज्ञा' //Word type, in hindi (hardcoded, not in ui function)
	*				meaning: 'string' //string containing meaning as input in textarea
	*				syn: 'string' //string containing synonyms as input in inputbox
	*				ant: 'string' //string containing antonyms as input in inputbox
	*				trans: //optional trans object
	*					{ //TRANS OBJECT BEGINS
	*						'hi': 'string translation into hi',
	*						'two-letter lang code': 'translation in that lang'
	*						//MORE OPTIONAL TRANSLATIONS
	*					} //TRANS OBJECT ENDS
	*			} //MEANING OBJECT ENDS
	*			{}, {}, ... //MORE MEANING OBJECTS
	*		] //MEANING ARRAY ENDS
	*	} //SUBOBJECT ENDS
	*	{}, {}, {} //MORE SUBOBJECTS. EACH SUBOBJECT IS ONE LANGUAGE TAB.
	* } //MAIN OBJECT ENDS
	*/
	function getVals() {
		var //$form = $( 'div#mw-gadget-pagecreator-container' ),
			//$tablist = $( '#mw-gadget-pagecreator-tablist' ),
			$tab = $( '.mw-gadget-pagecreator-tab' ),
			out = {};
		$tab.each(function (k, v) {
			out[k] = {};
			out[k].lang = $( v ).find( '.mw-gadget-pagecreator-languages' ).val();
			out[k].meanings = [];
			$( v ).find( '.mw-gadget-pagecreator-meaning' ).each( function (key, val) {
				out[k].meanings[key] = {};
				out[k].meanings[key].type = $( val ).find( '.mw-gadget-pagecreator-meaning-type' ).val();
				out[k].meanings[key].meaning = $( val ).find( '.mw-gadget-pagecreator-meaning-textarea' ).val();
				out[k].meanings[key].syn = $( val ).find( '.mw-gadget-pagecreator-meaning-syn' ).val();
				out[k].meanings[key].ant = $( val ).find( '.mw-gadget-pagecreator-meaning-ant' ).val();
				out[k].meanings[key].trans = {};
				$( val ).find( '.mw-gadget-pagecreator-meaning-trans' ).each( function (keys, vals) {
					out[k].meanings[key].trans[ $( vals ).prev().val() ] = $( vals ).val();
				} );
			} );
		} );
//		console.log( out );
		return out;
	}

	/**
	* addTemplate(): Function to
	* add a template to the wikitext.
	* Called by valsToWikitext().
	* 
	* @param template: template name,
	* which is prefixed by the globalTemplatePrefix
	* @param params: template parameters,
	* an object with the keys being the
	* parameter names and the values being
	* the parameter values
	* Optional, defaults to empty object
	* @param subst: a boolean, decides whether
	* the template is substituted or not
	* Optional, defaults to true
	*  
	* @return String for the template
	*/
	function addTemplate( template, params, subst ) {
		var out = '', i;
		if ( typeof params !== 'object' ) {
			params = {};
		}
		if ( typeof subst !== 'boolean' ) {
			subst = true;
		}

		out += ( subst === true ) ? '{{subst:' : '{{';
		out += globalTemplatePrefix + template;

		for ( i in params ) {
			if ( params.hasOwnProperty( i ) ) {
				out += '|' + i + '=' + params[i];
			}
		}
		out += '}}\n';

		return out;
	}

	/**
	* stringToParamsObject(): Function
	* to convert the string inputs for
	* synonyms and antonyms into an
	* object acceptable to the
	* addTemplate function
	* 
	* @param string: String input from
	* the form
	* 
	* @return Object
	*/
	function stringToParamsObject( string ) {
		var out = {}, i, arr = string.split( ',' );

		for (i in arr) {
			if ( arr.hasOwnProperty( i ) ) {
				arr[i] = arr[i].trim();
				out[parseInt(i, 10) + 1] = arr[i];
			}
		}

		return out;
	}

	/**
	* valsToWikitext(): Function to
	* convert js object into wikitext.
	* 
	* @param obj: object output by
	* getVals()
	* 
	* @return String
	* 
	* The returned string uses
	* templates for substitution.
	* All formatting can be
	* customized using the on-wiki
	* templates.
	* 
	* Functions Called:
	* addTemplate
	* stringToParamsObject
	*/
	function valsToWikitext( obj ) {
		var i, j, k, out = '', cats = '';

		for ( i in obj ) {
			if ( obj.hasOwnProperty( i ) ) {
				out += addTemplate( 'language', { 'lang': obj[i].lang } );
				if ( cats.indexOf( addTemplate( 'categories/language', { 'lang': obj[i].lang } ) ) === -1 ) {
					cats += addTemplate( 'categories/language', { 'lang': obj[i].lang } );
				}
				for (j = 0; j < obj[i].meanings.length; j += 1) {
					if ( cats.indexOf( addTemplate( 'categories/language and type', { 'lang': obj[i].lang, 'type': obj[i].meanings[j].type } ) ) === -1 ) {
						cats += addTemplate( 'categories/language and type', { 'lang': obj[i].lang, 'type': obj[i].meanings[j].type } );
					}

					//Add Meaning
					out += addTemplate( 'meaning/heading', { 'type': obj[i].meanings[j].type } );
					out += addTemplate( 'meaning/body', { 'meaning': obj[i].meanings[j].meaning } );

					//Add synonyms
					if ( obj[i].meanings[j].syn !== '' ) {
						out += addTemplate( 'synonyms/heading' );
						out += addTemplate( 'synonyms/body', stringToParamsObject( obj[i].meanings[j].syn ) );
					}

					//Add antonyms
					if ( obj[i].meanings[j].ant !== '' ) {
						out += addTemplate( 'antonyms/heading' );
						out += addTemplate( 'antonyms/body', stringToParamsObject( obj[i].meanings[j].ant ) );
					}

					if ( !$.isEmptyObject( obj[i].meanings[j].trans ) ) {
						out += addTemplate( 'translation/heading' );
						for ( k in obj[i].meanings[j].trans ) {
							if ( obj[i].meanings[j].trans.hasOwnProperty( k ) ) {
								out += addTemplate( 'translation/body', { 'lang': k, 'trans': obj[i].meanings[j].trans[k] } );
							}
						}
					}
				}
			}
		}
		out += cats;
//		console.log( out );
		return out;
	}

	/**
	* previewPage(): function to
	* preview the wikitext that
	* will be added to the page
	* on saving.
	*
	* @param wikitext: the wikitext
	* to preview
	*
	* Functions called:
	* ui
	*/
	function previewPage( wikitext ) {
		var previewrequest = $.ajax( {
			url: mw.config.get( 'wgServer' ) + mw.config.get( 'wgScriptPath' ) + '/api.php?',
			data: {
				'action': 'parse',
				'title': mw.config.get( 'wgPageName' ),
				'format': 'json',
				'text': wikitext,
				'prop': 'text|categorieshtml',
				'pst': 'true'
			},
			dataType: 'json',
			type: 'POST',
		} );

		$( 'div#catlinks' )
			.insertBefore( 'div.mw-gadget-pagecreator' )//move categories to just above the gadget
			.addClass( 'catlinks-allhidden' );//hide categories

		if( $( 'div.mw-gadget-pagecreator-status' ).html() === undefined ) {
			$( '<div>' )
				.addClass( 'mw-gadget-pagecreator-status' )
				.insertBefore( 'div.mw-gadget-pagecreator' );
		}

		//show status element
		$( 'div.mw-gadget-pagecreator-status' ).css( { 'display': 'block' } );
		//hide old preview while preparing a new one
		$( 'div.mw-gadget-pagecreator-preview' ).css( { 'display': 'none' } );

		previewrequest.done(function ( data, textStatus, jqXHR ) {
			$( 'div#catlinks' ).replaceWith( data.parse.categorieshtml['*'] );
			$( 'div.mw-gadget-pagecreator-status' ).css( { 'display': '' } );
			if ( $( 'div#mw-content-text div.mw-content-ltr' ).html() !== undefined ) {
				$( 'div#mw-content-text div.mw-content-ltr' ).html( data.parse.text['*'] );
				$( 'div.mw-gadget-pagecreator-preview' ).css( { 'display': '' } );
				return;
			}

			$( 'div#mw-content-text' ).prepend(
				$( '<div>' )
					.addClass( 'ontop mw-gadget-pagecreator-preview' )
					.attr( {
						'id': 'wikiPreview'
					} )
					.append( $( '<div>' )
						.addClass( 'previewnote' )
						.append( $( '<h2>' )
							.attr( 'id', 'mw-previewheader' )
							.text( ui( 'preview-header' ) )
						)
						.append( $( '<p>' )
							.text( ui( 'preview-toptext' ) )
						)
					)
					.append( $( '<div>' )
						.attr( {
							'lang': 'hi',
							'dir': 'ltr',
							'class': 'mw-content-ltr'
						} )
						.html( data.parse.text['*'] )
					)
			);
		});

		previewrequest.fail(function ( jqXHR, textStatus, errorThrown ) {
			$( 'div.mw-gadget-pagecreator-status' ).css( { 'display': '' } );
			if (errorThrown === undefined) {
				errorThrown = '';
			}
			$( 'div#mw-content-text' ).prepend(
				$( '<div>' )
					.addClass( 'mw-gadget-pagecreator-error' )
					.html( textStatus + '<br/>' + errorThrown )
			);
		});
	}
	
	/**
	* savePage(): function to save
	* the page.
	*
	* @param wikitext: the wikitext
	* to be saved
	*
	* Functions called:
	* getPrefs
	*/
	function savePage( wikitext ) {
		var saverequest = $.ajax( {
			url: mw.config.get( 'wgServer' ) + mw.config.get( 'wgScriptPath' ) + '/api.php?',
			data: {
				'action': 'edit',
				'title': mw.config.get( 'wgPageName' ),
				'text': wikitext,
				'token': edittoken,
				'summary': getPrefs( 'summary' ) + getPrefs( 'summaryAd' ),
				'format': 'json',
				'notminor': 'true',
				'createonly': 'true'/*,
				'contentformat': 'text/x-wiki',
				'contentmodel': 'wikitext'*/
			},
			dataType: 'json',
			type: 'POST',
		} );

		saverequest.done(function() {
			document.location.reload();
		});

		saverequest.error(function ( jqXHR, textStatus, errorThrown ) {
			if (errorThrown === undefined) {
				errorThrown = '';
			}
			$( 'div#mw-content-text' ).prepend(
				$( '<div>' )
					.addClass( 'mw-gadget-pagecreator-error' )
					.html( textStatus + '\n' + errorThrown )
			);
		});
	}

	/**
	* tabcountCheck(): function to check the
	* number of tabs.
	*
	* @returns : boolean
	* true if not nine
	* false if nine
	* SHOULD NOT BE CALLED AFTER NINE
	*
	* Functions called:
	* ui
	*/
	function tabcountCheck() {
		if (tabcount === 9) {
			alert( ui( 'error-maxtabs' ) );
			return false;
		}
		return true;
	}

	/**
	* appendLangOptions(): Function to
	* append the options to the language
	* menu.
	*
	* @param $select: the jquery object
	* containing the select element
	* to which the options are to be
	* appended.
	*
	* @return the input jquery object
	* with the options appended to the
	* underlying html element.
	*
	* Functions called:
	* ui
	* getPrefs
	*/
	function appendLangOptions( $select ) {
		var i, j,
			preflangs = getPrefs( 'langs' ),
			$prefGroup = $( '<optgroup>' ).attr( 'label', ui( 'optgroup-pref' ) ),
			$allGroup = $( '<optgroup>' ).attr( 'label', ui( 'optgroup-all' ) );
		
		for ( i = 0; i < preflangs.length; i+=1 ) {
			$prefGroup.append( $( '<option>' )
				.attr( {
				'value': preflangs[i]
				} )
				.text( ui( preflangs[i] ) )
			);
		}
		
		for ( j = 0; j < langcodes.length; j += 1 ) {
			$allGroup.append( $( '<option>' )
				.attr( {
				'value': langcodes[j]
				} )
				.text( ui( langcodes[j] ) )
			);
		}
		
		return $select.append( $prefGroup ).append( $allGroup );
	}

	/**
	* addTypeOptions(): Function
	* to append the Word Type options
	*
	* @param $select: jquery object
	* containing the select element
	* to which the options are to
	* be appended
	*
	* @return the input object
	* with the options appended
	*
	* Functions called:
	* ui
	*/
	function addTypeOptions( $select ) {
		/*
		the types array contains a list of types
		the elements are used as keys in the ui() function
		and
		for the #switch parser function in the on-wiki template
		meaning/heading
		*/
		var types = [ 'noun', 'pronoun', 'verb', 'adjective', 'adverb', 'adposition', 'conjunction', 'interjection' ], i;
		for ( i in types ) {
			$select.append( $( '<option>' )
				.attr( {
				'value': types[i]
				} )
				.text( ui( types[i] ) )
			);
		}
		return $select;
	}

	/**
	* appendTranslation(): Function to
	* append a translation to a meaning.
	* 
	* @param $ul: jquery object of <ul>
	* element.
	* 
	* @return input object with the
	* <input> html element appended.
	*/
	function appendTranslation ( $ul ) {
		var $langmenu = appendLangOptions( $( '<select>' ).addClass( 'mw-gadget-pagecreator-languages' ) );
		return $ul.append( $( '<li>' )
				.append( $( '<span>' ).text( ui( 'translations' ) ) )
				.append( $langmenu )
				.append( $( '<input>' )
					.attr( {
						'type': 'text'
					} )
					.addClass( 'mw-gadget-pagecreator-meaning-trans' )
				)
			);
	}

	/**
	* clickAddTranslationButton():
	* click event handler for when
	* the Add Translation button is
	* clicked.
	*
	* @param e: the event object
	*
	* Functions called:
	* appendAddTranslationButton
	* appendTranslation
	*/
	function clickAddTranslationButton ( e ) {
		var $target = $( e.target ),
		$ul = $target.parent().parent();
		$target.parent().remove();
		$ul = appendAddTranslationButton( appendTranslation( $ul ) );
	}

	/**
	* appendAddTranslationButton():
	* Function to append an
	* Add Translation button.
	*
	* @param $ul: jquery object
	* containing <ul> element.
	*
	* @return the input object with
	* the button appended in an <li>
	* element.
	*
	* Functions called:
	* clickAddTranslationButton
	* ui
	*/
	appendAddTranslationButton = function( $ul ) {
		return $ul.append( $( '<li>' )
				.append(
					$( '<input>' )
						.attr( {
							'type': 'button',
							'value': ui( 'button-addTrans' ),
							'class': 'mw-gadget-pagecreator-button-add-trans'
						} )
						.click( clickAddTranslationButton )
				)
			);
	};
	
	/**
	* appendMeaningToTab(): Function to add
	* a meaning box in a <ul> element to
	* a tab.
	*
	* @param $tab : the element to which the
	* box is to be appended. Function is
	* called with an <li> element.
	*
	* Functions called:
	* appendAddTranslationButton
	* ui
	* 
	* @return : the input element with the
	* ul element appended.
	*/
	function appendMeaningToTab( $tab ) {
		return $tab.append( $( '<ul>' )
			.addClass( 'mw-gadget-pagecreator-meaning' )
			.append( $( '<li>' )
				.append( $( '<label>' )
					.text( ui( 'type' ) + ':' )
					.append(
						addTypeOptions(
							$( '<select>' )
							.addClass( 'mw-gadget-pagecreator-meaning-type' )
						)
					)
				)
			)
			.append( $( '<li>' )
				.append( $( '<label>' )
					.text( ui( 'meaning' ) + ':' )
					.append( $( '<textarea>' )
						.addClass( 'mw-gadget-pagecreator-meaning-textarea' )
					)
				)
			)
			.append( $( '<li>' )
				.append( $( '<label>' )
					.text( ui( 'synonyms' ) + ':' )
					.append( $( '<input>' )
						.attr( {
							'type': 'text'
						} )
						.addClass( 'mw-gadget-pagecreator-meaning-syn' )
					)
				)
			)
			.append( $( '<li>' )
				.append( $( '<label>' )
					.text( ui( 'antonyms' ) + ':' )
					.append( $( '<input>' )
						.attr( {
							'type': 'text'
						} )
						.addClass( 'mw-gadget-pagecreator-meaning-ant' )
					)
				)
			)
			.append( $( '<li>' )
				.append(
					appendAddTranslationButton(
						$( '<ul>' ).addClass( 'mw-gadget-pagecreator-meaning-translist' )
					)
				)
			)
		);
	}

	/**
	* appendTabLabel(): Function to append
	* a label contained in an <li> element
	* to the tabs list in the gadget.
	*
	* @param $tablabels : The <ul> element
	* to which the label is to be appended.
	*
	* @return : the input ul element with
	* the li element appended.
	*
	* Functions called:
	* ui
	*/
	function appendTabLabel( $tablabels ) {
		var $append = $( '<li>' )
				.addClass( 'mw-gadget-pagecreator-tabs-labels' )
				.text( ui( 'lang' ) + ' ' + ui( 'n-' + tabcount.toString() ) );
		if (tabcount === 1) {
			$append = $append.attr( 'id', 'mw-gadget-pagecreator-tabs-label-selected' );
		}
//		$tablabels = $tablabels.last().before( $append ); //add the label as the penultimate label, leaving the addTabButton as the last label
//		$( e.target ).before();

		return $tablabels.append( $append );
	}

	/**
	* clickAddMeaningButton():
	* Event handler called when the
	* "Add Meaning" button is clicked.
	* Adds another meaning form to
	* the tab.
	* 
	* @param e: the event object
	*
	* Functions called:
	* appendMeaningToTab
	* appendAddMeaningButton
	*/
	function clickAddMeaningButton() {
		$( '.mw-gadget-pagecreator-button-add-meaning' ).filter(':visible').parent().remove(); //remove the button
		var $tab = $('.mw-gadget-pagecreator-tab').filter(':visible'), //$(e.target).parents('.mw-gadget-pagecreator-tab') doesn't work ?!?
			$meaning = appendMeaningToTab( $( '<li>' ) );
		$tab.append( $meaning );
		$tab = appendAddMeaningButton( $tab );
		return;
	}
	
	/**
	* appendAddMeaningButton()
	* Function to append the "Add Meaning"
	* button to a tab.
	* Also adds the click handler for the button.
	* 
	* @param $tab: the tab element to which
	* the button is to be appended. Called
	* with a <ul> element.
	* 
	* @return the input element with the button
	* appended in an <li> element.
	* 
	* Functions called:
	* clickAddMeaningButton
	* ui
	*/
	appendAddMeaningButton = function( $tab ) {
		return $tab.append( $( '<li>' )
				.append(
					$( '<input>' )
						.attr( {
							'type': 'button',
							'value': ui( 'button-addMeaning' ),
							'class': 'mw-gadget-pagecreator-button-add-meaning'
						} )
						.click( clickAddMeaningButton )
				)
			);
	};

	/**
	* appendTabToForm(): Function to add
	* a tab contained in a <ul> element
	* to the gadget. A tab represents
	* the presence of a word in 1 language.
	*
	* @param $tabcontainer: div element
	* to which the tab is to be appended.
	*
	* @return the input div element with
	* the ul element appended.
	*
	* Functions called:
	* appendLangOptions
	* appendMeaningToTab
	* appendAddMeaningButton
	* ui
	*/
	function appendTabToForm( $tabcontainer ) {
		tabcount += 1;
		var $langmenu = appendLangOptions( $( '<select>' ).addClass( 'mw-gadget-pagecreator-languages' ) ),
		$tab = $( '<ul>' )
		.addClass( 'mw-gadget-pagecreator-tab' )
		.append( $( '<li>' )
			.append( $( '<label>' )
				.text( ui( 'lang' ) + ':' )
				.append( $langmenu )
			)
		),
		$meaning = appendMeaningToTab( $( '<li>' ) );
		$tab.append( $meaning );
		$tab = appendAddMeaningButton( $tab );
		
		return $tabcontainer.append( $tab );
	}

	/**
	* clickAddTabButton( e ): onclick handler
	* function for "add tab" button.
	* 
	* @param e : the click event
	* 
	* Functions called:
	* tabcountCheck
	* appendTabToForm
	* appendTabLabel
	* appendAddTabButton
	*/
	function clickAddTabButton() {
		var $tablabels, /*= $( '.mw-gadget-pagecreator-tablist' ),*/
			$tabcontainer = $( '#mw-gadget-pagecreator-tabs' ); //redefined since this is a separate function
		if ( !tabcountCheck() ) {
			return;
		}
		$( '#mw-gadget-pagecreator-button-add-tab' ).remove(); //remove the button
//					$tablabels = $tablabels.last().remove(); //remove the button
		$tabcontainer = appendTabToForm( $tabcontainer );
		$tablabels = appendTabLabel( $( '#mw-gadget-pagecreator-tablist' ) ); //add the label
		$tablabels = appendAddTabButton( $tablabels ); //readd the button
		return;
//					console.log( $tablabels[0] );
//					console.log( $tabcontainer[0] );
	}

	/**
	* appendAddTabButton(): function to add
	* the "add tab" button to the labels list.
	* Also contains the click handler for it.
	*
	* @param $tablabels : The <ul> element
	* to which the label is to be appended.
	* @param $tabcontainer: div element
	* to which the tab is to be appended.
	*
	* Functions called:
	* clickAddTabButton
	* ui
	*/
	appendAddTabButton = function( $tablabels ) {
		var $addTabButton = $( '<li>' )
			.addClass( 'mw-gadget-pagecreator-tabs-labels' )
			.text( ui( 'n-plus' ) )
			.attr( {
				'title': ui( 'addLang' ),
				'id': 'mw-gadget-pagecreator-button-add-tab'
			} )
			.click( clickAddTabButton );
		return $tablabels.append( $addTabButton );
	};

	/**
	* buttonClickHandler():
	* click handler function for
	* the main form buttons,
	* currently preview and save.
	*
	* @param e: the event object
	*
	* Functions called:
	* getVals
	* valsToWikitext
	* previewPage
	* savePage
	*/
	function buttonClickHandler( e ) {
		var pageObj = getVals(),
			wikitext = valsToWikitext( pageObj );
//			console.log( 'pageObj' );
		switch ( e.data.type ) {
			case 'preview':
				previewPage( wikitext );
				break;
			case 'save':
				savePage( wikitext );
				break;
			default:
				break;
		}
	}
	
	/**
	* appendButtonsToForm(): function to add
	* buttons to the gadget form. Adds the
	* following buttons:
	* * Preview
	* * Save
	* 
	* @param $buttons : div element to which
	* the buttons are appended.
	*
	* @return input element with the buttons
	* appended.
	* 
	* Functions called:
	* buttonClickHandler
	* ui
	*/
	function appendButtonsToForm( $buttons ) {
		var $preview = $( '<input>' )
			.attr( {
				'type': 'button',
				'value': ui( 'button-preview' )
			} ),
		$save = $( '<input>' )
			.attr( {
				'type': 'button',
				'value': ui( 'button-save' )
			} );

		$preview.click( { type: 'preview' } , buttonClickHandler );
		$save.click( { type: 'save' } , buttonClickHandler );
		return $buttons.append( [$preview, $save] );
	}
	
	/**
	* chooseVisibleTab(): Function to apply
	* css for tab selection.
	*/
	function chooseVisibleTab ( e ) {
		var thislabel, thisindex, selectedlabel, selectionindex, tabs;
		if ( e.target.id === 'mw-gadget-pagecreator-button-add-tab' ) {
//			console.log( 'if' );
			thislabel = $( '#mw-gadget-pagecreator-tablist>li:nth-last-child(2)' );
//			thislabel = $( e.target ).prev(); DOESN'T WORK ?!?
//			console.log( thislabel );
		}
		else {
			thislabel = $( e.target );
		}
		thisindex = thislabel.index();
//		console.log( 'thisindex=' + thisindex );
		selectedlabel = $( '#mw-gadget-pagecreator-tabs-label-selected' );
		selectionindex = selectedlabel.index();
		tabs = $( '.mw-gadget-pagecreator-tab' );
//			console.log(thisindex);:nth-child(selectionindex)
		//Remove css from previous selecion.
//			console.log(selectedlabel);
//			console.log(selectionindex);
		$( tabs[selectionindex] ).css( {
				'display': ''//'none' none added thru static css
		} );
		selectedlabel = selectedlabel
			.attr('id', '' );
//			console.log(selectedlabel);	
		//Add css to current selection.
		thislabel.attr( 'id', 'mw-gadget-pagecreator-tabs-label-selected' );
		$( tabs[thisindex] ).css( {
			'display': 'block'
		} );
	}

	/**
	* createForm(): function to create the
	* container elements for the gadget.
	* Does the DOM replacement of
	* noarticletext with the gadget.
	*
	* Functions called:
	* chooseVisibleTab
	* appendTabToForm
	* appendTabLabel
	* appendAddTabButton
	* appendButtonsToForm
	* ui
	*/
	function createForm() {
		var $form = $( '<div>' )
			.addClass( 'mw-gadget-pagecreator' )
			.attr( 'id', 'mw-gadget-pagecreator-container' )
			.append( $( '<h2>' )
				.addClass( 'mw-gadget-pagecreator-heading' )
				.text( ui( 'name' ) )
			),
		$tablabels = $( '<ul>' )
			.addClass( 'mw-gadget-pagecreator-tablist' )
			.attr( 'id', 'mw-gadget-pagecreator-tablist' )
			.click( chooseVisibleTab ),
		$tabcontainer = $( '<div>' )
		.attr( {
			'id': 'mw-gadget-pagecreator-tabs'
		} ),
		$buttons = $( '<div>' )
		.attr( {
			'id': 'mw-gadget-pagecreator-buttons'
		} );
		
		$tabcontainer = appendTabToForm( $tabcontainer ); //Add first tab
		$tablabels = appendTabLabel( $tablabels ); //Add label for first tab
		$tablabels = appendAddTabButton( $tablabels );
		$buttons = appendButtonsToForm( $buttons );
		
		$form.append( $tablabels )
			.append( $tabcontainer )
			.append( $buttons );
		$( 'div#mw-content-text' ).html( '' ); //Remove default content
		$( 'div#mw-content-text' ).append( $form ); //Add gadget
	}

	if ( mw.config.get('wgNamespaceNumber') !== 0 && mw.config.get('wgNamespaceNumber') !== 2 ) {
		return;
	}
	if ( mw.config.get('wgAction') !== 'view' && !( mw.config.get('wgAction') === 'edit' && mw.config.get('wgArticleId') === 0 && mw.config.get('wgNamespaceNumber') === 0 ) ) {
		return;
	}
	if ( mw.config.get('wgArticleId') !== 0 ) {
		return;
	}
	if (edittoken === undefined) {
		alert( ui( 'error-login' ) );
		return;
	}

	createForm(); //Create Form
	$( '#mw-gadget-pagecreator-tablist>li' )[0].click(); //Simulate click on first tab label to show first tab
} );
} ( window, document, jQuery )); // End wrap with anonymous function
//</nowiki>