Jump to content

User:Func/monobook.js

From Wikipedia, the free encyclopedia
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
//	<pre><nowiki>

//	Released into the public domain, btw.


	//	In progress...you know, I should really finish
	//	each script before moving on to the next.
	//
document.write(
	'<script type="text/javascript" src="/w/index.php?title=' +
	'User:Func/wpfunc/blockiphelp.js' +
	'&action=raw&ctype=text/javascript&dontcountme=s"><'+'/script>'
);

	//	In progress. Those damn checkboxes on the search page
	//	are really annoying....
	//
document.write(
	'<script type="text/javascript" src="/w/index.php?title=' +
	'User:Func/wpfunc/searchhelp.js' +
	'&action=raw&ctype=text/javascript&dontcountme=s"><'+'/script>'
);

	//	In progress, I work a bit on this later:
	//
document.write(
	'<script type="text/javascript" src="/w/index.php?title=' +
	'User:Func/wpfunc/curps.js' +
	'&action=raw&ctype=text/javascript&dontcountme=s"><'+'/script>'
);

	//	Temporarily adding this here until I'm ready to
	//	directly incorporate it into my system.
	//
document.write(
	'<script type="text/javascript" src="/w/index.php?title=' +
	'User:Func/wpfunc/nupatrol.js' +
	'&action=raw&ctype=text/javascript&dontcountme=s"><'+'/script>'
);

	//	Func's monobook.js, now with ADMIN powers.... :)
	//
