<!--{{{-->
<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 0em 1em 1em; left:-1px; top:-1px;}
.headerForeground {position:absolute; padding:4.5em 0em 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:0em 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 .3em 0;}
#sidebarTabs .tabContents {width:15em; overflow:hidden;}

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

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

.tiddlerPopupButton {padding:0.2em 0.2em 0.2em 0.2em;}
.popupTiddler {position: absolute; z-index:300; padding:1em 1em 1em 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 0em;}
.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 0em 0em 0.5em;}
.tab {margin:0em 0em 0em 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 0em 14em;}

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

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

.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:0em 0.25em; padding:0em 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 0em; font-size:.9em;}
.editorFooter .button {padding-top:0px; padding-bottom:0px;}

.fieldsetFix {border:0; padding:0; margin:1px 0px 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 0.3em 0.5em;}
#backstageToolbar {position:relative;}
#backstageArea a {font-weight:bold; margin-left:0.5em; padding:0.3em 0.5em 0.3em 0.5em;}
#backstageButton {display:none; position:absolute; z-index:175; top:0em; right:0em;}
#backstageButton a {padding:0.1em 0.4em 0.1em 0.4em; margin:0.1em 0.1em 0.1em 0.1em;}
#backstage {position:relative; width:100%; z-index:50;}
#backstagePanel {display:none; z-index:100; position:absolute; width:90%; margin:0em 3em 0em 3em; padding:1em 1em 1em 1em;}
.backstagePanelFooter {padding-top:0.2em; float:right;}
.backstagePanelFooter a {padding:0.2em 0.4em 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 1em;}
/* Fixes a feature in Firefox 1.5.0.2 where print preview displays the noscript content */
noscript {display:none;}
}
/*}}}*/
<!--{{{-->
<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'></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>>
A minute about an event recorded as a journal entry using the ''new journal'' command.

Type the text for '2008.08.31 13:11:45'
Type the text for '31 August 2008'
|Name|~TiddlyTimeJournal|
| Description|A simple tool to help you keep a journal of where your time goes|
| Version|0.9 beta|
| Date|<<today>>|
| Source|http://ttj.wombatdiet.net|
| Author|Eats Wombats|
| Email|eatswombats (at) wombatdiet (dot) net|
| License|[img[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/images/public/somerights20][http://creativecommons.org/licenses/by-sa/3.0/]]|

~TiddlyTimeJournal is based upon ~TiddlyWiki <<version>>, written by Jeremy Ruston, &copy;2005 Osmosoft Limited, published under a BSD open source license. Redistribution and Use in source and binary forms, with or without Modification are granted, unless otherwise noted, subject to the terms and conditions of the license (click on the image above for details).

''Core:'' Tiddlywiki <<version>> http://www.tiddlywiki.com

''Plugins''

TaskTimerPlugin 1.3.0 by Eric Shulman
[[Clock2]] 1.06 by Simon Baird
BetterTimelineMacro 0.5b by Saq Imtiaz; requires DeprecatedFunctionsPlugin with TW 2.4.1
DeprecatedFunctionsPlugin
InstantTimestamp 1.0.4 by Simon Baird
LessBackupsPlugin 3.0.1 by Simon Baird
LinkToMeMacro by Simon Baird
SaveOnExitPlugin 2.0 by Eric Shulman
ForEachTiddlerPlugin 1.0.8 by Udo Borkowski
ForEachTiddlerMacro 1.0.8 by Udo Borkowski; 
ToggleSideBarMacro 1.0 by Saq Imtiaz

''Customizations You May Wish To Make''
*To adjust the number of backups made when you save changes: click here: LessBackupsPlugin, and edit as required. 
*Likewise, the date format for timestamps can be changed by editing the InstantTimestamp plugin. Date format information [[here|http://tiddlywiki.com/#DateFormatString]].
!Version History

0.9 beta 1; TW 2.4.1 {{ds{2008-08-18}}}

{{systemcontents scrollauto{
|//Date//|//Description//|//Started//|//Stopped//|//Elapsed//|
|2008-08-18|First|02:47:04|02:47:10|00:00:06|
|2008-08-29| Procrastination|22:58:32|22:59:10|00:00:37|
|2008-08-30|phone|02:43:52|02:44:06|00:00:14|
|2008-09-25|test|11:34:03|11:34:15|00:00:12|
|2008-09-25|Time wasted|21:30:30|21:30:45|00:00:14|
|2008-09-27|testing|01:25:21|01:25:36|00:00:14|
|2008-09-27|Another test|03:26:18|03:26:34|00:00:16|
|2008-09-27| test|09:00:16|09:00:54|00:00:37|
|2008-09-27|Last test|09:25:35|09:25:52|00:00:16|
|2008-10-02|test|07:08:02|07:08:10|00:00:08|
|2008-10-02|test|08:18:16|08:18:23|00:00:07|
|2008-10-02| |11:14:53|11:14:55|00:00:02|
|2008-10-02| |12:02:54|12:02:57|00:00:02|
/%tasktimer%/
}}}
!!!!!<<gradient horiz #fcb #fff>>&nbsp;AllTabs>>
<<list all>>
I created TTJ because I couldn't find, quickly, a //simple, elegant and free// application to help me keep a time journal. At first, I wanted something that would run in Vista's taskbar, or, better, a Yahoo desktop or an Opera browser widget.

There are countless time recording and activity logging applications out there whose focus is on invoicing -- on the attribution of billable hours. Many are expensive. Some are large (e.g., [[TimeStation|http://www.timestation.dataflower.net]]). Most are old Windows applications of uncertain origin and security. A lot are simply unattractive for the price. There may be some freely available gems, but who can find them amidst the dross?

What if you are a student or someone whose time isn't billed? What if your concern is not ''billable hours'' but simply monitoring your ''focus'', managing your attention and being aware of, and hopefully minimising, the impact of interruptions of various kinds? What if you work on more than one kind of computer? 

<html><font size=4><b>With TiddlyTimeJournal you can</b></font></html>
* Quickly and easily record time expended on various activities //and interruptions// with a minimum of keystrokes
* Rapidly record date & time stamped events and milestones in an event log
* Create date & time stamped notes instantly (click ''new journal'' on the right menu bar)
It runs on @@any@@ computer that runs Firefox. ~TiddlyTimeJournal uses a clock animation that is not compatible with Internet Explorer, but this doesn't affect the rest of its functionality.

Click here for some [[Tips]]. You're welcome to send me yours, especially if you find a better mousetrap.

config.messages.backstage = {
	open: {text: " ", tooltip: "Open the backstage tools."},
	close: {text: " ", tooltip: "Close the backstage area"},
	prompt: " ",
decal: {
		edit: {text: "edit", tooltip: "Edit the tiddler '%0'"}
}
};
config.messages.backstage = {
	open: {text: " ", tooltip: "Open the backstage tools."},
	close: {text: " ", tooltip: "Close the backstage area"},
	prompt: "backstage: ",
	decal: {
		edit: {text: "edit", tooltip: "Edit the tiddler '%0'"}
	}
};

Source: [[SideSnips|file:///H:/SideSnip/sidesnips-try.html#BackstageButtonConfig]]
/***
!!!<<gradient horiz #fc3 #fff >><<tiddler RefreshStyles>>&nbsp;BackstageCSS>>/%==================================================%/
***/



#backstageArea {background-color:#00a;font-size:8pt;}
#backstageArea a {background-color:#abf;color:#000; border:none;}
#backstageArea a:hover {background:#fff; color:#f00; }
#backstageArea a.backstageSelTab {background:#abf; color:#fff;}
#backstageButton {background:transparent; font-size:9pt;}
#backstageButton a {background:transparent; color:#000; border:none;}
#backstageButton a:hover {background:#fff;color:#f00; border:none;}
#backstagePanel {background:#abf; color:#000; border-color:#fcf ;width:50em;}
#backstagePanel a {color:#00f;}
#backstagePanel a:hover {background:#eee;color:#f00;  border:#f00 solid 1px;}
.backstagePanelFooter .button {border:none; color:#fcf ;}
.backstagePanelFooter .button:hover {color:#0f0;}


#backstageCloak {background:[[ColorPalette::Foreground]]; opacity:0.5; filter:'alpha(opacity:50)';}
#backstageArea { width:100%;display:none; position:relative; overflow: hidden; z-index:150; padding:0.2em 0.5em 0.2em 0.5em;margin-left:auto;margin-right:auto;}

#backstageToolbar {position:relative; width:60%;margin-left:0;margin-right:auto;}
#backstageButton {display:none; position:absolute; z-index:175; top:0em; margin-right:auto;margin-left:auto; padding:0.1em 0.5em 0.2em 0.5em;}

#backstageArea a {font-weight:normal; margin-left:0.5em; padding:0.2em 0.5em 0.2em 0.5em;}

#backstage {position:relative; width:100%;}

#backstagePanel {display:none; z-index:100; position:absolute; margin:0em 3em 0em 0.2em; padding:1em 1em 1em 1em;}
.backstagePanelFooter {padding-top:0.2em; float:right;}
.backstagePanelFooter a {padding:0.2em 0.4em 0.2em 0.4em;}
#backstageCloak {display:none; z-index:50; position:absolute; width:100%; height:100px;}

.contentWrapper {margin-top:0em;
}



.popup {position: absolute;  z-index:0; font-size:.9em; padding:0; list-style-type: decimal; margin:-1.0em;}

config.tasks.viewTabs = {
	text: "ViewTabs",
	tooltip: "A custom backstage tab",
	content: "|width:18em;<<tiddler ViewTabs>><<tiddler MoreTools>>|"
};
config.backstageTasks.splice(config.backstageTasks.indexOf("save")+0,0,"viewTabs");
config.tasks.sidebaroptions = {
	text: "SideBarOptions",
	tooltip: "A custom backstage tab",
	content: "|width:30em;<<tiddler SideBarOptions>><<tiddler SideBarTabs>>|"
};
config.backstageTasks.push("sidebaroptions");
/***
!!!Adjustments to Backstage appearances
***/
//{{{
if (config.tasks!=undefined) { // TW2.2B3 or above

// hide "backstage/close" text, use alternative glyphs
config.messages.backstage.open.text="";
config.messages.backstage.close.text="";
config.glyphs.codes.bentArrowLeft=["\u00ab","\u00ab"]; // left double-angle quote (&laquo;)
config.glyphs.codes.bentArrowRight=["\u00bb","\u00bb"]; // right double-angle quote (&raquo;)
// config.glyphs.codes.downTriangle=["\u25bc","\u25bc"]; // down triangle

// adjust backstage panel styles
setStylesheet("\
	#backstagePanel \
		{ background:#eee !important; padding:.5em; \
		border:2px solid; border-width-top:0px; \
		-moz-border-radius-bottomleft:1em; -moz-border-radius-bottomright:1em} \
	#backstageButton \
		{ font-size:9pt; } \
	#backstageArea \
		{ font-size:7pt; } \
	","BackstageTweaks");

// Hijack backstage.init() to add "mouseover" class to backstage button
backstage.save_init=backstage.init;
backstage.init=function() {
	this.save_init.apply(this,arguments);
	var btn=document.getElementById("backstageShow");
	if (btn && (addClass instanceof Function)) addClass(btn,"mouseover");
}

} // end if (config.tasks)
//}}}
!!!!!<<gradient horiz #fcb #fff>>&nbsp;[[BasicTabs]]>>
@@color:#C06;''&raquo; &raquo;'' @@ Tabs for basic Sidebar
----
{{systemcontents{
<script>
// get all tiddlers tagged with "basic"
var tids=store.getTaggedTiddlers("basic");
// keep only tiddlers *also* tagged with New
var list=[];
for (var t=0; t<tids.length; t++)
   if (tids[t].isTagged("basic")) list.push(tids[t]);
// create output list of tiddler titles, one per line
var out="";
for (var t=0; t<list.length; t++) out+="#[["+list[t].title+"]]\n";
return out;
</script> 
}}}
/***
|Name|BetterTimelineMacro|
|Created by|SaqImtiaz|
|Location|http://tw.lewcid.org/#BetterTimelineMacro|
|Version|0.5 beta|
|Requires|~TW2.x|
!!!Description:
A replacement for the core timeline macro that offers more features:
*list tiddlers with only specfic tag
*exclude tiddlers with a particular tag
*limit entries to any number of days, for example one week
*specify a start date for the timeline, only tiddlers after that date will be listed.

!!!Installation:
Copy the contents of this tiddler to your TW, tag with systemConfig, save and reload your TW.
Edit the ViewTemplate to add the fullscreen command to the toolbar. 

(Ignore last instruction. Not needed. Depends on another Lewcid extension and this was not indicated -- EW)

!!!Syntax:
{{{<<timeline better:true>>}}}
''the param better:true enables the advanced features, without it you will get the old timeline behaviour.''

additonal params:
(use only the ones you want)
{{{<<timeline better:true  onlyTag:Tag1 excludeTag:Tag2 sortBy:modified/created firstDay:YYYYMMDD maxDays:7 maxEntries:30>>}}}

Note: Use this to replace the contents of the ShadowTiddler TabTimeline -- EW

''explanation of syntax:''
onlyTag: only tiddlers with this tag will be listed. Default is to list all tiddlers.
excludeTag: tiddlers with this tag will not be listed.
sortBy: sort tiddlers by date modified or date created. Possible values are modified or created.
firstDay: useful for starting timeline from a specific date. Example: 20060701 for 1st of July, 2006
maxDays: limits timeline to include only tiddlers from the specified number of days. If you use a value of 7 for example, only tiddlers from the last 7 days will be listed.
maxEntries: limit the total number of entries in the timeline.


!!!History:
*28-07-06: ver 0.5 beta, first release

!!!Code
***/
//{{{
// Return the tiddlers as a sorted array
TiddlyWiki.prototype.getTiddlers = function(field,excludeTag,includeTag)
{
          var results = [];
          this.forEachTiddler(function(title,tiddler)
          {
          if(excludeTag == undefined || tiddler.tags.find(excludeTag) == null)
                        if(includeTag == undefined || tiddler.tags.find(includeTag)!=null)
                                      results.push(tiddler);
          });
          if(field)
                   results.sort(function (a,b) {if(a[field] == b[field]) return(0); else return (a[field] < b[field]) ? -1 : +1; });
          return results;
}



//this function by Udo
function getParam(params, name, defaultValue)
{
          if (!params)
          return defaultValue;
          var p = params[0][name];
          return p ? p[0] : defaultValue;
}

window.old_timeline_handler= config.macros.timeline.handler;
config.macros.timeline.handler = function(place,macroName,params,wikifier,paramString,tiddler)
{
          var args = paramString.parseParams("list",null,true);
          var betterMode = getParam(args, "better", "false");
          if (betterMode == 'true')
          {
          var sortBy = getParam(args,"sortBy","modified");
          var excludeTag = getParam(args,"excludeTag",undefined);
          var includeTag = getParam(args,"onlyTag",undefined);
          var tiddlers = store.getTiddlers(sortBy,excludeTag,includeTag);
          var firstDayParam = getParam(args,"firstDay",undefined);
          var firstDay = (firstDayParam!=undefined)? firstDayParam: "00010101";
          var lastDay = "";
          var field= sortBy;
          var maxDaysParam = getParam(args,"maxDays",undefined);
          var maxDays = (maxDaysParam!=undefined)? maxDaysParam*24*60*60*1000: (new Date()).getTime() ;
          var maxEntries = getParam(args,"maxEntries",undefined);
          var last = (maxEntries!=undefined) ? tiddlers.length-Math.min(tiddlers.length,parseInt(maxEntries)) : 0;
          for(var t=tiddlers.length-1; t>=last; t--)
                  {
                  var tiddler = tiddlers[t];
                  var theDay = tiddler[field].convertToLocalYYYYMMDDHHMM().substr(0,8);
                  if ((theDay>=firstDay)&& (tiddler[field].getTime()> (new Date()).getTime() - maxDays))
                     {
                     if(theDay != lastDay)
                               {
                               var theDateList = document.createElement("ul");
                               place.appendChild(theDateList);
                               createTiddlyElement(theDateList,"li",null,"listTitle",tiddler[field].formatString(this.dateFormat));
                               lastDay = theDay;
                               }
                  var theDateListItem = createTiddlyElement(theDateList,"li",null,"listLink",null);
                  theDateListItem.appendChild(createTiddlyLink(place,tiddler.title,true));
                  }
                  }
          }

          else
              {
              window.old_timeline_handler.apply(this,arguments);
              }
}
//}}}
/***
!!!<<gradient horiz #fc3 #fff >><<tiddler RefreshStyles>>&nbsp;ButtonStyle>>/%==================================================%/
***/


input.btn{
   color:#000;
   font-family:Trebuchet MS,aerial,helvetica,sans-serif;
   font-size:100%;
   font-weight:normal;
   background:url("http://img520.imageshack.us/img520/8688/mainmenugray7ef.gif") repeat-x top left;top left;
  background-color:#eee;
   border:1px solid;
   border-top-color:#000;
   border-left-color:#000;
   border-right-color:#000;
   border-bottom-color:#000;
   -moz-border-radius : .25em 0.25em 0.25em 0.25em;
}


input.btnhov{
   color:#a00;
   background:#fff;
   background:url("http://img520.imageshack.us/img520/8688/mainmenugray7ef.gif") repeat-x top left;top left;
   border-top-color:#c06;
   border-left-color:#c06;
   border-right-color:#c06;
   border-bottom-color:#c06;
   -moz-border-radius : .25em 0.25em 0.25em 0.25em;
}
merge(config.macros.saveChanges,{
	label: "save",
	prompt: "Save all tiddlers to create a new TiddlyWiki",
	accessKey: "S"});

merge(config.macros.newTiddler,{
	label: "tiddler",
	prompt: "Create a new tiddler",
	title: "New Tiddler",
	accessKey: "N"});

merge(config.macros.newJournal,{
	label: "journal",
	prompt: "Create a new tiddler from the current date and time",
	accessKey: "J"});
/***
| Name:|Clock2|
| Author:|Simon Baird|
| Description:|A skinnable, sizeable analog clock|
| Source:|http://tiddlyspot.com/mptw/#Clock2|
| Requires:|Firefox 1.5.x or maybe Safari|
| Version:|1.0.6|
| Date:|8-Jul-2008|
!!Note
* Does not work in IE or Opera due to lack of canvas support.
* If you make a nice skin send it to me and I will include it here.
*I'm not actively maintaining this plugin
* See also http://randomibis.com/coolclock/
!!Ideas
* Can we support IE with this? http://sourceforge.net/projects/excanvas
* Skin should specify order of drawing so things can be on top of other things
* Fix it so we can have filled and/or stroked elements
* Skin should allow any number of moving and static elements
* Make download and example for non-TW use
* Make floating draggable?
!!Examples
{{{
<<clock2 fancy>><<clock2 120>>
<<clock2 chunkySwiss>> <<clock2 60 chunkySwiss noSeconds>><<clock2 '{
	outerBorder: { lineWidth: 60, radius:55, color: "#dd8877", alpha: 1 },
	smallIndicator: { lineWidth: 4, startAt: 80, endAt: 95, color: "white", alpha: 1 },
	largeIndicator: { lineWidth: 12, startAt: 77, endAt: 89, color: "#dd8877", alpha: 1 },
	hourHand: { lineWidth: 15, startAt: -15, endAt: 50, color: "white", alpha: 1 },
	minuteHand: { lineWidth: 10, startAt: 24, endAt: 200, color: "#771100", alpha: 0.6 },
	secondHand: { lineWidth: 3, startAt: 22, endAt: 83, color: "green", alpha: 0 },
	secondDecoration: { lineWidth: 1, startAt: 52, radius: 26, fillColor: "white", color: "red", alpha: 0.2 }
}'>>

}}}
<<clock2 fancy>><<clock2 120>>
<<clock2 chunkySwiss>> <<clock2 60 chunkySwiss noSeconds>><<clock2 '{
	outerBorder: { lineWidth: 60, radius:55, color: "#dd8877", alpha: 1 },
	smallIndicator: { lineWidth: 4, startAt: 80, endAt: 95, color: "white", alpha: 1 },
	largeIndicator: { lineWidth: 12, startAt: 77, endAt: 89, color: "#dd8877", alpha: 1 },
	hourHand: { lineWidth: 15, startAt: -15, endAt: 50, color: "white", alpha: 1 },
	minuteHand: { lineWidth: 10, startAt: 24, endAt: 200, color: "#771100", alpha: 0.6 },
	secondHand: { lineWidth: 3, startAt: 22, endAt: 83, color: "green", alpha: 0 },
	secondDecoration: { lineWidth: 1, startAt: 52, radius: 26, fillColor: "white", color: "red", alpha: 0.2 }
}'>>

See also BigClock.
!!Code
***/
//{{{

window.CoolClock = function(canvasId,displayRadius,skinId,showSecondHand) {
	return this.init(canvasId,displayRadius,skinId,showSecondHand);
}

CoolClock.config = {
	clockTracker: {},
	tickDelay: 1000,
	longTickDelay: 15000,
	defaultRadius: 85,
	renderRadius: 100,
	defaultSkin: "swissRail",
	skins:	{
		// try making your own...
		swissRail: {
			outerBorder: { lineWidth: 1, radius:95, color: "black", alpha: 1 },
			smallIndicator: { lineWidth: 2, startAt: 89, endAt: 93, color: "black", alpha: 1 },
			largeIndicator: { lineWidth: 4, startAt: 80, endAt: 93, color: "black", alpha: 1 },
			hourHand: { lineWidth: 8, startAt: -15, endAt: 50, color: "black", alpha: 1 },
			minuteHand: { lineWidth: 7, startAt: -15, endAt: 75, color: "black", alpha: 1 },
			secondHand: { lineWidth: 1, startAt: -20, endAt: 85, color: "red", alpha: 1 },
			secondDecoration: { lineWidth: 1, startAt: 70, radius: 4, fillColor: "red", color: "red", alpha: 1 }
		},
		chunkySwiss: {
			outerBorder: { lineWidth: 5, radius:97, color: "black", alpha: 1 },
			smallIndicator: { lineWidth: 4, startAt: 89, endAt: 93, color: "black", alpha: 1 },
			largeIndicator: { lineWidth: 8, startAt: 80, endAt: 93, color: "black", alpha: 1 },
			hourHand: { lineWidth: 12, startAt: -15, endAt: 60, color: "black", alpha: 1 },
			minuteHand: { lineWidth: 10, startAt: -15, endAt: 85, color: "black", alpha: 1 },
			secondHand: { lineWidth: 4, startAt: -20, endAt: 85, color: "red", alpha: 1 },
			secondDecoration: { lineWidth: 2, startAt: 70, radius: 8, fillColor: "red", color: "red", alpha: 1 }
		},
		fancy: {
			outerBorder: { lineWidth: 5, radius:95, color: "green", alpha: 0.7 },
			smallIndicator: { lineWidth: 1, startAt: 80, endAt: 93, color: "black", alpha: 0.4 },
			largeIndicator: { lineWidth: 1, startAt: 30, endAt: 93, color: "black", alpha: 0.5 },
			hourHand: { lineWidth: 8, startAt: -15, endAt: 50, color: "blue", alpha: 0.7 },
			minuteHand: { lineWidth: 7, startAt: -15, endAt: 92, color: "red", alpha: 0.7 },
			secondHand: { lineWidth: 10, startAt: 80, endAt: 85, color: "blue", alpha: 0.3 },
			secondDecoration: { lineWidth: 1, startAt: 30, radius: 50, fillColor: "blue", color: "red", alpha: 0.15 }
		}
	}
};

CoolClock.prototype = {
	init: function(canvasId,displayRadius,skinId,showSecondHand) {
		this.canvasId = canvasId;
		this.displayRadius = displayRadius || CoolClock.config.defaultRadius;
		this.skinId = skinId || CoolClock.config.defaultSkin;
		this.showSecondHand = typeof showSecondHand == "boolean" ? showSecondHand : true;
		this.tickDelay = CoolClock.config[ this.showSecondHand ? "tickDelay" : "longTickDelay"];

		this.canvas = document.getElementById(canvasId);
		this.canvas.setAttribute("width",this.displayRadius*2);
		this.canvas.setAttribute("height",this.displayRadius*2);

		this.renderRadius = CoolClock.config.renderRadius; 

		var scale = this.displayRadius / this.renderRadius;
		this.ctx = this.canvas.getContext("2d");
		this.ctx.scale(scale,scale);

		CoolClock.config.clockTracker[canvasId] = this;
		this.tick();
		return this;
	},

	fullCircle: function(skin) {
		this.fullCircleAt(this.renderRadius,this.renderRadius,skin);
	},

	fullCircleAt: function(x,y,skin) {
		with (this.ctx) {
			save();
			globalAlpha = skin.alpha;
			lineWidth = skin.lineWidth;
			if (!document.all)
				beginPath();
			arc(x, y, skin.radius, 0, 2*Math.PI, false);
			if (skin.fillColor) {
				fillStyle = skin.fillColor
				fill();
			}
			else {
				// XXX why not stroke and fill
				strokeStyle = skin.color;
				stroke();
			}
			restore();
		}
	},

	radialLineAtAngle: function(angleFraction,skin) {
		with (this.ctx) {
			save();
			translate(this.renderRadius,this.renderRadius);
			rotate(Math.PI * (2 * angleFraction - 0.5));
			globalAlpha = skin.alpha;
			strokeStyle = skin.color;
			lineWidth = skin.lineWidth;
			if (skin.radius) {
				this.fullCircleAt(skin.startAt,0,skin)
			}
			else {
				beginPath();
				moveTo(skin.startAt,0)
				lineTo(skin.endAt,0);
				stroke();
			}
			restore();
		}
	},

	render: function(hour,min,sec) {
		var skin = CoolClock.config.skins[this.skinId];
		this.ctx.clearRect(0,0,this.renderRadius*2,this.renderRadius*2);

		this.fullCircle(skin.outerBorder);

		for (var i=0;i<60;i++)
			this.radialLineAtAngle(i/60,skin[ i%5 ? "smallIndicator" : "largeIndicator"]);
				
		this.radialLineAtAngle((hour+min/60)/12,skin.hourHand);
		this.radialLineAtAngle((min+sec/60)/60,skin.minuteHand);
		if (this.showSecondHand) {
			this.radialLineAtAngle(sec/60,skin.secondHand);
			this.radialLineAtAngle(sec/60,skin.secondDecoration);
		}
	},


	nextTick: function() {
		setTimeout("CoolClock.config.clockTracker['"+this.canvasId+"'].tick()",this.tickDelay);
	},

	stillHere: function() {
		return document.getElementById(this.canvasId) != null;
	},

	refreshDisplay: function() {
		var now = new Date();
		this.render(now.getHours(),now.getMinutes(),now.getSeconds());
	},

	tick: function() {
		if (this.stillHere()) {
			this.refreshDisplay()
			this.nextTick();
		}
	}
}



config.macros.clock2 = {
	counter: 0,
	handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		var size,skin,seconds,skinData;
		for (var i=0;i<params.length;i++)
			if (/^\d+$/.exec(params[i]))
				size = params[i];
			else if (params[i] == "noSeconds")
				seconds = false;
			else if (/^\{/.exec(params[i]))
				eval("skinData = " + params[i]);
			else
				skin = params[i];
		if (skinData) {
			CoolClock.config.skins.customSkin = skinData;
			skin = "customSkin";
		}
		var canvas = createTiddlyElement(place,"canvas","clockcanvas"+this.counter);
		var clock = new CoolClock("clockcanvas"+this.counter,size,skin,seconds);
		this.counter++;
	}
}

//}}}
/***
|Name|CoreTweaks|
|Source|http://www.TiddlyTools.com/#CoreTweaks|
|Version|n/a|
|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.2.4|
|Type|plugin|
|Requires||
|Overrides|various|
|Description|a small collection of overrides to TW core functions|
This tiddler contains some quick tweaks and modifications to TW core functions to provide minor changes in standard features or behavior.  It is hoped that some of these tweaks may be incorporated into later versions of the TW core, so that these adjustments will be available without needing these add-on definitions. ''Note: the changes contained in this tiddler are generally applicable for the current version of TiddlyWiki (<<version>>)./% Please view [[CoreTweaksArchive]] for tweaks and modifications that may be used with earlier versions of TiddlyWiki.%/''

To install //all// of these tweaks, import (or copy/paste) this tiddler into your document.  To include only //some// of the tweaks, you can edit the imported tiddler to remove the tweaks that you don't want.  Alternatively, you could copy/paste a few selected tweaks from this tiddler into a tiddler that you create in your own document.  Be certain to tag that tiddler with<<tag systemConfig>> (i.e., a plugin tiddler) and then save-and-reload for the tweaks to take effect.
***/
/***
!!! Ticketed Tweaks
***/
// // {{groupbox small{
// // http://trac.tiddlywiki.org/ticket/628 - OPEN
// // When invoking a macro that is not defined, this tweak prevents the display of the "error in macro... no such macro" message.  This is useful when rendering tiddler content or templates that reference macros that are defined by //optional// plugins that have not been installed in the current document.
// //
// // <<option chkHideMissingMacros>> hide "no such macro" error messages
//{{{
if (config.options.chkHideMissingMacros===undefined)
	config.options.chkHideMissingMacros=false;

window.coreTweaks_missingMacro_invokeMacro = window.invokeMacro;
window.invokeMacro = function(place,macro,params,wikifier,tiddler) {
	if (!config.macros[macro] || !config.macros[macro].handler)
		if (config.options.chkHideMissingMacros) return;
	window.coreTweaks_missingMacro_invokeMacro.apply(this,arguments);
}
//}}}
// // }}}
// // {{groupbox small{
// // http://trac.tiddlywiki.org/ticket/623 - OPEN
/***
This tweak allows date format strings to contain backslash-quoted characters that bypass date format replacement.  This allows sequences such as "s\s", "m\m" or "a\m" to be used so that "ss", "mm" or "am" can appears as literal text within journal titles or other date-formatted values.

For example:
>{{{<<today "withhold less hummingbirds - YYYY.0MM.0DD 0hh:0mm:0ss">>}}}
>results in: <<today "withhold less hummingbirds - YYYY.0MM.0DD 0hh:0mm:0ss">>
while:
>{{{<<today "with\hold les\s hum\mingbirds - YYYY.0MM.0DD 0hh:0mm:0ss">>}}}
>results in: <<today "with\hold les\s hum\mingbirds - YYYY.0MM.0DD 0hh:0mm:0ss">>
***/
//{{{
Date.prototype.coreTweaks_formatString = Date.prototype.formatString;
Date.prototype.formatString = function(template) {
	var t = Date.prototype.coreTweaks_formatString.apply(this,arguments);
	t = t.replace(/\\/g,""); // strip backslashes used to quote formats
	return t;
};
//}}}
// // }}}
// // {{groupbox small{
// // http://trac.tiddlywiki.org/ticket/609 - OPEN (separators)
// // http://trac.tiddlywiki.org/ticket/610 - OPEN (wikify tiddler/slice/section content)
// // These tweaks extend the {{{<<toolbar>>}}} macro to permit use of "|" as separators, as well as recognizing references to tiddlernames, slices, or sections and rendering their content inline within the toolbar
// // ''see [[ToolbarCommands]] for examples of how these features can be used''
//{{{
merge(config.macros.toolbar,{
	separator: "|"
	});
config.macros.toolbar.handler = function(place,macroName,params,wikifier,paramString,tiddler)
{
	for(var t=0; t<params.length; t++) {
		var c = params[t];
		switch(c) {
			case '|':  // ELS - SEPARATOR
			case '!':  // ELS - SEPARATOR (alternative for use in tiddler slices)
				createTiddlyText(place,this.separator); // ELS
				break; // ELS
			case '>':
				var btn = createTiddlyButton(place,this.moreLabel,this.morePrompt,config.macros.toolbar.onClickMore);
				addClass(btn,"moreCommand");
				var e = createTiddlyElement(place,"span",null,"moreCommand");
				e.style.display = "none";
				place = e;
				break;
			default:
				var theClass = "";
				switch(c.substr(0,1)) {
					case "+":
						theClass = "defaultCommand";
						c = c.substr(1);
						break;
					case "-":
						theClass = "cancelCommand";
						c = c.substr(1);
						break;
				}
				if(c in config.commands)
					this.createCommand(place,c,tiddler,theClass);
				else { // ELS - WIKIFY TIDDLER/SLICE/SECTION
					if (c.substr(0,1)=="~") c=c.substr(1); // ignore leading ~
					var txt=store.getTiddlerText(c);
					if (txt) {
						txt=txt.replace(/^\n*/,"").replace(/\n*$/,""); // trim any leading/trailing newlines
						txt=txt.replace(/^{{{\n/,"").replace(/\n}}}$/,""); // trim PRE format wrapper if any
						wikify(txt,createTiddlyElement(place,"span"),null,tiddler);
					}
				} // ELS - end WIKIFY CONTENT
				break;
		}
	}
};
//}}}
// // }}}
// // {{groupbox small{
// // http://trac.tiddlywiki.org/ticket/608 - OPEN
// // This tweak extends the {{{<<toolbar>>}}} macro to make the ">" (more) a //toggle// between more/less with the additional toolbar commands displayed on a separate line.
//{{{
merge(config.macros.toolbar,{
	moreLabel: 'more',
	morePrompt: "Show additional commands",
	lessLabel: 'less',
	lessPrompt: "Hide additional commands"
});
config.macros.toolbar.onClickMore = function(ev)
{
	var e = this.nextSibling;
	var showing=e.style.display=="block";
	e.style.display = showing?"none":"block";
	this.innerHTML=showing?config.macros.toolbar.moreLabel:config.macros.toolbar.lessLabel;
	this.title=showing?config.macros.toolbar.morePrompt:config.macros.toolbar.lessPrompt;
	return false;
};
//}}}
// // }}}
// // {{groupbox small{
// // http://trac.tiddlywiki.org/ticket/607 - OPEN
// // This tweak automatically sets the HREF for the 'permaview' sidebar command link so you can use the 'right click' context menu for faster, easier bookmarking.  Note that this does ''not'' automatically set the permaview in the browser's current location URL... it just sets the HREF on the command link.  You still have to click the link to apply the permaview.
//{{{
config.macros.permaview.handler = function(place)
{
	var btn=createTiddlyButton(place,this.label,this.prompt,this.onClick);
	addEvent(btn,"mouseover",this.setHREF);
	addEvent(btn,"focus",this.setHREF);
};
config.macros.permaview.setHREF = function(event){
	var links = [];
	story.forEachTiddler(function(title,element) {
		links.push(String.encodeTiddlyLink(title));
	});
	var newURL=document.location.href;
	var hashPos=newURL.indexOf("#");
	if (hashPos!=-1) newURL=newURL.substr(0,hashPos);
	this.href=newURL+"#"+encodeURIComponent(links.join(" "));
}
//}}}
// // }}}
// // {{groupbox small{
// // 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;
};
}
//}}}
// // }}}
// // {{groupbox small{
// // http://trac.tiddlywiki.org/ticket/471 - OPEN
// // This tweak HIJACKS the core's saveTiddler() function to automatically add a "creator" field to a tiddler when it is FIRST created. You can use {{{<<view creator>>}}} (or {{{<<view creator wikified>>}}} if you prefer) to show this value embedded directly within the tiddler content, or {{{<span macro="view creator"></span>}}} in the ViewTemplate and/or EditTemplate to display the creator value in each tiddler.  
//{{{
// hijack saveTiddler()
TiddlyWiki.prototype.CoreTweaks_creatorSaveTiddler=TiddlyWiki.prototype.saveTiddler;
TiddlyWiki.prototype.saveTiddler=function(title,newTitle,newBody,modifier,modified,tags,fields)
{
	var existing=store.tiddlerExists(title);
	var tiddler=this.CoreTweaks_creatorSaveTiddler.apply(this,arguments);
	if (!existing) store.setValue(title,"creator",config.options.txtUserName);
	return tiddler;
}
//}}}
// // }}}
// // {{groupbox small{
// // http://trac.tiddlywiki.org/ticket/458 - CURRENTLY CLOSED AS: WON'T FIX
// // This tweak assigns a "permalink"-like HREF to internal Tiddler links (which normally do not have any HREF defined).  This permits the link's context menu (right-click) to include 'open link in another window/tab' command.  Based on a request from Dustin Spicuzza.
//{{{
window.coreTweaks_createTiddlyLink=window.createTiddlyLink;
window.createTiddlyLink=function(place,title,includeText,theClass,isStatic,linkedFromTiddler,noToggle)
{
	// create the core button, then add the HREF (to internal links only)
	var link=window.coreTweaks_createTiddlyLink.apply(this,arguments);
	if (!isStatic)
		link.href=document.location.href.split("#")[0]+"#"+encodeURIComponent(String.encodeTiddlyLink(title));
	return link;
}
//}}}
// // }}}
// // {{groupbox small{
// // http://trac.tiddlywiki.org/ticket/444 - OPEN
// // When invoking a macro, this tweak makes the current containing tiddler object and DOM rendering location available as global variables (window.tiddler and window.place, respectively).  These globals can then be used within "computed macro parameters" to retrieve tiddler-relative and/or DOM-relative values or perform tiddler-specific side-effect functionality.
//{{{
window.coreTweaks_invokeMacro = window.invokeMacro;
window.invokeMacro = function(place,macro,params,wikifier,tiddler) {
	var here=story.findContainingTiddler(place);
	window.tiddler=here?store.getTiddler(here.getAttribute("tiddler")):null;
	window.place=place;
	window.coreTweaks_invokeMacro.apply(this,arguments);
}
//}}}
// // }}}
// // {{groupbox small{
// // http://trac.tiddlywiki.org/ticket/401 - OPEN
// // This tweak allows definition of an optional [[PageTitle]] tiddler that, when present, provides alternative text for display in the browser window's titlebar, instead of using the combined text content from [[SiteTitle]] and [[SiteSubtitle]] (which will still be displayed as usual in the TiddlyWiki document header area)
//{{{
window.coreTweaks_getPageTitle=window.getPageTitle;
window.getPageTitle=function() { 
	var txt=wikifyPlain("PageTitle"); if (txt.length) return txt;
	return window.coreTweaks_getPageTitle.apply(this,arguments);
}
store.addNotification("PageTitle",refreshPageTitle); // so title stays in sync with tiddler changes
//}}}
// // }}}
// // {{groupbox small{
// // http://trac.tiddlywiki.org/ticket/67 - OPEN
// // The "missing links" list includes items contained within "quoted" text (i.e., content that will not render as wiki-syntax, and so CANNOT create any tiddler links, even if the quoted text matches valid link syntax).  This tweak removes content contained between certain delimiters before scanning tiddler source for possible links.
/***
Delimiters include:
{{{
/%...%/
{{{...}}}
"""..."""
<nowiki>...</nowiki>
<html>...</html>
<script>...</script>
}}}
***/
//{{{
Tiddler.prototype.coreTweaks_changed = Tiddler.prototype.changed;
Tiddler.prototype.changed = function()
{
	var savedtext=this.text;
	// remove 'quoted' text before scanning tiddler source
	this.text=this.text.replace(/\/%((?:.|\n)*?)%\//g,""); // /%...%/
	this.text=this.text.replace(/\{{3}((?:.|\n)*?)\}{3}/g,""); // {{{...}}}
	this.text=this.text.replace(/"{3}((?:.|\n)*?)"{3}/g,""); // """..."""
	this.text=this.text.replace(/\<nowiki\>((?:.|\n)*?)\<\/nowiki\>/g,""); // <nowiki>...</nowiki>
	this.text=this.text.replace(/\<html\>((?:.|\n)*?)\<\/html\>/g,""); // <html>...</html>
	this.text=this.text.replace(/\<script((?:.|\n)*?)\<\/script\>/g,""); // <script>...</script>
	this.coreTweaks_changed.apply(this,arguments);
	// restore quoted text to tiddler source
	this.text=savedtext;
};
//}}}
// // }}}
/***
!!! Fixed in TW240
***/
// // {{groupbox small{
// // calculate version number for conditional inclusion of tweaks below...
//{{{
var ver=version.major+version.minor/10;
//}}}
// // }}}
// // {{groupbox small{
// // http://trac.tiddlywiki.org/ticket/578 - FIXED IN TW240
// // This tweak trims any leading whitespace/newline and the trailing newline from tiddler sections
//{{{
if (ver<2.4) {
TiddlyWiki.prototype.coreTweaks_getTiddlerText = TiddlyWiki.prototype.getTiddlerText;
TiddlyWiki.prototype.getTiddlerText = function(title,defaultText)
{
	var r=TiddlyWiki.prototype.coreTweaks_getTiddlerText.apply(this,arguments);
	if (r&&title.indexOf(config.textPrimitives.sectionSeparator)!=-1)
		r=r.replace(/^[ \t]*\n/,"").replace(/\n$/,""); // trim any leading/trailing newlines
	return r;
};
}
//}}}
// // }}}
// // {{groupbox small{
// // http://trac.tiddlywiki.org/ticket/541 - FIXED IN TW240
// // This tweak adds a conditional check to the core's 'open' paramifier, so that when the document is viewed in readOnly mode, non-existent tiddlers specified using a permalink/permaview (i.e. "#TiddlerName" in the document URL) will not be displayed as an empty tiddler (which shows the "double-click to create" default text).
//{{{
if (ver<2.4) {
config.paramifiers.open = { 
onstart: function(v) { 
		if(!readOnly || store.tiddlerExists(v) || store.isShadowTiddler(v)) 
			story.displayTiddler("bottom",v,null,false,null); 
	} 
}; 
}
//}}}
// // }}}
// // {{groupbox small{
// // http://trac.tiddlywiki.org/ticket/470 - FIXED IN TW240
// // This tweak lets you set an alternative initial focus field when editing a tiddler (default field is "text")
// // Enter initial focus field name: <<option txtEditorFocus>> (//usage:// {{{<<option txtEditorFocus>>}}})
//{{{
if (ver<2.4) {
config.commands.editTiddler.coreTweaks_handler = config.commands.editTiddler.handler;
config.commands.editTiddler.handler = function(event,src,title)
{
	if (config.options.txtEditorFocus==undefined) config.options.txtEditorFocus="text";
	this.coreTweaks_handler.apply(this,arguments);
	story.focusTiddler(title,config.options.txtEditorFocus);
	return false;
};
}
//}}}
// // }}}
// // {{groupbox small{
// // http://trac.tiddlywiki.org/ticket/468 - FIXED IN TW240
// // This tweak extends the core's {{{<<tag>>}}} macro to accept additional parameters for specifying alternative label and tooltip text for the tag popup "button" link (i.e., "`PrettyTags").  Based on a suggestion by ~PBee.
//{{{
// hijack tag handler()
if (ver<2.4) {
config.macros.tag.CoreTweaks_handler=config.macros.tag.handler;
config.macros.tag.handler = function(place,macroName,params)
{
	this.CoreTweaks_handler.apply(this,arguments);
	var btn=place.lastChild;
	if (params[1]) btn.innerHTML=params[1];
	if (params[2]) btn.title=params[2];
}
}
//}}}
// // }}}
// // {{groupbox small{
// // http://trac.tiddlywiki.org/ticket/320 - FIXED IN TW240
// // This tweak updates the core's forceReflow() function to fix a Firefox rendering problem, whereby the contents of the a tiddler editor text area can be incorrectly displayed (overlapping other content) when more than one tiddler is in edit mode.
//{{{
if (ver<2.4) {
function forceReflow()
{
	if(config.browser.isGecko) {
		setStylesheet("body {top:-0px;margin-top:0px;}");
		setTimeout('setStylesheet("")',1); // invoke async to bypass browser optimization
	}
}
}
//}}}
// // }}}
// // {{groupbox small{
// // http://trac.tiddlywiki.org/ticket/42 - FIXED IN TW240
// // This tweak adjusts the left position of a TW popup so that it won't overlap with the browser window's vertical scrollbar, when present.
//{{{
if (ver<2.4) {
Popup.place = function(root,popup,offset)
{
	if(!offset) var offset = {x:0, y:0};
	var rootLeft = findPosX(root);
	var rootTop = findPosY(root);
	var rootHeight = root.offsetHeight;
	var popupLeft = rootLeft + offset.x;
	var popupTop = rootTop + rootHeight + offset.y;
	var winWidth = findWindowWidth();
	if(popup.offsetWidth > winWidth*0.75)
		popup.style.width = winWidth*0.75 + "px";
	var popupWidth = popup.offsetWidth;
	// ELS: leave space for vertical scrollbar
	var scrollWidth=winWidth-document.body.offsetWidth;
	if(popupLeft+popupWidth > winWidth-scrollWidth-1)
		popupLeft = winWidth-popupWidth-scrollWidth-1;
	popup.style.left = popupLeft + "px";
	popup.style.top = popupTop + "px";
	popup.style.display = "block";
};
}
//}}}
// // }}}
/***
!!!Unticketed Tweaks
***/
// // {{groupbox small{
// // This tweak adds an optional 'sortby' parameter to the {{{<<tag tagname label tip sortby>>}}} macro, as well as the {{{<<allTags excludeTag sortby>>}}} macro (used to generate the sidebar contents 'tags' list.  This parameter lets you specify the field on which the contents of each tag popup is to be sorted, with a "+" or "-" prefix to indicate ascending/descending order, respectively.

// // Example: {{{<<tag systemConfig "plugins" "list plugins by date, most recent first" "-modified">>}}}
// // Try it: <<tag systemConfig "plugins" "list plugins by date, most recent first" "-modified">>

// // Similarly, to change the sort order used by the popups from all tags shown in the sidebar contents, edit the [[TagTags]] shadow tiddler and enter: {{{<<allTags excludeLists -modified>>}}}

// // note: the hijack for the {{{<<tag>>}}} macro handler also includes the tweak for ticket #468 to support 'label' and 'tip' params (already fixed in TW240)
//{{{
// hijack tag handler() to add 'sortby' attribute to tag button
config.macros.tag.CoreTweaksSortTags_handler=config.macros.tag.handler;
config.macros.tag.handler = function(place,macroName,params)
{
	this.CoreTweaksSortTags_handler.apply(this,arguments);
	var btn=place.lastChild;
	if (params[1]) btn.innerHTML=params[1]; // ticket #468
	if (params[2]) btn.title=params[2]; // ticket #468
	if (params[3]) btn.setAttribute("sortby",params[3]);
}
// REPLACE macro handler for <<allTags>> macro to add sorting parameter to each tag entry
config.macros.allTags.handler = function(place,macroName,params)
{
	var tags = store.getTags(params[0]);
	var ul = createTiddlyElement(place,"ul");
	if(tags.length == 0)
		createTiddlyElement(ul,"li",null,"listTitle",this.noTags);
	for(var t=0; t<tags.length; t++) {
		var title = tags[t][0];
		var info = getTiddlyLinkInfo(title);
		var li =createTiddlyElement(ul,"li");
		var btn = createTiddlyButton(li,title + " (" + tags[t][1] + ")",this.tooltip.format([title]),onClickTag,info.classes);
		btn.setAttribute("tag",title);
		btn.setAttribute("refresh","link");
		btn.setAttribute("tiddlyLink",title);
		if (params[1]) btn.setAttribute("sortby",params[1]); // ELS
	}
};
// REPLACE event handler for clicking on a tiddler tag to add sorting of popup contents
function onClickTag(ev)
{
	var e = ev ? ev : window.event;
	var popup = Popup.create(this);
	var tag = this.getAttribute("tag");
	var title = this.getAttribute("tiddler");
	if(popup && tag) {
		var tagged = store.getTaggedTiddlers(tag);
		var sortby = this.getAttribute("sortby"); // ELS
		if (sortby&&sortby.length) store.sortTiddlers(tagged,sortby); // ELS
		var titles = [];
		var li,r;
		for(r=0;r<tagged.length;r++) {
			if(tagged[r].title != title)
				titles.push(tagged[r].title);
		}

		var lingo = config.views.wikified.tag;
		if(titles.length > 0) {
			var openAll = createTiddlyButton(createTiddlyElement(popup,"li"),lingo.openAllText.format([tag]),lingo.openAllTooltip,onClickTagOpenAll);
			openAll.setAttribute("tag",tag);
			createTiddlyElement(createTiddlyElement(popup,"li",null,"listBreak"),"div");
			for(r=0; r<titles.length; r++) {
				createTiddlyLink(createTiddlyElement(popup,"li"),titles[r],true);
			}
		} else {
			createTiddlyText(createTiddlyElement(popup,"li",null,"disabled"),lingo.popupNone.format([tag]));
		}
		createTiddlyElement(createTiddlyElement(popup,"li",null,"listBreak"),"div");
		var h = createTiddlyLink(createTiddlyElement(popup,"li"),tag,false);
		createTiddlyText(h,lingo.openTag.format([tag]));
	}
	Popup.show();
	e.cancelBubble = true;
	if(e.stopPropagation) e.stopPropagation();
	return false;
}
//}}}
// // }}}
// // {{groupbox small{
// // This tweak adds URL paramifier handlers for "hide:elementID" and "show:elementID".  This is useful for forcing the display state of specific TW page elements, without requiring StyleSheet changes.  For example, if your customized StyleSheet hides the sidebar (useful for 'read only' published documents), you can force it to display when you need to edit the document by adding {{{#show:sidebar}}} to the document URL.  Alternatively, you might want to supress non-tiddler content when printing by hiding the sidebars and header (e.g., {{{#hide:mainMenu hide:sidebar hide:header}}})
//{{{
if (config.paramifiers) { // check for backward-compatibility
	config.paramifiers.hide = { onstart: function(id) { var e=document.getElementById(id); if (e) e.style.display="none"; } };
	config.paramifiers.show = { onstart: function(id) { var e=document.getElementById(id); if (e) e.style.display="block"; } };
}
//}}}
// // }}}
// // {{groupbox small{
// // This HIJACK tweak pre-processes source content to convert "double-backslash-newline" into {{{<br>}}} before wikify(), so that literal newlines can be embedded in line-mode wiki syntax (e.g., tables, bullets, etc.).  Based on a suggestion from Sitaram Chamarty.
//{{{
window.coreWikify = wikify;
window.wikify = function(source,output,highlightRegExp,tiddler)
{
	if (source) arguments[0]=source.replace(/\\\\\n/mg,"<br>");
	coreWikify.apply(this,arguments);
}
//}}}
// // }}}
/***
!!!<<gradient horiz #fc3 #fff >><<tiddler RefreshStyles>>&nbsp;CustomCSS>>/%==================================================%/
***/

/***CustomCSS is a style sheet that contains the "custom class" CSS to customize special features in TW Help.  It is placed in StyleSheet as a [[NestedStyleSheet|NestedStyleSheets]] and is an essential component.***/

/***There may be extra nested stylesheets at the end of this stylesheet***/

/***
!!!<<gradient horiz #FF8888 #ffffff >>&nbsp;~CustomTable>>/%==================================================%/
***/

/*{{{*/

.marginleft3 {
margin-left: 3em !important; margin-right: auto !important;
}

.liststyleimagenone {list-style-image: none; margin-left:0em;padding: 0em}

.viewer table {
border: 1px solid #008;
margin-left:0em;
}

#tiddlerFolderTree {color:#050;}
#tiddlerHistory .tabContents {color:#050; background:#eee;}
#tiddlerFolderTree .tabContents {color:#050;}
#tiddlerTimeline {color:#050;}


.scroll{overflow: scroll}
.scrollauto {overflow: auto}

.nowrap {white-space:nowrap;}
.wrap{wrap;}

#tiddlerDirectory {line-height: 1em;}

.systemcontents {
 height: auto; 
 width: 250px; 
 position:relative;
 overflow: auto;
 margin:auto;
 margin-left:0em;
 }

.popup {
 max-height:275px;
 min-height:auto;
 width: auto; 
 overflow: auto;
 margin:auto;
-moz-border-radius : 0.65em 0.2em 0.2em 0.65em;

}


.doubleborder {
    border: 4px double #fcf;
    margin: 8px;
}

.tableright  table {border:0 !important;td.vertical-align:top;margin-left:auto ; margin-right:0  auto !important; text-align:left; padding:0px;}


.tablecenter  table{ border:1 !important;td.vertical-align:top;margin-left: auto; margin-right: auto; text-align:left; padding:0px;}
.tablecenterpad17 table { td.vertical-align:top;margin-left: auto; margin-right: auto; text-align:
left; padding:17px;}

.borderless, .borderless table, .borderless td, .borderless tr, .borderless th, .borderless tbody
	{ border:0 !important; margin:0 !important; padding:3px !important; td.vertical-align:top !important;margin-left: auto !important; margin-right: auto !important;}

.borderless5px, .borderless5px table, .borderless5px td, .borderless5px tr, .borderless5px th, .borderless5px tbody { border:0 !important; margin:0 !important; padding:5px !important; td.vertical-align:top !important;margin-left: auto !important; margin-right: auto !important;}

.borderlessL, .borderlessL table, .borderlessL td, .borderlessL tr, .borderlessL th, .borderlessL tbody
	{ border:0 !important; margin:0 !important; padding:7px !important; td.vertical-align:top !important;margin-left: 0 !important; margin-right: auto !important;}

.borderlessL0, .borderlessL 0table, .borderlessL0 td, .borderlessL0 tr, .borderlessL0 th, .borderlessL0 tbody
	{ border:0 !important; margin:0 !important; padding:0px !important; td.vertical-align:top !important;margin-left: 0 !important; margin-right: auto !important;}

.borderlessR, .borderlessR table, .borderlessR td, .borderlessR tr, .borderlessR th, .borderlessR tbody
	{ border:0 !important; margin:0 !important; padding:7px !important; td.vertical-align:top !important;margin-left: auto !important; margin-right: 0 !important;}


.viewer tr.oddRow { background-color: #eaeaea;}
.viewer tr.evenRow { background-color:#fff; } 

/%row code for html%/
tr.d0 td {background-color: #ccc; color: black;}
tr.d1 td {background-color: #eaeaea; color: black;}


/*}}}*/
/***
!!!<<gradient horiz #FF8888 #ffffff >>&nbsp;~CustomText>>/%==================================================%/
***/
/*{{{*/

.c06 {color:#c06;}
.gray9 {color:#999;}

.fontsize40 {font-size:0.5em}
.fontsize80 {font-size:0.75em}

.textleft { display:block;text-align:left; }
.textleftM { display:block;text-align:left; margin:0;padding:0;border:0;margin-left:4.5em; }

.textright { display:block;text-align:right; }
.textcenter { display:block;text-align:center; }
.textjustify { display:block;text-align:justify; }
.textindent05 { display:block;margin:0;padding:0;border:0;margin-left:0.5em; }
.textindent1 { display:block;margin:0;padding:0;border:0;margin-left:1em; }
.textindent2 { display:block;margin:0;padding:0;border:0;margin-left:2em; }


.wrap { white-space:normal; }
.nowrap	{ white-space:nowrap; }

.headingcolor{color:#FFF;background:#ff8888;}
.wrappingClass{padding: 0px 0.5em 0px 0.5em;color: #FFF; background: #06f;}



.firstletter{
display:block;
float:left;
width:1.0em;
font-size:400%;
font-family:times,courier;
line-height:80%;
}

.firstletterK{
display:block;
float:left;
width:0.75em;
font-size:400%;
font-family:times,courier;
line-height:80%;
}

.firstletterT{
display:block;
float:left;
width:0.65em;
font-size:300%;
font-family:times,courier;
line-height:95%;
}

.headline{
color:#c06;
font-size:180%;
font-family:times,arial;
line-height:60%;
}

/*}}}*/
/***
!!!<<gradient horiz #FF8888 #ffffff >>&nbsp;Layout>>/%==================================================%/
***/
/*{{{*/

.twocolumns { display:block; -moz-column-count:2; -moz-column-gap:1em; -moz-column-
width:50%;}
.threecolumns { display:block; -moz-column-count:3; -moz-column-gap:1em; -moz-column-
width:33%}
.fourcolumns { display:block; -moz-column-count:4; -moz-column-gap:1em; -moz-column-
width:25%}

.doubleborder {
    border: 4px double #fcf;
    margin: 8px;
}

.floatboxright {
    float: right;
    width: 20em;
    border: solid 1px;
    padding:3px;
    background-color:#fcf;
    /* whatever other styling you want.. */
} 


.floatboxleft {
    float: left;
    width: 20em;
    border: solid 1px;
    padding:3px;
    background-color:#fcf;
    /* whatever other styling you want.. */
} 

.floatleft{ float:left; }
.floatright{ float:right; }

.moveovermainmenu{margin-left:7px;}
.textleftpad5{text-align:left;padding: 0px 5px 0px 5px;}
.textindent25 {text-indent:25px;}
.smallform{ white-space:nowrap; }

.imgfloatright{display:block;float:right;padding:1em;}
.imgfloatleft{display:block;float:left;padding:1em;}
.imgfloatcenter{display:block;margin-left: auto;margin-right: auto;padding:0.3em;}

.alt { background-color:#abf; }
.fdfbackground {background:#fdf;} 

/*}}}*/
/***
!!!<<gradient horiz #FF8888 #ffffff >>&nbsp;Links>>/%==================================================%/
***/
/*{{{*/

.boldLink a {font-weight:bold;}
.unboldLink a {font-weight:normal;}
.underlineLink  a {font-weight:normal;text-decoration:underline;}

.bigLink a { font-size:10pt;font-weight:bold;}
.whiteLink a { color: #fff;font-weight:normal; } 
.twLink a { color: #090;font-weight:normal; }
.locLink a { color: #c06;font-weight:normal; }
.remLink a { color: #c90;font-weight:normal; } 
.blueLink a {color:#00f;}
.grayLink a {color:#ccc;}
.darkgrayLink a {color:#999;}
.editLink a {color:#ccc;font-size:0.01em}

.wrappingLinks{color: #000; background: #B3FFB3;}
.wrappingLinksAlt{color: #000; background: #C0FFFF;}

/*}}}*/
/***
!!!<<gradient horiz #FF8888 #ffffff >> Specific Tiddler Custom CSSCSS>>/%=================================================%/
***/
/*{{{*/

{{{
For tiddler titles with spaces
#tiddlerNew\000020Tiddler a {color: #f00;}
}}}

#tiddlerSilverHeader a {color:#009;}
#tiddlerSilverHeader .button {color:#009;}
#tiddlerSilverHeader a:hover{
	background: #FFF;
	color: #F00;
}



#tiddlerFolderTree ul,ul {
list-style-type: square;
}

#tiddlerFolderTree ul,ul {
list-style-type: &#x25b2;
}


#tiddlerTimeline {
 height: 350px; 
 width: 100%; 
 position:relative;
 overflow: auto;
 margin:auto;
 }


#tiddlerSystemContents .tabContents {padding 0.5em;margin:auto;}



#tiddlerScience .firstletter{
float:left;
width:0.75em;
margin-right:0.2em;
font-size:400%;
font-family:times,arial;
line-height:70%;
}


#tiddlerEditTemplate .button {color: #000;text-decoration:none;}


#tiddlerTWHelp-SearchResults .viewer {
overflow: auto;
height: 350px; 
 width: 100%; 
 position:relative;
 overflow: auto;
 margin:auto;
margin-left:0em;
}

#tiddlerTranslate .viewer {
overflow: auto;
}

#tiddlerSideBarOptions {
color:#ffc;
background: transparent;
}

#tiddlerNewWelcome .viewer .tabContents {
background: transparent;
border-top: 1px solid #999;
border-right: 0px solid #999;
border-bottom: 0px solid #999;
border-left: 0px solid #999;
}

#tiddlerTWHelpSiteLinks ol { list-style-type: decimal }


#tiddlerBorderlessIframe .viewer {
background:#fff;
}


#mainMenu a:hover{
	background: #FFF;
	color: #F00;
}

#SilverHeader


#tiddlerMargin_Properties.viewer th{
        border: 1px solid #000;
	padding: 0px;
        vertical-align:top;
}

#tiddlerFormattingPageIntro .viewer th, .viewer td, .viewer tr,.viewer caption{
        border: 1px solid #F6F;
	padding: 0px;
        vertical-align:top;
}

#tiddlerTWHelp-SearchResults .viewer table, .viewer td{
border: 1px solid #F6F;
padding-left: 5px;
padding-right: 5px;
vertical-align:top;
td.vertical-align:top;
margin-left: auto;
margin-right: auto;

}

#tiddlerTables .viewer td.even{
background:#ccc;
}

#tiddlerTWHelp-SearchResults .viewer a {
color:#04b;
text-decoration:none;
}

#tiddlerAlpha .viewer tr.oddRow { background-color: #abf;}
#tiddlerAlpha .viewer tr.evenRow { background-color:#eaeaea; } 

#tiddlerNewWelcome .viewer tr.oddRow { background-color: #eaeaea;}
#tiddlerNewWelcome .viewer tr.evenRow { background-color:#fff; } 

#tiddlerImages img {
    border: 5px double #999;
    margin: 4px;

} 

#searchBar {
	float: right;
	font-size: 0.9em;
        padding-right: 1.5em;
        padding-bottom: 0em;
}

#searchBar .button {
	padding-right: 0.5em;
	border: none;
}

.gotoBar {
	float: right;
	font-size: 0.9em;
        padding-right: 1.5em;
        padding-top: 1.0em;
}


/*}}}*/
/***
!!!<<gradient horiz #FF8888 #ffffff >>Footer >>/%==================================================%/
***/
/*{{{*/

#ContentFooter {
  text-align: center;
 clear: both;
 color:#ccc;
 background: transparent;
 padding: 1em 2em;
 font-weight:normal;

}


#ContentFooter a {
 color:#ccc;
}



/*}}}*/
/***
!!!<<gradient horiz #090 #fff>>&nbsp;@@color:#fff;End@@>>/%==================================================%/
***/
/*{{{*/

/***
|Name|DataListPlugin(Mod)|
|Source|http://baggr.tiddlyspot.com|
|Version|0.111|
|Author|molicule [at] gmail [dot] com|
|License|BSD open source|
|Type|plugin|
|Requires|DataTiddlerPlugin|
|Description|Turn a tiddler into a data list such as a todo list.|
Provides the ability to create and maintain simple lists housed in a tiddler. Requires the DataTidlerPlugin.
!!!!!Usage
<<<
{{{
<<datalist>>
}}}
<<<
!!!!!How it works
<<<
A form input is provided and the data entered is stored within the tiddler in a JSON format.
This data is read by the plugin and displayed. Convenient actions such as move up, down,
delete and close/unclose are provided.
<<<
!!!!!Data storage format
<<<
{{{<data>{"open": ["list", "of", "open", "items"], "closed": ["list", "of", "closed", "items"], "order": "up" ]}</data>}}}
<<<
!!!!!Change Log
<<<
Sep 26 2008: Added entry order toggle up / down, default being up. New entries can now be added on top or 
on the bottom.
<<<
!!!!!Code
***/
//{{{
config.datalist = {
    list_refresh: function(title) {
        story.refreshTiddler(title, null, true);
    },
    open_add: function(title) {
        var stub = "datalist_" + title.replace(/ /g, "_");
        var new_item = document.getElementById(stub + "_add").value;
        var t = store.getTiddler(title);
        var data = t.data("open");
        var order = t.data("order");
        if (order == "up") {
            data.unshift(new_item);
        } else {
            data.push(new_item);
        }
        t.setData("open", data);
        this.list_refresh(title);
        return false;
    },
    change_order:function(title) {
        var stub = "datalist_" + title.replace(/ /g, "_");
        var t = store.getTiddler(title);
        var data = t.data("order");
        if (data == 'up') {
            data = "down";
        } else {
            data = "up";
        }
        t.setData("order", data);
        this.list_refresh(title);
    },
    open_click: function(title, num) {
        var t = store.getTiddler(title);
        var data = t.data("open");
        var r = data.splice(num*1, 1);
        var h = t.data("closed");
        if (!h) { h = [] };
        h.push(r[0]);
        t.setData("open", data);
        t.setData("closed", h);
        this.list_refresh(title);
    },
    closed_click: function(title, num) {
        var t = store.getTiddler(title);
        var data_d = t.data("closed");
        var r = data_d.splice(num*1, 1);
        var h = t.data("open");
        if (!h) { h = [] };
        h.unshift(r[0]);
        t.setData("open", h);
        t.setData("closed", data_d);
        this.list_refresh(title);
    },
    open_del: function(title, num) {
        var t = store.getTiddler(title);
        var data = t.data("open");
        data.splice(num*1, 1);
        t.setData("open", data);
        this.list_refresh(title);
    },
    closed_del: function(title, num) {
        var t = store.getTiddler(title);
        var data = t.data("closed");
        data.splice(num*1, 1);
        t.setData("closed", data);
        this.list_refresh(title);
    },
    item_over: function(e) {
        e.style.backgroundColor = "#f0f0f0";
    },
    item_out: function(e) {
        e.style.backgroundColor = "#ffffff";
    },
    open_up: function(title, s) {
        var t = store.getTiddler(title);
        var data = t.data("open");
        var s = s*1;
        var a = data[s];
        var b = data[s-1];
        data[s] = b;
        data[s-1] = a;
        t.setData("open", data);
        this.list_refresh(title);
    },
    open_down: function(title, s) {
        var t = store.getTiddler(title);
        var data = t.data("open");
        var s = s*1;
        var a = data[s];
        var b = data[s+1];
        data[s+1] = a;
        data[s] = b;
        t.setData("open", data);
        this.list_refresh(title);
    },
    open_delall: function(title) {
        var t = store.getTiddler(title);
        t.setData("open", []);
        this.list_refresh(title);
    },
    item_closeall: function(title) {
        var t = store.getTiddler(title);
        var data_l = t.data("open").reverse();
        var data_d = t.data("closed");
        for (var i=0; i<data_l.length; i++) {
            data_d.unshift(data_l[i]);
        }
        t.setData("open", []);
        t.setData("closed", data_d);
        this.list_refresh(title);
    },
    item_openall: function(title) {
        var t = store.getTiddler(title);
        var data_l = t.data("open");
        var data_d = t.data("closed").reverse();
        for (var i=0; i<data_d.length; i++) {
            data_l.unshift(data_d[i]);
        }
        t.setData("open", data_l);
        t.setData("closed", []);
        this.list_refresh(title);
    },
    closed_delall: function(title) {
        var t = store.getTiddler(title);
        t.setData("closed", []);
        this.list_refresh(title);
    },
    open_build: function(title, stub, data) {
        var txt = "<div id=" + stub + "_thelist style=\"\">";
        txt += "<div style=\"float:right;margin:0px\">[<input type=checkbox checked onclick='config.datalist.item_closeall(\"" + title + "\")'>all] &nbsp; <a href='javascript:config.datalist.open_delall(\"" + title + "\")' style=\"color:red\">[x all]</a></div>";
        txt += "<div style=\"padding-top:5px;border-bottom:1px solid #f0f0f0\"><b>open</b></div>";
        for (var i=0; i<data.length; i++) {
            var s = i.toString();
            txt += "<div id=" + stub + "_theitem_" + i.toString();
            txt += " onmouseover=\"config.datalist.item_over(this)\"";
            txt += " onmouseout=\"config.datalist.item_out(this)\"";
            txt += ">";
            txt += "<table width=300 style=\"margin:0px;padding:0px;border:0px\"><tr style=\"border:0px\"><td style=\"border:0px\" width=195>";
            txt += "<input id=" + stub + "_checkbox_" + s + " type=checkbox onclick='config.datalist.open_click(\"" + title + "\", \"" + s + "\");'> " + data[i];
            txt += "</td><td style=\"text-align:right;border:0px;\">";
            txt += "<a ";
            if (i>0) {
            txt += "href=\"javascript:config.datalist.open_up('" + title + "', '" + s + "');\"";
            }
            txt += ">";
            txt += "↑</a> &nbsp; ";
            txt += "<a ";
            if (i != data.length-1) {
            txt += "href=\"javascript:config.datalist.open_down('" + title + "', '" + s + "');\"";
            }
            txt += ">";
            txt += "↓</a> &nbsp; ";
            txt += "<a style=\"color:red;\" href=\"javascript:config.datalist.open_del('" + title + "', '" + s + "');\">x</a>";
            txt += "</td></tr></table>";
            txt += "</div>";
        }
        txt += "</div>";
        return txt;
    },
    closed_build: function(title, stub, data) {
        var txt = "<div id=" + stub + "_theclosed style=\"margin-top:10px\">";
        txt += "<div style=\"float:right;margin:0px\">[<input type=checkbox onclick='config.datalist.item_openall(\"" + title + "\")'>all] &nbsp; <a href='javascript:config.datalist.closed_delall(\"" + title + "\")' style=\"color:red\">[x all]</a></div>";
        txt += "<div style=\"padding-top:4px;border-bottom:1px solid #f0f0f0\"><b>closed</b></div>";
        for (var i=0; i<data.length; i++) {
            var s = i.toString();
            txt += "<div id=" + stub + "_closeditem_" + i.toString();
            txt += " onmouseover=\"config.datalist.item_over(this)\"";
            txt += " onmouseout=\"config.datalist.item_out(this)\"";
            txt += ">";
            txt += "<table width=98% style=\"margin:0px;padding:0px;border:0px\"><tr style=\"border:0px\"><td style=\"border:0px\" width=85%>";
            txt += "<input id=" + stub + "_checkclosed_" + s + " type=checkbox checked onclick='config.datalist.closed_click(\"" + title + "\", \"" + s + "\");'> " + data[i];
            txt += "</td><td style=\"text-align:right;border:0px;\">";
            txt += "<a style=\"color:red;\" href=\"javascript:config.datalist.closed_del('" + title + "', '" + s + "');\">x</a>";
            txt += "</td></tr></table>";
            txt += "</div>";
        }
        txt += "</div>";
        return txt;
    },
    form_build: function(title, data) {
        var stub = "datalist_" + title.replace(/ /g, "_");
        var form_name = stub + "_form";
       var txt = "<table width=300 style=\"margin:0px;padding:0px;border:0px;\"><tr style=\"border:0px\"><td style=\"border:0px\"><form id=" + form_name + " name= " + form_name + " onsubmit='return config.datalist.open_add(\"" + title + "\");'>";
        txt += "<input id=" + stub + "_add name=" + stub + "_add type=text style='width:45'> <input type=submit name=add value=add>";
        txt += " &nbsp; <span id=" + stub + "_order style=\"cursor:pointer\" onclick=config.datalist.change_order('" + title + "')>";
        if (data['order'] == 'up') {
            txt += "↑";
        } else {
            txt += "↓";
        }
        txt += "</span><br/>";
        txt += "<input type=hidden id=" + stub + "_numitems name=" + stub + "_numitems value=" + data['open'].length + ">";
        if (data['open'].length >0) {
            txt += this.open_build(title, stub, data['open']);
        }
        if (data['closed'].length>0) {
            txt += this.closed_build(title, stub, data['closed']);
        }
        txt += "</form></table>";
        return txt;
    }
};
config.macros.datalist = {
    handler: function(place,macroName,params, wikifier, paramString, tiddler) {
        var data = tiddler.data();
        if (!data) { data = {} };
        if (!data['open']) { data['open'] = []; tiddler.setData('open', []);}
        if (!data['closed']) { data['closed'] = []; tiddler.setData('closed', []);}
        if (!data['order']) { data['order'] = "up"; tiddler.setData('order', "up");}
        if (params.length>0) {
            if (params[0].toLowerCase() == "down") {
                config.datalist.entry_order="down";
            }
        }
        var txt = config.datalist.form_build(tiddler.title, data);
        // place.innerHTML += txt;
        wikify("<html> " + txt + " </html>", place);
    }
};
//}}}
/***
|Name|DataListPlugin|
|Source|http://baggr.tiddlyspot.com|
|Version|0.1|
|Author|molicule [at] gmail [dot] com|
|License|BSD open source|
|Type|plugin|
|Requires|DataTiddlerPlugin|
|Description|Turn a tiddler into a data list such as a todo list.|

Provides the ability to create and maintain simple lists housed in a tiddler. Requires the DataTidlerPlugin.
!!!!!Usage
<<<
&lt;&lt;datalist&gt;&gt;
<<<

!!!!!How it works
<<<
A form input is provided and the data entered is stored within the tiddler in a JSON format.
This data is read by the plugin and displayed. Convenient actions such as move up, down,
delete and close/unclose are provided.
<<<
!!!!!Data storage format
<<<
{{{<data>{"open": ["list", "of", "open", "items"], "closed": ["list", "of", "closed", "items"]}</data>}}}
<<<
!!!!!Code
***/

//{{{

config.datalist = {
    list_refresh: function(title) {
        story.refreshTiddler(title, null, true);
    },

    open_add: function(title) {
        var stub = "datalist_" + title.replace(/ /g, "_");
        var new_item = document.getElementById(stub + "_add").value;
        var t = store.getTiddler(title);
        var data = t.data("open");
        data.unshift(new_item);
        t.setData("open", data);
        this.list_refresh(title);
        return false;
    },

    open_click: function(title, num) {
        var t = store.getTiddler(title);
        var data = t.data("open");
        var r = data.splice(num*1, 1);
        var h = t.data("closed");
        if (!h) { h = [] };
        h.push(r[0]);
        t.setData("open", data);
        t.setData("closed", h);
        this.list_refresh(title);
    },

    closed_click: function(title, num) {
        var t = store.getTiddler(title);
        var data_d = t.data("closed");
        var r = data_d.splice(num*1, 1);
        var h = t.data("open");
        if (!h) { h = [] };
        h.unshift(r[0]);
        t.setData("open", h);
        t.setData("closed", data_d);
        this.list_refresh(title);
    },

    open_del: function(title, num) {
        var t = store.getTiddler(title);
        var data = t.data("open");
        data.splice(num*1, 1);
        t.setData("open", data);
        this.list_refresh(title);
    },

    closed_del: function(title, num) {
        var t = store.getTiddler(title);
        var data = t.data("closed");
        data.splice(num*1, 1);
        t.setData("closed", data);
        this.list_refresh(title);
    },

    item_over: function(e) {
        e.style.backgroundColor = "#f0f0f0";
    },

    item_out: function(e) {
        e.style.backgroundColor = "#ffffff";
    },

    open_up: function(title, s) {
        var t = store.getTiddler(title);
        var data = t.data("open");
        var s = s*1;
        var a = data[s];
        var b = data[s-1];
        data[s] = b;
        data[s-1] = a;
        t.setData("open", data);
        this.list_refresh(title);
    },

    open_down: function(title, s) {
        var t = store.getTiddler(title);
        var data = t.data("open");
        var s = s*1;
        var a = data[s];
        var b = data[s+1];
        data[s+1] = a;
        data[s] = b;
        t.setData("open", data);
        this.list_refresh(title);
    },

    open_delall: function(title) {
        var t = store.getTiddler(title);
        t.setData("open", []);
        this.list_refresh(title);
    },

    item_closeall: function(title) {
        var t = store.getTiddler(title);
        var data_l = t.data("open").reverse();
        var data_d = t.data("closed");
        for (var i=0; i<data_l.length; i++) {
            data_d.unshift(data_l[i]);
        }
        t.setData("open", []);
        t.setData("closed", data_d);
        this.list_refresh(title);
    },

    item_openall: function(title) {
        var t = store.getTiddler(title);
        var data_l = t.data("open");
        var data_d = t.data("closed").reverse();
        for (var i=0; i<data_d.length; i++) {
            data_l.unshift(data_d[i]);
        }
        t.setData("open", data_l);
        t.setData("closed", []);
        this.list_refresh(title);
    },

    closed_delall: function(title) {
        var t = store.getTiddler(title);
        t.setData("closed", []);
        this.list_refresh(title);
    },

    open_build: function(title, stub, data) {
        var txt = "<div id=" + stub + "_thelist style=\"\">";
        txt += "<div style=\"float:right;margin:0px\">[<input type=checkbox checked onclick='config.datalist.item_closeall(\"" + title + "\")'>all] &nbsp; <a href='javascript:config.datalist.open_delall(\"" + title + "\")' style=\"color:red\">[x all]</a></div>";
        txt += "<div style=\"padding-top:5px;border-bottom:1px solid #f0f0f0\"><b>open</b></div>";
        for (var i=0; i<data.length; i++) {
            var s = i.toString();
            txt += "<div id=" + stub + "_theitem_" + i.toString();
            txt += " onmouseover=\"config.datalist.item_over(this)\"";
            txt += " onmouseout=\"config.datalist.item_out(this)\"";
            txt += ">";
            txt += "<table width=300 style=\"margin:0px;padding:0px;border:0px\"><tr style=\"border:0px\"><td style=\"border:0px\" width=195>";
            txt += "<input id=" + stub + "_checkbox_" + s + " type=checkbox onclick='config.datalist.open_click(\"" + title + "\", \"" + s + "\");'> " + data[i];

            txt += "</td><td style=\"text-align:right;border:0px;\">";

            txt += "<a ";
            if (i>0) {
            txt += "href=\"javascript:config.datalist.open_up('" + title + "', '" + s + "');\"";
            }
            txt += ">";
            txt += "&uarr;</a> &nbsp; ";

            txt += "<a ";
            if (i != data.length-1) {
            txt += "href=\"javascript:config.datalist.open_down('" + title + "', '" + s + "');\"";
            }
            txt += ">";
            txt += "&darr;</a> &nbsp; ";

            txt += "<a style=\"color:red;\" href=\"javascript:config.datalist.open_del('" + title + "', '" + s + "');\">x</a>";
            txt += "</td></tr></table>";

            txt += "</div>";
        }
        txt += "</div>";
        return txt;
    },

    closed_build: function(title, stub, data) {
        var txt = "<div id=" + stub + "_theclosed style=\"margin-top:10px\">";
        txt += "<div style=\"float:right;margin:0px\">[<input type=checkbox onclick='config.datalist.item_openall(\"" + title + "\")'>all] &nbsp; <a href='javascript:config.datalist.closed_delall(\"" + title + "\")' style=\"color:red\">[x all]</a></div>";
        txt += "<div style=\"padding-top:4px;border-bottom:1px solid #f0f0f0\"><b>closed</b></div>";
        for (var i=0; i<data.length; i++) {
            var s = i.toString();
            txt += "<div id=" + stub + "_closeditem_" + i.toString();
            txt += " onmouseover=\"config.datalist.item_over(this)\"";
            txt += " onmouseout=\"config.datalist.item_out(this)\"";
            txt += ">";
            txt += "<table width=98% style=\"margin:0px;padding:0px;border:0px\"><tr style=\"border:0px\"><td style=\"border:0px\" width=85%>";
            txt += "<input id=" + stub + "_checkclosed_" + s + " type=checkbox checked onclick='config.datalist.closed_click(\"" + title + "\", \"" + s + "\");'> " + data[i];

            txt += "</td><td style=\"text-align:right;border:0px;\">";

            txt += "<a style=\"color:red;\" href=\"javascript:config.datalist.closed_del('" + title + "', '" + s + "');\">x</a>";
            txt += "</td></tr></table>";

            txt += "</div>";
        }
        txt += "</div>";
        return txt;
    },

    form_build: function(title, data) {
        var stub = "datalist_" + title.replace(/ /g, "_");
        var form_name = stub + "_form";

       var txt = "<table width=300 style=\"margin:0px;padding:0px;border:0px;\"><tr style=\"border:0px\"><td style=\"border:0px\"><form id=" + form_name + " name= " + form_name + " onsubmit='return config.datalist.open_add(\"" + title + "\");'>";
        txt += "<input id=" + stub + "_add name=" + stub + "_add type=text style='width:40'> <input type=submit name=add value=add><br/>";
        txt += "<input type=hidden id=" + stub + "_numitems name=" + stub + "_numitems value=" + data['open'].length + ">";

        if (data['open'].length >0) {
            txt += this.open_build(title, stub, data['open']);
        }


        if (data['closed'].length>0) {
            txt += this.closed_build(title, stub, data['closed']);
        }
        txt += "</form></table>";

        return txt;
    }
    
};

config.macros.datalist = {
    handler: function(place,macroName,params, wikifier, paramString, tiddler) {
        var data = tiddler.data();
        if (!data) { data = {} };
        if (!data['open']) { data['open'] = []; tiddler.setData('open', []);}
        if (!data['closed']) { data['closed'] = []; tiddler.setData('closed', []);}
        var txt = config.datalist.form_build(tiddler.title, data);
        // place.innerHTML += txt;
        wikify("<html> " + txt + " </html>", place);
    }
};
//}}}
/***
|''Name:''|DataTiddlerPlugin|
|''Version:''|1.0.6 (2006-08-26)|
|''Source:''|http://tiddlywiki.abego-software.de/#DataTiddlerPlugin|
|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|
|''Licence:''|[[BSD open source license]]|
|''TiddlyWiki:''|1.2.38+, 2.0|
|''Browser:''|Firefox 1.0.4+; InternetExplorer 6.0|
!Description
Enhance your tiddlers with structured data (such as strings, booleans, numbers, or even arrays and compound objects) that can be easily accessed and modified through named fields (in JavaScript code).

Such tiddler data can be used in various applications. E.g. you may create tables that collect data from various tiddlers. 

''//Example: "Table with all December Expenses"//''
{{{
<<forEachTiddler
    where
        'tiddler.tags.contains("expense") && tiddler.data("month") == "Dec"'
    write
        '"|[["+tiddler.title+"]]|"+tiddler.data("descr")+"| "+tiddler.data("amount")+"|\n"'
>>
}}}
//(This assumes that expenses are stored in tiddlers tagged with "expense".)//
<<forEachTiddler
    where
        'tiddler.tags.contains("expense") && tiddler.data("month") == "Dec"'
    write
        '"|[["+tiddler.title+"]]|"+tiddler.data("descr")+"| "+tiddler.data("amount")+"|\n"'
>>
For other examples see DataTiddlerExamples.




''Access and Modify Tiddler Data''

You can "attach" data to every tiddler by assigning a JavaScript value (such as a string, boolean, number, or even arrays and compound objects) to named fields. 

These values can be accessed and modified through the following Tiddler methods:
|!Method|!Example|!Description|
|{{{data(field)}}}|{{{t.data("age")}}}|Returns the value of the given data field of the tiddler. When no such field is defined or its value is undefined {{{undefined}}} is returned.|
|{{{data(field,defaultValue)}}}|{{{t.data("isVIP",false)}}}|Returns the value of the given data field of the tiddler. When no such field is defined or its value is undefined the defaultValue is returned.|
|{{{data()}}}|{{{t.data()}}}|Returns the data object of the tiddler, with a property for every field. The properties of the returned data object may only be read and not be modified. To modify the data use DataTiddler.setData(...) or the corresponding Tiddler method.|
|{{{setData(field,value)}}}|{{{t.setData("age",42)}}}|Sets the value of the given data field of the tiddler to the value. When the value is {{{undefined}}} the field is removed.|
|{{{setData(field,value,defaultValue)}}}|{{{t.setData("isVIP",flag,false)}}}|Sets the value of the given data field of the tiddler to the value. When the value is equal to the defaultValue no value is set (and the field is removed).|

Alternatively you may use the following functions to access and modify the data. In this case the tiddler argument is either a tiddler or the name of a tiddler.
|!Method|!Description|
|{{{DataTiddler.getData(tiddler,field)}}}|Returns the value of the given data field of the tiddler. When no such field is defined or its value is undefined {{{undefined}}} is returned.|
|{{{DataTiddler.getData(tiddler,field,defaultValue)}}}|Returns the value of the given data field of the tiddler. When no such field is defined or its value is undefined the defaultValue is returned.|
|{{{DataTiddler.getDataObject(tiddler)}}}|Returns the data object of the tiddler, with a property for every field. The properties of the returned data object may only be read and not be modified. To modify the data use DataTiddler.setData(...) or the corresponding Tiddler method.|
|{{{DataTiddler.setData(tiddler,field,value)}}}|Sets the value of the given data field of the tiddler to the value. When the value is {{{undefined}}} the field is removed.|
|{{{DataTiddler.setData(tiddler,field,value,defaultValue)}}}|Sets the value of the given data field of the tiddler to the value. When the value is equal to the defaultValue no value is set (and the field is removed).|
//(For details on the various functions see the detailed comments in the source code.)//


''Data Representation in a Tiddler''

The data of a tiddler is stored as plain text in the tiddler's content/text, inside a "data" section that is framed by a {{{<data>...</data>}}} block. Inside the data section the information is stored in the [[JSON format|http://www.crockford.com/JSON/index.html]]. 

//''Data Section Example:''//
{{{
<data>{"isVIP":true,"user":"John Brown","age":34}</data>
}}}

The data section is not displayed when viewing the tiddler (see also "The showData Macro").

Beside the data section a tiddler may have all kind of other content.

Typically you will not access the data section text directly but use the methods given above. Nevertheless you may retrieve the text of the data section's content through the {{{DataTiddler.getDataText(tiddler)}}} function.


''Saving Changes''

The "setData" methods respect the "ForceMinorUpdate" and "AutoSave" configuration values. I.e. when "ForceMinorUpdate" is true changing a value using setData will not affect the "modifier" and "modified" attributes. With "AutoSave" set to true every setData will directly save the changes after a setData.


''Notifications''

No notifications are sent when a tiddler's data value is changed through the "setData" methods. 

''Escape Data Section''
In case that you want to use the text {{{<data>}}} or {{{</data>}}} in a tiddler text you must prefix the text with a tilde ('~'). Otherwise it may be wrongly considered as the data section. The tiddler text {{{~<data>}}} is displayed as {{{<data>}}}.


''The showData Macro''

By default the data of a tiddler (that is stored in the {{{<data>...</data>}}} section of the tiddler) is not displayed. If you want to display this data you may used the {{{<<showData ...>>}}} macro:

''Syntax:'' 
|>|{{{<<}}}''showData '' [''JSON''] [//tiddlerName//] {{{>>}}}|
|''JSON''|By default the data is rendered as a table with a "Name" and "Value" column. When defining ''JSON'' the data is rendered in JSON format|
|//tiddlerName//|Defines the tiddler holding the data to be displayed. When no tiddler is given the tiddler containing the showData macro is used. When the tiddler name contains spaces you must quote the name (or use the {{{[[...]]}}} syntax.)|
|>|~~Syntax formatting: Keywords in ''bold'', optional parts in [...]. 'or' means that exactly one of the two alternatives must exist.~~|


!Revision history
* v1.0.6 (2006-08-26) 
** Removed misleading comment
* v1.0.5 (2006-02-27) (Internal Release Only)
** Internal
*** Make "JSLint" conform
* v1.0.4 (2006-02-05)
** Bugfix: showData fails in TiddlyWiki 2.0
* v1.0.3 (2006-01-06)
** Support TiddlyWiki 2.0
* v1.0.2 (2005-12-22)
** Enhancements:
*** Handle texts "<data>" or "</data>" more robust when used in a tiddler text or as a field value.
*** Improved (JSON) error messages.
** Bugs fixed: 
*** References are not updated when using the DataTiddler.
*** Changes to compound objects are not always saved.
*** "~</data>" is not rendered correctly (expected "</data>")
* v1.0.1 (2005-12-13)
** Features: 
*** The showData macro supports an optional "tiddlername" argument to specify the tiddler containing the data to be displayed
** Bugs fixed: 
*** A script immediately following a data section is deleted when the data is changed. (Thanks to GeoffS for reporting.)
* v1.0.0 (2005-12-12)
** initial version

!Code
***/
//{{{
//============================================================================
//============================================================================
//                           DataTiddlerPlugin
//============================================================================
//============================================================================

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



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

// For backward compatibility with v1.2.x
//
if (!window.story) window.story=window; 
if (!TiddlyWiki.prototype.getTiddler) {
	TiddlyWiki.prototype.getTiddler = function(title) { 
		var t = this.tiddlers[title]; 
		return (t !== undefined && t instanceof Tiddler) ? t : null; 
	};
}

//============================================================================
// DataTiddler Class
//============================================================================

// ---------------------------------------------------------------------------
// Configurations and constants 
// ---------------------------------------------------------------------------

function DataTiddler() {
}

DataTiddler = {
    // Function to stringify a JavaScript value, producing the text for the data section content.
    // (Must match the implementation of DataTiddler.parse.)
    //
    stringify : null,
    

    // Function to parse the text for the data section content, producing a JavaScript value.
    // (Must match the implementation of DataTiddler.stringify.)
    //
    parse : null
};

// Ensure access for IE
window.DataTiddler = DataTiddler;

// ---------------------------------------------------------------------------
// Data Accessor and Mutator
// ---------------------------------------------------------------------------


// Returns the value of the given data field of the tiddler.
// When no such field is defined or its value is undefined
// the defaultValue is returned.
// 
// @param tiddler either a tiddler name or a tiddler
//
DataTiddler.getData = function(tiddler, field, defaultValue) {
    var t = (typeof tiddler == "string") ? store.getTiddler(tiddler) : tiddler;
    if (!(t instanceof Tiddler)) {
        throw "Tiddler expected. Got "+tiddler;
    }

    return DataTiddler.getTiddlerDataValue(t, field, defaultValue);
};


// Sets the value of the given data field of the tiddler to
// the value. When the value is equal to the defaultValue
// no value is set (and the field is removed)
//
// Changing data of a tiddler will not trigger notifications.
// 
// @param tiddler either a tiddler name or a tiddler
//
DataTiddler.setData = function(tiddler, field, value, defaultValue) {
    var t = (typeof tiddler == "string") ? store.getTiddler(tiddler) : tiddler;
    if (!(t instanceof Tiddler)) {
        throw "Tiddler expected. Got "+tiddler+ "("+t+")";
    }

    DataTiddler.setTiddlerDataValue(t, field, value, defaultValue);
};


// Returns the data object of the tiddler, with a property for every field.
//
// The properties of the returned data object may only be read and
// not be modified. To modify the data use DataTiddler.setData(...) 
// or the corresponding Tiddler method.
//
// If no data section is defined a new (empty) object is returned.
//
// @param tiddler either a tiddler name or a Tiddler
//
DataTiddler.getDataObject = function(tiddler) {
    var t = (typeof tiddler == "string") ? store.getTiddler(tiddler) : tiddler;
    if (!(t instanceof Tiddler)) {
        throw "Tiddler expected. Got "+tiddler;
    }

    return DataTiddler.getTiddlerDataObject(t);
};

// Returns the text of the content of the data section of the tiddler.
//
// When no data section is defined for the tiddler null is returned 
//
// @param tiddler either a tiddler name or a Tiddler
// @return [may be null]
//
DataTiddler.getDataText = function(tiddler) {
    var t = (typeof tiddler == "string") ? store.getTiddler(tiddler) : tiddler;
    if (!(t instanceof Tiddler)) {
        throw "Tiddler expected. Got "+tiddler;
    }

    return DataTiddler.readDataSectionText(t);
};


// ---------------------------------------------------------------------------
// Internal helper methods (must not be used by code from outside this plugin)
// ---------------------------------------------------------------------------

// Internal.
//
// The original JSONError is not very user friendly, 
// especially it does not define a toString() method
// Therefore we extend it here.
//
DataTiddler.extendJSONError = function(ex) {
	if (ex.name == 'JSONError') {
        ex.toString = function() {
			return ex.name + ": "+ex.message+" ("+ex.text+")";
		};
	}
	return ex;
};

// Internal.
//
// @param t a Tiddler
//
DataTiddler.getTiddlerDataObject = function(t) {
    if (t.dataObject === undefined) {
        var data = DataTiddler.readData(t);
        t.dataObject = (data) ? data : {};
    }
    
    return t.dataObject;
};


// Internal.
//
// @param tiddler a Tiddler
//
DataTiddler.getTiddlerDataValue = function(tiddler, field, defaultValue) {
    var value = DataTiddler.getTiddlerDataObject(tiddler)[field];
    return (value === undefined) ? defaultValue : value;
};


// Internal.
//
// @param tiddler a Tiddler
//
DataTiddler.setTiddlerDataValue = function(tiddler, field, value, defaultValue) {
    var data = DataTiddler.getTiddlerDataObject(tiddler);
    var oldValue = data[field];
	
    if (value == defaultValue) {
        if (oldValue !== undefined) {
            delete data[field];
            DataTiddler.save(tiddler);
        }
        return;
    }
    data[field] = value;
    DataTiddler.save(tiddler);
};

// Internal.
//
// Reads the data section from the tiddler's content and returns its text
// (as a String).
//
// Returns null when no data is defined.
//
// @param tiddler a Tiddler
// @return [may be null]
//
DataTiddler.readDataSectionText = function(tiddler) {
    var matches = DataTiddler.getDataTiddlerMatches(tiddler);
    if (matches === null || !matches[2]) {
        return null;
    }
    return matches[2];
};

// Internal.
//
// Reads the data section from the tiddler's content and returns it
// (as an internalized object).
//
// Returns null when no data is defined.
//
// @param tiddler a Tiddler
// @return [may be null]
//
DataTiddler.readData = function(tiddler) {
    var text = DataTiddler.readDataSectionText(tiddler);
	try {
	    return text ? DataTiddler.parse(text) : null;
	} catch(ex) {
		throw DataTiddler.extendJSONError(ex);
	}
};

// Internal.
// 
// Returns the serialized text of the data of the given tiddler, as it
// should be stored in the data section.
//
// @param tiddler a Tiddler
//
DataTiddler.getDataTextOfTiddler = function(tiddler) {
    var data = DataTiddler.getTiddlerDataObject(tiddler);
    return DataTiddler.stringify(data);
};


// Internal.
// 
DataTiddler.indexOfNonEscapedText = function(s, subString, startIndex) {
	var index = s.indexOf(subString, startIndex);
	while ((index > 0) && (s[index-1] == '~')) { 
		index = s.indexOf(subString, index+1);
	}
	return index;
};

// Internal.
//
DataTiddler.getDataSectionInfo = function(text) {
	// Special care must be taken to handle "<data>" and "</data>" texts inside
	// a data section. 
	// Also take care not to use an escaped <data> (i.e. "~<data>") as the start 
	// of a data section. (Same for </data>)

    // NOTE: we are explicitly searching for a data section that contains a JSON
    // string, i.e. framed with braces. This way we are little bit more robust in
    // case the tiddler contains unescaped texts "<data>" or "</data>". This must
    // be changed when using a different stringifier.

	var startTagText = "<data>{";
	var endTagText = "}</data>";

	var startPos = 0;

	// Find the first not escaped "<data>".
	var startDataTagIndex = DataTiddler.indexOfNonEscapedText(text, startTagText, 0);
	if (startDataTagIndex < 0) {
		return null;
	}

	// Find the *last* not escaped "</data>".
	var endDataTagIndex = text.indexOf(endTagText, startDataTagIndex);
	if (endDataTagIndex < 0) {
		return null;
	}
	var nextEndDataTagIndex;
	while ((nextEndDataTagIndex = text.indexOf(endTagText, endDataTagIndex+1)) >= 0) {
		endDataTagIndex = nextEndDataTagIndex;
	}

	return {
		prefixEnd: startDataTagIndex, 
		dataStart: startDataTagIndex+(startTagText.length)-1, 
		dataEnd: endDataTagIndex, 
		suffixStart: endDataTagIndex+(endTagText.length)
	};
};

// Internal.
// 
// Returns the "matches" of a content of a DataTiddler on the
// "data" regular expression. Return null when no data is defined
// in the tiddler content.
//
// Group 1: text before data section (prefix)
// Group 2: content of data section
// Group 3: text behind data section (suffix)
//
// @param tiddler a Tiddler
// @return [may be null] null when the tiddler contains no data section, otherwise see above.
//
DataTiddler.getDataTiddlerMatches = function(tiddler) {
	var text = tiddler.text;
	var info = DataTiddler.getDataSectionInfo(text);
	if (!info) {
		return null;
	}

	var prefix = text.substr(0,info.prefixEnd);
	var data = text.substr(info.dataStart, info.dataEnd-info.dataStart+1);
	var suffix = text.substr(info.suffixStart);
	
	return [text, prefix, data, suffix];
};


// Internal.
//
// Saves the data in a <data> block of the given tiddler (as a minor change). 
//
// The "chkAutoSave" and "chkForceMinorUpdate" options are respected. 
// I.e. the TiddlyWiki *file* is only saved when AutoSave is on.
//
// Notifications are not send. 
//
// This method should only be called when the data really has changed. 
//
// @param tiddler
//             the tiddler to be saved.
//
DataTiddler.save = function(tiddler) {

    var matches = DataTiddler.getDataTiddlerMatches(tiddler);

    var prefix;
    var suffix;
    if (matches === null) {
        prefix = tiddler.text;
        suffix = "";
    } else {
        prefix = matches[1];
        suffix = matches[3];
    }

    var dataText = DataTiddler.getDataTextOfTiddler(tiddler);
    var newText = 
            (dataText !== null) 
                ? prefix + "<data>" + dataText + "</data>" + suffix
                : prefix + suffix;
    if (newText != tiddler.text) {
        // make the change in the tiddlers text
        
        // ... see DataTiddler.MyTiddlerChangedFunction
        tiddler.isDataTiddlerChange = true;
        
        // ... do the action change
        tiddler.set(
                tiddler.title,
                newText,
                config.options.txtUserName, 
                config.options.chkForceMinorUpdate? undefined : new Date(),
                tiddler.tags);

        // ... see DataTiddler.MyTiddlerChangedFunction
        delete tiddler.isDataTiddlerChange;

        // Mark the store as dirty.
        store.dirty = true;
 
        // AutoSave if option is selected
        if(config.options.chkAutoSave) {
           saveChanges();
        }
    }
};

// Internal.
//
DataTiddler.MyTiddlerChangedFunction = function() {
    // Remove the data object from the tiddler when the tiddler is changed
    // by code other than DataTiddler code. 
    //
    // This is necessary since the data object is just a "cached version" 
    // of the data defined in the data section of the tiddler and the 
    // "external" change may have changed the content of the data section.
    // Thus we are not sure if the data object reflects the data section 
    // contents. 
    // 
    // By deleting the data object we ensure that the data object is 
    // reconstructed the next time it is needed, with the data defined by
    // the data section in the tiddler's text.
    
    // To indicate that a change is a "DataTiddler change" a temporary
    // property "isDataTiddlerChange" is added to the tiddler.
    if (this.dataObject && !this.isDataTiddlerChange) {
        delete