// (function($) {  /*  ****************************************  *** twinklexfd.js: XFD module  ****************************************  * Mode of invocation:     Tab ("অপসারণ প্রস্তাবনা")  * Active on:              Existing, non-special pages, except for file pages with no local (non-Commons) file which are not redirects  */  Twinkle.xfd = function twinklexfd() { 	// Disable on: 	// * special pages 	// * non-existent pages 	// * files on Commons, whether there is a local page or not (unneeded local pages of files on Commons are eligible for CSD F2, or R4 if it's a redirect) 	if (mw.config.get('wgNamespaceNumber') < 0 || !mw.config.get('wgArticleId') || (mw.config.get('wgNamespaceNumber') === 6 && document.getElementById('mw-sharedupload'))) { 		return; 	}  	var tooltip = 'একটি অপসারণ প্রস্তাবনা শুরু করুন'; 	if (mw.config.get('wgIsRedirect')) { 		tooltip += ' অথবা এটিকে অন্যত্র পুনর্নির্দেশ করুন'; 	} else { 		switch (mw.config.get('wgNamespaceNumber')) { 			case 0: 				tooltip += ' অথবা এই নিবন্ধটি স্থানান্তর করুন'; 				break; 			case 10: 				tooltip += ' অথবা এই টেমপ্লেটটি একীভূত করুন'; 				break; 			case 828: 				tooltip += ' অথবা এই মডিউলটি একীভূত করুন'; 				break; 			case 6: 				tooltip += ' এই ফাইল'; 				break; 			case 14: 				tooltip += ', এই বিষয়শ্রেণীটি একীভূত অথবা পুনঃনামকরণ'; 				break; 			default: 				tooltip += ' এই পাতা'; 				break; 		} 	} 	Twinkle.addPortletLink(Twinkle.xfd.callback, 'অপসারণ প্রস্তাবনা', 'tw-xfd', tooltip); };  var utils = { 	/** Get ordinal number figure */ 	num2order: function(num) { 		switch (num) { 			case 1: return ''; 			case 2: return '২য়'; 			case 3: return '৩য়'; 			case 4: return '৪র্থ'; 			case 5: return '৫ম'; 			case 6: return '৬ষ্ঠ'; 			case 7: return '৭ম'; 			case 8: return '৮ম'; 			case 9: return '৯ম'; 			case 10: return '১০ম'; 			default: return num + 'তম'; 		} 	},  	/** 	 * Remove namespace name from title if present 	 * Exception-safe wrapper around mw.Title 	 * @param {string} title 	 */ 	stripNs: function(title) { 		var title_obj = mw.Title.newFromUserInput(title); 		if (!title_obj) { 			return title; // user entered invalid input; do nothing 		} 		return title_obj.getNameText(); 	},  	/** 	 * Add namespace name to page title if not already given 	 * CAUTION: namespace name won't be added if a namespace (*not* necessarily 	 * the same as the one given) already is there in the title 	 * @param {string} title 	 * @param {number} namespaceNumber 	 */ 	addNs: function(title, namespaceNumber) { 		var title_obj = mw.Title.newFromUserInput(title, namespaceNumber); 		if (!title_obj) { 			return title;  // user entered invalid input; do nothing 		} 		return title_obj.toText(); 	},  	/** 	 * Provide Wikipedian TLA style: AfD, RfD, CfDS, RM, SfD, etc. 	 * @param {string} venue 	 * @returns {string} 	 */ 	toTLACase: function(venue) { 		return venue 			.toString() 			// Everybody up, inclduing rm and the terminal s in cfds 			.toUpperCase() 			// Lowercase the central f in a given TLA and normalize sfd-t and sfr-t 			.replace(/(.)F(.)(?:-.)?/, '$1f$2'); 	} };  Twinkle.xfd.currentRationale = null;  // error callback on Morebits.status.object Twinkle.xfd.printRationale = function twinklexfdPrintRationale() { 	if (Twinkle.xfd.currentRationale) { 		Morebits.status.printUserText(Twinkle.xfd.currentRationale, 'আপনার অপসারণের যুক্তি নিচে দেওয়া হয়েছে, আপনি যদি আবার চেষ্টা করতে চান তাহলে আপনি একটি নতুন অপসারণ ডায়ালগে অনুলিপি ও প্রতিলিপি করতে পারেন:'); 		// only need to print the rationale once 		Twinkle.xfd.currentRationale = null; 	} };  Twinkle.xfd.callback = function twinklexfdCallback() { 	var Window = new Morebits.simpleWindow(700, 400); 	Window.setTitle('একটি অপসারণ প্রস্তাবনা শুরু করুন (XFD)'); 	Window.setScriptName('টুইংকল'); 	Window.addFooterLink('অপসারণ আলোচনা প্রসঙ্গ', 'WP:XFD'); 	Window.addFooterLink('অপসারণ প্রস্তাবনার পছন্দ', 'WP:TW/PREF#xfd'); 	Window.addFooterLink('টুইংকল সাহায্য', 'WP:TW/DOC#xfd'); 	Window.addFooterLink('মতামত দিন', 'WT:TW');  	var form = new Morebits.quickForm(Twinkle.xfd.callback.evaluate); 	var categories = form.append({ 		type: 'select', 		name: 'venue', 		label: 'অপসারণ আলোচনার স্থান:', 		tooltip: 'সক্ষম করা হলে একটি নামস্থানের ভিত্তিতে পূর্বনির্ধারিত নির্বাচন তৈরি হবে। এই পূর্বনির্ধারিতটি সবচেয়ে বেশি গণ্য হওয়া উচিত।', 		event: Twinkle.xfd.callback.change_category 	}); 	var namespace = mw.config.get('wgNamespaceNumber');  	categories.append({ 		type: 'option', 		label: 'AfD (নিবন্ধ অপসারণের প্রস্তাবনা)', 		selected: namespace === 0,  // Main namespace 		value: 'afd' 	}); 	categories.append({ 		type: 'option', 		label: 'TfD (টেমপ্লেট অপসারণের প্রস্তাবনা)', 		selected: [ 10, 828 ].indexOf(namespace) !== -1,  // Template and module namespaces 		value: 'tfd' 	}); 	categories.append({ 		type: 'option', 		label: 'FfD (ফাইল অপসারণের প্রস্তাবনা)', 		selected: namespace === 6,  // File namespace 		value: 'ffd' 	}); 	categories.append({ 		type: 'option', 		label: 'CfD (বিষয়শ্রেণী অপসারণের প্রস্তাবনা)', 		selected: namespace === 14 || (namespace === 10 && /-stub$/.test(Morebits.pageNameNorm)),  // Category namespace and stub templates 		value: 'cfd' 	}); 	categories.append({ 		type: 'option', 		label: 'CfD/S (বিষয়শ্রেণী দ্রুত নামান্তর)', 		value: 'cfds' 	}); 	categories.append({ 		type: 'option', 		label: 'MfD (বিবিধ অপসারণ)', 		selected: [ 0, 6, 10, 14, 828 ].indexOf(namespace) === -1 || Morebits.pageNameNorm.indexOf('Template:User ', 0) === 0, 		// Other namespaces, and userboxes in template namespace 		value: 'mfd' 	}); 	categories.append({ 		type: 'option', 		label: 'RfD (পুনর্নির্দেশ অপসারণের প্রস্তাবনা)', 		selected: mw.config.get('wgIsRedirect'), 		value: 'rfd' 	}); 	categories.append({ 		type: 'option', 		label: 'RM (Requested moves)', 		selected: false, 		value: 'rm' 	});  	form.append({ 		type: 'div', 		id: 'wrong-venue-warn', 		style: 'color: red; font-style: italic' 	});  	form.append({ 		type: 'checkbox', 		list: [ 			{ 				label: 'পাতা তৈরিকারীকে সম্ভব হলে জানান', 				value: 'notify', 				name: 'notifycreator', 				tooltip: "A notification template will be placed on the creator's talk page if this is true.", 				checked: true 			} 		] 	}); 	form.append({ 		type: 'field', 		label: 'কর্মক্ষত্র', 		name: 'work_area' 	});  	var previewlink = document.createElement('a'); 	$(previewlink).click(function() { 		Twinkle.xfd.callbacks.preview(result);  // |result| is defined below 	}); 	previewlink.style.cursor = 'pointer'; 	previewlink.textContent = 'প্রাকদর্শন'; 	form.append({ type: 'div', id: 'xfdpreview', label: [ previewlink ] }); 	form.append({ type: 'div', id: 'twinklexfd-previewbox', style: 'display: none' });  	form.append({ type: 'submit' });  	var result = form.render(); 	Window.setContent(result); 	Window.display(); 	result.previewer = new Morebits.wiki.preview($(result).find('div#twinklexfd-previewbox').last()[0]);  	// We must init the controls 	var evt = document.createEvent('Event'); 	evt.initEvent('change', true, true); 	result.venue.dispatchEvent(evt); };  Twinkle.xfd.callback.wrongVenueWarning = function twinklexfdWrongVenueWarning(venue) { 	var text = ''; 	var namespace = mw.config.get('wgNamespaceNumber');  	switch (venue) { 		case 'afd': 			if (namespace !== 0) { 				text = 'AfD is generally appropriate only for articles.'; 			} else if (mw.config.get('wgIsRedirect')) { 				text = 'Please use RfD for redirects.'; 			} 			break; 		case 'tfd': 			if (namespace === 10 && /-stub$/.test(Morebits.pageNameNorm)) { 				text = 'Use CfD for stub templates.'; 			} else if (Morebits.pageNameNorm.indexOf('Template:User ') === 0) { 				text = 'Please use MfD for userboxes'; 			} 			break; 		case 'cfd': 			if ([ 10, 14 ].indexOf(namespace) === -1) { 				text = 'CfD is only for categories and stub templates.'; 			} 			break; 		case 'cfds': 			if (namespace !== 14) { 				text = 'CfDS is only for categories.'; 			} 			break; 		case 'ffd': 			if (namespace !== 6) { 				text = 'FFD is selected but this page doesn\'t look like a file!'; 			} 			break; 		case 'rm': 			if (namespace === 14) { // category 				text = 'বিষয়শ্রেণী পরিবর্তনের জন্য দয়া করে CfD বা CfDS ব্যবহার করুন।'; 			} else if ([118, 119, 2, 3].indexOf(namespace) > -1) { // draft, draft talk, user, user talk  				text = 'RMs are not permitted in draft and userspace, unless they are uncontroversial technical requests.'; 			} 			break;  		default: // mfd or rfd 			break; 	}  	$('#wrong-venue-warn').text(text);  };  Twinkle.xfd.callback.change_category = function twinklexfdCallbackChangeCategory(e) { 	var value = e.target.value; 	var form = e.target.form; 	var old_area = Morebits.quickForm.getElements(e.target.form, 'work_area')[0]; 	var work_area = null;  	var oldreasontextbox = form.getElementsByTagName('textarea')[0]; 	var oldreason = oldreasontextbox ? oldreasontextbox.value : '';  	var appendReasonBox = function twinklexfdAppendReasonBox() { 		work_area.append({ 			type: 'textarea', 			name: 'reason', 			label: 'কারণ:', 			value: oldreason, 			tooltip: 'আপনি কারণে উইকি মার্কআপ ব্যবহার করতে পারেন। টুইংকল স্বংয়ক্রিয়ভাবে আপনার স্বাক্ষর যোগ করবে।' 		}); 	};  	Twinkle.xfd.callback.wrongVenueWarning(value);  	form.previewer.closePreview();  	switch (value) { 		case 'afd': 			work_area = new Morebits.quickForm.element({ 				type: 'field', 				label: 'নিবন্ধ অপসারণের প্রস্তাবনা', 				name: 'work_area' 			});  			work_area.append({ 				type: 'div', 				label: '', // Added later by Twinkle.makeFindSourcesDiv() 				id: 'twinkle-xfd-findsources', 				style: 'margin-bottom: 5px; margin-top: -5px;' 			});  			work_area.append({ 				type: 'checkbox', 				list: [ 					{ 						label: 'অপসারণ ট্যাগকে <noinclude> দিয়ে আবৃত করুন', 						value: 'noinclude', 						name: 'noinclude', 						tooltip: 'Will wrap the deletion tag in <noinclude> tags, so that it won\'t transclude. This option is not normally required.' 					} 				] 			}); 			work_area.append({ 				type: 'select', 				name: 'xfdcat', 				label: 'অপসারণ প্রস্তাবনার বিষয় নির্বাচন করুন:', 				list: [ 					{ type: 'option', label: 'অজানা', value: '?', selected: true }, 					{ type: 'option', label: 'মিডিয়া ও সঙ্গীত', value: 'M' }, 					{ type: 'option', label: 'সংস্থা, করপোরেশন, বা পণ্য', value: 'O' }, 					{ type: 'option', label: 'জীবনী', value: 'B' }, 					{ type: 'option', label: 'সামাজিক বিষয়', value: 'S' }, 					{ type: 'option', label: 'ওয়েব বা ইন্টারনেট', value: 'W' }, 					{ type: 'option', label: 'খেলাধুলা', value: 'G' }, 					{ type: 'option', label: 'বিজ্ঞান ও প্রযুক্তি', value: 'T' }, 					{ type: 'option', label: 'কথাসাহিত্য ও শিল্পকলা', value: 'F' }, 					{ type: 'option', label: 'স্থান ও পরিবহন', value: 'P' }, 					{ type: 'option', label: 'অনির্ণেয় বা শ্রেণিকরণযোগ্য নয় এমন বিষয়', value: 'I' }, 					{ type: 'option', label: 'বিতর্ক এখনো শ্রেনিবিভক্ত করা হয়নি', value: 'U' } 				] 			}); 			/*** 			work_area.append({ 				type: 'select', 				multiple: true, 				name: 'delsortCats', 				label: 'Choose deletion sorting categories:', 				tooltip: 'Select a few categories that are specifically relevant to the subject of the article. Be as precise as possible; categories like People and USA should only be used when no other categories apply.' 			});  			// grab deletion sort categories from en-wiki 			Morebits.wiki.getCachedJson('Wikipedia:WikiProject_Deletion_sorting/Computer-readable.json').then(function(delsortCategories) { 				var $select = $('[name="delsortCats"]'); 				$.each(delsortCategories, function(groupname, list) { 					var $optgroup = $('<optgroup>').attr('label', groupname); 					var $delsortCat = $select.append($optgroup); 					list.forEach(function(item) { 						var $option = $('<option>').val(item).text(item); 						$delsortCat.append($option); 					}); 				}); 			});   ****/ 			appendReasonBox(); 			work_area = work_area.render(); 			old_area.parentNode.replaceChild(work_area, old_area);  			Twinkle.makeFindSourcesDiv('#twinkle-xfd-findsources');  			$(work_area).find('[name=delsortCats]') 				.attr('data-placeholder', 'Select delsort pages') 				.select2({ 					width: '100%', 					matcher: Morebits.select2.matcher, 					templateResult: Morebits.select2.highlightSearchMatches, 					language: { 						searching: Morebits.select2.queryInterceptor 					}, 					// Link text to the page itself 					templateSelection: function(choice) { 						return $('<a>').text(choice.text).attr({ 							href: mw.util.getUrl('Wikipedia:WikiProject_Deletion_sorting/' + choice.text), 							target: '_blank' 						}); 					} 				}); 				 			mw.util.addCSS( 				// Remove black border 				'.select2-container--default.select2-container--focus .select2-selection--multiple { border: 1px solid #aaa; }' +  				// Reduce padding 				'.select2-results .select2-results__option { padding-top: 1px; padding-bottom: 1px; }' + 				'.select2-results .select2-results__group { padding-top: 1px; padding-bottom: 1px; } ' +  				// Adjust font size 				'.select2-container .select2-dropdown .select2-results { font-size: 13px; }' + 				'.select2-container .selection .select2-selection__rendered { font-size: 13px; }' +  				// Make the tiny cross larger 				'.select2-selection__choice__remove { font-size: 130%; }' 			); 			break;  		case 'tfd': 			work_area = new Morebits.quickForm.element({ 				type: 'field', 				label: 'Templates for discussion', 				name: 'work_area' 			});  			var templateOrModule = mw.config.get('wgPageContentModel') === 'Scribunto' ? 'module' : 'template'; 			work_area.append({ 				type: 'select', 				label: 'Choose type of action wanted:', 				name: 'xfdcat', 				event: function(e) { 					var target = e.target, 						tfdtarget = target.form.tfdtarget; 					// add/remove extra input box 					if (target.value === 'tfm' && !tfdtarget) { 						tfdtarget = new Morebits.quickForm.element({ 							name: 'tfdtarget', 							type: 'input', 							label: 'Other ' + templateOrModule + ' to be merged:', 							tooltip: 'Required. Should not include the ' + Morebits.string.toUpperCaseFirstChar(templateOrModule) + ': namespace prefix.', 							required: true 						}); 						target.parentNode.appendChild(tfdtarget.render()); 					} else { 						$(Morebits.quickForm.getElementContainer(tfdtarget)).remove(); 						tfdtarget = null; 					} 				}, 				list: [ 					{ type: 'option', label: 'অপসারণ', value: 'tfd', selected: true }, 					{ type: 'option', label: 'একত্রীকরণ', value: 'tfm' } 				] 			}); 			work_area.append({ 				type: 'select', 				name: 'templatetype', 				label: 'Deletion tag display style:', 				tooltip: 'Which <code>type=</code> parameter to pass to the TfD tag template.', 				list: templateOrModule === 'module' ? [ 					{ type: 'option', value: 'module', label: 'Module', selected: true } 				] : [ 					{ type: 'option', value: 'standard', label: 'Standard', selected: true }, 					{ type: 'option', value: 'sidebar', label: 'Sidebar/infobox', selected: $('.infobox').length }, 					{ type: 'option', value: 'inline', label: 'Inline template', selected: $('.mw-parser-output > p .Inline-Template').length }, 					{ type: 'option', value: 'tiny', label: 'Tiny inline' }, 					{ type: 'option', value: 'disabled', label: 'Disabled' } 				] 			});  			work_area.append({ 				type: 'checkbox', 				list: [ 					{ 						label: 'Wrap deletion tag with <noinclude> (for substituted templates only)', 						value: 'noinclude', 						name: 'noinclude', 						tooltip: 'Will wrap the deletion tag in <noinclude> tags, so that it won\'t get substituted along with the template.', 						disabled: templateOrModule === 'module', 						checked: !!$('.box-Subst_only').length // Default to checked if page carries {{subst only}} 					} 				] 			});  			work_area.append({ 				type: 'checkbox', 				list: [ 					{ 						label: 'Notify users of the template', 						value: 'devpages', 						name: 'devpages', 						tooltip: 'A notification template will be sent to Twinkle, AWB, and Ultraviolet if this is true.', 						checked: true 					} 				] 			});  			appendReasonBox(); 			work_area = work_area.render(); 			old_area.parentNode.replaceChild(work_area, old_area); 			break;  		case 'mfd': 			work_area = new Morebits.quickForm.element({ 				type: 'field', 				label: 'বিবিধ অপসারণের প্রস্তাবনা', 				name: 'work_area' 			}); 			work_area.append({ 				type: 'checkbox', 				list: [ 					{ 						label: 'Wrap deletion tag with <noinclude>', 						value: 'noinclude', 						name: 'noinclude', 						tooltip: 'Will wrap the deletion tag in <noinclude> tags, so that it won\'t transclude. Select this option for userboxes.' 					} 				] 			}); 			if ((mw.config.get('wgNamespaceNumber') === 2 /* User: */ || mw.config.get('wgNamespaceNumber') === 3 /* User talk: */) && mw.config.exists('wgRelevantUserName')) { 				work_area.append({ 					type: 'checkbox', 					list: [ 						{ 							label: 'Notify owner of userspace (if they are not the page creator)', 							value: 'notifyuserspace', 							name: 'notifyuserspace', 							tooltip: 'If the user in whose userspace this page is located is not the page creator (for example, the page is a rescued article stored as a userspace draft), notify the userspace owner as well.', 							checked: true 						} 					] 				}); 			} 			appendReasonBox(); 			work_area = work_area.render(); 			old_area.parentNode.replaceChild(work_area, old_area); 			break; 		case 'ffd': 			work_area = new Morebits.quickForm.element({ 				type: 'field', 				label: 'Discussion venues for files', 				name: 'work_area' 			}); 			appendReasonBox(); 			work_area = work_area.render(); 			old_area.parentNode.replaceChild(work_area, old_area); 			break;  		case 'cfd': 			work_area = new Morebits.quickForm.element({ 				type: 'field', 				label: 'Categories for discussion', 				name: 'work_area' 			}); 			var isCategory = mw.config.get('wgNamespaceNumber') === 14; 			work_area.append({ 				type: 'select', 				label: 'Choose type of action wanted:', 				name: 'xfdcat', 				event: function(e) { 					var value = e.target.value, 						cfdtarget = e.target.form.cfdtarget, 						cfdtarget2 = e.target.form.cfdtarget2;  					// update enabled status 					cfdtarget.disabled = value === 'cfd' || value === 'sfd-t';  					if (isCategory) { 						// update label 						if (value === 'cfs') { 							Morebits.quickForm.setElementLabel(cfdtarget, 'Target categories: '); 						} else if (value === 'cfc') { 							Morebits.quickForm.setElementLabel(cfdtarget, 'Target article: '); 						} else { 							Morebits.quickForm.setElementLabel(cfdtarget, 'Target category: '); 						} 						// add/remove extra input box 						if (value === 'cfs') { 							if (cfdtarget2) { 								cfdtarget2.disabled = false; 								$(cfdtarget2).show(); 							} else { 								cfdtarget2 = document.createElement('input'); 								cfdtarget2.setAttribute('name', 'cfdtarget2'); 								cfdtarget2.setAttribute('type', 'text'); 								cfdtarget2.setAttribute('required', 'true'); 								cfdtarget.parentNode.appendChild(cfdtarget2); 							} 						} else { 							$(cfdtarget2).prop('disabled', true); 							$(cfdtarget2).hide(); 						} 					} else { // Update stub template label 						Morebits.quickForm.setElementLabel(cfdtarget, 'Target stub template: '); 					} 				}, 				list: isCategory ? [ 					{ type: 'option', label: 'অপসারণ', value: 'cfd', selected: true }, 					{ type: 'option', label: 'একত্রীকরণ', value: 'cfm' }, 					{ type: 'option', label: 'পুনঃনামকরণ', value: 'cfr' }, 					{ type: 'option', label: 'বিভক্তিকরণ', value: 'cfs' }, 					{ type: 'option', label: 'নিবন্ধে রপান্তরকরণ', value: 'cfc' } 				] : [ 					{ type: 'option', label: 'অসম্পূর্ণ নিবন্ধ অপসারণ', value: 'sfd-t', selected: true }, 					{ type: 'option', label: 'অসম্পূর্ণ নিবন্ধ পুনঃনামকরণ', value: 'sfr-t' } 				] 			});  			work_area.append({ 				type: 'input', 				name: 'cfdtarget', 				label: 'লক্ষ্য বিষয়শ্রেণী:', // default, changed above 				disabled: true, 				required: true, // only when enabled 				value: '' 			}); 			appendReasonBox(); 			work_area = work_area.render(); 			old_area.parentNode.replaceChild(work_area, old_area); 			break;  		case 'cfds': 			work_area = new Morebits.quickForm.element({ 				type: 'field', 				label: 'দ্রুত পুনঃনামকরণের প্রয়োজন এমন বিষয়শ্রেণী', 				name: 'work_area' 			}); 			work_area.append({ 				type: 'select', 				label: 'সি২ উপ-মাপদণ্ড:', 				name: 'xfdcat', 				tooltip: 'সম্পূর্ণ ব্যাখ্যার জন্য WP:CFDS দেখুন।', 				list: [ 					{ type: 'option', label: 'C2A: টাইপোগ্রাফিক এবং বানান সংশোধন', value: 'C2A', selected: true }, 					{ type: 'option', label: 'C2B: নামকরণ এবং দ্ব্যর্থতা নিরসন', value: 'C2B' }, 					{ type: 'option', label: 'C2C: অনুরূপ বিষয়শ্রেণীর নামের সাথে সামঞ্জস্য', value: 'C2C' }, 					{ type: 'option', label: 'C2D: নিবন্ধের নামের সাথে মিল রেখে নাম পরিবর্তন', value: 'C2D' }, 					{ type: 'option', label: 'C2E: লেখকের অনুরোধ', value: 'C2E' }, 					{ type: 'option', label: 'C2F: One eponymous article', value: 'C2F' } 				] 			});  			work_area.append({ 				type: 'input', 				name: 'cfdstarget', 				label: 'নতুন নাম:', 				value: '', 				required: true 			}); 			appendReasonBox(); 			work_area = work_area.render(); 			old_area.parentNode.replaceChild(work_area, old_area); 			break;  		case 'rfd': 			work_area = new Morebits.quickForm.element({ 				type: 'field', 				label: 'Redirects for discussion', 				name: 'work_area' 			});  			work_area.append({ 				type: 'checkbox', 				list: [ 					{ 						label: 'সম্ভব হলে ব্যবহারকারীকে অবহিত করুন', 						value: 'relatedpage', 						name: 'relatedpage', 						tooltip: "এই পুনঃনির্দেশ ব্যবহারকারীর আলাপ পাতায় একটি বিজ্ঞপ্তি পাঠাবে, যদি এটি সত্য হয়।", 						checked: true 					} 				] 			}); 			appendReasonBox(); 			work_area = work_area.render(); 			old_area.parentNode.replaceChild(work_area, old_area); 			break;  		case 'rm': 			work_area = new Morebits.quickForm.element({ 				type: 'field', 				label: 'অনুরোধকৃত স্থানান্তর', 				name: 'work_area' 			}); 			work_area.append({ 				type: 'checkbox', 				list: [ 					{ 						label: 'বিতর্কিত প্রযুক্তিগত অনুরোধ', 						value: 'rmtr', 						name: 'rmtr', 						tooltip: 'এই বিকল্পটি ব্যবহার করুন যখন আপনি একটি প্রযুক্তিগত কারণে (যেমন একটি পৃষ্ঠা ইতিমধ্যেই নতুন শিরোনামে বিদ্যমান, বা পৃষ্ঠাটি সুরক্ষিত) এর কারণে এই বিতর্কিত পদক্ষেপটি নিতে পারছেন না।', 						checked: false, 						event: function() { 							form.newname.required = this.checked; 						}, 						subgroup: { 							type: 'checkbox', 							list: [ 								{ 									label: 'Opt out of discussion if the request is contested', 									value: 'rmtr-discuss', 									name: 'rmtr-discuss', 									tooltip: 'আপনি যদি প্রতিদ্বন্দ্বিতা করে অনুরোধটি প্রত্যাহার করতে পছন্দ করেন তবে এই বিকল্পটি ব্যবহার করুন, এটি নিয়ে আলোচনা না করে। এটি "আলোচনা" সংযোগকে দমন করে, যা আপনার অনুরোধকে আলাপ পাতায় আলোচনায় রূপান্তর করতে ব্যবহার করা যেতে পারে।', 									checked: false 								} 							] 						} 					} 				] 			}); 			work_area.append({ 				type: 'input', 				name: 'newname', 				label: 'নতুন শিরোনাম:', 				tooltip: 'প্রযুক্তিগত অনুরোধের জন্য প্রয়োজন। অন্যথায়, উপযুক্ত শিরোনাম সম্পর্কে অনিশ্চিত হলে, আপনি এটি খালি রাখতে পারেন।' 			});  			appendReasonBox(); 			work_area = work_area.render(); 			old_area.parentNode.replaceChild(work_area, old_area); 			break;  		default: 			work_area = new Morebits.quickForm.element({ 				type: 'field', 				label: 'Nothing for anything', 				name: 'work_area' 			}); 			work_area = work_area.render(); 			old_area.parentNode.replaceChild(work_area, old_area); 			break; 	}  	// Return to checked state when switching, but no creator notification for CFDS or RM 	form.notifycreator.disabled = value === 'cfds' || value === 'rm'; 	form.notifycreator.checked = !form.notifycreator.disabled; };  Twinkle.xfd.callbacks = { 	// Requires having the tag text (params.tagText) set ahead of time 	autoEditRequest: function(pageobj, params) { 		var talkName = new mw.Title(pageobj.getPageName()).getTalkPage().toText(); 		if (talkName === pageobj.getPageName()) { 			pageobj.getStatusElement().error('পৃষ্ঠাটি সুরক্ষিত এবং কোথাও একটি সম্পাদনা অনুরোধ যোগের জন্য কিছু পাওয়া যায়নি, বাতিল করা হচ্ছে'); 		} else { 			pageobj.getStatusElement().warn('পৃষ্ঠা সুরক্ষিত, সম্পাদনার অনুরোধ করা হচ্ছে');  			var editRequest = '{{subst:Xfd edit protected|page=' + pageobj.getPageName() + 				'|discussion=' + params.discussionpage + (params.venue === 'rfd' ? '|rfd=yes' : '') + 				'|tag=<nowiki>' + params.tagText + '\u003C/nowiki>}}'; // U+003C: <  			var talk_page = new Morebits.wiki.page(talkName, 'আলাপ পাতায় স্বয়ংক্রিয়ভাবে সম্পাদনার অনুরোধ যোগ করা হচ্ছে'); 			talk_page.setNewSectionTitle(utils.toTLACase(params.venue) + ' মনোনয়ন সম্পন্ন করতে সম্পাদনার অনুরোধ'); 			talk_page.setNewSectionText(editRequest); 			talk_page.setCreateOption('recreate'); 			talk_page.setWatchlist(Twinkle.getPref('xfdWatchPage')); 			talk_page.setFollowRedirect(true);  // should never be needed, but if the article is moved, we would want to follow the redirect 			talk_page.setChangeTags(Twinkle.changeTags); 			talk_page.setCallbackParameters(params); 			talk_page.newSection(null, function() { 				talk_page.getStatusElement().warn('সম্পাদনার অনুরোধ করা যায়নি, আলাপ পাতাটি সম্ভবত সুরক্ষিত করা'); 			}); 		} 	}, 	getDiscussionWikitext: function(venue, params) { 		if (venue === 'cfds') { // CfD/S takes a completely different style 			return '* [[:' + Morebits.pageNameNorm + ']] to [[:' + params.cfdstarget + ']]\u00A0\u2013 ' + 				params.xfdcat + (params.reason ? ': ' + Morebits.string.formatReasonText(params.reason) : '।') + ' ~~~~'; 			// U+00A0 NO-BREAK SPACE; U+2013 EN RULE 		} 		if (venue === 'rm') { 			// even if invoked from talk page, propose the subject page for move 			var pageName = new mw.Title(Morebits.pageNameNorm).getSubjectPage().toText(); 			var rmtrDiscuss = params['rmtr-discuss'] ? '|discuss=no' : ''; 			var rmtr = '{{subst:RMassist|1=' + pageName + '|2=' + params.newname + rmtrDiscuss + '|reason=' + params.reason + '}}'; 			var requestedMove = '{{subst:Requested move|current1=' + pageName + '|new1=' + params.newname + '|reason=' + params.reason + '}}'; 			return params.rmtr ? rmtr : requestedMove; 		}  		var text = '{{subst:' + venue + '2'; 		var reasonKey = venue === 'ffd' ? 'Reason' : 'text'; 		// Add a reason unconditionally, so that at least a signature is added 		text += '|' + reasonKey + '=' + Morebits.string.formatReasonText(params.reason, true);  		if (venue === 'afd' || venue === 'mfd') { 			text += '|pg=' + Morebits.pageNameNorm; 			if (venue === 'afd') { 				text += '|cat=' + params.xfdcat; 			} 		} else if (venue === 'rfd') { 			text += '|redirect=' + Morebits.pageNameNorm; 		} else { 			text += mw.config.get('wgTitle'); 			if (mw.config.get('wgPageContentModel') === 'Scribunto') { 				text += '|module=Module:'; 			} 		}  		if (params.rfdtarget) { 			text += '|target=' + params.rfdtarget + (params.section ? '#' + params.section : ''); 		} else if (params.tfdtarget) { 			text += '|2=' + params.tfdtarget; 		} else if (params.cfdtarget) { 			text += '|2=' + params.cfdtarget; 			if (params.cfdtarget2) { 				text += '|3=' + params.cfdtarget2; 			} 		} else if (params.uploader) { 			text += '|Uploader=' + params.uploader; 		}  		text += '}}';  		// Don't delsort if delsortCats is undefined (TFD, FFD, etc.) 		// Don't delsort if delsortCats is an empty array (AFD where user chose no categories) 		if (Array.isArray(params.delsortCats) && params.delsortCats.length) { 			params.delsortCats.forEach(function (cat) { 				text += '\n{{subst:delsort|' + cat + '|~~~~}}'; 			}); 		}  		return text; 	}, 	showPreview: function(form, venue, params) { 		var templatetext = Twinkle.xfd.callbacks.getDiscussionWikitext(venue, params); 		if (venue === 'rm') { // RM templates are sensitive to page title 			form.previewer.beginRender(templatetext, params.rmtr ? 'Wikipedia:Requested moves/Technical requests' : new mw.Title(Morebits.pageNameNorm).getTalkPage().toText()); 		} else { 			form.previewer.beginRender(templatetext, 'WP:TW'); // Force wikitext 		} 	}, 	preview: function(form) { 		// venue, reason, xfdcat, tfdtarget, cfdtarget, cfdtarget2, cfdstarget, delsortCats, newname 		var params = Morebits.quickForm.getInputData(form);  		var venue = params.venue;  		// Remove CfD or TfD namespace prefixes if given 		if (params.tfdtarget) { 			params.tfdtarget = utils.stripNs(params.tfdtarget); 		} else if (params.cfdtarget) { 			params.cfdtarget = utils.stripNs(params.cfdtarget); 			if (params.cfdtarget2) { 				params.cfdtarget2 = utils.stripNs(params.cfdtarget2); 			} 		} else if (params.cfdstarget) { // Add namespace if not given (CFDS) 			params.cfdstarget = utils.addNs(params.cfdstarget, 14); 		}  		if (venue === 'ffd') { 			// Fetch the uploader 			var page = new Morebits.wiki.page(mw.config.get('wgPageName')); 			page.lookupCreation(function() { 				params.uploader = page.getCreator(); 				Twinkle.xfd.callbacks.showPreview(form, venue, params); 			}); 		} else if (venue === 'rfd') { // Find the target 			Twinkle.xfd.callbacks.rfd.findTarget(params, function(params) { 				Twinkle.xfd.callbacks.showPreview(form, venue, params); 			}); 		} else if (venue === 'cfd') { // Swap in CfD subactions 			Twinkle.xfd.callbacks.showPreview(form, params.xfdcat, params); 		} else { 			Twinkle.xfd.callbacks.showPreview(form, venue, params); 		} 	}, 	/** 	 * Unified handler for sending {{Xfd notice}} notifications 	 * Also handles userspace logging 	 * @param {object} params 	 * @param {string} notifyTarget The user or page being notified 	 * @param {boolean} [noLog=false] Whether to skip logging to userspace 	 * XfD log, especially useful in cases in where multiple notifications 	 * may be sent out (MfD, TfM, RfD) 	 * @param {string} [actionName] Alternative description of the action 	 * being undertaken. Required if not notifying a user talk page. 	 */ 	notifyUser: function(params, notifyTarget, noLog, actionName) { 		// Ensure items with User talk or no namespace prefix both end 		// up at user talkspace as expected, but retain the 		// prefix-less username for addToLog 		notifyTarget = mw.Title.newFromText(notifyTarget, 3); 		var targetNS = notifyTarget.getNamespaceId(); 		var usernameOrTarget = notifyTarget.getRelativeText(3); 		notifyTarget = notifyTarget.toText(); 		if (targetNS === 3) { 			// Disallow warning yourself 			if (usernameOrTarget === mw.config.get('wgUserName')) { 				Morebits.status.warn('আপনি (' + usernameOrTarget + ') এই পাতাটি তৈরি করেছেন; বিজ্ঞপ্তি পাঠানো এড়িয়ে যাওয়া হচ্ছে');  				// if we thought we would notify someone but didn't, 				// then jump to logging. 				Twinkle.xfd.callbacks.addToLog(params, null); 				return; 			} 			// Default is notifying the initial contributor, but MfD also 			// notifies userspace page owner 			actionName = actionName || 'মূল অবদানকারীকে জানানো হচ্ছে (' + usernameOrTarget + ')'; 		}  		var notifytext = '\n{{subst:' + params.venue + ' notice'; 		// Venue-specific parameters 		switch (params.venue) { 			case 'afd': 			case 'mfd': 				notifytext += params.numbering !== '' ? '|order= ' + params.numbering : ''; 				break; 			case 'tfd': 				if (params.xfdcat === 'tfm') { 					notifytext = '\n{{subst:Tfm notice|2=' + params.tfdtarget; 				} 				break; 			case 'cfd': 				notifytext += '|action=' + params.action + (mw.config.get('wgNamespaceNumber') === 10 ? '|stub=yes' : ''); 				break; 			default: // ffd, rfd 				break; 		} 		notifytext += '|1=' + Morebits.pageNameNorm + '}} ~~~~';  		// Link to the venue; object used here rather than repetitive items in switch 		var venueNames = { 			afd: 'নিবন্ধ অপসারণের প্রস্তাবনা', 			tfd: 'টেমপ্লেট অপসারণের প্রস্তাবনা', 			mfd: 'অন্যান অপসারণ প্রস্তাবনা', 			cfd: 'বিষয়শ্রেণী অপসারণের প্রস্তাবনা', 			ffd: 'চিত্র অপসারণের প্রস্তাবনা', 			rfd: 'পুনর্নির্দেশ অপসারণের প্রস্তাবনা' 		}; 		var editSummary = 'বিজ্ঞপ্তি: [[উইকিপিডিয়া:' + venueNames[params.venue] + ']]-এ [[:' + 			Morebits.pageNameNorm + ']] পাতাটি [[' + params.discussionpage + '|তালিকাভুক্ত]] করা হয়েছে।';  		var usertalkpage = new Morebits.wiki.page(notifyTarget, actionName); 		usertalkpage.setAppendText(notifytext); 		usertalkpage.setEditSummary(editSummary); 		usertalkpage.setChangeTags(Twinkle.changeTags); 		usertalkpage.setCreateOption('recreate'); 		// Different pref for RfD target notifications 		if (params.venue === 'rfd' && targetNS !== 3) { 			usertalkpage.setWatchlist(Twinkle.getPref('xfdWatchRelated')); 		} else { 			usertalkpage.setWatchlist(Twinkle.getPref('xfdWatchUser')); 		} 		usertalkpage.setFollowRedirect(true, false);  		if (noLog) { 			usertalkpage.append(); 		} else { 			usertalkpage.append(function onNotifySuccess() { 				// Don't treat RfD target or MfD userspace owner as initialContrib in log 				if (!params.notifycreator) { 					notifyTarget = null; 				} 				// add this nomination to the user's userspace log 				Twinkle.xfd.callbacks.addToLog(params, usernameOrTarget); 			}, function onNotifyError() { 				// if user could not be notified, log nomination without mentioning that notification was sent 				Twinkle.xfd.callbacks.addToLog(params, null); 			}); 		} 	}, 	addToLog: function(params, initialContrib) { 		if (!Twinkle.getPref('logXfdNominations') || Twinkle.getPref('noLogOnXfdNomination').indexOf(params.venue) !== -1) { 			return; 		}  		var usl = new Morebits.userspaceLogger(Twinkle.getPref('xfdLogPageName'));// , 'Adding entry to userspace log');  		usl.initialText = 			"এটি [[WP:Afd|অপসারণ প্রস্তাবনার]] মনোনয়নের একটি লগ যা [[WP:TW|টুইংকলের]] Xfd মডিউল ব্যবহার করে এই ব্যবহারকারী তৈরি করেছেন।\n\n" + 			'আপনি যদি এই লগটি আর রাখতে না চান, তাহলে আপনি  [[উইকিপিডিয়া:টুইংকল/পছন্দসমূহ|পছন্দসমূহ প্যানেল]] ব্যবহার করে এটি বন্ধ করতে পারেন, এবং '+ '[[WP:CSD#U1|সিএসডি ব১]]-এর অধীনে এই পাতাটি দ্রুত অপসারণের জন্য মনোনয়ন করতে পারেন।' + 			(Morebits.userIsSysop ? '\n\nএই লগটি টুইংকল ব্যবহার করে Xfd সংক্রান্ত মুছে ফেলা পাতা তালিকাভুক্ত করে না।' : '');  		var editsummary =  'অপসারণ প্রস্তাবনার লগ তালিকাভুক্ত করা হচ্ছে; [[:' + Morebits.pageNameNorm + ']]।';  		// If a logged file is deleted but exists on commons, the wikilink will be blue, so provide a link to the log 		var fileLogLink = mw.config.get('wgNamespaceNumber') === 6 ? ' ([{{fullurl:Special:Log|page=' + mw.util.wikiUrlencode(mw.config.get('wgPageName')) + '}} লগ])' : ''; 		// CFD/S and RM don't have canonical links 		var nominatedLink = params.discussionpage ? '[[' + params.discussionpage + '|nominated]]' : 'nominated';  		var appendText = '# [[:' + Morebits.pageNameNorm + ']]:' + fileLogLink + ' ' + nominatedLink + ' at [[WP:' + params.venue.toUpperCase() + '|' + utils.toTLACase(params.venue) + ']]';  		switch (params.venue) { 			case 'tfd': 				if (params.xfdcat === 'tfm') { 					appendText += ' (merge)'; 					if (params.tfdtarget) { 						var contentModel = mw.config.get('wgPageContentModel') === 'Scribunto' ? 'Module:' : 'Template:'; 						appendText += '; Other ' + contentModel.toLowerCase() + ' [['; 						if (!new RegExp('^:?' + Morebits.namespaceRegex([10, 828]) + ':', 'i').test(params.tfdtarget)) { 							appendText += contentModel; 						} 						appendText += params.tfdtarget + ']]'; 					} 				} 				break; 			case 'mfd': 				if (params.notifyuserspace && params.userspaceOwner && params.userspaceOwner !== initialContrib) { 					appendText += '; {{user|1=' + params.userspaceOwner + '}}-কে জানানো হয়েছে'; 				} 				break; 			case 'cfd': 				appendText += ' (' + utils.toTLACase(params.xfdcat) + ')'; 				if (params.cfdtarget) { 					var categoryOrTemplate = params.xfdcat.charAt(0) === 's' ? 'Template:' : ':Category:'; 					appendText += '; ' + params.action + ' to [[' + categoryOrTemplate + params.cfdtarget + ']]'; 					if (params.xfdcat === 'cfs' && params.cfdtarget2) { 						appendText += ', [[' + categoryOrTemplate + params.cfdtarget2 + ']]'; 					} 				} 				break; 			case 'cfds': 				appendText += ' (' + utils.toTLACase(params.xfdcat) + ')'; 				// Ensure there's more than just 'Category:' 				if (params.cfdstarget && params.cfdstarget.length > 9) { 					appendText += '; New name: [[:' + params.cfdstarget + ']]'; 				} 				break; 			case 'rfd': 				if (params.rfdtarget) { 					appendText += '; Target: [[:' + params.rfdtarget + ']]'; 					if (params.relatedpage) { 						appendText += ' (notified)'; 					} 				} 				break; 			case 'rm': 				if (params.rmtr) { 					appendText += ' (technical)'; 				} 				if (params.newname) { 					appendText += '; New name: [[:' + params.newname + ']]'; 				} 				break;  			default: // afd or ffd 				break; 		}  		if (initialContrib && params.notifycreator) { 			appendText += '; {{user|1=' + initialContrib + '}} কে জানানো হয়েছে'; 		} 		appendText += ' ~~~~~'; 		if (params.reason) { 			appendText += "\n#* '''কারণ''': " + Morebits.string.formatReasonForLog(params.reason); 		}  		usl.changeTags = Twinkle.changeTags; 		usl.log(appendText, editsummary); 	},  	afd: { 		main: function(apiobj) { 			var response = apiobj.getResponse(); 			var titles = response.query.allpages;  			// There has been no earlier entries with this prefix, just go on. 			if (titles.length <= 0) { 				apiobj.params.numbering = apiobj.params.number = ''; 			} else { 				var number = 0; 				for (var i = 0; i < titles.length; ++i) { 					var title = titles[i].title;  					// First, simple test, is there an instance with this exact name? 					if (title === 'উইকিপিডিয়া:নিবন্ধ অপসারণের প্রস্তাবনা/' + Morebits.pageNameNorm) { 						number = Math.max(number, 1); 						continue; 					}  					var order_re = new RegExp('^' + 						Morebits.string.escapeRegExp('উইকিপিডিয়া:নিবন্ধ অপসারণের প্রস্তাবনা/' + Morebits.pageNameNorm) + 						'\\s*\\(\\s*(\\d+)(?:(?:th|nd|rd|st) nom(?:ination)?)?\\s*\\)\\s*$'); 					var match = order_re.exec(title);  					// No match; A non-good value or the match is an unrealistically high number. Avoid false positives such as Wikipedia:Articles for deletion/The Basement (2014), by ignoring matches greater than 100 					if (!match || match[1] > 100) { 						continue; 					}  					// A match, set number to the max of current 					number = Math.max(number, Number(match[1])); 				} 				apiobj.params.number = utils.num2order(parseInt(number, 10) + 1); 				apiobj.params.numbering = number > 0 ? ' (' + apiobj.params.number + ' মনোনয়ন)' : ''; 			} 			apiobj.params.discussionpage = 'উইকিপিডিয়া:নিবন্ধ অপসারণের প্রস্তাবনা/' + Morebits.pageNameNorm + apiobj.params.numbering;  			Morebits.status.info('পরবর্তী আলোচনার পাতা', '[[' + apiobj.params.discussionpage + ']]');  			// Updating data for the action completed event 			Morebits.wiki.actionCompleted.redirect = apiobj.params.discussionpage; 			Morebits.wiki.actionCompleted.notice = 'মনোনয়ন সম্পন্ন, আলোচনার পাতায় পুনঃনির্দেশ করা হচ্ছে';  			// Tagging article 			var wikipedia_page = new Morebits.wiki.page(mw.config.get('wgPageName'), 'পাতায় অপসারণ প্রস্তাবনার ট্যাগ যুক্ত করা হচ্ছে'); 			wikipedia_page.setFollowRedirect(true);  // should never be needed, but if the article is moved, we would want to follow the redirect 			wikipedia_page.setChangeTags(Twinkle.changeTags); // Here to apply to triage 			wikipedia_page.setCallbackParameters(apiobj.params); 			wikipedia_page.load(Twinkle.xfd.callbacks.afd.taggingArticle); 		}, 		// Tagging needs to happen before everything else: this means we can check if there is an AfD tag already on the page 		taggingArticle: function(pageobj) { 			var text = pageobj.getPageText(); 			var params = pageobj.getCallbackParameters(); 			var statelem = pageobj.getStatusElement();  			if (!pageobj.exists()) { 				statelem.error("It seems that the page doesn't exist; perhaps it has already been deleted"); 				return; 			}  			// Check for existing AfD tag, for the benefit of new page patrollers 			var textNoAfd = text.replace(/<!--.*AfD.*\n\{\{(?:Article for deletion\/dated|AfDM).*\}\}\n<!--.*(?:\n<!--.*)?AfD.*(?:\s*\n)?/g, ''); 			if (text !== textNoAfd) { 				if (confirm('এই নিবন্ধে একটি অপসারণ প্রস্তাবনার ট্যাগ পাওয়া গেছে। সম্ভবত আপনার আগেই কেউ প্রস্তাব দিয়েছে।  \nবর্তমান ট্যাগকে প্রতিস্থাপন করতে ঠিক আছে চাপুন (না করার পরামর্শ দেওয়া হচ্ছে), অথবা প্রস্তাবনা দেওয়া এড়িয়ে যেতে বাতিল চাপুন।')) { 					text = textNoAfd; 				} else { 					statelem.error('Article already tagged with AfD tag, and you chose to abort'); 					window.location.reload(); 					return; 				} 			}  			// Now we know we want to go ahead with it, trigger the other AJAX requests  			// Mark the page as curated/patrolled, if wanted 			if (Twinkle.getPref('markXfdPagesAsPatrolled')) { 				new Morebits.wiki.page(Morebits.pageNameNorm).triage(); 			}  			// Start discussion page, will also handle pagetriage and delsort listings 			var wikipedia_page = new Morebits.wiki.page(params.discussionpage, 'নিবন্ধ অপসারণ প্রস্তাবনার পাতা তৈরি করা হচ্ছে'); 			wikipedia_page.setCallbackParameters(params); 			wikipedia_page.load(Twinkle.xfd.callbacks.afd.discussionPage);  			// Today's list 			var date = new Morebits.date(pageobj.getLoadTime()); 			wikipedia_page = new Morebits.wiki.page('উইকিপিডিয়া:নিবন্ধ অপসারণের প্রস্তাবনা/' + new Date().toLocaleDateString("bn", { year: "numeric" }) + ' ' + 				date.format('MMMM', 'utc'), "এই মাসের তালিকায় আলোচনা যোগ করা হচ্ছে"); 			wikipedia_page.setFollowRedirect(true); 			wikipedia_page.setCallbackParameters(params); 			wikipedia_page.load(Twinkle.xfd.callbacks.afd.todaysList); 			// Notification to first contributor 			if (params.notifycreator) { 				var thispage = new Morebits.wiki.page(mw.config.get('wgPageName')); 				thispage.setCallbackParameters(params); 				thispage.setLookupNonRedirectCreator(true); // Look for author of first non-redirect revision 				thispage.lookupCreation(function(pageobj) { 					Twinkle.xfd.callbacks.notifyUser(pageobj.getCallbackParameters(), pageobj.getCreator()); 				}); 			// or, if not notifying, add this nomination to the user's userspace log without the initial contributor's name 			} else { 				Twinkle.xfd.callbacks.addToLog(params, null); 			}  			params.tagText = (params.noinclude ? '<noinclude>{{' : '{{') + (params.number === '' ? 'subst:afd|help=off' : 'subst:afdx|' + 					params.number + '|help=off') + (params.noinclude ? '}}</noinclude>\n' : '}}\n');  			if (pageobj.canEdit()) { 			// Remove some tags that should always be removed on AfD. 				text = text.replace(/\{\{\s*(dated prod|dated prod blp|Prod blp\/dated|Proposed deletion\/dated|prod2|Proposed deletion endorsed|Userspace draft)\s*(\|(?:\{\{[^{}]*\}\}|[^{}])*)?\}\}\s*/ig, ''); 				// Then, test if there are speedy deletion-related templates on the article. 				var textNoSd = text.replace(/\{\{\s*(db(-\w*)?|delete|(?:hang|hold)[- ]?on)\s*(\|(?:\{\{[^{}]*\}\}|[^{}])*)?\}\}\s*/ig, ''); 				if (text !== textNoSd && confirm('এই পাতায় একটি দ্রুত অপসারণ ট্যাগ পাওয়া গেছে। এটি অপসারণ করবেন?')) { 					text = textNoSd; 				}  				// Insert tag after short description or any hatnotes 				var wikipage = new Morebits.wikitext.page(text); 				text = wikipage.insertAfterTemplates(params.tagText, Twinkle.hatnoteRegex).getText();  				pageobj.setPageText(text); 				pageobj.setEditSummary('অপসারণের জন্য মনোনীত করা হয়েছে; [[:' + params.discussionpage + ']] দেখুন।'); 				pageobj.setWatchlist(Twinkle.getPref('xfdWatchPage')); 				pageobj.setCreateOption('nocreate'); 				pageobj.save(); 			} else { 				Twinkle.xfd.callbacks.autoEditRequest(pageobj, params); 			} 		}, 		discussionPage: function(pageobj) { 			var params = pageobj.getCallbackParameters();  			pageobj.setPageText(Twinkle.xfd.callbacks.getDiscussionWikitext('afd', params)); 			pageobj.setEditSummary('[[:' + Morebits.pageNameNorm + ']]-এর জন্য আলোচনার পাতা তৈরি করা হয়েছে।'); 			pageobj.setChangeTags(Twinkle.changeTags); 			pageobj.setWatchlist(Twinkle.getPref('xfdWatchDiscussion')); 			pageobj.setCreateOption('createonly'); 			pageobj.save(function() { 				Twinkle.xfd.currentRationale = null;  // any errors from now on do not need to print the rationale, as it is safely saved on-wiki  				// Actions that should wait on the discussion page actually being created 				// and whose errors shouldn't output the user rationale 				// List at deletion sorting pages 				if (params.delsortCats) { 					params.delsortCats.forEach(function (cat) { 						var delsortPage = new Morebits.wiki.page('Wikipedia:WikiProject Deletion sorting/' + cat, 'Adding to list of ' + cat + '-related deletion discussions'); 						delsortPage.setFollowRedirect(true); // In case a category gets renamed 						delsortPage.setCallbackParameters({discussionPage: params.discussionpage}); 						delsortPage.load(Twinkle.xfd.callbacks.afd.delsortListing); 					}); 				} 			}); 		}, 		todaysList: function(pageobj) { 			var params = pageobj.getCallbackParameters(); 			var statelem = pageobj.getStatusElement();  			var added_data = '{{subst:afd3|pg=' + Morebits.pageNameNorm + params.numbering + '}}\n'; 			var text;  			// add date header if the log is found to be empty (a bot should do this automatically) 			if (!pageobj.exists()) { 				text = '{{subst:AfD log}}\n' + added_data; 			} else { 				var old_text = pageobj.getPageText() + '\n';  // MW strips trailing blanks, but we like them, so we add a fake one  				text = old_text.replace(/(<!-- নতুন ভুক্তি নিচের তালিকার সবার উপরে যুক্ত করুন -->\n+)/, '$1' + added_data); 				if (text === old_text) { 					var linknode = document.createElement('a'); 					linknode.setAttribute('href', mw.util.getUrl('Wikipedia:Twinkle/Fixing AFD') + '?action=purge'); 					linknode.appendChild(document.createTextNode('How to fix AFD')); 					statelem.error([ 'Could not find the target spot for the discussion. To fix this problem, please see ', linknode, '.' ]); 					return; 				} 			}  			pageobj.setPageText(text); 			pageobj.setEditSummary('[[:' + params.discussionpage + ']] যোগ করা হয়েছে।'); 			pageobj.setChangeTags(Twinkle.changeTags); 			pageobj.setWatchlist(Twinkle.getPref('xfdWatchList')); 			pageobj.setCreateOption('recreate'); 			pageobj.save(); 		}, 		delsortListing: function(pageobj) { 			var discussionPage = pageobj.getCallbackParameters().discussionPage; 			var text = pageobj.getPageText().replace('directly below this line -->', 'directly below this line -->\n{{' + discussionPage + '}}'); 			pageobj.setPageText(text); 			pageobj.setEditSummary('[[:' + discussionPage + ']] তালিকাভুক্ত করা হচ্ছে।'); 			pageobj.setChangeTags(Twinkle.changeTags); 			pageobj.setCreateOption('nocreate'); 			pageobj.save(); 		} 	},  	tfd: { 		main: function(pageobj) { 			var params = pageobj.getCallbackParameters();  			var date = new Morebits.date(pageobj.getLoadTime()); 			params.logpage = 'Wikipedia:Templates for discussion/Log/' + date.format('YYYY MMMM D', 'utc'), 			params.discussionpage = params.logpage + '#' + Morebits.pageNameNorm; 			// Add log/discussion page params to the already-loaded page object 			pageobj.setCallbackParameters(params);  			// Defined here rather than below to reduce duplication 			var watchModule, watch_query; 			if (params.scribunto) { 				var watchPref = Twinkle.getPref('xfdWatchPage'); 				// action=watch has no way to rely on user 				// preferences (T262912), so we do it manually. 				// The watchdefault pref appears to reliably return '1' (string), 				// but that's not consistent among prefs so might as well be "correct" 				watchModule = watchPref !== 'no' && (watchPref !== 'default' || !!parseInt(mw.user.options.get('watchdefault'), 10)); 				if (watchModule) { 					watch_query = { 						action: 'watch', 						titles: [ mw.config.get('wgPageName') ], 						token: mw.user.tokens.get('watchToken') 					}; 					// Only add the expiry if page is unwatched or already temporarily watched 					if (pageobj.getWatched() !== true && watchPref !== 'default' && watchPref !== 'yes') { 						watch_query.expiry = watchPref; 					} 				} 			}  			// Tagging template(s)/module(s) 			if (params.xfdcat === 'tfm') { // Merge 				var wikipedia_otherpage; 				if (params.scribunto) { 					wikipedia_otherpage = new Morebits.wiki.page(params.otherTemplateName + '/নথি', 'Tagging other module documentation with merge tag');  					// Watch tagged module pages as well 					if (watchModule) { 						watch_query.titles.push(params.otherTemplateName); 						new Morebits.wiki.api('Adding Modules to watchlist', watch_query).post(); 					} 				} else { 					wikipedia_otherpage = new Morebits.wiki.page(params.otherTemplateName, 'Tagging other template with merge tag'); 				} 				// Tag this template/module 				Twinkle.xfd.callbacks.tfd.taggingTemplateForMerge(pageobj);  				// Tag other template/module 				wikipedia_otherpage.setFollowRedirect(true); 				var otherParams = $.extend({}, params); 				otherParams.otherTemplateName = Morebits.pageNameNorm; 				wikipedia_otherpage.setCallbackParameters(otherParams); 				wikipedia_otherpage.load(Twinkle.xfd.callbacks.tfd.taggingTemplateForMerge); 			} else { // delete 				if (params.scribunto && Twinkle.getPref('xfdWatchPage') !== 'no') { 					// Watch tagged module page as well 					if (watchModule) { 						new Morebits.wiki.api('Adding Module to watchlist', watch_query).post(); 					} 				} 				Twinkle.xfd.callbacks.tfd.taggingTemplate(pageobj); 			}  			// Updating data for the action completed event 			Morebits.wiki.actionCompleted.redirect = params.logpage; 			Morebits.wiki.actionCompleted.notice = "Nomination completed, now redirecting to today's log";  			// Adding discussion 			var wikipedia_page = new Morebits.wiki.page(params.logpage, "Adding discussion to today's log"); 			wikipedia_page.setFollowRedirect(true); 			wikipedia_page.setCallbackParameters(params); 			wikipedia_page.load(Twinkle.xfd.callbacks.tfd.todaysList);  			// Notification to first contributors 			if (params.notifycreator) { 				var involvedpages = []; 				var seenusers = []; 				involvedpages.push(new Morebits.wiki.page(mw.config.get('wgPageName'))); 				if (params.xfdcat === 'tfm') { 					if (params.scribunto) { 						involvedpages.push(new Morebits.wiki.page('Module:' + params.tfdtarget)); 					} else { 						involvedpages.push(new Morebits.wiki.page('Template:' + params.tfdtarget)); 					} 				} 				involvedpages.forEach(function(page) { 					page.setCallbackParameters(params); 					page.lookupCreation(function(innerpage) { 						var username = innerpage.getCreator(); 						if (seenusers.indexOf(username) === -1) { 							seenusers.push(username); 							// Only log once on merge nominations, for the initial template 							Twinkle.xfd.callbacks.notifyUser(innerpage.getCallbackParameters(), username, 								params.xfdcat === 'tfm' && innerpage.getPageName() !== Morebits.pageNameNorm); 						} 					}); 				}); 			// or, if not notifying, add this nomination to the user's userspace log without the initial contributor's name 			} else { 				Twinkle.xfd.callbacks.addToLog(params, null); 			}  			// Notify developer(s) of script(s) that use(s) the nominated template 			if (params.devpages) { 				var inCategories = mw.config.get('wgCategories'); 				var categoryNotificationPageMap = { 					'Templates used by Twinkle': 'Wikipedia talk:Twinkle', 					'Templates used by AutoWikiBrowser': 'Wikipedia talk:AutoWikiBrowser', 					'Templates used by Ultraviolet': 'Wikipedia talk:Ultraviolet' 				}; 				$.each(categoryNotificationPageMap, function(category, page) { 					if (inCategories.indexOf(category) !== -1) { 						Twinkle.xfd.callbacks.notifyUser(params, page, true, 'Notifying ' + page + ' of template nomination'); 					} 				}); 			}  		}, 		taggingTemplate: function(pageobj) { 			var text = pageobj.getPageText(); 			var params = pageobj.getCallbackParameters();  			params.tagText = '{{subst:template for discussion|help=off' + (params.templatetype !== 'standard' ? '|type=' + params.templatetype : '') + '}}';  			if (pageobj.getContentModel() === 'sanitized-css') { 				params.tagText = '/* ' + params.tagText + ' */'; 			} else { 				if (params.noinclude) { 					params.tagText = '<noinclude>' + params.tagText + '</noinclude>'; 				} 					params.tagText += params.templatetype === 'standard' || params.templatetype === 'sidebar' || params.templatetype === 'disabled' ? '\n' : ''; // No newline for inline 			}  			if (pageobj.canEdit() && ['wikitext', 'sanitized-css'].indexOf(pageobj.getContentModel()) !== -1) { 				pageobj.setPageText(params.tagText + text); 				pageobj.setEditSummary('অপসারণের জন্য মনোনীত করা হয়েছে; [[:' + params.discussionpage + ']] দেখুন।'); 				pageobj.setChangeTags(Twinkle.changeTags); 				pageobj.setWatchlist(Twinkle.getPref('xfdWatchPage')); 				if (params.scribunto) { 					pageobj.setCreateOption('recreate'); // Module /doc might not exist 				} 				pageobj.save(); 			} else { 				Twinkle.xfd.callbacks.autoEditRequest(pageobj, params); 			} 		}, 		taggingTemplateForMerge: function(pageobj) { 			var text = pageobj.getPageText(); 			var params = pageobj.getCallbackParameters();  			params.tagText = '{{subst:tfm|help=off|' + (params.templatetype !== 'standard' ? 'type=' + params.templatetype + '|' : '') + 				'1=' + params.otherTemplateName.replace(new RegExp('^' + Morebits.namespaceRegex([10, 828]) + ':'), '') + '}}';  			if (pageobj.getContentModel() === 'sanitized-css') { 				params.tagText = '/* ' + params.tagText + ' */'; 			} else { 				if (params.noinclude) { 					params.tagText = '<noinclude>' + params.tagText + '</noinclude>'; 				} 				params.tagText += params.templatetype === 'standard' || params.templatetype === 'sidebar' || params.templatetype === 'disabled' ? '\n' : ''; // No newline for inline 			}  			if (pageobj.canEdit() && ['wikitext', 'sanitized-css'].indexOf(pageobj.getContentModel()) !== -1) { 				pageobj.setPageText(params.tagText + text); 				pageobj.setEditSummary('Listed for merging with [[:' + params.otherTemplateName + ']]; see [[:' + params.discussionpage + ']].'); 				pageobj.setChangeTags(Twinkle.changeTags); 				pageobj.setWatchlist(Twinkle.getPref('xfdWatchPage')); 				if (params.scribunto) { 					pageobj.setCreateOption('recreate'); // Module /doc might not exist 				} 				pageobj.save(); 			} else { 				Twinkle.xfd.callbacks.autoEditRequest(pageobj, params); 			} 		}, 		todaysList: function(pageobj) { 			var params = pageobj.getCallbackParameters();  			var added_data = Twinkle.xfd.callbacks.getDiscussionWikitext(params.xfdcat, params); 			var text;  			// add date header if the log is found to be empty (a bot should do this automatically) 			if (!pageobj.exists()) { 				text = '{{subst:TfD log}}\n' + added_data; 			} else { 				var old_text = pageobj.getPageText();  				text = old_text + '\n\n' + added_data; 			}  			pageobj.setPageText(text); 			pageobj.setEditSummary('Adding ' + (params.xfdcat === 'tfd' ? 'deletion nomination' : 'merge listing') + ' of [[:' + Morebits.pageNameNorm + ']].'); 			pageobj.setChangeTags(Twinkle.changeTags); 			pageobj.setWatchlist(Twinkle.getPref('xfdWatchDiscussion')); 			pageobj.setCreateOption('recreate'); 			pageobj.save(function() { 				Twinkle.xfd.currentRationale = null;  // any errors from now on do not need to print the rationale, as it is safely saved on-wiki 			}); 		} 	},  	mfd: { 		main: function(apiobj) { 			var response = apiobj.getResponse(); 			var titles = response.query.allpages;  			// There has been no earlier entries with this prefix, just go on. 			if (titles.length <= 0) { 				apiobj.params.numbering = apiobj.params.number = ''; 			} else { 				var number = 0; 				for (var i = 0; i < titles.length; ++i) { 					var title = titles[i].title;  					// First, simple test, is there an instance with this exact name? 					if (title === 'উইকিপিডিয়া:বিবিধ অপসারণের প্রস্তাবনা/' + Morebits.pageNameNorm) { 						number = Math.max(number, 1); 						continue; 					}  					var order_re = new RegExp('^' + 							Morebits.string.escapeRegExp('উইকিপিডিয়া:বিবিধ অপসারণের প্রস্তাবনা/' + Morebits.pageNameNorm) + 							'\\s*\\(\\s*(\\d+)(?:(?:th|nd|rd|st) nom(?:ination)?)?\\s*\\)\\s*$'); 					var match = order_re.exec(title);  					// No match; A non-good value 					if (!match) { 						continue; 					}  					// A match, set number to the max of current 					number = Math.max(number, Number(match[1])); 				} 				apiobj.params.number = utils.num2order(parseInt(number, 10) + 1); 				apiobj.params.numbering = number > 0 ? ' (' + apiobj.params.number + ' মনোনয়ন)' : ''; 			} 			apiobj.params.discussionpage = 'উইকিপিডিয়া:বিবিধ অপসারণের প্রস্তাবনা/' + Morebits.pageNameNorm + apiobj.params.numbering;  			apiobj.statelem.info('next in order is [[' + apiobj.params.discussionpage + ']]');  			// Tagging page 			var wikipedia_page = new Morebits.wiki.page(mw.config.get('wgPageName'), 'পাতায় অপসারণ ট্যাগ যোগ করা হচ্ছে'); 			wikipedia_page.setFollowRedirect(true);  // should never be needed, but if the page is moved, we would want to follow the redirect 			wikipedia_page.setCallbackParameters(apiobj.params); 			wikipedia_page.load(Twinkle.xfd.callbacks.mfd.taggingPage);  			// Updating data for the action completed event 			Morebits.wiki.actionCompleted.redirect = apiobj.params.discussionpage; 			Morebits.wiki.actionCompleted.notice = 'মনোনয়ন সম্পন্ন, আলোচনা পাতায় পুনর্নির্দেশ করা হচ্ছে';  			// Discussion page 			wikipedia_page = new Morebits.wiki.page(apiobj.params.discussionpage, 'অপসারণ আলোচনার পাতা তৈরি করা হচ্ছে'); 			wikipedia_page.setCallbackParameters(apiobj.params); 			wikipedia_page.load(Twinkle.xfd.callbacks.mfd.discussionPage);  			// Today's list 			wikipedia_page = new Morebits.wiki.page('উইকিপিডিয়া:বিবিধ অপসারণের প্রস্তাবনা', "এই মাসের তালিকায় আলোচনা যোগ করা হচ্ছে"); 			wikipedia_page.setPageSection(2); 			wikipedia_page.setFollowRedirect(true); 			wikipedia_page.setCallbackParameters(apiobj.params); 			wikipedia_page.load(Twinkle.xfd.callbacks.mfd.todaysList);  			// Notification to first contributor and/or notification to owner of userspace 			if (apiobj.params.notifycreator || apiobj.params.notifyuserspace) { 				var thispage = new Morebits.wiki.page(mw.config.get('wgPageName')); 				thispage.setCallbackParameters(apiobj.params); 				thispage.lookupCreation(Twinkle.xfd.callbacks.mfd.sendNotifications); 			// or, if not notifying, add this nomination to the user's userspace log without the initial contributor's name 			} else { 				Twinkle.xfd.callbacks.addToLog(apiobj.params, null); 			} 		}, 		taggingPage: function(pageobj) { 			var text = pageobj.getPageText(); 			var params = pageobj.getCallbackParameters();  			params.tagText = '{{' + (params.number === '' ? 'mfd' : 'mfdx|' + params.number) + '|help=off}}';  			if (['javascript', 'css', 'sanitized-css'].indexOf(mw.config.get('wgPageContentModel')) !== -1) { 				params.tagText = '/* ' + params.tagText + ' */\n'; 			} else { 				params.tagText += '\n'; 				if (params.noinclude) { 					params.tagText = '<noinclude>' + params.tagText + '</noinclude>'; 				} 			}  			if (pageobj.canEdit() && ['wikitext', 'javascript', 'css', 'sanitized-css'].indexOf(pageobj.getContentModel()) !== -1) { 				pageobj.setPageText(params.tagText + text); 				pageobj.setEditSummary('Nominated for deletion; see [[:' + params.discussionpage + ']].'); 				pageobj.setChangeTags(Twinkle.changeTags); 				pageobj.setWatchlist(Twinkle.getPref('xfdWatchPage')); 				pageobj.setCreateOption('nocreate'); 				pageobj.save(); 			} else { 				Twinkle.xfd.callbacks.autoEditRequest(pageobj, params); 			} 		}, 		discussionPage: function(pageobj) { 			var params = pageobj.getCallbackParameters();  			pageobj.setPageText(Twinkle.xfd.callbacks.getDiscussionWikitext('mfd', params)); 			pageobj.setEditSummary('Creating deletion discussion page for [[:' + Morebits.pageNameNorm + ']].'); 			pageobj.setChangeTags(Twinkle.changeTags); 			pageobj.setWatchlist(Twinkle.getPref('xfdWatchDiscussion')); 			pageobj.setCreateOption('createonly'); 			pageobj.save(function() { 				Twinkle.xfd.currentRationale = null;  // any errors from now on do not need to print the rationale, as it is safely saved on-wiki 			}); 		}, 		todaysList: function(pageobj) { 			var text = pageobj.getPageText(); 			var params = pageobj.getCallbackParameters(); 			var statelem = pageobj.getStatusElement();  			var date = new Morebits.date(pageobj.getLoadTime()); 			var date_header = date.format('===MMMM D, YYYY===\n', 'utc'); 			var date_header_regex = new RegExp(date.format('(===[\\s]*MMMM[\\s]+D,[\\s]+YYYY[\\s]*===)', 'utc')); 			var added_data = '{{subst:mfd3|pg=' + Morebits.pageNameNorm + params.numbering + '}}';  			if (date_header_regex.test(text)) { // we have a section already 				statelem.info('Found today\'s section, proceeding to add new entry'); 				text = text.replace(date_header_regex, '$1\n' + added_data); 			} else { // we need to create a new section 				statelem.info('No section for today found, proceeding to create one'); 				text = text.replace('===', date_header + added_data + '\n\n==='); 			}  			pageobj.setPageText(text); 			pageobj.setEditSummary('[[:' + params.discussionpage + ']] যোগ করা হয়েছে।'); 			pageobj.setChangeTags(Twinkle.changeTags); 			pageobj.setWatchlist(Twinkle.getPref('xfdWatchList')); 			pageobj.setCreateOption('recreate'); 			pageobj.save(); 		}, 		sendNotifications: function(pageobj) { 			var initialContrib = pageobj.getCreator(); 			var params = pageobj.getCallbackParameters();  			// Notify the creator 			if (params.notifycreator) { 				Twinkle.xfd.callbacks.notifyUser(params, initialContrib); 			}  			// Notify the user who owns the subpage if they are not the creator 			params.userspaceOwner = mw.config.get('wgRelevantUserName'); 			if (params.notifyuserspace) { 				if (params.userspaceOwner !== initialContrib) { 					// Don't log if notifying creator above, will log then 					Twinkle.xfd.callbacks.notifyUser(params, params.userspaceOwner, params.notifycreator, 'Notifying owner of userspace (' + params.userspaceOwner + ')'); 				} else if (!params.notifycreator) { 					// If we thought we would notify the owner but didn't, 					// then we need to log if we didn't notify the creator 					// Twinkle.xfd.callbacks.addToLog(params, null); 					Twinkle.xfd.callbacks.addToLog(params, initialContrib); 				} 			} 		} 	},  	ffd: { 		taggingImage: function(pageobj) { 			var text = pageobj.getPageText(); 			var params = pageobj.getCallbackParameters();  			var date = new Morebits.date(pageobj.getLoadTime()).format('YYYY MMMM D', 'utc'); 			params.logpage = 'Wikipedia:Files for discussion/' + date; 			params.discussionpage = params.logpage + '#' + Morebits.pageNameNorm;  			params.tagText = '{{ffd|log=' + date + '|help=off}}\n'; 			if (pageobj.canEdit()) { 				text = text.replace(/\{\{(mtc|(copy |move )?to ?commons|move to wikimedia commons|copy to wikimedia commons)[^}]*\}\}/gi, '');  				pageobj.setPageText(params.tagText + text); 				pageobj.setEditSummary('Listed for discussion at [[:' + params.discussionpage + ']].'); 				pageobj.setChangeTags(Twinkle.changeTags); 				pageobj.setWatchlist(Twinkle.getPref('xfdWatchPage')); 				pageobj.setCreateOption('recreate');  // it might be possible for a file to exist without a description page 				pageobj.save(); 			} else { 				Twinkle.xfd.callbacks.autoEditRequest(pageobj, params); 			}  			// Updating data for the action completed event 			Morebits.wiki.actionCompleted.redirect = params.logpage; 			Morebits.wiki.actionCompleted.notice = 'Nomination completed, now redirecting to the discussion page';  			// Contributor specific edits 			var wikipedia_page = new Morebits.wiki.page(mw.config.get('wgPageName')); 			wikipedia_page.setCallbackParameters(params); 			wikipedia_page.lookupCreation(Twinkle.xfd.callbacks.ffd.main); 		}, 		main: function(pageobj) { 			// this is coming in from lookupCreation...! 			var params = pageobj.getCallbackParameters(); 			var initialContrib = pageobj.getCreator(); 			params.uploader = initialContrib;  			// Adding discussion 			var wikipedia_page = new Morebits.wiki.page(params.logpage, "Adding discussion to today's list"); 			wikipedia_page.setFollowRedirect(true); 			wikipedia_page.setCallbackParameters(params); 			wikipedia_page.load(Twinkle.xfd.callbacks.ffd.todaysList);  			// Notification to first contributor 			if (params.notifycreator) { 				Twinkle.xfd.callbacks.notifyUser(params, initialContrib); 			// or, if not notifying, add this nomination to the user's userspace log without the initial contributor's name 			} else { 				Twinkle.xfd.callbacks.addToLog(params, null); 			} 		}, 		todaysList: function(pageobj) { 			var text = pageobj.getPageText(); 			var params = pageobj.getCallbackParameters();  			// add date header if the log is found to be empty (a bot should do this automatically) 			if (!pageobj.exists()) { 				text = '{{subst:FfD log}}'; 			}  			pageobj.setPageText(text + '\n\n' + Twinkle.xfd.callbacks.getDiscussionWikitext('ffd', params)); 			pageobj.setEditSummary('[[:' + Morebits.pageNameNorm + ']] যোগ করা হয়েছে।'); 			pageobj.setChangeTags(Twinkle.changeTags); 			pageobj.setWatchlist(Twinkle.getPref('xfdWatchDiscussion')); 			pageobj.setCreateOption('recreate'); 			pageobj.save(function() { 				Twinkle.xfd.currentRationale = null;  // any errors from now on do not need to print the rationale, as it is safely saved on-wiki 			}); 		} 	},  	cfd: { 		main: function(pageobj) { 			var params = pageobj.getCallbackParameters();  			var date = new Morebits.date(pageobj.getLoadTime()); 			params.logpage = 'Wikipedia:Categories for discussion/Log/' + date.format('YYYY MMMM D', 'utc'); 			params.discussionpage = params.logpage + '#' + Morebits.pageNameNorm; 			// Add log/discussion page params to the already-loaded page object 			pageobj.setCallbackParameters(params);  			// Tagging category 			Twinkle.xfd.callbacks.cfd.taggingCategory(pageobj);  			// Updating data for the action completed event 			Morebits.wiki.actionCompleted.redirect = params.logpage; 			Morebits.wiki.actionCompleted.notice = "Nomination completed, now redirecting to today's log";  			// Adding discussion to list 			var wikipedia_page = new Morebits.wiki.page(params.logpage, "Adding discussion to today's list"); 			wikipedia_page.setFollowRedirect(true); 			wikipedia_page.setCallbackParameters(params); 			wikipedia_page.load(Twinkle.xfd.callbacks.cfd.todaysList);  			// Notification to first contributor 			if (params.notifycreator) { 				wikipedia_page = new Morebits.wiki.page(mw.config.get('wgPageName')); 				wikipedia_page.setCallbackParameters(params); 				wikipedia_page.lookupCreation(function(pageobj) { 					Twinkle.xfd.callbacks.notifyUser(pageobj.getCallbackParameters(), pageobj.getCreator()); 				}); 			// or, if not notifying, add this nomination to the user's userspace log without the initial contributor's name 			} else { 				Twinkle.xfd.callbacks.addToLog(params, null); 			} 		}, 		taggingCategory: function(pageobj) { 			var text = pageobj.getPageText(); 			var params = pageobj.getCallbackParameters();  			params.tagText = '{{subst:' + params.xfdcat; 			var editsummary = (mw.config.get('wgNamespaceNumber') === 14 ? 'বিষয়শ্রেণী' : 'অসম্পূর্ণ টেমপ্লেট') + 				params.action + '-এর জন্য বিবেচিত হচ্ছে'; 			switch (params.xfdcat) { 				case 'cfd': 				case 'sfd-t': 					break; 				case 'cfc': 					editsummary += ' একটি নিবন্ধে'; 					// falls through 				case 'cfm': 				case 'cfr': 				case 'sfr-t': 					params.tagText += '|' + params.cfdtarget; 					break; 				case 'cfs': 					params.tagText += '|' + params.cfdtarget + '|' + params.cfdtarget2; 					break; 				default: 					alert('twinklexfd in taggingCategory(): unknown CFD action'); 					break; 			} 			params.tagText += '}}\n'; 			editsummary += '; [[:' + params.discussionpage + ']] দেখুন।';  			if (pageobj.canEdit()) { 				pageobj.setPageText(params.tagText + text); 				pageobj.setEditSummary(editsummary); 				pageobj.setChangeTags(Twinkle.changeTags); 				pageobj.setWatchlist(Twinkle.getPref('xfdWatchPage')); 				pageobj.setCreateOption('recreate');  // since categories can be populated without an actual page at that title 				pageobj.save(); 			} else { 				Twinkle.xfd.callbacks.autoEditRequest(pageobj, params); 			} 		}, 		todaysList: function(pageobj) { 			var params = pageobj.getCallbackParameters(); 			var statelem = pageobj.getStatusElement();  			var added_data = Twinkle.xfd.callbacks.getDiscussionWikitext(params.xfdcat, params); 			var text;  			// add date header if the log is found to be empty (a bot should do this automatically) 			if (!pageobj.exists()) { 				text = '{{subst:CfD log}}\n' + added_data; 			} else { 				var old_text = pageobj.getPageText();  				text = old_text.replace('এই লাইনের নিচে -->', 'এই লাইনের নিচে -->\n' + added_data); 				if (text === old_text) { 					statelem.error('আলোচনার জন্য নির্ধারিত জায়গা খুঁজে পেতে ব্যর্থ'); 					return; 				} 			}  			pageobj.setPageText(text); 			pageobj.setEditSummary('[[:' + Morebits.pageNameNorm + ']]-এর ' + params.action + ' মনোনয়ন যোগ করা হচ্ছে।'); 			pageobj.setChangeTags(Twinkle.changeTags); 			pageobj.setWatchlist(Twinkle.getPref('xfdWatchDiscussion')); 			pageobj.setCreateOption('recreate'); 			pageobj.save(function() { 				Twinkle.xfd.currentRationale = null;  // any errors from now on do not need to print the rationale, as it is safely saved on-wiki 			}); 		} 	},  	cfds: { 		taggingCategory: function(pageobj) { 			var text = pageobj.getPageText(); 			var params = pageobj.getCallbackParameters();  			params.tagText = '{{subst:cfr-speedy|1=' + params.cfdstarget.replace(/^:?Category:/, '') + '}}\n'; 			if (pageobj.canEdit()) { 				pageobj.setPageText(params.tagText + text); 				pageobj.setEditSummary('Listed for speedy renaming; see [[WP:CFDS|Categories for discussion/Speedy]].'); 				pageobj.setChangeTags(Twinkle.changeTags); 				pageobj.setWatchlist(Twinkle.getPref('xfdWatchPage')); 				pageobj.setCreateOption('recreate');  // since categories can be populated without an actual page at that title 				pageobj.save(function() { 					// No user notification for CfDS, so just add this nomination to the user's userspace log 					Twinkle.xfd.callbacks.addToLog(params, null); 				}); 			} else { 				Twinkle.xfd.callbacks.autoEditRequest(pageobj, params); 				// No user notification for CfDS, so just add this nomination to the user's userspace log 				Twinkle.xfd.callbacks.addToLog(params, null); 			} 		}, 		addToList: function(pageobj) { 			var old_text = pageobj.getPageText(); 			var params = pageobj.getCallbackParameters(); 			var statelem = pageobj.getStatusElement();  			var text = old_text.replace('এই লাইনের নিচে -->', 'এই লাইনের নিচে -->\n' + Twinkle.xfd.callbacks.getDiscussionWikitext('cfds', params)); 			if (text === old_text) { 				statelem.error('failed to find target spot for the discussion'); 				return; 			}  			pageobj.setPageText(text); 			pageobj.setEditSummary('[[:' + Morebits.pageNameNorm + ']] যোগ করা হয়েছে।'); 			pageobj.setChangeTags(Twinkle.changeTags); 			pageobj.setWatchlist(Twinkle.getPref('xfdWatchDiscussion')); 			pageobj.setCreateOption('recreate'); 			pageobj.save(function() { 				Twinkle.xfd.currentRationale = null;  // any errors from now on do not need to print the rationale, as it is safely saved on-wiki 			}); 		} 	},  	rfd: { 		// This gets called both on submit and preview to determine the redirect target 		findTarget: function(params, callback) { 			// Used by regular redirects to find the target, but for all redirects, 			// avoid relying on the client clock to build the log page 			var query = { 				action: 'query', 				curtimestamp: true, 				format: 'json' 			}; 			if (document.getElementById('softredirect')) { 				// For soft redirects, define the target early 				// to skip target checks in findTargetCallback 				params.rfdtarget = document.getElementById('softredirect').textContent.replace(/^:+/, ''); 			} else { 				// Find current target of redirect 				query.titles = mw.config.get('wgPageName'); 				query.redirects = true; 			} 			var wikipedia_api = new Morebits.wiki.api('Finding target of redirect', query, Twinkle.xfd.callbacks.rfd.findTargetCallback(callback)); 			wikipedia_api.params = params; 			wikipedia_api.post(); 		}, 		// This is a closure for the callback from the above API request, which gets the target of the redirect 		findTargetCallback: function(callback) { 			return function(apiobj) { 				var response = apiobj.getResponse(); 				apiobj.params.curtimestamp = response.curtimestamp;  				if (!apiobj.params.rfdtarget) { // Not a softredirect 					var target = response.query.redirects && response.query.redirects[0].to; 					if (!target) { 						var message = 'No target found. this page does not appear to be a redirect, aborting'; 						if (mw.config.get('wgAction') === 'history') { 							message += '. If this is a soft redirect, try again from the content page, not the page history.'; 						} 						apiobj.statelem.error(message); 						return; 					} 					apiobj.params.rfdtarget = target; 					var section = response.query.redirects[0].tofragment; 					apiobj.params.section = section; 				} 				callback(apiobj.params); 			}; 		}, 		main: function(params) { 			var date = new Morebits.date(params.curtimestamp); 			params.logpage = 'Wikipedia:Redirects for discussion/Log/' + date.format('YYYY MMMM D', 'utc'); 			params.discussionpage = params.logpage + '#' + Morebits.pageNameNorm;  			// Tagging redirect 			var wikipedia_page = new Morebits.wiki.page(mw.config.get('wgPageName'), 'Adding deletion tag to redirect'); 			wikipedia_page.setFollowRedirect(false); 			wikipedia_page.setCallbackParameters(params); 			wikipedia_page.load(Twinkle.xfd.callbacks.rfd.taggingRedirect);  			// Updating data for the action completed event 			Morebits.wiki.actionCompleted.redirect = params.logpage; 			Morebits.wiki.actionCompleted.notice = "Nomination completed, now redirecting to today's log";  			// Adding discussion 			wikipedia_page = new Morebits.wiki.page(params.logpage, "Adding discussion to today's log"); 			wikipedia_page.setFollowRedirect(true); 			wikipedia_page.setCallbackParameters(params); 			wikipedia_page.load(Twinkle.xfd.callbacks.rfd.todaysList);  			// Notifications 			if (params.notifycreator || params.relatedpage) { 				var thispage = new Morebits.wiki.page(mw.config.get('wgPageName')); 				thispage.setCallbackParameters(params); 				thispage.lookupCreation(Twinkle.xfd.callbacks.rfd.sendNotifications); 			// or, if not notifying, add this nomination to the user's userspace log without the initial contributor's name 			} else { 				Twinkle.xfd.callbacks.addToLog(params, null); 			} 		}, 		taggingRedirect: function(pageobj) { 			var text = pageobj.getPageText(); 			var params = pageobj.getCallbackParameters(); 			// Imperfect for edit request but so be it 			params.tagText = '{{subst:rfd|' + (mw.config.get('wgNamespaceNumber') === 10 ? 'showontransclusion=1|' : '') + 'content=\n';  			if (pageobj.canEdit()) { 				pageobj.setPageText(params.tagText + text + '\n}}'); 				pageobj.setEditSummary('Listed for discussion at [[:' + params.discussionpage + ']].'); 				pageobj.setChangeTags(Twinkle.changeTags); 				pageobj.setWatchlist(Twinkle.getPref('xfdWatchPage')); 				pageobj.setCreateOption('nocreate'); 				pageobj.save(); 			} else { 				Twinkle.xfd.callbacks.autoEditRequest(pageobj, params); 			} 		}, 		todaysList: function(pageobj) { 			var params = pageobj.getCallbackParameters(); 			var statelem = pageobj.getStatusElement();  			var added_data = Twinkle.xfd.callbacks.getDiscussionWikitext('rfd', params); 			var text;  			// add date header if the log is found to be empty (a bot should do this automatically) 			if (!pageobj.exists()) { 				text = '{{subst:RfD log}}' + added_data; 			} else { 				var old_text = pageobj.getPageText(); 				text = old_text.replace(/(<!-- Add new entries directly below this line\.? -->)/, '$1\n' + added_data); 				if (text === old_text) { 					statelem.error('failed to find target spot for the discussion'); 					return; 				} 			}  			pageobj.setPageText(text); 			pageobj.setEditSummary('[[:' + Morebits.pageNameNorm + ']] যোগ করা হয়েছে।'); 			pageobj.setChangeTags(Twinkle.changeTags); 			pageobj.setWatchlist(Twinkle.getPref('xfdWatchDiscussion')); 			pageobj.setCreateOption('recreate'); 			pageobj.save(function() { 				Twinkle.xfd.currentRationale = null;  // any errors from now on do not need to print the rationale, as it is safely saved on-wiki 			}); 		}, 		sendNotifications: function(pageobj) { 			var initialContrib = pageobj.getCreator(); 			var params = pageobj.getCallbackParameters(); 			var statelem = pageobj.getStatusElement();  			// Notifying initial contributor 			if (params.notifycreator) { 				Twinkle.xfd.callbacks.notifyUser(params, initialContrib); 			}  			// Notifying target page's watchers, if not a soft redirect 			if (params.relatedpage) { 				var targetTalk = new mw.Title(params.rfdtarget).getTalkPage();  				// On the offchance it's a circular redirect 				if (params.rfdtarget === mw.config.get('wgPageName')) { 					statelem.warn('Circular redirect; skipping target page notification'); 				} else if (document.getElementById('softredirect')) { 					statelem.warn('Soft redirect; skipping target page notification'); 				// Don't issue if target talk is the initial contributor's talk or your own 				} else if (targetTalk.getNamespaceId() === 3 && targetTalk.getNameText() === initialContrib) { 					statelem.warn('Target is initial contributor; skipping target page notification'); 				} else if (targetTalk.getNamespaceId() === 3 && targetTalk.getNameText() === mw.config.get('wgUserName')) { 					statelem.warn('You (' + mw.config.get('wgUserName') + ') are the target; skipping target page notification'); 				} else { 					// Don't log if notifying creator above, will log then 					Twinkle.xfd.callbacks.notifyUser(params, targetTalk.toText(), params.notifycreator, 'Notifying redirect target of the discussion'); 					return; 				} 				// If we thought we would notify the target but didn't, 				// we need to log if we didn't notify the creator 				if (!params.notifycreator) { 					Twinkle.xfd.callbacks.addToLog(params, null); 				} 			} 		} 	},  	rm: { 		listAtTalk: function(pageobj) { 			var params = pageobj.getCallbackParameters();  			pageobj.setAppendText('\n\n' + Twinkle.xfd.callbacks.getDiscussionWikitext('rm', params)); 			pageobj.setEditSummary('Proposing move' + (params.newname ? ' to [[:' + params.newname + ']]' : '')); 			pageobj.setChangeTags(Twinkle.changeTags); 			pageobj.setCreateOption('recreate'); // since the talk page need not exist 			pageobj.setWatchlist(Twinkle.getPref('xfdWatchDiscussion')); 			pageobj.append(function() { 				Twinkle.xfd.currentRationale = null;  // any errors from now on do not need to print the rationale, as it is safely saved on-wiki 				// add this nomination to the user's userspace log 				Twinkle.xfd.callbacks.addToLog(params, null); 			}); 		},  		listAtRMTR: function(pageobj) { 			var text = pageobj.getPageText(); 			var params = pageobj.getCallbackParameters(); 			var statelem = pageobj.getStatusElement();  			var hiddenCommentRE = /---- and enter on a new line.* -->/; 			var newtext = text.replace(hiddenCommentRE, '$&\n' + Twinkle.xfd.callbacks.getDiscussionWikitext('rm', params)); 			if (text === newtext) { 				statelem.error('failed to find target spot for the entry'); 				return; 			} 			pageobj.setPageText(newtext); 			pageobj.setEditSummary('[[:' + Morebits.pageNameNorm + ']] যোগ করা হয়েছে।'); 			pageobj.setChangeTags(Twinkle.changeTags); 			pageobj.save(function() { 				Twinkle.xfd.currentRationale = null;  // any errors from now on do not need to print the rationale, as it is safely saved on-wiki 				// add this nomination to the user's userspace log 				Twinkle.xfd.callbacks.addToLog(params, null); 			}); 		} 	} };  Twinkle.xfd.callback.evaluate = function(e) { 	var form = e.target;  	var params = Morebits.quickForm.getInputData(form);  	Morebits.simpleWindow.setButtonsEnabled(false); 	Morebits.status.init(form);  	Twinkle.xfd.currentRationale = params.reason; 	Morebits.status.onError(Twinkle.xfd.printRationale);  	var query, wikipedia_page, wikipedia_api; 	switch (params.venue) {  		case 'afd': // AFD 			query = { 				action: 'query', 				list: 'allpages', 				apprefix: 'নিবন্ধ অপসারণের প্রস্তাবনা/' + Morebits.pageNameNorm, 				apnamespace: 4, 				apfilterredir: 'nonredirects', 				aplimit: 'max', // 500 is max for normal users, 5000 for bots and sysops 				format: 'json' 			}; 			wikipedia_api = new Morebits.wiki.api('নিবন্ধটিতে অপসারণ ট্যাগ যুক্ত করা হচ্ছে', query, Twinkle.xfd.callbacks.afd.main); 			wikipedia_api.params = params; 			wikipedia_api.post(); 			break;  		case 'tfd': // TFD 			if (params.tfdtarget) { // remove namespace name 				params.tfdtarget = utils.stripNs(params.tfdtarget); 			}  			// Modules can't be tagged, TfD instructions are to place on /doc subpage 			params.scribunto = mw.config.get('wgPageContentModel') === 'Scribunto'; 			if (params.xfdcat === 'tfm') { // Merge 				// Tag this template/module 				if (params.scribunto) { 					wikipedia_page = new Morebits.wiki.page(mw.config.get('wgPageName') + '/নথি', 'একত্রীতকরণের ট্যাগ দিয়ে এই মডিউলের নথি ট্যাগ করা হচ্ছে'); 					params.otherTemplateName = 'Module:' + params.tfdtarget; 				} else { 					wikipedia_page = new Morebits.wiki.page(mw.config.get('wgPageName'), 'একত্রীতকরণের ট্যাগ দিয়ে এই টেমপ্লেট ট্যাগ করা হচ্ছে'); 					params.otherTemplateName = 'Template:' + params.tfdtarget; 				} 			} else { // delete 				if (params.scribunto) { 					wikipedia_page = new Morebits.wiki.page(mw.config.get('wgPageName') + '/নথি', 'অপসারণের ট্যাগ দিয়ে এই মডিউলের নথি ট্যাগ করা হচ্ছে'); 				} else { 					wikipedia_page = new Morebits.wiki.page(mw.config.get('wgPageName'), 'অপসারণের ট্যাগ দিয়ে এই টেমপ্লেট ট্যাগ করা হচ্ছে'); 				} 			} 			wikipedia_page.setFollowRedirect(true);  // should never be needed, but if the page is moved, we would want to follow the redirect 			wikipedia_page.setCallbackParameters(params); 			wikipedia_page.load(Twinkle.xfd.callbacks.tfd.main); 			break;  		case 'mfd': // MFD 			query = { 				action: 'query', 				list: 'allpages', 				apprefix: 'বিবিধ অপসারণের প্রস্তাবনা/' + Morebits.pageNameNorm, 				apnamespace: 4, 				apfilterredir: 'nonredirects', 				aplimit: 'max', // 500 is max for normal users, 5000 for bots and sysops 				format: 'json' 			}; 			wikipedia_api = new Morebits.wiki.api('এই পৃষ্ঠার পূর্বের মনোনয়ন খোঁজা হচ্ছে', query, Twinkle.xfd.callbacks.mfd.main); 			wikipedia_api.params = params; 			wikipedia_api.post(); 			break;  		case 'ffd': // FFD 			// Tagging file 			// A little out of order with this coming before 'main', 			// but tagging doesn't need the uploader parameter, 			// while everything else does, so tag then get the uploader 			wikipedia_page = new Morebits.wiki.page(mw.config.get('wgPageName'), 'ফাইলের পাতায় অপসারণ ট্যাগ যোগ করা হচ্ছে'); 			wikipedia_page.setFollowRedirect(true); 			wikipedia_page.setCallbackParameters(params); 			wikipedia_page.load(Twinkle.xfd.callbacks.ffd.taggingImage); 			break;  		case 'cfd': 			if (params.cfdtarget) { 				params.cfdtarget = utils.stripNs(params.cfdtarget); 			} else { 				params.cfdtarget = ''; // delete 			} 			if (params.cfdtarget2) { // split 				params.cfdtarget2 = utils.stripNs(params.cfdtarget2); 			}  			// Used for customized actions in edit summaries and the notification template 			var summaryActions = { 				'cfd': 'deletion', 				'sfd-t': 'deletion', 				'cfm': 'merging', 				'cfr': 'renaming', 				'sfr-t': 'renaming', 				'cfs': 'splitting', 				'cfc': 'conversion' 			}; 			params.action = summaryActions[params.xfdcat];  			// Tagging category 			wikipedia_page = new Morebits.wiki.page(mw.config.get('wgPageName'), 'Tagging category with ' + params.action + ' tag'); 			wikipedia_page.setFollowRedirect(true); // should never be needed, but if the page is moved, we would want to follow the redirect 			wikipedia_page.setCallbackParameters(params); 			wikipedia_page.load(Twinkle.xfd.callbacks.cfd.main); 			break;  		case 'cfds': 			// add namespace name if missing 			params.cfdstarget = utils.addNs(params.cfdstarget, 14);  			var logpage = 'Wikipedia:Categories for discussion/Speedy';  			// Updating data for the action completed event 			Morebits.wiki.actionCompleted.redirect = logpage; 			Morebits.wiki.actionCompleted.notice = 'Nomination completed, now redirecting to the discussion page';  			// Tagging category 			wikipedia_page = new Morebits.wiki.page(mw.config.get('wgPageName'), 'Tagging category with rename tag'); 			wikipedia_page.setFollowRedirect(true); 			wikipedia_page.setCallbackParameters(params); 			wikipedia_page.load(Twinkle.xfd.callbacks.cfds.taggingCategory);  			// Adding discussion to list 			wikipedia_page = new Morebits.wiki.page(logpage, 'Adding discussion to the list'); 			wikipedia_page.setFollowRedirect(true); 			wikipedia_page.setCallbackParameters(params); 			wikipedia_page.load(Twinkle.xfd.callbacks.cfds.addToList);  			break;  		case 'rfd': 			// find target and pass main as the callback 			Twinkle.xfd.callbacks.rfd.findTarget(params, Twinkle.xfd.callbacks.rfd.main); 			break;  		case 'rm': 			var nomPageName = params.rmtr ? 				'Wikipedia:Requested moves/Technical requests' : 				new mw.Title(Morebits.pageNameNorm).getTalkPage().toText();  			Morebits.wiki.actionCompleted.redirect = nomPageName; 			Morebits.wiki.actionCompleted.notice = 'Nomination completed, now redirecting to the discussion page';  			wikipedia_page = new Morebits.wiki.page(nomPageName, params.rmtr ? 'Adding entry at WP:RM/TR' : 'Adding entry on talk page'); 			wikipedia_page.setFollowRedirect(true); 			wikipedia_page.setCallbackParameters(params);  			if (params.rmtr) { 				wikipedia_page.setPageSection(2); 				wikipedia_page.load(Twinkle.xfd.callbacks.rm.listAtRMTR); 			} else { 				// listAtTalk uses .append(), so no need to load the page 				Twinkle.xfd.callbacks.rm.listAtTalk(wikipedia_page); 			} 			break;  		default: 			alert('twinklexfd: unknown XFD discussion venue'); 			break; 	} };  Twinkle.addInitCallback(Twinkle.xfd, 'xfd'); })(jQuery);  //