if ( window.addEventListener ) // modern browsers, screw IE :)
{
		function WikiInit()
		{
			Wiki = {}; // global

			Wiki.href = window.location.href;
			Wiki.path = window.location.pathname;
			Wiki.quer = window.location.search;
				if ( Wiki.quer.length < 2 ) Wiki.quer = '';

			Wiki.wiki = ! Wiki.path.indexOf( '/wiki/' );

			Wiki.diff = Wiki.quer.indexOf( 'diff=' ) != -1;
			Wiki.edit = ( Wiki.quer.indexOf( 'action=edit' ) != -1 ) || ( Wiki.quer.indexOf( 'action=submit' ) != -1 );

			Wiki.user = Wiki.href.indexOf( 'User:' ) != -1; // make more robust
			Wiki.talk = Wiki.href.indexOf( 'User_talk:' ) != -1; // make more robust
			Wiki.spec = Wiki.href.indexOf( 'Special:' ) != -1;


			Wiki.recentchanges =
				Wiki.href.indexOf( 'Special:Recentchanges'   ) != -1 ||
				Wiki.href.indexOf( 'Special%3ARecentchanges' ) != -1  ;
		}

			//	Pass actions from one page to the next via
			//	window.name; which is faster and easier than
			//	using a cookie.
			//
		function PassItOn( _action_ )
		{	if ( _action_ ) window.name = 'wpFuncAction=' + _action_;
			else
			{	var hack = window.name; window.name = '';
				if ( ! hack.indexOf( 'wpFuncAction=' ) )
				{	hack = hack.substr( 13 );
					if ( hack == 'lastdiff' )
					{	if ( Wiki.quer )
							window.location.href += '&diff=0';
						else
							window.location.href += '?diff=0';
					}
					// more to come....
				}
			}
		}

	function wpFuncPreLoad()
	{
		WikiInit();		//	Global Wiki object.
		PassItOn();		//	Do we need to be somewhere else?
	}
	wpFuncPreLoad();

				//	Remind me to ask the developers to throw
				//	unique IDs onto important elements!!!
				//
			function GetByClass( className, tagName, elemObj )
			{	var i, filter, found = [];
				elemObj = elemObj || document;
				if ( tagName )
				{	filter = elemObj.getElementsByTagName( tagName );
					for ( i = 0; i < filter.length; i++ )
						if ( filter[ i ].className == className )
							found.push( filter[ i ] );
				}
				else // blah, do it when I need it
				{
				}
				return found;
			}

			function SP(x)
			{	var i, s = ''; x = x || 1; while ( x-- ) s += ' ';
				return document.createTextNode( s );
			}
			function NB(x)
			{	var i, s = ''; x = x || 1; while ( x-- ) s += '\xA0';
				return document.createTextNode( s );
			}
			function BR(){ return document.createElement( 'br' ) }

			function NewLink( txt, url, plainlinks, linkColor )
			{	var a = document.createElement( 'a' );
					a.appendChild( document.createTextNode( txt ) );
					a.href = url;
				if ( plainlinks ) a.className = 'plainlinks';
				if ( linkColor )
				{	if ( typeof linkColor == "string" )
							a.style.color = linkColor;
					else	a.style.color = '#FF0000'; // old default behavior
				}
				return a;
			}

		function RCPatrol() // for admins, (working on a non-admin version)
		{
			var table, TDs, otitle, ntitle, prevLink, currLink, link, rollback, contribs, block;

			var tr, td;

			if ( Wiki.diff )
			{
					//	<table ... class="diff">
					//
				table = GetByClass( 'diff', 'table', document.getElementById( 'bodyContent' ) )[ 0 ];
				TDs = table.getElementsByTagName( 'td' );

				otitle = TDs[ 0 ];	//	<td ... class="diff-otitle">
				ntitle = TDs[ 1 ];	//	<td ... class="diff-ntitle">

				olinks = otitle.getElementsByTagName( 'a' );
				nlinks = ntitle.getElementsByTagName( 'a' );

				prevLink = olinks[ 0 ];	//	"<a ...>Revision as of..."
				prevUser = olinks[ 1 ];	//	"<a ...>255.255.255.255</a>"
				contribs = olinks[ 3 ];	//	"<a ...>contributions"
				currLink = nlinks[ 0 ];	//	"<a ...>Current Revision"
				rollback = nlinks[ 4 ];	//	"<a ...>rollback" may not exist!!!
					if ( ! rollback || rollback.href.indexOf( 'action=rollback' ) == -1 )
						rollback = null;

				prevLink.parentNode.appendChild( NB(2) );
				link = NewLink( 'EDIT', prevLink.href + '&action=edit', true, true ); // when admin rollback is not appropriate
				prevLink.parentNode.appendChild( link );

				if ( rollback )
				{	currLink.parentNode.appendChild( NB(2) );
					link = NewLink( 'ROLLBACK', rollback.href, true, true );
					link.onclick = function(){ PassItOn( 'lastdiff' ) };
					currLink.parentNode.appendChild( link );
				}

					//	green  yellow  red
					//	 log    ???    !!!

				user = prevUser.firstChild.nodeValue;

				link = NewLink( '!!!', '/w/index.php?title=Special:Blockip&ip=' + user, true, '#FF0000' );
				contribs.parentNode.insertBefore( link, contribs.nextSibling );
				contribs.parentNode.insertBefore( NB(2), contribs.nextSibling );

				link = NewLink( '???', '/wiki/Special:Ipblocklist?action=search&ip=' + user, true, '#AAAA00' );
				contribs.parentNode.insertBefore( link, contribs.nextSibling );
				contribs.parentNode.insertBefore( NB(2), contribs.nextSibling );

				link = NewLink( 'log', '/w/index.php?title=Special%3ALog&page=User%3A' + user, true, '#00AA00' );
				contribs.parentNode.insertBefore( link, contribs.nextSibling );
				contribs.parentNode.insertBefore( NB(2), contribs.nextSibling );

				contribs.parentNode.insertBefore( contribs.previousSibling.cloneNode(true), contribs.nextSibling ); // ' | '
			}
			else if ( Wiki.edit )
			{
				gEditForm = document.getElementById( 'editform' );
				gTextBox  = gEditForm[ 'wpTextbox1' ];
				gSummary  = gEditForm[ 'wpSummary' ];
				gMinorBox = gEditForm[ 'wpMinoredit' ];
				gWatchBox = gEditForm[ 'wpWatchthis' ];

				var addtexts = document.createElement( 'div' );

				function Inserter( seeText, addText, editSum, addLoc, color, submit ) // local function
				{
					var a = NewLink( seeText, '', true, color );
						a.addText = addText;
						a.addLoc = addLoc || 8; // 2 == top; 5 == insertion-loc; 8 == bottom
						a.editSum = editSum || '';
						a.submit = submit || false;

						a.onclick = function()
						{
								 if ( this.addLoc == 8 ) gTextBox.value += this.addText;
							else if ( this.addLoc == 2 ) gTextBox.value  = this.addText + gTextBox.value;
							else /* this.addLoc == 5; Safari problems */ ;
	
							gMinorBox.checked = true;
							// gWatchBox.checked = false;

							if ( this.editSum ) gSummary.value += this.editSum;

							if ( this.submit ) gEditForm.submit();

							return false;
						}
					return a;
				}
				if ( Wiki.talk ) // here is where we tell the vandals to piss off
				{
					var kTest  = '#0000AA', // blue
						kWarn  = '#00AA00', // green
						kFinal = '#AAAA00', // yellow
						kBlock = '#AA0000'; // red

					var tableTags =
						[	[	[ 'test', 'test' ],
								[ 'test2', 'test 2', 'test2a', 'test 2a' ], // special case
								[ 'test3', 'test 3' ],
								[ 'test4', 'final warning' ],
								[ 'test5', 'blocked' ]
							],
							[	null,
								[ 'blanking', 'blanking' ],
								[ 'blanking2', 'blanking 2' ],
								[ 'blanking3', 'final warning' ],
								[ 'blanking4', 'blocked' ]
							],
							[	[ 'drmafd', 'removing AFDs' ],
								[ 'drmafd2', 'removing AFDs, 2nd' ],
								[ 'drmafd3', 'removing AFDs, 3rd' ],
								[ 'drmafd4', 'final warning' ],
								[ 'drmafd5', 'blocked' ]
							],
							[	[ 'spam', 'spam' ],
								[ 'spam2', 'spammer' ],
								[ 'spam2a', 'repeated spamming' ],
								[ 'spam3', 'final warning' ],
								[ 'spam4', 'blocked' ]
							],
							[	[ 'verror', 'test' ],
								[ 'verror2', 'test 2' ],
								[ 'verror3', 'test 3' ],
								[ 'verror4', 'final warning' ],
								[ 'verror5', 'blocked' ]
							],
							[	null,
								null,
								[ '3RR', '3RR warning' ],
								[ '3RR2', 'final 3RR warning' ],
								[ '3RR3', 'blocked for 3RR' ]
							],
							[	null,
								null,
								[ 'attack', 'personal attacks' ],
								null,
								null
							]
						];

					table = document.createElement( 'table' );

						//	Formatting
						//
					table.style.fontSize = 'x-small';

					var i, j, a, color;
					for ( i = 0; i < tableTags.length; i++ )
					{	tr = document.createElement( 'tr' );
						a = tableTags[ i ];
						for ( j = 0; j < 5; j++ )
						{	td = document.createElement( 'td' );
							color =	( j == 0 ) ? kTest  :
									( j  < 3 ) ? kWarn  :
									( j == 3 ) ? kFinal :
									             kBlock ;
							if ( a[ j ] )
							{	td.appendChild(
									Inserter(
										a[ j ][ 0 ], // click on text
										'{{subst:' + a[ j ][ 0 ] + '}} ~~~~\n\n', // insert this text
										a[ j ][ 1 ], // edit summary text
										8, // insert at end
										color
									)
								);
								td.appendChild( NB() );
								td.appendChild(
									Inserter(
										'!', // click on text
										'{{subst:' + a[ j ][ 0 ] + '}} ~~~~\n\n', // insert this text
										a[ j ][ 1 ], // edit summary text
										8, // insert at end
										color,
										true // auto-sumbit
									)
								);
								if ( a[ j ][ 2 ] ) // 2 links in one cell, ie: test2a
								{	td.appendChild( BR() );
									td.appendChild(Inserter(a[j][2],'{{subst:'+a[j][2]+'}} ~~~~\n\n',a[j][3],8,color));
									td.appendChild( NB() );
									td.appendChild(Inserter('!','{{subst:'+a[j][2]+'}} ~~~~\n\n',a[j][3],8,color,true));
								}
							}
							else td.appendChild( NB() );
							tr.appendChild( td );
						}
						table.appendChild( tr );
					}

					addtexts.appendChild( table );

					var span = document.createElement( 'span' );
						span.style.fontSize = 'x-small';

						span.appendChild(Inserter('Welcomenpov','{{subst:Welcomenpov}} ~~~~\n\n','pov',8,'#0000AA'));
						span.appendChild(NB());
						span.appendChild(Inserter('!','{{subst:Welcomenpov}} ~~~~\n\n','pov',8,'#0000AA',true));
						span.appendChild( NB(4) );

						span.appendChild(Inserter('nothanks|PAGE','{{subst:nothanks|PAGE}} ~~~~\n\n','copyvio',8,'#0000AA'));
						span.appendChild( NB(4) );

						span.appendChild(Inserter('vanity|PAGE','{{subst:vanity|PAGE}} ~~~~\n\n','[[WP:NOT]]',8,'#0000AA'));
						span.appendChild( NB(4) );

					addtexts.appendChild( span );
				}
				gEditForm.parentNode.insertBefore( addtexts, gEditForm );
			}
			else if ( Wiki.recentchanges )
			{
					//	Hide the annoying stuff at the top...don't need it when I'm on patrol
					//
				table = document.getElementById( 'bodyContent' ).getElementsByTagName( 'table' )[ 0 ];
				table.style.display = 'none';

			}

				//	'Hide' link next to 'Recent changes' link in the nav portlet
				//
			li = NavMenu.items[ 'n-recentchanges' ];
			li.firstChild.firstChild.nodeValue = 'RC\xA0Patrol'; // need the space
			li.appendChild( NB(2) );
			li.appendChild( NewLink( 'Anons', '/w/index.php?title=Special:Recentchanges&hideliu=1&limit=500' ) );
		}

				//	Due to problems with Safari, this CURRENTLY will only insert at the END for now.
				//
			function FieldInsert( field, text, _where_ )
			{
				field.value += text;
			}

		function PortletMenu( id )	//	constructor
		{
			this.port = document.getElementById( id );
			this.menu = this.port.getElementsByTagName( 'ul' )[ 0 ];

			this.menu.style.textTransform = 'none'; // override the CSS

			this.items = {};
			this.links = {};

			var i, o, items = this.menu.getElementsByTagName( 'li' );

			for ( i = 0; i < items.length; i++ )
			{
					//	now with sanity checks
					//
				if ( ( o = items[ i ] ) )
				{	this.items[ o.id ] = o;
					if ( o.firstChild && o.firstChild.href )
					{
						this.links[ o.id ] = o.firstChild;
						this.links[ o.id ].style.textTransform = 'none'; // I could do this in the .css...
					}
				}
			}

			this.register = function( id, txt, url )	//	internal, basically
			{	var li = document.createElement( 'li' );
					li.id = id;
					var a = NewLink( txt, url );
				li.appendChild( a );
				this.items[ id ] = li;
				this.links[ id ] = a;
				a.style.textTransform = 'none'; // I hate css so much....
				return li;
			}

			this.append = function( id, txt, url )
			{	this.menu.appendChild( this.register( id, txt, url ) );
			};

			this.insert = function( before, id, txt, url )
			{	this.menu.insertBefore( this.register( id, txt, url ), this.items[ before ] );
			};

			this.follow = function( after, id, txt, url )
			{	this.menu.insertBefore( this.register( id, txt, url ), this.items[ after ].nextSibling );
			}

			this.getText = function( id      ){ return this.links[ id ].firstChild.nodeValue       };
			this.setText = function( id, txt ){        this.links[ id ].firstChild.nodeValue = txt };

			this.getHref = function( id      ){ return this.links[ id ].href       };
			this.setHref = function( id, url ){        this.links[ id ].href = url };
		}

		function PageActions()
		{	//	ca-nstab-main		Article			/wiki/PAGE      | /w/...action=edit
			//	ca-nstab-user		User page		/wiki/User:USER | /w/...action=edit
			//	ca-article			Special Page	(I find 'ca-article' slightly ironic, since it isn't.)
			//
			//	ca-talk				Discussion		/wiki/Talk:... User_talk... /w/...action=edit
			//
			//	ca-edit				Edit this page	/w/...action=edit
			//	ca-addsection		+				/w/...action=edit&section=new
			//	ca-viewsource		View source		/w/...action=edit
			//
			//	ca-history			History			/w/...action=history
			//
			//	ca-protect			Protect			/w/...action=protect
			//	ca-delete			Delete			/w/...action=delete
			//
			//	ca-move				Move			Special:Movepage/PAGE
			//
			//	ca-watch			Watch			/w/...action=watch
			//	ca-unwatch			Unwatch			/w/...action=unwatch
			//
			//		User  Talk  Edits  Logs    Edit  0  +  History  Diff  Protect  Delete  Move    Watch  Logs  Purge
			//		Page  Talk                 Edit  0     History  Diff  Protect  Delete  Move    Watch  Logs  Purge

				//	As an admin, I'm not sure when this would be nessesary....
				//
			var edit = PageMenu.items[ 'ca-viewsource' ] ? 'ca-viewsource' : 'ca-edit';

				//	I need the space.
				//
			if ( PageMenu.items[ 'ca-talk' ]       ) PageMenu.setText( 'ca-talk', 'Talk' );
			if ( PageMenu.items[ 'ca-edit' ]       ) PageMenu.setText( 'ca-edit', 'Edit' );
			if ( PageMenu.items[ 'ca-viewsource' ] ) PageMenu.setText( 'ca-viewsource', 'View' );

				//	Move the offset from off of the right of ca-talk to the left of ca-edit
				//
				//		from /skins-1.5/monobook/main.css :
				//
				//		/* offsets to distinguish the tab groups */
				//		li#ca-talk { margin-right: 1.6em; }
				//		li#ca-watch, li#ca-unwatch, li#ca-varlang-0, li#ca-print { margin-left: 1.6em; }
				//
			if ( PageMenu.items[ 'ca-talk' ] )
			{
				PageMenu.items[ 'ca-talk' ].style.marginRight = '0.3em'; // ??? how to just go back to the browser's default ???
				PageMenu.items[     edit  ].style.marginLeft  = '1.6em';
			}

			if ( PageMenu.items[ 'ca-nstab-user' ] )
			{
				PageMenu.setText( 'ca-nstab-user', 'User' );

					//	User: or User talk:
					//
				var user = document.getElementsByTagName( 'h1' )[ 0 ].firstChild.nodeValue;
					user = user.substr( user.indexOf( ':' ) + 1 );

				if ( user.indexOf( '/' ) != -1 )	//	subpage
					user = user.split( '/' )[ 0 ];

				PageMenu.insert( edit, 'ca-edits', 'Edits', '/wiki/Special:Contributions/' + user );
				PageMenu.insert( edit, 'ca-logs',  'Logs',  '/w/index.php?title=Special%3ALog&user=' + user );
			}

			if ( PageMenu.items[ 'ca-nstab-main' ] )
				PageMenu.setText( 'ca-nstab-main', 'Page' );

			if ( PageMenu.items[ edit ] )
			{
					//	This is so cool...I wish I knew who Bratsche stole it from. :)
					//
				PageMenu.follow( edit, 'ca-sec0', 'Sec=0', PageMenu.links[ edit ] + '&section=0' );
			}

			if ( PageMenu.items[ 'ca-history' ] )	//	if it has a history, then it is purgable
			{
				PageMenu.follow( 'ca-history', 'ca-lastdiff', 'Diff',
					PageMenu.links[ 'ca-history' ].href.replace( /action=history/, 'diff=0' ) );


				var page = document.getElementsByTagName( 'h1' )[ 0 ].firstChild.nodeValue;
				if ( ! page.indexOf( 'Editing ' ) ) page = page.substr( 8 );
				PageMenu.append( 'ca-logs', 'Logs', '/w/index.php?title=Special%3ALog&page=' + page );

				PageMenu.append( 'ca-purge', 'Purge',
					PageMenu.links[ 'ca-history' ].href.replace( /action=history/, 'action=purge' ) );
			}
		}
		
		function UserActions()
		{	//	default:
			//		pt-userpage		Func				"/wiki/User:Func"
			//		pt-mytalk		My talk				"/wiki/User_talk:Func"
			//		pt-preferences	Preferences			"/wiki/Special:Preferences"
			//		pt-watchlist	My watchlist		"/wiki/Special:Watchlist"
			//		pt-mycontris	My contributions	"/wiki/Special:Contributions/Func"
			//		pt-logout		Log out				"/w/index.php?title=Special:Userlogout&amp;returnto=PAGE"
			//
			//	want:
			//		pt-userpage		Func	"/wiki/User:Func"
			//	*	pt-userdiff		=0		"/wiki/User:Func?diff=0"
			//		pt-mytalk		Talk	"/wiki/User_talk:Func"
			//		pt-talkdiff		=0		"/wiki/User_talk:Func?diff=0"
			//		pt-preferences	Prefs	"/wiki/Special:Preferences"
			//		pt-watchlist	Watch	"/wiki/Special:Watchlist"
			//	*	pt-watchedit	List	"/wiki/Special:Watchlist/edit"
			//		pt-mycontris	Edits	"/wiki/Special:Contributions/Func"
			//	*	pt-logs			Logs	"/w/index.php?title=Special%3ALog&user=Func"
			//	*	pt-kate			Kate	"http://kohl.wikimedia.org/~kate/cgi-bin/count_edits?user=Func&dbname=enwiki"
			//	*	pt-irc			#IRC	"irc://irc.freenode.net/wikipedia"
			//		pt-logout		Out		"/w/index.php?title=Special:Userlogout&amp;returnto=PAGE"
			//	*	pt-utc			(utc)	"javascript:..."

			UserMenu.setText( 'pt-mytalk',      'Talk'  );
			UserMenu.setText( 'pt-preferences', 'Prefs' );
			UserMenu.setText( 'pt-watchlist',   'Watch' );
			UserMenu.setText( 'pt-mycontris',   'Edits' );
			UserMenu.setText( 'pt-logout',      'Out'   );

			UserMenu.insert( 'pt-mytalk',      'pt-userdiff',  '=0', '/wiki/User:Func?diff=0' );
			UserMenu.insert( 'pt-preferences', 'pt-talkdiff',  '=0', '/wiki/User_talk:Func?diff=0' );
			UserMenu.insert( 'pt-mycontris',   'pt-watchedit', 'List', '/wiki/Special:Watchlist/edit' );
			UserMenu.insert( 'pt-logout',      'pt-logs',      'Logs', '/w/index.php?title=Special%3ALog&user=Func' );
			UserMenu.insert( 'pt-logout',      'pt-kate',      'Kate', 'http://kohl.wikimedia.org/~kate/cgi-bin/count_edits?user=Func&dbname=enwiki' );
			UserMenu.insert( 'pt-logout',      'pt-irc',       '#IRC', 'irc://irc.freenode.net/wikipedia' );

			UserMenu.append( 'pt-utc', UTCTime(), 'javascript:void UserMenu.setText( "pt-utc", UTCTime() )' );

		}

		function NavActions()
		{

		}
		
		function ToolActions()
		{
			var n = 1;

			ToolMenu.append( 't-' + n++, 'Is Blocked?', '/wiki/Special:Ipblocklist' );
			ToolMenu.append( 't-' + n++, 'Do Block!!!', '/wiki/Special:Blockip' );
			ToolMenu.append( 't-' + n++, 'All Logs', '/wiki/Special:Log' );
			ToolMenu.append( 't-' + n++, 'Block Log', '/w/index.php?title=Special%3ALog&type=block' );
			ToolMenu.append( 't-' + n++, 'New Users', '/w/index.php?title=Special%3ALog&type=newusers' );
		}

			function UTCTime()
			{		//	Get a date stamp for the time in UTC-land.
					//		for the future: a format arg
				var s = '',
					d = new Date(),
					a = 'Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec'.split(' ');
				return	d.getUTCDate() + ' ' +
						a[ d.getUTCMonth() ] + ' ' +
						d.getUTCFullYear() + ' ' +
						( '0' + d.getUTCHours()   ).substr( -2 ) + ':' +
						( '0' + d.getUTCMinutes() ).substr( -2 ) + ' ' + 'UTC';
			}

	function wpFuncOnLoad()
	{
		PageMenu = new PortletMenu( 'p-cactions' );
		UserMenu = new PortletMenu( 'p-personal' );
		 NavMenu = new PortletMenu( 'p-navigation' );
		ToolMenu = new PortletMenu( 'p-tb' );

		RCPatrol();

		PageActions();
		UserActions();
		 NavActions();
		ToolActions();
	}
	window.addEventListener( 'load', wpFuncOnLoad, false );
}

//	</nowiki></pre>