<!--{{{-->
<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml' />
<!--}}}-->
Background: #fff
Foreground: #000
PrimaryPale: #8cf
PrimaryLight: #18f
PrimaryMid: #04b
PrimaryDark: #014
SecondaryPale: #ffc
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #841
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #666
Error: #f88
/*{{{*/
body {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}

a {color:[[ColorPalette::PrimaryMid]];}
a:hover {background-color:[[ColorPalette::PrimaryMid]]; color:[[ColorPalette::Background]];}
a img {border:0;}

h1,h2,h3,h4,h5,h6 {color:[[ColorPalette::SecondaryDark]]; background:transparent;}
h1 {border-bottom:2px solid [[ColorPalette::TertiaryLight]];}
h2,h3 {border-bottom:1px solid [[ColorPalette::TertiaryLight]];}

.button {color:[[ColorPalette::PrimaryDark]]; border:1px solid [[ColorPalette::Background]];}
.button:hover {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::SecondaryLight]]; border-color:[[ColorPalette::SecondaryMid]];}
.button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::SecondaryDark]];}

.header {background:[[ColorPalette::PrimaryMid]];}
.headerShadow {color:[[ColorPalette::Foreground]];}
.headerShadow a {font-weight:normal; color:[[ColorPalette::Foreground]];}
.headerForeground {color:[[ColorPalette::Background]];}
.headerForeground a {font-weight:normal; color:[[ColorPalette::PrimaryPale]];}

.tabSelected{color:[[ColorPalette::PrimaryDark]];
	background:[[ColorPalette::TertiaryPale]];
	border-left:1px solid [[ColorPalette::TertiaryLight]];
	border-top:1px solid [[ColorPalette::TertiaryLight]];
	border-right:1px solid [[ColorPalette::TertiaryLight]];
}
.tabUnselected {color:[[ColorPalette::Background]]; background:[[ColorPalette::TertiaryMid]];}
.tabContents {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::TertiaryPale]]; border:1px solid [[ColorPalette::TertiaryLight]];}
.tabContents .button {border:0;}

#sidebar {}
#sidebarOptions input {border:1px solid [[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel {background:[[ColorPalette::PrimaryPale]];}
#sidebarOptions .sliderPanel a {border:none;color:[[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel a:hover {color:[[ColorPalette::Background]]; background:[[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel a:active {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::Background]];}

.wizard {background:[[ColorPalette::PrimaryPale]]; border:1px solid [[ColorPalette::PrimaryMid]];}
.wizard h1 {color:[[ColorPalette::PrimaryDark]]; border:none;}
.wizard h2 {color:[[ColorPalette::Foreground]]; border:none;}
.wizardStep {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];
	border:1px solid [[ColorPalette::PrimaryMid]];}
.wizardStep.wizardStepDone {background:[[ColorPalette::TertiaryLight]];}
.wizardFooter {background:[[ColorPalette::PrimaryPale]];}
.wizardFooter .status {background:[[ColorPalette::PrimaryDark]]; color:[[ColorPalette::Background]];}
.wizard .button {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryLight]]; border: 1px solid;
	border-color:[[ColorPalette::SecondaryPale]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryPale]];}
.wizard .button:hover {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Background]];}
.wizard .button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::Foreground]]; border: 1px solid;
	border-color:[[ColorPalette::PrimaryDark]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryDark]];}

.wizard .notChanged {background:transparent;}
.wizard .changedLocally {background:#80ff80;}
.wizard .changedServer {background:#8080ff;}
.wizard .changedBoth {background:#ff8080;}
.wizard .notFound {background:#ffff80;}
.wizard .putToServer {background:#ff80ff;}
.wizard .gotFromServer {background:#80ffff;}

#messageArea {border:1px solid [[ColorPalette::SecondaryMid]]; background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]];}
#messageArea .button {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::SecondaryPale]]; border:none;}

.popupTiddler {background:[[ColorPalette::TertiaryPale]]; border:2px solid [[ColorPalette::TertiaryMid]];}

.popup {background:[[ColorPalette::TertiaryPale]]; color:[[ColorPalette::TertiaryDark]]; border-left:1px solid [[ColorPalette::TertiaryMid]]; border-top:1px solid [[ColorPalette::TertiaryMid]]; border-right:2px solid [[ColorPalette::TertiaryDark]]; border-bottom:2px solid [[ColorPalette::TertiaryDark]];}
.popup hr {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::PrimaryDark]]; border-bottom:1px;}
.popup li.disabled {color:[[ColorPalette::TertiaryMid]];}
.popup li a, .popup li a:visited {color:[[ColorPalette::Foreground]]; border: none;}
.popup li a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border: none;}
.popup li a:active {background:[[ColorPalette::SecondaryPale]]; color:[[ColorPalette::Foreground]]; border: none;}
.popupHighlight {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
.listBreak div {border-bottom:1px solid [[ColorPalette::TertiaryDark]];}

.tiddler .defaultCommand {font-weight:bold;}

.shadow .title {color:[[ColorPalette::TertiaryDark]];}

.title {color:[[ColorPalette::SecondaryDark]];}
.subtitle {color:[[ColorPalette::TertiaryDark]];}

.toolbar {color:[[ColorPalette::PrimaryMid]];}
.toolbar a {color:[[ColorPalette::TertiaryLight]];}
.selected .toolbar a {color:[[ColorPalette::TertiaryMid]];}
.selected .toolbar a:hover {color:[[ColorPalette::Foreground]];}

.tagging, .tagged {border:1px solid [[ColorPalette::TertiaryPale]]; background-color:[[ColorPalette::TertiaryPale]];}
.selected .tagging, .selected .tagged {background-color:[[ColorPalette::TertiaryLight]]; border:1px solid [[ColorPalette::TertiaryMid]];}
.tagging .listTitle, .tagged .listTitle {color:[[ColorPalette::PrimaryDark]];}
.tagging .button, .tagged .button {border:none;}

.footer {color:[[ColorPalette::TertiaryLight]];}
.selected .footer {color:[[ColorPalette::TertiaryMid]];}

.sparkline {background:[[ColorPalette::PrimaryPale]]; border:0;}
.sparktick {background:[[ColorPalette::PrimaryDark]];}

.error, .errorButton {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Error]];}
.warning {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryPale]];}
.lowlight {background:[[ColorPalette::TertiaryLight]];}

.zoomer {background:none; color:[[ColorPalette::TertiaryMid]]; border:3px solid [[ColorPalette::TertiaryMid]];}

.imageLink, #displayArea .imageLink {background:transparent;}

.annotation {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border:2px solid [[ColorPalette::SecondaryMid]];}

.viewer .listTitle {list-style-type:none; margin-left:-2em;}
.viewer .button {border:1px solid [[ColorPalette::SecondaryMid]];}
.viewer blockquote {border-left:3px solid [[ColorPalette::TertiaryDark]];}

.viewer table, table.twtable {border:2px solid [[ColorPalette::TertiaryDark]];}
.viewer th, .viewer thead td, .twtable th, .twtable thead td {background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::Background]];}
.viewer td, .viewer tr, .twtable td, .twtable tr {border:1px solid [[ColorPalette::TertiaryDark]];}

.viewer pre {border:1px solid [[ColorPalette::SecondaryLight]]; background:[[ColorPalette::SecondaryPale]];}
.viewer code {color:[[ColorPalette::SecondaryDark]];}
.viewer hr {border:0; border-top:dashed 1px [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::TertiaryDark]];}

.highlight, .marked {background:[[ColorPalette::SecondaryLight]];}

.editor input {border:1px solid [[ColorPalette::PrimaryMid]];}
.editor textarea {border:1px solid [[ColorPalette::PrimaryMid]]; width:100%;}
.editorFooter {color:[[ColorPalette::TertiaryMid]];}
.readOnly {background:[[ColorPalette::TertiaryPale]];}

#backstageArea {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::TertiaryMid]];}
#backstageArea a {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
#backstageArea a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; }
#backstageArea a.backstageSelTab {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
#backstageButton a {background:none; color:[[ColorPalette::Background]]; border:none;}
#backstageButton a:hover {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
#backstagePanel {background:[[ColorPalette::Background]]; border-color: [[ColorPalette::Background]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]];}
.backstagePanelFooter .button {border:none; color:[[ColorPalette::Background]];}
.backstagePanelFooter .button:hover {color:[[ColorPalette::Foreground]];}
#backstageCloak {background:[[ColorPalette::Foreground]]; opacity:0.6; filter:'alpha(opacity=60)';}
/*}}}*/
/*{{{*/
* html .tiddler {height:1%;}

body {font-size:.75em; font-family:arial,helvetica; margin:0; padding:0;}

h1,h2,h3,h4,h5,h6 {font-weight:bold; text-decoration:none;}
h1,h2,h3 {padding-bottom:1px; margin-top:1.2em;margin-bottom:0.3em;}
h4,h5,h6 {margin-top:1em;}
h1 {font-size:1.35em;}
h2 {font-size:1.25em;}
h3 {font-size:1.1em;}
h4 {font-size:1em;}
h5 {font-size:.9em;}

hr {height:1px;}

a {text-decoration:none;}

dt {font-weight:bold;}

ol {list-style-type:decimal;}
ol ol {list-style-type:lower-alpha;}
ol ol ol {list-style-type:lower-roman;}
ol ol ol ol {list-style-type:decimal;}
ol ol ol ol ol {list-style-type:lower-alpha;}
ol ol ol ol ol ol {list-style-type:lower-roman;}
ol ol ol ol ol ol ol {list-style-type:decimal;}

.txtOptionInput {width:11em;}

#contentWrapper .chkOptionInput {border:0;}

.externalLink {text-decoration:underline;}

.indent {margin-left:3em;}
.outdent {margin-left:3em; text-indent:-3em;}
code.escaped {white-space:nowrap;}

.tiddlyLinkExisting {font-weight:bold;}
.tiddlyLinkNonExisting {font-style:italic;}

/* the 'a' is required for IE, otherwise it renders the whole tiddler in bold */
a.tiddlyLinkNonExisting.shadow {font-weight:bold;}

#mainMenu .tiddlyLinkExisting,
	#mainMenu .tiddlyLinkNonExisting,
	#sidebarTabs .tiddlyLinkNonExisting {font-weight:normal; font-style:normal;}
#sidebarTabs .tiddlyLinkExisting {font-weight:bold; font-style:normal;}

.header {position:relative;}
.header a:hover {background:transparent;}
.headerShadow {position:relative; padding:4.5em 0 1em 1em; left:-1px; top:-1px;}
.headerForeground {position:absolute; padding:4.5em 0 1em 1em; left:0px; top:0px;}

.siteTitle {font-size:3em;}
.siteSubtitle {font-size:1.2em;}

#mainMenu {position:absolute; left:0; width:10em; text-align:right; line-height:1.6em; padding:1.5em 0.5em 0.5em 0.5em; font-size:1.1em;}

#sidebar {position:absolute; right:3px; width:16em; font-size:.9em;}
#sidebarOptions {padding-top:0.3em;}
#sidebarOptions a {margin:0 0.2em; padding:0.2em 0.3em; display:block;}
#sidebarOptions input {margin:0.4em 0.5em;}
#sidebarOptions .sliderPanel {margin-left:1em; padding:0.5em; font-size:.85em;}
#sidebarOptions .sliderPanel a {font-weight:bold; display:inline; padding:0;}
#sidebarOptions .sliderPanel input {margin:0 0 0.3em 0;}
#sidebarTabs .tabContents {width:15em; overflow:hidden;}

.wizard {padding:0.1em 1em 0 2em;}
.wizard h1 {font-size:2em; font-weight:bold; background:none; padding:0; margin:0.4em 0 0.2em;}
.wizard h2 {font-size:1.2em; font-weight:bold; background:none; padding:0; margin:0.4em 0 0.2em;}
.wizardStep {padding:1em 1em 1em 1em;}
.wizard .button {margin:0.5em 0 0; font-size:1.2em;}
.wizardFooter {padding:0.8em 0.4em 0.8em 0;}
.wizardFooter .status {padding:0 0.4em; margin-left:1em;}
.wizard .button {padding:0.1em 0.2em;}

#messageArea {position:fixed; top:2em; right:0; margin:0.5em; padding:0.5em; z-index:2000; _position:absolute;}
.messageToolbar {display:block; text-align:right; padding:0.2em;}
#messageArea a {text-decoration:underline;}

.tiddlerPopupButton {padding:0.2em;}
.popupTiddler {position: absolute; z-index:300; padding:1em; margin:0;}

.popup {position:absolute; z-index:300; font-size:.9em; padding:0; list-style:none; margin:0;}
.popup .popupMessage {padding:0.4em;}
.popup hr {display:block; height:1px; width:auto; padding:0; margin:0.2em 0;}
.popup li.disabled {padding:0.4em;}
.popup li a {display:block; padding:0.4em; font-weight:normal; cursor:pointer;}
.listBreak {font-size:1px; line-height:1px;}
.listBreak div {margin:2px 0;}

.tabset {padding:1em 0 0 0.5em;}
.tab {margin:0 0 0 0.25em; padding:2px;}
.tabContents {padding:0.5em;}
.tabContents ul, .tabContents ol {margin:0; padding:0;}
.txtMainTab .tabContents li {list-style:none;}
.tabContents li.listLink { margin-left:.75em;}

#contentWrapper {display:block;}
#splashScreen {display:none;}

#displayArea {margin:1em 17em 0 14em;}

.toolbar {text-align:right; font-size:.9em;}

.tiddler {padding:1em 1em 0;}

.missing .viewer,.missing .title {font-style:italic;}

.title {font-size:1.6em; font-weight:bold;}

.missing .subtitle {display:none;}
.subtitle {font-size:1.1em;}

.tiddler .button {padding:0.2em 0.4em;}

.tagging {margin:0.5em 0.5em 0.5em 0; float:left; display:none;}
.isTag .tagging {display:block;}
.tagged {margin:0.5em; float:right;}
.tagging, .tagged {font-size:0.9em; padding:0.25em;}
.tagging ul, .tagged ul {list-style:none; margin:0.25em; padding:0;}
.tagClear {clear:both;}

.footer {font-size:.9em;}
.footer li {display:inline;}

.annotation {padding:0.5em; margin:0.5em;}

* html .viewer pre {width:99%; padding:0 0 1em 0;}
.viewer {line-height:1.4em; padding-top:0.5em;}
.viewer .button {margin:0 0.25em; padding:0 0.25em;}
.viewer blockquote {line-height:1.5em; padding-left:0.8em;margin-left:2.5em;}
.viewer ul, .viewer ol {margin-left:0.5em; padding-left:1.5em;}

.viewer table, table.twtable {border-collapse:collapse; margin:0.8em 1.0em;}
.viewer th, .viewer td, .viewer tr,.viewer caption,.twtable th, .twtable td, .twtable tr,.twtable caption {padding:3px;}
table.listView {font-size:0.85em; margin:0.8em 1.0em;}
table.listView th, table.listView td, table.listView tr {padding:0px 3px 0px 3px;}

.viewer pre {padding:0.5em; margin-left:0.5em; font-size:1.2em; line-height:1.4em; overflow:auto;}
.viewer code {font-size:1.2em; line-height:1.4em;}

.editor {font-size:1.1em;}
.editor input, .editor textarea {display:block; width:100%; font:inherit;}
.editorFooter {padding:0.25em 0; font-size:.9em;}
.editorFooter .button {padding-top:0px; padding-bottom:0px;}

.fieldsetFix {border:0; padding:0; margin:1px 0px;}

.sparkline {line-height:1em;}
.sparktick {outline:0;}

.zoomer {font-size:1.1em; position:absolute; overflow:hidden;}
.zoomer div {padding:1em;}

* html #backstage {width:99%;}
* html #backstageArea {width:99%;}
#backstageArea {display:none; position:relative; overflow: hidden; z-index:150; padding:0.3em 0.5em;}
#backstageToolbar {position:relative;}
#backstageArea a {font-weight:bold; margin-left:0.5em; padding:0.3em 0.5em;}
#backstageButton {display:none; position:absolute; z-index:175; top:0; right:0;}
#backstageButton a {padding:0.1em 0.4em; margin:0.1em;}
#backstage {position:relative; width:100%; z-index:50;}
#backstagePanel {display:none; z-index:100; position:absolute; width:90%; margin-left:3em; padding:1em;}
.backstagePanelFooter {padding-top:0.2em; float:right;}
.backstagePanelFooter a {padding:0.2em 0.4em;}
#backstageCloak {display:none; z-index:20; position:absolute; width:100%; height:100px;}

.whenBackstage {display:none;}
.backstageVisible .whenBackstage {display:block;}
/*}}}*/
/***
StyleSheet for use when a translation requires any css style changes.
This StyleSheet can be used directly by languages such as Chinese, Japanese and Korean which need larger font sizes.
***/
/*{{{*/
body {font-size:0.8em;}
#sidebarOptions {font-size:1.05em;}
#sidebarOptions a {font-style:normal;}
#sidebarOptions .sliderPanel {font-size:0.95em;}
.subtitle {font-size:0.8em;}
.viewer table.listView {font-size:0.95em;}
/*}}}*/
/*{{{*/
@media print {
#mainMenu, #sidebar, #messageArea, .toolbar, #backstageButton, #backstageArea {display: none !important;}
#displayArea {margin: 1em 1em 0em;}
noscript {display:none;} /* Fixes a feature in Firefox 1.5.0.2 where print preview displays the noscript content */
}
/*}}}*/
<!--{{{-->
<div class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>
<div class='headerShadow'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
<div class='headerForeground'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
</div>
<div id='mainMenu' refresh='content' tiddler='MainMenu'></div>
<div id='sidebar'>
<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>
<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
</div>
<div id='displayArea'>
<div id='messageArea'></div>
<div id='tiddlerDisplay'></div>
</div>
<!--}}}-->
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::ViewToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date'></span> (<span macro='message views.wikified.createdPrompt'></span> <span macro='view created date'></span>)</div>
<div class='tagging' macro='tagging'></div>
<div class='tagged' macro='tags'></div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
<!--}}}-->
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::EditToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='editor' macro='edit title'></div>
<div macro='annotations'></div>
<div class='editor' macro='edit text'></div>
<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser excludeLists'></span></div>
<!--}}}-->
To get started with this blank [[TiddlyWiki]], you'll need to modify the following tiddlers:
* [[SiteTitle]] & [[SiteSubtitle]]: The title and subtitle of the site, as shown above (after saving, they will also appear in the browser title bar)
* [[MainMenu]]: The menu (usually on the left)
* [[DefaultTiddlers]]: Contains the names of the tiddlers that you want to appear when the TiddlyWiki is opened
You'll also need to enter your username for signing your edits: <<option txtUserName>>
These [[InterfaceOptions]] for customising [[TiddlyWiki]] are saved in your browser

Your username for signing your edits. Write it as a [[WikiWord]] (eg [[JoeBloggs]])

<<option txtUserName>>
<<option chkSaveBackups>> [[SaveBackups]]
<<option chkAutoSave>> [[AutoSave]]
<<option chkRegExpSearch>> [[RegExpSearch]]
<<option chkCaseSensitiveSearch>> [[CaseSensitiveSearch]]
<<option chkAnimate>> [[EnableAnimations]]

----
Also see [[AdvancedOptions]]
<<importTiddlers>>
[[Welcome]]
//{{{
version.extensions.InlineJavascriptPlugin= {major: 1, minor: 9, revision: 6, date: new Date(2010,12,15)};

