MediaWiki:Gadget-twinklespeedy.js

Vikipediya, ochiq ensiklopediya

Eʼtibor bering: Oʻzgartirishlaringizni koʻrish uchun, yangi moslamalaringizning saqlashdan keyin, brauzer keshini tozalash kerak:
Mozilla / Firefox: Ctrl+Shift+R, IE: Ctrl+F5, Safari: Cmd+Shift+R, Konqueror: F5, Opera: Tools → Preferences orqali keshni tozalang.

// <nowiki>


(function($) {


/*
 ****************************************
 *** twinklespeedy.js: TOʻM moduli
 ****************************************
 * Mode of invocation:     Tab ("TOʻM")
 * Active on:              Non-special, existing pages
 *
 * NOTE FOR DEVELOPERS:
 *   If adding a new criterion, add it to the appropriate places at the top of
 *   twinkleconfig.js.  Also check out the default values of the CSD preferences
 *   in twinkle.js, and add your new criterion to those if you think it would be
 *   good.
 */

Twinkle.speedy = function twinklespeedy() {
	// Disable on:
	// * special pages
	// * non-existent pages
	if (mw.config.get('wgNamespaceNumber') < 0 || !mw.config.get('wgArticleId')) {
		return;
	}

	Twinkle.addPortletLink(Twinkle.speedy.callback, 'TOʻM', 'tw-csd', Morebits.userIsSysop ? 'VP:TOʻMga binoan sahifani oʻchirish' : 'VP:TOʻMga binoan sahifani tezda oʻchirishga nomzod oʻlaroq koʻrsatish');
};

// This function is run when the CSD tab/header link is clicked
Twinkle.speedy.callback = function twinklespeedyCallback() {
	Twinkle.speedy.initDialog(Morebits.userIsSysop ? Twinkle.speedy.callback.evaluateSysop : Twinkle.speedy.callback.evaluateUser, true);
};

// Used by unlink feature
Twinkle.speedy.dialog = null;
// Used throughout
Twinkle.speedy.hasCSD = !!$('#delete-reason').length;

// Prepares the speedy deletion dialog and displays it
Twinkle.speedy.initDialog = function twinklespeedyInitDialog(callbackfunc) {
	var dialog;
	Twinkle.speedy.dialog = new Morebits.simpleWindow(Twinkle.getPref('speedyWindowWidth'), Twinkle.getPref('speedyWindowHeight'));
	dialog = Twinkle.speedy.dialog;
	dialog.setTitle('Quyidagi mezonlardan birini/bir nechtasini tanlang');
	dialog.setScriptName('Twinkle');
	dialog.addFooterLink('Tezda oʻchirish mezonlari', 'VP:TOʻM');
	dialog.addFooterLink('Moslamalar', 'Vikipediya:Twinkle/Moslamalar#speedy');
	dialog.addFooterLink('Yordam', 'VP:TW/HUJJAT#speedy');
	dialog.addFooterLink('Fikr-mulohaza berish', 'Vikipediya munozarasi:Twinkle');

	var form = new Morebits.quickForm(callbackfunc, Twinkle.getPref('speedySelectionStyle') === 'radioClick' ? 'change' : null);
	if (Morebits.userIsSysop) {
		form.append({
			type: 'checkbox',
			list: [
				{
					label: 'Sahifaga faqat {{tezda oʻchirishga}} andozasi qoʻshilsin (sahifa oʻchirilmasin)',
					value: 'tag_only',
					name: 'tag_only',
					tooltip: 'Bunda sahifa oʻchirilmaydi, balki faqatgina {{tezda oʻchirishga}} andozasi qoʻshiladi',
					checked: !(Twinkle.speedy.hasCSD || Twinkle.getPref('deleteSysopDefaultToDelete')),
					event: function(event) {
						var cForm = event.target.form;
						var cChecked = event.target.checked;
						// enable talk page checkbox
						if (cForm.talkpage) {
							cForm.talkpage.checked = !cChecked && Twinkle.getPref('deleteTalkPageOnDelete');
						}
						// enable redirects checkbox
						cForm.redirects.checked = !cChecked;
						// enable delete multiple
						cForm.delmultiple.checked = false;
						// enable notify checkbox
						cForm.notify.checked = cChecked;
						// enable deletion notification checkbox
						cForm.warnusertalk.checked = !cChecked && !Twinkle.speedy.hasCSD;
						// enable multiple
						cForm.multiple.checked = false;
						// enable requesting creation protection
						cForm.salting.checked = false;

						Twinkle.speedy.callback.modeChanged(cForm);

						event.stopPropagation();
					}
				}
			]
		});

		var deleteOptions = form.append({
			type: 'div',
			name: 'delete_options'
		});
		deleteOptions.append({
			type: 'header',
			label: 'Oʻchirish boʻyicha opsiyalar'
		});
		if (mw.config.get('wgNamespaceNumber') % 2 === 0 && (mw.config.get('wgNamespaceNumber') !== 2 || (/\//).test(mw.config.get('wgTitle')))) {  // hide option for user pages, to avoid accidentally deleting user talk page
			deleteOptions.append({
				type: 'checkbox',
				list: [
					{
						label: 'Sahifaning munozara sahifasi ham oʻchirilsin',
						value: 'talkpage',
						name: 'talkpage',
						tooltip: "Bunda sahifaning munozara sahifasi ham oʻchiriladi.",
						checked: Twinkle.getPref('deleteTalkPageOnDelete'),
						event: function(event) {
							event.stopPropagation();
						}
					}
				]
			});
		}
		deleteOptions.append({
			type: 'checkbox',
			list: [
				{
					label: 'Sahifaga qoldirilgan barcha yoʻnaltiruvchi sahifalar oʻchirilsin',
					value: 'redirects',
					name: 'redirects',
					tooltip: 'Bunda sahifaga qoldirilgan barcha yoʻnaltiruvchi sahifalar oʻchiriladi.',
					checked: Twinkle.getPref('deleteRedirectsOnDelete'),
					event: function (event) {
						event.stopPropagation();
					}
				},
				{
					label: 'Birdan ortiq mezonlarga binoan oʻchirilsin',
					value: 'delmultiple',
					name: 'delmultiple',
					tooltip: 'Bunda sahifa birgina mezonga binoan emas, balki birdan ortiq mezonlarga binoan oʻchiriladi (masalan, M2 va U7 mezonlariga binoan).',
					event: function(event) {
						Twinkle.speedy.callback.modeChanged(event.target.form);
						event.stopPropagation();
					}
				},
				{
					label: 'Sahifa oʻchirilgani haqida sahifa yaratuvchisi xabardor qilinsin',
					value: 'warnusertalk',
					name: 'warnusertalk',
					tooltip: 'Bunda sahifa oʻchirilgani haqida xabardor qiluvchi tegishli andoza sahifa yaratuvchisining foydalanuvchi munozara sahifasiga qoʻshiladi. ' +
						'Bundan tashqari, foydalanuvchi qarshilanishi ham mumkin (agar allaqachon qarshilanmagan boʻlsa).',
                    checked: !Twinkle.speedy.hasCSD,
					event: function(event) {
						event.stopPropagation();
					}
				}
			]
		});
	}

	var tagOptions = form.append({
		type: 'div',
		name: 'tag_options'
	});

	if (Morebits.userIsSysop) {
		tagOptions.append({
			type: 'header',
			label: 'Sahifaga {{tezda oʻchirishga}} andozasini qoʻshish boʻyicha opsiyalar'
		});
	}

	tagOptions.append({
		type: 'checkbox',
		list: [
			{
				label: 'Iloji boʻlsa, bu haqda sahifa yaratuvchisi xabardor qilinsin',
				value: 'notify',
				name: 'notify',
					tooltip: 'Bunda sahifaga {{tezda oʻchirishga}} andozasi qoʻshilgani haqida xabardor qiluvchi tegishli andoza sahifa yaratuvchisining foydalanuvchi munozara sahifasiga qoʻshiladi. ' +
						'Bundan tashqari, foydalanuvchi qarshilanishi ham mumkin (agar allaqachon qarshilanmagan boʻlsa).',
				checked: !Morebits.userIsSysop || !(Twinkle.speedy.hasCSD || Twinkle.getPref('deleteSysopDefaultToDelete')),
				event: function(event) {
					event.stopPropagation();
				}
			},
			{
				label: 'Yaratishga qarshi himoya andozasi ({{salt}}) ham qoʻshilsin',
				value: 'salting',
				name: 'salting',
				tooltip: 'Bunda sahifaga {{salt}} andozasi ham qoʻshiladi.',
				event: function(event) {
					event.stopPropagation();
				}
			},
			{
				label: 'Birdan ortiq mezonlarga binoan {{tezda oʻchirishga}} andozasini qoʻshilsin',
				value: 'multiple',
				name: 'multiple',
				tooltip: 'Bunda sahifani faqat birgina mezonga binoan emas, balki birdan ortiq mezonlarga binoan tezda oʻchirishga nomzod oʻlaroq koʻrsatishingiz mumkin boʻladi.',
				event: function(event) {
					Twinkle.speedy.callback.modeChanged(event.target.form);
					event.stopPropagation();
				}
			}
		]
	});

	form.append({
		type: 'div',
		id: 'prior-deletion-count',
		style: 'font-style: italic'
	});

	form.append({
		type: 'div',
		name: 'work_area',
		label: 'TOʻM modulida xatolik yuz berdi. Birozdan keyin qayta urinib koʻring yoki bu haqda \'Vikipediya munozarasi:Twinkle\' sahifasida xabar qoldiring.'
	});

	if (Twinkle.getPref('speedySelectionStyle') !== 'radioClick') {
		form.append({ type: 'submit', className: 'tw-speedy-submit' }); // Renamed in modeChanged
	}

	var result = form.render();
	dialog.setContent(result);
	dialog.display();

	Twinkle.speedy.callback.modeChanged(result);

	// Check for prior deletions.  Just once, upon init
	Twinkle.speedy.callback.priorDeletionCount();
};

Twinkle.speedy.callback.modeChanged = function twinklespeedyCallbackModeChanged(form) {
	var namespace = mw.config.get('wgNamespaceNumber');

	// first figure out what mode we're in
	var mode = {
		isSysop: !!form.tag_only && !form.tag_only.checked,
		isMultiple: form.tag_only && !form.tag_only.checked ? form.delmultiple.checked : form.multiple.checked,
		isRadioClick: Twinkle.getPref('speedySelectionStyle') === 'radioClick'
	};

	if (mode.isSysop) {
		$('[name=delete_options]').show();
		$('[name=tag_options]').hide();
		$('button.tw-speedy-submit').text('Sahifani oʻchirish');
	} else {
		$('[name=delete_options]').hide();
		$('[name=tag_options]').show();
		$('button.tw-speedy-submit').text('Sahifaga {{tezda oʻchirishga}} andozasini qoʻshish');
	}

	var work_area = new Morebits.quickForm.element({
		type: 'div',
		name: 'work_area'
	});

	if (mode.isMultiple && mode.isRadioClick) {
		var evaluateType = mode.isSysop ? 'evaluateSysop' : 'evaluateUser';

		work_area.append({
			type: 'div',
			label: 'Berilgan mezonlardan birini/bir nechtasini tanlab boʻlgach, quyidagi tugmani bosing:'
		});
		work_area.append({
			type: 'button',
			name: 'submit-multiple',
			label: mode.isSysop ? 'Sahifani oʻchirish' : 'Sahifaga {{tezda oʻchirishga}} andozasini qoʻshish',
			event: function(event) {
				Twinkle.speedy.callback[evaluateType](event);
				event.stopPropagation();
			}
		});
	}

	var appendList = function(headerLabel, csdList) {
		work_area.append({ type: 'header', label: headerLabel });
		work_area.append({ type: mode.isMultiple ? 'checkbox' : 'radio', name: 'csd', list: Twinkle.speedy.generateCsdList(csdList, mode) });
	};

	if (mode.isSysop && !mode.isMultiple) {
		appendList('Custom rationale', Twinkle.speedy.customRationale);
	}

	if (namespace % 2 === 1 && namespace !== 3) {
		// show db-talk on talk pages, but not user talk pages
		appendList('Munozara sahifalari', Twinkle.speedy.talkList);
	}

	if (!Morebits.isPageRedirect()) {
		switch (namespace) {
			case 0:  // article
			case 1:  // talk
				appendList('Maqolalar', Twinkle.speedy.articleList);
				break;

			case 2:  // user
			case 3:  // user talk
				appendList('Foydalanuvchi sahifalari', Twinkle.speedy.userList);
				break;

			case 6:  // file
			case 7:  // file talk
				appendList('Fayllar', Twinkle.speedy.fileList);
				if (!mode.isSysop) {
					work_area.append({ type: 'div', label: 'Tagging for CSD F4 (no license), F5 (orphaned fair use), F6 (no fair use rationale), and F11 (no permission) can be done using Twinkle\'s "DI" tab.' });
				}
				break;

			case 14:  // category
			case 15:  // category talk
				appendList('Turkumlar', Twinkle.speedy.categoryList);
				break;

			default:
				break;
		}
	} else {
		if (namespace === 2 || namespace === 3) {
			appendList('Foydalanuvchi sahifalari', Twinkle.speedy.userList);
		}
		appendList('Yoʻnaltiruvchi sahifalar', Twinkle.speedy.redirectList);
	}

	var generalCriteria = Twinkle.speedy.generalList;

	// custom rationale lives under general criteria when tagging
	if (!mode.isSysop) {
		generalCriteria = Twinkle.speedy.customRationale.concat(generalCriteria);
	}
	appendList('Umumiy mezonlar', generalCriteria);

	var old_area = Morebits.quickForm.getElements(form, 'work_area')[0];
	form.replaceChild(work_area.render(), old_area);

	// if sysop, check if CSD is already on the page and fill in custom rationale
	if (mode.isSysop && Twinkle.speedy.hasCSD) {
		var customOption = $('input[name=csd][value=reason]')[0];
		if (customOption) {
			if (Twinkle.getPref('speedySelectionStyle') !== 'radioClick') {
				// force listeners to re-init
				customOption.click();
				customOption.parentNode.appendChild(customOption.subgroup);
			}
			customOption.subgroup.querySelector('input').value = decodeURIComponent($('#delete-reason').text()).replace(/\+/g, ' ');
		}
	}
};

Twinkle.speedy.callback.priorDeletionCount = function () {
	var query = {
		action: 'query',
		format: 'json',
		list: 'logevents',
		letype: 'delete',
		leaction: 'delete/delete', // Just pure page deletion, no redirect overwrites or revdel
		letitle: mw.config.get('wgPageName'),
		leprop: '', // We're just counting we don't actually care about the entries
		lelimit: 5  // A little bit goes a long way
	};

	new Morebits.wiki.api('Checking for past deletions', query, function(apiobj) {
		var response = apiobj.getResponse();
		var delCount = response.query.logevents.length;
		if (delCount) {
			var message = delCount + ' previous deletion';
			if (delCount > 1) {
				message += 's';
				if (response.continue) {
					message = 'More than ' + message;
				}

				// 3+ seems problematic
				if (delCount >= 3) {
					$('#prior-deletion-count').css('color', 'red');
				}
			}

			// Provide a link to page logs (CSD templates have one for sysops)
			var link = Morebits.htmlNode('a', '(logs)');
			link.setAttribute('href', mw.util.getUrl('Special:Log', {page: mw.config.get('wgPageName')}));
			link.setAttribute('target', '_blank');

			$('#prior-deletion-count').text(message + ' '); // Space before log link
			$('#prior-deletion-count').append(link);
		}
	}).post();
};


Twinkle.speedy.generateCsdList = function twinklespeedyGenerateCsdList(list, mode) {

	var pageNamespace = mw.config.get('wgNamespaceNumber');

	var openSubgroupHandler = function(e) {
		$(e.target.form).find('input').prop('disabled', true);
		$(e.target.form).children().css('color', 'gray');
		$(e.target).parent().css('color', 'black').find('input').prop('disabled', false);
		$(e.target).parent().find('input:text')[0].focus();
		e.stopPropagation();
	};
	var submitSubgroupHandler = function(e) {
		var evaluateType = mode.isSysop ? 'evaluateSysop' : 'evaluateUser';
		Twinkle.speedy.callback[evaluateType](e);
		e.stopPropagation();
	};

	return $.map(list, function(critElement) {
		var criterion = $.extend({}, critElement);

		if (mode.isMultiple) {
			if (criterion.hideWhenMultiple) {
				return null;
			}
			if (criterion.hideSubgroupWhenMultiple) {
				criterion.subgroup = null;
			}
		} else {
			if (criterion.hideWhenSingle) {
				return null;
			}
			if (criterion.hideSubgroupWhenSingle) {
				criterion.subgroup = null;
			}
		}

		if (mode.isSysop) {
			if (criterion.hideWhenSysop) {
				return null;
			}
			if (criterion.hideSubgroupWhenSysop) {
				criterion.subgroup = null;
			}
		} else {
			if (criterion.hideWhenUser) {
				return null;
			}
			if (criterion.hideSubgroupWhenUser) {
				criterion.subgroup = null;
			}
		}

		if (Morebits.isPageRedirect() && criterion.hideWhenRedirect) {
			return null;
		}

		if (criterion.showInNamespaces && criterion.showInNamespaces.indexOf(pageNamespace) < 0) {
			return null;
		}
		if (criterion.hideInNamespaces && criterion.hideInNamespaces.indexOf(pageNamespace) > -1) {
			return null;
		}

		if (criterion.subgroup && !mode.isMultiple && mode.isRadioClick) {
			if (Array.isArray(criterion.subgroup)) {
				criterion.subgroup = criterion.subgroup.concat({
					type: 'button',
					name: 'submit',
					label: mode.isSysop ? 'Sahifani oʻchirish' : 'Sahifaga {{tezda oʻchirishga}} andozasini qoʻshish',
					event: submitSubgroupHandler
				});
			} else {
				criterion.subgroup = [
					criterion.subgroup,
					{
						type: 'button',
						name: 'submit',  // ends up being called "csd.submit" so this is OK
						label: mode.isSysop ? 'Sahifani oʻchirish' : 'Sahifaga {{tezda oʻchirishga}} andozasini qoʻshish',
						event: submitSubgroupHandler
					}
				];
			}
			// FIXME: does this do anything?
			criterion.event = openSubgroupHandler;
		}

		return criterion;
	});
};

Twinkle.speedy.customRationale = [
	{
		label: 'Berilgan mezonlar orasidan sahifaga mos keluvchisini topa olmadim' + (Morebits.userIsSysop ? '' : ''),
		value: 'reason',
		tooltip: 'Bunda sahifani nima sababdan tezda oʻchirishga nomzod oʻlaroq koʻrsatganingizni bayon etishingiz mumkin boʻladi.',
		subgroup: {
			name: 'reason_1',
			type: 'input',
			label: 'Sabab:',
			size: 60
		},
		hideWhenMultiple: true
	}
];

Twinkle.speedy.talkList = [
	{
		label: 'G8: Talk pages with no corresponding subject page',
		value: 'talk',
		tooltip: 'This excludes any page that is useful to the project - in particular, user talk pages, talk page archives, and talk pages for files that exist on Wikimedia Commons.'
	}
];

Twinkle.speedy.fileList = [
	{
		label: 'F1: Litsenziyasi nomaʼlum fayl',
		value: 'F1: Litsenziyasi nomaʼlum fayl',
		tooltip: ''
	},
	{
		label: 'F2: Birorta sahifada ishlatilmagan noerkin fayl',
		value: 'F2: Birorta sahifada ishlatilmagan noerkin fayl',
		tooltip: ''
	},
	{
		label: 'F3: Foydalanish asosi koʻrsatilmagan noerkin fayl',
		value: 'F3: Foydalanish asosi koʻrsatilmagan noerkin fayl',
		tooltip: '',
		hideWhenUser: true
	},
	{
		label: 'F4: Vikiomborda mavjud fayl',
		value: 'F4: Vikiomborda mavjud fayl',
		tooltip: ''
	}
];

Twinkle.speedy.articleList = [
	{
		label: 'M1: Ensiklopedik boʻlmagan qisqa maqola',
		value: '[[VP:M1|M1]]: Ensiklopedik boʻlmagan qisqa maqola',
		tooltip: 'Masalan: Anvarning qizil rangli mashinasi bor.'
	},
	{
		label: 'M2: Butkul oʻzbekcha boʻlmagan maqola',
		value: '[[VP:M2|M2]]: Butkul oʻzbekcha boʻlmagan maqola',
		tooltip: 'Butkul oʻzbekcha boʻlmagan maqolalar, agar ular yaqin orada tarjima qilinmasa.'
	},
	{
		label: 'M2: Tuzatib boʻlmas mashina tarjimasi',
		value: '[[VP:M2|M2]]: Tuzatib boʻlmas mashina tarjimasi',
		tooltip: 'Mazmunsiz mashina tarjimasidan iborat boʻlgan maqolalar.'
	},
	{
		label: 'M3: Faqatgina ishoratlardan iborat maqola',
		value: '[[VP:M3|M3]]: Faqatgina ishoratlardan iborat maqola',
		tooltip: 'Bu faqat turkumlardan iborat maqolalarni ham oʻz ichiga oladi.'
	},
	{
		label: 'M4: Boshqa Vikimedia loyihalaridan koʻchirib olib oʻtilgan maqola',
		value: '[[VP:M4|M4]]: Boshqa Vikimedia loyihalaridan koʻchirib olib oʻtilgan maqola',
		tooltip: 'Masalan, boshqa Vikimedia loyihalaridagi (Vikilugʻat, Vikimanba va hk.) sahifalar matnini koʻchirib qoʻyish.'
	},
	{
		label: 'M6: Keng ommaga mashhur boʻlmagan kishi, tashkilot, veb-sayt yoki hodisa haqidagi maqola',
		value: '[[VP:M6|M6]]: Keng ommaga mashhur boʻlmagan kishi, tashkilot, veb-sayt yoki hodisa haqidagi maqola',
		tooltip: 'Masalan: „Eshmat Toshmatov — universitet 1-kurs talabasi, 1990-yilda tugʻilgan“ va hk. Agarda maqola muallifi unda taʼriflangan obyektni mashhur, deb iddao etsa, munozara sahifasida bu iddaoni izohlashi shart.'
	},
	{
		label: 'M8: Avvaldan mavjud maqolaning nusxasi boʻlgan maqola',
		value: '[[VP:M8|M8]]: Avvaldan mavjud maqolaning nusxasi boʻlgan maqola',
		tooltip: ''
	}
];

Twinkle.speedy.categoryList = [
	{
		label: 'T1: Boʻsh turkum',
		value: 'T1: Boʻsh turkum',
		tooltip: ''
	},
	{
		label: 'T2: Nomi imlo xatosi bilan yozilgan turkum',
		value: 'T2: Nomi imlo xatosi bilan yozilgan turkum',
		tooltip: ''
	}
];

Twinkle.speedy.userList = [
	{
		label: 'FS1: Foydalanuvchi iltimosi bilan',
		value: 'FS1: Foydalanuvchi iltimosi bilan',
		tooltip: ''
//		subgroup: mw.config.get('wgNamespaceNumber') === 3 && mw.config.get('wgTitle').indexOf('/') === -1 ? {
//			name: 'userreq_rationale',
//			type: 'input',
//			label: 'A mandatory rationale to explain why this user talk page should be deleted:',
//			tooltip: 'User talk pages are deleted only in highly exceptional circumstances. See WP:DELTALK.',
//			size: 60
//		} : null,
	},
	{
		label: 'FS2: Mavjud boʻlmagan foydalanuvchi uchun yaratilgan sahifa',
		value: 'FS2: Mavjud boʻlmagan foydalanuvchi uchun yaratilgan sahifa',
		tooltip: ''
	},
	{
		label: 'FS3: Foydalanuvchi sahifasidan nojoʻya foydalanish',
		value: 'FS3: Foydalanuvchi sahifasidan nojoʻya foydalanish',
		tooltip: ''
	}
];

Twinkle.speedy.generalList = [
	{
		label: 'U1: Maʼnosiz',
		value: '[[VP:U1|U1]]: Maʼnosiz',
		tooltip: 'Maʼnosiz, yaʼni tayinli maʼlumot bermaydigan, tushunarsiz belgilar ketma-ketligi (masalan, asdafbs bsnmgbasg s ADADFAF agbcxbxcb kabilar).',
		hideInNamespaces: [ 2 ] // Not applicable in userspace
	},
	{
		label: 'U2: Test sahifa',
		value: '[[VP:U2|U2]]: Test sahifa',
		tooltip: 'Vikipediyaning texnik imkoniyatlarini sinash uchun yaratilgan sahifa, buning uchun maxsus moʻljallangan sahifalar bundan mustasno.',
		hideInNamespaces: [ 2 ] // Not applicable in userspace
	},
	{
		label: 'U3: Vandalizm',
		value: '[[VP:U3|U3]]: Vandalizm',
		tooltip: 'Shu jumladan aniq yolgʻon, shuningdek vandalizm oqibatlarini bartaraf etish paytida yaratilgan vaqtinchalik yoʻnaltirishlar.'
	},
	{
		label: 'U4: Avval oʻchirilgan va qayta yaratish taʼqiqlangan sahifa',
		value: '[[VP:U4|U4]]: Avval oʻchirilgan va qayta yaratish taʼqiqlangan sahifa',
		tooltip: 'Ushbu mezon munozara asosida avval oʻchirilgan sahifaning asossiz tiklangan nusxalariga nisbatan qoʻllaniladi.'
	},
	{
		label: 'U5: Bloklangan foydalanuvchi tomonidan yaratilgan sahifa',
		value: '[[VP:U5|U5]]: Bloklangan foydalanuvchi tomonidan yaratilgan sahifa',
		tooltip: 'Ushbu mezon bloklangan foydalanuvchilar tomonidan yaratilgan sahifalarga nisbatan qoʻllaniladi.'
//		subgroup: {
//			name: 'repost_xfd',
//			type: 'input',
//			label: 'Page where the deletion discussion took place:',
//			tooltip: 'Must start with "Wikipedia:"',
//			size: 60
//		}
	},
	{
		label: 'U6: Sahifa muallifi istagi bilan',
		value: '[[VP:U6|U6]]: Sahifa muallifi istagi bilan',
		tooltip: 'Ushbu mezon biror sahifani uni yaratgan foydalanuvchi (yaʼni, shu sahifa muallif) oʻchirilishini ilimos qilgan hollarga nisbatan qoʻllaniladi (bunda, sahifa shu muallif tomonidan yozilgan boʻlishi va oʻchirish sababi koʻrsatilishi lozim).'
	},
	{
		label: 'U7: Koʻchirish imkoniyatini yaratish uchun',
		value: '[[VP:U7|U7]]: Koʻchirish imkoniyatini yaratish uchun',
		tooltip: 'Sahifani koʻchirish yoki tahrirlar tarixini birlashtirish uchun. Ushbu amal eʼtiroz uygʻotmasligi yoki oldindan kelishuv asosida qilinishi lozim.'
	},
	{
		label: 'U8: Oʻchirilgan sahifaning ostsahifasi yoki munozara sahifasi',
		value: '[[VP:U8|U8]]: Oʻchirilgan sahifaning ostsahifasi yoki munozara sahifasi',
		tooltip: 'Misollar: \n* Tegishli mavzu sahifasi boʻlmagan munozara sahifalari \n* Asosiy, bosh sahifasi boʻlmagan ostsahifalar \n* Mavjud boʻlmagan sahifalarga yoʻnaltirish qoldirilgan yoʻnaltiruvchi sahifalar'
	},
	{
		label: 'U9: Kamsituvchi va shundan boshqa maqsadlarga xizmat qilmaydigan sahifa',
		value: '[[VP:U9|U9]]: Kamsituvchi va shundan boshqa maqsadlarga xizmat qilmaydigan sahifa',
		tooltip: 'Ushbu mezon boʻhton, tahdid, taʼqib yoki qoʻrqitish uchun moʻljallangan materiallarni oʻz ichiga olgan sahifalarga nisbatan qoʻllaniladi.'
	},
	{
		label: 'U10: Reklama',
		value: '[[VP:U10|U10]]: Reklama',
		tooltip: 'Bu faqat reklama uchun moʻljallangan sahifalarga taalluqli hisoblanadi. Agar mavzu diqqatga sazovor boʻlsa va kontentni neytral (betaraf) nuqtai nazardan yozilgan matn bilan almashtirish imkoni mavjud boʻlsa, bu sahifani saqlash oʻchirishdan koʻra afzaldir (albatta, qayta tahrirlansa).'
	},
	{
		label: 'U11: Mualliflik huquqlarining yaqqol buzilishi',
		value: '[[VP:U11|U11]]: Mualliflik huquqlarining yaqqol buzilishi',
		tooltip: 'Bu mualliflik huquqlari bilan himoyalangan materialni biror-bir veb-saytdan hech qanday oʻzgartirishsiz matn koʻchirib qoʻyilgan hollarda, erkin litsenziyasiz, saqlashga arzigulik kontent boʻlmagan matnli sahifalarga nisbatan qoʻllaniladi. Batafsil tanishish uchun Vikipediya:Mualliflik huquqlari buzilishi sahifasiga qarang.'
	}
];

Twinkle.speedy.redirectList = [
	{
		label: 'Y1: Mavjud boʻlmagan sahifaga yoʻnaltirish',
		value: 'Y1: Mavjud boʻlmagan sahifaga yoʻnaltirish',
		tooltip: '',
		showInNamespaces: [ 0 ]
	},
	{
		label: 'Y2: Nomfazolararo yoʻnaltirish',
		value: 'Y2: Nomfazolararo yoʻnaltirish',
		tooltip: ''
	},
	{
		label: 'Y3: Nomida qoʻpol xatoga yoʻl qoʻyilgan yoʻnaltirish',
		value: 'Y3: Nomida qoʻpol xatoga yoʻl qoʻyilgan yoʻnaltirish',
		tooltip: '',
		showInNamespaces: [ 6 ]
	}
];

Twinkle.speedy.normalizeHash = {
	'reason': 'db',
	'[[VP:U1|U1]]: Maʼnosiz': 'g1',
	'[[VP:U2|U2]]: Test sahifa': 'g2',
	'[[VP:U3|U3]]: Vandalizm': 'g3',
	'[[VP:U4|U4]]: Avval oʻchirilgan va qayta yaratish taʼqiqlangan sahifa': 'g4',
	'[[VP:U5|U5]]: Bloklangan foydalanuvchi tomonidan yaratilgan sahifa': 'g5',
	'[[VP:U6|U6]]: Sahifa muallifi istagi bilan': 'g7',
	'[[VP:U7|U7]]: Koʻchirish imkoniyatini yaratish uchun': 'g6',
	'[[VP:U8|U8]]: Oʻchirilgan sahifaning ostsahifasi yoki munozara sahifasi': 'g8',
	'[[VP:U9|U9]]: Kamsituvchi va shundan boshqa maqsadlarga xizmat qilmaydigan sahifa': 'g10',
	'[[VP:U10|U10]]: Reklama': 'g11',
	'[[VP:U11|U11]]: Mualliflik huquqlarining yaqqol buzilishi': 'g12',
	'[[VP:M1|M1]]: Ensiklopedik boʻlmagan qisqa maqola': 'a3',
	'[[VP:M2|M2]]: Butkul oʻzbekcha boʻlmagan maqola': 'a2',
	'[[VP:M2|M2]]: Tuzatib boʻlmas mashina tarjimasi': 'a2',
	'[[VP:M3|M3]]: Faqatgina ishoratlardan iborat maqola': 'a3',
	'[[VP:M4|M4]]: Boshqa Vikimedia loyihalaridan koʻchirib olib oʻtilgan maqola': 'a2',
	'[[VP:M6|M6]]: Keng ommaga mashhur boʻlmagan kishi, tashkilot, veb-sayt yoki hodisa haqidagi maqola': 'a7',
	'[[VP:M8|M8]]: Avvaldan mavjud maqolaning nusxasi boʻlgan maqola': 'a10',
	'Y1: Mavjud boʻlmagan sahifaga yoʻnaltirish': 'g8',
	'Y2: Nomfazolararo yoʻnaltirish': 'r2',
	'Y3: Nomida qoʻpol xatoga yoʻl qoʻyilgan yoʻnaltirish': 'r3',
	'F1: Litsenziyasi nomaʼlum fayl': 'f4',
	'F2: Birorta sahifada ishlatilmagan noerkin fayl': 'f5',
	'F3: Foydalanish asosi koʻrsatilmagan noerkin fayl': 'f6',
	'F4: Vikiomborda mavjud fayl': 'f8',
	'T1: Boʻsh turkum': 'c1',
	'T2: Nomi imlo xatosi bilan yozilgan turkum': 'c1',
	'FS1: Foydalanuvchi iltimosi bilan': 'u1',
	'FS2: Mavjud boʻlmagan foydalanuvchi uchun yaratilgan sahifa': 'u2',
	'FS3: Foydalanuvchi sahifasidan nojoʻya foydalanish': 'u5'
};

    Twinkle.speedy.callbacks = {
        getTemplateCodeAndParams: function(params) {
            var code, parameters, i;
            if (params.normalizeds.length > 1) {
                code = "{{tezda oʻchirishga|";
                params.utparams = {};
                $.each(params.normalizeds, function(index, norm) {
                    code += (index === 0 ? '' : ', ') + params.values[index];
                    parameters = params.templateParams[index] || [];
                    for (var i in parameters) {
                        if (typeof parameters[i] === 'string' && !parseInt(i, 10)) { // skip numeric parameters - {{db-multiple}} doesn't understand them
                            code += '+' + i + '=' + parameters[i];
                        }
                    }
                    $.extend(params.utparams, Twinkle.speedy.getUserTalkParameters(norm, parameters));
                });
                code += '}}';
            } else {
                parameters = params.templateParams[0] || [];
                code = '{{tezda oʻchirishga|' + params.values[0];
                for (i in parameters) {
                    if (typeof parameters[i] === 'string') {
                        code += '|' + i + '=' + parameters[i];
                    }
                }
                if (params.usertalk) {
                    code += '';
                }
                code += '}}';
                params.utparams = Twinkle.speedy.getUserTalkParameters(params.normalizeds[0], parameters);
            }

            return [code, params.utparams];
        },

	parseWikitext: function(wikitext, callback) {
		var query = {
			action: 'parse',
			prop: 'text',
			pst: 'true',
			text: wikitext,
			contentmodel: 'wikitext',
			title: mw.config.get('wgPageName'),
			disablelimitreport: true,
			format: 'json'
		};

		var statusIndicator = new Morebits.status('Oʻchirish sababini oʻz ichiga olgan tahrir izohi yaratilyapti');
		var api = new Morebits.wiki.api('Parsing deletion template', query, function(apiobj) {
			var reason = decodeURIComponent($(apiobj.getResponse().parse.text).find('#delete-reason').text()).replace(/\+/g, ' ');
			if (!reason) {
				statusIndicator.warn('Tahrir izohi yaratib boʻlmadi');
			} else {
				statusIndicator.info('complete');
			}
			callback(reason);
		}, statusIndicator);
		api.post();
	},

	noteToCreator: function(pageobj) {
		var params = pageobj.getCallbackParameters();
		var initialContrib = pageobj.getCreator();

		// disallow notifying yourself
		if (initialContrib === mw.config.get('wgUserName')) {
			Morebits.status.warn('Bu sahifani siz (' + initialContrib + ') yaratgangiz, shu sababli foydalanuvchi munozara sahifangizga xabar andozasi qoʻshilmaydi');
			initialContrib = null;

		// don't notify users when their user talk page is nominated/deleted
		} else if (initialContrib === mw.config.get('wgTitle') && mw.config.get('wgNamespaceNumber') === 3) {
			Morebits.status.warn('Notifying initial contributor: this user created their own user talk page; skipping notification');
			initialContrib = null;

		// quick hack to prevent excessive unwanted notifications, per request. Should actually be configurable on recipient page...
		} else if ((initialContrib === 'Cyberbot I' || initialContrib === 'SoxBot') && params.normalizeds[0] === 'f2') {
			Morebits.status.warn('Notifying initial contributor: page created procedurally by bot; skipping notification');
			initialContrib = null;

		// Check for already existing tags
		} else if (Twinkle.speedy.hasCSD && params.warnUser && !confirm('Sahifaga {{oʻchirishga}} andozasi qoʻshilgan. Shu sababli, katta ehtimol bilan sahifa yaratuvchisi ham bu haqda xabardor etilgan. Sahifa yaratuvchisi sahifani oʻchirganingiz haqida ham xabardor etilishini xohlaysizmi?')) {
			Morebits.status.info('Sahifa yaratuvchisi xabardor qilinyapti', '(foydalanuvchi bekor qildi)');
			initialContrib = null;
		}

		if (initialContrib) {
			var usertalkpage = new Morebits.wiki.page('Foydalanuvchi munozarasi:' + initialContrib, 'Sahifa yaratuvchisi xabardor qilinyapti (' + initialContrib + ')'),
				notifytext, i, editsummary;

			// special cases: "db" and "db-multiple"
		/*	if (params.normalizeds.length > 1) {
				notifytext = '\n{{subst:db-' + (params.warnUser ? 'deleted' : 'notice') + '|1=' + Morebits.pageNameNorm;
				var count = 2;
				$.each(params.normalizeds, function(index, norm) {
					notifytext += '|' + count++ + '=' + norm.toUpperCase();
				});
			} else if (params.normalizeds[0] === 'db') {
				notifytext = '\n{{subst:db-' + (params.warnUser ? 'deleted' : 'notice') + ' |1=' + Morebits.pageNameNorm;
			} else {
				notifytext = '\n{{subst:db-' + (params.warnUser ? 'deleted' : 'notice') + ' |1=';
				if (params.values[0] === 'copypaste') {
					notifytext += params.templateParams[0].sourcepage;
				} else {
					notifytext += Morebits.pageNameNorm;
				}
				notifytext += '|2=' + params.values[0];
			}

			for (i in params.utparams) {
				if (typeof params.utparams[i] === 'string') {
					notifytext += '|' + i + '=' + params.utparams[i];
				}
			}
			notifytext += (params.welcomeuser ? '' : '|nowelcome=yes') + '}}';
			
			editsummary = '[[:' + Morebits.pageNameNorm + ']] sahifasi tezda' + (params.warnUser ? ' oʻchirildi' : ' oʻchirishga nomzod oʻlaroq koʻrsatildi');
			if (params.normalizeds.indexOf('g10') === -1) {  // no article name in summary for G10 taggings
				editsummary += '';
			} else {
				editsummary += '';
			} */
          
            notifytext = '\n{{subst:db-' + (params.warnUser ? 'deleted' : 'notice') + '|1=' + Morebits.pageNameNorm + '|2=' + params.values.join(', ') + '}}';
            
            editsummary = '[[VP:TOʻM|TOʻM]]: [[:' + Morebits.pageNameNorm + ']] sahifasi tezda' + (params.warnUser ? ' oʻchirildi' : ' oʻchirishga nomzod oʻlaroq koʻrsatildi');
            if (params.normalizeds.indexOf('g10') === -1) {  
                editsummary = '[[VP:TOʻM|TOʻM]]: [[:' + Morebits.pageNameNorm + ']] sahifasi tezda' + (params.warnUser ? ' oʻchirildi' : ' oʻchirishga nomzod oʻlaroq koʻrsatildi');
            } else {
                editsummary = '[[VP:TOʻM|TOʻM]]: [[:' + Morebits.pageNameNorm + ']] sahifasi tezda' + (params.warnUser ? ' oʻchirildi' : ' oʻchirishga nomzod oʻlaroq koʻrsatildi');
            }

			usertalkpage.setAppendText(notifytext);
			usertalkpage.setEditSummary(editsummary);
			usertalkpage.setChangeTags(Twinkle.changeTags);
			usertalkpage.setCreateOption('recreate');
			usertalkpage.setWatchlist(Twinkle.getPref('watchSpeedyUser'));
			usertalkpage.setFollowRedirect(true, false);
			usertalkpage.append(function onNotifySuccess() {
				// add this nomination to the user's userspace log, if the user has enabled it
				if (params.lognomination) {
					Twinkle.speedy.callbacks.user.addToLog(params, initialContrib);
				}
			}, function onNotifyError() {
				// if user could not be notified, log nomination without mentioning that notification was sent
				if (params.lognomination) {
					Twinkle.speedy.callbacks.user.addToLog(params, null);
				}
			});
		} else if (params.lognomination) {
			// log nomination even if the user notification wasn't sent
			Twinkle.speedy.callbacks.user.addToLog(params, null);
		}
	},

	sysop: {
        main: function(params) {
            var reason = params.values[0];
            //params.templateParams[0]['1']
            if (params.templateParams[0]['1']) {
                reason = 'Sahifani oʻchirish sababi: ' + params.templateParams[0]['1'];
                Twinkle.speedy.callbacks.sysop.deletePage(reason, params);
            } else {
                if (params.promptForSummary) {
                    reason = prompt("Oʻchirish sababini kiriting yoki avtomatik ravishda yaratilgan sababni OK tugmasini bosish orqali maʼqullang.", reason);
                }
                Twinkle.speedy.callbacks.sysop.deletePage(reason, params);
            }
        },
	// 
	/*	main: function(params) {
			var reason;
			if (!params.normalizeds.length && params.normalizeds[0] === 'db') {
				reason = prompt('Enter the deletion summary to use, which will be entered into the deletion log:', '');
				Twinkle.speedy.callbacks.sysop.deletePage(reason, params);
			} else {
				var code = Twinkle.speedy.callbacks.getTemplateCodeAndParams(params)[0];
				Twinkle.speedy.callbacks.parseWikitext(code, function(reason) {
					if (params.promptForSummary) {
						reason = prompt('Enter the deletion summary to use, or press OK to accept the automatically generated one.', reason);
					}
					Twinkle.speedy.callbacks.sysop.deletePage(reason, params);
				});
			}
		},*/
		deletePage: function(reason, params) {
			var thispage = new Morebits.wiki.page(mw.config.get('wgPageName'), 'Sahifani oʻchirish');

			if (reason === null) {
				return Morebits.status.error('Asking for reason', 'Foydalanuvchi bekor qildi');
			} else if (!reason || !reason.replace(/^\s*/, '').replace(/\s*$/, '')) {
				return Morebits.status.error('Asking for reason', "you didn't give one.  I don't know... what with admins and their apathetic antics... I give up...");
			}

			var deleteMain = function(callback) {
				thispage.setEditSummary(reason);
				thispage.setChangeTags(Twinkle.changeTags);
				thispage.setWatchlist(params.watch);
				thispage.deletePage(function() {
					thispage.getStatusElement().info('done');
					typeof callback === 'function' && callback();
					Twinkle.speedy.callbacks.sysop.deleteTalk(params);
				});
			};

			// look up initial contributor. If prompting user for deletion reason, just display a link.
			// Otherwise open the talk page directly
			if (params.warnUser) {
				thispage.setCallbackParameters(params);
				thispage.lookupCreation(function(pageobj) {
					deleteMain(function() {
						Twinkle.speedy.callbacks.noteToCreator(pageobj);
					});
				});
			} else {
				deleteMain();
			}
		},
		deleteTalk: function(params) {
			// delete talk page
			if (params.deleteTalkPage &&
					params.normalized !== 'f8' &&
					!document.getElementById('ca-talk').classList.contains('new')) {
				var talkpage = new Morebits.wiki.page(mw.config.get('wgFormattedNamespaces')[mw.config.get('wgNamespaceNumber') + 1] + ':' + mw.config.get('wgTitle'), 'Deleting talk page');
				talkpage.setEditSummary('[[VP:TOʻM#U8|U8]]: Oʻchirilgan sahifa (' + Morebits.pageNameNorm + ') ning munozara sahifasi');
				talkpage.setChangeTags(Twinkle.changeTags);
				talkpage.deletePage();
				// this is ugly, but because of the architecture of wiki.api, it is needed
				// (otherwise success/failure messages for the previous action would be suppressed)
				window.setTimeout(function() {
					Twinkle.speedy.callbacks.sysop.deleteRedirects(params);
				}, 1800);
			} else {
				Twinkle.speedy.callbacks.sysop.deleteRedirects(params);
			}
		},
		deleteRedirects: function(params) {
			// delete redirects
			if (params.deleteRedirects) {
				var query = {
					action: 'query',
					titles: mw.config.get('wgPageName'),
					prop: 'redirects',
					rdlimit: 'max', // 500 is max for normal users, 5000 for bots and sysops
					format: 'json'
				};
				var wikipedia_api = new Morebits.wiki.api('getting list of redirects...', query, Twinkle.speedy.callbacks.sysop.deleteRedirectsMain,
					new Morebits.status('Deleting redirects'));
				wikipedia_api.params = params;
				wikipedia_api.post();
			}

			// Ichki ishoratlarni yoʻqotgich asbobi
			var $link, $bigtext;
			if (mw.config.get('wgNamespaceNumber') === 6 && params.normalized !== 'f8') {
				$link = $('<a/>', {
					href: '#',
					text: 'Ichki ishoratlarni yoʻqotgich asbobidan foydalanmoqchi boʻlsangiz, bu yerga bosing.',
					css: { fontSize: '130%', fontWeight: 'bold' },
					click: function() {
						Morebits.wiki.actionCompleted.redirect = null;
						Twinkle.speedy.dialog.close();
						Twinkle.unlink.callback('Oʻchirilgan faylga qoldirilgan ichki ishoratlar yoʻqotilyapti ' + Morebits.pageNameNorm);
					}
				});
				$bigtext = $('<span/>', {
					text: 'Bu sahifa/faylga qoldirilgan ichki ishoratlarni sahifalardan yoʻqotish',
					css: { fontSize: '130%', fontWeight: 'bold' }
				});
				Morebits.status.info($bigtext[0], $link[0]);
			} else if (params.normalized !== 'f8') {
				$link = $('<a/>', {
					href: '#',
					text: 'Ichki ishoratlarni yoʻqotgich asbobidan foydalanmoqchi boʻlsangiz, bu yerga bosing.',
					css: { fontSize: '130%', fontWeight: 'bold' },
					click: function() {
						Morebits.wiki.actionCompleted.redirect = null;
						Twinkle.speedy.dialog.close();
						Twinkle.unlink.callback('Oʻchirilgan sahifaga qoldirilgan ichki ishoratlar yoʻqotilyapti ' + Morebits.pageNameNorm);
					}
				});
				$bigtext = $('<span/>', {
					text: 'Bu sahifaga qoldirilgan ichki ishoratlarni sahifalardan yoʻqotish',
					css: { fontSize: '130%', fontWeight: 'bold' }
				});
				Morebits.status.info($bigtext[0], $link[0]);
			}
		},
		deleteRedirectsMain: function(apiobj) {
			var response = apiobj.getResponse();
			var snapshot = response.query.pages[0].redirects || [];
			var total = snapshot.length;
			var statusIndicator = apiobj.statelem;

			if (!total) {
				statusIndicator.status('no redirects found');
				return;
			}

			statusIndicator.status('0%');

			var current = 0;
			var onsuccess = function(apiobjInner) {
				var now = parseInt(100 * ++current / total, 10) + '%';
				statusIndicator.update(now);
				apiobjInner.statelem.unlink();
				if (current >= total) {
					statusIndicator.info(now + ' (bajarildi)');
					Morebits.wiki.removeCheckpoint();
				}
			};

			Morebits.wiki.addCheckpoint();

			snapshot.forEach(function(value) {
				var title = value.title;
				var page = new Morebits.wiki.page(title, 'Deleting redirect "' + title + '"');
				page.setEditSummary('Oʻchirilgan sahifa („' + Morebits.pageNameNorm + '“) ga yoʻnaltiruvchi sahifa');
				page.setChangeTags(Twinkle.changeTags);
				page.deletePage(onsuccess);
			});
		}
	},

	user: {
		main: function(pageobj) {
			var statelem = pageobj.getStatusElement();

			if (!pageobj.exists()) {
				statelem.error("Bunday nomli sahifa mavjud emas.");
				return;
			}

			var params = pageobj.getCallbackParameters();

			// given the params, builds the template and also adds the user talk page parameters to the params that were passed in
			// returns => [<string> wikitext, <object> utparams]
			var buildData = Twinkle.speedy.callbacks.getTemplateCodeAndParams(params),
				code = buildData[0];
			params.utparams = buildData[1];

			// Set the correct value for |ts= parameter in {{db-g13}}
			if (params.normalizeds.indexOf('g13') !== -1) {
				code = code.replace('$TIMESTAMP', pageobj.getLastEditTime());
			}

			// Tag if possible, post on talk if not
			if (pageobj.canEdit() && ['wikitext', 'Scribunto', 'javascript', 'css', 'sanitized-css'].indexOf(pageobj.getContentModel()) !== -1) {
				var text = pageobj.getPageText();

				statelem.status('Checking for tags on the page...');

				// check for existing deletion tags
				var tag = /(?:\{\{\s*(db|delete|[Tt]ezda oʻchirishga|[Oo]ʻchirishga|db-.*?|speedy deletion-.*?)(?:\s*\||\s*\}\}))/.exec(text);
				// This won't make use of the db-multiple template but it probably should
				if (tag && !confirm('Sahifaga allaqachon {{tezda oʻchirishga}} andozasi qoʻshilgan. TOʻM andozasini qoʻshmoqchi ekanligingizga aminmisiz?')) {
					return;
				}

				var xfd = /\{\{((?:article for deletion|proposed deletion|prod blp|template for discussion)\/dated|[cfm]fd\b)/i.exec(text) || /#invoke:(RfD)/.exec(text);
				if (xfd && !confirm('Sahifaga allaqachon {{oʻchirishga}} andozasi qoʻshilgan. TOʻM andozasini qoʻshmoqchi ekanligingizga aminmisiz?')) {
					return;
				}

				// curate/patrol the page
				if (Twinkle.getPref('markSpeedyPagesAsPatrolled')) {
					pageobj.triage();
				}

				// Wrap SD template in noinclude tags if we are in template space.
				// Won't work with userboxes in userspace, or any other transcluded page outside template space
				if (mw.config.get('wgNamespaceNumber') === 10) {  // Template:
					code = '<noinclude>' + code + '</noinclude>';
				}

				// Remove tags that become superfluous with this action
				text = text.replace(/\{\{\s*([Uu]serspace draft)\s*(\|(?:\{\{[^{}]*\}\}|[^{}])*)?\}\}\s*/g, '');
				if (mw.config.get('wgNamespaceNumber') === 6) {
					// remove "move to Commons" tag - deletion-tagged files cannot be moved to Commons
					text = text.replace(/\{\{(mtc|(copy |move )?to ?commons|move to wikimedia commons|copy to wikimedia commons)[^}]*\}\}/gi, '');
				}

				if (params.requestsalt) {
					if (params.normalizeds.indexOf('g10') === -1) {
						code += '\n{{salt}}';
					} else {
						code = '{{salt}}\n' + code;
					}
				}

				if (mw.config.get('wgPageContentModel') === 'Scribunto') {
					// Scribunto isn't parsed like wikitext, so CSD templates on modules need special handling to work
					var equals = '';
					while (code.indexOf(']' + equals + ']') !== -1) {
						equals += '=';
					}
					code = "require('Module:Module wikitext')._addText([" + equals + '[' + code + ']' + equals + ']);';
				} else if (['javascript', 'css', 'sanitized-css'].indexOf(mw.config.get('wgPageContentModel')) !== -1) {
					// Likewise for JS/CSS pages
					code = '/* ' + code + ' */';
				}

				// Generate edit summary for edit
				var editsummary;
				if (params.normalizeds.length > 1) {
					editsummary = 'Sahifa tezda oʻchirishga nomzod oʻlaroq koʻrsatildi (';
					$.each(params.normalizeds, function(index, norm) {
						editsummary += '[[VP:TOʻM#' + norm.toUpperCase() + '|TOʻM – ' + norm.toUpperCase() + ']], ';
					});
					editsummary = editsummary.substr(0, editsummary.length - 2); // remove trailing comma
					editsummary += ').';
				} else if (params.normalizeds[0] === 'db') {
					editsummary = 'Sahifa [[VP:TOʻM|tezda oʻchirishga]] nomzod oʻlaroq koʻrsatildi („' + params.templateParams[0]['1'] + '“).';
				} else {
					editsummary = 'Sahifa tezda oʻchirishga nomzod oʻlaroq koʻrsatildi ([[VP:TOʻM#' + params.normalizeds[0].toUpperCase() + '|TOʻM – ' + params.normalizeds[0].toUpperCase() + ']]).';
				}

				// Blank attack pages
				if (params.normalizeds.indexOf('g10') !== -1) {
					text = code;
				} else {
					// Insert tag after short description or any hatnotes
					var wikipage = new Morebits.wikitext.page(text);
					text = wikipage.insertAfterTemplates(code + '\n', Twinkle.hatnoteRegex).getText();
				}


				pageobj.setPageText(text);
				pageobj.setEditSummary(editsummary);
				pageobj.setWatchlist(params.watch);
				pageobj.save(Twinkle.speedy.callbacks.user.tagComplete);
			} else { // Attempt to place on talk page
				var talkName = new mw.Title(pageobj.getPageName()).getTalkPage().toText();
				if (talkName !== pageobj.getPageName()) {
					if (params.requestsalt) {
						code += '\n{{salt}}';
					}

					pageobj.getStatusElement().warn('Sahifani tahrirlab boʻlmadi, shu yuzdan {{tezda oʻchirishga}} andozasi munozara sahifasiga qoʻshildi');

					var talk_page = new Morebits.wiki.page(talkName, 'Automatically placing tag on talk page');
					talk_page.setNewSectionTitle('„' + pageobj.getPageName() + '“ sahifasi tezda oʻchirishga nomzod oʻlaroq koʻrsatildi');
					talk_page.setNewSectionText(code + '\n\n„' + pageobj.getPageName() + '“ sahifasiga {{tl|tezda oʻchirishga}} andozasini qoʻya olmadim, sababi menda sahifani tahrirlashga ruxsat yoʻq. Iltimos, sahifani oʻchiring. ~~~~');
					talk_page.setCreateOption('recreate');
					talk_page.setFollowRedirect(true);
					talk_page.setWatchlist(params.watch);
					talk_page.setChangeTags(Twinkle.changeTags);
					talk_page.setCallbackParameters(params);
					talk_page.newSection(Twinkle.speedy.callbacks.user.tagComplete);
				} else {
					pageobj.getStatusElement().error('Page protected and nowhere to add an edit request, aborting');
				}
			}
		},

		tagComplete: function(pageobj) {
			var params = pageobj.getCallbackParameters();

			// Notification to first contributor, will also log nomination to the user's userspace log
			if (params.usertalk) {
				var thispage = new Morebits.wiki.page(Morebits.pageNameNorm);
				thispage.setCallbackParameters(params);
				thispage.lookupCreation(Twinkle.speedy.callbacks.noteToCreator);
			// or, if not notifying, add this nomination to the user's userspace log without the initial contributor's name
			} else if (params.lognomination) {
				Twinkle.speedy.callbacks.user.addToLog(params, null);
			}
		},

		addToLog: function(params, initialContrib) {
			var usl = new Morebits.userspaceLogger(Twinkle.getPref('speedyLogPageName'));
			usl.initialText =
				"This is a log of all [[WP:CSD|speedy deletion]] nominations made by this user using [[WP:TW|Twinkle]]'s CSD module.\n\n" +
				'If you no longer wish to keep this log, you can turn it off using the [[Wikipedia:Twinkle/Preferences|preferences panel]], and ' +
				'nominate this page for speedy deletion under [[VP:TOʻM#U1|CSD U1]].' +
				(Morebits.userIsSysop ? '\n\nThis log does not track outright speedy deletions made using Twinkle.' : '');

			var formatParamLog = function(normalize, csdparam, input) {
				if ((normalize === 'G4' && csdparam === 'xfd') ||
					(normalize === 'G6' && csdparam === 'page') ||
					(normalize === 'G6' && csdparam === 'fullvotepage') ||
					(normalize === 'G6' && csdparam === 'sourcepage') ||
					(normalize === 'A2' && csdparam === 'source') ||
					(normalize === 'A10' && csdparam === 'article') ||
					(normalize === 'F1' && csdparam === 'filename')) {
					input = '[[:' + input + ']]';
				} else if (normalize === 'G5' && csdparam === 'user') {
					input = '[[:Foydalanuvchi:' + input + ']]';
				} else if (normalize === 'G12' && csdparam.lastIndexOf('url', 0) === 0 && input.lastIndexOf('http', 0) === 0) {
					input = '[' + input + ' ' + input + ']';
				} else if (normalize === 'F8' && csdparam === 'filename') {
					input = '[[commons:' + input + ']]';
				}
				return ' {' + normalize + ' ' + csdparam + ': ' + input + '}';
			};

			var extraInfo = '';

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

			var editsummary = 'Logging speedy deletion nomination';
			var appendText = '# [[:' + Morebits.pageNameNorm;

			if (params.normalizeds.indexOf('g10') === -1) {  // no article name in log for G10 taggings
				appendText += ']]' + fileLogLink + ': ';
				editsummary += ' of [[:' + Morebits.pageNameNorm + ']].';
			} else {
				appendText += '|This]] attack page' + fileLogLink + ': ';
				editsummary += ' of an attack page.';
			}
			if (params.normalizeds.length > 1) {
				appendText += 'multiple criteria (';
				$.each(params.normalizeds, function(index, norm) {
					appendText += '[[VP:TOʻM#' + norm.toUpperCase() + '|' + norm.toUpperCase() + ']], ';
				});
				appendText = appendText.substr(0, appendText.length - 2);  // remove trailing comma
				appendText += ')';
			} else if (params.normalizeds[0] === 'db') {
				appendText += '{{tl|db-reason}}';
			} else {
				appendText += '[[VP:TOʻM#' + params.normalizeds[0].toUpperCase() + '|TOʻM ' + params.normalizeds[0].toUpperCase() + ']] ({{tl|db-' + params.values[0] + '}})';
			}

                // If params is "empty" it will still be full of empty arrays, but ask anyway
                /*if (params.templateParams) {
                    // Treat custom rationale individually
                    if (params.normalizeds[0] && params.normalizeds[0] === 'db') {
                        extraInfo += formatParamLog('Custom', 'rationale', params.templateParams[0]['1']);
                    } else {
                        params.templateParams.forEach(function(item, index) {
                            var keys = Object.keys(item);
                            if (keys[0] !== undefined && keys[0].length > 0) {
                                // Second loop required since some items (G12, F9) may have multiple keys
                                keys.forEach(function(key, keyIndex) {
                                    if (keys[keyIndex] === 'blanked' || keys[keyIndex] === 'ts') {
                                        return true; // Not worth logging
                                    }
                                    extraInfo += formatParamLog(params.normalizeds[index].toUpperCase(), keys[keyIndex], item[key]);
                                });
                            }
                        });
                    }
                }*/

			if (params.requestsalt) {
				appendText += '; sahifa yaratishga qarshi himoyalashga nomzod oʻlaroq koʻrsatildi';
			}
			if (extraInfo) {
				appendText += '; qoʻshimcha maʼlumot:' + extraInfo;
			}
			if (initialContrib) {
				appendText += '; {{user|1=' + initialContrib + '}} xabardor etildi';
			}
			appendText += ' ~~~~~\n';

			usl.changeTags = Twinkle.changeTags;
			usl.log(appendText, editsummary);
		}
	}
};

// validate subgroups in the form passed into the speedy deletion tag
Twinkle.speedy.getParameters = function twinklespeedyGetParameters(form, values) {
	var parameters = [];

	$.each(values, function(index, value) {
		var currentParams = [];
		switch (value) {
			case 'reason':
				if (form['csd.reason_1']) {
					var dbrationale = form['csd.reason_1'].value;
					if (!dbrationale || !dbrationale.trim()) {
						alert('Custom rationale:  Please specify a rationale.');
						parameters = null;
						return false;
					}
					currentParams['1'] = dbrationale;
				}
				break;

			case 'userreq':  // U1
				if (form['csd.userreq_rationale']) {
					var u1rationale = form['csd.userreq_rationale'].value;
					if (mw.config.get('wgNamespaceNumber') === 3 && !(/\//).test(mw.config.get('wgTitle')) &&
							(!u1rationale || !u1rationale.trim())) {
						alert('CSD U1:  Please specify a rationale when nominating user talk pages.');
						parameters = null;
						return false;
					}
					currentParams.rationale = u1rationale;
				}
				break;

			case 'repost':  // G4
				if (form['csd.repost_xfd']) {
					var deldisc = form['csd.repost_xfd'].value;
					if (deldisc) {
						currentParams.xfd = deldisc;
					}
				}
				break;

			case 'banned':  // G5
				if (form['csd.banned_user'] && form['csd.banned_user'].value) {
					currentParams.user = form['csd.banned_user'].value.replace(/^\s*User:/i, '');
				}
				break;

			case 'move':  // G6
				if (form['csd.move_page'] && form['csd.move_reason']) {
					var movepage = form['csd.move_page'].value,
						movereason = form['csd.move_reason'].value;
					if (!movepage || !movepage.trim()) {
						alert('CSD G6 (move):  Please specify the page to be moved here.');
						parameters = null;
						return false;
					}
					if (!movereason || !movereason.trim()) {
						alert('CSD G6 (move):  Please specify the reason for the move.');
						parameters = null;
						return false;
					}
					currentParams.page = movepage;
					currentParams.reason = movereason;
				}
				break;

			case 'xfd':  // G6
				if (form['csd.xfd_fullvotepage']) {
					var xfd = form['csd.xfd_fullvotepage'].value;
					if (xfd) {
						currentParams.fullvotepage = xfd;
					}
				}
				break;

			case 'afc-move':  // G6
				if (form['csd.draft_page']) {
					var draftpage = form['csd.draft_page'].value;
					if (!draftpage || !draftpage.trim()) {
						alert('CSD G6 (AfC move):  Please specify the draft to be moved here.');
						parameters = null;
						return false;
					}
					currentParams.page = draftpage;
				}
				break;

			case 'copypaste':  // G6
				if (form['csd.copypaste_sourcepage']) {
					var copypaste = form['csd.copypaste_sourcepage'].value;
					if (!copypaste || !copypaste.trim()) {
						alert('CSD G6 (copypaste):  Please specify the source page name.');
						parameters = null;
						return false;
					}
					currentParams.sourcepage = copypaste;
				}
				break;

			case 'g6':  // G6
				if (form['csd.g6_rationale'] && form['csd.g6_rationale'].value) {
					currentParams.rationale = form['csd.g6_rationale'].value;
				}
				break;

			case 'author':  // G7
				if (form['csd.author_rationale'] && form['csd.author_rationale'].value) {
					currentParams.rationale = form['csd.author_rationale'].value;
				}
				break;

			case 'g8':  // G8
				if (form['csd.g8_rationale'] && form['csd.g8_rationale'].value) {
					currentParams.rationale = form['csd.g8_rationale'].value;
				}
				break;

			case 'templatecat':  // G8
				if (form['csd.templatecat_rationale'] && form['csd.templatecat_rationale'].value) {
					currentParams.rationale = form['csd.templatecat_rationale'].value;
				}
				break;

			case 'attack':  // G10
				currentParams.blanked = 'yes';
				// it is actually blanked elsewhere in code, but setting the flag here
				break;

			case 'copyvio':  // G12
				if (form['csd.copyvio_url'] && form['csd.copyvio_url'].value) {
					currentParams.url = form['csd.copyvio_url'].value;
				}
				if (form['csd.copyvio_url2'] && form['csd.copyvio_url2'].value) {
					currentParams.url2 = form['csd.copyvio_url2'].value;
				}
				if (form['csd.copyvio_url3'] && form['csd.copyvio_url3'].value) {
					currentParams.url3 = form['csd.copyvio_url3'].value;
				}
				break;

			case 'afc':  // G13
				currentParams.ts = '$TIMESTAMP'; // to be replaced by the last revision timestamp when page is saved
				break;

			case 'redundantimage':  // F1
				if (form['csd.redundantimage_filename']) {
					var redimage = form['csd.redundantimage_filename'].value;
					if (!redimage || !redimage.trim()) {
						alert('CSD F1:  Please specify the filename of the other file.');
						parameters = null;
						return false;
					}
					currentParams.filename = new RegExp('^\\s*' + Morebits.namespaceRegex(6) + ':', 'i').test(redimage) ? redimage : 'File:' + redimage;
				}
				break;

			case 'badfairuse':  // F7
				if (form['csd.badfairuse_rationale'] && form['csd.badfairuse_rationale'].value) {
					currentParams.rationale = form['csd.badfairuse_rationale'].value;
				}
				break;

			case 'commons':  // F8
				if (form['csd.commons_filename']) {
					var filename = form['csd.commons_filename'].value;
					if (filename && filename.trim() && filename !== Morebits.pageNameNorm) {
						currentParams.filename = new RegExp('^\\s*' + Morebits.namespaceRegex(6) + ':', 'i').test(filename) ? filename : 'File:' + filename;
					}
				}
				break;

			case 'imgcopyvio':  // F9
				if (form['csd.imgcopyvio_url'] && form['csd.imgcopyvio_rationale']) {
					var f9url = form['csd.imgcopyvio_url'].value;
					var f9rationale = form['csd.imgcopyvio_rationale'].value;
					if ((!f9url || !f9url.trim()) && (!f9rationale || !f9rationale.trim())) {
						alert('CSD F9: You must enter a url or reason (or both) when nominating a file under F9.');
						parameters = null;
						return false;
					}
					if (form['csd.imgcopyvio_url'].value) {
						currentParams.url = f9url;
					}
					if (form['csd.imgcopyvio_rationale'].value) {
						currentParams.rationale = f9rationale;
					}
				}
				break;

			case 'foreign':  // A2
				if (form['csd.foreign_source']) {
					var foreignlink = form['csd.foreign_source'].value;
					if (!foreignlink || !foreignlink.trim()) {
						alert('CSD A2:  Please specify an interwiki link to the article of which this is a copy.');
						parameters = null;
						return false;
					}
					currentParams.source = foreignlink;
				}
				break;

			case 'a10':  // A10
				if (form['csd.a10_article']) {
					var duptitle = form['csd.a10_article'].value;
					if (!duptitle || !duptitle.trim()) {
						alert('CSD A10:  Please specify the name of the article which is duplicated.');
						parameters = null;
						return false;
					}
					currentParams.article = duptitle;
				}
				break;

			default:
				break;
		}
		parameters.push(currentParams);
	});
	return parameters;
};

// Function for processing talk page notification template parameters
// key1/value1: for {{db-criterion-[notice|deleted]}} (via {{db-csd-[notice|deleted]-custom}})
// utparams.param: for {{db-[notice|deleted]-multiple}}
Twinkle.speedy.getUserTalkParameters = function twinklespeedyGetUserTalkParameters(normalized, parameters) {
	var utparams = [];

	// Special cases
	if (normalized === 'db') {
		utparams['2'] = parameters['1'];
	} else if (normalized === 'g6') {
		utparams.key1 = 'to';
		utparams.value1 = Morebits.pageNameNorm;
	} else if (normalized === 'g12') {
		['url', 'url2', 'url3'].forEach(function(item, idx) {
			if (parameters[item]) {
				idx++;
				utparams['key' + idx] = item;
				utparams['value' + idx] = utparams[item] = parameters[item];
			}
		});
	} else {
		// Handle the rest
		var param;
		switch (normalized) {
			case 'g4':
				param = 'xfd';
				break;
			case 'a2':
				param = 'source';
				break;
			case 'a10':
				param = 'article';
				break;
			case 'f9':
				param = 'url';
				break;
			default:
				break;
		}
		// No harm in providing a usertalk template with the others' parameters
		if (param && parameters[param]) {
			utparams.key1 = param;
			utparams.value1 = utparams[param] = parameters[param];
		}
	}
	return utparams;
};

/**
 * @param {Event} e
 * @returns {Array}
 */
Twinkle.speedy.resolveCsdValues = function twinklespeedyResolveCsdValues(e) {
	var values = (e.target.form ? e.target.form : e.target).getChecked('csd');
	if (values.length === 0) {
		alert('Please select a criterion!');
		return null;
	}
	return values;
};

Twinkle.speedy.callback.evaluateSysop = function twinklespeedyCallbackEvaluateSysop(e) {
	var form = e.target.form ? e.target.form : e.target;

	if (e.target.type === 'checkbox' || e.target.type === 'text' ||
			e.target.type === 'select') {
		return;
	}

	var tag_only = form.tag_only;
	if (tag_only && tag_only.checked) {
		Twinkle.speedy.callback.evaluateUser(e);
		return;
	}

	var values = Twinkle.speedy.resolveCsdValues(e);
	if (!values) {
		return;
	}
	var templateParams = Twinkle.speedy.getParameters(form, values);
	if (!templateParams) {
		return;
	}

	var normalizeds = values.map(function(value) {
		return Twinkle.speedy.normalizeHash[value];
	});

	// analyse each criterion to determine whether to watch the page, prompt for summary, or notify the creator
	var watchPage, promptForSummary;
	normalizeds.forEach(function(norm) {
		if (Twinkle.getPref('watchSpeedyPages').indexOf(norm) !== -1) {
			watchPage = Twinkle.getPref('watchSpeedyExpiry');
		}
		if (Twinkle.getPref('promptForSpeedyDeletionSummary').indexOf(norm) !== -1) {
			promptForSummary = true;
		}
	});

	var warnusertalk = form.warnusertalk.checked && normalizeds.some(function (norm, index) {
		return Twinkle.getPref('warnUserOnSpeedyDelete').indexOf(norm) !== -1 &&
			!(norm === 'g6' && values[index] !== 'copypaste');
	});

	var welcomeuser = warnusertalk && normalizeds.some(function (norm) {
		return Twinkle.getPref('welcomeUserOnSpeedyDeletionNotification').indexOf(norm) !== -1;
	});

	var params = {
		values: values,
		normalizeds: normalizeds,
		watch: watchPage,
		deleteTalkPage: form.talkpage && form.talkpage.checked,
		deleteRedirects: form.redirects.checked,
		warnUser: warnusertalk,
		welcomeuser: welcomeuser,
		promptForSummary: promptForSummary,
		templateParams: templateParams
	};

	Morebits.simpleWindow.setButtonsEnabled(false);
	Morebits.status.init(form);

	Twinkle.speedy.callbacks.sysop.main(params);
};

Twinkle.speedy.callback.evaluateUser = function twinklespeedyCallbackEvaluateUser(e) {
	var form = e.target.form ? e.target.form : e.target;

	if (e.target.type === 'checkbox' || e.target.type === 'text' ||
			e.target.type === 'select') {
		return;
	}

	var values = Twinkle.speedy.resolveCsdValues(e);
	if (!values) {
		return;
	}
	var templateParams = Twinkle.speedy.getParameters(form, values);
	if (!templateParams) {
		return;
	}

	// var multiple = form.multiple.checked;

	var normalizeds = values.map(function(value) {
		return Twinkle.speedy.normalizeHash[value];
	});

	// analyse each criterion to determine whether to watch the page/notify the creator
	var watchPage = normalizeds.some(function(csdCriteria) {
		return Twinkle.getPref('watchSpeedyPages').indexOf(csdCriteria) !== -1;
	}) && Twinkle.getPref('watchSpeedyExpiry');

	var notifyuser = form.notify.checked && normalizeds.some(function(norm, index) {
		return Twinkle.getPref('notifyUserOnSpeedyDeletionNomination').indexOf(norm) !== -1 &&
			!(norm === 'g6' && values[index] !== 'copypaste');
	});
	var welcomeuser = notifyuser && normalizeds.some(function(norm) {
		return Twinkle.getPref('welcomeUserOnSpeedyDeletionNotification').indexOf(norm) !== -1;
	});
	var csdlog = Twinkle.getPref('logSpeedyNominations') && normalizeds.some(function(norm) {
		return Twinkle.getPref('noLogOnSpeedyNomination').indexOf(norm) === -1;
	});

	var params = {
		values: values,
		normalizeds: normalizeds,
		watch: watchPage,
		usertalk: notifyuser,
		welcomeuser: welcomeuser,
		lognomination: csdlog,
		requestsalt: form.salting.checked,
		templateParams: templateParams
	};

	Morebits.simpleWindow.setButtonsEnabled(false);
	Morebits.status.init(form);

	Morebits.wiki.actionCompleted.redirect = mw.config.get('wgPageName');
	Morebits.wiki.actionCompleted.notice = 'Sahifaga andoza qoʻshildi';

	var wikipedia_page = new Morebits.wiki.page(mw.config.get('wgPageName'), 'Sahifaga {{tezda oʻchirishga}} andozasini qoʻshish');
	wikipedia_page.setChangeTags(Twinkle.changeTags); // Here to apply to triage
	wikipedia_page.setCallbackParameters(params);
	wikipedia_page.load(Twinkle.speedy.callbacks.user.main);
};

Twinkle.addInitCallback(Twinkle.speedy, 'speedy');
})(jQuery);


// </nowiki>