<!--{{{-->
<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]];}

#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>>
/***
|Name|AliasPlugin|
|Source|http://www.TiddlyTools.com/#AliasPlugin|
|Documentation|http://www.TiddlyTools.com/#AliasPluginInfo|
|Version|1.1.1|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|Create text-substitution macros|
Define macros for abbreviations and other "aliases", and then embed them in the rest of your tiddler content to quickly insert common terms, phrases and links without a lot of repetitive typing.
!!!!!Documentation
> see [[AliasPluginInfo]]
!!!!!Revisions
<<<
2009.09.09 [1.1.1] 'tiddler' arg passed to wikify() so aliases containing macros render with correct context
| Please see [[AliasPluginInfo]] for previous revision details |
2005.08.12 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.AliasPlugin= {major: 1, minor: 1, revision: 1, date: new Date(2009,9,9)};
config.macros.alias= { };
config.macros.alias.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
	var alias=params.shift(); if (!alias) return; alias=alias.replace(/ /g,"_"); // don't allow spaces in alias
	if (config.macros[alias]==undefined) { // create new macro (as needed)
		config.macros[alias] = { };
		config.macros[alias].handler =
			function (place,macroName,params,wikifier,paramString,tiddler)
				{ wikify(config.macros[macroName].text.format(params),place,null,tiddler); }
	}
	config.macros[alias].text = params[0]?params.join(' '):alias;	// set alias text
}
//}}}
/***
|''Name:''|AnnotationsPlugin|
|''Description:''|Inline annotations for tiddler text.|
|''Author:''|Saq Imtiaz ( lewcid@gmail.com )|
|''Source:''|http://tw.lewcid.org/#AnnotationsPlugin|
|''Code Repository:''|http://tw.lewcid.org/svn/plugins|
|''Version:''|2.0|
|''Date:''||
|''License:''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''~CoreVersion:''|2.2.3|

!!Usage:
*{{{((text to annotate(annotation goes here)))}}}
* To include the text being annotated, in the popup as a title, put {{{^}}} as the first letter of the annotation text.
** {{{((text to annotate(^annotation goes here)))}}}

!!Examples:
Mouse over, the text below:
* ((banana(the best fruit in the world)))
* ((banana(^ the best fruit in the world)))

***/
// /%
config.formatters.unshift({name:"annotations",match:"\\(\\(",lookaheadRegExp:/\(\((.*?)\((\^?)((?:.|\n)*?)\)\)\)/g,handler:function(w){
this.lookaheadRegExp.lastIndex=w.matchStart;
var _2=this.lookaheadRegExp.exec(w.source);
if(_2&&_2.index==w.matchStart){
var _3=createTiddlyElement(w.output,"span",null,"annosub",_2[1]);
_3.anno=_2[3];
if(_2[2]){
_3.subject=_2[1];
}
_3.onmouseover=this.onmouseover;
_3.onmouseout=this.onmouseout;
_3.ondblclick=this.onmouseout;
w.nextMatch=_2.index+_2[0].length;
}
},onmouseover:function(e){
popup=createTiddlyElement(document.body,"div",null,"anno");
this.popup=popup;
if(this.subject){
wikify("!"+this.subject+"\n",popup);
}
wikify(this.anno,popup);
addClass(this,"annosubover");
Popup.place(this,popup,{x:25,y:7});
},onmouseout:function(e){
removeNode(this.popup);
this.popup=null;
removeClass(this,"annosubover");
}});
setStylesheet(".anno{position:absolute;border:2px solid #000;background-color:#DFDFFF; color:#000;padding:0.5em;max-width:15em;width:expression(document.body.clientWidth > (255/12) *parseInt(document.body.currentStyle.fontSize)?'15em':'auto' );}\n"+".anno h1, .anno h2{margin-top:0;color:#000;}\n"+".annosub{background:#ccc;}\n"+".annosubover{z-index:25; background-color:#DFDFFF;cursor:help;}\n","AnnotationStyles");


// %/
/***
|Name|AttachFilePluginFormatters|
|Source|http://www.TiddlyTools.com/#AttachFilePluginFormatters|
|Version|4.0.1|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1.3|
|Type|plugin|
|Description|run-time library for displaying attachment tiddlers|
Runtime processing for //rendering// attachment tiddlers created by [[AttachFilePlugin]].   Attachment tiddlers are tagged with<<tag attachment>>and contain binary file content (e.g., jpg, gif, pdf, mp3, etc.) that has been stored directly as base64 text-encoded data or can be loaded from external files stored on a local filesystem or remote web server.  Note: after creating new attachment tiddlers, you can remove [[AttachFilePlugin]], as long as you retain //this// tiddler (so that images can be rendered later on).
!!!!!Formatters
<<<
This plugin extends the behavior of the following TiddlyWiki core "wikify()" formatters:
* embedded images: {{{[img[tooltip|image]]}}}
* linked embedded images: {{{[img[tooltip|image][link]]}}}
* external/"pretty" links: {{{[[label|link]]}}}
''Please refer to AttachFilePlugin (source: http://www.TiddlyTools.com/#AttachFilePlugin) for additional information.''
<<<
!!!!!Revisions
<<<
2009.10.10 [4.0.1] in fileExists(), check for IE to avoid hanging Chrome during startup
2009.06.04 [4.0.0] changed attachment storage format to use //sections// instead of embedded substring markers.
2008.01.08 [*.*.*] plugin size reduction: documentation moved to ...Info
2007.12.04 [*.*.*] update for TW2.3.0: replaced deprecated core functions, regexps, and macros
2007.10.29 [3.7.0] more code reduction: removed upload handling from AttachFilePlugin (saves ~7K!)
2007.10.28 [3.6.0] removed duplicate formatter code from AttachFilePlugin (saves ~10K!) and updated documentation accordingly.  This plugin ([[AttachFilePluginFormatters]]) is now //''required''// in order to display attached images/binary files within tiddler content.
2006.05.20 [3.4.0] through 2007.03.01 [3.5.3] sync with AttachFilePlugin
2006.05.13 [3.2.0] created from AttachFilePlugin v3.2.0
<<<
!!!!!Code
***/
// // version
//{{{
version.extensions.AttachFilePluginFormatters= {major: 4, minor: 0, revision: 1, date: new Date(2009,10,10)};
//}}}

//{{{
if (config.macros.attach==undefined) config.macros.attach= { };
//}}}
//{{{
if (config.macros.attach.isAttachment==undefined) config.macros.attach.isAttachment=function (title) {
	var tiddler = store.getTiddler(title);
	if (tiddler==undefined || tiddler.tags==undefined) return false;
	return (tiddler.tags.indexOf("attachment")!=-1);
}
//}}}

//{{{
// test for local file existence - returns true/false without visible error display
if (config.macros.attach.fileExists==undefined) config.macros.attach.fileExists=function(f) {
	if(window.Components) { // MOZ
		try { netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); }
		catch(e) { return false; } // security access denied
		var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
		try { file.initWithPath(f); }
		catch(e) { return false; } // invalid directory
		return file.exists();
	}
	else if (config.browser.isIE) { // IE
		var fso = new ActiveXObject("Scripting.FileSystemObject");
		return fso.FileExists(f);
	}
	else return true; // other browsers: assume file exists
}
//}}}

//{{{
if (config.macros.attach.getAttachment==undefined) config.macros.attach.getAttachment=function(title) {

	// extract embedded data, local and remote links (if any)
	var text=store.getTiddlerText(title,'');
	var embedded=store.getTiddlerText(title+'##data','').trim();
	var locallink=store.getTiddlerText(title+'##file','').trim();
	var remotelink=store.getTiddlerText(title+'##url','').trim();

	// backward-compatibility for older attachments (pre 4.0.0)
	var startmarker="---BEGIN_DATA---\n";
	var endmarker="\n---END_DATA---";
	var pos=0; var endpos=0;
	if ((pos=text.indexOf(startmarker))!=-1 && (endpos=text.indexOf(endmarker))!=-1)
		embedded="data:"+(text.substring(pos+startmarker.length,endpos)).replace(/\n/g,'');
	if ((pos=text.indexOf("/%LOCAL_LINK%/"))!=-1)
		locallink=text.substring(text.indexOf("|",pos)+1,text.indexOf("]]",pos));
	if ((pos=text.indexOf("/%REMOTE_LINK%/"))!=-1)
		remotelink=text.substring(text.indexOf("|",pos)+1,text.indexOf("]]",pos));

	// if there is a data: URI defined (not supported by IE)
	if (embedded.length && !config.browser.isIE) return embedded;

	// document is being served remotely... use remote URL (if any)  (avoids security alert)
	if (remotelink.length && document.location.protocol!="file:")
		return remotelink;  

	// local link only... return link without checking file existence (avoids security alert)
	if (locallink.length && !remotelink.length) 
		return locallink; 

	// local link, check for file exist... use local link if found
	if (locallink.length) { 
		locallink=locallink.replace(/^\.[\/\\]/,''); // strip leading './' or '.\' (if any)
		if (this.fileExists(getLocalPath(locallink))) return locallink;
		// maybe local link is relative... add path from current document and try again
		var pathPrefix=document.location.href;  // get current document path and trim off filename
		var slashpos=pathPrefix.lastIndexOf("/"); if (slashpos==-1) slashpos=pathPrefix.lastIndexOf("\\"); 
		if (slashpos!=-1 && slashpos!=pathPrefix.length-1) pathPrefix=pathPrefix.substr(0,slashpos+1);
		if (this.fileExists(getLocalPath(pathPrefix+locallink))) return locallink;
	}

	// no embedded data, no local (or not found), fallback to remote URL (if any)
	if (remotelink.length) return remotelink;

	// attachment URL doesn't resolve, just return input as is
	return title;
}
//}}}
//{{{
if (config.macros.attach.init_formatters==undefined) config.macros.attach.init_formatters=function() {
	if (this.initialized) return;

	// find the formatter for "image" and replace the handler
	for (var i=0; i<config.formatters.length && config.formatters[i].name!="image"; i++);
	if (i<config.formatters.length)	config.formatters[i].handler=function(w) {
		this.lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source)
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) // Simple bracketted link
			{
			var e = w.output;
			if(lookaheadMatch[5])
				{
				var link = lookaheadMatch[5];
				// ELS -------------
				var external=config.formatterHelpers.isExternalLink(link);
				if (external)
					{
					if (config.macros.attach.isAttachment(link))
						{
						e = createExternalLink(w.output,link);
						e.href=config.macros.attach.getAttachment(link);
						e.title = config.macros.attach.linkTooltip + link;
						}
					else
						e = createExternalLink(w.output,link);
					}
				else 
					e = createTiddlyLink(w.output,link,false,null,w.isStatic);
				// ELS -------------
				addClass(e,"imageLink");
				}
			var img = createTiddlyElement(e,"img");
			if(lookaheadMatch[1])
				img.align = "left";
			else if(lookaheadMatch[2])
				img.align = "right";
			if(lookaheadMatch[3])
				img.title = lookaheadMatch[3];
			img.src = lookaheadMatch[4];
			// ELS -------------
			if (config.macros.attach.isAttachment(lookaheadMatch[4]))
				img.src=config.macros.attach.getAttachment(lookaheadMatch[4]);
			// ELS -------------
			w.nextMatch = this.lookaheadRegExp.lastIndex;
		}
	}
//}}}
//{{{
	// find the formatter for "prettyLink" and replace the handler
	for (var i=0; i<config.formatters.length && config.formatters[i].name!="prettyLink"; i++);
	if (i<config.formatters.length)	{
		config.formatters[i].handler=function(w) {
			this.lookaheadRegExp.lastIndex = w.matchStart;
			var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
			if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
				var e;
				var text = lookaheadMatch[1];
				if(lookaheadMatch[3]) {
					// Pretty bracketted link
					var link = lookaheadMatch[3];
					if (config.macros.attach.isAttachment(link)) {
						e = createExternalLink(w.output,link);
						e.href=config.macros.attach.getAttachment(link);
						e.title=config.macros.attach.linkTooltip+link;
					}
					else e = (!lookaheadMatch[2] && config.formatterHelpers.isExternalLink(link))
						? createExternalLink(w.output,link)
						: createTiddlyLink(w.output,link,false,null,w.isStatic);
				} else {
					e = createTiddlyLink(w.output,text,false,null,w.isStatic);
				}
				createTiddlyText(e,text);
				w.nextMatch = this.lookaheadRegExp.lastIndex;
			}
		}
	} // if "prettyLink" formatter found
	this.initialized=true;
}
//}}}
//{{{
config.macros.attach.init_formatters(); // load time init
//}}}
//{{{
if (TiddlyWiki.prototype.coreGetRecursiveTiddlerText==undefined) {
	TiddlyWiki.prototype.coreGetRecursiveTiddlerText = TiddlyWiki.prototype.getRecursiveTiddlerText;
	TiddlyWiki.prototype.getRecursiveTiddlerText = function(title,defaultText,depth) {
		return config.macros.attach.isAttachment(title)?
			config.macros.attach.getAttachment(title):this.coreGetRecursiveTiddlerText.apply(this,arguments);
	}
}
//}}}
Back Bay Large Installation System Administration. See http://www.bblisa.org.
Replace this text with links to tiddlers.
<<matchTags inline "* %0" "\n" sort:title chapter>>
This is the rss feed for new content changes from <<tiddler "GettingStarted::courseHomeRss">>.

<<rssReader noDesc {{store.getTiddlerSlice('GettingStarted', 'courseHomeRss');}} >>
/***
|Name|CopyTiddlerPlugin|
|Source|http://www.TiddlyTools.com/#CopyTiddlerPlugin|
|Version|3.2.5|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.3|
|Type|plugin|
|Requires||
|Overrides||
|Description|Quickly create a copy of any existing tiddler|
!!!Usage
<<<
The plugin automatically updates the default (shadow) ToolbarCommands definitions to insert the ''copyTiddler'' command, which will appear as ''copy'' when a tiddler is rendered.  If you are already using customized toolbar definitions, you will need to manually add the ''copyTiddler'' toolbar command to your existing ToolbarCommands tiddler, e.g.:
{{{
|EditToolbar|... copyTiddler ... |
}}}
When the ''copy'' command is selected, a new tiddler is created containing an exact copy of the current text/tags/fields, using a title of "{{{TiddlerName (n)}}}", where ''(n)'' is the next available number (starting with 1, of course).  If you copy while //editing// a tiddler, the current values displayed in the editor are used (including any changes you may have already made to those values), and the new tiddler is immediately opened for editing.

The plugin also provides a macro that allows you to embed a ''copy'' command directly in specific tiddler content:
{{{
<<copyTiddler TidderName label:"..." prompt:"...">>
}}}
where
* ''TiddlerName'' (optional)<br>specifies the //source// tiddler to be copied.  If omitted, the current containing tiddler (if any) will be copied.
* ''label:"..."'' (optional)<br>specifies text to use for the embedded link (default="copy TiddlerName")
* ''prompt:"..."'' (optional)<br>specifies mouseover 'tooltip' help text for link
//Note: to use non-default label/prompt values with the current containing tiddler, use "" for the TiddlerName//
<<<
!!!Configuration
<<<
<<option chkCopyTiddlerDate>> use date/time from existing tiddler (otherwise, use current date/time)
{{{<<option chkCopyTiddlerDate>>}}}
<<<
!!!Revisions
<<<
2009.06.08 [3.2.5] added option to use timestamp from source tiddler
2009.03.09 [3.2.4] fixed IE-specific syntax error
2009.03.02 [3.2.3] refactored code (again) to restore use of config.commands.copyTiddler.* custom settings
2009.02.13 [3.2.2] in click(), fix calls to displayTiddler() to use current tiddlerElem and use getTiddlerText() to permit copying of shadow tiddler content
2009.01.30 [3.2.1] fixed handling for copying field values when in edit mode
2009.01.23 [3.2.0] refactored code and added {{{<<copyTiddler TiddlerName>>}}} macro
2008.12.18 [3.1.4] corrected code for finding next (n) value when 'sparse' handling is in effect (thanks to RussThomas for identifying and diagnosing the problem)
2008.11.14 [3.1.3] added optional 'sparse' setting (avoids 'filling in' missing numbers that may have been previously deleted)
2008.11.14 [3.1.2] added optional 'zeroPad' setting
2008.11.14 [3.1.1] moved hard-coded '(n)' regex into 'suffixPattern' object property so it can be customized
2008.09.26 [3.1.0] changed new title generation to use '(n)' suffix instead of 'Copy of' prefix
2008.05.20 [3.0.3] in handler, when copying from VIEW mode, create duplicate array from existing tags array before saving new tiddler.
2007.12.19 [3.0.2] in handler, when copying from VIEW mode, duplicate custom fields before saving new tiddler. Thanks to bug report from Ken Girard.
2007.09.26 [3.0.1] in handler, use findContainingTiddler(src) to get tiddlerElem (and title).  Allows 'copy' command to find correct tiddler when transcluded using {{{<<tiddler>>}}} macro or enhanced toolbar inclusion (see [[CoreTweaks]])
2007.06.28 [3.0.0] complete re-write to handle custom fields and alternative view/edit templates
2007.05.17 [2.1.2] use store.getTiddlerText() to retrieve tiddler content, so that SHADOW tiddlers can be copied correctly when in VIEW mode
2007.04.01 [2.1.1] in copyTiddler.handler(), fix check for editor fields by ensuring that found field actually has edit=='text' attribute
2007.02.05 [2.1.0] in copyTiddler.handler(), if editor fields (textfield and/or tagsfield) can't be found (i.e., tiddler is in VIEW mode, not EDIT mode), then get text/tags values from stored tiddler instead of active editor fields.  Allows use of COPY toolbar directly from VIEW mode (based on a request from LaurentCharles)
2006.12.12 [2.0.0] completely rewritten so plugin just creates a new tiddler EDITOR with a copy of the current tiddler EDITOR contents, instead of creating the new tiddler in the STORE by copying the current tiddler values from the STORE.
2005.xx.xx [1.0.0] original version by Tim Morgan
<<<
!!!Code
***/
//{{{
version.extensions.CopyTiddlerPlugin= {major: 3, minor: 2, revision: 5, date: new Date(2009,6,8)};

// automatically tweak shadow EditTemplate to add 'copyTiddler' toolbar command (following 'cancelTiddler')
config.shadowTiddlers.ToolbarCommands=config.shadowTiddlers.ToolbarCommands.replace(/cancelTiddler/,'cancelTiddler copyTiddler');

if (config.options.chkCopyTiddlerDate===undefined) config.options.chkCopyTiddlerDate=false;

config.commands.copyTiddler = {
	text: 'copy',
	hideReadOnly: true,
	tooltip: 'Make a copy of this tiddler',
	notitle: 'this tiddler',
	prefix: '',
	suffixText: ' (%0)',
	suffixPattern: / \(([0-9]+)\)$/,
	zeroPad: 0,
	sparse: false,
	handler: function(event,src,title)
		{ return config.commands.copyTiddler.click(src,event); },
	click: function(here,ev) {
		var tiddlerElem=story.findContainingTiddler(here);
		var template=tiddlerElem?tiddlerElem.getAttribute('template'):null;
		var title=here.getAttribute('from');
		if (!title || !title.length) {
			if (!tiddlerElem) return false;
			else title=tiddlerElem.getAttribute('tiddler');
		}
		var root=title.replace(this.suffixPattern,''); // title without suffix
		// find last matching title
		var last=title;
		if (this.sparse) { // don't fill-in holes... really find LAST matching title
			var tids=store.getTiddlers('title','excludeLists');
			for (var t=0; t<tids.length; t++) if (tids[t].title.startsWith(root)) last=tids[t].title;
		}
		// get next number (increment from last matching title)
		var n=1; var match=this.suffixPattern.exec(last); if (match) n=parseInt(match[1])+1;
		var newTitle=this.prefix+root+this.suffixText.format([String.zeroPad(n,this.zeroPad)]);
		// if not sparse mode, find the next hole to fill in...
		while (store.tiddlerExists(newTitle)||document.getElementById(story.idPrefix+newTitle))
			{ n++; newTitle=this.prefix+root+this.suffixText.format([String.zeroPad(n,this.zeroPad)]); }
		if (!story.isDirty(title)) { // if tiddler is not being EDITED
			// duplicate stored tiddler (if any)
			var text=store.getTiddlerText(title,'');
			var who=config.options.txtUserName;
			var when=new Date();
			var newtags=[]; var newfields={};
			var tid=store.getTiddler(title); if (tid) {
				if (config.options.chkCopyTiddlerDate) var when=tid.modified;
				for (var t=0; t<tid.tags.length; t++) newtags.push(tid.tags[t]);
				store.forEachField(tid,function(t,f,v){newfields[f]=v;},true);
			}
	                store.saveTiddler(newTitle,newTitle,text,who,when,newtags,newfields,true);
			story.displayTiddler(tiddlerElem,newTitle,template);
		} else {
			story.displayTiddler(tiddlerElem,newTitle,template);
			var fields=config.commands.copyTiddler.gatherFields(tiddlerElem); // get current editor fields
			var newTiddlerElem=document.getElementById(story.idPrefix+newTitle);
			for (var f=0; f<fields.length; f++) {  // set fields in new editor
				if (fields[f].name=='title') fields[f].value=newTitle; // rename title in new tiddler
				var fieldElem=config.commands.copyTiddler.findField(newTiddlerElem,fields[f].name);
				if (fieldElem) {
					if (fieldElem.getAttribute('type')=='checkbox')
						fieldElem.checked=fields[f].value;
					else 
						fieldElem.value=fields[f].value;
				}
			}
		}
		story.focusTiddler(newTitle,'title');
		return false;
	},
	findField: function(tiddlerElem,field) {
		var inputs=tiddlerElem.getElementsByTagName('input');
		for (var i=0; i<inputs.length; i++) {
			if (inputs[i].getAttribute('type')=='checkbox' && inputs[i].field == field) return inputs[i];
			if (inputs[i].getAttribute('type')=='text' && inputs[i].getAttribute('edit') == field) return inputs[i];
		}
		var tas=tiddlerElem.getElementsByTagName('textarea');
		for (var i=0; i<tas.length; i++) if (tas[i].getAttribute('edit') == field) return tas[i];
		var sels=tiddlerElem.getElementsByTagName('select');
		for (var i=0; i<sels.length; i++) if (sels[i].getAttribute('edit') == field) return sels[i];
		return null;
	},
	gatherFields: function(tiddlerElem) { // get field names and values from current tiddler editor
		var fields=[];
		// get checkboxes and edit fields
		var inputs=tiddlerElem.getElementsByTagName('input');
		for (var i=0; i<inputs.length; i++) {
			if (inputs[i].getAttribute('type')=='checkbox')
				if (inputs[i].field) fields.push({name:inputs[i].field,value:inputs[i].checked});
			if (inputs[i].getAttribute('type')=='text')
				if (inputs[i].getAttribute('edit')) fields.push({name:inputs[i].getAttribute('edit'),value:inputs[i].value});
		}
		// get textareas (multi-line edit fields)
		var tas=tiddlerElem.getElementsByTagName('textarea');
		for (var i=0; i<tas.length; i++)
			if (tas[i].getAttribute('edit')) fields.push({name:tas[i].getAttribute('edit'),value:tas[i].value});
		// get selection lists (droplist or listbox)
		var sels=tiddlerElem.getElementsByTagName('select');
		for (var i=0; i<sels.length; i++)
			if (sels[i].getAttribute('edit')) fields.push({name:sels[i].getAttribute('edit'),value:sels[i].value});
		return fields;
	}
};
//}}}
// // MACRO DEFINITION
//{{{
config.macros.copyTiddler = {
	label: 'copy',
	prompt: 'Make a copy of %0',
	handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		var title=params.shift();
		params=paramString.parseParams('anon',null,true,false,false);
		var label	=getParam(params,'label',this.label+(title?' '+title:''));
		var prompt	=getParam(params,'prompt',this.prompt).format([title||this.notitle]);
		var b=createTiddlyButton(place,label,prompt,
			function(ev){return config.commands.copyTiddler.click(this,ev)});
		b.setAttribute('from',title||'');
	}
};
//}}}
! Copyright

All tiddlers marked with the structure or content tags are copyrighted &copy; by the author.

! Additional licenses
Parts of this coursebook use components that are licensed separately from the content. This section contains the license information under which they are made available, or permission from the author to use the component.

!! ~TiddlyWiki license
From: http://tiddlywiki.org/wiki/TiddlyWiki_License

{{{
TiddlyWiki created by Jeremy Ruston, (jeremy [at] osmosoft [dot] com)

Copyright (c) UnaMesa Association 2004-2008

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.

Neither the name of the UnaMesa Association nor the names of its contributors may be
used to endorse or promote products derived from this software without specific
prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
}}}

!! ~TiddlySaver.jar License

From http://www.mail-archive.com/tiddlywiki@googlegroups.com/msg07643.html:

{{{
[tw] Re: Can TiddlyWiki and TiddlySaver.jar be redistributed? Licensing and copyright questions.

Jeremy Ruston
Sat, 01 Aug 2009 11:55:02 -0700

For licensing purposes TiddlySaver is intended to be considered to be
a component of TiddlyWiki, and available under the same terms.

Cheers

Jerm
}}}

!! Plugins from tiddlytools.com

All the plugins/scripts  from tiddlytools.com are covered by http://www.tiddlytools.com/#LegalStatements.

<<<
This work is based upon TiddlyWiki <<version>>, written by Jeremy Ruston, &copy; [[UnaMesa Association|http://www.unamesa.org/]] 2004-2008.

Modifications and additions to this work, including (but not limited to) original programmatic components ("plugins", "macros", "scripts", "stylesheets") have been created by Eric L. Shulman and/or ELS Design Studios.  These components are currently distributed using an ''open source'' model; however, they are ''not in the public domain'', and the author ''retains all applicable rights''.  Nonetheless, you //are// permitted to ''use, copy, and/or modify'' individual components of this work, subject to the licensing ''terms and conditions'' specifically included within or referenced by those individual components, as well as other terms, conditions, instructions, and guidelines included herein or by reference to the [[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]].

This work may contain portions of copyrighted materials from other sources.  In accordance with "fair use" principles (see [[United States Copyright Law, Title 17, Section 107|http://www.copyright.gov/title17/92chap1.html#107]]), such materials have been reproduced without profit for purposes of criticism, comment, news reporting, instruction, scholarship, and/or research.  ''All other original content, including (but not limited to) writings, illustrations, photographic images, sound recordings, and videos, are the property of Eric L. Shulman and/or ELS Design Studios, or are used under license or agreement with third parties'' and, except as required for normative operation and viewing of this work, may not be stored, displayed or re-transmitted in any form, nor used for any commercial purposes, without the specific prior permission of the respective rights holders.

This work includes or makes reference to icons that are part of the [["Silk" icon set|http://www.famfamfam.com/lab/icons/silk/ ]] containing 1000 16-by-16 pixel icons in PNG format, created by Mark James, and is licensed under a Creative Commons Attribution 2.5 License. Please visit http://www.famfamfam.com/ for further information and licensing details regarding this icon set.

''Terms of use:''

This work contains ''individual components that are intended to be selectively copied and installed'' into your own TiddlyWiki files in order to enhance and customize those documents.  You may not re-distribute this document in it's entirety, nor re-use it's overall design without specific prior permission.  You may, however, ''download and save this work for use only as a //local// resource'' to assist you in developing your //own// TiddlyWiki document designs.

Because people can import plugins from anyone's TiddlyWiki document, as soon as you share your document with just ONE other person, you become a "re-distributor" of the components you have installed in that document.  As such, ''you should avoid modifying any ~TiddlyTools components you have installed in your own documents'' unless there is a compelling, //functional// reason to do so and, even then, ''the best approach is often to simply submit a feature request'' to the original author/publisher and leave it up to them to determine the best way to modify and re-publish their components.

Nonetheless, if you //do// modify and/or share components of this work, you should ''always retain the original published content within those those components'', including all documentation, credits, licensing information, and URL references to the official distribution source for the unaltered versions of those components.  In addition, ''all modified components must be clearly identifiable as derivative works'' that have been differentiated from the original versions by renaming those components, as well as adding inline comments and a "revision history" to document specific changes.

If you share a modified ~TiddlyTools component, you must be prepared to support it.  All ''problems that occur within a modified component should be reported first directly to the provider of that modified component'', and then only reported to ~TiddlyTools if it can be shown that the problem also occurs in ~TiddlyTools' officially-published version of the component.  Any ''problems that are reported for //undifferentiated// modifications won't receive help from ~TiddlyTools'' (once they are determined to be modified, of course!), other than to direct the inquiry to wherever they got the modified components from in the first place.

Except for officially-published links to specific components of this work, ''you must not create or share deep links'' to online components of this work (e.g., images, audio, video, etc.).  Instead, you should copy the desired components (subject to applicable licenses and copyrights) to your own system or online hosting service, and ensure that your document contains references to //those// copies.

''Trademarks/servicemarks:''

"ELS Design Studios", "~TiddlyTools", "~TiddlyStudios", "~TiddlyTech", "~TiddlyLabs", "Small Tools for Big Ideas!", "Intuitive Interfaces for Intelligent Interactions" and the "i4" logo (in graphical //and// text forms) are trademarks or servicemarks of ELS Design Studios and may not be used without permission.  Limited use of "ELS Design Studios" and "~TiddlyTools" marks in other works is granted for attribution purposes only.  Such use does not create or imply any endorsement, agency or partner relationship with Eric L. Shulman and/or ELS Design Studios, nor with any designated representatives, agents, or heirs thereof.

''Limits on Liability:''

All materials are presented on an "as-is" basis and are subject to change without notice.  The author of this document makes no claims regarding the suitability or reliability of the information presented, and assumes no liability for any damages that may occur as a result of its use.

''Privacy Notice: ''

This site limits the collection and use of non-public, personal customer information to that which is needed to offer products and services, and to file reports or financial statements as required by law. This site has physical, electronic and procedural safeguards to maintain the protections of private information, and does not provide, sell or otherwise disclose such information to non-affiliated third parties.
<<<

!! Plugins from tiddlywiki.bidx.info

Licensed under BSD open source license. http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D

!! Plugins from tw.lewcid.org

Plugins created by Saq Imtiaz are covered under the creative commons license: http://creativecommons.org/licenses/by-sa/3.0/ license.

!! Plugins from tiddlywiki.abego-software.de

Are licensed under the Bsd License that is referenced from the plugin and is located at:
http://tiddlywiki.abego-software.de/#%5B%5BBSD%20open%20source%20license%5D%5D

!! Paulo Soares plugins

http://www.math.ist.utl.pt/~psoares/addons.html  licensed under http://creativecommons.org/licenses/by-sa/3.0/

!! ~Clint Checketts and Paul Petterson

RedirectMacro - Multiple attempts to contact the author have failed. From this thread:
<<<
http://groups.google.com/group/tiddlywiki/browse_thread/thread/2e65045b53d231cf/efc9861ded20605e?q=redirect#efc9861ded20605e
<<<
it appears to be abandoned. As a result it falls into the public domain.

!! TiddlyLockPlugin

http://creativecommons.org/licenses/by-sa/3.0/

!! RefreshCommand

Email addresses were changed to prevent harvesting.

{{{
From:    Simon Baird <simon.baird at gmail dot .com>
Subject: Re: Rights to redistribute the RefreshCommand

--0016e64bd5bc00cdad0471eff216
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

Please go ahead.

License details for my TW related plugins:
http://mptw.tiddlyspot.com/#License%20TheBSDLicense

On Tue, Aug 25, 2009 at 2:23 PM, John P. Rouillard <[[redacted]]>wrote:

>
> Hello Mr. Baird:
>
> I am developing a TiddlyWiki for use in a class I am teaching.  I
> would like to include your RefreshCommand plugin, however I am unable
> to find any license/copyright for it.
>
> Since the TiddlyWiki will be distributed by the sponsor as part of the
> materials for the course, I need to be able to satisfy them that I
> have the right to redistribute the plugin as part of the course book.
>
> Also I plan on releasing the TiddlyWiki Coursebook for others to use
> and as a result it would include a copy of your plugin.
>
> Do I have your permission to redistribute the plugin?
>
> Thank you for your time.
>
}}}

!! DisplayOpenTiddlersPlugin

{{{
Date:    Wed, 26 Aug 2009 14:15:19 -0000
To:      rouilj@[[redacted]]

From:    shadowman131 at comcast dot net
Subject: Re: Right to redistribute the DisplayOpenTiddlersPlugin

------=_Part_192496_151585835.1251296119472
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 7bit

Hi John, 

You have absolute permission to distribute/modify DisplayOpenTiddlersPlugin as
much as you like. It was very kind of you to ask. Let me know if you happen to
need anything else.

Thanks, 
-Walt 

----- Original Message ----- 
From: "John P. Rouillard" <rouilj at cs.umb.edu> 
To: shadowman131 at comcast dot .net 
Sent: Monday, August 24, 2009 8:48:37 PM GMT -08:00 US/Canada Pacific 
Subject: Right to redistribute the DisplayOpenTiddlersPlugin 

Hello Mr. Woods: 

I am developing a TiddlyWiki for use in a class I am teaching. I 
would like to include your DisplayOpenTiddlersPlugin plugin, however I 
am unable to find any license/copyright for it. 

Since the tiddlywiki will be distributed by the sponsor as part of the 
materials for the course, I need to be able to satisfy them that I 
have the right to redistribute the plugin as part of the course book. 

Also I plan on releasing the TiddlyWiki Coursebook for other to use 
and as a result it would include a copy of your plugin. 

Do I have your permission to redistribute the plugin? 

Thank you for your time. 

Sincerely yours, 

-- 
-- rouilj 
John Rouillard 
}}}
This course has:
<html>
<hide linebreaks>
<ul>
<li class="overlay1">Presentations - instructor led slide shows</li>
<li class="overlay2">Chapters - additional contents that extends the presentations and reference material</li>
<li class="overlay3">Quizzes - usually included in the chapters, these test your knowledge of the material</li>
</ul>
</html>
{{overlay4 {
All three are accessible from the left hand menu
}}}
In normal mode coursebook has a three column layout:
* left - the MainMenu has links to the major components of the coursebook
* center - called the story column (or just story) contains the tiddlers for reading
* right - controls to search, jump to tiddlers, save configure and get additional info

@@display: block;text-align: center;[img(75%,)[Frontscreen.png]]@@

In presentation (slide show) mode the three columns are reduced to one and a slide is shown full screen.
[[ToolIndex]]
[[Welcome]]
The tiddlers marked with DeletedTiddler have been superseded by other tiddlers. To cleanup your coursebook, delete them.

If there are any tiddlers you need to delete, there will be a grey box marked "tagging" on the top left (not to be confused with the "tags" box on the right). You can go through each tiddler and find out why it was deleted and preserve any notes you may have for that tiddler before you delete it.

The following link will delete them automatically, it can not be undone, you will have to reload this tiddlywiki before saving or go to backups to recover the tiddlers.

<script label="Remove the tiddlers marked with DeletedTiddlers">
var tids=store.getTaggedTiddlers('DeletedTiddler'); for (var t=0; t<tids.length; t++) store.deleteTiddler(tids[t].title);
displayMessage('Deleted ' + tids.length + ' tiddlers.');
</script>

After deleting the tiddlers, you need to save the coursebook using the ''save changes'' link in the right hand sidebar. Note that there may not be any indication that the coursebook has changed.

/***
|Name|DisplayOpenTiddlersPlugin|
|Location|http://www.orst.edu/~woodswa/tiddlywikiplugs.html|
|Version|1.0|
|Author|Walt Woods|
|Requirements||

!Description
Displays similar to the popular BreadCrumbsPlugin by AlanHecht, this plugin instead keeps a list of currently open tiddlers.

!History
09-06-2009: JohnRouillard modified seperator between items on tiddler line.
08-06-2007: Initial version.

!Code
***/
//{{{
version.extensions.DisplayOpenTiddlers = {major: 1, minor: 0, revision: 0};

function addOpenTiddlerLine(title, element)
{
 if (title != openTiddlerClosing)
 {
  if (tiddlerLine != "")
   tiddlerLine += " &bull; ";
  tiddlerLine += "[[" + title + "]]";
 }
}

function refreshOpenTiddlersList()
{
 if (!document.getElementById("openTiddlers")) {
  var ta = document.createElement("div");
  ta.id = "openTiddlers";
  ta.style.visibility= "hidden";
  var targetArea = document.getElementById("tiddlerDisplay")||document.getElementById("storyDisplay");
  targetArea.parentNode.insertBefore(ta,targetArea);
 }

 var tiddlers = document.getElementById("openTiddlers");
 tiddlers.style.visibility = "visible";
 removeChildren(tiddlers);
 
 tiddlerLine = "";
 story.forEachTiddler(addOpenTiddlerLine);
 wikify(tiddlerLine,tiddlers)
}

Story.prototype.displayTiddlerDisplayOpenTiddlers = Story.prototype.displayTiddler;
Story.prototype.displayTiddler = function(srcElement,title,template,animate,slowly)
{
 this.displayTiddlerDisplayOpenTiddlers(srcElement,title,template,animate,slowly);
 openTiddlerClosing = "";
 refreshOpenTiddlersList();
}

Story.prototype.closeTiddlerDisplayOpenTiddlers = Story.prototype.closeTiddler;
Story.prototype.closeTiddler = function(title,animate,unused)
{
 this.closeTiddlerDisplayOpenTiddlers(title,animate,unused);
 openTiddlerClosing = title;
 refreshOpenTiddlersList();
}
//}}}
<html>
<hide linebreaks>
<ul>
<li>It's still a beta tool</li>
<li class="overlay1">Single user tool. No collaborative editing.</li>
<li class="overlay2">Formatting is annoying</li>
<li class="overlay3">Printing takes some trial and error</li>
<li class="overlay4">Have to pay attention to the pointer location when generating new items or draging/dropping.</li>
</ul>
</html>
<html>
<hide linebreaks>
<ul>
<li>Logbook - make text immutable immediately or after some period of time</li>
<li class="overlay1">Simple Blogging Platform - supports user registration and validation via email</li>
<li class="overlay2">Basic bug tracker - define fields for severity, state etc.</li>
<li class="overlay3">Small Database - Define fields for items</li>
<li class="overlay4">Personal Notebook - consider it blogging on a stick</li>
<li class="overlay5">File distribution - attach files to notes for other to grab</li>
</ul>
</html>
[[ELOG|https://midas.psi.ch/elog/]] was designed as an online log book for the ~PiBeta  and Mugamma particle experiments at  PSI.

It can be downloaded from: https://midas.psi.ch/elog/download.html or http://sourceforge.net/projects/elog/.
[[Elog in the Beginning]]
[[Elog Use Cases]]
[[Getting It Running]]
[[Demo]]
[[Some Features]]
/***
|Name|ExportTiddlersPlugin|
|Source|http://www.TiddlyTools.com/#ExportTiddlersPlugin|
|Documentation|http://www.TiddlyTools.com/#ExportTiddlersPluginInfo|
|Version|2.9.4|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|interactively select/export tiddlers to a separate file|
!!!!!Documentation
>see [[ExportTiddlersPluginInfo]]
!!!!!Inline control panel (live):
><<exportTiddlers inline>>
!!!!!Revisions
<<<
2009.09.12 [2.9.4] fixed 'return false' to prevent IE page transitions
2009.07.06 [2.9.3] moved HTML to section for size reduction
|please see [[ExportTiddlersPluginInfo]] for additional revision details|
2005.10.09 [0.0.0] development started
<<<
!!!!!Code
***/
//{{{
// version
version.extensions.ExportTiddlersPlugin= {major: 2, minor: 9, revision: 4, date: new Date(2009,9,12)};

// default shadow definition
config.shadowTiddlers.ExportTiddlers='<<exportTiddlers inline>>';

// add 'export' backstage task (following built-in import task)
if (config.tasks) { // TW2.2 or above
	config.tasks.exportTask = {
		text:'export',
		tooltip:'Export selected tiddlers to another file',
		content:'<<exportTiddlers inline>>'
	}
	config.backstageTasks.splice(config.backstageTasks.indexOf('importTask')+1,0,'exportTask');
}

config.macros.exportTiddlers = {
	$: function(id) { return document.getElementById(id); }, // abbreviation
	label: 'export tiddlers',
	prompt: 'Copy selected tiddlers to an export document',
	okmsg: '%0 tiddlers written to %1',
	failmsg: 'An error occurred while creating %1',
	mergeprompt: '%0\nalready contains tiddlers.\n'
		+'\nPress OK to merge new/revised tiddlers into existing file.'
		+'\nor, press Cancel to completely replace the file contents',
	mergestatus: 'Merged %0 new/revised tiddlers with %1 previously saved tiddlers',
	statusmsg: '%0 tiddler%1 - %2 selected for export',
	newdefault: 'export.html',
	datetimefmt: '0MM/0DD/YYYY 0hh:0mm:0ss',  // for 'filter date/time' edit fields
	type_TW: "tw", type_PS: "ps", type_TX: "tx", type_CS: "cs", type_NF: "nf", // file type tokens
	type_map: { // maps type param to token values
		tiddlywiki:"tw", tw:"tw", wiki: "tw",
		purestore: "ps", ps:"ps", store:"ps",
		plaintext: "tx", tx:"tx", text: "tx",
		comma:     "cs", cs:"cs", csv:  "cs",
		newsfeed:  "nf", nf:"nf", xml:  "nf", rss:"nf"
	},
	handler: function(place,macroName,params) {
		if (params[0]!='inline')
			{ createTiddlyButton(place,this.label,this.prompt,this.togglePanel); return; }
		var panel=this.createPanel(place);
		panel.style.position='static';
		panel.style.display='block';
	},
	createPanel: function(place) {
		var panel=this.$('exportPanel');
		if (panel) { panel.parentNode.removeChild(panel); }
		setStylesheet(store.getTiddlerText('ExportTiddlersPlugin##css',''),'exportTiddlers');
		panel=createTiddlyElement(place,'span','exportPanel',null,null)
		panel.innerHTML=store.getTiddlerText('ExportTiddlersPlugin##html','');
		this.initFilter();
		this.refreshList(0);
		var fn=this.$('exportFilename');
		if (window.location.protocol=='file:' && !fn.value.length) {
			// get new target path/filename
			var newPath=getLocalPath(window.location.href);
			var slashpos=newPath.lastIndexOf('/'); if (slashpos==-1) slashpos=newPath.lastIndexOf('\\'); 
			if (slashpos!=-1) newPath=newPath.substr(0,slashpos+1); // trim filename
			fn.value=newPath+this.newdefault;
		}
		return panel;
	},
	togglePanel: function(e) { var e=e||window.event;
		var cme=config.macros.exportTiddlers; // abbrev
		var parent=resolveTarget(e).parentNode;
		var panel=cme.$('exportPanel');
		if (panel==undefined || panel.parentNode!=parent)
			panel=cme.createPanel(parent);
		var isOpen=panel.style.display=='block';
		if(config.options.chkAnimate)
			anim.startAnimating(new Slider(panel,!isOpen,e.shiftKey || e.altKey,'none'));
		else
			panel.style.display=isOpen?'none':'block' ;
		if (panel.style.display!='none') {
			cme.refreshList(0);
			cme.$('exportFilename').focus(); 
			cme.$('exportFilename').select();
		}
		e.cancelBubble = true; if (e.stopPropagation) e.stopPropagation(); return(false);
	},
	process: function(which) { // process panel control interactions
		var theList=this.$('exportList'); if (!theList) return false;
		var count = 0;
		var total = store.getTiddlers('title').length;
		switch (which.id) {
			case 'exportFilter':
				count=this.filterExportList();
				var panel=this.$('exportFilterPanel');
				if (count==-1) { panel.style.display='block'; break; }
				this.$('exportStart').disabled=(count==0);
				this.$('exportDelete').disabled=(count==0);
				this.displayStatus(count,total);
				if (count==0) { alert('No tiddlers were selected'); panel.style.display='block'; }
				break;
			case 'exportStart':
				this.go();
				break;
			case 'exportDelete':
				this.deleteTiddlers();
				break;
			case 'exportHideFilter':
			case 'exportToggleFilter':
				var panel=this.$('exportFilterPanel')
				panel.style.display=(panel.style.display=='block')?'none':'block';
				break;
			case 'exportSelectChanges':
				var lastmod=new Date(document.lastModified);
				for (var t = 0; t < theList.options.length; t++) {
					if (theList.options[t].value=='') continue;
					var tiddler=store.getTiddler(theList.options[t].value); if (!tiddler) continue;
					theList.options[t].selected=(tiddler.modified>lastmod);
					count += (tiddler.modified>lastmod)?1:0;
				}
				this.$('exportStart').disabled=(count==0);
				this.$('exportDelete').disabled=(count==0);
				this.displayStatus(count,total);
				if (count==0) alert('There are no unsaved changes');
				break;
			case 'exportSelectAll':
				for (var t = 0; t < theList.options.length; t++) {
					if (theList.options[t].value=='') continue;
					theList.options[t].selected=true;
					count += 1;
				}
				this.$('exportStart').disabled=(count==0);
				this.$('exportDelete').disabled=(count==0);
				this.displayStatus(count,count);
				break;
			case 'exportSelectOpened':
				for (var t=0; t<theList.options.length; t++) theList.options[t].selected=false;
				var tiddlerDisplay=this.$('tiddlerDisplay');
				for (var t=0; t<tiddlerDisplay.childNodes.length;t++) {
					var tiddler=tiddlerDisplay.childNodes[t].id.substr(7);
					for (var i=0; i<theList.options.length; i++) {
						if (theList.options[i].value!=tiddler) continue;
						theList.options[i].selected=true; count++; break;
					}
				}
				this.$('exportStart').disabled=(count==0);
				this.$('exportDelete').disabled=(count==0);
				this.displayStatus(count,total);
				if (count==0) alert('There are no tiddlers currently opened');
				break;
			case 'exportSelectRelated':
				// recursively build list of related tiddlers
				function getRelatedTiddlers(tid,tids) {
					var t=store.getTiddler(tid); if (!t || tids.contains(tid)) return tids;
					tids.push(t.title);
					if (!t.linksUpdated) t.changed();
					for (var i=0; i<t.links.length; i++)
						if (t.links[i]!=tid) tids=getRelatedTiddlers(t.links[i],tids);
					return tids;
				}
				// for all currently selected tiddlers, gather up the related tiddlers (including self) and select them as well
				var tids=[];
				for (var i=0; i<theList.options.length; i++)
					if (theList.options[i].selected) tids=getRelatedTiddlers(theList.options[i].value,tids);
				// select related tiddlers (includes original selected tiddlers)
				for (var i=0; i<theList.options.length; i++)
					theList.options[i].selected=tids.contains(theList.options[i].value);
				this.displayStatus(tids.length,total);
				break;
			case 'exportListSmaller':	// decrease current listbox size
				var min=5;
				theList.size-=(theList.size>min)?1:0;
				break;
			case 'exportListLarger':	// increase current listbox size
				var max=(theList.options.length>25)?theList.options.length:25;
				theList.size+=(theList.size<max)?1:0;
				break;
			case 'exportClose':
				this.$('exportPanel').style.display='none';
				break;
		}
		return false;
	},
	displayStatus: function(count,total) {
		var txt=this.statusmsg.format([total,total!=1?'s':'',!count?'none':count==total?'all':count]);
		clearMessage();	displayMessage(txt);
		return txt;
	},
	refreshList: function(selectedIndex) {
		var theList = this.$('exportList'); if (!theList) return;
		// get the sort order
		var sort;
		if (!selectedIndex)   selectedIndex=0;
		if (selectedIndex==0) sort='modified';
		if (selectedIndex==1) sort='title';
		if (selectedIndex==2) sort='modified';
		if (selectedIndex==3) sort='modifier';
		if (selectedIndex==4) sort='tags';

		// unselect headings and count number of tiddlers actually selected
		var count=0;
		for (var t=5; t < theList.options.length; t++) {
			if (!theList.options[t].selected) continue;
			if (theList.options[t].value!='')
				count++;
			else { // if heading is selected, deselect it, and then select and count all in section
				theList.options[t].selected=false;
				for ( t++; t<theList.options.length && theList.options[t].value!=''; t++) {
					theList.options[t].selected=true;
					count++;
				}
			}
		}

		// disable 'export' and 'delete' buttons if no tiddlers selected
		this.$('exportStart').disabled=(count==0);
		this.$('exportDelete').disabled=(count==0);

		// show selection count
		var tiddlers = store.getTiddlers('title');
		if (theList.options.length) this.displayStatus(count,tiddlers.length);

		// if a [command] item, reload list... otherwise, no further refresh needed
		if (selectedIndex>4) return;

		// clear current list contents
		while (theList.length > 0) { theList.options[0] = null; }
		// add heading and control items to list
		var i=0;
		var indent=String.fromCharCode(160)+String.fromCharCode(160);
		theList.options[i++]=
			new Option(tiddlers.length+' tiddlers in document', '',false,false);
		theList.options[i++]=
			new Option(((sort=='title'   )?'>':indent)+' [by title]', '',false,false);
		theList.options[i++]=
			new Option(((sort=='modified')?'>':indent)+' [by date]', '',false,false);
		theList.options[i++]=
			new Option(((sort=='modifier')?'>':indent)+' [by author]', '',false,false);
		theList.options[i++]=
			new Option(((sort=='tags'    )?'>':indent)+' [by tags]', '',false,false);

		// output the tiddler list
		switch(sort) {
			case 'title':
				for(var t = 0; t < tiddlers.length; t++)
					theList.options[i++] = new Option(tiddlers[t].title,tiddlers[t].title,false,false);
				break;
			case 'modifier':
			case 'modified':
				var tiddlers = store.getTiddlers(sort);
				// sort descending for newest date first
				tiddlers.sort(function (a,b) {if(a[sort] == b[sort]) return(0); else return (a[sort] > b[sort]) ? -1 : +1; });
				var lastSection = '';
				for(var t = 0; t < tiddlers.length; t++) {
					var tiddler = tiddlers[t];
					var theSection = '';
					if (sort=='modified') theSection=tiddler.modified.toLocaleDateString();
					if (sort=='modifier') theSection=tiddler.modifier;
					if (theSection != lastSection) {
						theList.options[i++] = new Option(theSection,'',false,false);
						lastSection = theSection;
					}
					theList.options[i++] = new Option(indent+indent+tiddler.title,tiddler.title,false,false);
				}
				break;
			case 'tags':
				var theTitles = {}; // all tiddler titles, hash indexed by tag value
				var theTags = new Array();
				for(var t=0; t<tiddlers.length; t++) {
					var title=tiddlers[t].title;
					var tags=tiddlers[t].tags;
					if (!tags || !tags.length) {
						if (theTitles['untagged']==undefined) { theTags.push('untagged'); theTitles['untagged']=new Array(); }
						theTitles['untagged'].push(title);
					}
					else for(var s=0; s<tags.length; s++) {
						if (theTitles[tags[s]]==undefined) { theTags.push(tags[s]); theTitles[tags[s]]=new Array(); }
						theTitles[tags[s]].push(title);
					}
				}
				theTags.sort();
				for(var tagindex=0; tagindex<theTags.length; tagindex++) {
					var theTag=theTags[tagindex];
					theList.options[i++]=new Option(theTag,'',false,false);
					for(var t=0; t<theTitles[theTag].length; t++)
						theList.options[i++]=new Option(indent+indent+theTitles[theTag][t],theTitles[theTag][t],false,false);
				}
				break;
			}
		theList.selectedIndex=selectedIndex; // select current control item
		this.$('exportStart').disabled=true;
		this.$('exportDelete').disabled=true;
		this.displayStatus(0,tiddlers.length);
	},
	askForFilename: function(here) {
		var msg=here.title; // use tooltip as dialog box message
		var path=getLocalPath(document.location.href);
		var slashpos=path.lastIndexOf('/'); if (slashpos==-1) slashpos=path.lastIndexOf('\\'); 
		if (slashpos!=-1) path = path.substr(0,slashpos+1); // remove filename from path, leave the trailing slash
		var filetype=this.$('exportFormat').value.toLowerCase();
		var defext='html';
		if (filetype==this.type_TX) defext='txt';
		if (filetype==this.type_CS) defext='csv';
		if (filetype==this.type_NF) defext='xml';
		var file=this.newdefault.replace(/html$/,defext);
		var result='';
		if(window.Components) { // moz
			try {
				netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
				var nsIFilePicker = window.Components.interfaces.nsIFilePicker;
				var picker = Components.classes['@mozilla.org/filepicker;1'].createInstance(nsIFilePicker);
				picker.init(window, msg, nsIFilePicker.modeSave);
				var thispath = Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsILocalFile);
				thispath.initWithPath(path);
				picker.displayDirectory=thispath;
				picker.defaultExtension=defext;
				picker.defaultString=file;
				picker.appendFilters(nsIFilePicker.filterAll|nsIFilePicker.filterText|nsIFilePicker.filterHTML);
				if (picker.show()!=nsIFilePicker.returnCancel) var result=picker.file.persistentDescriptor;
			}
			catch(e) { alert('error during local file access: '+e.toString()) }
		}
		else { // IE
			try { // XPSP2 IE only
				var s = new ActiveXObject('UserAccounts.CommonDialog');
				s.Filter='All files|*.*|Text files|*.txt|HTML files|*.htm;*.html|XML files|*.xml|';
				s.FilterIndex=defext=='txt'?2:'html'?3:'xml'?4:1;
				s.InitialDir=path;
				s.FileName=file;
				if (s.showOpen()) var result=s.FileName;
			}
			catch(e) {  // fallback
				var result=prompt(msg,path+file);
			}
		}
		return result;
	},
	initFilter: function() {
		this.$('exportFilterStart').checked=false; this.$('exportStartDate').value='';
		this.$('exportFilterEnd').checked=false;  this.$('exportEndDate').value='';
		this.$('exportFilterTags').checked=false; this.$('exportTags').value='';
		this.$('exportFilterText').checked=false; this.$('exportText').value='';
		this.showFilterFields();
	},
	showFilterFields: function(which) {
		var show=this.$('exportFilterStart').checked;
		this.$('exportFilterStartBy').style.display=show?'block':'none';
		this.$('exportStartDate').style.display=show?'block':'none';
		var val=this.$('exportFilterStartBy').value;
		this.$('exportStartDate').value
			=this.getFilterDate(val,'exportStartDate').formatString(this.datetimefmt);
		if (which && (which.id=='exportFilterStartBy') && (val=='other'))
			this.$('exportStartDate').focus();

		var show=this.$('exportFilterEnd').checked;
		this.$('exportFilterEndBy').style.display=show?'block':'none';
		this.$('exportEndDate').style.display=show?'block':'none';
		var val=this.$('exportFilterEndBy').value;
		this.$('exportEndDate').value
			=this.getFilterDate(val,'exportEndDate').formatString(this.datetimefmt);
		 if (which && (which.id=='exportFilterEndBy') && (val=='other'))
			this.$('exportEndDate').focus();

		var show=this.$('exportFilterTags').checked;
		this.$('exportTags').style.display=show?'block':'none';

		var show=this.$('exportFilterText').checked;
		this.$('exportText').style.display=show?'block':'none';
	},
	getFilterDate: function(val,id) {
		var result=0;
		switch (val) {
			case 'file':
				result=new Date(document.lastModified);
				break;
			case 'other':
				result=new Date(this.$(id).value);
				break;
			default: // today=0, yesterday=1, one week=7, two weeks=14, a month=31
				var now=new Date(); var tz=now.getTimezoneOffset()*60000; now-=tz;
				var oneday=86400000;
				if (id=='exportStartDate')
					result=new Date((Math.floor(now/oneday)-val)*oneday+tz);
				else
					result=new Date((Math.floor(now/oneday)-val+1)*oneday+tz-1);
				break;
		}
		return result;
	},
	filterExportList: function() {
		var theList  = this.$('exportList'); if (!theList) return -1;
		var filterStart=this.$('exportFilterStart').checked;
		var val=this.$('exportFilterStartBy').value;
		var startDate=config.macros.exportTiddlers.getFilterDate(val,'exportStartDate');
		var filterEnd=this.$('exportFilterEnd').checked;
		var val=this.$('exportFilterEndBy').value;
		var endDate=config.macros.exportTiddlers.getFilterDate(val,'exportEndDate');
		var filterTags=this.$('exportFilterTags').checked;
		var tags=this.$('exportTags').value;
		var filterText=this.$('exportFilterText').checked;
		var text=this.$('exportText').value;
		if (!(filterStart||filterEnd||filterTags||filterText)) {
			alert('Please set the selection filter');
			this.$('exportFilterPanel').style.display='block';
			return -1;
		}
		if (filterStart&&filterEnd&&(startDate>endDate)) {
			var msg='starting date/time:\n'
			msg+=startDate.toLocaleString()+'\n';
			msg+='is later than ending date/time:\n'
			msg+=endDate.toLocaleString()
			alert(msg);
			return -1;
		}
		// if filter by tags, get list of matching tiddlers
		// use getMatchingTiddlers() (if MatchTagsPlugin is installed) for full boolean expressions
		// otherwise use getTaggedTiddlers() for simple tag matching
		if (filterTags) {
			var fn=store.getMatchingTiddlers||store.getTaggedTiddlers;
			var t=fn.apply(store,[tags]);
			var tagged=[];
			for (var i=0; i<t.length; i++) tagged.push(t[i].title);
		}
		// scan list and select tiddlers that match all applicable criteria
		var total=0;
		var count=0;
		for (var i=0; i<theList.options.length; i++) {
			// get item, skip non-tiddler list items (section headings)
			var opt=theList.options[i]; if (opt.value=='') continue;
			// get tiddler, skip missing tiddlers (this should NOT happen)
			var tiddler=store.getTiddler(opt.value); if (!tiddler) continue; 
			var sel=true;
			if ( (filterStart && tiddler.modified<startDate)
			|| (filterEnd && tiddler.modified>endDate)
			|| (filterTags && !tagged.contains(tiddler.title))
			|| (filterText && (tiddler.text.indexOf(text)==-1) && (tiddler.title.indexOf(text)==-1)))
				sel=false;
			opt.selected=sel;
			count+=sel?1:0;
			total++;
		}
		return count;
	},
	deleteTiddlers: function() {
		var list=this.$('exportList'); if (!list) return;
		var tids=[];
		for (i=0;i<list.length;i++)
			if (list.options[i].selected && list.options[i].value.length)
				tids.push(list.options[i].value);
		if (!confirm('Are you sure you want to delete these tiddlers:\n\n'+tids.join(', '))) return;
		store.suspendNotifications();
		for (t=0;t<tids.length;t++) {
			var tid=store.getTiddler(tids[t]); if (!tid) continue;
			var msg="'"+tid.title+"' is tagged with 'systemConfig'.\n\n";
			msg+='Removing this tiddler may cause unexpected results.  Are you sure?'
			if (tid.tags.contains('systemConfig') && !confirm(msg)) continue;
			store.removeTiddler(tid.title);
			story.closeTiddler(tid.title);
		}
		store.resumeNotifications();
		alert(tids.length+' tiddlers deleted');
		this.refreshList(0); // reload listbox
		store.notifyAll(); // update page display
	},
	go: function() {
		if (window.location.protocol!='file:') // make sure we are local
			{ displayMessage(config.messages.notFileUrlError); return; }
		// get selected tidders, target filename, target type, and notes
		var list=this.$('exportList'); if (!list) return;
		var tids=[]; for (var i=0; i<list.options.length; i++) {
			var opt=list.options[i]; if (!opt.selected||!opt.value.length) continue;
			var tid=store.getTiddler(opt.value); if (!tid) continue;
			tids.push(tid);
		}
		if (!tids.length) return; // no tiddlers selected
		var target=this.$('exportFilename').value.trim();
		if (!target.length) {
			displayMessage('A local target path/filename is required',target);
			return;
		}
		var filetype=this.$('exportFormat').value.toLowerCase();
		var notes=this.$('exportNotes').value.replace(/\n/g,'<br>');
		var total={val:0};
		var out=this.assembleFile(target,filetype,tids,notes,total);
		var link='file:///'+target.replace(/\\/g,'/');
		var samefile=link==decodeURIComponent(window.location.href);
		var p=getLocalPath(document.location.href);
		if (samefile) {
			if (config.options.chkSaveBackups) { var t=loadOriginal(p);if(t)saveBackup(p,t); }
			if (config.options.chkGenerateAnRssFeed && saveRss instanceof Function) saveRss(p);
		}
		var ok=saveFile(target,out);
		displayMessage((ok?this.okmsg:this.failmsg).format([total.val,target]),link);
	},
	plainTextHeader:
		 'Source:\n\t%0\n'
		+'Title:\n\t%1\n'
		+'Subtitle:\n\t%2\n'
		+'Created:\n\t%3 by %4\n'
		+'Application:\n\tTiddlyWiki %5 / %6 %7\n\n',
	plainTextTiddler:
		'- - - - - - - - - - - - - - -\n'
		+'|     title: %0\n'
		+'|   created: %1\n'
		+'|  modified: %2\n'
		+'| edited by: %3\n'
		+'|      tags: %4\n'
		+'- - - - - - - - - - - - - - -\n'
		+'%5\n',
	plainTextFooter:
		'',
	newsFeedHeader:
		 '<'+'?xml version="1.0"?'+'>\n'
		+'<rss version="2.0">\n'
		+'<channel>\n'
		+'<title>%1</title>\n'
		+'<link>%0</link>\n'
		+'<description>%2</description>\n'
		+'<language>en-us</language>\n'
		+'<copyright>Copyright '+(new Date().getFullYear())+' %4</copyright>\n'
		+'<pubDate>%3</pubDate>\n'
		+'<lastBuildDate>%3</lastBuildDate>\n'
		+'<docs>http://blogs.law.harvard.edu/tech/rss</docs>\n'
		+'<generator>TiddlyWiki %5 / %6 %7</generator>\n',
	newsFeedTiddler:
		'\n%0\n',
	newsFeedFooter:
		'</channel></rss>',
	pureStoreHeader:
		 '<html><body>'
		+'<style type="text/css">'
		+'	#storeArea {display:block;margin:1em;}'
		+'	#storeArea div {padding:0.5em;margin:1em;border:2px solid black;height:10em;overflow:auto;}'
		+'	#pureStoreHeading {width:100%;text-align:left;background-color:#eeeeee;padding:1em;}'
		+'</style>'
		+'<div id="pureStoreHeading">'
		+'	TiddlyWiki "PureStore" export file<br>'
		+'	Source'+': <b>%0</b><br>'
		+'	Title: <b>%1</b><br>'
		+'	Subtitle: <b>%2</b><br>'
		+'	Created: <b>%3</b> by <b>%4</b><br>'
		+'	TiddlyWiki %5 / %6 %7<br>'
		+'	Notes:<hr><pre>%8</pre>'
		+'</div>'
		+'<div id="storeArea">',
	pureStoreTiddler:
		'%0\n%1',
	pureStoreFooter:
		'</div><!--POST-BODY-START-->\n<!--POST-BODY-END--></body></html>',
	assembleFile: function(target,filetype,tids,notes,total) {
		var revised='';
		var now = new Date().toLocaleString();
		var src=convertUnicodeToUTF8(document.location.href);
		var title = convertUnicodeToUTF8(wikifyPlain('SiteTitle').htmlEncode());
		var subtitle = convertUnicodeToUTF8(wikifyPlain('SiteSubtitle').htmlEncode());
		var user = convertUnicodeToUTF8(config.options.txtUserName.htmlEncode());
		var twver = version.major+'.'+version.minor+'.'+version.revision;
		var v=version.extensions.ExportTiddlersPlugin; var pver = v.major+'.'+v.minor+'.'+v.revision;
		var headerargs=[src,title,subtitle,now,user,twver,'ExportTiddlersPlugin',pver,notes];
		switch (filetype) {
			case this.type_TX: // plain text
				var header=this.plainTextHeader.format(headerargs);
				var footer=this.plainTextFooter;
				break;
			case this.type_CS: // comma-separated
				var fields={};
				for (var i=0; i<tids.length; i++) for (var f in tids[i].fields) fields[f]=f;
				var names=['title','created','modified','modifier','tags','text'];
				for (var f in fields) names.push(f);
				var header=names.join(',')+'\n';
				var footer='';
				break;
			case this.type_NF: // news feed (XML)
				headerargs[0]=store.getTiddlerText('SiteUrl','');
				var header=this.newsFeedHeader.format(headerargs);
				var footer=this.newsFeedFooter;
				break;
			case this.type_PS: // PureStore (no code)
				var header=this.pureStoreHeader.format(headerargs);
				var footer=this.pureStoreFooter;
				break;
			case this.type_TW: // full TiddlyWiki
			default:
				var currPath=getLocalPath(window.location.href);
				var original=loadFile(currPath);
				if (!original) { displayMessage(config.messages.cantSaveError); return; }
				var posDiv = locateStoreArea(original);
				if (!posDiv) { displayMessage(config.messages.invalidFileError.format([currPath])); return; }
				var header = original.substr(0,posDiv[0]+startSaveArea.length)+'\n';
				var footer = '\n'+original.substr(posDiv[1]);
				break;
		}
		var out=this.getData(target,filetype,tids,fields);
		var revised = header+convertUnicodeToUTF8(out.join('\n'))+footer;
		// if full TW, insert page title and language attr, and reset all MARKUP blocks...
		if (filetype==this.type_TW) {
			var newSiteTitle=convertUnicodeToUTF8(getPageTitle()).htmlEncode();
			revised=revised.replaceChunk('<title'+'>','</title'+'>',' ' + newSiteTitle + ' ');
			revised=updateLanguageAttribute(revised);
			var titles=[]; for (var i=0; i<tids.length; i++) titles.push(tids[i].title);
			revised=updateMarkupBlock(revised,'PRE-HEAD',
				titles.contains('MarkupPreHead')? 'MarkupPreHead' :null);
			revised=updateMarkupBlock(revised,'POST-HEAD',
				titles.contains('MarkupPostHead')?'MarkupPostHead':null);
			revised=updateMarkupBlock(revised,'PRE-BODY',
				titles.contains('MarkupPreBody')? 'MarkupPreBody' :null);
			revised=updateMarkupBlock(revised,'POST-SCRIPT',
				titles.contains('MarkupPostBody')?'MarkupPostBody':null);
		}
		total.val=out.length;
		return revised;
	},
	getData: function(target,filetype,tids,fields) {
		// output selected tiddlers and gather list of titles (for use with merge)
		var out=[]; var titles=[];
		var url=store.getTiddlerText('SiteUrl','');
		for (var i=0; i<tids.length; i++) {
			out.push(this.formatItem(store,filetype,tids[i],url,fields));
			titles.push(tids[i].title);
		}
		// if TW or PureStore format, ask to merge with existing tiddlers (if any)
		if (filetype==this.type_TW || filetype==this.type_PS) {
			var txt=loadFile(target);
			if (txt && txt.length) {
				var remoteStore=new TiddlyWiki();
				if (version.major+version.minor*.1+version.revision*.01<2.52) txt=convertUTF8ToUnicode(txt);
				if (remoteStore.importTiddlyWiki(txt) && confirm(this.mergeprompt.format([target]))) {
					var existing=remoteStore.getTiddlers('title');
					for (var i=0; i<existing.length; i++)
						if (!titles.contains(existing[i].title))
							out.push(this.formatItem(remoteStore,filetype,existing[i],url));
					displayMessage(this.mergestatus.format([tids.length,out.length-tids.length]));
				}
			}
		}
		return out;
	},
	formatItem: function(s,f,t,u,fields) {
		if (f==this.type_TW)
			var r=s.getSaver().externalizeTiddler(s,t);
		if (f==this.type_PS)
			var r=this.pureStoreTiddler.format([t.title,s.getSaver().externalizeTiddler(s,t)]);
		if (f==this.type_NF)
			var r=this.newsFeedTiddler.format([t.saveToRss(u)]);
		if (f==this.type_TX)
			var r=this.plainTextTiddler.format([t.title, t.created.toLocaleString(), t.modified.toLocaleString(),
				t.modifier, String.encodeTiddlyLinkList(t.tags), t.text]);
		if (f==this.type_CS) {
			function toCSV(t) { return '"'+t.replace(/"/g,'""')+'"'; } // always encode CSV
			var out=[ toCSV(t.title), toCSV(t.created.toLocaleString()), toCSV(t.modified.toLocaleString()),
				toCSV(t.modifier), toCSV(String.encodeTiddlyLinkList(t.tags)), toCSV(t.text) ];
			for (var f in fields) out.push(toCSV(t.fields[f]||''));
			var r=out.join(',');
		}
		return r||"";
	}
}
//}}}
/***
!!!Control panel CSS
//{{{
!css
#exportPanel {
	display: none; position:absolute; z-index:12; width:35em; right:105%; top:6em;
	background-color: #eee; color:#000; font-size: 8pt; line-height:110%;
	border:1px solid black; border-bottom-width: 3px; border-right-width: 3px;
	padding: 0.5em; margin:0em; -moz-border-radius:1em;-webkit-border-radius:1em;
}
#exportPanel a, #exportPanel td a { color:#009; display:inline; margin:0px; padding:1px; }
#exportPanel table {
	width:100%; border:0px; padding:0px; margin:0px;
	font-size:8pt; line-height:110%; background:transparent;
}
#exportPanel tr { border:0px;padding:0px;margin:0px; background:transparent; }
#exportPanel td { color:#000; border:0px;padding:0px;margin:0px; background:transparent; }
#exportPanel select { width:98%;margin:0px;font-size:8pt;line-height:110%;}
#exportPanel input  { width:98%;padding:0px;margin:0px;font-size:8pt;line-height:110%; }
#exportPanel textarea  { width:98%;padding:0px;margin:0px;overflow:auto;font-size:8pt; }
#exportPanel .box {
	border:1px solid black; padding:3px; margin-bottom:5px;
	background:#f8f8f8; -moz-border-radius:5px;-webkit-border-radius:5px; }
#exportPanel .topline { border-top:2px solid black; padding-top:3px; margin-bottom:5px; }
#exportPanel .rad { width:auto;border:0 }
#exportPanel .chk { width:auto;border:0 }
#exportPanel .btn { width:auto; }
#exportPanel .btn1 { width:98%; }
#exportPanel .btn2 { width:48%; }
#exportPanel .btn3 { width:32%; }
#exportPanel .btn4 { width:24%; }
#exportPanel .btn5 { width:19%; }
!end
//}}}
!!!Control panel HTML
//{{{
!html
<!-- target path/file  -->
<div>
export to path/filename:<br>
<input type="text" id="exportFilename" size=40 style="width:93%"><input 
	type="button" id="exportBrowse" value="..." title="select or enter a local folder/file..." style="width:5%" 
	onclick="var fn=config.macros.exportTiddlers.askForFilename(this); if (fn.length) this.previousSibling.value=fn; ">
</div>

<!-- output format -->
<div>
output file format:
<select id="exportFormat" size=1>
	<option value="TW">TiddlyWiki HTML document (includes core code)</option>
	<option value="PS">TiddlyWiki "PureStore" HTML file (tiddler data only)</option>
	<option value="TX">TiddlyWiki plain text TXT file (tiddler source listing)</option>
	<option value="CS">Comma-Separated Value (CSV) data file</option>
	<option value="NF">RSS NewsFeed XML file</option>
</select>
</div>

<!-- notes -->
<div>
notes:<br>
<textarea id="exportNotes" rows=3 cols=40 style="height:4em;margin-bottom:5px;" onfocus="this.select()"></textarea> 
</div>

<!-- list of tiddlers -->
<table><tr align="left"><td>
	select:
	<a href="JavaScript:;" id="exportSelectAll"
		onclick="return config.macros.exportTiddlers.process(this)" title="select all tiddlers">
		&nbsp;all&nbsp;</a>
	<a href="JavaScript:;" id="exportSelectChanges"
		onclick="return config.macros.exportTiddlers.process(this)" title="select tiddlers changed since last save">
		&nbsp;changes&nbsp;</a>
	<a href="JavaScript:;" id="exportSelectOpened"
		onclick="return config.macros.exportTiddlers.process(this)" title="select tiddlers currently being displayed">
		&nbsp;opened&nbsp;</a>
	<a href="JavaScript:;" id="exportSelectRelated"
		onclick="return config.macros.exportTiddlers.process(this)" title="select tiddlers related to the currently selected tiddlers">
		&nbsp;related&nbsp;</a>
	<a href="JavaScript:;" id="exportToggleFilter"
		onclick="return config.macros.exportTiddlers.process(this)" title="show/hide selection filter">
		&nbsp;filter&nbsp;</a>
</td><td align="right">
	<a href="JavaScript:;" id="exportListSmaller"
		onclick="return config.macros.exportTiddlers.process(this)" title="reduce list size">
		&nbsp;&#150;&nbsp;</a>
	<a href="JavaScript:;" id="exportListLarger"
		onclick="return config.macros.exportTiddlers.process(this)" title="increase list size">
		&nbsp;+&nbsp;</a>
</td></tr></table>
<select id="exportList" multiple size="10" style="margin-bottom:5px;"
	onchange="config.macros.exportTiddlers.refreshList(this.selectedIndex)">
</select><br>

<!-- selection filter -->
<div id="exportFilterPanel" style="display:none">
<table><tr align="left"><td>
	selection filter
</td><td align="right">
	<a href="JavaScript:;" id="exportHideFilter"
		onclick="return config.macros.exportTiddlers.process(this)" title="hide selection filter">hide</a>
</td></tr></table>
<div class="box">

<input type="checkbox" class="chk" id="exportFilterStart" value="1"
	onclick="config.macros.exportTiddlers.showFilterFields(this)"> starting date/time<br>
<table cellpadding="0" cellspacing="0"><tr valign="center"><td width="50%">
	<select size=1 id="exportFilterStartBy"
		onchange="config.macros.exportTiddlers.showFilterFields(this);">
		<option value="0">today</option>
		<option value="1">yesterday</option>
		<option value="7">a week ago</option>
		<option value="30">a month ago</option>
		<option value="file">file date</option>
		<option value="other">other (mm/dd/yyyy hh:mm)</option>
	</select>
</td><td width="50%">
	<input type="text" id="exportStartDate" onfocus="this.select()"
		onchange="config.macros.exportTiddlers.$('exportFilterStartBy').value='other';">
</td></tr></table>

<input type="checkbox" class="chk" id="exportFilterEnd" value="1"
	onclick="config.macros.exportTiddlers.showFilterFields(this)"> ending date/time<br>
<table cellpadding="0" cellspacing="0"><tr valign="center"><td width="50%">
	<select size=1 id="exportFilterEndBy"
		onchange="config.macros.exportTiddlers.showFilterFields(this);">
		<option value="0">today</option>
		<option value="1">yesterday</option>
		<option value="7">a week ago</option>
		<option value="30">a month ago</option>
		<option value="file">file date</option>
		<option value="other">other (mm/dd/yyyy hh:mm)</option>
	</select>
</td><td width="50%">
	<input type="text" id="exportEndDate" onfocus="this.select()"
		onchange="config.macros.exportTiddlers.$('exportFilterEndBy').value='other';">
</td></tr></table>

<input type="checkbox" class="chk" id=exportFilterTags value="1"
	onclick="config.macros.exportTiddlers.showFilterFields(this)"> match tags<br>
<input type="text" id="exportTags" onfocus="this.select()">

<input type="checkbox" class="chk" id=exportFilterText value="1"
	onclick="config.macros.exportTiddlers.showFilterFields(this)"> match titles/tiddler text<br>
<input type="text" id="exportText" onfocus="this.select()">

</div> <!--box-->
</div> <!--panel-->

<!-- action buttons -->
<div style="text-align:center">
<input type=button class="btn4" onclick="config.macros.exportTiddlers.process(this)"
	id="exportFilter" value="apply filter">
<input type=button class="btn4" onclick="config.macros.exportTiddlers.process(this)"
	id="exportStart" value="export tiddlers">
<input type=button class="btn4" onclick="config.macros.exportTiddlers.process(this)"
	id="exportDelete" value="delete tiddlers">
<input type=button class="btn4" onclick="config.macros.exportTiddlers.process(this)"
	id="exportClose" value="close">
</div><!--center-->
!end
//}}}
***/
 
/***
|Name|ExportTiddlersPluginInfo|
|Source|http://www.TiddlyTools.com/#ExportTiddlersPlugin|
|Documentation|http://www.TiddlyTools.com/#ExportTiddlersPluginInfo|
|Version|2.9.3|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|documentation|
|Requires||
|Overrides||
|Description|Documentation for ExportTiddlersPlugin|
interactively select and extract tiddlers from your ~TiddlyWiki document, and write them into another file, using one of several different file formats:
* ~TiddlyWiki - a complete, stand-alone, standard TiddlyWiki HTML document
* ~PureStore - a small HTML archive file containing tiddler data only (no core code)
* ~PlainText - a simple TXT text file with tiddler source listings
* Comma - a "Comma Separated Value" data/spreadsheet file
* ~NewsFeed  - an XML-format file that can be published for RSS syndication.
!!!!!Usage
<<<
{{{
<<exportTiddlers>> (sidebar menu item)
<<exportTiddlers inline>> (embedded control panel)
}}}

Inline control panel (live):
<<exportTiddlers inline>>

Optional "special tiddlers" used by this plugin:
* SiteUrl<br>URL for official server-published version of document being viewed (used in XML export). Default: //none//
<<<
!!!!!Revisions
<<<
2009.07.06 [2.9.3] moved HTML to section for size reduction
2009.07.03 [2.9.2] TW252 fixup: don't call convertUTF8ToUnicode() for local loadFile() I/O
2009.04.30 [2.9.1] custom fields in CSV output
2009.04.19 [2.9.0] added CSV format
2009.02.26 [2.8.5] use macro-specific definition of $() function abbreviation (avoids conflict with JQuery)
2008.09.29 [2.8.4] in getData(), convert existing TW file from UTF8 to Unicode before merging to correct handling of international characters and symbols.
2008.09.26 [2.8.3] in go(), if rewriting *current* file and chkSaveBackups and/or chkGenerateAnRssFeed is enabled, then write a backup file or RSS feed, respectively.
2008.09.24 [2.8.2] in assembleFile(), make sure that markup block is updated if corresponding Markup* tiddler is exported.
2008.09.19 [2.8.1] in formatItem(), removed unnecessary convertUnicodeToUTF8() (was causing double-conversion!)
2008.09.11 [2.8.0] extensive code cleanup: moved all global functions inside macro object. Re-wrote file generator and I/O to support TiddlyWiki, PlainText, PureStore, and NewsFeed file formats.  Replaced inline 'match tags' code with use of getMatchingTiddlers() from [[MatchTagsPlugin]] (if installed), with fallback to core getTaggedTiddlers() otherwise.
2008.05.27 [2.7.0] added ability to 'merge' with existing export file.  Also, revised 'matchTags' functionality to be more robust and more efficient
2008.05.12 [2.6.1] automatically add 'export' task to backstage (moved from BackstageTweaks)
2008.03.10 [2.6.0] added "delete tiddlers" button
2007.12.04 [*.*.*] update for TW2.3.0: replaced deprecated core functions, regexps, and macros
2007.11.10 [2.5.1] removed debugging alert messages from promptForExportFilename()
2007.10.31 [2.5.0] code reduction: removed incomplete/unused interface and supporting functions for exporting directly to http, https or ftp servers.  Plugin now supports exporting to local file only.  Also, updated TW document output to generate TW2.2 compatible file format.
2007.10.30 [2.4.2] added automatic shadow tiddler definition for [[ExportTiddlers]]
2007.07.16 [2.4.1] in exportTWHeader(), reset HTML source 'markup' so installed markup is NOT copied to new file.
2007.06.30 [2.4.0] added "select related tiddlers" feature.  Recursively scans the tiddler links[] info to find all tiddlers referenced by any of the currently selected tiddler, and then selects them all (including the original tiddlers).
2007.04.19 [2.3.0] in exportData(), pass SiteURL value as param to saveToRss().  Fixes 'undefined' appearing in tiddler link in XML output.  Also, in refreshExportList(), added 'sort by tags'.  Also, added 'group select'... selecting a heading (date,author,tag) auto-selects all tiddlers in that group.
2007.03.02 [2.2.6] in onClickExportButton(), when selecting open tiddlers for TW2.2, look for "storyDisplay" with fallback to "tiddlerDisplay" for TW2.1 or earlier
2007.03.01 [2.2.5] removed hijack of store.saveChanges()
2006.11.08 [2.2.4] added promptForExportFilename() and replaced type="file" control with edit field + browse button ("...").
2006.10.12 [2.2.3] in exportDIVFooter(), write POST-BODY-START/END markers for compatibility with TW2.1 core file format.
2006.05.11 [2.2.2] in createExportPanel, removed call to addNotification() to reduce unneeded feedback messages and increase overall document performance.
2006.05.02 [2.2.1] Use displayMessage() to show number of selected tiddlers instead of updating listbox 'header' item after each selection.  Prevents awkward 'scroll-to-top' behavior that made multi-select via ctrl-click nearly impossible.
2006.04.29 [2.2.0] New features: free-form "Notes" text inserted in the header of PureStore files.
2006.03.29 [2.1.3] added calls to convertUnicodeToUTF8() for generated output, so it better handles international characters.
2006.02.12 [2.1.2] more FF1501 bug fixes.
2006.02.04 [2.1.1] added var to unintended globals to avoids FireFox1501 crash bug
2006.02.02 [2.1.0] Added support for output of complete TiddlyWiki documents
2006.01.21 [2.0.1] Defer initial panel creation and only register a notification function when panel first is created
in saveChanges 'hijack', create panel as needed.  Note: if window.event is not available to identify the click location, the export panel is positioned relative to the 'tiddlerDisplay' element of the TW document.
2005.12.27 [2.0.0] Update for TW2.0.
2005.12.24 [0.9.5] Minor adjustments to CSS to force correct link colors regardless of TW stylesheet selection
2005.12.16 [0.9.4] Dynamically create/remove exportPanel so only one instance exists at a time
2005.11.15 [0.9.2] added non-Ajax post to bypass cross-domain security restrictions.
2005.11.08 [0.9.1] moved HTML, CSS and control initialization into exportInit() function and call from macro handler instead of at load time.
2005.10.28 [0.9.0] added 'select opened tiddlers' feature. Based on a suggestion by Geoff Slocock
2005.10.24 [0.8.3] Corrected hijack of 'save changes' when using http:
2005.10.18 [0.8.2] added AJAX functions
2005.10.18 [0.8.1] Corrected timezone handling and error checking/reporting when filtering tiddlers. More style tweaks, minor text changes and some assorted layout cleanup.
2005.10.17 [0.8.0] First pre-release.
2005.10.16 [0.7.0] filter by tags
2005.10.15 [0.6.0] filter by title/text
2005.10.14 [0.5.0] export to local file (DIV or XML)
2005.10.14 [0.4.0] filter by start/end date
2005.10.13 [0.3.0] panel interaction
2005.10.11 [0.2.0] panel layout
2005.10.10 [0.1.0] code framework
2005.10.09 [0.0.0] development started
<<<
/%
|Description|Saving changes for online documents if the network goes down|
%/
{{small{
__Saving changes to online documents if your network connection goes down while editing__

If you have been editing a document online (e.g., using an account on http://www.TiddlySpot.com with [[UploadPlugin]]), and your internet connection has gone down while editing, it is not possible to save your changes in the usual manner because, without the internet, the remotely-stored document is //inaccessible//.

Unfortunately, you also cannot save the document locally because of security restrictions that prevent access to your local filesystem when working with a server-hosted document (i.e., viewed via http:).

Fortunately, there is a ''manual work-around that will let you 'rescue' TiddlyWiki's internal //storeArea// for the current document, including your unsaved changes to tiddler content'' by using the following command link:

{{big center{<<tiddler RescueStoreAreaCommand with: "rescue storeArea">>}}}
When clicked, this link ''opens a new window and writes a copy of the storeArea into that window.''  The content in that window is displayed as plain-text, and includes //only the storeArea DIVs that define the tiddlers, without any of the surrounding TiddlyWiki core code.//  To preserve this storeArea, ''select and copy/paste the displayed content into a local text file for safe-keeping.''

Then, to merge this 'rescued store area' with the rest of the TW core, use a plain-text editor (not the browser) to open a ''copy'' of any locally-stored TW document.  If a locally-stored TiddlyWiki document is not available, you will have to wait until your network connection has been re-established, so that you can download your TiddlyWiki document from the server, or [[obtain an empty TiddlyWiki document from http://www.TiddlyWiki.com|http://www.TiddlyWiki.com/empty.html]].

Then, find the 'storeArea' in that document, which looks like this:
{{{
<!--POST-SHADOWAREA-->
<div id="storeArea">
.... *** replace this part *** ...
</div>
<!--POST-STOREAREA-->
}}}
Select everything //inside the storeArea DIV//, and replace it with the rescued store area content, and then save the file.  If all goes well, the saved file can then be opened in your browser as a complete TW document, *with* all the saved content in place!

Note: The command link shown above may also be installed directly into your browser as an [[InstantBookmarklet|InstantBookmarklets]]. To create a bookmarklet, simply ''//drag-and-drop the command link directly onto your browser's toolbar//'' or right-click and use 'bookmark this link' (or 'add to favorites') to add the bookmarklet to your browser's bookmarks menu.  Once installed, you can use this command with //any// TiddlyWiki document, even when [[RescueStoreAreaCommand]] and [[InlineJavascriptPlugin]] have not been installed in that document!
}}}
<html>
<hide linebreaks>
<ul>
<li>Can remap keys to make entering data easier</li>
<li class="overlay1">Generally easy to work with after a little experience</li>
<li class="overlay2">Drag and drop reordering of nodes/branches</li>
<li class="overlay3">Exports to a number of formats: png, pdf, html (foldable/clickable), flash, ODF, java applet ... (13 in all)</li>
<li class="overlay4">Map is stored in XML format</li>
</ul>
</html>
<html>
<hide linebreaks>
<ul>
<li>Easier to use than M4</li>
<li class="overlay1">Doesn't leave messy blank lines and compiler specific info in files like cpp</li>
<li class="overlay2">Permits use of Perl expressions in conditionals (so you can use regular expressions for example)</li>
<li class="overlay3">Supports looping</li>
<li class="overlay4">Written in Perl so you can develop modules to perform other actions</li>
</ul>
</html>
<html>
<hide linebreaks>
<ul>
<li>Create a website with a consistent look and feel</li>
<li class="overlay1">Generate configuration files that are 90% identical except for certain parameters</li>
<li class="overlay2">Enhance the configuration language of a tool you use</li><ul>
<li class="overlay3">Define new commands</li>
<li class="overlay4">Allow looping in your config files rather than adding a ton of identical statements</li></ul>
<li class="overlay5">Define things once and incorporate them into documentation and code</li>
</ul>
</html>
[[What is a Macro Processor]]
[[What is Filepp]]
[[Filepp Uses]]
[[Filepp Benefits]]
[[Simple Example]]
[[Sample Language Enhancement]]
/***
|''Name:''|FootnotesPlugin|
|''Description:''|Create automated tiddler footnotes.|
|''Author:''|Saq Imtiaz ( lewcid@gmail.com )|
|''Source:''|http://tw.lewcid.org/#FootnotesPlugin|
|''Code Repository:''|http://tw.lewcid.org/svn/plugins|
|''Version:''|2.01|
|''Date:''|10/25/07|
|''License:''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''~CoreVersion:''|2.2.2|

!!Usage:
*To create a footnote, just put the footnote text inside triple backticks.
*Footnotes are numbered automatically, and listed at the bottom of the tiddler.
*{{{Creating a footnote is easy. ```This is the text for my footnote```}}}
*[[Example|FootnotesDemo]]
***/
// /%
//!BEGIN-PLUGIN-CODE
config.footnotesPlugin = {
	backLabel: "back",
	prompt:"show footnote"
};

config.formatters.unshift( {
    name: "footnotes",
    match: "```",
    lookaheadRegExp: /```((?:.|\n)*?)```/g,
    handler: function(w)
    {
        // rouilj to prevent function from erroring when rendered during an rss export operation
        // just exit if not being rendered within a story.
        if (!story.findContainingTiddler(place)) return;
        // end patch
        this.lookaheadRegExp.lastIndex = w.matchStart;
        var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
        if(lookaheadMatch && lookaheadMatch.index == w.matchStart )
            {
			var tiddler = story.findContainingTiddler(w.output);
			if (!tiddler.notes)
				tiddler.notes = [];
			var title = tiddler.getAttribute("tiddler");
			tiddler.notes.pushUnique(lookaheadMatch[1]);
			var pos = tiddler.notes.indexOf(lookaheadMatch[1]) + 1;
			createTiddlyButton(w.output,pos,config.footnotesPlugin.prompt,function(){var x = document.getElementById(title+"ftn"+pos);window.scrollTo(0,ensureVisible(x)+(ensureVisible(x)<findScrollY()?(findWindowHeight()-x.offsetHeight):0));return false;},"ftnlink",title+"ftnlink"+pos);			
			w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
            }
    }
});

old_footnotes_refreshTiddler = Story.prototype.refreshTiddler;
Story.prototype.refreshTiddler = function(title,template,force)
{
    var tiddler = old_footnotes_refreshTiddler.apply(this,arguments);
	if (tiddler && tiddler.notes && tiddler.notes.length)
	{
		var holder = createTiddlyElement(null,"div",null,"footnoteholder");
		var list = createTiddlyElement(holder,"ol",title+"footnoteholder");
		for (var i=0; i<tiddler.notes.length; i++)
		{
			var ftn = createTiddlyElement(list,"li",title+"ftn"+(i+1),"footnote");
			wikify(tiddler.notes[i]+" ",ftn);
			createTiddlyButton(ftn,"["+config.footnotesPlugin.backLabel+"]",config.footnotesPlugin.backLabel,function(){window.scrollTo(0,ensureVisible(document.getElementById(this.parentNode.id.replace("ftn","ftnlink"))));return false;},"ftnbklink");
		}
		var count = tiddler.childNodes.length;
		for (var j=0; j<count; j++){
			if(hasClass(tiddler.childNodes[j],"viewer")){
				var viewer = tiddler.childNodes[j];	
			}
		}
		viewer.appendChild(holder);
		tiddler.notes = [];
	}
    return tiddler;
};

setStylesheet(
".tiddler a.ftnlink {vertical-align: super; font-size: 0.8em; color:red;}\n"+
".tiddler a.ftnlink:hover, .tiddler .footnoteholder a.ftnbklink:hover{color:#fff;background:red;}\n"+
".tiddler div.footnoteholder{margin:1.8em 1.0em; padding:0.1em 1.0em 0.1em 1.0em ;border-left: 1px solid #ccc;}"+
".tiddler footnoteholder ol {font-size: 0.9em; line-height: 1.2em;}\n"+
".tiddler .footnoteholder li.footnote {margin: 0 0 5px 0;}\n"+
".tiddler .footnoteholder a.ftnbklink{color:red;}\n","FootNotesStyles");
//!END-PLUGIN-CODE
// %/
There are a bunch of GTD supporting verticals:
;~GTDTiddlyWiki
:http://nathanbowers.com/gtdtw/ - the original one from 2005
;gtd_tiddlywiki
:http://www.checkettsweb.com/tw/gtd_tiddlywiki.htm - a newer release with updated core
;~MonkeyGTD
:http://monkeygtd.tiddlyspot.com - a newer release supporting realms (e.g. work and personal, you and your spouse ...). See also: http://wiki.43folders.com/index.php/Monkey_GTD
;D3
:http://www.dcubed.ca/Welcome_to_d-cubed.html - to download samples and blanks to work in. See also: http://wiki.43folders.com/index.php/D3
;tbGTD
:http://tbgtd.tiddlyspot.com/ - yet another entry into the fray 
;tiddlyDu3
:http://www.giffmex.org/tiddlydu3.html - another take on GTD
!Inline Formatting
|!Option|!Syntax|!Output|
|bold font|{{{''bold''}}}|''bold''|
|italic type|{{{//italic//}}}|//italic//|
|underlined text|{{{__underlined__}}}|__underlined__|
|strikethrough text|{{{--strikethrough--}}}|--strikethrough--|
|superscript text|{{{^^super^^script}}}|^^super^^script|
|subscript text|{{{~~sub~~script}}}|~~sub~~script|
|highlighted text|{{{@@highlighted@@}}}|@@highlighted@@|
|preformatted text|<html><code>{{{preformatted}}}</code></html>|{{{preformatted}}}|
!Block Elements
!!Headings
{{{
!Heading 1
!!Heading 2
!!!Heading 3
!!!!Heading 4
!!!!!Heading 5
}}}
<<<
!Heading 1
!!Heading 2
!!!Heading 3
!!!!Heading 4
!!!!!Heading 5
<<<
!!Lists
{{{
* unordered list, level 1
** unordered list, level 2
*** unordered list, level 3

# ordered list, level 1
## ordered list, level 2
### unordered list, level 3

; definition list, term
: definition list, description
}}}
<<<
* unordered list, level 1
** unordered list, level 2
*** unordered list, level 3

# ordered list, level 1
## ordered list, level 2
### unordered list, level 3

; definition list, term
: definition list, description
<<<
!!Blockquotes
{{{
> blockquote, level 1
>> blockquote, level 2
>>> blockquote, level 3

<<<
blockquote
<<<
}}}
<<<
> blockquote, level 1
>> blockquote, level 2
>>> blockquote, level 3

> blockquote
<<<
!!Preformatted Text
<html><pre>
{{{
preformatted (e.g. code)
}}}
</pre></html>
<<<
{{{
preformatted (e.g. code)
}}}
<<<
!!Tables
{{{
|CssClass|k
|!heading column 1|!heading column 2|
|row 1, column 1|row 1, column 2|
|row 2, column 1|row 2, column 2|
|>|COLSPAN|
|ROWSPAN| … |
|~| … |
|CssProperty:value;…| … |
|caption|c
}}}
''Annotation:''
* The {{{>}}} marker creates a "colspan", causing the current cell to merge with the one to the right.
* The {{{~}}} marker creates a "rowspan", causing the current cell to merge with the one above.
<<<
|CssClass|k
|!heading column 1|!heading column 2|
|row 1, column 1|row 1, column 2|
|row 2, column 1|row 2, column 2|
|>|COLSPAN|
|ROWSPAN| … |
|~| … |
|CssProperty:value;…| … |
|caption|c
<<<
!!Images /% TODO %/
cf. [[TiddlyWiki.com|http://www.tiddlywiki.com/#EmbeddedImages]]
!Hyperlinks
* [[WikiWords|WikiWord]] are automatically transformed to hyperlinks to the respective tiddler
** the automatic transformation can be suppressed by preceding the respective WikiWord with a tilde ({{{~}}}): {{{~WikiWord}}}
* [[PrettyLinks]] are enclosed in square brackets and contain the desired tiddler name: {{{[[tiddler name]]}}}
** optionally, a custom title or description can be added, separated by a pipe character ({{{|}}}): {{{[[title|target]]}}}<br>'''N.B.:''' In this case, the target can also be any website (i.e. URL).
!Custom Styling
* {{{@@CssProperty:value;CssProperty:value;…@@}}}<br>''N.B.:'' CSS color definitions should use lowercase letters to prevent the inadvertent creation of WikiWords.
* <html><code>{{customCssClass{…}}}</code></html>
* raw HTML can be inserted by enclosing the respective code in HTML tags: {{{<html> … </html>}}}
!Special Markers
* {{{<br>}}} forces a manual line break
* {{{----}}} creates a horizontal ruler
* [[HTML entities|http://www.tiddlywiki.com/#HtmlEntities]]
* {{{<<macroName>>}}} calls the respective [[macro|Macros]]
* To hide text within a tiddler so that it is not displayed, it can be wrapped in {{{/%}}} and {{{%/}}}.<br/>This can be a useful trick for hiding drafts or annotating complex markup.
* To prevent wiki markup from taking effect for a particular section, that section can be enclosed in three double quotes: e.g. {{{"""WikiWord"""}}}.
[[Mind Mapping]]
[[The FreeMind Tool]]
[[Demo]]
[[Features]]
[[Drawbacks]]
!usage
{{{[img[Frontscreen.png]]}}}
[img[Frontscreen.png]]
!notes
Layout of the coursebook
!type
image/png
!file
./images/Frontscreen.png
!url
http://www.example.com/class/Frontscreen.png
!data
data:image/png;base64,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
!What would you pay for this?
{{overlay1{Well it's free.}}}
{{overlay2{Best of all one single executable, no databases, web servers etc. to deploy.}}}
{{overlay3{Uses a text file for configuration}}}
{{overlay4{Uses files in a directory for storing notes/files}}}
{{overlay5{Pretty standard C, compile under cygwin, linux, solaris, windows...}}}
{{adiv{
<<showWhen window.location.protocol!='file:'>>
You ''MUST'' download the coursebook to your local disk from: <<tiddler "GettingStarted::courseHomeBook">> (using the browser's download/save link mechanism). You are currenty viewing it using http or https and ''can not'' save it while viewing it from the net.
{{adiv{
<<showWhen ! (config.browser.isIE || (navigator.userAgent.indexOf('Firefox') != -1)) >>
You must also download/save to disk <<tiddler "GettingStarted::courseHomeTs">> in the same directory as the coursebook since you are not using Internet Explorer or Firefox.
}}}
}}} {{adiv{
<<showWhen window.location.protocol=='file:'>>
If you are seeing this tiddler when you first load the file, there is no content loaded in your coursebook yet. Follow the directions below to prepare this coursebook.

# Enter your username for signing your edits: <<option txtUserName>>.
# Click the outlined `button' below to load content into this empty book:<br /> <<loadTiddlers "label:Import new content from %0" updates {{store.getTiddlerSlice('GettingStarted','courseHomeContent')}} {{config.options['chkLoadTiddlersShowReport']=false;}} >>.{{aspan{<<showWhenExists Welcome>>@@<br />''Content has been loaded successfully''.@@}}}
# Once the content is loaded (it can take a minute),  click on <<saveChanges>> to save the changes.
# Then click to <html><a style="border: 1px solid #DDBB44" onClick="window.location.reload()">reload the page</a></html> or use F5 in your browser.
}}}

/%
Original content of this tiddler is located below.
----
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
%/


/%
Enter the url's for your coursebook here.

The publication directory
courseHome: http://www.example.com/class

The tiddlywiki copy of the studentbook
courseHomeBook: http://www.example.com/class/studentbook.html

The TiddlySaver.jar file
courseHomeTs: http://www.example.com/class/TiddlySaver.jar

The purestore content file
courseHomeContent: http://www.example.com/class/content.html

The published content rss feed
courseHomeRss: http://www.example.com/class/content.xml
%/
/***
|Name|GotoPlugin|
|Source|http://www.TiddlyTools.com/#GotoPlugin|
|Documentation|http://www.TiddlyTools.com/#GotoPluginInfo|
|Version|1.9.2|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|view any tiddler by entering it's title - displays list of possible matches|
''View a tiddler by typing its title and pressing //enter//.''  As you type, a list of possible matches is displayed.  You can scroll-and-click (or use arrows+enter) to select/view a tiddler, or press escape to close the listbox to resume typing.  When the listbox is not displayed, pressing //escape// clears the current input.
!!!Documentation
>see [[GotoPluginInfo]]
!!!Configuration
<<<
*Match titles only after {{twochar{<<option txtIncrementalSearchMin>>}}} or more characters are entered.<br>Use down-arrow to start matching with shorter input.  //Note: This option value is also set/used by [[SearchOptionsPlugin]]//.
*To set the maximum height of the listbox, you can create a tiddler tagged with <<tag systemConfig>>, containing:
//{{{
config.macros.gotoTiddler.listMaxSize=10;  // change this number
//}}}
<<<
!!!Revisions
<<<
2009.05.22 [1.9.2] use reverseLookup() for IncludePlugin
|please see [[GotoPluginInfo]] for additional revision details|
2006.05.05 [0.0.0] started
<<<
!!!Code
***/
//{{{
version.extensions.GotoPlugin= {major: 1, minor: 9, revision: 2, date: new Date(2009,5,22)};

// automatically tweak shadow SideBarOptions to add <<gotoTiddler>> macro above <<search>>
config.shadowTiddlers.SideBarOptions=config.shadowTiddlers.SideBarOptions.replace(/<<search>>/,"{{button{goto}}}\n<<gotoTiddler>><<search>>");

if (config.options.txtIncrementalSearchMin===undefined) config.options.txtIncrementalSearchMin=3;

config.macros.gotoTiddler= { 
	listMaxSize: 10,
	listHeading: 'Found %0 matching title%1...',
	searchItem: "Search for '%0'...",
	handler:
	function(place,macroName,params,wikifier,paramString,tiddler) {
		var quiet	=params.contains("quiet");
		var showlist	=params.contains("showlist");
		var search	=params.contains("search");
		params = paramString.parseParams("anon",null,true,false,false);
		var instyle	=getParam(params,"inputstyle","");
		var liststyle	=getParam(params,"liststyle","");
		var filter	=getParam(params,"filter","");
		var html=this.html;
		var keyevent=window.event?"onkeydown":"onkeypress"; // IE event fixup for ESC handling
		html=html.replace(/%keyevent%/g,keyevent);
		html=html.replace(/%search%/g,search);
		html=html.replace(/%quiet%/g,quiet);
		html=html.replace(/%showlist%/g,showlist);
		html=html.replace(/%display%/g,showlist?'block':'none');
		html=html.replace(/%position%/g,showlist?'static':'absolute');
		html=html.replace(/%instyle%/g,instyle);
		html=html.replace(/%liststyle%/g,liststyle);
		html=html.replace(/%filter%/g,filter);
		if (config.browser.isIE) html=this.IEtableFixup.format([html]);
		var span=createTiddlyElement(place,'span');
		span.innerHTML=html; var form=span.getElementsByTagName("form")[0];
		if (showlist) this.fillList(form.list,'',filter,search,0);
	},
	html:
	'<form onsubmit="return false" style="display:inline;margin:0;padding:0">\
		<input name=gotoTiddler type=text autocomplete="off" accesskey="G" style="%instyle%"\
			title="Enter title text... ENTER=goto, SHIFT-ENTER=search for text, DOWN=select from list"\
			onfocus="this.select(); this.setAttribute(\'accesskey\',\'G\');"\
			%keyevent%="return config.macros.gotoTiddler.inputEscKeyHandler(event,this,this.form.list,%search%,%showlist%);"\
			onkeyup="return config.macros.gotoTiddler.inputKeyHandler(event,this,%quiet%,%search%,%showlist%);">\
		<select name=list style="display:%display%;position:%position%;%liststyle%"\
			onchange="if (!this.selectedIndex) this.selectedIndex=1;"\
			onblur="this.style.display=%showlist%?\'block\':\'none\';"\
			%keyevent%="return config.macros.gotoTiddler.selectKeyHandler(event,this,this.form.gotoTiddler,%showlist%);"\
			onclick="return config.macros.gotoTiddler.processItem(this.value,this.form.gotoTiddler,this,%showlist%);">\
		</select><input name="filter" type="hidden" value="%filter%">\
	</form>',
	IEtableFixup:
	"<table style='width:100%;display:inline;padding:0;margin:0;border:0;'>\
		<tr style='padding:0;margin:0;border:0;'><td style='padding:0;margin:0;border:0;'>\
		%0</td></tr></table>",
	getItems:
	function(list,val,filter) {
		if (!list.cache || !list.cache.length || val.length<=config.options.txtIncrementalSearchMin) {
			// starting new search, fetch and cache list of tiddlers/shadows/tags
			list.cache=new Array();
			if (filter.length) {
				var fn=store.getMatchingTiddlers||store.getTaggedTiddlers;
				var tiddlers=store.sortTiddlers(fn.apply(store,[filter]),'title');
			} else 
				var tiddlers=store.reverseLookup('tags','excludeLists');
			for(var t=0; t<tiddlers.length; t++) list.cache.push(tiddlers[t].title);
			if (!filter.length) {
				for (var t in config.shadowTiddlers) list.cache.pushUnique(t);
				var tags=store.getTags();
				for(var t=0; t<tags.length; t++) list.cache.pushUnique(tags[t][0]);
			}
		}
		var found = [];
		var match=val.toLowerCase();
		for(var i=0; i<list.cache.length; i++)
			if (list.cache[i].toLowerCase().indexOf(match)!=-1) found.push(list.cache[i]);
		return found;
	},
	getItemSuffix:
	function(t) {
		if (store.tiddlerExists(t)) return "";  // tiddler
		if (store.isShadowTiddler(t)) return " (shadow)"; // shadow
		return " (tag)"; // tag 
	},
	fillList:
	function(list,val,filter,search,key) {
		if (list.style.display=="none") return; // not visible... do nothing!
		var indent='\xa0\xa0\xa0';
		var found = this.getItems(list,val,filter); // find matching items...
		found.sort(); // alpha by title
		while (list.length > 0) list.options[0]=null; // clear list
		var hdr=this.listHeading.format([found.length,found.length==1?"":"s"]);
		list.options[0]=new Option(hdr,"",false,false);
		for (var t=0; t<found.length; t++) list.options[list.length]=
			new Option(indent+found[t]+this.getItemSuffix(found[t]),found[t],false,false);
		if (search)
			list.options[list.length]=new Option(this.searchItem.format([val]),"*",false,false);
		list.size=(list.length<this.listMaxSize?list.length:this.listMaxSize); // resize list...
		list.selectedIndex=key==38?list.length-1:key==40?1:0;
	},
	keyProcessed:
	function(ev) { // utility function
		ev.cancelBubble=true; // IE4+
		try{event.keyCode=0;}catch(e){}; // IE5
		if (window.event) ev.returnValue=false; // IE6
		if (ev.preventDefault) ev.preventDefault(); // moz/opera/konqueror
		if (ev.stopPropagation) ev.stopPropagation(); // all
		return false;
	},
	inputEscKeyHandler:
	function(event,here,list,search,showlist) {
		if (event.keyCode==27) {
			if (showlist) { // clear input, reset list
				here.value=here.defaultValue;
				this.fillList(list,'',here.form.filter.value,search,0);
			}
			else if (list.style.display=="none") // clear input
				here.value=here.defaultValue;
			else list.style.display="none"; // hide list
			return this.keyProcessed(event);
		}
		return true; // key bubbles up
	},
	inputKeyHandler:
	function(event,here,quiet,search,showlist) {
		var key=event.keyCode;
		var list=here.form.list;
		var filter=here.form.filter;
		// non-printing chars bubble up, except for a few:
		if (key<48) switch(key) {
			// backspace=8, enter=13, space=32, up=38, down=40, delete=46
			case 8: case 13: case 32: case 38: case 40: case 46: break; default: return true;
		}
		// blank input... if down/enter... fall through (list all)... else, and hide or reset list
		if (!here.value.length && !(key==40 || key==13)) {
			if (showlist) this.fillList(here.form.list,'',here.form.filter.value,search,0);
			else list.style.display="none";
			return this.keyProcessed(event);
		}
		// hide list if quiet, or below input minimum (and not showlist)
		list.style.display=(!showlist&&(quiet||here.value.length<config.options.txtIncrementalSearchMin))?'none':'block';
		// non-blank input... enter=show/create tiddler, SHIFT-enter=search for text
		if (key==13 && here.value.length) return this.processItem(event.shiftKey?'*':here.value,here,list,showlist);
		// up or down key, or enter with blank input... shows and moves to list...
		if (key==38 || key==40 || key==13) { list.style.display="block"; list.focus(); }
		this.fillList(list,here.value,filter.value,search,key);
		return true; // key bubbles up
	},
	selectKeyHandler:
	function(event,list,editfield,showlist) {
		if (event.keyCode==27) // escape... hide list, move to edit field
			{ editfield.focus(); list.style.display=showlist?'block':'none'; return this.keyProcessed(event); }
		if (event.keyCode==13 && list.value.length) // enter... view selected item
			{ this.processItem(list.value,editfield,list,showlist); return this.keyProcessed(event); }
		return true; // key bubbles up
	},
	processItem:
	function(title,here,list,showlist) {
		if (!title.length) return;
		list.style.display=showlist?'block':'none';
		if (title=="*")	{ story.search(here.value); return false; } // do full-text search
		if (!showlist) here.value=title;
		story.displayTiddler(null,title); // show selected tiddler
		return false;
	}
}
//}}}
/***
|Name|GotoPluginInfo|
|Source|http://www.TiddlyTools.com/#GotoPlugin|
|Documentation|http://www.TiddlyTools.com/#GotoPluginInfo|
|Version|1.9.2|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|documentation|
|Requires||
|Overrides||
|Description|Documentation for GotoPlugin|
''View a tiddler by typing its title and pressing //enter//.''  As you type, a list of possible matches is displayed.  You can scroll-and-click (or use arrows+enter) to select/view a tiddler, or press escape to close the listbox to resume typing.  When the listbox is not displayed, pressing //escape// clears the current input.
!!!!!Usage/Examples
<<<
syntax: {{{<<gotoTiddler quiet search inputstyle:... liststyle:... filter:...>>}}}
All parameters are optional.
* ''quiet'' (//keyword//)<br>list will not be automatically display as each character is typed.  Use //down// or //enter// to view the list.
* ''showlist'' (//keyword//)<br>list will always be displayed, inline, directly below the input field.
* ''search'' (//keyword//)<br>adds an extra 'command item' to the list that can be used to invoke a full-text search using the entered value.  This can be especially useful when no matching tiddler titles have been found.
* ''inputstyle:'' and ''liststyle:''<br>are CSS declarations that modify the default input and listbox styles, respectively.  Note: the CSS styles must be surrounded by ({{{"..."}}} or {{{'...'}}}) or ({{{[[...]]}}}) (e.g., {{{liststyle:"border:1px dotted blue;color:green;..."}}}.
* ''filter:''<br>is a single tag value (or a boolean tag expression if MatchTagsPlugin is installed), and is used to limit the search to only those tiddlers matching the indicated tag or tag expression (e.g., {{{<<gotoTiddler filter:"faq or help">>}}})
{{{<<gotoTiddler>>}}}
<<gotoTiddler>>
{{{<<gotoTiddler search>>}}}
<<gotoTiddler search>>
{{{<<gotoTiddler showlist filter:"pluginInfo" liststyle:"height:10em;width:auto;">>}}}
<<gotoTiddler showlist filter:"pluginInfo" liststyle:"height:10em;width:auto;">>
<<<
!!!!!Configuration
<<<
*Match titles only after {{twochar{<<option txtIncrementalSearchMin>>}}} or more characters are entered.<br>Use down-arrow to start matching with shorter input.  //Note: This option value is also set/used by [[SearchOptionsPlugin]]//.
*To set the maximum height of the listbox, you can create a tiddler tagged with <<tag systemConfig>>, containing:
//{{{
config.macros.gotoTiddler.listMaxSize=10;  // change this number
//}}}
<<<
!!!!!Revisions
<<<
2009.05.22 [1.9.2] use reverseLookup() for IncludePlugin
2009.04.12 [1.9.1] support multiple instances with different filters by using per-element tiddler cache instead of shared static cache
2009.04.05 [1.9.0] added 'showlist' parameter for inline display with listbox always visible.
2009.03.23 [1.8.0] added txtIncrementalSearchMin (default=3).  Avoids fetching long lists.  Use down arrow to force search with short input.
2008.12.15 [1.7.1] up arrow from input field now moves to end of droplist (search for input).  Also, shift+enter cam now be used to quickly invoke search for text.
2008.10.16 [1.7.0] in macro handler(), changed to use //named// params instead of positional params, and added optional "filter:" param for tag filtering.  Removed 'insert' handling (now provided by [[QuickEditPlugin]]).
2008.10.02 [1.6.1] for IE, wrap controls in a table.  Corrects placement of listbox so it is below input field.
2008.10.02 [1.6.0] added 'search' param for optional "Search for:" item that invokes full text search (especially useful when no title matches are found)
2008.02.17 [1.5.0] ENTER key always displays tiddler based on current input regardless of whether input matches any existing tiddler
2007.10.31 [1.4.3] removed extra trailing comma on last property of config.macros.gotoTiddler object.  This fixes an error under InternetExplorer that was introduced 6 days ago... sure, I should have found it sooner, but... WHY DON'T PEOPLE TELL ME WHEN THINGS ARE BROKEN!!!!
2007.10.25 [1.4.2] added onclick handler for input field, so that clicking in field hides the listbox.
2007.10.25 [1.4.1] re-wrote getItems() to cache list of tiddlers/shadows/tags and use case-folded simple text match instead of regular expression to find matching tiddlers.  This *vastly* reduces processing overhead between keystrokes, especially for documents with many (>1000) tiddlers.  Also, removed local definition of replaceSelection(), now supported directly by the TW2.2+ core, as well as via backward-compatible plugin
2007.04.25 [1.4.0] renamed macro from "goto" to "gotoTiddler".  This was necessary to avoid a fatal syntax error in Opera (and other browsers) that require strict adherence to ECMAScript 1.5 standards which defines the identifier "goto" as "reserved for FUTURE USE"... *sigh*
2007.04.21 [1.3.2] in html definition, removed DIV around droplist (see 1.2.6 below).  It created more layout problems then it solved. :-(
2007.04.01 [1.3.1] in processItem(), ensure that correct textarea field is found by checking for edit=="text" attribute
2007.03.30 [1.3.0] tweak SideBarOptions shadow to automatically add {{{<<goto>>}}} when using default sidebar content
2007.03.30 [1.2.6] in html definition, added DIV around droplist to fix IE problem where list appears next to input field instead of below it.  
2007.03.28 [1.2.5] in processItem(), set focus to text area before setting selection (needed for IE to get correct selection 'range')
2007.03.28 [1.2.4] added prompt for 'pretty text' when inserting a link into tiddler content
2007.03.28 [1.2.3] added local copy of core replaceSelection() and modified for different replace logic
2007.03.27 [1.2.2] in processItem(), use story.getTiddlerField() to retrieve textarea control
2007.03.26 [1.2.1] in html, use either 'onkeydown' (IE) or 'onkeypress' (Moz) event to process <esc> key sooner, to prevent <esc> from 'bubbling up' to the tiddler (which will close the current editor).
2007.03.26 [1.2.0] added support for optional "insert" keyword param.
2006.05.10 [1.1.2] when filling listbox, set selection to 'heading' item... auto-select first tiddler title when down/enter moves focus into listbox
2006.05.08 [1.1.1] added accesskey ("G") to input field html (also set when field gets focus).  Also, inputKeyHandler() skips non-printing/non-editing keys. 
2006.05.08 [1.1.0] added heading to listbox for better feedback (also avoids problems with 1-line droplist)
2006.05.07 [1.0.0] list matches against tiddlers/shadows/tags.  input field auto-completion... 1st enter=complete matching input (or show list)... 2nd enter=view tiddler.  "quiet" param controls when listbox appears.  handling for enter (13), escape(27), and down(40) keys.   Change 'ondblclick' to 'onclick' to avoid unintended triggering of tiddler editor).  Shadow titles inserted into list instead of appended to the end.
2006.05.05 [0.0.0] started
<<<
/***
|Name|HTMLFormattingPlugin|
|Source|http://www.TiddlyTools.com/#HTMLFormattingPlugin|
|Documentation|http://www.TiddlyTools.com/#HTMLFormattingPluginInfo|
|Version|2.4.0|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|embed wiki syntax formatting inside of HTML content|
The ~HTMLFormatting plugin allows you to ''mix wiki-style formatting syntax within HTML formatted content'' by extending the action of the standard TiddlyWiki formatting handler.
!!!!!Documentation
>see [[HTMLFormattingPluginInfo]]
!!!!!Revisions
<<<
2009.01.05 [2.4.0] in wikifyTextNodes(), pass w.highlightRegExp and w.tiddler to wikify() so that search term highlighting and tiddler-relative macro processing will work
| see [[HTMLFormattingPluginInfo]] for additional revision details |
2005.06.26 [1.0.0] Initial Release (as code adaptation - pre-dates TiddlyWiki plugin architecture!!)
<<<
!!!!!Code
***/
//{{{
version.extensions.HTMLFormattingPlugin= {major: 2, minor: 4, revision: 0, date: new Date(2009,1,5)};

// find the formatter for HTML and replace the handler
initHTMLFormatter();
function initHTMLFormatter()
{
	for (var i=0; i<config.formatters.length && config.formatters[i].name!="html"; i++);
	if (i<config.formatters.length)	config.formatters[i].handler=function(w) {
		if (!this.lookaheadRegExp)  // fixup for TW2.0.x
			this.lookaheadRegExp = new RegExp(this.lookahead,"mg");
		this.lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source)
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
			var html=lookaheadMatch[1];
			// if <nowiki> is present, just let browser handle it!
			if (html.indexOf('<nowiki>')!=-1)
				createTiddlyElement(w.output,"span").innerHTML=html;
			else {
				// if <hide linebreaks> is present, suppress wiki-style literal handling of newlines
				if (html.indexOf('<hide linebreaks>')!=-1) html=html.replace(/\n/g,' ');
				// remove all \r's added by IE textarea and mask newlines and macro brackets
				html=html.replace(/\r/g,'').replace(/\n/g,'\\n').replace(/<</g,'%%(').replace(/>>/g,')%%');
				// create span, let browser parse HTML
				var e=createTiddlyElement(w.output,"span"); e.innerHTML=html;
				// then re-render text nodes as wiki-formatted content
				wikifyTextNodes(e,w);
			}
			w.nextMatch = this.lookaheadRegExp.lastIndex; // continue parsing
		}
	}
}

// wikify #text nodes that remain after HTML content is processed (pre-order recursion)
function wikifyTextNodes(theNode,w)
{
	function unmask(s) { return s.replace(/\%%\(/g,'<<').replace(/\)\%%/g,'>>').replace(/\\n/g,'\n'); }
	switch (theNode.nodeName.toLowerCase()) {
		case 'style': case 'option': case 'select':
			theNode.innerHTML=unmask(theNode.innerHTML);
			break;
		case 'textarea':
			theNode.value=unmask(theNode.value);
			break;
		case '#text':
			var txt=unmask(theNode.nodeValue);
			var newNode=createTiddlyElement(null,"span");
			theNode.parentNode.replaceChild(newNode,theNode);
			wikify(txt,newNode,highlightHack,w.tiddler);
			break;
		default:
			for (var i=0;i<theNode.childNodes.length;i++)
				wikifyTextNodes(theNode.childNodes.item(i),w); // recursion
			break;
	}
}
//}}}
|Name|HTMLFormattingPluginInfo|
|Source|http://www.TiddlyTools.com/#HTMLFormattingPlugin|
|Documentation|http://www.TiddlyTools.com/#HTMLFormattingPluginInfo|
|Version|2.4.0|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|documentation|
|Description|documentation for HTMLFormattingPlugin|
The ~HTMLFormatting plugin allows you to freely ''mix wiki-style formatting syntax within HTML formatted content'' by extending the action of the standard TiddlyWiki formatting handler.
!!!!!Usage
<<<
The shorthand Wiki-style formatting syntax of ~TiddlyWiki is very convenient and enables most content to be reasonably well presented. However, there are times when tried-and-true HTML formatting syntax allows more more precise control of the content display.

When a tiddler is about to be displayed, ~TiddlyWiki looks for tiddler content contained within {{{<html>}}} and {{{</html>}}} markers.  When present, the TiddlyWiki core simply passes this content directly to the browser's internal "rendering engine" to process as ~HTML-formatted content.  However, TiddlyWiki does not also process the HTML source content for any embedded wiki-formatting syntax it may contain.  This means that while you can use HTML formatted content, you cannot mix wiki-formatted content within the HTML formatting.

This plugin extends the TiddlyWiki core processing so that, after the HTML formatting has been processed, all the pieces of text occuring within the HTML block are then processed one piece at a time, so that normal wiki-style formatting can be applied to the individual text pieces.

Note: To bypass this extended processing for a specific section of HTML content, embed ''{{{<nowiki>}}}'' //anywhere// inside the {{{<html>...</html>}}} delimiters, and wiki formatting will not be applied to that content.
<<<
!!!!!Line breaks
<<<
One major difference between Wiki formatting and HTML formatting is how "line breaks" are processed. Wiki formatting treats all line breaks as literal content to be displayed //as-is//. However, because HTML normally ignores line breaks and actually processes them as simple "word separators" instead, many people who write HTML include extra line breaks in their documents, just to make the "source code" easier to read.

Even though you can use HTML tags within your tiddler content, the default treatment for line breaks still follows the Wiki-style rule (i.e., all new lines are displayed as-is). When adding HTML content to a tiddler (especially if you cut-and-paste it from another web page), you should take care to avoid adding extra line breaks to the text.

If removing all the extra line breaks from your HTML content would be a big hassle, you can quickly //override the default Wiki-style line break rule// so that the line breaks use the standard HTML rules, by placing ''{{{<hide linebreaks>}}}'' //anywhere// within the HTML content.  This automatically converts all line breaks to spaces before rendering the content, so that the literal line breaks will be processed as simple word-breaks instead.

Note: this does //not// alter the actual tiddler content that is stored in the document, just the manner in which it is displayed. Any line breaks contained in the tiddler will still be there when you edit its content. Also, to include a literal line break when the ''<{{{hide linebreaks}}}>'' tag is present, you will need to use a ''<{{{br}}}>'' or ''<{{{p}}}>'' HTML tag instead of simply typing a line break.
<<<
!!!!!How it works
<<<
The TW core support for HTML does not let you put ANY wiki-style syntax (including TW macros) *inside* the {{{<html>...</html>}}} block.  Everything between {{{<html>}}} and {{{</html>}}} is handed to the browser for processing and that is it.

However, not all wiki syntax can be safely passed through the browser's parser. Specifically, any TW macros inside the HTML will get 'eaten' by the browser since the macro brackets, {{{<<...>>}}} use the "<" and ">" that normally delimit the HTML/XML syntax recognized by the browser's parser.

Similarly, you can't use InlineJavascript within the HTML because the {{{<script>...</script>}}} syntax will also be consumed by the browser and there will be nothing left to process afterward.  Note: unfortunately, even though the browser removes the {{{<script>...</script>}}} sequence, it doesn't actually execute the embedded javascript code that it removes, so any scripts contained inside of <html> blocks in TW are currently being ignored. :-(

As a work-around to allow TW *macros* (but not inline scripts) to exist inside of <html> formatted blocks of content, the plugin first converts the {{{<<}}} and {{{>>}}} into "%%(" and ")%%", making them "indigestible" so they can pass unchanged through the belly of the beast (the browser's HTML parser).

After the browser has done its job, the wiki syntax sequences (including the "undigested" macros) are contained in #text nodes in the browser-generated DOM elements.  The plugin then recursively locates and processes each #text node, converts the %%( and )%% back into {{{<<}}} and {{{>>}}}, passes the result to wikify() for further rendering of the wiki-formatted syntax into a containing SPAN that replaces the previous #text node.  At the end of this process, none of the encoded %%( and )%% sequences remain in the rendered tiddler output.
<<<
!!!!!Revisions
<<<
2009.01.05 2.4.0 in wikifyTextNodes(), pass w.highlightRegExp and w.tiddler to wikify() so that search term highlighting and tiddler-relative macro processing will work
2008.10.02 2.3.0 added use of {{{<nowiki>}}} marker to bypass all wikification inside a specific HTML block
2008.09.19 2.2.0 in wikifyTextNodes(), don't wikify the contents of STYLE nodes (thanks to MorrisGray for bug report)
2008.04.26 [*.*.*] plugin size reduction: more documentation moved to HTMLFormattingInfo
2008.01.08 [*.*.*] plugin size reduction: documentation moved to HTMLFormattingInfo
2007.12.04 [*.*.*] update for TW2.3.0: replaced deprecated core functions, regexps, and macros
2007.06.14 2.1.5 in formatter, removed call to e.normalize().  Creates an INFINITE RECURSION error in Safari!!!!
2006.09.10 2.1.4 update formatter for 2.1 compatibility (use this.lookaheadRegExp instead of temp variable)
2006.05.28 2.1.3 in wikifyTextNodes(), decode the *value* of TEXTAREA nodes, but don't wikify() its children.  (thanks to "ayj" for bug report)
2006.02.19 2.1.2 in wikifyTextNodes(), put SPAN element into tiddler DOM (replacing text node), BEFORE wikifying the text content.  This ensures that the 'place' passed to any macros is correctly defined when the macro is evaluated, so that calls to story.findContainingTiddler(place) will work as expected. (Thanks for bug report from GeoffSlocock)
2006.02.05 2.1.1 wrapped wikifier hijack in init function to eliminate globals and avoid FireFox 1.5.0.1 crash bug when referencing globals
2005.12.01 2.1.0 don't wikify #TEXT nodes inside SELECT and TEXTAREA elements
2005.11.06 2.0.1 code cleanup
2005.10.31 2.0.0 replaced hijack wikify() with hijack config.formatters["html"] and simplified recursive WikifyTextNodes() code
2005.10.09 1.0.2 combined documentation and code into a single tiddler
2005.08.05 1.0.1 moved HTML and CSS definitions into plugin code instead of using separate tiddlers
2005.07.26 1.0.1 Re-released as a plugin. Added <{{{html}}}>...</{{{nohtml}}}> and <{{{hide newlines}}}> handling
2005.06.26 1.0.0 Initial Release (as code adaptation - pre-dates TiddlyWiki plugin architecture!!)
<<<
/***
|Name:|HideWhenPlugin|
|Description:|Allows conditional inclusion/exclusion in templates|
|Version:|3.1 ($Rev: 3919 $)|
|Date:|$Date: 2008-03-13 02:03:12 +1000 (Thu, 13 Mar 2008) $|
|Source:|http://mptw.tiddlyspot.com/#HideWhenPlugin|
|Author:|Simon Baird <simon.baird@gmail.com>|
|License:|http://mptw.tiddlyspot.com/#TheBSDLicense|
For use in ViewTemplate and EditTemplate. Example usage:
{{{<div macro="showWhenTagged Task">[[TaskToolbar]]</div>}}}
{{{<div macro="showWhen tiddler.modifier == 'BartSimpson'"><img src="bart.gif"/></div>}}}
***/
//{{{

window.hideWhenLastTest = false;

window.removeElementWhen = function(test,place) {
	window.hideWhenLastTest = test;
	if (test) {
		removeChildren(place);
		place.parentNode.removeChild(place);
	}
};


merge(config.macros,{

	hideWhen: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( eval(paramString), place);
	}},

	showWhen: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( !eval(paramString), place);
	}},

	hideWhenTagged: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( tiddler.tags.containsAll(params), place);
	}},

	showWhenTagged: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( !tiddler.tags.containsAll(params), place);
	}},

	hideWhenTaggedAny: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( tiddler.tags.containsAny(params), place);
	}},

	showWhenTaggedAny: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( !tiddler.tags.containsAny(params), place);
	}},

	hideWhenTaggedAll: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( tiddler.tags.containsAll(params), place);
	}},

	showWhenTaggedAll: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( !tiddler.tags.containsAll(params), place);
	}},

	hideWhenExists: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( store.tiddlerExists(params[0]) || store.isShadowTiddler(params[0]), place);
	}},

	showWhenExists: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( !(store.tiddlerExists(params[0]) || store.isShadowTiddler(params[0])), place);
	}},

	hideWhenTitleIs: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( tiddler.title == params[0], place);
	}},

	showWhenTitleIs: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( tiddler.title != params[0], place);
	}},

	'else': { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( !window.hideWhenLastTest, place);
	}}

});

//}}}
http://www.example.com/class/images/
/***
|Name|ImagePathPlugin|
|Source|http://www.TiddlyTools.com/#ImagePathPlugin|
|Version|0.7.1|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin,formatter|
|Requires||
|Overrides|'image' formatter|
|Description|Tell TiddlyWiki where to look for image files.  Permits multiple 'fallback' locations|
|Status|ALPHA - initial development/testing only - may be unstable - do not distribute|

!!!!!Usage
<<<
This plugin adds "resolvePath()" fallback processing to the {{{[img[...]]}}} formatter's handler, so that local image file references can be successfully resolved, even if the files cannot be located on the local filesystem.

The plugin tries alternative file "paths" that are listed, one per line, in an optional tiddler, [[ImagePathList]].  Each path in the list is combined with the image filename, which is then checked for existence, until the file is located.  If no alternative is found, or [[ImagePathList]] is not present, then a 'last-ditch' fallback is attempted using the remote system and path specified in [[SiteUrl]] (if present).

If no fallback attempt is successful (i.e., because no [[ImagePathList]] OR [[SiteUrl]] tiddlers have been defined), the plugin simply passes the original image file value along for default handling by the browser without any "path resolution" being applied.(i.e, the current TW core behavior occurs).

| ''Important note: This plugin may cause one or more security alert messages to appear, because it uses browser-specific functions that can require security permission in order to access the local filesystem to check for the existence of a given image file.  If you block local access, the 'last-ditch' fallback using the remote [[SiteUrl]] (if present) will be attempted.'' |

Note: the image formatter code contained here also includes support for AttachFilePlugin extensions (if installed).  AttachFilePlugin includes its own fallback mechanism for handling embedded vs. local file vs. remote URL references to the attached binary file.  Both methods may be used: ImagePathPlugin provides fallback for images contained in tiddler content, while AttachFilePlugin works well for access to non-image binary files (or images used in CSS as backgrounds, textures, etc.)
<<<
!!!!!Examples
<<<
coming soon...
<<<
!!!!!Revisions
<<<
''2007.04.13 [0.7.1]'' in testFile(), convert any file:// references to local native format before checking for existence.
''2007.03.26 [0.7.0]'' for IE, use onError handling to trigger call to resolvePath() so it will only be invoked if the original path/file is not found by the browser-native lookup.  This avoids an unneeded call to fileExists() and the accompanying ActiveX security alert message box (as well as being slightly more efficient...)
''2007.03.25 [0.6.0]'' code cleanup (moved global functions into config.formatterHelpers) plus documentation re-write
''2007.03.24 [0.5.0]'' initial implementation - ALPHA - do not distribute
<<<
!!!!!Code
***/
//{{{
version.extensions.ImagePathPlugin= {major: 0, minor: 7, revision: 1, date: new Date(2007,4,13)};
//}}}
//{{{
// name of path definition tiddler
if (config.options.txtPathTiddler==undefined) config.options.txtPathTiddler="ImagePathList";
//}}}
//{{{
// low-level wrapper for platform-specific tests for local file existence
// returns true/false without visible error display
// Uses Components for FF and ActiveX FSO object for MSIE
// NOTE: this can cause a security warning on some browsers
config.formatterHelpers.fileExists=function(theFile) {
	var found=false;
	// DEBUG: alert('testing fileExists('+theFile+')...');
	if(window.Components) {
		try { netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); }
		catch(e) { return false; } // security access denied
		var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
		try { file.initWithPath(theFile); }
		catch(e) { return false; } // invalid directory
		found = file.exists();
	}
	else { // use ActiveX FSO object for MSIE 
		var fso = new ActiveXObject("Scripting.FileSystemObject");
		found = fso.FileExists(theFile)
	}
	// DEBUG: alert(theFile+" "+(found?"exists":"not found"));
	return found;
}
//}}}
//{{{
// higher-level logic for checking local file existence.
// with secondary check for finding relative file references
// and automatic OK of http-based references without checking local filesystem
config.formatterHelpers.testFile=function(theFile) {
	if (document.location.protocol!="file:") return true; // viewing remote document, can't test local filesystem... assume OK
	if (theFile.substr(0,5)=="http:") return true; // remote HTTP reference... assume OK
	if (theFile.substr(0,5)=="file:") theFile=getLocalPath(theFile); // convert local FILE reference to native format
	if (this.fileExists(theFile)) return true; // file exists locally... OK to use!
	// file might have been relative, add path from current document and try again
	var docPath=document.location.href;
	var slashpos=docPath.lastIndexOf("/"); if (slashpos==-1) slashpos=docPath.lastIndexOf("\\"); 
	if (slashpos!=-1 && slashpos!=docPath.length-1) docPath=docPath.substr(0,slashpos+1); // trim off filename
	if (this.fileExists(getLocalPath(docPath+theFile)))
		return true; // ah ha!... file exists relative to current document... OK to use!
	return false; // file not found on local system
}
//}}}
//{{{
// given a path/file string, check for existence and
// try alternatives (if any) defined in a tiddler
// with last-ditch using system/path from SiteUrl (if any)
config.formatterHelpers.resolvePath=function(theFile,testoriginal) {
	if (testoriginal && this.testFile(theFile)) return theFile; // FOUND FILE - use specified path/file without modification
	// get the filename portion only
	var slashpos=theFile.lastIndexOf("/"); if (slashpos==-1) slashpos=theFile.lastIndexOf("\\"); 
	var theName=(slashpos==-1)?theFile:theFile.substr(slashpos+1);
	// get list of fallbacks (if any)
	var pathText=store.getTiddlerText(config.options.txtPathTiddler);
	if (pathText && pathText.length) {
		var paths=pathText.split("\n");
		for (p=0; p<paths.length; p++) // combine path+filename until one works...
			if (this.testFile(paths[p]+theName))
				return paths[p]+theName; // FOUND FILE - use alternative path+filename
	}
	// try "last ditch" fallback using SiteURL - assumes that original path/file was relative to document location
	var siteURL=store.getTiddlerText("SiteUrl");
	if (!siteURL||!siteURL.length) return theFile; // NO FALLBACK - use original path/file and hope for the best
	// trim filename (if any) from site URL
	var slashpos=siteURL.lastIndexOf("/"); if (slashpos==-1) slashpos=siteURL.lastIndexOf("\\"); 
	if (slashpos!=-1 && slashpos!=siteURL.length-1) siteURL=siteURL.substr(0,slashpos+1);
	return siteURL+theFile; // LAST DITCH: use system/path from SiteUrl combined with original file/path
}
//}}}
//{{{
// replace standard handler for image formatter
// adds call to resolvePath() to handle fallback processing
// includes support for AttachFilePlugin as well
config.formatters[config.formatters.findByField("name","image")].handler=function(w) {
	if (!this.lookaheadRegExp)  // fixup for TW2.0.x
		this.lookaheadRegExp = new RegExp(this.lookahead,"mg");
	this.lookaheadRegExp.lastIndex = w.matchStart;
	var lookaheadMatch = this.lookaheadRegExp.exec(w.source)
	if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
		// Simple bracketted link
		var e = w.output;
		if(lookaheadMatch[5]) {
			var link = lookaheadMatch[5];
			if (!config.formatterHelpers.isExternalLink) // fixup for TW2.0.x
				var external=!store.tiddlerExists(link)&&!store.isShadowTiddler(link);
			else
				var external=config.formatterHelpers.isExternalLink(link);
			if (external) {
				if (config.macros.attach && config.macros.attach.isAttachment(link)) { // ELS - attachments
					e = createExternalLink(w.output,link);
					e.href=config.macros.attach.getAttachment(link);
					e.title = config.macros.attach.linkTooltip + link;
				} else
					e = createExternalLink(w.output,link);
			} else 
				e = createTiddlyLink(w.output,link,false,null,w.isStatic);
			addClass(e,"imageLink");
		}
		var img = createTiddlyElement(e,"img");
		if(lookaheadMatch[1])
			img.align = "left";
		else if(lookaheadMatch[2])
			img.align = "right";
		if(lookaheadMatch[3])
			img.title = lookaheadMatch[3];
		if (config.macros.attach!=undefined && config.macros.attach.isAttachment(lookaheadMatch[4])) // ELS - attachments
			img.src=config.macros.attach.getAttachment(lookaheadMatch[4]);
		else {
			if (config.browser.isIE || config.browser.isSafari) { // ELS - path processing
				// IE and Safari use browser's onError handling to check the original file...
				// avoids extra security alert messages due to use of Components/ActiveX for filesystem access
				img.onerror=(function(){this.src=config.formatterHelpers.resolvePath(this.src,false);return false;});
				img.src=lookaheadMatch[4]; // ELS - path processing
			} else {
				// if NOT IE or Safari, always check the original path/file before rendering
				img.src=config.formatterHelpers.resolvePath(lookaheadMatch[4],true);
			}
		}
		w.nextMatch = this.lookaheadRegExp.lastIndex;
	}
}
//}}}
/***
|Name|ImageSizePlugin|
|Source|http://www.TiddlyTools.com/#ImageSizePlugin|
|Version|1.2.1|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin,formatter|
|Requires||
|Overrides|'image' formatter|
|Description|adds support for resizing images|
This plugin adds optional syntax to scale an image to a specified width and height and/or interactively resize the image with the mouse.
!!!!!Usage
<<<
The extended image syntax is:
{{{
[img(w+,h+)[...][...]]
}}}
where ''(w,h)'' indicates the desired width and height (in CSS units, e.g., px, em, cm, in, or %). Use ''auto'' (or a blank value) for either dimension to scale that dimension proportionally (i.e., maintain the aspect ratio). You can also calculate a CSS value 'on-the-fly' by using a //javascript expression// enclosed between """{{""" and """}}""". Appending a plus sign (+) to a dimension enables interactive resizing in that dimension (by dragging the mouse inside the image). Use ~SHIFT-click to show the full-sized (un-scaled) image. Use ~CTRL-click to restore the starting size (either scaled or full-sized).
<<<
!!!!!Examples
<<<
{{{
[img(100px+,75px+)[images/meow2.jpg]]
}}}
[img(100px+,75px+)[images/meow2.jpg]]
{{{
[<img(34%+,+)[images/meow.gif]]
[<img(21% ,+)[images/meow.gif]]
[<img(13%+, )[images/meow.gif]]
[<img( 8%+, )[images/meow.gif]]
[<img( 5% , )[images/meow.gif]]
[<img( 3% , )[images/meow.gif]]
[<img( 2% , )[images/meow.gif]]
[img(  1%+,+)[images/meow.gif]]
}}}
[<img(34%+,+)[images/meow.gif]]
[<img(21% ,+)[images/meow.gif]]
[<img(13%+, )[images/meow.gif]]
[<img( 8%+, )[images/meow.gif]]
[<img( 5% , )[images/meow.gif]]
[<img( 3% , )[images/meow.gif]]
[<img( 2% , )[images/meow.gif]]
[img(  1%+,+)[images/meow.gif]]
{{tagClear{
}}}
<<<
!!!!!Revisions
<<<
2009.02.24 [1.2.1] cleanup width/height regexp, use '+' suffix for resizing
2009.02.22 [1.2.0] added stretchable images
2008.01.19 [1.1.0] added evaluated width/height values
2008.01.18 [1.0.1] regexp for "(width,height)" now passes all CSS values to browser for validation
2008.01.17 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.ImageSizePlugin= {major: 1, minor: 2, revision: 1, date: new Date(2009,2,24)};
//}}}
//{{{
var f=config.formatters[config.formatters.findByField("name","image")];
f.match="\\[[<>]?[Ii][Mm][Gg](?:\\([^,]*,[^\\)]*\\))?\\[";
f.lookaheadRegExp=/\[([<]?)(>?)[Ii][Mm][Gg](?:\(([^,]*),([^\)]*)\))?\[(?:([^\|\]]+)\|)?([^\[\]\|]+)\](?:\[([^\]]*)\])?\]/mg;
f.handler=function(w) {
	this.lookaheadRegExp.lastIndex = w.matchStart;
	var lookaheadMatch = this.lookaheadRegExp.exec(w.source)
	if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
		var floatLeft=lookaheadMatch[1];
		var floatRight=lookaheadMatch[2];
		var width=lookaheadMatch[3];
		var height=lookaheadMatch[4];
		var tooltip=lookaheadMatch[5];
		var src=lookaheadMatch[6];
		var link=lookaheadMatch[7];

		// Simple bracketted link
		var e = w.output;
		if(link) { // LINKED IMAGE
			if (config.formatterHelpers.isExternalLink(link)) {
				if (config.macros.attach && config.macros.attach.isAttachment(link)) {
					// see [[AttachFilePluginFormatters]]
					e = createExternalLink(w.output,link);
					e.href=config.macros.attach.getAttachment(link);
					e.title = config.macros.attach.linkTooltip + link;
				} else
					e = createExternalLink(w.output,link);
			} else 
				e = createTiddlyLink(w.output,link,false,null,w.isStatic);
			addClass(e,"imageLink");
		}

		var img = createTiddlyElement(e,"img");
		if(floatLeft) img.align="left"; else if(floatRight) img.align="right";
		if(width||height) {
			var x=width.trim(); var y=height.trim();
			var stretchW=(x.substr(x.length-1,1)=='+'); if (stretchW) x=x.substr(0,x.length-1);
			var stretchH=(y.substr(y.length-1,1)=='+'); if (stretchH) y=y.substr(0,y.length-1);
			if (x.substr(0,2)=="{{")
				{ try{x=eval(x.substr(2,x.length-4))} catch(e){displayMessage(e.description||e.toString())} }
			if (y.substr(0,2)=="{{")
				{ try{y=eval(y.substr(2,y.length-4))} catch(e){displayMessage(e.description||e.toString())} }
			img.style.width=x.trim(); img.style.height=y.trim();
			config.formatterHelpers.addStretchHandlers(img,stretchW,stretchH);
		}
		if(tooltip) img.title = tooltip;

		// GET IMAGE SOURCE
		if (config.macros.attach && config.macros.attach.isAttachment(src))
			src=config.macros.attach.getAttachment(src); // see [[AttachFilePluginFormatters]]
		else if (config.formatterHelpers.resolvePath) { // see [[ImagePathPlugin]]
			if (config.browser.isIE || config.browser.isSafari) {
				img.onerror=(function(){
					this.src=config.formatterHelpers.resolvePath(this.src,false);
					return false;
				});
			} else
				src=config.formatterHelpers.resolvePath(src,true);
		}
		img.src=src;
		w.nextMatch = this.lookaheadRegExp.lastIndex;
	}
}

config.formatterHelpers.addStretchHandlers=function(e,stretchW,stretchH) {
	e.title=((stretchW||stretchH)?'DRAG=stretch/shrink, ':'')
		+'SHIFT-CLICK=show full size, CTRL-CLICK=restore initial size';
	e.statusMsg='width=%0, height=%1';
	e.style.cursor='move';
	e.originalW=e.style.width;
	e.originalH=e.style.height;
	e.minW=Math.max(e.offsetWidth/20,10);
	e.minH=Math.max(e.offsetHeight/20,10);
	e.stretchW=stretchW;
	e.stretchH=stretchH;
	e.onmousedown=function(ev) { var ev=ev||window.event;
		this.sizing=true;
		this.startX=!config.browser.isIE?ev.pageX:(ev.clientX+findScrollX());
		this.startY=!config.browser.isIE?ev.pageY:(ev.clientY+findScrollY());
		this.startW=this.offsetWidth;
		this.startH=this.offsetHeight;
		return false;
	};
	e.onmousemove=function(ev) { var ev=ev||window.event;
		if (this.sizing) {
			var s=this.style;
			var currX=!config.browser.isIE?ev.pageX:(ev.clientX+findScrollX());
			var currY=!config.browser.isIE?ev.pageY:(ev.clientY+findScrollY());
			var newW=(currX-this.offsetLeft)/(this.startX-this.offsetLeft)*this.startW;
			var newH=(currY-this.offsetTop )/(this.startY-this.offsetTop )*this.startH;
			if (this.stretchW) s.width =Math.floor(Math.max(newW,this.minW))+'px';
			if (this.stretchH) s.height=Math.floor(Math.max(newH,this.minH))+'px';
			clearMessage(); displayMessage(this.statusMsg.format([s.width,s.height]));
		}
		return false;
	};
	e.onmouseup=function(ev) { var ev=ev||window.event;
		if (ev.shiftKey) { this.style.width=this.style.height=''; }
		if (ev.ctrlKey)  { this.style.width=this.originalW; this.style.height=this.originalH; }
		this.sizing=false;
		clearMessage();
		return false;
	};
	e.onmouseout=function(ev) { var ev=ev||window.event;
		this.sizing=false;
		clearMessage();
		return false;
	};
}
//}}}
The plugins in this package provide interactive functionality for importing/exporting tiddlers to/from other TiddlyWiki documents.  Additional plugins provide enhanced local/remote file I/O features, including "save as", "save from web" and "upload" functionality.
/***
|Name|ImportTiddlersPlugin|
|Source|http://www.TiddlyTools.com/#ImportTiddlersPlugin|
|Documentation|http://www.TiddlyTools.com/#ImportTiddlersPluginInfo|
|Version|4.6.0|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|interactive controls for import/export with filtering.|
Combine tiddlers from any two TiddlyWiki documents.  Interactively select and copy tiddlers from another TiddlyWiki source document.  Includes prompting for skip, rename, merge or replace actions when importing tiddlers that match existing titles.  When done, a list of all imported tiddlers is written into [[ImportedTiddlers]].
!!!!!Documentation
<<<
see [[ImportTiddlersPluginInfo]] for details
<<<
!!!!!interactive control panel
<<<
<<importTiddlers inline>>
{{clear{
^^(see also: [[ImportTiddlers]] shadow tiddler)^^}}}
<<<
!!!!!Revisions
<<<
2009.10.06 4.6.0 added createTiddlerFromFile (import text files)
|please see [[ImportTiddlersPluginInfo]] for additional revision details|
2005.07.20 1.0.0 Initial Release
<<<
!!!!!Code
***/
//{{{
version.extensions.ImportTiddlersPlugin= {major: 4, minor: 6, revision: 0, date: new Date(2009,10,6)};

// IE needs explicit global scoping for functions/vars called from browser events
window.onClickImportButton=onClickImportButton;
window.refreshImportList=refreshImportList;

// default cookie/option values
if (!config.options.chkImportReport) config.options.chkImportReport=true;

// default shadow definition
config.shadowTiddlers.ImportTiddlers='<<importTiddlers inline>>';

// use shadow tiddler content in backstage panel
if (config.tasks) config.tasks.importTask.content='<<tiddler ImportTiddlers>>' // TW2.2 or above
//}}}
//{{{
// backward-compatiblity for TW2.0.x and TW1.2.x
if (config.macros.importTiddlers==undefined) config.macros.importTiddlers={};
if (typeof merge=='undefined') {
	function merge(dst,src,preserveExisting) {
		for(var i in src) { if(!preserveExisting || dst[i] === undefined) dst[i] = src[i]; }
		return dst;
	}
}
if (config.browser.isGecko===undefined)
	config.browser.isGecko=(config.userAgent.indexOf('gecko')!=-1);
//}}}
//{{{
merge(config.macros.importTiddlers,{
	$: function(id) { return document.getElementById(id); }, // abbreviation
	label: 'import tiddlers',
	prompt: 'Copy tiddlers from another document',
	openMsg: 'Opening %0',
	openErrMsg: 'Could not open %0 - error=%1',
	readMsg: 'Read %0 bytes from %1',
	foundMsg: 'Found %0 tiddlers in %1',
	filterMsg: "Filtered %0 tiddlers matching '%1'",
	summaryMsg: '%0 tiddler%1 in the list',
	summaryFilteredMsg: '%0 of %1 tiddler%2 in the list',
	plural: 's are',
	single: ' is',
	countMsg: '%0 tiddlers selected for import',
	processedMsg: 'Processed %0 tiddlers',
	importedMsg: 'Imported %0 of %1 tiddlers from %2',
	loadText: 'please load a document...',
	closeText: 'close',
	doneText: 'done',
	startText: 'import',
	stopText: 'stop',
	local: true,		// default to import from local file
	src: '',		// path/filename or URL of document to import (retrieved from SiteUrl)
	proxy: '',		// URL for remote proxy script (retrieved from SiteProxy)
	useProxy: false,	// use specific proxy script in front of remote URL
	inbound: null,		// hash-indexed array of tiddlers from other document
	newTags: '',		// text of tags added to imported tiddlers
	addTags: true,		// add new tags to imported tiddlers
	listsize: 10,		// # of lines to show in imported tiddler list
	importTags: true,	// include tags from remote source document when importing a tiddler
	keepTags: true,		// retain existing tags when replacing a tiddler
	sync: false,		// add 'server' fields to imported tiddlers (for sync function)
	lastFilter: '',		// most recent filter (URL hash) applied
	lastAction: null,	// most recent collision button performed
	index: 0,		// current processing index in import list
	sort: ''		// sort order for imported tiddler listbox
});
//}}}
//{{{
// hijack core macro handler
if (config.macros.importTiddlers.coreHandler==undefined)
	config.macros.importTiddlers.coreHandler=config.macros.importTiddlers.handler;

config.macros.importTiddlers.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
	if (!params[0] || params[0].toLowerCase()=='core') { // default to built in
		if (config.macros.importTiddlers.coreHandler)
			config.macros.importTiddlers.coreHandler.apply(this,arguments);
		else 
			createTiddlyButton(place,this.label,this.prompt,onClickImportMenu);
	} else if (params[0]=='link') { // show link to floating panel
		createTiddlyButton(place,params[1]||this.label,params[2]||this.prompt,onClickImportMenu);
	} else if (params[0]=='inline') {// show panel as INLINE tiddler content
		createImportPanel(place);
		this.$('importPanel').style.position='static';
		this.$('importPanel').style.display='block';
	} else if (config.macros.loadTiddlers)
		config.macros.loadTiddlers.handler(place,macroName,params); // any other params: loadtiddlers
}
//}}}
//{{{
// Handle link click to create/show/hide control panel
function onClickImportMenu(e) { var e=e||window.event;
	var parent=resolveTarget(e).parentNode;
	var panel=document.getElementById('importPanel');
	if (panel==undefined || panel.parentNode!=parent) panel=createImportPanel(parent);
	var isOpen=panel.style.display=='block';
	if(config.options.chkAnimate)
		anim.startAnimating(new Slider(panel,!isOpen,false,'none'));
	else
		panel.style.display=isOpen?'none':'block';
	e.cancelBubble = true; if (e.stopPropagation) e.stopPropagation(); return(false);
}
//}}}
//{{{
// Create control panel: HTML, CSS
function createImportPanel(place) {
	var cmi=config.macros.importTiddlers; // abbrev
	var panel=cmi.$('importPanel');
	if (panel) { panel.parentNode.removeChild(panel); }
	setStylesheet(store.getTiddlerText('ImportTiddlersPlugin##css'),'importTiddlers');
	panel=createTiddlyElement(place,'span','importPanel',null,null)
	panel.innerHTML=store.getTiddlerText('ImportTiddlersPlugin##html');
	refreshImportList();
	if (!cmi.src.length) cmi.src=store.getTiddlerText('SiteUrl')||'';
	cmi.$('importSourceURL').value=cmi.src;
	if (!cmi.proxy.length) cmi.proxy=store.getTiddlerText('SiteProxy')||'SiteProxy';
	cmi.$('importSiteProxy').value=cmi.proxy;
	if (config.browser.isGecko) { // FF3 FIXUP
		cmi.$('fileImportSource').style.display='none';
		cmi.$('importLocalPanelFix').style.display='block';
	}
	cmi.$('chkSync').checked=cmi.sync;
	cmi.$('chkImportTags').checked=cmi.importTags;
	cmi.$('chkKeepTags').checked=cmi.keepTags;
	cmi.$('chkAddTags').checked=cmi.addTags;
	cmi.$('txtNewTags').value=cmi.newTags;
	cmi.$('txtNewTags').style.display=cmi.addTags?'block':'none';
	cmi.$('chkSync').checked=cmi.sync;
	cmi.$('chkImportReport').checked=config.options.chkImportReport;
	return panel;
}
//}}}
//{{{
// process control interactions
function onClickImportButton(which,event) {
	var cmi=config.macros.importTiddlers; // abbreviation
	var list=cmi.$('importList'); if (!list) return false;
	var thePanel=cmi.$('importPanel');
	var theCollisionPanel=cmi.$('importCollisionPanel');
	var theNewTitle=cmi.$('importNewTitle');
	var count=0;
	switch (which.id)
		{
		case 'importFromFile':	// show local panel
		case 'importFromWeb':	// show HTTP panel
			cmi.local=(which.id=='importFromFile');
			cmi.showPanel('importLocalPanel',cmi.local);
			cmi.showPanel('importHTTPPanel',!cmi.local);
			break;
		case 'importOptions':	// show/hide options panel
			cmi.showPanel('importOptionsPanel',cmi.$('importOptionsPanel').style.display=='none');
			break;
		case 'fileImportSource':
		case 'importLoad':		// load import source into hidden frame
			importReport();		// if an import was in progress, generate a report
			cmi.inbound=null;	// clear the imported tiddler buffer
			refreshImportList();	// reset/resize the listbox
			if (cmi.src=='') break;
			// Load document, read it's DOM and fill the list
			cmi.loadRemoteFile(cmi.src,cmi.filterTiddlerList);
			break;
		case 'importSelectFeed':	// select a pre-defined systemServer feed URL
			var p=Popup.create(which); if (!p) return false;
			var tids=store.getTaggedTiddlers('systemServer');
			if (!tids.length)
				createTiddlyText(createTiddlyElement(p,'li'),'no pre-defined server feeds');
			for (var t=0; t<tids.length; t++) {
				var u=store.getTiddlerSlice(tids[t].title,'URL');
				var d=store.getTiddlerSlice(tids[t].title,'Description');
				if (!d||!d.length) d=store.getTiddlerSlice(tids[t].title,'description');
				if (!d||!d.length) d=u;
				createTiddlyButton(createTiddlyElement(p,'li'),tids[t].title,d,
					function(){
						var u=this.getAttribute('url');
						document.getElementById('importSourceURL').value=u;
						config.macros.importTiddlers.src=u;
						document.getElementById('importLoad').onclick();
					},
					null,null,null,{url:u});
			}
			Popup.show();
			event.cancelBubble = true;
			if (event.stopPropagation) event.stopPropagation();
			return false;
			// create popup with feed list
			// onselect, insert feed URL into input field.
			break;
		case 'importSelectAll':		// select all tiddler list items (i.e., not headings)
			importReport();		// if an import was in progress, generate a report
			for (var t=0,count=0; t < list.options.length; t++) {
				if (list.options[t].value=='') continue;
				list.options[t].selected=true;
				count++;
			}
			clearMessage(); displayMessage(cmi.countMsg.format([count]));
			cmi.$('importStart').disabled=!count;
			break;
		case 'importSelectNew':		// select tiddlers not in current document
			importReport();		// if an import was in progress, generate a report
			for (var t=0,count=0; t < list.options.length; t++) {
				list.options[t].selected=false;
				if (list.options[t].value=='') continue;
				list.options[t].selected=!store.tiddlerExists(list.options[t].value);
				count+=list.options[t].selected?1:0;
			}
			clearMessage(); displayMessage(cmi.countMsg.format([count]));
			cmi.$('importStart').disabled=!count;
			break;
		case 'importSelectChanges':		// select tiddlers that are updated from existing tiddlers
			importReport();		// if an import was in progress, generate a report
			for (var t=0,count=0; t < list.options.length; t++) {
				list.options[t].selected=false;
				if (list.options[t].value==''||!store.tiddlerExists(list.options[t].value)) continue;
				for (var i=0; i<cmi.inbound.length; i++) // find matching inbound tiddler
					{ var inbound=cmi.inbound[i]; if (inbound.title==list.options[t].value) break; }
				list.options[t].selected=(inbound.modified-store.getTiddler(list.options[t].value).modified>0); // updated tiddler
				count+=list.options[t].selected?1:0;
			}
			clearMessage(); displayMessage(cmi.countMsg.format([count]));
			cmi.$('importStart').disabled=!count;
			break;
		case 'importSelectDifferences':		// select tiddlers that are new or different from existing tiddlers
			importReport();		// if an import was in progress, generate a report
			for (var t=0,count=0; t < list.options.length; t++) {
				list.options[t].selected=false;
				if (list.options[t].value=='') continue;
				if (!store.tiddlerExists(list.options[t].value)) { list.options[t].selected=true; count++; continue; }
				for (var i=0; i<cmi.inbound.length; i++) // find matching inbound tiddler
					{ var inbound=cmi.inbound[i]; if (inbound.title==list.options[t].value) break; }
				list.options[t].selected=(inbound.modified-store.getTiddler(list.options[t].value).modified!=0); // changed tiddler
				count+=list.options[t].selected?1:0;
			}
			clearMessage(); displayMessage(cmi.countMsg.format([count]));
			cmi.$('importStart').disabled=!count;
			break;
		case 'importApplyFilter':	// filter list to include only matching tiddlers
			importReport();		// if an import was in progress, generate a report
			clearMessage();
			if (!cmi.all) // no tiddlers loaded = '0 selected'
				{ displayMessage(cmi.countMsg.format([0])); return false; }
			var hash=cmi.$('importLastFilter').value;
			cmi.inbound=cmi.filterByHash('#'+hash,cmi.all);
			refreshImportList();	// reset/resize the listbox
			break;
		case 'importStart':		// initiate the import processing
			importReport();		// if an import was in progress, generate a report
			cmi.$('importApplyToAll').checked=false;
			cmi.$('importStart').value=cmi.stopText;
			if (cmi.index>0) cmi.index=-1; // stop processing
			else cmi.index=importTiddlers(0); // or begin processing
			importStopped();
			break;
		case 'importClose':		// unload imported tiddlers or hide the import control panel
			// if imported tiddlers not loaded, close the import control panel
			if (!cmi.inbound) { thePanel.style.display='none'; break; }
			importReport();		// if an import was in progress, generate a report
			cmi.inbound=null;	// clear the imported tiddler buffer
			refreshImportList();	// reset/resize the listbox
			break;
		case 'importSkip':	// don't import the tiddler
			cmi.lastAction=which;
			var theItem	= list.options[cmi.index];
			for (var j=0;j<cmi.inbound.length;j++)
			if (cmi.inbound[j].title==theItem.value) break;
			var theImported = cmi.inbound[j];
			theImported.status='skipped after asking';			// mark item as skipped
			theCollisionPanel.style.display='none';
			cmi.index=importTiddlers(cmi.index+1);	// resume with NEXT item
			importStopped();
			break;
		case 'importRename':		// change name of imported tiddler
			cmi.lastAction=which;
			var theItem		= list.options[cmi.index];
			for (var j=0;j<cmi.inbound.length;j++)
			if (cmi.inbound[j].title==theItem.value) break;
			var theImported		= cmi.inbound[j];
			theImported.status	= 'renamed from '+theImported.title;	// mark item as renamed
			theImported.set(theNewTitle.value,null,null,null,null);		// change the tiddler title
			theItem.value		= theNewTitle.value;			// change the listbox item text
			theItem.text		= theNewTitle.value;			// change the listbox item text
			theCollisionPanel.style.display='none';
			cmi.index=importTiddlers(cmi.index);	// resume with THIS item
			importStopped();
			break;
		case 'importMerge':	// join existing and imported tiddler content
			cmi.lastAction=which;
			var theItem	= list.options[cmi.index];
			for (var j=0;j<cmi.inbound.length;j++)
			if (cmi.inbound[j].title==theItem.value) break;
			var theImported	= cmi.inbound[j];
			var theExisting	= store.getTiddler(theItem.value);
			var theText	= theExisting.text+'\n----\n^^merged from: ';
			theText		+='[['+cmi.src+'#'+theItem.value+'|'+cmi.src+'#'+theItem.value+']]^^\n';
			theText		+='^^'+theImported.modified.toLocaleString()+' by '+theImported.modifier+'^^\n'+theImported.text;
			var theDate	= new Date();
			var theTags	= theExisting.getTags()+' '+theImported.getTags();
			theImported.set(null,theText,null,theDate,theTags);
			theImported.status   = 'merged with '+theExisting.title;	// mark item as merged
			theImported.status  += ' - '+theExisting.modified.formatString('MM/DD/YYYY 0hh:0mm:0ss');
			theImported.status  += ' by '+theExisting.modifier;
			theCollisionPanel.style.display='none';
			cmi.index=importTiddlers(cmi.index);	// resume with this item
			importStopped();
			break;
		case 'importReplace':		// substitute imported tiddler for existing tiddler
			cmi.lastAction=which;
			var theItem		  = list.options[cmi.index];
			for (var j=0;j<cmi.inbound.length;j++)
			if (cmi.inbound[j].title==theItem.value) break;
			var theImported     = cmi.inbound[j];
			var theExisting	  = store.getTiddler(theItem.value);
			theImported.status  = 'replaces '+theExisting.title;		// mark item for replace
			theImported.status += ' - '+theExisting.modified.formatString('MM/DD/YYYY 0hh:0mm:0ss');
			theImported.status += ' by '+theExisting.modifier;
			theCollisionPanel.style.display='none';
			cmi.index=importTiddlers(cmi.index);	// resume with THIS item
			importStopped();
			break;
		case 'importListSmaller':		// decrease current listbox size, minimum=5
			if (list.options.length==1) break;
			list.size-=(list.size>5)?1:0;
			cmi.listsize=list.size;
			break;
		case 'importListLarger':		// increase current listbox size, maximum=number of items in list
			if (list.options.length==1) break;
			list.size+=(list.size<list.options.length)?1:0;
			cmi.listsize=list.size;
			break;
		case 'importListMaximize':	// toggle listbox size between current and maximum
			if (list.options.length==1) break;
			list.size=(list.size==list.options.length)?cmi.listsize:list.options.length;
			break;
		}
}
//}}}
//{{{
config.macros.importTiddlers.showPanel=function(place,show,skipAnim) {
	if (typeof place=='string') var place=document.getElementById(place);
	if (!place||!place.style) return;
	if(!skipAnim && anim && config.options.chkAnimate) anim.startAnimating(new Slider(place,show,false,'none'));
	else place.style.display=show?'block':'none';
}
//}}}
//{{{
function refreshImportList(selectedIndex) {
	var cmi=config.macros.importTiddlers; // abbrev
	var list=cmi.$('importList'); if (!list) return;
	// if nothing to show, reset list content and size
	if (!cmi.inbound) {
		while (list.length > 0) { list.options[0] = null; }
		list.options[0]=new Option(cmi.loadText,'',false,false);
		list.size=cmi.listsize;
		cmi.$('importLoad').disabled=false;
		cmi.$('importLoad').style.display='inline';
		cmi.$('importStart').disabled=true;
		cmi.$('importOptions').disabled=true;
		cmi.$('importOptions').style.display='none';
		cmi.$('fileImportSource').disabled=false;
		cmi.$('importFromFile').disabled=false;
		cmi.$('importFromWeb').disabled=false;
		cmi.$('importStart').value=cmi.startText;
		cmi.$('importClose').value=cmi.doneText;
		cmi.$('importSelectPanel').style.display='none';
		cmi.$('importOptionsPanel').style.display='none';
		return;
	}
	// there are inbound tiddlers loaded...
	cmi.$('importLoad').disabled=true;
	cmi.$('importLoad').style.display='none';
	cmi.$('importOptions').style.display='inline';
	cmi.$('importOptions').disabled=false;
	cmi.$('fileImportSource').disabled=true;
	cmi.$('importFromFile').disabled=true;
	cmi.$('importFromWeb').disabled=true;
	cmi.$('importClose').value=cmi.closeText;
	if (cmi.$('importSelectPanel').style.display=='none')
		cmi.showPanel('importSelectPanel',true);

	// get the sort order
	if (!selectedIndex)   selectedIndex=0;
	if (selectedIndex==0) cmi.sort='title';		// heading
	if (selectedIndex==1) cmi.sort='title';
	if (selectedIndex==2) cmi.sort='modified';
	if (selectedIndex==3) cmi.sort='tags';
	if (selectedIndex>3) {
		// display selected tiddler count
		for (var t=0,count=0; t < list.options.length; t++) {
			if (!list.options[t].selected) continue;
			if (list.options[t].value!='')
				count+=1;
			else { // if heading is selected, deselect it, and then select and count all in section
				list.options[t].selected=false;
				for ( t++; t<list.options.length && list.options[t].value!=''; t++) {
					list.options[t].selected=true;
					count++;
				}
			}
		}
		clearMessage(); displayMessage(cmi.countMsg.format([count]));
	}
	cmi.$('importStart').disabled=!count;
	if (selectedIndex>3) return; // no refresh needed

	// get the alphasorted list of tiddlers
	var tiddlers=cmi.inbound;
	tiddlers.sort(function (a,b) {if(a['title'] == b['title']) return(0); else return (a['title'] < b['title']) ? -1 : +1; });
	// clear current list contents
	while (list.length > 0) { list.options[0] = null; }
	// add heading and control items to list
	var i=0;
	var indent=String.fromCharCode(160)+String.fromCharCode(160);
	if (cmi.all.length==tiddlers.length)
		var summary=cmi.summaryMsg.format([tiddlers.length,(tiddlers.length!=1)?cmi.plural:cmi.single]);
	else
		var summary=cmi.summaryFilteredMsg.format([tiddlers.length,cmi.all.length,(cmi.all.length!=1)?cmi.plural:cmi.single]);
	list.options[i++]=new Option(summary,'',false,false);
	list.options[i++]=new Option(((cmi.sort=='title'   )?'>':indent)+' [by title]','',false,false);
	list.options[i++]=new Option(((cmi.sort=='modified')?'>':indent)+' [by date]','',false,false);
	list.options[i++]=new Option(((cmi.sort=='tags')?'>':indent)+' [by tags]','',false,false);
	// output the tiddler list
	switch(cmi.sort) {
		case 'title':
			for(var t = 0; t < tiddlers.length; t++)
				list.options[i++] = new Option(tiddlers[t].title,tiddlers[t].title,false,false);
			break;
		case 'modified':
			// sort descending for newest date first
			tiddlers.sort(function (a,b) {if(a['modified'] == b['modified']) return(0); else return (a['modified'] > b['modified']) ? -1 : +1; });
			var lastSection = '';
			for(var t = 0; t < tiddlers.length; t++) {
				var tiddler = tiddlers[t];
				var theSection = tiddler.modified.toLocaleDateString();
				if (theSection != lastSection) {
					list.options[i++] = new Option(theSection,'',false,false);
					lastSection = theSection;
				}
				list.options[i++] = new Option(indent+indent+tiddler.title,tiddler.title,false,false);
			}
			break;
		case 'tags':
			var theTitles = {}; // all tiddler titles, hash indexed by tag value
			var theTags = new Array();
			for(var t=0; t<tiddlers.length; t++) {
				var title=tiddlers[t].title;
				var tags=tiddlers[t].tags;
				if (!tags || !tags.length) {
					if (theTitles['untagged']==undefined) { theTags.push('untagged'); theTitles['untagged']=new Array(); }
					theTitles['untagged'].push(title);
				}
				else for(var s=0; s<tags.length; s++) {
					if (theTitles[tags[s]]==undefined) { theTags.push(tags[s]); theTitles[tags[s]]=new Array(); }
					theTitles[tags[s]].push(title);
				}
			}
			theTags.sort();
			for(var tagindex=0; tagindex<theTags.length; tagindex++) {
				var theTag=theTags[tagindex];
				list.options[i++]=new Option(theTag,'',false,false);
				for(var t=0; t<theTitles[theTag].length; t++)
					list.options[i++]=new Option(indent+indent+theTitles[theTag][t],theTitles[theTag][t],false,false);
			}
			break;
		}
	list.selectedIndex=selectedIndex;		  // select current control item
	if (list.size<cmi.listsize) list.size=cmi.listsize;
	if (list.size>list.options.length) list.size=list.options.length;
}
//}}}
//{{{
// re-entrant processing for handling import with interactive collision prompting
function importTiddlers(startIndex) {
	var cmi=config.macros.importTiddlers; // abbrev
	if (!cmi.inbound) return -1;
	var list=cmi.$('importList'); if (!list) return;
	var t;
	// if starting new import, reset import status flags
	if (startIndex==0)
		for (var t=0;t<cmi.inbound.length;t++)
			cmi.inbound[t].status='';
	for (var i=startIndex; i<list.options.length; i++) {
		// if list item is not selected or is a heading (i.e., has no value), skip it
		if ((!list.options[i].selected) || ((t=list.options[i].value)==''))
			continue;
		for (var j=0;j<cmi.inbound.length;j++)
			if (cmi.inbound[j].title==t) break;
		var inbound = cmi.inbound[j];
		var theExisting = store.getTiddler(inbound.title);
		// avoid redundant import for tiddlers that are listed multiple times (when 'by tags')
		if (inbound.status=='added')
			continue;
		// don't import the 'ImportedTiddlers' history from the other document...
		if (inbound.title=='ImportedTiddlers')
			continue;
		// if tiddler exists and import not marked for replace or merge, stop importing
		if (theExisting && (inbound.status.substr(0,7)!='replace') && (inbound.status.substr(0,5)!='merge'))
			return i;
		// assemble tags (remote + existing + added)
		var newTags = '';
		if (cmi.importTags)
			newTags+=inbound.getTags()	// import remote tags
		if (cmi.keepTags && theExisting)
			newTags+=' '+theExisting.getTags(); // keep existing tags
		if (cmi.addTags && cmi.newTags.trim().length)
			newTags+=' '+cmi.newTags; // add new tags
		inbound.set(null,null,null,null,newTags.trim());
		// set the status to 'added' (if not already set by the 'ask the user' UI)
		inbound.status=(inbound.status=='')?'added':inbound.status;
		// set sync fields
		if (cmi.sync) {
			if (!inbound.fields) inbound.fields={}; // for TW2.1.x backward-compatibility
			inbound.fields['server.page.revision']=inbound.modified.convertToYYYYMMDDHHMM();
			inbound.fields['server.type']='file';
			inbound.fields['server.host']=(cmi.local&&!cmi.src.startsWith('file:')?'file:///':'')+cmi.src;
		}
		// do the import!
		store.suspendNotifications();
		store.saveTiddler(inbound.title, inbound.title, inbound.text, inbound.modifier, inbound.modified, inbound.tags, inbound.fields, true, inbound.created);
                store.fetchTiddler(inbound.title).created = inbound.created; // force creation date to imported value (needed for TW2.1.x and earlier)
		store.resumeNotifications();
		}
	return(-1);	// signals that we really finished the entire list
}
function importStopped() {
	var cmi=config.macros.importTiddlers; // abbrev
	var list=cmi.$('importList'); if (!list) return;
	var theNewTitle=cmi.$('importNewTitle');
	if (cmi.index==-1){ 
		cmi.$('importStart').value=cmi.startText;
		importReport();	// import finished... generate the report
	} else {
		// import collision...
		// show the collision panel and set the title edit field
		cmi.$('importStart').value=cmi.stopText;
		cmi.showPanel('importCollisionPanel',true);
		theNewTitle.value=list.options[cmi.index].value;
		if (cmi.$('importApplyToAll').checked && cmi.lastAction && cmi.lastAction.id!='importRename')
			onClickImportButton(cmi.lastAction);
	}
}
//}}}
//{{{
function importReport() {
	var cmi=config.macros.importTiddlers; // abbrev
	if (!cmi.inbound) return;
	// if import was not completed, the collision panel will still be open... close it now.
	var panel=cmi.$('importCollisionPanel'); if (panel) panel.style.display='none';
	// get the alphasorted list of tiddlers
	var tiddlers = cmi.inbound;
	// gather the statistics
	var count=0; var total=0;
	for (var t=0; t<tiddlers.length; t++) {
		if (!tiddlers[t].status || !tiddlers[t].status.trim().length) continue;
		if (tiddlers[t].status.substr(0,7)!='skipped') count++;
		total++;
	}
	// generate a report
	if (total) displayMessage(cmi.processedMsg.format([total]));
	if (count && config.options.chkImportReport) {
		// get/create the report tiddler
		var theReport = store.getTiddler('ImportedTiddlers');
		if (!theReport) { theReport=new Tiddler(); theReport.title='ImportedTiddlers'; theReport.text=''; }
		// format the report content
		var now = new Date();
		var newText = 'On '+now.toLocaleString()+', '+config.options.txtUserName
		newText +=' imported '+count+' tiddler'+(count==1?'':'s')+' from\n[['+cmi.src+'|'+cmi.src+']]:\n';
		if (cmi.addTags && cmi.newTags.trim().length)
			newText += 'imported tiddlers were tagged with: "'+cmi.newTags+'"\n';
		newText += '<<<\n';
		for (var t=0; t<tiddlers.length; t++) if (tiddlers[t].status)
			newText += '#[['+tiddlers[t].title+']] - '+tiddlers[t].status+'\n';
		newText += '<<<\n';
		// update the ImportedTiddlers content and show the tiddler
		theReport.text	 = newText+((theReport.text!='')?'\n----\n':'')+theReport.text;
		theReport.modifier = config.options.txtUserName;
		theReport.modified = new Date();
                store.saveTiddler(theReport.title, theReport.title, theReport.text, theReport.modifier, theReport.modified, theReport.tags, theReport.fields);
		story.displayTiddler(null,theReport.title,1,null,null,false);
		story.refreshTiddler(theReport.title,1,true);
	}
	// reset status flags
	for (var t=0; t<cmi.inbound.length; t++) cmi.inbound[t].status='';
	// mark document as dirty and let display update as needed
	if (count) { store.setDirty(true); store.notifyAll(); }
	// always show final message when tiddlers were actually loaded
	if (count) displayMessage(cmi.importedMsg.format([count,tiddlers.length,cmi.src.replace(/%20/g,' ')]));
}
//}}}
//{{{
// // File and XMLHttpRequest I/O
config.macros.importTiddlers.askForFilename=function(here) {
	var msg=here.title; // use tooltip as dialog box message
	var path=getLocalPath(document.location.href);
	var slashpos=path.lastIndexOf('/'); if (slashpos==-1) slashpos=path.lastIndexOf('\\'); 
	if (slashpos!=-1) path = path.substr(0,slashpos+1); // remove filename from path, leave the trailing slash
	var file='';
	var result='';
	if(window.Components) { // moz
		try {
			netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');

			var nsIFilePicker = window.Components.interfaces.nsIFilePicker;
			var picker = Components.classes['@mozilla.org/filepicker;1'].createInstance(nsIFilePicker);
			picker.init(window, msg, nsIFilePicker.modeOpen);
			var thispath = Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsILocalFile);
			thispath.initWithPath(path);
			picker.displayDirectory=thispath;
			picker.defaultExtension='html';
			picker.defaultString=file;
			picker.appendFilters(nsIFilePicker.filterAll|nsIFilePicker.filterText|nsIFilePicker.filterHTML);
			if (picker.show()!=nsIFilePicker.returnCancel) var result=picker.file.persistentDescriptor;
		}
		catch(e) { alert('error during local file access: '+e.toString()) }
	}
	else { // IE
		try { // XPSP2 IE only
			var s = new ActiveXObject('UserAccounts.CommonDialog');
			s.Filter='All files|*.*|Text files|*.txt|HTML files|*.htm;*.html|';
			s.FilterIndex=3; // default to HTML files;
			s.InitialDir=path;
			s.FileName=file;
			if (s.showOpen()) var result=s.FileName;
		}
		catch(e) {  // fallback
			var result=prompt(msg,path+file);
		}
	}
	return result;
}

config.macros.importTiddlers.loadRemoteFile = function(src,callback) {
	if (src==undefined || !src.length) return null; // filename is required
	var original=src; // URL as specified
	var hashpos=src.indexOf('#'); if (hashpos!=-1) src=src.substr(0,hashpos); // URL with #... suffix removed (needed for IE)
	clearMessage();
	displayMessage(this.openMsg.format([src.replace(/%20/g,' ')]));
	if (src.substr(0,5)!='http:' && src.substr(0,5)!='file:') { // if not a URL, read from local filesystem
		var txt=loadFile(src);
		if (!txt) { // file didn't load, might be relative path.. try fixup
			var pathPrefix=document.location.href;  // get current document path and trim off filename
			var slashpos=pathPrefix.lastIndexOf('/'); if (slashpos==-1) slashpos=pathPrefix.lastIndexOf('\\'); 
			if (slashpos!=-1 && slashpos!=pathPrefix.length-1) pathPrefix=pathPrefix.substr(0,slashpos+1);
			src=pathPrefix+src;
			if (pathPrefix.substr(0,5)!='http:') src=getLocalPath(src);
			var txt=loadFile(src);
		}
		if (!txt) { // file still didn't load, report error
			displayMessage(config.macros.importTiddlers.openErrMsg.format([src.replace(/%20/g,' '),'(filesystem error)']));
		} else {
			displayMessage(config.macros.importTiddlers.readMsg.format([txt.length,src.replace(/%20/g,' ')]));
			if (version.major+version.minor*.1+version.revision*.01!=2.52) txt=convertUTF8ToUnicode(txt);
			if (callback) callback(true,original,txt,src,null);
		}
	} else {
		doHttp('GET',src,null,null,config.options.txtRemoteUsername,config.options.txtRemotePassword,callback,original,null);
	}
}

config.macros.importTiddlers.readTiddlersFromHTML=function(html){
	var remoteStore=new TiddlyWiki();
	remoteStore.importTiddlyWiki(html);
	return remoteStore.getTiddlers('title');	
}

config.macros.importTiddlers.readTiddlersFromCSV=function(CSV){
	var remoteStore=new TiddlyWiki();
	// GET NAMES
	var lines=CSV.replace(/\r/g,'').split('\n');
	var names=lines.shift().replace(/"/g,'').split(',');
	CSV=lines.join('\n');
	// ENCODE commas and newlines within quoted values
	var comma='!~comma~!'; var commaRE=new RegExp(comma,'g');
	var newline='!~newline~!'; var newlineRE=new RegExp(newline,'g');
	CSV=CSV.replace(/"([^"]*?)"/g,
		function(x){ return x.replace(/\,/g,comma).replace(/\n/g,newline); });
	// PARSE lines
	var lines=CSV.split('\n');
	for (var i=0; i<lines.length; i++) { if (!lines[i].length) continue;
		var values=lines[i].split(',');
		// DECODE commas, newlines, and doubled-quotes, and remove enclosing quotes (if any)
		for (var v=0; v<values.length; v++)
			values[v]=values[v].replace(commaRE,',').replace(newlineRE,'\n')
				.replace(/^"|"$/g,'').replace(/""/g,'"');
		// EXTRACT tiddler values
		var title=''; var text=''; var tags=[]; var fields={};
		var created=null; var when=new Date(); var who=config.options.txtUserName;
		for (var v=0; v<values.length; v++) { var val=values[v];
			if (names[v]) switch(names[v].toLowerCase()) {
				case 'title':	title=val.replace(/\[\]\|/g,'_'); break;
				case 'created': created=new Date(val); break;
				case 'modified':when=new Date(val); break;
				case 'modifier':who=val; break;
				case 'text':	text=val; break;
				case 'tags':	tags=val.readBracketedList(); break;
				default:	fields[names[v].toLowerCase()]=val; break;
			}
		}
		// CREATE tiddler in temporary store
		if (title.length)
			remoteStore.saveTiddler(title,title,text,who,when,tags,fields,true,created||when);
	}
	return remoteStore.getTiddlers('title');
}

config.macros.importTiddlers.createTiddlerFromFile=function(src,txt) {
	var t=new Tiddler();
	var pos=src.lastIndexOf("/"); if (pos==-1) pos=src.lastIndexOf("\\");
	t.title=pos==-1?src:src.substr(pos+1);
	t.text=txt; 
	t.created=t.modified=new Date();
	t.modifier=config.options.txtUserName;
	if (src.substr(src.length-3,3)=='.js') t.tags=['systemConfig'];
	return [t];
}

config.macros.importTiddlers.filterTiddlerList=function(success,params,txt,src,xhr){
	var cmi=config.macros.importTiddlers; // abbreviation
	var src=src.replace(/%20/g,' ');
	if (!success) { displayMessage(cmi.openErrMsg.format([src,xhr.status])); return; }
	cmi.all=cmi.readTiddlersFromHTML(txt);
	if (!cmi.all||!cmi.all.length) cmi.all=cmi.readTiddlersFromCSV(txt)
	if (!cmi.all||!cmi.all.length) cmi.all=cmi.createTiddlerFromFile(src,txt)
	var count=cmi.all?cmi.all.length:0;
	var querypos=src.lastIndexOf('?'); if (querypos!=-1) src=src.substr(0,querypos);
	displayMessage(cmi.foundMsg.format([count,src]));
	cmi.inbound=cmi.filterByHash(params,cmi.all); // use full URL including hash (if any)
	cmi.$('importLastFilter').value=cmi.lastFilter;
	window.refreshImportList(0);
}

config.macros.importTiddlers.filterByHash=function(src,tiddlers){
	var hashpos=src.lastIndexOf('#'); if (hashpos==-1) return tiddlers;
	var hash=src.substr(hashpos+1); if (!hash.length) return tiddlers;
	var tids=[];
	var params=hash.parseParams('anon',null,true,false,false);
	for (var p=1; p<params.length; p++) {
		switch (params[p].name) {
			case 'anon':
			case 'open':
				tids.pushUnique(params[p].value);
				break;
			case 'tag':
				if (store.getMatchingTiddlers) { // for boolean expressions - see MatchTagsPlugin
					var r=store.getMatchingTiddlers(params[p].value,null,tiddlers);
					for (var t=0; t<r.length; t++) tids.pushUnique(r[t].title);
				} else for (var t=0; t<tiddlers.length; t++)
					if (tiddlers[t].isTagged(params[p].value))
						tids.pushUnique(tiddlers[t].title);
				break;
			case 'story':
				for (var t=0; t<tiddlers.length; t++)
					if (tiddlers[t].title==params[p].value) {
						tiddlers[t].changed();
						for (var s=0; s<tiddlers[t].links.length; s++)
							tids.pushUnique(tiddlers[t].links[s]);
						break;
					}
				break;
			case 'search':
				for (var t=0; t<tiddlers.length; t++)
					if (tiddlers[t].text.indexOf(params[p].value)!=-1)
						tids.pushUnique(tiddlers[t].title);
				break;
		}
	}
	var matches=[];
	for (var t=0; t<tiddlers.length; t++)
		if (tids.contains(tiddlers[t].title))
			matches.push(tiddlers[t]);
	displayMessage(config.macros.importTiddlers.filterMsg.format([matches.length,hash]));
	config.macros.importTiddlers.lastFilter=hash;
	return matches;
}
//}}}
/***
!!!Control panel CSS
//{{{
!css
#importPanel {
	display: none; position:absolute; z-index:11; width:35em; right:105%; top:3em;
	background-color: #eee; color:#000; font-size: 8pt; line-height:110%;
	border:1px solid black; border-bottom-width: 3px; border-right-width: 3px;
	padding: 0.5em; margin:0em; -moz-border-radius:1em;-webkit-border-radius:1em;
}
#importPanel a, #importPanel td a { color:#009; display:inline; margin:0px; padding:1px; }
#importPanel table { width:100%; border:0px; padding:0px; margin:0px; font-size:8pt; line-height:110%; background:transparent; }
#importPanel tr { border:0px;padding:0px;margin:0px; background:transparent; }
#importPanel td { color:#000; border:0px;padding:0px;margin:0px; background:transparent; }
#importPanel select { width:100%;margin:0px;font-size:8pt;line-height:110%;}
#importPanel input  { width:98%;padding:0px;margin:0px;font-size:8pt;line-height:110%}
#importPanel .box { border:1px solid #000; background-color:#eee; padding:3px 5px; margin-bottom:5px; -moz-border-radius:5px;-webkit-border-radius:5px;}
#importPanel .topline { border-top:1px solid #999; padding-top:2px; margin-top:2px; }
#importPanel .rad { width:auto; }
#importPanel .chk { width:auto; margin:1px;border:0; }
#importPanel .btn { width:auto; }
#importPanel .btn1 { width:98%; }
#importPanel .btn2 { width:48%; }
#importPanel .btn3 { width:32%; }
#importPanel .btn4 { width:23%; }
#importPanel .btn5 { width:19%; }
#importPanel .importButton { padding: 0em; margin: 0px; font-size:8pt; }
#importPanel .importListButton { padding:0em 0.25em 0em 0.25em; color: #000000; display:inline }
#backstagePanel #importPanel { left:10%; right:auto; }
!end
//}}}
!!!Control panel HTML
//{{{
!html
<!-- source and report -->
<table><tr><td align=left>
	import from
	<input type="radio" class="rad" name="importFrom" id="importFromFile" value="file" CHECKED
		onclick="onClickImportButton(this,event)" title="show file controls"> local file
	<input type="radio" class="rad" name="importFrom" id="importFromWeb"  value="http"
		onclick="onClickImportButton(this,event)" title="show web controls"> web server
</td><td align=right>
	<input type=checkbox class="chk" id="chkImportReport"
		onClick="config.options['chkImportReport']=this.checked;"> create report
</td></tr></table>

<div class="box" id="importSourcePanel" style="margin:.5em">
<div id="importLocalPanel" style="display:block;margin-bottom:2px;"><!-- import from local file  -->
enter or browse for source path/filename<br>
<input type="file" id="fileImportSource" size=57 style="width:100%"
	onKeyUp="config.macros.importTiddlers.src=this.value"
	onChange="config.macros.importTiddlers.src=this.value;document.getElementById('importLoad').onclick()">
<div id="importLocalPanelFix" style="display:none"><!-- FF3 FIXUP -->
	<input type="text" id="fileImportSourceFix" style="width:90%"
		title="Enter a path/file to import"
		onKeyUp="config.macros.importTiddlers.src=this.value"
		onChange="config.macros.importTiddlers.src=this.value;document.getElementById('importLoad').onclick()">
	<input type="button" id="fileImportSourceFixButton" style="width:7%" value="..."
		title="Select a path/file to import"
		onClick="var r=config.macros.importTiddlers.askForFilename(this); if (!r||!r.length) return;
			document.getElementById('fileImportSourceFix').value=r;
			config.macros.importTiddlers.src=r;
			document.getElementById('importLoad').onclick()">
</div><!--end FF3 FIXUP-->
</div><!--end local-->
<div id="importHTTPPanel" style="display:none;margin-bottom:2px;"><!-- import from http server -->
<table><tr><td align=left>
	enter a URL or <a href="javascript:;" id="importSelectFeed"
		onclick="return onClickImportButton(this,event)" title="select a pre-defined 'systemServer' URL">
		select a server</a><br>
</td><td align=right>
	<input type="checkbox" class="chk" id="importUsePassword"
		onClick="config.macros.importTiddlers.usePassword=this.checked;
			config.macros.importTiddlers.showPanel('importIDPWPanel',this.checked,true);">password
	<input type="checkbox" class="chk" id="importUseProxy"
		onClick="config.macros.importTiddlers.useProxy=this.checked;
			config.macros.importTiddlers.showPanel('importSiteProxy',this.checked,true);">proxy
</td></tr></table>
<input type="text" id="importSiteProxy" style="display:none;margin-bottom:1px" onfocus="this.select()" value="SiteProxy"
	onKeyUp="config.macros.importTiddlers.proxy=this.value"
	onChange="config.macros.importTiddlers.proxy=this.value;">
<input type="text" id="importSourceURL" onfocus="this.select()" value="SiteUrl"
	onKeyUp="config.macros.importTiddlers.src=this.value"
	onChange="config.macros.importTiddlers.src=this.value;">
<div id="importIDPWPanel" style="text-align:center;margin-top:2px;display:none";>
username: <input type=text id="txtImportID" style="width:25%" 
	onChange="config.options.txtRemoteUsername=this.value;">
 password: <input type=password id="txtImportPW" style="width:25%" 
	onChange="config.options.txtRemotePassword=this.value;">
</div><!--end idpw-->
</div><!--end http-->
</div><!--end source-->

<div class="box" id="importSelectPanel" style="display:none;margin:.5em;">
<table><tr><td align=left>
select:
<a href="javascript:;" id="importSelectAll"
	onclick="return onClickImportButton(this)" title="SELECT all tiddlers">
	all</a>
&nbsp;<a href="javascript:;" id="importSelectNew"
	onclick="return onClickImportButton(this)" title="SELECT tiddlers not already in destination document">
	added</a>
&nbsp;<a href="javascript:;" id="importSelectChanges"
	onclick="return onClickImportButton(this)" title="SELECT tiddlers that have been updated in source document">
	changes</a>
&nbsp;<a href="javascript:;" id="importSelectDifferences"
	onclick="return onClickImportButton(this)" title="SELECT tiddlers that have been added or are different from existing tiddlers">
	differences</a>
</td><td align=right>
<a href="javascript:;" id="importListSmaller"
	onclick="return onClickImportButton(this)" title="SHRINK list size">
	&nbsp;&#150;&nbsp;</a>
<a href="javascript:;" id="importListLarger"
	onclick="return onClickImportButton(this)" title="GROW list size">
	&nbsp;+&nbsp;</a>
<a href="javascript:;" id="importListMaximize"
	onclick="return onClickImportButton(this)" title="MAXIMIZE/RESTORE list size">
	&nbsp;=&nbsp;</a>
</td></tr></table>
<select id="importList" size=8 multiple
	onchange="setTimeout('refreshImportList('+this.selectedIndex+')',1)">
	<!-- NOTE: delay refresh so list is updated AFTER onchange event is handled -->
</select>
<div style="text-align:center">
	<a href="javascript:;"
		title="click for help using filters..."
		onclick="alert('A filter consists of one or more space-separated combinations of: tiddlertitle, tag:[[tagvalue]], tag:[[tag expression]] (requires MatchTagsPlugin), story:[[TiddlerName]], and/or search:[[searchtext]]. Use a blank filter to restore the list of all tiddlers.'); return false;"
	>filter</a>
	<input type="text" id="importLastFilter" style="margin-bottom:1px; width:65%"
		title="Enter a combination of one or more filters. Use a blank filter for all tiddlers."
		onfocus="this.select()" value=""
		onKeyUp="config.macros.importTiddlers.lastFilter=this.value"
		onChange="config.macros.importTiddlers.lastFilter=this.value;">
	<input type="button" id="importApplyFilter" style="width:20%" value="apply"
		title="filter list of tiddlers to include only those that match certain criteria"
		onclick="return onClickImportButton(this)">
	</div>
</div><!--end select-->

<div class="box" id="importOptionsPanel" style="text-align:center;margin:.5em;display:none;">
	apply tags: <input type=checkbox class="chk" id="chkImportTags" checked
		onClick="config.macros.importTiddlers.importTags=this.checked;">from source&nbsp;
	<input type=checkbox class="chk" id="chkKeepTags" checked
		onClick="config.macros.importTiddlers.keepTags=this.checked;">keep existing&nbsp;
	<input type=checkbox class="chk" id="chkAddTags" 
		onClick="config.macros.importTiddlers.addTags=this.checked;
			config.macros.importTiddlers.showPanel('txtNewTags',this.checked,false);
			if (this.checked) document.getElementById('txtNewTags').focus();">add tags<br>
	<input type=text id="txtNewTags" style="margin-top:4px;display:none;" size=15 onfocus="this.select()" 
		title="enter tags to be added to imported tiddlers" 
		onKeyUp="config.macros.importTiddlers.newTags=this.value;
		document.getElementById('chkAddTags').checked=this.value.length>0;" autocomplete=off>
	<nobr><input type=checkbox class="chk" id="chkSync" 
		onClick="config.macros.importTiddlers.sync=this.checked;">
		link tiddlers to source document (for sync later)</nobr>
</div><!--end options-->

<div id="importButtonPanel" style="text-align:center">
	<input type=button id="importLoad"	class="importButton btn3" value="open"
		title="load listbox with tiddlers from source document"
		onclick="onClickImportButton(this)">
	<input type=button id="importOptions"	class="importButton btn3" value="options..."
		title="set options for tags, sync, etc."
		onclick="onClickImportButton(this)">
	<input type=button id="importStart"	class="importButton btn3" value="import"
		title="start/stop import of selected source tiddlers into current document"
		onclick="onClickImportButton(this)">
	<input type=button id="importClose"	class="importButton btn3" value="done"
		title="clear listbox or hide control panel"
		onclick="onClickImportButton(this)">
</div>

<div class="none" id="importCollisionPanel" style="display:none;margin:.5em 0 .5em .5em;">
	<table><tr><td style="width:65%" align="left">
		<table><tr><td align=left>
			tiddler already exists:
		</td><td align=right>
			<input type=checkbox class="chk" id="importApplyToAll" 
			onclick="document.getElementById('importRename').disabled=this.checked;"
			checked>apply to all
		</td></tr></table>
		<input type=text id="importNewTitle" size=15 autocomplete=off">
	</td><td style="width:34%" align="center">
		<input type=button id="importMerge"
			class="importButton" style="width:47%" value="merge"
			title="append the incoming tiddler to the existing tiddler"
			onclick="onClickImportButton(this)"><!--
		--><input type=button id="importSkip"
			class="importButton" style="width:47%" value="skip"
			title="do not import this tiddler"
			onclick="onClickImportButton(this)"><!--
		--><br><input type=button id="importRename"
			class="importButton" style="width:47%" value="rename"
			title="rename the incoming tiddler"
			onclick="onClickImportButton(this)"><!--
		--><input type=button id="importReplace"
			class="importButton" style="width:47%" value="replace"
			title="discard the existing tiddler"
			onclick="onClickImportButton(this)">
	</td></tr></table>
</div><!--end collision-->
!end
//}}}
***/
 
/***
|Name|ImportTiddlersPluginInfo|
|Source|http://www.TiddlyTools.com/#ImportTiddlersPlugin|
|Documentation|http://www.TiddlyTools.com/#ImportTiddlersPluginInfo|
|Version|4.6.0|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|documentation|
|Description|documentation for ImportTiddlersPlugin|
Combine tiddlers from any two TiddlyWiki documents.  An interactive control panel lets you pick a source document and import selected tiddlers, with prompting for skip, rename, merge or replace actions when importing tiddlers that match existing titles.  Generates a detailed report of import 'history' in ImportedTiddlers.
!!!!!Usage
<<<
{{{<<importTiddlers>>}}} or {{{<<importTiddlers core>>}}}
invokes the built-in importTiddlers macro (TW2.1.x+).  If installed in documents using TW2.0.x or earlier, fallback is to use 'link' display (see below)

{{{<<importTiddlers link label tooltip>>}}}
The ''link'' keyword creates an "import tiddlers" link that when clicked to show/hide import control panel.  ''label'' and ''tooltip'' are optional text parameters (enclosed in quotes or {{{[[...]]}}}, and allow you to override the default display text for the link and the mouseover help text, respectively.

{{{<<importTiddlers inline>>}}}
creates import control panel directly in tiddler content

<<importTiddlers inline>>

Enter a document URL or press "..." to select a TiddlyWiki file to import, and then press ''[open]''.  //Note: There may be a delay before the list of tiddlers appears.//  Use the ''[-]'', ''[+]'', or ''[=]'' links to adjust the listbox size so you can view more (or less) tiddler titles at one time.

Select one or more titles from the listbox.  Use CTRL-click or SHIFT-click to select/deselect individual titles.  Click on ''all'', ''new'', ''changes'', or ''differences'' to automatically select a subset of tiddlers from the list, based on a comparison of the two documents:
*''all'' selects ALL tiddlers from the import source document, even if they have not been changed.
*''new'' selects only tiddlers that are found in the import source document, but do not yet exist in the destination document
*''changes'' selects only tiddlers that exist in both documents but that are newer in the source document
*''differences'' selects all new and existing tiddlers that are different from the destination document (even if destination tiddler is newer)

Press ''[import]'' to begin copying tiddlers to the current document.  If an 'inbound' tiddler matches one that already exists in the document, the import process pauses and the tiddler title is displayed in an input field, along with four push buttons: ''skip'', ''rename'', ''merge'' and ''replace''.
* to bypass importing the tiddler, press ''skip''
* to give the inbound tiddler a different name, so that both the old and new tiddlers will exist when the import is done, enter a new title in the input field and press ''rename'' 
* to combine the content from both tiddlers into a single tiddler so you can then edit it later to eliminate unwanted content, press ''merge''
* to overwrite the existing tiddler with the imported one (discarding the previous content), press ''[replace]''

''Import Report History''

Whenever tiddlers are imported, a report is generated into a tiddler named [[ImportedTiddlers]], recording when the latest import was performed, the number of tiddlers successfully imported, from what location, and by whom, as well as a list of the tiddlers that were processed.  When more tiddlers are imported at a later time, a new report is //added// to the existing [[ImportedTiddlers]], above the previous report (i.e., at the top of the tiddler), so that a history of imports is maintained.  If this record is not desired, you can delete [[ImportedTiddlers]] at any time.

Note: You can prevent a report from being generated for any given import activity by clearing the "create a report" checkbox before pressing the ''import'' button
<<<
!!!!!Installation Notes
<<<
* As of 6/27/2007, support for TW2.1.x and earlier have been moved to [[ImportTiddlersPluginPatch]].  ''//Only install the patch plugin when using TW2.1.x or earlier.//''
<<<
!!!!!Revisions
<<<
2009.10.06 4.6.0 added createTiddlerFromFile (import text files)
2009.09.27 4.5.5 in readTiddlersFromCSV(), strip \r from input and fixed handling for quoted values
2009.09.12 4.5.4 fixed 'return false' to prevent IE page transition. Also, moved html/css definitions to separate sections
2009.08.23 4.5.3 in importTiddlers(), add 'file:///' to local server.host sync field only if not already present in URL
2009.08.20 4.5.2 only use SiteURL/SiteProxy values if control panel value has not yet been set
2009.07.03 4.5.1 fixups for TW252: doHttp() doesn't return XHR and convertUTF8ToUnicode() not needed for local I/O
2009.05.04 4.5.0 import from CSV-formatted files
2009.03.04 4.4.2 in createImportPanel(), init option checkboxes so display matches internal state variables
2009.02.26 4.4.1 use macro-specific definition of $() function abbreviation (avoids conflict with JQuery)
2008.09.30 4.4.0 added fallback definition of merge() for use with TW2.0.x and TW1.2.x
2008.08.12 4.3.3 rewrite backstage and shadow tiddler definitions for easier customization
2008.08.05 4.3.2 rewrote loadRemoteFile() to eliminate use of platform-specific fileExists() function
2008.06.29 4.3.1 More layout/animation work for simpler sequential interaction.  Code reduction/cleanup
2008.06.28 4.3.0 HTML and CSS cleanup and tweaks to layout.  Added animation to panels
2008.06.22 4.2.0 For FireFox, use HTML with separate text+button control instead of type='file' control
2008.06.05 4.1.0 in filterByHash(), added support for boolean tag expressions using getMatchingTiddlers() (defined by MatchTagsPlugin)
2008.05.12 4.0.2 automatically tweak the backstage "import" task to add the ImportTiddlers control panel
2008.04.30 4.0.1 trim #... suffix for loading files/URLs in IE
2008.04.30 4.0.0 added source filtering (using URL paramifiers).  Also, abbreviations for code-size reduction.
2008.04.13 3.9.0 added 'apply to all' checkbox for collision processing
2008.03.26 3.8.0 added support for selecting pre-defined systemServer URLs
2008.03.25 3.7.0 added support for setting 'server' fields on imported tiddlers (for later synchronizing of changes)
2008.01.03 3.6.0 in loadRemoteFile(), use lower-level doHttp() instead of loadRemoteFile() in order to support username/password access to remote server
2007.10.30 3.5.6 update [[ImportTiddlers]] shadow tiddler definition to include "inline" link
2007.06.27 3.5.5 added missing 'fields' params to saveTiddler() calls.  Fixes problem where importing tiddlers would lose the custom fields.  Also, moved functions for TW2.1.x to [[ImportTiddlersPluginPatch2.1.x]].
2007.06.25 3.5.4 added calls to store.suspendNotifications() and store.resumeNotifications().  Eliminates redisplay processing overhead DURING import activities
2007.04.29 3.5.3 in refreshImportList() when inbound tiddlers are loaded, change "close" button to "done", and disable certain controls to creates a modal condition, so that actions that reload tiddlers cannot be performed unless "done" is first pressed to end the mode..
2007.04.28 3.5.2 in handler(), added param support for custom link label/prompt
2007.04.19 3.5.1 in readTiddlersFromHTML(), for TW2.2 and above, use importTiddlyWiki() (new core functionality) to get tiddlers from remote file content.  Also, copied updated TW21Loader.prototype.internalizeTiddler() definition from TW2.2b5 so plugin can read tiddlers from TW2.2+ even when running under TW2.1.x
2007.03.22 3.5.0 in refreshImportList(), add handling for 'select section' when a heading is selected.  Makes it really easy to import by tag or date!
2007.03.21 3.4.0 split loadTiddlers functionality into separate plugin (see [[LoadTiddlersPlugin]])
2007.03.20 3.3.1 tweak to previous change to allow relative file references via http: (bypasses getLocalPath() so remote URL will be used)
2007.03.20 3.3.0 added support for local, relative file references: in loadRemoteFile(), check for fileExists().  If not found, prepend relative path and retry.
2007.02.24 3.2.1 re-labeled control panel "open" button to "load"
2007.02.09 3.2.0 loadTiddlers: added support for "noReload" tag (prevents overwriting existing tiddler, even if inbound tiddler is newer)
2007.02.08 3.1.3 loadTiddlers: added missing code and documentation for "newTags" handling (a feature change from long, long ago that somehow got lost!)
2006.11.14 3.1.2 fix macro handler parameter declaration (double-pasted param list corrupts IE)
2006.11.13 3.1.1 use apply() method to invoke hijacked core handler
2006.11.13 3.1.0 hijack built-in importTiddlers.handler() to co-exist with plugin interface.  If no params or 'core' keyword, display core interface.  "link" param embeds "import tiddlers" link that shows floating panel when clicked.
2006.10.12 3.0.8 in readTiddlersFromHTML(), fallback to find end of store area by matching "/body" when POST-BODY-START is not present (backward compatibility for older documents)
2006.09.10 3.0.7 in readTiddlersFromHTML(), find end of store area by matching "POST-BODY-START" instead of "/body" 
2006.08.16 3.0.6 Use higher-level store.saveTiddler() instead of store.addTiddler() to avoid conflicts with adaptations that hijack low-level tiddler handling.  in CreateImportPanel(), removed "refresh listbox after every tiddler change".
2006.07.29 3.0.5 added noChangeMsg to loadTiddlers processing.  if not 'quiet' mode, reports skipped tiddlers.
2006.04.18 3.0.4 in loadTiddlers.handler, fixed parsing of "prompt:" param. Also, corrected parameters mismatch in loadTiddlers() callback function definition (order of params was wrong, resulting in filters NOT being applied)
2006.04.12 3.0.3 moved many display messages to macro properties for easier L10N translations via 'lingo' definitions.
2006.04.12 3.0.2 more work on 'core candidate' code.  Proposed API now defines "loadRemoteFile()" for XMLHttpRequest processing with built in fallback for handling local filesystem access, and readTiddlersFromHTML() to process the resulting source HTML content.
2006.04.04 3.0.1 in refreshImportList(), when using [by tags], tiddlers without tags are now included in a new "untagged" psuedo-tag list section
2006.04.04 3.0.0 Separate non-interactive {{{<<importTiddlers...>>}}} macro functionality for incorporation into TW2.1 core and renamed as {{{<<loadTiddlers>>}}} macro.  New parameters for loadTiddlers: ''label:text'' and ''prompt:text'' for link creation,  ''ask'' for filename/URL, ''tag:text'' for filtering, "confirm" for accept/reject of individual inbound tiddlers.  Removed support for "importReplace/importPublic" tags and "force" param (unused feature). 
2006.03.30 2.9.1 when extracting store area from remote URL, look for "</body>" instead of "</body>\n</html>" so it will match even if the "\n" is absent from the source.
2006.03.30 2.9.0 added optional 'force' macro param.  When present, autoImportTiddlers() bypasses the checks for importPublic and importReplace.  Based on a request from Tom Otvos.
2006.03.28 2.8.1 in loadImportFile(), added checks to see if 'netscape' and 'x.overrideMimeType()' are defined (not in IE). Also, when extracting store area, look for "</body>\n</html>" and omit extra content that may have been added to the end of the file.
2006.02.21 2.8.0 added support for "tiddler:TiddlerName" filtering parameter in auto-import processing
2006.02.21 2.7.1 Clean up layout problems with IE.  (Use tables for alignment instead of SPANs styled with float:left and float:right)
2006.02.21 2.7.0 Added "local file" and "web server" radio buttons.  Default remote URL uses value from [[SiteURL]].  Also, added 'proxy' option, using value from [[SiteProxy]] as prefix to permit cross-domain document access via server-side scripting.
2006.02.17 2.6.0 Removed "differences only" listbox display mode, replaced with selection filter 'presets': all/new/changes/differences.  fixed init of "add new tags" checkbox
2006.02.16 2.5.4 added checkbox options to control "import remote tags" and "keep existing tags" behavior, in addition to existing "add new tags" functionality.
2006.02.14 2.5.3 FF1501 corrected unintended global 't' (loop index) in importReport() and autoImportTiddlers()
2006.02.10 2.5.2 corrected unintended global variable in importReport().
2006.02.05 2.5.1 moved globals from window.* to config.macros.importTiddlers.* to avoid FireFox 1.5.0.1 crash bug when referencing globals
2006.01.18 2.5.0 added checkbox for "create a report".  Default is to create/update the ImportedTiddlers report.
2006.01.15 2.4.1 added "importPublic" tag and inverted default so that auto sharing is NOT done unless tagged with importPublic
2006.01.15 2.4.0 Added support for tagging tiddlers with importSkip, importReplace, and/or importPrivate to enable/disable overwriting or sharing with others when using auto-import macro syntax.  Defaults: don't overwrite existing tiddlers, and allow your tiddlers to be auto-imported by others.
2006.01.15 2.3.2 Added "ask" parameter to confirm each tiddler before importing (for use with auto-importing)
2006.01.15 2.3.1 Strip TW core scripts from import source content and load just the storeArea into the hidden IFRAME to prevent imported document's core code from being invoked.  Also, when importing local documents, use convertUTF8ToUnicode() to support international characters sets.
2006.01.12 2.3.0 Reorganized code to use callback function for loading import files to support event-driven I/O via an ASYNCHRONOUS XMLHttpRequest instead of waiting for remote hosts to respond to URL requests.  Added non-interactive 'batch' mode, using macro parameters to specify source path/file or URL, and select tiddlers to import.  Improved messages and added optional 'quiet' switch for batch mode to eliminate //most// feedback.
2006.01.11 2.2.0 Added "[by tags]" to list of tiddlers, based on code submitted by BradleyMeck
2006.01.08 2.1.0 IMPORT FROM ANYWHERE!!! re-write getImportedTiddlers() logic to either read a local file (using local I/O), OR... read a remote file, using a combination of XML and an iframe to permit cross-domain reading of DOM elements.  Adapted from example code and techniques courtesy of Jonny LeRoy.
2006.01.06 2.0.2 When refreshing list contents, fixed check for tiddlerExists() when "show differences only" is selected, so that imported tiddlers that don't exist in the current file will be recognized as differences and included in the list.
2006.01.04 2.0.1 When "show differences only" is NOT checked, import all tiddlers that have been selected even when they have a matching title and date.
2005.12.27 2.0.0 Update for TW2.0
Defer initial panel creation and only register a notification function when panel first is created
2005.12.22 1.3.1 tweak formatting in importReport() and add 'discard report' link to output
2005.12.03 1.3.0 Dynamically create/remove importPanel as needed to ensure only one instance of interface elements exists, even if there are multiple instances of macro embedding.  Also, dynamically create/recreate importFrame each time an external TW document is loaded for importation (reduces DOM overhead and ensures a 'fresh' frame for each document)
2005.11.29 1.2.1 fixed formatting of 'detail info' in importReport()
2005.11.11 1.2.0 added 'inline' param to embed controls in a tiddler
2005.11.09 1.1.0 only load HTML and CSS the first time the macro handler is called.  Allows for redundant placement of the macro without creating multiple instances of controls with the same ID's.
2005.10.25 1.0.5 fixed typo in importReport() that prevented reports from being generated
2005.10.09 1.0.4 combined documentation with plugin code instead of using separate tiddlers
2005.08.05 1.0.3 moved CSS and HTML definitions into plugin code instead of using separate tiddlers
2005.07.27 1.0.2 core update 1.2.29: custom overlayStyleSheet() replaced with new core setStylesheet()
2005.07.23 1.0.1 added parameter checks and corrected addNotification() usage
2005.07.20 1.0.0 Initial Release
<<<
/***
|Name|InlineJavascriptPlugin|
|Source|http://www.TiddlyTools.com/#InlineJavascriptPlugin|
|Documentation|http://www.TiddlyTools.com/#InlineJavascriptPluginInfo|
|Version|1.9.5|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|Insert Javascript executable code directly into your tiddler content.|
''Call directly into TW core utility routines, define new functions, calculate values, add dynamically-generated TiddlyWiki-formatted output'' into tiddler content, or perform any other programmatic actions each time the tiddler is rendered.
!!!!!Documentation
>see [[InlineJavascriptPluginInfo]]
!!!!!Revisions
<<<
2009.04.11 [1.9.5] pass current tiddler object into wrapper code so it can be referenced from within 'onclick' scripts
2009.02.26 [1.9.4] in $(), handle leading '#' on ID for compatibility with JQuery syntax
|please see [[InlineJavascriptPluginInfo]] for additional revision details|
2005.11.08 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.InlineJavascriptPlugin= {major: 1, minor: 9, revision: 5, date: new Date(2009,4,11)};

config.formatters.push( {
	name: "inlineJavascript",
	match: "\\<script",
	lookahead: "\\<script(?: src=\\\"((?:.|\\n)*?)\\\")?(?: label=\\\"((?:.|\\n)*?)\\\")?(?: title=\\\"((?:.|\\n)*?)\\\")?(?: key=\\\"((?:.|\\n)*?)\\\")?( 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;
		}
	}
} )
//}}}

// // Backward-compatibility for TW2.1.x and earlier
//{{{
if (typeof(wikifyPlainText)=="undefined") window.wikifyPlainText=function(text,limit,tiddler) {
	if(limit > 0) text = text.substr(0,limit);
	var wikifier = new Wikifier(text,formatter,null,tiddler);
	return wikifier.wikifyPlain();
}
//}}}

// // GLOBAL FUNCTION: $(...) -- 'shorthand' convenience syntax for document.getElementById()
//{{{
if (typeof($)=='undefined') { function $(id) { return document.getElementById(id.replace(/^#/,'')); } }
//}}}
/***
|Name|InlineJavascriptPluginInfo|
|Source|http://www.TiddlyTools.com/#InlineJavascriptPlugin|
|Documentation|http://www.TiddlyTools.com/#InlineJavascriptPluginInfo|
|Version|1.9.4|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|documentation|
|Requires||
|Overrides||
|Description|Documentation for InlineJavascriptPlugin|
''Call directly into TW core utility routines, define new functions, calculate values, add dynamically-generated TiddlyWiki-formatted output'' into tiddler content, or perform any other programmatic actions each time the tiddler is rendered.
!!!!!Usage
<<<
This plugin adds wiki syntax for surrounding tiddler content with {{{<script>}}} and {{{</script>}}} markers, so that it can be recognized as embedded javascript code.
<script show>
	/* javascript code goes here... */
</script>Every time the tiddler content is rendered, the javascript code is automatically evaluated, allowing you to invoke 'side-effect' processing and/or produce dynamically-generated content that is then inserted into the tiddler content, immediately following the script (see below).  By including the optional ''show'' keyword as the final parameter in a {{{<script>}}} marker, the plugin will also include the script source code in the output that it displays in the tiddler.  This is helpful when creating examples for documentation purposes (such as used in this tiddler!)

__''Deferred execution from an 'onClick' link''__
<script label="click here" title="mouseover tooltip text" key="X" show>
	/* javascript code goes here... */
	alert('you clicked on the link!');
</script>
By including a {{{label="..."}}} parameter in the initial {{{<script>}}} marker, the plugin will create a link to an 'onclick' script that will only be executed when that specific link is clicked, rather than running the script each time the tiddler is rendered.  You may also include a {{{title="..."}}} parameter to specify the 'tooltip' text that will appear whenever the mouse is moved over the onClick link text, and a {{{key="X"}}} parameter to specify an //access key// (which must be a //single// letter or numeric digit only).

__''Loading scripts from external source files''__
<script src="URL" show>
	/* optional javascript code goes here... */
</script>You can also load javascript directly from an external source URL, by including a src="..." parameter in the initial {{{<script>}}} marker (e.g., {{{<script src="demo.js"></script>}}}).  This is particularly useful when incorporating third-party javascript libraries for use in custom extensions and plugins.  The 'foreign' javascript code remains isolated in a separate file that can be easily replaced whenever an updated library file becomes available.

In addition to loading the javascript from the external file, you can also use this feature to invoke javascript code contained within the {{{<script>...</script>}}} markers.  This code is invoked //after// the external script file has been processed, and can make immediate use of the functions and/or global variables defined by the external script file.
>Note: To ensure that your javascript functions are always available when needed, you should load the libraries from a tiddler that is rendered as soon as your TiddlyWiki document is opened, such as MainMenu.  For example: put your {{{<script src="..."></script>}}} syntax into a separate 'library' tiddler (e.g., LoadScripts), and then add {{{<<tiddler LoadScripts>>}}} to MainMenu so that the library is loaded before any other tiddlers that rely upon the functions it defines. 
>
>Normally, loading external javascript in this way does not produce any direct output, and should not have any impact on the appearance of your MainMenu.  However, if your LoadScripts tiddler contains notes or other visible content, you can suppress this output by using 'inline CSS' in the MainMenu, like this: {{{@@display:none;<<tiddler LoadScripts>>@@}}}
<<<
!!!!!Creating dynamic tiddler content and accessing the ~TiddlyWiki DOM
<<<
An important difference between TiddlyWiki inline scripting and conventional embedded javascript techniques for web pages is the method used to produce output that is dynamically inserted into the document: in a typical web document, you use the {{{document.write()}}} (or {{{document.writeln()}}}) function to output text sequences (often containing HTML tags) that are then rendered when the entire document is first loaded into the browser window.

However, in a ~TiddlyWiki document, tiddlers (and other DOM elements) are created, deleted, and rendered "on-the-fly", so writing directly to the global 'document' object does not produce the results you want (i.e., replacing the embedded script within the tiddler content), and instead will //completely replace the entire ~TiddlyWiki document in your browser window (which is clearly not a good thing!)//.  In order to allow scripts to use {{{document.write()}}}, the plugin automatically converts and buffers all HTML output so it can be safely inserted into your tiddler content, immediately following the script.

''Note that {{{document.write()}}} can only be used to output "pure HTML" syntax.  To produce //wiki-formatted// output, your script should instead return a text value containing the desired wiki-syntax content'', which will then be automatically rendered immediately following the script.  If returning a text value is not sufficient for your needs, the plugin also provides an automatically-defined variable, 'place', that gives the script code ''direct access to the //containing DOM element//'' into which the tiddler output is being rendered.  You can use this variable to ''perform direct DOM manipulations'' that can, for example:
* generate wiki-formatted output using {{{wikify("...content...",place)}}}
* vary the script's actions based upon the DOM element in which it is embedded
* access 'tiddler-relative' DOM information using {{{story.findContainingTiddler(place)}}}
Note:
''When using an 'onclick' script, the 'place' element actually refers to the onclick //link text// itself, instead of the containing DOM element.''  This permits you to directly reference or modify the link text to reflect any 'stateful' conditions that might set by the script.  To refer to the containing DOM element from within an 'onclick' script, you can use "place.parentNode" instead.
<<<
!!!!!Instant "bookmarklets"
<<<
You can also use an 'onclick' link to define a "bookmarklet": a small piece of javascript that can be ''invoked directly from the browser without having to be defined within the current document.''  This allows you to create 'stand-alone' commands that can be applied to virtually ANY TiddlyWiki document... even remotely-hosted documents that have been written by others!!  To create a bookmarklet, simply define an 'onclick' script and then grab the resulting link text and drag-and-drop it onto your browser's toolbar (or right-click and use the 'bookmark this link' command to add it to the browser's menu).

Notes:
*When writing scripts intended for use as bookmarklets, due to the ~URI-encoding required by the browser, ''you cannot not use ANY double-quotes (") within the bookmarklet script code.''
*All comments embedded in the bookmarklet script must ''use the fully-delimited {{{/* ... */}}} comment syntax,'' rather than the shorter {{{//}}} comment syntax.
*Most importantly, because bookmarklets are invoked directly from the browser interface and are not embedded within the TiddlyWiki document, there is NO containing 'place' DOM element surrounding the script.  As a result, ''you cannot use a bookmarklet to generate dynamic output in your document,''  and using {{{document.write()}}} or returning wiki-syntax text or making reference to the 'place' DOM element will halt the script and report a "Reference Error" when that bookmarklet is invoked.  
Please see [[InstantBookmarklets]] for many examples of 'onclick' scripts that can also be used as bookmarklets.
<<<
!!!!!Special reserved function name
<<<
The plugin 'wraps' all inline javascript code inside a function, {{{_out()}}}, so that any return value you provide can be correctly handled by the plugin and inserted into the tiddler.  To avoid unpredictable results (and possibly fatal execution errors), this function should never be redefined or called from ''within'' your script code.
<<<
!!!!!$(...) 'shorthand' function
<<<
As described by Dustin Diaz [[here|http://www.dustindiaz.com/top-ten-javascript/]], the plugin defines a 'shorthand' function that allows you to write:
{{{
$(id)
}}}
in place of the normal standard javascript syntax:
{{{
document.getElementById(id)
}}}
This function is provided merely as a convenience for javascript coders that may be familiar with this abbreviation, in order to allow them to save a few bytes when writing their own inline script code.
<<<
!!!!!Examples
<<<
simple dynamic output:
><script show>
	document.write("The current date/time is: "+(new Date())+"<br>");
	return "link to current user: [["+config.options.txtUserName+"]]\n";
</script>
dynamic output using 'place' to get size information for current tiddler:
><script show>
	if (!window.story) window.story=window;
	var title=story.findContainingTiddler(place).getAttribute("tiddler");
	var size=store.getTiddlerText(title).length;
	return title+" is using "+size+" bytes";
</script>
dynamic output from an 'onclick' script, using {{{document.write()}}} and/or {{{return "..."}}}
><script label="click here" show>
	document.write("<br>The current date/time is: "+(new Date())+"<br>");
	return "link to current user: [["+config.options.txtUserName+"]]\n";
</script>
creating an 'onclick' button/link that accesses the link text AND the containing tiddler:
><script label="click here" title="clicking this link will show an 'alert' box" key="H" show>
	if (!window.story) window.story=window;
	var txt=place.firstChild.data;
	var tid=story.findContainingTiddler(place).getAttribute('tiddler');
	alert('Hello World!\nlinktext='+txt+'\ntiddler='+tid);
</script>
dynamically setting onclick link text based on stateful information:
>{{block{
{{{
<script label="click here">
	/* toggle "txtSomething" value */
	var on=(config.txtSomething=="ON");
	place.innerHTML=on?"enable":"disable";
	config.txtSomething=on?"OFF":"ON";
	return "\nThe current value is: "+config.txtSomething;
</script><script>
	/* initialize onclick link text based on current "txtSomething" value */
	var on=(config.txtSomething=="ON");
	place.lastChild.previousSibling.innerHTML=on?"disable":"enable";
</script>
}}}
<script label="click here">
	/* toggle "txtSomething" value */
	var on=(config.txtSomething=="ON");
	place.innerHTML=on?"enable":"disable";
	config.txtSomething=on?"OFF":"ON";
	return "\nThe current value is: "+config.txtSomething;
</script><script>
	/* initialize onclick link text based on current "txtSomething" value */
	var on=(config.txtSomething=="ON");
	place.lastChild.innerHTML=on?"enable":"disable";
</script>
}}}
loading a script from a source url:
>http://www.TiddlyTools.com/demo.js contains:
>>{{{function inlineJavascriptDemo() { alert('Hello from demo.js!!') } }}}
>>{{{displayMessage('InlineJavascriptPlugin: demo.js has been loaded');}}}
>note: When using this example on your local system, you will need to download the external script file from the above URL and install it into the same directory as your document.
>
><script src="demo.js" show>
	return "inlineJavascriptDemo() function has been defined"
</script>
><script label="click to invoke inlineJavascriptDemo()" key="D" show>
	inlineJavascriptDemo();
</script>
<<<
!!!!!Revisions
<<<
2009.02.26 [1.9.4] in $(), handle leading '#' on ID for compatibility with JQuery syntax
2008.06.11 [1.9.3] added $(...) function as 'shorthand' for document.getElementById()
2008.03.03 [1.9.2] corrected fallback declaration of wikifyPlainText() (fixes Safari "parse error")
2008.02.23 [1.9.1] in onclick function, use string instead of array for 'bufferedHTML' (fixes IE errors)
2008.02.21 [1.9.0] output from 'onclick' scripts (return value or document.write() calls) are now buffered and rendered into into a span following the script.  Also, added default 'return false' handling if no return value provided (prevents HREF from being triggered -- return TRUE to allow HREF to be processed).  Thanks to Xavier Verges for suggestion and preliminary code.
2008.02.14 [1.8.1] added backward-compatibility for use of wikifyPlainText() in TW2.1.3 and earlier
2008.01.08 [*.*.*] plugin size reduction: documentation moved to ...Info tiddler
2007.12.28 [1.8.0] added support for key="X" syntax to specify custom access key definitions
2007.12.15 [1.7.0] autogenerate URI encoded HREF on links for onclick scripts.  Drag links to browser toolbar to create bookmarklets.  IMPORTANT NOTE: place is NOT defined when scripts are used as bookmarklets.  In addition, double-quotes will cause syntax errors.  Thanks to PaulReiber for debugging and brainstorming.
2007.11.26 [1.6.2] when converting "document.write()" function calls in inline code, allow whitespace between "write" and "(" so that "document.write ( foobar )" is properly converted.
2007.11.16 [1.6.1] when rendering "onclick scripts", pass label text through wikifyPlainText() to parse any embedded wiki-syntax to enable use of HTML entities or even TW macros to generate dynamic label text.
2007.02.19 [1.6.0] added support for title="..." to specify mouseover tooltip when using an onclick (label="...") script
2006.10.16 [1.5.2] add newline before closing '}' in 'function out_' wrapper.  Fixes error caused when last line of script is a comment.
2006.06.01 [1.5.1] when calling wikify() on script return value, pass hightlightRegExp and tiddler params so macros that rely on these values can render properly
2006.04.19 [1.5.0] added 'show' parameter to force display of javascript source code in tiddler output
2006.01.05 [1.4.0] added support 'onclick' scripts.  When label="..." param is present, a button/link is created using the indicated label text, and the script is only executed when the button/link is clicked.  'place' value is set to match the clicked button/link element.
2005.12.13 [1.3.1] when catching eval error in IE, e.description contains the error text, instead of e.toString().  Fixed error reporting so IE shows the correct response text.  Based on a suggestion by UdoBorkowski
2005.11.09 [1.3.0] for 'inline' scripts (i.e., not scripts loaded with src="..."), automatically replace calls to 'document.write()' with 'place.innerHTML+=' so script output is directed into tiddler content.  Based on a suggestion by BradleyMeck
2005.11.08 [1.2.0] handle loading of javascript from an external URL via src="..." syntax
2005.11.08 [1.1.0] pass 'place' param into scripts to provide direct DOM access 
2005.11.08 [1.0.0] initial release
<<<
/***
|''Name:''|IntelliTaggerPlugin|
|''Version:''|1.0.2 (2007-07-25)|
|''Type:''|plugin|
|''Source:''|http://tiddlywiki.abego-software.de/#IntelliTaggerPlugin|
|''Author:''|Udo Borkowski (ub [at] abego-software [dot] de)|
|''Documentation:''|[[IntelliTaggerPlugin Documentation]]|
|''~SourceCode:''|[[IntelliTaggerPlugin SourceCode]]|
|''Licence:''|[[BSD open source license (abego Software)]]|
|''~CoreVersion:''|2.0.8|
|''Browser:''|Firefox 1.5.0.2 or better|
***/
/***
!Version History
* 1.0.2 (2007-07-25): 
** Feature: "Return" key may be used to accept first tag suggestion (beside "Alt-1")
** Bugfix: Keyboard shortcuts (Alt+3 etc.) shifted
* 1.0.1 (2007-05-18): Improvement: Speedup when using TiddlyWikis with many tags
* 1.0.0 (2006-04-26): Initial release

***/
// /%
if(!version.extensions.IntelliTaggerPlugin){if(!window.abego){window.abego={};}if(!abego.internal){abego.internal={};}abego.alertAndThrow=function(s){alert(s);throw s;};if(version.major<2){abego.alertAndThrow("Use TiddlyWiki 2.0.8 or better to run the IntelliTagger Plugin.");}version.extensions.IntelliTaggerPlugin={major:1,minor:0,revision:2,date:new Date(2007,6,25),type:"plugin",source:"http://tiddlywiki.abego-software.de/#IntelliTaggerPlugin",documentation:"[[IntelliTaggerPlugin Documentation]]",sourcecode:"[[IntelliTaggerPlugin SourceCode]]",author:"Udo Borkowski (ub [at] abego-software [dot] de)",licence:"[[BSD open source license (abego Software)]]",tiddlywiki:"Version 2.0.8 or better",browser:"Firefox 1.5.0.2 or better"};abego.createEllipsis=function(_2){var e=createTiddlyElement(_2,"span");e.innerHTML="&hellip;";};abego.isPopupOpen=function(_4){return _4&&_4.parentNode==document.body;};abego.openAsPopup=function(_5){if(_5.parentNode!=document.body){document.body.appendChild(_5);}};abego.closePopup=function(_6){if(abego.isPopupOpen(_6)){document.body.removeChild(_6);}};abego.getWindowRect=function(){return {left:findScrollX(),top:findScrollY(),height:findWindowHeight(),width:findWindowWidth()};};abego.moveElement=function(_7,_8,_9){_7.style.left=_8+"px";_7.style.top=_9+"px";};abego.centerOnWindow=function(_a){if(_a.style.position!="absolute"){throw "abego.centerOnWindow: element must have absolute position";}var _b=abego.getWindowRect();abego.moveElement(_a,_b.left+(_b.width-_a.offsetWidth)/2,_b.top+(_b.height-_a.offsetHeight)/2);};abego.isDescendantOrSelf=function(_c,e){while(e){if(_c==e){return true;}e=e.parentNode;}return false;};abego.toSet=function(_e){var _f={};for(var i=0;i<_e.length;i++){_f[_e[i]]=true;}return _f;};abego.filterStrings=function(_11,_12,_13){var _14=[];for(var i=0;i<_11.length&&(_13===undefined||_14.length<_13);i++){var s=_11[i];if(s.match(_12)){_14.push(s);}}return _14;};abego.arraysAreEqual=function(a,b){if(!a){return !b;}if(!b){return false;}var n=a.length;if(n!=b.length){return false;}for(var i=0;i<n;i++){if(a[i]!=b[i]){return false;}}return true;};abego.moveBelowAndClip=function(_1b,_1c){if(!_1c){return;}var _1d=findPosX(_1c);var _1e=findPosY(_1c);var _1f=_1c.offsetHeight;var _20=_1d;var _21=_1e+_1f;var _22=findWindowWidth();if(_22<_1b.offsetWidth){_1b.style.width=(_22-100)+"px";}var _23=_1b.offsetWidth;if(_20+_23>_22){_20=_22-_23-30;}if(_20<0){_20=0;}_1b.style.left=_20+"px";_1b.style.top=_21+"px";_1b.style.display="block";};abego.compareStrings=function(a,b){return (a==b)?0:(a<b)?-1:1;};abego.sortIgnoreCase=function(arr){var _27=[];var n=arr.length;for(var i=0;i<n;i++){var s=arr[i];_27.push([s.toString().toLowerCase(),s]);}_27.sort(function(a,b){return (a[0]==b[0])?0:(a[0]<b[0])?-1:1;});for(i=0;i<n;i++){arr[i]=_27[i][1];}};abego.getTiddlerField=function(_2d,_2e,_2f){var _30=document.getElementById(_2d.idPrefix+_2e);var e=null;if(_30!=null){var _32=_30.getElementsByTagName("*");for(var t=0;t<_32.length;t++){var c=_32[t];if(c.tagName.toLowerCase()=="input"||c.tagName.toLowerCase()=="textarea"){if(!e){e=c;}if(c.getAttribute("edit")==_2f){e=c;}}}}return e;};abego.setRange=function(_35,_36,end){if(_35.setSelectionRange){_35.setSelectionRange(_36,end);var max=0+_35.scrollHeight;var len=_35.textLength;var top=max*_36/len,bot=max*end/len;_35.scrollTop=Math.min(top,(bot+top-_35.clientHeight)/2);}else{if(_35.createTextRange!=undefined){var _3b=_35.createTextRange();_3b.collapse();_3b.moveEnd("character",end);_3b.moveStart("character",_36);_3b.select();}else{_35.select();}}};abego.internal.TagManager=function(){var _3c=null;var _3d=function(){if(_3c){return;}_3c={};store.forEachTiddler(function(_3e,_3f){for(var i=0;i<_3f.tags.length;i++){var tag=_3f.tags[i];var _42=_3c[tag];if(!_42){_42=_3c[tag]={count:0,tiddlers:{}};}_42.tiddlers[_3f.title]=true;_42.count+=1;}});};var _43=TiddlyWiki.prototype.saveTiddler;TiddlyWiki.prototype.saveTiddler=function(_44,_45,_46,_47,_48,_49){var _4a=this.fetchTiddler(_44);var _4b=_4a?_4a.tags:[];var _4c=(typeof _49=="string")?_49.readBracketedList():_49;_43.apply(this,arguments);if(!abego.arraysAreEqual(_4b,_4c)){abego.internal.getTagManager().reset();}};var _4d=TiddlyWiki.prototype.removeTiddler;TiddlyWiki.prototype.removeTiddler=function(_4e){var _4f=this.fetchTiddler(_4e);var _50=_4f&&_4f.tags.length>0;_4d.apply(this,arguments);if(_50){abego.internal.getTagManager().reset();}};this.reset=function(){_3c=null;};this.getTiddlersWithTag=function(tag){_3d();var _52=_3c[tag];return _52?_52.tiddlers:null;};this.getAllTags=function(_53){_3d();var _54=[];for(var i in _3c){_54.push(i);}for(i=0;_53&&i<_53.length;i++){_54.pushUnique(_53[i],true);}abego.sortIgnoreCase(_54);return _54;};this.getTagInfos=function(){_3d();var _56=[];for(var _57 in _3c){_56.push([_57,_3c[_57]]);}return _56;};var _58=function(a,b){var a1=a[1];var b1=b[1];var d=b[1].count-a[1].count;return d!=0?d:abego.compareStrings(a[0].toLowerCase(),b[0].toLowerCase());};this.getSortedTagInfos=function(){_3d();var _5e=this.getTagInfos();_5e.sort(_58);return _5e;};this.getPartnerRankedTags=function(_5f){var _60={};for(var i=0;i<_5f.length;i++){var _62=this.getTiddlersWithTag(_5f[i]);for(var _63 in _62){var _64=store.getTiddler(_63);if(!(_64 instanceof Tiddler)){continue;}for(var j=0;j<_64.tags.length;j++){var tag=_64.tags[j];var c=_60[tag];_60[tag]=c?c+1:1;}}}var _68=abego.toSet(_5f);var _69=[];for(var n in _60){if(!_68[n]){_69.push(n);}}_69.sort(function(a,b){var d=_60[b]-_60[a];return d!=0?d:abego.compareStrings(a.toLowerCase(),b.toLowerCase());});return _69;};};abego.internal.getTagManager=function(){if(!abego.internal.gTagManager){abego.internal.gTagManager=new abego.internal.TagManager();}return abego.internal.gTagManager;};(function(){var _6e=2;var _6f=1;var _70=30;var _71;var _72;var _73;var _74;var _75;var _76;if(!abego.IntelliTagger){abego.IntelliTagger={};}var _77=function(){return _72;};var _78=function(tag){return _75[tag];};var _7a=function(s){var i=s.lastIndexOf(" ");return (i>=0)?s.substr(0,i):"";};var _7d=function(_7e){var s=_7e.value;var len=s.length;return (len>0&&s[len-1]!=" ");};var _81=function(_82){var s=_82.value;var len=s.length;if(len>0&&s[len-1]!=" "){_82.value+=" ";}};var _85=function(tag,_87,_88){if(_7d(_87)){_87.value=_7a(_87.value);}story.setTiddlerTag(_88.title,tag,0);_81(_87);abego.IntelliTagger.assistTagging(_87,_88);};var _89=function(n){if(_76&&_76.length>n){return _76[n];}return (_74&&_74.length>n)?_74[n]:null;};var _8b=function(n,_8d,_8e){var _8f=_89(n);if(_8f){_85(_8f,_8d,_8e);}};var _90=function(_91){var pos=_91.value.lastIndexOf(" ");var _93=(pos>=0)?_91.value.substr(++pos,_91.value.length):_91.value;return new RegExp(_93.escapeRegExp(),"i");};var _94=function(_95,_96){var _97=0;for(var i=0;i<_95.length;i++){if(_96[_95[i]]){_97++;}}return _97;};var _99=function(_9a,_9b,_9c){var _9d=1;var c=_9a[_9b];for(var i=_9b+1;i<_9a.length;i++){if(_9a[i][1].count==c){if(_9a[i][0].match(_9c)){_9d++;}}else{break;}}return _9d;};var _a0=function(_a1,_a2){var _a3=abego.internal.getTagManager().getSortedTagInfos();var _a4=[];var _a5=0;for(var i=0;i<_a3.length;i++){var c=_a3[i][1].count;if(c!=_a5){if(_a2&&(_a4.length+_99(_a3,i,_a1)>_a2)){break;}_a5=c;}if(c==1){break;}var s=_a3[i][0];if(s.match(_a1)){_a4.push(s);}}return _a4;};var _a9=function(_aa,_ab){return abego.filterStrings(abego.internal.getTagManager().getAllTags(_ab),_aa);};var _ac=function(){if(!_71){return;}var _ad=store.getTiddlerText("IntelliTaggerMainTemplate");if(!_ad){_ad="<b>Tiddler IntelliTaggerMainTemplate not found</b>";}_71.innerHTML=_ad;applyHtmlMacros(_71,null);refreshElements(_71,null);};var _ae=function(e){if(!e){var e=window.event;}var tag=this.getAttribute("tag");if(_73){_73.call(this,tag,e);}return false;};var _b2=function(_b3){createTiddlyElement(_b3,"span",null,"tagSeparator"," | ");};var _b4=function(_b5,_b6,_b7,_b8,_b9){if(!_b6){return;}var _ba=_b8?abego.toSet(_b8):{};var n=_b6.length;var c=0;for(var i=0;i<n;i++){var tag=_b6[i];if(_ba[tag]){continue;}if(c>0){_b2(_b5);}if(_b9&&c>=_b9){abego.createEllipsis(_b5);break;}c++;var _bf="";var _c0=_b5;if(_b7<10){_c0=createTiddlyElement(_b5,"span",null,"numberedSuggestion");_b7++;var key=_b7<10?""+(_b7):"0";createTiddlyElement(_c0,"span",null,"suggestionNumber",key+") ");var _c2=_b7==1?"Return or ":"";_bf=" (Shortcut: %1Alt-%0)".format([key,_c2]);}var _c3=config.views.wikified.tag.tooltip.format([tag]);var _c4=(_78(tag)?"Remove tag '%0'%1":"Add tag '%0'%1").format([tag,_bf]);var _c5="%0; Shift-Click: %1".format([_c4,_c3]);var btn=createTiddlyButton(_c0,tag,_c5,_ae,_78(tag)?"currentTag":null);btn.setAttribute("tag",tag);}};var _c7=function(){if(_71){window.scrollTo(0,ensureVisible(_71));}if(_77()){window.scrollTo(0,ensureVisible(_77()));}};var _c8=function(e){if(!e){var e=window.event;}if(!_71){return;}var _cb=resolveTarget(e);if(_cb==_77()){return;}if(abego.isDescendantOrSelf(_71,_cb)){return;}abego.IntelliTagger.close();};addEvent(document,"click",_c8);var _cc=Story.prototype.gatherSaveFields;Story.prototype.gatherSaveFields=function(e,_ce){_cc.apply(this,arguments);var _cf=_ce.tags;if(_cf){_ce.tags=_cf.trim();}};var _d0=function(_d1){story.focusTiddler(_d1,"tags");var _d2=abego.getTiddlerField(story,_d1,"tags");if(_d2){var len=_d2.value.length;abego.setRange(_d2,len,len);window.scrollTo(0,ensureVisible(_d2));}};var _d4=config.macros.edit.handler;config.macros.edit.handler=function(_d5,_d6,_d7,_d8,_d9,_da){_d4.apply(this,arguments);var _db=_d7[0];if((_da instanceof Tiddler)&&_db=="tags"){var _dc=_d5.lastChild;_dc.onfocus=function(e){abego.IntelliTagger.assistTagging(_dc,_da);setTimeout(function(){_d0(_da.title);},100);};_dc.onkeyup=function(e){if(!e){var e=window.event;}if(e.altKey&&!e.ctrlKey&&!e.metaKey&&(e.keyCode>=48&&e.keyCode<=57)){_8b(e.keyCode==48?9:e.keyCode-49,_dc,_da);}else{if(e.ctrlKey&&e.keyCode==32){_8b(0,_dc,_da);}}if(!e.ctrlKey&&(e.keyCode==13||e.keyCode==10)){_8b(0,_dc,_da);}setTimeout(function(){abego.IntelliTagger.assistTagging(_dc,_da);},100);return false;};_81(_dc);}};var _e0=function(e){if(!e){var e=window.event;}var _e3=resolveTarget(e);var _e4=_e3.getAttribute("tiddler");if(_e4){story.displayTiddler(_e3,_e4,"IntelliTaggerEditTagsTemplate",false);_d0(_e4);}return false;};var _e5=config.macros.tags.handler;config.macros.tags.handler=function(_e6,_e7,_e8,_e9,_ea,_eb){_e5.apply(this,arguments);abego.IntelliTagger.createEditTagsButton(_eb,createTiddlyElement(_e6.lastChild,"li"));};var _ec=function(){if(_71&&_72&&!abego.isDescendantOrSelf(document,_72)){abego.IntelliTagger.close();}};setInterval(_ec,100);abego.IntelliTagger.displayTagSuggestions=function(_ed,_ee,_ef,_f0,_f1){_74=_ed;_75=abego.toSet(_ee);_76=_ef;_72=_f0;_73=_f1;if(!_71){_71=createTiddlyElement(document.body,"div",null,"intelliTaggerSuggestions");_71.style.position="absolute";}_ac();abego.openAsPopup(_71);if(_77()){var w=_77().offsetWidth;if(_71.offsetWidth<w){_71.style.width=(w-2*(_6e+_6f))+"px";}abego.moveBelowAndClip(_71,_77());}else{abego.centerOnWindow(_71);}_c7();};abego.IntelliTagger.assistTagging=function(_f3,_f4){var _f5=_90(_f3);var s=_f3.value;if(_7d(_f3)){s=_7a(s);}var _f7=s.readBracketedList();var _f8=_f7.length>0?abego.filterStrings(abego.internal.getTagManager().getPartnerRankedTags(_f7),_f5,_70):_a0(_f5,_70);abego.IntelliTagger.displayTagSuggestions(_a9(_f5,_f7),_f7,_f8,_f3,function(tag,e){if(e.shiftKey){onClickTag.call(this,e);}else{_85(tag,_f3,_f4);}});};abego.IntelliTagger.close=function(){abego.closePopup(_71);_71=null;return false;};abego.IntelliTagger.createEditTagsButton=function(_fb,_fc,_fd,_fe,_ff,id,_101){if(!_fd){_fd="[edit]";}if(!_fe){_fe="Edit the tags";}if(!_ff){_ff="editTags";}var _102=createTiddlyButton(_fc,_fd,_fe,_e0,_ff,id,_101);_102.setAttribute("tiddler",(_fb instanceof Tiddler)?_fb.title:String(_fb));return _102;};abego.IntelliTagger.getSuggestionTagsMaxCount=function(){return 100;};config.macros.intelliTagger={label:"intelliTagger",handler:function(_103,_104,_105,_106,_107,_108){var _109=_107.parseParams("list",null,true);var _10a=_109[0]["action"];for(var i=0;_10a&&i<_10a.length;i++){var _10c=_10a[i];var _10d=config.macros.intelliTagger.subhandlers[_10c];if(!_10d){abego.alertAndThrow("Unsupported action '%0'".format([_10c]));}_10d(_103,_104,_105,_106,_107,_108);}},subhandlers:{showTags:function(_10e,_10f,_110,_111,_112,_113){_b4(_10e,_74,_76?_76.length:0,_76,abego.IntelliTagger.getSuggestionTagsMaxCount());},showFavorites:function(_114,_115,_116,_117,_118,_119){_b4(_114,_76,0);},closeButton:function(_11a,_11b,_11c,_11d,_11e,_11f){var _120=createTiddlyButton(_11a,"close","Close the suggestions",abego.IntelliTagger.close);},version:function(_121){var t="IntelliTagger %0.%1.%2".format([version.extensions.IntelliTaggerPlugin.major,version.extensions.IntelliTaggerPlugin.minor,version.extensions.IntelliTaggerPlugin.revision]);var e=createTiddlyElement(_121,"a");e.setAttribute("href","http://tiddlywiki.abego-software.de/#IntelliTaggerPlugin");e.innerHTML="<font color=\"black\" face=\"Arial, Helvetica, sans-serif\">"+t+"<font>";},copyright:function(_124){var e=createTiddlyElement(_124,"a");e.setAttribute("href","http://tiddlywiki.abego-software.de");e.innerHTML="<font color=\"black\" face=\"Arial, Helvetica, sans-serif\">&copy; 2006-2007 <b><font color=\"red\">abego</font></b> Software<font>";}}};})();config.shadowTiddlers["IntelliTaggerStyleSheet"]="/***\n"+"!~IntelliTagger Stylesheet\n"+"***/\n"+"/*{{{*/\n"+".intelliTaggerSuggestions {\n"+"\tposition: absolute;\n"+"\twidth: 600px;\n"+"\n"+"\tpadding: 2px;\n"+"\tlist-style: none;\n"+"\tmargin: 0;\n"+"\n"+"\tbackground: #eeeeee;\n"+"\tborder: 1px solid DarkGray;\n"+"}\n"+"\n"+".intelliTaggerSuggestions .currentTag   {\n"+"\tfont-weight: bold;\n"+"}\n"+"\n"+".intelliTaggerSuggestions .suggestionNumber {\n"+"\tcolor: #808080;\n"+"}\n"+"\n"+".intelliTaggerSuggestions .numberedSuggestion{\n"+"\twhite-space: nowrap;\n"+"}\n"+"\n"+".intelliTaggerSuggestions .intelliTaggerFooter {\n"+"\tmargin-top: 4px;\n"+"\tborder-top-width: thin;\n"+"\tborder-top-style: solid;\n"+"\tborder-top-color: #999999;\n"+"}\n"+".intelliTaggerSuggestions .favorites {\n"+"\tborder-bottom-width: thin;\n"+"\tborder-bottom-style: solid;\n"+"\tborder-bottom-color: #999999;\n"+"\tpadding-bottom: 2px;\n"+"}\n"+"\n"+".intelliTaggerSuggestions .normalTags {\n"+"\tpadding-top: 2px;\n"+"}\n"+"\n"+".intelliTaggerSuggestions .intelliTaggerFooter .button {\n"+"\tfont-size: 10px;\n"+"\n"+"\tpadding-left: 0.3em;\n"+"\tpadding-right: 0.3em;\n"+"}\n"+"\n"+"/*}}}*/\n";config.shadowTiddlers["IntelliTaggerMainTemplate"]="<!--\n"+"{{{\n"+"-->\n"+"<div class=\"favorites\" macro=\"intelliTagger action: showFavorites\"></div>\n"+"<div class=\"normalTags\" macro=\"intelliTagger action: showTags\"></div>\n"+"<!-- The Footer (with the Navigation) ============================================ -->\n"+"<table class=\"intelliTaggerFooter\" border=\"0\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\"><tbody>\n"+"  <tr>\n"+"\t<td align=\"left\">\n"+"\t\t<span macro=\"intelliTagger action: closeButton\"></span>\n"+"\t</td>\n"+"\t<td align=\"right\">\n"+"\t\t<span macro=\"intelliTagger action: version\"></span>, <span macro=\"intelliTagger action: copyright \"></span>\n"+"\t</td>\n"+"  </tr>\n"+"</tbody></table>\n"+"<!--\n"+"}}}\n"+"-->\n";config.shadowTiddlers["IntelliTaggerEditTagsTemplate"]="<!--\n"+"{{{\n"+"-->\n"+"<div class='toolbar' macro='toolbar +saveTiddler -cancelTiddler'></div>\n"+"<div class='title' macro='view title'></div>\n"+"<div class='tagged' macro='tags'></div>\n"+"<div class='viewer' macro='view text wikified'></div>\n"+"<div class='toolbar' macro='toolbar +saveTiddler -cancelTiddler'></div>\n"+"<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser'></span></div>\n"+"<!--\n"+"}}}\n"+"-->\n";config.shadowTiddlers["BSD open source license (abego Software)"]="See [[Licence|http://tiddlywiki.abego-software.de/#%5B%5BBSD%20open%20source%20license%5D%5D]].";config.shadowTiddlers["IntelliTaggerPlugin Documentation"]="[[Documentation on abego Software website|http://tiddlywiki.abego-software.de/doc/IntelliTagger.pdf]].";config.shadowTiddlers["IntelliTaggerPlugin SourceCode"]="[[Plugin source code on abego Software website|http://tiddlywiki.abego-software.de/archive/IntelliTaggerPlugin/Plugin-IntelliTagger-src.1.0.2.js]]\n";(function(){var _126=restart;restart=function(){setStylesheet(store.getTiddlerText("IntelliTaggerStyleSheet"),"IntelliTaggerStyleSheet");_126.apply(this,arguments);};})();}
// %/
/***
|''Name:''|IntelliTagsEditCommandPlugin|
|''Version:''|1.0.0 (2007-10-03)|
|''Type:''|plugin|
|''Description:''|A command for your tiddler's toolbar to directly edit the tiddler's tags using the IntelliTaggerPlugin, without switching to "edit mode".|
|''Source:''|http://tiddlywiki.abego-software.de/#IntelliTagsEditCommandPlugin|
|''Requires:''|IntelliTaggerPlugin http://tiddlywiki.abego-software.de/#IntelliTaggerPlugin|
|''Author:''|Udo Borkowski (ub [at] abego-software [dot] de)|
|''Licence:''|[[BSD open source license (abego Software)]]|
|''~CoreVersion:''|2.0.8|
|''Browser:''|Firefox 1.5.0.2 or better|
***/
/***
!Using the "IntelliTagsEditCommandPlugin"
Add the command {{{intelliTagsEdit}}} into the 'macro' attribute of the 'toolbar' {{{<div...>}}} in your ViewTemplate.

''Example:''
{{{
<div class='toolbar' 
        macro='toolbar -closeTiddler closeOthers +editTiddler intelliTagsEdit permalink references jump'>
</div>
}}}

This adds a "tags" button to the toolbar of the tiddlers (next to the ''edit'' button). Pressing the "tags" button will open the input field for the tiddler's tags and let you edit the tags with all the [[IntelliTaggerPlugin|http://tiddlywiki.abego-software.de/#IntelliTaggerPlugin]] features.
***/
/***
!Source Code
***/
//{{{
(function(){

if (!version.extensions.IntelliTaggerPlugin)
    throw Error("IntelliTagsEditCommandPlugin requires the IntelliTaggerPlugin (http://tiddlywiki.abego-software.de/#IntelliTaggerPlugin)");

if (config.commands.intelliTagsEdit) 
    return;

config.commands.intelliTagsEdit = {
	text: "tags",
	tooltip: "edit the tags"
};

config.commands.intelliTagsEdit.handler = function(event,src,title) {
	var button = abego.IntelliTagger.createEditTagsButton(title, null, "tags", "edit the tags");
	button.onclick(event);
	return false;
};

})();
//}}}
/***
|Name|LoadTiddlersPlugin|
|Source|http://www.TiddlyTools.com/#LoadTiddlersPlugin|
|Documentation|http://www.TiddlyTools.com/#LoadTiddlersPluginInfo|
|Version|3.8.1|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|macro for automated updates or one-click installations of tiddlers from remote sources|
!!!!!Documentation
>see [[LoadTiddlersPluginInfo]]
!!!!!Configuration
<<<
<<option chkLoadTiddlersShowReport>>after loading tiddlers, automatically display [[ImportedTiddlers]] (if created)
__password-protected server settings //(optional, if needed)//:__
>username: <<option txtRemoteUsername>> password: <<option txtRemotePassword>>
>{{{usage: <<option txtRemoteUsername>> <<option txtRemotePassword>>}}}
>''note: these settings are also used by [[ExternalTiddlersPlugin]] and [[ImportTiddlersPlugin]]''
<<<
!!!!!Revisions
<<<
2009.10.08 3.8.1 removed switchTheme() from doImport()... causes an INFINITE cycle of imports!
|please see [[LoadTiddlersPluginInfo]] for additional revision details|
2005.07.20 1.0.0 Initial Release
<<<
!!!!!Code
***/
//{{{
version.extensions.LoadTiddlersPlugin= {major: 3, minor: 8, revision: 1, date: new Date(2009,10,8)};

if (config.options.chkLoadTiddlersShowReport===undefined)
	config.options.chkLoadTiddlersShowReport=true;

config.macros.loadTiddlers = {
	label: '',
	tip: "add/update tiddlers from '%0'",
	lockedTag: 'noReload',	// if existing tiddler has this tag value, don't overwrite it, even if inbound tiddler is newer
	askMsg: 'Please enter a local path/filename or a remote URL',
	openMsg: 'Opening %0',
	openErrMsg: 'Could not open %0 - error=%1',
	readMsg: 'Read %0 bytes from %1',
	foundMsg: 'Found %0 tiddlers in %1',
	nochangeMsg: "'%0' is up-to-date... skipped.",
	lockedMsg: "'%0' is tagged '%1'... skipped.",
	skippedMsg: 'skipped (cancelled by user)',
	loadedMsg: 'Loaded %0 of %1 tiddlers from %2',
	reportTitle: 'ImportedTiddlers',
	warning: "Warning!!  Processing '%0' as a systemConfig (plugin) tiddler may produce unexpected results! Are you sure you want to proceed?",
	handler: function(place,macroName,params) {
		var label=(params[0] && params[0].substr(0,6)=='label:')?params.shift().substr(6):this.label;
		var tip=(params[0] && params[0].substr(0,7)=='prompt:')?params.shift().substr(7):this.tip;
		var filter='updates';
		if (params[0] && (params[0]=='all' || params[0]=='new' || params[0]=='changes' || params[0]=='updates'
			|| params[0].substr(0,8)=='tiddler:' || params[0].substr(0,4)=='tag:'))
			filter=params.shift();
		var src=params.shift(); if (!src || !src.length) return; // filename is required
		var quiet=(params[0]=='quiet'); if (quiet) params.shift();
		var ask=(params[0]=='confirm'); if (ask) params.shift();
		var force=(params[0]=='force'); if (force) params.shift();
		var init=(params[0]=='init'); if (init) params.shift();
		var nodirty=(params[0]=='nodirty'); if (nodirty) params.shift();
		var norefresh=(params[0]=='norefresh'); if (norefresh) params.shift();
		var noreport=(params[0]=='noreport'); if (noreport) params.shift();
		this.newTags=[]; if (params[0]) this.newTags=params; // any remaining params are used as 'autotags'
		if (label.trim().length) {
			// link triggers load tiddlers from another file/URL and then applies filtering rules to add/replace tiddlers in the store
			createTiddlyButton(place,label.format([src.replace(/%20/g,' ')]),tip.format([src.replace(/%20/g,' ')]), function() {
				if (src=='ask') src=prompt(this.askMsg);
				config.macros.loadTiddlers.loadFile(src,config.macros.loadTiddlers.doImport,{quiet:quiet,ask:ask,filter:filter,force:force,init:init,noreport:noreport});
				return false;
			})
		}
		else {
			// load tiddlers from another file/URL and then apply filtering rules to add/replace tiddlers in the store
			if (src=='ask') src=prompt(this.askMsg);
			config.macros.loadTiddlers.loadFile(src,config.macros.loadTiddlers.doImport,{quiet:quiet,ask:ask,filter:filter,force:force,init:init,nodirty:nodirty,norefresh:norefresh,noreport:noreport});
		}
	},
	loadFile: function(src,callback,params) {
		var quiet=params.quiet;
		if (src==undefined || !src.length) return null; // filename is required
		if (!quiet) clearMessage();
		if (!quiet) displayMessage(this.openMsg.format([src.replace(/%20/g,' ')]));
		// if working locally and src is not a URL, read from local filesystem
		if (document.location.protocol=='file:' && src.substr(0,5)!='http:' && src.substr(0,5)!='file:') {
			var txt=loadFile(src);
			if (!txt) { // file didn't load, might be relative path.. try fixup
				var pathPrefix=document.location.href;  // get current document path and trim off filename
				var slashpos=pathPrefix.lastIndexOf('/'); if (slashpos==-1) slashpos=pathPrefix.lastIndexOf('\\'); 
				if (slashpos!=-1 && slashpos!=pathPrefix.length-1) pathPrefix=pathPrefix.substr(0,slashpos+1);
				src=pathPrefix+src;
				if (pathPrefix.substr(0,5)!='http:') src=getLocalPath(src);
				var txt=loadFile(src);
			}
			if (!txt) { // file still didn't load, report error
				if (!quiet) displayMessage(this.openErrMsg.format([src.replace(/%20/g,' '),'(unknown)']));
			} else {
				if (!quiet) displayMessage(this.readMsg.format([txt.length,src.replace(/%20/g,' ')]));
				if (version.major+version.minor*.1+version.revision*.01!=2.52)
					txt=convertUTF8ToUnicode(txt);
				if (callback) callback(true,params,txt,src,null);
			}
		} else { // use XMLHttpRequest
			doHttp('GET',src,null,null,config.options.txtRemoteUsername,config.options.txtRemotePassword,callback,params,null);
		}
	},
	readTiddlersFromHTML: function(html) {
		// for TW2.2+
		if (TiddlyWiki.prototype.importTiddlyWiki!=undefined) {
			var remoteStore=new TiddlyWiki();
			remoteStore.importTiddlyWiki(html);
			return remoteStore.getTiddlers('title');	
		}
	},
	readTiddlersFromCSV: function(CSV) {
		var remoteStore=new TiddlyWiki();
		// GET NAMES
		var lines=CSV.replace(/\r/g,'').split('\n');
		var names=lines.shift().replace(/"/g,'').split(',');
		CSV=lines.join('\n');
		// ENCODE commas and newlines within quoted values
		var comma='!~comma~!'; var commaRE=new RegExp(comma,'g');
		var newline='!~newline~!'; var newlineRE=new RegExp(newline,'g');
		CSV=CSV.replace(/"([^"]*?)"/g,
			function(x){ return x.replace(/\,/g,comma).replace(/\n/g,newline); });
		// PARSE lines
		var lines=CSV.split('\n');
		for (var i=0; i<lines.length; i++) { if (!lines[i].length) continue;
			var values=lines[i].split(',');
			// DECODE commas, newlines, and doubled-quotes, and remove enclosing quotes (if any)
			for (var v=0; v<values.length; v++)
				values[v]=values[v].replace(commaRE,',').replace(newlineRE,'\n')
					.replace(/^"|"$/g,'').replace(/""/g,'"');
			// EXTRACT tiddler values
			var title=''; var text=''; var tags=[]; var fields={};
			var created=null; var when=new Date(); var who=config.options.txtUserName;
			for (var v=0; v<values.length; v++) { var val=values[v];
				if (names[v]) switch(names[v].toLowerCase()) {
					case 'title':	title=val.replace(/\[\]\|/g,'_'); break;
					case 'created': created=new Date(val); break;
					case 'modified':when=new Date(val); break;
					case 'modifier':who=val; break;
					case 'text':	text=val; break;
					case 'tags':	tags=val.readBracketedList(); break;
					default:	fields[names[v].toLowerCase()]=val; break;
				}
			}
			// CREATE tiddler in temporary store
			if (title.length)
				remoteStore.saveTiddler(title,title,text,who,when,tags,fields,true,created||when);
		}
		return remoteStore.getTiddlers('title');	
	},
	createTiddlerFromFile: function(src,txt) {
		var t=new Tiddler();
		var pos=src.lastIndexOf("/"); if (pos==-1) pos=src.lastIndexOf("\\");
		t.title=pos==-1?src:src.substr(pos+1);
		t.text=txt; 
		t.created=t.modified=new Date();
		t.modifier=config.options.txtUserName;
		if (src.substr(src.length-3,3)=='.js') t.tags=['systemConfig'];
		return [t];
	},
	doImport: function(status,params,html,src,xhr) {
		var cml=config.macros.loadTiddlers; // abbrev
		src=src.split('?')[0]; // strip off "?nocache=..."
		if (!status) {
			displayMessage(cml.openErrMsg.format([src.replace(/%20/g,' '),xhr.status]));
			return false;
		}
		var quiet=params.quiet;
		var ask=params.ask;
		var filter=params.filter;
		var force=params.force;
		var init=params.init;
		var nodirty=params.nodirty;
		var norefresh=params.norefresh;
		var noreport=params.noreport;
		var tiddlers = cml.readTiddlersFromHTML(html);
		if (!tiddlers||!tiddlers.length) tiddlers=cml.readTiddlersFromCSV(html);
		if (!tiddlers||!tiddlers.length) tiddlers=cml.createTiddlerFromFile(src,html);
		var count=tiddlers?tiddlers.length:0;
		if (!quiet) displayMessage(cml.foundMsg.format([count,src.replace(/%20/g,' ')]));
		var wasDirty=store.isDirty();
		store.suspendNotifications();
		var count=0;
		if (tiddlers) for (var t=0;t<tiddlers.length;t++) {
			var inbound = tiddlers[t];
			var theExisting = store.getTiddler(inbound.title);
			if (inbound.title==cml.reportTitle)
				continue; // skip 'ImportedTiddlers' history from the other document...
			if (theExisting && theExisting.tags.contains(cml.lockedTag)) {
				if (!quiet) displayMessage(cml.lockedMsg.format([theExisting.title,cml.lockedTag]));
				continue; // skip existing tiddler if tagged with 'noReload'
			}
			// apply the all/new/changes/updates filter (if any)
			if (filter && filter!='all') {
				if ((filter=='new') && theExisting) // skip existing tiddlers
					continue;
				if ((filter=='changes') && !theExisting) // skip new tiddlers
					continue;
				if ((filter.substr(0,4)=='tag:') && inbound.tags.indexOf(filter.substr(4))==-1) // must match specific tag value
					continue;
				if ((filter.substr(0,8)=='tiddler:') && inbound.title!=filter.substr(8)) // must match specific tiddler name
					continue;
				if (!force && store.tiddlerExists(inbound.title) && ((theExisting.modified.getTime()-inbound.modified.getTime())>=0)) {
					var msg=cml.nochangeMsg;
					if (!quiet&&msg.length) displayMessage(msg.format([inbound.title]));
					continue;
				}
			}
			// get confirmation if required
			var msg=(theExisting?'Update':'Add')+" tiddler '"+inbound.title+"'\n"
				+'from '+src.replace(/%20/g,' ')+'\n\nOK to proceed?';
			if (ask && !confirm(msg))
				{ tiddlers[t].status=cml.skippedMsg; continue; }
			// DO IT!
			var tags=new Array().concat(inbound.tags,cml.newTags);
	                store.saveTiddler(inbound.title, inbound.title, inbound.text, inbound.modifier,
				inbound.modified, tags, inbound.fields, true, inbound.created);
			// force creation date to imported value - needed for TW2.1.3 or earlier
	                store.fetchTiddler(inbound.title).created = inbound.created;
			tiddlers[t].status=theExisting?'updated':'added'
			if (init && tags.contains('systemConfig') && !tags.contains('systemConfigDisable')) {
				var ok=true;
				if (ask||!quiet) ok=confirm(cml.warning.format([inbound.title]))
				if (ok) { // run the plugin
					try { window.eval(inbound.text); tiddlers[t].status+=' (plugin initialized)'; }
					catch(ex) { displayMessage(config.messages.pluginError.format([exceptionText(ex)])); }
				}
			}
			count++;
		}
		store.resumeNotifications();
		if (count) {
			// set/clear 'unsaved changes' flag, refresh page display, and generate a report
			store.setDirty(wasDirty||!nodirty);
			if (!norefresh) {
				story.forEachTiddler(function(t,e){
					if(!story.isDirty(t))story.refreshTiddler(t,null,true)
				});
				store.notifyAll();
			}
			if (!noreport) cml.report(src,tiddlers,count,quiet);
		}
		// show message whenver tiddlers are actually loaded
		if (!quiet||count)
			displayMessage(cml.loadedMsg.format([count,tiddlers.length,src.replace(/%20/g,' ')]));
	},
	showReport: true,
	report: function(src,tiddlers,count,quiet) {
		var cml=config.macros.loadTiddlers; // abbrev
		// format the new report content
		var newText = 'On '+(new Date()).toLocaleString()+', ';
		newText += config.options.txtUserName+' loaded '+count+' tiddlers ';
		newText += 'from\n[['+src+'|'+src+']]:\n';
		newText += '<<<\n';
		for (var t=0; t<tiddlers.length; t++)
			if (tiddlers[t].status)
				newText += '#[['+tiddlers[t].title+']] - '+tiddlers[t].status+'\n';
		newText += '<<<\n';
		var title=cml.reportTitle;
		var currText='';
		var t=store.getTiddler(title);
		if (t) currText=(t.text.length?'\n----\n':'')+t.text;
		store.saveTiddler(title, title, newText+currText,
			config.options.txtUserName, new Date(),	t?t.tags:null, t?t.fields:null);
		if (!quiet) {
			if (config.options.chkLoadTiddlersShowReport)
				story.displayTiddler(null,title);
			story.refreshTiddler(title,null,true);
		}
	}
}
//}}}
/***
|Name|LoadTiddlersPluginInfo|
|Source|http://www.TiddlyTools.com/#LoadTiddlersPlugin|
|Documentation|http://www.TiddlyTools.com/#LoadTiddlersPluginInfo|
|Version|3.8.1|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|documentation|
|Description|documentation for LoadTiddlersPlugin|
!!!!!Usage
<<<
Syntax:
{{{<<loadTiddlers label:text prompt:text filter source quiet confirm force init noreport tag tag tag...>>}}}

Example:
{{{<<loadTiddlers "label:load tiddlers from %0" example.html confirm temporary>>}}}
<<loadTiddlers "label:load tiddlers from %0" example.html confirm temporary>>

Where:
''"""label:text"""'' and ''"""prompt:text"""''
>defines link text and tooltip (prompt) that can be clicked to trigger the load tiddler processing.  If a label is NOT provided, then no link is created and the loadTiddlers function is performed whenever the containing tiddler is rendered.
''filter'' (optional) determines which tiddlers will be automatically selected for importing.  Use one of the following keywords:
>''"all"'' retrieves ALL tiddlers from the import source document, even if they have not been changed.
>''"new"'' retrieves only tiddlers that are found in the import source document, but do not yet exist in the destination document
>''"changes"'' retrieves only tiddlers that exist in both documents for which the import source tiddler is newer than the existing tiddler
>''"updates"'' retrieves both ''new'' and ''changed'' tiddlers (this is the default action when none is specified)
>''""""tiddler:TiddlerName""""'' retrieves only the specific tiddler named in the parameter.
>''""""tag:text""""'' retrieves only the tiddlers tagged with the indicated text.
>> Note: ''if an existing tiddler is tagged with 'noReload', then it will not be overwritten'', even if the inbound tiddler has been selected by the filtering process.  This allows you to make local changes to imported tiddlers while ensuring that those changes won't be lost due to automatic tiddler updates retrieved from the import source document.
''source'' (required) is the location of the imported document.  It can be either a local document path/filename in whatever format your system requires, or a remote web location (starting with "http://" or "https://")
>use the keyword ''ask'' to prompt for a source location whenever the macro is invoked
''"quiet"'' (optional)
>supresses all status message during the import processing (e.g., "opening local file...", "found NN tiddlers..." etc).  Note that if ANY tiddlers are actualy imported, a final information message will still be displayed (along with the ImportedTiddlers report), even when 'quiet' is specified.  This ensures that changes to your document cannot occur without any visible indication at all.
''"confirm"'' (optional)
>adds interactive confirmation.  A browser message box (OK/Cancel) is displayed for each tiddler that will be imported, so that you can manually bypass any tiddlers that you do not want to import.
''"init"'' (optional)
>invoke tiddlers tagged with <<tag systemConfig>> as plugins as soon as they are imported, without requiring a save-and-reload action first.  For safety, a browser message box (OK/Cancel) is displayed for each imported plugin, so that you can manually bypass any plugins that you do not want to invoke.  Note, however, that those tiddlers are still //imported// into your document and therefore will still take effect the next time you save-and-reload the document.
''"force"'' (optional)
>import all matching tiddlers, even if unchanged
''"noreport"'' (optional)
>suppress generation of [[ImportedTiddlers]] report
''"tag tag tag..."'' (optional)
>any remaining parameters are used as tag values to be added to each imported tiddler (i.e., "tag-on-import")
<<<
!!!!!Configuration
<<<
<<option chkLoadTiddlersShowReport>>after loading tiddlers, automatically display [[ImportedTiddlers]] (if created)
__password-protected server settings //(optional, if needed)//:__
>username: <<option txtRemoteUsername>> password: <<option txtRemotePassword>>
>{{{usage: <<option txtRemoteUsername>> <<option txtRemotePassword>>}}}
>''note: these settings are also used by [[ExternalTiddlersPlugin]] and [[ImportTiddlersPlugin]]''
<<<
!!!!!Revisions
<<<
2009.10.08 3.8.1 removed switchTheme() from doImport()... causes an INFINITE cycle of imports!
2009.10.06 3.8.0 added createTiddlerFromFile (import text files)
2009.10.04 3.7.8 in doImport(), call switchTheme() after loading tiddlers
2009.09.27 3.7.7 in readTiddlersFromCSV(), strip \r from input and fixed handling for quoted values
2009.09.01 3.7.6 added config.options.chkLoadTiddlersShowReport (default=true)
2009.09.01 3.7.6 added config.options.chkLoadTiddlersShowReport (default=true)
2009.08.30 3.7.5 in doImport(), check status and report error, if any
2009.08.29 3.7.4 in handler(), added 'return false' in button function (fixes IE page transition)
2009.08.19 3.7.3 in doImport(), fixed 'init' handling
2009.08.16 3.7.2 in doImport(), corrected check for tiddlers returned by readTiddlersFromHTML();
2009.07.03 3.7.1 fixups for TW252: doHttp() doesn't return XHR and convertUTF8ToUnicode() not needed for local I/O
2009.05.04 3.7.0 read CSV file format
2008.11.14 3.6.4 in loadFile(), force use of XMLHttpRequest if not viewing a local document (supports use of relative file references when online)
2008.10.27 3.6.3 in doImport(), fixed Safari bug by replacing static Array.concat(...) with new Array().concat(...)
2008.08.05 3.6.2 rewrote loadFile() to eliminate use of platform-specific fileExists() test
2008.08.03 3.6.1 in handler(), changed variable 'prompt' to 'tip' to avoid conflict with prompt() function
2008.01.07 3.6.0 added 'init' option to automatically invoke plugin tiddlers as soon as they are loaded (without needing save/reload)
2008.01.03 3.5.0 in loadFile(), use lower-level doHttp() instead of loadRemoteFile() in order to support username/password access to remote server
2007.12.04 *.*.* update for TW2.3.0: replaced deprecated core functions, regexps, and macros
2007.06.27 3.4.8 added missing 'fields' params to saveTiddler() call. Fixes problem where importing tiddlers would lose the custom fields.
2007.06.25 3.4.7 add calls to store.suspendNotifications() and store.resumeNotifications() to eliminate redisplay overhead DURING import activities.
2007.05.27 3.4.6 in handler(), loadRemoteFile() and doImport(), added 'noreport' flag to suppress generation of ImportedTiddlers
2007.05.27 3.4.5 in handler(), initialize 'newTags' to [] (empty array) instead of null... fixes fatal error when loading tiddler without autotagging.
2007.04.22 3.4.4 in readTiddlersFromHTML(), for TW2.2 and above, use importTiddlyWiki() (new core functionality) to get tiddlers from remote file content.  Also, copied updated TW21Loader.prototype.internalizeTiddler() definition from TW2.2b5 so plugin can read tiddlers from TW2.2+ even when running under TW2.1.x
2007.04.05 3.4.3 in doImport(), changed this.readTiddlersFromHTML(html) to config.macros.loadTiddlers.readTiddlersFromHTML(html).
2007.03.26 3.4.2 renamed import() to doImport() to fix IE load-time error ("identifier expected").  "import" is a reserved word in some browsers...
2007.03.22 3.4.1 code cleanup: moved all functions inside object def'n, re-wrote report function
2007.03.21 3.4.0 split ImportTiddlersPlugin and LoadTiddlersPlugin into separate plugins
|please see [[ImportTiddlersPluginInfo]] for additional revision details|
2005.07.20 1.0.0 Initial Release
<<<
/***
These tweaks are from www.tiddlytools.com. Not all of the tweaks on that site are included here, so it is named LocalCoreTweaks so
that it is not updated from the original sire (because of the name change).
***/

/***
!!!529 IE fixup - case-sensitive element lookup of tiddler elements
***/
/***
http://trac.tiddlywiki.org/ticket/529 - OPEN
This tweak hijacks the standard browser function, document.getElementById(), to work-around the case-INsensitivity error in Internet Explorer (all versions up to and including IE7) //''Note: This tweak is only applied when using IE, and only for lookups of rendered tiddler elements within the containing 'tiddlerDisplay' element.''//
***/
//{{{
if (config.browser.isIE) {
document.coreTweaks_coreGetElementById=document.getElementById;
document.getElementById=function(id) {
	var e=document.coreTweaks_coreGetElementById(id);
	if (!e || !e.parentNode || e.parentNode.id!='tiddlerDisplay') return e;
	for (var i=0; i<e.parentNode.childNodes.length; i++)
		if (id==e.parentNode.childNodes[i].id) return e.parentNode.childNodes[i];
	return null;
};
}
//}}}

/***
!!! 1134 handle references to tiddler sections in shadows
***/
/***
http://trac.tiddlywiki.org/ticket/1134
This tweak REPLACES and extends {{{store.getTiddlerText()}}} so it can return sections defined in shadow tiddlers.  It also permits use of leading whitespace in section headings.
***/
//{{{
TiddlyWiki.prototype.getTiddlerText = function(title,defaultText)
{
	if(!title) return defaultText;
	var parts = title.split(config.textPrimitives.sectionSeparator);
	var title = parts[0];
	var section = parts[1];
	var parts = title.split(config.textPrimitives.sliceSeparator);
	var title = parts[0];
	var slice = parts[1]?this.getTiddlerSlice(title,parts[1]):null;
	if(slice) return slice;
	var tiddler = this.fetchTiddler(title);
	var text = defaultText;
	if(this.isShadowTiddler(title))
		text = this.getShadowTiddlerText(title);
	if(tiddler)
		text = tiddler.text;
	if(!section) return text;
	var re = new RegExp("(^!{1,6}[ \t]*" + section.escapeRegExp() + "[ \t]*\n)","mg");
	re.lastIndex = 0;
	var match = re.exec(text);
	if(match) {
		var t = text.substr(match.index+match[1].length);
		var re2 = /^!/mg;
		re2.lastIndex = 0;
		match = re2.exec(t); //# search for the next heading
		if(match)
			t = t.substr(0,match.index-1);//# don't include final \n
		return t;
	}
	return defaultText;
};
//}}}
[[Welcome]]
[[ToolIndex]]
--------
<<tiddler ShowPopup with: [[BookmarkList]] "Bookmarks" "User's list of bookmarked tiddlers." >> @@font-size: smaller;[[(edit)|BookmarkList]]@@
--------
<<toggleSideBar "Toggle Right Bar" '' show>>
--------
<<tiddler InstructorMainMenu>>
!Presentations
<<openStory list "Presentation" >>
<<tiddler PresentationList>>
!Chapters
<<openStory list "Chapter" >>
<<tiddler ChapterList>>
!Quizzes
<<tiddler QuizList>>
/***
|Name|MatchTagsPlugin|
|Source|http://www.TiddlyTools.com/#MatchTagsPlugin|
|Documentation|http://www.TiddlyTools.com/#MatchTagsPluginInfo|
|Version|2.0.1|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|'tag matching' with full boolean expressions (AND, OR, NOT, and nested parentheses)|
!!!!!Documentation
> see [[MatchTagsPluginInfo]]
!!!!!Revisions
<<<
2009.08.29 [2.0.1] added support for {{{config.macros.matchTags.defTags}}} to auto-tag [[MatchingTiddlers]] output
| please see [[MatchTagsPluginInfo]] for additional revision details |
2008.02.28 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.MatchTagsPlugin= {major: 2, minor: 0, revision: 1, date: new Date(2009,8,29)};

// store.getMatchingTiddlers() processes boolean expressions for tag matching
//    sortfield (optional) sets sort order for tiddlers - default=title
//    tiddlers (optional) use alternative set of tiddlers (instead of current store)
TiddlyWiki.prototype.getMatchingTiddlers = function(tagexpr,sortfield,tiddlers) {

	var debug=config.options.chkDebug; // abbreviation
	var cmm=config.macros.matchTags; // abbreviation
	var r=[]; // results are an array of tiddlers
	var tids=tiddlers||store.getTiddlers(sortfield||"title");
	if (tiddlers && sortfield) store.sortTiddlers(tids,sortfield);
	if (debug) displayMessage(cmm.msg1.format([tids.length]));

	// try simple lookup to quickly find single tags or tags that
	// contain boolean operators as literals, e.g. "foo and bar"
	for (var t=0; t<tids.length; t++)
		if (tids[t].isTagged(tagexpr)) r.pushUnique(tids[t]);
	if (r.length) {
		if (debug) displayMessage(cmm.msg4.format([r.length,tagexpr]));
		return r;
	}
	
	// convert expression into javascript code with regexp tests,
	// so that "tag1 AND ( tag2 OR NOT tag3 )" becomes
	// "/\~tag1\~/.test(...) && ( /\~tag2\~/.test(...) || ! /\~tag3\~/.test(...) )"

	// normalize whitespace, tokenize operators, delimit with "~"
	var c=tagexpr.trim(); // remove leading/trailing spaces
	c = c.replace(/\s+/ig," "); // reduce multiple spaces to single spaces
	c = c.replace(/\(\s?/ig,"~(~"); // open parens
	c = c.replace(/\s?\)/ig,"~)~"); // close parens
	c = c.replace(/(\s|~)?&&(\s|~)?/ig,"~&&~"); // &&
	c = c.replace(/(\s|~)AND(\s|~)/ig,"~&&~"); // AND
	c = c.replace(/(\s|~)?\|\|(\s|~)?/ig,"~||~"); // ||
	c = c.replace(/(\s|~)OR(\s|~)/ig,"~||~"); // OR
	c = c.replace(/(\s|~)?!(\s|~)?/ig,"~!~"); // !
	c = c.replace(/(^|~|\s)NOT(\s|~)/ig,"~!~"); // NOT
	c = c.replace(/(^|~|\s)NOT~\(/ig,"~!~("); // NOT(
	// change tag terms to regexp tests
	var terms=c.split("~"); for (var i=0; i<terms.length; i++) { var t=terms[i];
		if (/(&&)|(\|\|)|[!\(\)]/.test(t) || t=="") continue; // skip operators/parens/spaces
		if (t==config.macros.matchTags.untaggedKeyword)
			terms[i]="tiddlertags=='~~'"; // 'untagged' tiddlers
		else
			terms[i]="/\\~"+t+"\\~/.test(tiddlertags)";
	}
	c=terms.join(" ");
	if (debug) { displayMessage(cmm.msg2.format([tagexpr])); displayMessage(cmm.msg3.format([c])); }

	// scan tiddlers for matches
	for (var t=0; t<tids.length; t++) {
	 	// assemble tags from tiddler into string "~tag1~tag2~tag3~"
		var tiddlertags = "~"+tids[t].tags.join("~")+"~";
		try { if(eval(c)) r.push(tids[t]); } // test tags
		catch(e) { // error in test
			displayMessage(cmm.msg2.format([tagexpr]));
			displayMessage(cmm.msg3.format([c]));
			displayMessage(e.toString());
			break; // skip remaining tiddlers
		}
	}
	if (debug) displayMessage(cmm.msg4.format([r.length,tagexpr]));
	return r;
}
//}}}
//{{{
config.macros.matchTags = {
	msg1: "scanning %0 input tiddlers",
	msg2: "looking for '%0'",
	msg3: "using expression: '%0'",
	msg4: "found %0 tiddlers matching '%1'",
	noMatch: "no matching tiddlers",
	untaggedKeyword: "-",
	untaggedLabel: "no tags",
	untaggedPrompt: "show tiddlers with no tags",
	defTiddler: "MatchingTiddlers",
	defTags: "",
	defFormat: "%0",
	defSeparator: "\n",
	reportHeading: "Found %0 tiddlers tagged with: '{{{%1}}}'\n----\n",
	handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		var mode=params[0]?params[0].toLowerCase():'';
		if (mode=="inline")
			params.shift();
		if (mode=="report" || mode=="panel") {
			params.shift();
			var target=params.shift()||this.defTiddler;
		}
		if (mode=="popup") {
			params.shift();
			if (params[0]&&params[0].substr(0,6)=="label:") var label=params.shift().substr(6);
			if (params[0]&&params[0].substr(0,7)=="prompt:") var prompt=params.shift().substr(7);
		} else {
			var fmt=(params.shift()||this.defFormat).unescapeLineBreaks();
			var sep=(params.shift()||this.defSeparator).unescapeLineBreaks();
		}
		var sortBy="+title";
		if (params[0]&&params[0].substr(0,5)=="sort:") sortBy=params.shift().substr(5);
		var expr = params.join(" ");
		if (mode!="panel" && (!expr||!expr.trim().length)) return;
		if (expr==this.untaggedKeyword)
			{ var label=this.untaggedLabel; var prompt=this.untaggedPrompt };
		switch (mode) {
			case "popup": this.createPopup(place,label,expr,prompt,sortBy); break;
			case "panel": this.createPanel(place,expr,fmt,sep,sortBy,target); break;
			case "report": this.createReport(target,this.defTags,expr,fmt,sep,sortBy); break;
			case "inline": default: this.createInline(place,expr,fmt,sep,sortBy); break;
		}
	},
	formatList: function(tids,fmt,sep) {
		var out=[];
		for (var t=0; t<tids.length; t++) {
			var title="[["+tids[t].title+"]]";
			var who=tids[t].modifier;
			var when=tids[t].modified.toLocaleString();
			var text=tids[t].text;
			var first=tids[t].text.split("\n")[0];
			var desc=store.getTiddlerSlice(tids[t].title,"description");
			desc=desc||store.getTiddlerSlice(tids[t].title,"Description");
			desc=desc||store.getTiddlerText(tids[t].title+"##description");
			desc=desc||store.getTiddlerText(tids[t].title+"##Description");
			out.push(fmt.format([title,who,when,text,first,desc]));
		}
		return out.join(sep);
	},
	createInline: function(place,expr,fmt,sep,sortBy) {
		wikify(this.formatList(store.sortTiddlers(store.getMatchingTiddlers(expr),sortBy),fmt,sep),place);
	},
	createPopup: function(place,label,expr,prompt,sortBy) {
		var btn=createTiddlyButton(place,
			(label||expr).format([expr]),
			(prompt||config.views.wikified.tag.tooltip).format([expr]),
			function(ev){ return config.macros.matchTags.showPopup(this,ev||window.event); });
		btn.setAttribute("sortBy",sortBy);
		btn.setAttribute("expr",expr);
	},
	showPopup: function(here,ev) {
		var p=Popup.create(here); if (!p) return false;
		var tids=store.getMatchingTiddlers(here.getAttribute("expr"));
		store.sortTiddlers(tids,here.getAttribute("sortBy"));
		var list=[]; for (var t=0; t<tids.length; t++) list.push(tids[t].title);
		if (!list.length) createTiddlyText(p,this.noMatch);
		else {
			var b=createTiddlyButton(createTiddlyElement(p,"li"),
				config.views.wikified.tag.openAllText,
				config.views.wikified.tag.openAllTooltip,
				function() {
					var list=this.getAttribute("list").readBracketedList();
					story.displayTiddlers(null,tids);
				});
			b.setAttribute("list","[["+list.join("]] [[")+"]]");
			createTiddlyElement(p,"hr");
		}
		var out=this.formatList(tids," &nbsp;%0&nbsp; ","\n"); wikify(out,p);
		Popup.show();
		ev.cancelBubble=true;
		if(ev.stopPropagation) ev.stopPropagation();
		return false;
	},
	createReport: function(target,tags,expr,fmt,sep,sortBy) {
		var tids=store.sortTiddlers(store.getMatchingTiddlers(expr),sortBy);
		if (!tids.length) { displayMessage('no matches for: '+expr); return false; }
		var msg=config.messages.overwriteWarning.format([target]);
		if (store.tiddlerExists(target) && !confirm(msg)) return false;
		var out=this.reportHeading.format([tids.length,expr])
		out+=this.formatList(tids,fmt,sep);
		store.saveTiddler(target,target,out,config.options.txtUserName,new Date(),tags,{});
		story.closeTiddler(target); story.displayTiddler(null,target);
	},
	createPanel: function(place,expr,fmt,sep,sortBy,tid) {
		var s=createTiddlyElement(place,"span"); s.innerHTML=store.getTiddlerText("MatchTagsPlugin##html");
		var f=s.getElementsByTagName("form")[0];
		f.expr.value=expr; f.fmt.value=fmt; f.sep.value=sep.escapeLineBreaks();
		f.tid.value=tid; f.tags.value=this.defTags;
	}
};
//}}}
/***
//{{{
!html
<form style='display:inline;white-space:nowrap'>
<input type='text'    name='expr' style='width:50%' title='tag expression'><!--
--><input type='text'    name='fmt'  style='width:10%' title='list item format'><!--
--><input type='text'    name='sep'  style='width:5%'  title='list item separator'><!--
--><input type='text'    name='tid'  style='width:12%' title='target tiddler title'><!--
--><input type='text'    name='tags' style='width:10%' title='target tiddler tags'><!--
--><input type='button'  name='go'   style='width:8%'  value='go' onclick="
	var expr=this.form.expr.value;
	if (!expr.length) { alert('Enter a boolean tag expression'); return false; }
	var fmt=this.form.fmt.value;
	if (!fmt.length) { alert('Enter the list item output format'); return false; }
	var sep=this.form.sep.value.unescapeLineBreaks();
	var tid=this.form.tid.value;
	if (!tid.length) { alert('Enter a target tiddler title'); return false; }
	var tags=this.form.tags.value;
	config.macros.matchTags.createReport(tid,tags,expr,fmt,sep,'title');
	return false;">
</form>
!end
//}}}
***/
//{{{
// SHADOW TIDDLER for displaying default panel input form
config.shadowTiddlers.MatchTags="<<matchTags panel>>";
//}}}
//{{{
// TWEAK core filterTiddlers() for enhanced boolean matching in [tag[...]] syntax:
// use getMatchingTiddlers instead getTaggedTiddlers
var fn=TiddlyWiki.prototype.filterTiddlers;
fn=fn.toString().replace(/getTaggedTiddlers/g,"getMatchingTiddlers");
eval("TiddlyWiki.prototype.filterTiddlers="+fn);
//}}}
//{{{
// REDEFINE core handler for enhanced boolean matching in tag:"..." paramifier
// use filterTiddlers() instead of getTaggedTiddlers() to get list of tiddlers.
config.paramifiers.tag = {
	onstart: function(v) {
		var tagged = store.filterTiddlers("[tag["+v+"]]");
		story.displayTiddlers(null,tagged,null,false,null);
	}
};
//}}}
/***
|Name|MatchTagsPluginInfo|
|Source|http://www.TiddlyTools.com/#MatchTagsPlugin|
|Documentation|http://www.TiddlyTools.com/#MatchTagsPluginInfo|
|Version|2.0.1|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|documentation|
|Requires||
|Overrides||
|Description|documentation for MatchTagsPlugin|
!!!!!Usage
<<<
This plugin extends the {{{[tag[tagname]]}}} macro parameter syntax used by the TiddlyWiki core {{{<<list>>}}} macro so that, instead of a simple tagname value, you can specify a complex combination of tagname values using a //boolean expression// containing AND, OR, and NOT operators, enclosed in nested parentheses if needed.
{{{
<<list filter "[tag[expression]]">>
}}}
In addition, the plugin defines a new macro, {{{<<matchTags ...>>}}} that can be used instead of the core {{{<<list>>}}} macro to output a list of matching tiddlers //using a custom 'item format' and 'separator'//.  You can also use this macro to create a command link that displays the matching tiddlers within a popup list, similar to the standard {{{<<tag tagName>>}}} macro, but matching a combination of tag values rather than a single tag value.
{{{
<<matchTags inline "format" "separator" sort:fieldname tag expression>>
<<matchTags popup "label:..." "prompt:..." sort:fieldname tag expression>>
<<matchTags report TiddlerName "format" "separator" sort:fieldname tag expression>>
<<matchTags panel  Tiddlername "format" "separator" sort:fieldname tag expression>>
}}}
where:
* ''inline'', ''report'', ''panel'', and ''popup''<br>are keywords that indicate the type of output that the macro should produce:
** ''inline'' //(default)// - displays a list of matching tiddlers embedded directly in tiddler content
** ''popup'' - embeds a command button that, when clicked, lists matching tiddlers in a ~TiddlyWiki popup display
** ''report'' - generates a list of matching tiddler in a separate [[MatchingTiddlers]] report tiddler
** ''panel'' - displays an interactive form for generating a [[MatchingTiddlers]] report
* ''format''<br>defines the wiki-syntax for rendering list items.  The following //substitution markers// can be used to insert tiddler-specific information for each matched tiddler:
** {{{%0}}} - title
** {{{%1}}} - modifier (author)
** {{{%2}}} - modified (date of last change)
** {{{%3}}} - text (all tiddler content)
** {{{%4}}} - firstline (tiddler content up to the first newline)
** {{{%5}}} - description (tiddler slice or section content named "description" or "Description")
* ''separator''<br>defines the wiki-syntax to use //between// each matching title (e.g., ", " creates a comma-separated list, while "\n" displays one tiddler per line).
* ''sort:fieldname'' (optional)<br>specifies the sort order for the resulting list of tiddlers.  You can specify any tiddler field name (standard or custom-defined).  Standard tiddler fieldnames include: //title, created, modified, modifier//.  If not specified, tiddlers are sorted by title.  You can prefix the fieldname with "+" or "-" to indicate ascending or descending order, respectively.
* ''tag expression''<br>the remaining parameter(s) are joined together to define the boolean expression to be matched.
When using the ''popup'' option, there are two additional (and optional) parameters you can specify:
* ''"label:..."''(optional)<br> indicates the text for the popup command link.  The default is to display the specified tag expression itself.
* ''"prompt:..."'' (optional)<br>indicates the mouseover 'tooltip' for the popup command link.
When using the ''report'' or ''panel'' option, an additional parameter may be provided:
* ''~TiddlerName''<br>specifies the target tiddler into which the output will be generated (default: [[MatchingTiddlers]])
Notes:
*A tag expression can use any combination of text operators: ''AND'', ''OR'', ''NOT'' (or their equivalent javascript operators: ''&&'', ''||'', ''!''), contained in nested parentheses as needed.
*Operators should be delimited by spaces or parentheses.
*Before matching, leading/trailing spaces are automatically trimmed and multiple spaces are reduced to single spaces.
*Tag values containing embedded spaces do //not// have to be enclosed in {{{[[...]]}}}.
*Tag values that contain boolean operators as ''literal text'' (e.g., {{{"foo and bar"}}} or {{{"foo && bar"}}} cannot be used within a compound boolean expression, but //can// be matched if specified by themselves, without any other tag values or operators.
*To match tiddlers that are untagged, use "-" as a special tag value within the expression.
*You can match "wildcard" tags  by using //regular expression// (i.e., "text pattern") syntax within a tag value, e.g. {{{[Tt]agvalue.*}}}
<<<
!!!!!Examples:
<<<
display a popup list:
{{{
<<matchTags popup sample OR (settings AND systemConfig)>>
}}}
><<matchTags popup sample OR (settings AND systemConfig)>>
display a popup list with custom label:
{{{
<<matchTags popup "label:samples and settings" sample OR (settings AND systemConfig)>>
}}}
><<matchTags popup "label:samples and settings" sample OR (settings AND systemConfig)>>
display a popup list of untagged tiddlers:
{{{
<<matchTags popup ->>
}}}
><<matchTags popup ->>
generate a report using interactive form control panel
{{{
<<matchTags panel "MatchingTiddlers" "%0" "\n" sample OR (settings AND systemConfig)>>
}}}
>{{smallform{<<matchTags panel "MatchingTiddlers" "%0" "\n" sample OR (settings AND systemConfig)>>}}}
comma-separated list:
{{{
<<matchTags "%0" ", " sample OR (settings AND systemConfig)>>
}}}
><<matchTags "%0" ", " sample OR (settings AND systemConfig)>>
numbered list (sorted by modification date, most recent first):
{{{
<<matchTags "#%0 (%2)<br>^^%5^^" "\n" sort:-modified sample OR (settings AND systemConfig)>>
}}}
><<matchTags "#%0 (%2)<br>^^%5^^" "\n" sort:-modified sample OR (settings AND systemConfig)>>
bullet-item list (using the TiddlyWiki core {{{<<list filter ...>>}}} macro):
//(Note: when using the core {{{<<list>>}}} macro, you should always enclose the entire tag filter parameter within quotes)//
{{{
<<list filter "[tag[sample OR (settings AND systemConfig)]]">>
}}}
><<list filter "[tag[sample OR (settings AND systemConfig)]]">>
<<<
!!!!!Revisions
<<<
2009.08.29 [2.0.1] added support for {{{config.macros.matchTags.defTags}}} to auto-tag [[MatchingTiddlers]] output
2008.09.04 [2.0.0] added "report" and "panel" options to generate formatted results and store in a tiddler.  Also, added config.macros.matchTags.formatList(place,fmt,sep) API to return formatted output for use with other plugins/scripts
2008.09.01 [1.9.2] fixed return value from popup button handler so IE doesn't attempt to leave the page
2008.08.31 [1.9.1] improved expression conversion handling to permit use of regular expressions for "wildcard" matching within tag values
2008.06.12 [1.9.0] added support for formatted output of: title, who, when, text, firstline, description (slice or section)
2008.06.05 [1.8.0] in getMatchingTiddlers(), added optional sortfield and tiddlers params to support use of alternative set of tiddlers instead of using current store content (provides filtering support for ImportTiddlersPlugin)
2008.06.04 [1.7.1] in getMatchingTiddlers(), reworked conversion of expression for more robust parsing of whitespace, parentheses and javascript operators and allow use of "-" (untagged) //within// expressions
2008.05.19 [1.7.0] in getMatchingTiddlers(), use reverseLookup() instead of forEachTiddler() to permit access to tiddlers included via [[IncludePlugin|http://tiddlywiki.abego-software.de/#IncludePlugin]]
2008.05.17 [1.6.0] in getMatchingTiddlers(), rewrote expression conversion to handle tags with spaces tag values that are substrings of other tag values.
2008.05.16 [1.5.0] added special case using "-" to find UNTAGGED tiddlers
2008.05.15 [1.4.0] added "popup" output option
2008.05.14 [1.3.4] instead of hijacking getTaggedTiddlers(), added tweak of filterTiddlers() prototype to replace getTaggedTiddlers() with getMatchingTiddler() so that core use of getTaggedTiddlers() does not perform boolean processing of tiddler titles such as [[To Be or not To Be]].  Also, improved "filter error" messages in getMatchingTiddlers() to report tag expression in addition to actual eval error.
2008.04.25 [1.3.3] in getTaggedTiddlers(), fixed handling for "not" embedded within a tag
2008.04.21 [1.3.2] in getTaggedTiddlers(), fixed handling for initial "NOT" and "NOT(expr)" syntax
2008.04.20 [1.3.1] in getTaggedTiddlers(), corrected check for boolean expression to avoid excess processing of tags containing spaces.  Also, improved handling for non-existing tags that contain text of existing tags
2008.04.19 [1.3.0] in filterTiddlers(), use getTaggedTiddlers() instead of matchTags(), and then hijack getTaggedTiddlers() to add matchTags() handling
2008.04.19 [*.*.*] plugin size reduction: moved documentation to [[MatchTagsPluginInfo]]
2008.03.25 [1.2.0] added optional "sort:fieldname" parameter
2008.03.20 [1.1.2] in handler(), replace 'encodeTiddlyLink' with explicit [[...]] brackets to ensure that one-word tiddler titles are properly rendered as TiddlyLinks
2008.02.29 [1.1.1] in matchTags(), added handling to skip remaining tiddlers if expression has an error
2008.02.29 [1.1.0] refactored to define store.matchTags() and extend store.filterTiddlers()
2008.02.28 [1.0.0] initial release
<<<
!What is ~MindMapping?

{{overlay1{[[Wikipedia|http://en.wikipedia.org/wiki/Mind_map]]:
<<<
 A mind map is a diagram used to represent words, ideas, tasks, or other items linked to and arranged around a central key word or idea. Mind maps are used to generate, visualize, structure, and classify ideas, and as an aid in study, organization, problem solving, decision making, and writing.
<<<
}}}
{{overlay2{
!!Use Cases
}}}
<html>
<hide linebreaks>
<ul>
<li class="overlay2">Outlining</li>
<li class="overlay3">Process design/diagram</li>
<li class="overlay4">Project management</li>
<li class="overlay5">Brainstorming</li>
<li class="overlay6">Structured notebook</li>
</ul>
</html>
/***
|Name|NestedSlidersPlugin|
|Source|http://www.TiddlyTools.com/#NestedSlidersPlugin|
|Documentation|http://www.TiddlyTools.com/#NestedSlidersPluginInfo|
|Version|2.4.9|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Options|##Configuration|
|Description|show content in nest-able sliding/floating panels, without creating separate tiddlers for each panel's content|
!!!!!Documentation
>see [[NestedSlidersPluginInfo]]
!!!!!Configuration
<<<
<<option chkFloatingSlidersAnimate>> allow floating sliders to animate when opening/closing
>Note: This setting can cause 'clipping' problems in some versions of InternetExplorer.
>In addition, for floating slider animation to occur you must also allow animation in general (see [[AdvancedOptions]]).
<<<
!!!!!Revisions
<<<
2008.11.15 - 2.4.9 in adjustNestedSlider(), don't make adjustments if panel is marked as 'undocked' (CSS class).  In onClickNestedSlider(), SHIFT-CLICK docks panel (see [[MoveablePanelPlugin]])
|please see [[NestedSlidersPluginInfo]] for additional revision details|
2005.11.03 - 1.0.0 initial public release.  Thanks to RodneyGomes, GeoffSlocock, and PaulPetterson for suggestions and experiments.
<<<
!!!!!Code
***/
//{{{
version.extensions.NestedSlidersPlugin= {major: 2, minor: 4, revision: 9, date: new Date(2008,11,15)};

// options for deferred rendering of sliders that are not initially displayed
if (config.options.chkFloatingSlidersAnimate===undefined)
	config.options.chkFloatingSlidersAnimate=false; // avoid clipping problems in IE

// default styles for 'floating' class
setStylesheet(".floatingPanel { position:absolute; z-index:10; padding:0.5em; margin:0em; \
	background-color:#eee; color:#000; border:1px solid #000; text-align:left; }","floatingPanelStylesheet");

// if removeCookie() function is not defined by TW core, define it here.
if (window.removeCookie===undefined) {
	window.removeCookie=function(name) {
		document.cookie = name+'=; expires=Thu, 01-Jan-1970 00:00:01 UTC; path=/;'; 
	}
}

config.formatters.push( {
	name: "nestedSliders",
	match: "\\n?\\+{3}",
	terminator: "\\s*\\={3}\\n?",
	lookahead: "\\n?\\+{3}(\\+)?(\\([^\\)]*\\))?(\\!*)?(\\^(?:[^\\^\\*\\@\\[\\>]*\\^)?)?(\\*)?(\\@)?(?:\\{\\{([\\w]+[\\s\\w]*)\\{)?(\\[[^\\]]*\\])?(\\[[^\\]]*\\])?(?:\\}{3})?(\\#[^:]*\\:)?(\\>)?(\\.\\.\\.)?\\s*",
	handler: function(w)
		{
			lookaheadRegExp = new RegExp(this.lookahead,"mg");
			lookaheadRegExp.lastIndex = w.matchStart;
			var lookaheadMatch = lookaheadRegExp.exec(w.source)
			if(lookaheadMatch && lookaheadMatch.index == w.matchStart)
			{
				var defopen=lookaheadMatch[1];
				var cookiename=lookaheadMatch[2];
				var header=lookaheadMatch[3];
				var panelwidth=lookaheadMatch[4];
				var transient=lookaheadMatch[5];
				var hover=lookaheadMatch[6];
				var buttonClass=lookaheadMatch[7];
				var label=lookaheadMatch[8];
				var openlabel=lookaheadMatch[9];
				var panelID=lookaheadMatch[10];
				var blockquote=lookaheadMatch[11];
				var deferred=lookaheadMatch[12];

				// location for rendering button and panel
				var place=w.output;

				// default to closed, no cookie, no accesskey, no alternate text/tip
				var show="none"; var cookie=""; var key="";
				var closedtext=">"; var closedtip="";
				var openedtext="<"; var openedtip="";

				// extra "+", default to open
				if (defopen) show="block";

				// cookie, use saved open/closed state
				if (cookiename) {
					cookie=cookiename.trim().slice(1,-1);
					cookie="chkSlider"+cookie;
					if (config.options[cookie]==undefined)
						{ config.options[cookie] = (show=="block") }
					show=config.options[cookie]?"block":"none";
				}

				// parse label/tooltip/accesskey: [label=X|tooltip]
				if (label) {
					var parts=label.trim().slice(1,-1).split("|");
					closedtext=parts.shift();
					if (closedtext.substr(closedtext.length-2,1)=="=")	
						{ key=closedtext.substr(closedtext.length-1,1); closedtext=closedtext.slice(0,-2); }
					openedtext=closedtext;
					if (parts.length) closedtip=openedtip=parts.join("|");
					else { closedtip="show "+closedtext; openedtip="hide "+closedtext; }
				}

				// parse alternate label/tooltip: [label|tooltip]
				if (openlabel) {
					var parts=openlabel.trim().slice(1,-1).split("|");
					openedtext=parts.shift();
					if (parts.length) openedtip=parts.join("|");
					else openedtip="hide "+openedtext;
				}

				var title=show=='block'?openedtext:closedtext;
				var tooltip=show=='block'?openedtip:closedtip;

				// create the button
				if (header) { // use "Hn" header format instead of button/link
					var lvl=(header.length>5)?5:header.length;
					var btn = createTiddlyElement(createTiddlyElement(place,"h"+lvl,null,null,null),"a",null,buttonClass,title);
					btn.onclick=onClickNestedSlider;
					btn.setAttribute("href","javascript:;");
					btn.setAttribute("title",tooltip);
				}
				else
					var btn = createTiddlyButton(place,title,tooltip,onClickNestedSlider,buttonClass);
				btn.innerHTML=title; // enables use of HTML entities in label

				// set extra button attributes
				btn.setAttribute("closedtext",closedtext);
				btn.setAttribute("closedtip",closedtip);
				btn.setAttribute("openedtext",openedtext);
				btn.setAttribute("openedtip",openedtip);
				btn.sliderCookie = cookie; // save the cookiename (if any) in the button object
				btn.defOpen=defopen!=null; // save default open/closed state (boolean)
				btn.keyparam=key; // save the access key letter ("" if none)
				if (key.length) {
					btn.setAttribute("accessKey",key); // init access key
					btn.onfocus=function(){this.setAttribute("accessKey",this.keyparam);}; // **reclaim** access key on focus
				}
				btn.setAttribute("hover",hover?"true":"false");
				btn.onmouseover=function(ev) {
					// optional 'open on hover' handling
					if (this.getAttribute("hover")=="true" && this.sliderPanel.style.display=='none') {
						document.onclick.call(document,ev); // close transients
						onClickNestedSlider(ev); // open this slider
					}
					// mouseover on button aligns floater position with button
					if (window.adjustSliderPos) window.adjustSliderPos(this.parentNode,this,this.sliderPanel);
				}

				// create slider panel
				var panelClass=panelwidth?"floatingPanel":"sliderPanel";
				if (panelID) panelID=panelID.slice(1,-1); // trim off delimiters
				var panel=createTiddlyElement(place,"div",panelID,panelClass,null);
				panel.button = btn; // so the slider panel know which button it belongs to
				btn.sliderPanel=panel; // so the button knows which slider panel it belongs to
				panel.defaultPanelWidth=(panelwidth && panelwidth.length>2)?panelwidth.slice(1,-1):"";
				panel.setAttribute("transient",transient=="*"?"true":"false");
				panel.style.display = show;
				panel.style.width=panel.defaultPanelWidth;
				panel.onmouseover=function(event) // mouseover on panel aligns floater position with button
					{ if (window.adjustSliderPos) window.adjustSliderPos(this.parentNode,this.button,this); }

				// render slider (or defer until shown) 
				w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
				if ((show=="block")||!deferred) {
					// render now if panel is supposed to be shown or NOT deferred rendering
					w.subWikify(blockquote?createTiddlyElement(panel,"blockquote"):panel,this.terminator);
					// align floater position with button
					if (window.adjustSliderPos) window.adjustSliderPos(place,btn,panel);
				}
				else {
					var src = w.source.substr(w.nextMatch);
					var endpos=findMatchingDelimiter(src,"+++","===");
					panel.setAttribute("raw",src.substr(0,endpos));
					panel.setAttribute("blockquote",blockquote?"true":"false");
					panel.setAttribute("rendered","false");
					w.nextMatch += endpos+3;
					if (w.source.substr(w.nextMatch,1)=="\n") w.nextMatch++;
				}
			}
		}
	}
)

function findMatchingDelimiter(src,starttext,endtext) {
	var startpos = 0;
	var endpos = src.indexOf(endtext);
	// check for nested delimiters
	while (src.substring(startpos,endpos-1).indexOf(starttext)!=-1) {
		// count number of nested 'starts'
		var startcount=0;
		var temp = src.substring(startpos,endpos-1);
		var pos=temp.indexOf(starttext);
		while (pos!=-1)  { startcount++; pos=temp.indexOf(starttext,pos+starttext.length); }
		// set up to check for additional 'starts' after adjusting endpos
		startpos=endpos+endtext.length;
		// find endpos for corresponding number of matching 'ends'
		while (startcount && endpos!=-1) {
			endpos = src.indexOf(endtext,endpos+endtext.length);
			startcount--;
		}
	}
	return (endpos==-1)?src.length:endpos;
}
//}}}
//{{{
window.onClickNestedSlider=function(e)
{
	if (!e) var e = window.event;
	var theTarget = resolveTarget(e);
	while (theTarget && theTarget.sliderPanel==undefined) theTarget=theTarget.parentNode;
	if (!theTarget) return false;
	var theSlider = theTarget.sliderPanel;
	var isOpen = theSlider.style.display!="none";

	// if SHIFT-CLICK, dock panel first (see [[MoveablePanelPlugin]])
	if (e.shiftKey && config.macros.moveablePanel) config.macros.moveablePanel.dock(theSlider,e);

	// toggle label
	theTarget.innerHTML=isOpen?theTarget.getAttribute("closedText"):theTarget.getAttribute("openedText");
	// toggle tooltip
	theTarget.setAttribute("title",isOpen?theTarget.getAttribute("closedTip"):theTarget.getAttribute("openedTip"));

	// deferred rendering (if needed)
	if (theSlider.getAttribute("rendered")=="false") {
		var place=theSlider;
		if (theSlider.getAttribute("blockquote")=="true")
			place=createTiddlyElement(place,"blockquote");
		wikify(theSlider.getAttribute("raw"),place);
		theSlider.setAttribute("rendered","true");
	}

	// show/hide the slider
	if(config.options.chkAnimate && (!hasClass(theSlider,'floatingPanel') || config.options.chkFloatingSlidersAnimate))
		anim.startAnimating(new Slider(theSlider,!isOpen,e.shiftKey || e.altKey,"none"));
	else
		theSlider.style.display = isOpen ? "none" : "block";

	// reset to default width (might have been changed via plugin code)
	theSlider.style.width=theSlider.defaultPanelWidth;

	// align floater panel position with target button
	if (!isOpen && window.adjustSliderPos) window.adjustSliderPos(theSlider.parentNode,theTarget,theSlider);

	// if showing panel, set focus to first 'focus-able' element in panel
	if (theSlider.style.display!="none") {
		var ctrls=theSlider.getElementsByTagName("*");
		for (var c=0; c<ctrls.length; c++) {
			var t=ctrls[c].tagName.toLowerCase();
			if ((t=="input" && ctrls[c].type!="hidden") || t=="textarea" || t=="select")
				{ try{ ctrls[c].focus(); } catch(err){;} break; }
		}
	}
	var cookie=theTarget.sliderCookie;
	if (cookie && cookie.length) {
		config.options[cookie]=!isOpen;
		if (config.options[cookie]!=theTarget.defOpen) window.saveOptionCookie(cookie);
		else window.removeCookie(cookie); // remove cookie if slider is in default display state
	}

	// prevent SHIFT-CLICK from being processed by browser (opens blank window... yuck!)
	// prevent clicks *within* a slider button from being processed by browser
	// but allow plain click to bubble up to page background (to close transients, if any)
	if (e.shiftKey || theTarget!=resolveTarget(e))
		{ e.cancelBubble=true; if (e.stopPropagation) e.stopPropagation(); }
	Popup.remove(); // close open popup (if any)
	return false;
}
//}}}
//{{{
// click in document background closes transient panels 
document.nestedSliders_savedOnClick=document.onclick;
document.onclick=function(ev) { if (!ev) var ev=window.event; var target=resolveTarget(ev);

	if (document.nestedSliders_savedOnClick)
		var retval=document.nestedSliders_savedOnClick.apply(this,arguments);
	// if click was inside a popup... leave transient panels alone
	var p=target; while (p) if (hasClass(p,"popup")) break; else p=p.parentNode;
	if (p) return retval;
	// if click was inside transient panel (or something contained by a transient panel), leave it alone
	var p=target; while (p) {
		if ((hasClass(p,"floatingPanel")||hasClass(p,"sliderPanel"))&&p.getAttribute("transient")=="true") break;
		p=p.parentNode;
	}
	if (p) return retval;
	// otherwise, find and close all transient panels...
	var all=document.all?document.all:document.getElementsByTagName("DIV");
	for (var i=0; i<all.length; i++) {
		 // if it is not a transient panel, or the click was on the button that opened this panel, don't close it.
		if (all[i].getAttribute("transient")!="true" || all[i].button==target) continue;
		// otherwise, if the panel is currently visible, close it by clicking it's button
		if (all[i].style.display!="none") window.onClickNestedSlider({target:all[i].button})
		if (!hasClass(all[i],"floatingPanel")&&!hasClass(all[i],"sliderPanel")) all[i].style.display="none";
	}
	return retval;
};
//}}}
//{{{
// adjust floating panel position based on button position
if (window.adjustSliderPos==undefined) window.adjustSliderPos=function(place,btn,panel) {
	if (hasClass(panel,"floatingPanel") && !hasClass(panel,"undocked")) {
		// see [[MoveablePanelPlugin]] for use of 'undocked'
		var rightEdge=document.body.offsetWidth-1;
		var panelWidth=panel.offsetWidth;
		var left=0;
		var top=btn.offsetHeight; 
		if (place.style.position=="relative" && findPosX(btn)+panelWidth>rightEdge) {
			left-=findPosX(btn)+panelWidth-rightEdge; // shift panel relative to button
			if (findPosX(btn)+left<0) left=-findPosX(btn); // stay within left edge
		}
		if (place.style.position!="relative") {
			var left=findPosX(btn);
			var top=findPosY(btn)+btn.offsetHeight;
			var p=place; while (p && !hasClass(p,'floatingPanel')) p=p.parentNode;
			if (p) { left-=findPosX(p); top-=findPosY(p); }
			if (left+panelWidth>rightEdge) left=rightEdge-panelWidth;
			if (left<0) left=0;
		}
		panel.style.left=left+"px"; panel.style.top=top+"px";
	}
}
//}}}
//{{{
// TW2.1 and earlier:
// hijack Slider stop handler so overflow is visible after animation has completed
Slider.prototype.coreStop = Slider.prototype.stop;
Slider.prototype.stop = function()
	{ this.coreStop.apply(this,arguments); this.element.style.overflow = "visible"; }

// TW2.2+
// hijack Morpher stop handler so sliderPanel/floatingPanel overflow is visible after animation has completed
if (version.major+.1*version.minor+.01*version.revision>=2.2) {
	Morpher.prototype.coreStop = Morpher.prototype.stop;
	Morpher.prototype.stop = function() {
		this.coreStop.apply(this,arguments);
		var e=this.element;
		if (hasClass(e,"sliderPanel")||hasClass(e,"floatingPanel")) {
			// adjust panel overflow and position after animation
			e.style.overflow = "visible";
			if (window.adjustSliderPos) window.adjustSliderPos(e.parentNode,e.button,e);
		}
	};
}
//}}}
/***
|Name|NestedSlidersPluginInfo|
|Source|http://www.TiddlyTools.com/#NestedSlidersPlugin|
|Documentation|http://www.TiddlyTools.com/#NestedSlidersPluginInfo|
|Version|2.4.9|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|documentation|
|Requires||
|Overrides||
|Description|documentation for NestedSlidersPlugin|
This plugin adds new wiki syntax for embedding 'slider' panels directly into tiddler content.
!!!!!Usage
<<<
Use {{{+++}}} and {{{===}}} to delimit the slider content.  You can also 'nest' these sliders as deep as you like (see complex nesting example below), so that expandable 'tree-like' hierarchical displays can be created.  This is most useful when converting existing in-line text content to create in-line annotations, footnotes, context-sensitive help, or other subordinate information displays.

Additional optional syntax elements let you specify
*default to open
*cookiename
*heading level
*floater (with optional CSS width value)
*transient display (clicking elsewhere closes panel)
*open on hover (without needing to click)
*custom class/label/tooltip/accesskey
*alternate label/tooltip (displayed when panel is open)
*panelID (for later use with {{{<<DOM>>}}} macro.  See [[DOMTweaksPlugin]])
*automatic blockquote style on panel
*deferred rendering of panel content
The complete syntax, using all options, is:
//{{{
++++(cookiename)!!!!!^width^*@{{class{[label=key|tooltip][altlabel|alttooltip]}}}#panelID:>...
content goes here
===
//}}}
where:
* ''"""+++""" (or """++++""") and """==="""''<br>marks the start and end of the slider definition, respectively.  When the extra {{{+}}} is used, the slider will be open when initially displayed.
* ''"""(cookiename)"""''<br>saves the slider opened/closed state, and restores this state whenever the slider is re-rendered.
* ''"""! through !!!!!"""''<br>displays the slider label using a formatted headline (Hn) style instead of a button/link style
* ''"""^width^ (or just ^)"""''<br>makes the slider 'float' on top of other content rather than shifting that content downward.  'width' must be a valid CSS value (e.g., "30em", "180px", "50%", etc.).  If omitted, the default width is "auto" (i.e., fit to content)
* ''"""*"""''<br>denotes "transient display": when a click occurs elsewhere in the document, the slider/floating panel will be automatically closed.  This is useful for creating 'pulldown menus' that automatically go away after they are used.  //Note: using SHIFT-click on a slider label will open/close that slider without triggering the automatic closing of any transient slider panels that are currently displayed, permitting ''temporary'' display of several transient panels at once.//
* ''"""@"""''<br>denotes "open on hover": the slider/floating panel will be automatically opened as soon as the mouse moves over the slider label, without requiring a click.
* ''"""{{class{[label=key|tooltip][altlabel|alttooltip]}}}"""''<br>uses label/tooltip/accesskey.  """{{class{...}}}""", """=key""", """|tooltip""" and """[altlabel|alttooltip]""" are optional.  'class' is any valid CSS class name, used to style the slider label text.  'key' must be a ''single letter only''.  altlabel/alttooltip specify alternative label/tooltip for use when slider/floating panel is displayed.  //Note: you can use HTML syntax within the label text to include HTML entities (e.g., {{{&raquo;}}} (&raquo;) or {{{&#x25ba;}}} (&#x25ba;), or even embedded images (e.g., {{{<img src="images/eric3.gif">}}}).//
* ''"""#panelID:"""''<br>defines a unique DOM element ID that is assigned to the panel element used to display the slider content.  This ID can then be used later to reposition the panel using the {{{<<DOM move id>>}}} macro (see [[DOMTweaksPlugin]]), or to access/modify the panel element through use of {{{document.getElementById(...)}}}) javascript code in a plugin or inline script.
* ''""">"""''<br>automatically adds blockquote formatting to slider content
* ''"""..."""''<br>defers rendering of closed sliders until the first time they are opened.  //Note: deferred rendering may produce unexpected results in some cases.  Use with care.//

//Note: to make slider definitions easier to read and recognize when editing a tiddler, newlines immediately following the {{{+++}}} 'start slider' or preceding the {{{===}}} 'end slider' sequence are automatically supressed so that excess whitespace is eliminated from the output.//
<<<
!!!!!Examples
<<<
simple in-line slider: 
{{{
+++
   content
===
}}}
+++
   content
===
----
use a custom label and tooltip: 
{{{
+++[label|tooltip]
   content
===
}}}
+++[label|tooltip]
   content
===
----
content automatically blockquoted: 
{{{
+++>
   content
===
}}}
+++>
   content
===
----
all options (except cookie) //(default open, heading, sized floater, transient, open on hover, class, label/tooltip/key, blockquoted, deferred)//
{{{
++++!!!^30em^*@{{big{[label=Z|click or press Alt-Z to open]}}}>...
   content
===
}}}
++++!!!^30em^*@{{big{[label=Z|click or press Alt-Z to open]}}}>...
   content
===
----
complex nesting example:
{{{
+++[get info...=I|click for information or press Alt-I]
	put some general information here,
	plus a floating panel with more specific info:
	+++^10em^[view details...|click for details]
		put some detail here, which could in turn contain a transient panel,
		perhaps with a +++^25em^*[glossary definition]explaining technical terms===
	===
===
}}}
+++[get info...=I|click for information or press Alt-I]
	put some general information here,
	plus a floating panel with more specific info:
	+++^10em^[view details...|click for details]
		put some detail here, which could in turn contain a transient panel,
		perhaps with a +++^25em^*[glossary definition]explaining technical terms===
	===
===
----
embedded image as slider button
{{{
+++[<img src=images/eric3.gif>|click me!]>
	{{big{OUCH!}}}
===
}}}
+++[<img src=images/eric3.gif>|click me!]>
	{{big{OUCH!}}}
===
<<<
!!!!!Revisions
<<<
2008.11.15 - 2.4.9 in adjustNestedSlider(), don't make adjustments if panel is marked as 'undocked' (CSS class).  In onClickNestedSlider(), SHIFT-CLICK docks panel (see [[MoveablePanelPlugin]])
2008.11.13 - 2.4.8 in document.onclick(), if transient panel is not a sliderPanel or floatingPanel, hide it via CSS
2008.10.05 - 2.4.7 in onClickNestedSlider(), added try/catch around focus() call to prevent IE error if input field being focused on is currently not visible.
2008.09.07 - 2.4.6 added removeCookie() function for compatibility with [[CookieManagerPlugin]]
2008.06.07 - 2.4.5 in 'onmouseover' handler for 'open on hover' slider buttons, use call() method when invoking document.onclick function (avoids error in IE)
2008.06.07 - 2.4.4 changed default for chkFloatingSlidersAnimate to FALSE to avoid clipping problem on some browsers (IE).  Updated Morpher hijack (again) to adjust regular sliderPanel styles as well as floatingPanel styles.
2008.05.07 - 2.4.3 updated Morpher hijack to adjust floatingPanel styles after animation without affecting other animated elements (i.e. popups).  Also, updated adjustSliderPos() to account for scrollwidth and use core findWindowWidth().
2008.04.02 - 2.4.2 in onClickNestedSlider, handle clicks on elements contained //within// slider buttons (e.g., when using HTML to display an image as a slider button).
2008.04.01 - 2.4.1 open on hover also triggers document.onclick to close other transient sliders
2008.04.01 - 2.4.0 re-introduced 'open on hover' feature using "@" symbol
2008.03.26 - 2.3.5 in document.onclick(), if click is in popup, don't dismiss transient panel (if any)
2008.01.08 - [*.*.*] plugin size reduction: documentation moved to ...Info tiddler
2007.12.28 - 2.3.4 added hijack for Animator.prototype.startAnimating().  Previously, the plugin code simply set the overflow to "visible" after animation.  This code tweak corrects handling of elements that were styled with overflow=hidden/auto/scroll before animation by saving the overflow style and then restoring it after animation has completed.
2007.12.17 - 2.3.3 use hasClass() instead of direct comparison to test for "floatingPanel" class.  Allows floating panels to have additional classes assigned to them (i.e., by AnimationEffectsPlugin).
2007.11.14 - 2.3.2 in onClickNestedSlider(), prevent SHIFT-click events from opening a new, empty browser window by setting "cancelBubble=true" and calling "stopPropagation()".  Note: SHIFT-click is still processed as a normal click (i.e., it toggles the slider panel display).  Also, using SHIFT-click will prevent 'transient' sliders from being automatically closed when another slider is opened, allowing you to *temporarily* display several transient sliders at once.
2007.07.26 - 2.3.1 in document.onclick(), propagate return value from hijacked core click handler to consume OR bubble up click as needed.  Fixes "IE click disease", whereby nearly every mouse click causes a page transition.
2007.07.20 - 2.3.0 added syntax for setting panel ID (#panelID:).  This allows individual slider panels to be repositioned within tiddler content simply by giving them a unique ID and then moving them to the desired location using the {{{<<DOM move id>>}}} macro.
2007.07.19 - 2.2.0 added syntax for alttext and alttip (button label and tooltip to be displayed when panel is open)
2007.07.14 - 2.1.2 corrected use of 'transient' attribute in IE to prevent (non-recursive) infinite loop
2007.07.12 - 2.1.0 replaced use of "*" for 'open/close on rollover' (which didn't work too well).  "*" now indicates 'transient' panels that are automatically closed if a click occurs somewhere else in the document.  This permits use of nested sliders to create nested "pulldown menus" that automatically disappear after interaction with them has been completed.  Also, in onClickNestedSlider(), use "theTarget.sliderCookie", instead of "this.sliderCookie" to correct cookie state tracking when automatically dismissing transient panels.
2007.06.10 - 2.0.5 add check to ensure that window.adjustSliderPanel() is defined before calling it (prevents error on shutdown when mouse event handlers are still defined)
2007.05.31 - 2.0.4 add handling to invoke adjustSliderPanel() for onmouseover events on slider button and panel.  This allows the panel position to be re-synced when the button position shifts due to changes in unrelated content above it on the page.  (thanks to Harsha for bug report)
2007.03.30 - 2.0.3 added chkFloatingSlidersAnimate (default to FALSE), so that slider animation can be disabled independent of the overall document animation setting (avoids strange rendering and focus problems in floating panels)
2007.03.01 - 2.0.2 for TW2.2+, hijack Morpher.prototype.stop so that "overflow:hidden" can be reset to "overflow:visible" after animation ends
2007.03.01 - 2.0.1 in hijack for Slider.prototype.stop, use apply() to pass params to core function
2006.07.28 - 2.0.0 added custom class syntax around label/tip/key syntax: {{{{{classname{[label=key|tip]}}}}}}
2006.07.25 - 1.9.3 when parsing slider, save default open/closed state in button element, then in onClickNestedSlider(), if slider state matches saved default, instead of saving cookie, delete it.  Significantly reduces the 'cookie overhead' when default slider states are used.
2006.06.29 - 1.9.2 in onClickNestedSlider(), when setting focus to first control, skip over type="hidden"
2006.06.22 - 1.9.1 added panel.defaultPanelWidth to save requested panel width, even after resizing has changed the style value
2006.05.11 - 1.9.0 added optional '^width^' syntax for floating sliders and '=key' syntax for setting an access key on a slider label
2006.05.09 - 1.8.0 in onClickNestedSlider(), when showing panel, set focus to first child input/textarea/select element
2006.04.24 - 1.7.8 in adjustSliderPos(), if floating panel is contained inside another floating panel, subtract offset of containing panel to find correct position
2006.02.16 - 1.7.7 corrected deferred rendering to account for use-case where show/hide state is tracked in a cookie
2006.02.15 - 1.7.6 in adjustSliderPos(), ensure that floating panel is positioned completely within the browser window (i.e., does not go beyond the right edge of the browser window)
2006.02.04 - 1.7.5 add 'var' to unintended global variable declarations to avoid FireFox 1.5.0.1 crash bug when assigning to globals
2006.01.18 - 1.7.4 only define adjustSliderPos() function if it has not already been provided by another plugin.  This lets other plugins 'hijack' the function even when they are loaded first.
2006.01.16 - 1.7.3 added adjustSliderPos(place,btn,panel,panelClass) function to permit specialized logic for placement of floating panels.  While it provides improved placement for many uses of floating panels, it exhibits a relative offset positioning error when used within *nested* floating panels.  Short-term workaround is to only adjust the position for 'top-level' floaters.
2006.01.16 - 1.7.2 added button property to slider panel elements so that slider panel can tell which button it belongs to.  Also, re-activated and corrected animation handling so that nested sliders aren't clipped by hijacking Slider.prototype.stop so that "overflow:hidden" can be reset to "overflow:visible" after animation ends
2006.01.14 - 1.7.1 added optional "^" syntax for floating panels.  Defines new CSS class, ".floatingPanel", as an alternative for standard in-line ".sliderPanel" styles.
2006.01.14 - 1.7.0 added optional "*" syntax for rollover handling to show/hide slider without requiring a click (Based on a suggestion by tw4efl)
2006.01.03 - 1.6.2 When using optional "!" heading style, instead of creating a clickable "Hn" element, create an "A" element inside the "Hn" element.  (allows click-through in SlideShowPlugin, which captures nearly all click events, except for hyperlinks)
2005.12.15 - 1.6.1 added optional "..." syntax to invoke deferred ('lazy') rendering for initially hidden sliders
removed checkbox option for 'global' application of lazy sliders
2005.11.25 - 1.6.0 added optional handling for 'lazy sliders' (deferred rendering for initially hidden sliders)
2005.11.21 - 1.5.1 revised regular expressions: if present, a single newline //preceding// and/or //following// a slider definition will be suppressed so start/end syntax can be place on separate lines in the tiddler 'source' for improved readability.  Similarly, any whitespace (newlines, tabs, spaces, etc.) trailing the 'start slider' syntax or preceding the 'end slider' syntax is also suppressed.
2005.11.20 - 1.5.0 added (cookiename) syntax for optional tracking and restoring of slider open/close state
2005.11.11 - 1.4.0 added !!!!! syntax to render slider label as a header (Hn) style instead of a button/link style
2005.11.07 - 1.3.0 removed alternative syntax {{{(((}}} and {{{)))}}} (so they can be used by other formatting extensions) and simplified/improved regular expressions to trim multiple excess newlines
2005.11.05 - 1.2.1 changed name to NestedSlidersPlugin
2005.11.04 - 1.2.0 added alternative character-mode syntax {{{(((}}} and {{{)))}}}
tweaked "eat newlines" logic for line-mode {{{+++}}} and {{{===}}} syntax
2005.11.03 - 1.1.1 fixed toggling of default tooltips ("more..." and "less...") when a non-default button label is used.  code cleanup, added documentation
2005.11.03 - 1.1.0 changed delimiter syntax from {{{(((}}} and {{{)))}}} to {{{+++}}} and {{{===}}}.  changed name to EasySlidersPlugin
2005.11.03 - 1.0.0 initial public release
<<<
/% {{ "$1" != "$" + "1" ? "$1"  : "Open links in %0"}} 
    computed param when called as: <<tiddler OpenStoryButton with: "button label" "tooltip" > >
    $1  is set to "button label" and $2 is set to "tooltip" if no params are specified, $1 and $2 are
    not substituted. So the computed param checks to see if $1 was replaced (by concatenating
    $ and 1 so I don't have the obviously false "$1" != "$1") and if it was uses it. If it wasn't use
    the alternate string with %1 being the name of the parent tiddler.

   No return after the % and / so no newline is rendered when included.
%/{{openStoryButton{
<<openStory {{tiddler.title}} {{ "$1" != "$" + "1" ? "$1"  : "Open links in %0"}} {{ "$2" != "$" + "2" ? "$2"  : "Open all of the links in %0 according to the check boxes"}}>>
''The first/topmost checked box determines how tidders are opened''
<<option chkStoryClose>> close other tiddlers when opening
<<option chkStoryBottom>> open tiddlers at bottom of story column
<<option chkStoryTop>> open tiddlers at top of story column
}}}
Verticals are the name supplied to TiddlyWiki used for a specific task.
<html>
<hide linebreaks>
<ul>
<li>Educational Coursebook - Textbook, presentations and note taking all in one</li>
<li class="overlay2">TWAB - http://www.tiddly-twab.com/ - ~TiddlyWIki Address Book</li>
<li class="overlay3">~MediaWiki unplugged - http://mediawikiunplugged.com/ - take your mediawiki with you</li> 
<li class="overlay4">Team Tasks - http://getteamtasks.com/ -- a task management tool
<li class="overlay5">~NoteStorm - http://www.giffmex.org/NoteStorm.html -- an astonishingly simple way to take and organize notes
</ul>
</html>
{{overlay5{See more at the non-profit company that supports TiddlyWiki: http://www.osmosoft.com/#Products}}}
! Toolbar command for tiddlers tagged with content.

|~ContentViewToolbar|closeTiddler closeOthers editTiddler refresh jump >  fields permalink references < |
<!--{{{-->
<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>
<span style='display:none' macro='tiddler SiteStartup'></span>
<!--}}}-->
/***
|<html><a name="Top"/></html>''Name:''|PartTiddlerPlugin|
|''Version:''|1.0.9 (2007-07-14)|
|''Source:''|http://tiddlywiki.abego-software.de/#PartTiddlerPlugin|
|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|
|''Licence:''|[[BSD open source license]]|
|''CoreVersion:''|2.1.3|
|''Browser:''|Firefox 1.0.4+; InternetExplorer 6.0|
!Table of Content<html><a name="TOC"/></html>
* <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Description',null, event)">Description, Syntax</a></html>
* <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Applications',null, event)">Applications</a></html>
** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('LongTiddler',null, event)">Refering to Paragraphs of a Longer Tiddler</a></html>
** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Citation',null, event)">Citation Index</a></html>
** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('TableCells',null, event)">Creating "multi-line" Table Cells</a></html>
** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Tabs',null, event)">Creating Tabs</a></html>
** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Sliders',null, event)">Using Sliders</a></html>
* <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Revisions',null, event)">Revision History</a></html>
* <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Code',null, event)">Code</a></html>
!Description<html><a name="Description"/></html>
With the {{{<part aPartName> ... </part>}}} feature you can structure your tiddler text into separate (named) parts. 
Each part can be referenced as a "normal" tiddler, using the "//tiddlerName//''/''//partName//" syntax (e.g. "About/Features").  E.g. you may create links to the parts (e.g. {{{[[Quotes/BAX95]]}}} or {{{[[Hobbies|AboutMe/Hobbies]]}}}), use it in {{{<<tiddler...>>}}} or {{{<<tabs...>>}}} macros etc.


''Syntax:'' 
|>|''<part'' //partName// [''hidden''] ''>'' //any tiddler content// ''</part>''|
|//partName//|The name of the part. You may reference a part tiddler with the combined tiddler name "//nameOfContainerTidder//''/''//partName//. <br />If you use a partName containing spaces you need to quote it (e.g. {{{"Major Overview"}}} or {{{[[Shortcut List]]}}}).|
|''hidden''|When defined the content of the part is not displayed in the container tiddler. But when the part is explicitly referenced (e.g. in a {{{<<tiddler...>>}}} macro or in a link) the part's content is displayed.|
|<html><i>any&nbsp;tiddler&nbsp;content</i></html>|<html>The content of the part.<br>A part can have any content that a "normal" tiddler may have, e.g. you may use all the formattings and macros defined.</html>|
|>|~~Syntax formatting: Keywords in ''bold'', optional parts in [...]. 'or' means that exactly one of the two alternatives must exist.~~|
<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>

!Applications<html><a name="Applications"/></html>
!!Refering to Paragraphs of a Longer Tiddler<html><a name="LongTiddler"/></html>
Assume you have written a long description in a tiddler and now you want to refer to the content of a certain paragraph in that tiddler (e.g. some definition.) Just wrap the text with a ''part'' block, give it a nice name, create a "pretty link" (like {{{[[Discussion Groups|Introduction/DiscussionGroups]]}}}) and you are done.

Notice this complements the approach to first writing a lot of small tiddlers and combine these tiddlers to one larger tiddler in a second step (e.g. using the {{{<<tiddler...>>}}} macro). Using the ''part'' feature you can first write a "classic" (longer) text that can be read "from top to bottom" and later "reuse" parts of this text for some more "non-linear" reading.

<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>

!!Citation Index<html><a name="Citation"/></html>
Create a tiddler "Citations" that contains your "citations". 
Wrap every citation with a part and a proper name. 

''Example''
{{{
<part BAX98>Baxter, Ira D. et al: //Clone Detection Using Abstract Syntax Trees.// 
in //Proc. ICSM//, 1998.</part>

<part BEL02>Bellon, Stefan: //Vergleich von Techniken zur Erkennung duplizierten Quellcodes.// 
Thesis, Uni Stuttgart, 2002.</part>

<part DUC99>Ducasse, Stéfane et al: //A Language Independent Approach for Detecting Duplicated Code.// 
in //Proc. ICSM//, 1999.</part>
}}}

You may now "cite" them just by using a pretty link like {{{[[Citations/BAX98]]}}} or even more pretty, like this {{{[[BAX98|Citations/BAX98]]}}}.

<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>

!!Creating "multi-line" Table Cells<html><a name="TableCells"/></html>
You may have noticed that it is hard to create table cells with "multi-line" content. E.g. if you want to create a bullet list inside a table cell you cannot just write the bullet list
{{{
* Item 1
* Item 2
* Item 3
}}}
into a table cell (i.e. between the | ... | bars) because every bullet item must start in a new line but all cells of a table row must be in one line.

Using the ''part'' feature this problem can be solved. Just create a hidden part that contains the cells content and use a {{{<<tiddler >>}}} macro to include its content in the table's cell.

''Example''
{{{
|!Subject|!Items|
|subject1|<<tiddler ./Cell1>>|
|subject2|<<tiddler ./Cell2>>|

<part Cell1 hidden>
* Item 1
* Item 2
* Item 3
</part>
...
}}}

Notice that inside the {{{<<tiddler ...>>}}} macro you may refer to the "current tiddler" using the ".".

BTW: The same approach can be used to create bullet lists with items that contain more than one line.

<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>

!!Creating Tabs<html><a name="Tabs"/></html>
The build-in {{{<<tabs ...>>}}} macro requires that you defined an additional tiddler for every tab it displays. When you want to have "nested" tabs you need to define a tiddler for the "main tab" and one for every tab it contains. I.e. the definition of a set of tabs that is visually displayed at one place is distributed across multiple tiddlers.

With the ''part'' feature you can put the complete definition in one tiddler, making it easier to keep an overview and maintain the tab sets.

''Example''
The standard tabs at the sidebar are defined by the following eight tiddlers:
* SideBarTabs
* TabAll
* TabMore
* TabMoreMissing
* TabMoreOrphans
* TabMoreShadowed
* TabTags
* TabTimeline

Instead of these eight tiddlers one could define the following SideBarTabs tiddler that uses the ''part'' feature:
{{{
<<tabs txtMainTab 
    Timeline Timeline SideBarTabs/Timeline 
    All 'All tiddlers' SideBarTabs/All 
    Tags 'All tags' SideBarTabs/Tags 
    More 'More lists' SideBarTabs/More>>
<part Timeline hidden><<timeline>></part>
<part All hidden><<list all>></part>
<part Tags hidden><<allTags>></part>
<part More hidden><<tabs txtMoreTab 
    Missing 'Missing tiddlers' SideBarTabs/Missing 
    Orphans 'Orphaned tiddlers' SideBarTabs/Orphans 
    Shadowed 'Shadowed tiddlers' SideBarTabs/Shadowed>></part>
<part Missing hidden><<list missing>></part>
<part Orphans hidden><<list orphans>></part>
<part Shadowed hidden><<list shadowed>></part>
}}}

Notice that you can easily "overwrite" individual parts in separate tiddlers that have the full name of the part.

E.g. if you don't like the classic timeline tab but only want to see the 100 most recent tiddlers you could create a tiddler "~SideBarTabs/Timeline" with the following content:
{{{
<<forEachTiddler 
		sortBy 'tiddler.modified' descending 
		write '(index < 100) ? "* [["+tiddler.title+"]]\n":""'>>
}}}
<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>

!!Using Sliders<html><a name="Sliders"/></html>
Very similar to the build-in {{{<<tabs ...>>}}} macro (see above) the {{{<<slider ...>>}}} macro requires that you defined an additional tiddler that holds the content "to be slid". You can avoid creating this extra tiddler by using the ''part'' feature

''Example''
In a tiddler "About" we may use the slider to show some details that are documented in the tiddler's "Details" part.
{{{
...
<<slider chkAboutDetails About/Details details "Click here to see more details">>
<part Details hidden>
To give you a better overview ...
</part>
...
}}}

Notice that putting the content of the slider into the slider's tiddler also has an extra benefit: When you decide you need to edit the content of the slider you can just doubleclick the content, the tiddler opens for editing and you can directly start editing the content (in the part section). In the "old" approach you would doubleclick the tiddler, see that the slider is using tiddler X, have to look for the tiddler X and can finally open it for editing. So using the ''part'' approach results in a much short workflow.

<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>

!Revision history<html><a name="Revisions"/></html>
* v1.0.9 (2007-07-14)
** Bugfix: Error when using the SideBarTabs example and switching between "More" and "Shadow". Thanks to cmari for reporting the issue.
* v1.0.8 (2007-06-16)
** Speeding up display of tiddlers containing multiple pard definitions. Thanks to Paco Rivière for reporting the issue.
** Support "./partName" syntax inside <<tabs ...>> macro
* v1.0.7 (2007-03-07)
** Bugfix: <<tiddler "./partName">> does not always render correctly after a refresh (e.g. like it happens when using the "Include" plugin). Thanks to Morris Gray for reporting the bug.
* v1.0.6 (2006-11-07)
** Bugfix: cannot edit tiddler when UploadPlugin by Bidix is installed. Thanks to José Luis González Castro for reporting the bug.
* v1.0.5 (2006-03-02)
** Bugfix: Example with multi-line table cells does not work in IE6. Thanks to Paulo Soares for reporting the bug.
* v1.0.4 (2006-02-28)
** Bugfix: Shadow tiddlers cannot be edited (in TW 2.0.6). Thanks to Torsten Vanek for reporting the bug.
* v1.0.3 (2006-02-26)
** Adapt code to newly introduced Tiddler.prototype.isReadOnly() function (in TW 2.0.6). Thanks to Paulo Soares for reporting the problem.
* v1.0.2 (2006-02-05)
** Also allow other macros than the "tiddler" macro use the "." in the part reference (to refer to "this" tiddler)
* v1.0.1 (2006-01-27)
** Added Table of Content for plugin documentation. Thanks to RichCarrillo for suggesting.
** Bugfix: newReminder plugin does not work when PartTiddler is installed. Thanks to PauloSoares for reporting.
* v1.0.0 (2006-01-25)
** initial version
<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>

!Code<html><a name="Code"/></html>
<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
***/
//{{{
//============================================================================
//                           PartTiddlerPlugin

// Ensure that the PartTiddler Plugin is only installed once.
//
if (!version.extensions.PartTiddlerPlugin) {



version.extensions.PartTiddlerPlugin = {
    major: 1, minor: 0, revision: 9,
    date: new Date(2007, 6, 14), 
    type: 'plugin',
    source: "http://tiddlywiki.abego-software.de/#PartTiddlerPlugin"
};

if (!window.abego) window.abego = {};
if (version.major < 2) alertAndThrow("PartTiddlerPlugin requires TiddlyWiki 2.0 or newer.");

//============================================================================
// Common Helpers

// Looks for the next newline, starting at the index-th char of text. 
//
// If there are only whitespaces between index and the newline 
// the index behind the newline is returned, 
// otherwise (or when no newline is found) index is returned.
//
var skipEmptyEndOfLine = function(text, index) {
	var re = /(\n|[^\s])/g;
	re.lastIndex = index;
	var result = re.exec(text);
	return (result && text.charAt(result.index) == '\n') 
			? result.index+1
			: index;
}


//============================================================================
// Constants

var partEndOrStartTagRE = /(<\/part>)|(<part(?:\s+)((?:[^>])+)>)/mg;
var partEndTagREString = "<\\/part>";
var partEndTagString = "</part>";

//============================================================================
// Plugin Specific Helpers

// Parse the parameters inside a <part ...> tag and return the result.
//
// @return [may be null] {partName: ..., isHidden: ...}
//
var parseStartTagParams = function(paramText) {
	var params = paramText.readMacroParams();
	if (params.length == 0 || params[0].length == 0) return null;
	
	var name = params[0];
	var paramsIndex = 1;
	var hidden = false;
	if (paramsIndex < params.length) {
		hidden = params[paramsIndex] == "hidden";
		paramsIndex++;
	}
	
	return {
		partName: name, 
		isHidden: hidden
	};
}

// Returns the match to the next (end or start) part tag in the text, 
// starting the search at startIndex.
// 
// When no such tag is found null is returned, otherwise a "Match" is returned:
// [0]: full match
// [1]: matched "end" tag (or null when no end tag match)
// [2]: matched "start" tag (or null when no start tag match)
// [3]: content of start tag (or null if no start tag match)
//
var findNextPartEndOrStartTagMatch = function(text, startIndex) {
	var re = new RegExp(partEndOrStartTagRE);
	re.lastIndex = startIndex;
	var match = re.exec(text);
	return match;
}

//============================================================================
// Formatter

// Process the <part ...> ... </part> starting at (w.source, w.matchStart) for formatting.
//
// @return true if a complete part section (including the end tag) could be processed, false otherwise.
//
var handlePartSection = function(w) {
	var tagMatch = findNextPartEndOrStartTagMatch(w.source, w.matchStart);
	if (!tagMatch) return false;
	if (tagMatch.index != w.matchStart || !tagMatch[2]) return false;

	// Parse the start tag parameters
	var arguments = parseStartTagParams(tagMatch[3]);
	if (!arguments) return false;
	
	// Continue processing
	var startTagEndIndex = skipEmptyEndOfLine(w.source, tagMatch.index + tagMatch[0].length);
	var endMatch = findNextPartEndOrStartTagMatch(w.source, startTagEndIndex);
	if (endMatch && endMatch[1]) {
		if (!arguments.isHidden) {
			w.nextMatch = startTagEndIndex;
			w.subWikify(w.output,partEndTagREString);
		}
		w.nextMatch = skipEmptyEndOfLine(w.source, endMatch.index + endMatch[0].length);
		
		return true;
	}
	return false;
}

config.formatters.push( {
    name: "part",
    match: "<part\\s+[^>]+>",
	
	handler: function(w) {
		if (!handlePartSection(w)) {
			w.outputText(w.output,w.matchStart,w.matchStart+w.matchLength);
		}
	}
} )

//============================================================================
// Extend "fetchTiddler" functionality to also recognize "part"s of tiddlers 
// as tiddlers.

var currentParent = null; // used for the "." parent (e.g. in the "tiddler" macro)

// Return the match to the first <part ...> tag of the text that has the
// requrest partName.
//
// @return [may be null]
//
var findPartStartTagByName = function(text, partName) {
	var i = 0;
	
	while (true) {
		var tagMatch = findNextPartEndOrStartTagMatch(text, i);
		if (!tagMatch) return null;

		if (tagMatch[2]) {
			// Is start tag
	
			// Check the name
			var arguments = parseStartTagParams(tagMatch[3]);
			if (arguments && arguments.partName == partName) {
				return tagMatch;
			}
		}
		i = tagMatch.index+tagMatch[0].length;
	}
}

// Return the part "partName" of the given parentTiddler as a "readOnly" Tiddler 
// object, using fullName as the Tiddler's title. 
//
// All remaining properties of the new Tiddler (tags etc.) are inherited from 
// the parentTiddler.
// 
// @return [may be null]
//
var getPart = function(parentTiddler, partName, fullName) {
	var text = parentTiddler.text;
	var startTag = findPartStartTagByName(text, partName);
	if (!startTag) return null;
	
	var endIndexOfStartTag = skipEmptyEndOfLine(text, startTag.index+startTag[0].length);
	var indexOfEndTag = text.indexOf(partEndTagString, endIndexOfStartTag);

	if (indexOfEndTag >= 0) {
		var partTiddlerText = text.substring(endIndexOfStartTag,indexOfEndTag);
		var partTiddler = new Tiddler();
		partTiddler.set(
						fullName,
						partTiddlerText,
						parentTiddler.modifier,
						parentTiddler.modified,
						parentTiddler.tags,
						parentTiddler.created);
		partTiddler.abegoIsPartTiddler = true;
		return partTiddler;
	}
	
	return null;
}

// Hijack the store.fetchTiddler to recognize the "part" addresses.
//
var hijackFetchTiddler = function() {
	var oldFetchTiddler = store.fetchTiddler ;
	store.fetchTiddler = function(title) {
		var result = oldFetchTiddler.apply(this, arguments);
		if (!result && title) {
			var i = title.lastIndexOf('/');
			if (i > 0) {
				var parentName = title.substring(0, i);
				var partName = title.substring(i+1);
				var parent = (parentName == ".") 
						? store.resolveTiddler(currentParent)
						: oldFetchTiddler.apply(this, [parentName]);
				if (parent) {
					return getPart(parent, partName, parent.title+"/"+partName);
				}
			}
		}
		return result;	
	};
};

// for debugging the plugin is not loaded through the systemConfig mechanism but via a script tag. 
// At that point in the "store" is not yet defined. In that case hijackFetchTiddler through the restart function.
// Otherwise hijack now.
if (!store) {
	var oldRestartFunc = restart;
	window.restart = function() {
		hijackFetchTiddler();
		oldRestartFunc.apply(this,arguments);
	};
} else
	hijackFetchTiddler();




// The user must not edit a readOnly/partTiddler
//

config.commands.editTiddler.oldIsReadOnlyFunction = Tiddler.prototype.isReadOnly;

Tiddler.prototype.isReadOnly = function() {
	// Tiddler.isReadOnly was introduced with TW 2.0.6.
	// For older version we explicitly check the global readOnly flag
	if (config.commands.editTiddler.oldIsReadOnlyFunction) {
		if (config.commands.editTiddler.oldIsReadOnlyFunction.apply(this, arguments)) return true;
	} else {
		if (readOnly) return true;
	}

	return this.abegoIsPartTiddler;
}

config.commands.editTiddler.handler = function(event,src,title)
{
	var t = store.getTiddler(title);
	// Edit the tiddler if it either is not a tiddler (but a shadowTiddler)
	// or the tiddler is not readOnly
	if(!t || !t.abegoIsPartTiddler)
		{
		clearMessage();
		story.displayTiddler(null,title,DEFAULT_EDIT_TEMPLATE);
		story.focusTiddler(title,"text");
		return false;
		}
}

// To allow the "./partName" syntax in macros we need to hijack 
// the invokeMacro to define the "currentParent" while it is running.
// 
var oldInvokeMacro = window.invokeMacro;
function myInvokeMacro(place,macro,params,wikifier,tiddler) {
	var oldCurrentParent = currentParent;
	if (tiddler) currentParent = tiddler;
	try {
		oldInvokeMacro.apply(this, arguments);
	} finally {
		currentParent = oldCurrentParent;
	}
}
window.invokeMacro = myInvokeMacro;

// To correctly support the "./partName" syntax while refreshing we need to hijack 
// the config.refreshers.tiddlers to define the "currentParent" while it is running.
// 
(function() {
	var oldTiddlerRefresher= config.refreshers.tiddler;
	config.refreshers.tiddler = function(e,changeList) {
		var oldCurrentParent = currentParent;
		try {
			currentParent = e.getAttribute("tiddler");
			return oldTiddlerRefresher.apply(this,arguments);
		} finally {
			currentParent = oldCurrentParent;
		}
	};
})();

// Support "./partName" syntax inside <<tabs ...>> macro
(function() {
	var extendRelativeNames = function(e, title) {
		var nodes = e.getElementsByTagName("a");
		for(var i=0; i<nodes.length; i++) {
			var node = nodes[i];
			var s = node.getAttribute("content");
			if (s && s.indexOf("./") == 0)
				node.setAttribute("content",title+s.substr(1));
		}
	};
	var oldHandler = config.macros.tabs.handler;
	config.macros.tabs.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
		var result = oldHandler.apply(this,arguments);
		if (tiddler)
			extendRelativeNames(place, tiddler.title);
		return result;
	};
})();

// Scroll the anchor anchorName in the viewer of the given tiddler visible.
// When no tiddler is defined use the tiddler of the target given event is used.
window.scrollAnchorVisible = function(anchorName, tiddler, evt) {
	var tiddlerElem = null;
	if (tiddler) {
		tiddlerElem = document.getElementById(story.idPrefix + tiddler);
	}
	if (!tiddlerElem && evt) {
		var target = resolveTarget(evt);
		tiddlerElem = story.findContainingTiddler(target);
	}
	if (!tiddlerElem) return;

	var children = tiddlerElem.getElementsByTagName("a");
	for (var i = 0; i < children.length; i++) {
		var child = children[i];
		var name = child.getAttribute("name");
		if (name == anchorName) {
			var y = findPosY(child);
			window.scrollTo(0,y);
			return;
		}
	}
}

} // of "install only once"
//}}}

/***
<html><sub><a href="javascript:;" onclick="scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>

!Licence and Copyright
Copyright (c) abego Software ~GmbH, 2006 ([[www.abego-software.de|http://www.abego-software.de]])

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.

Neither the name of abego Software nor the names of its contributors may be
used to endorse or promote products derived from this software without specific
prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

<html><sub><a href="javascript:;" onclick="scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
***/
{{nocol{}}}

This describes the changes made to the plugins that are tagged with PatchedPlugin. These plugins should not be redistributed outside of the coursebook. The following plugins have been patched:

{{sectionTOC{}}}

! AnnotationsPlugin

Fixed usage comments from:

{{{
((text to annotate(annotation goes here)
}}}

to

{{{
((text to annotate(annotation goes here)))
}}}

in both places.

! FootnotesPlugin

Fix for issues when rendered as part of saving rss feed. It tries to add itself to the containing tiddler as though it was being rendered in the story column. But for RSS there is no story and it errors. Added:

{{{
 if (!story.findContainingTiddler(place)) return;
}}}

at the top of the handler function.

Also fixed a mising check to see if tiddler was defined:
{{{
Story.prototype.refreshTiddler = function(title,template,force)
{
    var tiddler = old_footnotes_refreshTiddler.apply(this,arguments);
	if (tiddler && tiddler.notes && tiddler.notes.length)
	{ ...
}}}
prepended the "{{{tiddler &&}}}" to the if statement in case the refresh returns null (was causing an error in IE 7).

! PartTiddlerPlugin

Change {{{<<br>>}}} to {{{<br />}}}.

! QuizzerPlugin

Added {{{return false;}}} at the end of checkOut to prevent IE from alerting about leaving the web page.

! SyncFromSourcePlugin

change ~FileAdaptor.minHostName to ~AdaptorBase.minHostName to get it to work with newer tiddlywikis.

!TableSortingPlugin

From: http://groups.google.com/group/TiddlyWiki/browse_thread/thread/cced75d513e00a21

{{{
The fix is to use a more precise conditional by changing these two
lines:
        if(!x && hasClass(h,"autosort")) {
        if(x)
to:
        if(x===null && hasClass(h,"autosort")) {
        if(x!==null)

That should do it. 
}}}

! TiddlerNotesPlugin

From discussion in:

http://groups.google.com/group/TiddlyWiki/browse_thread/thread/c70af7be67524685/770b706c64529caa?#770b706c64529caa

Well guess I answered my own question. I started firebug and reloaded the tw. Then I switched to the script tab and enabled "break on all errors". Then I opened the import tab, switched to web and clicked on select a server and that resulted in:
{{{
77 if(attribs){
78     for(var n in attribs){
79            e.setAttribute(n,attribs[n]);
80     }
81 }
}}}
the error it reports is:
{{{
    e is not defined
}}}
this code is inside the function:
{{{
 function createTiddlyButton
(theParent,theText,theTooltip,theAction,theClass,theId,theAccessKey,attribs)
}}}
Looking at the function: {{{function createTiddlyElement (theParent,theElement,theID,theClass,theText,attribs)}}}
it uses the variable e in a similar way, however in createTiddlyButton the variable is:
{{{
  var theButton = document.createElement("a");
}}}
could it be that e.setAttribute should be theButton.setAttribute? 

Yes it should be.

!! Enhancement to allow printing of notes without empty notes blocks

When printing the story column, the notes block were taking up a lot of room and if they were empty, they were just wasted space.
I could turn off printing of the notes block, but I wanted to print them if the notes blocks had content. I patched the TiddlerNotesPlugin
to add the class ~TiddlerNotesExists to the notes blocks where there is a notes tiddler (indicating useful information). The patch replaced:
{{{
		var box = createTiddlyElement(place,"div","notesContainer"+tiddler.title,"TiddlerNotes",null,{"source":tiddler.title,params:paramString,heading:heading,tag:tag,suffix:suffix});
}}}
in the notes handler with:
{{{
                // rouilj add a class for notes that have contents in a tiddler.
                var notesTiddlerExists = store.tiddlerExists(tiddler.title+"-"+suffix);
		var box = createTiddlyElement(place,"div","notesContainer"+tiddler.title,"TiddlerNotes"  + (notesTiddlerExists?" TiddlerNotesExists":""),null,{"source":tiddler.title,params:paramString,heading:heading,tag:tag,suffix:suffix});
}}}
note the space between the " and ~TiddlerNotesExists. It must be there so that ~TiddlerNotes has a space after it otherwise the class names aren't correct.

Then the stylesheet was changed to not display the class ~TiddlerNotes but to display ~TiddlerNotesExists when printing. Also the edit notes button was hidden for printing.

! TiddlyLockPlugin

In top documentation table in the Overrides section, replaced obsolete {{{<<br>>}}}  macro with {{{<br />}}}.

Also doesn't work under safari. Notify the user and bypass it's lock.

<<sectionTOC>>
[[What is plod?]]
[[What are the enhancements?]]
[[Using plod]]
[[Reporting from plod]]
[[Searching plod]]
[[Demo]]
Intro to the coursebook and {{exclude{tiddlywiki}}} in general
[[Slide Welcome]]
[[What is a TiddlyWiki]]
[[Coursebook Orientation]]

The parts of this coursebook:
   * Chapters
   * Presentations (shows)
   * Quizzes

[[Tiddler Types in This Coursebook]]
[[Course Structure]]
[[Using Notebook]]
[[Using Shows]]
[[Using Chapters]]

/%use sort order to override default title based ordering. Anything with an explicit order will be sorted before the title sorted section.%/ {{adiv{<<showWhenExists InstructorSlideShowStyleSheet>><<matchTags inline {{'* <<slideShow noClicks tiddler:%0 label:%0 clock:-15 theme:InstructorSlideShowStyleSheet toc:titles >' + '> @@font-size:smaller;%0@@'}} "\n" sort:title Presentation>>}}}{{adiv{<<hideWhenExists InstructorSlideShowStyleSheet>><<matchTags inline {{'* <<slideShow noKeyboard noClicks noOverlays tiddler:%0 label:%0 toc:titles >' + '>'}} "\n" sort:title Presentation>>}}}
<!--{{{-->
<div class='toolbar' macro='toolbar [[OtherToolbarCommands::ContentViewToolbar]]'></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='showWhenExists InstructorSlideShowStyleSheet'>
<div macro='tiddler SlideStyleLinks##Instructor'></div>
<div macro='slideShow  theme:InstructorSlideShowStyleSheet toc:titles noClicks footer:"copyright&copy; 2009<br />John Rouillard" clock:+ label:"Instructor" tooltip:"Start slideshow in instructor projection mode"'></div>
</div>

<div macro='tiddler SlideStyleLinks##Student'></div>
<div class='viewer' macro='slideShow noClicks noKeyboard noOverlays toc:titles label:"Student" tooltip:"Start the slideshow in student mode"'></div>

<div macro='tiddler SlideStyleLinks##Print'></div>
<div class='viewer' macro='slideShow showAll theme:PrintingSlideShowStyleSheet label:Print tooltip:"Display slide show for printing"'></div>
<hr />
</div>
<div class='viewer' macro='view text wikified'></div>
<span macro="sectionTOC"></span>
<div id="Notes" class='notes viewer' macro='notes heading:Notebook tag:"Notes excludeLists noReload" suffix:Notes'></div>
<div class='tagClear'></div>
<!--}}}-->
/*{{{*/
/* Default style sheet settings for printing */
#contentWrapper.slideShowMode #displayArea{
 font-size: 150%;
 margin: 1em 15.5em 0em 1em !important;
}

h1,h2,h3 {margin-top:0.3em}

.slideFooterOff #navigator{
 display: none;
}

#controlBar{
 display: none;
}

@media print {
.tiddler{
 page-break-after: always;
 border: 2px solid blue;
 margin: 1em 0 1em 0;
 padding: 0.5em
}
.viewer pre { background-color: transparent; }

#contentWrapper.slideShowMode .comment{
 background-color: transparent;
}
}

.notes {
display: none;
}

.comment{
 border: 1pt dashed;
 padding: 0.5em;
}

#contentWrapper.slideShowMode  #displayArea {margin: 1em 0em 0em 0em !important;}
}
/*}}}*/
<<matchTags inline "* %0" "\n" sort:title quiz>> @@display:none; use sort order to override default title based ordering. Anything with an explicit order will be sorted before the title sorted section. @@
/***
|''Name:''|QuizzerPlugin|
|''Description:''|Makes quizzes with optional grades|
|''Version:''|1.0.2|
|''Date:''|Nov 11, 2008|
|''Source:''|http://www.math.ist.utl.pt/~psoares/addons.html|
|''Documentation:''|[[QuizzerPlugin Documentation|QuizzerPluginDoc]]|
|''Author:''|Paulo Soares|
|''License:''|[[Creative Commons Attribution-Share Alike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''~CoreVersion:''|2.1.0|
***/
//{{{
config.macros.quiz = {
	wrongAnswer: "Incorrect answer. Please think again.",
	rightAnswer: "That's right!",
	trueValue: "True",
	falseValue: "False",
	handler: function(place,macroName,params,wikifier,paramString){
		var par = paramString.parseParams("list",null,true);
		var type = getParam(par,"type","M");
		var panelType = (type.length>1) ? type.charAt(1) : "";
		type = type.charAt(0);
		var id = getParam(par,"id","");
		if(id=="" && type!="M") return; // not sure about this
		var value = getParam(par,"value",false);
		var tiddler = getParam(par,"tiddler","");
		var score = parseFloat(getParam(par,"score",0));
		var toolTip = "";
		if(type=="T"){
			toolTip = this.trueValue;
			if(value==false){
				var tempTiddler=tiddler;
				tiddler="";
				var tempScore=score;
				score=0;
			}
		}
		this.createAnswer(place, type, toolTip, true, panelType, tiddler, value, score, id);
		if(type=="T"){
			tiddler=(value==false)?tempTiddler:"";
			score=(value==false)?tempScore:0;
			toolTip = this.falseValue;
			this.createAnswer(place, type, toolTip, false, panelType, tiddler, !value, score, id);
		}
	},
	createAnswer: function(place, type, toolTip, correction, panelType, tiddler, value, score, id){
		var checked=false;
		if(correction){
			var correct = createTiddlyElement(place,"span","","correction","");
			correct.style.display='none';
			correct.style.fontWeight='bold';
			checked=true;
		}
		if(type=="M"){
			var btn = createTiddlyCheckbox(place,"",false,this.onClickAnswer);
		} else {
			var btn = createTiddlyRadiobox(place,"",checked,this.onClickAnswer,id);
		}
		btn.className = "answerItem";
		btn.value=score;
		if(toolTip!="") btn.title=toolTip;
		var panelClass = (panelType=="=") ? "sliderPanel" : "floatingPanel"; //default to floating
		var text = (tiddler!="") ? store.getTiddlerText(tiddler) : ""; 
		if(text==""){text = (value) ? this.rightAnswer : this.wrongAnswer;}
		var panel = createTiddlyElement(null,"div","",panelClass);
		panel.style.display = "none"; //default to closed
		panel.onclick=function(){this.style.display="none";};
		place.appendChild(panel);
		wikify(text,panel,null);
	},
	onClickAnswer: function(e){
		if(!e) var e = window.event;
		var panel = this.nextSibling;
		if(this.checked){
			var validated = 1;
			var visiblePanel=document.getElementById('visiblePanel');
			var sC = Story.prototype.findContainingTiddler(this).id.substr(7)+'_scoreCard';
			var scoreCard=document.getElementById(sC);
			if(visiblePanel){
				visiblePanel.style.display="none";
				visiblePanel.id="";
			}
			if(scoreCard){validated = scoreCard.value;}
			if(validated==1){
				panel.style.display = "block";
				panel.id="visiblePanel";
				var left= e.clientX +10;
				panel.style.left = left + "px";
			}
		} else {
			panel.style.display = "none";
			panel.id="";
		}
	}
};

config.macros.score= {
	trueSymbol: "✔",
	falseSymbol: "✘",
	label: "Score »",
	handler: function(place,macroName,params,wikifier,paramString,tiddler){
		var btn = createTiddlyButton(place,this.label,"",this.checkOut);
		btn.id=tiddler.title+"_scoreCard";
		btn.value=0;
	},
	checkOut: function(e){
		if(this.value==1) return;
		var total=score=points=0;
		var answers=getElementsByClass("answerItem",document.getElementById('viewer'));
		var answersLen=answers.length;
		for(var i=0; i<answersLen; i++) {
			points=parseFloat(answers[i].value);
			score+=answers[i].checked*points;
			if(points>0)total+=points;
			var correct=answers[i].previousSibling;
			if(correct.className=="correction"){
				if(answers[i].checked == (points>0)){
					correct.firstChild.data=config.macros.score.trueSymbol;
					correct.style.color = '#0f0';
				} else {
					correct.firstChild.data=config.macros.score.falseSymbol;
					correct.style.color = '#f00';
				}
				correct.style.display='inline';
			}
		}
		var text = " " + score+"/"+total;
		createTiddlyElement(this,"span","","",text);
		this.value=1;
                return false;
	}
};

function getElementsByClass(searchClass,node,tag) {
	var classElements = new Array();
	if ( node == null ) node = document;
	if ( tag == null ) tag = '*';
	var els = node.getElementsByTagName(tag);
	var elsLen = els.length;
	var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
	for (var i = 0; i < elsLen; i++) {
		if ( pattern.test(els[i].className) ) {classElements.push(els[i]);}
	}
	return classElements;
}

function createTiddlyRadiobox(theParent,caption,checked,onChange,id){
	var cb = document.createElement("input");
	cb.type = "radio";
	cb.name = id;
	cb.onclick = onChange;
	theParent.appendChild(cb);
	cb.checked = checked;
	cb.className = "chkOptionInput";
	if(caption) wikify(caption,theParent);
	return cb;
}

setStylesheet("/*{{{*/\n.floatingPanel {\n color: black;\n;position: absolute;\nz-index: 10;\npadding: 0.5em;\nbackground-color: #eee;\nborder: 1px solid #333;\ncursor: crosshair}\n\n.sliderPanel {padding: 0.5em;\nborder: 1px dotted #333;\nwidth: auto;\ncursor: crosshair}\n\n/*}}}*/","AnswerPanelStyles");

config.shadowTiddlers.QuizzerPluginDoc="The documentation is missing. It is available [[here|http://www.math.ist.utl.pt/~psoares/addons.html#QuizzerPluginDoc]].";
//}}}
!!!!Syntax
The QuizzerPlugin has five parameters; most are optional:
//{{{
<<quiz [type:type[=]] [id:id] [tiddler:tiddler] [value:value] [score:score]>>
//}}}
Parameters:
*type (string)
**"M" (multiple answer checkbox) (default)
**"S" (single-answer radio button group)
**"T" (true/false question)
***append "=" for sliding panel (e.g., T=, S=, M=) 
*id (string)
**required for types S  and T only
***for type S value must be unique across a group of questions
***for type T value must be unique for each question 
*tiddler (string, //optional//)
**display text from tiddler in the panel
**default is config.macros.answer.wrongAnswer or config.macros.answer.rightAnswer according to the value of the next parameter
*value
**use {{{value:true}}} to indicate that the true answer is right
**should be omitted otherwise
*score (number)
**sets the score for an answer
** default is 0
/***
|''Name:''|RSSReaderPlugin|
|''Description:''|This plugin provides a RSSReader for TiddlyWiki|
|''Version:''|1.1.2|
|''Date:''|2008-09-02|
|''Source:''|http://tiddlywiki.bidix.info/#RSSReaderPlugin|
|''Documentation:''|http://tiddlywiki.bidix.info/#RSSReaderPluginDoc|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''Credit:''|BramChen for RssNewsMacro|
|''[[License]]:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0|
|''OptionalRequires:''|http://www.tiddlytools.com/#NestedSlidersPlugin|
***/
//{{{
version.extensions.RSSReaderPlugin = {
	major: 1, minor: 1, revision: 2,
	date: new Date("2008-09-02"),
	source: "http://TiddlyWiki.bidix.info/#RSSReaderPlugin",
	author: "BidiX",
	coreVersion: '2.2.0'
};

config.macros.rssReader = {
	dateFormat: "DDD, DD MMM YYYY",
	itemStyle: "display: block;border: 1px solid black;padding: 5px;margin: 5px;", //useed  '@@'+itemStyle+itemText+'@@'
	msg:{
		permissionDenied: "Permission to read preferences was denied.",
		noRSSFeed: "No RSS Feed at this address %0",
		urlNotAccessible: " Access to %0 is not allowed"
	},
	cache: [], 	// url => XMLHttpRequest.responseXML
	desc: "noDesc",
	
	handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		var desc = params[0];
		var feedURL = params[1];
		var toFilter = (params[2] ? true : false);
		var filterString = (toFilter?(params[2].substr(0,1) == ' '? tiddler.title:params[2]):'');
		var place = createTiddlyElement(place, "div", "RSSReader");
		wikify("^^<<rssFeedUpdate "+feedURL+" [[" + tiddler.title + "]]>>^^\n",place);
		if (this.cache[feedURL]) {
			this.displayRssFeed(this.cache[feedURL], feedURL, place, desc, toFilter, filterString);
		}
		else {
			var r = loadRemoteFile(feedURL,config.macros.rssReader.processResponse, [place, desc, toFilter, filterString]);
			if (typeof r == "string")
				displayMessage(r);
		}
		
	},

	// callback for loadRemoteFile 
	// params : [place, desc, toFilter, filterString]
	processResponse: function(status, params, responseText, url, xhr) { // feedURL, place, desc, toFilter, filterString) {	
		if (window.netscape){
			try {
				if (document.location.protocol.indexOf("http") == -1) {
					netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
				}
			}
			catch (e) { displayMessage(e.description?e.description:e.toString()); }
		}
		if (xhr.status == 404)
		 {
			displayMessage(config.macros.rssReader.noRSSFeed.format([url]));
			return;
		}
		if (!status)
		 {
			displayMessage(config.macros.rssReader.noRSSFeed.format([url]));
			return;
		}
		if (xhr.responseXML) {
			// response is interpreted as XML
			config.macros.rssReader.cache[url] = xhr.responseXML;
			config.macros.rssReader.displayRssFeed(xhr.responseXML, params[0], url, params[1], params[2], params[3]);
		}
		else {
			if (responseText.substr(0,5) == "<?xml") {
				// response exists but not return as XML -> try to parse it 
				var dom = (new DOMParser()).parseFromString(responseText, "text/xml"); 
				if (dom) {
					// parsing successful so use it
					config.macros.rssReader.cache[url] = dom;
					config.macros.rssReader.displayRssFeed(dom, params[0], url, params[1], params[2], params[3]);
					return;
				}
			}
			// no XML display as html 
			wikify("<html>" + responseText + "</html>", params[0]);
			displayMessage(config.macros.rssReader.msg.noRSSFeed.format([url]));
		}
	},

	// explore down the DOM tree
	displayRssFeed: function(xml, place, feedURL, desc, toFilter, filterString){
		// Channel
		var chanelNode = xml.getElementsByTagName('channel').item(0);
		var chanelTitleElement = (chanelNode ? chanelNode.getElementsByTagName('title').item(0) : null);
		var chanelTitle = "";
		if ((chanelTitleElement) && (chanelTitleElement.firstChild)) 
			chanelTitle = chanelTitleElement.firstChild.nodeValue;
		var chanelLinkElement = (chanelNode ? chanelNode.getElementsByTagName('link').item(0) : null);
		var chanelLink = "";
		if (chanelLinkElement) 
			chanelLink = chanelLinkElement.firstChild.nodeValue;
		var titleTxt = "!![["+chanelTitle+"|"+chanelLink+"]]\n";
		var title = createTiddlyElement(place,"div",null,"ChanelTitle",null);
		wikify(titleTxt,title);
		// ItemList
		var itemList = xml.getElementsByTagName('item');
		var article = createTiddlyElement(place,"ul",null,null,null);
		var lastDate;
		var re;
		if (toFilter) 
			re = new RegExp(filterString.escapeRegExp());
		for (var i=0; i<itemList.length; i++){
			var titleElm = itemList[i].getElementsByTagName('title').item(0);
			var titleText = (titleElm ? titleElm.firstChild.nodeValue : '');
			if (toFilter && ! titleText.match(re)) {
				continue;
			}
			var descText = '';
			descElem = itemList[i].getElementsByTagName('description').item(0);
			if (descElem){
				try{
					for (var ii=0; ii<descElem.childNodes.length; ii++) {
						descText += descElem.childNodes[ii].nodeValue;
					}
				}
				catch(e){}
				descText = descText.replace(/<br \/>/g,'\n');
				if (desc == "asHtml")
					descText = "<html>"+descText+"</html>";
			}
			var linkElm = itemList[i].getElementsByTagName("link").item(0);
			var linkURL = linkElm.firstChild.nodeValue;
			var pubElm = itemList[i].getElementsByTagName('pubDate').item(0);
			var pubDate;
			if (!pubElm) {
				pubElm = itemList[i].getElementsByTagName('date').item(0); // for del.icio.us
				if (pubElm) {
					pubDate = pubElm.firstChild.nodeValue;
					pubDate = this.formatDateString(this.dateFormat, pubDate);
					}
					else {
						pubDate = '0';
					}
				}
			else {
				pubDate = (pubElm ? pubElm.firstChild.nodeValue : 0);
				pubDate = this.formatDate(this.dateFormat, pubDate);
			}
			titleText = titleText.replace(/\[|\]/g,'');
			var rssText = '*'+'[[' + titleText + '|' + linkURL + ']]' + '' ;
			if ((desc != "noDesc") && descText){
				rssText = rssText.replace(/\n/g,' ');
				descText = '@@'+this.itemStyle+descText + '@@\n';				
				if (version.extensions.nestedSliders){
					descText = '+++[...]' + descText + '===';
				}
				rssText = rssText + descText;
			}
			var story;
			if ((lastDate != pubDate) && ( pubDate != '0')) {
				story = createTiddlyElement(article,"li",null,"RSSItem",pubDate);
				lastDate = pubDate;
			}
			else {
				lastDate = pubDate;
			}
			story = createTiddlyElement(article,"div",null,"RSSItem",null);
			wikify(rssText,story);
		}
	},
	
	formatDate: function(template, date){
		var dateString = new Date(date);
		// template = template.replace(/hh|mm|ss/g,'');
		return dateString.formatString(template);
	},
	
	formatDateString: function(template, date){
		var dateString = new Date(date.substr(0,4), date.substr(5,2) - 1, date.substr(8,2)
			);
		return dateString.formatString(template);
	}
	
};

config.macros.rssFeedUpdate = {
	label: "Update",
	prompt: "Clear the cache and redisplay this RssFeed",
	handler: function(place,macroName,params) {
		var feedURL = params[0];
		var tiddlerTitle = params[1];
		createTiddlyButton(place, this.label, this.prompt, 
			function () {
				if (config.macros.rssReader.cache[feedURL]) {
					config.macros.rssReader.cache[feedURL] = null; 
			}
			story.refreshTiddler(tiddlerTitle,null, true);
		return false;});
	}
};

//}}}
//last update: RSSReaderPlugin v 1.1.1//

!Description
This plugin provides a RSSReader for TiddlyWiki
* It accesses asynchronously an RSSFeed
*Depending on the chanel item format, each item could be written as :
**simple text wikified
**html

!Usage
{{{
<<rssReader noDesc|asHtml|asText rssUrl ['filtering string']>>
	noDesc: only title of item is printed

	asHtml: if you know that description contain html (links, img ...), 
		the text is enclosed with <html> </html> tags

 	asText: if the description should not be interpreted as html the 
		description is wikified

	rssUrl: the rssFeed url that could be accessed. 
	
	'filtering string': if present, the rssfeed item title must contained 
		this string to be displayed. 
		If 'filering string' contained space characters only, the tiddler 
		title is used for filtering.

}}}

For security reasons, if the TiddlyWiki is accessed from http, a ProxyService should be used to access an rssFeed from an other site.

!examples
| !reader | !RSSFeed type | !working from |
| BidiXTWRSS | Description asHtml | file: or tiddlywiki.bidix.info |
| [[Le Monde]] | Description asText | file: or tiddlywiki.bidix.info using proxy |
| YahooNewsSport | Description asHtml | file: or tiddlywiki.bidix.info using proxy |
| TiddlyWikiRSS | Description asHtml | file: or tiddlywiki.bidix.info using proxy |
| [[Libération]] | noDesc | file: or tiddlywiki.bidix.info using proxy |
| [[TestComment]] | asText and filters | file: or tiddlywiki.bidix.info using proxy |
see : <<tag RSSFeed>> for the full list.

!Revision history
* V1.1.0 (2207/04/13)
**No more import functions
* V1.0.0 (2006/11/11)
**refactoring using core loadRemoteFile function
**import using new tiddlywiki:tiddler element
**import and presentation preserved without EricShulman's NestedSliderPlugin
**better display of items 
* v0.3.0 (24/08/2006)
** Filter on RSS item title
** Place to display redefined for asynchronous processing
* v0.2.2 (22/08/2006)
**Haloscan feed has no pubDate.
* v0.2.1 (08/05/2006)
* v0.2.0 (01/05/2006)
**Small adapations for del.icio.us feed
* v0.1.1 (28/04/2006)
**Bug : Channel without title 
* v0.1.0 (24/04/2006)
** initial release
/***
|Macro|redirect (alias)|
|Author|[[Clint Checketts]] and Paul Petterson|
|Version|1.1 Jan 26, 2006|
|Location|http://checkettsweb.com/styles/themes.htm#RedirectMacro|
|Description|This macro tells TW to find all instances of a word and makes it point to a different link. For example, whenever I put the word 'Clint' in a tiddler I want TiddlyWiki to turn it into a link that points to a tiddler titled 'Clint Checketts' Or the word 'TW' could point to a tiddler called 'TiddlyWiki' It even matches clint (which is lowercase) [[Clint]] leet lEEt LEET|
|Usage|{{{<<redirect TW TiddlyWiki>>}}} |
|Example|<<redirect TW "TiddlyWiki">> <<redirect Clint "Clint Checketts">> (Nothing should appear, its just setting it all up)<<redirectExact lEEt Elite>>|

!Revisions
1.1- Fixed tiddler refresh so a tiddler declaring a redirect will also render the redirect
1.0- Updated to work with TiddlyWiki 2.0 (thanks to Udo Borkowski)
0.9- Original release October 2005

!Code
***/
//{{{
version.extensions.redirectExact = {major: 1, minor: 2, revision: 0, date: new Date(2005,10,24)};
config.macros.redirectExact = {label: "Pickles Rock!"};
config.macros.redirectExact.handler = function(place,macroName,params,wikifier,paramString,tiddler){
 config.macros.redirect.handler(place,macroName,params,wikifier,paramString,tiddler);
}

version.extensions.redirect = {major: 1, minor: 2, revision: 0, date: new Date(2005,10,24)};
config.macros.redirect = {label: "Pickles Rock!"};

config.macros.redirect.handler = function(place,macroName,params,wikifier,paramString,tiddler){

var redirectExists = false
// Check to see if the wikifier exists
for (var i=0;i<config.formatters.length;i++)
 if (config.formatters[i].name == "redirect"+params[0])
 redirectExists = true;

//If it doesn't exist, add it!
if (!redirectExists){
 for( var i=0; i<config.formatters.length; i++ )
 if ( config.formatters[i].name=='wikiLink') break ;

 if ( i >= config.formatters.length ) {
 var e = "Can't find formatter for wikiLink!" ;
 displayMessage( e ) ;
 throw( e ) ;
 }

var pattern;
 if (macroName == 'redirect'){pattern=params[0].escapeRegExp().replace(/([A-Z])/img, function($1) {return("["+$1.toUpperCase()+$1.toLowerCase()+"]");});
 } else {
 pattern=params[0].escapeRegExp();
 }

 config.formatters.splice( i, 0, {
 name: "redirect"+params[0],
 match: "(?:\\b)(?:\\[\\[)?"+pattern+"(?:\\]\\])?(?:\\b)",
 subst: params[1],
 handler: function(w) {
 var link = createTiddlyLink(w.output,this.subst,false);
 w.outputText(link,w.matchStart,w.nextMatch);
 }
 });
 formatter = new Formatter(config.formatters); //update the tiddler
 if(tiddler) story.refreshTiddler(tiddler.title,null,true); //refresh tiddler so the new rule is applied
} // End if
}
//}}}
/***
***/

//{{{

config.commands.refresh = {
 text: 'refresh',
 tooltip: 'Refresh this tiddler',
 handler: function(e,src,title) {
  clearMessage();
  story.refreshTiddler(title,false,true); // force=true
  return false;
 }
};

//}}}
{{{plod -T -d 12/01/2009 -D 12/08/2009}}}
{{overlay1{
{{{
         Programming:                 3:50
         Programming:c                0:10
         Programming:perl             3:40
         TR:                          0:30
         TR:23                        0:10
         TR:32                        0:20
         zTOTAL =                     4:20
}}}
}}}
/%
|Name|RescueStoreAreaCommand|
|Source|http://www.TiddlyTools.com/#RescueStoreAreaCommand|
|Version|1.0.0|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|script bookmarklet|
|Requires|InlineJavascriptPlugin|
|Overrides||
|Description|rescue tiddler changes from online document when net goes down during editing|
%/<script label="$1" title="rescue tiddlers from current document storeArea">
	if(typeof version==undefined||version.title!='TiddlyWiki')
		{alert(document.location.href+'\n\nis not a TiddlyWiki document');return false;}
	if (!confirm('Preparing to rescue storeArea contents... press OK to proceed')) return false;
	var sa=store.allTiddlersAsHtml().htmlEncode();
	var win=window.open();
	win.document.open();
	win.document['write']('<html><body><pre>'+sa+'</pre></body></html>');
	win.document.close();
	alert('copy/paste the displayed storeArea content into a local text file');
	win.focus();
</script><script>
	if ("$1"=="$"+"1") place.lastChild.innerHTML="Rescue current storeArea contents";
</script>
Here is an example expanding the rdist(1) configuration language to add a command to perform a diff between the master file and the file currently installed. It is called as:
{{{
   ntp-verify:
   $C/ntp/clients.conf -> ${NTP_SLAVES}
         VERIFYFILE(/etc/ntp.conf);
}}}
{{{
#bigdef  VERIFYFILE(TARGET)
install TARGET.verify ;
        special "diff -u TARGET ${REMFILE}; exit=$?; rm -f ${REMFILE}; exit $exit"##
#endbigdef
}}}
{{{plod -G Programming}}}
{{overlay1{
{{{
-----
12/04/2009, 14:47 --  Programming:perl
working on a new release of plod
}}}
}}}
/***
|Name|SectionLinksPlugin|
|Source|http://www.TiddlyTools.com/#SectionLinksPlugin|
|Documentation|http://www.TiddlyTools.com/#SectionLinksPlugin|
|Version|1.3.4|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|allow tiddler sections in TiddlyLinks to be used as anchor points|
This plugin enhances the processing of section references so they can be used in links to auto-scroll to the indicated heading within a tiddler (i.e., similar to the 'anchor' behavior provided in HTML by {{{<a name="foo">}}} and {{{<a href="#foo">...</a>}}})
!!!Usage
<<<
!!!!!{{{<<tiddler>>}}} macro 
>The {{{<<tiddler SomeTiddler##SomeSection>>}}} syntax has been extended so that when the tiddler title is omitted or the 'here' keyword is used (e.g., {{{<<tiddler ##SomeSection>>}}} or {{{<<tiddler here##SomeSection>>}}}), then the current containing tiddler is implied by default.
!!!!!~TiddlyLink syntax
>the standard link syntax has been extended so that a section name can included in a tiddler link (e.g., {{{[[SomeTiddler##SomeSection]]}}}).  When clicked, the tiddler is displayed and the specified section heading will be automatically scrolled into view. If the tiddler title is omitted or the 'here' keyword is used (e.g., {{{[[##SomeSection]]}}} or {{{[[here##SomeSection]]>>}}}), then the current containing tiddler is implied by default.
!!!!!"""<<sectionTOC>>""" macro
>This macro generates a 'Table of Contents'-style numbered-bullet list with links to all sections within the current tiddler.  Simply place the following macro at the //end of the tiddler content// (i.e., following all section headings):
{{{
<<sectionTOC>> or <<sectionTOC className>>
}}}
>Note: The macro must occur at the end of the tiddler in order to locate the rendered section headings that precede it. In addition, to position the macro's //output// within the tiddler, you must create a special 'target element' that uses a specified classname (default='sectionTOC'), like this:
{{{
{{sectionTOC{}}}
}}}
>When the {{{<<sectionTOC>>}}} macro is rendered, it will find the matching 'sectionTOC'-classed element and writes it's output there.  You can also add the macro and/or target elements directly to the [[ViewTemplate]] definition, so that every tiddler can automatically display the table of contents:
{{{
<span class='sectionTOC'></span> <!-- target element -->
...
<span macro='sectionTOC'></span> <!-- must be at end of tiddler -->
}}}
<<<
!!!Revisions
<<<
2009.08.21 [1.3.4] added handling to ignore leading/trailing whitespace in section references
2009.08.21 [1.3.3] in createTiddlyLink(), add tiddlyLinkNonExistingSection class if matching section is not found
2009.08.14 [1.3.2] in createTiddlyLink(), don't override core value for ~TiddlyLink attribute
2009.08.02 [1.3.1] in sectionTOC.handler(), trim leading/trailing whitespace from generated section links
2009.08.01 [1.3.0] in scrollToSection(), apply 3-tier section matching (exact, startsWith, contains)
2009.07.06 [1.2.2] fixed displayTiddler() hijack
2009.07.03 [1.2.1] in {{{<<sectionTOC>>}}}, suppress output if target is not found
2009.06.02 [1.2.0] added support for 'here' keyword in {{{[[here##section]]}}} links and {{{<<tiddler here##section>>}}} macro
2009.04.09 [1.1.1] in sectionTOC macro, make target visible when TOC is rendered.
2009.01.18 [1.1.0] added {{{<<sectionTOC>>}}} macro to generate numbered-bullet links to sections of current tiddler
2009.01.06 [1.0.0] converted to stand-alone plugin
2008.10.14 [0.0.0] initial release (as [[CoreTweaks]] #784 - http://trac.tiddlywiki.org/ticket/784)
<<<
!!!Code
***/
//{{{
version.extensions.SectionLinksPlugin= {major: 1, minor: 3, revision: 4, date: new Date(2009,8,21)};

Story.prototype.scrollToSection = function(title,section) {
	if (!title||!section) return; var t=this.getTiddler(title); if (!t) return null;
	var elems=t.getElementsByTagName('*'); var heads=[];
	for (var i=0; i<elems.length; i++)
		if (['H1','H2','H3','H4','H5'].contains(elems[i].nodeName)) heads.push(elems[i]);
	for (var i=0; i<heads.length; i++)
		if (getPlainText(heads[i]).trim()==section) break;
	if (i==heads.length) for (var i=0; i<heads.length; i++)
		if (getPlainText(heads[i]).trim().startsWith(section)) break;
	if (i==heads.length) for (var i=0; i<heads.length; i++)
		if (getPlainText(heads[i]).trim().indexOf(section)!=-1) break;
	if (i<heads.length) { var h=heads[i];
		// if section heading is collapsed, click to expand it - see [[FoldHeadingsPlugin]]
		if (hasClass(h,'foldable') && h.nextSibling.style.display=='none') h.onclick();
		// scroll *after* tiddler animation
		var delay=config.options.chkAnimate?config.animDuration+100:0;
		setTimeout('window.scrollTo('+findPosX(h)+','+findPosY(h)+')',delay);
		return h;
	}
}
//}}}
/***
!!!!core hijacks
***/
/***
!!!!!createTiddlyLink
***/
//{{{
// [[tiddlername##section]] and [[##section]]
if (!window.createTiddlyLink_section)
	window.createTiddlyLink_section=window.createTiddlyLink;
window.createTiddlyLink=function(place,title) {
	var t=story.findContainingTiddler(place); var tid=t?t.getAttribute('tiddler'):'';
	var parts=title.split(config.textPrimitives.sectionSeparator);
	var title=parts[0]; var section=parts[1]; if (section) section=section.trim();
	if (!title.length || title.toLowerCase()=='here') title=tid;  // default=current tiddler
	arguments[1]=title;
	var btn=createTiddlyLink_section.apply(this,arguments);
	if (section) {
		btn.setAttribute('section',section);
		if (store.getTiddlerText(title+config.textPrimitives.sectionSeparator+section)===null)
			addClass(btn,'tiddlyLinkNonExistingSection');
	}
	return btn;
}
//}}}
/***
!!!!!onClickTiddlerLink
***/
//{{{
if (!window.onClickTiddlerLink_section)
	window.onClickTiddlerLink_section=window.onClickTiddlerLink;
window.onClickTiddlerLink=function(ev) {
	var e=ev||window.event;	var target=resolveTarget(e); var title=null;
	while (target!=null && title==null) {
		title=target.getAttribute('tiddlyLink');
		section=target.getAttribute('section');
		target=target.parentNode;
	} 
	var t=story.findContainingTiddler(target); var tid=t?t.getAttribute('tiddler'):'';
	if (title!=tid||!section) // avoid excess scrolling for intra-tiddler links
		onClickTiddlerLink_section.apply(this,arguments);
	story.scrollToSection(title,section);
	return false;
}
//}}}
/***
!!!!! displayTiddler
***/
//{{{
if (!Story.prototype.displayTiddler_section)
	Story.prototype.displayTiddler_section=Story.prototype.displayTiddler;
Story.prototype.displayTiddler = function(srcElement,tiddler)
{
	var title=(tiddler instanceof Tiddler)?tiddler.title:tiddler;
	var parts=title.split(config.textPrimitives.sectionSeparator);
	var title=parts[0]; var section=parts[1]; if (section) section=section.trim();
	if (!title.length || title.toLowerCase()=='here') {
		var t=story.findContainingTiddler(place);
		title=t?t.getAttribute('tiddler'):'';
	}
	arguments[1]=title;  // default=current tiddler
	this.displayTiddler_section.apply(this,arguments);
	story.scrollToSection(title,section);
}
//}}}
/***
!!!!!isExternalLink
***/
//{{{
if (!config.formatterHelpers.isExternalLink_section)
	config.formatterHelpers.isExternalLink_section=config.formatterHelpers.isExternalLink;
config.formatterHelpers.isExternalLink=function(link) {
	if (link.indexOf(config.textPrimitives.sectionSeparator)!=-1) return false;
	return config.formatterHelpers.isExternalLink_section.apply(this,arguments);
}
//}}}
/***
!!!!!tiddler.handler
***/
//{{{
if (!config.macros.tiddler.handler_section)
	config.macros.tiddler.handler_section=config.macros.tiddler.handler;
config.macros.tiddler.handler=function(place,macroName,params,wikifier,paramString,tiddler)
{
	if (!params[0]) return;
	var sep=config.textPrimitives.sectionSeparator;
	var parts=params[0].split(sep); var tid=parts[0]; var sec=parts[1]; if (sec) sec=sec.trim();
	if ((tid.toLowerCase()=='here'||!tid.length) && sec) { // fixup for 'here##section' and '##section'
		var here=story.findContainingTiddler(place)
		var tid=here?here.getAttribute('tiddler'):tiddler?tiddler.title:'';
		arguments[2][0]=tid+sep+sec;
		arguments[4]=paramString.replace(new RegExp('(here)?'+sep+sec),tid+sep+sec);
	}
	config.macros.tiddler.handler_section.apply(this,arguments);
}
//}}}
/***
!!!!sectionTOC macro
***/
//{{{
config.macros.sectionTOC = {
	targetClass: 'sectionTOC',
	handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		var out=[];
		var targetClass=params[0]||this.targetClass;
		var t=story.findContainingTiddler(place); if (!t) return;
		var elems=t.getElementsByTagName('*');
		var level=5; // topmost heading level
		for (var i=0; i<elems.length; i++) {
			var txt=getPlainText(elems[i]).trim();
			var link='[['+txt+'|##'+txt+']]';
			switch(elems[i].nodeName) {
				case 'H1': out.push('#'+link);		level=1; break;
				case 'H2': out.push('##'+link);		level=level<2?level:2; break;
				case 'H3': out.push('###'+link);	level=level<3?level:3; break;
				case 'H4': out.push('####'+link);	level=level<4?level:4; break;
				case 'H5': out.push('#####'+link);	level=level<5?level:5; break;
				default: if (hasClass(elems[i],targetClass)) var target=elems[i];
			}
		}
		// trim excess bullet levels
		if (level>1) for (var i=0; i<out.length; i++) out[i]=out[i].substr(level-1);
		// show numbered list
		if (out.length && target) {
			if (target.style.display=='none') target.style.display='block';
			wikify(out.join('\n'),target);
		}
	}
}
//}}}
/***
!!!Invoke macro
{{{
<<sectionTOC>>
}}}
***/
// //<<sectionTOC>>
/%
!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|transcluded html|
|Requires||
|Overrides||
|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]]>>
A sample of a password file generation tool. Using
{{{
filepp -D SERVICES="BIND POSTFIX" password.template
}}}
the named and postfix users will be generated.
{{{
#if "SERVICES" =~ /\bBIND\b/
named:x:25:25:Named:/var/named:/sbin/nologin
#endif

#if "SERVICES" =~ /POSTGRES/
postgres:x:26:26:PostgreSQL Server:...
#endif

#if "SERVICES" =~ /POSTFIX/
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
#endif
}}}
/% This tiddler is included by the PageTemplate and is used to trigger macro invocations. It should not actually
     display anything. All the macros here are invoked for their side effects and not for display. %/

/% A seperate tiddler for items to be executed only in the instructors cousebook. Since this tiddler is missing
   from the student coursebook copy it will have not effect for the student %/
<<tiddler InstructorSiteStartup>>

/% all references to tiddlywiki should point to TiddlyWiki %/
<<redirectExact tiddlywiki TiddlyWiki>>

John Rouillard - BBlisa Dec 9 2009
30 Minute Tools
http://www.example.com/class/content.html
<<tiddler Welcome/coursebook>>
/***
|''Name:''|SlideShowPlugin|
|''Description:''|Creates a slide show from a group of tiddlers|
|''Author:''|Paulo Soares|
|''Contributors:''|John P. Rouillard|
|''Version:''|2.1.2|
|''Date:''|2009-11-29|
|''Source:''|http://www.math.ist.utl.pt/~psoares/addons.html|
|''Documentation:''|[[SlideShowPlugin Documentation|SlideShowPluginDoc]]|
|''License:''|[[Creative Commons Attribution-Share Alike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''~CoreVersion:''|2.5.0|
***/
//{{{
if(!version.extensions.SlideShowPlugin) { //# ensure that the plugin is only installed once
version.extensions.SlideShowPlugin = {installed: true};

(function($) {
config.macros.slideShow = {maxTOCLength: 30};

config.macros.slideShow.text = {
  label: "slide show", tooltip: "Start slide show",
  quit: {label: "x", tooltip: "Quit the slide show"},
  firstSlide: {label: "<<", tooltip: "Go to first slide"},
  previous: {label: "<", tooltip: "Go back"},
  next: {label: ">", tooltip: "Advance"},
  lastSlide: {label: ">>", tooltip: "Go to last slide"},
  goto: {label: "Go to slide:"},
  resetClock: {tooltip: "Reset the clock"},
  overlay: "overlay"
};

config.macros.slideShow.handler = function(place,macroName,params,wikifier,paramString){
  var args = paramString.parseParams(null,null,false);
  this.label = getParam(args,"label",this.text.label);
  this.tooltip = getParam(args,"tooltip",this.text.tooltip);
  var onclick = function(){config.macros.slideShow.onClick(place,paramString); return false;};
  createTiddlyButton(place,this.label,this.tooltip,onclick);
  return false;
}

config.macros.slideShow.onClick = function(place,paramString) {
  var slide, cm = config.macros.slideShow;
  var title = story.findContainingTiddler(place);
  title = title ? title.getAttribute("tiddler") : null;
  var args = paramString.parseParams(null,null,false);
  title =  getParam(args,"tiddler",title);
  var argsArray = paramString.readMacroParams();
  this.clicks = ($.inArray('noClicks',argsArray) < 0);
  this.keyboard = ($.inArray('noKeyboard',argsArray) < 0);
  this.showAll = ($.inArray('showAll',argsArray) > -1);
  this.cycle = ($.inArray('cycle',argsArray) > -1);
  this.overlays = ($.inArray('noOverlays',argsArray) < 0);
  this.theme = getParam(args,"theme");
  this.tag = getParam(args,"tag");
  this.toc = getParam(args,"toc","headers");
  this.sort = getParam(args,"sort");
  this.clockFormat = getParam(args,"clockFormat",'0hh:0mm:0ss');
  this.auto = getParam(args,"auto",0);
  this.header = getParam(args,"header",title);
  this.footer = getParam(args,"footer","");
  this.clock = getParam(args,"clock");
  this.blocked = 0;
  if(this.clock){
    var startTime = new Date(0);
    this.clockCorrection=startTime.getTimezoneOffset()*60000;
    startTime = new Date();
    this.clockMultiplier = 1;
    this.clockInterval = 0;
    var clockType= parseFloat(this.clock);
    if(clockType < 0) {
      this.clockMultiplier = -1;
      this.clockInterval = -clockType*60000;
    } else if(clockType == 0){
      this.clockCorrection = 0;
      startTime = new Date(0);
    }
    this.clockStartTime=startTime.getTime();
  }
  this.slides = [];
  this.openTiddlers = [];
  $("#tiddlerDisplay > *").each(function(){cm.openTiddlers.push($(this).attr('tiddler'))});
  var count = 0;
  this.slideTOC=[];
  if(this.tag){
    var content = store.getTaggedTiddlers(this.tag,this.sort);
    $.each(content, function(){
      count++;
      cm.buildTOC(count,this.title);
      cm.slides.push(this.title);
    });
  } else {
    story.displayTiddler(null,title);
    var list = $('[tiddler='+title+']'+" .tiddlyLinkExisting");
    $.each(list,function(){
      if(!$(this).parents().hasClass("exclude")){
        slide = $(this).attr('tiddlylink');
        count++;
        cm.buildTOC(count,slide);
        cm.slides.push(slide);
      }
    });
  }
  this.nSlides = this.slides.length;
  if(this.nSlides==0) return false;
  clearMessage();
  this.toggleSlideStyles();
  if(!this.showAll){
    //Attach the key and mouse listeners
    if(this.keyboard && !$("#tiddlerDisplay").hasClass("noKeyboard")) $(document).keyup(cm.keys);
    if(this.clicks){
      $("#displayArea").mouseup(cm.clicker);
      document.oncontextmenu = function(){return false;}
    }
    if(this.clock) this.slideClock=setInterval(this.setClock, 1000);
    if(this.auto>0){
      this.autoAdvance=setInterval(cm.next, this.auto*1000);
    }
    this.showSlide(1);
  } else {
    story.closeAllTiddlers();
    story.displayTiddlers(null,this.slides);
    $(".tiddler").attr("ondblclick",null);
    $(document).keyup(cm.endSlideShow);
  }
  return false;
}

config.macros.slideShow.buildNavigator = function() {
  //Create the navigation bar
  var i, slidefooter = $("#controlBar")[0];
  if(!slidefooter) return;
  $(slidefooter).addClass("slideFooterOff noClicks");
  var navigator = createTiddlyElement(slidefooter,"SPAN","navigator");
  var buttonBar = createTiddlyElement(navigator,"SPAN","buttonBar");
  //Make it so that when the footer is hovered over the class will change to make it visible
  $(slidefooter).bind("mouseenter mouseleave", function(e){$(this).toggleClass("slideFooterOff");});
  //Create the control buttons for the navigation
 
  createTiddlyButton(buttonBar,this.text.firstSlide.label,this.text.firstSlide.tooltip,this.firstSlide,"button");
  createTiddlyButton(buttonBar,this.text.previous.label,this.text.previous.tooltip,this.previous,"button");
  createTiddlyButton(buttonBar,this.text.quit.label,this.text.quit.tooltip,this.endSlideShow,"button");
  createTiddlyButton(buttonBar,this.text.next.label,this.text.next.tooltip,this.next,"button");
  createTiddlyButton(buttonBar,this.text.lastSlide.label,this.text.lastSlide.tooltip,this.lastSlide,"button");
  if(this.clock){
    if(this.clock == 0){
       createTiddlyElement(navigator,"SPAN","slideClock");
    } else {
      createTiddlyButton(navigator," ",this.text.resetClock.tooltip,this.resetClock,"button","slideClock");
    }
    this.setClock();
  }
  var index = createTiddlyElement(slidefooter,"SPAN","slideCounter");
  index.onclick = this.toggleTOC;
  var toc = createTiddlyElement(slidefooter,"SPAN","toc");
  var tocLine;
  for(i=0; i<this.slideTOC.length; i++){
    $(toc).append(this.slideTOC[i][2]);
    tocLine = toc.lastChild;
    $(tocLine).addClass("tocLevel"+this.slideTOC[i][1]).css("cursor", "pointer").hover(function () {
        $(this).addClass("highlight");}, function () {
        $(this).removeClass("highlight");});
    tocLine.setAttribute("slide",this.slideTOC[i][0]);
    $(tocLine).click(config.macros.slideShow.showSlideFromTOC);
  }
  //Input box to jump to specific slide
  var tocItem = createTiddlyElement(toc,"DIV","jumpItem",null,this.text.goto.label);
  var tocJumpInput = createTiddlyElement(tocItem,"INPUT","jumpInput");
  tocJumpInput.type="text";
  $(tocJumpInput).keyup(config.macros.slideShow.jumpToSlide);
}

//Used to shorten the TOC fields
config.macros.slideShow.abbreviate = function(label){
  if(label.length>this.maxTOCLength) {
    var temp = new Array();
    temp = label.split(' ');
    label = temp[0];
    for(var j=1; j<temp.length; j++){
      if((label.length+temp[j].length)<=this.maxTOCLength){
        label += " " + temp[j];
      } else {
        label += " ...";
        break;
      }
    }
  }
  return label;
}

config.macros.slideShow.buildTOC = function(count,title) {
  var level = 1, text;
  switch(this.toc){
  case "headers":
    var frag = wikifyStatic(store.getTiddlerText(title));
    text = frag.replace(/<div class="comment">.*<\/div>/mg,"");
    var matches =  text.match(/<h[123456]>.*?<\/h[123456]>/mgi);
    if(matches){
      for (var j=0; j<matches.length; j++){
        level = matches[j].charAt(2);
        text = matches[j].replace(/<\/?h[123456]>/gi,"");
        text = this.abbreviate(text);
        this.slideTOC.push([count,level,"<div>("+count+") "+text+"</div>"]);
      }
    }
    break;
  case "titles":
    text = this.abbreviate(title);
    this.slideTOC.push([count,level,"<div>("+count+") "+text+"</div>"]);
  }
}

config.macros.slideShow.showSlideFromTOC = function(e) {
  var cm = config.macros.slideShow;
  var slide = parseInt(e.target.getAttribute('slide'));
  $("#toc").hide();
  cm.showSlide(slide);
  return false;
}

config.macros.slideShow.toggleTOC = function(){
  $("#toc").toggle();
  $("#jumpInput").focus().val('');
  return false;
}

config.macros.slideShow.isInteger = function(s){
  for (var i = 0; i < s.length; i++){
    // Check that current character is number
    var c = s.charAt(i);
    if (((c < "0") || (c > "9"))) return false;
  }
  // All characters are numbers
  return true;
}

config.macros.slideShow.jumpToSlide = function(e){
  var cm = config.macros.slideShow;
  if(e.which==13){
    var input= $("#jumpInput").val();
    if(cm.isInteger(input) && input>0 && input<=cm.nSlides){
      $("#toc").hide();
      cm.showSlide(input);
    } else  {$("#jumpInput").val('');}
  }
  return false;
}

config.macros.slideShow.toggleSlideStyles = function(){
  var contentWrapper = $('#contentWrapper');
  if(contentWrapper.hasClass("slideShowMode")){
    refreshPageTemplate();
    removeStyleSheet("SlideShowStyleSheet");
    if(this.theme) removeStyleSheet(this.theme);
  } else {
    $("#displayArea").prepend('<div id="slideBlanker" style="display:none"></div><div id="slideHeader">'+this.header+'</div><div id="slideFooter">'+this.footer+'</div><div id="controlBar"></div>');
    setStylesheet(store.getRecursiveTiddlerText("SlideShowStyleSheet"),"SlideShowStyleSheet");
    if(this.theme && store.tiddlerExists(this.theme)){setStylesheet(store.getRecursiveTiddlerText(this.theme),this.theme);}
    this.buildNavigator();
  }
  contentWrapper.toggleClass("slideShowMode");
  return false;
}

config.macros.slideShow.showSlide = function(n){
  if(this.cycle) {
    if(n>this.nSlides) {
      n = 1;
    } else if(n<1) {
      n = this.nSlides;
    }
  } else {
    if(n>this.nSlides || n<1) return;
  }
  story.closeAllTiddlers();
  if(this.clock=='-'){this.resetClock();}
  story.displayTiddler(null,String(this.slides[n-1]));
  $(".tiddler").attr("ondblclick",null);
  this.curSlide = n;
  $("#slideCounter").text(this.curSlide+"/"+this.nSlides);
  if(this.overlays){
    var contents = $(".viewer *");
    this.numOverlays = 1;
    while(1){
      if(contents.hasClass(this.text.overlay+this.numOverlays)){
        this.numOverlays++;
      } else {break;}
    }
    this.numOverlays--;
    this.showOverlay(0);
  }
  return false;
}

config.macros.slideShow.showOverlay = function(n){
  var i, set, cm = config.macros.slideShow;
  if(!cm.overlays || cm.numOverlays == 0 || n<0 || n>cm.numOverlays){return;}
  for(i=1; i<n; i++){
    set = $(".viewer "+"."+cm.text.overlay+i);
    set.removeClass("currentOverlay nextOverlay");
    set.addClass("previousOverlay");
  }
  set = $(".viewer "+"."+cm.text.overlay+n);
  set.removeClass("previousOverlay nextOverlay");
  set.addClass("currentOverlay");
  for(i=n; i<config.macros.slideShow.numOverlays; i++){
    set = $(".viewer "+"."+cm.text.overlay+(i+1));
    set.removeClass("previousOverlay currentOverlay");
    set.addClass("nextOverlay");
  }
  cm.curOverlay = n;
}

config.macros.slideShow.firstSlide = function(){
  config.macros.slideShow.showSlide(1);
  return false;
}

config.macros.slideShow.lastSlide = function(){
  config.macros.slideShow.showSlide(config.macros.slideShow.nSlides);
  return false;
}

config.macros.slideShow.next = function(){
  var cm = config.macros.slideShow;
  if(!cm.overlays || cm.numOverlays == 0 || cm.curOverlay == cm.numOverlays) {
    cm.showSlide(cm.curSlide+1);
  } else {
    cm.showOverlay(cm.curOverlay+1);
  }
  return false;
}

config.macros.slideShow.previous = function(){
  var cm = config.macros.slideShow;
  if(!cm.overlays || cm.numOverlays == 0 || cm.curOverlay == 0) {
    cm.showSlide(cm.curSlide-1);
    cm.showOverlay(cm.numOverlays);
  } else {
    cm.showOverlay(cm.curOverlay-1);
  }
  return false;
}

config.macros.slideShow.endSlideShow=function(){
  var cm = config.macros.slideShow;
  if(cm.autoAdvance) {clearInterval(cm.autoAdvance);}
  if(this.clock) clearInterval(this.slideClock);
  story.closeAllTiddlers();
  cm.toggleSlideStyles();
  story.displayTiddlers(null,cm.openTiddlers);
  $(document).unbind();
  document.oncontextmenu =  function(){};
  return false;
}

// 'keys' code adapted from S5 which in turn was adapted from MozPoint (http://mozpoint.mozdev.org/)
config.macros.slideShow.keys = function(key) {
  var cm = config.macros.slideShow;
  switch(key.which) {
  case 32: // spacebar
    if(cm.auto>0 && cm.blocked==0){
      if(cm.autoAdvance){
        clearInterval(cm.autoAdvance);
        cm.autoAdvance = null;
      } else {
        cm.autoAdvance=setInterval(cm.next, cm.auto*1000);
      }
    } else {
      if(cm.blocked==0) cm.next();
    }
    break;
  case 34: // page down
    if(cm.blocked==0) cm.showSlide(cm.curSlide+1);
    break;
  case 39: // rightkey
    if(cm.blocked==0) cm.next();
    break;
  case 40: // downkey
    if(cm.blocked==0) cm.showOverlay(cm.numOverlays);
    break;
  case 33: // page up
    if(cm.blocked==0) cm.showSlide(cm.curSlide-1);
    break;
  case 37: // leftkey
    if(cm.blocked==0) cm.previous();
    break;
  case 38: // upkey
    if(cm.blocked==0) cm.showOverlay(0);
    break;
  case 36: // home
    if(cm.blocked==0) cm.firstSlide();
    break;
  case 35: // end
    if(cm.blocked==0) cm.lastSlide();
    break;
  case 27: // escape
    cm.endSlideShow();
    break;
  case 66: // B
    $("#slideBlanker").toggle();
    cm.blocked = (cm.blocked +1)%2;
    break;
  }
  return false;
}

config.macros.slideShow.clicker = function(e) {
  var cm = config.macros.slideShow;
  if(cm.blocked==1 || $(e.target).attr('href') || $(e.target).parents().andSelf().hasClass('noClicks')){
    return true;
  }
  if($("#toc").is(':visible')){
    cm.toggleTOC();
  } else {
    if((!e.which && e.button == 1) || e.which == 1) {
      cm.next();
    }
    if((!e.which && e.button == 2) || e.which == 3) {
      cm.previous();
    }
  }
  return false;
}

config.macros.slideShow.setClock = function(){
  var cm = config.macros.slideShow;
  var actualTime = new Date();
  var newTime = actualTime.getTime() - cm.clockStartTime;
  newTime = cm.clockMultiplier*newTime+cm.clockInterval+cm.clockCorrection;
  actualTime.setTime(newTime);
  newTime = actualTime.formatString(cm.clockFormat);
  $("#slideClock").text(newTime);
  return false;
}

config.macros.slideShow.resetClock = function(){
  var cm = config.macros.slideShow;
  if(cm.clock == 0) return;
  var time = new Date(0);
  if(cm.clockStartTime>time){
    var startTime = new Date();
    cm.clockStartTime=startTime.getTime();
  }
  return false;
}

config.shadowTiddlers.SlideShowStyleSheet="/*{{{*/\n.header, #mainMenu, #sidebar, #backstageButton, #backstageArea, .toolbar, .title, .subtitle, .tagging, .tagged, .tagClear, .comment{\n display:none !important\n}\n\n#slideBlanker{\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: 90; \n background-color: #000;\n opacity: 0.9;\n filter: alpha(opacity=90)\n}\n\n.nextOverlay{\n visibility: hidden\n}\n\n.previousOverlay,.currentOverlay{\n visibility: visible\n}\n\n#displayArea{\n font-size: 250%;\n margin: 0 !important;\n padding: 0\n}\n\n#controlBar{\n position: fixed;\n bottom: 2px;\n right: 2px;\n width: 100%;\n text-align: right\n}\n\n#controlBar .button{\n margin: 0 0.25em;\n padding: 0 0.25em\n}\n\n#slideHeader{\n font-size: 200%;\n font-weight: bold\n}\n\n#slideFooter{\n position: fixed;\n bottom: 2px\n}\n\n.slideFooterOff #navigator{\n visibility: hidden\n}\n\n#slideClock{\n margin: 0 5px 0 5px\n}\n\n#slideCounter{\n cursor: pointer;\n color: #aaa\n}\n\n#toc{\n display: none;\n position: absolute;\n font-size: .75em;\n bottom: 2em;\n right: 0;\n background: #fff;\n border: 1px solid #000;\n text-align: left\n}\n\n#jumpItem{\n padding-left:0.25em\n}\n\n#jumpInput{\n margin-left: 0.25em;\n width: 3em\n}\n\n.tocLevel1{\n font-size: .8em\n}\n\n.tocLevel2{\n margin-left: 1em;\n font-size: .75em\n}\n\n.tocLevel3{\n margin-left: 2em;\n font-size: .7em\n}\n\n.tocLevel4{\n margin-left: 3em;\n font-size: .65em\n}\n\n.tocLevel5{\n margin-left: 4em;\n font-size: .6em\n}\n\n.tocLevel6{\n margin-left: 5em;\n font-size: .55em\n}\n/*}}}*/";

config.shadowTiddlers.SlideShowPluginDoc="The documentation is available [[here|http://www.math.ist.utl.pt/~psoares/addons.html#SlideShowPluginDoc]].";
})(jQuery)
}
//}}}
!Description
This plugin turns a set of tiddlers into a slide show. A single macro provides a flexible way to present a set of tiddlers, including:
#a full screen presentation that hides the TiddlyWiki structure (header, sidebar, main menu);
#a way to navigate through a set of tiddlers keeping the TiddlyWiki structure (similar to the [[NavigationMacro|http://tw.lewcid.org/#NavigationMacro]] by Saq Imtiaz);
#a display of all the selected tiddlers ready to be printed.
!Main features
Most features that are usually found in presentation software are available. 
*Build a slide show from a list of tiddlers' titles or selecting a specific tag with optional sort
*Fully customizable presentations (CSS knowledge required)
*Auto-advancing slide show (kiosk mode) and looping (circular mode)
*Incremental display (several overlays or layers in a slide)
*Optional clock with 4 different modes:
**local time
**elapsed time of presentation
**elapsed time for each slide
**countdown clock for a given period
*Screen blanking for pauses
!Installation
To install this plugin copy the tiddler SlideShowPlugin to your TiddlyWiki, label it with the ''systemConfig'' tag, save the TW and refresh the browser.
Optionally, you can also copy this documentation tiddler. If you don't, a link to the original one in my site is provided.  
!Quick start
The simplest way to make a slide show is to create a new tiddler with references to all the tiddlers you want to include in your presentation. Any reference or group of references to tiddlers that should be skipped must be wrapped in a {{{exclude}}} class as in the following example:
{{{
MissingSlide
[[First slide|SlideShowExample-1]] {{exclude{(the tiddler SlideShowPluginDoc will not be included in the presentation)}}}
SlideShowExample-2
SlideShowExample-3
SlideShowExample-4
}}}
Add {{{<<slideShow>>}}} anywhere in the tiddler, close the edit form, click the ''slide show'' button and there you are. Move forward/backward in the presentation with the mouse left/right button. If you move the mouse pointer over the bottom of the browser window you will see a few navigation buttons. Click the ''x'' button or press the ''Escape'' key to exit.
!Options
{{{
<<slideShow
  noClicks
  noKeyboard
  noOverlays
  cycle
  showAll
  tiddler:tiddler
  label:string
  tooltip:string
  tag:tag
  sort:field
  theme:tiddler
  toc:string
  auto:time
  clock:type
  clockFormat:string
  header:string
  footer:string
>> 
}}}
''noClicks''
Disables navigation through mouse clicks on the tiddlers. This is useful when there are lots of clickable elements in the presentation.
If you want to keep using the mouse to move around the presentation and there are occasional elements that require mouse clicking, these can be formatted with a {{{noClicks}}} class (read more [[here|http://www.tiddlywiki.com/#CustomCssClass]]).

''noKeyboard''
Disables keyboard navigation.

''noOverlays''
Disables the incremental display of overlays.

''cycle''
The slide shows runs in a continuous loop. 

''showAll''
To print a presentation all the selected tiddlers are opened in the specified order. Press any key to return to the default TiddlyWiki layout.

''tiddler''
Use this option to indicate the tiddler where your slide show is defined when it is not the same one that contains the button that starts the presentation.

''label''
Text to replace the default text in the slide show button.

''tooltip''
Text to be shown when the mouse is over the slide show button.

''tag''
Use this option to create a slide show with the tiddlers with the provided tag instead of providing a list of tiddlers.

''sort''
If the ''tag'' option is used you can use this other option to sort the tiddlers according to a specific field. Valid values are: //created// (default), //modified//, //title// and //text//.

''theme''
A user provided tiddler containing CSS rules that define the style of the slide show. To redefine the default style, edit the SlideShowStyleSheet shadow tiddler. 

''toc''
Choose the type of table of contents. Possible values: ''titles'' will enable the use of the tiddlers titles, ''headers'' (default) to choose html headers (h1, h2,...), anything else will disable the table of contents.  

''auto''
The slide show auto advances after the defined number of seconds. The slide show can be paused by pressing the ''space bar''.

''clock''
Displays a clock near the navigation buttons at the bottom of the screen. Four types of clocks can be defined:
#''clock:0'' -- shows the local time.
#''clock:'+''' -- displays the elapsed time of the presentation. Click the clock display to reset the time.
#''clock:'-''' -- displays the elapsed for each slide. Click the clock display to reset the time.
#''clock:-20'' -- displays a countdown clock for the given (negative) number of minutes. Click the clock display to reset the time.
''clockFormat''
A string that defines the clock format. The default is '0hh:0mm:0ss' where the prefix '0' forces a leading zero. 

''header''
A string to be used as a permanent header for the slide show. By default it's used the title of tiddler that defines the slide show.

''footer''
A string to be used as a permanent footer for the slide show. By default the footer is empty.
!Incremental display
A succession of overlays (or layers) can be defined in each slide by marking blocks of text with
{{{
{{overlay1{...some text...}}}, {{overlay2{...some text...}}}, {{overlay3{...some text...}}}, ...
}}}
The default name of the classes (//overlay//) can be redefined with //config.macros.slideShow.text.overlay = "layer"//, for example. 
To costumize the way overlays are shown you can redefine the following CSS classes
*.previousOverlay 
*.currentOverlay 
*.nextOverlay 
in a ~StyleSheet. The default style simply hides the next overlays and shows the current and the previous ones as normal text.
!Slide show navigation
You can navigate through a slide show using the keyboard or the mouse. 
!!Mouse navigation
Left (right) clicking on a slide jumps to the next (previous) slide or overlay. To move to the first or last slides you must use the navigation bar at the bottom of the browser's window.
!!Keyboard
The following keys are defined:
*Home - first slide
*~PageUp - previous slide
*~PageDown - next slide
*End - last slide
*Escape - exit slide show
*Up arrow - first overlay
*Left arrow - previous overlay/slide
*Pause/Right arrow - next overlay/slide
*Down arrow - last overlay
*Spacebar - pause/resume slide show in auto advance mode, next overlay/slide otherwise
*B - blank screen and block the slide show
!Miscellaneous 
Any block of text marked as
{{{
{{comment{For my eyes only!}}}
}}}
will not be displayed in the slide show.

All translatable strings are defined in //config.macros.slideShow.text// parameter. See SlideShowPluginMsgPT with the portuguese translation as an example.
/*{{{*/
/* Default slide show style sheet settings */
.header, #mainMenu, #sidebar, #backstageButton, #backstageArea, .toolbar, .title, .subtitle, .tagging, .tagged, .tagClear, .comment{
 display:none !important
}

#slideBlanker{
 position: absolute;
 top: 0;
 left: 0;
 width: 100%;
 height: 100%;
 z-index: 90; 
 background-color: #000;
 opacity: 0.9;
 filter: alpha(opacity=90)
}

.nextOverlay{
 visibility: hidden
}

.previousOverlay,.currentOverlay{
 visibility: visible
}

#displayArea{
 font-size: 250%;
 margin: 0 !important;
 padding: 0
}

#controlBar{
 position: fixed;
 bottom: 2px;
 right: 2px;
 width: 100%;
 text-align: right
}

#controlBar .button{
 margin: 0 0.25em;
 padding: 0 0.25em
}

#slideHeader{
 font-size: 200%;
 font-weight: bold
}

#slideFooter{
 position: fixed;
 bottom: 2px
}

.slideFooterOff #navigator{
 visibility: hidden
}

#slideClock{
 margin: 0 5px 0 5px
}

#slideCounter{
 cursor: pointer;
 color: #aaa
}

#toc{
 display: none;
 position: absolute;
 font-size: .75em;
 bottom: 2em;
 right: 0;
 background: #fff;
 border: 1px solid #000;
 text-align: left
}

#jumpItem{
 padding-left:0.25em
}

#jumpInput{
 margin-left: 0.25em;
 width: 3em
}

.tocLevel1{
 font-size: .8em
}

.tocLevel2{
 margin-left: 1em;
 font-size: .75em
}

.tocLevel3{
 margin-left: 2em;
 font-size: .7em
}

.tocLevel4{
 margin-left: 3em;
 font-size: .65em
}

.tocLevel5{
 margin-left: 4em;
 font-size: .6em
}

.tocLevel6{
 margin-left: 5em;
 font-size: .55em
}

/* local changes for coursebook */

/* Disable slide blanker */
#slideBlanker {
 opacity: 0.0;
 filter: alpha(opacity=0)
}

/* Don't do overlay displays, display whole thing at once. */
.nextOverlay{
 visibility: visible
}

/* navigator always visible, black text on white background */
.slideFooterOff #navigator{
 visibility: visible;
 background: #FFF;
 foreground: #000;
}

#displayArea{
 font-size: 130%;
}

.title {
display: block !important;
left-margin: 6em;
}

/* put control bar in top right of header */
#controlBar{
 position: relative;
 bottom: 2px;
 right: 2px;
 width: 100%;
 text-align: right;
}

#controlBar .button {
border: 2px solid #000;
border-style: outset;
}

/* put toc as drop down menu not drop up */
#toc{
 font-size: 1em;
 top: 2em;
 right: 0;
 background: #888;
}

/* display comments in student mode with sea green background  */
#contentWrapper.slideShowMode .comment{
 display: block !important;
 background: #FFCC00;
}
.notes {
display: block;
}

#openTiddlers { display: none !important }
/*}}}*/
!PageTemplate
<!--{{{-->
<div id='displayArea'>
<div id='slideBlanker' style='display:none'></div>
<div id='slideHeader'></div>
<div id='tiddlerDisplay'></div>
<div id='slideFooter'></div>
<div id='controlBar' class='slideFooterOff noClicks'></div>
</div>
<!--}}}-->
!ViewTemplate
<!--{{{-->
<div class='title' macro='view title'></div>
<div class='viewer' macro='view text wikified'></div>
<!--}}}-->
!contentViewTemplate
<!--{{{-->
theme
<div class='title' macro='view title'></div>
<div class='viewer' macro='view text wikified'></div>
<!--}}}-->
!StyleSheet
/*{{{*/
#slideBlanker{
 position:absolute;
 top: 0;
 left: 0;
 width: 100%;
 height: 100%;
 z-index: 90; 
 background-color: #000;
 opacity:.9;filter: alpha(opacity=90);
}

#backstageShow, #contentWrapper.slideShowMode .comment{
 display: none !important;
}

#contentWrapper.slideShowMode .nextOverlay{
 visibility: hidden;
}

#contentWrapper.slideShowMode .previousOverlay, #contentWrapper.slideShowMode .currentOverlay{
 visibility: visible;
}

#contentWrapper.slideShowMode #displayArea{
 font-size: 220%;
 margin: 0 !important;
 padding: 0;
}

#controlBar{
 position: fixed;
 bottom: 2px;
 right: 2px;
 width: 100%;
 text-align: right;
}

#controlBar .button{
 margin:0em 0.25em;
 padding:0em 0.25em;
}

#slideHeader{
 font-size: 200%;
 font-weight: bold;
}

#slideFooter{
 position: absolute;
 bottom: 2px;
 font-size: 50%;
}

.slideFooterOff #navigator{
 visibility: hidden;
}

#slideClock{
 margin: 0 5px 0 5px
}

#slideCounter{
 cursor: pointer;
}

#toc{
 display: none;
 position: absolute;
 font-size: .75em;
 bottom: 2em;
 right: 0;
 background: #fff;
 border: 1px solid #000;
 text-align: left;
}

.tocJumpItem input{
 margin-left: 1em;
 width: 3em
}

.tocLevel1{
 font-size: .8em;
}

.tocLevel2{
 margin-left: 1em;
 font-size: .75em;
}

.tocLevel3{
 margin-left: 2em;
 font-size: .7em;
}

.tocLevel4{
 margin-left: 3em;
 font-size: .65em;
}

.tocLevel5{
 margin-left: 4em;
 font-size: .6em;
}

.tocLevel6{
 margin-left: 5em;
 font-size: .55em;
}
/*}}}*/
These sections are used in presentations to provide the text before the buttons that start the slideshows (so the tiddlers mentioned aren't included in the slideshow). Make sure each section is only one line. No blank lines as they display as blank lines when used. The end section merely defines the end for the print section.

!Instructor
Instructor show with theme {{exclude{[[InstructorSlideShowStyleSheet]]}}}:
!Student
Student show using  {{exclude{[[SlideShowStyleSheet]]}}}:
!Print
Print show with theme {{exclude{[[PrintingSlideShowStyleSheet]]}}}:
!end
<html>
<hide linebreaks>
<ul>
<li class="overlay1">Automatic hyperlinking mailto:..., ftp:..., http:..., https:..., elog:&lt;id&gt;</li>
<li class="overlay2">Fill new entries with a template</li>
<li class="overlay3">Required attributes on new entries</li>
<li class="overlay4">Email notifications of new entries</li>
<li class="overlay5">Can use text, its formatting language or html to create entries</li>
<li class="overlay6">"filtered browsing" - when displaying an entry find similar entries</li>
<li class="overlay7">Command line submission of entries</li>
<li class="overlay8">Supports ssl - so you can encrypt your traffic</li>
<li class="overlay9">Supports replication - 15 minutes to set it up to replicate</li>
</ul>
</html>
{{overlay10{See the demo at: https://midas.psi.ch/elogs/Linux+Demo/}}}
/***
|Name|StorySaverPlugin|
|Source|http://www.TiddlyTools.com/#StorySaverPlugin|
|Documentation|http://www.TiddlyTools.com/#StorySaverPluginInfo|
|Version|1.8.3|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Requires|MarkupPostBody|
|Description|save/restore current tiddler view between browser sessions|
Automatically save a list of currently viewed tiddlers (the 'story') in a local cookie, {{{txtSavedStory}}} and then open those tiddlers when the document is reloaded, so you can resume working from the same place you left off!!  Also, use {{{<<saveStory>>}}} and {{{<<openStory>>}}} macros to quickly save/re-display stories stored in tiddlers, using a command link, droplist, or popup display.
!!!!!Documentation
>see [[StorySaverPluginInfo]]
!!!!!Configuration
<<<
<<option chkSaveStory>> use automatic story cookie (reopens tiddlers on startup)
<<option chkStoryAllowAdd>>include 'add a story' command in droplist/popup
<<option chkStoryFold>>fold story tiddlers when opening a story (see [[CollapseTiddlersPlugin]])
<<option chkStoryClose>>close other tiddlers when opening a story
<<option chkStoryTop>>open story tiddlers at top of column
<<option chkStoryBottom>>open story tiddlers at bottom of column
<<<
!!!!!Revisions
<<<
2009.10.20 1.8.3 fix handling for 'add' item in popup menu
|please see [[StorySaverPluginInfo]] for additional revision details|
2007.10.05 1.0.0 initial release. Moved [[SetDefaultTiddlers]] inline script and rewrote as a {{{<<saveStory>>}}} macro.
<<<
!!!!!Code
***/
//{{{
version.extensions.StorySaverPlugin= {major: 1, minor: 8, revision: 3, date: new Date(2009,10,20)};

var defaults={
	chkSaveStory:		false,
	chkStoryFold:		true,
	chkStoryClose:		true,
	chkStoryAllowAdd:	true,
	chkStoryTop:		true,
	chkStoryBottom:		false
};
for (var id in defaults) if (config.options[id]===undefined)
	config.options[id]=defaults[id];

// if removeCookie() function is not defined by TW core, define it here.
if (window.removeCookie===undefined) {
	window.removeCookie=function(name) {
		document.cookie = name+'=; expires=Thu, 01-Jan-1970 00:00:01 UTC; path=/;'; 
	}
}

// save or clear story cookie on exit
if (window.coreTweaks_confirmExit==undefined) {
	window.coreTweaks_confirmExit=window.confirmExit;
	window.confirmExit=function() {
		if (config.options.chkSaveStory) { // save cookie
			var links=[];
			story.forEachTiddler(function(title,element){links.push('[['+title+']]');});
			config.options.txtSavedStory=links.join(' ');
			saveOptionCookie('txtSavedStory');
		} else removeCookie('txtSavedStory');
		return window.coreTweaks_confirmExit.apply(this,arguments);
	}
}
//}}}
/***
''apply saved story on startup:'' //important note: the following code is actually located in [[MarkupPostBody]].  This is because it needs to supercede the core's getParameters() function, which is called BEFORE plugins are loaded, preventing the normal plugin-based hijack method from working, while code loaded into [[MarkupPostBody]] will be processed as soon as the document is read, even before the TW main() function is invoked.//
<<tiddler MarkupPostBody>>
***/
//{{{
config.macros.saveStory = {
	label: 'set default tiddlers',
	defaultTiddler: 'DefaultTiddlers',
	prompt: 'store a list of currently displayed tiddlers in another tiddler',
	askMsg: 'Enter the name of a tiddler in which to save the current story:',
	tag: 'story',
	excludeTag: 'excludeStory',
	handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		var tid=params.shift()||'DefaultTiddlers';
		var label=params.shift()||this.label;
		var tip=params.shift()||this.prompt;
		var btn=createTiddlyButton(place,label,tip,this.setTiddler,'button');
		btn.setAttribute('tid',tid);
		btn.setAttribute('extratags','[['+params.join(']] [[')+']]');
	},
	setTiddler: function() {
		var cms=config.macros.saveStory; // abbrev
		// get list of current open tiddlers
		var tids=[];
		story.forEachTiddler(function(title,element){
			var t=store.getTiddler(title);
			if (!t || !t.isTagged(cms.excludeTag)) tids.push('[['+title+']]');
		});
		// get target tiddler
		var tid=this.getAttribute('tid');
		if (!tid || tid=='ask') {
			tid=prompt(cms.askMsg,cms.defaultTiddler);
			if (!tid || !tid.length) return false; // cancelled by user
		}
		if(store.tiddlerExists(tid) && !confirm(config.messages.overwriteWarning.format([tid])))
			return false;
		tids=tids.join('\n');
		var t=store.getTiddler(tid); var tags=t?t.tags:[];
		var extratags=(this.getAttribute('extratags')||'').readBracketedList();
		for (var i=0; i<extratags.length; i++) tags.pushUnique(extratags[i]);
		tags.pushUnique(cms.tag);
		store.saveTiddler(tid,tid,tids,config.options.txtUserName,new Date(),tags,t?t.fields:null);
		story.displayTiddler(null,tid);
		story.refreshTiddler(tid,null,true);
		displayMessage(tid+' has been '+(t?'updated':'created'));
		return false;
	}
}
//}}}
//{{{
config.macros.openStory = {
	label: 'open story: %0',
	prompt: 'open the set of tiddlers listed in: %0',
	popuplabel: 'stories',
	popupprompt: 'view a set of tiddlers',
	tag: 'story',
	selectprompt: 'select a story...',
	optionsprompt: 'viewing options...',
	foldcmd: '[%0] fold story',
	foldprompt: 'fold story tiddlers when opening a story',
	closecmd: '[%0] close others',
	closeprompt: 'close other tiddlers when opening a story',
	topcmd: '[%0] open at top',
	topprompt: 'open story tiddlers at top of column',
	bottomcmd: '[%0] open at bottom',
	bottomprompt: 'open story tiddlers at bottom of column',
	addcmd: 'add a story...',
	addprompt: 'create a new story',
	excludeTag: 'excludeStory',
	handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		if (params[0].toLowerCase()=='list') return this.createList(place,params);
		else if (params[0].toLowerCase()=='popup') return this.createPopup(place,params);
		else this.createButton(place,params);
	},
	showStory: function(tid,fold) {
		var co=config.options; // abbrev
		var tids=[];
		var t=store.getTiddler(tid);
		var tagged=store.getTaggedTiddlers(tid,'title');
		if (tagged.length) // if tiddler IS a tag, use tagged tiddlers as story
			for (var i=0; i<tagged.length; i++) tids.push(tagged[i].title);
		else if (t) { // get tiddler list from content
			if (!t.linksUpdated) t.changed();
			for (var i=0; i<t.links.length; i++) {
				var tid=store.getTiddler(t.links[i]);
				if (tid && !tid.isTagged(this.excludeTag))
					tids.push(t.links[i]);
			}
		}
		var template=null;
		if (fold||co.chkStoryFold) template='CollapsedTemplate'; // see [[CollapseTiddlersPlugin]]
		if (!store.tiddlerExists('CollapsedTemplate')) template=null;
		if (co.chkStoryClose) story.closeAllTiddlers();
		var pos='top'; var first=tids[0];
		if (!story.isEmpty() && co.chkStoryBottom) { pos='bottom'; tids=tids.reverse(); }
		story.displayTiddlers(pos,tids,template);
		var cmd='var t=story.getTiddler("'+first+'");if(t)window.scrollTo(0,t.offsetTop);';
		var delay=config.options.chkAnimate?config.animDuration+100:0;
		setTimeout(cmd,delay);
	},
	createButton: function(place,params) {
		var tid=params[0]||'';
		var label=params[1]||this.label; label=label.format([tid]);
		var tip=params[2]||this.prompt; tip=tip.format([tid]);
		var fold=(params[3]&&(params[3].toLowerCase()=='fold'))||config.options.chkStoryFold;
		var fn=function(){config.macros.openStory.showStory(this.getAttribute('tid'),this.getAttribute('fold')); return false; };
		var btn=createTiddlyButton(place,label,tip,fn,'button');
		btn.setAttribute('tid',tid);
		if (fold) btn.setAttribute('fold',fold);
	},
	createPopup: function(place,params) {
		params.shift(); // discard 'popup' keyword
		var label=params.shift()||this.popuplabel;
		var tip=params.shift()||this.popupprompt;
		var btn=createTiddlyButton(place,label,tip,this.showPopup,'button');
		btn.setAttribute('filter',params.shift()||config.macros.openStory.tag);
	},
	showPopup: function(ev) { var e=ev||window.event;
		var co=config.options; // abbrev
		var cmo=config.macros.openStory; // abbrev
		var indent='\xa0\xa0';
		var p=Popup.create(this); if (!p) return false;
		createTiddlyText(createTiddlyElement(p,'li'),cmo.selectprompt);
		var stories=store.filterTiddlers('[tag['+this.getAttribute('filter')+']]');
		for (var s=0; s<stories.length; s++) {
			var label=indent+stories[s].title;
			var tip=cmo.prompt.format([stories[s].title]);
			var fn=function(){config.macros.openStory.showStory(this.getAttribute('tid'));return false;};
			var btn=createTiddlyButton(createTiddlyElement(p,'li'),label,tip,fn,'button');
			btn.setAttribute('tid',stories[s].title);
		}
		createTiddlyText(createTiddlyElement(p,'li'),cmo.optionsprompt);
		if (store.tiddlerExists('CollapsedTemplate')) {
			var label=indent+cmo.foldcmd.format([co.chkStoryFold?'x':'\xa0\xa0']);
			var tip=cmo.foldprompt;
			var fn=function(){ config.macros.option.propagateOption(
				'chkStoryFold','checked',!config.options.chkStoryFold,'input'); return false; };
			var btn=createTiddlyButton(createTiddlyElement(p,'li'),label,tip,fn,'button');
		}
		var label=indent+cmo.closecmd.format([co.chkStoryClose?'x':'\xa0\xa0']);
		var tip=indent+cmo.closeprompt;
		var fn=function(){ config.macros.option.propagateOption(
			'chkStoryClose','checked',!config.options.chkStoryClose,'input'); return false; };
		var btn=createTiddlyButton(createTiddlyElement(p,'li'),label,tip,fn,'button');
		if (!co.chkStoryClose) {
			var label=indent+cmo.topcmd.format([co.chkStoryTop?'x':'\xa0\xa0']);
			var tip=indent+cmo.topprompt;
			var fn=function(){
				config.macros.option.propagateOption(
					'chkStoryTop','checked',!config.options.chkStoryTop,'input');
				config.macros.option.propagateOption(
					'chkStoryBottom','checked',!config.options.chkStoryTop,'input');
				return false;
			};
			var btn=createTiddlyButton(createTiddlyElement(p,'li'),label,tip,fn,'button');
			var label=indent+cmo.bottomcmd.format([co.chkStoryBottom?'x':'\xa0\xa0']);
			var tip=indent+cmo.botprompt;
			var fn=function(){
				config.macros.option.propagateOption(
					'chkStoryBottom','checked',!config.options.chkStoryBottom,'input');
				config.macros.option.propagateOption(
					'chkStoryTop','checked',!config.options.chkStoryBottom,'input');
				return false;
			};
			var btn=createTiddlyButton(createTiddlyElement(p,'li'),label,tip,fn,'button');
		}
		if (!readOnly && co.chkStoryAllowAdd) {
			var label=cmo.addcmd;
			var tip=cmo.addprompt;
			var fn=config.macros.saveStory.setTiddler;
			createTiddlyElement(createTiddlyElement(p,'li'),'hr');
			var btn=createTiddlyButton(createTiddlyElement(p,'li'),label,tip,fn,'button');
		}
		Popup.show();
		e.cancelBubble=true;if(e.stopPropagation)e.stopPropagation();
		return false;
	},
	createList: function(place,params) {
		var cmo=config.macros.openStory; // abbrev
		var s=createTiddlyElement(place,'select',null,'storyListbox');
		s.size=1;
		s.onchange=function() {
			if (this.value=='_fold') {
				config.macros.option.propagateOption('chkStoryFold','checked',
					!config.options.chkStoryFold,'input');
				cmo.refreshList();
			} else if (this.value=='_close') {
				config.macros.option.propagateOption('chkStoryClose','checked',
					!config.options.chkStoryClose,'input');
				cmo.refreshList();
			} else if (this.value=='_top') {
				config.macros.option.propagateOption('chkStoryTop','checked',
					!config.options.chkStoryTop,'input');
				cmo.refreshList();
			} else if (this.value=='_bottom') {
				config.macros.option.propagateOption('chkStoryBottom','checked',
					!config.options.chkStoryBottom,'input');
				cmo.refreshList();
			} else if (this.value=='_add')
				config.macros.saveStory.setTiddler.apply(this,arguments);
			else cmo.showStory(this.value);
		}
		params.shift(); // discard 'list' keyword
		s.setAttribute('filter',params.shift()||cmo.tag);
		setStylesheet('.storyListbox { width:100%; }', 'StorySaverStyles');
		store.addNotification(null,this.refreshList); this.refreshList();
		return;
	},
	refreshList: function() {
		var cmo=config.macros.openStory; // abbrev
		var indent='\xa0\xa0\xa0\xa0';
		var lists=document.getElementsByTagName('select');
		for (var i=0; i<lists.length; i++) { if (lists[i].className!='storyListbox') continue;
			var here=lists[i];
			var stories=store.filterTiddlers('[tag['+here.getAttribute('filter')+']]');
			while (here.length) here.options[0]=null; // remove current list items
			here.options[here.length]=new Option(cmo.selectprompt,'',true,true);
			for (var s=0; s<stories.length; s++)
				here.options[here.length]=new Option(indent+stories[s].title,stories[s].title);
			if (!readOnly && config.options.chkStoryAllowAdd)
				here.options[here.length]=new Option(cmo.addcmd,'_add');
			here.options[here.length]=new Option(cmo.optionsprompt,'');
			if (store.tiddlerExists('CollapsedTemplate')) {
				var msg=cmo.foldcmd.format([config.options.chkStoryFold?'x':'\xa0\xa0']);
				here.options[here.length]=new Option(indent+msg,'_fold');
			}
			var msg=cmo.closecmd.format([config.options.chkStoryClose?'x':'\xa0\xa0']);
			here.options[here.length]=new Option(indent+msg,'_close',false,false);
			if (!config.options.chkStoryClose) {
				var msg=cmo.topcmd.format([config.options.chkStoryTop?'x':'\xa0\xa0']);
				here.options[here.length]=new Option(indent+msg,'_top',false,false);
				var msg=cmo.bottomcmd.format([config.options.chkStoryBottom?'x':'\xa0\xa0']);
				here.options[here.length]=new Option(indent+msg,'_bottom',false,false);
			}
		}
	}
}
//}}}
/***
! StorySaverPlugin

Try to override text for the popup. Remove the word story add section.
***/
//{{{
config.macros.openStory.label = "open: %0";
config.macros.openStory.popuplabel = "section";
config.macros.openStory.selectprompt = "select a section...";
config.macros.openStory.foldprompt = "fold story tiddlers when opening a section";
config.macros.openStory.closeprompt = "close other tiddlers when opening a section";

config.options.chkStoryAllowAdd = false;
//}}}
/***
|Name|StorySaverPlugin|
|Source|http://www.TiddlyTools.com/#StorySaverPlugin|
|Documentation|http://www.TiddlyTools.com/#StorySaverPluginInfo|
|Version|1.8.3|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|documentation|
|Requires|MarkupPostBody|
|Description|documentation for [[StorySaverPlugin]]|
Automatically saves a list of currently viewed tiddlers (the "story") in a local cookie, {{{txtSavedStory}}} and then opens those tiddlers when the document is subsequently reloaded, allowing you to quickly resume working with the document from the same place you left off!! The plugin also defines {{{<<saveStory>>}}} and {{{<<openStory>>}}} macros that allow you to quickly save/re-display stories stored in tiddlers, using simple, one-click command links or droplists.
!!!!!Usage
<<<
If a document URL does not contain a paramifier (i.e., a "#..." suffix), then the saved story cookie (if any) will be used //as if// it had been entered as a permaview (e.g., a "#tiddler tiddler tiddler..." suffix on the URL), bypassing the [[DefaultTiddlers]] definition.  This behavior is automatically applied whenever the plugin is installed in your document.  You can enable/disable the automatic cookie-based StorySaver feature by using the checkbox below:
><<option chkSaveStory>> enable StorySaverPlugin
>//usage:// {{{<<option chkSaveStory>>}}}
You can also temporarily //bypass// the redisplay of a saved story ''without disabling the StorySaver cookie'' by including a trailing "#" at the end of the document URL.  This will cause your document to be loaded into the browser without displaying //any// initial tiddlers at all.  Alternatively, you can enter {{{#story:storyname}}} on the end of the URL (e.g., {{{#story:DefaultTiddlers}}}) to display any specific saved story, regardless of the value of the cookie-based saved story.

__''saveStory macro:''__
The {{{<<saveStory>>}}} macro lets you write the list of currently viewed tiddlers to a specified tiddler name (e.g., DefaultTiddlers, MyFavorites, etc.).  Tiddlers containing saved stories are automatically tagged with <<tag story>>, so that they can be recognized by the {{{<<storyViewer>>}}} macro (see [[StoryViewerPlugin]]).  The syntax for the {{{<<saveStory>>}}} macro is:
{{{
<<saveStory storyname label tooltip tag tag tag...>>
}}}
*''storyname''<br>is the target tiddler in which to save the current story.  If you use the keyword, ''ask'', in place of the tiddlername, you will be prompted to enter a tiddler title when saving the story (default: DefaultTiddlers).
*''label'' and ''tooltip''<br>are the link text and mouseover guide-text
*''tag tag tag...'' (optional)<br>are extra tags that are added when saving a story tiddler (in addition to the default<<tag story>>tag).

__''openStory macro:''__
To redisplay a saved story, the {{{<<openStory>>}}} macro can be used to embed either a droplist of all saved stories, or a link for a specified story.  Selecting from the droplist or clicking the link opens the corresponding set of tiddlers.  
{{{
<<openStory list tagValue>>
<<openStory popup label tooltip tagValue>>
<<openStory storyname label tooltip fold>>
}}}
*''list''<br>shows a droplist of all saved stories, plus additional commands/viewing options.  Selecting a story opens the corresponding tiddlers.
*''popup''<br>shows a popup display containing a list of all saved stories, plus additional commands/viewing options.  Selecting a story opens the corresponding tiddlers.  ''label'' and ''tooltip'' are optional and provide alternative display text and mouseover help text, respectively.
*''storyname''<br>is a tiddler containing a saved story.  //Note: You can also use a tag value as a storyname, in which case the story view will be composed of all tiddlers tagged with the specified tag value.//
*''label''<br>is the command link text (default: "open story: %0", where %0 is replaced by the storyname).
*''tooltip''<br>is the command mouseover guide-text (default: "open the set of tiddlers listed in: '%0'"),
*''tagValue'' (optional, default='story')<br>specifies an alternative tag value to match when listing story tiddlers.  Note: if MatchTagsPlugin is installed, you can also use a compound //boolean tag expression//, enclosed within doubled square brackets.
*''fold''<br>If this optional keyword is present, the story tiddlers are initially 'folded' using [[CollapsedTemplate]] instead of the usual [[ViewTemplate]] (see [[CollapseTiddlersPlugin]]).

__''excludeStory tag:''__
Any tiddlers tagged with<<tag excludeStory>>will be automatically omitted when creating new story tiddlers with {{{<<saveStory>>}}}.  Similarly, if a tiddler that is part of a saved story is tagged with<<tag excludeStory>>, it will not be displayed when that story is opened via {{{<<openStory>>}}}.

__''PermaView command link enhancement:''__
In order to further aide in saving/restoring the list of tiddlers currently being viewed, the core {{{<<permaview>>}}} command has been enhanced, so its link value always includes the current story view tiddler list as a paramifier in the URL.  This let you quickly use the browser's right-click menu directly on the permalink command text to "bookmark this link...".  Depending upon your system, you may also be able to drag the 'permaview' link directly from the page and drop it onto your desktop to create an instant permaview-bearing URL shortcut icon.
<<<
!!!!!Examples
<<<
*{{{<<saveStory TestStory "save a test story">>}}}<br>{{smallform{<<saveStory TestStory "save a test story">>}}}
*{{{<<openStory TestStory>>}}}<br><<openStory TestStory>>
*{{{<<openStory list>>}}}<br>{{smallform{<<openStory list>>}}}
*{{{<<openStory popup label tooltip>>}}}<br>{{smallform{<<openStory popup>>}}}
<<<
!!!!!Configuration
<<<
<<option chkSaveStory>> use automatic story cookie (reopens tiddlers on startup)
<<option chkStoryAllowAdd>>include 'add a story' command in droplist/popup
<<option chkStoryFold>>fold story tiddlers when opening a story (see [[CollapseTiddlersPlugin]])
<<option chkStoryClose>>close other tiddlers when opening a story
<<option chkStoryTop>>open story tiddlers at top of column
<<option chkStoryBottom>>open story tiddlers at bottom of column
<<<
!!!!!Revisions
<<<
2009.10.20 1.8.3 fix handling for 'add' item in popup menu
2009.08.29 1.8.2 added 'return false' to all button handlers to fix IE page-transition error
2009.08.23 1.8.1 fixed 'excludeStory' handling for links to missing tiddlers
2009.08.20 1.8.0 added 'excludeStory' tag handling
2009.07.27 1.7.1 corrected test for {{{chkStoryAllowAdd}}} when rendering //list// output
2009.07.27 1.7.0 added options: {{{chkStoryAllowAdd=true}}}, {{{chkStoryTop=true}}}, and {{{chkStoryBottom=false}}}.  Also, autoscroll to first tiddler in story
2009.07.26 1.6.0 added optional 'extratags' param to {{{<<saveStory>>}}} and 'tagfilter' to {{{<<openStory>>}}}
2009.07.06 1.5.1 in setTiddler(), use pushUnique() to avoid double 'story' tag
2009.04.24 1.5.0 added optional 'fold' param to {{{<<openStory StoryName ...>>}}} macro
2008.09.07 1.4.3 added removeCookie() function for compatibility with [[CookieManagerPlugin]]
2008.07.11 1.4.2 in confirmExit(), corrected bracketing for titles containing spaces
2008.03.10 [*.*.*] plugin size reduction: documentation moved to [[StorySaverPluginInfo]]
2008.01.01 1.4.1 sort list of stories alphabetically
2008.01.01 1.4.0 added popup option
2007.12.31 1.3.1 instead of readBracketedList(), use internal tiddler.links[] to retrieve story list from tiddler content. Allows more flexible formatting of story tiddler content: anything content that is not a tiddler link is automatically filtered out of the list.
2007.10.23 1.3.0 split {{{<<storyViewer>>}}} macro definition into stand-alone [[StoryViewerPlugin]] to allow separate installation of story saving vs. story viewing features.
2007.10.21 1.2.0 added {{{<<openStory>>}}} and {{{<<storyViewer>>}}} macros.
2007.10.20 1.1.0 in setTiddler(), automatically add "story" tag to saved story tiddlers
2007.10.18 1.0.1 added default initialization for chkSaveStory option value.  Also, in setTiddler(), call displayTiddler() after saving story to ensure that altered tiddler is shown to the user.
2007.10.05 1.0.0 initial release.   Moved [[SetDefaultTiddlers]] inline script and rewrote as a {{{<<saveStory>>}}} macro.  Moved permaview "mouseover HREF" enhancement from [[CoreTweaks]].
<<<
/*{{{*/

/* Make the main menu fill from the left */
#mainMenu {text-align: left}
#mainMenu ul{margin-left: 0em; padding-left: 0.5em;margin: 0 0;}
#mainMenu h1 {margin-bottom: 0; margin-top: 5px; }

/* insert a scroll bar in the message area if it gets too long say from loadTiddlers output */
#messageArea { max-height:25em; overflow:auto; }

/* custom styles for two parallel columns. Classes cola and colb */
.col2a {width:45%; float:left; margin-left:0.5em;}
.col2b {width:45%; float:left; margin-left:1.5em;}

/* custom syles for three column layout */
.col3a {width:30%; float:left; margin-left:0.5em;}
.col3b {width:30%; float:left; margin-left:1.5em;}
.col3c {width:30%; float:left; margin-left:1.5em;}

/* reset any column style */
.nocol{clear:both;display: block;}

/* used for slides with multicolumn where I don't want unordered list indented
    usually used with col2a/col2b */
.liflushleft ul{margin-left:0em !important;padding-left:0.5em !important;}

/* diagram support styles */
/* borderless tables for diagrams */
.viewer table.diagram, .viewer table.diagram * {
	border: 0;
        margin-left:auto;
        margin-right:auto;
}

/* some resizing of elements: reduce header size and space on main menu headers */
.headerForeground, .headerShadow{padding:2.5em 0 1em 1em} 

/* increase width of annotation plugin popups */
.anno{max-width: 45%;}

@media print {
/* disable the stuff that is useful only online */
  /* opentiddlers index div across top of story */
#openTiddlers {display: none}

  /* remove: last changed by whom, list of tags on tiddler, table of contents,
     openstorybutton controls*/
.subtitle, .tagged, .sectionTOC, .openStoryButton {display: none}

  /* hide certain images when printing. Be nice to the environment with non-content images */
.noprintimage { display: none !important }

 /* hide empty notes when printing. With rouilj's patch to TiddlerNotesPlugin if the notes tiddler
     exists (indicating a non-empty note) the notes box also gets the TiddlerNotesExists class
     which is used to turn on printing for notes with contents while leaving empty notes blocks
     undisplayed. Controls of the box are undisplayed and for printing make the background of the
     notes box go away (transparent). Don't hide the .notes class as that also hides footnotes
     which are supposed to be printed. */
 .TiddlerNotes {display: none; background: transparent; }
 .editNotesButton {display: none}
 .TiddlerNotesExists {display: block}

/* when printing slides with comments use these styles */
div.comment {
 border: 1pt dashed;
 padding: 0.5em;
}

/* putting a box around comment spans doesn't work,
    it boxes every line so change color */
span.comment {
background: #efefef;
}

 /* slideViewTemplate is used for slides which are defined by having the slide tag as the first tag on the tiddler
     so this css rule makes every slide tiddler start on a new page. */

*[template="slideViewTemplate"] {page-break-after: always}

/* try to prevent terms from being orphaned at the bottom of a page */
dt {page-break-after: avoid}

.breakhere {page-break-before:always}
}

/* Put the included style sheet here. If the style sheet doesn't exist and this include
   occurs before the @media print... above, then the print styles are used for video
   display when running IE 8 in IE 7 compatibility mode. */

[[InstructorStyleSheet]]

/*}}}*/
/***
|''Name:''|TableSortingPlugin|
|''Description:''|Dynamically sort tables by clicking on column headers|
|''Author:''|Saq Imtiaz ( lewcid@gmail.com )|
|''Source:''|http://tw.lewcid.org/#TableSortingPlugin|
|''Code Repository:''|http://tw.lewcid.org/svn/plugins|
|''Version:''|2.02|
|''Date:''|25-01-2008|
|''License:''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''~CoreVersion:''|2.2.3|
!!Usage:
* Make sure your table has a header row
** {{{|Name|Phone Number|Address|h}}}<br> Note the /h/ that denote a header row 
* Give the table a class of 'sortable'
** {{{
|sortable|k }}}<br />{{{
|Name|Phone Number|Address|h
}}}<br />Note the /k/ that denotes a class name being assigned to the table.
* To disallow sorting by a column, place {{{<<nosort>>}}} in it's header
* To automatically sort a table by a column, place {{{<<autosort>>}}} in the header for that column
** Or to sort automatically but in reverse order, use {{{<<autosort reverse>>}}}

!!Example:
|sortable|k
|Name |Salary |Extension |Performance |File Size |Start date |h
|ZBloggs, Fred |$12000.00 |1353 |+1.2 |74.2Kb |Aug 19, 2003 21:34:00 |
|ABloggs, Fred |$12000.00 |1353 |1.2 |3350b |09/18/2003 |
|CBloggs, Fred |$12000 |1353 |1.200 |55.2Kb |August 18, 2003 |
|DBloggs, Fred |$12000.00 |1353 |1.2 |2100b |07/18/2003 |
|Bloggs, Fred |$12000.00 |1353 |01.20 |6.156Mb |08/17/2003 05:43 |
|Turvey, Kevin |$191200.00 |2342 |-33 |1b |02/05/1979 |
|Mbogo, Arnold |$32010.12 |2755 |-21.673 |1.2Gb |09/08/1998 |
|Shakespeare, Bill |£122000.00|3211 |6 |33.22Gb |12/11/1961 |
|Shakespeare, Hamlet |£9000 |9005 |-8 |3Gb |01/01/2002 |
|Fitz, Marvin |€3300.30 |5554 |+5 |4Kb |05/22/1995 |

***/
// /%
//!BEGIN-PLUGIN-CODE
config.tableSorting = {
	
	darrow: "\u2193",
	
	uarrow: "\u2191",
	
	getText : function (o) {
		var p = o.cells[SORT_INDEX];
		return p.innerText || p.textContent || '';
	},
	
	sortTable : function (o,rev) {
		SORT_INDEX = o.getAttribute("index");
		var c = config.tableSorting;
		var T = findRelated(o.parentNode,"TABLE");
		if(T.tBodies[0].rows.length<=1) 
			return;
		var itm = "";
		var i = 0;
		while (itm == "" && i < T.tBodies[0].rows.length) {
			itm = c.getText(T.tBodies[0].rows[i]).trim();
			i++;
		}
		if (itm == "") 
			return; 	
		var r = [];
		var S = o.getElementsByTagName("span")[0];		
		c.fn = c.sortAlpha; 
		if(!isNaN(Date.parse(itm)))
			c.fn = c.sortDate; 
		else if(itm.match(/^[$|£|€|\+|\-]{0,1}\d*\.{0,1}\d+$/)) 
			c.fn = c.sortNumber; 
		else if(itm.match(/^\d*\.{0,1}\d+[K|M|G]{0,1}b$/)) 
			c.fn = c.sortFile; 
		for(i=0; i<T.tBodies[0].rows.length; i++) {
			 r[i]=T.tBodies[0].rows[i]; 
		} 
		r.sort(c.reSort);
		if(S.firstChild.nodeValue==c.darrow || rev) {
			r.reverse();
			S.firstChild.nodeValue=c.uarrow;
		} 
		else 
			S.firstChild.nodeValue=c.darrow;
		var thead = T.getElementsByTagName('thead')[0]; 
		var headers = thead.rows[thead.rows.length-1].cells;
		for(var k=0; k<headers.length; k++) {
			if(!hasClass(headers[k],"nosort"))
				addClass(headers[k].getElementsByTagName("span")[0],"hidden");
		}
		removeClass(S,"hidden");
		for(i=0; i<r.length; i++) { 
			T.tBodies[0].appendChild(r[i]);
			c.stripe(r[i],i);
			for(var j=0; j<r[i].cells.length;j++){
				removeClass(r[i].cells[j],"sortedCol");
			}
			addClass(r[i].cells[SORT_INDEX],"sortedCol");
		}
	},
	
	stripe : function (e,i){
		var cl = ["oddRow","evenRow"];
		i&1? cl.reverse() : cl;
		removeClass(e,cl[1]);
		addClass(e,cl[0]);
	},
	
	sortNumber : function(v) {
		var x = parseFloat(this.getText(v).replace(/[^0-9.-]/g,''));
		return isNaN(x)? 0: x;
	},
	
	sortDate : function(v) {
		return Date.parse(this.getText(v));
	},

	sortAlpha : function(v) {
		return this.getText(v).toLowerCase();
	},
	
	sortFile : function(v) { 		
		var j, q = config.messages.sizeTemplates, s = this.getText(v);
		for (var i=0; i<q.length; i++) {
			if ((j = s.toLowerCase().indexOf(q[i].template.replace("%0\u00a0","").toLowerCase())) != -1)
				return q[i].unit * s.substr(0,j);
		}
		return parseFloat(s);
	},
	
	reSort : function(a,b){
		var c = config.tableSorting;
		var aa = c.fn(a);
		var bb = c.fn(b);
		return ((aa==bb)? 0 : ((aa<bb)? -1:1));
	}
};

Story.prototype.tSort_refreshTiddler = Story.prototype.refreshTiddler;
Story.prototype.refreshTiddler = function(title,template,force,customFields,defaultText){
	var elem = this.tSort_refreshTiddler.apply(this,arguments);
	if(elem){
		var tables = elem.getElementsByTagName("TABLE");
		var c = config.tableSorting;
		for(var i=0; i<tables.length; i++){
			if(hasClass(tables[i],"sortable")){
				var x = null, rev, table = tables[i], thead = table.getElementsByTagName('thead')[0], headers = thead.rows[thead.rows.length-1].cells;
				for (var j=0; j<headers.length; j++){
					var h = headers[j];
					if (hasClass(h,"nosort"))
						continue;
					h.setAttribute("index",j);
					h.onclick = function(){c.sortTable(this); return false;};
					h.ondblclick = stopEvent;
					if(h.getElementsByTagName("span").length == 0)
						createTiddlyElement(h,"span",null,"hidden",c.uarrow); 
					if(x==null && hasClass(h,"autosort")) {
						x = j;
						rev = hasClass(h,"reverse");
					}
				}
				if(x!=null)
					c.sortTable(headers[x],rev);		
			}
		}
	}
	return elem; 
};

setStylesheet("table.sortable span.hidden {visibility:hidden;}\n"+
	"table.sortable thead {cursor:pointer;}\n"+
	"table.sortable .nosort {cursor:default;}\n"+
	"table.sortable td.sortedCol {background:#ffc;}","TableSortingPluginStyles");

function stopEvent(e){
	var ev = e? e : window.event;
	ev.cancelBubble = true;
	if (ev.stopPropagation) ev.stopPropagation();
	return false;	
}	

config.macros.nosort={
	handler : function(place){
		addClass(place,"nosort");
	}	
};

config.macros.autosort={
	handler : function(place,m,p,w,pS){
		addClass(place,"autosort"+" "+pS);		
	}	
};
//!END-PLUGIN-CODE
// %/
/***
|Name|TaggedTemplateTweak|
|Source|http://www.TiddlyTools.com/#TaggedTemplateTweak|
|Documentation|http://www.TiddlyTools.com/#TaggedTemplateTweakInfo|
|Version|1.6.1|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides|Story.prototype.chooseTemplateForTiddler()|
|Description|use alternative ViewTemplate/EditTemplate for specific tiddlers|
This plugin extends the core function, story.chooseTemplateForTiddler(), so that any given tiddler can be viewed and/or edited using alternatives to the standard tiddler templates.
!!!!!Documentation
>see [[TaggedTemplateTweakInfo]]
!!!!!Revisions
<<<
2009.09.02 [1.6.1] apply field-based template (if any) *before* tag-based template
| please see [[TaggedTemplateTweakInfo]] for previous revision details |
2007.06.11 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.TaggedTemplateTweak= {major: 1, minor: 6, revision: 1, date: new Date(2009,9,2)};

if (!config.options.txtTemplateTweakFieldname)	
	config.options.txtTemplateTweakFieldname='template';

Story.prototype.taggedTemplate_chooseTemplateForTiddler = Story.prototype.chooseTemplateForTiddler
Story.prototype.chooseTemplateForTiddler = function(title,template)
{
	// get core template and split into theme and template name
	var coreTemplate=this.taggedTemplate_chooseTemplateForTiddler.apply(this,arguments);
	var theme=""; var template=coreTemplate;
	var parts=template.split(config.textPrimitives.sectionSeparator);
	if (parts[1]) { theme=parts[0]; template=parts[1]; }
	else theme=config.options.txtTheme||""; // if theme is not specified
	theme+=config.textPrimitives.sectionSeparator;

	// look for template using title as prefix
	if (!store.getTaggedTiddlers(title).length) { // if tiddler is not a tag
		if (store.getTiddlerText(theme+title+template))
			{ return theme+title+template; } // theme##TitleTemplate
		if (store.getTiddlerText(title+template))
			{ return title+template; }	 // TitleTemplate
	}

	// look for templates using custom field value as prefix
	var v=store.getValue(title,config.options.txtTemplateTweakFieldname);
	if (store.getTiddlerText(theme+v+template))
		{ return theme+v+template; }	// theme##valueTemplate
	if (store.getTiddlerText(v+template))
		{ return v+template; }		// valueTemplate

	// look for template using tags as prefix
	var tiddler=store.getTiddler(title);
	if (!tiddler) return coreTemplate; // tiddler doesn't exist... use core result
	for (i=0; i<tiddler.tags.length; i++) {
		var t=tiddler.tags[i]+template; // add tag prefix to template
		var c=t.substr(0,1).toUpperCase()+t.substr(1); // capitalized for WikiWord title
		if (store.getTiddlerText(theme+t))	{ return theme+t; } // theme##tagTemplate
		if (store.getTiddlerText(theme+c))	{ return theme+c; } // theme##TagTemplate
		if (store.getTiddlerText(t)) 		{ return t; }	    // tagTemplate
		if (store.getTiddlerText(c))		{ return c; }	    // TagTemplate
	}
	
	// no match... use core result
	return coreTemplate;
}
//}}}
/***
|Name|TaggedTemplateTweakInfo|
|Source|http://www.TiddlyTools.com/#TaggedTemplateTweak|
|Documentation|http://www.TiddlyTools.com/#TaggedTemplateTweakInfo|
|Version|1.6.1|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|documentation|
|Requires||
|Overrides||
|Description|Documentation for TaggedTemplateTweak|
This plugin extends the core function, story.chooseTemplateForTiddler(), so that any given tiddler can be viewed and/or edited using alternatives to the standard tiddler templates.  To select alternative templates, a 'template prefix' is determined by using the tiddler's title or matching a tag value or using a value stored in a custom tiddler field.  
!!!!!Usage
<<<
The plugin first attempts to use the tiddler's //title// as a prefix added to the standard TiddlyWiki template titles, [[ViewTemplate]] and [[EditTemplate]] (i.e., ''TiddlerNameViewTemplate'' and ''TiddlerNameEditTemplate'').  This allows you to associate a custom template with a specific tiddler, without needing to add any special tags or custom field values to that individual tiddler.  

You can also define a tiddler's template prefix by using a //custom tiddler field// named 'template'.  If no corresponding template was found using the tiddler's title, then the tiddler's 'template' field value, if present, will be used as a prefix (e.g., if template='SomeThing', then [[SomeThingViewTemplate]] will be applied).
*You can redefine the //name// of the custom field used to store the template prefix.  For example, to use the name of a TiddlyWeb server-side 'bag' as a prefix (so that tiddlers from separate bags can have different appearances), add the following to a tiddler tagged with<<tag systemConfig>>:

If no template is found using the either the title or 'template' field, then each of the tiddler's tags is tried as a template prefix, until a corresponding template, if any, is found.  For example, any tiddlers that are tagged with ''<<tag media>>'' could find alternative templates named [[mediaViewTemplate]] and [[mediaEditTemplate]].
*To permit use of templates that have proper WikiWord tiddler titles (e.g., [[MediaViewTemplate]] and [[MediaEditTemplate]]), the plugin also attempts to use a capitalized form of the tag value (e.g., ''Media'') as a prefix.  //This capitalization is for comparison purposes only and will not alter the actual tag values that are stored in the tiddler.//
*If you are applying a systemTheme definition, the plugin also tries prepending the currently selected theme (specified by {{{config.options.txtTheme}}}) plus the 'section separator' (##) to the template name (e.g. ''[[SomeTheme##MediaViewTemplate]]'') so that the alternative template definitions can be contained as //sections// within a single systemTheme tiddler.
{{{
config.options.txtTemplateTweakFieldname='server.bag'; // use TiddlyWeb bag name as prefix
}}}
Lastly, if no alternative template is found at all, the standard [[ViewTemplate]] or [[EditTemplate]] definition as determined by the TiddlyWiki core handler is used.

''To add your own custom templates:''
>First, decide upon a suitable tag keyword to uniquely identify your custom templates and create custom view and/or edit templates using that keyword as a prefix (e.g., "KeywordViewTemplate" and "KeywordEditTemplate").  Then, simply create a tiddler and tag it with your chosen keyword... that's it!  As long as the tiddler is tagged with your keyword, it will be displayed using the corresponding alternative templates.  If you remove the tag or rename/delete the alternative templates, the tiddler will revert to using the standard viewing and editing templates.
<<<
!!!!!Examples
<<<
|Sample tiddler| tag | view template | edit template |
|[[MediaSample - QuickTime]]| <<tag media>> | [[MediaViewTemplate]] | [[MediaEditTemplate]] |
|[[MediaSample - Windows]]| <<tag media>> | [[MediaViewTemplate]] | [[MediaEditTemplate]] |
|[[CDSample]]| <<tag CD>> | [[CDViewTemplate]] | [[CDEditTemplate]] |
|<<newTiddler label:"create new task..." title:SampleTask tag:task text:"Type some text and then press DONE to view the task controls">> | <<tag task>> | [[TaskViewTemplate]] | [[EditTemplate]] |

//(note: if these samples are not present in your document, please visit// http://www.TiddlyTools.com/ //to view these sample tiddlers on-line)//
<<<
!!!!!Revisions
<<<
2009.09.02 [1.6.1] apply field-based template (if any) *before* tag-based template
2009.07.31 [1.6.0] added support for using custom field value as prefix
2009.05.04 [1.5.2] check for tiddler exist *after* title-as-prefix (allows shadow tiddlers to use custom templates)
2009.01.06 [1.5.1] reversed logic so that title-as-prefix takes precedence over tag-matched prefix
2008.12.18 [1.5.0] added handling for using tiddler //title// as prefix (e.g., {{{SomeTiddlerViewTemplate}}}) 
2008.08.29 [1.4.1] corrected handling for tiddlers with no matching tagged template when non-default theme is in effect (e.g., use "MyTheme##ViewTemplate").
2008.05.15 [1.4.0] support use of *shadow* tagged templates (e.g., [[DiscussionViewTemplate]] created by [[DiscussionPlugin]])
2008.05.10 [1.3.0] corrected handling for determining core template when using theme with sections
2008.05.01 [1.2.5] added support for tagged templates stored as sections in a theme
2008.04.01 [1.2.0] added support for using systemTheme section-based template definitions (requested by Phil Hawksworth)
2008.01.22 [*.*.*] plugin size reduction - documentation moved to [[TaggedTemplateTweakInfo]]
2007.06.23 [1.1.0] re-written to use automatic 'tag prefix' search instead of hard coded check for each tag.  Allows new custom tags to be used without requiring code changes to this plugin.
2007.06.11 [1.0.0] initial release
<<<
/***
|Name|TemporaryTiddlersPlugin|
|Source|http://www.TiddlyTools.com/#TemporaryTiddlersPlugin|
|Version|1.1.2|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides|SaverBase.prototype.externalize()|
|Options|##Configuration|
|Description|blocks tiddlers tagged with "temporary" from being saved into the TW file|
!!!!!Usage
<<<
When the TW document is saved (either to local disk or remote URL), any tiddlers tagged with "temporary" will be skipped over, so that they are not written to the file.  To keep a temporary tiddler, simply edit it and remove the tag before saving the file.  This feature can be combined with various plugins that can automatically create new tiddlers, such as [[SearchOptionsPlugin]] ([[SearchResults]]) and [[ImportTiddlersPlugin]] ([[ImportedTiddlers]]) so that these transient results are not retained when you save you document.

You can also use this tag with the {{{<<loadTiddlers>>}}} macro and the //auto-tagging// features provided by [[ImportTiddlersPlugin]], so that each time you open your document, you can automatically retrieve an up-to-date set of common tiddlers that are stored in another document (either local or via remote URL), without those tiddlers being retained when you save your document.
<<<
!!!!!Configuration
<<<
When saving the document:
<<option chkTemporaryQuiet>> Suppress reporting of individual temporary tiddlers that have not been saved
<<option chkTemporaryKeep>> Keep temporary tiddlers (i.e., ignore the 'temporary' tag)
Enter a tag value to use when marking tiddlers as temporary: <<option txtTemporaryTag>>
<<<
!!!!!Revisions
<<<
2008.11.14 [1.1.2] added "nnn temporary tiddlers not saved" summary message
2008.04.08 [1.1.1] don't automatically add configuration options to AdvancedOptions tiddler
2008.03.01 [1.1.0] added support for recognizing 'temporary' flag stored as a tiddler *field* (as an optional alternative to using a tag)
2007.02.08 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.TemporaryTiddlersPlugin= {major: 1, minor: 1, revision: 2, date: new Date(2008,11,14)};

// configuration defaults
if (config.options.chkTemporaryKeep ==undefined) config.options.chkTemporaryKeep =false;
if (config.options.chkTemporaryQuiet==undefined) config.options.chkTemporaryQuiet=true;
if (config.options.txtTemporaryTag==undefined) config.options.txtTemporaryTag="temporary";
// lingo
config.messages.TemporaryWarning = "'%0' ...temporary tiddler";
config.messages.TemporarySummary = "%0 temporary tiddlers will not be saved";
// core override
SaverBase.prototype.externalize = function(store) 
{
	var results=[]; var totaltemps=0;
	var tiddlers=store.getTiddlers("title");
	for (var t=0; t<tiddlers.length; t++) {
		if (config.options.chkTemporaryKeep||!(tiddlers[t].fields['temporary']||tiddlers[t].isTagged(config.options.txtTemporaryTag)))
			results.push(this.externalizeTiddler(store, tiddlers[t]));
		else {
			if (!config.options.chkTemporaryQuiet) // notify user that tiddler won't be saved
				displayMessage(config.messages.TemporaryWarning.format([tiddlers[t].title]));
			totaltemps++;
		}
	}
	if (totaltemps) displayMessage(config.messages.TemporarySummary.format([totaltemps]));
	return results.join("\n");
}
//}}}
Written in Java (uses 1.5 or 1.6).

Main web site: http://freemind.sourceforge.net/wiki/index.php/Main_Page

Current release 0.9.0rc6.
<<tiddler Welcome/tiddlerclass >>
/***
|''Name:''|TiddlerNotesPlugin|
|''Description:''|Add notes to tiddlers without modifying the original content|
|''Author:''|Saq Imtiaz ( lewcid@gmail.com )|
|''Source:''|http://tw.lewcid.org/#TiddlerNotesPlugin|
|''Code Repository:''|http://tw.lewcid.org/svn/plugins|
|''Version:''|2.1|
|''Date:''|26/10/07|
|''License:''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''~CoreVersion:''|2.2.3|

!!Concept:
*The TiddlerNotesPlugin allows you to add notes to tiddlers, without needing to edit the original tiddler. This means that your original content will remain unaltered, and if you update it in the future, you won’t lose your notes. Notes are stored in separate tiddlers, but can be viewed and edited from within the original tiddler.
*For a tiddler titled "~MySlide", the notes are by default saved in a tiddler titled "~MySlide-Notes" and is given a tag of "Notes". The suffix and tags of the notes tiddlers are customizable. You can have one or multiple notes per tiddlers. So it is possible to have for example, teacher's notes and student's notes in the same file.
*Notes can be configured to start off blank, or pre-filled with the contents of the original tiddler.

!!Usage:
*{{{<<notes>>}}} is the simplest usage form.
* additional optional parameters include:
**{{{heading:}}} the heading to use for the notes box
**{{{tag:}}} the tag to be given to the notes tiddler
**{{{suffix:}}} the suffix to be used when naming the notes tiddler
* a full macro call could look like: {{{<<notes heading:"My Notes" tag:"NoteTiddlers" suffix:"Comments">>}}}
* To avoid adding {{{<<notes>>}}} to each tiddler you want notes for, you could add the macro call to the ViewTemplate
** below the line {{{<div class='viewer' macro='view text wikified'></div>}}} add the following line: <br> {{{<div class='viewer' macro='notes'></div>}}}
** Used in combination with the ~HideWhenPlugin or ~PublisherPlugin, you could have notes be shown only for tiddlers with specific tags. The ~PublisherPlugin would allow you for instance to only have the ~TeachersNotes visible to the teacher, and the ~StudentsNotes for the same tiddler visible to the Student.

!!Configuration
*<<option chkPrefillNotes>> Enable to pre-fill notes with the original tiddler's contents

!!Demo:
* [[MySlide]]

***/
// /%
//!BEGIN-PLUGIN-CODE

if (!config.options.chkPrefillNotes)
	config.options.chkPrefillNotes = false;
	
function createTiddlyElement(theParent,theElement,theID,theClass,theText,attribs)
{
	var e = document.createElement(theElement);
	if(theClass != null)
		e.className = theClass;
	if(theID != null)
		e.setAttribute("id",theID);
	if(theText != null)
		e.appendChild(document.createTextNode(theText));
	if(attribs){
		for(var n in attribs){
			e.setAttribute(n,attribs[n]);
		}
	}
	if(theParent != null)
		theParent.appendChild(e);
	return e;
}

function createTiddlyButton(theParent,theText,theTooltip,theAction,theClass,theId,theAccessKey,attribs)
{
	var theButton = document.createElement("a");
	if(theAction) {
		theButton.onclick = theAction;
		theButton.setAttribute("href","javascript:;");
	}
	if(theTooltip)
		theButton.setAttribute("title",theTooltip);
	if(theText)
		theButton.appendChild(document.createTextNode(theText));
	if(theClass)
		theButton.className = theClass;
	else
		theButton.className = "button";
	if(theId)
		theButton.id = theId;
	if(attribs){
		for(var n in attribs){
			theButton.setAttribute(n,attribs[n]);
		}
	}
	if(theParent)
		theParent.appendChild(theButton);
	if(theAccessKey)
		theButton.setAttribute("accessKey",theAccessKey);
	return theButton;
}

config.macros.notes={
	
	cancelWarning: "Are you sure you want to abandon changes to your notes for '%0'?",
	editLabel: "edit notes",
	editTitle: "double click to edit",
	saveLabel: "save notes",
	saveTitle: "double click to save",
	cancelLabel: "cancel",
	heading: "Notes",
	suffix: "Notes",
	tag: "Notes",
	
	saveNotes: function(ev){
		e = ev? ev : window.event;
		var theTarget = resolveTarget(e);
		if (theTarget.nodeName.toLowerCase() == "textarea")
			return false;
		var title = story.findContainingTiddler(theTarget).getAttribute("tiddler");
		story.setDirty(title,false);
		var box = document.getElementById("notesContainer"+title);
		var textarea = document.getElementById("notesTextArea"+title);
		if(textarea.getAttribute("oldText")!=textarea.value && !hasClass(theTarget,"cancelNotesButton")){
			var suffix = box.getAttribute("suffix");
			var t = store.getTiddler(title+"-"+suffix);
			store.saveTiddler(title+"-"+suffix,title+"-"+suffix,textarea.value,config.options.txtUserName,new Date(),t?t.tags:box.getAttribute("tag"),t?t.fields:{});
		}
		story.refreshTiddler(title,1,true);
		autoSaveChanges(true);
		return false;
	},
	
	editNotes: function(box,tiddler){
		removeChildren(box);
		story.setDirty(tiddler,true);
		box.title = this.saveTitle;
		box.ondblclick = this.saveNotes;
		createTiddlyButton(box,this.cancelLabel,this.cancelLabel,this.saveNotes,"cancelNotesButton");
		createTiddlyButton(box,this.saveLabel,this.saveLabel,this.saveNotes,"saveNotesButton");
		wikify("!!"+box.getAttribute("heading")+"\n",box);
		addClass(box,"editor");
		var wrapper1 = createTiddlyElement(null,"fieldset",null,"fieldsetFix");
		var wrapper2 = createTiddlyElement(wrapper1,"div");
		var e = createTiddlyElement(wrapper2,"textarea","notesTextArea"+tiddler);
		var v = store.getValue(tiddler+"-"+box.getAttribute("suffix"),"text");
		if(!v) 
			v = config.options.chkPrefillNotes? store.getValue(tiddler,"text"):'';
		e.value = v;
		e.setAttribute("oldText",v);
		var rows = 10;
		var lines = v.match(/\n/mg);
		var maxLines = Math.max(parseInt(config.options.txtMaxEditRows),5);
		if(lines != null && lines.length > rows)
			rows = lines.length + 5;
		rows = Math.min(rows,maxLines);
		e.setAttribute("rows",rows);
		box.appendChild(wrapper1);
	},
	
	editNotesButtonOnclick: function(e){
		var title = story.findContainingTiddler(this).getAttribute("tiddler");
		var box = document.getElementById("notesContainer"+title);
		config.macros.notes.editNotes(box,title);
		return false;
	},
	
	ondblclick : function(ev){
		e = ev? ev : window.event;
		var theTarget = resolveTarget(e);
		var title = story.findContainingTiddler(theTarget).getAttribute("tiddler");
		var box = document.getElementById("notesContainer"+title);
		config.macros.notes.editNotes(box,title);
		e.cancelBubble = true;
		if(e.stopPropagation) e.stopPropagation();
		return false;
	},
	
	handler : function(place,macroName,params,wikifier,paramString,tiddler){
		
		params = paramString.parseParams("anon",null,true,false,false);
		var heading = getParam(params,"heading",this.heading);
		var tag = getParam(params,"tag",this.tag);
		var suffix = getParam(params,"suffix",this.suffix);
                // rouilj add a class for notes that have contents in a tiddler.
                var notesTiddlerExists = store.tiddlerExists(tiddler.title+"-"+suffix);
		var box = createTiddlyElement(place,"div","notesContainer"+tiddler.title,"TiddlerNotes"  + (notesTiddlerExists?" TiddlerNotesExists":""),null,{"source":tiddler.title,params:paramString,heading:heading,tag:tag,suffix:suffix});
		// var box = createTiddlyElement(place,"div","notesContainer"+tiddler.title,"TiddlerNotes",null,{"source":tiddler.title,params:paramString,heading:heading,tag:tag,suffix:suffix});
		createTiddlyButton(box,this.editLabel,this.editLabel,this.editNotesButtonOnclick,"editNotesButton");
		wikify("!!"+heading+"\n",box);
		box.title=this.editTitle;
		box.ondblclick = this.ondblclick;
		wikify("<<tiddler [["+tiddler.title+"-"+suffix+"]]>>",box);
	}		
};

Story.prototype.old_notes_closeTiddler = Story.prototype.closeTiddler;
Story.prototype.closeTiddler = function(title,animate,unused){
	if(story.isDirty(title)) {
            if(!confirm(config.macros.notes.cancelWarning.format([title])))
    		    return false;
         }
	return this.old_notes_closeTiddler.apply(this,arguments);
}

setStylesheet(".TiddlerNotes {\n"+ " background:#eee;\n"+ " border:1px solid #ccc;\n"+ " padding:10px;\n"+ " margin:15px;\n"+ "}\n"+ "\n"+ ".cancelNotesButton,.editNotesButton, .saveNotesButton {\n"+ " float:right;\n"+ " border:1px solid #ccc;\n"+ " padding:2px 5px;\n"+ "}\n"+ "\n"+ ".saveNotesButton{\n"+ " margin-right:0.5em;\n"+ "}\n"+ "\n"+ ".TiddlerNotes.editor textarea{\n"+ " border:1px solid #ccc;\n"+ "}","NotesPluginStyles");
//!END-PLUGIN-CODE
// %/
/***
|Name|TiddlyLockPlugin|
|Source|http://www.minormania.com/tiddlylock/tiddlylock.html|
|Version|1.0.4|
|TiddlyWiki Core Version|2.2.4|
|Author|Richard Hobbis|
|License|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|Type|plugin|
|Overrides|config.macros.newTiddler.onClickNewTiddler()<br />config.commands.cancelTiddler.handler()<br />config.commands.deleteTiddler.handler<br />config.commands.editTiddler.handler()<br />config.commands.saveTiddler.handler()<br />saveChanges()<br />checkUnsavedChanges()|
|Description|Automatically locks and unlocks the TiddlyWiki as required, allowing multiple users to edit the TiddlyWiki without fear of overwriting other users' changes.|
!!!Usage
<<<
Simply import TiddlyLockPlugin into your TiddlyWiki!
<<<
!!!Installation
<<<
Import (or copy/paste) ''this tiddler'' into your TiddlyWiki and make sure it's tagged with <<tag systemConfig>>. Reload your TiddlyWiki to enable TiddlyLock.
<<<
!!!Configuration
<<<
None required!
<<<
!!!Revision History
<<<
''2007.06.22 [1.0.4]'' Added locking on 'new tiddler' which also traps 'new journal'. Tweaked messages.
''2007.06.20 [1.0.3]'' Fixed an issue that occurred when a user navigated away from the TiddlyWiki without saving outstanding changes.
''2007.05.10 [1.0.2]'' Implemented a timestamp to track the last update time. This fixes the multi-browser edit issue and also removes the need for a password.
''2007.05.08 [1.0.1]'' Function overrides are now done using apply() ensuring clean upgrades (thanks Martin!)
''2007.05.01 [1.0.0]'' Initial Release
<<<
!!!Known Issues
<<<
*Monkey Pirate TiddlyWiki (MPTW) adds a ''disable'' button to the toolbar for systemConfig tiddlers. This button is available even when the TW is marked as readOnly and therefore it's possible for two users to disable/enable plugins at the same time. In this case, whoever saves the TW last will 'win' and their changes will be saved. Note that this is only an issue if there are no other unsaved changes in both browsers - TiddlyLock still handles all other changes.
<<<
!!!Credits
<<<
This feature was developed by Richard Hobbis (rhobbis [at] hotmail [dot] com).
<<<
!!!Code
***/

//{{{
// Convert a date to UTC YYYYMMDDHHMMSSMMM string format
// This is the same as the builtin function convertToYYYYMMDDHHMMSSMMM() but
// without the '.' in the middle - this allows simple date comparisons
Date.prototype.TLConvertToYYYYMMDDHHMMSSMMM = function()
{
  return(String.zeroPad(this.getUTCFullYear(),4)
    + String.zeroPad(this.getUTCMonth()+1,2)
    + String.zeroPad(this.getUTCDate(),2)
    + String.zeroPad(this.getUTCHours(),2)
    + String.zeroPad(this.getUTCMinutes(),2)
    + String.zeroPad(this.getUTCSeconds(),2)
    + String.zeroPad(this.getUTCMilliseconds(),4));
}

// namespace for TiddlyLock
TiddlyLock = {};

// Load/Last Update timestamp
TiddlyLock.TimeStamp = new Date().TLConvertToYYYYMMDDHHMMSSMMM();

// Lockfile
TiddlyLock.LockPath = '';
TiddlyLock.OldLockData = '';
TiddlyLock.LockData = '';
TiddlyLock.NotifyDisabled = 0;

// define messages
TiddlyLock.Msg = {
  Locked: 'File locked',
  Unlocked: 'File unlocked',
  LockFailed: 'Failed to lock file',
  UnlockFailed: 'Failed to unlock file',
  ReadOnly: 'Now in Read-Only mode.',
  Changed: 'This file has been changed by someone else.',
  Reload: 'Reload this file before editing.',
  Disabled: 'TiddlyLock does not work with Safari. You should disable the plugin from the backstage menu.'};

// create/update the lock file
function TLSave(timeStamp,lockedBy)
{
  var lockedText='';
  if (lockedBy!='')
  {
    lockedText=timeStamp+'##'+lockedBy;
  }
  else lockedText=timeStamp+'##';
    var lockSave=saveFile(TiddlyLock.LockPath,lockedText);
  TiddlyLock.TimeStamp = timeStamp;
  return false;
}


// Create/update the lock file to prevent other users from editing the TW
function TLLock()
{
  clearMessage();
  lockSave = TLSave(new Date().TLConvertToYYYYMMDDHHMMSSMMM(),config.options.txtUserName);
  displayMessage(TiddlyLock.Msg.Locked,'');
  return false;
}


// Clear the lock file if necessary, but only if I have it locked, setting the
// timestamp in the lockfile to the specified value
function TLUnlock(timeStamp)
{
  if ((store && store.isDirty && !store.isDirty())
    && (story && story.areAnyDirty && !story.areAnyDirty())
    && TLIsLocked()
    && TLIsLockedByMe())
  {
    lockSave=TLSave(timeStamp,'','');
    displayMessage(TiddlyLock.Msg.Unlocked,'');
    TiddlyLock.OldLockData = TiddlyLock.LockData;
  }
  return false;
}

// Get the contents of the lock file, if it exists
function TLLockPath()
{
  var lockPath,p;
  var originalPath=document.location.toString();
  var localPath=getLocalPath(originalPath);
  if((p=localPath.lastIndexOf('.')) != -1)
    lockPath=localPath.substr(0,p) + '.lck';
  else lockPath=localPath + '.lck';
    return lockPath;
}


// Get the contents of the lock file, if it exists
function TLLockData()
{
  TiddlyLock.LockPath = TLLockPath();
  return loadFile(TiddlyLock.LockPath);
}

// Get the contents of the lock file, if it exists
function TLIsLocked()
{
  TiddlyLock.LockData = TLLockData();
  if (TiddlyLock.LockData
      && ( TLLockedBy(TiddlyLock.LockData)!='' // someone has it locked
         || TiddlyLock.TimeStamp < TLLockedTimeStamp(TiddlyLock.LockData) // changed by someone else but not currently locked
         )
     )
    return true;
  else
    return false;
}


// check if locked by me
function TLIsLockedByMe()
{
  if(TiddlyLock.LockData == TiddlyLock.TimeStamp+'##' + config.options.txtUserName)
    return true;
  else
    return false;
}


// returns just the timestamp portion of the supplied lock file contents
function TLLockedTimeStamp(lockData)
{
  if(lockData)
    return lockData.split('##')[0];
  else
    return '';
}


// returns just the username portion of the supplied lock file contents
function TLLockedBy(lockData)
{
  if(lockData)
    return lockData.split('##')[1];
  else
    return '';
}

// display a message if locked or changed
function TLChangesAllowed()
{
  // Under safari tiddlylock doesn't work. Report that and permit
  // saving

  if ( config.browser.isSafari  ) {
    if ( ! TiddlyLock.NotifyDisabled ) {
      alert(TiddlyLock.Msg.Disabled);
      TiddlyLock.NotifyDisabled = 1;
    }
    return true;
  }

  if(TLIsLocked() && !TLIsLockedByMe())
  {
//    if(!readOnly)
    {
      readOnly=true;
      if(TLLockedBy(TiddlyLock.LockData))
      {
        displayMessage(TiddlyLock.Msg.Locked+' by '+TLLockedBy(TiddlyLock.LockData));
        alert(TiddlyLock.Msg.Locked+' by '+TLLockedBy(TiddlyLock.LockData)+'. '+TiddlyLock.Msg.ReadOnly);
      }
      else
      {
        displayMessage(TiddlyLock.Msg.Changed+' '+TiddlyLock.Msg.Reload);
        alert(TiddlyLock.Msg.Changed+' '+TiddlyLock.Msg.Reload);
      }
    }
    return false;
  }
  else
    return true;
}


//*********************************************
// OVERRIDE STANDARD FUNCTIONS
//*********************************************

//
// OVERRIDE onClickNewTiddler()
//
TiddlyLock.onClickNewTiddler = config.macros.newTiddler.onClickNewTiddler;
config.macros.newTiddler.onClickNewTiddler = function(event,src,title)
{
  if (TLChangesAllowed())
  {
    TiddlyLock.OldLockData = TiddlyLock.LockData;
    TLLock();
    var ret = TiddlyLock.onClickNewTiddler.apply(this,arguments);
    return ret;
  }
}

//
// OVERRIDE checkUnsavedChanges()
//
TiddlyLock.checkUnsavedChanges = checkUnsavedChanges;
checkUnsavedChanges = function(event,src,title)
{
  var ret = TiddlyLock.checkUnsavedChanges.apply(this,arguments);
  if(TLIsLocked() && TLIsLockedByMe())
    lockSave=TLSave(TLLockedTimeStamp(TiddlyLock.OldLockData),'','');
  return ret;
}


//
// OVERRIDE cancelTiddler()
//
TiddlyLock.cancelTiddler = config.commands.cancelTiddler.handler;
config.commands.cancelTiddler.handler = function(event,src,title)
{
  var ret = TiddlyLock.cancelTiddler.apply(this,arguments);
  TLUnlock(TLLockedTimeStamp(TiddlyLock.OldLockData));
  return ret;
}

//
// OVERRIDE deleteTiddler()
//
TiddlyLock.deleteTiddler = config.commands.deleteTiddler.handler;
config.commands.deleteTiddler.handler = function(event,src,title)
{
  if (TLChangesAllowed())
  {
    TiddlyLock.OldLockData = TiddlyLock.LockData;
    TLLock();
    var ret = TiddlyLock.deleteTiddler.apply(this,arguments);
    return ret;
  }
}

//
// OVERRIDE editTiddler()
//
TiddlyLock.editTiddler = config.commands.editTiddler.handler;
config.commands.editTiddler.handler = function(event,src,title)
{
  if (TLChangesAllowed())
  {
    TiddlyLock.OldLockData = TiddlyLock.LockData;
    TLLock();
  }
  var ret = TiddlyLock.editTiddler.apply(this,arguments);
  return ret;
}

//
// OVERRIDE saveChanges()
//
TiddlyLock.saveChanges = saveChanges;
saveChanges = function(onlyIfDirty)
{
  if(TLChangesAllowed())
  {
    var ret = TiddlyLock.saveChanges.apply(this,arguments);
    TLUnlock(new Date().TLConvertToYYYYMMDDHHMMSSMMM());
    return ret;
  }
  else
    return false;
}

//
// OVERRIDE saveTiddler()
//
TiddlyLock.saveTiddler= config.commands.saveTiddler.handler;
config.commands.saveTiddler.handler=function(event,src,title)
{
  var ret = TiddlyLock.saveTiddler.apply(this,arguments);
  TLUnlock(new Date().TLConvertToYYYYMMDDHHMMSSMMM());
  return ret;
}

//}}}
TiddlySnip is a plugin for Firefox that allows you to cut and paste info into a ~TiddlyWiki to create a new //tiddler//. The home page is: http://tiddlysnip.com/#About

It competes with tools like Zotero, Google Notebook Bookmarklet, ~OneNote Firefox Extention for web research and annotation.
<html>
<hide linebreaks>
<ul>
<li class="overlay1">Bookmarks on steriods </li>
<li class="overlay2">Allows you to cut and past example text as well as just links.</li>
<li class="overlay3">Allows you to tag the content to allow it to be found more easily</li>
<li class="overlay4">Can clip text from the windows clipboard</li>
<li class="overlay5">Uses a TiddlyWiki as it's storage location so it's portable, accessible and searchable</li>
</ul>
</html>
There are a few disadvantages:
<html>
<hide linebreaks>
<ul>
<li>It is now community supported as the author isn't that interested in it anymore</li>
<li>Download the xpi from http://groups.google.com/group/tiddlysnip</li>
<li>The packaged version may need a little TLC to work with Firefox version greater than 3.5.</li>
</ul>
</html>
See http://www.tiddlywiki.com for a tiddlywiki.
The main web site and wiki/trac is at http://www.tiddlywiki.org.
[[What is TiddlyWiki]]
[[TiddlySnip]]
[[Demo]]
[[TiddlySnip Advantages]]
[[TiddlySnip Disadvantages]]
[[Other Tiddly Things]]
[[For the Getting Things Done Crowd]]
/***

|Name|ToggleSideBarMacro|
|Created by|SaqImtiaz|
|Location|http://tw.lewcid.org/#ToggleSideBarMacro|
|Version|1.0|
|Requires|~TW2.x|
!Description:
Provides a button for toggling visibility of the SideBar. You can choose whether the SideBar should initially be hidden or displayed.

!Demo
<<toggleSideBar "Toggle Sidebar">>

!Usage:
{{{<<toggleSideBar>>}}} <<toggleSideBar>>
additional options:
{{{<<toggleSideBar label tooltip show/hide>>}}} where:
label = custom label for the button,
tooltip = custom tooltip for the button,
show/hide = use one or the other, determines whether the sidebar is shown at first or not.
(default is to show the sidebar)

You can add it to your tiddler toolbar, your MainMenu, or where you like really.
If you are using a horizontal MainMenu and want the button to be right aligned, put the following in your StyleSheet:
{{{ .HideSideBarButton {float:right;} }}}

!History
*23-07-06: version 1.0: completely rewritten, now works with custom stylesheets too, and easier to customize start behaviour. 
*20-07-06: version 0.11
*27-04-06: version 0.1: working.

!Code
***/
//{{{
config.macros.toggleSideBar={};

config.macros.toggleSideBar.settings={
         styleHide :  "#sidebar { display: none;}\n"+"#contentWrapper #displayArea { margin-right: 1em;}\n"+"",
         styleShow : " ",
         arrow1: "«",
         arrow2: "»"
};

config.macros.toggleSideBar.handler=function (place,macroName,params,wikifier,paramString,tiddler)
{
          var tooltip= params[1]||'toggle sidebar';
          var mode = (params[2] && params[2]=="hide")? "hide":"show";
          var arrow = (mode == "hide")? this.settings.arrow1:this.settings.arrow2;
          var label= (params[0]&&params[0]!='.')?params[0]+" "+arrow:arrow;
          var theBtn = createTiddlyButton(place,label,tooltip,this.onToggleSideBar,"button HideSideBarButton");
          if (mode == "hide")
             { 
             (document.getElementById("sidebar")).setAttribute("toggle","hide");
              setStylesheet(this.settings.styleHide,"ToggleSideBarStyles");
             }
};

config.macros.toggleSideBar.onToggleSideBar = function(){
          var sidebar = document.getElementById("sidebar");
          var settings = config.macros.toggleSideBar.settings;
          if (sidebar.getAttribute("toggle")=='hide')
             {
              setStylesheet(settings.styleShow,"ToggleSideBarStyles");
              sidebar.setAttribute("toggle","show");
              this.firstChild.data= (this.firstChild.data).replace(settings.arrow1,settings.arrow2);
              }
          else
              {    
               setStylesheet(settings.styleHide,"ToggleSideBarStyles");
               sidebar.setAttribute("toggle","hide");
               this.firstChild.data= (this.firstChild.data).replace(settings.arrow2,settings.arrow1);
              }

     return false;
}

setStylesheet(".HideSideBarButton .button {font-weight:bold; padding: 0 5px;}\n","ToggleSideBarButtonStyles");

//}}}
The tools in alphabetic order:

''elog'' - electronic log book home page: https://midas.psi.ch/elog

''filepp'' - file pre processor home page: http://www.cabaret.demon.co.uk/filepp/

''freemind'' - mindmapping software home page: http://freemind.sourceforge.net/wiki/index.php/Main_Page

''plod'' - personal logging device (enhanced version) home page:  http://www.cs.umb.edu/~rouilj/#plod

''tiddlysnip'' - firefox addon for clipping web pages to a tiddlywiki, download page: http://groups.google.com/group/tiddlysnip. Home page http://tiddlysnip.com/#About.

Tiddlywiki verticals:
* TWAB - http://www.tiddly-twab.com/ - ~TiddlyWIki Address Book
* ~MediaWiki unplugged - http://mediawikiunplugged.com/ - take your mediawiki with you
* ~Team Tasks - http://getteamtasks.com/ - a task management tool
* ~NoteStorm - http://www.giffmex.org/NoteStorm.html - an astonishingly simple way to take and organize notes 
* Getting Things Done verticals:
** ~GTDTiddlyWiki - http://nathanbowers.com/gtdtw/ - the original one from 2005
** gtd_tiddlywiki - http://www.checkettsweb.com/tw/gtd_tiddlywiki.htm - a newer release with updated core
** ~MonkeyGTD -  http://monkeygtd.tiddlyspot.com - a newer release supporting realms (e.g. work and personal, you and your spouse ...). See also: http://wiki.43folders.com/index.php/Monkey_GTD
** D3 - http://www.dcubed.ca/Welcome_to_d-cubed.html - to download samples and blanks to work in. See also: http://wiki.43folders.com/index.php/D3
** tbGTD - http://tbgtd.tiddlyspot.com/ - yet another entry into the fray
** tiddlyDu3 - http://www.giffmex.org/tiddlydu3.html - another take on GTD
/***
|Name|UnsavedChangesPlugin|
|Source|http://www.TiddlyTools.com/#UnsavedChangesPlugin|
|Version|3.3.3|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides|TiddlyWiki.prototype.setDirty,store.saveTiddler,store.removeTiddler|
|Description|show droplist of tiddlers that have changed since the last time the document was saved|
Display a list of tiddlers that have been changed since the last time the document was saved.  The list includes all new/modified tiddlers as well as those changed with "minor edits" enabled and any tiddlers that you import during the session, regardless of their modification date.
!!!!!Usage
<<<
{{{
<<unsavedChanges panel>> or <<unsavedChanges>>
}}}
{{indent{
the ''panel'' keyword displays a 'control panel' interface containing a droplist of unsaved tiddlers and a 'goto' button, along with a command link to 'save changes'.  Depending upon what other plugins are installed, several additional elements will also be displayed: When [[NestedSlidersPlugin]] is installed, the entire control panel is contained within a ''SLIDER''.  When [[LoadTiddlersPlugin]] is installed, a ''REVERT'' button is added.  When [[SaveAsPlugin]] is installed, a ''SAVE AS'' link is added.  When [[UploadPlugin]] is installed, an ''UPLOAD'' (or ''save to web'') link is added.  When [[TrashPlugin]] is installed and there are tiddlers tagged with<<tag Trash>>, an ''EMPTY TRASH'' link is added.
}}}
{{{
<<unsavedChanges list separator>>
}}}
{{indent{
the ''list'' keyword displays a simple space-separated list of unsaved tiddlers without any other command links.  You can specify an optional ''separator'' value that can be used in place of the default space character.  For example, you can specify {{{"<br>"}}} as the separator in order to display each link, one per line.
}}}
{{{
<<unsavedChanges command label tip>>
}}}
{{indent{
the ''command'' keyword displays a single 'command link' that, when clicked, displays a ~TiddlyWiki popup containing the list of unsaved tiddlers, the 'save changes' command and, depending upon what other plugins are installed, additional commands for 'save as', 'upload', and 'empty trash' (similar to the panel display described above).

You can specify optional ''label'' and ''tip'' parameters in the macro to customize the command link text and tooltip.  The default label for the command link is: "There %1 %0 unsaved tiddler%2...", where:
* %0 is automatically replaced with the number of unsaved changes
* %1 is either "is" (if changes=1) or "are" (if changes>1)
* %2 is either blank (if changes=1) or "s" (if changes>1)
resulting in the text: //"There is 1 unsaved tiddler...", "There are 2 unsaved tiddlers...", etc.//
}}}
<<<
!!!!!Examples
<<<
^^//note: the following examples will not display any output unless you have already created/modified tiddlers in the current document.//^^
{{{<<unsavedChanges>>}}}
<<unsavedChanges>>
----
{{{<<unsavedChanges command>>}}}
<<unsavedChanges command>>
----
{{{<<unsavedChanges list>>}}}
<<unsavedChanges list>>
----
{{{<<unsavedChanges list "<br>">>}}}
<<unsavedChanges list "<br>">>
<<<
!!!!!Revisions
<<<
2009.03.02 [3.3.3] fix handling for titles that contain HTML special chars (lt,gt,quot,amp)
2008.09.02 [3.3.2] cleanup popup list output generation and added timestamps/sizes to popup display
2008.08.23 [3.3.1] added optional custom 'label' and 'tip' params to 'command' mode and defined default values for mode, label, tip, and separator as object properties for I18N/L10N-readiness.
2008.08.21 [3.3.0] complete re-write of rendering and refresh processing to support multiple instances and automatic self-refresh (no longer depends upon core refresh notifications)
2008.08.21 [3.2.0] added 'command' option for link+popup as alternative to 'control panel' interface
2008.04.22 [3.1.2] use SaveAsPlugin instead of obsolete NewDocumentPlugin to add "save as" link
2007.12.22 [3.1.1] hijack removeTiddler() instead of low-level deleteTiddler() to correct tracking and refresh handling issues.  in saveTiddler(), check for 'tiddler rename' (title!=newtitle) and adjust list accordingly.
2007.12.21 [3.1.0] added support for {{{<<unsavedChanges list separator>>}}} usage to unsaved tiddlers as a simple list of links, embedded in tiddler content (e.g., [[MainMenu]])
2007.12.20 [3.0.0] rewrite to track ALL changed tiddlers, including imports and minor edits, regardless of saved modification dates.  Also, rewrote display logic to directly refresh macro output instead of triggering a page refresh.  The entire process is MUCH more efficient now.
2007.08.02 [2.0.0] converted from inline script
2007.01.01 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.UnsavedChangesPlugin= {major: 3, minor: 3, revision: 3, date: new Date(2009,3,2)};

config.macros.unsavedChanges = {
	changed: [], // list of currently unsaved tiddler titles
	defMode: "panel",
	defSep: " ",
	defLabel: "There %1 %0 unsaved tiddler%2...",
	defTip: "view a list of unsaved tiddler changes",
	handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		var wrapper=createTiddlyElement(place,"span",null,"unsavedChanges");
		wrapper.setAttribute("mode",params[0]||this.defMode);
		wrapper.setAttribute("sep",params[1]||this.defSep); // for 'list' mode
		wrapper.setAttribute("label",params[1]||this.defLabel); // for 'command' mode
		wrapper.setAttribute("tip",params[2]||this.defTip); // for 'command' mode
		this.render(wrapper);
	},
	render: function(wrapper) {
		removeChildren(wrapper); // make sure its empty
		if (!this.changed.length) return; // no changes = no output
		switch (wrapper.getAttribute("mode")) {
			case "command": this.command(wrapper); break;
			case "list": this.list(wrapper); break;
			case "panel": default: this.panel(wrapper); break;
		}
	},
	refresh: function() {
		var wrappers=document.getElementsByTagName("span");
		for (var w=0; w<wrappers.length; w++)
			if (hasClass(wrappers[w],"unsavedChanges"))
				this.render(wrappers[w]);
	},
	list: function(place) { // show simple list of unsaved tiddlers
		wikify("[["+this.changed.join("]]"+place.getAttribute("sep")+"[[")+"]]",place);
	},
	command: function(place) { // show command link with popup list
		var c=this.changed.length;
		var txt=place.getAttribute("label").format([c,c==1?'is':'are',c==1?'':'s']);
		var tip=place.getAttribute("tip");
		var action=function(ev) { if (!ev) var ev=window.event;
			var p=Popup.create(this); if (!p) return false;
			var d=createTiddlyElement(p,"div");
			d.style.whiteSpace="normal"; d.style.width="auto"; d.style.padding="2px";
			// gather pretty links for changed tiddlers
			var list=[]; var item=" &nbsp;[[%1 - %0 (%2 bytes)|%0]]&nbsp; ";
			for (var i=config.macros.unsavedChanges.changed.length-1; i>=0; i--) {
				var tid=store.getTiddler(config.macros.unsavedChanges.changed[i]);
				if (!tid) continue;
				var when=tid.modified.formatString('YYYY.0MM.0DD 0hh:0mm:0ss');
				list.push(item.format([tid.title,when,tid.text.length]));
			}
			wikify("@@white-space:nowrap;"+list.join("<br>")+"@@",d);
			if (!readOnly) {
				var t="\n----\n";
				t+="@@white-space:nowrap;display:block;text-align:center; &nbsp;";
				t+="<<saveChanges>>";
				t+=config.macros.saveAs?" | <<saveAs>>":"";
				t+=config.macros.upload?" | <<upload>>":"";
				t+=(config.macros.emptyTrash&&store.getTaggedTiddlers("Trash").length)?" | <<emptyTrash>>":"";
				t+="&nbsp; @@";
				wikify(t,d);
			}
			Popup.show();
			ev.cancelBubble=true; if(ev.stopPropagation)ev.stopPropagation();
			return(false);
		}
		createTiddlyButton(place,txt,tip,action,"button");
	},
	panel: function(place) { // show composite droplist+buttons+commands
		// gather changed tiddlers (in reverse order by date - most recent first)
		var tids=[]; for (var i=this.changed.length-1; i>=0; i--)
			{ var t=store.getTiddler(this.changed[i]); if (t) tids.push(t); }
		tids.sort(function(a,b){return a.modified<b.modified?-1:(a.modified==b.modified?0:1);});
		// generate droplist items
 		var list=[]; var item='<option value="%0">%1 - %0 (%2 bytes)</option>';
		for (var i=tids.length-1; i>=0; i--) {
			var when=tids[i].modified.formatString('YYYY.0MM.0DD 0hh:0mm:0ss');
			list.push(item.format([tids[i].title.htmlEncode(),when,tids[i].text.length]));
		}
		// display droplist, buttons, and command links
		var out=''; var c=this.changed.length;
		var NSP=config.formatters.findByField("name","nestedSliders");
		var summary=this.defLabel.format([c,c==1?'is':'are',c==1?'':'s'])
		out+=NSP?'+++(unsaved)['+summary+'|'+this.defTip+']...':(summary+"\n");
		out+='<html><form style="display:inline"><!--\
			--><select size="1" name="list" \
				title="select a tiddler to view" \
				onchange="var v=this.value; if (v.length) story.displayTiddler(null,v);"><!--\
			-->'+list.join('')+'<!--\
			--></select><!--\
			--><input type="button" value="goto" onclick="this.form.list.onchange();">';
		if (config.macros.loadTiddlers)  {
			out+='<input type="button" value="revert" \
				title="import the last saved version of this tiddler" \
				onclick="var v=this.form.list.value; if (!v.length) return; \
					var t=\'<\'+\'<loadTiddlers [[tiddler:\'+v+\']] \'; \
					t+=document.location.href; \
					t+=\' confirm force noreport>\'+\'>\'; \
					var e=document.getElementById(\'executeRevert\'); \
					if (e) e.parentNode.removeChild(e); \
					e=document.createElement(\'span\'); \
					e.id=\'executeRevert\'; \
					wikify(t,e);">';
		}
		out+='</form></html>';
		if (!readOnly) {
			out+='\n{{small nowrap{';
			out+="<<saveChanges>>";
			out+=config.macros.saveAs?" | <<saveAs>>":"";
			out+=config.macros.upload?" | <<upload>>":"";
			out+=(config.macros.emptyTrash&&store.getTaggedTiddlers("Trash").length)?" | <<emptyTrash>>":"";
			out+='}}}';
		}
		out+=NSP?'===':'';
		wikify(out,place);
	}
};

// hijack store.saveTiddler() to track changes to tiddlers
if (store.showUnsaved_saveTiddler==undefined) {
	store.showUnsaved_saveTiddler=store.saveTiddler;
	store.saveTiddler=function(title,newtitle) {
		if (title!=newtitle) {
			var i=config.macros.unsavedChanges.changed.indexOf(title);
			if (i!=-1) config.macros.unsavedChanges.changed.splice(i,1); // remove old from list
		} 
		var i=config.macros.unsavedChanges.changed.indexOf(newtitle);
		if (i!=-1) config.macros.unsavedChanges.changed.splice(i,1); // remove new title from list
		config.macros.unsavedChanges.changed.push(newtitle); // add new title to END of list
		var t=this.showUnsaved_saveTiddler.apply(this,arguments);
		if (!this.notificationLevel) config.macros.unsavedChanges.refresh();
		return t;
	}
}

// hijack store.removeTiddler() to track changes to tiddlers
if (store.showUnsaved_removeTiddler==undefined) {
	store.showUnsaved_removeTiddler=store.removeTiddler;
	store.removeTiddler=function(title) {
		var i=config.macros.unsavedChanges.changed.indexOf(title);
		if (i!=-1) config.macros.unsavedChanges.changed.splice(i,1); // remove from list
		this.showUnsaved_removeTiddler.apply(this,arguments);
		if (!this.notificationLevel) config.macros.unsavedChanges.refresh();
	}
}

// hijack store.setDirty() function to reset change list after file save
// note: do NOT hijack the prototype function.  This hijack should only be applied to
// the main 'store' instance only (i.e., don't refresh when loading temporary store
// as part of ImportTiddlers processing)
if (store.showUnsaved_setDirty==undefined) {
	store.showUnsaved_setDirty=store.setDirty;
	store.setDirty = function(flag) {
		var refresh=this.isDirty() && !flag; // 'dirty' to 'clean', force a refresh...
		this.showUnsaved_setDirty.apply(this,arguments); // but change the flag first.
		if (refresh) {
			config.macros.unsavedChanges.changed=[]; // clear changed list
			config.macros.unsavedChanges.refresh();
		}
	}
}
//}}}
! Chapters are listed in the MainMenu
* Use the pulldown listing all the chapters is provided in the MainMenu
* A  chapter is composed of multiple tiddlers.
* Viewing options allow you to replace the story column with the chapter or add it to the open tiddlers.
* At the top of the story column is a list of all open tiddlers for easy access
* Alternatively use a tiddler's jump menu item to jump to a specific open tiddler
* A notebook is provided after each tiddler
/%
----------
* A chapter is a single tiddler
* A table of contents is provided to jump to a location in the tiddler
* A notebook is provided at the end of each chapter
-----------
%/

{{comment{There are two mechanisms for accessing chapters. The pull down menu that allows you to control how the new tiddlers are opened as well as a traditional set of links to the "control topic"/table of contents (TOC) for the chapter. Both are provided to allow users with browsers that cut off the chapter titles in the pull down to use the links below to select the proper chapter.

If you click on a link to go to the chapter list tiddler, a button at the bottom along with some check boxes will allow you to open all the sections that are listed.}}}
Notebook blocks are:
* placed at the end of each content tiddler
* colored gray
* edited with doubleclick or {{{edit notes}}} button
* saved by clicking on {{{save notes}}} before moving in slide view mode
The left hand menu contains the presentations:
* Click on the link to display the control tiddler for the show.
* Start the show use the Student button at the top of the control tiddler
* Take notes using the notes block (don't forget to save)
* Use the navigation controls at the top right to: move forward [>], move back [<], exit [x], jump to a slide (click on slide number and select).

* Print the slide show (including instructor but not student notes) use the Print button at the top of the control tiddler. (Press any key to exit print mode.)

{{comment{The print mode does not show the student's notes. To display them, open the slides in the story column using the drop down select box at the top of the presentation list in the MainMenu}}}
! Using this Tiddlywiki
For those of you who are used to tiddlywiki's this one has a few changes. It is based on version <<version>> of tiddlywiki with a number of plugins and customizations. The most obvious of these changes is the inability to edit tiddlers tagged with {{{content}}} by double clicking on them. You must use the edit menu to edit content tiddlers. This prevents inadvertent changes that will be destroyed on your next synchronization from the source. It also means that you can select text from content tiddlers using double or triple clicks. Use the notes block to record your changes/notes.

!! Editing Notebook
You will see below every content tiddler a notebook tiddler block. Double click on the gray notes block, or use the edit notes button to add your own notes and observations to the content tiddler. The notes are not overwritten by a [[sync]] operation and provides you with a way to annotate the pages even if newer pages are released with corrected errors or more explanatory material.

You can use ~TiddlyWiki formatting markup which is summarized in the FormattingCheatSheet tiddler.

!! Presentations
Presentations are accessed from the MainMenu on the left hand side of the page.

!!! View Presentations in student mode
Running a slide show presentation in student form allows you to follow along with the instructor's slide display. The student mode display presents the same material but in a different style from the instructor.

To start the student mode display:
* click on the link for the presentation in the MainMenu, this will open the control tiddler for the slide show
* click on the "Student" button at the top of the control tiddler

The student display mode creates a slide show right on your desktop. The student mode allows you to:
* view each slide without the clutter of the normal tiddlywiki display
* move between slides using the controls at the top right
* view instructor comments on the slide (highlighted in yellow)
* add your notes to the slide

!!! Other Presentation modes
On the control tiddler is a print button. This creates a display of the slides including the instructor comments (but not including your notes) where each slide is printed on a seperate page which can be used for manual note taking if you can't bring your computer to the lecture. You can use your browser's print function to print them off.

If you use the pulldown select box right below the Presentation header in the MainMenu, all of the slides for that presentation will open in the center column. In this mode, you can print the ((slide contents, instructor comments and your notes(With every slide on a new page))) using your browser's print function.

!! Chapters
Chapters provide a structured presentation for the non-structured wiki format material. They are composed of multiple tiddlers. You can display them using the pulldown select box under the Chapters header in the MainMenu on the left hand side of the page. Chapters can also be displayed by clicking on one of the links to display the control tiddler for the chapter. The check boxes and button on the bottom of the control tiddler let you control how to open the chapter.

Using the browser's print function you can print a chapter where the first tiddler of every chapter will start on a new page. When you print a chapter, your notes are printed as well.

!! Searching
The search box on the upper right allows you to search for tiddlers that match the keywords that your type in. Try it now to look for the words: "presentation searching". It searches as you type (once you have entered three characters, use enter to trigger searching for fewer characters) so you can see the list of tiddlers being refined. It displays list of tiddlers that match the terms along with the list of tags and a synopsis of the content in the tiddler. You can refine the search operation by changing the settings on [[YourSearch Options]]. For full details of the search functionality see: [[YourSearch Help]]

!! Getting updates and errata
Books and manuals have errors and need to be updated. Image having a book that updates and corrects itself while preserving the notes you write in the margins. Using tiddlywiki you can gather these updates into your tiddlywiki from the author's web site. Also there is an rss reader located on the ContentChanges page to notify you with the latest changes.

All tiddlers marked with the tags {{{content}}} or {{{structure}}} are sourced from the author's tiddlywiki. See the [[sync]] page for instructions on updating these tiddlers with current copies.

!! Emergency recovery
In the event you have made changes to the coursebook that you want to save and something is preventing you from saving it, you can use the RescueStoreAreaCommand which is documented at FAQ_RescueStoreArea to create a text copy of the coursebook content that can be copied and then hand edited into the coursebook. This should rarely if ever be needed, but can be useful on occasion.
<html> <hide linebreaks> <ul>
<li>{{{plod save this note}}} -- store a single line note</li>
<li class="overlay1">{{{plod}}} -- type multiline message and end with ^D or . on a line by itself</li>
<li class="overlay2">{{{plod -b mail}}} -- start a job timer adding the time to the category mail</li>
<li class="overlay3">{{{plod -j phone:trouble -t 30}}} -- record a 30 minute job to the category phone subcat trouble (and subtract from current job)</li>
<li class="overlay4">{{{plod -J}}} -- suspend (or resume) the current job (e.g. going to lunch)</li>
<li class="overlay5">{{{plod -S}}} -- report status of current job</li>
<li class="overlay6">{{{plod -e -t -30}}} -- end the current job time and subtract 30 minutes from it</li>
</ul></html>
{{sectionTOC{}}}

<part coursebook>
This coursebook is based on version <<version>> of [[tiddlywiki|http://www.tiddlywiki.org]] and serves as:
* A textbook for the class (including quizzes)
* A notebook during the class
* A presentation tool for the class
</part>
<part tiddlerclass>
It has two main types of entries called tiddlers:
# Content tiddlers are can be updated from the main website for this class
# Note tiddlers are used to store your notes for each tiddler
Content tiddlers are overwritten when you choose to [[sync]] your Coursebook to the updated contents from the master Coursebook.

Your notes are safely preserved across updates.

Identify content tiddlers by looking for {{{content}}} in the gray "tags" block on the upper right side of a tiddler.
</part>

You can hover over the content tag box on the upper right and see all the tiddlers tagged with content.

You can search for particular keywords using the search box at the upper right.

A list of chapters is shown below:

<<tiddler ChapterList>>

<<tiddler [[Using This Tiddlywiki]]>>

+++(welcomelegal)![Legal stuff <sub>click to display</sub>|Click to display legal information]...
<<tiddler [[Copyright and Legal Stuff]]>>
===
The [[patched version|http://www.cs.umb.edu/~rouilj/#plod]] adds job timing support to plod
{{overlay1{
* define jobs to work on
* record start and stop time on jobs
* generate reports showing total time spent on a job
}}}
Filepp is a generic (language agnostic) file preprocessor available from http://www.cabaret.demon.co.uk/filepp/ and owes its syntax more to cpp than to M4 @@font-size: smaller;(anybody who has looked at the sendmail config file generation mechanism is very happy about now)@@.
!Directives
{{col2a{
{{{
#include <filename>
#define/#undef
#define macro(arg1,arg2,...) ...
}}}
}}}{{col2b{
{{{
#ifdef/#ifndef, #endif
#if, #elif, #else, #endif
}}}
}}}{{nocol{}}}
plus more as defined by modules for:
* looping over a list of strings
* formatting strings (upper/lower case printf type operations)
* string replacement (ala sed)
* methods for generating multiline defines and macros
* and many more
A tiddlywiki is a single html file that acts like a wiki thanks to javascript. If you liked ~HyperCard you will like TiddlyWiki.
<html>
<hide linebreaks>
<ul>
<li class="overlay1">Edit right in the browser with a text area using ~TiddlyWiki markup</li>
<li class="overlay2">Email and trade them with your friends</li>
<li class="overlay3">Has a plugin architecture allowing hundreds of plugins to be used for special purposes
  <ul>
   <li>Attach files to a tiddlywiki</li>
   <li>Enhanced search plugins</li>
   <li>Turn your ~TiddlyWiki into a <a href="http://www.math.ist.utl.pt/~psoares/addons.html#SlideShowPlugin">slide show</a></li>
   <li>[[QuickEdit|http://www.tiddlytools.com/#QuickEditPackage]] or [[EasyEdit|http://visualtw.ouvaton.org/VisualTW.html#EasyEditPlugin]] brings WYSIWYG like functionality to ~TiddlyWiki</li>
   <li>Change <a href="http://www.martinswiki.com/">markup language</a> to ~MediaWiki, ~TWiki, Trac ... format</li>
   <li>Hundreds of other plugins</li>
  </ul>
</li>
</ul>
</html>
From [[Wikipedia|http://en.wikipedia.org/wiki/General_purpose_macro_processor]]:
<<<
A macro processor is a program that copies a stream of text from one place to another, making a systematic set of replacements as it does so. Macro processors are often embedded in other programs, such as assemblers and compilers. Sometimes they are standalone programs that can be used to process any kind of text.<br> Macro processors have been used for language expansion (defining new language constructs that can be expressed in terms of existing language components), for systematic text replacements that require decision making, and for text reformatting (e.g. conditional extraction of material from an HTML file).
<<<
It is another tool in the pantheon of text processing languages:
> sed, AWK, Perl (filepp is written in Perl), M4, cpp
A [[TiddlyWiki|http://www.tiddlywiki.org]] is:

* An html file that uses javascript to create a wiki (like Wikipedia)
* You edit not pages, but pieces of micro content called tiddlers
The Personal ~LOgging Device was written by Hal Pomeranz and presented at LISA 93
{{overlay1{
<<<
PLOD  is a simple text interface which allows System Administrators (and others) to keep a record of the work they from day to day. The program was developed in Perl with device independence, flexibility, extensibility, and ease of use in mind. The user-interface is reminiscent of Berkeley mail, complete with many pre-defined tilde-escapes which perform various useful functions. Users may easily extend the program by defining their own personal escape sequences. 
<<<
}}}
{{overlay2{An enhanced version is available from http://www.cs.umb.edu/~rouilj/#plod}}}
/***
|''Name:''|YourSearchPlugin|
|''Version:''|2.1.4 (2009-09-04)|
|''Source:''|http://tiddlywiki.abego-software.de/#YourSearchPlugin|
|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|
|''Licence:''|[[BSD open source license (abego Software)|http://www.abego-software.de/legal/apl-v10.html]]|
|''Copyright:''|&copy; 2005-2009 [[abego Software|http://www.abego-software.de]]|
|''~CoreVersion:''|2.1.0|
|''Community:''|[[del.icio.us|http://del.icio.us/post?url=http://tiddlywiki.abego-software.de/index.html%23YourSearchPlugin]]|
|''Browser:''|Firefox 1.0.4+; Firefox 1.5; ~InternetExplorer 6.0|
!About YourSearch
YourSearch gives you a bunch of new features to simplify and speed up your daily searches in TiddlyWiki. It seamlessly integrates into the standard TiddlyWiki search: just start typing into the 'search' field and explore!

For more information see [[Help|YourSearch Help]].
!Compatibility
This plugin requires TiddlyWiki 2.1. 
Check the [[archive|http://tiddlywiki.abego-software.de/archive]] for ~YourSearchPlugins supporting older versions of TiddlyWiki.
!Source Code
***/
/***
This plugin's source code is compressed (and hidden). Use this [[link|http://tiddlywiki.abego-software.de/archive/YourSearchPlugin/Plugin-YourSearch-src.2.1.4.js]] to get the readable source code.
***/
///%
if(!version.extensions.YourSearchPlugin){version.extensions.YourSearchPlugin={major:2,minor:1,revision:4,source:"http://tiddlywiki.abego-software.de/#YourSearchPlugin",licence:"[[BSD open source license (abego Software)|http://www.abego-software.de/legal/apl-v10.html]]",copyright:"Copyright (c) abego Software GmbH, 2005-2009 (www.abego-software.de)"};if(!window.abego){window.abego={};}if(!Array.forEach){Array.forEach=function(_1,_2,_3){for(var i=0,_4=_1.length;i<_4;i++){_2.call(_3,_1[i],i,_1);}};Array.prototype.forEach=function(_5,_6){for(var i=0,_7=this.length;i<_7;i++){_5.call(_6,this[i],i,this);}};}abego.toInt=function(s,_8){if(!s){return _8;}var n=parseInt(s);return (n==NaN)?_8:n;};abego.createEllipsis=function(_9){var e=createTiddlyElement(_9,"span");e.innerHTML="&hellip;";};abego.shallowCopy=function(_a){if(!_a){return _a;}var _b={};for(var n in _a){_b[n]=_a[n];}return _b;};abego.copyOptions=function(_c){return !_c?{}:abego.shallowCopy(_c);};abego.countStrings=function(_d,s){if(!s){return 0;}var _e=s.length;var n=0;var _f=0;while(1){var i=_d.indexOf(s,_f);if(i<0){return n;}n++;_f=i+_e;}return n;};abego.getBracedText=function(_10,_11,_12){if(!_11){_11=0;}var re=/\{([^\}]*)\}/gm;re.lastIndex=_11;var m=re.exec(_10);if(m){var s=m[1];var _13=abego.countStrings(s,"{");if(!_13){if(_12){_12.lastIndex=re.lastIndex;}return s;}var len=_10.length;for(var i=re.lastIndex;i<len&&_13;i++){var c=_10.charAt(i);if(c=="{"){_13++;}else{if(c=="}"){_13--;}}}if(!_13){if(_12){_12.lastIndex=i-1;}return _10.substring(m.index+1,i-1);}}};abego.select=function(_14,_15,_16,_17){if(!_17){_17=[];}_14.forEach(function(t){if(_15.call(_16,t)){_17.push(t);}});return _17;};abego.consumeEvent=function(e){if(e.stopPropagation){e.stopPropagation();}if(e.preventDefault){e.preventDefault();}e.cancelBubble=true;e.returnValue=true;};abego.TiddlerFilterTerm=function(_18,_19){if(!_19){_19={};}var _1a=_18;if(!_19.textIsRegExp){_1a=_18.escapeRegExp();if(_19.fullWordMatch){_1a="\\b"+_1a+"\\b";}}var _1b=new RegExp(_1a,"m"+(_19.caseSensitive?"":"i"));this.tester=new abego.MultiFieldRegExpTester(_1b,_19.fields,_19.withExtendedFields);};abego.TiddlerFilterTerm.prototype.test=function(_1c){return this.tester.test(_1c);};abego.parseNewTiddlerCommandLine=function(s){var m=/(.*?)\.(?:\s+|$)([^#]*)(#.*)?/.exec(s);if(!m){m=/([^#]*)()(#.*)?/.exec(s);}if(m){var r;if(m[3]){var s2=m[3].replace(/#/g,"");r=s2.parseParams("tag");}else{r=[[]];}var _1d=m[2]?m[2].trim():"";r.push({name:"text",value:_1d});r[0].text=[_1d];return {title:m[1].trim(),params:r};}else{return {title:s.trim(),params:[[]]};}};abego.parseTiddlerFilterTerm=function(_1e,_1f,_20){var re=/\s*(?:(?:\{([^\}]*)\})|(?:(=)|([#%!])|(?:(\w+)\s*\:(?!\/\/))|(?:(?:("(?:(?:\\")|[^"])+")|(?:\/((?:(?:\\\/)|[^\/])+)\/)|(\w+\:\/\/[^\s]+)|([^\s\)\-\"]+)))))/mg;var _21={"!":"title","%":"text","#":"tags"};var _22={};var _23;re.lastIndex=_1f;while(1){var i=re.lastIndex;var m=re.exec(_1e);if(!m||m.index!=i){throw "Word or String literal expected";}if(m[1]){var _24={};var _25=abego.getBracedText(_1e,0,_24);if(!_25){throw "Invalid {...} syntax";}var f=Function("tiddler","return ("+_25+");");return {func:f,lastIndex:_24.lastIndex,markRE:null};}if(m[2]){_23=true;}else{if(m[3]){_22[_21[m[3]]]=1;}else{if(m[4]){_22[m[4]]=1;}else{var _26=m[6];var _27=m[5]?window.eval(m[5]):m[6]?m[6]:m[7]?m[7]:m[8];var _20=abego.copyOptions(_20);_20.fullWordMatch=_23;_20.textIsRegExp=_26;var _28=[];for(var n in _22){_28.push(n);}if(_28.length==0){_20.fields=_20.defaultFields;}else{_20.fields=_28;_20.withExtendedFields=false;}var _29=new abego.TiddlerFilterTerm(_27,_20);var _2a=_26?_27:_27.escapeRegExp();if(_2a&&_23){_2a="\\b"+_2a+"\\b";}return {func:function(_2b){return _29.test(_2b);},lastIndex:re.lastIndex,markRE:_2a?"(?:"+_2a+")":null};}}}}};abego.BoolExp=function(s,_2c,_2d){this.s=s;var _2e=_2d&&_2d.defaultOperationIs_OR;var _2f=/\s*(?:(\-|not)|(\())/gi;var _30=/\s*\)/g;var _31=/\s*(?:(and|\&\&)|(or|\|\|))/gi;var _32=/\s*[^\)\s]/g;var _33=/\s*(\-|not)?(\s*\()?/gi;var _34;var _35=function(_36){_33.lastIndex=_36;var m=_33.exec(s);var _37;var _38;if(m&&m.index==_36){_36+=m[0].length;_37=m[1];if(m[2]){var e=_34(_36);_30.lastIndex=e.lastIndex;if(!_30.exec(s)){throw "Missing ')'";}_38={func:e.func,lastIndex:_30.lastIndex,markRE:e.markRE};}}if(!_38){_38=_2c(s,_36,_2d);}if(_37){_38.func=(function(f){return function(_39){return !f(_39);};})(_38.func);_38.markRE=null;}return _38;};_34=function(_3a){var _3b=_35(_3a);while(1){var l=_3b.lastIndex;_31.lastIndex=l;var m=_31.exec(s);var _3c;var _3d;if(m&&m.index==l){_3c=!m[1];_3d=_35(_31.lastIndex);}else{try{_3d=_35(l);}catch(e){return _3b;}_3c=_2e;}_3b.func=(function(_3e,_3f,_40){return _40?function(_41){return _3e(_41)||_3f(_41);}:function(_42){return _3e(_42)&&_3f(_42);};})(_3b.func,_3d.func,_3c);_3b.lastIndex=_3d.lastIndex;if(!_3b.markRE){_3b.markRE=_3d.markRE;}else{if(_3d.markRE){_3b.markRE=_3b.markRE+"|"+_3d.markRE;}}}};var _43=_34(0);this.evalFunc=_43.func;if(_43.markRE){this.markRegExp=new RegExp(_43.markRE,_2d.caseSensitive?"mg":"img");}};abego.BoolExp.prototype.exec=function(){return this.evalFunc.apply(this,arguments);};abego.BoolExp.prototype.getMarkRegExp=function(){return this.markRegExp;};abego.BoolExp.prototype.toString=function(){return this.s;};abego.MultiFieldRegExpTester=function(re,_44,_45){this.re=re;this.fields=_44?_44:["title","text","tags"];this.withExtendedFields=_45;};abego.MultiFieldRegExpTester.prototype.test=function(_46){var re=this.re;for(var i=0;i<this.fields.length;i++){var s=store.getValue(_46,this.fields[i]);if(typeof s=="string"&&re.test(s)){return this.fields[i];}}if(this.withExtendedFields){return store.forEachField(_46,function(_47,_48,_49){return typeof _49=="string"&&re.test(_49)?_48:null;},true);}return null;};abego.TiddlerQuery=function(_4a,_4b,_4c,_4d,_4e){if(_4c){this.regExp=new RegExp(_4a,_4b?"mg":"img");this.tester=new abego.MultiFieldRegExpTester(this.regExp,_4d,_4e);}else{this.expr=new abego.BoolExp(_4a,abego.parseTiddlerFilterTerm,{defaultFields:_4d,caseSensitive:_4b,withExtendedFields:_4e});}this.getQueryText=function(){return _4a;};this.getUseRegExp=function(){return _4c;};this.getCaseSensitive=function(){return _4b;};this.getDefaultFields=function(){return _4d;};this.getWithExtendedFields=function(){return _4e;};};abego.TiddlerQuery.prototype.test=function(_4f){if(!_4f){return false;}if(this.regExp){return this.tester.test(_4f);}return this.expr.exec(_4f);};abego.TiddlerQuery.prototype.filter=function(_50){return abego.select(_50,this.test,this);};abego.TiddlerQuery.prototype.getMarkRegExp=function(){if(this.regExp){return "".search(this.regExp)>=0?null:this.regExp;}return this.expr.getMarkRegExp();};abego.TiddlerQuery.prototype.toString=function(){return (this.regExp?this.regExp:this.expr).toString();};abego.PageWiseRenderer=function(){this.firstIndexOnPage=0;};merge(abego.PageWiseRenderer.prototype,{setItems:function(_51){this.items=_51;this.setFirstIndexOnPage(0);},getMaxPagesInNavigation:function(){return 10;},getItemsCount:function(_52){return this.items?this.items.length:0;},getCurrentPageIndex:function(){return Math.floor(this.firstIndexOnPage/this.getItemsPerPage());},getLastPageIndex:function(){return Math.floor((this.getItemsCount()-1)/this.getItemsPerPage());},setFirstIndexOnPage:function(_53){this.firstIndexOnPage=Math.min(Math.max(0,_53),this.getItemsCount()-1);},getFirstIndexOnPage:function(){this.firstIndexOnPage=Math.floor(this.firstIndexOnPage/this.getItemsPerPage())*this.getItemsPerPage();return this.firstIndexOnPage;},getLastIndexOnPage:function(){return Math.min(this.getFirstIndexOnPage()+this.getItemsPerPage()-1,this.getItemsCount()-1);},onPageChanged:function(_54,_55){},renderPage:function(_56){if(_56.beginRendering){_56.beginRendering(this);}try{if(this.getItemsCount()){var _57=this.getLastIndexOnPage();var _58=-1;for(var i=this.getFirstIndexOnPage();i<=_57;i++){_58++;_56.render(this,this.items[i],i,_58);}}}finally{if(_56.endRendering){_56.endRendering(this);}}},addPageNavigation:function(_59){if(!this.getItemsCount()){return;}var _5a=this;var _5b=function(e){if(!e){var e=window.event;}abego.consumeEvent(e);var _5c=abego.toInt(this.getAttribute("page"),0);var _5d=_5a.getCurrentPageIndex();if(_5c==_5d){return;}var _5e=_5c*_5a.getItemsPerPage();_5a.setFirstIndexOnPage(_5e);_5a.onPageChanged(_5c,_5d);};var _5f;var _60=this.getCurrentPageIndex();var _61=this.getLastPageIndex();if(_60>0){_5f=createTiddlyButton(_59,"Previous","Go to previous page (Shortcut: Alt-'<')",_5b,"prev");_5f.setAttribute("page",(_60-1).toString());_5f.setAttribute("accessKey","<");}for(var i=-this.getMaxPagesInNavigation();i<this.getMaxPagesInNavigation();i++){var _62=_60+i;if(_62<0){continue;}if(_62>_61){break;}var _63=(i+_60+1).toString();var _64=_62==_60?"currentPage":"otherPage";_5f=createTiddlyButton(_59,_63,"Go to page %0".format([_63]),_5b,_64);_5f.setAttribute("page",(_62).toString());}if(_60<_61){_5f=createTiddlyButton(_59,"Next","Go to next page (Shortcut: Alt-'>')",_5b,"next");_5f.setAttribute("page",(_60+1).toString());_5f.setAttribute("accessKey",">");}}});abego.LimitedTextRenderer=function(){var _65=40;var _66=4;var _67=function(_68,_69,_6a){var n=_68.length;if(n==0){_68.push({start:_69,end:_6a});return;}var i=0;for(;i<n;i++){var _6b=_68[i];if(_6b.start<=_6a&&_69<=_6b.end){var r;var _6c=i+1;for(;_6c<n;_6c++){r=_68[_6c];if(r.start>_6a||_69>_6b.end){break;}}var _6d=_69;var _6e=_6a;for(var j=i;j<_6c;j++){r=_68[j];_6d=Math.min(_6d,r.start);_6e=Math.max(_6e,r.end);}_68.splice(i,_6c-i,{start:_6d,end:_6e});return;}if(_6b.start>_6a){break;}}_68.splice(i,0,{start:_69,end:_6a});};var _6f=function(_70){var _71=0;for(var i=0;i<_70.length;i++){var _72=_70[i];_71+=_72.end-_72.start;}return _71;};var _73=function(c){return (c>="a"&&c<="z")||(c>="A"&&c<="Z")||c=="_";};var _74=function(s,_75){if(!_73(s[_75])){return null;}for(var i=_75-1;i>=0&&_73(s[i]);i--){}var _76=i+1;var n=s.length;for(i=_75+1;i<n&&_73(s[i]);i++){}return {start:_76,end:i};};var _77=function(s,_78,_79){var _7a;if(_79){_7a=_74(s,_78);}else{if(_78<=0){return _78;}_7a=_74(s,_78-1);}if(!_7a){return _78;}if(_79){if(_7a.start>=_78-_66){return _7a.start;}if(_7a.end<=_78+_66){return _7a.end;}}else{if(_7a.end<=_78+_66){return _7a.end;}if(_7a.start>=_78-_66){return _7a.start;}}return _78;};var _7b=function(s,_7c){var _7d=[];if(_7c){var _7e=0;var n=s.length;var _7f=0;do{_7c.lastIndex=_7e;var _80=_7c.exec(s);if(_80){if(_7e<_80.index){var t=s.substring(_7e,_80.index);_7d.push({text:t});}_7d.push({text:_80[0],isMatch:true});_7e=_80.index+_80[0].length;}else{_7d.push({text:s.substr(_7e)});break;}}while(true);}else{_7d.push({text:s});}return _7d;};var _81=function(_82){var _83=0;for(var i=0;i<_82.length;i++){if(_82[i].isMatch){_83++;}}return _83;};var _84=function(s,_85,_86,_87,_88){var _89=Math.max(Math.floor(_88/(_87+1)),_65);var _8a=Math.max(_89-(_86-_85),0);var _8b=Math.min(Math.floor(_86+_8a/3),s.length);var _8c=Math.max(_8b-_89,0);_8c=_77(s,_8c,true);_8b=_77(s,_8b,false);return {start:_8c,end:_8b};};var _8d=function(_8e,s,_8f){var _90=[];var _91=_81(_8e);var pos=0;for(var i=0;i<_8e.length;i++){var t=_8e[i];var _92=t.text;if(t.isMatch){var _93=_84(s,pos,pos+_92.length,_91,_8f);_67(_90,_93.start,_93.end);}pos+=_92.length;}return _90;};var _94=function(s,_95,_96){var _97=_96-_6f(_95);while(_97>0){if(_95.length==0){_67(_95,0,_77(s,_96,false));return;}else{var _98=_95[0];var _99;var _9a;if(_98.start==0){_99=_98.end;if(_95.length>1){_9a=_95[1].start;}else{_67(_95,_99,_77(s,_99+_97,false));return;}}else{_99=0;_9a=_98.start;}var _9b=Math.min(_9a,_99+_97);_67(_95,_99,_9b);_97-=(_9b-_99);}}};var _9c=function(_9d,s,_9e,_9f,_a0){if(_9f.length==0){return;}var _a1=function(_a2,s,_a3,_a4,_a5){var t;var _a6;var pos=0;var i=0;var _a7=0;for(;i<_a3.length;i++){t=_a3[i];_a6=t.text;if(_a4<pos+_a6.length){_a7=_a4-pos;break;}pos+=_a6.length;}var _a8=_a5-_a4;for(;i<_a3.length&&_a8>0;i++){t=_a3[i];_a6=t.text.substr(_a7);_a7=0;if(_a6.length>_a8){_a6=_a6.substr(0,_a8);}if(t.isMatch){createTiddlyElement(_a2,"span",null,"marked",_a6);}else{createTiddlyText(_a2,_a6);}_a8-=_a6.length;}if(_a5<s.length){abego.createEllipsis(_a2);}};if(_9f[0].start>0){abego.createEllipsis(_9d);}var _a9=_a0;for(var i=0;i<_9f.length&&_a9>0;i++){var _aa=_9f[i];var len=Math.min(_aa.end-_aa.start,_a9);_a1(_9d,s,_9e,_aa.start,_aa.start+len);_a9-=len;}};this.render=function(_ab,s,_ac,_ad){if(s.length<_ac){_ac=s.length;}var _ae=_7b(s,_ad);var _af=_8d(_ae,s,_ac);_94(s,_af,_ac);_9c(_ab,s,_ae,_af,_ac);};};(function(){function _b0(msg){alert(msg);throw msg;};if(version.major<2||(version.major==2&&version.minor<1)){_b0("YourSearchPlugin requires TiddlyWiki 2.1 or newer.\n\nCheck the archive for YourSearch plugins\nsupporting older versions of TiddlyWiki.\n\nArchive: http://tiddlywiki.abego-software.de/archive");}abego.YourSearch={};var _b1;var _b2;var _b3=function(_b4){_b1=_b4;};var _b5=function(){return _b1?_b1:[];};var _b6=function(){return _b1?_b1.length:0;};var _b7=4;var _b8=10;var _b9=2;var _ba=function(s,re){var m=s.match(re);return m?m.length:0;};var _bb=function(_bc,_bd){var _be=_bd.getMarkRegExp();if(!_be){return 1;}var _bf=_bc.title.match(_be);var _c0=_bf?_bf.length:0;var _c1=_ba(_bc.getTags(),_be);var _c2=_bf?_bf.join("").length:0;var _c3=_bc.title.length>0?_c2/_bc.title.length:0;var _c4=_c0*_b7+_c1*_b9+_c3*_b8+1;return _c4;};var _c5=function(_c6,_c7,_c8,_c9,_ca,_cb){_b2=null;var _cc=_c6.reverseLookup("tags",_cb,false);try{var _cd=[];if(config.options.chkSearchInTitle){_cd.push("title");}if(config.options.chkSearchInText){_cd.push("text");}if(config.options.chkSearchInTags){_cd.push("tags");}_b2=new abego.TiddlerQuery(_c7,_c8,_c9,_cd,config.options.chkSearchExtendedFields);}catch(e){return [];}var _ce=_b2.filter(_cc);var _cf=abego.YourSearch.getRankFunction();for(var i=0;i<_ce.length;i++){var _d0=_ce[i];var _d1=_cf(_d0,_b2);_d0.searchRank=_d1;}if(!_ca){_ca="title";}var _d2=function(a,b){var _d3=a.searchRank-b.searchRank;if(_d3==0){if(a[_ca]==b[_ca]){return (0);}else{return (a[_ca]<b[_ca])?-1:+1;}}else{return (_d3>0)?-1:+1;}};_ce.sort(_d2);return _ce;};var _d4=80;var _d5=50;var _d6=250;var _d7=50;var _d8=25;var _d9=10;var _da="yourSearchResult";var _db="yourSearchResultItems";var _dc;var _dd;var _de;var _df;var _e0;var _e1=function(){if(version.extensions.YourSearchPlugin.styleSheetInited){return;}version.extensions.YourSearchPlugin.styleSheetInited=true;setStylesheet(store.getTiddlerText("YourSearchStyleSheet"),"yourSearch");};var _e2=function(){return _dd!=null&&_dd.parentNode==document.body;};var _e3=function(){if(_e2()){document.body.removeChild(_dd);}};var _e4=function(e){_e3();var _e5=this.getAttribute("tiddlyLink");if(_e5){var _e6=this.getAttribute("withHilite");var _e7=highlightHack;if(_e6&&_e6=="true"&&_b2){highlightHack=_b2.getMarkRegExp();}story.displayTiddler(this,_e5);highlightHack=_e7;}return (false);};var _e8=function(){if(!_de){return;}var _e9=_de;var _ea=findPosX(_e9);var _eb=findPosY(_e9);var _ec=_e9.offsetHeight;var _ed=_ea;var _ee=_eb+_ec;var _ef=findWindowWidth();if(_ef<_dd.offsetWidth){_dd.style.width=(_ef-100)+"px";_ef=findWindowWidth();}var _f0=_dd.offsetWidth;if(_ed+_f0>_ef){_ed=_ef-_f0-30;}if(_ed<0){_ed=0;}_dd.style.left=_ed+"px";_dd.style.top=_ee+"px";_dd.style.display="block";};var _f1=function(){if(_dd){window.scrollTo(0,ensureVisible(_dd));}if(_de){window.scrollTo(0,ensureVisible(_de));}};var _f2=function(){_e8();_f1();};var _f3;var _f4;var _f5=new abego.PageWiseRenderer();var _f6=function(_f7){this.itemHtml=store.getTiddlerText("YourSearchItemTemplate");if(!this.itemHtml){_b0("YourSearchItemTemplate not found");}this.place=document.getElementById(_db);if(!this.place){this.place=createTiddlyElement(_f7,"div",_db);}};merge(_f6.prototype,{render:function(_f8,_f9,_fa,_fb){_f3=_fb;_f4=_f9;var _fc=createTiddlyElement(this.place,"div",null,"yourSearchItem");_fc.innerHTML=this.itemHtml;applyHtmlMacros(_fc,null);refreshElements(_fc,null);},endRendering:function(_fd){_f4=null;}});var _fe=function(){if(!_dd||!_de){return;}var _ff=store.getTiddlerText("YourSearchResultTemplate");if(!_ff){_ff="<b>Tiddler YourSearchResultTemplate not found</b>";}_dd.innerHTML=_ff;applyHtmlMacros(_dd,null);refreshElements(_dd,null);var _100=new _f6(_dd);_f5.renderPage(_100);_f2();};_f5.getItemsPerPage=function(){var n=(config.options.chkPreviewText)?abego.toInt(config.options.txtItemsPerPageWithPreview,_d9):abego.toInt(config.options.txtItemsPerPage,_d8);return (n>0)?n:1;};_f5.onPageChanged=function(){_fe();};var _101=function(){if(_de==null||!config.options.chkUseYourSearch){return;}if((_de.value==_dc)&&_dc&&!_e2()){if(_dd&&(_dd.parentNode!=document.body)){document.body.appendChild(_dd);_f2();}else{abego.YourSearch.onShowResult(true);}}};var _102=function(){_e3();_dd=null;_dc=null;};var _103=function(self,e){while(e!=null){if(self==e){return true;}e=e.parentNode;}return false;};var _104=function(e){if(e.target==_de){return;}if(e.target==_df){return;}if(_dd&&_103(_dd,e.target)){return;}_e3();};var _105=function(e){if(e.keyCode==27){_e3();}};addEvent(document,"click",_104);addEvent(document,"keyup",_105);var _106=function(text,_107,_108){_dc=text;_b3(_c5(store,text,_107,_108,"title","excludeSearch"));abego.YourSearch.onShowResult();};var _109=function(_10a,_10b,_10c,_10d,_10e,_10f){_e1();_dc="";var _110=null;var _111=function(txt){if(config.options.chkUseYourSearch){_106(txt.value,config.options.chkCaseSensitiveSearch,config.options.chkRegExpSearch);}else{story.search(txt.value,config.options.chkCaseSensitiveSearch,config.options.chkRegExpSearch);}_dc=txt.value;};var _112=function(e){_111(_de);return false;};var _113=function(e){if(!e){var e=window.event;}_de=this;switch(e.keyCode){case 13:if(e.ctrlKey&&_e0&&_e2()){_e0.onclick.apply(_e0,[e]);}else{_111(this);}break;case 27:if(_e2()){_e3();}else{this.value="";clearMessage();}break;}if(String.fromCharCode(e.keyCode)==this.accessKey||e.altKey){_101();}if(this.value.length<3&&_110){clearTimeout(_110);}if(this.value.length>2){if(this.value!=_dc){if(!config.options.chkUseYourSearch||config.options.chkSearchAsYouType){if(_110){clearTimeout(_110);}var txt=this;_110=setTimeout(function(){_111(txt);},500);}}else{if(_110){clearTimeout(_110);}}}if(this.value.length==0){_e3();}};var _114=function(e){this.select();clearMessage();_101();};var args=_10e.parseParams("list",null,true);var _115=getFlag(args,"buttonAtRight");var _116=getParam(args,"sizeTextbox",this.sizeTextbox);var btn;if(!_115){btn=createTiddlyButton(_10a,this.label,this.prompt,_112);}var txt=createTiddlyElement(null,"input",null,null,null);if(_10c[0]){txt.value=_10c[0];}txt.onkeyup=_113;txt.onfocus=_114;txt.setAttribute("size",_116);txt.setAttribute("accessKey",this.accessKey);txt.setAttribute("autocomplete","off");if(config.browser.isSafari){txt.setAttribute("type","search");txt.setAttribute("results","5");}else{txt.setAttribute("type","text");}if(_10a){_10a.appendChild(txt);}if(_115){btn=createTiddlyButton(_10a,this.label,this.prompt,_112);}_de=txt;_df=btn;};var _117=function(){_e3();var _118=_b5();var n=_118.length;if(n){var _119=[];for(var i=0;i<n;i++){_119.push(_118[i].title);}story.displayTiddlers(null,_119);}};var _11a=function(_11b,_11c,_11d,_11e){invokeMacro(_11b,"option",_11c,_11d,_11e);var elem=_11b.lastChild;var _11f=elem.onclick;elem.onclick=function(e){var _120=_11f.apply(this,arguments);_fe();return _120;};return elem;};var _121=function(s){var _122=["''","{{{","}}}","//","<<<","/***","***/"];var _123="";for(var i=0;i<_122.length;i++){if(i!=0){_123+="|";}_123+="("+_122[i].escapeRegExp()+")";}return s.replace(new RegExp(_123,"mg"),"").trim();};var _124=function(){var i=_f3;return (i>=0&&i<=9)?(i<9?(i+1):0):-1;};var _125=new abego.LimitedTextRenderer();var _126=function(_127,s,_128){_125.render(_127,s,_128,_b2.getMarkRegExp());};var _129=TiddlyWiki.prototype.saveTiddler;TiddlyWiki.prototype.saveTiddler=function(_12a,_12b,_12c,_12d,_12e,tags,_12f){_129.apply(this,arguments);_102();};var _130=TiddlyWiki.prototype.removeTiddler;TiddlyWiki.prototype.removeTiddler=function(_131){_130.apply(this,arguments);_102();};config.macros.yourSearch={label:"yourSearch",prompt:"Gives access to the current/last YourSearch result",handler:function(_132,_133,_134,_135,_136,_137){if(_134.length==0){return;}var name=_134[0];var func=config.macros.yourSearch.funcs[name];if(func){func(_132,_133,_134,_135,_136,_137);}},tests:{"true":function(){return true;},"false":function(){return false;},"found":function(){return _b6()>0;},"previewText":function(){return config.options.chkPreviewText;}},funcs:{itemRange:function(_138){if(_b6()){var _139=_f5.getLastIndexOnPage();var s="%0 - %1".format([_f5.getFirstIndexOnPage()+1,_139+1]);createTiddlyText(_138,s);}},count:function(_13a){createTiddlyText(_13a,_b6().toString());},query:function(_13b){if(_b2){createTiddlyText(_13b,_b2.toString());}},version:function(_13c){var t="YourSearch %0.%1.%2".format([version.extensions.YourSearchPlugin.major,version.extensions.YourSearchPlugin.minor,version.extensions.YourSearchPlugin.revision]);var e=createTiddlyElement(_13c,"a");e.setAttribute("href","http://tiddlywiki.abego-software.de/#YourSearchPlugin");e.innerHTML="<font color=\"black\" face=\"Arial, Helvetica, sans-serif\">"+t+"<font>";},copyright:function(_13d){var e=createTiddlyElement(_13d,"a");e.setAttribute("href","http://www.abego-software.de");e.innerHTML="<font color=\"black\" face=\"Arial, Helvetica, sans-serif\">&copy; 2005-2008 <b><font color=\"red\">abego</font></b> Software<font>";},newTiddlerButton:function(_13e){if(_b2){var r=abego.parseNewTiddlerCommandLine(_b2.getQueryText());var btn=config.macros.newTiddler.createNewTiddlerButton(_13e,r.title,r.params,"new tiddler","Create a new tiddler based on search text. (Shortcut: Ctrl-Enter; Separators: '.', '#')",null,"text");var _13f=btn.onclick;btn.onclick=function(){_e3();_13f.apply(this,arguments);};_e0=btn;}},linkButton:function(_140,_141,_142,_143,_144,_145){if(_142<2){return;}var _146=_142[1];var text=_142<3?_146:_142[2];var _147=_142<4?text:_142[3];var _148=_142<5?null:_142[4];var btn=createTiddlyButton(_140,text,_147,_e4,null,null,_148);btn.setAttribute("tiddlyLink",_146);},closeButton:function(_149,_14a,_14b,_14c,_14d,_14e){var _14f=createTiddlyButton(_149,"close","Close the Search Results (Shortcut: ESC)",_e3);},openAllButton:function(_150,_151,_152,_153,_154,_155){var n=_b6();if(n==0){return;}var _156=n==1?"open tiddler":"open all %0 tiddlers".format([n]);var _157=createTiddlyButton(_150,_156,"Open all found tiddlers (Shortcut: Alt-O)",_117);_157.setAttribute("accessKey","O");},naviBar:function(_158,_159,_15a,_15b,_15c,_15d){_f5.addPageNavigation(_158);},"if":function(_15e,_15f,_160,_161,_162,_163){if(_160.length<2){return;}var _164=_160[1];var _165=(_164=="not");if(_165){if(_160.length<3){return;}_164=_160[2];}var test=config.macros.yourSearch.tests[_164];var _166=false;try{if(test){_166=test(_15e,_15f,_160,_161,_162,_163)!=_165;}else{_166=(!eval(_164))==_165;}}catch(ex){}if(!_166){_15e.style.display="none";}},chkPreviewText:function(_167,_168,_169,_16a,_16b,_16c){var _16d=_169.slice(1).join(" ");var elem=_11a(_167,"chkPreviewText",_16a,_16c);elem.setAttribute("accessKey","P");elem.title="Show text preview of found tiddlers (Shortcut: Alt-P)";return elem;}}};config.macros.foundTiddler={label:"foundTiddler",prompt:"Provides information on the tiddler currently processed on the YourSearch result page",handler:function(_16e,_16f,_170,_171,_172,_173){var name=_170[0];var func=config.macros.foundTiddler.funcs[name];if(func){func(_16e,_16f,_170,_171,_172,_173);}},funcs:{title:function(_174,_175,_176,_177,_178,_179){if(!_f4){return;}var _17a=_124();var _17b=_17a>=0?"Open tiddler (Shortcut: Alt-%0)".format([_17a.toString()]):"Open tiddler";var btn=createTiddlyButton(_174,null,_17b,_e4,null);btn.setAttribute("tiddlyLink",_f4.title);btn.setAttribute("withHilite","true");_126(btn,_f4.title,_d4);if(_17a>=0){btn.setAttribute("accessKey",_17a.toString());}},tags:function(_17c,_17d,_17e,_17f,_180,_181){if(!_f4){return;}_126(_17c,_f4.getTags(),_d5);},text:function(_182,_183,_184,_185,_186,_187){if(!_f4){return;}_126(_182,_121(_f4.text),_d6);},field:function(_188,_189,_18a,_18b,_18c,_18d){if(!_f4){return;}var name=_18a[1];var len=_18a.length>2?abego.toInt(_18a[2],_d7):_d7;var v=store.getValue(_f4,name);if(v){_126(_188,_121(v),len);}},number:function(_18e,_18f,_190,_191,_192,_193){var _194=_124();if(_194>=0){var text="%0)".format([_194.toString()]);createTiddlyElement(_18e,"span",null,"shortcutNumber",text);}}}};var opts={chkUseYourSearch:true,chkPreviewText:true,chkSearchAsYouType:true,chkSearchInTitle:true,chkSearchInText:true,chkSearchInTags:true,chkSearchExtendedFields:true,txtItemsPerPage:_d8,txtItemsPerPageWithPreview:_d9};for(var n in opts){if(config.options[n]==undefined){config.options[n]=opts[n];}}config.shadowTiddlers.AdvancedOptions+="\n<<option chkUseYourSearch>> Use 'Your Search' //([[more options|YourSearch Options]]) ([[help|YourSearch Help]])// ";config.shadowTiddlers["YourSearch Help"]="!Field Search\nWith the Field Search you can restrict your search to certain fields of a tiddler, e.g"+" only search the tags or only the titles. The general form is //fieldname//'':''//textToSearch// (e."+"g. {{{title:intro}}}). In addition one-character shortcuts are also supported for the standard field"+"s {{{title}}}, {{{text}}} and {{{tags}}}:\n|!What you want|!What you type|!Example|\n|Search ''titles "+"only''|start word with ''!''|{{{!jonny}}} (shortcut for {{{title:jonny}}})|\n|Search ''contents/text "+"only''|start word with ''%''|{{{%football}}} (shortcut for {{{text:football}}})|\n|Search ''tags only"+"''|start word with ''#''|{{{#Plugin}}} (shortcut for {{{tags:Plugin}}})|\n\nUsing this feature you may"+" also search the extended fields (\"Metadata\") introduced with TiddlyWiki 2.1, e.g. use {{{priority:1"+"}}} to find all tiddlers with the priority field set to \"1\".\n\nYou may search a word in more than one"+" field. E.g. {{{!#Plugin}}} (or {{{title:tags:Plugin}}} in the \"long form\") finds tiddlers containin"+"g \"Plugin\" either in the title or in the tags (but does not look for \"Plugin\" in the text). \n\n!Boole"+"an Search\nThe Boolean Search is useful when searching for multiple words.\n|!What you want|!What you "+"type|!Example|\n|''All words'' must exist|List of words|{{{jonny jeremy}}} (or {{{jonny and jeremy}}}"+")|\n|''At least one word'' must exist|Separate words by ''or''|{{{jonny or jeremy}}}|\n|A word ''must "+"not exist''|Start word with ''-''|{{{-jonny}}} (or {{{not jonny}}})|\n\n''Note:'' When you specify two"+" words, separated with a space, YourSearch finds all tiddlers that contain both words, but not neces"+"sarily next to each other. If you want to find a sequence of word, e.g. '{{{John Brown}}}', you need"+" to put the words into quotes. I.e. you type: {{{\"john brown\"}}}.\n\nUsing parenthesis you may change "+"the default \"left to right\" evaluation of the boolean search. E.g. {{{not (jonny or jeremy)}}} finds"+" all tiddlers that contain neither \"jonny\" nor \"jeremy. In contrast to this {{{not jonny or jeremy}}"+"} (i.e. without parenthesis) finds all tiddlers that either don't contain \"jonny\" or that contain \"j"+"eremy\".\n\n!'Exact Word' Search\nBy default a search result all matches that 'contain' the searched tex"+"t. E.g. if you search for {{{Task}}} you will get all tiddlers containing 'Task', but also '~Complet"+"edTask', '~TaskForce' etc.\n\nIf you only want to get the tiddlers that contain 'exactly the word' you"+" need to prefix it with a '='. E.g. typing '=Task' will find the tiddlers that contain the word 'Tas"+"k', ignoring words that just contain 'Task' as a substring.\n\n!~CaseSensitiveSearch and ~RegExpSearch"+"\nThe standard search options ~CaseSensitiveSearch and ~RegExpSearch are fully supported by YourSearc"+"h. However when ''~RegExpSearch'' is on Filtered and Boolean Search are disabled.\n\nIn addition you m"+"ay do a \"regular expression\" search even with the ''~RegExpSearch'' set to false by directly enterin"+"g the regular expression into the search field, framed with {{{/.../}}}. \n\nExample: {{{/m[ae][iy]er/"+"}}} will find all tiddlers that contain either \"maier\", \"mayer\", \"meier\" or \"meyer\".\n\n!~JavaScript E"+"xpression Filtering\nIf you are familiar with JavaScript programming and know some TiddlyWiki interna"+"ls you may also use JavaScript expression for the search. Just enter a JavaScript boolean expression"+" into the search field, framed with {{{ { ... } }}}. In the code refer to the variable tiddler and e"+"valuate to {{{true}}} when the given tiddler should be included in the result. \n\nExample: {{{ { tidd"+"ler.modified > new Date(\"Jul 4, 2005\")} }}} returns all tiddler modified after July 4th, 2005.\n\n!Com"+"bined Search\nYou are free to combine the various search options. \n\n''Examples''\n|!What you type|!Res"+"ult|\n|{{{!jonny !jeremy -%football}}}|all tiddlers with both {{{jonny}}} and {{{jeremy}}} in its tit"+"les, but no {{{football}}} in content.|\n|{{{#=Task}}}|All tiddlers tagged with 'Task' (the exact wor"+"d). Tags named '~CompletedTask', '~TaskForce' etc. are not considered.|\n\n!Access Keys\nYou are encour"+"aged to use the access keys (also called \"shortcut\" keys) for the most frequently used operations. F"+"or quick reference these shortcuts are also mentioned in the tooltip for the various buttons etc.\n\n|"+"!Key|!Operation|\n|{{{Alt-F}}}|''The most important keystroke'': It moves the cursor to the search in"+"put field so you can directly start typing your query. Pressing {{{Alt-F}}} will also display the pr"+"evious search result. This way you can quickly display multiple tiddlers using \"Press {{{Alt-F}}}. S"+"elect tiddler.\" sequences.|\n|{{{ESC}}}|Closes the [[YourSearch Result]]. When the [[YourSearch Resul"+"t]] is already closed and the cursor is in the search input field the field's content is cleared so "+"you start a new query.|\n|{{{Alt-1}}}, {{{Alt-2}}},... |Pressing these keys opens the first, second e"+"tc. tiddler from the result list.|\n|{{{Alt-O}}}|Opens all found tiddlers.|\n|{{{Alt-P}}}|Toggles the "+"'Preview Text' mode.|\n|{{{Alt-'<'}}}, {{{Alt-'>'}}}|Displays the previous or next page in the [[Your"+"Search Result]].|\n|{{{Return}}}|When you have turned off the 'as you type' search mode pressing the "+"{{{Return}}} key actually starts the search (as does pressing the 'search' button).|\n\n//If some of t"+"hese shortcuts don't work for you check your browser if you have other extensions installed that alr"+"eady \"use\" these shortcuts.//";config.shadowTiddlers["YourSearch Options"]="|>|!YourSearch Options|\n|>|<<option chkUseYourSearch>> Use 'Your Search'|\n|!|<<option chkPreviewText"+">> Show Text Preview|\n|!|<<option chkSearchAsYouType>> 'Search As You Type' Mode (No RETURN required"+" to start search)|\n|!|Default Search Filter:<<option chkSearchInTitle>>Title ('!')     <<option chk"+"SearchInText>>Text ('%')     <<option chkSearchInTags>>Tags ('#')    <<option chkSearchExtendedFiel"+"ds>>Extended Fields<html><br><font size=\"-2\">The fields of a tiddlers that are searched when you don"+"'t explicitly specify a filter in the search text <br>(Explictly specify fields using one or more '!"+"', '%', '#' or 'fieldname:' prefix before the word/text to find).</font></html>|\n|!|Number of items "+"on search result page: <<option txtItemsPerPage>>|\n|!|Number of items on search result page with pre"+"view text: <<option txtItemsPerPageWithPreview>>|\n";config.shadowTiddlers["YourSearchStyleSheet"]="/***\n!~YourSearchResult Stylesheet\n***/\n/*{{{*/\n.yourSearchResult {\n\tposition: absolute;\n\twidth: 800"+"px;\n\n\tpadding: 0.2em;\n\tlist-style: none;\n\tmargin: 0;\n\n\tbackground: #ffd;\n\tborder: 1px solid DarkGra"+"y;\n}\n\n/*}}}*/\n/***\n!!Summary Section\n***/\n/*{{{*/\n.yourSearchResult .summary {\n\tborder-bottom-width:"+" thin;\n\tborder-bottom-style: solid;\n\tborder-bottom-color: #999999;\n\tpadding-bottom: 4px;\n}\n\n.yourSea"+"rchRange, .yourSearchCount, .yourSearchQuery   {\n\tfont-weight: bold;\n}\n\n.yourSearchResult .summary ."+"button {\n\tfont-size: 10px;\n\n\tpadding-left: 0.3em;\n\tpadding-right: 0.3em;\n}\n\n.yourSearchResult .summa"+"ry .chkBoxLabel {\n\tfont-size: 10px;\n\n\tpadding-right: 0.3em;\n}\n\n/*}}}*/\n/***\n!!Items Area\n***/\n/*{{{*"+"/\n.yourSearchResult .marked {\n\tbackground: none;\n\tfont-weight: bold;\n}\n\n.yourSearchItem {\n\tmargin-to"+"p: 2px;\n}\n\n.yourSearchNumber {\n\tcolor: #808080;\n}\n\n\n.yourSearchTags {\n\tcolor: #008000;\n}\n\n.yourSearc"+"hText {\n\tcolor: #808080;\n\tmargin-bottom: 6px;\n}\n\n/*}}}*/\n/***\n!!Footer\n***/\n/*{{{*/\n.yourSearchFoote"+"r {\n\tmargin-top: 8px;\n\tborder-top-width: thin;\n\tborder-top-style: solid;\n\tborder-top-color: #999999;"+"\n}\n\n.yourSearchFooter a:hover{\n\tbackground: none;\n\tcolor: none;\n}\n/*}}}*/\n/***\n!!Navigation Bar\n***/"+"\n/*{{{*/\n.yourSearchNaviBar a {\n\tfont-size: 16px;\n\tmargin-left: 4px;\n\tmargin-right: 4px;\n\tcolor: bla"+"ck;\n\ttext-decoration: underline;\n}\n\n.yourSearchNaviBar a:hover {\n\tbackground-color: none;\n}\n\n.yourSe"+"archNaviBar .prev {\n\tfont-weight: bold;\n\tcolor: blue;\n}\n\n.yourSearchNaviBar .currentPage {\n\tcolor: #"+"FF0000;\n\tfont-weight: bold;\n\ttext-decoration: none;\n}\n\n.yourSearchNaviBar .next {\n\tfont-weight: bold"+";\n\tcolor: blue;\n}\n/*}}}*/\n";config.shadowTiddlers["YourSearchResultTemplate"]="<!--\n{{{\n-->\n<span macro=\"yourSearch if found\">\n<!-- The Summary Header ============================"+"================ -->\n<table class=\"summary\" border=\"0\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\">"+"<tbody>\n  <tr>\n\t<td align=\"left\">\n\t\tYourSearch Result <span class=\"yourSearchRange\" macro=\"yourSearc"+"h itemRange\"></span>\n\t\t&nbsp;of&nbsp;<span class=\"yourSearchCount\" macro=\"yourSearch count\"></span>\n"+"\t\tfor&nbsp;<span class=\"yourSearchQuery\" macro=\"yourSearch query\"></span>\n\t</td>\n\t<td class=\"yourSea"+"rchButtons\" align=\"right\">\n\t\t<span macro=\"yourSearch chkPreviewText\"></span><span class=\"chkBoxLabel"+"\">preview text</span>\n\t\t<span macro=\"yourSearch newTiddlerButton\"></span>\n\t\t<span macro=\"yourSearch openAllButton\"></span>\n\t\t<span macro=\"yourSearch lin"+"kButton 'YourSearch Options' options 'Configure YourSearch'\"></span>\n\t\t<span macro=\"yourSearch linkB"+"utton 'YourSearch Help' help 'Get help how to use YourSearch'\"></span>\n\t\t<span macro=\"yourSearch clo"+"seButton\"></span>\n\t</td>\n  </tr>\n</tbody></table>\n\n<!-- The List of Found Tiddlers ================="+"=========================== -->\n<div id=\"yourSearchResultItems\" itemsPerPage=\"25\" itemsPerPageWithPr"+"eview=\"10\"></div>\n\n<!-- The Footer (with the Navigation) ==========================================="+"= -->\n<table class=\"yourSearchFooter\" border=\"0\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\"><tbody"+">\n  <tr>\n\t<td align=\"left\">\n\t\tResult page: <span class=\"yourSearchNaviBar\" macro=\"yourSearch naviBar"+"\"></span>\n\t</td>\n\t<td align=\"right\"><span macro=\"yourSearch version\"></span>, <span macro=\"yourSearc"+"h copyright\"></span>\n\t</td>\n  </tr>\n</tbody></table>\n<!-- end of the 'tiddlers found' case ========="+"================================== -->\n</span>\n\n\n<!-- The \"No tiddlers found\" case ================="+"========================== -->\n<span macro=\"yourSearch if not found\">\n<table class=\"summary\" border="+"\"0\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\"><tbody>\n  <tr>\n\t<td align=\"left\">\n\t\tYourSearch Resu"+"lt: No tiddlers found for <span class=\"yourSearchQuery\" macro=\"yourSearch query\"></span>.\n\t</td>\n\t<t"+"d class=\"yourSearchButtons\" align=\"right\">\n\t\t<span macro=\"yourSearch newTiddlerButton\"></span>\n\t\t<span macro=\"yourSearch linkButton 'YourSearch Options'"+" options 'Configure YourSearch'\"></span>\n\t\t<span macro=\"yourSearch linkButton 'YourSearch Help' help"+" 'Get help how to use YourSearch'\"></span>\n\t\t<span macro=\"yourSearch closeButton\"></span>\n\t</td>\n  <"+"/tr>\n</tbody></table>\n</span>\n\n\n<!--\n}}}\n-->\n";config.shadowTiddlers["YourSearchItemTemplate"]="<!--\n{{{\n-->\n<span class='yourSearchNumber' macro='foundTiddler number'></span>\n<span class='yourSea"+"rchTitle' macro='foundTiddler title'/></span>&nbsp;-&nbsp;\n<span class='yourSearchTags' macro='found"+"Tiddler field tags 50'/></span>\n<span macro=\"yourSearch if previewText\"><div class='yourSearchText' macro='fo"+"undTiddler field text 250'/></div></span>\n<!--\n}}}\n-->";config.shadowTiddlers["YourSearch"]="<<tiddler [[YourSearch Help]]>>";config.shadowTiddlers["YourSearch Result"]="The popup-like window displaying the result of a YourSearch query.";config.macros.search.handler=_109;var _195=function(){if(config.macros.search.handler!=_109){alert("Message from YourSearchPlugin:\n\n\nAnother plugin has disabled the 'Your Search' features.\n\n\nYou may "+"disable the other plugin or change the load order of \nthe plugins (by changing the names of the tidd"+"lers)\nto enable the 'Your Search' features.");}};setTimeout(_195,5000);abego.YourSearch.getStandardRankFunction=function(){return _bb;};abego.YourSearch.getRankFunction=function(){return abego.YourSearch.getStandardRankFunction();};abego.YourSearch.getCurrentTiddler=function(){return _f4;};abego.YourSearch.closeResult=function(){_e3();};abego.YourSearch.getFoundTiddlers=function(){return _b1;};abego.YourSearch.getQuery=function(){return _b2;};abego.YourSearch.onShowResult=function(_196){highlightHack=_b2?_b2.getMarkRegExp():null;if(!_196){_f5.setItems(_b5());}if(!_dd){_dd=createTiddlyElement(document.body,"div",_da,"yourSearchResult");}else{if(_dd.parentNode!=document.body){document.body.appendChild(_dd);}}_fe();highlightHack=null;};})();}
//%/
{{nocol{}}}
<<tiddler OpenStoryButton with: "Open all tiddlers tagged with attachment" "Open the attachment tiddlers to cache their source URLs">>
<!--{{{-->
<div class='toolbar' macro='toolbar [[OtherToolbarCommands::ContentViewToolbar]]'></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>
<span macro="sectionTOC"></span>
<div id="Notes" class='notes viewer' macro='notes heading:Notebook tag:"Notes excludeLists noReload" suffix:Notes'></div>
<div class='tagClear'></div>
<!--}}}-->
<!--{{{-->
<div class='toolbar' macro='toolbar [[OtherToolbarCommands::ContentViewToolbar]]'></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 id="Notes" class='notes viewer' macro='notes heading:Notebook tag:"Notes excludeLists noReload" suffix:Notes'></div>
<div class='tagClear'></div>
<!--}}}-->
To synchronize your {{{content}}} and {{{structure}}} tiddlers use the import button below. It will import all the updated tiddlers from the source site while preserving your notes.

<<loadTiddlers "label:Import new content from %0" updates {{store.getTiddlerSlice('GettingStarted','courseHomeContent')}} >>

If you want you can also manually import particular tiddlers using the import tool in  the backstage menu after seeing which tiddlers have been updated by looking at the ContentChanges tiddler.

After performing an update you may want to visit DeletedTiddler to remove/clean up any tiddlers that have been superseded and are no longer necessary. You can also display the removed tiddlers and copy any notes you may have before deleting the tiddlers.
/***
See also [[StorySaverPluginConfig]].
***/
/***
! Implementing excludeOrphans

Add the functionality for an excludeOrphans tag similar to excludeMissing. When a tiddler is tagged with excludeOrphans, it won't be shown as an orphan even if there are no referrers to it. It's used to allow top level tiddlers (like story tiddlers) to be referenced by the result of a search rather than hard coded into tiddlers.

Ideas from: [[Searching for excludeOrphans tag functionality|http://groups.google.com/group/TiddlyWiki/browse_thread/thread/39f7be322883586e/2a19fc0a30a6c3ee]].
***/
//{{{
var orig = TiddlyWiki.prototype.getOrphans;
TiddlyWiki.prototype.getOrphans = function() {
     var results = [];
     var orphans = orig.apply(this, arguments);

     for (var i=0;i<orphans.length;i++) {
       var title = orphans[i];
       var tiddler = store.getTiddler(title); 
       if(this.getReferringTiddlers(title).length == 0 &&
             !tiddler.isTagged("excludeLists") &&
             !tiddler.isTagged("excludeOrphans")) {
                        results.push(title);
         }
     }
     results.sort();
     return results;
}; 
//}}}

/***
! Set the shadow DefaultTiddlers for Coursebook

Set the Welcome tiddler as the default tiddlers when student coursebook opens.
Set a default Instructor main menu to suppress missing tiddler report when editing
coursebook with instructor/editing style sheet and macro definitions.
***/
//{{{
config.shadowTiddlers.DefaultTiddlers = "[[Welcome]]";
config.shadowTiddlers.InstructorMainMenu = "";
//}}}

/***
! Make Unsaved Changes active in the SideBarOptions

Add call to < <unsavedChanges command> > to sidebar right before saveChanges
***/
//{{{
config.shadowTiddlers.SideBarOptions=config.shadowTiddlers.SideBarOptions.replace('<<saveChanges>>','<<unsavedChanges command>><<saveChanges>>');
//}}}

/***
! Closing a tiddler moves back to tiddler that it was linked from

From http://groups.google.com/group/tiddlywiki/browse_thread/thread/05719eb737c9ae22/fa2cff7e65fa2cb8?#fa2cff7e65fa2cb8:
{{{
From: FND <F...@gmx.net>
Date: Thu, 03 Sep 2009 17:44:55 +0100
Local: Thurs, Sep 3 2009 12:44 pm 
Subject: Re: [tw] Re: Close tiddler and go back to the one which opened it? Any thoughts?
Reply | Reply to author | Forward | Print | Individual message | Show original | Report this message | Find messages by this author 
You could try this quick hack: 
--------------- 
}}}
***/
//{{{
(function() {

var _closeTiddler = config.commands.closeTiddler.handler;
config.commands.closeTiddler.handler = function(event, src, title) {
     var tiddlerElem = story.getTiddler(title);
     var origin = tiddlerElem.getAttribute("origin");
     origin = tiddlerElem ? story.getTiddler(origin) : null;
     var status = _closeTiddler.apply(this, arguments);
     if(origin) {
         if(config.options.chkAnimate) {
             anim.startAnimating(new Zoomer(title, tiddlerElem, origin),
                 new Scroller(origin));
         } else {
             window.scrollTo(0,ensureVisible(origin));
         }
     }
     return status;

};

var _onClickTiddlerLink = onClickTiddlerLink;
onClickTiddlerLink = function(ev) {
     var status = _onClickTiddlerLink.apply(this, arguments);
     var target = resolveTarget(ev || window.event);
     var link = target;
     do {
         title = link.getAttribute("tiddlyLink");
         link = link.parentNode;
     } while(title === null && link !== null);
     var el = story.getTiddler(title);
     var origin = story.findContainingTiddler(target);
     origin = origin ? origin.getAttribute("tiddler") : null;
     el.setAttribute("origin", origin);
     return status;

};
})();
//}}}

/***
! Set an off mode for the Tabs in the sidebar

***/
//{{{
config.shadowTiddlers.SideBarTabs=config.shadowTiddlers.SideBarTabs.replace('<<tabs txtMainTab','<<tabs txtMainTab "Off" "A blank tab" ""');

//}}}

/***
! Define isFirefox config.browser option

To determine if this is running within firefox.
***/
//{{{
config.browser.isFirefox = navigator.userAgent.indexOf('Firefox') != -1;
//}}}