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

#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]];}

table {border:2px solid [[ColorPalette::TertiaryDark]];}
th, thead td {background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::Background]];}
td, 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:absolute; top:2em; right:0em; margin:0.5em; padding:0.5em; z-index:200;}
*[id='messageArea'] {position:fixed !important; z-index:200;}
.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;}

table {border-collapse:collapse; margin:0.8em 1.0em;}
.viewer th, .viewer td, .viewer tr,.viewer 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; 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:50; 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 use a logographic writing system and 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;}

.htmlarea .toolbarHA table {border:1px solid ButtonFace; margin:0em 0em;}
/*}}}*/
/*{{{*/
@media print {
#mainMenu, #sidebar, #messageArea, .toolbar {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 closeTiddler closeOthers +editTiddler > fields syncing permalink references jump'></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 +saveTiddler -cancelTiddler deleteTiddler'></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
Dog
|''Type:''|file|
|''URL:''|http://tiddlywiki.bidix.info/#UploadPlugin|
|''Workspace:''|(default)|

This tiddler was automatically created to record the details of this server
/***
|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.

!!!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>>}}}

''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);
              }
}
//}}}
/***
|Name|BlogViewPlugin|
|Created by|Craig Rindt|
|Location|http://parsons.its.uci.edu/~crindt/noteblog.html#BlogViewPlugin|
|Version|0.21|
|Requires|~TW2.x|
!!!Description:
Open a user defined number of recent tiddlers automatically when the TW loads.
You can also specify a tag and only load tiddlers that have that tag.
To change the number of tiddlers automatically opened, or define a tag to use, ed the config.autoOpenTiddlers part of the code below.
A fork of [[AutoOpenTiddlersPlugin|http://tw.lewcid.org/#AutoOpenTiddlersPlugin]]

!!!Code
***/
//{{{
//edit this section to change the default settings
config.blogViewTiddlers = 
{
          count: 5,   //number of tiddlers opened.
          tag: 'Blog' //change if you want to open tiddlers with a specific tag, eg: 'DefaultTiddlers'
}


config.blogViewTiddlers.handler = function()
{
          if (this.tag == undefined)
             var newTiddlers = store.getTiddlers( 'modified' );
          else
             var newTiddlers = store.getTaggedTiddlers(this.tag, 'modified' );
          var newTiddlers = newTiddlers.reverse();
           var max = Math.min(this.count,newTiddlers.length-1);
          for (var i=max; i>=0; i--)
               { story.displayTiddler(null,newTiddlers[i].title);} 

          var staticTiddlers = store.getTaggedTiddlers( 'Static content', 'modified' );
          var staticTiddlers = staticTiddlers.reverse();
          for ( var i = staticTiddlers.length-1; i >= 0; i-- )
                { story.displayTiddler( null, staticTiddlers[ i ].title ); }
}

window.old_blogViewTiddlers_restart = restart;
restart = function ()
{
        window.old_blogViewTiddlers_restart();
        config.blogViewTiddlers.handler();
}
//}}}
/***
|Name|BreadcrumbsPlugin|
|Source|http://www.TiddlyTools.com/#BreadcrumbsPlugin|
|OriginalAuthor|Alan Hecht (with 2.0 update from 'jack' and revisions by Bram Chen)|
|Version|1.5.7.0TT|
|Author|Eric Shulman|
|License|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides|Story.prototype.displayTiddler,TiddlyWiki.prototype.deleteTiddler|
|Description|show a list of tiddlers viewed during this session.  Also defines "back" (previousTiddler) toolbar button and macro|

!Configuration
<<<
<<option chkShowBreadcrumbs>> show breadcrumbs display
>//Note: although this checkbox does toggle the breadcrumbs ''setting'', the actual breadcrumbs ''display'' is not updated until the next crumb is added (or a previous crumb is clicked on).  In order for the checkbox setting to have ''immediate'' effect, please see [[ToggleBreadcrumbs]], which uses [[InlineJavascriptPlugin]] to synchronize the checkbox setting and the breadcrumbs display.//
<<option chkReorderBreadcrumbs>> re-order breadcrumbs when visiting a previously viewed tiddler
>//Note: standard (non-enabled) behavior is to ''trim'' the breadcrumbs list when visiting a previously viewed tiddler, so that all crumbs following that tiddler are removed from the list.//
<<<
!Revision History:
__TiddlyTools (TT) variant:__
1.5.8.0 2007.05.26 - added support for {{{<<option chkReorderBreadcrumbs>>}}} to toggle trim vs. re-order behavior when visiting previously viewed tiddlers
1.5.7.0 2007.05.25 - added support for {{{<<option chkShowBreadcrumbs>>}}} to toggle //display// of breadcrumbs
1.5.6.0 2007.05.24 - in refreshCrumbs(), remove non-existing tiddler titles from crumb list.  Also, hijack deleteTiddler() so crumbs can be updated after tiddler is deleted.
1.5.5.0 2007.04.11 - added optional params to previousTiddler macro handler() to allow alternative label and tooltip text (instead of default "back")
1.5.4.0 2007.03.02 - in refreshCrumbs(), for TW2.2, look for "storyDisplay" instead of "tiddlerDisplay" but keep fallback to "tiddlerDisplay" for TW2.1 or earlier
1.5.3.0 2007.02.24 - changed from hijack of onClickTiddlerLink to hijack of displayTiddler() so that ALL displayed tiddlers are recorded in the crumbs, including programmatically displayed tiddlers opened by macros, scripts, etc., (such as [[GotoPlugin]], among many others) in addition to those opened by clicks on links.
1.5.2.0 2007.02.24 - eliminated global space clutter by moving function and data declarations so they are contained inside config.breadCrumbs object.
1.5.1.0 2007.02.06 - added "previousTiddler" macro (for use in sidebar)
1.5.0.0 2007.02.05 - added "previousTiddler" toolbar command (aka, "back")
1.4.0.1 2006.08.04 - change spaces to tabs
1.4.0.0 2006.08.04 - modified from 1.4.0 distro:
<<<
in refreshCrumbs(), set {{{display:none/block}}} instead of {{{visibility:hidden/visible}}}
in restartHome(), check for valid crumbArea before setting style
general code cleanup/reformat using tabs to indent
<<<
|1.4.0|Aug 02, 2006|Fixed bug, the redefined onClickTiddlerLink_orig_breadCrumbs works incorrectly on IE|
|1.3.0|Jul 20, 2006|Runs compatibly with TW 2.1.0 (rev #403+)|
|1.2.0|Feb 07, 2006|change global array breadCrumbs to config.breadCrumbs by Eric's suggestion|
|1.1.0|Feb 04, 2006|JSLint checked|
|1.0.0|Feb 01, 2006|TW2 ready and code Cleaned-up|

!Code section:
***/
//{{{
version.extensions.breadCrumbs = {major: 1, minor: 5, revision: 8, date: new Date("May 26, 2007")};

// show/hide display option (default is to SHOW breadcrumbs)
if (config.options.chkShowBreadcrumbs==undefined)
	config.options.chkShowBreadcrumbs=true;

// REORDER breadcrumbs when visiting previously viewed tiddler (default is to TRIM breadcrumbs)
if (config.options.chkReorderBreadcrumbs==undefined)
	config.options.chkReorderBreadcrumbs=false;

// hijack story.displayTiddler() so crumbs can be refreshed when a tiddler is displayed
if (Story.prototype.breadCrumbs_coreDisplayTiddler==undefined)
	Story.prototype.breadCrumbs_coreDisplayTiddler=Story.prototype.displayTiddler;
Story.prototype.displayTiddler = function(srcElement,title,template,animate,slowly)
{
	this.breadCrumbs_coreDisplayTiddler.apply(this,arguments);
	// if not displaying tiddler during document startup, then add it to the breadcrumbs
	// note: 'startingUp' flag is a global, set/reset by the core init() function
	if (!startingUp) config.breadCrumbs.addCrumb(title);
}

// hijack store.removeTiddler() so crumbs can be refreshed when a tiddler is deleted
if (TiddlyWiki.prototype.breadCrumbs_coreRemoveTiddler==undefined)
	TiddlyWiki.prototype.breadCrumbs_coreRemoveTiddler=TiddlyWiki.prototype.removeTiddler;
TiddlyWiki.prototype.removeTiddler= function(title)
{
	this.breadCrumbs_coreRemoveTiddler.apply(this,arguments);
	config.breadCrumbs.refreshCrumbs();
}

config.breadCrumbs =  {
	crumbs: [], // the list of current breadcrumbs
	addCrumb: function (title) { // ELS: changed from passing event, "e", to passing tiddler title
		var thisCrumb = "[[" + title + "]]";
		var ind = this.crumbs.find(thisCrumb);
		if(ind === null)
			this.crumbs.push(thisCrumb);
		else if (config.options.chkReorderBreadcrumbs)
			this.crumbs.push(this.crumbs.splice(ind,1)[0]); // reorder crumbs
		else
			this.crumbs=this.crumbs.slice(0,ind+1); // trim crumbs
		this.refreshCrumbs();
		return false;
	},
	refreshCrumbs: function() {
		var crumbArea = document.getElementById("breadCrumbs");
		if (!crumbArea) {
			var crumbArea = document.createElement("div");
		 	crumbArea.id = "breadCrumbs";
		 	crumbArea.style.display= "none";
			var targetArea= document.getElementById("tiddlerDisplay"); // TW2.1-
			if (!targetArea) targetArea = document.getElementById("storyDisplay"); // TW2.2+
		 	targetArea.parentNode.insertBefore(crumbArea,targetArea);
		}
		crumbArea.style.display = config.options.chkShowBreadcrumbs?"block":"none";
		removeChildren(crumbArea);
		createTiddlyButton(crumbArea,"Home",null,this.restartHome);
		for (c=0; c<this.crumbs.length; c++)
			if (!store.tiddlerExists(this.crumbs[c].replace(/\[\[/,'').replace(/\]\]/,'')))
				this.crumbs.splice(c,1); // remove non-existing tiddler from crumbs
		wikify(" | " + this.crumbs.join(' > '),crumbArea);
	},
	restartHome: function() {
		story.closeAllTiddlers();
		restart();
		config.breadCrumbs.crumbs = [];
		var crumbArea = document.getElementById("breadCrumbs");
		if (crumbArea) crumbArea.style.display = "none";
	}
};

config.commands.previousTiddler = {
	text: 'back',
	tooltip: 'view the previous tiddler',
	hideReadOnly: false,
	dateFormat: 'DDD, MMM DDth YYYY hh:0mm:0ss',
	handler: function(event,src,title) {
		var here=story.findContainingTiddler(src); if (!here) return;
		if (config.breadCrumbs.crumbs.length>1) {
			var crumb=config.breadCrumbs.crumbs[config.breadCrumbs.crumbs.length-2].replace(/\[\[/,'').replace(/\]\]/,'');
			story.displayTiddler(here,crumb);
		}
		else
			config.breadCrumbs.restartHome();
		return false;
	}
};

config.macros.previousTiddler= {
	label: 'back',
	prompt: 'view the previous tiddler',
	handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		var label=params.shift(); if (!label) label=this.label;
		var prompt=params.shift(); if (!prompt) prompt=this.prompt;
		createTiddlyButton(place,label,prompt,function() {
			if (config.breadCrumbs.crumbs.length>1) {
				var crumb=config.breadCrumbs.crumbs[config.breadCrumbs.crumbs.length-2].replace(/\[\[/,'').replace(/\]\]/,'');
				story.displayTiddler(place,crumb);
			}
			else
				config.breadCrumbs.restartHome();
		});
	}
}
//}}}
A project funded by Caltrans to have the [[Institute of Transportation Studies, Irvine]] develop on-line courseware for their technical staff and managers.
Cartesius is a multi-agent, multi-jurisdictional incident management system created by [[Fillipo Logi]] for his Ph.D. dissertation at the [[UC Irvine]].