config.formatters.push( {
	name: "inlineJavascript",
	match: "\\<script",
	lookahead: "\\<script(?: type=\\\"[^\\\"]*\\\")?(?: src=\\\"([^\\\"]*)\\\")?(?: label=\\\"([^\\\"]*)\\\")?(?: title=\\\"([^\\\"]*)\\\")?(?: key=\\\"([^\\\"]*)\\\")?( show)?\\>((?:.|\\n)*?)\\</script\\>",
	handler: function(w) {
		var lookaheadRegExp = new RegExp(this.lookahead,"mg");
		lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = lookaheadRegExp.exec(w.source)
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
			var src=lookaheadMatch[1];
			var label=lookaheadMatch[2];
			var tip=lookaheadMatch[3];
			var key=lookaheadMatch[4];
			var show=lookaheadMatch[5];
			var code=lookaheadMatch[6];
			if (src) { // external script library
				var script = document.createElement("script"); script.src = src;
				document.body.appendChild(script); document.body.removeChild(script);
			}
			if (code) { // inline code
				if (show) // display source in tiddler
					wikify("{{{\n"+lookaheadMatch[0]+"\n}}}\n",w.output);
				if (label) { // create 'onclick' command link
					var link=createTiddlyElement(w.output,"a",null,"tiddlyLinkExisting",wikifyPlainText(label));
					var fixup=code.replace(/document.write\s*\(/gi,'place.bufferedHTML+=(');
					link.code="function _out(place,tiddler){"+fixup+"\n};_out(this,this.tiddler);"
					link.tiddler=w.tiddler;
					link.onclick=function(){
						this.bufferedHTML="";
						try{ var r=eval(this.code);
							if(this.bufferedHTML.length || (typeof(r)==="string")&&r.length)
								var s=this.parentNode.insertBefore(document.createElement("span"),this.nextSibling);
							if(this.bufferedHTML.length)
								s.innerHTML=this.bufferedHTML;
							if((typeof(r)==="string")&&r.length) {
								wikify(r,s,null,this.tiddler);
								return false;
							} else return r!==undefined?r:false;
						} catch(e){alert(e.description||e.toString());return false;}
					};
					link.setAttribute("title",tip||"");
					var URIcode='javascript:void(eval(decodeURIComponent(%22(function(){try{';
					URIcode+=encodeURIComponent(encodeURIComponent(code.replace(/\n/g,' ')));
					URIcode+='}catch(e){alert(e.description||e.toString())}})()%22)))';
					link.setAttribute("href",URIcode);
					link.style.cursor="pointer";
					if (key) link.accessKey=key.substr(0,1); // single character only
				}
				else { // run script immediately
					var fixup=code.replace(/document.write\s*\(/gi,'place.innerHTML+=(');
					var c="function _out(place,tiddler){"+fixup+"\n};_out(w.output,w.tiddler);";
					try	 { var out=eval(c); }
					catch(e) { out=e.description?e.description:e.toString(); }
					if (out && out.length) wikify(out,w.output,w.highlightRegExp,w.tiddler);
				}
			}
			w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
		}
	}
} )
//}}}
/***
!Information
|Name|LineBreakPlugin|
|Author|axs|
|Version|0.2|
|Source|http://axs.tiddlyspot.com/#LineBreakPlugin|
|Core Version|2.6|
|Description|Allows styling of spaces between paragraphs.|

!Description
This will replace 2 or more consecutive line breaks with one line break whose styling is controlled by the class {{{.multipleLinebreak}}}. Set the desired style by pressing the "edit style" button. The {{{margin-bottom}}} property will control how much space is between the two blocks of text separated by the line break. After changing the style, press "update style" for changes to take effect;

Note: This doesn't recognize consecutive {{{<br>}}} tags.

<html><span class="button" style="cursor:pointer;" onclick="LBP_editStyle();">edit style</span></html>
<html><textarea style="display:none" id="LBP_styleEditor" rows="10" cols="25"></textarea></html>
<html>
<span id="LBP_cancelEditBtn" style="display:none;cursor:pointer" class="button" style="cursor:pointer;" onclick="LBP_hideEditor()">cancel</span>
<span id="LBP_updateStyleBtn" style="display:none;cursor:pointer" class="button" style="cursor:pointer;" onclick="LBP_updateStyle()">update style</span>
</html>

!Revisions
2011.05.26 v.0.2 style live edit/update capability
2011.05.26 v.0.1 first release

/%
!Style
.multipleLinebreak{
	font-size:1px;
	line-height:1px;
	margin-bottom:3px;
}
!end
%/
!Code
***/
//{{{
config.formatters.splice(config.formatters.findByField("name","lineBreak"),0,{
	name: 'multipleLinebreaks',
	match: '\\n{2,}',
	handler:function(w){
		createTiddlyElement(w.output,'div',null,'multipleLinebreak').innerHTML="&nbsp;";
	}	
});
setStylesheet(store.getTiddlerText('LineBreakPlugin##Style'),'MultipleLineBreak');

function LBP_editStyle(){
	jQuery('#LBP_styleEditor').val(store.getTiddlerText('LineBreakPlugin##Style')).show();
	jQuery('#LBP_updateStyleBtn,#LBP_cancelEditBtn').show();
}

function LBP_hideEditor(){
	jQuery('#LBP_styleEditor,#LBP_updateStyleBtn,#LBP_cancelEditBtn').hide();
}
function LBP_updateStyle(){
	LBP_hideEditor();
	var newStyle=jQuery('#LBP_styleEditor').val();
	var text=store.getTiddlerText('LineBreakPlugin').replace(store.getTiddlerText('LineBreakPlugin##Style'),newStyle)
	store.saveTiddler('LineBreakPlugin','LineBreakPlugin',text,config.options.txtUserName,new Date(),store.getValue('LineBreakPlugin','tags'));
	setStylesheet(newStyle,'MultipleLineBreak');
	story.refreshTiddler('LineBreakPlugin',null,true);
}
//}}}
/***
|''Name:''|LoadRemoteFileThroughProxy (previous LoadRemoteFileHijack)|
|''Description:''|When the TiddlyWiki file is located on the web (view over http) the content of [[SiteProxy]] tiddler is added in front of the file url. If [[SiteProxy]] does not exist "/proxy/" is added. |
|''Version:''|1.1.0|
|''Date:''|mar 17, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#LoadRemoteFileHijack|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0|
***/
//{{{
version.extensions.LoadRemoteFileThroughProxy = {
 major: 1, minor: 1, revision: 0, 
 date: new Date("mar 17, 2007"), 
 source: "http://tiddlywiki.bidix.info/#LoadRemoteFileThroughProxy"};

if (!window.bidix) window.bidix = {}; // bidix namespace
if (!bidix.core) bidix.core = {};

bidix.core.loadRemoteFile = loadRemoteFile;
loadRemoteFile = function(url,callback,params)
{
 if ((document.location.toString().substr(0,4) == "http") && (url.substr(0,4) == "http")){ 
 url = store.getTiddlerText("SiteProxy", "/proxy/") + url;
 }
 return bidix.core.loadRemoteFile(url,callback,params);
}
//}}}
Plugins:
TagglyTagsMenuPlugin
LineBreakPlugin
StyleTabWithLinksPlugin
Type the text for 'testNew Tiddler'
/***
|''Name:''|PasswordOptionPlugin|
|''Description:''|Extends TiddlyWiki options with non encrypted password option.|
|''Version:''|1.0.2|
|''Date:''|Apr 19, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#PasswordOptionPlugin|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0 (Beta 5)|
***/
//{{{
version.extensions.PasswordOptionPlugin = {
	major: 1, minor: 0, revision: 2, 
	date: new Date("Apr 19, 2007"),
	source: 'http://tiddlywiki.bidix.info/#PasswordOptionPlugin',
	author: 'BidiX (BidiX (at) bidix (dot) info',
	license: '[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D]]',
	coreVersion: '2.2.0 (Beta 5)'
};

config.macros.option.passwordCheckboxLabel = "Save this password on this computer";
config.macros.option.passwordInputType = "password"; // password | text
setStylesheet(".pasOptionInput {width: 11em;}\n","passwordInputTypeStyle");

merge(config.macros.option.types, {
	'pas': {
		elementType: "input",
		valueField: "value",
		eventName: "onkeyup",
		className: "pasOptionInput",
		typeValue: config.macros.option.passwordInputType,
		create: function(place,type,opt,className,desc) {
			// password field
			config.macros.option.genericCreate(place,'pas',opt,className,desc);
			// checkbox linked with this password "save this password on this computer"
			config.macros.option.genericCreate(place,'chk','chk'+opt,className,desc);			
			// text savePasswordCheckboxLabel
			place.appendChild(document.createTextNode(config.macros.option.passwordCheckboxLabel));
		},
		onChange: config.macros.option.genericOnChange
	}
});

merge(config.optionHandlers['chk'], {
	get: function(name) {
		// is there an option linked with this chk ?
		var opt = name.substr(3);
		if (config.options[opt]) 
			saveOptionCookie(opt);
		return config.options[name] ? "true" : "false";
	}
});

merge(config.optionHandlers, {
	'pas': {
 		get: function(name) {
			if (config.options["chk"+name]) {
				return encodeCookie(config.options[name].toString());
			} else {
				return "";
			}
		},
		set: function(name,value) {config.options[name] = decodeCookie(value);}
	}
});

// need to reload options to load passwordOptions
loadOptionsCookie();

/*
if (!config.options['pasPassword'])
	config.options['pasPassword'] = '';

merge(config.optionsDesc,{
		pasPassword: "Test password"
	});
*/
//}}}
//{{{
PlusEditor=function(tiddler,field,place,height){
	if(!tiddler || !field || !place) {return;}
	this.place=place;
	this.height=height || PlusEditor.defaultHeight;
	this.tiddler=tiddler;
	this.field=field;
	this.wrapper=createTiddlyElement(place,"div",null,"PlusEditor");
	this.wrapper.setAttribute('PlusEdit',this.field);
	jQuery(this.wrapper).css('white-space','pre-wrap');
	this.editor=createTiddlyElement(null,"div",null,"PlusEditorField");
	this.editor.tiddler=tiddler;
	this.editor.PlusEditorHistory=[];
	this.toolbar = new PlusEditor.Toolbar(this.wrapper,this.editor);
	this.wrapper.appendChild(this.editor);
	this.setupEditor();
	setStylesheet(PlusEditor.Stylesheet,'PlusEditorStylesheet');
};

PlusEditor.prototype.setupEditor=function(){
	jQuery(this.editor).attr('style',"height:" + this.height +";");
	if (!this.tiddler.isReadOnly() && this.editor.contentEditable!=true) {
		this.editor.contentEditable = true;
		jQuery(this.editor).css('word-wrap','normal');
	}
	this.loadContent();
	//this.iframe.contentWindow.focus();
};

PlusEditor.prototype.loadContent=function(){
	var content=store.getValue(this.tiddler,this.field);
	wikifier = new Wikifier(content,PlusEditor.parsers.preParser);
	wikifier.subWikify(this.editor);
	jQuery()
	//jQuery(this.editor).append('<br>'); //need this IF replacing the return key 'keypress' event
};

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
PlusEditor.Toolbar=function(place,editorDiv,buttonList,btwnButtons,btwnParams){
	this.editor=editorDiv;
	this.target=editorDiv;
	this.place=place;
	this.buttons=[];
	this.buttonList = buttonList || store.getValue('PlusEditorButtonList','text') || config.shadowTiddlers.PlusEditorButtonList;
	this.btwnButtons = btwnButtons || PlusEditor.Toolbar.btwnButtonDelim;
	this.btwnParams = btwnParams || PlusEditor.Toolbar.btwnParamsDelim;
	
	this.element = createTiddlyElement(place,"div",null,"PlusEditorToolbar");
	
	var row = createTiddlyElement(this.element,"div");
	var group=createTiddlyElement(row,'span',null,"PEgroup");
	var buttons = this.buttonList.split(this.btwnButtons);
	for(var i = 0; i < buttons.length; i++){
		var temp=buttons[i].split(this.btwnParams);
		var n = jQuery.trim(temp[0]); //command name with white-space removed at both ends
		var l = temp[1] || null ; //label
		var t = temp[2] || null ; //tooltip
		var p = temp[3] || null ; //parameter
	    var r = temp[4] || null ; //prompt text
		var c = jQuery.trim(temp[5]) || null ; //css styling
		var s = jQuery.trim(temp[6]) || null ; //button span
		
		if(c && c[c.length-1]!=';'){
			c=c+';';
		}
		switch(n){
			case 'newrow':
				//format: newrow[|HR] , [HR] gives a horizontal line between rows
				if (l){ l=jQuery.trim(l); }
				if (l=='HR') { createTiddlyElement(this.element,'hr',null,'PEhr'); }
				row = createTiddlyElement(this.element,"div");
				group=createTiddlyElement(row,'span',null,"PEgroup");
				break;
			case 'newgroup':
				//format: newgroup[|space] or newgroup[|smallspace] : [space] or [smallspace] gives a 1-button-width space between groups
				if (l){ l=jQuery.trim(l); }				
				if (l=='space'){createTiddlyElement(group,"span",null,"PEseparator").innerHTML="&nbsp;"; }
				if (l=='smallspace') {createTiddlyElement(group,"span",null,"PEseparator PEseparatorSmall").innerHTML="&nbsp;"; }
				createTiddlyElement(row,'span',null,'PEspace').innerHTML='&#8203;';
				group=createTiddlyElement(row,'span',null,"PEgroup");	
				break;		
			case 'label':
				//format: label|<label text>[|integer][|css] the integer will dictate the span, overruling any width tags in the css
				if(p && p[p.length-1]!=';'){
					p=p+';';
				}
				if (l){
					if(t){
						t=jQuery.trim(t);
						if(t>0){
							var width = t*PlusEditor.Button.buttonSize + (t-1)*6 +2; //the 6 and the 2 are for maintaining button alignment: a label's padding is 0px, while a button's padding is 1px
							p = p? ( p + 'width:'+ width +'px;') : ('width:'+ width +'px;'); //if there is a button span specified this is added as a width to the buttons style attribute, note that because this width will be last in the definition, it will overrule any width declarations in the user-specified css
						}
					}
				
					var label=createTiddlyElement(group,"span",null,'PElabel');
					label.innerHTML=l;
					
					if (p){ jQuery(label).attr('style',p); }
				}
				break;
			case '':
				//an empty command name a button does not make! this takes care of multiple accidental delimiters in the button list definition
				break;
			default:
				this.buttons.push(new PlusEditor.Button(group,editorDiv,n,l,t,p,r,c,s));	
				//format: <command name>|[button label]|[button tooltip]|[command parameter]|[prompt text]|[css styling]|[span]
				break;
		};
	};
	PlusEditor.Toolbar.initializeEvents(this); 
};

PlusEditor.Toolbar.initializeEvents=function(toolbar){
	jQuery(toolbar.target).mouseup(function(){PlusEditor.Toolbar.scheduleButtonsRefresh(toolbar)});
	jQuery(toolbar.target).keyup(function(){PlusEditor.Toolbar.scheduleButtonsRefresh(toolbar)});
	jQuery(toolbar.target).keydown(function(){PlusEditor.Toolbar.scheduleButtonsRefresh(toolbar)});
	jQuery(toolbar.target).click(function(){PlusEditor.Toolbar.scheduleButtonsRefresh(toolbar)});

	jQuery(toolbar.target).keypress(function(ev){ //this is ensures that pressing enter will insert a line break ('\n') instead of <div> or <p> or <br> or whatever else the browser wants to insert
		if (ev.which == '13') {
			selection=rangy.getSelection();
			oldselValue=selection.focusNode.nodeValue;
			var parents=jQuery(selection.focusNode).parents();
			if(selection.focusNode.nodeName.toLowerCase()=='li'){ return; }
			for(i=0;i<parents.length;i++){
				if(parents[i].nodeName.toLowerCase()=='li'){
					return;
				}
			}
			
			
			
			/*
			first cache the current innerHTML to history
			if the selection is not collapsed, delete the contents of the selection, which collapses the selection as well
			insert the '\n' into the selection focus node
			collapse the selection and focus it after the newly inserted '\n'
			*/
			if(selection.focusNode.nodeType!=3){ return; }
			ev.preventDefault();
			toolbar.target.ownerDocument.execCommand('insertHTML',false,'&#x000D;');
	/*		
			//toolbar.target.PlusEditorHistory.push(toolbar.target.innerHTML);
			
			var insertText='\n';
			var newFocus=selection.focusOffset+1;
			if(!selection.isCollapsed){
				selection.deleteFromDocument();
			}else if(selection.focusOffset==selection.focusNode.nodeValue.length){ //means we're at EOL and need to insert TWO \n's
				insertText='\n ';
			}
			selection.focusNode.nodeValue=selection.focusNode.nodeValue.substr(0,selection.focusOffset)+insertText+selection.focusNode.nodeValue.substr(selection.focusOffset);
			selection.collapse(selection.focusNode,newFocus);
			/*
			range=selection.getRangeAt(0);
			range.deleteContents();
			range.setStartAfter(range.endContainer);
			range.setEndAfter(range.endContainer);
			range.collapse(false);
			selection.removeAllRanges();
			selection.setSingleRange(range);
			*/		
	   }
	
	});
	
};

PlusEditor.Toolbar.scheduleButtonsRefresh=function(toolbar){
	if (toolbar.nextUpdate) { window.clearTimeout(toolbar.nextUpdate); }
	toolbar.nextUpdate = window.setTimeout(function(){PlusEditor.Toolbar.updateButtons(toolbar)},PlusEditor.refreshButtonDelay);
};

PlusEditor.Toolbar.updateButtons=function(toolbar){ // called at intervals by scheduleButtonsRefresh() and by the default PlusEditor.Button.onClick() handler
	for (i=0;i<toolbar.buttons.length;i++)
		{ if(toolbar.buttons[i].onRefresh) toolbar.buttons[i].onRefresh(toolbar.buttons[i]); };
};
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
PlusEditor.Button=function(place,editorDiv,n,l,t,p,r,c,s,onClick,onRefresh,onBeforeCreate,onAfterCreate){ //using this order for ease of usability b/c onClick is expected to be used > onRefresh > onBeforeCreate, onAfterCreate
	if(!place || !n || !editorDiv) return;
	var tempButton = PlusEditor.Toolbar.buttons[n] ? jQuery.extend({},PlusEditor.Toolbar.buttons[n]) : {} ;
	jQuery.extend(this,tempButton); //copy predefined button object into this button
	this.place=place;
	this.editor = editorDiv;
	this.target = editorDiv;
	this.doc = editorDiv.ownerDocument || document;
	this.name = n;
	this.label = l || tempButton.label || n[0];
	this.tooltip = t || tempButton.tooltip || n;
	this.parameter = p || tempButton.parameter || null;
	this.prompt = r || tempButton.prompt || null;
	this.css = c || tempButton.css || null;
	if(this.css && this.css[this.css.length-1]!=';'){
		this.css=this.css+';';
	}
	this.span = s || tempButton.span || null;
	this.onBeforeCreate = onBeforeCreate || tempButton.onBeforeCreate || null;
	this.onAfterCreate = onAfterCreate || tempButton.onAfterCreate || null;
	this.onClick = onClick || tempButton.onClick || PlusEditor.Button.onClick;	
	this.onRefresh = onRefresh || tempButton.onRefresh || PlusEditor.Button.onRefresh;
	
	if (this.onBeforeCreate){
		this.onBeforeCreate.call(this);
	}
	PlusEditor.Button.createButton(this);
	if(this.onAfterCreate){
		this.onAfterCreate.call(this);
	}
};

PlusEditor.Button.createButton=function(button){	
	var buttonElement=createTiddlyButton(button.place,null,button.tooltip,null,PlusEditor.Button.buttonClass,null,null,{href:"javascript:;"});
	buttonElement.innerHTML=button.label;
	if(button.span){
			var width = button.span*PlusEditor.Button.buttonSize + (button.span-1)*6;
			button.css = button.css? ( button.css + 'width:'+ width +'px;') : ('width:'+ width +'px;'); //if there is a button span specified this is added as a width to the label's style attribute, note that because this width will be last in the definition, it will overrule any width declarations in the user-specified css
	}
	if(button.css) {jQuery(buttonElement).attr('style',button.css)};
	button.element=buttonElement;
	
	jQuery(buttonElement).click({button:button},function(ev){ //jQuery event handlers run in the scope of the element, so to get at the button we need to pass it in the event data
		ev.cancelBubble=true; 
		if(ev.stopPropagation) ev.stopPropagation();
		var clickedButton = ev.data.button;
		var selection = rangy.getSelection(clickedButton.target.ownerDocument.defaultView);
		var range= selection.rangeCount ? selection.getRangeAt(0) : null;
		
		if (clickedButton.name==='undo'){
			if (clickedButton.target.PlusEditorHistory && clickedButton.target.PlusEditorHistory.length>0){
				clickedButton.target.innerHTML=clickedButton.target.PlusEditorHistory.pop();
			}else{
				clickedButton.target.PlusEditorHistory=[];
			}
		}else if (PlusEditor.Button.testSelectionLocation(clickedButton,selection)){
			clickedButton.target.PlusEditorHistory.push(clickedButton.target.innerHTML); //push the current HTML to the history stack;
			clickedButton.onClick.call(clickedButton,ev,selection,range);
			clickedButton.onRefresh.call(clickedButton);
		}
		return false;	
	});
};

PlusEditor.Button.testSelectionLocation=function(button,selection){ //check whether the selection is inside button.target; without this, selections in any PlusEditorField div can be operated on by any PlusEditor Button
	if (selection.anchorNode && selection.focusNode){
		return ( isDescendant(selection.anchorNode,button.target) && isDescendant(selection.focusNode,button.target) );
	}else{
		return false;
	}

};
// onClick & onRefresh runs in the button scope (this=button); however the button is passed to it as well; the event object that is passed to it is the normalized jQuery Event object
PlusEditor.Button.onClick=function(ev,selection,range){ 
	var button = this; // need to change the occurrences below;
	var withDefaultUI=false;
	var parameter = button.parameter || (button.prompt ? prompt(button.prompt) : null) ;
	/* above code explained:
	if(button.parameter){parameter=button.parameter} //if there's a parameter given, use it without respect for whether there is a prompt or not
	else if (button.prompt){parameter=prompt(button.prompt);} // there's no parameter, but if there is a prompt, use it to get the parameter
	else {undefinedParameter} //there's no parameter given and there's no prompt, could set up to use the deafault browser UI to get the parameter but FF 'breaks' the editor when withDefaultUI is true and this is called for commands w/o parameters such as bold or italic
	*/
	
	/*if there was a prompt specified, there must have been a valid entry for parameter in order to run the command, 
	//if there was no prompt, then run it with whatever parameter we have and see what happens
	NOTE that some commands, like insertHTML, run with null parameters may erase the current selection !!
	*/
	selection.setSingleRange(range);
	if((button.prompt && parameter) || (!button.prompt) ){ 
		button.doc.execCommand(button.name,withDefaultUI,parameter);
	}
	return false;
};

PlusEditor.Button.onRefresh=function(){ //called for a button after onClick() runs, and at intervals by PlusEditor.Toolbar.updateButtons() 
	var button = this //need to change this below;
	if (PlusEditor.Button.getCommandState(button)) addClass(button.element,PlusEditor.Button.buttononClass);
	else removeClass(button.element,PlusEditor.Button.buttononClass);
	////button.editor.window.focus();
};

PlusEditor.Button.getCommandState = function(button){
	try { return button.doc.queryCommandState(button.name);}
	catch(err){return false;}
};

PlusEditor.Button.getCommandValue = function(button){
	try { 
		var selectionValue=button.doc.queryCommandState(button.name);
		var match = (selectionValue).indexOf(button.parameter);
		return  match!=-1;
	}catch(err){ return false; };
};

PlusEditor.Button.getCommandStateOrValue=function(){
	
};

PlusEditor.Button.debugCommand=function(){
	var commands=['bold','italic','underline','strikethrough','indent','outdent','justifyleft','justifycenter','justifyright','justifyfull','fontname','fontsize','forecolor','hilitecolor','backcolor'];
	for(i=0;i<commands.length;i++){
		var command=commands[i];
		console.log(command);
		try{console.log(button.doc.queryCommandValue(command))}catch(er){};
		try{console.log(button.doc.queryCommandState(command))}catch(er){};
		try{console.log(button.doc.queryCommandEnabled(command))}catch(er){};
		console.log('----------------');
	};
};

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// custom formatters to render various TW text correctly
PlusEditor.parsers={};

PlusEditor.preFormatters=[];

PlusEditor.preFormatters.push(jQuery.extend({},config.formatters[config.formatters.findByField("name","html")]));
PlusEditor.preFormatters[PlusEditor.preFormatters.length-1].handler=function (w) {
		this.lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
			var htmlEl=createTiddlyElement(w.output,"span",null,'PlusEditorPreWrap'); //added the class definition, bc later on config.macros.PlusEdit.cleanup(), all spans with this class are replaced by their innerHTML, which cuts down on unecessary tags
			htmlEl.innerHTML = lookaheadMatch[1]; 
			PlusEditor_wikifyTextNodes(htmlEl,w);
			w.nextMatch = this.lookaheadRegExp.lastIndex;
		}
};
//if(config.options.chkPlusEditorConvertWikitoHTML){
	PlusEditor.preFormatters.push(config.formatters[config.formatters.findByField("name","table")]);
	PlusEditor.preFormatters.push(config.formatters[config.formatters.findByField("name","heading")]);
	PlusEditor.preFormatters.push(config.formatters[config.formatters.findByField("name","list")]);
	PlusEditor.preFormatters.push(config.formatters[config.formatters.findByField("name","quoteByBlock")]);
	PlusEditor.preFormatters.push(config.formatters[config.formatters.findByField("name","quoteByLine")]);
	PlusEditor.preFormatters.push(config.formatters[config.formatters.findByField("name","rule")]);
	PlusEditor.preFormatters.push(config.formatters[config.formatters.findByField("name","monospacedByLine")]);
	//PlusEditor.preFormatters.push(config.formatters[config.formatters.findByField("name","wikifyComment")]);
	//PlusEditor.preFormatters.push(config.formatters[config.formatters.findByField("name","prettyLink")]);
	//PlusEditor.preFormatters.push(config.formatters[config.formatters.findByField("name","wikiLink")]);
	//PlusEditor.preFormatters.push(config.formatters[config.formatters.findByField("name","urlLink")]);
	PlusEditor.preFormatters.push(config.formatters[config.formatters.findByField("name","image")]);
	//PlusEditor.preFormatters.push(config.formatters[config.formatters.findByField("name","commentByBlock")]);
	//PlusEditor.preFormatters.push(config.formatters[config.formatters.findByField("name","characterFormat")]);
	PlusEditor.preFormatters.push(config.formatters[config.formatters.findByField("name","customFormat")]);
	PlusEditor.preFormatters.push(config.formatters[config.formatters.findByField("name","mdash")]);
	PlusEditor.preFormatters.push(config.formatters[config.formatters.findByField("name","lineBreak")]);
	PlusEditor.preFormatters.push(config.formatters[config.formatters.findByField("name","rawText")]);
	PlusEditor.preFormatters.push(config.formatters[config.formatters.findByField("name","htmlEntitiesEncoding")]);
