MyAnimeList (MAL) Track Missing Relations

Allows to find missing relations and entries with wrong chapter/episode count.

当前为 2015-05-05 提交的版本,查看 最新版本

// ==UserScript==
// @name		MyAnimeList (MAL) Track Missing Relations
// @namespace	https://greasyfork.org/users/7517
// @description	Allows to find missing relations and entries with wrong chapter/episode count.
// @icon		http://i.imgur.com/b7Fw8oH.png
// @version		4.2
// @author		akarin
// @include		/^http:\/\/myanimelist\.net\/panel\.php(\?go=editmanga)?$/
// @include		/^http:\/\/myanimelist\.net\/editlist\.php\?type=anime$/
// @grant		none
// @noframes
// ==/UserScript==

(function($) {

var mal = {
	cache: '4.0',
	ajax: { delay: 300, timeout: 5000 },
	name: $('#header-menu span.profile-name').text().trim(),
	type: document.URL.match(/\?type=anime$/) ? 'anime' : 'manga'
};

function main() {
	if (mal.name.length === 0) {
		return;
	}

	mal.content.setVersion('v' + GM_info.script.version);
	mal.content.body.append(mal.content.list);
	
	$('<div></div>').hide().append(mal.content.body).insertAfter('#contentWrapper');
	
	if (document.URL.match(/^http:\/\/myanimelist\.net\/panel\.php$/)) {
		pagePanel();
	}
	else {
		pageList();
	}
}

function pageList() {
	$.ajaxSetup({ timeout: mal.ajax.timeout });
	
	if (!mal.entries.checkVersion()) {
		mal.entries.clear();
		mal.entries.save();
	}

	mal.entries.load();
	mal.content.update(false);
	
	$('<span id="mr_link"></span>')
		.append('<span>&nbsp;&nbsp;|&nbsp;&nbsp;</span>')
		.append($('<a href="#mr_body">Missing Relations</a>').fancybox({
			'hideOnContentClick': false, 
			'hideOnOverlayClick': true,
			'transitionIn': 'none', 
			'transitionOut': 'none',
			'titleShow': false,	
			'scrolling': 'no'
		}))
		.append('&nbsp;(')
		.append($('<span></span>')
			.append('scan: ')
			.append($('<a href="javascript:void(0);">all</a>').click(function() {
				if (true === confirm('Recalculate all entries?')) {
					mal.entries.update(false);
				}
			}))
			.append(', ')
			.append($('<a href="javascript:void(0);">new</a>').click(function() {
				if (true === confirm('Recalculate new entries?')) {
					mal.entries.updateNew(false);
				}
			}))
			.append('&nbsp;|&nbsp;full scan: ')
			.append($('<a href="javascript:void(0);">all</a>').click(function() {
				if (true === confirm('Recalculate all entries and their relations?')) {
					mal.entries.update(true);
				}
			}))
			.append(', ')
			.append($('<a href="javascript:void(0);">new</a>').click(function() {
				if (true === confirm('Recalculate new entries and their relations?')) {
					mal.entries.updateNew(true);
				}
			}))
		)
		.append(')&nbsp;').append(mal.content.done)
		.append('&nbsp;').append(mal.content.fail)
		.appendTo('#content > div:first');
}

function pagePanel() {
	var animeLink = $('<a href="#mr_body" id="mr_link_anime" style="font-size: 11px; font-weight: normal;">Missing Anime Relations</a>'),
		mangaLink = $('<a href="#mr_body" id="mr_link_manga" style="font-size: 11px; font-weight: normal;">Missing Manga Relations</a>'),
		links = $('<div class="floatRightHeader"></div>').append(animeLink).append(' - ').append(mangaLink)
			.appendTo('#panel_left > .container > div.bgColor1:first-of-type + .spaceit');		
	
	$('a[id^="mr_link_"]', links).each(function() {
		var type = this.id.match(/^mr_link_(\w+)$/)[1];
		$(this).fancybox({
			'hideOnContentClick': false, 
			'hideOnOverlayClick': true,
			'transitionIn': 'none',
			'transitionOut': 'none',
			'titleShow': false,	
			'scrolling': 'no',
			'onStart': function() {		
				var listType = $('#mr_list_type', mal.content.body);
				mal.type = type;
				
				if (listType.length === 0 || listType.val() !== mal.type) {
					if (mal.entries.checkVersion()) {
						mal.entries.load();
					}
					else {
						mal.entries.clear();
					}
					mal.content.update(false);					
				}
			}
		});
	});
}

mal.entries = {
	version: mal.cache,
	left: {}, graph: {}, title: {}, wrong: {}, ignore: {}, // cache data
	total: 0, done: 0, fail: 0,
	right: {}, // for internal use only
			
	load: function() {
		mal.entries.clear();
		mal.entries.left = mal.loadValue('mal.entries.left', mal.entries.left);
		mal.entries.graph = mal.loadValue('mal.entries.graph', mal.entries.graph);
		mal.entries.title = mal.loadValue('mal.entries.title', mal.entries.title);
		mal.entries.wrong = mal.loadValue('mal.entries.wrong', mal.entries.wrong);
		mal.entries.ignore = mal.loadValue('mal.entries.ignore', mal.entries.ignore);
	},

	save: function() {
		mal.saveValue('mal.entries.version', mal.entries.version);
		mal.saveValue('mal.entries.left', mal.entries.left);
		mal.saveValue('mal.entries.graph', mal.entries.graph);
		mal.saveValue('mal.entries.title', mal.entries.title);
		mal.saveValue('mal.entries.wrong', mal.entries.wrong);
		mal.entries.saveIgnore();
	},
	
	saveIgnore: function() {
		mal.saveValue('mal.entries.ignore', mal.entries.ignore);
	},

	clear: function() {
		mal.entries.total = mal.entries.done = mal.entries.fail = 0;
		mal.entries.left = {};
		mal.entries.graph = {};
		mal.entries.title = {};
		mal.entries.wrong = {};
	},
	
	clearIgnore: function() {
		mal.entries.ignore = {};
	},
	
	checkVersion: function() {
		return mal.loadValue('mal.entries.version', '') === mal.entries.version;
	},
	
	isUpdating: function() {
		return (mal.entries.done + mal.entries.fail) < mal.entries.total;
	},
	
	getTitle: function(id) {
		var result = mal.entries.title.hasOwnProperty(id) ? mal.entries.title[id] : '';
		return result.length === 0 ? '?' : result;
	},
	
	update: function(fullRefresh) {
		if (!mal.entries.isUpdating()) {
			mal.entries.clear();
			mal.entries.updateNew(fullRefresh);
		}
	},
	
	updateNew: function(fullRefresh) {
		if (mal.entries.isUpdating()) {
			return;
		}
		
		var index = 0,
			links = $('#content strong + a');

		mal.entries.done = mal.entries.fail = 0;
		mal.entries.total = links.length;
		mal.entries.right = {};
		
		mal.content.done.text('');
		mal.content.fail.text('');
		$('#content span[class^="mr_status_id_"]').empty();
		
		if (links.length === 0) {
			mal.content.update(true);
			return;
		}
		
		links.each(function() {
			var id = parseInt($(this).prop('href').match(/\d+$/)[0]),
				span = $(this).parent().find('span[class="mr_status_id_' + id + '"]');
			
			if (span.length === 0) {
				span = $('<span class="mr_status_id_' + id + '"></span>').appendTo($(this).parent());
			}
			
			if (mal.entries.left.hasOwnProperty(id)) {
				mal.content.done.text('done: ' + (++mal.entries.done) + '/' + mal.entries.total);
				return;
			}
			
			mal.entries.left[id] = true;
			mal.entries.title[id] = $(this).prev('strong').text().trim();
			
			setTimeout(function() {
				$.ajax('/' + mal.type + '/' + id)
					.done(function(data) {
						var rels = mal.entries.findRelations(id, data);
						if (!mal.entries.checkRelation(data)) {
							mal.entries.wrong[id] = true;
						}

						if (fullRefresh) {
							$.each(rels, function(i, id) {
								mal.entries.right[id] = true;
							});
						}
		
						span.html('<small style="color: green;">done</small>');
						mal.content.done.text('done: ' + (++mal.entries.done) + '/' + mal.entries.total);
						
						if (fullRefresh) {
							mal.entries.updateFull();
						}
						else {
							mal.content.update(true);
						}
					})
					.fail(function() {
						span.html('<small style="color: red;">fail</small>');
						mal.content.fail.text('fail: ' + (++mal.entries.fail));
						
						if (fullRefresh) {
							mal.entries.updateFull();
						}
						else {
							mal.content.update(true);
						}
					});
			}, mal.ajax.delay * (index++));
		});
	},
	
	updateFull: function() {
		if (mal.entries.isUpdating()) {
			return;
		}
		
		$.each(mal.entries.right, function(id) {
			if (mal.entries.left.hasOwnProperty(id)) {
				delete mal.entries.right[id];
			}
		});
		
		var index = 0,
			doneStr = 'done: ' + mal.entries.done + '/' + mal.entries.total,
			failStr = 'fail: ' + mal.entries.fail;
		
		mal.entries.done = mal.entries.fail = 0;
		mal.entries.total = Object.keys(mal.entries.right).length;
		
		if (mal.entries.total === 0) {
			mal.content.update(true);
			return;
		}

		$.each(mal.entries.right, function(id) {
			setTimeout(function() { 
				$.ajax('/' + mal.type + '/' + id)
					.done(function(data) {
						mal.entries.findRelations(id, data);
						mal.content.done.text(doneStr + '+' + (++mal.entries.done) + '/' + mal.entries.total);
						mal.content.update(true);
					})
					.fail(function() {
						mal.content.fail.text(failStr + '+' + (++mal.entries.fail));
						mal.content.update(true);
					});
			}, mal.ajax.delay * (index++));
		});
	},
	
	comparator: function(a, b) {
		var aTitle = mal.entries.getTitle(a).toLowerCase(),
			bTitle = mal.entries.getTitle(b).toLowerCase();
		return aTitle.localeCompare(bTitle);
	},
	
	findRelations: function(lId, data) {
		var result = [],
			cnRe = />Related (Anime|Manga)<\/h2>[\s\S]*?<h2>/,
			idRe = new RegExp('/' + mal.type + '/(\\d+)/');

		$('a', '<context>' + data.match(cnRe) + '</context>').each(function() {
			var idData = $(this).prop('href').match(idRe);
			if (idData !== null && idData.length > 1) {
				var rId = parseInt(idData[1]);
				mal.entries.title[rId] = $(this).text().trim();
				mal.entries.addRelation(lId, rId);
				result.push(rId);
			}
		});
		
		return result;
	},
	
	addRelation: function(lId, rId) {
		if (!mal.entries.graph.hasOwnProperty(lId)) {
			mal.entries.graph[lId] = [];
		}
		if (!mal.entries.graph.hasOwnProperty(rId)) {
			mal.entries.graph[rId] = [];
		}
		if (mal.entries.graph[lId].indexOf(rId) < 0) {
			mal.entries.graph[lId].push(rId);
			mal.entries.graph[rId].push(lId);
		}
	},
	
	checkRelation: function(data) {
		var myStatusData = data.match(/selected>(.*?)<\/option/);
		if (myStatusData === null) {
			return false;
		}
		
		var status = data.match(/>Status:<\/span>([\s\S]*?)<\/div>/)[1].trim();
		var myStatus = myStatusData[1].trim();

		if ((status.match(/Not yet/) && !myStatus.match(/Plan to/)) ||
			(status.match(/(Currently|Publishing)/) && myStatus === 'Completed')) {
			return false;
		}
		
		if (myStatus !== 'Completed') {
			return true;
		}
		
		function check(type, selector) {
			var progRe = new RegExp('>' + type + ':</span>([\\s\\S]*?)</div>', 'i'),
				myprRe = new RegExp(selector + '[\\s\\S]*?value="(\\d*)"'),
				prog = data.match(progRe)[1].trim().replace('Unknown', '0'),
				mypr = data.match(myprRe)[1].trim();				
			return parseInt(mypr) === parseInt(prog);
		}
		
		if (mal.type === 'anime') {
			if (!check('Episodes', 'name="myinfo_watchedeps"')) {
				return false;
			}
		}
		else {	
			if (!check('Volumes', 'id="myinfo_volumes"') ||
				!check('Chapters', 'id="myinfo_chapters"')){
				return false;
			}
		}
		
		return true;
	},
	
	findComps: function() {
		var result = {}, used = {}, comp = [];
		
		function dfs(v) {
			used[v] = true;
			comp.push(v);
			
			if (!mal.entries.graph.hasOwnProperty(v)) {
				return;
			}
			
			$.each(mal.entries.graph[v], function(i, to) {
				if (!used.hasOwnProperty(to)) {
					dfs(to);
				}
			});
		}

		$.each(mal.entries.graph, function(v) {
			if (!used.hasOwnProperty(v)) {
				comp = [];
				dfs(v);
				if (comp.length > 1) {
					result[v] = comp;
				}
			}
		});
		
		return result;
	}
};

mal.content = {
	body: $('<div id="mr_body"><h2 id="mr_body_title">Missing Relations <span><a id="mr_version" href="http://greasyfork.org/scripts/9261" target="_blank"></a></span></h2></div>'),
	list: $('<div id="mr_list"></div>'),
	done: $('<span id="mr_status_done" style="color: green;"></span>'),
	fail: $('<span id="mr_status_fail" style="color: #c32;"></span>'),
	
	setVersion: function(str) {
		$('#mr_version', mal.content.body).text(str);
	},
	
	update: function(save) {
		if (mal.entries.isUpdating()) {
			return;
		}

		if (save === true) {
			mal.entries.save();
		}
		
		var title = $('#mr_body_title', mal.content.body),
			listType = $('<input type="hidden" id="mr_list_type" value="' + mal.type + '" />');
		
		title.html(title.html().replace(/Missing (.*?)Relations/, 'Missing ' + (mal.type === 'anime' ? 'Anime' : 'Manga') + ' Relations'));
		
		var comps = mal.entries.findComps();
		
		if (Object.keys(comps).length === 0) {
			var p = $('<p>No missing relations found.</p>');
			if (document.URL.match(/^http:\/\/myanimelist\.net\/panel\.php$/)) {
				p.append(' ').append('<a href="' + (mal.type === 'anime' ? '/editlist.php?type=anime' : '/panel.php?go=editmanga') + '">Refresh</a>');
			}
			mal.content.list.empty().append(p).append(listType);
			return;
		}
			
		var table = $('<table id="relTable" border="0" cellpadding="0" cellspacing="0" width="100%"><thead><tr><th>You\'ve ' + (mal.type === 'anime' ? 'watched' : 'read') + ' this…</th><th>…so you might want to check this:</th></tr></table>'),
		    undel = $('<div id="mr_undelete"><p id="mr_undelete_msg" style="display: none;">There are <span id="mr_undelete_num" style="font-weight: bold;"></span> hidden relations. <a href="javascript:void(0);" title="Show ignored relations" onclick="window.showIgnoredRelations();">Show them</a></p></div>'),
			tfoot = $('<tfoot><tr><td class="mr_td_left"><div class="mr_count"><span></span></div></td><td class="mr_td_right"><div class="mr_count"><span></span></div></td></tr></tfoot>');
		
		// red relations
		var wrong = Object.keys(mal.entries.wrong);
		if (wrong.length > 0) {			
			var ul = $('<ul></ul>'), size = 0;
			
			$.each(wrong.sort(mal.entries.comparator), function(i, id) {
				mal.content.getLiLeft(id).prop('id', 'mr_li_red_' + id).appendTo(ul);
				++size;
			});
				
			var tbody = $('<tbody></tbody>'),
				tr = $('<tr class="mr_tr_data"></tr>')
					.append($('<td class="mr_td_left"></td>').append(ul))
					.append($('<td class="mr_td_right"></td>').append(mal.content.getEntryWarning()))
					.appendTo(tbody);
				
			if (size > 5) {
				tr.addClass('mr_tr_collapsed');
				$('<tr class="mr_tr_more"></tr>').append(mal.content.getMoreLink()).insertAfter(tr);
			}
			
			tbody.appendTo(table);
		}
		
		// normal relations
		$.each(comps, function(i, comp) {			
			var ulLeft = $('<ul></ul>'), ulRight = $('<ul></ul>'),
				lSize = 0, rSize = 0;
			
			$.each(comp.sort(mal.entries.comparator), function(i, id) {
				if (mal.entries.left.hasOwnProperty(id)) {
					mal.content.getLiLeft(id).prop('id', 'mr_li_' + id).appendTo(ulLeft);
					++lSize;
				}
				else {
					mal.content.getLiRight(id).prop('id', 'mr_li_' + id).appendTo(ulRight);
					++rSize;
				}
			});
			
			if (lSize > 0 && rSize > 0) {
				var tbody = $('<tbody></tbody>'),
					tr = $('<tr class="mr_tr_data"></tr>')
						.append($('<td class="mr_td_left"></td>').append(ulLeft))
						.append($('<td class="mr_td_right"></td>').append(ulRight))
						.appendTo(tbody);
					
				if (lSize > 5 || rSize > 5) {
					tr.addClass('mr_tr_collapsed');
					$('<tr class="mr_tr_more"></tr>').append(mal.content.getMoreLink()).insertAfter(tr);
				}
				
				tbody.appendTo(table);
			}
		});
		
		mal.content.list.empty()
			.append(undel)
			.append(table.append(tfoot))
			.append(listType);
		
		mal.hideIgnoredRelations(true);
		mal.content.updateLineCount();
	},
	
	getLiLeft: function(id) {
		return $('<li></li>')
			.append(mal.content.getEntryLink(id, mal.entries.getTitle(id)));
	},
		
	getLiRight: function(id) {
		return $('<li></li>')
			.append(mal.content.getHideButton('window.ignoreRelation(' + id + ');', 'Hide this relation'))
			.append(mal.content.getEntryLink(id, mal.entries.getTitle(id)));
	},

	getEntryLink: function(id, title) {
		return $('<a title="' + title + '"href="' + '/' + mal.type + '/' + id + '" target="_blank">' + title + '</a>');
	},

	getEntryWarning: function() {
		return $('<div class="mr_warning"><span>Wrong status or ' + (mal.type === 'anime' ? 'episode' : 'vol./chap.') + ' count</span></div>');
	},

	getHideButton: function(func, title) {
		return $('<div class="mr_hide"><span><a href="javascript:void(0);" title="' + title + '" onclick="' + func + '">x</a></span></div>');
	},
	
	getMoreLink: function() {
		var result = $('<td colspan="2"></td>');
		$('<a class="mr_more" href="javascript:void(0);">show more</a>').click(function() {
			var tr = $(this).closest('tr');
			tr.prev('.mr_tr_data').removeClass('mr_tr_collapsed');
			tr.remove();
		}).appendTo(result);
		return result;
	},

	updateLineCount: function() {
		var count = $('#relTable td.mr_td_right li:not([style*="display: none"])', mal.content.list).length,
			total = $('#relTable td.mr_td_right li', mal.content.list).length,
			left = $('#relTable td.mr_td_left li', mal.content.list).length;
		$('tfoot td.mr_td_left .mr_count span', mal.content.list).text('Total: ' + left);
		$('tfoot td.mr_td_right .mr_count span', mal.content.list).text('Total: ' + total + ', Visible: ' + count);
	}
};

mal.ignoreRelation = function(id, save) {
	var li = $('td.mr_td_right li[id="mr_li_' + id + '"]', mal.content.list);
	if (li.length === 0) {
		if (mal.entries.ignore.hasOwnProperty(id)) {
			delete mal.entries.ignore[id];
		}
		if (save) {
			mal.entries.saveIgnore();
		}
		return;
	}
	
	var row = li.hide().closest('tbody'),
		count = $('td.mr_td_right li:not([style*="display: none;"])', row).length;
		
	row.toggle(count > 0);	
	if (count <= 5) {
		$('a.mr_more', row).trigger('click');
	}
	
	mal.entries.ignore[id] = true;	
	if (save) {
		mal.entries.saveIgnore();
		count = Object.keys(mal.entries.ignore).length;
		$('#mr_undelete_num', mal.content.list).text(count);
		$('#mr_undelete_msg', mal.content.list).toggle(count > 0);
	}		
};
	
mal.hideIgnoredRelations = function(save) {
	mal.showIgnoredRelations(false);
	$.each(mal.entries.ignore, function(id) {
		mal.ignoreRelation(id, false);
	});
	
	var count = Object.keys(mal.entries.ignore).length;
	$('#mr_undelete_num', mal.content.list).text(count);
	$('#mr_undelete_msg', mal.content.list).toggle(count > 0);
	if (save) {
		mal.entries.saveIgnore();
	}
};
	
mal.showIgnoredRelations = function(save) {
	$('#mr_undelete_msg', mal.content.list).hide();
	$('li[id^="mr_li_"]', mal.content.list).show();
	$('tbody', mal.content.list).show();
	if (save) {
		mal.entries.clearIgnore();
		mal.entries.saveIgnore();
	}
};

mal.loadValue = function(key, value) {
	try {
		value = JSON.parse(localStorage.getItem(mal.name + '#' + mal.type + '#' + key)) || value;
	} catch (e) {}
	return value;
};

mal.saveValue = function(key, value) {
	localStorage.setItem(mal.name + '#' + mal.type + '#' + key, JSON.stringify(value));
};

window.ignoreRelation = function(id) {
	mal.ignoreRelation(id, true);
	mal.content.updateLineCount();
};

window.showIgnoredRelations = function() {
	mal.showIgnoredRelations(true);
	mal.content.updateLineCount();
};

$('<style type="text/css"></style>').html(
	'#content span[class^="mr_status_id_"] { float: right; padding: 0 7px; }' +
	'div#mr_body { text-align: center; width: 670px; height: auto; }' +
	'div#mr_body a, div#mr_body a:visited { color: #1969cb; text-decoration: none; }' +
	'div#mr_body a:hover { color: #2d7de0; text-decoration: underline; }' +
	'div#mr_body #mr_body_title { font-size: 16px; font-weight: normal; text-align: center; margin: 0 0 8px 0; position: relative; border: 0; }' +
	'div#mr_body #mr_body_title span { font-size: 12px; font-weight: normal; }' +
	'div#mr_body #mr_body_title:after { content: ""; position: absolute; bottom: -14px; left: 0; width: 100%; height: 8px; border-top: 1px solid #eee; background: center bottom no-repeat radial-gradient(#f6f6f6, #fff 70%); background-size: 100% 16px; }' +
	'div#mr_body div#mr_undelete { background-color: #fff; padding: 0; margin: 0; }' +
	'div#mr_body p#mr_undelete_msg { margin: 0 0 10px; font-weight: normal; text-align: center; line-height: 20px; font-size: 13px; }' +
	'div#mr_list { width: auto; height: 680px; overflow-x: hidden; overflow-y: auto; margin: 18px auto 0; }' +
	'div#mr_list #relTable { border: 1px solid #f5f5f5; }' +
	'div#mr_list #relTable thead { background-color: #f5f5f5; }' +
	'div#mr_list #relTable th { background-color: transparent; width: 50%; padding: 5px 0 5px 6px; font-size: 12px; font-weight: bold; text-align: left; line-height: 20px !important; box-shadow: none; }' +
	'div#mr_list #relTable tbody { background-color: #fff; }' +
	'div#mr_list #relTable tbody:hover { background-color: #f5f5f5; }' +
	'div#mr_list #relTable tbody tr:first-of-type td { box-shadow: 0px 1em 1em -1em #ddd inset; }' +
	'div#mr_list #relTable td { background-color: transparent; width: 50%; padding: 5px 0 5px 6px; font-size: 13px; font-weight: normal; text-align: left; line-height: 20px !important; vertical-align: top; }' +
	'div#mr_list #relTable td div span { line-height: 20px !important; }' +
	'div#mr_list #relTable td ul { list-style-type: none; margin: 0; padding: 0; }' +
	'div#mr_list #relTable tr.mr_tr_collapsed td ul { height: 100px; overflow-y: hidden; }' +
	'div#mr_list #relTable td ul li { width: 100%; padding: 0; margin: 0; }' +
	'div#mr_list #relTable td ul li > a { display: block; width: 295px !important; line-height: 20px !important; text-overflow: ellipsis; white-space: nowrap; overflow: hidden; }' +
	'div#mr_list #relTable td.mr_td_left ul li > a { width: 310px !important; }' +
	'div#mr_list #relTable tfoot td { border-top: 1px solid #f5f5f5; }' +
	'div#mr_list #relTable td .mr_count { color: #666; font-size: 11px; font-weight: normal; text-align: left; }' +
	'div#mr_list #relTable td .mr_warning { width: 260px; color: #e43; font-size: 12px; font-weight: bold; text-align: left; }' +
	'div#mr_list #relTable td .mr_hide { display: inline-block !important; width: 15px; float: right; text-align: left; font-size: 11px; }' +
	'div#mr_list #relTable td .mr_hide a { color: #888 !important; line-height: 20px !important; font-style: normal !important; text-decoration: none !important; }' +
	'div#mr_list #relTable tr.mr_tr_more td { padding: 0 0 2px 0; }' +
	'div#mr_list #relTable td .mr_more { display: block !important; text-align: center; color: #c0c0c0 !important; font-style: normal !important; font-size: 0.9em; text-decoration: none !important; }'
).appendTo('head');

main(); 

})(jQuery);