Thành viên:AzusaNyan/common.js

Bách khoa toàn thư mở Wikipedia

Chú ý: Sau khi lưu thay đổi trang, bạn phải xóa bộ nhớ đệm của trình duyệt để nhìn thấy các thay đổi. Google Chrome, Firefox, Internet ExplorerSafari: Giữ phím ⇧ Shift và nhấn nút Reload/Tải lại trên thanh công cụ của trình duyệt. Để biết chi tiết và hướng dẫn cho các trình duyệt khác, xem Trợ giúp:Xóa bộ nhớ đệm.

//----------------------------------------------------------------------------GHI CÔNG-------------------------------------------------------------------------------//

// Credit - Ghi công:

// Các nội dung trong trang này không phải do mình viết nên mà sưu tầm lại từ các tình nguyện viên khác trên toàn bộ dự án Wikimedia. Xin chân thành cảm ơn tác giả của những công cụ hỗ trợ này.

// The content on this page is not written by me, and collected from other volunteers in the Wikimedia project. Many thanks to the authors of these support tools.

// Credit: Counter Vandalism (@Krinkle); Cat-A-Lot; Restorer (@BrandonXLF); SectionMover (@DannyS712); QuickEdit (@BrandonXLF); Todolist (@BrandonXLF); LinkReport (@NguoiDungKhongDinhDanh); AfD Closer (@NguoiDungKhongDinhDanh).

//---------------------------------------------------------------------------HẾT GHI CÔNG----------------------------------------------------------------------------//


//----------------------------------------------------------------------------MÃ NGUỒN-------------------------------------------------------------------------------//


/**
 * This is a collection of tools, scripts and small UI modications I find helpful in patrolling and fighting vandalism.
 * @source meta.wikimedia.org/wiki/User:Krinkle/Scripts/Countervandalism.js
 * @track [[File:Krinkle_Countervandalism.js]]
 */
(function () {
	// [[File:Krinkle_RTRC.js]]
	mw.loader.getState('ext.gadget.rtrc') ? mw.loader.load('ext.gadget.rtrc') : mw.loader.load('https://www.mediawiki.org/w/load.php?debug=false&modules=ext.gadget.rtrc&lang=' + mw.config.get('wgUserLanguage', 'en'));
	
	// [[File:Krinkle_WhatLeavesHere.js]]
	mw.loader.load('//meta.wikimedia.org/w/index.php?title=User:Krinkle/Tools/WhatLeavesHere.js&action=raw&ctype=text/javascript');

	// [[File:Krinkle_CVNSimpleOverlay_wiki.js]]
	mw.loader.load('//meta.wikimedia.org/w/index.php?title=User:Krinkle/Scripts/CVNSimpleOverlay_wiki.js&action=raw&ctype=text/javascript');

	mw.loader.using(['mediawiki.util', 'mediawiki.user'], function () {
		$(function () {
			// Clone .mw-contributions-footer to the top aswell
			if (mw.config.get('wgCanonicalSpecialPageName') === 'Contributions' && $('.mw-contributions-footer').length) {
				$('#contentSub').after($('.mw-contributions-footer').eq(0).clone());
			}

			// Extra links
			mw.util.addPortletLink('p-tb', mw.util.getUrl('Special:Prefixindex/' + mw.config.get('wgPageName')), 'Prefixindex', 'tb-prefixindex');
		});
	});

	/* Vector only */
	if (mw.config.get('skin') === 'vector') {
		/**
		 * Add "Purge" content action link.
		 *
		 * Dependencies: mediawiki.util, mediawiki.api
		 *
		 * @source https://www.mediawiki.org/wiki/Snippets/Purge_action
		 * @revision 2016-05-17
		 */
		$.when(mw.loader.using(['mediawiki.util', 'mediawiki.api']), $.ready).then(function () {
			if ($('#ca-purge').length) return;
			var node = mw.util.addPortletLink( 'p-cactions',
				mw.util.getUrl(null, { action: 'purge' }),
				'Purge',
				'ca-purge',
				'Purge the server cache of this page'
			);
			$(node).on('click', function (e) {
				var tag = 'snippet-purge-' + (++$.guid);
				mw.notify('Purging...', { tag: tag });
				new mw.Api().post({ action: 'purge', titles: mw.config.get('wgPageName'), forcelinkupdate: '1' }).then(function () {
					mw.notify('Purge completed.', { tag: tag });
					location.reload();
				}, function () {
					mw.notify('Purge failed.', { type: 'error', tag: tag });
				});
				e.preventDefault();
			});
		});
	}
}());

//<nowiki>
/* Cat-a-lot - changes category of multiple files */
mw.loader.using(['jquery.ui', 'mediawiki.util'], function(){
	mw.loader.load('//commons.wikimedia.org/w/load.php?modules=ext.gadget.Cat-a-lot');
});
////////// Cat-a-lot user preferences //////////
window.catALotPrefs = {"watchlist":"preferences","minor":true,"editpages":true,"docleanup":false,"subcatcount":10};
////////////////////////////////////catALotEnd//
//</nowiki>
// [[File:Krinkle_RTRC.js]]
(mw.loader.getState('ext.gadget.rtrc') ? mw.loader.load('ext.gadget.rtrc') : mw.loader.load('https://www.mediawiki.org/w/load.php?modules=ext.gadget.rtrc&lang=' + mw.config.get('wgUserLanguage', 'vi')));

/*** Restorer ***/

// Documentation at [[User:BrandonXLF/Restorer]]
// By [[User:BrandonXLF]]
// Dịch sang tiếng Việt bởi [[User: AzusaNyan]]

$(function() {
	if (mw.config.get('wgAction') != 'history') return;

	window.restorerSummary = window.restorerSummary || 'Lùi sửa về phiên bản $ID bởi [[Special:Contributions/$USER|$USER]] sử dụng [[En:User:BrandonXLF/Restorer|Restorer]]';

	function restore(user, revid) {
		return new mw.Api().postWithEditToken({
			action: 'edit',
			pageid: mw.config.get('wgArticleId'),
			undo: mw.config.get('wgCurRevisionId'),
			undoafter: revid,
			summary: window.restorerSummary.replace(/\$ID/g, revid).replace(/\$USER/g, user)
		}).then(
			function() {
				mw.notify('Lùi sửa thành công.');
				location.reload();
			},
			function(_, data) {
				mw.notify(new mw.Api().getErrorMessage(data), {type: 'error'});
			}
		);
	}

	function addLink(item) {
		var revid = item.getAttribute('data-mw-revid'),
			user,
			links,
			el,
			parent;

		if (revid == mw.config.get('wgCurRevisionId')) return;

		user = item.getElementsByClassName('mw-userlink')[0].textContent.replace('User:', '');
		links = item.getElementsByClassName('mw-changeslist-links');
		links = links[links.length - 1];
		parent = document.createElement('span');
		el = document.createElement('a');

		el.addEventListener('click', function() {
			el.className = 'restorer-loading';

			restore(user, revid).always(function() {
				el.className = '';
			});
		});

		el.innerHTML = 'lùi tự động';
		parent.appendChild(el);
		links.appendChild(parent);
	}

	var parents = document.querySelectorAll('li[data-mw-revid]');

	for (var i = 0; i < parents.length; i++) {
		addLink(parents[i]);
	}

	mw.loader.addStyleTag(
		'@keyframes restorer-loading {' +
		'0%, 100% {content: " ⡁"} 16% {content: " ⡈"} 33% {content: " ⠔"} 50% {content: " ⠒"} 66% {content: " ⠢"} 83% {content: " ⢁"}}' +
		'.restorer-loading::after {white-space: pre; content: ""; animation: restorer-loading 0.5s infinite}'
	);
});