[[My|Craig Rindt]] involvement with began as a support role during its original development and has evolved to the point that I am the maintainer and primary (OK, sole) developer of the system.  The most recent work on Cartesius is being performed as part of the [[Cartesius/CTNET]] project.
The Cartesius/CTNET project is an effort to integrate the [[Cartesius]] multi-jurisdictional traffic management system with the [[CTNET]] traffic signal management system created by [[Caltrans]].
Craig Rindt is me.  I am a postdoctoral researcher at the [[Institute of Transportation Studies|http://www.its.uci.edu]] at [[UC Irvine|http://www.uci.edu]] where I obtained my Ph.D. in Transportation Engineering in 2003.

/***
|Name|ExportTiddlersPlugin|
|Source|http://www.TiddlyTools.com/#ExportTiddlersPlugin|
|Version|2.3.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <<br>>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|select and extract tiddlers from your ~TiddlyWiki documents and save them to a local file|

When many people edit copies of the same TiddlyWiki document, the ability to easily copy and share these changes so they can then be redistributed to the entire group is very important.  This ability is also very useful when moving your own tiddlers from document to document (e.g., when upgrading to the latest version of TiddlyWiki, or 'pre-loading' your favorite stylesheets into a new 'empty' TiddlyWiki document.)

ExportTiddlersPlugin let you ''select and extract tiddlers from your ~TiddlyWiki documents and save them to a local file'' or a remote server (requires installation of compatible server-side scripting, still under development...).  An interactive control panel lets you specify a destination, and then select which tiddlers to export.  A convenient 'selection filter' helps you pick desired tiddlers by specifying a combination of modification dates, tags, or tiddler text to be matched or excluded.  ''Tiddler data can be output as ~TiddlyWiki "storeArea ~DIVs" that can be imported into another ~TiddlyWiki or as ~RSS-compatible XML that can be published for RSS syndication.''

!!!!!Inline interface (live)
<<<
<<exportTiddlers inline>>
<<<
!!!!!Usage
<<<
Optional "special tiddlers" used by this plugin:
* SiteUrl^^
URL for official server-published version of document being viewed (used in XML export)
default: //none//^^
* SiteHost^^
host name/address for remote server (e.g., "www.server.com" or "192.168.1.27")
default: //none//^^
* SitePost^^
remote path/filename for submitting changes (e.g., "/cgi-bin/submit.cgi")
default: //none//^^
* SiteParams^^
arguments (if any) for server-side receiving script
default: //none//^^
* SiteNotify^^
addresses (if any) for sending automatic server-side email notices
default: //none//^^
* SiteID^^
username or other authorization identifier for login-controlled access to remote server
default: current TiddlyWiki username (e.g., "YourName")^^
* SiteDate^^
stored date/time stamp for most recent published version of document
default: current document.modified value (i.e., the 'file date')^^
<<<
!!!!!Example
<<<
<<exportTiddlers>>
<<<
!!!!!Installation
<<<
Import (or copy/paste) the following tiddlers into your document:
''ExportTiddlersPlugin'' (tagged with <<tag systemConfig>>)

create/edit ''SideBarOptions'': (sidebar menu items) 
^^Add {{{<<exportTiddlers>>}}} macro^^
<<<
!!!!!Revision History
<<<
''2007.04.19 [2.3.0]'' in exportData(), pass SiteURL value as param to saveToRss().  Fixes 'undefined' appearing in tiddler link in XML output.  Also, in refreshExportList(), added 'sort by tags'.  Also, added 'group select'... selecting a heading (date,author,tag) auto-selects all tiddlers in that group.
''2007.03.02 [2.2.6]'' in onClickExportButton(), when selecting open tiddlers for TW2.2, look for "storyDisplay" instead of "tiddlerDisplay" but keep fallback to "tiddlerDisplay" for TW2.1 or earlier
''2007.03.01 [2.2.5]'' removed hijack of store.saveChanges() (was catching save on http:, but there are other solutions that do a much better job of handling save to server.
|please see [[ExportTiddlersPluginHistory]] for additional revision details|
''2005.10.09 [0.0.0]'' development started
<<<
!!!!!Credits
<<<
This feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]]
<<<
!!!!!Code
***/
// // version
//{{{
version.extensions.exportTiddlers = {major: 2, minor: 3, revision: 0, date: new Date(2007,4,19)};
//}}}

// // macro handler
//{{{
config.macros.exportTiddlers = {
	label: "export tiddlers",
	prompt: "Copy selected tiddlers to an export document",
	newdefault: "export.html",
	datetimefmt: "0MM/0DD/YYYY 0hh:0mm:0ss" // for "filter date/time" edit fields
};

config.macros.exportTiddlers.handler = function(place,macroName,params) {
	if (params[0]!="inline")
		{ createTiddlyButton(place,this.label,this.prompt,onClickExportMenu); return; }
	var panel=createExportPanel(place);
	panel.style.position="static";
	panel.style.display="block";
}

function createExportPanel(place) {
	var panel=document.getElementById("exportPanel");
	if (panel) { panel.parentNode.removeChild(panel); }
	setStylesheet(config.macros.exportTiddlers.css,"exportTiddlers");
	panel=createTiddlyElement(place,"span","exportPanel",null,null)
	panel.innerHTML=config.macros.exportTiddlers.html;
	exportShowPanel(document.location.protocol);
	exportInitFilter();
	refreshExportList(0);
	return panel;
}

function onClickExportMenu(e)
{
	if (!e) var e = window.event;
	var parent=resolveTarget(e).parentNode;
	var panel = document.getElementById("exportPanel");
	if (panel==undefined || panel.parentNode!=parent)
		panel=createExportPanel(parent);
	var isOpen = panel.style.display=="block";
	if(config.options.chkAnimate)
		anim.startAnimating(new Slider(panel,!isOpen,e.shiftKey || e.altKey,"none"));
	else
		panel.style.display = isOpen ? "none" : "block" ;
	if (panel.style.display!="none") refreshExportList(0); // update list when panel is made visible
	e.cancelBubble = true;
	if (e.stopPropagation) e.stopPropagation();
	return(false);
}
//}}}

// // IE needs explicit scoping for functions called by browser events
//{{{
window.onClickExportMenu=onClickExportMenu;
window.onClickExportButton=onClickExportButton;
window.exportShowPanel=exportShowPanel;
window.exportShowFilterFields=exportShowFilterFields;
window.refreshExportList=refreshExportList;
//}}}

// // CSS for floating export control panel
//{{{
config.macros.exportTiddlers.css = '\
#exportPanel {\
	display: none; position:absolute; z-index:12; width:35em; right:105%; top:6em;\
	background-color: #eee; color:#000; font-size: 8pt; line-height:110%;\
	border:1px solid black; border-bottom-width: 3px; border-right-width: 3px;\
	padding: 0.5em; margin:0em; -moz-border-radius:1em;\
}\
#exportPanel a, #exportPanel td a { color:#009; display:inline; margin:0px; padding:1px; }\
#exportPanel table { width:100%; border:0px; padding:0px; margin:0px; font-size:8pt; line-height:110%; background:transparent; }\
#exportPanel tr { border:0px;padding:0px;margin:0px; background:transparent; }\
#exportPanel td { color:#000; border:0px;padding:0px;margin:0px; background:transparent; }\
#exportPanel select { width:98%;margin:0px;font-size:8pt;line-height:110%;}\
#exportPanel input  { width:98%;padding:0px;margin:0px;font-size:8pt;line-height:110%; }\
#exportPanel textarea  { width:98%;padding:0px;margin:0px;overflow:auto;font-size:8pt; }\
#exportPanel .box { border:1px solid black; padding:3px; margin-bottom:5px; background:#f8f8f8; -moz-border-radius:5px; }\
#exportPanel .topline { border-top:2px solid black; padding-top:3px; margin-bottom:5px; }\
#exportPanel .rad { width:auto;border:0 }\
#exportPanel .chk { width:auto;border:0 }\
#exportPanel .btn { width:auto; }\
#exportPanel .btn1 { width:98%; }\
#exportPanel .btn2 { width:48%; }\
#exportPanel .btn3 { width:32%; }\
#exportPanel .btn4 { width:24%; }\
#exportPanel .btn5 { width:19%; }\
';
//}}}

// // HTML for export control panel interface
//{{{
config.macros.exportTiddlers.html = '\
<!-- output target and format -->\
<table cellpadding="0" cellspacing="0"><tr><td width=50%>\
	export to\
	<select size=1 id="exportTo" onchange="exportShowPanel(this.value);">\
	<option value="file:" SELECTED>this computer</option>\
	<option value="http:">web server (http)</option>\
	<option value="https:">secure web server (https)</option>\
	<option value="ftp:">file server (ftp)</option>\
	</select>\
</td><td width=50%>\
	output format\
	<select id="exportFormat" size=1>\
	<option value="DIV">TiddlyWiki export file</option>\
	<option value="TW">TiddlyWiki document</option>\
	<option value="XML">RSS feed (XML)</option>\
	</select>\
</td></tr></table>\
\
<!-- export to local file  -->\
<div id="exportLocalPanel" style="margin-top:5px;">\
local path/filename<br>\
<input type="text" id="exportFilename" size=40 style="width:93%"><input \
	type="button" id="exportBrowse" value="..." title="select or enter a local folder/file..." style="width:5%" \
	onclick="this.previousSibling.value=window.promptForExportFilename(this);">\
<!--<input type="file" id="exportFilename" size=57 style="width:100%"><br>-->\
</div><!--panel-->\
\
<!-- export to http server -->\
<div id="exportHTTPPanel" style="display:none;margin-top:5px;">\
<table><tr><td align=left>\
	server location, script, and parameters<br>\
</td><td align=right>\
	<input type="checkbox" class="chk" id="exportNotify"\
		onClick="document.getElementById(\'exportSetNotifyPanel\').style.display=this.checked?\'block\':\'none\'"> notify\
</td></tr></table>\
<input type="text" id="exportHTTPServerURL" onfocus="this.select()"><br>\
<div id="exportSetNotifyPanel" style="display:none">\
	send email notices to<br>\
	<input type="text" id="exportNotifyTo" onfocus="this.select()"><br>\
</div>\
</div><!--panel-->\
\
<!-- export to ftp server -->\
<div id="exportFTPPanel" style="display:none;margin-top:5px;">\
<table cellpadding="0" cellspacing="0" width="32%"><tr valign="top"><td>\
	host server<br>\
	<input type="text" id="exportFTPHost" onfocus="this.select()"><br>\
</td><td width="32%">\
	username<br>\
	<input type="text" id="exportFTPID" onfocus="this.select()"><br>\
</td><td width="32%">\
	password<br>\
	<input type="password" id="exportFTPPW" onfocus="this.select()"><br>\
</td></tr></table>\
FTP path/filename<br>\
<input type="text" id="exportFTPFilename" onfocus="this.select()"><br>\
</div><!--panel-->\
\
<!-- notes -->\
notes<br>\
<textarea id="exportNotes" rows=3 cols=40 style="height:4em;margin-bottom:5px;" onfocus="this.select()"></textarea> \
\
<!-- list of tiddlers -->\
<table><tr align="left"><td>\
	select:\
	<a href="JavaScript:;" id="exportSelectAll"\
		onclick="onClickExportButton(this)" title="select all tiddlers">\
		&nbsp;all&nbsp;</a>\
	<a href="JavaScript:;" id="exportSelectChanges"\
		onclick="onClickExportButton(this)" title="select tiddlers changed since last save">\
		&nbsp;changes&nbsp;</a> \
	<a href="JavaScript:;" id="exportSelectOpened"\
		onclick="onClickExportButton(this)" title="select tiddlers currently being displayed">\
		&nbsp;opened&nbsp;</a> \
	<a href="JavaScript:;" id="exportToggleFilter"\
		onclick="onClickExportButton(this)" title="show/hide selection filter">\
		&nbsp;filter&nbsp;</a>  \
</td><td align="right">\
	<a href="JavaScript:;" id="exportListSmaller"\
		onclick="onClickExportButton(this)" title="reduce list size">\
		&nbsp;&#150;&nbsp;</a>\
	<a href="JavaScript:;" id="exportListLarger"\
		onclick="onClickExportButton(this)" title="increase list size">\
		&nbsp;+&nbsp;</a>\
</td></tr></table>\
<select id="exportList" multiple size="10" style="margin-bottom:5px;"\
	onchange="refreshExportList(this.selectedIndex)">\
</select><br>\
</div><!--box-->\
\
<!-- selection filter -->\
<div id="exportFilterPanel" style="display:none">\
<table><tr align="left"><td>\
	selection filter\
</td><td align="right">\
	<a href="JavaScript:;" id="exportHideFilter"\
		onclick="onClickExportButton(this)" title="hide selection filter">hide</a>\
</td></tr></table>\
<div class="box">\
<input type="checkbox" class="chk" id="exportFilterStart" value="1"\
	onclick="exportShowFilterFields(this)"> starting date/time<br>\
<table cellpadding="0" cellspacing="0"><tr valign="center"><td width="50%">\
	<select size=1 id="exportFilterStartBy" onchange="exportShowFilterFields(this);">\
		<option value="0">today</option>\
		<option value="1">yesterday</option>\
		<option value="7">a week ago</option>\
		<option value="30">a month ago</option>\
		<option value="site">SiteDate</option>\
		<option value="file">file date</option>\
		<option value="other">other (mm/dd/yyyy hh:mm)</option>\
	</select>\
</td><td width="50%">\
	<input type="text" id="exportStartDate" onfocus="this.select()"\
		onchange="document.getElementById(\'exportFilterStartBy\').value=\'other\';">\
</td></tr></table>\
<input type="checkbox" class="chk" id="exportFilterEnd" value="1"\
	onclick="exportShowFilterFields(this)"> ending date/time<br>\
<table cellpadding="0" cellspacing="0"><tr valign="center"><td width="50%">\
	<select size=1 id="exportFilterEndBy" onchange="exportShowFilterFields(this);">\
		<option value="0">today</option>\
		<option value="1">yesterday</option>\
		<option value="7">a week ago</option>\
		<option value="30">a month ago</option>\
		<option value="site">SiteDate</option>\
		<option value="file">file date</option>\
		<option value="other">other (mm/dd/yyyy hh:mm)</option>\
	</select>\
</td><td width="50%">\
	<input type="text" id="exportEndDate" onfocus="this.select()"\
		onchange="document.getElementById(\'exportFilterEndBy\').value=\'other\';">\
</td></tr></table>\
<input type="checkbox" class="chk" id=exportFilterTags value="1"\
	onclick="exportShowFilterFields(this)"> match tags<br>\
<input type="text" id="exportTags" onfocus="this.select()">\
<input type="checkbox" class="chk" id=exportFilterText value="1"\
	onclick="exportShowFilterFields(this)"> match titles/tiddler text<br>\
<input type="text" id="exportText" onfocus="this.select()">\
</div> <!--box-->\
</div> <!--panel-->\
\
<!-- action buttons -->\
<div style="text-align:center">\
<input type=button class="btn3" onclick="onClickExportButton(this)"\
	id="exportFilter" value="apply filter">\
<input type=button class="btn3" onclick="onClickExportButton(this)"\
	id="exportStart" value="export tiddlers">\
<input type=button class="btn3" onclick="onClickExportButton(this)"\
	id="exportClose" value="close">\
</div><!--center-->\
';
//}}}

// // initialize interface
// // exportShowPanel(which)
//{{{
function exportShowPanel(which) {
	var index=0; var panel='exportLocalPanel';
	switch (which) {
		case 'file:':
		case undefined:
			index=0; panel='exportLocalPanel'; break;
		case 'http:':
			index=1; panel='exportHTTPPanel'; break;
		case 'https:':
			index=2; panel='exportHTTPPanel'; break;
		case 'ftp:':
			index=3; panel='exportFTPPanel'; break;
		default:
			alert("Sorry, export to "+which+" is not yet available");
			break;
	}
	exportInitPanel(which);
	document.getElementById('exportTo').selectedIndex=index;
	document.getElementById('exportLocalPanel').style.display='none';
	document.getElementById('exportHTTPPanel').style.display='none';
	document.getElementById('exportFTPPanel').style.display='none';
	document.getElementById(panel).style.display='block';
}
//}}}

// // exportInitPanel(which)
//{{{
function exportInitPanel(which) {
	switch (which) {
		case "file:": // LOCAL EXPORT PANEL: file/path:
			// ** no init - security issues in IE **
			break;
		case "http:": // WEB EXPORT PANEL
		case "https:": // SECURE WEB EXPORT PANEL
			// url
			if (store.tiddlerExists("unawiki_download")) {
				var theURL=store.getTiddlerText("unawiki_download");
				theURL=theURL.replace(/\[\[download\|/,'').replace(/\]\]/,'');
				var title=(store.tiddlerExists("unawiki_host"))?"unawiki_host":"SiteHost";
				var theHost=store.getTiddlerText(title);
				if (!theHost || !theHost.length) theHost=document.location.host;
				if (!theHost || !theHost.length) theHost=title;
			}
			// server script/params
			var title=(store.tiddlerExists("unawiki_host"))?"unawiki_host":"SiteHost";
			var theHost=store.getTiddlerText(title);
			if (!theHost || !theHost.length) theHost=document.location.host;
			if (!theHost || !theHost.length) theHost=title;
			// get POST
			var title=(store.tiddlerExists("unawiki_post"))?"unawiki_post":"SitePost";
			var thePost=store.getTiddlerText(title);
			if (!thePost || !thePost.length) thePost="/"+title;
			// get PARAMS
			var title=(store.tiddlerExists("unawiki_params"))?"unawiki_params":"SiteParams";
			var theParams=store.getTiddlerText(title);
			if (!theParams|| !theParams.length) theParams=title;
			var serverURL = which+"//"+theHost+thePost+"?"+theParams;
			document.getElementById("exportHTTPServerURL").value=serverURL;
			// get NOTIFY
			var theAddresses=store.getTiddlerText("SiteNotify");
			if (!theAddresses|| !theAddresses.length) theAddresses="SiteNotify";
			document.getElementById("exportNotifyTo").value=theAddresses;
			break;
		case "ftp:": // FTP EXPORT PANEL
			// host
			var siteHost=store.getTiddlerText("SiteHost");
			if (!siteHost || !siteHost.length) siteHost=document.location.host;
			if (!siteHost || !siteHost.length) siteHost="SiteHost";
			document.getElementById("exportFTPHost").value=siteHost;
			// username
			var siteID=store.getTiddlerText("SiteID");
			if (!siteID || !siteID.length) siteID=config.options.txtUserName;
			document.getElementById("exportFTPID").value=siteID;
			// password
			document.getElementById("exportFTPPW").value="";
			// file/path
			document.getElementById("exportFTPFilename").value="";
			break;
	}
}
//}}}

// // exportInitFilter()
//{{{
function exportInitFilter() {
	// start date
	document.getElementById("exportFilterStart").checked=false;
	document.getElementById("exportStartDate").value="";
	// end date
	document.getElementById("exportFilterEnd").checked=false;
	document.getElementById("exportEndDate").value="";
	// tags
	document.getElementById("exportFilterTags").checked=false;
	document.getElementById("exportTags").value="";
	// text
	document.getElementById("exportFilterText").checked=false;
	document.getElementById("exportText").value="";
	// show/hide filter input fields
	exportShowFilterFields();
}
//}}}

// // exportShowFilterFields(which)
//{{{
function exportShowFilterFields(which) {
	var show;

	show=document.getElementById('exportFilterStart').checked;
	document.getElementById('exportFilterStartBy').style.display=show?"block":"none";
	document.getElementById('exportStartDate').style.display=show?"block":"none";
	var val=document.getElementById('exportFilterStartBy').value;
	document.getElementById('exportStartDate').value
		=getFilterDate(val,'exportStartDate').formatString(config.macros.exportTiddlers.datetimefmt);
	 if (which && (which.id=='exportFilterStartBy') && (val=='other'))
		document.getElementById('exportStartDate').focus();

	show=document.getElementById('exportFilterEnd').checked;
	document.getElementById('exportFilterEndBy').style.display=show?"block":"none";
	document.getElementById('exportEndDate').style.display=show?"block":"none";
	var val=document.getElementById('exportFilterEndBy').value;
	document.getElementById('exportEndDate').value
		=getFilterDate(val,'exportEndDate').formatString(config.macros.exportTiddlers.datetimefmt);
	 if (which && (which.id=='exportFilterEndBy') && (val=='other'))
		document.getElementById('exportEndDate').focus();

	show=document.getElementById('exportFilterTags').checked;
	document.getElementById('exportTags').style.display=show?"block":"none";

	show=document.getElementById('exportFilterText').checked;
	document.getElementById('exportText').style.display=show?"block":"none";
}
//}}}

// // onClickExportButton(which): control interactions
//{{{
function onClickExportButton(which)
{
	// DEBUG alert(which.id);
	var theList=document.getElementById('exportList'); if (!theList) return;
	var count = 0;
	var total = store.getTiddlers('title').length;
	switch (which.id)
		{
		case 'exportFilter':
			count=filterExportList();
			var panel=document.getElementById('exportFilterPanel');
			if (count==-1) { panel.style.display='block'; break; }
			document.getElementById("exportStart").disabled=(count==0);
			clearMessage(); displayMessage("filtered "+formatExportMessage(count,total));
			if (count==0) { alert("No tiddlers were selected"); panel.style.display='block'; }
			break;
		case 'exportStart':
			exportTiddlers();
			break;
		case 'exportHideFilter':
		case 'exportToggleFilter':
			var panel=document.getElementById('exportFilterPanel')
			panel.style.display=(panel.style.display=='block')?'none':'block';
			break;
		case 'exportSelectChanges':
			var lastmod=new Date(document.lastModified);
			for (var t = 0; t < theList.options.length; t++) {
				if (theList.options[t].value=="") continue;
				var tiddler=store.getTiddler(theList.options[t].value); if (!tiddler) continue;
				theList.options[t].selected=(tiddler.modified>lastmod);
				count += (tiddler.modified>lastmod)?1:0;
			}
			document.getElementById("exportStart").disabled=(count==0);
			clearMessage(); displayMessage(formatExportMessage(count,total));
			if (count==0) alert("There are no unsaved changes");
			break;
		case 'exportSelectAll':
			for (var t = 0; t < theList.options.length; t++) {
				if (theList.options[t].value=="") continue;
				theList.options[t].selected=true;
				count += 1;
			}
			document.getElementById("exportStart").disabled=(count==0);
			clearMessage(); displayMessage(formatExportMessage(count,count));
			break;
		case 'exportSelectOpened':
			for (var t = 0; t < theList.options.length; t++) theList.options[t].selected=false;
			var tiddlerDisplay = document.getElementById("tiddlerDisplay"); // for TW2.1-
			if (!tiddlerDisplay) tiddlerDisplay = document.getElementById("storyDisplay"); // for TW2.2+
			for (var t=0;t<tiddlerDisplay.childNodes.length;t++) {
				var tiddler=tiddlerDisplay.childNodes[t].id.substr(7);
				for (var i = 0; i < theList.options.length; i++) {
					if (theList.options[i].value!=tiddler) continue;
					theList.options[i].selected=true; count++; break;
				}
			}
			document.getElementById("exportStart").disabled=(count==0);
			clearMessage(); displayMessage(formatExportMessage(count,total));
			if (count==0) alert("There are no tiddlers currently opened");
			break;
		case 'exportListSmaller':	// decrease current listbox size
			var min=5;
			theList.size-=(theList.size>min)?1:0;
			break;
		case 'exportListLarger':	// increase current listbox size
			var max=(theList.options.length>25)?theList.options.length:25;
			theList.size+=(theList.size<max)?1:0;
			break;
		case 'exportClose':
			document.getElementById('exportPanel').style.display='none';
			break;
		}
}
//}}}

// // list display
//{{{
function formatExportMessage(count,total)
{
	var txt=total+' tiddler'+((total!=1)?'s':'')+" - ";
	txt += (count==0)?"none":(count==total)?"all":count;
	txt += " selected for export";
	return txt;
}

function refreshExportList(selectedIndex)
{
	var theList  = document.getElementById("exportList");
	var sort;
	if (!theList) return;
	// get the sort order
	if (!selectedIndex)   selectedIndex=0;
	if (selectedIndex==0) sort='modified';
	if (selectedIndex==1) sort='title';
	if (selectedIndex==2) sort='modified';
	if (selectedIndex==3) sort='modifier';
	if (selectedIndex==4) sort='tags';

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

	// disable "export" button if no tiddlers selected
	document.getElementById("exportStart").disabled=(count==0);
	// show selection count
	var tiddlers = store.getTiddlers('title');
	if (theList.options.length) { clearMessage(); displayMessage(formatExportMessage(count,tiddlers.length)); }

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

	// clear current list contents
	while (theList.length > 0) { theList.options[0] = null; }
	// add heading and control items to list
	var i=0;
	var indent=String.fromCharCode(160)+String.fromCharCode(160);
	theList.options[i++]=
		new Option(tiddlers.length+" tiddlers in document", "",false,false);
	theList.options[i++]=
		new Option(((sort=="title"        )?">":indent)+' [by title]', "",false,false);
	theList.options[i++]=
		new Option(((sort=="modified")?">":indent)+' [by date]', "",false,false);
	theList.options[i++]=
		new Option(((sort=="modifier")?">":indent)+' [by author]', "",false,false);
	theList.options[i++]=
		new Option(((sort=="tags"	)?">":indent)+' [by tags]', "",false,false);
	// output the tiddler list
	switch(sort)
		{
		case "title":
			for(var t = 0; t < tiddlers.length; t++)
				theList.options[i++] = new Option(tiddlers[t].title,tiddlers[t].title,false,false);
			break;
		case "modifier":
		case "modified":
			var tiddlers = store.getTiddlers(sort);
			// sort descending for newest date first
			tiddlers.sort(function (a,b) {if(a[sort] == b[sort]) return(0); else return (a[sort] > b[sort]) ? -1 : +1; });
			var lastSection = "";
			for(var t = 0; t < tiddlers.length; t++)
				{
				var tiddler = tiddlers[t];
				var theSection = "";
				if (sort=="modified") theSection=tiddler.modified.toLocaleDateString();
				if (sort=="modifier") theSection=tiddler.modifier;
				if (theSection != lastSection)
					{
					theList.options[i++] = new Option(theSection,"",false,false);
					lastSection = theSection;
					}
				theList.options[i++] = new Option(indent+indent+tiddler.title,tiddler.title,false,false);
				}
			 break;
		case "tags":
			var theTitles = {}; // all tiddler titles, hash indexed by tag value
			var theTags = new Array();
			for(var t=0; t<tiddlers.length; t++) {
				var title=tiddlers[t].title;
				var tags=tiddlers[t].tags;
				if (!tags || !tags.length) {
					if (theTitles["untagged"]==undefined) { theTags.push("untagged"); theTitles["untagged"]=new Array(); }
					theTitles["untagged"].push(title);
				}
				else for(var s=0; s<tags.length; s++) {
					if (theTitles[tags[s]]==undefined) { theTags.push(tags[s]); theTitles[tags[s]]=new Array(); }
					theTitles[tags[s]].push(title);
				}
			}
			theTags.sort();
			for(var tagindex=0; tagindex<theTags.length; tagindex++) {
				var theTag=theTags[tagindex];
				theList.options[i++]=new Option(theTag,"",false,false);
				for(var t=0; t<theTitles[theTag].length; t++)
					theList.options[i++]=new Option(indent+indent+theTitles[theTag][t],theTitles[theTag][t],false,false);
			}
			break;
		}
	theList.selectedIndex=selectedIndex;		  // select current control item
}
//}}}

// // list filtering
//{{{
function getFilterDate(val,id)
{
	var result=0;
	switch (val) {
		case 'site':
			var timestamp=store.getTiddlerText("SiteDate");
			if (!timestamp) timestamp=document.lastModified;
			result=new Date(timestamp);
			break;
		case 'file':
			result=new Date(document.lastModified);
			break;
		case 'other':
			result=new Date(document.getElementById(id).value);
			break;
		default: // today=0, yesterday=1, one week=7, two weeks=14, a month=31
			var now=new Date(); var tz=now.getTimezoneOffset()*60000; now-=tz;
			var oneday=86400000;
			if (id=='exportStartDate')
				result=new Date((Math.floor(now/oneday)-val)*oneday+tz);
			else
				result=new Date((Math.floor(now/oneday)-val+1)*oneday+tz-1);
			break;
	}
	// DEBUG alert('getFilterDate('+val+','+id+')=='+result+"\nnow="+now);
	return result;
}

function filterExportList()
{
	var theList  = document.getElementById("exportList"); if (!theList) return -1;

	var filterStart=document.getElementById("exportFilterStart").checked;
	var val=document.getElementById("exportFilterStartBy").value;
	var startDate=getFilterDate(val,'exportStartDate');

	var filterEnd=document.getElementById("exportFilterEnd").checked;
	var val=document.getElementById("exportFilterEndBy").value;
	var endDate=getFilterDate(val,'exportEndDate');

	var filterTags=document.getElementById("exportFilterTags").checked;
	var tags=document.getElementById("exportTags").value;

	var filterText=document.getElementById("exportFilterText").checked;
	var text=document.getElementById("exportText").value;

	if (!(filterStart||filterEnd||filterTags||filterText)) {
		alert("Please set the selection filter");
		document.getElementById('exportFilterPanel').style.display="block";
		return -1;
	}
	if (filterStart&&filterEnd&&(startDate>endDate)) {
		var msg="starting date/time:\n"
		msg+=startDate.toLocaleString()+"\n";
		msg+="is later than ending date/time:\n"
		msg+=endDate.toLocaleString()
		alert(msg);
		return -1;
	}

	// scan list and select tiddlers that match all applicable criteria
	var total=0;
	var count=0;
	for (var i=0; i<theList.options.length; i++) {
		// get item, skip non-tiddler list items (section headings)
		var opt=theList.options[i]; if (opt.value=="") continue;
		// get tiddler, skip missing tiddlers (this should NOT happen)
		var tiddler=store.getTiddler(opt.value); if (!tiddler) continue; 
		var sel=true;
		if ( (filterStart && tiddler.modified<startDate)
		|| (filterEnd && tiddler.modified>endDate)
		|| (filterTags && !matchTags(tiddler,tags))
		|| (filterText && (tiddler.text.indexOf(text)==-1) && (tiddler.title.indexOf(text)==-1)))
			sel=false;
		opt.selected=sel;
		count+=sel?1:0;
		total++;
	}
	return count;
}
//}}}

//{{{
function matchTags(tiddler,cond)
{
	if (!cond||!cond.trim().length) return false;

	// build a regex of all tags as a big-old regex that 
	// OR's the tags together (tag1|tag2|tag3...) in length order
	var tgs = store.getTags();
	if ( tgs.length == 0 ) return results ;
	var tags = tgs.sort( function(a,b){return (a[0].length<b[0].length)-(a[0].length>b[0].length);});
	var exp = "(" + tags.join("|") + ")" ;
	exp = exp.replace( /(,[\d]+)/g, "" ) ;
	var regex = new RegExp( exp, "ig" );

	// build a string such that an expression that looks like this: tag1 AND tag2 OR NOT tag3
	// turns into : /tag1/.test(...) && /tag2/.test(...) || ! /tag2/.test(...)
	cond = cond.replace( regex, "/$1\\|/.test(tiddlerTags)" );
	cond = cond.replace( /\sand\s/ig, " && " ) ;
	cond = cond.replace( /\sor\s/ig, " || " ) ;
	cond = cond.replace( /\s?not\s/ig, " ! " ) ;

	// if a boolean uses a tag that doesn't exist - it will get left alone 
	// (we only turn existing tags into actual tests).
	// replace anything that wasn't found as a tag, AND, OR, or NOT with the string "false"
	// if the tag doesn't exist then /tag/.test(...) will always return false.
	cond = cond.replace( /(\s|^)+[^\/\|&!][^\s]*/g, "false" ) ;

	// make a string of the tags in the tiddler and eval the 'cond' string against that string 
	// if it's TRUE then the tiddler qualifies!
	var tiddlerTags = (tiddler.tags?tiddler.tags.join("|"):"")+"|" ;
	try { if ( eval( cond ) ) return true; }
	catch( e ) { displayMessage("Error in tag filter '" + e + "'" ); }
	return false;
}
//}}}

// // output data formatting
// // exportHeader(format)
//{{{
function exportHeader(format)
{
	switch (format) {
		case "TW":	return exportTWHeader();
		case "DIV":	return exportDIVHeader();
		case "XML":	return exportXMLHeader();
	}
}
//}}}

// // exportFooter(format)
//{{{
function exportFooter(format)
{
	switch (format) {
		case "TW":	return exportDIVFooter();
		case "DIV":	return exportDIVFooter();
		case "XML":	return exportXMLFooter();
	}
}
//}}}

// // exportTWHeader()
//{{{
function exportTWHeader()
{
	// Get the URL of the document
	var originalPath = document.location.href;
	// Check we were loaded from a file URL
	if(originalPath.substr(0,5) != "file:")
		{ alert(config.messages.notFileUrlError); return; }
	// Remove any location part of the URL
	var hashPos = originalPath.indexOf("#"); if(hashPos != -1) originalPath = originalPath.substr(0,hashPos);
	// Convert to a native file format assuming
	// "file:///x:/path/path/path..." - pc local file --> "x:\path\path\path..."
	// "file://///server/share/path/path/path..." - FireFox pc network file --> "\\server\share\path\path\path..."
	// "file:///path/path/path..." - mac/unix local file --> "/path/path/path..."
	// "file://server/share/path/path/path..." - pc network file --> "\\server\share\path\path\path..."
	var localPath;
	if(originalPath.charAt(9) == ":") // pc local file
		localPath = unescape(originalPath.substr(8)).replace(new RegExp("/","g"),"\\");
	else if(originalPath.indexOf("file://///") == 0) // FireFox pc network file
		localPath = "\\\\" + unescape(originalPath.substr(10)).replace(new RegExp("/","g"),"\\");
	else if(originalPath.indexOf("file:///") == 0) // mac/unix local file
		localPath = unescape(originalPath.substr(7));
	else if(originalPath.indexOf("file:/") == 0) // mac/unix local file
		localPath = unescape(originalPath.substr(5));
	else // pc network file
		localPath = "\\\\" + unescape(originalPath.substr(7)).replace(new RegExp("/","g"),"\\");
	// Load the original file
	var original = loadFile(localPath);
	if(original == null)
		{ alert(config.messages.cantSaveError); return; }
	// Locate the storeArea div's
	var posOpeningDiv = original.indexOf(startSaveArea);
	var posClosingDiv = original.lastIndexOf(endSaveArea);
	if((posOpeningDiv == -1) || (posClosingDiv == -1))
		{ alert(config.messages.invalidFileError.format([localPath])); return; }
	return original.substr(0,posOpeningDiv+startSaveArea.length)
}
//}}}

// // exportDIVHeader()
//{{{
function exportDIVHeader()
{
	var out=[];
	var now = new Date();
	var title = convertUnicodeToUTF8(wikifyPlain("SiteTitle").htmlEncode());
	var subtitle = convertUnicodeToUTF8(wikifyPlain("SiteSubtitle").htmlEncode());
	var user = convertUnicodeToUTF8(config.options.txtUserName.htmlEncode());
	var twver = version.major+"."+version.minor+"."+version.revision;
	var pver = version.extensions.exportTiddlers.major+"."
		+version.extensions.exportTiddlers.minor+"."+version.extensions.exportTiddlers.revision;
	out.push("<html><body>");
	out.push("<style type=\"text/css\">");
	out.push("#storeArea {display:block;margin:1em;}");
	out.push("#storeArea div");
	out.push("{padding:0.5em;margin:1em;border:2px solid black;height:10em;overflow:auto;}");
	out.push("#javascriptWarning");
	out.push("{width:100%;text-align:left;background-color:#eeeeee;padding:1em;}");
	out.push("</style>");
	out.push("<div id=\"javascriptWarning\">");
	out.push("TiddlyWiki export file<br>");
	out.push("Source"+": <b>"+convertUnicodeToUTF8(document.location.href)+"</b><br>");
	out.push("Title: <b>"+title+"</b><br>");
	out.push("Subtitle: <b>"+subtitle+"</b><br>");
	out.push("Created: <b>"+now.toLocaleString()+"</b> by <b>"+user+"</b><br>");
	out.push("TiddlyWiki "+twver+" / "+"ExportTiddlersPlugin "+pver+"<br>");
	out.push("Notes:<hr><pre>"+document.getElementById("exportNotes").value.replace(regexpNewLine,"<br>")+"</pre>");
	out.push("</div>");
	out.push("<div id=\"storeArea\">");
	return out;
}
//}}}

// // exportDIVFooter()
//{{{
function exportDIVFooter()
{
	var out=[];
	out.push("</div><!--POST-BODY-START-->\n<!--POST-BODY-END--></body></html>");
	return out;
}
//}}}

// // exportXMLHeader()
//{{{
function exportXMLHeader()
{
	var out=[];
	var now = new Date();
	var u = store.getTiddlerText("SiteUrl",null);
	var title = convertUnicodeToUTF8(wikifyPlain("SiteTitle").htmlEncode());
	var subtitle = convertUnicodeToUTF8(wikifyPlain("SiteSubtitle").htmlEncode());
	var user = convertUnicodeToUTF8(config.options.txtUserName.htmlEncode());
	var twver = version.major+"."+version.minor+"."+version.revision;
	var pver = version.extensions.exportTiddlers.major+"."
		+version.extensions.exportTiddlers.minor+"."+version.extensions.exportTiddlers.revision;
	out.push("<" + "?xml version=\"1.0\"?" + ">");
	out.push("<rss version=\"2.0\">");
	out.push("<channel>");
	out.push("<title>" + title + "</title>");
	if(u) out.push("<link>" + convertUnicodeToUTF8(u.htmlEncode()) + "</link>");
	out.push("<description>" + subtitle + "</description>");
	out.push("<language>en-us</language>");
	out.push("<copyright>Copyright " + now.getFullYear() + " " + user + "</copyright>");
	out.push("<pubDate>" + now.toGMTString() + "</pubDate>");
	out.push("<lastBuildDate>" + now.toGMTString() + "</lastBuildDate>");
	out.push("<docs>http://blogs.law.harvard.edu/tech/rss</docs>");
	out.push("<generator>TiddlyWiki "+twver+" plus ExportTiddlersPlugin "+pver+"</generator>");
	return out;
}
//}}}

// // exportXMLFooter()
//{{{
function exportXMLFooter()
{
	var out=[];
	out.push("</channel></rss>");
	return out;
}
//}}}

// // exportData()
//{{{
function exportData(theList,theFormat)
{
	// scan export listbox and collect DIVs or XML for selected tiddler content
	var out=[];
	for (var i=0; i<theList.options.length; i++) {
		// get item, skip non-selected items and section headings
		var opt=theList.options[i]; if (!opt.selected||(opt.value=="")) continue;
		// get tiddler, skip missing tiddlers (this should NOT happen)
		var thisTiddler=store.getTiddler(opt.value); if (!thisTiddler) continue; 
		if (theFormat=="TW")	out.push(convertUnicodeToUTF8(thisTiddler.saveToDiv()));
		if (theFormat=="DIV")	out.push(convertUnicodeToUTF8(thisTiddler.title+"\n"+thisTiddler.saveToDiv()));
		if (theFormat=="XML")	out.push(convertUnicodeToUTF8(thisTiddler.saveToRss(store.getTiddlerText("SiteUrl",""))));
	}
	return out;
}
//}}}

// // exportTiddlers(): output selected data to local or server
//{{{
function exportTiddlers()
{
	var theList  = document.getElementById("exportList"); if (!theList) return;

	// get the export settings
	var theProtocol = document.getElementById("exportTo").value;
	var theFormat = document.getElementById("exportFormat").value;

	// assemble output: header + tiddlers + footer
	var theData=exportData(theList,theFormat);
	var count=theData.length;
	var out=[]; var txt=out.concat(exportHeader(theFormat),theData,exportFooter(theFormat)).join("\n");
	var msg="";
	switch (theProtocol) {
		case "file:":
			var theTarget = document.getElementById("exportFilename").value.trim();
			if (!theTarget.length) msg = "A local path/filename is required\n";
			if (!msg && saveFile(theTarget,txt))
				msg=count+" tiddler"+((count!=1)?"s":"")+" exported to local file";
			else if (!msg)
				msg+="An error occurred while saving to "+theTarget;
			break;
		case "http:":
		case "https:":
			var theTarget = document.getElementById("exportHTTPServerURL").value.trim();
			if (!theTarget.length) msg = "A server URL is required\n";
			if (document.getElementById('exportNotify').checked)
				theTarget+="&notify="+encodeURIComponent(document.getElementById('exportNotifyTo').value);
			if (document.getElementById('exportNotes').value.trim().length)
				theTarget+="&notes="+encodeURIComponent(document.getElementById('exportNotes').value);
			if (!msg && exportPost(theTarget+encodeURIComponent(txt)))
				msg=count+" tiddler"+((count!=1)?"s":"")+" exported to "+theProtocol+" server";
			else if (!msg)
				msg+="An error occurred while saving to "+theTarget;
			break;
		case "ftp:":
		default:
			msg="Sorry, export to "+theLocation+" is not yet available";
			break;
	}
	clearMessage(); displayMessage(msg,theTarget);
}
//}}}

// // exportPost(url): cross-domain post uses hidden iframe to submit url and capture responses
//{{{
function exportPost(url)
{
	var f=document.getElementById("exportFrame"); if (f) document.body.removeChild(f);
	f=document.createElement("iframe"); f.id="exportFrame";
	f.style.width="0px"; f.style.height="0px"; f.style.border="0px";
	document.body.appendChild(f);
	var d=f.document;
	if (f.contentDocument) d=f.contentDocument; // For NS6
	else if (f.contentWindow) d=f.contentWindow.document; // For IE5.5 and IE6
 	d.location.replace(url);
 	return true;
}
//}}}

// // promptForFilename(msg,path,file) uses platform/browser specific functions to get local filespec
//{{{
function promptForExportFilename(here)
{
	var msg=here.title; // use tooltip as dialog box message
	var path=getLocalPath(document.location.href);
	var slashpos=path.lastIndexOf("/"); if (slashpos==-1) slashpos=path.lastIndexOf("\\"); 
	if (slashpos!=-1) path = path.substr(0,slashpos+1); // remove filename from path, leave the trailing slash
	var file=config.macros.exportTiddlers.newdefault;
	var result="";
	if(window.Components) { // moz
		try {
			netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
			var nsIFilePicker = window.Components.interfaces.nsIFilePicker;
			var picker = Components.classes['@mozilla.org/filepicker;1'].createInstance(nsIFilePicker);
			picker.init(window, msg, nsIFilePicker.modeSave);
			var thispath = Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsILocalFile);
			thispath.initWithPath(path);
			picker.displayDirectory=thispath;
			picker.defaultExtension='html';
			picker.defaultString=file;
			picker.appendFilters(nsIFilePicker.filterAll|nsIFilePicker.filterText|nsIFilePicker.filterHTML);
			if (picker.show()!=nsIFilePicker.returnCancel) var result=picker.file.persistentDescriptor;
		}
		catch(e) { alert('error during local file access: '+e.toString()) }
	}
	else { // IE
		try { // XP only
			var s = new ActiveXObject('UserAccounts.CommonDialog');
			s.Filter='All files|*.*|Text files|*.txt|HTML files|*.htm;*.html|';
			s.FilterIndex=3; // default to HTML files;
			s.InitialDir=path;
			s.FileName=file;
			if (s.showOpen()) var result=s.FileName;
		}
		catch(e) { var result=prompt(msg,path+file); } // fallback for non-XP IE
	}
	return result;
}
//}}}
The Household Activity Pattern Problem is a mathematical programming formulation due to [[Recker|http://repositories.cdlib.org/cgi/viewcontent.cgi?article=1052&context=itsirvine/casa]] of the problem faced by a household (or arbitrary social group) to jointly perform a set of activities given a stable of vehicles to travel through time and space.
[[ITS-Irvine|http://www.its.uci.edu/]] is [[my|Craig Rindt]] employer.
[[Publications]]
[[Projects]]
[[Photos|http://parsons.its.uci.edu/~crindt/photos/]]
[[CV|http://parsons.its.uci.edu/~crindt/professional/cv/Craig_Rindt_CV-Long.xhtml]]


This is my stuff
With apologies to the TiddlyWiki team, NoteBlog is my term for a "reusable non-linear personal web notebook".
PasswordOptionPlugin extends the core Options with a non encrypted password type.

Notice:
*How a style can be specified for a specific option in StyleSheet

----
Test Password: <<option pasPassword myPasOptionInput >>
/***
|''Name:''|PasswordOptionPlugin|
|''Description:''|Extends TiddlyWiki options with non encrypted password option.|
|''Version:''|1.0.2|
|''Date:''|Apr 19, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#PasswordOptionPlugin|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0 (Beta 5)|
***/
//{{{
version.extensions.PasswordOptionPlugin = {
	major: 1, minor: 0, revision: 2, 
	date: new Date("Apr 19, 2007"),
	source: 'http://tiddlywiki.bidix.info/#PasswordOptionPlugin',
	author: 'BidiX (BidiX (at) bidix (dot) info',
	license: '[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D]]',
	coreVersion: '2.2.0 (Beta 5)'
};

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

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

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

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

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

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

merge(config.optionsDesc,{
		pasPassword: "Test password"
	});
*/
//}}}
These are the various projects I am or have worked on.
Representative publications are available on my [[CV|http://parsons.its.uci.edu/~crindt/professional/cv]]
<<search>><<closeAll>><<permaview>><<newTiddler>><<newJournal 'DD MMM YYYY'>><<saveChanges>><<upload>><<slider chkSliderOptionsPanel OptionsPanel 'options ยป' 'Change TiddlyWiki advanced options'>> <<exportTiddlers>>
/***
|Name|SinglePageModePlugin|
|Source|http://www.TiddlyTools.com/#SinglePageModePlugin|
|Version|2.3.1|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <<br>>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides|Story.prototype.displayTiddler(), Story.prototype.displayTiddlers()|
|Description|Display tiddlers one at a time with automatic update of URL (permalink).  Also, options to always open tiddlers at top/bottom of page|

Normally, as you click on the links in TiddlyWiki, more and more tiddlers are displayed on the page. The order of this tiddler display depends upon when and where you have clicked. Some people like this non-linear method of reading the document, while others have reported that when many tiddlers have been opened, it can get somewhat confusing.

!!!!!Usage
<<<
SinglePageMode allows you to configure TiddlyWiki to navigate more like a traditional multipage web site with only one item displayed at a time.  When SinglePageMode is enabled, the title of the current tiddler is automatically displayed in the browser window's titlebar and the browser's location URL is updated with a 'permalink' for the current tiddler so that it is easier to create a browser 'bookmark' for the current tiddler.

Even when SinglePageMode is disabled (i.e., displaying multiple tiddlers is permitted), you can reduce the potential for confusion by enable TopOfPageMode, which forces tiddlers to always open at the top of the page instead of being displayed following the tiddler containing the link that was clicked.
<<<
!!!!!Configuration
<<<
When installed, this plugin automatically adds checkboxes in the AdvancedOptions tiddler so you can enable/disable the plugin behavior.  For convenience, these checkboxes are also included here:

<<option chkSinglePageMode>> Display one tiddler at a time
<<option chkTopOfPageMode>> Always open tiddlers at the top of the page
<<option chkBottomOfPageMode>> Always open tiddlers at the bottom of the page
//(note: if both settings are selected, "top of page" is used)//
<<<
!!!!!Installation
<<<
import (or copy/paste) the following tiddlers into your document:
''SinglePageModePlugin'' (tagged with <<tag systemConfig>>)
^^documentation and javascript for SinglePageMode handling^^

When installed, this plugin automatically adds checkboxes in the ''shadow'' AdvancedOptions tiddler so you can enable/disable this behavior.  However, if you have customized your AdvancedOptions, you will need to ''manually add these checkboxes to your customized tiddler.''
<<<
!!!!!Revision History
<<<
''2007.03.03 [2.3.1]'' fix typo when adding BPM option to AdvancedOptions (prevented checkbox from appearing)
''2007.03.03 [2.3.0]'' added support for BottomOfPageMode (BPM) based on request from DaveGarbutt
''2007.02.06 [2.2.3]'' in Story.prototype.displayTiddler(), use convertUnicodeToUTF8() for correct I18N string handling when creating URL hash string from tiddler title (based on bug report from BidiX)
''2007.01.08 [2.2.2]'' use apply() to invoke hijacked core functions
''2006.07.04 [2.2.1]'' in hijack for displayTiddlers(), suspend TPM as well as SPM so that DefaultTiddlers displays in the correct order.
''2006.06.01 [2.2.0]'' added chkTopOfPageMode (TPM) handling
''2006.02.04 [2.1.1]'' moved global variable declarations to config.* to avoid FireFox 1.5.0.1 crash bug when assigning to globals
''2005.12.27 [2.1.0]'' hijack displayTiddlers() so that SPM can be suspended during startup while displaying the DefaultTiddlers (or #hash list).  Also, corrected initialization for undefined SPM flag to "false", so default behavior is to display multiple tiddlers
''2005.12.27 [2.0.0]'' Update for TW2.0
''2005.11.24 [1.1.2]'' When the back and forward buttons are used, the page now changes to match the URL.  Based on code added by Clint Checketts
''2005.10.14 [1.1.1]'' permalink creation now calls encodeTiddlyLink() to handle tiddler titles with spaces in them
''2005.10.14 [1.1.0]'' added automatic setting of window title and location bar ('auto-permalink').  feature suggestion by David Dickens.
''2005.10.09 [1.0.1]'' combined documentation and code in a single tiddler
''2005.08.15 [1.0.0]'' Initial Release
<<<
!!!!!Credits
<<<
This feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]].
Support for BACK/FORWARD buttons adapted from code developed by Clint Checketts
<<<
!!!!!Code
***/
//{{{
version.extensions.SinglePageMode= {major: 2, minor: 3, revision: 1, date: new Date(2007,3,3)};

if (config.options.chkSinglePageMode==undefined) config.options.chkSinglePageMode=false;
config.shadowTiddlers.AdvancedOptions += "\n<<option chkSinglePageMode>> Display one tiddler at a time";

if (config.options.chkTopOfPageMode==undefined) config.options.chkTopOfPageMode=false;
config.shadowTiddlers.AdvancedOptions += "\n<<option chkTopOfPageMode>> Always open tiddlers at the top of the page";

if (config.options.chkBottomOfPageMode==undefined) config.options.chkBottomOfPageMode=false;
config.shadowTiddlers.AdvancedOptions += "\n<<option chkBottomOfPageMode>> Always open tiddlers at the bottom of the page";

config.SPMTimer = 0;
config.lastURL = window.location.hash;
function checkLastURL()
{
	if (!config.options.chkSinglePageMode)
		{ window.clearInterval(config.SPMTimer); config.SPMTimer=0; return; }
	if (config.lastURL == window.location.hash)
		return;
	var tiddlerName = convertUTF8ToUnicode(decodeURI(window.location.hash.substr(1)));
	tiddlerName=tiddlerName.replace(/\[\[/,"").replace(/\]\]/,""); // strip any [[ ]] bracketing
	if (tiddlerName.length) story.displayTiddler(null,tiddlerName,1,null,null);
}

if (Story.prototype.SPM_coreDisplayTiddler==undefined) Story.prototype.SPM_coreDisplayTiddler=Story.prototype.displayTiddler;
Story.prototype.displayTiddler = function(srcElement,title,template,animate,slowly)
{
	if (config.options.chkSinglePageMode) {
		window.location.hash = encodeURIComponent(convertUnicodeToUTF8(String.encodeTiddlyLink(title)));
		config.lastURL = window.location.hash;
		document.title = wikifyPlain("SiteTitle") + " - " + title;
		story.closeAllTiddlers();
		if (!config.SPMTimer) config.SPMTimer=window.setInterval(function() {checkLastURL();},1000);
	}
	if (config.options.chkTopOfPageMode) { story.closeTiddler(title); srcElement=null; }
	else if (config.options.chkBottomOfPageMode) { story.closeTiddler(title); srcElement="bottom"; }
	this.SPM_coreDisplayTiddler.apply(this,arguments);
	if (config.options.chkTopOfPageMode) window.scrollTo(0,0); // make sure top of page is visible
	else if (config.options.chkBottomOfPageMode) {
		var display=document.getElementById("tiddlerDisplay"); // for TW2.1-
		if (!display) var display=document.getElementById("storyDisplay"); // for TW2.2+
		window.scrollTo(0,ensureVisible(display.lastChild)); // make sure last tiddler is visible
	}
}

if (Story.prototype.SPM_coreDisplayTiddlers==undefined) Story.prototype.SPM_coreDisplayTiddlers=Story.prototype.displayTiddlers;
Story.prototype.displayTiddlers = function(srcElement,titles,template,unused1,unused2,animate,slowly)
{
	// suspend single-page mode (and/or top/bottom display options) when showing multiple tiddlers
	var saveSPM=config.options.chkSinglePageMode; config.options.chkSinglePageMode=false;
	var saveTPM=config.options.chkTopOfPageMode; config.options.chkTopOfPageMode=false;
	var saveBPM=config.options.chkBottomOfPageMode; config.options.chkBottomOfPageMode=false;
	this.SPM_coreDisplayTiddlers.apply(this,arguments);
	config.options.chkBottomOfPageMode=saveBPM;
	config.options.chkTopOfPageMode=saveTPM;
	config.options.chkSinglePageMode=saveSPM;
}
//}}}
a static homepage for obtaining information about me...
Craig Rindt
http://parsons.its.uci.edu/~crindt/index.html
Tiddlers with this tag will always be displayed on the site.
<<timeline better:true onlyTag:Blog sortBy:created maxDays:7 maxEntries:30>>
/***
| Name|TagglyTaggingPlugin|
| Description|tagglyTagging macro is a replacement for the builtin tagging macro in your ViewTemplate|
| Version|3.0 ($Rev: 2101 $)|
| Date|$Date: 2007-04-20 00:24:20 +1000 (Fri, 20 Apr 2007) $|
| Source|http://mptw.tiddlyspot.com/#TagglyTaggingPlugin|
| Author|Simon Baird <simon.baird@gmail.com>|
| License|http://mptw.tiddlyspot.com/#TheBSDLicense|
!Notes
See http://mptw.tiddlyspot.com/#TagglyTagging
***/
//{{{
config.taggly = {

	// for translations
	lingo: {
		labels: {
			asc:        "\u2191", // down arrow
			desc:       "\u2193", // up arrow
			title:      "title",
			modified:   "modified",
			created:    "created",
			show:       "+",
			hide:       "-",
			normal:     "normal",
			group:      "group",
			commas:     "commas",
			sitemap:    "sitemap",
			numCols:    "cols\u00b1", // plus minus sign
			label:      "Tagged as '%0':",
			excerpts:   "excerpts",
			noexcerpts: "no excerpts"
		},

		tooltips: {
			title:    "Click to sort by title",
			modified: "Click to sort by modified date",
			created:  "Click to sort by created date",
			show:     "Click to show tagging list",
			hide:     "Click to hide tagging list",
			normal:   "Click to show a normal ungrouped list",
			group:    "Click to show list grouped by tag",
			sitemap:  "Click to show a sitemap style list",
			commas:   "Click to show a comma separated list",
			numCols:  "Click to change number of columns"
		}
	},

	config: {
		showTaggingCounts: true,
		listOpts: {
			// the first one will be the default
			sortBy:     ["title","modified","created"],
			sortOrder:  ["asc","desc"],
			hideState:  ["show","hide"],
			listMode:   ["normal","group","sitemap","commas"],
			numCols:    ["1","2","3","4","5","6"],
			excerpts:   ["noexcerpts","excerpts"]
		},
		valuePrefix: "taggly.",
		excludeTags: ["excludeLists","excludeTagging"],
		excerptSize: 50,
		excerptMarker: "/%"+"%/"
	},

	getTagglyOpt: function(title,opt) {
		var val = store.getValue(title,this.config.valuePrefix+opt);
		return val ? val : this.config.listOpts[opt][0];
	},

	setTagglyOpt: function(title,opt,value) {
		if (!store.tiddlerExists(title))
			// create it silently
			store.saveTiddler(title,title,config.views.editor.defaultText.format([title]),config.options.txtUserName,new Date(),null);
		// if value is default then remove it to save space
		return store.setValue(title,
			this.config.valuePrefix+opt,
			value == this.config.listOpts[opt][0] ? null : value);
	},

	getNextValue: function(title,opt) {
		var current = this.getTagglyOpt(title,opt);
		var pos = this.config.listOpts[opt].indexOf(current);
		// a little usability enhancement. actually it doesn't work right for grouped or sitemap
		var limit = (opt == "numCols" ? store.getTaggedTiddlers(title).length : this.config.listOpts[opt].length);
		var newPos = (pos + 1) % limit;
		return this.config.listOpts[opt][newPos];
	},

	toggleTagglyOpt: function(title,opt) {
		var newVal = this.getNextValue(title,opt);
		this.setTagglyOpt(title,opt,newVal);
	}, 

	createListControl: function(place,title,type) {
		var lingo = config.taggly.lingo;
		var label;
		var tooltip;
		var onclick;

		if ((type == "title" || type == "modified" || type == "created")) {
			// "special" controls. a little tricky. derived from sortOrder and sortBy
			label = lingo.labels[type];
			tooltip = lingo.tooltips[type];

			if (this.getTagglyOpt(title,"sortBy") == type) {
				label += lingo.labels[this.getTagglyOpt(title,"sortOrder")];
				onclick = function() {
					config.taggly.toggleTagglyOpt(title,"sortOrder");
					return false;
				}
			}
			else {
				onclick = function() {
					config.taggly.setTagglyOpt(title,"sortBy",type);
					config.taggly.setTagglyOpt(title,"sortOrder",config.taggly.config.listOpts.sortOrder[0]);
					return false;
				}
			}
		}
		else {
			// "regular" controls, nice and simple
			label = lingo.labels[type == "numCols" ? type : this.getNextValue(title,type)];
			tooltip = lingo.tooltips[type == "numCols" ? type : this.getNextValue(title,type)];
			onclick = function() {
				config.taggly.toggleTagglyOpt(title,type);
				return false;
			}
		}

		// hide button because commas don't have columns
		if (!(this.getTagglyOpt(title,"listMode") == "commas" && type == "numCols"))
			createTiddlyButton(place,label,tooltip,onclick,type == "hideState" ? "hidebutton" : "button");
	},

	makeColumns: function(orig,numCols) {
		var listSize = orig.length;
		var colSize = listSize/numCols;
		var remainder = listSize % numCols;

		var upperColsize = colSize;
		var lowerColsize = colSize;

		if (colSize != Math.floor(colSize)) {
			// it's not an exact fit so..
			upperColsize = Math.floor(colSize) + 1;
			lowerColsize = Math.floor(colSize);
		}

		var output = [];
		var c = 0;
		for (var j=0;j<numCols;j++) {
			var singleCol = [];
			var thisSize = j < remainder ? upperColsize : lowerColsize;
			for (var i=0;i<thisSize;i++) 
				singleCol.push(orig[c++]);
			output.push(singleCol);
		}

		return output;
	},

	drawTable: function(place,columns,theClass) {
		var newTable = createTiddlyElement(place,"table",null,theClass);
		var newTbody = createTiddlyElement(newTable,"tbody");
		var newTr = createTiddlyElement(newTbody,"tr");
		for (var j=0;j<columns.length;j++) {
			var colOutput = "";
			for (var i=0;i<columns[j].length;i++) 
				colOutput += columns[j][i];
			var newTd = createTiddlyElement(newTr,"td",null,"tagglyTagging"); // todo should not need this class
			wikify(colOutput,newTd);
		}
		return newTable;
	},

	createTagglyList: function(place,title) {
		switch(this.getTagglyOpt(title,"listMode")) {
			case "group":  return this.createTagglyListGrouped(place,title); break;
			case "normal": return this.createTagglyListNormal(place,title,false); break;
			case "commas": return this.createTagglyListNormal(place,title,true); break;
			case "sitemap":return this.createTagglyListSiteMap(place,title); break;
		}
	},

	getTaggingCount: function(title) {
		// thanks to Doug Edmunds
		if (this.config.showTaggingCounts) {
			var tagCount = store.getTaggedTiddlers(title).length;
			if (tagCount > 0)
				return " ("+tagCount+")";
		}
		return "";
	},

	getExcerpt: function(inTiddlerTitle,title) {
		if (this.getTagglyOpt(inTiddlerTitle,"excerpts") == "excerpts") {
			var t = store.getTiddler(title);
			if (t) {
				var text = t.text.replace(/\n/," ");
				var marker = text.indexOf(this.config.excerptMarker);
				if (marker != -1) {
					return " {{excerpt{<nowiki>" + text.substr(0,marker) + "</nowiki>}}}";
				}
				else if (text.length < this.config.excerptSize) {
					return " {{excerpt{<nowiki>" + t.text + "</nowiki>}}}";
				}
				else {
					return " {{excerpt{<nowiki>" + t.text.substr(0,this.config.excerptSize) + "..." + "</nowiki>}}}";
				}
			}
		}
		return "";
	},

	notHidden: function(t,inTiddler) {
		if (typeof t == "string") 
			t = store.getTiddler(t);
		return (!t || !t.tags.containsAny(this.config.excludeTags) ||
				(inTiddler && this.config.excludeTags.contains(inTiddler)));
	},

	// this is for normal and commas mode
	createTagglyListNormal: function(place,title,useCommas) {

		var list = store.getTaggedTiddlers(title,this.getTagglyOpt(title,"sortBy"));

		if (this.getTagglyOpt(title,"sortOrder") == "desc")
			list = list.reverse();

		var output = [];
		var first = true;
		for (var i=0;i<list.length;i++) {
			if (this.notHidden(list[i],title)) {
				var countString = this.getTaggingCount(list[i].title);
				var excerpt = this.getExcerpt(title,list[i].title);
				if (useCommas)
					output.push((first ? "" : ", ") + "[[" + list[i].title + "]]" + countString + excerpt);
				else
					output.push("*[[" + list[i].title + "]]" + countString + excerpt + "\n");

				first = false;
			}
		}

		return this.drawTable(place,
			this.makeColumns(output,useCommas ? 1 : parseInt(this.getTagglyOpt(title,"numCols"))),
			useCommas ? "commas" : "normal");
	},

	// this is for the "grouped" mode
	createTagglyListGrouped: function(place,title) {
		var sortBy = this.getTagglyOpt(title,"sortBy");
		var sortOrder = this.getTagglyOpt(title,"sortOrder");

		var list = store.getTaggedTiddlers(title,sortBy);

		if (sortOrder == "desc")
			list = list.reverse();

		var leftOvers = []
		for (var i=0;i<list.length;i++)
			leftOvers.push(list[i].title);

		var allTagsHolder = {};
		for (var i=0;i<list.length;i++) {
			for (var j=0;j<list[i].tags.length;j++) {

				if (list[i].tags[j] != title) { // not this tiddler

					if (this.notHidden(list[i].tags[j],title)) {

						if (!allTagsHolder[list[i].tags[j]])
							allTagsHolder[list[i].tags[j]] = "";

						if (this.notHidden(list[i],title)) {
							allTagsHolder[list[i].tags[j]] += "**[["+list[i].title+"]]"
										+ this.getTaggingCount(list[i].title) + this.getExcerpt(title,list[i].title) + "\n";

							leftOvers.setItem(list[i].title,-1); // remove from leftovers. at the end it will contain the leftovers

						}
					}
				}
			}
		}

		var allTags = [];
		for (var t in allTagsHolder)
			allTags.push(t);

		var sortHelper = function(a,b) {
			if (a == b) return 0;
			if (a < b) return -1;
			return 1;
		};

		allTags.sort(function(a,b) {
			var tidA = store.getTiddler(a);
			var tidB = store.getTiddler(b);
			if (sortBy == "title") return sortHelper(a,b);
			else if (!tidA && !tidB) return 0;
			else if (!tidA) return -1;
			else if (!tidB) return +1;
			else return sortHelper(tidA[sortBy],tidB[sortBy]);
		});

		var leftOverOutput = "";
		for (var i=0;i<leftOvers.length;i++)
			if (this.notHidden(leftOvers[i],title))
				leftOverOutput += "*[["+leftOvers[i]+"]]" + this.getTaggingCount(leftOvers[i]) + this.getExcerpt(title,leftOvers[i]) + "\n";

		var output = [];

		if (sortOrder == "desc")
			allTags.reverse();
		else if (leftOverOutput != "")
			// leftovers first...
			output.push(leftOverOutput);

		for (var i=0;i<allTags.length;i++)
			if (allTagsHolder[allTags[i]] != "")
				output.push("*[["+allTags[i]+"]]" + this.getTaggingCount(allTags[i]) + this.getExcerpt(title,allTags[i]) + "\n" + allTagsHolder[allTags[i]]);

		if (sortOrder == "desc" && leftOverOutput != "")
			// leftovers last...
			output.push(leftOverOutput);

		return this.drawTable(place,
				this.makeColumns(output,parseInt(this.getTagglyOpt(title,"numCols"))),
				"grouped");

	},

	// used to build site map
	treeTraverse: function(title,depth,sortBy,sortOrder) {

		var list = store.getTaggedTiddlers(title,sortBy);
		if (sortOrder == "desc")
			list.reverse();

		var indent = "";
		for (var j=0;j<depth;j++)
			indent += "*"

		var childOutput = "";
		for (var i=0;i<list.length;i++)
			if (list[i].title != title)
				if (this.notHidden(list[i].title,this.config.inTiddler))
					childOutput += this.treeTraverse(list[i].title,depth+1,sortBy,sortOrder);

		if (depth == 0)
			return childOutput;
		else
			return indent + "[["+title+"]]" + this.getTaggingCount(title) + this.getExcerpt(this.config.inTiddler,title) + "\n" + childOutput;
	},

	// this if for the site map mode
	createTagglyListSiteMap: function(place,title) {
		this.config.inTiddler = title; // nasty. should pass it in to traverse probably
		var output = this.treeTraverse(title,0,this.getTagglyOpt(title,"sortBy"),this.getTagglyOpt(title,"sortOrder"));
		return this.drawTable(place,
				this.makeColumns(output.split(/(?=^\*\[)/m),parseInt(this.getTagglyOpt(title,"numCols"))), // regexp magic
				"sitemap"
				);
	},

	macros: {
		tagglyTagging: {
			handler: function (place,macroName,params,wikifier,paramString,tiddler) {
				var refreshContainer = createTiddlyElement(place,"div");
				// do some refresh magic to make it keep the list fresh - thanks Saq
				refreshContainer.setAttribute("refresh","macro");
				refreshContainer.setAttribute("macroName",macroName);
        			refreshContainer.setAttribute("title",tiddler.title);
				this.refresh(refreshContainer);
			},

			refresh: function(place) {
				var title = place.getAttribute("title");
				removeChildren(place);
				if (store.getTaggedTiddlers(title).length > 0) {
					var lingo = config.taggly.lingo;
					config.taggly.createListControl(place,title,"hideState");
					if (config.taggly.getTagglyOpt(title,"hideState") == "show") {
						createTiddlyElement(place,"span",null,"tagglyLabel",lingo.labels.label.format([title]));
						config.taggly.createListControl(place,title,"title");
						config.taggly.createListControl(place,title,"modified");
						config.taggly.createListControl(place,title,"created");
						config.taggly.createListControl(place,title,"listMode");
						config.taggly.createListControl(place,title,"excerpts");
						config.taggly.createListControl(place,title,"numCols");
						config.taggly.createTagglyList(place,title);
					}
				}
			}
		}
	},

	// todo fix these up a bit
	styles: [
"/*{{{*/",
"/* created by TagglyTaggingPlugin */",
".tagglyTagging { padding-top:0.5em; }",
".tagglyTagging li.listTitle { display:none; }",
".tagglyTagging ul {",
"	margin-top:0px; padding-top:0.5em; padding-left:2em;",
"	margin-bottom:0px; padding-bottom:0px;",
"}",
".tagglyTagging { vertical-align: top; margin:0px; padding:0px; }",
".tagglyTagging table { margin:0px; padding:0px; }",
".tagglyTagging .button { visibility:hidden; margin-left:3px; margin-right:3px; }",
".tagglyTagging .button, .tagglyTagging .hidebutton {",
"	color:[[ColorPalette::TertiaryLight]]; font-size:90%;",
"	border:0px; padding-left:0.3em;padding-right:0.3em;",
"}",
".tagglyTagging .button:hover, .hidebutton:hover, ",
".tagglyTagging .button:active, .hidebutton:active  {",
"	border:0px; background:[[ColorPalette::TertiaryPale]]; color:[[ColorPalette::TertiaryDark]];",
"}",
".selected .tagglyTagging .button { visibility:visible; }",
".tagglyTagging .hidebutton { color:[[ColorPalette::Background]]; }",
".selected .tagglyTagging .hidebutton { color:[[ColorPalette::TertiaryLight]] }",
".tagglyLabel { color:[[ColorPalette::TertiaryMid]]; font-size:90%; }",
".tagglyTagging ul {padding-top:0px; padding-bottom:0.5em; margin-left:1em; }",
".tagglyTagging ul ul {list-style-type:disc; margin-left:-1em;}",
".tagglyTagging ul ul li {margin-left:0.5em; }",
".editLabel { font-size:90%; padding-top:0.5em; }",
".tagglyTagging .commas { padding-left:1.8em; }",
"/* not technically tagglytagging but will put them here anyway */",
".tagglyTagged li.listTitle { display:none; }",
".tagglyTagged li { display: inline; font-size:90%; }",
".tagglyTagged ul { margin:0px; padding:0px; }",
".excerpt { color:[[ColorPalette::TertiaryMid]]; }",
"div.tagglyTagging table,",
"div.tagglyTagging table tr,",
"td.tagglyTagging",
" {border-style:none!important; }",
"/*}}}*/",
		""].join("\n"),

	init: function() {
		merge(config.macros,this.macros);
		config.shadowTiddlers["TagglyTaggingStyles"] = this.styles;
		store.addNotification("TagglyTaggingStyles",refreshStyles);
	}
};

config.taggly.init();

//}}}

[[TiddlyWiki|http://www.tiddlywiki.com]] is the "software" used on these personal web pages.  It is implemented entirely using client-side javascript and is very cool. If you're reading this right now, your web browser contains my complete blog/wiki (or, as I'm calling it, my [[NoteBlog]]).
UploadPlugin with <<tag UploadService>> extend TiddlyWiki with @@upload@@ and @@save to web@@ commands. 

See [[HowToUpload]].

[[Upload]] is :
<<tiddler UploadPluginDoc>>
This form upload any file with an UploadService describe in [[Upload]]
----
<html><center>
<form enctype="multipart/form-data" action="store.php" method="post" target="_blank">
 <input type="hidden" name="MAX_FILE_SIZE" value="3000000" />
This file : <input name="userfile" type="file" /><p>
Options* : <input type="text" name="UploadPlugin" size=80 value="backupDir=BACKUP_DIR;uploaddir=UPLOAD_DIR;user=UPLOAD_USER;password=UPLOAD_PASSWORD;debug=0;" /><p>
 <input type="submit" value="Upload" />
</form></center>
</html>
----
 * Substitute BACKUP_DIR, UPLOAD_DIR, UPLOAD_USER and UPLOAD_PASSWORD with your values. See UploadPlugin for option details. 
For security reason, don't save your password in a tiddler.
| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |
| 11/06/2007 10:58:39 | Craig Rindt | [[noteblog.html|file:///home/crindt/Desktop/noteblog/noteblog.html]] | [[store-tw.php|file:///home/crindt/Desktop/noteblog/[http://parsons.its.uci.edu/~crindt/store-tw.php]] | [noteblog | [[[index.html | file:///home/crindt/Desktop/noteblog/[http://parsons.its.uci.edu/~crindt/[noteblog/[index.html]] | [noteblog/backup |
| 11/06/2007 10:58:55 | Craig Rindt | [[noteblog.html|file:///home/crindt/Desktop/noteblog/noteblog.html]] | [[store-tw.php|http://parsons.its.uci.edu/~crindt/store-tw.php]] | noteblog | [[index.html | http://parsons.its.uci.edu/~crindt/noteblog/index.html]] | noteblog/backup | ok |
| 11/06/2007 10:59:02 | Craig Rindt | [[noteblog.html|file:///home/crindt/Desktop/noteblog/noteblog.html]] | [[store-tw.php|file:///home/crindt/Desktop/noteblog/[http://parsons.its.uci.edu/~crindt/store-tw.php]] | [noteblog | [[[index.html | file:///home/crindt/Desktop/noteblog/[http://parsons.its.uci.edu/~crindt/[noteblog/[index.html]] | [noteblog/backup |
| 11/06/2007 10:59:19 | Craig Rindt | [[noteblog.html|file:///home/crindt/Desktop/noteblog/noteblog.html]] | [[store-tw.php|http://parsons.its.uci.edu/~crindt/store-tw.php]] | noteblog | [[index.html | http://parsons.its.uci.edu/~crindt/noteblog/index.html]] | noteblog/backup | ok |
| 11/06/2007 11:29:57 | Craig Rindt | [[noteblog.html|file:///home/crindt/Desktop/noteblog/noteblog.html]] | [[store.php|file:///home/crindt/Desktop/noteblog/store.php]] | . | [[index.html | file:///home/crindt/Desktop/noteblog/index.html]] | noteblog/backup |
| 11/06/2007 11:30:08 | Craig Rindt | [[noteblog.html|file:///home/crindt/Desktop/noteblog/noteblog.html]] | [[store-tw.php|http://parsons.its.uci.edu/~crindt/store-tw.php]] | noteblog | [[index.html | http://parsons.its.uci.edu/~crindt/noteblog/index.html]] | noteblog/backup | ok |
| 15/06/2007 09:01:08 | Craig Rindt | [[index.html|file:///home/crindt/public_html/index.html]] | [[store.php|file:///home/crindt/public_html/store.php]] | . | [[index.html | file:///home/crindt/public_html/index.html]] | noteblog/backup |
| 15/06/2007 09:02:52 | Craig Rindt | [[index.html|file:///home/crindt/public_html/index.html]] | [[store.php|file:///home/crindt/public_html/store.php]] | . | [[index.html | file:///home/crindt/public_html/index.html]] | noteblog/backup |
| 15/06/2007 09:09:28 | Craig Rindt | [[index.html|file:///home/crindt/public_html/index.html]] | [[store.php|file:///home/crindt/public_html/store.php]] | . | [[index.html | file:///home/crindt/public_html/index.html]] | noteblog/backup |
| 15/06/2007 09:10:20 | Craig Rindt | [[index.html|file:///home/crindt/public_html/index.html]] | [[store-tw.php|http://parsons.its.uci.edu/~crindt/store-tw.php]] | . | [[index.html | http://parsons.its.uci.edu/~crindt/index.html]] | homepage-backup | failed |
UploadPlugin uses the following sequence for finding parameters :
#''macro'' parameters
#''Options'' saved in cookies
#''Plugin'' default values
!Options used by UploadPlugin
| Option | Value | Default |
|Upload Username: |<<option txtUploadUserName>>| |
|Upload Password: |<<option pasUploadPassword>>| |
|Url of the UploadService script: |<<option txtUploadStoreUrl urlInput>>| store.php |
|Relative Directory where to store the file: |<<option txtUploadDir urlInput>>| . (the script directory) |
|Filename of the uploaded file: |<<option txtUploadFilename urlInput>>| index.html |
|Directory to backup file on webserver^^(1)^^: |<<option txtUploadBackupDir urlInput>>| //null// (none/no backup) |
|Log in UploadLog |<<option chkUploadLog>> Trace Upload| true |
|Maximum of lines in UploadLog |<<option txtUploadLogMaxLine>>| 10 |

^^(1)^^No backup if Backup Directory is empty, the previous file will be overwritten. Use a '.' to backup in the script directory.

<<upload>> with these options.

!Upload Macro parameters
{{{
<<upload [storeUrl [toFilename [backupDir [uploadDir [username]]]]]>>
 Optional positional parameters can be passed to overwrite UploadOptions. 
}}}

!UploadToFile Macro Macro parameters
{{{
<<uploadTofile [filename [tiddlerTitle]]>>
 tiddlerTitle, filename: if omitted the title of the current tiddler
}}}

<<uploadToFile allowedsites.txt allowedsites.txt>>
/***
|''Name:''|UploadPlugin|
|''Description:''|Save to web a TiddlyWiki|
|''Version:''|4.1.0|
|''Date:''|May 5, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#UploadPlugin|
|''Documentation:''|http://tiddlywiki.bidix.info/#UploadPluginDoc|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0 (#3125)|
|''Requires:''|PasswordOptionPlugin|
***/
//{{{
version.extensions.UploadPlugin = {
	major: 4, minor: 1, revision: 0,
	date: new Date("May 5, 2007"),
	source: 'http://tiddlywiki.bidix.info/#UploadPlugin',
	author: 'BidiX (BidiX (at) bidix (dot) info',
	coreVersion: '2.2.0 (#3125)'
};

//
// Environment
//

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

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

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

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

config.macros.upload.action = function(params)
{
		// for missing macro parameter set value from options
		var storeUrl