//}
PlusEditor.parsers.preParser = new Formatter(PlusEditor.preFormatters);




PlusEditor.postFormatters=[
{	name: "html",
	match: "&lt;[Hh][Tt][Mm][Ll]&gt;",
	lookaheadRegExp: /&lt;[Hh][Tt][Mm][Ll]&gt;((?:.|\n)*?)&lt;\/[Hh][Tt][Mm][Ll]&gt;/mg,
	handler: function(w){
		this.lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
			createTiddlyElement(w.output,"span").innerHTML = lookaheadMatch[1];
			w.nextMatch = this.lookaheadRegExp.lastIndex;
		}
	}
}
];
PlusEditor.parsers.postParser = new Formatter(PlusEditor.postFormatters);


function PlusEditor_wikifyTextNodes(el,w){
	if(el.nodeType==3){
		var newNode=createTiddlyElement(null,'span');
		el.parentNode.replaceChild(newNode,el);
		var wikifier= new Wikifier(el.nodeValue,PlusEditor.parsers.preParser);
		wikifier.subWikify(newNode);
	}else if(el.childNodes){
		for(var i=0;i<el.childNodes.length;i++){
			PlusEditor_wikifyTextNodes(el.childNodes.item(i),w);
		}
	}
};
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// hijack story.gatherSaveFields to find the new tiddler text -- this uses the original EasyEdit gatherSaveFields(), though gather() has been changed
Story.prototype.previousGatherSaveEasyEdit = Story.prototype.previousGatherSaveEasyEdit ? Story.prototype.previousGatherSaveEasyEdit : Story.prototype.gatherSaveFields; // to avoid looping if this line is called several times
Story.prototype.gatherSaveFields = function(e,fields){
	if(e && e.getAttribute) {
		var f = e.getAttribute("PlusEdit");
		if(f){
			var newVal = config.macros.PlusEdit.gather(e);
			if (newVal) fields[f] = newVal;
		}
		this.previousGatherSaveEasyEdit(e, fields);
	}
};

//  MACRO & COMMAND
//TODO: change the way that tiddler is fetched to use TW core functions

config.macros.PlusEdit = {
	handler : function(place,macroName,params,wikifier,paramString,tiddler) {
		var prms = paramString.parseParams(null, null, true);
		var field = params[0];
		var height = config.options.txtPlusEditorHeight;
		var tiddler= getParam(prms, "tiddler") ? store.getTiddler(getParam(prms, "tiddler")) : tiddler;
		editor = field ? new PlusEditor(tiddler,field,place,height) : null;
	},
	gather: function(element){
		//element here is an instance of the <div class=PlusEditor edit=text>...
		var PlusEditorField=jQuery(element).find('.PlusEditorField')[0];
		if (PlusEditorField){
			jQuery(PlusEditorField).find('.PlusEditorPreWrap').replaceWith(function() {
			  return jQuery(this).contents(); //replace all found instances of .PlusEditorPreWrap with its contents
			});
			//then apply PlusEditorFormatters
			this.format(PlusEditorField)
			//then clean everything:
			this.cleanUp(PlusEditorField);
			//then wrap everything with a .PlusEditorPreWrap span
			var text = "<html><span class='PlusEditorPreWrap' style='white-space:pre-wrap;'>"+PlusEditorField.innerHTML+"</span></html>";
			return text;
		}
		return null;
	},
	cleanUp: function(PlusEditorField){ //this is purely an attempt at cleanup because some of the returned markup of execCommand() can be horrendous
		//this removes the class='Apple-style-span' that webkit adds:
		//jQuery(PlusEditorField).find('.Apple-style-span').removeClass('Apple-style-span'); //this leaves an empty "class"	attribute, so use the following line instead 
		jQuery(PlusEditorField).find('.Apple-style-span').removeAttr('class');
		//TODO: add code to replace <font> tags --> <span>s with style attribute
	},
	format: function(PlusEditorField){
		//this code is borrowed from PlusEditor.prototype.loadContent()
		/*
		var content=jQuery(PlusEditorField).html();
		var tempDiv=jQuery('<div></div>')[0];
		wikifier = new Wikifier(content,PlusEditor.parsers.postParser);
		wikifier.subWikify(tempDiv);
		jQuery(PlusEditorField).html(jQuery(tempDiv).text());
		*/ //todo:change this to make sure that the text nodes are wikified
		var content=PlusEditorField.innerHTML;
		wikifier= new Wikifier(PlusEditorField.innerHTML,PlusEditor.parsers.preParser);
		PlusEditor_wikifyTextNodes(PlusEditorField,wikifier);
	}
};

config.commands.PlusEdit={
	text: "edit+", //"✍",
	tooltip: "edit with Plus Editor",
	readOnlyText: "view",
	readOnlyTooltip: "view source",
	handler : function(event,src,title) {
		clearMessage();
		var tiddlerElem = document.getElementById(story.idPrefix + title);
		var fields = tiddlerElem.getAttribute("tiddlyFields");
		story.displayTiddler(null,title,config.options.txtPlusEditorTemplate || "PlusEditorTemplate",false,null,fields);
		return false;
	}
};
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function contextualCallback(obj, func) {
    return function(){return func.call(obj)}
};
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Settings & Default Button Definitions
PlusEditor.refreshButtonDelay=200;
PlusEditor.defaultHeight='200px';
PlusEditor.Toolbar.btwnButtonDelim ='~' ; // TODO: change the appropriate sections in the code to reflect this abstraction
PlusEditor.Toolbar.btwnParamsDelim = '|';
PlusEditor.Button.buttonHalfHeightClass="PEbuttonHalfHeight";
PlusEditor.Button.buttonClass="PEbutton";
PlusEditor.Button.buttononClass="PEbuttonON";
PlusEditor.Button.buttonSize=20; //(width & height will be equal), this should be in px and *EVEN* b/c of division by 2 for halfHeight buttons and smallspace spaces


config.shadowTiddlers.PlusEditorButtonList='undo~removeformat~\n\
newgroup|space~bold~italic~underline~strikethrough~superscript~subscript~\n\
newgroup|space~justifyleft~justifycenter~justifyright~justifyfull ~\n\
newgroup|space~insertunorderedlist~insertorderedlist~indent~outdent ~\n\
newgroup|space~FontMenu~FontSizeMenu~\n\
newrow~label|back\ncolor ~\n\
hilitecolor|&nbsp;|highlight black|black||background-color: black ~\n\
hilitecolor|&nbsp;|highlight white|white||background-color: white ~\n\
hilitecolor|&nbsp;|highlight pink|pink||background-color: pink ~\n\
hilitecolor|&nbsp;|highlight orange|orange||background-color: orange ~\n\
hilitecolor|&nbsp;|highlight yellow|yellow||background-color: yellow ~\n\
hilitecolor|&nbsp;|highlight green|lightgreen||background-color: lightgreen ~\n\
hilitecolor|&nbsp;|highlight blue|lightblue||background-color: lightblue ~\n\
hilitecolor|&nbsp;|highlight purple|#D9B2D9||background-color: #D9B2D9~\n\
newgroup~label|text\ncolor: ~\n\
forecolor|&nbsp;|black|black||background-color: black ~\n\
forecolor|&nbsp;|white|white||background-color: white ~\n\
forecolor|&nbsp;|red|red||background-color: red ~\n\
forecolor|&nbsp;|orange|orange||background-color: orange ~\n\
forecolor|&nbsp;|yellow|yellow||background-color: yellow ~\n\
forecolor|&nbsp;|green|green||background-color: green ~\n\
forecolor|&nbsp;|blue|blue||background-color: blue ~\n\
forecolor|&nbsp;|purple|purple||background-color: purple|~\n\
newrow|HR~label|insert: |2~\n\
insertparagraph~inserthorizontalrule~insertHTML~insertLink~unlink~insertSymbol~';

config.annotations.PlusEditorButtonList='This tiddler contains the complete button list for the PlusEditor toolbar.\n\
Ordinary buttons are defined in the following format:\n\
{{{~<command name>|<button label>|[button tooltip]|[command parameter]|[prompt text]|[button css styling]|[button span]~}}}\n\
There are some predefined button commands:\n\
* {{{~newgroup[|space]~}}} creates a new group in the toolbar. The optional {{{space}}} will create a space between the new group and previous group.\n\
* {{{~newrow[|HR]~}}} creates a new row in the toolbar. The optional {{{HR}}} creates a horizontal line between the new row and the previous row.\n\
* {{{label|<label text>[|span integer][|css]}}} will create a new group and place a label before it. {{{label text}}} is required.\n\
Some rules:\n\
* anything in {{{< >}}} brackets is REQUIRED, but may be different for different buttons\n\
* anything in {{{[ ]}}} brackets is optional\n\
* do not use tildes (~) or the pipe character (|) //anywhere// except to delimit buttons and button parameters. These are reserved characters.\n\
* do not enter ANYTHING for parameters you wish to leave blank. If you want to define a parameter downstream from an empty parameter, insert the appropriate number of {{{|}}}\'s without any spaces\n\
See PlusEditorPluginInfo for detailed information on button definitions and customization of PlusEditor.';

PlusEditor.Info='*tildes (~) separate buttons in the toolbar. They are REQUIRED between EVERY button! Do NOT use tildes anywhere else (prompts,button labels, etc..)\n\
*anything in {{{< >}}} brackets is REQUIRED, but may be different for different buttons\n\
*anything in {{{[ ]}}} brackets is optional\n\
*DO NOT enter the brackets when creating a button entry!\n\
*an example button that sets the font color to dark blue is:\n\
{{{~ forecolor|&nbsp;|darkblue|darkblue||background-color: darkblue; ~}}}';





PlusEditor.Toolbar.buttons = {
undo: {label:'↩', tooltip:'restore text before last BUTTON action\n(does not undo typing!)'},
removeformat : {label:"&#8855;", tooltip : "remove formatting from selection\n(sometimes it's necessary to make the selection extend BEYOND the area that will be reset)", css:"font-family:'courier new';font-size:25px;"},
bold : {label:"B", tooltip : "bold", css:'font-weight:bold; font-family:georgia;'},
italic : {label:"I", tooltip : "italic", css:'font-style:italic; font-family:georgia;'},
superscript: {label:"x<sup>2</sup>", tooltip:'superscript',css:'font-size:15px;line-height:15px;'},
subscript:{label:'x<sub>2</sub>',tooltip:'subscript',css:'font-size:15px;line-height:15px;'},
underline : {label:"U", tooltip : "underline", css:'text-decoration:underline; font-family:georgia;'},
strikethrough : {label:"S", tooltip : "strikethrough", css:'text-decoration:line-through; font-family:georgia;'},
justifyleft : {label:"[\u2261", tooltip : "align left"},
justifyright : {label:"\u2261]", tooltip : "align right"},
justifycenter : {label:"\u2261", tooltip : "align center"},
justifyfull : {label:"[\u2261]", tooltip : "justify"},
fontsize : {label:"\u00B1", tooltip : "set font size", prompt: "Enter font size (1-6)"},
forecolor : {label:"C", tooltip : "set custom text color", prompt: "Set custom text color: \n  enter color (example: black, red, darkblue, ...) \n  or rgb color code (e.g. rgb(#,#,#) ) \n  or hex color code (e.g. #ABC or #AABBCC) "},
fontname : {label:"F", tooltip : "set font name", prompt: "Enter font name (example: times, arial, courier new, ...)", css:'font-family:serif'},
heading : {label:"H", tooltip : "set heading level", prompt: "Enter heading level (example : h1, h2, ...)", css:"font-family:georgia"},
indent : {label:"\u2192]", tooltip : "indent paragraph"},
outdent : {label:"[\u2190", tooltip : "outdent paragraph"},
increasefontsize : {label:"+", tooltip : "Increase font size"},
decreasefontsize : {label:"-", tooltip : "Decrease font size"},
unlink: {label:'L-',tooltip:'remove link from HTML link',css:'font-family:georgia;'},
insertunorderedlist : {label:"\u25CF", tooltip : "bulleted list"},
insertorderedlist : {label:"#.", tooltip : "numbered list"},
inserthorizontalrule : {label:"\u2014", tooltip : "insert horizontal line"},
insertimage : {label:"\u263C", tooltip : "insert image", prompt: "Enter image url \n(example: http://www.example.com/image.jpg)"},
insertparagraph:{label:'P', tooltip:'insert a new paragraph',css:'font-family:georgia;'},
insertHTML: {label:'H', tooltip:'insert HTML', prompt:'enter HTML below and press OK to insert at selection',css:'font-family:georgia;'}
};
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// STYLES
/*
you can add more "PElabel<n>" classes for support of larger labels:
* the formula for the correct width is: n*PlusEditor.Toolbar.buttonSize + (n-1)*6
* so the correct approach is: .PlusEditorToolbar .PElabel<n> {width:"+(<n>*PlusEditor.Toolbar.buttonSize + (<n>-1)*6)+"px;}
* math/JS is not permitted in CSS, so the following method is recommended:
** add this line in a tiddler tagged systemConfig (PlusEditorPluginOptions tiddler recommended):
** n=<>; config.shadowTiddlers.PlusEditorToolbarStyleSheet+=".PlusEditorToolbar .PElabel"+n+" {width:"+(n*PlusEditor.Toolbar.buttonSize + (n-1)*6)+"px;}\n";
* where the <> is replaced by the integer number of buttons that you wish to have the label span (example: n=5;)
* FYI: the 6 is for the border+margin+padding on either side (all 1px)
* of course any width can be set for any element in the toolbar, but this approach maintains a consistent alignment that is visually appealing
*/
PlusEditor.Stylesheet = "/*{{{*/\n\
.PlusEditorField {border:1px solid #DDD; border-top: 0px solid #DDD; overflow:auto; white-space:pre-wrap; word-wrap:normal; margin-top:4px}\n\
.PlusEditorToolbar {border:1px solid #DDD; overflow:auto; background-color:white;}\n\
.PEgroup {white-space:pre}\n\
.PEseparator ,.PElabel ,."+PlusEditor.Button.buttonClass+" {display:inline-block; border:1px solid #888; padding:1px; margin:1px; text-align:center; vertical-align:middle; color:#444; overflow:hidden; font-size:17px; width:"+PlusEditor.Button.buttonSize+"px; height:"+PlusEditor.Button.buttonSize+"px; line-height:"+PlusEditor.Button.buttonSize+"px; }\n\
.PEseparatorSmall{width: 2px;}\n\
.PElabel {padding:0px; border:1px solid transparent; text-align:left; font-size:10px; line-height:10px; word-wrap:break-word; white-space:pre-wrap; width:"+(PlusEditor.Button.buttonSize+2)+"px;}\n\
."+PlusEditor.Button.buttonHalfHeightClass+"{}\n\
.PEseparator {border-color:white; border-color: transparent}\n\
.PEspace {}\n\
.PlusEditorToolbar>div{clear:both;}\n\
.PEhr {border:1px; border-top:1px solid #DDD; margin:1px 0px;}\n\
."+PlusEditor.Button.buttonClass+":hover{color:darkblue;background-color:#cceeff}\n\
."+PlusEditor.Button.buttonClass+":active{color:darkblue;background-color:#cceeff; border-color:blue;}\n\
."+PlusEditor.Button.buttononClass+" {color:darkblue;background-color:#cceeff; border-color:blue;}\n\
."+PlusEditor.Button.buttononClass+" .highlight {color:darkblue;background-color:#cceeff; border-color:blue;}\n\
/*}}}*/";


// TEMPLATE
config.shadowTiddlers.PlusEditorTemplate = config.shadowTiddlers.EditTemplate.replace(/macro='edit text'/,"macro='PlusEdit text'");
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//Plus Editor Prompt Class
PlusEditor.Prompt=function(caller,inputs,data,onOK){
	this.data=data || null;
	this.submitted=false;
	this.caller=caller;
	this.onOK=onOK || null;
	this.inputs=[];
	var promptID=this.id=PlusEditor.Prompt.count ++; 
	var inputCount=0;
	var p= PlusEditor.Prompt.createPopup(this.caller,null,'popup sticky PEprompt'); if(!p) return;
	this.popup = p;
	var pd=createTiddlyElement(p,'div');
	if(inputs[0].caption){ 
		createTiddlyElement(pd,'div',null,'PEpromptCaption').innerHTML=inputs[0].caption;
		createTiddlyElement(pd,'hr',null,'PEpromptHR'); 
	}
	var width = inputs[0].width ? (inputs[0].width +'px') : '200px';	
	var startForLoop= (inputs[0].caption || inputs[0]) ? 1 : 0;	
	for(i=startForLoop;i<inputs.length;i++){
		if(inputs[i].grouplabel){
			var d=createTiddlyElement(pd,'div',null,'PEpromptSection').innerHTML=inputs[i].grouplabel;
		}else{
			this.inputs.push(inputs[i]);
			inputCount ++;
			inputs[i].id='PEPinput'+inputCount; // of course, this also sets the id of this.inputs[i]
			var d=createTiddlyElement(pd,'div',null,'PEpromptSection');
			
			if(inputs[i].label){
				var l=jQuery(createTiddlyElement(d,'label',null,'PEpromptLabel',inputs[i].label)).attr('for',inputs[i].id)[0];
			}
			if(inputs[i].type==='radio'||inputs[i].type==='checkbox'){ 
				var iEl= createTiddlyElement(d,'input',inputs[i].id,'PEpromptRadioCheck',null,{type:inputs[i].type,name:inputs[i].name||'PEPinput'});
				iEl.checked = inputs[i].checked || false; 
			}
			if(inputs[i].type=='text') { 
				var iEl= createTiddlyElement(d,'input',inputs[i].id,'PEpromptText',null,{type:inputs[i].type,name:inputs[i].name||'PEPinput'});
				iEl.value=inputs[i].value || ''; 
			}
			if(inputs[i].css){
				jQuery(iEl).attr('style',inputs[i].css);
			}
		}	
	}
	createTiddlyElement(pd,'hr',null,'PEpromptHR');
	createTiddlyButton(pd,'Cancel',null,function(){PlusEditor.Prompt.onCancel(promptID);}, 'button PEpromptButton');
	createTiddlyButton(pd,'OK',null,function(){PlusEditor.Prompt.onSubmit(promptID);},'button PEpromptButton').style.marginRight='5px';
	setStylesheet('.PEprompt {font-size:13px;padding:1px;width:'+width+' background-color:white;}\n.PEprompt div {clear:both;}\n.PEprompt .PEpromptRadioCheck{position:absolute;right:0px;margin:1px 0px 1px;}\n.PEpromptText{ border-width:0px; outline-width:0px;}\n.PEprompt .PEpromptCaption{font-size:15px;}\n.PEprompt .PEpromptSection{padding:2px 0px; white-space:pre-wrap;}\n.PEprompt .PEpromptLabel{display:inline-block;width:100%;}\n.PEpromptButton {float:right;}','PlusEditorPromptStylesheet');
	PlusEditor.Prompt.stack.push(this);
	this.show();
}

PlusEditor.Prompt.createPopup=function(root,elem,className){
	//return createTiddlyElement(document.body,elem || "ol","popup",className || "popup");
	return Popup.create(root,elem,className)
}

PlusEditor.Prompt.prototype.show=function(){
	/*Popup.place(this.caller,this.popup);
	window.scrollTo(0,ensureVisible(this.popup));
	this.displayed=true;
	*/
	Popup.stack.push({root:this.caller,popup:this.popup});
	Popup.show();	
}

PlusEditor.Prompt.prototype.remove=function(){
	//jQuery(this.popup).remove();
	Popup.remove();
}

PlusEditor.Prompt.stack=[] // where all PEprompts will get pushed
PlusEditor.Prompt.count=0; //how many prompts
PlusEditor.Prompt.onSubmit=function(promptID){
	var PEprompt=PlusEditor.Prompt.stack[promptID]; if(!PEprompt) {return;}
	for(i=0;i<PEprompt.inputs.length; i++){
		var inEl=document.getElementById(PEprompt.inputs[i].id)
		switch(PEprompt.inputs[i].type){
			case 'text':
				PEprompt.inputs[i].value=inEl.value;
				break;
			case 'radio':
			case 'checkbox':
				PEprompt.inputs[i].checked=inEl.checked;
				break;
			default:
		}
	}
	PEprompt.submitted=true;
	if (PEprompt.onOK) {
		PEprompt.onOK(PEprompt.toOK);
	}
	PEprompt.remove();
}

