User:Gene93k/delsort.js
Appearance
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump. This code will be executed when previewing this page. |
Documentation for this user script can be added at User:Gene93k/delsort. |
// Copied from User:Tom Morris/delsort.js (http://wiki.riteme.site/w/index.php?title=User:Tom_Morris/delsort.js&oldid=454585461)
//
// [[Wikipedia:WikiProject Deletion sorting]] <pre><nowiki>
// This is a development version of [[Wikipedia:WikiProject Deletion sorting/delsort.js]]
if( typeof( DelsortConfig ) == 'undefined' ) {
DelsortConfig = function() {};
}
DelsortConfig.compactPage = 'Wikipedia:WikiProject_Deletion_sorting/Compact';
var Delsort = function() {};
// Used to emulate CSS columns in Opera
function add_opera_delsort_compact_css() {
if ( wgNamespaceNumber == 4 && wgPageName == DelsortConfig.compactPage ) {
if( navigator.userAgent.indexOf("Opera") != -1 ) {
importStylesheet('Wikipedia:WikiProject Deletion sorting/compact opera.css');
}
}
}
// adds 'delsort' tab to p-cactions
function add_delsort_tab()
{
if ( DelsortConfig['debugLevel'] > 0 ) {
Delsort.displayPopup( '', "Setting up buttons.." );
Status.init( window['delsortWindow'].content );
Delsort.debug ('Adding delsort button ...');
}
var tabs = document.getElementById('p-cactions').getElementsByTagName('ul')[0];
var ul = addlimenu(tabs, 'delsort', 'delsort');
if ( DelsortConfig['debugLevel'] > 0 ) Delsort.debug ('ul = ' + ul.tagName);
var menuitem = ul.previousSibling;
menuitem.setAttribute('href','javascript:showDelsortFrame()');
// when the user is in edit mode, save a reference to it
Delsort.afdForm = document.getElementById( 'editform' );
// support deprecated shortcut list
if ( window['delsortPages'] )
DelsortConfig.shortcuts = window['delsortPages'];
// add each shortcut
if ( DelsortConfig['shortcuts'] &&
DelsortConfig['shortcuts']['length'] ) {
for (i = 0; i < DelsortConfig.shortcuts.length; i++) {
if ( DelsortConfig['debugLevel'] > 0 ) Delsort.debug ('adding shortcut "' +
DelsortConfig.shortcuts[i] + '"');
mw.util.addPortletLink('delsort',
'javascript:delsortArticle("' + DelsortConfig.shortcuts[i] + '")',
DelsortConfig.shortcuts[i],
'');
}
}
if ( DelsortConfig['debugLevel'] > 0 ) {
Delsort.debug ('done');
}
}
Delsort.add_inline_ui = function() {
if ( DelsortConfig['debugLevel'] > 0 ) {
Delsort.displayPopup( '', "Setting up inline delsort buttons.." );
Status.init( window['delsortWindow'].content );
Delsort.debug ('Adding delsort to ...');
}
var spans = document.getElementsByTagName('SPAN');
for (i = 0; i < spans.length; i++) {
if (spans[i].className == 'editsection') {
// spans[i] is a section, which is usually the start of a transclude.
// It could be a section within the transcluded page
var sectionEditAnchor = spans[i].getElementsByTagName('A');
if ( sectionEditAnchor ) sectionEditAnchor = sectionEditAnchor[0];
Delsort.debug ('-- Found section "' + sectionEditAnchor.title + '"');
if ( sectionEditAnchor && /Wikipedia:Articles for deletion/.exec ( sectionEditAnchor.title ) ) {
window['wgAfdPage'] = sectionEditAnchor.title;
Delsort.debug ('Looking for more signs that "' + sectionEditAnchor.title + '" is an Afd...');
}
else {
window['wgAfdPage'] = '';
}
}
if (window['wgAfdPage'] && spans[i].className == 'mw-headline') {
// span[i] is the beginning of the transcluded Afd content
if ( window['wgAfdPage'].indexOf ( spans[i].textContent ) > -1 ) {
window['wgNominatedArticle'] = spans[i].textContent;
Delsort.debug (' ' + window['wgAfdPage'] + ': ' + window['wgNominatedArticle']);
parentNode = spans[i].parentNode;
var laNode = null;
// try looking for {{la|...}} directly after
if (parentNode.nextSibling.nodeValue == '\n' &&
parentNode.nextSibling.nextSibling.tagName == 'DL' ) {
// looks like we have found {{la|...}}
laNode = parentNode.nextSibling.nextSibling;
}
// try looking for {{la|...}} by skipping a "AfDs for this article" DIV
if (parentNode.nextSibling.nodeValue == '\n' &&
parentNode.nextSibling.nextSibling.tagName == 'DIV' &&
parentNode.nextSibling.nextSibling.nextSibling.nodeValue == '\n' &&
parentNode.nextSibling.nextSibling.nextSibling.nextSibling.tagName == 'DL' ) {
// looks like we have found {{la|...}}
laNode = parentNode.nextSibling.nextSibling.nextSibling.nextSibling;
}
if (laNode) {
if (laNode.childNodes[1].tagName == 'DD') {
var viewAfdNode = laNode.childNodes[1].lastChild.previousSibling;
if (viewAfdNode) {
if (viewAfdNode.textContent == 'View AfD' &&
viewAfdNode.previousSibling) {
viewAfdNode.previousSibling.nodeValue = ' — (Afd: ';
viewAfdNode.firstChild.nodeValue = 'View';
var delsortAfdNode = viewAfdNode.cloneNode(true);
delsortAfdNode.firstChild.nodeValue = 'Delsort';
delsortAfdNode.setAttribute('href', 'javascript:showDelsortFrame("' + wgAfdPage + '")');
delsortAfdNode = viewAfdNode.parentNode.insertBefore( delsortAfdNode, viewAfdNode.parentNode.lastChild );
viewAfdNode.parentNode.insertBefore( document.createTextNode ( ' | ' ), delsortAfdNode );
}
else {
var delsortAfdNode = document.createElement('A');
delsortAfdNode.setAttribute('href', 'javascript:showDelsortFrame("' + wgAfdPage + '")');
delsortAfdNode.innerHTML = 'Delsort';
laNode.appendChild ( document.createTextNode ( ' - ' ) );
laNode.appendChild ( delsortAfdNode );
}
}
}
}
else {
// Delsort.debug ('Skipping nomination "' + window['wgAfdPage'] + '"; expected preamble not present.');
var delsortAfdNode = document.createElement('A');
delsortAfdNode.setAttribute('href', 'javascript:showDelsortFrame("' + wgAfdPage + '")');
delsortAfdNode.innerHTML = 'Delsort';
parentNode.parentNode.insertBefore ( document.createTextNode ( ' - ' ), parentNode.nextSibling );
parentNode.parentNode.insertBefore ( delsortAfdNode , parentNode.nextSibling );
}
}
else {
Delsort.debug ('Skipping headline "' + spans[i].textContent + '"');
}
}
}
}
Delsort.status = function( text ) {
return new Status( text, 'Status', 'status' );
}
Delsort.info = function( text ) {
return new Status( text, 'Info', 'info' );
}
Delsort.warn = function( text ) {
return new Status( text, 'Warning', 'error' );
}
Delsort.error = function( text ) {
return new Status( text, 'Error', 'error' );
}
Delsort.progress = function( text ) {
// disable the "....." until I can work out how to
// achieve that again using the new TW framework
if ( text == '.' ) return;
return new Status( text, 'Progress', 'info' );
}
Delsort.debug = function( text ) {
if ( DelsortConfig['debugLevel'] > 0 ) {
return new Status( text, 'Debug', 'info' );
}
}
Delsort.init = function() {
add_opera_delsort_compact_css();
if ( typeof DelsortConfig.transcludeRE == 'undefined' )
DelsortConfig.transcludeRE = new RegExp('Wikipedia:Deletion today|Wikipedia:Articles for deletion\/Log\/');
if ( typeof ( WikiPage ) == 'function' ) {
// create wgWikiPage for the current page if it doesnt already exist
if (! window['wgWikiPage'] )
wgWikiPage = new WikiPage(null,wgPageName);
if ( DelsortConfig.transcludeRE.test ( wgWikiPage.page ) )
Delsort.add_inline_ui();
if ( wgWikiPage.superarticle == 'Articles for deletion' &&
wgWikiPage.subarticle.substr(0,3) != 'Log' ) {
window['wgAfdPage'] = wgPageName;
add_delsort_tab();
}
return;
}
if ( wgNamespaceNumber == 4 ) {
var subTitleRE = /^([^/]+)\/(.+)/;
if ( subTitleRE.exec ( wgTitle ) ) {
window['wgDirname'] = RegExp.$1;
window['wgSubTitle'] = RegExp.$2;
}
if (!window['wgDirname'] || !window['wgSubTitle'] || wgDirname != 'Articles for deletion') return;
window['wgAfdPage'] = wgPageName;
add_delsort_tab();
}
}
addOnloadHook(Delsort.init);
function showDelsortFrame(pAfdPage) {
if (pAfdPage)
window['wgAfdPage'] = pAfdPage;
// The frame contents are cached
if ( Delsort['PopupContents'] )
Delsort.displayPopup( Delsort.PopupContents, "Select deletion sorting criteria" );
else
Delsort.loadFrameContents();
}
Delsort.loadFrameContents = function () {
try {
delsortCompatList = sajax_init_object();
delsortCompatList.overrideMimeType('text/xml');
var query = {
'title': DelsortConfig.compactPage
};
delsortCompatList.onreadystatechange = showDelsortFrameCallback;
delsortCompatList.open( 'GET' , mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/index.php?' + QueryString.create( query ), true );
delsortCompatList.send( null );
} catch(e) {
if( e instanceof Exception ) {
Delsort.error( 'Error: ' + e.what() );
} else {
Delsort.error( 'Error: ' + e );
}
}
}
function showDelsortFrameCallback() {
if ( delsortCompatList.readyState != 4 ){
return;
}
if( delsortCompatList.status != 200 ){
Delsort.error('Bad status , bailing out; status = ' + delsortCompatList.status );
return;
}
var doc = delsortCompatList.responseXML;
var list = doc.getElementById('bodyContent').cloneNode(true);
if(! list ) {
Delsort.error( 'Unable to get the list, aborting.');
return;
}
var currentNode = list.firstChild;
var node;
// removed by TM: don't care
// remove the heading
//do {
// node = currentNode;
// currentNode = node.nextSibling;
//
// list.removeChild ( node );
//} while (node.id != 'toc');
// remove the edit links
var spans = list.getElementsByTagName('span');
var i = 0;
for (i = 0; i < spans.length; i++) {
if (spans[i].className == 'editsection') {
spans[i].parentNode.removeChild ( spans[i] );
}
}
var delsortLinkRE = new RegExp ('\/wiki\/Wikipedia:WikiProject_Deletion_sorting\/(.*)');
// remove the edit links
var anchors = list.getElementsByTagName('a');
var i = 0;
for (i = 0; i < anchors.length; i++) {
if ( anchors[i].href && delsortLinkRE.exec(anchors[i].href) ) {
pType = RegExp.$1;
pType = pType.replace(/_/g,' ');
if( navigator.userAgent.indexOf("Opera") != -1 ) {
anchors[i].href = "#";
anchors[i].onclick = new Function("delsortArticle('" + pType + "')");
}
else {
anchors[i].href = "javascript:delsortArticle('" + pType + "')";
}
}
}
Delsort.PopupContents = list;
Delsort.displayPopup( list, "Select deletion sorting criteria" );
}
Delsort.displayPopup = function(pContent, pTitle) {
if ( DelsortConfig['debugLevel'] > 0 )
Status.debugLevel = DelsortConfig.debugLevel;
if (!window['delsortWindow']) {
delsortWindow = new SimpleWindow( 800, 400 );
}
if (pTitle)
delsortWindow.setTitle( pTitle )
if (pContent)
delsortWindow.setContent( pContent );
delsortWindow.display();
}
function delsortArticle( pType ) {
pType = unescape(pType);
window['twDelsortType'] = pType;
wgAfdPage = unescape(wgAfdPage).replace('_',' ','g');
Delsort.displayPopup ( null, "Performing deletion sorting" );
Status.init( window['delsortWindow'].content );
var subpageRE = new RegExp('Wikipedia:Articles for deletion\/(.*)');
if ( subpageRE.exec( wgAfdPage ) ) {
wgNominatedArticle = RegExp.$1;
}
else {
Delsort.error( 'Can not determine article name for "' + wgAfdPage + '", aborting');
return;
}
var additionalNominationRE = new RegExp(' ([(]([0-9]+..|[a-z]+) [Nn]omination[)])');
var pRegexResults = additionalNominationRE.exec( wgNominatedArticle );
wgNominationIndex = '';
if ( pRegexResults ) {
wgNominationIndex = pRegexResults[1];
wgNominatedArticle = wgNominatedArticle.substr(0, pRegexResults.index);
}
Delsort.status( 'Nominated article name: ' + wgNominatedArticle );
if (wgNominationIndex)
Delsort.status( 'Nomination index: ' + wgNominationIndex );
// check the article exists
try {
delsortXML = sajax_init_object();
Delsort.debug( 'delsortXML' + delsortXML );
delsortXML.overrideMimeType('text/xml');
var query = {
'action': 'query',
'titles': wgNominatedArticle,
'prop': 'info',
'format': 'xml'
};
Delsort.status( 'Check the article "' + wgNominatedArticle + '" exists ...');
delsortXML.onreadystatechange = Delsort.verifyArticleExistsCallback;
if (typeof (query.toSource) == 'undefined') {
Delsort.debug( 'query:' + query );
}
else {
Delsort.debug( 'query:' + query.toSource() );
}
var url = mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/api.php?' + QueryString.create( query );
Delsort.debug( 'url:' + url );
delsortXML.open( 'GET' , url, true );
delsortXML.send( null );
} catch(e) {
if( e instanceof Exception ) {
Delsort.error( 'Error: ' + e.what() );
} else {
Delsort.error( 'Error: ' + e );
}
}
}
Delsort.verifyArticleExistsCallback = function() {
var doc = Delsort.getAJAXResponse();
if (typeof doc != 'object') return;
Delsort.debug( ' Article test responseXML = ' + delsortXML.responseText );
var pageNode = doc.getElementsByTagName('page');
if (!pageNode || !pageNode[0] || !pageNode[0].getAttribute('lastrevid')) {
Delsort.status( 'Article not found' );
return;
}
Delsort.status( ' OK ' );
try {
delsortXML = sajax_init_object();
Delsort.debug( 'delsortXML' + delsortXML );
delsortXML.overrideMimeType('text/xml');
var query = {
'action': 'submit',
'title': 'Wikipedia:WikiProject Deletion sorting/' + window['twDelsortType'],
'section': 1
};
Delsort.status( 'Grabbing edit form for ' + query.title);
delsortXML.onreadystatechange = delsortCallback;
Delsort.debug( 'query:' + query.toSource() );
delsortXML.open( 'GET' , mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/index.php?' + QueryString.create( query ), true );
delsortXML.send( null );
} catch(e) {
if( e instanceof Exception ) {
Delsort.error( 'Error: ' + e.what() );
} else {
Delsort.error( 'Error: ' + e );
}
}
}
function delsortCallback() {
var delsortForm = Delsort.getAJAXEditForm();
if (typeof delsortForm != 'object') return;
var doc = delsortForm.ownerDocument;
var textbox = doc.getElementById( 'wpTextbox1' );
Delsort.status( 'Checking contents of ' + window['twDelsortType'] + ' list');
Delsort.debug( 'Looking for ' + wgNominatedArticle + ' in ' + textbox.value);
if ( (textbox.value.indexOf( wgNominatedArticle + '}}' ) != -1) ||
(textbox.value.indexOf( wgNominatedArticle.replace(/ /g,'_') + '}}' ) != -1) )
{
Delsort.error( wgNominatedArticle + ' already listed on ' + window['twDelsortType']);
return;
}
Delsort.progress( ': ok' );
// remove (U.S. State) and (country) after Georgia
var sectionHeaderTitle = window['twDelsortType'].replace(/ [(].*[)]/,'');
var sectionHeaderRE = new RegExp('(==+ *(.*[^=\n]*) *==+)\n(\n*<[^>]*>)*(\n)*');
if ( ! sectionHeaderRE.test( textbox.value ) ) {
Delsort.error( 'Unable to locate where to place the new listing; aborting.' );
return;
}
var sectionHeader = RegExp.$1;
Delsort.debug( 'Found section ' + sectionHeader );
var sectionHeaderAcceptRE = new RegExp('(List of deletion discussions|Articles for deletion|General|Other|' + sectionHeaderTitle + ')');
if ( ! sectionHeaderAcceptRE.test( sectionHeader ) ) {
Delsort.error( 'The section header title "' + sectionHeader + '" looks a bit odd; aborting.' );
return;
}
var newval = textbox.value.replace(sectionHeaderRE,'$&{{' + wgAfdPage + '}}\n');
if (textbox.value == newval) {
Delsort.error( 'Unable to add Afd, will abort.' );
return;
}
textbox.value = newval;
Delsort.debug('contents = ' + textbox.value);
Delsort.status( 'Updating the summary...' );
var summary = "Listing [[" + wgNominatedArticle + "]]";
if ( wgNominationIndex )
summary += wgNominationIndex;
Delsort.progress( summary );
// safety valve to prevent bad edit summaries
if ( summary.indexOf ( 'Log' ) > -1 ) {
Delsort.error ( 'incorrect summary, aborting' );
return;
}
doc.getElementById( 'wpSummary' ).value = summary; // + TwinkleConfig.summaryAd;
// Mark adding an article to a delsort list as a major edit
// to ensure it appears on Watchlists
doc.getElementById( 'wpMinoredit' ).checked = false;
if ( DelsortConfig['watchDelsortedLists'] > 0 ) {
Delsort.debug( ' (Watching the Delsort list) ' );
doc.getElementById( 'wpWatchthis' ).checked = true;
}
if ( DelsortConfig['watchDelsortedLists'] == 0 ) {
Delsort.debug( ' (Not watching the Delsort list) ' );
doc.getElementById( 'wpWatchthis' ).checked = false;
}
// debugging interrupt to prevent damage
// return;
if (! Delsort.submitHiddenForm ( delsortForm ) )
return;
Delsort.progress( 'done' );
// if the user was in edit mode, use the current form
if (typeof Delsort.afdForm == 'object' && Delsort.afdForm &&
Delsort.afdForm['tagName'] && Delsort.afdForm['tagName'] == 'FORM') {
Delsort.debug( ' Found that the Afd is already in edit mode... ' );
Delsort.markAfdDelsorted( Delsort.afdForm );
return;
}
Delsort.debug( ' Calling markDelsortedArticle()... ' );
markDelsortedArticle();
}
function markDelsortedArticle( pType ) {
if ( pType && !window['twDelsortType'])
window['twDelsortType'] = pType;
Delsort.debug( ' In markDelsortedArticle... ' );
try {
delsortXML = sajax_init_object();
Delsort.debug( 'delsortXML' + delsortXML );
delsortXML.overrideMimeType('text/xml');
var query = {
'action': 'submit',
'title': wgAfdPage
};
Delsort.status( 'Grabbing edit form for ' + query.title);
delsortXML.onreadystatechange = markDelsortedCallback;
Delsort.debug( 'query:' + query.toSource() );
delsortXML.open( 'GET' , mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/index.php?' + QueryString.create( query ), true );
delsortXML.send( null );
} catch(e) {
if( e instanceof Exception ) {
Delsort.error( 'Error: ' + e.what() );
} else {
Delsort.error( 'Error: ' + e );
}
}
}
function markDelsortedCallback() {
var afdForm = Delsort.getAJAXEditForm ();
if (typeof afdForm != 'object') return;
Delsort.markAfdDelsorted ( afdForm );
}
// returns 0 when still in progress
// -1 if there was an error
// or the edit form when successfully obtained
Delsort.getAJAXResponse = function() {
if ( delsortXML.readyState != 4 ){
Delsort.progress('.');
return 0;
}
if( delsortXML.status != 200 ){
Delsort.error('Bad status , bailing out; status = ' + delsortXML.status);
return -1;
}
var doc = delsortXML.responseXML;
if( !doc ) {
Delsort.error( 'Possible failure in receiving document, will abort.' );
return -1;
}
Delsort.progress( 'done' );
return doc;
}
Delsort.getAJAXEditForm = function() {
var doc = Delsort.getAJAXResponse();
if (typeof doc != 'object') return doc;
var editForm = doc.getElementById( 'editform' );
if(! editForm ) {
Delsort.error( 'Possible failure in receiving document, aborting.' + doc);
return -1;
}
return editForm;
}
Delsort.markAfdDelsorted = function( pAfdForm ) {
var textbox = pAfdForm['wpTextbox1'];
var modified = ( textbox.value == textbox.defaultValue ) ? 0 : 1;
// if the last character in the box is a sig, add a new link character
if (/[~]$/.test ( textbox.value ) )
textbox.value += "\n";
textbox.value += "{{subst:" + "User:Gene93k/deletion-sorting|" + window['twDelsortType'] + "}} <small>~~" + "~~</small>";
Delsort.debug('contents = ' + textbox.value);
Delsort.status( 'Updating the summary...' );
// TODO: the " (xth nom)" needs to be stripped
var summary = "Listing on [[WP:DELSORT]] under " + window['twDelsortType'];
// preserve any manual comments in the edit summary
var wpSummaryNode = pAfdForm['wpSummary'];
if ( wpSummaryNode.value != wpSummaryNode.defaultValue )
wpSummaryNode.value += '; ' + summary;
else
wpSummaryNode.value = summary;
Delsort.progress( summary );
wpPreviewMode = document.getElementById("wikiPreview") ? 1 : 0;
// Marking article as delsorted is a minor edit
// unless the the Afd form is in preview mode or the user
// has manually changed the textbox
var wpMinoreditNode = pAfdForm['wpMinoredit'];
if ( wpMinoreditNode.checked == false &&
!wpPreviewMode && !modified )
wpMinoreditNode.checked = true;
if ( DelsortConfig['watchDelsortedAfd'] > 0 ) {
Delsort.debug( ' (Watching the Afd) ' );
pAfdForm['wpWatchthis'].checked = true;
}
if ( DelsortConfig['watchDelsortedAfd'] == 0 ) {
Delsort.debug( ' (Not watching the Afd) ' );
pAfdForm['wpWatchthis'].checked = false;
}
// when the Afd has been trancluded onto the currently displayed
// page (i.e. the logs), the form submission happens in the background
if ( unescape(wgPageName).replace('_',' ','g') != wgAfdPage ) {
Delsort.submitHiddenForm(pAfdForm);
if (window['delsortWindow'] && window['delsortWindow']['frame'] ) {
try {
document.body.removeChild( window['delsortWindow'].frame );
} catch (x) {}
}
return;
}
// if the form was in edit mode, there is no need to add the from to
// the document before submission.
if (! Delsort.afdForm ) {
Delsort.debug( ' appending the form to the document ' );
document.body.appendChild( pAfdForm );
}
Delsort.status( 'Submitting the form...' );
pAfdForm.submit();
}
Delsort.getIFrame = function() {
var iFrameID = 'delsortFrame';
var iFrame = document.getElementById('delsortFrame');
if (iFrame) {
iFrame.setAttribute('src', 'about:blank');
return iFrame;
}
iFrame = document.createElement('IFRAME');
if(! iFrame ) {
Delsort.error( 'Unable to create an IFRAME, aborting.');
return;
}
iFrame.setAttribute('src', 'about:blank');
iFrame.setAttribute('id', iFrameID);
iFrame.setAttribute('NAME', iFrameID);
iFrame.style.display = 'none';
iFrame.style.width = 0;
iFrame.style.height = 0;
document.body.appendChild( iFrame );
return iFrame;
}
Delsort.submitHiddenForm = function(pForm) {
iFrame = Delsort.getIFrame();
pForm.target = iFrame.id;
iFrame.appendChild( pForm);
Delsort.status( 'Submitting the form...' );
try {
pForm.submit();
} catch(e) {
if( e instanceof Exception ) {
Delsort.error( 'Error: ' + e.what() );
} else {
Delsort.error( 'Error: ' + e );
}
return false;
}
return true;
}
// </nowiki></pre>