diff src/nabble/view/naml/topic.naml @ 0:7ecd1a4ef557

add content
author Franklin Schmidt <fschmidt@gmail.com>
date Thu, 21 Mar 2019 19:15:52 -0600
parents
children 18cf4872fd7f
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/nabble/view/naml/topic.naml	Thu Mar 21 19:15:52 2019 -0600
@@ -0,0 +1,1659 @@
+<macro name="topic" requires="servlet">
+	<n.if.is_blog_topic>
+		<then.switch. value="[n.topic_view/]">
+			<n.case value="[n.classic_view/]" do="[n.classic_blog_topic/]" />
+			<n.case value="[n.list_view/]" do="[n.list_blog_topic/]" />
+			<n.case value="[n.threaded_view/]" do="[n.threaded_blog_topic/]" />
+		</then.switch.>
+		<else.switch. value="[n.topic_view/]">
+			<n.case value="[n.classic_view/]" do="[n.classic_forum_topic/]" />
+			<n.case value="[n.list_view/]" do="[n.list_forum_topic/]" />
+			<n.case value="[n.threaded_view/]" do="[n.threaded_forum_topic/]" />
+		</else.switch.>
+	</n.if.is_blog_topic>
+</macro>
+
+<macro name="topic canonical path" requires="http_request">
+	<n.get_node_from_parameter.topic_path
+		view="[n.get_parameter name='view'/]"
+		index_record="[n.get_parameter name='index_record'/]"
+	/>
+</macro>
+
+<macro name="is_blog_topic">
+	<n.regex_matches text="[n.node_page.page_node.app_or_root.type/]" pattern="news|gallery|blog"/>
+</macro>
+
+<namespace name="blog_topic_namespace" />
+<namespace name="forum_topic_namespace" />
+<namespace name="classic_view_namespace" />
+<namespace name="list_view_namespace" />
+<namespace name="threaded_view_namespace" />
+
+<subroutine name="classic_blog_topic" requires="basic,nabble,servlet">
+	<n.classic_view_namespace.blog_topic_namespace.topic_html_page/>
+</subroutine>
+
+<subroutine name="list_blog_topic" requires="basic,nabble,servlet">
+	<n.list_view_namespace.blog_topic_namespace.topic_html_page/>
+</subroutine>
+
+<subroutine name="threaded_blog_topic" requires="basic,nabble,servlet">
+	<n.threaded_view_namespace.blog_topic_namespace.topic_html_page/>
+</subroutine>
+
+<subroutine name="classic_forum_topic" requires="basic,nabble,servlet">
+	<n.classic_view_namespace.forum_topic_namespace.topic_html_page/>
+</subroutine>
+
+<subroutine name="list_forum_topic" requires="basic,nabble,servlet">
+	<n.list_view_namespace.forum_topic_namespace.topic_html_page/>
+</subroutine>
+
+<subroutine name="threaded_forum_topic" requires="basic,nabble,servlet">
+	<n.threaded_view_namespace.forum_topic_namespace.topic_html_page/>
+</subroutine>
+
+
+<macro name="topic_html_page" requires="servlet">
+	<n.topic_html/>
+</macro>
+
+<macro name="topic_html" requires="servlet">
+	<n.topic_min_html>
+		<head>
+			<n.topic_common_head/>
+			<n.topic_head/>
+			<n.topic_meta/>
+			<n.increment_view_count/>
+		</head>
+		<body>
+			<n.page_node.topic_hardcoded_notices/>
+			<n.newsflash/>
+			<n.topic_header/>
+			<n.topic_controls/>
+			<n.topic_contents.view_contents.page_node.topic_rows/>
+			<n.topic_footer/>
+		</body>
+	</n.topic_min_html>
+</macro>
+
+
+<macro name="topic_rows" requires="node,blog_topic_namespace,classic_view_namespace">
+	<n.post_list.
+		sort="date-ascending"
+		start="[n.classic_index_record/]"
+		length="[n.classic_rows_per_page/]"
+	>
+		<n.preload_messages/>
+		<n.loop.classic_row/>
+	</n.post_list.>
+</macro>
+
+<macro name="topic_rows" requires="node,blog_topic_namespace,list_view_namespace">
+	<n.post_list.
+		sort="date-ascending"
+		start="1"
+		length="10000"
+	>
+		<n.preload_messages/>
+		<n.loop.current_node.clickable_post/>
+	</n.post_list.>
+</macro>
+
+<macro name="topic_rows" requires="node,blog_topic_namespace,threaded_view_namespace">
+	<n.children_list. start="0" length="10000">
+		<n.loop.current_node.threaded_posts/>
+	</n.children_list.>
+</macro>
+
+<macro name="topic_rows" requires="node,forum_topic_namespace,classic_view_namespace">
+	<n.post_list.
+		sort="date-ascending"
+		start="[n.classic_index_record/]"
+		length="[n.classic_rows_per_page/]"
+	>
+		<n.preload_messages/>
+		<n.loop.classic_row/>
+	</n.post_list.>
+</macro>
+
+<macro name="topic_rows" requires="node,forum_topic_namespace,list_view_namespace">
+	<n.post_list.
+		sort="date-ascending"
+		start="0"
+		length="10000"
+	>
+		<n.preload_messages/>
+		<n.loop.current_node.clickable_post/>
+	</n.post_list.>
+</macro>
+
+<macro name="topic_rows" requires="node,forum_topic_namespace,threaded_view_namespace">
+	<n.threaded_posts/>
+</macro>
+
+
+<macro name="topic_min_html" parameters="head,body" requires="servlet">
+	<n.node_page.>
+		<n.topic_caching/>
+		<n.check_that_is_post/>
+		<n.html>
+			<head>
+				<n.head/>
+			</head>
+			<body>
+				<n.body/>
+				<n.topic_bottom/>
+			</body>
+		</n.html>
+	</n.node_page.>
+</macro>
+
+<macro name="topic_bottom">
+	<n.comment.>To be overridden</n.comment.>
+</macro>
+
+<macro name="topic_caching">
+	<n.uncache_for.>
+		<n.descendant_changes.page_node.id/>
+		<n.bread_crumb_changes.page_node.id/>
+	</n.uncache_for.>
+</macro>
+
+<macro name="topic_title" dot_parameter="ending">
+	<title><n.compress.>
+		<n.page_node.topic_title_contents/>
+		<n.ending/>
+	</n.compress.></title>
+</macro>
+
+<macro name="topic_title_contents" requires="node">
+	<n.if.has_property name="page_title">
+		<then.get_property name="page_title"/>
+		<else.default_topic_title_contents/>
+	</n.if.has_property>
+</macro>
+
+<macro name="default_topic_title_contents" requires="node">
+	<n.app_or_root.subject/> -
+	<n.subject/>
+</macro>
+
+<macro name="topic_meta" requires="node_page,servlet">
+	<n.if.equal value1="[n.topic_view/]" value2="[n.classic_view/]">
+		<then>
+			<n.topic_meta_description/>
+			<n.topic_meta_keywords/>
+		</then>
+		<else>
+			<n.set_var. name='canonical_url'><n.page_node.topic_path view="[n.classic_view/]"/></n.set_var.>
+			<link rel="canonical" href="[n.var name='canonical_url'/]" />
+			<META NAME="robots" CONTENT="noindex,follow"/>
+		</else>
+	</n.if.equal>
+</macro>
+
+<macro name="topic_meta_description" requires="node_page">
+	<META NAME="description" CONTENT="[n.page_number_in_brackets/][n.page_node.build_meta_description/]"/>
+</macro>
+
+<macro name="topic_meta_keywords" requires="node_page">
+	<META NAME="keywords" CONTENT="[n.page_node.build_meta_keywords/]"/>
+</macro>
+
+<macro name="check_that_is_post">
+	<n.if.page_node.is_app>
+		<then.redirect_to.page_node.url/>
+	</n.if.page_node.is_app>
+</macro>
+
+<macro name="is_blog_style">
+	<n.cache. var="is_blog_style">
+		<n.regex_matches text="[n.page_node.app_or_root.type/]" pattern="news|gallery|blog"/>
+	</n.cache.>
+</macro>
+
+<macro name="topic_common_head">
+	<n.search_highlight_js/>
+	<n.message_width_js/>
+</macro>
+
+<macro name="message_width_js">
+	<script type="text/javascript">
+		Nabble.messageTextWidth();
+	</script>
+</macro>
+
+<macro name="search_highlight_js">
+	<script type="text/javascript">
+		var terms = Nabble.getSearchTerms();
+		var hasTurnOff = false;
+		Nabble.searchHighlight = function($elem) {
+			if (terms != null && terms.length > 0) {
+				$elem.each(function() {
+					Nabble.highlightSearchTerms(terms, this);
+				});
+				if (Nabble.hasHighlightedTerms && !hasTurnOff) {
+					var turnOffLink = '<span id="turn-off-highlight-control"><span class="highlight">&nbsp;X&nbsp;</span> ';
+					turnOffLink += '<a href="javascript:void(0)" onclick="Nabble.turnOffHighlight()"><t>Turn off highlighting</t></a></span>';
+					$('#topics-controls-right').prepend(turnOffLink);
+					hasTurnOff = true;
+				}
+			}
+		};
+		Nabble.turnOffHighlight = function() {
+			Nabble.deleteCookie("query");
+			Nabble.deleteCookie("searchuser");
+			Nabble.deleteCookie("searchterms");
+			$('span.search-highlight').removeClass('bold highlight');
+			$('#turn-off-highlight-control').hide();
+		};
+	</script>
+</macro>
+
+<macro name="topic_head" requires="classic_view_namespace">
+	<n.compress.>
+		<n.search_terms_js selector="h2.post-subject,div.message-text"/>
+		<n.classic_js/>
+		<n.if.has_small_avatar>
+			<then.classic_stylesheet_small_avatar/>
+			<else.classic_stylesheet_big_avatar/>
+		</n.if.has_small_avatar>
+	</n.compress.>
+
+	<n.topic_title.>
+		<n.hide_if_equals. value1="[n.topic_page_number/]" value2="1">
+			| <t>Page <t.number.topic_page_number/></t>
+		</n.hide_if_equals.>
+	</n.topic_title.>
+</macro>
+
+<macro name="page_number_in_brackets">
+	<n.hide_if_equals. value1="[n.topic_page_number/]" value2="1">
+		[<t>Page <t.number.topic_page_number/></t>]<n.space/>
+	</n.hide_if_equals.>
+</macro>
+
+<macro name="has_small_avatar">
+	<n.is_blog_style/>
+</macro>
+
+<macro name="search_terms_js" parameters="selector">
+	<script type="text/javascript">
+		$(document).ready(function() {
+			Nabble.searchHighlight($('<n.selector/>'));
+		});
+	</script>
+	<n.call_later value="[n.page_node.id/]" param="searchSpecial"/>
+</macro>
+
+<macro name="search_terms_special_js">
+	<n.param_loop. param="searchSpecial">
+		var nodeIds = [<n.page_node.as_node_page.search_namespace.descendants_ids_matching_search_query/>];
+		for (var i=0; i <n.lt/> nodeIds.length; i++)
+			$('span.post-date'+nodeIds[i]).addClass('highlight');
+	</n.param_loop.>
+</macro>
+
+<macro name="topic_head" requires="list_view_namespace">
+	<n.compress.>
+		<n.tooltip_head/>
+		<n.search_terms_js selector="span.post-subject"/>
+		<n.ajax_posts_js view_name="list"/>
+		<n.list_stylesheet/>
+	</n.compress.>
+	<n.topic_title.>
+		| <t>List View</t>
+	</n.topic_title.>
+</macro>
+
+<macro name="topic_head" requires="threaded_view_namespace">
+	<n.compress.>
+		<n.tooltip_head/>
+		<n.search_terms_js selector="span.post-subject"/>
+		<n.ajax_posts_js view_name="threaded"/>
+		<n.tree_panning_js/>
+		<n.threaded_stylesheet/>
+	</n.compress.>
+	<n.topic_title.>
+		| <t>Threaded View</t>
+	</n.topic_title.>
+</macro>
+
+<macro name="topic_contents" dot_parameter="contents" requires="forum_topic_namespace">
+	<n.topic_contents_div.contents />
+</macro>
+
+<macro name="topic_contents_div" dot_parameter="contents">
+	<div id="topic-contents" style="margin-top:1em;clear:both">
+		<n.contents/>
+	</div>
+</macro>
+
+<macro name="classic_row_count" requires="blog_topic_namespace">
+	<n.page_node.replies/>
+</macro>
+
+<macro name="classic_row_count" requires="forum_topic_namespace">
+	<n.page_node.descendant_count/>
+</macro>
+
+<macro name="classic_row" requires="node_list">
+	<n.if.has_small_avatar>
+		<then.current_node.classic_row_with_small_avatar/>
+		<else.current_node.classic_row_with_big_avatar/>
+	</n.if.has_small_avatar>
+	<n.if.is_last_element>
+		<then.current_node.mark_as_visited/>
+	</n.if.is_last_element>
+</macro>
+
+<macro name="mark_as_visited" requires="node">
+	<n.call_later value="[n.id/]" param="markVisited"/>
+</macro>
+
+<macro name="mark_as_visited_js">
+	<n.if.visitor.is_registered>
+		<then>
+			<n.param_loop. param="markVisited">
+				<n.if_node_parameter_is_valid.>
+					<n.visitor.mark_visited node="[n.page_node.topic_node/]" last_node_id="[n.page_node.id/]"/>
+				</n.if_node_parameter_is_valid.>
+			</n.param_loop.>
+		</then>
+	</n.if.visitor.is_registered>
+</macro>
+
+<macro name="classic_pagination" parameters="margin,row_count">
+	<n.paging.
+		total_rows="[n.row_count/]"
+		current_row="[n.classic_index_record/]"
+		rows_per_page="[n.classic_rows_per_page/]"
+	>
+		<n.generic_paging>
+			<margin><n.margin/></margin>
+			<url><n.page_node.topic_path view="[n.classic_view/]" index_record="[n.page_row/]"/></url>
+		</n.generic_paging>
+	</n.paging.>
+</macro>
+
+<macro name="classic_stylesheet_big_avatar">
+	<style type="text/css">
+		div.classic-header {
+			height:2.2em;
+			clear:both;
+			overflow:hidden;
+		}
+		div.classic-author-name {
+			float:left;
+			width: 140px;
+			overflow: hidden;
+			text-align:center;
+			font-weight:bold;
+		}
+		div.classic-subject-line {
+			left:.5em;
+			overflow:hidden;
+			height:1.3em;
+			position:relative;
+		}
+		div.classic-right-menu {
+			float:right;
+			padding-left:1em;
+		}
+		div.classic-bar {
+			padding:.5em .3em;
+			clear:both;
+			height:1.8em;
+		}
+		table.classic-body {
+			border-collapse:collapse;
+			margin-bottom:1em;
+			table-layout: fixed;
+			width:100%;
+		}
+		td.classic-author {
+			vertical-align: top;
+			text-align:center;
+			width:140px;
+			padding-bottom:1em;
+		}
+		td.classic-message {
+			vertical-align:top;
+			padding:1em;
+		}
+		div.message-text {
+		    cursor:text;
+			overflow-x:auto;
+		}
+		div.avatar-inner {
+			margin-left:20px;
+		}
+		div.avatar-outer {
+			width:140px;
+			text-align:left;
+		}
+		div.avatar-label {
+			white-space:nowrap;
+			font-size:80%;
+		}
+	</style>
+</macro>
+
+<macro name="classic_stylesheet_small_avatar">
+	<style type="text/css">
+		div.classic-header {
+			height:2.2em;
+			min-height:33px;
+			clear:both;
+			overflow:hidden;
+		}
+		div.classic-bar {
+			padding:0 .4em .7em;
+			clear:both;
+			height:1.7em;
+			min-height:33px;
+		}
+		table.classic-author-name {
+			border-spacing:0;
+			width: 140px;
+			float:left;
+		}
+		table.classic-author-name td {
+			overflow-x: hidden;
+			height:2.2em;
+		}
+		table.classic-author-name td.avatar {
+			width:30px;
+			overflow:visible;
+		}
+		div.classic-subject-line {
+			left:.5em;
+			overflow-x:hidden;
+			line-height:2.4em;
+			position:relative;
+		}
+		div.classic-right-menu {
+			float:right;
+			line-height:2.4em;
+			padding-left:1em;
+		}
+		table.classic-body {
+			border-collapse:collapse;
+			margin-bottom:1em;
+			table-layout: fixed;
+			width:100%;
+		}
+		td.classic-author {
+			vertical-align: top;
+			text-align:center;
+			width:5px;
+			padding:1em 0;
+		}
+		td.classic-message {
+			vertical-align:top;
+			padding:1em;
+		}
+		div.message-text {
+		    cursor:text;
+			overflow-x:auto;
+		}
+	</style>
+</macro>
+
+<macro name="classic_row_with_small_avatar" requires="node, node_list">
+	<div class="classic-row">
+		<div class="classic-header">
+			<div class="classic-bar shaded-bg-color rounded-top">
+				<table class="classic-author-name">
+					<tr>
+						<td class="avatar"><n.owner.avatar border_class="medium-border-color"/></td>
+						<td class="bold nowrap"><n.owner.user_link class="owner-link"/></td>
+					</tr>
+				</table>
+				<div class="classic-right-menu shaded-bg-color weak-color">
+					<n.reply_link/> |
+					<n.threaded_link/> |
+					<n.post_dropdown/>
+				</div>
+				<div class="classic-subject-line">
+					<n.classic_post_date/>
+					<n.classic_subject_line/>
+				</div>
+			</div>
+		</div>
+		<table class="classic-body">
+			<tr>
+				<td class="classic-author shaded-bg-color rounded-bottom">
+					<n.red_arrow_icon/>
+				</td>
+				<td class="classic-message">
+					<n.classic_message_cell/>
+				</td>
+			</tr>
+		</table>
+	</div>
+</macro>
+
+<macro name="classic_row_with_big_avatar" requires="node, node_list">
+	<div class="classic-row">
+		<div class="classic-header">
+			<div class="classic-bar shaded-bg-color rounded-top">
+				<div class="classic-author-name nowrap">
+					<n.owner.user_link/>
+				</div>
+				<div class="classic-right-menu shaded-bg-color weak-color">
+					<n.reply_link/> |
+					<n.threaded_link/> |
+					<n.post_dropdown/>
+				</div>
+				<div class="classic-subject-line">
+					<n.red_arrow_icon/>
+					<n.classic_post_date/>
+					<n.classic_subject_line/>
+				</div>
+			</div>
+		</div>
+		<table class="classic-body">
+			<tr>
+				<td class="classic-author shaded-bg-color rounded-bottom">
+					<n.classic_big_avatar_cell/>
+				</td>
+				<td class="classic-message">
+					<n.classic_message_cell/>
+				</td>
+			</tr>
+		</table>
+	</div>
+</macro>
+
+<macro name="classic_big_avatar_cell" requires="node">
+	<div class="avatar-outer">
+		<div class="avatar-inner">
+			<n.owner.avatar size="big" border_class="medium-border-color"/>
+		</div>
+	</div>
+	<n.avatar_label condition="[n.owner.is_site_admin/]" label="[b][t]Administrator[/t][/b]"/>
+	<n.avatar_label condition="[n.owner.is_banned/]" label="[t]Banned User[/t]"/>
+	<n.owner.post_count/>
+</macro>
+
+<macro name="avatar_label" parameters="condition" dot_parameter="label">
+	<n.if.condition>
+		<then>
+			<div class="avatar-label weak-color"><n.label/></div>
+		</then>
+	</n.if.condition>
+</macro>
+
+<macro name="classic_message_cell" requires="node">
+	<n.pending_notice/>
+	<n.updated_notice/>
+	<n.reply_notice/>
+	<n.message_text/>
+</macro>
+
+<macro name="post_count" requires="user">
+	<div class="post-count[n.user_tag_id/] avatar-label weak-color"></div>
+	<n.call_later value="[n.id/]" param="postCount"/>
+</macro>
+
+<macro name="post_count_js">
+	<n.param_loop. param="postCount">
+		<n.if.not.page_user.is_deactivated>
+			<then>
+				$('div.post-count<n.page_user.user_tag_id/>')
+					.html('<n.one_or_many n="[n.page_user.post_count_value/]" one_text="[t]post[/t]" many_text="[t]posts[/t]"/>');
+			</then>
+		</n.if.not.page_user.is_deactivated>
+	</n.param_loop.>
+</macro>
+
+<macro name="updated_notice" requires="node">
+	<n.if.was_updated>
+		<then>
+			<div class="weak-color" style="font-size:80%;padding-bottom:1em">
+				<t>This post was updated on <t.date.when_updated.long_format/>.</t>
+			</div>
+		</then>
+	</n.if.was_updated>
+</macro>
+
+<macro name="pending_notice" requires="node">
+	<n.if.is_pending>
+		<then>
+			<div class="info-message rounded" style="padding:.5em;margin:-.8em -.8em .8em -.8em;font-size:90%">
+				<t>This post has NOT been accepted by the mailing list yet.</t>
+			</div>
+		</then>
+	</n.if.is_pending>
+</macro>
+
+<macro name="reply_notice" requires="node">
+	<n.if.both condition1="[n.has_previous_node/]" condition2="[n.not.parent_node.equals.previous_node/]">
+		<then>
+			<div class="weak-color" style="font-size:80%;padding-bottom:1em">
+				<t>In reply to <n.parent_link.>this post</n.parent_link.> by <t.author.parent_node.owner.name/></t>
+			</div>
+		</then>
+	</n.if.both>
+</macro>
+
+<macro name="parent_link" dot_parameter="text" requires="node">
+	<a href="[n.parent_node.url/]" rel="nofollow"><n.text/></a>
+</macro>
+
+<macro name="classic_subject_line" requires="node">
+	<h2 class="post-subject float-left adbayes-content" style="width:30%;overflow:visible;font-family:inherit">
+		<n.break_up.subject/>
+	</h2>
+</macro>
+
+<macro name="red_arrow_icon" requires="node">
+	<span id="red-arrow[n.id/]" class="float-left invisible" style="margin-top:.2em">
+		<img title="Selected post" width="15" height="15" src="/images/arrow.png" alt="Selected post"/>
+	</span>
+</macro>
+
+<macro name="all_posts_js_array">
+	<n.page_node.post_list.
+		sort="date-ascending"
+		start="0"
+		length="10000"
+	>
+		<n.loop.>
+			<n.if.not.is_first_element>
+				<then>,</then>
+			</n.if.not.is_first_element>
+			<n.current_node.id/>
+		</n.loop.>
+	</n.page_node.post_list.>
+</macro>
+
+<macro name="all_urls_js_array">
+	<n.page_node.post_list.
+		sort="date-ascending"
+		start="0"
+		length="10000"
+	>
+		<n.no_output.next_node/>
+		<n.all_urls_js_array_url/>
+		<n.loop. by="[n.classic_rows_per_page/]">
+			,<n.all_urls_js_array_url/>
+		</n.loop.>
+	</n.page_node.post_list.>
+</macro>
+
+<macro name="all_urls_js_array_url">
+	"<n.page_node.topic_path view="[n.classic_view/]" index_record="[n.current_index/]"/>"
+</macro>
+
+<macro name="classic_js">
+	<script type="text/javascript">
+		var _hash = Nabble.hash();
+		if (_hash) {
+			(function(){
+				var post = _hash.substr(2);
+				var allPosts = [<n.compress.all_posts_js_array/>];
+				var allURLs = [<n.compress.all_urls_js_array/>];
+				var iPost = allPosts.indexOf(parseInt(post));
+				var lower = <n.default. to="0"><n.classic_index_record/></n.default.>;
+				var upper = lower + <n.classic_rows_per_page/>;
+<![CDATA[
+				if (iPost != -1 && (iPost < lower || iPost >= upper))
+]]>
+					location.replace(allURLs[Math.floor(iPost/<n.classic_rows_per_page/>)]+_hash);
+			})();
+		}
+
+		$(document).ready(function() {
+			var rootId = '<n.page_node.id/>';
+<![CDATA[
+			var currentPostId = rootId;
+			var isChangingViews = _hash == '#none';
+			if (_hash && !isChangingViews)
+				currentPostId = _hash.substr(2);
+
+			Nabble.hideQuotes();
+
+			function scrollToSelectedPost() {
+				var $arrow = $('#red-arrow'+currentPostId).show();
+				if ($arrow.size() > 0) {
+					var isRootPost = currentPostId == rootId;
+					if (Nabble.isEmbedded) {
+						if (Nabble.canScroll()) scrollTo(0, 0);
+						var y = isChangingViews? null : isRootPost? 1 : $arrow.parents('div.classic-row').offset().top;
+						Nabble.resizeFrames('', y);
+					} else if (Nabble.canScroll() && !isRootPost) {
+						var yPos = $arrow.offset().top;
+						scrollTo(0,yPos-20);
+					}
+				} else {
+					if (Nabble.isEmbedded && Nabble.canScroll()) {
+						Nabble.resizeFrames('', 1);
+					} else {
+						var tb = $('div.top-bar').get(0);
+						if (tb)
+							tb.scrollIntoView();
+					}
+				}
+			};
+			$(window).load(scrollToSelectedPost);
+
+			if (Nabble.isEmbedded) {
+				$('div.message-text img').load(Nabble.resizeFrames);
+			}
+]]>
+		});
+	</script>
+</macro>
+
+<macro name="classic_post_date" requires="node">
+	<span class="post-date float-left">
+		<n.when_created.long_format/>
+	</span>
+</macro>
+
+<macro name="classic_index_record" requires="servlet">
+	<n.get_parameter name="index_record"/>
+</macro>
+
+<macro name="classic_index_record" requires="blog_topic_namespace, servlet">
+	<n.int. i="[n.default. to='0'][n.get_parameter name='index_record'/][/n.default.]">
+		<n.plus i="1"/>
+	</n.int.>
+</macro>
+
+<macro name="classic_rows_per_page">
+	20
+</macro>
+
+<macro name="view_contents" dot_parameter="rows" requires="classic_view_namespace">
+	<div id="classic-contents">
+		<n.classic_pagination margin="0 .2em .5em" row_count="[n.classic_row_count/]" />
+		<n.rows/>
+		<n.classic_pagination margin="1em .2em 0" row_count="[n.classic_row_count/]" />
+	</div>
+</macro>
+
+<macro name="view_contents" dot_parameter="rows" requires="list_view_namespace">
+	<div id="list-contents">
+		<n.rows/>
+	</div>
+</macro>
+
+<macro name="view_contents" dot_parameter="rows" requires="threaded_view_namespace">
+	<div id="threaded-contents" style="margin-left:0">
+		<n.rows/>
+	</div>
+</macro>
+
+<macro name="threaded_stylesheet">
+	<style type="text/css">
+		#topic-contents {
+			overflow:hidden;
+			cursor: url("/images/hand.png"),w-resize;
+		}
+		div.clickable-row {
+			white-space:nowrap;
+			right:1em;
+			padding:.2em 0;
+			cursor:pointer;
+		}
+		div.full-row {
+			border-width:2px;
+			border-style:solid;
+			padding:.3em .8em .5em;
+			cursor:text;
+		}
+		div.full-row-header {
+			padding-bottom:1em;
+			cursor:pointer;
+		}
+		div.full-row-header > * {
+			cursor:pointer;
+		}
+		div.connect-outer {
+			background-image:url("/images/connect-line.gif");
+		}
+		div.outer-line {
+			background-repeat: repeat-y;
+		}
+		div.outer-end {
+			background-repeat: no-repeat;
+		}
+		div.connect-inner {
+			padding-left:1em;
+			cursor: url("/images/hand.png"),w-resize;
+		}
+		div.inner-line {
+			background:none;
+		}
+		div.inner-end {
+			background:url("/images/connect-end.gif") no-repeat;
+		}
+		span.post-snippet { font-size:75%; }
+
+		div.message-text {
+		    cursor:text;
+			overflow-x:auto;
+		}
+		div.right-menu {
+			float:right;
+			padding:.3em;
+		}
+		img.view-icon {
+			border:none;
+			width:18px;
+			height:18px;
+			vertical-align:middle;
+		}
+		img.close {
+			width:11px;
+			height:11px;
+		}
+	</style>
+</macro>
+
+<macro name="tree_panning_js">
+	<script type="text/javascript">
+		$(document).ready(function() {
+			(function() {
+				var down = null;
+				var initialLeft = null;
+				var $area = $('#threaded-contents');
+				function startDrag(e) {
+					if (e.target == this) {
+						down = e.pageX;
+						initialLeft = parseInt($area.css('margin-left'));
+						return false;
+					}
+				};
+				function drag(e) {
+					if (down) {
+						var m = initialLeft + (e.pageX - down);
+						$area.css('margin-left',m > 0? '0' : m+'px');
+					}
+				};
+				function stopDrag(e){
+					down = null;
+					initialLeft = null;
+				};
+				$('div.connect-inner,#topic-contents')
+					.mousedown(startDrag)
+					.mousemove(drag)
+					.mouseup(stopDrag);
+				$(document).mouseup(stopDrag);
+			})();
+		});
+	</script>
+</macro>
+
+<macro name="ajax_posts_js" parameters="view_name">
+	<script type="text/javascript">
+		var historyLength = history.length;
+		var loadedPosts = [];
+		var allPosts = [<n.compress.all_posts_js_array/>];
+
+		function setPostHover($e) {
+			$e.hover(
+				function(){ $(this).addClass('post-hover'); },
+				function(){ $(this).removeClass('post-hover'); });
+		};
+
+		var lastPostId = <n.page_node.last_node.id/>;
+<![CDATA[
+		Nabble.markUnreadPosts = function(lastVisitedId) {
+			if (lastVisitedId == null)
+				$('div.clickable-row').css('font-weight','bold');
+			if (lastVisitedId == lastPostId)
+				return;
+			else {
+				for (var i = 0; i < allPosts.length; i++) {
+					if (allPosts[i] > lastVisitedId) {
+						$('#clickable-row'+allPosts[i]).css('font-weight','bold');
+					}
+				}
+			}
+		};
+
+		$(document).ready(function() {
+			var $dummy = $('div.clickable-row');
+			setPostHover($dummy);
+			$dummy.click(function(){
+				var postId = $(this).attr('post-id');
+				Nabble.loadPost(postId);
+			});
+
+			/* Code to open initial post */
+			(function() {
+			var _hash = Nabble.hash();
+				var postId = allPosts[0];
+				if (_hash && _hash != '#none')
+					postId = parseInt(_hash.substr(2));
+				else if (_hash == '#none')
+					postId = allPosts.length == 1? allPosts[0] : null;
+				if (postId) {
+					if (allPosts.indexOf(postId) >= 0) {
+						var $dummy = $('#clickable-row'+postId);
+						$dummy.click();
+					}
+				}
+			})();
+		});
+]]>
+
+		var isFirst = true;
+		Nabble.loadPost = function(nodeId) {
+			if (loadedPosts.indexOf(nodeId) == -1) {
+				$('#loading'+nodeId).show("fast");
+				var url = "/"+"template/NamlServlet.jtp?macro=ajax_post&view=<n.view_name/>&node="+nodeId;
+				$.get(url, function(data) {
+					$('#clickable-row'+nodeId).replaceWith(data);
+
+					var $dummy = $('#clickable-row'+nodeId);
+					var $full = $('#full-row'+nodeId);
+
+					/* Click event that collapses the post  */
+					$full.children('div.full-row-header').click(function(e){
+						var t = e.target;
+						if (t == this || $(t).hasClass('close') || (t.nodeName != 'A' && t.nodeName != 'IMG')) {
+							$full.slideUp("normal", function() {
+								$dummy.show();
+								Nabble.resizeFrames();
+							});
+						}
+					});
+
+					/* Click event that expands the post  */
+					$dummy.click(function() {
+						$dummy.hide();
+						$full.slideDown('normal',Nabble.resizeFrames);
+					});
+					setPostHover($dummy);
+
+					var $msg = $('#message'+nodeId);
+					if (Nabble.isEmbedded) {
+						$('img',$msg).load(Nabble.resizeFrames);
+					}
+					Nabble.searchHighlight($msg);
+
+					<n.ajax_post_custom_scripts/>
+
+					$full.slideDown('normal',function(){
+						Nabble.hideQuotes(this);
+						if (isFirst) {
+							var isRootPost = nodeId == allPosts[0];
+							if (Nabble.isEmbedded) {
+								if (Nabble.canScroll()) scrollTo(0,0);
+								var y = isRootPost? 1 : $full.offset().top-30;
+								Nabble.resizeFrames('', y);
+							} else {
+								scrollTo(0,0);
+								if (!isRootPost)
+									scrollBy(0,$full.offset().top);
+							}
+							isFirst = false;
+						}
+					});
+					loadedPosts.push(nodeId);
+				});
+			}
+		};
+	</script>
+	<n.call_later value="[n.page_node.id/]" param="markUnreadPosts"/>
+</macro>
+
+<macro name="ajax_post_custom_scripts">
+	<n.comment>To be overridden</n.comment>
+</macro>
+
+<macro name="mark_unread_posts_js">
+	<n.if.visitor.is_registered>
+		<then>
+			<n.param_loop. param="markUnreadPosts">
+				<n.set_var. name='last_id'>
+					<n.if.visitor.has_visited_node node_id="[n.current_parameter_value/]">
+						<then.visitor.last_visited_node. node_id="[n.current_parameter_value/]">
+							<n.id/>
+						</then.visitor.last_visited_node.>
+						<else>null</else>
+					</n.if.visitor.has_visited_node>
+				</n.set_var.>
+				Nabble.markUnreadPosts(<n.var name='last_id'/>);
+			</n.param_loop.>
+		</then>
+	</n.if.visitor.is_registered>
+</macro>
+
+<subroutine name="threaded_posts" requires="basic,nabble,servlet,node">
+	<n.if.call_depth.is_greater_than i="60">
+		<then>
+				<div class="info-message" style="padding:.5em 1em">
+					<t>This branch is too big and some posts were omitted. Use the other views to read all posts.</t>
+				</div>
+			</then>
+		<else>
+			<div>
+				<n.clickable_post/>
+				<n.children_list. start="0" length="10000">
+					<n.loop.>
+						<div class="connect-outer outer-[n.connect_class_suffix/]">
+							<div class="connect-inner inner-[n.connect_class_suffix/]">
+								<n.current_node.threaded_posts/>
+							</div>
+						</div>
+					</n.loop.>
+				</n.children_list.>
+			</div>
+		</else>
+	</n.if.call_depth.is_greater_than>
+</subroutine>
+
+<macro name="connect_class_suffix" requires="node_list">
+	<n.if.is_last_element>
+		<then>end</then>
+		<else>line</else>
+	</n.if.is_last_element>
+</macro>
+
+<macro name="clickable_post" requires="node">
+	<div id="clickable-row[n.id/]" class="clickable-row" post-id="[n.id/]">
+		<n.post_short_date/>
+		<n.post_author/>
+		<n.post_subject separator="&ndash;"/>
+		<n.post_snippet/>
+		<div id="loading[n.id/]" class="important invisible"><t>Loading...</t></div>
+	</div>
+</macro>
+
+<macro name="ajax_post" requires="servlet">
+	<n.uncache_for.node_changes.get_parameter name="node"/>
+	<n.ajax. is_cached="true">
+		<n.node_page.>
+			<n.page_node.>
+				<n.mark_as_visited/>
+				<div id="clickable-row[n.id/]" class="clickable-row invisible">
+					<n.post_short_date/>
+					<n.post_author/>
+					<n.post_subject/>
+					<n.post_snippet/>
+				</div>
+				<div id="full-row[n.id/]" class="full-row medium-border-color invisible">
+					<div class="full-row-header">
+						<div class="right-menu">
+							<n.change_view_links/>
+							&nbsp;
+							<n.reply_link/>
+							&nbsp;
+							<n.post_dropdown/>
+							&nbsp;
+							<img src="/images/close.png" class="close" alt="Close"/>
+						</div>
+						<n.post_long_date/>
+						<n.owner.avatar size="small"/>
+						<n.owner.user_link/>
+						<n.post_subject/>
+					</div>
+					<n.pending_notice/>
+					<n.updated_notice/>
+					<n.message_text/>
+				</div>
+			</n.page_node.>
+		</n.node_page.>
+	</n.ajax.>
+</macro>
+
+<macro name="message_text" requires="node">
+	<div id="message[n.id/]" class="message-text adbayes-content">
+		<n.message_with_signature/>
+	</div>
+</macro>
+
+<macro name="change_view_links" requires="node">
+	<n.if.equal value1="[n.get_parameter name='view'/]" value2="[n.threaded_view/]">
+		<then>
+			<n.classic_icon_link/>
+			<n.list_icon_link/>
+		</then>
+		<else>
+			<n.classic_icon_link/>
+			<n.threaded_icon_link/>
+		</else>
+	</n.if.equal>
+</macro>
+
+<macro name="list_stylesheet">
+	<style type="text/css">
+		#topic-contents {
+			overflow:hidden;
+		}
+		div.clickable-row {
+			white-space:nowrap;
+			right:1em;
+			padding:.2em 0;
+			cursor:pointer;
+		}
+		div.full-row {
+			border-width:2px;
+			border-style:solid;
+			padding:.3em .8em .5em;
+			cursor:text;
+		}
+		div.full-row-header {
+			padding-bottom:1em;
+			cursor:pointer;
+		}
+		div.full-row-header > * {
+			cursor:pointer;
+		}
+		span.post-snippet { font-size:75%; }
+
+		div.message-text {
+		    cursor:text;
+			overflow-x:auto;
+		}
+		div.right-menu {
+			float:right;
+			padding:.3em;
+		}
+		img.view-icon {
+			border:none;
+			width:18px;
+			height:18px;
+			vertical-align:middle;
+		}
+		img.close {
+			width:11px;
+			height:11px;
+		}
+	</style>
+</macro>
+
+<macro name="post_short_date" requires="node">
+	<span class="post-date post-date[n.id/]">
+		<n.when_created.short_format/>
+	</span>
+</macro>
+
+<macro name="post_long_date" requires="node">
+	<span class="post-date post-date[n.id/]">
+		<n.when_created.long_format />
+	</span>
+</macro>
+
+<macro name="post_author" requires="node">
+	<span class="post-author">
+		<n.owner.name/>
+	</span>
+</macro>
+
+<macro name="post_subject" parameters="separator" requires="node">
+	<n.set_var. name='parent_subject'>
+		<n.if.has_parent>
+			<then.parent_node.subject/>
+		</n.if.has_parent>
+	</n.set_var.>
+	<n.if.not.ends_with text="[n.subject/]" suffix="[n.var name='parent_subject'/]">
+		<then>
+			<span class="post-subject adbayes-content"><n.subject/> <n.hide_null.separator/></span>
+		</then>
+	</n.if.not.ends_with>
+</macro>
+
+<macro name="post_snippet" requires="node">
+	<span class="post-snippet adbayes-content">
+		<n.truncate. size="150"><n.hide_emails.message.as_text_without_quotes/></n.truncate.>
+	</span>
+</macro>
+
+<macro name="topic_footer">
+	<div id="topic-footer" class="weak-color" style="padding-top:1em">
+		<n.page_node.return_to_link/>
+		&nbsp;|&nbsp;
+		<n.page_node.views show_text="true"/>
+	</div>
+</macro>
+
+<macro name="message_count">
+	<span style="padding-right:1em">
+		<n.one_or_many.page_node.descendant_count>
+			<one_text><t>message</t></one_text>
+			<many_text><t>messages</t></many_text>
+		</n.one_or_many.page_node.descendant_count>
+	</span>
+</macro>
+
+<macro name="topic_header">
+	<div id="topic-search-box" class="search-box float-right" style="padding:.5em 0">
+		<n.page_node.search_box/>
+	</div>
+
+	<h1 id="post-title" class="adbayes-content" style="margin:0.25em 0 .8em">
+		<n.break_up.page_node.subject/>
+	</h1>
+</macro>
+
+<macro name="topic_controls" requires="forum_topic_namespace">
+	<div style="margin:1.2em 0 5em">
+		<div id="topics-controls-left" class="float-left nowrap">
+			<n.topic_controls_left/>
+		</div>
+		<div id="topics-controls-right" class="float-right nowrap" style="padding-top:.3em">
+			<n.topic_controls_right/>
+		</div>
+	</div>
+</macro>
+
+<macro name="topic_controls_left" requires="forum_topic_namespace">
+	<n.view_selectors/>
+</macro>
+
+<macro name="topic_controls_right" requires="forum_topic_namespace">
+	<n.pin_icon/>
+	<n.lock_icon/>
+	<n.message_count/>
+	<img src="/images/gear.png" class="image16" alt="[t]Options[/t]"/>
+	<n.page_node.topic_dropdown/>
+</macro>
+
+<macro name="topic_controls" requires="blog_topic_namespace">
+	<div class="weak-color float-left" style="font-variant:small-caps">
+		<n.topic_left_controls/>
+	</div>
+
+	<div class="float-right" style="padding:.4em 0">
+		<n.topic_right_controls/>
+	</div>
+
+	<n.root_post_message/>
+</macro>
+
+<macro name="topic_right_controls" requires="blog_topic_namespace">
+	<n.root_dropdown/>
+</macro>
+
+<macro name="root_post_message">
+	<div class="root-text adbayes-content" style="margin:6em 0 2em;clear:both">
+		<n.page_node.node_message_as_html/>
+	</div>
+</macro>
+
+<macro name="topic_left_controls" requires="blog_topic_namespace">
+	<t>Posted by
+		<t.author>
+			<n.page_node.owner.avatar size="small"/>
+			<n.page_node.owner.user_link/>
+		</t.author></t>
+	&ndash;
+	<n.page_node.when_created.long_format/>
+</macro>
+
+<macro name="root_dropdown" requires="node_page">
+	<img src="/images/gear.png" class="image16" alt="[t]Options[/t]"/>
+	<n.page_node.root_post_dropdown/>
+</macro>
+
+<macro name="topic_contents" dot_parameter="contents" requires="blog_topic_namespace">
+	<div id="comment-section">
+		<n.if.page_node.has_replies>
+			<then>
+				<h2 class="second-font big-title" style="margin-bottom: .5em">
+					<n.one_or_many.page_node.replies>
+						<one_text><t>Comment</t></one_text>
+						<many_text><t>Comments</t></many_text>
+					</n.one_or_many.page_node.replies>
+				</h2>
+				<n.view_selectors/>
+			</then>
+		</n.if.page_node.has_replies>
+
+		<n.topic_contents_div.contents/>
+
+		<n.add_new_comment_link/>
+	</div>
+</macro>
+
+<macro name="add_new_comment_link">
+	<div class="shaded-bg-color rounded" style="width:25em;margin:1em 0 2em;padding: .5em">
+		<div style="float:left;margin-right:.5em">
+			<img src="/images/icon_post_message.png" class="image16" alt="[t]Post message[/t]"/>
+		</div>
+		<a href="[n.page_node.reply_path/]" rel="nofollow"><t>Add a new comment</t></a>
+	</div>
+</macro>
+
+<macro name="view_selectors">
+	<table>
+		<tr>
+			<n.topic_view_option name="[t]Classic[/t]" value="classic" image="view-classic.gif">
+				<url><n.page_node.topic_path view="[n.classic_view/]"/></url>
+			</n.topic_view_option>
+
+			<n.topic_view_option name="[t]List[/t]" value="list" image="view-list.gif">
+				<url><n.page_node.topic_path view="[n.list_view/]"/></url>
+			</n.topic_view_option>
+
+			<n.topic_view_option name="[t]Threaded[/t]" value="threaded" image="view-threaded.gif">
+				<url><n.page_node.topic_path view="[n.threaded_view/]"/></url>
+			</n.topic_view_option>
+		</tr>
+	</table>
+</macro>
+
+<macro name="topic_view" requires="servlet">
+	<n.get_parameter name="view"/>
+</macro>
+
+<macro name="classic_view">
+	classic
+</macro>
+
+<macro name="list_view">
+	list
+</macro>
+
+<macro name="threaded_view">
+	threaded
+</macro>
+
+<macro name="topic_page_number" requires="servlet">
+	<n.paging.
+		total_rows="0"
+		current_row="[n.classic_index_record/]"
+		rows_per_page="[n.classic_rows_per_page/]"
+	>
+		<n.current_page_number/>
+	</n.paging.>
+</macro>
+
+<macro name="topic_path" parameters="view,index_record,selected_id" requires="node">
+	<n.set_var. name="index_record">
+		<n.to_null_if. equals="0">
+			<n.index_record/>
+		</n.to_null_if.>
+	</n.set_var.>
+	<n.remove_spaces.>
+		/<n.url_encoded_subject/>
+		-t<n.view_char view="[n.view/]"/><n.id/>
+		<n.hide_null.prepend. prefix="i"><n.var name="index_record"/></n.hide_null.prepend.>
+		.html
+		<n.if>
+			<condition.both>
+				<condition1><n.not.is_null.selected_id/></condition1>
+				<condition2><n.not.equal value1="[n.id/]" value2="[n.selected_id/]"/></condition2>
+			</condition.both>
+			<then>
+				#a<n.selected_id/>
+			</then>
+		</n.if>
+	</n.remove_spaces.>
+</macro>
+
+<macro name="view_char" parameters="view">
+	<n.if.equal value1="[n.view/]" value2="[n.classic_view/]">
+		<then>d</then>
+		<else.if.equal value1="[n.view/]" value2="[n.threaded_view/]">
+			<then>t</then>
+			<else>c</else>
+		</else.if.equal>
+	</n.if.equal>
+</macro>
+
+<macro name="topic_path_for" dot_parameter="view" requires="node">
+	<n.set_var. name='id'><n.id/></n.set_var.>
+	<n.set_var. name='path'><n.topic_node.topic_path view="[n.view/]" selected_id="[n.var name='id'/]"/></n.set_var.>
+	<n.var name="path"/>
+</macro>
+
+<macro name="threaded_link" requires="node">
+	<a href="javascript:void(0)" onclick="Nabble.setView('threaded', '[n.topic_path_for.threaded_view/]',[n.id/])"><t>Threaded</t></a>
+	<n.tooltip.>
+		<t>Open this post in threaded view</t>
+	</n.tooltip.>
+</macro>
+
+<macro name="classic_icon_link" requires="node">
+	<a href="javascript:void(0)" onclick="Nabble.setView('classic', '[n.topic_path_for.classic_view/]',[n.id/])"><img src="/images/view-classic.gif" class="view-icon" alt="Classic"/></a>
+	<n.tooltip.>
+		<t>Open this post in classic view</t>
+	</n.tooltip.>
+</macro>
+
+<macro name="list_icon_link" requires="node">
+	<a href="javascript:void(0)" onclick="Nabble.setView('list', '[n.topic_path_for.list_view/]',[n.id/])"><img src="/images/view-list.gif" class="view-icon" alt="List"/></a>
+	<n.tooltip.>
+		<t>Open this post in list view</t>
+	</n.tooltip.>
+</macro>
+
+<macro name="threaded_icon_link" requires="node">
+	<a href="javascript:void(0)" onclick="Nabble.setView('threaded', '[n.topic_path_for.threaded_view/]',[n.id/])"><img src="/images/view-threaded.gif" class="view-icon" alt="Threaded"/></a>
+	<n.tooltip.>
+		<t>Open this post in threaded view</t>
+	</n.tooltip.>
+</macro>
+
+<macro name="topic_view_option" parameters="name,value,image,url">
+	<n.put_in_head.>
+		<script type="text/javascript">
+			Nabble.setView = function(view,url,post) {
+				Nabble.setVar("tview",view);
+				if (url.indexOf('#') == -1)
+					url += '#none';
+				location.replace(url);
+			};
+		</script>
+	</n.put_in_head.>
+
+	<n.topic_view_option_td value="[n.value/]" url="[n.url/]" style="padding-right:.1em">
+		<contents><img src="/images/[n.image/]" width="18" height="18" style="border:none" alt="[n.value/]"/></contents>
+	</n.topic_view_option_td>
+
+	<n.topic_view_option_td value="[n.value/]" url="[n.url/]" style="padding-right:1.1em">
+		<contents><n.name/></contents>
+	</n.topic_view_option_td>
+</macro>
+
+<macro name="topic_view_option_td" parameters="value,url,contents,style">
+	<td style="[n.style/]">
+		<n.if.equal value1="[n.topic_view/]" value2="[n.value/]">
+			<then><n.contents/></then>
+			<else><a href="javascript:void(0)" onclick="Nabble.setView('[n.value/]', '[n.url/]',null)"><n.contents/></a></else>
+		</n.if.equal>
+	</td>
+</macro>
+
+<macro name="raw_mail" requires="servlet">
+	<n.set_response_header name="Content-Type" value="text/plain; charset=iso-8859-1"/>
+	<n.node_page.>
+		<n.if.either condition1="[n.visitor.can_edit.page_node/]" condition2="[n.visitor.is_sysadmin/]">
+			<then.page_node.message.as_raw/>
+		</n.if.either>
+	</n.node_page.>
+</macro>
+
+<macro name="topic_hardcoded_notices" requires="node_page">
+	<n.inactive_node_deletion_ui/>
+</macro>
+
+<macro name="page_node_is_scheduled_for_deletion" requires="node_page">
+	<n.both>
+		<condition1><n.page_node.is_root/></condition1>
+		<condition2><n.site_has_delete_date/></condition2>
+	</n.both>
+</macro>
+
+<macro name="pin_icon">
+	<span style="padding-right:1em;height:21px">
+		<img id="pin-icon" src="/images/pin.png" width="20" height="21" title="[t]This topic has been pinned in [t.location.page_node.app_or_root.subject/].[/t]" style="vertical-align:middle;[n.hidden_if.not.page_node.is_pinned/]"/>
+		<n.tooltip use_title="true"/>
+	</span>
+</macro>
+
+<macro name="pin_topic_link" requires="node" dot_parameter="text" parameters="title, class">
+	<n.put_in_head.>
+		<script type="text/javascript">
+			Nabble.pinTopic = function(id) {
+				var call = '/' + 'template/NamlServlet.jtp?macro=pin_topic&node=' + id;
+				$.getScript(call, function() {
+					$('#pin-icon').show();
+					NabbleDropdown.show('unpinTopic');
+					NabbleDropdown.hide('pinTopic');
+					alert('<t>This topic has been pinned.</t>');
+				});
+			};
+		</script>
+	</n.put_in_head.>
+	<a href="javascript: void Nabble.pinTopic([n.id/])" class="[n.class/]" rel="nofollow" title="[n.title/]"><n.default. to="[t]Pin topic[/t]"><n.text/></n.default.></a>
+</macro>
+
+<macro name="unpin_topic_link" requires="node" dot_parameter="text" parameters="title, class">
+	<n.put_in_head.>
+		<script type="text/javascript">
+			Nabble.unpinTopic = function(id) {
+				var call = '/'+'template/NamlServlet.jtp?macro=unpin_topic&node=' + id;
+				$.getScript(call, function() {
+					$('#pin-icon').hide();
+					NabbleDropdown.hide('unpinTopic');
+					NabbleDropdown.show('pinTopic');
+					alert('<t>This topic has been unpinned.</t>');
+				});
+			};
+		</script>
+	</n.put_in_head.>
+	<a href="javascript: void Nabble.unpinTopic([n.id/])" class="[n.class/]" rel="nofollow" title="[n.title/]"><n.default. to="[t]Unpin topic[/t]"><n.text/></n.default.></a>
+</macro>
+
+<macro name="pin_topic" requires="servlet">
+	<n.node_page.>
+		<n.if.both condition1="[n.visitor.can_manage_pinned_topics_in.page_node/]" condition2="[n.not.page_node.is_pinned/]">
+			<then><n.page_node.pin/></then>
+		</n.if.both>
+	</n.node_page.>
+</macro>
+
+<macro name="unpin_topic" requires="servlet">
+	<n.node_page.>
+		<n.if.both condition1="[n.visitor.can_manage_pinned_topics_in.page_node/]" condition2="[n.page_node.is_pinned/]">
+			<then><n.page_node.unpin/></then>
+		</n.if.both>
+	</n.node_page.>
+</macro>
+
+<macro name="lock_icon">
+	<span id="lock-icon" class="weak-color" style="padding:0 .5em;margin-right:.5em;[n.hidden_if.not.page_node.is_locked_topic/]">
+		<img src="/images/lock_sm.png" width="10" height="15" style="vertical-align:middle"/> <t>Locked</t>
+	</span>
+</macro>
+
+<macro name="lock_topic_link" requires="node" dot_parameter="text" parameters="title, class">
+	<n.put_in_head.>
+		<script type="text/javascript">
+			Nabble.lockTopic = function(id) {
+				var call = '/'+'template/NamlServlet.jtp?macro=lock_topic&node=' + id;
+				$.getScript(call, function() {
+					$('#lock-icon').show();
+					NabbleDropdown.show('unlockTopic');
+					NabbleDropdown.hide('lockTopic');
+					alert('<t>This topic has been locked.</t>');
+				});
+			};
+		</script>
+	</n.put_in_head.>
+	<a href="javascript: void Nabble.lockTopic([n.id/])" class="[n.class/]" rel="nofollow" title="[n.title/]"><n.default. to="[t]Lock topic[/t]"><n.text/></n.default.></a>
+</macro>
+
+<macro name="lock_topic" requires="servlet">
+	<n.node_page.>
+		<n.if.both condition1="[n.visitor.can_manage_locked_topics_in.page_node/]" condition2="[n.not.page_node.is_locked_topic/]">
+			<then.edit_page_node.>
+				<n.add_permission permission="[n.reply_permission/]"/>
+			</then.edit_page_node.>
+		</n.if.both>
+	</n.node_page.>
+</macro>
+
+<macro name="unlock_topic_link" requires="node" dot_parameter="text" parameters="title, class">
+	<n.put_in_head.>
+		<script type="text/javascript">
+			Nabble.unlockTopic = function(id) {
+				var call = '/'+'template/NamlServlet.jtp?macro=unlock_topic&node=' + id;
+				$.getScript(call, function() {
+					$('#lock-icon').hide();
+					NabbleDropdown.hide('unlockTopic');
+					NabbleDropdown.show('lockTopic');
+					alert('<t>This topic has been unlocked.</t>');
+				});
+			};
+		</script>
+	</n.put_in_head.>
+	<a href="javascript: void Nabble.unlockTopic([n.id/])" class="[n.class/]" rel="nofollow" title="[n.title/]"><n.default. to="[t]Unlock topic[/t]"><n.text/></n.default.></a>
+</macro>
+
+<macro name="unlock_topic" requires="servlet">
+	<n.node_page.>
+		<n.if.both condition1="[n.visitor.can_manage_locked_topics_in.page_node/]" condition2="[n.page_node.is_locked_topic/]">
+			<then.edit_page_node.>
+				<n.remove_permission permission="[n.reply_permission/]"/>
+			</then.edit_page_node.>
+		</n.if.both>
+	</n.node_page.>
+</macro>
+
+<macro name="is_locked_topic" requires="node">
+	<n.both>
+		<condition1.node_has_permission.reply_permission />
+		<condition2.not.groups_have_permission groups="[n.registered_user_groups/]" permission="[n.reply_permission/]" />
+	</n.both>
+</macro>
+
+<macro name="smart_post_link" requires="node" dot_parameter="href" parameters="text, title, class">
+	<n.if.is_post>
+		<then>
+			<a href="[n.node_href.href/]" title="[n.title/]" class="[n.hide_null.class/] post-link[n.topic_node.id/]" node-id="[n.id/]"><n.node_text.text/></a>
+			<n.call_later value="[n.topic_node.id/]" param="markUnreadTopics"/>
+		</then>
+		<else.node_link text="[n.text/]"/>
+	</n.if.is_post>
+</macro>
+
+<macro name="mark_unread_topics_js">
+	<n.if.visitor.is_registered>
+		<then>
+			<![CDATA[
+			$('#nabble').append('<a id="not-visited" class="invisible" href="/any-url">x</a> <a id="visited" class="visited-link invisible" href="#">x</a>');
+			var notVisitedColor = $('#not-visited').css('color');
+			var visitedColor = $('#visited').css('color');
+			Nabble.markUnreadTopics = function(topic, lastVisitedId) {
+				$('a.post-link'+topic).each(function() {
+					var nodeId = $(this).attr('node-id');
+					var isVisited = lastVisitedId && lastVisitedId > 0 && parseInt(nodeId) <= lastVisitedId;
+					if (isVisited)
+						$(this).addClass('visited-link');
+					else {
+						var $this = $(this);
+						$this
+							.css('color', notVisitedColor)
+							.click(function() {
+								$this.css('color',visitedColor);
+							});
+					}
+				});
+			};
+			]]>
+			<n.param_loop. param="markUnreadTopics">
+				<n.set_var. name='last_visited_id'>
+					<n.if.visitor.has_visited_node node_id="[n.current_parameter_value/]">
+						<then.visitor.last_visited_node. node_id="[n.current_parameter_value/]">
+							<n.id/>
+						</then.visitor.last_visited_node.>
+						<else>null</else>
+					</n.if.visitor.has_visited_node>
+				</n.set_var.>
+				Nabble.markUnreadTopics(<n.current_parameter_value/>, <n.var name='last_visited_id'/>);
+			</n.param_loop.>
+		</then>
+	</n.if.visitor.is_registered>
+</macro>