PlusEditor.Prompt.onCancel=function(promptID){
	var PEprompt=PlusEditor.Prompt.stack[promptID]; if(!PEprompt) {return;}
	PEprompt.remove();
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
PlusEditor.Toolbar.DropDownToolbar=function(button,ev,valign,halign,commands,labels,tooltips,parameters,csss,span,buttonsInRow){
	var buttonList=new String();
	var rowButtonCount=0; //current # buttons in row
	for(var i=0;i<parameters.length;i++){
		buttonList+= PlusEditor.Toolbar.btwnButtonDelim ;
		if(isString(commands)){
			buttonList+= commands + PlusEditor.Toolbar.btwnParamsDelim;
		}else{
			buttonList+=commands[i] + PlusEditor.Toolbar.btwnParamsDelim;
		}
		if(labels && labels[i]){
			buttonList+=labels[i] + PlusEditor.Toolbar.btwnParamsDelim;
		}else{
			buttonList+=PlusEditor.Toolbar.btwnParamsDelim;
		}
		if(tooltips && tooltips[i]){
			buttonList+=tooltips[i] + PlusEditor.Toolbar.btwnParamsDelim;
		}else{
			buttonList+= PlusEditor.Toolbar.btwnParamsDelim;
		}	
		buttonList+= parameters[i] + PlusEditor.Toolbar.btwnParamsDelim + PlusEditor.Toolbar.btwnParamsDelim;
		if(csss && csss[i]){
			buttonList+=csss[i] + PlusEditor.Toolbar.btwnParamsDelim;
		}else{
			buttonList+=PlusEditor.Toolbar.btwnParamsDelim;
		}
		buttonList+=span;
		rowButtonCount++;
		if(rowButtonCount==buttonsInRow){
				buttonList+='~newrow~';
				rowButtonCount=0;
			}
		
	}
	var p=Popup.create(button.element,null,'sticky popup');
	PlusEditor.Toolbar(p,button.target,buttonList);
	Popup.show(valign || null, halign || null);
	ev.cancelBubble=true;
	if(ev.stopPropagation) {ev.stopPropagation();}
	return(false);
};
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Core Xtensions:
PlusEditor.Toolbar.buttons.FontMenu={
	label:'font',
	css:'font-family:times;font-size:12px;',
	tooltip:'set selection font',
	fonts:['Arial','Arial narrow','Courier new','Cursive','Fantasy','Garamond','Georgia','Helvetica','Impact','Lucida console','Monospace','Palatino','Serif','Sans-serif','Times','Verdana'],
	onClick:function(ev){
		var csss=[];
		for(var i=0;i<this.fonts.length;i++){
			csss.push('font-family:'+this.fonts[i]+';')
		}
		PlusEditor.Toolbar.DropDownToolbar(this,ev,null,null,'fontname',this.fonts,this.fonts,this.fonts,csss,7,1)
	}	
}
PlusEditor.Toolbar.buttons.FontSizeMenu={
	label:'size',
	css:'font-family:times;font-size:13px;',
	tooltip:'set font size',
	sizes:['1','2','3','4','5','6'],
	labels:['x-small','small','medium (normal)','large','x-large','xx-large'],
	onClick:function(ev){
		var csss=[];
		for(var i=0;i<this.labels.length;i++){
			csss.push('height:30px;line-height:30px;font-size:'+this.labels[i]+';')
		}
		PlusEditor.Toolbar.DropDownToolbar(this,ev,null,null,'fontsize',this.labels,null,this.sizes,csss,6,1);
	}	
}


PlusEditor.Toolbar.buttons.SymbolsMenu={
	halign:'right',
	valign:null,
	buttonsInRow: 20,
	label:'S',
	css:'font-family:georgia;',
	tooltip:'insert a symbol',
	symbols: ['&alpha;','&beta;'],
	onClick: function(ev){
		var tooltips=[];
		for(var i=0;i<this.symbols.length;i++){
			tooltips.push('insert '+this.symbols[i])
		}
		PlusEditor.Toolbar.DropDownToolbar(this,ev,null,null,'insertHTML',this.symbols,tooltips,this.symbols,null,1,this.buttonsInRow);
	}
}

PlusEditor.Toolbar.buttons.insertSymbol={
	label:'S',
	css:'font-family:georgia;',
	tooltip:'insert a symbol',
	onClick:function(ev){
		var buttonList='';
		for(name in PlusEditor.Symbols){
			buttonList+= PlusEditor.Toolbar.btwnButtonDelim + name +PlusEditor.Toolbar.btwnButtonDelim+'newrow';
		}
		var p=Popup.create(this.element,null,'sticky popup');
		tb=new PlusEditor.Toolbar(p,this.target,buttonList);
		Popup.show();
		ev.cancelBubble=true;
		if(ev.stopPropagation) {ev.stopPropagation();}
		return(false);
	}
}

PlusEditor.Symbols={
	arrows: ['&rarr;','&larr;','&uarr;','&darr;','&harr;','&rArr;','&lArr;','&uArr;','&dArr;','&hArr;'],
	greek: ['&alpha;','&beta;','&gamma;','&delta;','&epsilon;','&zeta;','&eta;','&theta;','&iota;','&kappa;','&lambda;','&mu;','&nu;','&xi;','&omicron;','&pi;','&rho;','&sigma;','&tau;','&upsilon;','&phi;','&chi;','&psi;','&omega;','&Alpha;','&Beta;','&Gamma;','&Delta;','&Epsilon;','&Zeta;','&Eta;','&Theta;','&Iota;','&Kappa;','&Lambda;','&Mu;','&Nu;','&Xi;','&Omicron;','&Pi;','&Rho;','&Sigma;','&Tau;','&Upsilon;','&Phi;','&Chi;','&Psi;','&Omega;'],
	math: ["&#x2200;", "&#x2201;", "&#x2202;", "&#x2203;", "&#x2204;", "&#x2205;", "&#x2206;", "&#x2207;", "&#x2208;", "&#x2209;", "&#x220A;", "&#x220B;", "&#x220C;", "&#x220D;", "&#x220E;", "&#x220F;", "&#x2210;", "&#x2211;", "&#x2212;", "&#x2213;", "&#x2214;", "&#x2215;", "&#x2216;", "&#x2217;", "&#x2218;", "&#x2219;", "&#x221A;", "&#x221B;", "&#x221C;", "&#x221D;", "&#x221E;", "&#x221F;", "&#x2220;", "&#x2221;", "&#x2222;", "&#x2223;", "&#x2224;", "&#x2225;", "&#x2226;", "&#x2227;", "&#x2228;", "&#x2229;", "&#x222A;", "&#x222B;", "&#x222C;", "&#x222D;", "&#x222E;", "&#x222F;", "&#x2230;", "&#x2231;", "&#x2232;", "&#x2233;", "&#x2234;", "&#x2235;", "&#x2236;", "&#x2237;", "&#x2238;", "&#x2239;", "&#x223A;", "&#x223B;", "&#x223C;", "&#x223D;", "&#x223E;", "&#x223F;", "&#x2240;", "&#x2241;", "&#x2242;", "&#x2243;", "&#x2244;", "&#x2245;", "&#x2246;", "&#x2247;", "&#x2248;", "&#x2249;", "&#x224A;", "&#x224B;", "&#x224C;", "&#x224D;", "&#x224E;", "&#x224F;", "&#x2250;", "&#x2251;", "&#x2252;", "&#x2253;", "&#x2254;", "&#x2255;", "&#x2256;", "&#x2257;", "&#x2258;", "&#x2259;", "&#x225A;", "&#x225B;", "&#x225C;", "&#x225D;", "&#x225E;", "&#x225F;", "&#x2260;", "&#x2261;", "&#x2262;", "&#x2263;", "&#x2264;", "&#x2265;", "&#x2266;", "&#x2267;", "&#x2268;", "&#x2269;", "&#x226A;", "&#x226B;", "&#x226C;", "&#x226D;", "&#x226E;", "&#x226F;", "&#x2270;", "&#x2271;", "&#x2272;", "&#x2273;", "&#x2274;", "&#x2275;", "&#x2276;", "&#x2277;", "&#x2278;", "&#x2279;", "&#x227A;", "&#x227B;", "&#x227C;", "&#x227D;", "&#x227E;", "&#x227F;", "&#x2280;", "&#x2281;", "&#x2282;", "&#x2283;", "&#x2284;", "&#x2285;", "&#x2286;", "&#x2287;", "&#x2288;", "&#x2289;", "&#x228A;", "&#x228B;", "&#x228C;", "&#x228D;", "&#x228E;", "&#x228F;", "&#x2290;", "&#x2291;", "&#x2292;", "&#x2293;", "&#x2294;", "&#x2295;", "&#x2296;", "&#x2297;", "&#x2298;", "&#x2299;", "&#x229A;", "&#x229B;", "&#x229C;", "&#x229D;", "&#x229E;", "&#x229F;", "&#x22A0;", "&#x22A1;", "&#x22A2;", "&#x22A3;", "&#x22A4;", "&#x22A5;", "&#x22A6;", "&#x22A7;", "&#x22A8;", "&#x22A9;", "&#x22AA;", "&#x22AB;", "&#x22AC;", "&#x22AD;", "&#x22AE;", "&#x22AF;", "&#x22B0;", "&#x22B1;", "&#x22B2;", "&#x22B3;", "&#x22B4;", "&#x22B5;", "&#x22B6;", "&#x22B7;", "&#x22B8;", "&#x22B9;", "&#x22BA;", "&#x22BB;", "&#x22BC;", "&#x22BD;", "&#x22BE;", "&#x22BF;", "&#x22C0;", "&#x22C1;", "&#x22C2;", "&#x22C3;", "&#x22C4;", "&#x22C5;", "&#x22C6;", "&#x22C7;", "&#x22C8;", "&#x22C9;", "&#x22CA;", "&#x22CB;", "&#x22CC;", "&#x22CD;", "&#x22CE;", "&#x22CF;", "&#x22D0;", "&#x22D1;", "&#x22D2;", "&#x22D3;", "&#x22D4;", "&#x22D5;", "&#x22D6;", "&#x22D7;", "&#x22D8;", "&#x22D9;", "&#x22DA;", "&#x22DB;", "&#x22DC;", "&#x22DD;", "&#x22DE;", "&#x22DF;", "&#x22E0;", "&#x22E1;", "&#x22E2;", "&#x22E3;", "&#x22E4;", "&#x22E5;", "&#x22E6;", "&#x22E7;", "&#x22E8;", "&#x22E9;", "&#x22EA;", "&#x22EB;", "&#x22EC;", "&#x22ED;", "&#x22EE;", "&#x22EF;", "&#x22F0;", "&#x22F1;", "&#x22F2;", "&#x22F3;", "&#x22F4;", "&#x22F5;", "&#x22F6;", "&#x22F7;", "&#x22F8;", "&#x22F9;", "&#x22FA;", "&#x22FB;", "&#x22FC;", "&#x22FD;", "&#x22FE;", "&#x22FF;","&#x2153;", "&#x2154;", "&#x2155;", "&#x2156;", "&#x2157;", "&#x2158;", "&#x2159;", "&#x215A;", "&#x215B;", "&#x215C;", "&#x215D;", "&#x215E;"],
	numbers: ["&#x2070;", "&#x2071;","&#xb2;","&#xb3;","&#x2074;", "&#x2075;", "&#x2076;", "&#x2077;", "&#x2078;", "&#x2079;", "&#x207A;", "&#x207B;", "&#x207C;", "&#x207D;", "&#x207E;", "&#x207F;", "&#x2080;", "&#x2081;", "&#x2082;", "&#x2083;", "&#x2084;", "&#x2085;", "&#x2086;", "&#x2087;", "&#x2088;", "&#x2089;", "&#x208A;", "&#x208B;", "&#x208C;", "&#x208D;", "&#x208E;"]
};

for(name in PlusEditor.Symbols){
	PlusEditor.Toolbar.buttons[name]=jQuery.extend({},PlusEditor.Toolbar.buttons.SymbolsMenu);
	PlusEditor.Toolbar.buttons[name].symbols=PlusEditor.Symbols[name];
	PlusEditor.Toolbar.buttons[name].label=name;
	PlusEditor.Toolbar.buttons[name].span=3;
};


PlusEditor.Toolbar.buttons.insertLink={
	label:'L+',
	tooltip:'create a link',
	css:'font-family:georgia',
	onClick: function(ev,selection,range){
		var data={
			button:this,
			selection: selection,
			range: range,
			canSurroundContents:true
		};
		if(selection.isCollapsed){
			var options=[
			{caption:"Insert link"},
			{type:'text',label:'link location',css:'width:98%;'},
			{type:'text',label:'link text',css:'width:98%;'}];	
		}else if(range.canSurroundContents()){
			var options=[
			{caption:"Insert link"},
			{type:'text',label:'link location', value:selection.toString(),css:'width:98%;'},
			{type:'text',label:'link text', value:selection.toString(),css:'width:98%;'}];
		} else {
			data.canSurroundContents=false;
			var options=[
			{caption:"Insert link"},
			{grouplabel:'Unable to insert link. \nMake sure that the selection surrounds contiguous text with the same formatting.\n\nTip: smaller selections are better.\n\n[error: selection partially selects a non-text node.]'}];
		}
		options.push({type:'radio',label:'wiki link',name:'linkType',checked:true},
					{type:'radio',label:'HTML link',name:'linkType'})
		
		new PlusEditor.Prompt(this.element,options,data,function(){
			if(data.canSurroundContents){
				var linklocation = this.inputs[0].value || this.inputs[1].value || null;
				var linktext=this.inputs[1].value || this.inputs[0].value || null;
				if (linklocation && linktext){
					if(this.inputs[2].checked){
						if(linklocation==linktext){
							var linkHTML='[['+linklocation+']]';
						}else{
							var linkHTML='[['+linktext+'|'+linklocation+ ']]';
						}
						
					}else{
						//a=createTiddlyLink
						var linkHTML="<a href='" +linklocation+ "' >" + linktext + "</a>";
					}
					data.selection.setSingleRange(data.range);//restore the selection to the editorfield
					data.button.doc.execCommand('insertHTML',false,linkHTML);
				}		
			}
		});	
	}
}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//}}}
//{{{
// rangy 1.1 BETA core compressed w/ Packer 3.0
eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('J 3e=(K(){J f="3f",5J="K",2G="2c";J g=["Q","T","U","V","1D","2H","5K","3g","3h","5L"];J h=["1r","2I","2J","1s","2K","3i","1E","2L","1N","2d","3j","3k","3Q","5M","3R","2M","2t","1c"];J j=["6Q","6R","6S","6T","6U","3S"];J k=["1E","3T","3l","6V","6W","4G","3m","6X","2u","3U"];K 1l(o,p){J t=1b o[p];M t==5J||(!!(t==f&&o[p]))||t=="6Y"}K 2e(o,p){M!!(1b o[p]==f&&o[p])}K 3n(o,p){M 1b o[p]!=2G}K 3V(b){M K(o,a){J i=a.S;1m(i--){L(!b(o,a[i])){M R}}M O}}J l=3V(1l);J m=3V(2e);J n=3V(3n);J q={21:R,2f:O,3o:{1l:1l,2e:2e,3n:3n,2N:l,3W:m,3X:n},1y:{},4H:{},3Y:{5N:R}};K 1F(a){1j.5O("4I 2g 2f 5P 6Z 70. 71: "+a);q.21=O;q.2f=R}q.1F=1F;K 4J(a){J b="4I 72: "+a;L(q.3Y.5N){1j.5O(b)}N L(1b 1j.2O!=2G&&1b 1j.2O.3Z!=2G){1j.2O.3Z(b)}}q.4J=4J;K 3p(){L(q.21){M}J a;J b=R,2h=R;L(1l(W,"1i")){a=W.1i();L(l(a,h)&&n(a,g)){b=O}a.1c()}J c=2e(W,"1O")?W.1O:W.40("1O")[0];L(c&&1l(c,"2v")){a=c.2v();L(l(a,k)&&n(a,j)){2h=O}}L(!b&&!2h){1F("73 13 74 4K 5Q 75")}q.21=O;q.1y={2P:b,2h:2h};J d=s.76(r);1d(J i=0,14=d.S;i<14;++i){22{d[i](q)}23(1R){L(2e(1j,"2O")&&1l(1j.2O,"3Z")){2O.3Z("77 78 79 7a 7b. 7c.",1R)}}}}q.3p=3p;J r=[];J s=[];q.7d=K(a){L(q.21){a(q)}N{r.2i(a)}};J u=[];q.4L=K(a){u.2i(a)};K 4M(a){a=a||1j;3p();1d(J i=0,14=u.S;i<14;++i){u[i](a)}}q.4M=4M;K 2j(a){I.4N=a;I.21=R;I.2f=R}2j.1w.1F=K(a){I.21=O;I.2f=R;Y P 1z("2j \'"+I.4N+"\' 7e 41 5R: "+a);};2j.1w.7f=K(a){M P 1z("1z 5P 4I "+I.4N+" 2Q: "+a)};q.3q=K(b,c){J d=P 2j(b);q.4H[b]=d;s.2i(K(a){c(a,d);d.21=O;d.2f=O})};q.42=K(a){1d(J i=0,14=a.S,2Q,3r;i<14;++i){3r=a[i];2Q=q.4H[3r];L(!2Q||!(2Q 43 2j)){Y P 1z("2j \'"+3r+"\' 2g 2k");}L(!2Q.2f){Y P 1z("2j \'"+3r+"\' 2g 2f");}}};J v=R;J w=K(e){L(!v){v=O;L(!q.21){3p()}}};L(1b 1j==2G){1F("2l 1j 2k");M}L(1b W==2G){1F("2l W 2k");M}L(1l(W,"3s")){W.3s("7g",w,R)}L(1l(1j,"3s")){1j.3s("5R",w,R)}N L(1l(1j,"4O")){1j.4O("7h",w)}N{1F("5S 4P 2g 4Q 7i 3s 4R 4O 4S")}M q})();3e.3q("44",K(f,g){J h="2c";J j=f.3o;L(!j.2N(W,["2R","2S","2T"])){g.1F("W 5T a 5U 7j 4S")}L(!j.1l(W,"40")){g.1F("W 5T 40 4S")}J k=W.2S("5V");L(!j.2N(k,["2U","1A","2m"]||!j.3W(k,["2w","24","1n","15"]))){g.1F("5W 4T 5X")}J l=W.2T("3t");L(!j.2N(l,["5Y","2V","5Z","60","2m"]||!j.3W(k,["2w","24","1n","15"])||!j.3X(l,["25"]))){g.1F("5W 7k 5U 5X")}J m=K(a,b){J i=a.S;1m(i--){L(a[i]===b){M O}}M R};K 1P(a){J i=0;1m((a=a.2w)){i++}M i}K 2x(a,b){J c=[],n;1d(n=a;n;n=n.15){c.2i(n)}1d(n=b;n;n=n.15){L(m(c,n)){M n}}M 16}K 1S(a,b,c){J n=c?b:b.15;1m(n){L(n===a){M O}N{n=n.15}}M R}K 1T(a,b,c){J p,n=c?a:a.15;1m(n){p=n.15;L(p===b){M n}n=p}M 16}K 1e(a){J t=a.1k;M t==3||t==4||t==8}K 3u(a,b){J c=b.24,4U=b.15;L(c){4U.2U(a,c)}N{4U.1A(a)}M a}K 2W(a,b){J c;L(a.1k==3){c=a.5Y(b)}N{c=a.2m();c.2V(0,b);a.2V(0,a.S-b);3u(c,a)}M c}K 1h(a){L(a.1k==9){M a}N L(1b a.61!=h){M a.61}N L(1b a.W!=h){M a.W}N L(a.15){M 1h(a.15)}N{Y P 1z("1h: 62 W 2k 1d 1t");}}K 45(a){J b=1h(a);L(1b b.4V!=h){M b.4V}N L(1b b.63!=h){M b.63}N{Y P 1z("7l 7m a 1j 3f 1d 1t");}}K 3v(a){L(1b a.46!=h){M a.46}N L(1b a.47!=h){M a.47.W}N{Y P 1z("2X: 2l 7n 3f 2k 1d 64 4W");}}K 2X(a){L(1b a.47!=h){M a.47}N L(1b a.46!=h){M a.46.4V}N{Y P 1z("2X: 2l 5S 3f 2k 1d 64 4W");}}K 26(a){M j.2e(a,"1O")?a.1O:a.40("1O")[0]}K 1u(a,b,c,d){J e,1G,3w,3x,n;L(a==c){M b===d?0:(b<d)?-1:1}N L((e=1T(c,a,O))){M b<=1P(e)?-1:1}N L((e=1T(a,c,O))){M 1P(e)<d?-1:1}N{1G=2x(a,c);3w=(a===1G)?1G:1T(a,1G,O);3x=(c===1G)?1G:1T(c,1G,O);L(3w===3x){Y P 1z("1u 7o 41 7p 4 65 3w 65 3x 5Q 3y 7q!");}N{n=1G.48;1m(n){L(n===3w){M-1}N L(n===3x){M 1}n=n.24}Y P 1z("7r 2g 49 7s!");}}}K 2Y(a){L(!a){M"[2l 1t]"}L(1e(a)){M\'"\'+a.25+\'"\'}N L(a.1k==1){J b=a.4X?\' 4X="\'+a.4X+\'"\':"";M"<"+a.66+b+">["+a.1n.S+"]"}N{M a.66}}K 4Y(a){I.1G=a;I.1o=a}4Y.1w={1x:16,4Z:K(){M!!I.1o},1M:K(){J n=I.1x=I.1o;J a,1M;L(I.1x){a=n.48;L(a){I.1o=a}N{1M=16;1m((n!==I.1G)&&!(1M=n.24)){n=n.15}I.1o=1M}}M I.1x},1c:K(){I.1x=I.1o=I.1G=16}};K 4a(a){M P 4Y(a)}K 2n(a,b){I.1t=a;I.1K=b}2n.1w={67:K(a){M I.1t===a.1t&I.1K==a.1K},1B:K(){M"[2n("+2Y(I.1t)+":"+I.1K+")]"}};K 2o(a){I.68=I[a];I.4b=a;I.4c="2o: "+I.4b}2o.1w={50:1,2Z:3,4d:4,69:7,4e:8,7t:9,4f:11};2o.1w.2t=K(){M I.4c};f.4g={51:m,1P:1P,2x:2x,1S:1S,1T:1T,1e:1e,3u:3u,2W:2W,1h:1h,45:45,2X:2X,3v:3v,26:26,1u:1u,2Y:2Y,4a:4a,2n:2n};f.2o=2o});3e.3q("2y",K(l,m){l.42(["44"]);J p=l.4g;J q=p.2n;J s=l.2o;K 1U(a,b){I.27=a;I.52=b;L(!a.1D){I.1L=a.Q;I.18=a.T;I.17=a.U;I.1f=a.V;J c=a.2H;L(I.1L===I.17&&p.1e(I.1L)){I.53=O;I.2z=I.2A=I.1o=I.1L}N{I.2z=I.1o=(I.1L===c&&!p.1e(I.1L))?I.1L.1n[I.18]:p.1T(I.1L,c,O);I.2A=(I.17===c&&!p.1e(I.17))?I.17.1n[I.1f-1]:p.1T(I.17,c,O)}}}1U.1w={1x:16,1o:16,2z:16,2A:16,53:R,6a:K(){I.1x=16;I.1o=I.2z},4Z:K(){M!!I.1o},1M:K(){J a=I.1x=I.1o;L(a){I.1o=(a!==I.2A)?a.24:16;L(p.1e(a)&&I.52){L(a===I.17){(a=a.2m(O)).2V(I.1f,a.S-I.1f)}L(I.1x===I.1L){(a=a.2m(O)).2V(0,I.18)}}}M a},54:K(){J a=I.1x,28,1C;L(p.1e(a)&&(a===I.1L||a===I.17)){28=(a===I.1L)?I.18:0;1C=(a===I.17)?I.1f:a.S;L(28!=1C){a.2V(28,1C-28)}}N{L(a.15){a.15.1V(a)}N{}}},3z:K(){J a=I.1x;M 4h(a,I.27)},3A:K(){J a;L(I.53){a=I.27.2M();a.1E()}N{a=P 13(1H(I.27));J b=I.1x;J c=b,T=0,U=b,V=2B(b);L(p.1S(b,I.1L,O)){c=I.1L;T=I.18}L(p.1S(b,I.17,O)){U=I.17;V=I.1f}4i(a,c,T,U,V)}M P 1U(a,I.52)},1c:K(a){L(a){I.27.1c()}I.27=I.1x=I.1o=I.2z=I.2A=I.1L=I.18=I.17=I.1f=16}};K 29(a){I.68=I[a];I.4b=a;I.4c="29: "+I.4b}29.1w={6b:1,55:2};29.1w.2t=K(){M I.4c};K 1H(a){M p.1h(a.Q)}K 56(a,b,c){J d=a.4j[b];L(d){1d(J i=0,14=d.S;i<14;++i){d[i].7u(a,{7v:a,7w:c})}}}K 57(a){M P q(a.15,p.1P(a))}K 4k(a){M P q(a.15,p.1P(a)+1)}K 2B(a){M p.1e(a)?a.S:(a.1n?a.1n.S:0)}K 58(a,n,o){J b=a.1k==11?a.48:a;L(p.1e(n)){L(o==n.S){p.3u(a,n)}N{n.15.2U(a,o==0?n:p.2W(n,o))}}N L(o>=n.1n.S){n.1A(a)}N{n.2U(a,n.1n[o])}M b}K 59(a){J b;1d(J c,1W=1H(a.27).2R(),2p;c=a.1M();){b=a.3z();c=c.2m(!b);L(b){2p=a.3A();c.1A(59(2p));2p.1c(O)}L(c.1k==10){Y P s("2Z");}1W.1A(c)}M 1W}K 3B(a,b,c){J d,n;c=c||{4l:R};1d(J e,4m;e=a.1M();){L(a.3z()){L(b(e)===R){c.4l=O;M}N{4m=a.3A();3B(4m,b,c);4m.1c(O);L(c.4l){M}}}N{d=p.4a(e);1m((n=d.1M())){L(b(n)===R){c.4l=O;M}}}}}K 5a(a){J b;1m(a.1M()){L(a.3z()){b=a.3A();5a(b);b.1c(O)}N{a.54()}}}K 5b(a){1d(J b,1W=1H(a.27).2R(),2p;b=a.1M();){L(a.3z()){b=b.2m(R);2p=a.3A();b.1A(5b(2p));2p.1c(O)}N{a.54()}L(b.1k==10){Y P s("2Z");}1W.1A(b)}M 1W}K 5c(b,c,d){J e=!!(c&&c.S),5d;J f=!!d;L(e){5d=P 7x("^("+c.4n("|")+")$")}J g=[];3B(P 1U(b,R),K(a){L((!e||5d.3t(a.1k))&&(!f||d(a))){g.2i(a)}});M g}K 1B(a){J b=(1b a.2C=="2c")?"13":a.2C();M"["+b+"("+p.2Y(a.Q)+":"+a.T+", "+p.2Y(a.U)+":"+a.V+")]"}K 5e(a,b,c){I.4o=5c(a,b,c);I.1o=I.4o[0];I.6c=0}5e.1w={1x:16,4Z:K(){M!!I.1o},1M:K(){I.1x=I.1o;I.1o=I.4o[++I.6c];M I.1x},1c:K(){I.1x=I.1o=I.4o=16}};K 4h(a,b){M(a.1k!=3)&&(p.1S(a,b.Q,O)||p.1S(a,b.U,O))}J u=[1,3,4,5,7,8,10];J v=[2,9,11];J w=[5,6,10,12];J x=[1,3,4,5,7,8,10,11];J y=[1,3,4,5,7,8];K 4p(c){M K(a,b){J t,n=b?a:a.15;1m(n){t=n.1k;L(p.51(c,t)){M n}n=n.15}M 16}}K 30(a){J b;1m((b=a.15)){a=b}M a}J z=4p([9,11]);J A=4p(w);J B=4p([6,10,12]);K 31(a,b){L(B(a,b)){Y P 29("55");}}K 19(a){L(!a.Q){Y P s("4f");}}K 32(a,b){L(!p.51(b,a.1k)){Y P 29("55");}}K 4q(a,b){L(b<0||b>(p.1e(a)?a.S:a.1n.S)){Y P s("50");}}K 4r(a,b){L(z(a,O)!==z(b,O)){Y P s("4d");}}K 3C(a){L(A(a,O)){Y P s("69");}}K 3D(a,b){L(!a){Y P s(b);}}K 5f(a){M!z(a,O)}K 5g(a,b){M b<=(p.1e(a)?a.S:a.1n.S)}K 1p(a){L(5f(a.Q)||5f(a.U)||!5g(a.Q,a.T)||!5g(a.U,a.V)){Y P 1z("13 13 7y: 13 7z 62 7A 7B 7C 7D 7E ("+a.1B()+")");}}J C=["Q","T","U","V","1D","2H"];J D=0,5h=1,6d=2,5i=3;J E=0,5j=1,5k=2,4s=3;K 5l(a){a.5K=D;a.3g=5h;a.5L=6d;a.3h=5i;a.7F=E;a.7G=5j;a.7H=5k;a.7I=4s}K 3E(33){5l(33);5l(33.1w)}K 3F(33,j,k){K 3G(c,d){M K(a){19(I);32(a,u);32(30(a),v);J b=(c?57:4k)(a);(d?5m:5n)(I,b.1t,b.1K)}}K 5m(a,b,c){J d=a.U,1f=a.V;L(b!==a.Q||c!==I.T){L(30(b)!=30(d)||p.1u(b,c,d,1f)==1){d=b;1f=c}j(a,b,c,d,1f)}}K 5n(a,b,c){J d=a.Q,18=a.T;L(b!==a.U||c!==I.V){L(30(b)!=30(d)||p.1u(b,c,d,18)==-1){d=b;18=c}j(a,d,18,b,c)}}K 6e(a,b,c){L(b!==a.Q||c!==I.T||b!==a.U||c!==I.V){j(a,b,c,b,c)}}K 5o(e){M K(){19(I);1p(I);J a=I.Q,18=I.T,1G=I.2H;J b=P 1U(I,O);J c,4t;L(a!==1G){c=p.1T(a,1G,O);4t=4k(c);a=4t.1t;18=4t.1K}3B(b,3C);b.6a();J d=e(b);b.1c();j(I,a,18,a,18);M d}}33.1w={6f:K(a,b){I.4j[a].2i(b)},1r:K(a,b){19(I);31(a,O);4q(a,b);5m(I,a,b)},1s:K(a,b){19(I);31(a,O);4q(a,b);5n(I,a,b)},2I:3G(O,O),2J:3G(R,O),2K:3G(O,R),3i:3G(R,R),1E:K(a){19(I);1p(I);L(a){j(I,I.Q,I.T,I.Q,I.T)}N{j(I,I.U,I.V,I.U,I.V)}},1N:K(a){19(I);31(a,O);j(I,a,0,a,2B(a))},2L:K(a){19(I);31(a,R);32(a,u);J b=57(a),1C=4k(a);j(I,b.1t,b.1K,1C.1t,1C.1K)},2d:K(a,b){19(I);1p(I);4r(I.Q,b.Q);J c,5p,5q,5r;J d=(a==5i||a==D)?"28":"1C";J e=(a==5h||a==D)?"28":"1C";c=I[d+"4u"];5p=I[d+"4v"];5q=b[e+"4u"];5r=b[e+"4v"];M p.1u(c,5p,5q,5r)},5M:K(a){19(I);1p(I);32(a,x);3C(I.Q);L(p.1S(a,I.Q,O)){Y P s("2Z");}J b=58(a,I.Q,I.T);I.2I(b)},3Q:K(){19(I);1p(I);J a,1W;L(I.1D){M 1H(I).2R()}N{L(I.Q===I.U&&p.1e(I.Q)){a=I.Q.2m(O);a.25=a.25.4w(I.T,I.V);1W=1H(I).2R();1W.1A(a);M 1W}N{J b=P 1U(I,O);a=59(b);b.1c()}M a}},3k:5o(5b),3j:5o(5a),6g:K(){19(I);1p(I);3C(I.Q);3C(I.U);J a=P 1U(I,O);J b=(a.2z&&(4h(a.2z,I))||(a.2A&&4h(a.2A,I)));a.1c();M!b},3R:K(a){32(a,y);L(!I.6g()){Y P 29("6b");}J b=I.3k();L(a.7J()){1m(a.6h){a.1V(a.6h)}}58(a,I.Q,I.T);a.1A(b);I.2L(a)},2M:K(){19(I);1p(I);J a=P 13(1H(I));J i=C.S,1Q;1m(i--){1Q=C[i];a[1Q]=I[1Q]}M a},1c:K(){k(I)},2t:K(){19(I);1p(I);J b=I.Q;L(b===I.U&&p.1e(b)){M(b.1k==3||b.1k==4)?b.25.4w(I.T,I.V):""}N{J c=[],5s=P 1U(I,O);3B(5s,K(a){L(a.1k==3||a.1k==4){c.2i(a.25)}});5s.1c();M c.4n("")}},6i:K(a){19(I);1p(I);J b=a.15;J c=p.1P(a);L(!b){Y P s("4e");}J d=I.3H(b,c),2q=I.3H(b,c+1);L(d<0){M(2q>0)?5k:E}N{M(2q>0)?5j:4s}},3H:K(a,b){19(I);1p(I);3D(a,"2Z");4r(a,I.Q);L(p.1u(a,b,I.Q,I.T)<0){M-1}N L(p.1u(a,b,I.U,I.V)>0){M 1}M 0},7K:K(a){19(I);J b=1H(I);J c=b.2S("5V");c.6j=a;J d=b.2R(),n;1m((n=c.48)){d.1A(n)}M d},6k:K(a,b){19(I);1p(I);3D(a,"4e");L(p.1h(a)!==1H(I)){M R}J c=a.15,1K=p.1P(a);3D(c,"4e");J d=p.1u(c,1K,I.U,I.V),2q=p.1u(c,1K+1,I.Q,I.T);M b?d<=0&&2q>=0:d<0&&2q>0},7L:K(a,b){19(I);1p(I);3D(a,"2Z");4r(a,I.Q);M(p.1u(a,b,I.Q,I.T)>=0)&&(p.1u(a,b,I.U,I.V)<=0)},6l:K(a){19(I);1p(I);L(1H(a)!=1H(I)){Y P s("4d");}M p.1u(I.Q,I.T,a.U,a.V)<0&&p.1u(I.U,I.V,a.Q,a.T)>0},7M:K(a){L(I.6l(a)){J b=p.1u(I.Q,I.T,a.Q,a.T),2q=p.1u(I.U,I.V,a.U,a.V);J c=I.2M();L(b==-1){c.1r(a.Q,a.T)}L(2q==1){c.1s(a.U,a.V)}M c}M 16},5t:K(a,b){L(b){M I.6k(a,R)}N{M I.6i(a)==4s}},7N:K(a){M I.3H(a,0)>=0&&I.3H(a,2B(a))<=0},7O:K(){19(I);1p(I);J a=I.Q,18=I.T,17=I.U,1f=I.V;J b=(a===17);L(p.1e(17)&&1f<17.S){p.2W(17,1f)}L(p.1e(a)&&18>0){a=p.2W(a,18);L(b){1f-=18;17=a}18=0}j(I,a,18,17,1f)},7P:K(){19(I);1p(I);J c=I.Q,18=I.T,17=I.U,1f=I.V;J d=K(a){J b=a.24;L(b&&b.1k==a.1k){17=a;1f=a.S;a.60(b.25);b.15.1V(b)}};J e=K(a){J b=a.2w;L(b&&b.1k==a.1k){c=a;18=b.S;a.5Z(0,b.25);b.15.1V(b);L(c==17){1f+=18;17=c}}};J f=O;L(p.1e(17)){L(17.S==1f){d(17)}}N{L(1f>0){J g=17.1n[1f-1];L(g&&p.1e(g)){d(g)}}f=!I.1D}L(f){L(p.1e(c)){L(18==0){e(c)}}N{L(18<c.1n.S){J h=c.1n[18];L(h&&p.1e(h)){e(h)}}}}N{c=17;18=1f}j(I,c,18,17,1f)},7Q:K(a,b){19(I);1p(I);M P 5e(I,a,b)},6m:K(a,b){19(I);1p(I);M 5c(I,a,b)},4x:K(a,b){19(I);1p(I);31(a,O);4q(a,b);6e(I,a,b)},7R:K(a){19(I);I.2K(a);I.1E(R)},7S:K(a){19(I);I.2J(a);I.1E(O)},2C:K(){M"2y"},67:K(a){M 13.4y(I,a)},1B:K(){M 1B(I)}};3E(33)}K 5u(a){a.1D=(a.Q===a.U&&a.T===a.V);a.2H=a.1D?a.Q:p.2x(a.Q,a.U)}K 4i(a,b,c,d,e){J f=(a.Q!==b||a.T!==c);J g=(a.U!==d||a.V!==e);a.Q=b;a.T=c;a.U=d;a.V=e;5u(a);56(a,"6n",{7T:f,7U:g})}K 1c(a){19(a);a.Q=a.T=a.U=a.V=16;a.1D=a.2H=16;56(a,"1c",16);a.4j=16}K 13(a){I.Q=a;I.T=0;I.U=a;I.V=0;I.4j={6n:[],1c:[]};5u(I)}3F(13,4i,1c);13.7V=K(r){J a=P 13(1H(r));4i(a,r.Q,r.T,r.U,r.V);M a};13.6o=C;13.1U=1U;13.3E=3E;13.3F=3F;13.1B=1B;13.1H=1H;13.4y=K(a,b){M a.Q===b.Q&&a.T===b.T&&a.U===b.U&&a.V===b.V};13.2B=2B;l.2y=13;l.29=29});3e.3q("34",K(p,q){p.42(["44","2y"]);J r;J s=p.4g;J t=s.2n;J u=p.2y;K 6p(a){J b=a.3m();J c=a.3l();c.1E(O);J d=c.3m();c=a.3l();c.1E(R);J e=c.3m();J f=(d==e)?d:s.2x(d,e);M f==b?f:s.2x(b,f)}K 6q(a){M a.3T("5v",a)==0}K 4z(a,b,c,d){J e=a.3l();e.1E(c);J f=e.3m();L(!s.1S(b,f,O)){f=b}L(!f.7W){M P t(f.15,s.1P(f))}J g=s.1h(f).2S("6r");J h,6s=c?"6t":"5v";J i,3I,35,36;7X{f.2U(g,g.2w);e.4G(g)}1m((h=e.3T(6s,a))>0&&g.2w);36=g.24;L(h==-1&&36&&s.1e(36)){e.3U(c?"7Y":"6u",a);J j;L(/[\\r\\n]/.3t(36.25)){J k=e.3l();J l=k.3S.7Z(/\\r\\n/g,"\\r").S;j=k.5w("5x",l);1m((h=k.3T("5v",k))==-1){j++;k.5w("5x",1)}}N{j=e.3S.S}35=P t(36,j)}N{i=(d||!c)&&g.2w;3I=(d||c)&&g.24;L(3I&&s.1e(3I)){35=P t(3I,0)}N L(i&&s.1e(i)){35=P t(i,i.S)}N{35=P t(f,s.1P(g))}}g.15.1V(g);M 35}K 4A(a,b){J c,37,4B=a.1K;J d=s.1h(a.1t);J e,1n,3J=d.1O.2v();J f=s.1e(a.1t);L(f){c=a.1t;37=c.15}N{1n=a.1t.1n;c=(4B<1n.S)?1n[4B]:16;37=a.1t}e=d.2S("6r");e.6j="&#80;";L(c){37.2U(e,c)}N{37.1A(e)}3J.4G(e);3J.1E(!b);37.1V(e);L(f){3J[b?"5w":"81"]("5x",4B)}M 3J}L(p.1y.2P){(K(){J h;J j=u.6o;J k;K 1I(a){J i=j.S,1Q;1m(i--){1Q=j[i];a[1Q]=a.Z[1Q]}}K 6v(a,b,c,d,e){J f=(a.Q!==b||a.T!=c);J g=(a.U!==d||a.V!=e);L(g){a.1s(d,e)}L(f){a.1r(b,c)}}K 1c(a){a.Z.1c();a.82=O;J i=j.S,1Q;1m(i--){1Q=j[i];a[1Q]=16}}J l;r=K(a){L(!a){Y P 1z("13 83 49 5y");}I.Z=a;1I(I)};u.3F(r,6v,1c);h=r.1w;h.2L=K(a){I.Z.2L(a);1I(I)};h.3j=K(){I.Z.3j();1I(I)};h.3k=K(){J a=I.Z.3k();1I(I);M a};h.3Q=K(){M I.Z.3Q()};h.3R=K(a){I.Z.3R(a);1I(I)};h.1E=K(a){I.Z.1E(a);1I(I)};h.2M=K(){M P r(I.Z.2M())};h.2a=K(){1I(I)};h.2t=K(){M I.Z.2t()};J m=W.2T("3t");s.26(W).1A(m);J n=W.1i();n.1r(m,0);n.1s(m,0);22{n.1r(m,1);k=O;h.1r=K(a,b){I.Z.1r(a,b);1I(I)};h.1s=K(a,b){I.Z.1s(a,b);1I(I)};l=K(b){M K(a){I.Z[b](a);1I(I)}}}23(1R){k=R;h.1r=K(a,b){22{I.Z.1r(a,b)}23(1R){I.Z.1s(a,b);I.Z.1r(a,b)}1I(I)};h.1s=K(a,b){22{I.Z.1s(a,b)}23(1R){I.Z.1r(a,b);I.Z.1s(a,b)}1I(I)};l=K(b,c){M K(a){22{I.Z[b](a)}23(1R){I.Z[c](a);I.Z[b](a)}1I(I)}}}h.2I=l("2I","2K");h.2J=l("2J","3i");h.2K=l("2K","2I");h.3i=l("3i","2J");n.1N(m);L(n.Q==m&&n.U==m&&n.T==0&&n.V==m.S){h.1N=K(a){I.Z.1N(a);1I(I)}}N{h.1N=K(a){I.1r(a,0);I.1s(a,u.2B(a))}}n.1N(m);n.1s(m,3);J o=W.1i();o.1N(m);o.1s(m,4);o.1r(m,2);L(n.2d(n.3g,o)==-1&&n.2d(n.3h,o)==1){h.2d=K(a,b){b=b.Z||b;L(a==b.3g){a=b.3h}N L(a==b.3h){a=b.3g}M I.Z.2d(a,b)}}N{h.2d=K(a,b){M I.Z.2d(a,b.Z||b)}}s.26(W).1V(m);n.1c();o.1c()})()}N L(p.1y.2h){r=K(a){I.38=a;I.2a()};r.1w=P u(W);r.1w.2a=K(){J a,1C;J b=6p(I.38);L(6q(I.38)){1C=a=4z(I.38,b,O,O)}N{a=4z(I.38,b,O,R);1C=4z(I.38,b,R,R)}I.1r(a.1t,a.1K);I.1s(1C.1t,1C.1K)};r.6w=K(a){L(a.1D){M 4A(P t(a.Q,a.T),O,O)}N{J b=4A(P t(a.Q,a.T),O,R);J c=4A(P t(a.U,a.V),R,R);J d=s.1h(a.Q).1O.2v();d.3U("6t",b);d.3U("6u",c);M d}};u.3E(r);J v=(K(){M I})();L(1b v.13=="2c"){v.13=r}}r.1w.2C=K(){M"34"};p.34=r;p.39=K(a){a=a||W;L(p.1y.2P){M a.1i()}N L(p.1y.2h){M a.1O.2v()}};p.1i=K(a){a=a||W;M P r(p.39(a))};p.6x=K(a){a=a||W;M P u(a)};p.84=K(a){M p.1i(s.3v(a))};p.85=K(a){M p.6x(s.3v(a))};p.4L(K(a){J b=a.W;L(1b b.1i=="2c"){b.1i=K(){M p.1i(I)}}b=a=16})});3e.3q("2D",K(h,j){h.42(["44","2y","34"]);h.3Y.6y=O;J k="86",4C="87";J l=h.4g;J m=h.3o;J n=h.2y;J o=h.34;J p=h.2o;J q=l.2n;J r,3a;L(h.3o.1l(1j,"2E")){r=K(a){M(a||1j).2E()}}N L(h.3o.2e(W,"3b")){r=K(a){M((a||1j).W.3b)}}N{j.1F("2l 5z 3K 6z a 3b 3f")}h.88=r;J s=r();J t=h.39(W);J u=l.26(W);J v=m.3W(s,["1q","1X"]&&m.3X(s,["1Y","1Z"]));h.1y.89=v;J w=m.1l(s,"6A");h.1y.8a=w;J x=(1b s.X=="5A");h.1y.8b=x;J y=R;J z=O;L(m.2N(s,["1v","2r","1J"])&&1b s.X=="5A"&&h.1y.2P){(K(){J a=u.1A(W.2T("8c"));J b=u.1A(W.2T("8d"));J c=h.39(W);c.1N(a);J d=h.39(W);d.1N(b);s.1J();s.1v(c);s.1v(d);y=(s.X==2);s.1J();a.15.1V(a);b.15.1V(b);J e=W.2S("p");e.8e=R;J f=e.1A(W.2T("3t"));u.1A(e);J g=h.1i();g.4x(f,1);s.1v(g.Z);z=(s.X==1);s.1J();u.1V(e)})()}h.1y.8f=y;h.1y.8g=z;J A=m.3n(s,"2F");J B=R,5B;L(u&&m.1l(u,"3L")){5B=u.3L();L(m.3X(5B,["2b","3M"])){B=O}}h.1y.8h=B;L(v){3a=K(a){M a.1q===a.1X&&a.1Y===a.1Z}}N{3a=K(a){M a.X?a.2r(a.X-1).1D:R}}K 3c(a,b,c){J d=c?"1C":"28",5C=c?"28":"1C";a.1q=b[d+"4u"];a.1Y=b[d+"4v"];a.1X=b[5C+"4u"];a.1Z=b[5C+"4v"]}K 6B(a){J b=a.1a;a.1q=b.1q;a.1Y=b.1Y;a.1X=b.1X;a.1Z=b.1Z}K 2s(a){a.1q=a.1X=16;a.1Y=a.1Z=0;a.X=0;a.20=O;a.1g.S=0}K 4D(a){J b;L(a 43 n){b=a.5D;L(!b){b=h.39(l.1h(a.Q));b.1s(a.U,a.V);b.1r(a.Q,a.T);a.5D=b;a.6f("1c",K(){I.5D=16})}}N L(a 43 o){b=a.Z}N L(1j.13&&(a 43 13)){b=a}M b}K 6C(a){L(!a.S||a[0].1k!=1){M R}1d(J i=1,14=a.S;i<14;++i){L(!l.1S(a[0],a[i])){M R}}M O}K 3N(a){J b=a.6m();L(!6C(b)){Y P 1z("3N: 27 "+a.1B()+" 8i 2g 8j 3K a 8k 4W");}M b[0]}K 3O(a){a.1g.S=0;L(a.1a.2F=="6D"){2s(a)}N{J b=a.1a.1i();a.X=b.S;J c,6E=l.1h(b.2b(0));1d(J i=0;i<a.X;++i){c=h.1i(6E);c.2L(b.2b(i));a.1g.2i(c)}a.20=a.X==1&&a.1g[0].1D;3c(a,a.1g[a.X-1],R)}}J C;L(m.1l(s,"2r")){C=K(a,b){22{M a.2r(b)}23(1R){M 16}}}N L(v){C=K(a){J b=l.1h(a.1q);J c=h.1i(b);c.1r(a.1q,a.1Y);c.1s(a.1X,a.1Z);L(c.1D!==I.20){c.1r(a.1X,a.1Z);c.1s(a.1q,a.1Y)}M c}}K 2D(a){I.1a=a;I.1g=[];I.2a()}h.2E=K(a){a=a||1j;J b=a[4C];L(b){b.1a=r(a);b.2a()}N{b=P 2D(r(a));a[4C]=b}M b};h.8l=K(a){M h.2E(l.2X(a))};J D=2D.1w;L(v&&m.2N(s,["1J","1v"])){D.1J=K(){I.1a.1J();2s(I)};J E=K(a,b){J c=n.1H(b);J d=h.1i(c);d.4x(b.U,b.V);a.1a.1v(4D(d));a.1a.6A(b.Q,b.T);a.2a()};L(x){D.1v=K(a,b){L(b&&w){E(I,a)}N{J c;L(y){c=I.X}N{I.1J();c=0}I.1a.1v(4D(a));I.X=I.1a.X;L(I.X==c+1){L(h.3Y.6y){J d=C(I.1a,I.X-1);L(d&&!n.4y(d,a)){a=P o(d)}}I.1g[I.X-1]=a;3c(I,a,H(I.1a));I.20=3a(I)}N{I.2a()}}}}N{D.1v=K(a,b){L(b&&w){E(I,a)}N{I.1a.1v(4D(a));I.2a()}}}D.4E=K(a){I.1J();1d(J i=0,14=a.S;i<14;++i){I.1v(a[i])}}}N L(m.1l(s,"5E")&&m.1l(t,"2u")&&A&&B){D.1J=K(){22{I.1a.5E();L(I.1a.2F!="6D"){J a;L(I.1q){a=l.1h(I.1q)}N L(I.1a.2F=="4F"){J b=I.1a.1i();L(b.S){a=l.1h(b.2b(0)).1O.2v()}}L(a){J c=a.1O.2v();c.2u();I.1a.5E()}}}23(1R){}2s(I)};D.1v=K(a){L(I.1a.2F=="4F"){J b=I.1a.1i();J c=3N(a);J d=l.1h(b.2b(0));J e=l.26(d).3L();1d(J i=0,14=b.S;i<14;++i){e.3M(b.2b(i))}22{e.3M(c)}23(1R){Y P 1z("1v(): 4T 6F 3y 5y 13 6G 2g 49 6H 41 6I 3b (4P 6J 4Q 6K?)");}e.2u();3O(I)}N{o.6w(a).2u();I.1g[0]=a;I.X=1;I.20=I.1g[0].1D;3c(I,a,R)}};D.4E=K(a){I.1J();J b=a.S;L(b>1){J c=l.1h(a[0].Q);J d=l.26(c).3L();1d(J i=0,5F;i<b;++i){5F=3N(a[i]);22{d.3M(5F)}23(1R){Y P 1z("4E(): 4T 6F 3y 8m 3K 3y 5y 6L 6G 2g 49 6H 41 6I 3b (4P 6J 4Q 6K?)");}}d.2u();3O(I)}N L(b){I.1v(a[0])}}}N{j.1F("2l 5z 3K 8n a 13 4R 4K 6M 2k");M R}D.2r=K(a){L(a<0||a>=I.X){Y P p("50");}N{M I.1g[a]}};J F;L(m.1l(s,"2r")&&1b s.X=="5A"){F=K(a){a.1g.S=a.X=a.1a.X;L(a.X){1d(J i=0,14=a.X;i<14;++i){a.1g[i]=P h.34(a.1a.2r(i))}3c(a,a.1g[a.X-1],H(a.1a));a.20=3a(a)}N{2s(a)}}}N L(v&&1b s.20==k&&1b t.1D==k&&h.1y.2P){F=K(a){J b,5G=a.1a;L(5G.1q){b=C(5G,0);a.1g=[b];a.X=1;6B(a);a.20=3a(a)}N{2s(a)}}}N L(m.1l(s,"1i")&&h.1y.2h){F=K(a){J b=a.1a.1i(),3P;L(a.1a.2F=="4F"){3O(a)}N L(b&&1b b.3S!="2c"){3P=P o(b);a.1g=[3P];3c(a,3P,R);a.X=1;a.20=3P.1D}N{2s(a)}}}N{j.1F("2l 5z 3K 6z a 13 4R 4K 8o 3y 8p\'s 3b 6M 2k");M R}D.2a=K(a){J b=a?I.1g.4w(0):16;F(I);L(a){J i=b.S;L(i!=I.1g.S){M R}1m(i--){L(!n.4y(b[i],I.1g[i])){M R}}M O}};J G=K(a,b){J c=a.5H(),3d=R;a.1J();1d(J i=0,14=c.S;i<14;++i){L(3d||b!==c[i]){a.1v(c[i])}N{3d=O}}L(!a.X){2s(a)}};L(A&&B){D.6N=K(a){L(I.1a.2F=="4F"){J b=I.1a.1i();J c=3N(a);J d=l.1h(b.2b(0));J e=l.26(d).3L();J f,3d=R;1d(J i=0,14=b.S;i<14;++i){f=b.2b(i);L(f!==c||3d){e.3M(b.2b(i))}N{3d=O}}e.2u();3O(I)}N{G(I,a)}}}N{D.6N=K(a){G(I,a)}}J H;L(v&&h.1y.2P){H=K(a){J b=R;L(a.1q){b=(l.1u(a.1q,a.1Y,a.1X,a.1Z)==1)}M b};D.6O=K(){M H(I)}}N{H=D.6O=K(){M R}}D.2t=K(){J a=[];1d(J i=0,14=I.X;i<14;++i){a[i]=""+I.1g[i]}M a.4n("")};K 5I(a,b){L(a.1q&&(l.1h(a.1q)!==l.1h(b))){Y P p("4d");}}D.1E=K(a,b){5I(I,a);J c=h.1i(l.1h(a));c.4x(a,b);I.1J();I.1v(c);I.20=O};D.8q=K(){L(I.X){J a=I.1g[0];I.1E(a.Q,a.T)}N{Y P p("4f");}};D.8r=K(){L(I.X){J a=I.1g[I.X-1];I.1E(a.U,a.V)}N{Y P p("4f");}};D.8s=K(a){5I(I,a);J b=h.1i(l.1h(a));b.1N(a);I.1J();I.1v(b)};D.8t=K(){L(I.X){J a=I.5H();I.1J();1d(J i=0,14=a.S;i<14;++i){a[i].3j()}I.1v(a[14-1])}};D.5H=K(){M I.1g.4w(0)};D.8u=K(a){I.4E([a])};D.5t=K(a,b){1d(J i=0,14=I.1g.S;i<14;++i){L(I.1g[i].5t(a,b)){M O}}M R};K 1B(a){J b=[];J c=P q(a.1q,a.1Y);J d=P q(a.1X,a.1Z);J e=(1b a.2C=="K")?a.2C():"6P";L(1b a.X!="2c"){1d(J i=0,14=a.X;i<14;++i){b[i]=n.1B(a.2r(i))}}M"["+e+"(6L: "+b.4n(", ")+")(8v: "+c.1B()+", 8w: "+d.1B()+"]"}D.2C=K(){M"2D"};D.1B=K(){M 1B(I)};D.1c=K(){L(I.1q){l.45(I.1q)[4C]=16}};2D.1B=1B;h.6P=2D;h.4L(K(a){L(1b a.2E=="2c"){a.2E=K(){M h.2E(I)}}a=16})});',62,529,'||||||||||||||||||||||||||||||||||||||||||||this|var|function|if|return|else|true|new|startContainer|false|length|startOffset|endContainer|endOffset|document|rangeCount|throw|nativeRange||||Range|len|parentNode|null|ec|so|assertNotDetached|nativeSelection|typeof|detach|for|isCharacterDataNode|eo|_ranges|getDocument|createRange|window|nodeType|isHostMethod|while|childNodes|_next|assertRangeValid|anchorNode|setStart|setEnd|node|comparePoints|addRange|prototype|_current|features|Error|appendChild|inspect|end|collapsed|collapse|fail|root|getRangeDocument|updateRangeProperties|removeAllRanges|offset|sc|next|selectNodeContents|body|getNodeIndex|prop|ex|isAncestorOf|getClosestAncestorIn|RangeIterator|removeChild|frag|focusNode|anchorOffset|focusOffset|isCollapsed|initialized|try|catch|nextSibling|data|getBody|range|start|RangeException|refresh|item|undefined|compareBoundaryPoints|isHostObject|supported|not|implementsTextRange|push|Module|found|No|cloneNode|DomPosition|DOMException|subIterator|endComparison|getRangeAt|updateEmptySelection|toString|select|createTextRange|previousSibling|getCommonAncestor|DomRange|_first|_last|getEndOffset|getName|WrappedSelection|getSelection|type|UNDEFINED|commonAncestorContainer|setStartBefore|setStartAfter|setEndBefore|selectNode|cloneRange|areHostMethods|console|implementsDomRange|module|createDocumentFragment|createElement|createTextNode|insertBefore|deleteData|splitDataNode|getIframeWindow|inspectNode|HIERARCHY_REQUEST_ERR|getRootContainer|assertNoDocTypeNotationEntityAncestor|assertValidNodeType|constructor|WrappedRange|boundaryPosition|boundaryNode|boundaryParent|textRange|createNativeRange|selectionIsCollapsed|selection|updateAnchorAndFocusFromRange|removed|rangy|object|START_TO_END|END_TO_START|setEndAfter|deleteContents|extractContents|duplicate|parentElement|isHostProperty|util|init|createModule|moduleName|addEventListener|test|insertAfter|getIframeDocument|childA|childB|the|isPartiallySelectedSubtree|getSubtreeIterator|iterateSubtree|assertNodeNotReadOnly|assertNode|copyComparisonConstants|createPrototypeRange|createBeforeAfterNodeSetter|comparePoint|nextNode|workingRange|of|createControlRange|add|getSingleElementFromRange|updateFromControlRange|wrappedRange|cloneContents|surroundContents|text|compareEndPoints|setEndPoint|createMultiplePropertyTest|areHostObjects|areHostProperties|config|log|getElementsByTagName|to|requireModules|instanceof|DomUtil|getWindow|contentDocument|contentWindow|firstChild|be|createIterator|codeName|message|WRONG_DOCUMENT_ERR|NOT_FOUND_ERR|INVALID_STATE_ERR|dom|isNonTextPartiallySelected|updateBoundaries|_listeners|getBoundaryAfterNode|stop|subRangeIterator|join|nodes|createAncestorFinder|assertValidOffset|assertSameDocumentOrFragment|n_i|boundary|Container|Offset|slice|collapseToPoint|rangesEqual|getTextRangeBoundaryPosition|createBoundaryTextRange|boundaryOffset|windowPropertyName|getNativeRange|setRanges|Control|moveToElementText|modules|Rangy|warn|TextRange|addCreateMissingNativeApiListener|createMissingNativeApi|name|attachEvent|does|have|or|method|Element|parent|defaultView|element|id|NodeIterator|hasNext|INDEX_SIZE_ERR|arrayContains|clonePartiallySelectedTextNodes|isSingleCharacterDataNode|remove|INVALID_NODE_TYPE_ERR|dispatchEvent|getBoundaryBeforeNode|insertNodeAtPosition|cloneSubtree|deleteSubtree|extractSubtree|getNodesInRange|regex|RangeNodeIterator|isOrphan|isValidOffset|s2e|e2s|n_a|n_b_a|copyComparisonConstantsToObject|setRangeStart|setRangeEnd|createRangeContentRemover|offsetA|nodeB|offsetB|iterator|containsNode|updateCollapsedAndCommonAncestor|StartToEnd|moveStart|character|specified|means|number|testControlRange|focusPrefix|_selectionNativeRange|empty|el|nativeSel|getAllRanges|assertNodeInSameDocument|FUNCTION|START_TO_START|END_TO_END|insertNode|alertOnWarn|alert|in|are|load|Window|missing|Node|div|Incomplete|implementation|splitText|insertData|appendData|ownerDocument|no|parentWindow|iframe|and|nodeName|equals|code|NO_MODIFICATION_ALLOWED_ERR|reset|BAD_BOUNDARYPOINTS_ERR|_pointer|e2e|setRangeStartAndEnd|attachListener|canSurroundContents|lastChild|compareNode|innerHTML|intersectsNode|intersectsRange|getNodes|boundarychange|rangeProperties|getTextRangeContainerElement|textRangeIsCollapsed|span|workingComparisonType|StartToStart|EndToEnd|updateNativeRange|rangeToTextRange|createRangyRange|checkSelectionRanges|obtaining|extend|updateAnchorAndFocusFromNativeSelection|rangeContainsSingleElement|None|doc|within|could|added|control|it|layout|Ranges|was|removeRange|isBackwards|Selection|boundingHeight|boundingLeft|boundingTop|boundingWidth|htmlText|getBookmark|moveToBookmark|pasteHTML|unknown|your|browser|Reason|warning|Neither|nor|implemented|concat|Init|listener|threw|an|exception|Continuing|addInitListener|failed|createError|DOMContentLoaded|onload|required|creation|Text|Cannot|get|Document|got|case|same|Should|here|NOT_SUPPORTED_ERR|call|target|args|RegExp|error|is|longer|valid|after|DOM|mutation|NODE_BEFORE|NODE_AFTER|NODE_BEFORE_AND_AFTER|NODE_INSIDE|hasChildNodes|createContextualFragment|isPointInRange|intersection|containsNodeContents|splitBoundaries|normalizeBoundaries|createNodeIterator|collapseBefore|collapseAfter|startMoved|endMoved|fromRange|canHaveHTML|do|EndToStart|replace|feff|moveEnd|detached|must|createIframeRange|createIframeRangyRange|boolean|_rangySelection|getNativeSelection|selectionHasAnchorAndFocus|selectionHasExtend|selectionHasRangeCount|One|Two|contentEditable|selectionSupportsMultipleRanges|collapsedNonEditableSelectionsSupported|implementsControlRange|did|consist|single|getIframeSelection|one|selecting|from|user|collapseToStart|collapseToEnd|selectAllChildren|deleteFromDocument|setSingleRange|anchor|focus'.split('|'),0,{}))
rangy.init();
//}}}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/* isString() code from http://www.planetpdf.com/developer/article.asp?ContentID=6383 */
function isString() {
	if (typeof arguments[0] == 'string') return true;
	if (typeof arguments[0] == 'object') {
		var criterion = arguments[0].constructor.toString().match(/string/i); 
 		return (criterion != null); 
	}
	return false;
}
This plugin extends Popup with a new function ShowAbove(), which is basically an edit of the original Show() function with some help from the HoverMenu plugin. It makes the Popup appear above the popup link.