// SectionMover
// Originaly by User:Flooded with them hundreds
// Copied to [[User:DannyS712/SectionMover.js]] after FWTH retired, who took over as maintainer

$.when( mw.loader.using(['mediawiki.util','mediawiki.api']), $.ready).done( function () {
	var validSections = {},
		fromTos = {},
		wikiText = '',
		revStamp, startMoveButton, overlay;

	if ( mw.config.get( 'wgNamespaceNumber' ) == -1 ) {
		// is a special page
		return;
	}
	$( 'head' ).append(
		'<style>a.arxylink { font-weight:bold } .arxyhighlight { background-color:#aef9fc }</style>'
	);

	startMoveButton = mw.util.addPortletLink(
		'p-cactions',
		'#',
		'Move section',
		'pt-oeca',
		'Enter/exit the process',
		null,
		null
	);
	overlay = $( document.createElement( 'button' ) );
	$( startMoveButton ).click( function ( e ) {
		$( '.arxylink' ).click();
		$( '.arxy' ).toggle();
		$( '#Movebutton' ).toggle();
	} );
	overlay.html( 'move' )
		.attr( 'id', 'Movebutton' )
		.css( 'position', 'fixed' )
		.css( 'bottom', '20px' )
		.css( 'height', '50px' )
		.css( 'width', '100%' )
		.css( 'font-size', '200%' );
	$( document.body ).append( overlay );
	overlay.toggle();
	overlay.click( function ( e ) {
		var numOfThreads, archiveTarget, sections, archiveThis, cutOffset,
			revisedPage;
		function cut( s, start, end ) {
			return s.substr( 0, start ) + s.substring( end );
		}
		cutOffset = numOfThreads = 0;
		revisedPage = wikiText;
		sections = $( 'a.arxylink' ).map( function () {
			return $( this ).attr( 'data-section' );
		} );
		if ( !( numOfThreads = sections.length ) ) {
			return alert( 'No sections selected, aborting' );
		}
		archiveTarget = prompt(
			'Moving' + numOfThreads + ' sections: where should we move them to?',
			mw.config.get( 'wgPageName' )
		);
		if ( !archiveTarget || archiveTarget == mw.config.get( 'wgPageName' ) ) {
			return alert( 'No target selected, aborting' );
		}
		sections.each( function ( i, n ) {
			revisedPage = cut(
				revisedPage,
				fromTos[ n ][ 0 ] - cutOffset,
				fromTos[ n ][ 1 ] - cutOffset
			);
			cutOffset += fromTos[ n ][ 1 ] - fromTos[ n ][ 0 ];
		} );
		archiveThis = sections.map( function () {
			return wikiText.substring( fromTos[ this ][ 0 ], fromTos[ this ][ 1 ] );
		} ).toArray().join( '' );
		console.log( 'archive this:' + archiveThis );
		console.log( 'revised page:' + revisedPage );
		if ( 1 ) {
			new mw.Api().postWithToken(
				'csrf',
				{
					action: 'edit',
					title: mw.config.get( 'wgPageName' ),
					text: revisedPage,
					summary: 'Chuyển phần mục đến [[' + archiveTarget + ']] sử dụng SectionMover',
					basetimestamp: revStamp,
					starttimestamp: revStamp
				}
			).done( function ( res1 ) {
				alert( 'Successfully moved sections from page' );
				console.log( res1 );
				new mw.Api().postWithToken(
					'csrf',
					{
						action: 'edit',
						title: archiveTarget,
						appendtext: '\n' + archiveThis,
						summary: 'Chuyển phần mục từ [[' + mw.config.get( 'wgPageName' ) + ']] sử dụng SectionMover'
					}
				).done( function ( res2 ) {
					alert( 'Successfully added sections to page' );
				} ).fail( function ( res2 ) {
					alert( 'failed to add sections to page. manual inspection needed.' );
				} ).always( function ( res2 ) {
					console.log( res2 );
					window.location.reload();
				} );
			} ).fail( function ( res1 ) {
					alert( 'failed to move sections from page. aborting process.' );
					console.log( res1 );
					window.location.reload();
				} );
		}
	} );
	new mw.Api().get( {
		action: 'parse',
		page: mw.config.get( 'wgPageName' )
	} ).done( function ( dataShit ) {
			var i;
			new mw.Api().get( {
				action: 'query',
				pageids: mw.config.get( 'wgArticleId' ),
				prop: [ 'revisions' ],
				rvprop: [ 'content', 'timestamp' ]
			} ).done( function ( shit ) {
				var rv;
				rv = shit.query.pages[ mw.config.get( 'wgArticleId' ) ].revisions[ 0 ];
				wikiText = rv[ '*' ];
				revStamp = rv.timestamp;
			} );
			$( dataShit.parse.sections )
				.filter( function ( i, s ) { return s.index == parseInt( s.index ) } )
				.each( function ( i, s ) { validSections[ s.index ] = s } );
			for ( i in validSections ) {
				i = parseInt( i );
				fromTos[ i ] = [
					validSections[ i ].byteoffset,
					validSections.hasOwnProperty( i + 1 ) ? validSections[ i + 1 ].byteoffset : Infinity
				];
			}
			$( '#mw-content-text' )
				.find( ':header' )
				.find( 'span.mw-headline' )
				.each( function ( i, title ) {
					var header, editSection, sectionNumber;
					header = $( this ).parent();
					editSection = header.find( '.mw-editsection' ); // 1st child
					sectionNumber = header.find( '.mw-editsection a:first' );
					if ( sectionNumber[ 0 ] ) {
						sectionNumber = sectionNumber.attr( 'href' ).match( /&section=(\d+)/ );
						if ( sectionNumber ) {
							sectionNumber = sectionNumber[ 1 ];
						} else {
							// eg <h2>not a real section</h2>
							sectionNumber = undefined;
						}
					}
					if ( validSections.hasOwnProperty( sectionNumber ) ) {
						editSection[ 0 ].innerHTML += '&nbsp;'
							+ '<span class=arxy style=display:none>'
							+ '<span class=mw-editsection-bracket>[</span>'
							+ '<a data-section=' + sectionNumber + ' '
							+ 'onclick=$(this).closest(\':header\').toggleClass(\'arxyhighlight\');$(this).toggleClass(\'arxylink\');>'
							+ 'move section</a>'
							+ '<span class=mw-editsection-bracket>]</span>'
							+ '</span>';
					}
				} );
		} );
} );