@@''Current limitation'': if the popup is so large that it extends beyond the top of the document, that section will be cut off. Therefore, for the time being, just use this for popups that are //small// enough to fit on the page!@@

To use, import the following tiddlers, and follow the instructions:
[[ShowPopupAbove]]
[[ShowPopupAbovePlugin]]

/%
!info
|Name|ShowPopup|
|Source|http://www.TiddlyTools.com/#ShowPopup|
|Version|1.2.0|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|transclusion|
|Description|display tiddler content in a TiddlyWiki popup panel|
Usage:
<<<
{{{
<<tiddler ShowPopup with: TiddlerName label tooltip buttonClass width popupClass>>
}}}
where:
*''~TiddlerName''<br>title of the tiddler to be displayed
*''label''<br>text for the command link
*''tooltip''<br>mouseover help text for the link
*''buttonClass''<br>CSS classname applied to the command text (default=button)
*''width''<br>width of the popup (using CSS measurements, default=auto)
*''popupClass''<br>CSS classname applied to the popup panel (default=none).<br>Use 'sticky' for persistent popups (see StickyPopupPlugin)
<<<
Example:
<<<
{{{
<<tiddler ShowPopup with: ShowPopup [[Try this]] [[show this tiddler in a popup]]>>
}}}
<<tiddler ShowPopup with: ShowPopup [[Try this]] [[show this tiddler in a popup]]>>
<<<
!end

!show
<html><hide linebreaks>
<a href="javascript:;" class="$4" title="$3" onclick="
	var p=Popup.create(this); if(!p)return;
	p.className+='$6'!='$'+'6'?' $6':'';
	var d=createTiddlyElement(p,'div');
	var s=d.style;
	s.whiteSpace='normal';
	s.width='$5'!='$'+'5'?'$5':'auto';
	s.padding='2px';
	wikify(store.getTiddlerText('$1',''),d);
	Popup.show();
	event.cancelBubble=true;
	if(event.stopPropagation)event.stopPropagation();
	return(false);
">$2</a></html>
!end

%/<<tiddler {{'ShowPopup##'+('$1'=='$'+'1'?'info':'show')}} with: [[$1]] [[$2]] [[$3]] [[$4]] [[$5]] [[$6]]>>
/%
!info
|Name|ShowPopupAbove|
|Author|Alex S (original ShowPopup code by Eric Schulman)|
|Type|transclusion|
|Description|display tiddler content in a TiddlyWiki popup panel above the popup link|
Usage:
<<<
{{{
<<tiddler ShowPopupAbove with: TiddlerName label tooltip buttonClass width popupClass>>
}}}
where:
*''~TiddlerName''<br>title of the tiddler to be displayed
*''label''<br>text for the command link
*''tooltip''<br>mouseover help text for the link
*''buttonClass''<br>CSS classname applied to the command text (default=button)
*''width''<br>width of the popup (using CSS measurements, default=auto)
*''popupClass''<br>CSS classname applied to the popup panel (default=none).<br>Use 'sticky' for persistent popups (see StickyPopupPlugin)
<<<
Example:
<<<
{{{
<<tiddler ShowPopupAbove with: ShowPopupAbove [[Click here]] [[show this tiddler in a popup]] button>>
}}}
<<tiddler ShowPopupAbove with: ShowPopupAbove [[Click here]] [[show this tiddler in a popup]] button>>
<<<
!end

!show

<html><hide linebreaks>
<a href="javascript:;" class="$4" title="$3" onclick="
	var p=Popup.create(this); if(!p)return;
	p.className+='$6'!='$'+'6'?' $6':'';
	var d=createTiddlyElement(p,'div');
	var s=d.style;
	s.whiteSpace='normal';
	s.width='$5'!='$'+'5'?'$5':'auto';
	s.padding='2px';
	wikify(store.getTiddlerText('$1',''),d);
	Popup.showAbove();
	event.cancelBubble=true;
	if(event.stopPropagation)event.stopPropagation();
	return(false);
">$2</a></html>
!end

%/<<tiddler {{'ShowPopupAbove##'+('$1'=='$'+'1'?'info':'show')}} with: [[$1]] [[$2]] [[$3]] [[$4]] [[$5]] [[$6]]>>