/** Quick Edit **/

// [[User:BrandonXLF/QuickEdit]]
// By [[User:BrandonXLF]]

(function() {
	var mobile = mw.config.get('skin') === 'minerva',
		apiSingleton,
		titleRegexp = new RegExp(
			mw.config.get('wgArticlePath').replace(/[.*+?^${}()|[\]\\]/g, '\\$&').replace(/\\\$1/, '([^?]+)') +
			'|[?&]title=([^&#]*)'
		);

	function api(func, params) {
		if (!apiSingleton) apiSingleton = new mw.Api();

		$.extend(params, {
			errorformat: 'html',
			errorlang: mw.config.get('wgUserLanguage'),
			errorsuselocal: true
		});

		return apiSingleton[func](params).fail(function(_, data) {
			mw.notify(apiSingleton.getErrorMessage(data), {
				type: 'error',
				tag: 'quickedit'
			});
		});
	}

	function getPageInfo(title, sectionID) {
		return api('get', {
			action: 'query',
			curtimestamp: 1,
			prop: 'revisions',
			indexpageids: 1,
			titles: title,
			rvprop: ['timestamp', 'content'],
			rvslots: 'main',
			rvsection: sectionID
		}).then(function(res) {
			var rev = res.query.pages[res.query.pageids[0]].revisions[0];

			return {
				start: res.curtimestamp,
				base: rev.timestamp,
				full: rev.slots.main['*']
			};
		});
	}

	function getPreviewCallback(editor) {
		editor.children('.preview').remove();

		new OO.ui.ProgressBarWidget().$element.css({
			maxWidth: '100%',
			borderRadius: '0',
			boxShadow: 'none',
			margin: '8px 0'
		}).addClass('preview').appendTo(editor);

		return function(html) {
			editor.children('.preview').remove();

			$('<div>').html(html).css({
				margin: '8px 0',
				border: '1px solid #a2a9b1',
				padding: '8px',
				overflowX: 'hidden'
			}).addClass('preview').appendTo(editor);
		};
	}

	function showCompare(editor, title, from, to) {
		mw.loader.load('mediawiki.diff.styles');

		api('post', {
			action: 'compare',
			fromslots: 'main',
			'fromtext-main': from,
			fromtitle: title,
			frompst: 'true',
			toslots: 'main',
			'totext-main': to,
			totitle: title,
			topst: 'true'
		}).then(function(r) {
			return r.compare['*'] ? $('<table>').addClass('diff').append(
				$('<colgroup>').append(
					$('<col>').addClass('diff-marker'),
					$('<col>').addClass('diff-content'),
					$('<col>').addClass('diff-marker'),
					$('<col>').addClass('diff-content')
				)
			).append(r.compare['*']) : 'No differences.';
		}).then(getPreviewCallback(editor));
	}

	// Parts taken from EditPage::extractSectionTitle and Parser::stripSectionName
	function getSectionSummary(text) {
		var match = text.match(/^(=+)(.+)\1\s*(\n|$)/);

		return !match ? '' : '/* ' + match[2].trim()
			// Strip internal link markup
			.replace(/\[\[:?([^[|]+)\|([^[]+)\]\]/g, '$2')
			.replace(/\[\[:?([^[]+)\|?\]\]/g, '$1')
			// Strip external link markup
			.replace(new RegExp('\\[(?:' + mw.config.get('wgUrlProtocols') + ')([^ ]+?) ([^\\[]+)\\]', 'ig'), '$2')
			// Remove wikitext quotes
			.replace(/(''|'''|''''')(?!')/g, '')
			// Strip HTML tags
			.replace(/<[^>]+?>/g, '') + ' */ ';
	}

	function showEditor(el) {
		var progress = new OO.ui.ProgressBarWidget(),
			heading = el.closest(':header'),
			matcher = heading.nextUntil.bind(heading),
			inserter = heading.after.bind(heading),
			targetEl = el.siblings('.quickedit-target').last(),
			titleMatch = targetEl.attr('href').match(titleRegexp),
			title = decodeURIComponent(titleMatch[1] || titleMatch[2]),
			sectionID = /[?&]v?e?section=T?-?(\d*)/.exec(targetEl.attr('href'))[1];

		if (!heading.closest('.mw-parser-output').length) {
			var articleContent = $('#mw-content-text .mw-parser-output');

			matcher = function(selector) {
				var child = articleContent.children(selector).first();

				if (child.length) return child.prevAll();
				return articleContent.children();
			};
			inserter = articleContent.prepend.bind(articleContent);
		}

		inserter(progress.$element.css({
			maxWidth: '100%',
			borderRadius: '0',
			boxShadow: 'none'
		}));

		el.addClass('quickedit-loading');
		$('.quickedit-hide').removeClass('quickedit-hide');
		$('.quickedit-heading').removeClass('quickedit-heading');
		$('#quickedit-editor').remove();

		getPageInfo(title, sectionID).then(function(r) {
			var start = r.start,
				base = r.base,
				full = r.full,
				saving = false,
				expanded = false,
				remainderStart = full.match(/\n=+.+=+(?:\n|$)/),
				part =  remainderStart ? full.substring(0, remainderStart.index) : full,
				remainder = remainderStart ? full.substring(remainderStart.index) : '',
				level = 0,
				editor;

			full.replace(/^(=+).+?(=+)(?:\n|$)/, function(m, a, b) {
				level = Math.min(a.length, b.length);
				return m;
			});

			var levelMatch = 'h1';
			for (var i = 2; i <= level; i++) levelMatch += ',h' + i + ':has(*)';

			var partSection = matcher(':header:has(*)'),
				fullSection = matcher(levelMatch),
				textarea = new OO.ui.MultilineTextInputWidget({
					rows: 1,
					maxRows: 20,
					autosize: true,
					value: part
				}),
				summary = new OO.ui.TextInputWidget({
					value: getSectionSummary(part)
				}),
				minor = new OO.ui.CheckboxInputWidget(),
				save = new OO.ui.ButtonInputWidget({
					label: 'Save',
					title: 'Save your changes',
					flags: ['primary', 'progressive']
				}),
				preview = new OO.ui.ButtonInputWidget({
					label: 'Preview',
					title: 'Preview the new wikitext'
				}),
				compare = new OO.ui.ButtonInputWidget({
					label: 'Compare',
					title: 'View the difference between the current revision and your revision'
				}),
				cancel = new OO.ui.ButtonInputWidget({
					useInputTag: true,
					label: 'Cancel',
					title: 'Close the edit form and discard changes',
					flags: ['secondary', 'destructive']
				}),
				more = new OO.ui.ButtonInputWidget({
					label: '+',
					title: 'Edit the entire section (including subsections)'
				}),
				buttons = new OO.ui.HorizontalLayout({
					items: [save, preview, compare, cancel]
				});

			if (part != full) {
				buttons.addItems([more], 3);
			}

			partSection.addClass('quickedit-hide');
			heading.addClass('quickedit-heading');
			el.removeClass('quickedit-loading');
			progress.$element.remove();
			textarea.$input.css({
				borderRadius: '0'
			});

			summary.on('enter', function() {
				save.emit('click');
			});

			save.on('click', function() {
				if (saving) return;

				var fullText = textarea.getValue() + (expanded ? '' : remainder);
				saving = true;
				save.setLabel('Saving...');
				compare.setDisabled(true);
				preview.setDisabled(true);
				cancel.setDisabled(true);
				more.setDisabled(true);

				api('postWithEditToken', {
					action: 'edit',
					title: title,
					section: sectionID,
					summary: summary.getValue(),
					text: fullText,
					minor: minor.isSelected() ? true : undefined,
					notminor: minor.isSelected() ? undefined : true,
					starttimestamp: start,
					basetimestamp: base
				}).then(function() {
					api('get', {
						action: 'parse',
						page: mw.config.get('wgPageName'),
						prop: ['text', 'categorieshtml']
					}).then(function(r) {
						var contentText = $('#mw-content-text'),
							catLinks = $('#catlinks');

						contentText.find('.mw-parser-output').replaceWith(r.parse.text['*']);
						mw.hook('wikipage.content').fire(contentText);

						catLinks.replaceWith(r.parse.categorieshtml['*']);
						mw.hook('wikipage.categories').fire(catLinks);

						saving = false;
					});
				}, function(code) {
					if (code == 'editconflict') {
						showEditConflict(editor, title, sectionID, fullText).then(function(r) {
							start = r.start;
							base = r.base;
							textarea = r.textarea;
							expanded = true;
						});
					}

					compare.setDisabled(false);
					preview.setDisabled(false);
					cancel.setDisabled(false);
					more.setDisabled(expanded);
					saving = false;
					save.setLabel('Save');
				});
			});

			preview.on('click', function() {
				api('post', {
					action: 'parse',
					title: title,
					prop: 'text',
					pst: 'true',
					disablelimitreport: 'true',
					disableeditsection: 'true',
					sectionpreview: 'true',
					disabletoc: 'true',
					text: textarea.getValue()
				}).then(function(r) {
					return r.parse.text['*'] + '<div style="clear:both;"></div>';
				}).then(getPreviewCallback(editor));
			});

			compare.on('click', function() {
				showCompare(editor, title, part + (expanded ? remainder : ''), textarea.getValue());
			});

			cancel.on('click', function() {
				editor.remove();
				heading.removeClass('quickedit-heading');
				fullSection.removeClass('quickedit-hide');
			});

			more.on('click', function() {
				expanded = true;
				textarea.setValue(textarea.getValue() + remainder);
				fullSection.addClass('quickedit-hide');
				more.setDisabled(true);
			});

			editor = $('<div id="quickedit-editor">').css({
				overflowX: 'hidden'
			}).append(
				$('<div>').css({
					backgroundColor: '#eaecf0',
					borderBottom: '1px solid #a2a9b1',
					marginBottom: '8px'
				}).append(
					textarea.$element.css({
						width: '100%',
						maxWidth: '100%',
						fontFamily: 'monospace, monospace'
					}).addClass('quickedit-textarea'),
					$('<div>').css({
						border: '1px solid #a2a9b1',
						borderWidth: '0 1px'
					}).append(
						$('<div>').css({
							padding: '8px 4px 8px 8px',
							display: 'table-cell',
							verticalAlign: 'middle'
						}).html('Edit&nbsp;summary:'),
						summary.$element.css({
							width: '100%',
							maxWidth: '100%',
							padding: '8px 0px',
							display: 'table-cell',
							verticalAlign: 'middle'
						}),
						new OO.ui.FieldLayout(minor, {
							label: new OO.ui.HtmlSnippet('Minor&nbsp;edit?'),
							align: 'inline'
						}).$element.css({
							padding: '8px 8px 8px 4px',
							display: 'table-cell',
							verticalAlign: 'middle'
						})
					),
					buttons.$element.css({
						border: '1px solid #a2a9b1',
						borderWidth: '0 1px',
						padding: '0px 8px 0'
					}),
					title !== mw.config.get('wgPageName') ? $('<div>').css({
						border: '1px solid #a2a9b1',
						borderWidth: '0 1px',
						padding: '0px 8px 8px'
					}).append(
						'Editing page: ',
						$('<a>').attr('href', mw.config.get('wgArticlePath').replace('$1', title)).css({
							fontWeight: 'bold'
						}).text(title.replace(/_/g, ' '))
					) : undefined
				)
			);

			inserter(editor);
		}, function() {
			el.removeClass('quickedit-loading');
			progress.$element.remove();
		});
	}

	function showEditConflict(editor, title, sectionID, text) {
		return getPageInfo(title, sectionID).then(function(r) {
			var textarea = new OO.ui.MultilineTextInputWidget({
					rows: 1,
					maxRows: 20,
					autosize: true,
					value: r.full
				}),
				textarea2 = new OO.ui.MultilineTextInputWidget({
					rows: 1,
					maxRows: 20,
					autosize: true,
					value: text,
				});

			function syncSize() {
				textarea.styleHeight = -1;
				textarea.adjustSize(true);

				textarea2.styleHeight = -1;
				textarea2.adjustSize(true);

				var height = Math.max(textarea.$input.height(), textarea2.$input.height());
				textarea.$input.height(height);
				textarea2.$input.height(height);
			}

			textarea.$input.css({
				borderRadius: '0'
			});
			editor.find('> :first-child > :first-child').remove();

			$('<table>').css({
				width: '100%',
				border: '1px solid #a2a9b1',
				borderBottom: 'none',
				borderSpacing: '0',
				margin: '0 !important'
			}).append(
				$('<tr>').append(
					$('<th>').css({
						width: '50%',
						paddingTop: '4px'
					}).text('Their version (to be saved)'),
					$('<th>').css({
						width: '50%',
						paddingTop: '4px'
					}).text('Your version')
				),
				$('<tr>').append(
					$('<td>').css({
						width: '50%',
						padding: '4px 4px 0 8px'
					}).append(
						textarea.$element.css({
							width: '100%',
							maxWidth: '100%',
							fontFamily: 'monospace, monospace'
						})
					),
					$('<td>').css({
						width: '50%',
						padding: '4px 8px 0 4px'
					}).append(
						textarea2.$element.css({
							width: '100%',
							maxWidth: '100%',
							fontFamily: 'monospace, monospace'
						})
					)
				)
			).prependTo(editor.find('> :first-child'));

			textarea.on('change', syncSize);
			textarea2.on('change', syncSize);
			syncSize();
			showCompare(editor, title, text, r.full);

			r.textarea = textarea;
			return r;
		});
	}

	function clickHandler(e) {
		var el = $(e.target);

		if (!el.hasClass('quickedit-editlink') || el.hasClass('quickedit-loading')) return;

		e.preventDefault();

		showEditor(el);
	}

	function addLinksToChildren(element) {
		element.find('#quickedit-editor, .quickedit-section').remove();
		element.find('.mw-editsection').each(function() {
			$('[href*="section="]', this).last().after(
				mobile ? '' : '<span class="quickedit-section"> | </span>',
				$('<a>').html(mobile ? '&nbsp;Q' : 'quick edit').addClass('quickedit-section quickedit-editlink')
			).addClass('quickedit-target');
		});
	}

	$.when(mw.loader.using('oojs-ui-core'), $.ready).done(function() {
		var body = $(document.body);

		body.on('click', clickHandler);
		addLinksToChildren(body);
		mw.hook('wikipage.content').add(addLinksToChildren);
	});

	mw.loader.addStyleTag(
		'.skin-minerva .mw-editsection { white-space: nowrap; }' +
		'.skin-minerva .content .collapsible-heading .quickedit-section { visibility: hidden; }' +
		'.skin-minerva .content .collapsible-heading.open-block .quickedit-section { visibility: visible; }' +
		'.quickedit-hide { display: none !important; }' +
		'.quickedit-loading, .quickedit-heading { color: #777; }'
	);
})();

/*** Todo List ***/

// Documentation at [[User:BrandonXLF/TodoList]]
// By [[User:BrandonXLF]]

$.when(mw.loader.using([
	'mediawiki.user',
	'oojs-ui-core',
	'oojs-ui-windows',
	'oojs-ui.styles.icons-movement',
	'oojs-ui.styles.icons-editing-core',
	'oojs-ui.styles.icons-interactions',
	'oojs-ui.styles.icons-moderation',
	'oojs-ui.styles.icons-content'
]), $.ready).then(function() {
	var messages = function() {
		var translations = {
			en: {
				todoPortlet: 'Todo',
				todoHover: 'Click to see your todo list',
				saving: 'Saving changes...',
				drag: 'Drag',
				delete: 'Delete',
				edit: 'Edit',
				pageNameUrl: 'Page name or URL',
				comment: 'Comment',
				save: 'Save',
				cancel: 'Cancel',
				moreinfo: 'More information',
				undo: 'Undo',
				redo: 'Redo',
				clear: 'Clear',
				clearConfirm: 'Are you sure you want to clear your todo list?',
				download: 'Download',
				upload: 'Upload',
				help: 'Help',
				add: 'Add',
				close: 'Close',
				yourList: 'Your todo list',
				noPopup: 'Unable to open todo list popup while on the todo list page.',
				addedTime: 'Added: $dateDate $dateMonth, $dateYear at $dateHours:$dateMinutes'
			},
			nb: {
				todoPortlet: 'Huskeliste',
				todoHover: 'Klikk for å se huskelista di',
				saving: 'Lagrer endringer …',
				drag: 'Dra',
				delete: 'Slett',
				edit: 'Rediger',
				pageNameUrl: 'Sidenavn eller URL',
				comment: 'Merknad',
				save: 'Lagre',
				cancel: 'Avbryt',
				moreinfo: 'Mer informasjon',
				undo: 'Angre',
				redo: 'Angre angring',
				clear: 'Tøm',
				clearConfirm: 'Er du sikker på at du vil tømme huskelista di?',
				download: 'Last ned',
				upload: 'Last opp',
				help: 'Hjelp',
				add: 'Legg til',
				close: 'Lukk',
				yourList: 'Huskelista di',
				noPopup: 'Kan ikke åpne oppsprettsboksen med huskelista mens du er på huskelistesiden.',
				addedTime: 'Lagt til: $dateDate. $dateMonth $dateYear kl. $dateHours.$dateMinutes'
			},
			nn: {
				todoPortlet: 'Hugseliste',
				todoHover: 'Klikk for å sjå hugselista di',
				saving: 'Lagrar endringar …',
				drag: 'Dra',
				delete: 'Slett',
				edit: 'Endre',
				pageNameUrl: 'Sidenamn eller URL',
				comment: 'Merknad',
				save: 'Lagre',
				cancel: 'Avbryt',
				moreinfo: 'Meir informasjon',
				undo: 'Angre',
				redo: 'Angre angring',
				clear: 'Tøm',
				clearConfirm: 'Er du sikker på at du vil tømme hugselista di?',
				download: 'Last ned',
				upload: 'Last opp',
				help: 'Hjelp',
				add: 'Legg til',
				close: 'Lukk',
				yourList: 'Hugselista di',
				noPopup: 'Kan ikkje opna oppsprettsboksen med hugselista mens du er på hugselistesida.',
				addedTime: 'Lagt til: $dateDate. $dateMonth $dateYear kl. $dateHours.$dateMinutes'
			}
		},
			chain = mw.language.getFallbackLanguageChain(),
			len = chain.length,
			ret = {},
			i = len - 1;
		while ( i >= 0 ) {
			if ( translations.hasOwnProperty( chain[ i ] ) ) {
      	$.extend( ret, translations[ chain[ i ] ] );
    	}
    	i = i - 1;
  	}
		return ret;
	}();
	
	mw.util.addCSS(
		'.userjs-todo-list .item:hover .act { visibility: visible !important; }' +
		'[data-drop="above"]::before { display: block; border-top: 2px solid #066; margin-top: -2px; content: ""; }' +
		'[data-drop="below"]::after { display: block; border-top: 2px solid #066; margin-top: -2px; content: ""; }' +
		'.userjs-todo-list .items:empty { border: none !important; margin: 0 !important; padding: 0 !important;}' +
		'.userjs-todo-moreinfo > a { min-width: unset !important; min-height: unset !important; padding: 0.65em !important; }' +
		'.userjs-todo-moreinfo > a > span { min-width: unset !important; min-height: unset !important; width: 1.3em !important; left: 0 !important; }'
	);

	if (mw.config.get('skin') === 'minerva') {
		mw.util.addCSS(
			'.userjs-todo-list .item .act { visibility: visible !important; }' +
			'#userjs-todo-popup { top: 0 !important; bottom: 0 !important; left: 0 !important; right: 0 !important; width: 100%; height: 100%; }' +
			'#userjs-todo-popup .userjs-todo-list { width: 100%; height: 100%; } '
		);
	}

	var api = new mw.Api(),
		link = $(mw.util.addPortletLink(
			'p-personal',
			mw.util.getUrl('Special:BlankPage/todo'),
			messages.todoPortlet,
			'userjs-todo',
			messages.todoHover,
			'd',
			'#pt-preferences')
		),
		changes = [mw.user.options.get('userjs-todo-script')],
		undo = 0,
		req = 0,
		parent,
		ispopup = false,
		loader = $('<input type="file" accept=".json" style="display:none;">').on('change', function() {
			if (!this.files || !this.files[0]) return;
			var file = this.files[0],
				reader = new FileReader();
			reader.onload = function() {
				save(reader.result, true, true);
			};
			reader.readAsText(file);
		}).appendTo(document.body);

	$(window).on('beforeunload', function() {
		if (req > 0) return true;
	});

	function save(what, record, relist) {
		if (typeof what != 'string') {
			what = JSON.stringify(what);
		}

		mw.user.options.set('userjs-todo-script', what);
		req++;
		parent.find('.status').text( messages.saving );

		api.saveOption('userjs-todo-script', what).done(function() {
			req--;
			if (req === 0) {
				parent.find('.status').text('');
			}
		});

		if (record !== false) {
			while (undo > 0) {
				changes.pop();
				undo--;
			}

			changes.push(mw.user.options.get('userjs-todo-script'));

			if (changes.length > 50) changes.shift();
		}

		if (relist) {
			list();

			if (req > 0) {
				parent.find('.status').text( messages.saving );
			}
		}
	}

	Math.clamp = function(max, x, min) {
		return Math.min(max, Math.max(min, x));
	};

	function item(parent, array) {
		var date = new Date(+array[2]),
			url = array[0] || '',
			txt = array[0] || '';

		if (url.match(/^(https:|http:|:)\/\//) && url.match(/ /)) {
			var reg = /(.*?) (.*)/.exec(url);
			url = reg[1];
			txt = reg[2];
		} else if (!url.match(/^(https:|http:|:)\/\//)) {
			url = mw.util.getUrl(url);
		}

		parent.append($('<div class="item" style="margin:5px 0;white-space:nowrap;"></div>')
			.attr('data-page', array[0] || '')
			.attr('data-info', array[1] || '')
			.attr('data-date', array[2] || '')
			.append((new OO.ui.IconWidget({icon: 'draggable', title: messages.drag })).$element
				.css({cursor: 'move', height: '1.2em', width: '1.2em', minWidth: 'unset', minHeight: 'unset', marginRight: '0.5em'})
				.on('mousedown', function() {
					$(this).parent().attr('draggable', 'true');
				})
				.on('mouseup', function() {
					$(this).parent().attr('draggable', 'false');
				})
			)
			.append($('<a>').addClass('page').attr('href', url).text(txt))
			.append(array[0] && array[1] ? ' . . ' : '')
			.append($('<span>').addClass('info').text(array[1] || ''))
			.append(array[0] || array[1] ? '<span class="act" style="visibility:hidden;"> . . </span>' : '')
			.append((new OO.ui.IconWidget({icon: 'trash', title: messages.delete, flags: ['destructive']})).$element
				.css({cursor: 'pointer', visibility: 'hidden', height: '1.1em', width: '1.1em', minWidth: 'unset', minHeight: 'unset', marginRight: '0.5em'})
				.addClass('act')
				.click(function() {
					var arr = [];
					$(this).parent().siblings().each(function() {
						arr.push([$(this).attr('data-page'), $(this).attr('data-info'), $(this).attr('data-date')]);
					});
					$(this).parent().remove();
					save(arr);
				})
			)
			.append((new OO.ui.IconWidget({icon: 'edit', title: messages.edit, flags: ['progressive']})).$element
				.css({cursor: 'pointer', visibility: 'hidden', height: '1em', width: '1em', minWidth: 'unset', minHeight: 'unset', marginRight: '0.5em'})
				.addClass('act edit')
				.click(function() {
					$(this).css('display', 'none');
					$('<div style="border:1px solid #a2a9b1;padding:0 4px;margin:0.5em 0;border-radius:4px;"></div>')
						.append((new OO.ui.TextInputWidget({
							placeholder: messages.pageNameUrl,
							classes: [ 'todo-pageNameUrl' ],
							value: $(this).parent().attr('data-page')
						})).$element.css({maxWidth: 'unset', margin: '4px 0'}))
						.append((new OO.ui.TextInputWidget({
							placeholder: messages.comment,
							classes: [ 'todo-comment' ],
							value: $(this).parent().attr('data-info')
						})).$element.css({maxWidth: 'unset', margin: '4px 0'}))
						.append($('<table style="width:100%;border-spacing:0;margin-bottom:0.5em;"></table>').append($('<tr></tr>')
							.append($('<td style="width:50%;padding-right:4px;"></td>').append((new OO.ui.ButtonWidget({
								label: messages.save,
								flags: ['progressive']
							}).$element.css('width', '100%').children().css('width', '100%').parent()).click(function() {
								var editbox = $(this).parent().parent().parent().parent(),
									listitem = editbox.parent();
								listitem.find('.page').text(editbox.find('.todo-pageNameUrl input').val());
								listitem.attr('data-page', editbox.find('.todo-pageNameUrl input').val());
								listitem.find('.info').text(editbox.find('.todo-comment input').val());
								if (listitem.find('.info')[0].previousSibling.nodeType != 3 && editbox.find('.todo-comment input').val() !== '') {
									listitem.find('.info').before(' . . ');
								} else if (
									listitem.find('.info')[0].previousSibling.nodeType == 3 &&
									editbox.find('.todo-comment input').val() === ''
								) {
									$(listitem.find('.info')[0].previousSibling).remove();
								}
								listitem.attr('data-info', editbox.find('.todo-comment input').val());
								var arr = [];
								listitem.parent().children().each(function() {
									arr.push([$(this).attr('data-page'), $(this).attr('data-info'), $(this).attr('data-date')]);
								});
								save(arr);
								link.find('.redo').remove();
								listitem.find('.edit').css('display', 'inline-block');
								editbox.remove();
							})
							))
							.append($('<td style="width:50%;padding-left:4px;"></td>').append((new OO.ui.ButtonWidget({
								label: messages.cancel,
								flags: ['destructive']
							}).$element.css('width', '100%').children().css('width', '100%').parent()).click(function() {
								var editbox = $(this).parent().parent().parent().parent(),
									listitem = editbox.parent();
								listitem.find('.edit').css('display', 'inline-block');
								editbox.remove();
							})
							))
						)).appendTo(this.parentNode);
				})
			)
			.append(array[2] ? (new OO.ui.PopupButtonWidget({
				icon: 'info',
				framed: false,
				label: messages.moreinfo,
				invisibleLabel: true,
				title: messages.moreinfo,
				popup: {
					$content: $('<p></p>').text( messages.addedTime
					 	.replace( '$dateDate', date.getDate() )
						.replace( '$dateMonth', mw.config.get('wgMonthNames')[date.getMonth() + 1] )
						.replace( '$dateYear', date.getFullYear() )
						.replace( '$dateHours', date.getHours() )
						.replace( '$dateMinutes', ('' + date.getMinutes()).padStart(2, '0') )
					),
					padded: true,
					align: 'forwards'
				}
			})).$element
				.addClass('userjs-todo-moreinfo')
				.css({cursor: 'pointer', visibility: 'hidden', height: '1.3em', width: '1.3em', minWidth: 'unset', minHeight: 'unset', marginRight: '0.5em'})
				.addClass('act') : ''
			)
			.on('dragover', function(e) {
				e.preventDefault();
				e.dataTransfer = e.originalEvent.dataTransfer;
				if (e.offsetY < ($(this).height()/2)) {
					this.setAttribute('data-drop', 'above');
				} else {
					this.setAttribute('data-drop', 'below');
				}
			})
			.on('dragleave', function() {
				this.setAttribute('data-drop', '');
			})
			.on('drop', function(e) {
				e.dataTransfer = e.originalEvent.dataTransfer;
				this.setAttribute('data-drop', '');
				var ele = $('[data-dragid="' + e.dataTransfer.getData('text/plain') + '"]')[0];
				if (e.offsetY < ($(this).height()/2)) {
					this.insertAdjacentElement('beforebegin', ele);
				} else {
					this.insertAdjacentElement('afterend', ele);
				}
				var arr = [];
				$(this).parent().children().each(function() {
					arr.push([$(this).attr('data-page'), $(this).attr('data-info'), $(this).attr('data-date') || '']);
				});
				save(arr);
			})
			.on('dragstart', function(e) {
				e.dataTransfer = e.originalEvent.dataTransfer;
				var uid = ('' + Math.random()).replace('.', '');
				$(this).attr('data-dragid', uid);
				e.dataTransfer.setData('text/plain', uid);
			})
		);
	}

	function list() {
		$('.userjs-todo-list').remove();
		var todo = parent.append($('<div class="userjs-todo-list" style="overflow:auto;"></div>')
			.append($('<div style="padding:0.5em;" class="todo-menu"></div>')
				.append(new OO.ui.ButtonWidget({
					framed: false,
					icon: 'undo',
					invisibleLabel: true,
					title: messages.undo
				}).$element.click(function() {
					if (changes[changes.length-undo-2] !== undefined) {
						save(changes[changes.length-undo-2], false, true);
						undo++;
					}
				}))
				.append(new OO.ui.ButtonWidget({
					framed: false,
					icon: 'redo',
					invisibleLabel: true,
					title: messages.redo
				}).$element.click(function() {
					if (changes[changes.length-undo] !== undefined) {
						save(changes[changes.length-undo], false, true);
						undo--;
					}
				}))
				.append(new OO.ui.ButtonWidget({
					framed: false,
					icon: 'trash',
					invisibleLabel: true,
					title: messages.clear
				}).$element.click(function() {
					OO.ui.confirm( messages.clearConfirm ).done(function(confirmed) {
						if (confirmed) {
							parent.find('.items').empty();
							save('', true, true);
						}
					});
				}))
				.append(new OO.ui.ButtonWidget({
					framed: false,
					icon: 'download',
					invisibleLabel: true,
					title: messages.download
				}).$element.click(function() {
					$($('<a download="todo.json" style="display:none;"></a>')
						.attr('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(mw.user.options.get('userjs-todo-script')))
						.appendTo(document.body)[0].click()
					).remove();
				}))
				.append(new OO.ui.ButtonWidget({
					framed: false,
					icon: 'upload',
					invisibleLabel: true,
					title: messages.upload
				}).$element.click(function() {
					loader.click();
				}))
				.append(new OO.ui.ButtonWidget({
					framed: false,
					icon: 'info',
					invisibleLabel: true,
					title: messages.help
				}).$element.click(function() {
					window.open('https://en.wikipedia.org/wiki/User:BrandonXLF/TodoList/Help');
				}))
			)
			.append($('<div style="padding:0 0.5em 0.5em;"></div>')
				.append((new OO.ui.TextInputWidget({
					placeholder: messages.pageNameUrl,
					classes: [ 'todo-pageNameUrl' ],
					value: mw.config.get('wgPageName').replace(/_/g, ' ') != 'Special:BlankPage/todo' ? mw.config.get('wgPageName').replace(/_/g, ' ') : ''
				})).$element.css({maxWidth: 'unset', margin: '4px 0'}))
				.append((new OO.ui.TextInputWidget({
					placeholder: messages.comment,
					classes: [ 'todo-comment' ]
				})).$element.css({maxWidth: 'unset', margin: '4px 0'}))
				.append((new OO.ui.ButtonWidget({
					label: messages.add
				}).$element.css('width', '100%').children().css('width', '100%').parent()).click(function() {
					var opts = JSON.parse(mw.user.options.get('userjs-todo-script') || '[]'),
						arr = [];

					arr.push($(this).parent().parent().find('.todo-pageNameUrl input').val());
					arr.push($(this).parent().parent().find('.todo-comment input').val());

					if (!arr.join('')) return;

					arr.push((new Date()).getTime());
					item($('.userjs-todo-list .items'), arr);
					opts.push(arr);
					save(opts);

					$('#userjs-todo-popup').css({top: Math.max(parseInt($('#userjs-todo-popup').css('top')), 0)});
				}))
			)
			.append($('<div class="items" style="margin:0.5em;padding-top:0.5em;border-top:1px solid #a2a9b1;"></div>'))
			.append('<div class="status" style="padding:0 0.5em 0.5em;"></div>')
		);
		if (ispopup) {
			todo.find('.todo-menu')
				.css('cursor', 'grab')
				.append((new OO.ui.ButtonWidget({
					framed: false,
					icon: 'close',
					invisibleLabel: true,
					title: messages.close
				}).$element.css({float: 'right', marginRight: '0'}).click(function() {
					parent.remove();
				})))
				.append(($('<a></a>').attr('href', mw.util.getUrl('Special:BlankPage/todo')).append((new OO.ui.ButtonWidget({
					framed: false,
					icon: 'newWindow',
					invisibleLabel: true,
					title: messages.yourList
				}).$element.css('float', 'right').click(function() {
					location.url = mw.util.getUrl('Special:BlankPage/todo');
				})))))
				.on('mousedown', function(e) {
					if (e.target !== this) return;
					this.style.cursor = 'grabbing';
					var x = parent.position().left - e.pageX,
						y = parent.position().top - e.pageY,
						b = $(document.body);
					function move(e) {
						parent.css({
							left: Math.clamp($(window).width() - parent.width(), e.pageX + x, 0) + 'px',
							top: Math.clamp($(window).height() - parent.height(), e.pageY +	y, 0) + 'px',
							right: '',
							bottom: ''
						});
					}
					function up() {
						e.target.style.cursor = 'grab';
						b.off('mousemove', move);
						b.off('mouseup', up);
					}
					b.on('mousemove', move);
					b.on('mouseup', up);
				});
		}

		$.each(JSON.parse(mw.user.options.get('userjs-todo-script') || '[]'), function(a, b) {
			item(todo.find('.items'), b);
		});

		return todo;
	}

	function repos(pos, css, pvar, cond, pcss, ccss) {
		return $('<div style="pointer-events:all;position:absolute;"></div>').attr('id', pos + 'gfdgfdgfd').css('cursor', pos + '-resize').css(css).on('mousedown', function(e) {
			if (e.target !== this) return;

			var p = parent,
				c = p.find('.userjs-todo-list'),
				q = eval(pvar),
				b = $(document.body);

			b.css('user-select', 'none');

			function move(e) {
				if (eval(cond)) return;
				(new Function('e', 'p', 'q', 'p.css(' + pcss + ')'))(e, p, q);
				(new Function('e', 'c', 'q', 'c.css(' + ccss + ')'))(e, c, q);
			}

			function up() {
				b.css('user-select', '');
				b.off('mousemove', move);
				b.off('mouseup', up);
			}

			b.on('mousemove', move);
			b.on('mouseup', up);
		});
	}

	if ( ( mw.config.get( 'wgCanonicalSpecialPageName' ) === 'Blankpage' ) && ( mw.config.get('wgPageName').split('/').pop() === 'todo' ) ) {
		document.title = messages.yourList + ' – ' + mw.config.get('wgSiteName');
		$('#firstHeading').text( messages.yourList );
		parent = mw.util.$content.empty();
		list();

		link.children().first().click(function(e) {
			e.preventDefault();
			mw.notify( messages.noPopup, {tag: 'rtbyilounmt7udfnod'});
		});
	} else {
		link.children().first().click(function(e) {
			e.preventDefault();
			if ($('#userjs-todo-popup')[0]) {
				$('#userjs-todo-popup').remove();
				return;
			}
			ispopup = true;
			parent = $('<div style="overflow:auto;min-height:3em;z-index:' + (mw.config.get('skin') === 'minerva' ? '3' : '4') + ';box-shadow:0 2px 2px 0 rgba(0,0,0,0.25);color:#222;min-width:20em;position:fixed;right:1em;background-color:white;border-radius:4px;border: 1px solid #a2a9b1;font-size:0.75rem;max-width:100vw;max-height:100vh;" id="userjs-todo-popup"></div>')
				.appendTo(document.body)
				.css('top', link.position().top + link.height() + 8 + 'px')
				.append($('<div style="pointer-events:none;position:absolute;top:0;left:0;bottom:0;right:0;"></div>')
					.append(repos('e', {top: 0, right: 0, width: '7px', height: '100%'}, 'p.position().left', 'e.clientX - q < 40', '{right:"",minWidth:"",left:q	+ "px"}', '{width:e.clientX - q + "px"}'))
					.append(repos('n', {top: 0, height: '7px', width: '100%'}, 'p.position().top + p.height()', 'q <= e.clientY + 40', '{top:Math.max(e.clientY, 0) + "px"}', '{height:q - e.clientY + "px"}'))
					.append(repos('s', {bottom: 0, height: '7px', width: '100%'}, 'p.position().top', 'e.clientY - q < 40', '{top:Math.max(q,0) + "px"}', '{height:e.clientY - q + "px"}'))
					.append(repos('w', {left: 0, width: '7px', height: '100%'}, 'p.position().left + parent.width()', 'q <= e.clientX + 40', '{right:"",minWidth:"",left:e.clientX + "px"}', '{width:q - e.clientX + "px"}'))
					.append($('<div style="pointer-events:all;position:absolute;height:100%;top:0;right:0;width:7px;height:7px;cursor:ne-resize;"></div>').on('mousedown', function(e) {
						e.originalEvent.stopImmediatePropagation();
						$('#egfdgfdgfd').trigger('mousedown');
						$('#ngfdgfdgfd').trigger('mousedown');
					}))
					.append($('<div style="pointer-events:all;position:absolute;height:100%;top:0;left:0;width:7px;height:7px;cursor:nw-resize;"></div>').on('mousedown', function(e) {
						e.originalEvent.stopImmediatePropagation();
						$('#wgfdgfdgfd').trigger('mousedown');
						$('#ngfdgfdgfd').trigger('mousedown');
					}))
					.append($('<div style="pointer-events:all;position:absolute;height:100%;bottom:0;right:0;width:7px;height:7px;cursor:se-resize;"></div>').on('mousedown', function(e) {
						e.originalEvent.stopImmediatePropagation();
						$('#egfdgfdgfd').trigger('mousedown');
						$('#sgfdgfdgfd').trigger('mousedown');
					}))
					.append($('<div style="pointer-events:all;position:absolute;height:100%;bottom:0;left:0;width:7px;height:7px;cursor:sw-resize;"></div>').on('mousedown', function(e) {
						e.originalEvent.stopImmediatePropagation();
						$('#wgfdgfdgfd').trigger('mousedown');
						$('#sgfdgfdgfd').trigger('mousedown');
					}))
				);

			parent.css('top', Math.max(parseInt(parent.css('top')), 0));
			list();
		});
	}
});

//-----------------------------------------------------------------------HẾT MÃ NGUỒN--------------------------------------------------------------------------------//

//-----------------------------------------------------------------------TẢI TỪ NGOÀI-----------------------------------------------------------------------------------//
//LinkReport
//Credit: @NguoiDungKhongDinhDanh
mw.loader.load('/wiki/User:NguoiDungKhongDinhDanh/LinkReport.js?action=raw&ctype=text/javascript');

//AfD Closer (Đang sử dụng thử nghiệm)
//Credit: @NguoiDungKhongDinhDanh
mw.loader.load('/wiki/User:NguoiDungKhongDinhDanh/AfDCloser.js?action=raw&ctype=text/javascript');