//{{{
Popup.showAbove=function (unused, slowly) {
	var curr = Popup.stack[Popup.stack.length-1];
	var rootLeft = findPosX(curr.root);
	var rootTop = findPosY(curr.root);
	var rootHeight = curr.root.offsetHeight;
	var popupLeft = rootLeft;
	var popupTop = rootTop - jQuery(curr.popup).outerHeight();
	var popupWidth = curr.popup.offsetWidth;
	var winWidth = findWindowWidth();
        var x = 0;
	if(popupLeft + popupWidth+x > winWidth)
		popupLeft = winWidth - popupWidth -x;
                curr.popup.style.left = popupLeft + "px";
	curr.popup.style.top = popupTop + "px";
	curr.popup.style.display = "block";
	addClass(curr.root,"highlight");
	if(config.options.chkAnimate)
		anim.startAnimating(new Scroller(curr.popup,slowly));
	else
		window.scrollTo(0,ensureVisible(curr.popup));
}
//}}}

/***
|Name|[[ShowPopupPlugin]]|
|Source|http://www.TiddlyTools.com/#ShowPopupPlugin|
|Version|2.0.0|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|display tiddler content in a TiddlyWiki popup panel|
!!!!!Documenatation
>see [[ShowPopupPluginInfo]]
!!!!!Revisions
<<<
2001.03.03 2.0.0 converted to plugin and added optional 'above' keyword param
| Please see [[ShowPopupPluginInfo]] for previous revision details |
2006.09.09 1.0.0 initial release (transclusion)
<<<
!!!!!Code
***/
//{{{
version.extensions.ShowPopupPlugin=
	{ major:2, minor:0, revision:1, date:new Date(2011,3,5) };
config.macros.showPopup = {
	tip: 'display "%0" in a popup',
	init: function() {
		config.shadowTiddlers.ShowPopup =
			'<<showPopup tiddler:[[$1]] label:"$2" tip:"$3" buttonClass:"button $4" width:"$5" popupClass:"$6" "$7">>';
		config.annotations.ShowPopup =
			'created by ShowPopupPlugin';
	},
	handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		var p=paramString.parseParams('name',null,true,false,true);
		var tid=getParam(p,'tiddler','TiddlerName');
		var label=getParam(p,'label',tid);
		var tip=getParam(p,'tip',this.tip.format([tid]));
		var buttonClass=getParam(p,'buttonClass','');
		var width=getParam(p,'width','auto');
		var popupClass=getParam(p,'popupClass','');
		var above=params.contains('above');
		var b=createTiddlyButton(place, label, tip, this.click, buttonClass, null, null,
			{ tid:tid, popupClass:popupClass, width:width, above:above });
		b.innerHTML=label; // for HTML entities, images, etc
	},
	click: function(ev) { var ev=ev||window.event;
		var p=Popup.create(this); if(!p)return false;
		addClass(p,this.getAttribute('popupClass'));
		var d=createTiddlyElement(p,'div');
		var s=d.style; s.whiteSpace='normal'; s.width=this.getAttribute('width'); s.padding='2px';
		wikify(store.getTiddlerText(this.getAttribute('tid'),''),d);
		if (this.getAttribute('above')!='true') Popup.show();
		else Popup.show('top','left',{x:0,y:-jQuery(d).outerHeight()});
		ev.cancelBubble=true; if(ev.stopPropagation)ev.stopPropagation(); return false;
	}
}
//}}}

AXS TiddlyWiki
/*{{{*/

.tabWithLinks{
	color: red;
}


#backstageToolbar{
	color: red;
}

/* give tiddlers 3d style border and explicit background */
.tiddler {
	background: [[ColorPalette::Background]];
	border-right: 1px black solid;
	border-bottom: 1px black solid;
	margin-bottom: 1em;
	padding-bottom: 1em;
}



#backstageButton .button{font-size: 8pt;}
#backstageArea{z-index:150;}
#backstage{z-index:149;}

.alignright {
 	text-align: right;
}

.popup{
	background-color:#FFFFFF;
	color:#000000;
}


.snapshot{
	background-color:white;
}
.snapshot .toolbar,.snapshot .tagged,.snapshot .tagging,.snapshot .sectionTOC { 
	display:none;
}

/* a contrasting background so I can see where one tiddler ends and the other begins */
body{
	background-color: lightGray;
}


.toolbar .command_closeTiddler,
.selected .toolbar .command_closeTiddler,
.toolbar .command_collapseTiddler,
.selected .toolbar .command_collapseTiddler,
.toolbar .command_expandTiddler,
.selected .toolbar .command_expandTiddler{
	color: darkblue;
	font-weight:bold;
}
.selected .toolbar .command_closeTiddler:hover,
.selected .toolbar .command_collapseTiddler:hover,
.selected .toolbar .command_expandTiddler:hover{
	color: darkblue;
	font-weight:bold;
}

.button{
	font-size:12pt;
	-moz-border-radius: 5px;
	border-radius: 5px;
}
/*}}}*/
/***
!Information
|Name|StyleTabWithLinksPlugin|
|Author|axs|
|Version|0.1|
|Source|http://axs.tiddlyspot.com/#StyleTabWithLinksPlugin|
|Core Version|2.6|
|Description|Allows styling of tabs in a tabset that contain tiddlyLinks inside.|

!Description
Add the CSS class {{{.tabWithLinks}}} to tabs in a tabset whose contents contain tiddlyLinks.
To set the style add something like this to your StyleSheet :
{{{
.tabWithLinks{
	color: red;
}
}}}

!Revisions
2011.06.06 v.0.1 first release

!Code
***/
//{{{
config.macros.tabs.onClickTab_old = config.macros.tabs.onClickTab;
config.macros.tabs.onClickTab = function (e) {
	config.macros.tabs.onClickTab_old.call(this,e);
        if(!this.parentNode.tabsWithLinks){this.parentNode.tabsWithLinks=[];}
	if(jQuery(this.parentNode.nextSibling).find('.tiddlyLink').length){
		this.parentNode.tabsWithLinks.push(this);
	}
	jQuery(this.parentNode.tabsWithLinks).addClass('tabWithLinks');
};
config.macros.tabs.handler_old = config.macros.tabs.handler;
config.macros.tabs.handler = function (place, macroName, params){
	config.macros.tabs.handler_old.call(this,place,macroName,params);
	var cookie = params[0]
	jQuery(place).find('div[cookie='+cookie+'] .tab').click();
	jQuery(place).find('div[cookie='+cookie+'] .tab').eq(0).click();
}

//}}}
/***

!Information
|Name|TagglyTagButtonPlugin|
|Author|axs|
|Version|0.2 (alpha) |
|Core Version|2.6|
|Description|Modifies tag button behavior to make list of new tag buttons, essentially allowing deep-browsing of TagglyTagged tiddlers.|
!!!!Description
>The core {{{<<tag [[tag]]>>}}} macro makes a tag button that when clicked calls the core {{{onClickTag()}}} function which displays a popup list of tiddlers tagged with that tag. This plugin modifies the {{{onClickTag()}}} behavior such that each tiddler item in the popup list is itself a tag button which popups a list of tiddlers tagged with that tiddler's name. This continues until there are no tiddlers tagged with the previous tiddler's name, in which case the tiddler is opened.

Tiddlers tagged with "excludeLists" will not be displayed in the popup menu
!!!!Usage
>Just use the core {{{<<tag [[tag]]>>}}} macro as usual to make the tag button. This code takes care of the rest.
!!!!Revisions
>2011.05.23 v.0.2 (alpha) - added support for "excludeLists"
>2011.03.03 v.0.1 (alpha) - initial commit
!Code
***/

//{{{

function onClickTag(ev) {
	var e = ev || window.event;
	var popup = Popup.create(this);
	addClass(popup,"taggedTiddlerList");
	var tag = this.getAttribute("tag");
	var title = this.getAttribute("tiddler");
	if(popup && tag) {
		var tagged = tag.indexOf("[")==-1 ? store.getTaggedTiddlers(tag) : store.filterTiddlers(tag);
		var sortby = this.getAttribute("sortby");
		if(sortby&&sortby.length) {
			store.sortTiddlers(tagged,sortby);
		}
		var titles = [];
		var li,r;
		for(r=0;r<tagged.length;r++) {
			if(tagged[r].title != title && !~store.getValue(tagged[r].title,'tags').indexOf('excludeLists')){
				titles.push(tagged[r].title);
			}
		}
		if(titles.length==0){story.displayTiddler(this,tag); return false;};
		
		var lingo = config.views.wikified.tag;
		
		var h = createTiddlyLink(createTiddlyElement(popup,"li"),tag,false);
		createTiddlyText(h,lingo.openTag.format([tag]));
		if(titles.length > 0) {
			createTiddlyElement(createTiddlyElement(popup,"li",null,"listBreak"),"div");
			for(r=0; r<titles.length; r++) {
				//create a Tag button with the "tag" being the title of the found tiddlers
				createTagButton(createTiddlyElement(popup,"li"), titles[r], null, titles[r], config.views.wikified.tag.tooltip.format([titles[r]]))
				
			}
			createTiddlyElement(createTiddlyElement(popup,"li",null,"listBreak"),"div");
			var openAll = createTiddlyButton(createTiddlyElement(popup,"li"),lingo.openAllText.format([tag]),lingo.openAllTooltip,onClickTagOpenAll);
			openAll.setAttribute("tag",tag);
			openAll.setAttribute("sortby",sortby);
		} else {
			//createTiddlyElement(popup,"li",null,"disabled",lingo.popupNone.format([tag]));
		}
		
		Popup.show();
		e.cancelBubble = true;
		if(e.stopPropagation) { e.stopPropagation(); }
		return false;	
	}		
}

//}}}
/***

!Information
|Name|TagglyTagsMenuPlugin|
|Author|axs|
|Version|0.1 (alpha)|
|Source|http://axs.tiddlyspot.com/#TagglyTagsMenuPlugin|
|Core Version|2.6|
|Description|Automatic menu generation for deep-browsing of TagglyTagged (hierarchically-tagged) tiddlers.|

!Description
The core {{{<<tag [[tag]]>>}}} macro makes a button that displays a popup list of tiddlers tagged with that tag. TagglyTagsMenu plugin goes one step further. It functions similarly to the core {{{<<tag]>>}}} macro, but instead of displaying a list of tiddler links, it displays a list of new tag buttons that themselves open sub-menus of tiddlers that are tagged with the titles. This allows quick and easy browsing of multi-dimensional wikis (i.e. 'taggly-tagged tiddlers') to any level by just using the top-level tag as the parameter to the {{{<<TagglyTagsMenu [[tag]]>>}}} macro. 

If a tiddler is not a tag of any other tiddlers, clicking on its title will just open the tiddler ( just like the regular {{{<<tag>>}}} macro). So, TagglyTagsMenu looks exactly like the core {{{<<tag>>}}} macro for one-dimensional tag-tiddler relationships.

TagglyTagsMenu respects the <<tag excludeLists>> tag, excluding tiddlers tagged with {{{excludeLists}}} from being shown in the list.

!What is TagglyTagging?
Taggly Tagging is a way of using TiddlyWiki to organize information by levels or hierarchies. For example, a group of tiddlers can be tagged with a common tag; this is one-dimensional and the simplest way of using TW. However, those tiddlers can themselves be tags of other tiddlers; this adds another dimension to the wiki. Continuing this process allows organization of information in a very powerful way. This plugin allows easy browsing of tiddlers organized in this multi-dimensional manner. 

!Usage
Similar to the core {{{<<tag>>}}} macro: 
{{{<<TagglyTagsMenu tag [title] [tooltip] [sortby]>>}}}  where:
* ''tag'' is the required tag name.
* ''title'' specifies the text to be displayed in the button. If it is not included, the tag name is used.
* ''tooltip'' specifies the text to be displayed in the popup tooltip. 
* ''sortby'' is a parameter that specifies how to sort the popup list. It can use any tiddler fields (custom and core), such as 'title', 'modified', 'created', 'changecount', etc.. Include a {{{+}}} before the sort field to sort in ascending order, or a {{{-}}} to sort in descending order. For example, to sort in descending order by the modified date (newer items first), use {{{-modified}}} .

Bracketed items are optional. If you include them, do so without the brackets. However, as usual in TW macros, if your text contains spaces, use double brackets around it.

!Examples
* {{{<<TagglyTagsMenu systemConfig>>}}} &rarr; <<TagglyTagsMenu systemConfig>>
* {{{<<TagglyTagsMenu systemConfig [[display systemConfig tiddlers]] [[open systemConfig]] -modified>>}}} &rarr; <<TagglyTagsMenu systemConfig [[display systemConfig tiddlers]] [[open systemConfig]] -modified>>
* see http://goljanpathology.tiddlyspot.com/#Contents for a real-world application. 

!Revisions
2011.05.23 v.0.1 (alpha)

!Code
***/
//{{{
config.macros.TagglyTagsMenu={
	handler: function (place,macroName,params,wikifier,paramString,tiddler){
		var tag=params[0],
			title = params[1] || params[0],
			tooltip = params[2] || ('open '+tag),
			sortby = params[3];
		this.createTagButton(place,tag,title,tooltip,sortby);
	},
	createTagButton: function(place,tag,title,tooltip,sortby){
		var btn=createTiddlyButton(place,title,tooltip, this.onclickBtn);
		btn.setAttribute('tag',tag);
		btn.setAttribute('sortby',sortby || null)
	},
	onclickBtn: function(ev){
		var e = ev || window.event;
		var popup = Popup.create(this);
		addClass(popup,"taggedTiddlerList");
		var tag = this.getAttribute("tag");
		var title = this.getAttribute("tiddler");
		if(popup && tag) {
			var tagged = tag.indexOf("[")==-1 ? store.getTaggedTiddlers(tag) : store.filterTiddlers(tag);
			var sortby = this.getAttribute("sortby");
			if(sortby&&sortby.length) { store.sortTiddlers(tagged,sortby); }
			var titles = [];
			var li,r;
			for(r=0;r<tagged.length;r++) {
				if(tagged[r].title != title && !~store.getValue(tagged[r].title,'tags').indexOf('excludeLists')){
					titles.push(tagged[r].title);
				}
			}
			if(titles.length==0){
				story.displayTiddler(this,tag); 
				return false;
			}
			
			var lingo = config.views.wikified.tag,
				h = createTiddlyLink(createTiddlyElement(popup,"li"),tag,false);
			createTiddlyText(h,'open '+tag);
			createTiddlyElement(createTiddlyElement(popup,"li",null,"listBreak"),"div");
			for(r=0; r<titles.length; r++) {
				config.macros.TagglyTagsMenu.createTagButton(createTiddlyElement(popup,"li"), titles[r],titles[r], 'open '+[titles[r]],sortby)
			}
			createTiddlyElement(createTiddlyElement(popup,"li",null,"listBreak"),"div");
			var openAll = createTiddlyButton(createTiddlyElement(popup,"li"),lingo.openAllText.format([tag]),lingo.openAllTooltip,onClickTagOpenAll);
			openAll.setAttribute("tag",tag);
			openAll.setAttribute("sortby",sortby);
			
			Popup.show();
			e.cancelBubble = true;
			if(e.stopPropagation) { e.stopPropagation(); }
			return false;	
		}
	}
}

//}}}
|~ViewToolbar|closeTiddler closeOthers editTiddler > fields syncing permalink references jump|
|~EditToolbar|+saveTiddler -cancelTiddler deleteTiddler|
/***
Description: Contains the stuff you need to use Tiddlyspot
Note, you also need UploadPlugin, PasswordOptionPlugin and LoadRemoteFileThroughProxy
from http://tiddlywiki.bidix.info for a complete working Tiddlyspot site.
***/
//{{{

// edit this if you are migrating sites or retrofitting an existing TW
config.tiddlyspotSiteId = 'axs';

// make it so you can by default see edit controls via http
config.options.chkHttpReadOnly = false;
window.readOnly = false; // make sure of it (for tw 2.2)
window.showBackstage = true; // show backstage too

// disable autosave in d3
if (window.location.protocol != "file:")
	config.options.chkGTDLazyAutoSave = false;

// tweak shadow tiddlers to add upload button, password entry box etc
with (config.shadowTiddlers) {
	SiteUrl = 'http://'+config.tiddlyspotSiteId+'.tiddlyspot.com';
	SideBarOptions = SideBarOptions.replace(/(<<saveChanges>>)/,"$1<<tiddler TspotSidebar>>");
	OptionsPanel = OptionsPanel.replace(/^/,"<<tiddler TspotOptions>>");
	DefaultTiddlers = DefaultTiddlers.replace(/^/,"[[WelcomeToTiddlyspot]] ");
	MainMenu = MainMenu.replace(/^/,"[[WelcomeToTiddlyspot]] ");
}

// create some shadow tiddler content
merge(config.shadowTiddlers,{

'TspotOptions':[
 "tiddlyspot password:",
 "<<option pasUploadPassword>>",
 ""
].join("\n"),

'TspotControls':[
 "| tiddlyspot password:|<<option pasUploadPassword>>|",
 "| site management:|<<upload http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/store.cgi index.html . .  " + config.tiddlyspotSiteId + ">>//(requires tiddlyspot password)//<br>[[control panel|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/controlpanel]], [[download (go offline)|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/download]]|",
 "| links:|[[tiddlyspot.com|http://tiddlyspot.com/]], [[FAQs|http://faq.tiddlyspot.com/]], [[blog|http://tiddlyspot.blogspot.com/]], email [[support|mailto:support@tiddlyspot.com]] & [[feedback|mailto:feedback@tiddlyspot.com]], [[donate|http://tiddlyspot.com/?page=donate]]|"
].join("\n"),

'WelcomeToTiddlyspot':[
 "This document is a ~TiddlyWiki from tiddlyspot.com.  A ~TiddlyWiki is an electronic notebook that is great for managing todo lists, personal information, and all sorts of things.",
 "",
 "@@font-weight:bold;font-size:1.3em;color:#444; //What now?// &nbsp;&nbsp;@@ Before you can save any changes, you need to enter your password in the form below.  Then configure privacy and other site settings at your [[control panel|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/controlpanel]] (your control panel username is //" + config.tiddlyspotSiteId + "//).",
 "<<tiddler TspotControls>>",
 "See also GettingStarted.",
 "",
 "@@font-weight:bold;font-size:1.3em;color:#444; //Working online// &nbsp;&nbsp;@@ You can edit this ~TiddlyWiki right now, and save your changes using the \"save to web\" button in the column on the right.",
 "",
 "@@font-weight:bold;font-size:1.3em;color:#444; //Working offline// &nbsp;&nbsp;@@ A fully functioning copy of this ~TiddlyWiki can be saved onto your hard drive or USB stick.  You can make changes and save them locally without being connected to the Internet.  When you're ready to sync up again, just click \"upload\" and your ~TiddlyWiki will be saved back to tiddlyspot.com.",
 "",
 "@@font-weight:bold;font-size:1.3em;color:#444; //Help!// &nbsp;&nbsp;@@ Find out more about ~TiddlyWiki at [[TiddlyWiki.com|http://tiddlywiki.com]].  Also visit [[TiddlyWiki.org|http://tiddlywiki.org]] for documentation on learning and using ~TiddlyWiki. New users are especially welcome on the [[TiddlyWiki mailing list|http://groups.google.com/group/TiddlyWiki]], which is an excellent place to ask questions and get help.  If you have a tiddlyspot related problem email [[tiddlyspot support|mailto:support@tiddlyspot.com]].",
 "",
 "@@font-weight:bold;font-size:1.3em;color:#444; //Enjoy :)// &nbsp;&nbsp;@@ We hope you like using your tiddlyspot.com site.  Please email [[feedback@tiddlyspot.com|mailto:feedback@tiddlyspot.com]] with any comments or suggestions."
].join("\n"),

'TspotSidebar':[
 "<<upload http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/store.cgi index.html . .  " + config.tiddlyspotSiteId + ">><html><a href='http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/download' class='button'>download</a></html>"
].join("\n")

});
//}}}
| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |
| 06/06/2011 15:19:04 | AS | [[/|http://axs.tiddlyspot.com/#StyleTabWithLinksPlugin]] | [[store.cgi|http://axs.tiddlyspot.com/store.cgi]] | . | [[index.html | http://axs.tiddlyspot.com/index.html]] | . |
| 06/06/2011 15:21:24 | AS | [[/|http://axs.tiddlyspot.com/]] | [[store.cgi|http://axs.tiddlyspot.com/store.cgi]] | . | [[index.html | http://axs.tiddlyspot.com/index.html]] | . |
| 06/06/2011 15:30:28 | AS | [[/|http://axs.tiddlyspot.com/]] | [[store.cgi|http://axs.tiddlyspot.com/store.cgi]] | . | [[index.html | http://axs.tiddlyspot.com/index.html]] | . | ok |
| 06/06/2011 15:32:13 | AS | [[/|http://axs.tiddlyspot.com/]] | [[store.cgi|http://axs.tiddlyspot.com/store.cgi]] | . | [[index.html | http://axs.tiddlyspot.com/index.html]] | . | ok |
| 06/06/2011 17:12:38 | AS | [[/|http://axs.tiddlyspot.com/#testTiddler4]] | [[store.cgi|http://axs.tiddlyspot.com/store.cgi]] | . | [[index.html | http://axs.tiddlyspot.com/index.html]] | . |
| 06/06/2011 17:23:40 | AS | [[/|http://axs.tiddlyspot.com/]] | [[store.cgi|http://axs.tiddlyspot.com/store.cgi]] | . | [[index.html | http://axs.tiddlyspot.com/index.html]] | . |
| 06/06/2011 17:24:35 | AS | [[/|http://axs.tiddlyspot.com/]] | [[store.cgi|http://axs.tiddlyspot.com/store.cgi]] | . | [[index.html | http://axs.tiddlyspot.com/index.html]] | . |
| 02/11/2018 16:01:57 | YourName | [[/|http://axs.tiddlyspot.com/]] | [[store.php|http://axs.tiddlyspot.com/store.php]] | . | [[index.html | http://axs.tiddlyspot.com/index.html]] |  |
| 02/11/2018 16:03:35 | YourName | [[/|http://axs.tiddlyspot.com/]] | [[store.cgi|http://axs.tiddlyspot.com/store.cgi]] | . | [[index.html | http://axs.tiddlyspot.com/index.html]] |  | failed |
| 02/11/2018 16:03:56 | YourName | [[/|http://axs.tiddlyspot.com/]] | [[store.cgi|http://axs.tiddlyspot.com/store.cgi]] | . | [[index.html | http://axs.tiddlyspot.com/index.html]] |  |
/***
|''Name:''|UploadPlugin|
|''Description:''|Save to web a TiddlyWiki|
|''Version:''|4.1.3|
|''Date:''|Feb 24, 2008|
|''Source:''|http://tiddlywiki.bidix.info/#UploadPlugin|
|''Documentation:''|http://tiddlywiki.bidix.info/#UploadPluginDoc|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0|
|''Requires:''|PasswordOptionPlugin|
***/
//{{{
version.extensions.UploadPlugin = {
	major: 4, minor: 1, revision: 3,
	date: new Date("Feb 24, 2008"),
	source: 'http://tiddlywiki.bidix.info/#UploadPlugin',
	author: 'BidiX (BidiX (at) bidix (dot) info',
	coreVersion: '2.2.0'
};

//
// Environment
//

if (!window.bidix) window.bidix = {}; // bidix namespace
bidix.debugMode = false;	// true to activate both in Plugin and UploadService
	
//
// Upload Macro
//

config.macros.upload = {
// default values
	defaultBackupDir: '',	//no backup
	defaultStoreScript: "store.php",
	defaultToFilename: "index.html",
	defaultUploadDir: ".",
	authenticateUser: true	// UploadService Authenticate User
};
	
config.macros.upload.label = {
	promptOption: "Save and Upload this TiddlyWiki with UploadOptions",
	promptParamMacro: "Save and Upload this TiddlyWiki in %0",
	saveLabel: "save to web", 
	saveToDisk: "save to disk",
	uploadLabel: "upload"	
};

config.macros.upload.messages = {
	noStoreUrl: "No store URL in parmeters or options",
	usernameOrPasswordMissing: "Username or password missing"
};

config.macros.upload.handler = function(place,macroName,params) {
	if (readOnly)
		return;
	var label;
	if (document.location.toString().substr(0,4) == "http") 
		label = this.label.saveLabel;
	else
		label = this.label.uploadLabel;
	var prompt;
	if (params[0]) {
		prompt = this.label.promptParamMacro.toString().format([this.destFile(params[0], 
			(params[1] ? params[1]:bidix.basename(window.location.toString())), params[3])]);
	} else {
		prompt = this.label.promptOption;
	}
	createTiddlyButton(place, label, prompt, function() {config.macros.upload.action(params);}, null, null, this.accessKey);
};

config.macros.upload.action = function(params)
{
		// for missing macro parameter set value from options
		if (!params) params = {};
		var storeUrl = params[0] ? params[0] : config.options.txtUploadStoreUrl;
		var toFilename = params[1] ? params[1] : config.options.txtUploadFilename;
		var backupDir = params[2] ? params[2] : config.options.txtUploadBackupDir;
		var uploadDir = params[3] ? params[3] : config.options.txtUploadDir;
		var username = params[4] ? params[4] : config.options.txtUploadUserName;
		var password = config.options.pasUploadPassword; // for security reason no password as macro parameter	
		// for still missing parameter set default value
		if ((!storeUrl) && (document.location.toString().substr(0,4) == "http")) 
			storeUrl = bidix.dirname(document.location.toString())+'/'+config.macros.upload.defaultStoreScript;
		if (storeUrl.substr(0,4) != "http")
			storeUrl = bidix.dirname(document.location.toString()) +'/'+ storeUrl;
		if (!toFilename)
			toFilename = bidix.basename(window.location.toString());
		if (!toFilename)
			toFilename = config.macros.upload.defaultToFilename;
		if (!uploadDir)
			uploadDir = config.macros.upload.defaultUploadDir;
		if (!backupDir)
			backupDir = config.macros.upload.defaultBackupDir;
		// report error if still missing
		if (!storeUrl) {
			alert(config.macros.upload.messages.noStoreUrl);
			clearMessage();
			return false;
		}
		if (config.macros.upload.authenticateUser && (!username || !password)) {
			alert(config.macros.upload.messages.usernameOrPasswordMissing);
			clearMessage();
			return false;
		}
		bidix.upload.uploadChanges(false,null,storeUrl, toFilename, uploadDir, backupDir, username, password); 
		return false; 
};

config.macros.upload.destFile = function(storeUrl, toFilename, uploadDir) 
{
	if (!storeUrl)
		return null;
		var dest = bidix.dirname(storeUrl);
		if (uploadDir && uploadDir != '.')
			dest = dest + '/' + uploadDir;
		dest = dest + '/' + toFilename;
	return dest;
};

//
// uploadOptions Macro
//

config.macros.uploadOptions = {
	handler: function(place,macroName,params) {
		var wizard = new Wizard();
		wizard.createWizard(place,this.wizardTitle);
		wizard.addStep(this.step1Title,this.step1Html);
		var markList = wizard.getElement("markList");
		var listWrapper = document.createElement("div");
		markList.parentNode.insertBefore(listWrapper,markList);
		wizard.setValue("listWrapper",listWrapper);
		this.refreshOptions(listWrapper,false);
		var uploadCaption;
		if (document.location.toString().substr(0,4) == "http") 
			uploadCaption = config.macros.upload.label.saveLabel;
		else
			uploadCaption = config.macros.upload.label.uploadLabel;
		
		wizard.setButtons([
				{caption: uploadCaption, tooltip: config.macros.upload.label.promptOption, 
					onClick: config.macros.upload.action},
				{caption: this.cancelButton, tooltip: this.cancelButtonPrompt, onClick: this.onCancel}
				
			]);
	},
	options: [
		"txtUploadUserName",
		"pasUploadPassword",
		"txtUploadStoreUrl",
		"txtUploadDir",
		"txtUploadFilename",
		"txtUploadBackupDir",
		"chkUploadLog",
		"txtUploadLogMaxLine"		
	],
	refreshOptions: function(listWrapper) {
		var opts = [];
		for(i=0; i<this.options.length; i++) {
			var opt = {};
			opts.push();
			opt.option = "";
			n = this.options[i];
			opt.name = n;
			opt.lowlight = !config.optionsDesc[n];
			opt.description = opt.lowlight ? this.unknownDescription : config.optionsDesc[n];
			opts.push(opt);
		}
		var listview = ListView.create(listWrapper,opts,this.listViewTemplate);
		for(n=0; n<opts.length; n++) {
			var type = opts[n].name.substr(0,3);
			var h = config.macros.option.types[type];
			if (h && h.create) {
				h.create(opts[n].colElements['option'],type,opts[n].name,opts[n].name,"no");
			}
		}
		
	},
	onCancel: function(e)
	{
		backstage.switchTab(null);
		return false;
	},
	
	wizardTitle: "Upload with options",
	step1Title: "These options are saved in cookies in your browser",
	step1Html: "<input type='hidden' name='markList'></input><br>",
	cancelButton: "Cancel",
	cancelButtonPrompt: "Cancel prompt",
	listViewTemplate: {
		columns: [
			{name: 'Description', field: 'description', title: "Description", type: 'WikiText'},
			{name: 'Option', field: 'option', title: "Option", type: 'String'},
			{name: 'Name', field: 'name', title: "Name", type: 'String'}
			],
		rowClasses: [
			{className: 'lowlight', field: 'lowlight'} 
			]}
};

//
// upload functions
//

if (!bidix.upload) bidix.upload = {};

if (!bidix.upload.messages) bidix.upload.messages = {
	//from saving
	invalidFileError: "The original file '%0' does not appear to be a valid TiddlyWiki",
	backupSaved: "Backup saved",
	backupFailed: "Failed to upload backup file",
	rssSaved: "RSS feed uploaded",
	rssFailed: "Failed to upload RSS feed file",
	emptySaved: "Empty template uploaded",
	emptyFailed: "Failed to upload empty template file",
	mainSaved: "Main TiddlyWiki file uploaded",
	mainFailed: "Failed to upload main TiddlyWiki file. Your changes have not been saved",
	//specific upload
	loadOriginalHttpPostError: "Can't get original file",
	aboutToSaveOnHttpPost: 'About to upload on %0 ...',
	storePhpNotFound: "The store script '%0' was not found."
};

bidix.upload.uploadChanges = function(onlyIfDirty,tiddlers,storeUrl,toFilename,uploadDir,backupDir,username,password)
{
	var callback = function(status,uploadParams,original,url,xhr) {
		if (!status) {
			displayMessage(bidix.upload.messages.loadOriginalHttpPostError);
			return;
		}
		if (bidix.debugMode) 
			alert(original.substr(0,500)+"\n...");
		// Locate the storeArea div's 
		var posDiv = locateStoreArea(original);
		if((posDiv[0] == -1) || (posDiv[1] == -1)) {
			alert(config.messages.invalidFileError.format([localPath]));
			return;
		}
		bidix.upload.uploadRss(uploadParams,original,posDiv);
	};
	
	if(onlyIfDirty && !store.isDirty())
		return;
	clearMessage();
	// save on localdisk ?
	if (document.location.toString().substr(0,4) == "file") {
		var path = document.location.toString();
		var localPath = getLocalPath(path);
		saveChanges();
	}
	// get original
	var uploadParams = new Array(storeUrl,toFilename,uploadDir,backupDir,username,password);
	var originalPath = document.location.toString();
	// If url is a directory : add index.html
	if (originalPath.charAt(originalPath.length-1) == "/")
		originalPath = originalPath + "index.html";
	var dest = config.macros.upload.destFile(storeUrl,toFilename,uploadDir);
	var log = new bidix.UploadLog();
	log.startUpload(storeUrl, dest, uploadDir,  backupDir);
	displayMessage(bidix.upload.messages.aboutToSaveOnHttpPost.format([dest]));
	if (bidix.debugMode) 
		alert("about to execute Http - GET on "+originalPath);
	var r = doHttp("GET",originalPath,null,null,username,password,callback,uploadParams,null);
	if (typeof r == "string")
		displayMessage(r);
	return r;
};

bidix.upload.uploadRss = function(uploadParams,original,posDiv) 
{
	var callback = function(status,params,responseText,url,xhr) {
		if(status) {
			var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\n", responseText.indexOf("destfile:")));
			displayMessage(bidix.upload.messages.rssSaved,bidix.dirname(url)+'/'+destfile);
			bidix.upload.uploadMain(params[0],params[1],params[2]);
		} else {
			displayMessage(bidix.upload.messages.rssFailed);			
		}
	};
	// do uploadRss
	if(config.options.chkGenerateAnRssFeed) {
		var rssPath = uploadParams[1].substr(0,uploadParams[1].lastIndexOf(".")) + ".xml";
		var rssUploadParams = new Array(uploadParams[0],rssPath,uploadParams[2],'',uploadParams[4],uploadParams[5]);
		var rssString = generateRss();
		// no UnicodeToUTF8 conversion needed when location is "file" !!!
		if (document.location.toString().substr(0,4) != "file")
			rssString = convertUnicodeToUTF8(rssString);	
		bidix.upload.httpUpload(rssUploadParams,rssString,callback,Array(uploadParams,original,posDiv));
	} else {
		bidix.upload.uploadMain(uploadParams,original,posDiv);
	}
};

bidix.upload.uploadMain = function(uploadParams,original,posDiv) 
{
	var callback = function(status,params,responseText,url,xhr) {
		var log = new bidix.UploadLog();
		if(status) {
			// if backupDir specified
			if ((params[3]) && (responseText.indexOf("backupfile:") > -1))  {
				var backupfile = responseText.substring(responseText.indexOf("backupfile:")+11,responseText.indexOf("\n", responseText.indexOf("backupfile:")));
				displayMessage(bidix.upload.messages.backupSaved,bidix.dirname(url)+'/'+backupfile);
			}
			var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\n", responseText.indexOf("destfile:")));
			displayMessage(bidix.upload.messages.mainSaved,bidix.dirname(url)+'/'+destfile);
			store.setDirty(false);
			log.endUpload("ok");
		} else {
			alert(bidix.upload.messages.mainFailed);
			displayMessage(bidix.upload.messages.mainFailed);
			log.endUpload("failed");			
		}
	};
	// do uploadMain
	var revised = bidix.upload.updateOriginal(original,posDiv);
	bidix.upload.httpUpload(uploadParams,revised,callback,uploadParams);
};

bidix.upload.httpUpload = function(uploadParams,data,callback,params)
{
	var localCallback = function(status,params,responseText,url,xhr) {
		url = (url.indexOf("nocache=") < 0 ? url : url.substring(0,url.indexOf("nocache=")-1));
		if (xhr.status == 404)
			alert(bidix.upload.messages.storePhpNotFound.format([url]));
		if ((bidix.debugMode) || (responseText.indexOf("Debug mode") >= 0 )) {
			alert(responseText);
			if (responseText.indexOf("Debug mode") >= 0 )
				responseText = responseText.substring(responseText.indexOf("\n\n")+2);
		} else if (responseText.charAt(0) != '0') 
			alert(responseText);
		if (responseText.charAt(0) != '0')
			status = null;
		callback(status,params,responseText,url,xhr);
	};
	// do httpUpload
	var boundary = "---------------------------"+"AaB03x";	
	var uploadFormName = "UploadPlugin";
	// compose headers data
	var sheader = "";
	sheader += "--" + boundary + "\r\nContent-disposition: form-data; name=\"";
	sheader += uploadFormName +"\"\r\n\r\n";
	sheader += "backupDir="+uploadParams[3] +
				";user=" + uploadParams[4] +
				";password=" + uploadParams[5] +
				";uploaddir=" + uploadParams[2];
	if (bidix.debugMode)
		sheader += ";debug=1";
	sheader += ";;\r\n"; 
	sheader += "\r\n" + "--" + boundary + "\r\n";
	sheader += "Content-disposition: form-data; name=\"userfile\"; filename=\""+uploadParams[1]+"\"\r\n";
	sheader += "Content-Type: text/html;charset=UTF-8" + "\r\n";
	sheader += "Content-Length: " + data.length + "\r\n\r\n";
	// compose trailer data
	var strailer = new String();
	strailer = "\r\n--" + boundary + "--\r\n";
	data = sheader + data + strailer;
	if (bidix.debugMode) alert("about to execute Http - POST on "+uploadParams[0]+"\n with \n"+data.substr(0,500)+ " ... ");
	var r = doHttp("POST",uploadParams[0],data,"multipart/form-data; ;charset=UTF-8; boundary="+boundary,uploadParams[4],uploadParams[5],localCallback,params,null);
	if (typeof r == "string")
		displayMessage(r);
	return r;
};

// same as Saving's updateOriginal but without convertUnicodeToUTF8 calls
bidix.upload.updateOriginal = function(original, posDiv)
{
	if (!posDiv)
		posDiv = locateStoreArea(original);
	if((posDiv[0] == -1) || (posDiv[1] == -1)) {
		alert(config.messages.invalidFileError.format([localPath]));
		return;
	}
	var revised = original.substr(0,posDiv[0] + startSaveArea.length) + "\n" +
				store.allTiddlersAsHtml() + "\n" +
				original.substr(posDiv[1]);
	var newSiteTitle = getPageTitle().htmlEncode();
	revised = revised.replaceChunk("<title"+">","</title"+">"," " + newSiteTitle + " ");
	revised = updateMarkupBlock(revised,"PRE-HEAD","MarkupPreHead");
	revised = updateMarkupBlock(revised,"POST-HEAD","MarkupPostHead");
	revised = updateMarkupBlock(revised,"PRE-BODY","MarkupPreBody");
	revised = updateMarkupBlock(revised,"POST-SCRIPT","MarkupPostBody");
	return revised;
};

//
// UploadLog
// 
// config.options.chkUploadLog :
//		false : no logging
//		true : logging
// config.options.txtUploadLogMaxLine :
//		-1 : no limit
//      0 :  no Log lines but UploadLog is still in place
//		n :  the last n lines are only kept
//		NaN : no limit (-1)

bidix.UploadLog = function() {
	if (!config.options.chkUploadLog) 
		return; // this.tiddler = null
	this.tiddler = store.getTiddler("UploadLog");
	if (!this.tiddler) {
		this.tiddler = new Tiddler();
		this.tiddler.title = "UploadLog";
		this.tiddler.text = "| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |";
		this.tiddler.created = new Date();
		this.tiddler.modifier = config.options.txtUserName;
		this.tiddler.modified = new Date();
		store.addTiddler(this.tiddler);
	}
	return this;
};

bidix.UploadLog.prototype.addText = function(text) {
	if (!this.tiddler)
		return;
	// retrieve maxLine when we need it
	var maxLine = parseInt(config.options.txtUploadLogMaxLine,10);
	if (isNaN(maxLine))
		maxLine = -1;
	// add text
	if (maxLine != 0) 
		this.tiddler.text = this.tiddler.text + text;
	// Trunck to maxLine
	if (maxLine >= 0) {
		var textArray = this.tiddler.text.split('\n');
		if (textArray.length > maxLine + 1)
			textArray.splice(1,textArray.length-1-maxLine);
			this.tiddler.text = textArray.join('\n');		
	}
	// update tiddler fields
	this.tiddler.modifier = config.options.txtUserName;
	this.tiddler.modified = new Date();
	store.addTiddler(this.tiddler);
	// refresh and notifiy for immediate update
	story.refreshTiddler(this.tiddler.title);
	store.notify(this.tiddler.title, true);
};

bidix.UploadLog.prototype.startUpload = function(storeUrl, toFilename, uploadDir,  backupDir) {
	if (!this.tiddler)
		return;
	var now = new Date();
	var text = "\n| ";
	var filename = bidix.basename(document.location.toString());
	if (!filename) filename = '/';
	text += now.formatString("0DD/0MM/YYYY 0hh:0mm:0ss") +" | ";
	text += config.options.txtUserName + " | ";
	text += "[["+filename+"|"+location + "]] |";
	text += " [[" + bidix.basename(storeUrl) + "|" + storeUrl + "]] | ";
	text += uploadDir + " | ";
	text += "[[" + bidix.basename(toFilename) + " | " +toFilename + "]] | ";
	text += backupDir + " |";
	this.addText(text);
};

bidix.UploadLog.prototype.endUpload = function(status) {
	if (!this.tiddler)
		return;
	this.addText(" "+status+" |");
};

//
// Utilities
// 

bidix.checkPlugin = function(plugin, major, minor, revision) {
	var ext = version.extensions[plugin];
	if (!
		(ext  && 
			((ext.major > major) || 
			((ext.major == major) && (ext.minor > minor))  ||
			((ext.major == major) && (ext.minor == minor) && (ext.revision >= revision))))) {
			// write error in PluginManager
			if (pluginInfo)
				pluginInfo.log.push("Requires " + plugin + " " + major + "." + minor + "." + revision);
			eval(plugin); // generate an error : "Error: ReferenceError: xxxx is not defined"
	}
};

bidix.dirname = function(filePath) {
	if (!filePath) 
		return;
	var lastpos;
	if ((lastpos = filePath.lastIndexOf("/")) != -1) {
		return filePath.substring(0, lastpos);
	} else {
		return filePath.substring(0, filePath.lastIndexOf("\\"));
	}
};

bidix.basename = function(filePath) {
	if (!filePath) 
		return;
	var lastpos;
	if ((lastpos = filePath.lastIndexOf("#")) != -1) 
		filePath = filePath.substring(0, lastpos);
	if ((lastpos = filePath.lastIndexOf("/")) != -1) {
		return filePath.substring(lastpos + 1);
	} else
		return filePath.substring(filePath.lastIndexOf("\\")+1);
};

bidix.initOption = function(name,value) {
	if (!config.options[name])
		config.options[name] = value;
};

//
// Initializations
//

// require PasswordOptionPlugin 1.0.1 or better
bidix.checkPlugin("PasswordOptionPlugin", 1, 0, 1);

// styleSheet
setStylesheet('.txtUploadStoreUrl, .txtUploadBackupDir, .txtUploadDir {width: 22em;}',"uploadPluginStyles");

//optionsDesc
merge(config.optionsDesc,{
	txtUploadStoreUrl: "Url of the UploadService script (default: store.php)",
	txtUploadFilename: "Filename of the uploaded file (default: in index.html)",
	txtUploadDir: "Relative Directory where to store the file (default: . (downloadService directory))",
	txtUploadBackupDir: "Relative Directory where to backup the file. If empty no backup. (default: ''(empty))",
	txtUploadUserName: "Upload Username",
	pasUploadPassword: "Upload Password",
	chkUploadLog: "do Logging in UploadLog (default: true)",
	txtUploadLogMaxLine: "Maximum of lines in UploadLog (default: 10)"
});

// Options Initializations
bidix.initOption('txtUploadStoreUrl','');
bidix.initOption('txtUploadFilename','');
bidix.initOption('txtUploadDir','');
bidix.initOption('txtUploadBackupDir','');
bidix.initOption('txtUploadUserName','');
bidix.initOption('pasUploadPassword','');
bidix.initOption('chkUploadLog',true);
bidix.initOption('txtUploadLogMaxLine','10');


// Backstage
merge(config.tasks,{
	uploadOptions: {text: "upload", tooltip: "Change UploadOptions and Upload", content: '<<uploadOptions>>'}
});
config.backstageTasks.push("uploadOptions");


//}}}

<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::ViewToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='subtitle'></div>
<div class='tagging' macro='tagging'></div>
<div class='tagged' macro='tags'></div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
<!--}}}-->
Welcome to axs.tiddlyspot.com!
Type the text for 'New Tiddler'

no links here
Type the text for 'New Tiddler'

MainMenu
TagglyTagsMenuPlugin
<<tabs someID
"one" "" "testTiddler1"
"two" "" "testTiddler2"
"three" "" "testTiddler3"
>>
Each button is in a <div> with different 'position' styling. I don't know what's up with the "absolute" positioned button. The last on is a "fixed" position button. In that one, the popup is positioned incorrectly (in Safari and Chrome, possibly other browsers too) when the core TW 2.6.2 findPosY() is used. 

absolute: <html><div style="position:absolute"><div macro="showPopup tiddler:GettingStarted"></div></html>


relative: <html><div style="position:relative"><div macro="showPopup tiddler:GettingStarted"></div></html>
inherit: <html><div style="position:inherit"><div macro="showPopup tiddler:GettingStarted"></div></html>
static: <html><div style="position:static"><div macro="showPopup tiddler:GettingStarted"></div></html>
fixed: <html><div style="position:fixed"><div macro="showPopup tiddler:GettingStarted"></div></html>


Change the behavior of findPosY() with the code below and try the test cases:
//{{{
findPosX_old=findPosX;
findPosY_old=findPosY;

findPosX=function(el){
	try{return jQuery(el).offset().left;}
	catch(err){return findPosX_old(el);}
	
}

findPosY=function(el){
	try{return jQuery(el).offset().top;}
	catch(err){return findPosY_old(el);}
}
//}}}