ParDelib is getting its ducks in a row ...
Javascript Required .
Participatory Deliberation - - It's about discourse! (TiddlyWiki on bentrem.sycks.net)
<!--{{{-->
<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml'/>
<!--}}}-->
Background: #fff
Foreground: #000
PrimaryPale: #8cf
PrimaryLight: #18f
PrimaryMid: #04b
PrimaryDark: #014
SecondaryPale: #ffc
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #841
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #666
Error: #f88
/*{{{*/
body {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

hr {height:1px;}

a {text-decoration:none;}

dt {font-weight:bold;}

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

.txtOptionInput {width:11em;}

#contentWrapper .chkOptionInput {border:0;}

.externalLink {text-decoration:underline;}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

----
Also see AdvancedOptions
<<importTiddlers>>
|''Type:''|file|
|''URL:''|file://C:\buffer\tw\empty.bak.html|
|''Workspace:''|(default)|

This tiddler was automatically created to record the details of this server
|''Type:''|file|
|''URL:''|file://C:\buffer\tw\plugins\formatting_tiddlytools.html|
|''Workspace:''|(default)|

This tiddler was automatically created to record the details of this server
|''Type:''|file|
|''URL:''|http://cctiddly.sourceforge.net|
|''Workspace:''|(default)|

This tiddler was automatically created to record the details of this server
|''Type:''|file|
|''URL:''|http://cctiddly.sourceforge.net/|
|''Workspace:''|(default)|

This tiddler was automatically created to record the details of this server
|''Type:''|file|
|''URL:''|http://tiddlytools.com|
|''Workspace:''|(default)|

This tiddler was automatically created to record the details of this server
|''Type:''|file|
|''URL:''|http://tiddlywiki.bidix.info/|
|''Workspace:''|(default)|

This tiddler was automatically created to record the details of this server
|''Type:''|file|
|''URL:''|http://tiddlywikitips.com/|
|''Workspace:''|(default)|

This tiddler was automatically created to record the details of this server
|''Type:''|file|
|''URL:''|http://wiki.osmosoft.com/alpha/pardelib|
|''Workspace:''|(default)|

This tiddler was automatically created to record the details of this server
This is paradigmatically different in many, many ways. 1st, no evidence of markup ... or help on the subject. 2nd failure at an intuitive level e.g. I add an item to DefaultTiddlers but don't see how I can add that to the menu alongside GettingStarted. 3rd, just plain weirdness: "Help" is located under "Options" ... HeyHo.

bummer
Since "New Journal" doesn't create a CamelCase tiddler, I wasn't able to add that item to DefaultTiddlers. So I created this one. Which doesn't show up as a link in DefaultTiddlers. *sigh*

This is paradigmatically different in many, many ways. 1st, no evidence of markup ... or help on the subject. 2nd failure at an intuitive level e.g. I add an item to DefaultTiddlers but don't see how I can add that to the menu alongside GettingStarted. 3rd, just plain weirdness: "Help" is located under "Options" ... HeyHo.

bummer
Well, with help from a number of sources I've nailed the basics ... even discovered how to do --strikeout--!

----

--see [[Requirements]] from http://cctiddly.sourceforge.net/-- ... this didn't work. Dunno why, copied the source directly from the original. ''This is now working''

AltMenu is the Main Menu from http://www.hawksworx.com/playground/TeamTasks/ ... a simple slider, without the nice internal nesting the other has, but at least this works here.
I just now discovered AnonDefaultTiddlers ... a good thing to find!

A few minutes ago I finished the first cut of [[Resources]] ... something to build on.

Earlier, with email from Simon, I gave Import a spin ... managed to grab one Tiddler, but --didn't get the slider functionality I'd wanted. ~HeyHo, and so it goes!--

//Addendum//: ~Ace_NoOne on IRC pointed me to this: [[SourceForge #NestedSlidersPlugin|http://cctiddly.sourceforge.net/#NestedSlidersPlugin]]
That brought me to [[TiddlyTools #NestedSlidersPlugin|http://www.tiddlytools.com/#NestedSlidersPlugin]] and [[TiddlyTools #NestedSlidersPluginInfo|http://www.tiddlytools.com/#NestedSlidersPluginInfo]]
The key instructions were on [[the Wiki Plugins page|http://www.tiddlywiki.org/wiki/Plugins]], i.e. "In order to install a plugin, the respective tiddler(s) need to be imported (or simply copied in edit mode) from the source into the TiddlyWiki document. In order to be processed on startup, plugins need to be assigned the "systemConfig" tag. "
[[Requirements]] is now fully nested.

>//NB: constantly having to log in again and again and again is fucking bullshit. Ok? Ok. Now, where was I ... ohhhh yaa, now I have to restore that whole fucking paragraph full of links. (How long has this been around? Yaa yaa I know, all I'm good for is picking gnits ... GD amateurs.)
It's like Twitter ... unless you want to lose your work before committing you select all and copy, then hit the button.//

----
Of historical interest:
*A [[whole list of interviews with TiddlyHackers|http://mptw1.tiddlyspot.com/#The TiddlyWiki Report]] at Simon Baird's [["MonkeyPirateTiddlyWiki"|http://mptw1.tiddlyspot.com/]]. (Do peek [[Simon's main blog|http://glosoli.blogspot.com/]].) 
Case in point: [["The TiddlyWiki Report, Part IV: Jeremy Ruston"|http://loosewire.typepad.com/blog/2005/08/the_tiddlywiki__3.html]] ("The man who started it all".)
And just now came upon Saq Imtiaz's [["TiddlySnip" FireFox extension|http://tiddlysnip.com/]]

Refactored [[Resources]] and GettingStarted.

Just now discovered http://tiddlychatter.tiddlyspot.com/
Also [[presentation template|http://lewcid.googlepages.com/presentation_empty_full.html]] ([[see it in action|http://lewcid.googlepages.com/tots.html]]) and [[WebView|http://www.giffmex.org/webviewtwexample.html]] (gotta luv the editor functions here!).
Should peek http://tiddlyspot.com/ as well.

Dragged in the TiddlerNotesPlugin, so [[Notes]] works ... but I had noped to use it in AnonGreets, so visitors could leave notes anonymousely (i.e. the //principle of ''non-destructive contribution''//) but no such luck.

''NB'': Lots of posts to grapple with on [[Saq's "Tiddly Learning" blog Lewcid.org|http://lewcid.org/]]

Hot Dang! see AccordionMenuDemo ... using [[tw.lewcid.org/#AccordionMenuPlugin|http://tw.lewcid.org/#AccordionMenuPlugin]]
''//~ToDo//'': Get a consistent look between this and the slider style in [[Resources]].
NB: StartingAccordion is a variant of GettingStarted ... note how it should be multiline but //each link causes a newline// ... ''not right''.

And likewise //Hot Dang//: DropDownDemo from [[tw.lewcid.org/#DropDownMenuPlugin|http://tw.lewcid.org/#DropDownMenuPlugin]]

Created TestTabs ... neat!

''//Project//'':
I'm seeing some really fine plugins on sites that are a) stale (unedited since sometime in 2006) and b) not accessible //via// "Import". So: how to harvest from sites such as [[Jim Barr's fully enhanced TW|http://tiddlywikitips.com/]]?
I just did a manual grap of his [[Plugin listTags]] ... no evidence that it's working; no documentation of how it's used. ~HeyHo.
His [[list of internal macros|http://tiddlywikitips.com/#Internal Macros]] is useful, for e.g. listing all tiddlers with a certain tag:
<<tag journal>>

I just grabbed his [[list of internal macros|InternalMacros]]. (The ref links are relative, so that needs to be hacked.)

Meh ... grabbed [[Plugin SplashScreen]] but no joy.

Meh again ... grabbed [[Plugin ImportTiddlers]] and got "A script from "http://wiki.osmosoft.com" was denied UniversalBrowserRead privileges." and exceptions / errors.
Ok, so now I'm getting "Could not open local document: C:\buffer\ripplerap\tiddlywikitips_empty.html" ... which isn't even slightly helpful. ~HeyHo ...
<<importTiddlers inline>>
''//NB://'' I had to un-deploy the systemConfig tag (by changing it to systemConfigwas) because it clashes with the "Backstage" import function.

----
Neato ... I just found how to include another tiddler's contents inside a tiddler, e.g. here's [[subtabB1]]:

<<tiddler "subtabB1">>
----

<<tag journal>>
*sigh* I click [[New Journal]] and the one I've been working on all day opens.
Can't have that sorta core dysfunction.
Can't.
~CannotRPTnot.

*sigh*


<<tag journal>>
//''NB''//: Disappointment: trying a use case, I a) imported a plugin (~RearrangeTiddlersPlugin) to my local file, b) uploaded that to [[my site|http://bentrem.sycks.net/tw/pardelib.html]], then c) came here and tried to import from my local ... which would have been nice. No joy. Meh.
>A script from "http://wiki.osmosoft.com" was denied UniversalBrowserRead privileges.
>[Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsIXMLHttpRequest.setRequestHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: http://wiki.osmosoft.com/alpha/pardelib :: doHttp :: line 6646" data: no]
When I tried to import from [[my site|http://bentrem.sycks.net/tw/pardelib.html]] I was again blocked, with a different error:
>"A script from "http://wiki.osmosoft.com" was denied UniversalBrowserRead privileges."
`cough`
I just tried to import from http://www.tiddlytools.com ... same problem.

So: ~ParDelib here is now out of sync with ~ParDelib local and at bentrem.sycks.net, which both have the Rearrange plugin.
And I can only see this getting worse.
Dang.

----

Ooooh, just gotta get the Plugin that gives Tiddlers a "collapse" function, see [[Deferential Geometry TW|http://deferentialgeometry.org/]]
That and getting the editor functions from [[WebView|http://www.giffmex.org/webviewtwexample.html]] ... I need a ~ToDo list! Break out the GTD functionality.

I just worked through [[Getting started with UploadPlugin|http://www.tiddlywiki.org/wiki/Getting_started_with_UploadPlugin]] and created a copy of this locally and uploaded to [[bentrem.sycks.net/tw/pardelib.html|http://bentrem.sycks.net/tw/pardelib.html]].

<<tag journal>>
My "CordonBlue" suggestion is getting [[some replies on Dev group|http://groups.google.com/group/TiddlyWikiDev/browse_thread/thread/6562d68583b31eb7?hl=en]] 

----
Well ... just started playing with stuff from bidix.com ... saved a local version and found it very attractive.
Proceeded to use the UpLoad tiddler and *blink* found it configured to pardelib.html ... it wudda blown away my previous work.
So I reconfigured it to bidix.com and [[succeeded with the upload|http://bentrem.sycks.net/tw/bidix.html]], which was nice. But then I peeked the upload config for ParDelib and, ayup, it had been changed to bidix.html.

So ... I mean, really ... my whole machine has been taken over by a single file?!
Sorry folks, that's just wrong-headed. Fine, fine, use cookies ... but cookie for bidix.html should be distinct from pardelib.html ... I mean it: really.
----

Gotta keep an eye on these:
* [[Simon Baird's Monkey Pirate TW blog|http://monkeypiratetiddlywiki.blogspot.com/]]
* Lots of posts to grapple with on [[Saq's "Tiddly Learning" blog Lewcid.org|http://lewcid.org/]]

And, incidentally: the [["It's All Text" extension for Firefox|https://addons.mozilla.org/fr/firefox/addon/4125]] (created by [[Dr. What|http://docwhat.gerf.org]]. I gotta say I'm getting more than a little fed up with people who maintain anonymity. ''Get over yourselves!'')... this is called up by the "Externalize" tiddler some TWs are using.

----

Of note: [[VisualTW|http://visualtw.ouvaton.org/VisualTW.html]] has a very interesting host: http://ouvaton.org ... most of it (all?) is in French (which don't bother me a bit), and a good deal of it relates to [[the cooperative movement over there|http://www.entreprises.coop/]] ... very interesting!

<<tag journal>>
<<section ChangedBGsIn2Plugins I switched bg color in ~DropDown and Accordion from #0066aa to #3278FC
>>
<<section MenuAccordions Trying to work DropDownDemo into MainMenu, but here's a subtle downside:
as is, my conventional [[MainMenu|MenuMenuBak]] uses inclusions ... when I create a new journal, I don't edit MainMenu, I edit [[Journals]] ... and likewise with [[Blurts]]. MainMenu doesn't change, and I end up with nice stand-alone slabs of links.
If I use drop-downs, I need to edit MainMenu, and lost those nice slabs.
>>
----
I just brought in SectionMacro from [[SabWiki (by GiffMex, at rsabine.com/|http://rsabine.com/]]
I wanted this here to work in the Section: {{{<<tiddler [[GFreeComment]]>>}}}
<<section SnagsWithSectionMacro I had hoped this section would allow me to include another Plugin, i.e. the code immediately above, but no such luck ... I can't get the functionality, I can't even include that quote code section ... bummer.>>
A near equivalent: AnonGreets now uses this type of accordion:
* Show Code
**{{myclass{
{{{<<tiddler [[GFreeComment]]>>}}}
}}}
<<accordion>>Which works well enough, but there seems no way to close it!

<<section TableFormats [[Customize your TW experience|For advanced users: Customize your TW experience]], from [[TW for the Rest of Us|http://giffmex.org/twfortherestofus.html]] ... it uses an interesting table layout; the "invisible" part isn't quite working, and --I can't get align:left and vertical-align:top; to work. So maybe FormatTables will help.-- //ayup, it did!//
!!!//haaaahaha// ... the spaces caused things to a) right align, and then b) screw up totally. heh!!!
>>
<<section GFreeCommentsWorking I just got [[GFreeComment|GFreeCommentInfo]] working and included it in tiddlers as [[GFreeComment]]. see http://gfreecomment.appspot.com/
>>
<<section ReFactorRightSideBar Just added RearrangeTiddlersPlugin ...
... and just now hid Timeline and the other tabs behind a slider, cutting the contents of SideBarTabs to SideBarContents
>>
I'm using osmosoft.com/alpha/pardelib as my test bed.

And, by way of introduction:
* http://bentrem.sycks.net
* http://groundplane.wordpress.com
* http://gnodal.livejournal.com

* http://twitter.com/bentrem/
* Section 1
** [[Link1]]
** [[Link2]]
** [[Link3]]
*Section 2
** [[Link4]]
** [[Link5]]
** [[Link6]]
*Section 3
**[[Link7]]
**[[Link8]]
**[[Link9]]
<<accordion>>

MultiLine:


* [[section1]]
**{{myclass{
Praesent posuere sodales tortor. Mauris ut erat non lacus semper porta. Mauris enim.
Phasellus tempor, metus ut dapibus lobortis, leo magna ornare metus, et pellentesque neque massa eget turpis.
Proin nec tellus. Donec aliquet.
Nullam sed leo bibendum justo rutrum rhoncus.}}}
* section2
**{{myclass{
Donec rhoncus sem eget urna.
Aenean tempor dolor vitae nisi.
Donec leo urna, placerat porttitor, auctor ut, volutpat a, purus,
Etiam eu sapien id nulla malesuada scelerisque.
Maecenas rhoncus, nibh ut aliquam consequat, mi odio luctus sem, eu lobortis dolor neque nec lectus. }}}
* section3
**{{myclass{
Donec rhoncus sem eget urna.
Aenean tempor dolor vitae nisi.
Donec leo urna, placerat porttitor, auctor ut, volutpat a, purus,
Etiam eu sapien id nulla malesuada scelerisque.
Maecenas rhoncus, nibh ut aliquam consequat, mi odio luctus sem, eu lobortis dolor neque nec lectus. }}}
<<accordion>>

<<tag demo>>
/***
|''Name:''|AccordionMenuPlugin|
|''Description:''|Turn an unordered list into an accordion style menu|
|''Author:''|Saq Imtiaz ( lewcid@gmail.com )|
|''Source:''|http://tw.lewcid.org/#AccordionMenuPlugin|
|''Code Repository:''|http://tw.lewcid.org/svn/plugins|
|''Version:''|2.0|
|''Date:''|03/11/2007|
|''License:''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''~CoreVersion:''|2.2.5|
!!Usage:
* put {{{<<accordion>>}}} on the line after your unordered list

!!Customizing:
* customize the css via the shadow tiddler StyleSheetAccordionMenuPlugin
* or give the list a custom class by passing the classes as parameters to the macro.
** Eg: {{{<<accordion ClassName1 ClassName2>>}}}

!!Examples:
*[[AccordionMenuPluginDemo]]

***/
// /%
//!BEGIN-PLUGIN-CODE
config.macros.accordion={
	dropchar : " \u00BB",
	handler : function(place,macroName,params,wikifier,paramString,tiddler){
		list = findRelated(place.lastChild,"UL","tagName","previousSibling");
		if (!list)
			return;
		addClass(list,"accordion");
		if (params.length){
			addClass(list,paramString);
		}
		this.fixLinks(list.childNodes);		
	},

	fixLinks : function(els){
		for (var i=0; i<els.length; i++){
			if(els[i].tagName.toLowerCase()=="li"){
				var link = findRelated(els[i].firstChild,"A","tagName","nextSibling");
				if(!link){
					var ih = els[i].firstChild.data;
					els[i].removeChild(els[i].firstChild);
					link = createTiddlyElement(null,"a",null,null,ih+this.dropchar,{href:"javascript:;"});
					els[i].insertBefore(link,els[i].firstChild);
				}
				else{
					link.firstChild.data = link.firstChild.data + this.dropchar;
					removeClass(link,"tiddlyLinkNonExisting");
				}
				link.onclick = this.show;
			}
		}
	},
	
	show : function(e){
		var list = this.parentNode.parentNode;
		var els = list.childNodes;
		for (var i=0; i<els.length; i++){
			removeClass(els[i],"accordion-active");
		}
		addClass(this.parentNode,"accordion-active");
	}	
};

config.shadowTiddlers["StyleSheetAccordionMenuPlugin"] = "/*{{{*/\n"+
	 "ul.accordion, ul.accordion li, ul.accordion li ul  {margin:0; padding:0; list-style-type:none;text-align:left;}\n"+
	 "ul.accordion li ul {display:none;}\n"+
	 "ul.accordion li.accordion-active ul {display:block;}\n"+
	 "\n"+
	 "ul.accordion li.accordion-active a {cursor:default;}\n"+
	 "ul.accordion li.accordion-active ul li a{cursor:pointer;}\n"+
	 "\n"+
	 "ul.accordion a {display:block; padding:0.5em;}\n"+
	 "ul.accordion li a.tiddlyLink, ul.accordion li a.tiddlyLinkNonExisting, ul.accordion li a {font-weight:bold;}\n"+
	 "ul.accordion li a {background:#3278FC; color:#FFF; border-bottom:1px solid #fff;}\n"+
	 "ul.accordion li.accordion-active a, ul.accordion li a:hover {background:#00558F;color:#FFF;}\n"+
	 "\n"+
	 "ul.accordion li ul li{display:inline-block;overflow:hidden;}\n"+
	 "ul.accordion li.accordion-active ul li {background:#eff3fa; color:#000; padding:0em;}\n"+
	 "ul.accordion li.accordion-active ul li div {padding:1em 1.5em; background:#eff3fa;}\n"+
	 "ul.accordion li.accordion-active ul a{background:#eff3fa; color:#000; padding:0.5em 0.5em 0.5em 1.0em;border:none;}\n"+
	 "ul.accordion li.accordion-active ul a:hover {background:#e0e8f5; color:#000;}\n" +
	 "/*}}}*/";
 
 store.addNotification("StyleSheetAccordionMenuPlugin",refreshStyles);
 //!END-PLUGIN-CODE
// %/
@@display:none;clear:both;@@

''Creating a navigation menu using the AccordionMenuPlugin is as simple as:''
# writing a two level unordered list using ~TiddlyWiki syntax
# and placing {{{<<accordion>>}}} on the line after it.
Example:
{{{
* Section 1
** [[Link1]]
** [[Link2]]
** [[Link3]]
*Section 2
** [[Link4]]
** [[Link5]]
** [[Link6]]
*Section 3
**[[Link7]]
**[[Link8]]
**[[Link9]]
<<accordion>>
}}}
gives:

* Section 1
** [[Link1]]
** [[Link2]]
** [[Link3]]
*Section 2
** [[Link4]]
** [[Link5]]
** [[Link6]]
*Section 3
**[[Link7]]
**[[Link8]]
**[[Link9]]
<<accordion>>

''The AccordionMenuPlugin was written with navigation menu's in mind but can be put to other uses as well. ''
By wrapping the content in a DIV, you can have multi-line content as well. Example:
{{{
* [[section1]]
**{{myclass{
Praesent posuere sodales tortor. Mauris ut erat non lacus semper porta. Mauris enim.
Phasellus tempor, metus ut dapibus lobortis, leo magna ornare metus, et pellentesque neque massa eget turpis.
Proin nec tellus. Donec aliquet.
Nullam sed leo bibendum justo rutrum rhoncus.}}}
* section2
**{{myclass{
Donec rhoncus sem eget urna.
Aenean tempor dolor vitae nisi.
Donec leo urna, placerat porttitor, auctor ut, volutpat a, purus,
Etiam eu sapien id nulla malesuada scelerisque.
Maecenas rhoncus, nibh ut aliquam consequat, mi odio luctus sem, eu lobortis dolor neque nec lectus. }}}
* section3
**{{myclass{
Donec rhoncus sem eget urna.
Aenean tempor dolor vitae nisi.
Donec leo urna, placerat porttitor, auctor ut, volutpat a, purus,
Etiam eu sapien id nulla malesuada scelerisque.
Maecenas rhoncus, nibh ut aliquam consequat, mi odio luctus sem, eu lobortis dolor neque nec lectus. }}}
}}}

gives you:

* [[section1]]
**{{myclass{
Praesent posuere sodales tortor. Mauris ut erat non lacus semper porta. Mauris enim.
Phasellus tempor, metus ut dapibus lobortis, leo magna ornare metus, et pellentesque neque massa eget turpis.
Proin nec tellus. Donec aliquet.
Nullam sed leo bibendum justo rutrum rhoncus.}}}
* section2
**{{myclass{
Donec rhoncus sem eget urna.
Aenean tempor dolor vitae nisi.
Donec leo urna, placerat porttitor, auctor ut, volutpat a, purus,
Etiam eu sapien id nulla malesuada scelerisque.
Maecenas rhoncus, nibh ut aliquam consequat, mi odio luctus sem, eu lobortis dolor neque nec lectus. }}}
* section3
**{{myclass{
Donec rhoncus sem eget urna.
Aenean tempor dolor vitae nisi.
Donec leo urna, placerat porttitor, auctor ut, volutpat a, purus,
Etiam eu sapien id nulla malesuada scelerisque.
Maecenas rhoncus, nibh ut aliquam consequat, mi odio luctus sem, eu lobortis dolor neque nec lectus. }}}
<<accordion>>
[["Performance Tips"|Tips for speeding up performance on large TiddlyWikis]] and [[Customize your TW experience|For advanced users: Customize your TW experience]], both from [[TW for the Rest of Us|http://giffmex.org/twfortherestofus.html]]

External resources:
*[[Plugin Development|http://tiddlywiki.org/wiki/Plugin_Development]]
*[[Bookmarklets|http://lewcid.org/tiddlywiki-bookmarklets/]]
* [[TiddlyVault index of extensions from Giffmex.org|http://tiddlyvault.tiddlyspot.com/]]
AnonGreets

[[29 June 2008]]
Hi! You've found your way to my (very preliminary) ~ParDelib page.

I invite you to snoop the material I've listed in the left sidebar menu ...
... but perhaps you want to set up your own ccTiddlyWiki? (That's the software this site is running.)
If that's the case, then head on over to [[OsmoSoft's hosting site|http://wiki.osmosoft.com/alpha/]] ... fill your boots!

- -[[bentrem|http://twitter.com/bentrem]]


* Login
**{{myclass{
<<ccLogin>>
}}}
* Comment!
**{{myclass{
<<tiddler [[GFreeComment]]>>
}}}
<<accordion>>

PluginArchives

External:
*[[TWFaq|http://twfaq.tiddlyspot.com/]] and [[elaborate help|http://tiddlyspot.com/twhelp/]] at [[TiddlySpot.com|http://tiddlyspot.com/]]
*[[CheatSheet (PDF)|http://nothickmanuals.info/lib/exe/fetch.php/cheatsheets:tiddlywiki_cheatsheet.pdf]]
*[[Daniel Baird's UserGuide|http://danielbaird.com/tiddlywikiguides/userguide-sample.html#TiddlyWiki User's Guide]]
*[[TW Resources on TiddlyWiki.org's Wiki|http://www.tiddlywiki.org/wiki/TiddlyWiki_Resources]]
*[[Jim Barr's fully enhanced TW|http://tiddlywikitips.com/]]
*[[TW for the Rest of Us|http://giffmex.org/twfortherestofus.html]]

From [[JeremyRuston's "Getting Started" at TiddlyWiki.com|http://www.tiddlywiki.com/#GettingStarted]]:
----
There is an extensive [[Community]] [[documentation wiki|http://www.tiddlywiki.org/]], including an invaluable [[FAQ|http://www.tiddlywiki.org/wiki/TiddlyWiki_FAQ]]. Other useful guides include:
* Jeremy Wagstaff's [[The Power of Tiddly|http://www.loosewireblog.com/2007/11/the-power-of-ti.html]]
* Dave Gifford's [[TiddlyWiki for the Rest of Us|http://www.giffmex.org/twfortherestofus.html]] and his [[slideshow introduction|http://www.giffmex.org/blog/?p=23]]
* Morris Gray's [[TW Help - TiddlyWiki help file for beginners|http://tiddlyspot.com/twhelp/]]
* Dmitri Popov's [[TiddlyWiki quick reference card|http://nothickmanuals.info/doku.php/cheatsheets]]
* Screencasts from [[JimVentola|http://faculty.massasoit.mass.edu/jventola/videocasts/tidhelp2/tidhelp2.html]] and [[LeonKilat|http://max.limpag.com/2006/09/07/using-a-tiddlywiki-a-video-guide/]].

----

<<tag resources>>
Having updated upload config in Bidix, have I trashed upload here?
- CordonBlue
- [[w/Chris Brogan|ChrisBrogan1]]
- [[OS & Community|OpenSourceCommunity]]
- MoralProvocation

<<tag menus>>
A reply I just crafted while chatting with [[Chris Brogan|http://twitter.com/chrisbrogan]] on ~FaceBook:

""We're tying threads together."
Indeed, indeed!

Have you come across "autopoesis"?
Fractals and such ... self-organizing systems ...

So long as a critical number of individuals are striving towards ?what? however they conceive of "the good", things will work themselves out. Kinda like how in conflict situations (Gaza, Iraq, Sudan) all that's required for evil to triumph is that people of good-will do nothing.

Michael Mandelbaum was on Charlie Rose last night ... produced a nice trope: "the irresistable force of democracy and free markets meeting the immovable object that is China's Communist Party" ... it's like that ... tectonic.

My worry: that "fun" increase dissipation catastrophically. (~MySpace comes to mind.)
My project: to create an online system that empowers real discourse. (For my money, conventional forums / wiki / blogs don't cut the mustard.)
From [[ChrisDent/experimental/TiddlyWeb/COOKBOOK|http://trac.tiddlywiki.org/browser/Trunk/contributors/ChrisDent/experimental/TiddlyWeb/COOKBOOK]]
(Thanks to [[Jeremy Ruston for his reply to my "CordonBlue" suggestion in google group|http://groups.google.com/group/TiddlyWikiDev/browse_thread/thread/6562d68583b31eb7]].)


----
>Document a COOKBOOK for getting starting with TiddlyWeb. A fairly long and involved tutorial to cover the basics of making things go.
>This was just rolled out, and is not my area of expertise so I would very much welcome tweaks from others.
----
See also ChrisCookbook

Ripped off from [[Chris' TechnicalOverview|http://peermore.com:8080/recipes/AutoTiddlyWeb/tiddlers.wiki#TiddlyWebTechnicalOverview]]
----

TiddlyWeb is written using version 2.5 of [[Python]].

Its basic architecture is strongly based on [[Joe Gregorio]]'s [[Robaccia]] toy framework, meaning: TiddlyWeb is a [[WSGI]] application that uses [[Selector]] to dispatch a small number of URLs to simple functions in simple modules that satisfy the request.

The TiddlyWeb UrlMap maps URLs to code.

There are three primary entities operating in the TiddlyWeb system:

* [[Recipe]]s
* [[Bag]]s
* [[Tiddler]]s

These are represented in code by very simple classes. Recipe, Bag and Tiddler objects have no methods, only attributes. Other modules use the objects in concert with other modules to perform required actions. These other modules can be divided into sets:

* WebHandlers
* [[Store]]s
* [[Serializer]]s
* [[Control]]
* [[Filter]]s
* [[WSGI Middleware]]

The UrlMap dispatches requests to WebHandlers. The WebHandlers instantiate Recipe, Bag and Tiddler objects and then get them from or put them to [[Store]]s. When the request requires some form of output, a [[Serializer]] is used to transform the object to the required form. A bastardized form of [Content Negotiation] is done to select which Serializer to use.

There are some notes on [[AUTH]] and [[REVISIONS]].

More to come.
----

And //that//, as they say, //is ''that''!//

<<tag history>>
Posted to [[the TW Dev google group|http://groups.google.com/group/TiddlyWikiDev]] ... I had in mind such as [[The "TiddlyVault" index of extensions|http://tiddlyvault.tiddlyspot.com/"]] and [[TiddlyWiki in Action|http://giffmex.tiddlyspot.com/]]
----

As you can see by http://wiki.osmosoft.com/alpha/pardelib#Resources and my Journals there I've been spidering quite a bit.
When I come across something like the editor function in http://www.giffmex.org/webviewtwexample.html the fact that Import is of limited scope really hammers me in the head.

So thinking, I pondered how we might "sync" plugins / templates etc.
Of course ginsu / cook / recipes came to mind.

Anecdotally, ExtJS allows the download of a customized build.
With that in mind an RFE came to mind.

A repository where ~TWs could be built from scratch using the groups aggregated resources. (Have any of you come across "Puppet"? "Make, on steroids" is how one wag described it.)

For e.g. I uploade the empty.html's that I've collected.
Those go into a directory and get ginsu'd.
A menu is generated.
I select from that collection and the chimera is produced, for me to download.
Heck, I can imagine an Import that would allow me to drag in Tiddlers from whatever ~TWs I've loaded!

Apologies if this is madly impractical.

cheers
[[--bentrem|http://twitter.com/bentrem/]]
----

<<tag blurt>>
[[Blurts]] | [[Journals]] | MainMenu | 

DefaultTiddlers | AnonDefaultTiddlers | SiteTitle & SiteSubtitle | 

*PageTemplate -- Contains the overall structure of the page, including the gradient macro for the masthead.
*EditTemplate -- Contains the structure and order of the tiddler editor screen
*ViewTemplate -- Contains the structure and order of the tiddler view screen
*ToolbarCommands | SideBarTabs
*StyleSheetColors -- Contains the CSS for colors
*StyleSheetLayout -- Contains the CSS for layout
*StyleSheetPrint -- Contains the CSS used when printing from the TiddlyWiki

----

The following block was ripped off from [[the tiddlywiki homepage|http://tiddlywiki.com/]]
----
You can customise the appearance and behaviour of TiddlyWiki to almost any degree you want:
* Use the ColorPalette to change the basic colour scheme
* Create a CustomStyleSheet for finer grained control over the appearance
* Customise the PageTemplate, ViewTemplate or EditTemplate to change the composition of the page and the layout of individual tiddlers
* Use off-the-shelf themes from [[TiddlyThemes|http://tiddlythemes.com/]]
* Visit the [[Configuration]] summary to see all the special configuration tiddlers
* Install [[Plugins]] to extend the core functionality (find them at [[TiddlyVault|http://tiddlyvault.tiddlyspot.com/]] or you can try [[writing or adapting your own|http://gimcrackd.com/etc/src/codex/]])
* Use TiddlyBookmarklets for low level hacking of TiddlyWiki documents
There are also a bunch of TiddlyWikiTools that you can use to enhance TiddlyWiki.
----

<<slider chkSliderOptionsPanel Resources 'Resources ยป' 'A list of sites'>>

<<tag resources>>
[[29 June 2008]]
OpenSourceCommunity
MoralProvocation
''horizontal:''

* menu #1
** [[item #1-1]]
** [[item #1-2]]
** [[item #1-3]]
* menu #2
** [[item #2-1]]
** [[item #2-2]]
** [[menu #2-3]]
* menu #3
** [[item #2-1]]
** [[item #2-2]]
** [[menu #2-3]]
<<dropMenu>>

''vertical:''

* menu #1
** [[item #1-1]]
** [[item #1-2]]
** [[item #1-3]]
* menu #2
** [[item #2-1]]
** [[item #2-2]]
** [[menu #2-3]]
<<dropMenu vertical>>


/% %/
''horizontal:''
{{{
* menu #1
** [[item #1-1]]
** [[item #1-2]]
** [[item #1-3]]
* menu #2
** [[item #2-1]]
** [[item #2-2]]
** [[menu #2-3]]
* menu #3
** [[item #2-1]]
** [[item #2-2]]
** [[menu #2-3]]
<<dropMenu>>
}}}
* menu #1
** [[item #1-1]]
** [[item #1-2]]
** [[item #1-3]]
* menu #2
** [[item #2-1]]
** [[item #2-2]]
** [[menu #2-3]]
* menu #3
** [[item #2-1]]
** [[item #2-2]]
** [[menu #2-3]]
<<dropMenu>>

''vertical:''
{{{
* menu #1
** [[item #1-1]]
** [[item #1-2]]
** [[item #1-3]]
* menu #2
** [[item #2-1]]
** [[item #2-2]]
** [[menu #2-3]]
<<dropMenu vertical>>
}}}

* menu #1
** [[item #1-1]]
** [[item #1-2]]
** [[item #1-3]]
* menu #2
** [[item #2-1]]
** [[item #2-2]]
** [[menu #2-3]]
<<dropMenu vertical>>


/% %/
*[[Roadmap and known bugs at Hawksworx.com|http://www.hawksworx.com/playground/TeamTasks/roadmap.html]] last modified byPhilHawkswort on 10 March 2008
*[["Tiddler Parts" plugin|http://tiddlywiki.abego-software.de/#PartTiddlerPlugin]] by [[Udo Borkowski|http://www.abego-software.de/]] (see also [[list of his plugins|http://tiddlywiki.abego-software.de/#Plugins]])
*[[FND's DevPad|http://devpad.tiddlyspot.com/]]
*[[Saq's "Tiddly Learning" blog Lewcid.org|http://lewcid.org/]]
*[[Some useful reference stuff by Jules|http://knighjm.googlepages.com/knightnet-default-tw.html#Reference]] including lists of built-in macros, formatting rules and useful javascript methods for developers.
*[[Repository for BidiX's TiddlyWiki Extensions|http://tiddlywiki.bidix.info/]]
*[[Extension Repository|http://tw.lewcid.org/]] from [[LewCid.org|http://lewcid.org/]]
*[[TiddlyChatter|http://tiddlychatter.tiddlyspot.com/]] at http://tiddlyspot.com/
*[[presentation template|http://lewcid.googlepages.com/presentation_empty_full.html]] ([[see it in action|http://lewcid.googlepages.com/tots.html]])
*[[WebView|http://www.giffmex.org/webviewtwexample.html]] (gotta luv the editor functions here!).
{{invisibletable{
|width:25em;align:left;vertical-align:top;Okay, so you know how to use ~TiddlyWiki, but now you want more. You want to change the color or layout. You want to add features to it. As the subtitle says, this is an entry-level introduction, so I am not going to show you how to do every possible thing you can do with ~TiddlyWiki. I probably don't know half of what can be done. Advanced documentation such as that found at http://www.tiddlywiki.org/wiki and http://tiddlyspot.com/twhelp/ can hopefully expand your horizons. What I will tell you is that there is a LOT more you can do with ~TiddlyWiki if you are interested and determined enough.|Here are a few ideas to get you started.<br><br>[[Advanced ideas for tags]]<br><br>[[More information on tables]]<br><br>[[Colors, images, gradients, stylesheets and other visuals]]<br><br>[[Changing the page layout]]<br><br>[[More with macros]]<br><br>[[A plug for Plugins]]<br><br>[[TiddlyVault collection of plugins and macros|TiddlyVault: your source for macros, plugins and themes]]<br><br>[[How to create new tiddlers based on a template tiddler]]<br><br>[[Create forms with editable fields]]<br><br>[[Access files, folders, etc from within TiddlyWiki]]<br><br>[[TiddlySnip Firefox addon]]|
}}}

I want to thank all the fine people at the Google group for ~TiddlyWiki. If it weren't for them, I wouldn't ever have been able to do these things, let alone explain them to you. It's rare to find such a helpful group of people available every day with same day answers. They are another reason ~TiddlyWiki is so great.

If you've forgotten your username and / or password, please contact the administrator:

simon@osmosoft.com
!This is the formatting:

{{{|!Table header|!Column Two|}}}
{{{|>| colspan |}}}
{{{| rowspan |left aligned|}}}
{{{|~| right aligned|}}}
{{{|bgcolor(#DC1A1A):colored| centered |}}}
{{{||*lists<br>*within<br>*tables<br><br>and double-spaced too|}}}
{{{|caption|c}}}

!This is the result:

|!Table header|!Column Two|
|>| colspan |
| rowspan |left aligned|
|~| right aligned|
|bgcolor(#DC1A1A):colored| centered |
||*lists<br>*within<br>*tables<br><br>and double-spaced too|
|caption|c
Say hello; leave me a note!
<html><div align="center">
<iframe border="0" style="border:none;padding:0;margin:0;" width="380" height="400" src="http://gfreecomment.appspot.com/freecomment/541?url=' + location.href + '"></iframe></html>
<html><div align="center">
<iframe border="0" style="border:none;padding:0;margin:0;" width="210" height="400" src="http://gfreecomment.appspot.com/freecomment/541?url=' + location.href + '">iframe</iframe></html>

This worked after stripping down the original cope, converting it from a document.write script to a naked <iframe>:
> &lt;script type="text/javascript">
>document.write('<iframe border="0" style="border:none;padding:0;margin:0;" width="210" height="400" src="http://gfreecomment.appspot.com/freecomment/541?url=' + location.href + '">iframe</iframe>');
>&lt;/script>
<<slider chkSliderOptionsPanel BasicRes 'Basic ยป' 'A list of sites'>>

<<slider chkSliderOptionsPanel AdvancedRes 'Advanced ยป' 'A list of sites'>>

<<slider chkSliderOptionsPanel ExporeRes 'To Be Explored ยป' 'A list of sites'>>

<<tag resources>>
To include another tiddler's contents inside a tiddler, e.g. here's [[subtabB1]]:

<<tiddler "subtabB1">>

<<tag demo>>
/***
|Name|InlineJavascriptPlugin|
|Source|http://www.TiddlyTools.com/#InlineJavascriptPlugin|
|Version|1.6.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|Insert Javascript executable code directly into your tiddler content.|

''Call directly into TW core utility routines, define new functions, calculate values, add dynamically-generated TiddlyWiki-formatted output'' into tiddler content, or perform any other programmatic actions each time the tiddler is rendered.
!!!!!Usage
<<<
When installed, this plugin adds new wiki syntax for surrounding tiddler content with {{{<script>}}} and {{{</script>}}} markers, so that it can be treated as embedded javascript and executed each time the tiddler is rendered.

''Deferred execution from an 'onClick' link''
By including a {{{label="..."}}} parameter in the initial {{{<script>}}} marker, the plugin will create a link to an 'onclick' script that will only be executed when that specific link is clicked, rather than running the script each time the tiddler is rendered.  You may also include a {{{title="..."}}} parameter to specify the 'tooltip' text that will appear whenever the mouse is moved over the onClick link text

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

''Display script source in tiddler output''
By including the keyword parameter "show", in the initial {{{<script>}}} marker, the plugin will include the script source code in the output that it displays in the tiddler.

''Defining javascript functions and libraries:''
Although the external javascript file is loaded while the tiddler content is being rendered, any functions it defines will not be available for use until //after// the rendering has been completed.  Thus, you cannot load a library and //immediately// use it's functions within the same tiddler.  However, once that tiddler has been loaded, the library functions can be freely used in any tiddler (even the one in which it was initially loaded).

To ensure that your javascript functions are always available when needed, you should load the libraries from a tiddler that will be rendered as soon as your TiddlyWiki document is opened.  For example, you could put your {{{<script src="..."></script>}}} syntax into a tiddler called LoadScripts, and then add {{{<<tiddler LoadScripts>>}}} in your MainMenu tiddler.

Since the MainMenu is always rendered immediately upon opening your document, the library will always be loaded before any other tiddlers that rely upon the functions it defines.  Loading an external javascript library does not produce any direct output in the tiddler, so these definitions should have no impact on the appearance of your MainMenu.

''Creating dynamic tiddler content''
An important difference between this implementation of embedded scripting and conventional embedded javascript techniques for web pages is the method used to produce output that is dynamically inserted into the document:
* In a typical web document, you use the document.write() function to output text sequences (often containing HTML tags) that are then rendered when the entire document is first loaded into the browser window.
* However, in a ~TiddlyWiki document, tiddlers (and other DOM elements) are created, deleted, and rendered "on-the-fly", so writing directly to the global 'document' object does not produce the results you want (i.e., replacing the embedded script within the tiddler content), and completely replaces the entire ~TiddlyWiki document in your browser window.
* To allow these scripts to work unmodified, the plugin automatically converts all occurences of document.write() so that the output is inserted into the tiddler content instead of replacing the entire ~TiddlyWiki document.

If your script does not use document.write() to create dynamically embedded content within a tiddler, your javascript can, as an alternative, explicitly return a text value that the plugin can then pass through the wikify() rendering engine to insert into the tiddler display.  For example, using {{{return "thistext"}}} will produce the same output as {{{document.write("thistext")}}}.

//Note: your script code is automatically 'wrapped' inside a function, {{{_out()}}}, so that any return value you provide can be correctly handled by the plugin and inserted into the tiddler.  To avoid unpredictable results (and possibly fatal execution errors), this function should never be redefined or called from ''within'' your script code.//

''Accessing the ~TiddlyWiki DOM''
The plugin provides one pre-defined variable, 'place', that is passed in to your javascript code so that it can have direct access to the containing DOM element into which the tiddler output is currently being rendered.

Access to this DOM element allows you to create scripts that can:
* vary their actions based upon the specific location in which they are embedded
* access 'tiddler-relative' information (use findContainingTiddler(place))
* perform direct DOM manipulations (when returning wikified text is not enough)
<<<
!!!!!Examples
<<<
an "alert" message box:
><script show>
	alert('InlineJavascriptPlugin: this is a demonstration message');
</script>
dynamic output:
><script show>
	return (new Date()).toString();
</script>
wikified dynamic output:
><script show>
	return "link to current user: [["+config.options.txtUserName+"]]";
</script>
dynamic output using 'place' to get size information for current tiddler:
><script show>
   if (!window.story) window.story=window;
   var title=story.findContainingTiddler(place).id.substr(7);
   return title+" is using "+store.getTiddlerText(title).length+" bytes";
</script>
creating an 'onclick' button/link that runs a script:
><script label="click here" title="clicking this link will show an 'alert' box" show>
   if (!window.story) window.story=window;
   alert("Hello World!\nlinktext='"+place.firstChild.data+"'\ntiddler='"+story.findContainingTiddler(place).id.substr(7)+"'");
</script>
loading a script from a source url:
>http://www.TiddlyTools.com/demo.js contains:
>>{{{function demo() { alert('this output is from demo(), defined in demo.js') } }}}
>>{{{alert('InlineJavascriptPlugin: demo.js has been loaded'); }}}
><script src="demo.js" show>
	return "loading demo.js..."
</script>
><script label="click to execute demo() function" show>
	demo()
</script>
<<<
!!!!!Installation
<<<
import (or copy/paste) the following tiddlers into your document:
''InlineJavascriptPlugin'' (tagged with <<tag systemConfig>>)
<<<
!!!!!Revision History
<<<
''2007.02.19 [1.6.0]'' added support for title="..." to specify mouseover tooltip when using an onclick (label="...") script
''2006.10.16 [1.5.2]'' add newline before closing '}' in 'function out_' wrapper.  Fixes error caused when last line of script is a comment.
''2006.06.01 [1.5.1]'' when calling wikify() on script return value, pass hightlightRegExp and tiddler params so macros that rely on these values can render properly
''2006.04.19 [1.5.0]'' added 'show' parameter to force display of javascript source code in tiddler output
''2006.01.05 [1.4.0]'' added support 'onclick' scripts.  When label="..." param is present, a button/link is created using the indicated label text, and the script is only executed when the button/link is clicked.  'place' value is set to match the clicked button/link element.
''2005.12.13 [1.3.1]'' when catching eval error in IE, e.description contains the error text, instead of e.toString().  Fixed error reporting so IE shows the correct response text.  Based on a suggestion by UdoBorkowski
''2005.11.09 [1.3.0]'' for 'inline' scripts (i.e., not scripts loaded with src="..."), automatically replace calls to 'document.write()' with 'place.innerHTML+=' so script output is directed into tiddler content.  Based on a suggestion by BradleyMeck
''2005.11.08 [1.2.0]'' handle loading of javascript from an external URL via src="..." syntax
''2005.11.08 [1.1.0]'' pass 'place' param into scripts to provide direct DOM access 
''2005.11.08 [1.0.0]'' initial release
<<<
!!!!!Credits
<<<
This feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]]
<<<
!!!!!Code
***/
//{{{
version.extensions.inlineJavascript= {major: 1, minor: 6, revision: 0, date: new Date(2007,2,19)};

config.formatters.push( {
	name: "inlineJavascript",
	match: "\\<script",
	lookahead: "\\<script(?: src=\\\"((?:.|\\n)*?)\\\")?(?: label=\\\"((?:.|\\n)*?)\\\")?(?: title=\\\"((?:.|\\n)*?)\\\")?( show)?\\>((?:.|\\n)*?)\\</script\\>",

	handler: function(w) {
		var lookaheadRegExp = new RegExp(this.lookahead,"mg");
		lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = lookaheadRegExp.exec(w.source)
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
			if (lookaheadMatch[1]) { // load a script library
				// make script tag, set src, add to body to execute, then remove for cleanup
				var script = document.createElement("script"); script.src = lookaheadMatch[1];
				document.body.appendChild(script); document.body.removeChild(script);
			}
			if (lookaheadMatch[5]) { // there is script code
				if (lookaheadMatch[4]) // show inline script code in tiddler output
					wikify("{{{\n"+lookaheadMatch[0]+"\n}}}\n",w.output);
				if (lookaheadMatch[2]) { // create a link to an 'onclick' script
					// add a link, define click handler, save code in link (pass 'place'), set link attributes
					var link=createTiddlyElement(w.output,"a",null,"tiddlyLinkExisting",lookaheadMatch[2]);
					link.onclick=function(){try{return(eval(this.code))}catch(e){alert(e.description?e.description:e.toString())}}
					link.code="function _out(place){"+lookaheadMatch[5]+"\n};_out(this);"
					link.setAttribute("title",lookaheadMatch[3]?lookaheadMatch[3]:"");
					link.setAttribute("href","javascript:;");
					link.style.cursor="pointer";
				}
				else { // run inline script code
					var code="function _out(place){"+lookaheadMatch[5]+"\n};_out(w.output);"
					code=code.replace(/document.write\(/gi,'place.innerHTML+=(');
					try { var out = eval(code); } catch(e) { out = e.description?e.description:e.toString(); }
					if (out && out.length) wikify(out,w.output,w.highlightRegExp,w.tiddler);
				}
			}
			w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
		}
	}
} )
//}}}
!!!Getting an account on Lycos (tripod)
#Go to http://www.tripod.lycos.co.uk/
#Signup for an account
#Wait for your account verification email and verify your account
#When your account is verified, login to your account
#Go to ''My account'', below ''Take a tour'' on your left
#Go to bottom of the page and locate five icons (green and black)
#click on ''PHP4U''
#Click on ''Active PHP4U now''
#On this page, record down your database info. I use my test site as an example
{{{
Name: cctiddly_uk_db
Username: cctiddly
Password: no password needed
Host: localhost
}}}

!!!Config and upload your ccTiddly
*open your ''default.php'' under your ''config'' directory with your favorite editor
*Change the following variables to the values required (change
{{{
$tiddlyCfg['db']['host'] = "localhost";		//sql host
$tiddlyCfg['db']['login'] = "cctiddly";		//login name
$tiddlyCfg['db']['pass'] = "";		//login password
$tiddlyCfg['db']['name'] = "cctiddly_uk_db";		//db name
}}}
*because the MySQL on Lycos do not support ''set names'', disable utf-8 in your config file (set it to 0, available in v1.0 final)
{{{
$tiddlyCfg['pref']['utf8'] = 0;
}}}

<<tag requirements>>
[[all of the Internal Macro Tiddlers at TiddlyWikiTips.com|http://TiddlyWikiTips.com/index.html#[[Tip #12: TiddlyWiki Internal Macros]] TipAllTags TipCloseAll TipNewJournal TipNewTiddler TipPermaView TipSaveChanges TipSearch TipSlider TipTabbedContent TipTagPopUp TipTiddlerContents TipTimeline TipToday TipTWVersion]]
----

In addition to the excellent Plugins found here and throughout the TiddlyWiki world, TiddlyWiki contains some internal Macros that, for the most part, remain undocumented. They can offer lots of interesting possibilities when customizing your TiddlyWiki. The Macro list below was compiled from TiddlyWiki version 1.2.31. Click on a macro's description below to view more detail about each Macro including syntax, description, and examples!

|!Macro|!Description|!Syntax|
|allTags|[[List all Tags in a Tiddler|TipAllTags]]|{{{<}}}{{{<allTags>>}}}|
|closeAll|[[Close all displayed Tiddlers|TipCloseAll]]|{{{<}}}{{{<closeAll>>}}}|
|list all|[[List all Tiddlers in a Tiddler|TipListAll]]|{{{<}}}{{{<list all>>}}}|
|list missing|[[List all Missing Tiddlers in a Tiddler|TipListMissing]]|{{{<}}}{{{<list missing>>}}}|
|list orphans|[[List all orphaned Tiddlers in a Tiddler|TipListOrphans]]|{{{<}}}{{{<list orphans>>}}}|
|newJournal|[[Create new date & Time stamped Tiddler|TipNewJournal]]|{{{<}}}{{{<newJournal>>}}}|
|newTiddler|[[Create new Tiddler|TipNewTiddler]]|{{{<}}}{{{<newTiddler>>}}}|
|permaview|[[URL link for all open Tiddlers|TipPermaView]]|{{{<}}}{{{<permaview>>}}}|
|saveChanges |[[Save all TiddlyWiki changes|TipSaveChanges]]|{{{<}}}{{{<saveChanges>>}}}|
|search|[[Display a Search box|TipSearch]]|{{{<}}}{{{<search>>}}}|
|slider|[[Display a Slider|TipSlider]]|{{{<}}}{{{<slider sliderID sliderTiddler sliderLabel>>}}}|
|tabs|[[Display Tabbed content|TipTabbedContent]]|{{{<}}}{{{<tabs indentifier tabLabel tabName Tiddler>>}}}|
|tag|[[Display a Tag PopUp|TipTagPopUp]]|{{{<}}}{{{<tag tagName>>}}}|
|tiddler|[[Display inline contents of a Tiddler|TipTiddlerContents]]|{{{<}}}{{{<tiddler Tiddler>>}}}|
|timeline|[[Display Timeline in a Tiddler|TipTimeline]]|{{{<}}}{{{<timeline>>}}}|
|today|[[Dusplay Today's Date|TipToday]]|{{{<}}}{{{<today>>}}}|
|version|[[Display TiddlyWiki's version|TipTWVersion]]|{{{<}}}{{{<version>>}}}|
- [[Blank1]]
- [[Blank2]]
(//recent first//)
-[[29June08|29 June 2008]]
-[[28June08|28 June 2008]]
-[[27June08|27 June 2008]]
-[[26June08-2|26 June 2008-2]]
-[[26June08|26 June 2008]]
-[[25June08|25 June 2008]]
- [[23June08-2]]
- [[23June08]]
<<slider chkSliderOptionsPanel Items 'Items ยป' 'A second list of journals'>>

<<tag menus>>
* ChrisDentSez
<<dropMenu vertical>>
----
* Blurts
** CordonBlue
** [[w/Chris Brogan|ChrisBrogan1]]
** [[OS & Community|OpenSourceCommunity]]
** MoralProvocation
* Journals
** [[29June08|29 June 2008]]
** [[28June08|28 June 2008]]
** [[27June08|27 June 2008]]
** [[26June08-2|26 June 2008-2]]
** [[26June08|26 June 2008]]
** [[25June08|25 June 2008]]
** [[23June08-2]]
** [[23June08]]
<<dropMenu vertical>>
----
* [[Customization]] 
* GettingStarted 
* [[Resources|Resources]]
<<dropMenu vertical>>
----
----
*AboutMe
*[[Comment!|GFreeComment]]
<<dropMenu vertical>>

[[Canonical|http://wiki.osmosoft.com/alpha/pardelib]]
[[SaveA)s pardelibTW.html|http://wiki.osmosoft.com/alpha/pardelib]]

<!--{{{-->
<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml'/>
<!--}}}-->

<style type="text/css">#contentWrapper {display:none;}</style><div id="SplashScreen" style="border: 3px solid #ccc; display: block; text-align: center; width: 320px; margin: 100px auto; padding: 50px; color:#000; font-size: 28px; font-family:Tahoma; background-color:#eee;"><b>ParDelib</b> is getting its ducks in a row<blink> ...</blink><br><span style="font-size: 14px; color:red;"><i>Javascript <b>Required</b></i> .</span></div>
ChrisDentSez
----
<<slider chkSliderOptionsPanel Blurts 'Blurts ยป' 'A list of blurts'>>
<<slider chkSliderOptionsPanel Journals 'Journals ยป' 'A list of journals'>>
----
*[[Customization]] 
*GettingStarted 
goto [[Resources|Resources]]
----
*AboutMe
[[Comment!|GFreeComment]]
[[SaveA)s pardelibTW.html|http://wiki.osmosoft.com/alpha/pardelib]]

<<tag bak>>
"''Even if you don't care, it still matters!''"

If there's something you don't care about, that "something" may still matter, it may be quite important. 

If there's something that's important that you don't care about, the fact that you don't care about it may be important! You not caring may matter a lot.

Living as though we're contented cows is no way to live ... we're human beings, we're sentient. When we don't respond to moral provocation it's exactly as though we'd been lobotomized.

for more see http://groundplane.wordpress.com/gp-101/
Translators and commentators sometimes make it sound as if Machiavelli were talking about something altogether different than the tradition, as if this were just an instance in which one word was being used for entirely different ideas.  But then Machiavelli's philosophical point would be lost.  Machiavelli is taking the traditional concept of virtue as natural human excellence, with all its teleological baggage, and giving it a partially new content.  Excellence for a ruler is not the same thing as excellence for a citizen, and excellence for a ruler involves a willingness to engage in what would otherwise be immoral, unjust conduct, and which still may tarnish the ruler's immortal soul, even if it is necessary in the situation for the safety / glory of the patria.  It is not the case that all virtues (= excellences) go together and imply one another, as Socrates optimistically believed.  New conception of an old concept, not just homonyms.
<<notes>>

<<tag demo>>
This allows notes!
/***
''NestedSlidersPlugin for TiddlyWiki version 1.2.x and 2.0''
^^author: Eric Shulman
source: http://www.TiddlyTools.com/#NestedSlidersPlugin
license: [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]^^

Quickly make any tiddler content into an expandable 'slider' panel, without needing to create a separate tiddler to contain the slider content.  Optional syntax allows ''default to open'', ''custom button label/tooltip'' and ''automatic blockquote formatting.''

You can also 'nest' these sliders as deep as you like (see complex nesting example below), so that expandable 'tree-like' hierarchical displays can be created.  This is most useful when converting existing in-line text content to create in-line annotations, footnotes, context-sensitive help, or other subordinate information displays.

For more details, please click on a section headline below:
++++!!!!![Configuration]>
Debugging messages for 'lazy sliders' deferred rendering:
<<option chkDebugLazySliderDefer>> show debugging alert when deferring slider rendering
<<option chkDebugLazySliderRender>> show debugging alert when deferred slider is actually rendered
===
++++!!!!![Usage]>
When installed, this plugin adds new wiki syntax for embedding 'slider' panels directly into tiddler content.  Use {{{+++}}} and {{{===}}} to delimit the slider content.  Additional optional syntax elements let you specify
*default to open
*cookiename
*heading level
*floater (with optional CSS width value)
*mouse auto rollover
*custom class/label/tooltip/accesskey
*automatic blockquote
*deferred rendering
The complete syntax, using all options, is:
//{{{
++++(cookiename)!!!!!^width^*{{class{[label=key|tooltip]}}}>...
content goes here
===
//}}}
where:
* {{{+++}}} (or {{{++++}}}) and {{{===}}}^^
marks the start and end of the slider definition, respectively.  When the extra {{{+}}} is used, the slider will be open when initially displayed.^^
* {{{(cookiename)}}}^^
saves the slider opened/closed state, and restores this state whenever the slider is re-rendered.^^
* {{{!}}} through {{{!!!!!}}}^^
displays the slider label using a formatted headline (Hn) style instead of a button/link style^^
* {{{^width^}}} (or just {{{^}}})^^
makes the slider 'float' on top of other content rather than shifting that content downward.  'width' must be a valid CSS value (e.g., "30em", "180px", "50%", etc.).  If omitted, the default width is "auto" (i.e., fit to content)^^
* {{{*}}}^^
automatically opens/closes slider on "rollover" as well as when clicked^^
* {{{{{class{[label=key|tooltip]}}}}}}^^
uses custom label/tooltip/accesskey.  {{{{{class{...}}}}}}, {{{=key}}} and {{{|tooltip}}} are optional.  'class' is any valid CSS class name, used to style the slider label text.  'key' must be a ''single letter only''.  Default labels/tootips are: ">" (more) and "<" (less), with no default access key assignment.^^
* {{{">"}}} //(without the quotes)//^^
automatically adds blockquote formatting to slider content^^
* {{{"..."}}} //(without the quotes)//^^
defers rendering of closed sliders until the first time they are opened.  //Note: deferred rendering may produce unexpected results in some cases.  Use with care.//^^

//Note: to make slider definitions easier to read and recognize when editing a tiddler, newlines immediately following the {{{+++}}} 'start slider' or preceding the {{{===}}} 'end slider' sequence are automatically supressed so that excess whitespace is eliminated from the output.//
===
++++!!!!![Examples]>
simple in-line slider:
{{{
+++
   content
===
}}}
+++
   content
===
----
use a custom label and tooltip:
{{{
+++[label|tooltip]
   content
===
}}}
+++[label|tooltip]
   content
===
----
content automatically blockquoted:
{{{
+++>
   content
===
}}}
+++>
   content
===
----
all options combined //(default open, cookie, heading, sized floater, rollover, class, label/tooltip/key, blockquoted, deferred)//
{{{
++++(testcookie)!!!^30em^*{{big{[label=Z|click or press Alt-Z to open]}}}>...
   content
===
}}}
++++(testcookie)!!!^30em^*{{big{[label=Z|click or press Alt-Z to open]}}}>...
   content
===
----
complex nesting example:
{{{
+++^[get info...=I|click for information or press Alt-I]
   put some general information here, plus a floating slider with more specific info:
   +++^10em^[view details...|click for details]
      put some detail here, which could include a rollover with a +++^25em^*[glossary definition]explaining technical terms===
   ===
===
}}}
+++^[get info...=I|click for information or press Alt-I]
   put some general information here, plus a floating slider with more specific info:
   +++^10em^[view details...|click for details]
      put some detail here, which could include a rollover with a +++^25em^*[glossary definition]explaining technical terms===
   ===
===
===
!!!!!Installation
<<<
import (or copy/paste) the following tiddlers into your document:
''NestedSlidersPlugin'' (tagged with <<tag systemConfig>>)
<<<
!!!!!Revision History
<<<
''2006.07.28 - 2.0.0'' added custom class syntax around label/tip/key syntax: {{{{{classname{[label=key|tip]}}}}}}
''2006.07.25 - 1.9.3'' when parsing slider, save default open/closed state in button element, then in onClickNestedSlider(), if slider state matches saved default, instead of saving cookie, delete it.  Significantly reduces the 'cookie overhead' when default slider states are used.
''2006.06.29 - 1.9.2'' in onClickNestedSlider(), when setting focus to first control, skip over type="hidden"
''2006.06.22 - 1.9.1'' added panel.defaultPanelWidth to save requested panel width, even after resizing has changed the style value
''2006.05.11 - 1.9.0'' added optional '^width^' syntax for floating sliders and '=key' syntax for setting an access key on a slider label
''2006.05.09 - 1.8.0'' in onClickNestedSlider(), when showing panel, set focus to first child input/textarea/select element
''2006.04.24 - 1.7.8'' in adjustSliderPos(), if floating panel is contained inside another floating panel, subtract offset of containing panel to find correct position
''2006.02.16 - 1.7.7'' corrected deferred rendering to account for use-case where show/hide state is tracked in a cookie
''2006.02.15 - 1.7.6'' in adjustSliderPos(), ensure that floating panel is positioned completely within the browser window (i.e., does not go beyond the right edge of the browser window)
''2006.02.04 - 1.7.5'' add 'var' to unintended global variable declarations to avoid FireFox 1.5.0.1 crash bug when assigning to globals
''2006.01.18 - 1.7.4'' only define adjustSliderPos() function if it has not already been provided by another plugin.  This lets other plugins 'hijack' the function even when they are loaded first.
''2006.01.16 - 1.7.3'' added adjustSliderPos(place,btn,panel,panelClass) function to permit specialized logic for placement of floating panels.  While it provides improved placement for many uses of floating panels, it exhibits a relative offset positioning error when used within *nested* floating panels.  Short-term workaround is to only adjust the position for 'top-level' floaters.
''2006.01.16 - 1.7.2'' added button property to slider panel elements so that slider panel can tell which button it belongs to.  Also, re-activated and corrected animation handling so that nested sliders aren't clipped by hijacking Slider.prototype.stop so that "overflow:hidden" can be reset to "overflow:visible" after animation ends
''2006.01.14 - 1.7.1'' added optional "^" syntax for floating panels.  Defines new CSS class, ".floatingPanel", as an alternative for standard in-line ".sliderPanel" styles.
''2006.01.14 - 1.7.0'' added optional "*" syntax for rollover handling to show/hide slider without requiring a click (Based on a suggestion by tw4efl)
''2006.01.03 - 1.6.2'' When using optional "!" heading style, instead of creating a clickable "Hn" element, create an "A" element inside the "Hn" element.  (allows click-through in SlideShowPlugin, which captures nearly all click events, except for hyperlinks)
''2005.12.15 - 1.6.1'' added optional "..." syntax to invoke deferred ('lazy') rendering for initially hidden sliders
removed checkbox option for 'global' application of lazy sliders
''2005.11.25 - 1.6.0'' added optional handling for 'lazy sliders' (deferred rendering for initially hidden sliders)
''2005.11.21 - 1.5.1'' revised regular expressions: if present, a single newline //preceding// and/or //following// a slider definition will be suppressed so start/end syntax can be place on separate lines in the tiddler 'source' for improved readability.  Similarly, any whitespace (newlines, tabs, spaces, etc.) trailing the 'start slider' syntax or preceding the 'end slider' syntax is also suppressed.
''2005.11.20 - 1.5.0'' added (cookiename) syntax for optional tracking and restoring of slider open/close state
''2005.11.11 - 1.4.0'' added !!!!! syntax to render slider label as a header (Hn) style instead of a button/link style
''2005.11.07 - 1.3.0'' removed alternative syntax {{{(((}}} and {{{)))}}} (so they can be used by other
formatting extensions) and simplified/improved regular expressions to trim multiple excess newlines
''2005.11.05 - 1.2.1'' changed name to NestedSlidersPlugin
more documentation
''2005.11.04 - 1.2.0'' added alternative character-mode syntax {{{(((}}} and {{{)))}}}
tweaked "eat newlines" logic for line-mode {{{+++}}} and {{{===}}} syntax
''2005.11.03 - 1.1.1'' fixed toggling of default tooltips ("more..." and "less...") when a non-default button label is used
code cleanup, added documentation
''2005.11.03 - 1.1.0'' changed delimiter syntax from {{{(((}}} and {{{)))}}} to {{{+++}}} and {{{===}}}
changed name to EasySlidersPlugin
''2005.11.03 - 1.0.0'' initial public release
<<<
!!!!!Credits
<<<
This feature was implemented by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]] with initial research and suggestions from RodneyGomes, GeoffSlocock, and PaulPetterson.
<<<
!!!!!Code
***/
//{{{
version.extensions.nestedSliders = {major: 2, minor: 0, revision: 0, date: new Date(2006,7,28)};
//}}}

//{{{
// options for deferred rendering of sliders that are not initially displayed
if (config.options.chkDebugLazySliderDefer==undefined) config.options.chkDebugLazySliderDefer=false;
if (config.options.chkDebugLazySliderRender==undefined) config.options.chkDebugLazySliderRender=false;

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

//{{{
config.formatters.push( {
	name: "nestedSliders",
	match: "\\n?\\+{3}",
	terminator: "\\s*\\={3}\\n?",
	lookahead: "\\n?\\+{3}(\\+)?(\\([^\\)]*\\))?(\\!*)?(\\^(?:[^\\^\\*\\[\\>]*\\^)?)?(\\*)?(?:\\{\\{([\\w]+[\\s\\w]*)\\{)?(\\[[^\\]]*\\])?(?:\\}{3})?(\\>)?(\\.\\.\\.)?\\s*",
	handler: function(w)
		{
			// defopen=lookaheadMatch[1]
			// cookiename=lookaheadMatch[2]
			// header=lookaheadMatch[3]
			// panelwidth=lookaheadMatch[4]
			// rollover=lookaheadMatch[5]
			// class=lookaheadMatch[6]
			// label=lookaheadMatch[7]
			// blockquote=lookaheadMatch[8]
			// deferred=lookaheadMatch[9]

			 lookaheadRegExp = new RegExp(this.lookahead,"mg");
			lookaheadRegExp.lastIndex = w.matchStart;
			var lookaheadMatch = lookaheadRegExp.exec(w.source)
			if(lookaheadMatch && lookaheadMatch.index == w.matchStart)
			{
				// location for rendering button and panel
				var place=w.output;

				// default to closed, no cookie, no accesskey
				var show="none"; var title=">"; var tooltip="show"; var cookie=""; var key="";

				// extra "+", default to open
				if (lookaheadMatch[1])
					{ show="block"; title="<"; tooltip="hide"; }

				// cookie, use saved open/closed state
				if (lookaheadMatch[2]) {
					cookie=lookaheadMatch[2].trim().slice(1,-1);
					cookie="chkSlider"+cookie;
					if (config.options[cookie]==undefined)
						{ config.options[cookie] = (show=="block") }
					if (config.options[cookie])
						{ show="block"; title="<"; tooltip="hide"; }
					else
						{ show="none"; title=">"; tooltip="show"; }
				}

				// parse custom label/tooltip/accesskey: [label=X|tooltip]
				if (lookaheadMatch[7]) {
					title = lookaheadMatch[7].trim().slice(1,-1);
					var pos=title.indexOf("|");
					if (pos!=-1) { tooltip = title.substr(pos+1,title.length); title=title.substr(0,pos); }
					if (title.substr(title.length-2,1)=="=") { key=title.substr(title.length-1,1); title=title.slice(0,-2); }
					if (pos==-1) tooltip += " "+title; // default tooltip: "show/hide <title>"
				}

				// create the button
				if (lookaheadMatch[3]) { // use "Hn" header format instead of button/link
					var lvl=(lookaheadMatch[3].length>6)?6:lookaheadMatch[3].length;
					var btn = createTiddlyElement(createTiddlyElement(place,"h"+lvl,null,null,null),"a",null,lookaheadMatch[6],title);
					btn.onclick=onClickNestedSlider;
					btn.setAttribute("href","javascript:;");
					btn.setAttribute("title",tooltip);
				}
				else
					var btn = createTiddlyButton(place,title,tooltip,onClickNestedSlider,lookaheadMatch[6]);

				// set extra button attributes
				btn.sliderCookie = cookie; // save the cookiename (if any) in the button object
				btn.defOpen=lookaheadMatch[1]!=null; // save default open/closed state (boolean)
				btn.keyparam=key; // save the access key letter ("" if none)
				if (key.length) {
					btn.setAttribute("accessKey",key); // init access key
					btn.onfocus=function(){this.setAttribute("accessKey",this.keyparam);}; // **reclaim** access key on focus
				}

				// "non-click" MouseOver open/close slider
				if (lookaheadMatch[5]) btn.onmouseover=onClickNestedSlider;

				// create slider panel
				var panelClass=lookaheadMatch[4]?"floatingPanel":"sliderPanel";
				var panel=createTiddlyElement(place,"div",null,panelClass,null);
				panel.button = btn; // so the slider panel know which button it belongs to
				panel.defaultPanelWidth=(lookaheadMatch[4] && lookaheadMatch[4].length>2)?lookaheadMatch[4].slice(1,-1):""; // save requested panel size
				btn.sliderPanel=panel;
				panel.style.display = show;
				panel.style.width=panel.defaultPanelWidth;

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

// TBD: ignore 'quoted' delimiters (e.g., "{{{+++foo===}}}" isn't really a slider)
function findMatchingDelimiter(src,starttext,endtext) {
	var startpos = 0;
	var endpos = src.indexOf(endtext);
	// check for nested delimiters
	while (src.substring(startpos,endpos-1).indexOf(starttext)!=-1) {
		// count number of nested 'starts'
		var startcount=0;
		var temp = src.substring(startpos,endpos-1);
		var pos=temp.indexOf(starttext);
		while (pos!=-1)  { startcount++; pos=temp.indexOf(starttext,pos+starttext.length); }
		// set up to check for additional 'starts' after adjusting endpos
		startpos=endpos+endtext.length;
		// find endpos for corresponding number of matching 'ends'
		while (startcount && endpos!=-1) {
			endpos = src.indexOf(endtext,endpos+endtext.length);
			startcount--;
		}
	}
	return (endpos==-1)?src.length:endpos;
}
//}}}

//{{{
window.onClickNestedSlider=function(e)
{
	if (!e) var e = window.event;
	var theTarget = resolveTarget(e);
	var theLabel = theTarget.firstChild.data;
	var theSlider = theTarget.sliderPanel
	var isOpen = theSlider.style.display!="none";
	// if using default button labels, toggle labels
	if (theLabel==">") theTarget.firstChild.data = "<";
	else if (theLabel=="<") theTarget.firstChild.data = ">";
	// if using default tooltips, toggle tooltips
	if (theTarget.getAttribute("title")=="show")
		theTarget.setAttribute("title","hide");
	else if (theTarget.getAttribute("title")=="hide")
		theTarget.setAttribute("title","show");
	if (theTarget.getAttribute("title")=="show "+theLabel)
		theTarget.setAttribute("title","hide "+theLabel);
	else if (theTarget.getAttribute("title")=="hide "+theLabel)
		theTarget.setAttribute("title","show "+theLabel);
	// deferred rendering (if needed)
	if (theSlider.getAttribute("rendered")=="false") {
		if (config.options.chkDebugLazySliderRender)
			alert("rendering '"+theLabel+"':\n\n"+theSlider.getAttribute("raw"));
		var place=theSlider;
		if (theSlider.getAttribute("blockquote")=="true")
			place=createTiddlyElement(place,"blockquote");
		wikify(theSlider.getAttribute("raw"),place);
		theSlider.setAttribute("rendered","true");
	}
	// show/hide the slider
	if(config.options.chkAnimate)
		anim.startAnimating(new Slider(theSlider,!isOpen,e.shiftKey || e.altKey,"none"));
	else
		theSlider.style.display = isOpen ? "none" : "block";
	// reset to default width (might have been changed via plugin code)
	theSlider.style.width=theSlider.defaultPanelWidth;
	// align slider/floater position with target button
	if (!isOpen) adjustSliderPos(theSlider.parentNode,theTarget,theSlider,theSlider.className);
	// if showing panel, set focus to first 'focus-able' element in panel
	if (theSlider.style.display!="none") {
		var ctrls=theSlider.getElementsByTagName("*");
		for (var c=0; c<ctrls.length; c++) {
			var t=ctrls[c].tagName.toLowerCase();
			if ((t=="input" && ctrls[c].type!="hidden") || t=="textarea" || t=="select")
				{ ctrls[c].focus(); break; }
		}
	}
	if (this.sliderCookie && this.sliderCookie.length) {
		config.options[this.sliderCookie]=!isOpen;
		if (config.options[this.sliderCookie]!=this.defOpen)
			saveOptionCookie(this.sliderCookie);
		else { // remove cookie if slider is in default display state
			var ex=new Date(); ex.setTime(ex.getTime()-1000);
			document.cookie = this.sliderCookie+"=novalue; path=/; expires="+ex.toGMTString();
		}
	}
	return false;
}

// hijack animation handler 'stop' handler so overflow is visible after animation has completed
Slider.prototype.coreStop = Slider.prototype.stop;
Slider.prototype.stop = function() { this.coreStop(); this.element.style.overflow = "visible"; }

// adjust panel position based on button position
if (window.adjustSliderPos==undefined) window.adjustSliderPos=function(place,btn,panel,panelClass) {
	if (panelClass=="floatingPanel") {
		var left=0;
		var top=btn.offsetHeight;
		if (place.style.position!="relative") {
			var left=findPosX(btn);
			var top=findPosY(btn)+btn.offsetHeight;
			var p=place; while (p && p.className!='floatingPanel') p=p.parentNode;
			if (p) { left-=findPosX(p); top-=findPosY(p); }
		}
		if (left+panel.offsetWidth > getWindowWidth()) left=getWindowWidth()-panel.offsetWidth-10;
		panel.style.left=left+"px"; panel.style.top=top+"px";
	}
}

function getWindowWidth() {
	if(document.width!=undefined)
		return document.width; // moz (FF)
	if(document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) )
		return document.documentElement.clientWidth; // IE6
	if(document.body && ( document.body.clientWidth || document.body.clientHeight ) )
		return document.body.clientWidth; // IE4
	if(window.innerWidth!=undefined)
		return window.innerWidth; // IE - general
	return 0; // unknown
}
//}}}
<<notes>>
Originally posted as [[a comment to Nick Webb's "Tiddlypreneurship at Osmosoft"|http://www.erraticmusings.com/?p=16]]:

As for โ€œwhether or not open source software is solely the domain of developersโ€ Iโ€™d agree with you on โ€œshouldnโ€™t beโ€, but would quite confidantly say โ€œIs, most of the time, very definitely.โ€

Take ccTW for example. I got [[mine up and running at osmosoft|http://wiki.osmosoft.com/alpha/pardelib]] pretty quickly after having come across [[Confabbโ€™s โ€œNote Saver"|http://blog.confabb.com/?p=106]]. Fast start followed by grinding frustration โ€ฆ for example markup copied from another TW not working on my install; not the sort of snafu you want to encounter on your first day.

Addressing documentation (my trade) itโ€™s only natural that developers leave just enough cookie crumbs for others like them to find their work โ€ฆ which isnโ€™t at all the same as enabling a naive participant.

Case in point: configuration of a server side install. Iโ€™ve found a lot of Tiddlers that nominally address that, but none of them have actual config data and instructions.
Oh-wooops, one of them does โ€ฆ incidentally โ€ฆ the one that describes installing at Lycos. Go figure!

Itโ€™s a cultural thing. Developers leave gaping voids where they (quite correctly) presume other developers to be up to speed. In my estimation encountering 2 or 3 of those voids would be enough to deter a naive participant โ€ฆ and nobody would ever know.

Itโ€™s a cultural thing.
Ben Tremblay at June 24th, 2008 around 6:10 pm

----
''Update //14:35MDT 30JUNE08//''
From my experience with ~OpenSource settings (most recently [[TiddlyIRC|irc://irc.freenode.net/tiddlywiki]]) these are (in contradistinction to the paradigmatic hippie-bus setting, or the best of garage startups), somewhat like NGOs and not.for.profit situations (which are gardens of personality games and opportunistic nastiness), these situations are hallmarked by individuals who score points by the quality of their passive aggression and its attendant plausible deniability i.e. diss and ignore are the most used tools.
----
More info on the company (~OsmoSoftians!!) and its products can be found one the [[osmosoft.com homepage|http://osmosoft.com/]]

If you don't already have an account here please [[register|Register]] for one.  (Note that user registration is a new feature and still requires some work.)

If you have any problems with this deployment please contact simon@osmosoft.com.
Feedback is welcomed!
/***
|''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"
	});
*/
//}}}
/***
''Import Tiddlers Plugin for TiddlyWiki version 1.2.x and 2.0''
^^author: Eric Shulman - ELS Design Studios
source: http://www.TiddlyTools.com/#ImportTiddlersPlugin
license: [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]^^

When many people share and edit copies of the same TiddlyWiki document, the ability to quickly collect all these changes back into a single, updated document that can then be redistributed to the entire group is very important.  This plugin lets you selectively combine tiddlers from any two TiddlyWiki documents.  It can also be 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.)

!!!!!Inline interface (live)
<<<
<<importTiddlers inline>>
<<<
!!!!!Macro Syntax
<<<
{{{<<importTiddlers>>}}}
creates "import tiddlers" link.  click to show/hide import control panel

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

{{{<<importTiddlers filter source quiet ask>>}}}
non-interactive 'automatic' import.
''filter'' determines which tiddlers will be automatically selected for importing.  Use one of the following keywords:
>''"new"'' retrieves only tiddlers that are found in the import source document, but do not yet exist in the destination document
>''"changes"'' retrieves only tiddlers that exist in both documents for which the import source tiddler is newer than the existing tiddler
>''"updates"'' retrieves both ''new'' and ''changed'' tiddlers (this is the default action when none is specified)
>''"all"'' retrieves ALL tiddlers from the import source document, even if they have not been changed.
''source'' is the location of the imported document.  It can be either a local document or an URL:
>filename is any local path/file, in whatever format your system requires
>URL is any remote web location that starts with "http://" or "https://"
''"quiet"'' (optional)
>supresses all status message during the import processing (e.g., "opening local file...", "found NN tiddlers..." etc).  Note that if ANY tiddlers are actualy imported, a final information message will still be displayed (along with the ImportedTiddlers report), even when 'quiet' is specified.  This ensures that changes to your document cannot occur without any visible indication at all.
''"ask"'' (optional)
>adds interactive confirmation.  A browser message box (OK/Cancel) is displayed for each tiddler that will be imported, so that you can manually bypass any tiddlers that you do not want to import.

''Special tag values: importReplace and importPublic''

By adding these special tags to an existing tiddler, you can precisely control whether or not to allow updates to that tiddler as well as decide which tiddlers in your document can be automatically imported by others.
*''For maximum safety, the default action is to prevent existing tiddlers from being unintentionally overwritten by incoming tiddlers.'' To allow an existing tiddler to be overwritten by an imported tiddler, you must tag the existing tiddler with ''<<tag importReplace>>''
*''For maximum privacy, the default action for //outgoing// tiddlers is to NOT automatically share your tiddlers with others.''  To allow a tiddler in your document to be shared via auto-import actions by others, you must tag it with ''<<tag importPublic>>''
//Note: these tags are only applied when using the auto-import processing.  When using the interactive control panel, all tiddlers in the imported document are available in the listbox, regardless of their tag values.//
<<<
!!!!!Interactive Usage
<<<
When used interactively, a control panel is displayed consisting of an "import source document" filename input (text field plus a ''[Browse...]'' button), a listbox of available tiddlers, a "differences only" checkbox, an "add tags" input field and four push buttons: ''[open]'', ''[select all]'', ''[import]'' and ''[close]''.

Press ''[browse]'' to select a TiddlyWiki document file to import.  You can also type in the path/filename or a remote document URL (starting with http://)and press ''[open]''.  //Note: There may be some delay to permit the browser time to access and load the document before updating the listbox with the titles of all tiddlers that are available to be imported.//

Select one or more titles from the listbox (hold CTRL or SHIFT while clicking to add/remove the highlight from individual list items).  You can press ''[select all]'' to quickly highlight all tiddler titles in the list.  Use the ''[-]'', ''[+]'', or ''[=]'' links to adjust the listbox size so you can view more (or less) tiddler titles at one time.  When you have chosen the tiddlers you want to import and entered any extra tags, press ''[import]'' to begin copying them to the current TiddlyWiki document.

''select: all, new, changes, or differences''

You can click on ''all'', ''new'', ''changes'', or ''differences'' to automatically select a subset of tiddlers from the list. This makes it very quick and easy to find and import just the updated tiddlers you are interested in:
>''"all"'' selects ALL tiddlers from the import source document, even if they have not been changed.
>''"new"'' selects only tiddlers that are found in the import source document, but do not yet exist in the destination document
>''"changes"'' selects only tiddlers that exist in both documents but that are newer in the source document
>''"differences"'' selects all new and existing tiddlers that are different from the destination document (even if destination tiddler is newer)

''Import Tagging:''

Tiddlers that have been imported can be automatically tagged, so they will be easier to find later on, after they have been added to your document.  New tags are entered into the "add tags" input field, and then //added// to the existing tags for each tiddler as it is imported.

''Skip, Rename, Merge, or Replace:''

When importing a tiddler whose title is identical to one that already exists, the import process pauses and the tiddler title is displayed in an input field, along with four push buttons: ''[skip]'', ''[rename]'', ''[merge]'' and ''[replace]''.

To bypass importing this tiddler, press ''[skip]''.  To import the tiddler with a different name (so that both the tiddlers will exist when the import is done), enter a new title in the input field and then press ''[rename]''.   Press ''[merge]'' to combine the content from both tiddlers into a single tiddler.  Press ''[replace]'' to overwrite the existing tiddler with the imported one, discarding the previous tiddler content.

//Note: if both the title ''and'' modification date/////time match, the imported tiddler is assumed to be identical to the existing one, and will be automatically skipped (i.e., not imported) without asking.//

''Import Report History''

When tiddlers are imported, a report is generated into ImportedTiddlers, indicating when the latest import was performed, the number of tiddlers successfully imported, from what location, and by whom. It also includes a list with the title, date and author of each tiddler that was imported.

When the import process is completed, the ImportedTiddlers report is automatically displayed for your review.  If more tiddlers are subsequently imported, a new report is //added// to ImportedTiddlers, above the previous report (i.e., at the top of the tiddler), so that a reverse-chronological history of imports is maintained.

If a cumulative record is not desired, the ImportedTiddlers report may be deleted at any time. A new ImportedTiddlers report will be created the next time tiddlers are imported.

Note: You can prevent the ImportedTiddlers report from being generated for any given import activity by clearing the "create a report" checkbox before beginning the import processing.

<<<
!!!!!Installation
<<<
copy/paste the following tiddlers into your document:
''ImportTiddlersPlugin'' (tagged with <<tag systemConfig>>)

create/edit ''SideBarOptions'': (sidebar menu items)
^^Add "< < ImportTiddlers > >" macro^^

''Quick Installation Tip #1:''
If you are using an unmodified version of TiddlyWiki (core release version <<version>>), you can get a new, empty TiddlyWiki with the Import Tiddlers plugin pre-installed (''[[download from here|TW+ImportExport.html]]''), and then simply import all your content from your old document into this new, empty document.
<<<
!!!!!Revision History
<<<
''2006.02.17 [2.6.0]''
Removed "differences only" listbox display mode, replaced with selection filter 'presets': all/new/changes/differences.  Also fixed initialization handling for "add new tags" so that checkbox state is correctly tracked when panel is first displayed.
''2006.02.16 [2.5.4]''
added checkbox options to control "import remote tags" and "keep existing tags" behavior, in addition to existing "add new tags" functionality.
''2006.02.14 [2.5.3]''
FF1501 corrected unintended global 't' (loop index) in importReport() and autoImportTiddlers()
''2006.02.10 [2.5.2]''
corrected unintended global variable in importReport().
''2006.02.05 [2.5.1]''
moved globals from window.* to config.macros.importTiddlers.* to avoid FireFox 1.5.0.1 crash bug when referencing globals
''2006.01.18 [2.5.0]''
added checkbox for "create a report".  Default is to create/update the ImportedTiddlers report.  Clear the checkbox to skip this step.
''2006.01.15 [2.4.1]''
added "importPublic" tag and inverted default so that auto sharing is NOT done unless tagged with importPublic
''2006.01.15 [2.4.0]''
Added support for tagging individual tiddlers with importSkip, importReplace, and/or importPrivate to control which tiddlers can be overwritten or shared with others when using auto-import macro syntax.  Defaults are to SKIP overwriting existing tiddlers with imported tiddlers, and ALLOW your tiddlers to be auto-imported by others.
''2006.01.15 [2.3.2]''
Added "ask" parameter to confirm each tiddler before importing (for use with auto-importing)
''2006.01.15 [2.3.1]''
Strip TW core scripts from import source content and load just the storeArea into the hidden IFRAME.  Makes loading more efficient by reducing the document size and by preventing the import document from executing its TW initialization (including plugins).  Seems to resolve the "Found 0 tiddlers" problem.  Also, when importing local documents, use convertUTF8ToUnicode() to convert the file contents so support international characters sets.
''2006.01.12 [2.3.0]''
Reorganized code to use callback function for loading import files to support event-driven I/O via an ASYNCHRONOUS XMLHttpRequest.  Let's processing continue while waiting for remote hosts to respond to URL requests.  Added non-interactive 'batch' macro mode, using parameters to specify which tiddlers to import, and from what document source.  Improved error messages and diagnostics, plus an optional 'quiet' switch for batch mode to eliminate //most// feedback.
''2006.01.11 [2.2.0]''
Added "[by tags]" to list of tiddlers, based on code submitted by BradleyMeck
''2006.01.09 [2.1.1]''
When a URL is typed in, and then the "open" button is pressed, it generates both an onChange event for the file input and a click event for open button.  This results in multiple XMLHttpRequest()'s which seem to jam things up quite a bit.  I removed the onChange handling for file input field.  To open a file (local or URL), you must now explicitly press the "open" button in the control panel.
''2006.01.08 [2.1.0]''
IMPORT FROM ANYWHERE!!! re-write getImportedTiddlers() logic to either read a local file (using local I/O), OR... read a remote file, using a combination of XML and an iframe to permit cross-domain reading of DOM elements.  Adapted from example code and techniques courtesy of Jonny LeRoy.
''2006.01.06 [2.0.2]''
When refreshing list contents, fixed check for tiddlerExists() when "show differences only" is selected, so that imported tiddlers that don't exist in the current file will be recognized as differences and included in the list.
''2006.01.04 [2.0.1]''
When "show differences only" is NOT checked, import all tiddlers that have been selected even when they have a matching title and date.
''2005.12.27 [2.0.0]''
Update for TW2.0
Defer initial panel creation and only register a notification function when panel first is created
''2005.12.22 [1.3.1]''
tweak formatting in importReport() and add 'discard report' link to output
''2005.12.03 [1.3.0]''
Dynamically create/remove importPanel as needed to ensure only one instance of interface elements exists, even if there are multiple instances of macro embedding.  Also, dynamically create/recreate importFrame each time an external TW document is loaded for importation (reduces DOM overhead and ensures a 'fresh' frame for each document)
''2005.11.29 [1.2.1]''
fixed formatting of 'detail info' in importReport()
''2005.11.11 [1.2.0]''
added 'inline' param to embed controls in a tiddler
''2005.11.09 [1.1.0]''
only load HTML and CSS the first time the macro handler is called.  Allows for redundant placement of the macro without creating multiple instances of controls with the same ID's.
''2005.10.25 [1.0.5]''
fixed typo in importReport() that prevented reports from being generated
''2005.10.09 [1.0.4]''
combined documentation with plugin code instead of using separate tiddlers
''2005.08.05 [1.0.3]''
moved CSS and HTML definitions into plugin code instead of using separate tiddlers
''2005.07.27 [1.0.2]''
core update 1.2.29: custom overlayStyleSheet() replaced with new core setStylesheet()
''2005.07.23 [1.0.1]''
added parameter checks and corrected addNotification() usage
''2005.07.20 [1.0.0]''
Initial Release
<<<
!!!!!Credits
<<<
This feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]]
<<<
!!!!!Code
***/

// // Version
//{{{
version.extensions.importTiddlers = {major: 2, minor: 6, revision: 0, date: new Date(2006,2,17)};
//}}}

// // 1.2.x compatibility
//{{{
if (!window.story) window.story=window;
if (!store.getTiddler) store.getTiddler=function(title){return store.tiddlers[title]}
if (!store.addTiddler) store.addTiddler=function(tiddler){store.tiddlers[tiddler.title]=tiddler}
if (!store.deleteTiddler) store.deleteTiddler=function(title){delete store.tiddlers[title]}
//}}}

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

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


// // ''MACRO DEFINITION''

//{{{
config.macros.importTiddlers = { };
config.macros.importTiddlers = {
	label: "import tiddlers",
	prompt: "Copy tiddlers from another document",
	countMsg: "%0 tiddlers selected for import",
	src: "",		// path/filename or URL of document to import
	inbound: null,		// hash-indexed array of tiddlers from other document
	newTags: "",		// text of tags added to imported tiddlers
	addTags: true,		// add new tags to imported tiddlers
	listsize: 8,		// # of lines to show in imported tiddler list
	importTags: true,	// include tags from remote source document when importing a tiddler
	keepTags: true,		// retain existing tags when replacing a tiddler
	index: 0,		// current processing index in import list
	sort: ""		// sort order for imported tiddler listbox
};

config.macros.importTiddlers.handler = function(place,macroName,params) {
	// LINK WITH FLOATING PANEL
	if (!params[0]) {
		createTiddlyButton(place,this.label,this.prompt,onClickImportMenu);
		return;
	}
	// INLINE TIDDLER CONTENT
	if (params[0]=="inline") {
		createImportPanel(place);
		document.getElementById("importPanel").style.position="static";
		document.getElementById("importPanel").style.display="block";
		return;
	}
	// NON-INTERACTIVE BATCH MODE
	switch (params[0]) {
		case 'all':
		case 'new':
		case 'changes':
		case 'updates':
			var filter=params.shift();
			break;
		default:
			var filter="updates";
			break;
	}
	if (!params[0]||!params[0].length) return; // filename is required
	config.macros.importTiddlers.src=params.shift();
	var quiet=(params[0]=="quiet"); if (quiet) params.shift();
	var ask=(params[0]=="ask"); if (ask) params.shift();
	config.macros.importTiddlers.inbound=null;	// clear the imported tiddler buffer
	// load storeArea from a hidden IFRAME, then apply import rules and add/replace tiddlers
	loadImportFile(config.macros.importTiddlers.src,filter,quiet,ask,autoImportTiddlers);
}
//}}}

// // ''READ TIDDLERS FROM ANOTHER DOCUMENT''

//{{{
function loadImportFile(src,filter,quiet,ask,callback) {
	if (!quiet) clearMessage();
	// LOCAL FILE
	if ((src.substr(0,7)!="http://")&&(src.substr(0,8)!="https://")) {
		if (!quiet) displayMessage("Opening local document: "+ src);
		var txt=loadFile(src);
		if(!txt) { if (!quiet) displayMessage("Could not open local document: "+src); }
		else {
			var s="<html><body>"+txt.substr(txt.indexOf('<div id="storeArea">'));
			if (!quiet) displayMessage(txt.length+" bytes in document.  ("+s.length+" bytes used for tiddler storage)");
			config.macros.importTiddlers.inbound = readImportedTiddlers(convertUTF8ToUnicode(s));
			var count=config.macros.importTiddlers.inbound?config.macros.importTiddlers.inbound.length:0;
			if (!quiet) displayMessage("Found "+count+" tiddlers in "+src);
			if (callback) callback(src,filter,quiet,ask);
		}
		return;
	}
	// REMOTE FILE
	var x; // XML object
	try {x = new XMLHttpRequest()}
	catch(e) {
		try {x = new ActiveXObject("Msxml2.XMLHTTP")}
		catch (e) {
			try {x = new ActiveXObject("Microsoft.XMLHTTP")}
			catch (e) { return }
		}
	}
	x.onreadystatechange = function() {
		if (x.readyState == 4) {
			if (x.status == 200) {
				var sa="<html><body>"+x.responseText.substr(x.responseText.indexOf('<div id="storeArea">'));
				if (!quiet) displayMessage(x.responseText.length+" bytes in document.  ("+sa.length+" bytes used for tiddler storage)");
				config.macros.importTiddlers.inbound = readImportedTiddlers(sa);
				var count=config.macros.importTiddlers.inbound?config.macros.importTiddlers.inbound.length:0;
				if (!quiet) displayMessage("Found "+count+" tiddlers in "+src);
				if (callback) callback(src,filter,quiet,ask);
			}
			else
				if (!quiet) displayMessage("Could not open remote document:"+ src+" (error="+x.status+")");
		}
	}
	if (document.location.protocol=="file:") { // UniversalBrowserRead only works from a local file context
		try {netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserRead')}
		catch (e) { if (!quiet) displayMessage(e.description?e.description:e.toString()); }
	}
	if (!quiet) displayMessage("Opening remote document: "+ src);
	try {
		var url=src+(src.indexOf('?')<0?'?':'&')+'nocache='+Math.random();
		x.open("GET",url,true);
		x.overrideMimeType('text/html');
		x.send(null);
	}
	catch (e) {
		if (!quiet) {
			displayMessage("Could not open remote document: "+src);
			displayMessage(e.description?e.description:e.toString());
		}
	}
}

function readImportedTiddlers(txt)
{
	var importedTiddlers = [];
	// create frame
	var f=document.getElementById("importFrame");
	if (f) document.body.removeChild(f);
	f=document.createElement("iframe");
	f.id="importFrame";
	f.style.width="0px"; f.style.height="0px"; f.style.border="0px";
	document.body.appendChild(f);
	// get document
	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
	// load source into document
	d.open(); d.writeln(txt); d.close();
	// read tiddler DIVs from storeArea DOM element
	var importStore = [];
	var importStoreArea = d.getElementById("storeArea");
	if (!importStoreArea || !(importStore=importStoreArea.childNodes) || (importStore.length==0)) { return null; }
	importStoreArea.normalize();
	for(var t = 0; t < importStore.length; t++) {
		var e = importStore[t];
		var title = null;
		if(e.getAttribute)
			title = e.getAttribute("tiddler");
		if(!title && e.id && (e.id.substr(0,5) == "store"))
			title = e.id.substr(5);
		if(title && title != "") {
			var theImported = new Tiddler();
			theImported.loadFromDiv(e,title);
			importedTiddlers.push(theImported);
		}
	}
	return importedTiddlers;
}
//}}}

// // ''NON-INTERACTIVE IMPORT''

// // import all/new/changed tiddlers into store, replacing or adding tiddlers as needed
//{{{
function autoImportTiddlers(src,filter,quiet,ask)
{
	var count=0;
	if (config.macros.importTiddlers.inbound) for (var t=0;t<config.macros.importTiddlers.inbound.length;t++) {
		var theImported = config.macros.importTiddlers.inbound[t];
		var theExisting = store.getTiddler(theImported.title);

		// only import tiddlers if tagged with "importPublic"
		if (theImported.tags && theImported.tags.find("importPublic")==null)
			{ config.macros.importTiddlers.inbound[t].status=""; continue; } // status=="" means don't show in report

		// never import the "ImportedTiddlers" history from the other document...
		if (theImported.title=='ImportedTiddlers')
			{ config.macros.importTiddlers.inbound[t].status=""; continue; } // status=="" means don't show in report

		// check existing tiddler for importReplace, or systemConfig tags
		config.macros.importTiddlers.inbound[t].status="added"; // default - add any tiddlers not filtered out
		if (store.tiddlerExists(theImported.title)) {
			config.macros.importTiddlers.inbound[t].status="replaced";
			if (!theExisting.tags||(theExisting.tags.find("importReplace")==null))
				{ config.macros.importTiddlers.inbound[t].status="not imported - tiddler already exists (use importReplace to allow changes)"; continue; }
			if ((theExisting.tags.find("systemConfig")!=null)||(theImported.tags.find("systemConfig")!=null))
				config.macros.importTiddlers.inbound[t].status+=" - WARNING: an active systemConfig plugin has been added or updated";
		}

		// apply the all/new/changes/updates filter
		if (filter!="all") {
			if ((filter=="new") && store.tiddlerExists(theImported.title))
				{ config.macros.importTiddlers.inbound[t].status="not imported - tiddler already exists"; continue; }
			if ((filter=="changes") && !store.tiddlerExists(theImported.title))
				{ config.macros.importTiddlers.inbound[t].status="not imported - new tiddler"; continue; }
			if (store.tiddlerExists(theImported.title) && ((theExisting.modified.getTime()-theImported.modified.getTime())>=0))
				{ config.macros.importTiddlers.inbound[t].status="not imported - tiddler is unchanged"; continue; }
		}

		// get confirmation if required
		if (ask && !confirm("Import "+(theExisting?"updated":"new")+" tiddler '"+theImported.title+"'\nfrom "+src))
			{ config.macros.importTiddlers.inbound[t].status="skipped - cancelled by user"; continue; }

		// DO THE IMPORT!!
		store.addTiddler(theImported); count++;
	}
	importReport(quiet);  // generate a report (as needed) and display it if not 'quiet'
	if (count) store.setDirty(true);
	// always show final message when tiddlers were actually imported
	if (!quiet||count) displayMessage("Imported "+count+" tiddler"+(count!=1?"s":"")+" from "+src);
}
//}}}

// // ''REPORT GENERATOR''

//{{{
function importReport(quiet)
{
	if (!config.macros.importTiddlers.inbound) return;
	// DEBUG alert('importReport: start');

	// if import was not completed, the Ask panel will still be open... close it now.
	var askpanel=document.getElementById('importAskPanel'); if (askpanel) askpanel.style.display='none';
	// get the alphasorted list of tiddlers
	var tiddlers = config.macros.importTiddlers.inbound;
	tiddlers.sort(function (a,b) {if(a['title'] == b['title']) return(0); else return (a['title'] < b['title']) ? -1 : +1; });
	// gather the statistics
	var count=tiddlers.length;
	var added=0; var replaced=0; var renamed=0; var skipped=0; var merged=0;
	for (var t=0; t<count; t++)
		if (tiddlers[t].status)
			{
			if (tiddlers[t].status=='added')			added++;
			if (tiddlers[t].status.substr(0,7)=='skipped')	skipped++;
			if (tiddlers[t].status.substr(0,6)=='rename')	renamed++;
			if (tiddlers[t].status.substr(0,7)=='replace')	replaced++;
			if (tiddlers[t].status.substr(0,6)=='merged')	merged++;
			}
	var omitted=count-(added+replaced+renamed+skipped+merged);
	// DEBUG alert('stats done: '+count+' total, '+added+' added, '+skipped+' skipped, '+renamed+' renamed, '+replaced+' replaced, '+merged+' merged');
	// skip the report if nothing was imported
	if (added+replaced+renamed+merged==0) return;
	// skip the report if not desired by user
	if (!config.options.chkImportReport) {
		// reset status flags
		for (var t=0; t<count; t++) config.macros.importTiddlers.inbound[t].status="";
		// refresh display since tiddlers have been imported
		store.notifyAll();
		// quick message area summary report
		var msg=(added+replaced+renamed+merged)+' of '+count+' tiddler'+((count!=1)?'s':"");
		msg+=' imported from '+config.macros.importTiddlers.src.replace(/\\/g,'/')
		displayMessage(msg);
		return;
	}
	// create the report tiddler (if not already present)
	var tiddler = store.getTiddler('ImportedTiddlers');
	if (!tiddler)	// create new report tiddler if it doesn't exist
		{
		tiddler = new Tiddler();
		tiddler.title = 'ImportedTiddlers';
		tiddler.text  = "";
		}
	// format the report header
	var now = new Date();
	var newText = "";
	newText += "On "+now.toLocaleString()+", "+config.options.txtUserName+" imported tiddlers from\n";
	newText += "[["+config.macros.importTiddlers.src+"|"+config.macros.importTiddlers.src+"]]:\n";
	newText += "<"+"<"+"<\n";
	newText += "Out of "+count+" tiddler"+((count!=1)?"s ":" ")+" in {{{"+config.macros.importTiddlers.src.replace(/\\/g,'/')+"}}}:\n";
	if (added+renamed>0)
		newText += (added+renamed)+" new tiddler"+(((added+renamed)!=1)?"s were":" was")+" added to your document.\n";
	if (merged>0)
		newText += merged+" tiddler"+((merged!=1)?"s were":" was")+" merged with "+((merged!=1)?"":"an ")+"existing tiddler"+((merged!=1)?"s":"")+".\n";
	if (replaced>0)
		newText += replaced+" existing tiddler"+((replaced!=1)?"s were":" was")+" replaced.\n";
	if (skipped>0)
		newText += skipped+" tiddler"+((skipped!=1)?"s were":" was")+" skipped after asking.\n";
	if (omitted>0)
		newText += omitted+" tiddler"+((omitted!=1)?"s":"")+((omitted!=1)?" were":" was")+" not imported.\n";
	if (config.macros.importTiddlers.addTags && config.macros.importTiddlers.newTags.trim().length)
		newText += "imported tiddlers were tagged with: \""+config.macros.importTiddlers.newTags+"\"\n";
	// output the tiddler detail and reset status flags
	for (var t=0; t<count; t++)
		if (tiddlers[t].status!="")
			{
			newText += "#["+"["+tiddlers[t].title+"]"+"]";
			newText += ((tiddlers[t].status!="added")?("^^\n"+tiddlers[t].status+"^^"):"")+"\n";
			config.macros.importTiddlers.inbound[t].status="";
			}
	newText += "<"+"<"+"<\n";
	// output 'discard report' link
	newText += "<html><input type=\"button\" href=\"javascript:;\" ";
	newText += "onclick=\"story.closeTiddler('"+tiddler.title+"'); store.deleteTiddler('"+tiddler.title+"');\" ";
	newText += "value=\"discard report\"></html>";
	// update the ImportedTiddlers content and show the tiddler
	tiddler.text	 = newText+((tiddler.text!="")?'\n----\n':"")+tiddler.text;
	tiddler.modifier = config.options.txtUserName;
	tiddler.modified = new Date();
	store.addTiddler(tiddler);
	if (!quiet) story.displayTiddler(null,"ImportedTiddlers",1,null,null,false);
	story.refreshTiddler("ImportedTiddlers",1,true);
	// refresh the display
	store.notifyAll();
}
//}}}

// // ''INTERFACE DEFINITION''

// // Handle link click to create/show/hide control panel
//{{{
function onClickImportMenu(e)
{
	if (!e) var e = window.event;
	var parent=resolveTarget(e).parentNode;
	var panel = document.getElementById("importPanel");
	if (panel==undefined || panel.parentNode!=parent)
		panel=createImportPanel(parent);
	var isOpen = panel.style.display=="block";
	if(config.options.chkAnimate)
		anim.startAnimating(new Slider(panel,!isOpen,e.shiftKey || e.altKey,"none"));
	else
		panel.style.display = isOpen ? "none" : "block" ;
	e.cancelBubble = true;
	if (e.stopPropagation) e.stopPropagation();
	return(false);
}
//}}}

// // Create control panel: HTML, CSS, register for notification
//{{{
function createImportPanel(place) {
	var panel=document.getElementById("importPanel");
	if (panel) { panel.parentNode.removeChild(panel); }
	setStylesheet(config.macros.importTiddlers.css,"importTiddlers");
	panel=createTiddlyElement(place,"span","importPanel",null,null)
	panel.innerHTML=config.macros.importTiddlers.html;
	store.addNotification(null,refreshImportList); // refresh listbox after every tiddler change
	refreshImportList();
	return panel;
}
//}}}

// // CSS
//{{{
config.macros.importTiddlers.css = '\
#importPanel {\
	display: none; position:absolute; z-index:11; width:35em; right:105%; top:3em;\
	padding: 0.5em; margin:0em; text-align:left; font-size: 8pt;\
	background-color: #eee; color:#000000; \
	border:1px solid black; border-bottom-width: 3px; border-right-width: 3px; -moz-border-radius:1em;\
}\
#importPanel a { color:#009; }\
#importPanel input  { width: 98%; margin: 1px; font-size:8pt; }\
#importPanel select { width: 98%; margin: 1px; font-size:8pt; }\
#importPanel .importButton { padding: 0em; margin: 0px; font-size:8pt; }\
#importPanel .importListButton { padding:0em 0.25em 0em 0.25em; color: #000000; display:inline }\
#importAskPanel { display:none; margin:0.5em 0em 0em 0em; }\
';
//}}}

// // HTML
//{{{
config.macros.importTiddlers.html = '\
<span style="float:left; padding:1px; white-space:nowrap">\
	import from source document\
</span>\
<span style="float:right; padding:1px; white-space:nowrap">\
	<input type=checkbox id="chkImportReport" checked style="height:1em; width:auto"\
		onClick="config.options[\'chkImportReport\']=this.checked;">create a report\
</span>\
<input type="file" id="fileImportSource" size=56\
	onKeyUp="config.macros.importTiddlers.src=this.value"\
	onChange="config.macros.importTiddlers.src=this.value;">\
<span style="float:left; padding:1px; white-space:nowrap">\
	select:\
	<a href="JavaScript:;" id="importSelectAll"\
		onclick="onClickImportButton(this)" title="select all tiddlers">\
		&nbsp;all&nbsp;</a>\
	<a href="JavaScript:;" id="importSelectNew"\
		onclick="onClickImportButton(this)" title="select tiddlers not already in destination document">\
		&nbsp;added&nbsp;</a> \
	<a href="JavaScript:;" id="importSelectChanges"\
		onclick="onClickImportButton(this)" title="select tiddlers that have been updated in source document">\
		&nbsp;changes&nbsp;</a> \
	<a href="JavaScript:;" id="importSelectDifferences"\
		onclick="onClickImportButton(this)" title="select tiddlers that have been added or are different from existing tiddlers">\
		&nbsp;differences&nbsp;</a> \
	<a href="JavaScript:;" id="importToggleFilter"\
		onclick="onClickImportButton(this)" title="show/hide selection filter">\
		&nbsp;filter&nbsp;</a> \
</span>\
<span style="float:right; padding:1px; white-space:nowrap">\
	<a href="JavaScript:;" id="importListSmaller"\
		onclick="onClickImportButton(this)" title="reduce list size">\
		&nbsp;&#150;&nbsp;</a>\
	<a href="JavaScript:;" id="importListLarger"\
		onclick="onClickImportButton(this)" title="increase list size">\
		&nbsp;+&nbsp;</a>\
	<a href="JavaScript:;" id="importListMaximize"\
		onclick="onClickImportButton(this)" title="maximize/restore list size">\
		&nbsp;=&nbsp;</a>\
</span>\
<select id="importList" size=8 multiple\
	onchange="setTimeout(\'refreshImportList(\'+this.selectedIndex+\')\',1)">\
	<!-- NOTE: delay refresh so list is updated AFTER onchange event is handled -->\
</select>\
<input type=checkbox id="chkAddTags" checked style="height:1em; width:auto"\
	onClick="config.macros.importTiddlers.addTags=this.checked;">add new tags &nbsp;\
<input type=checkbox id="chkImportTags" checked style="height:1em; width:auto"\
	onClick="config.macros.importTiddlers.importTags=this.checked;">import source tags &nbsp;\
<input type=checkbox id="chkKeepTags" checked style="height:1em; width:auto"\
	onClick="config.macros.importTiddlers.keepTags=this.checked;">keep existing tags\
<input type=text id="txtNewTags" size=15 onKeyUp="config.macros.importTiddlers.newTags=this.value" autocomplete=off>\
<div align=center>\
	<input type=button id="importOpen" class="importButton" style="width:32%" value="open"\
		onclick="onClickImportButton(this)">\
	<input type=button id="importStart"	 class="importButton" style="width:32%" value="import"\
		onclick="onClickImportButton(this)">\
	<input type=button id="importClose"	 class="importButton" style="width:32%" value="close"\
		onclick="onClickImportButton(this)">\
</div>\
<div id="importAskPanel">\
	tiddler already exists:\
	<input type=text id="importNewTitle" size=15 autocomplete=off">\
	<div align=center>\
	<input type=button id="importSkip"	class="importButton" style="width:23%" value="skip"\
		onclick="onClickImportButton(this)">\
	<input type=button id="importRename"  class="importButton" style="width:23%" value="rename"\
		onclick="onClickImportButton(this)">\
	<input type=button id="importMerge"   class="importButton" style="width:23%" value="merge"\
		onclick="onClickImportButton(this)">\
	<input type=button id="importReplace" class="importButton" style="width:23%" value="replace"\
		onclick="onClickImportButton(this)">\
	</div>\
</div>\
';
//}}}

// // refresh listbox
//{{{
function refreshImportList(selectedIndex)
{
	var theList  = document.getElementById("importList");
	if (!theList) return;
	// if nothing to show, reset list content and size
	if (!config.macros.importTiddlers.inbound)
	{
		while (theList.length > 0) { theList.options[0] = null; }
		theList.options[0]=new Option('please open a document...',"",false,false);
		theList.size=config.macros.importTiddlers.listsize;
		return;
	}
	// get the sort order
	if (!selectedIndex)   selectedIndex=0;
	if (selectedIndex==0) config.macros.importTiddlers.sort='title';		// heading
	if (selectedIndex==1) config.macros.importTiddlers.sort='title';
	if (selectedIndex==2) config.macros.importTiddlers.sort='modified';
	if (selectedIndex==3) config.macros.importTiddlers.sort='tags';
	if (selectedIndex>3) {
		// display selected tiddler count
		for (var t=0,count=0; t < theList.options.length; t++) count+=(theList.options[t].selected&&theList.options[t].value!="")?1:0;
		clearMessage(); displayMessage(config.macros.importTiddlers.countMsg.format([count]));
		return; // no refresh needed
	}

	// get the alphasorted list of tiddlers (optionally, filter out unchanged tiddlers)
	var tiddlers=config.macros.importTiddlers.inbound;
	tiddlers.sort(function (a,b) {if(a['title'] == b['title']) return(0); else return (a['title'] < b['title']) ? -1 : +1; });
	// clear current list contents
	while (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+' tiddler'+((tiddlers.length!=1)?'s are':' is')+' in the document',"",false,false);
	theList.options[i++]=new Option(((config.macros.importTiddlers.sort=="title"   )?">":indent)+' [by title]',"",false,false);
	theList.options[i++]=new Option(((config.macros.importTiddlers.sort=="modified")?">":indent)+' [by date]',"",false,false);
	theList.options[i++]=new Option(((config.macros.importTiddlers.sort=="tags")?">":indent)+' [by tags]',"",false,false);
	// output the tiddler list
	switch(config.macros.importTiddlers.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 "modified":
			// sort descending for newest date first
			tiddlers.sort(function (a,b) {if(a['modified'] == b['modified']) return(0); else return (a['modified'] > b['modified']) ? -1 : +1; });
			var lastSection = "";
			for(var t = 0; t < tiddlers.length; t++) {
				var tiddler = tiddlers[t];
				var theSection = tiddler.modified.toLocaleDateString();
				if (theSection != lastSection) {
					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;
				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
	if (theList.size<config.macros.importTiddlers.listsize) theList.size=config.macros.importTiddlers.listsize;
	if (theList.size>theList.options.length) theList.size=theList.options.length;
}
//}}}

// // Control interactions
//{{{
function onClickImportButton(which)
{
	// DEBUG alert(which.id);
	var theList		  = document.getElementById('importList');
	if (!theList) return;
	var thePanel	= document.getElementById('importPanel');
	var theAskPanel   = document.getElementById('importAskPanel');
	var theNewTitle   = document.getElementById('importNewTitle');
	var count=0;
	switch (which.id)
		{
		case 'fileImportSource':
		case 'importOpen':		// load import source into hidden frame
			importReport();		// if an import was in progress, generate a report
			config.macros.importTiddlers.inbound=null;	// clear the imported tiddler buffer
			refreshImportList();	// reset/resize the listbox
			if (config.macros.importTiddlers.src=="") break;
			// Load document into hidden iframe so we can read it's DOM and fill the list
			loadImportFile(config.macros.importTiddlers.src,"all",null,null,function(src,filter,quiet,ask){window.refreshImportList(0);});
			break;
		case 'importSelectAll':		// select all tiddler list items (i.e., not headings)
			importReport();		// if an import was in progress, generate a report
			for (var t=0,count=0; t < theList.options.length; t++) {
				if (theList.options[t].value=="") continue;
				theList.options[t].selected=true;
				count++;
			}
			clearMessage(); displayMessage(config.macros.importTiddlers.countMsg.format([count]));
			break;
		case 'importSelectNew':		// select tiddlers not in current document
			importReport();		// if an import was in progress, generate a report
			for (var t=0,count=0; t < theList.options.length; t++) {
				theList.options[t].selected=false;
				if (theList.options[t].value=="") continue;
				theList.options[t].selected=!store.tiddlerExists(theList.options[t].value);
				count+=theList.options[t].selected?1:0;
			}
			clearMessage(); displayMessage(config.macros.importTiddlers.countMsg.format([count]));
			break;
		case 'importSelectChanges':		// select tiddlers that are updated from existing tiddlers
			importReport();		// if an import was in progress, generate a report
			for (var t=0,count=0; t < theList.options.length; t++) {
				theList.options[t].selected=false;
				if (theList.options[t].value==""||!store.tiddlerExists(theList.options[t].value)) continue;
				for (var i=0; i<config.macros.importTiddlers.inbound.length; i++) // find matching inbound tiddler
					{ var inbound=config.macros.importTiddlers.inbound[i]; if (inbound.title==theList.options[t].value) break; }
				theList.options[t].selected=(inbound.modified-store.getTiddler(theList.options[t].value).modified>0); // updated tiddler
				count+=theList.options[t].selected?1:0;
			}
			clearMessage(); displayMessage(config.macros.importTiddlers.countMsg.format([count]));
			break;
		case 'importSelectDifferences':		// select tiddlers that are new or different from existing tiddlers
			importReport();		// if an import was in progress, generate a report
			for (var t=0,count=0; t < theList.options.length; t++) {
				theList.options[t].selected=false;
				if (theList.options[t].value=="") continue;
				if (!store.tiddlerExists(theList.options[t].value)) { theList.options[t].selected=true; count++; continue; }
				for (var i=0; i<config.macros.importTiddlers.inbound.length; i++) // find matching inbound tiddler
					{ var inbound=config.macros.importTiddlers.inbound[i]; if (inbound.title==theList.options[t].value) break; }
				theList.options[t].selected=(inbound.modified-store.getTiddler(theList.options[t].value).modified!=0); // changed tiddler
				count+=theList.options[t].selected?1:0;
			}
			clearMessage(); displayMessage(config.macros.importTiddlers.countMsg.format([count]));
			break;
		case 'importToggleFilter': // show/hide filter
		case 'importFilter': // apply filter
			alert("coming soon!");
			break;
		case 'importStart':		// initiate the import processing
			importReport();		// if an import was in progress, generate a report
			config.macros.importTiddlers.index=0;
			config.macros.importTiddlers.index=importTiddlers(0);
			importStopped();
			break;
		case 'importClose':		// unload imported tiddlers or hide the import control panel
			// if imported tiddlers not loaded, close the import control panel
			if (!config.macros.importTiddlers.inbound) { thePanel.style.display='none'; break; }
			importReport();		// if an import was in progress, generate a report
			config.macros.importTiddlers.inbound=null;	// clear the imported tiddler buffer
			refreshImportList();	// reset/resize the listbox
			break;
		case 'importSkip':	// don't import the tiddler
			var theItem	= theList.options[config.macros.importTiddlers.index];
			for (var j=0;j<config.macros.importTiddlers.inbound.length;j++)
			if (config.macros.importTiddlers.inbound[j].title==theItem.value) break;
			var theImported = config.macros.importTiddlers.inbound[j];
			theImported.status='skipped after asking';			// mark item as skipped
			theAskPanel.style.display='none';
			config.macros.importTiddlers.index=importTiddlers(config.macros.importTiddlers.index+1);	// resume with NEXT item
			importStopped();
			break;
		case 'importRename':		// change name of imported tiddler
			var theItem		= theList.options[config.macros.importTiddlers.index];
			for (var j=0;j<config.macros.importTiddlers.inbound.length;j++)
			if (config.macros.importTiddlers.inbound[j].title==theItem.value) break;
			var theImported		= config.macros.importTiddlers.inbound[j];
			theImported.status	= 'renamed from '+theImported.title;	// mark item as renamed
			theImported.set(theNewTitle.value,null,null,null,null);		// change the tiddler title
			theItem.value		= theNewTitle.value;			// change the listbox item text
			theItem.text		= theNewTitle.value;			// change the listbox item text
			theAskPanel.style.display='none';
			config.macros.importTiddlers.index=importTiddlers(config.macros.importTiddlers.index);	// resume with THIS item
			importStopped();
			break;
		case 'importMerge':	// join existing and imported tiddler content
			var theItem	= theList.options[config.macros.importTiddlers.index];
			for (var j=0;j<config.macros.importTiddlers.inbound.length;j++)
			if (config.macros.importTiddlers.inbound[j].title==theItem.value) break;
			var theImported = config.macros.importTiddlers.inbound[j];
			var theExisting = store.getTiddler(theItem.value);
			var theText	= theExisting.text+'\n----\n^^merged from: [['+config.macros.importTiddlers.src+'#'+theItem.value+'|'+config.macros.importTiddlers.src+'#'+theItem.value+']]^^\n^^'+theImported.modified.toLocaleString()+' by '+theImported.modifier+'^^\n'+theImported.text;
			var theDate     = new Date();
			var theTags     = theExisting.getTags()+' '+theImported.getTags();
			theImported.set(null,theText,null,theDate,theTags);
			theImported.status   = 'merged with '+theExisting.title;	// mark item as merged
			theImported.status  += ' - '+theExisting.modified.formatString("MM/DD/YYYY hh:mm:ss");
			theImported.status  += ' by '+theExisting.modifier;
			theAskPanel.style.display='none';
			config.macros.importTiddlers.index=importTiddlers(config.macros.importTiddlers.index);	// resume with this item
			importStopped();
			break;
		case 'importReplace':		// substitute imported tiddler for existing tiddler
			var theItem		  = theList.options[config.macros.importTiddlers.index];
			for (var j=0;j<config.macros.importTiddlers.inbound.length;j++)
			if (config.macros.importTiddlers.inbound[j].title==theItem.value) break;
			var theImported     = config.macros.importTiddlers.inbound[j];
			var theExisting	  = store.getTiddler(theItem.value);
			theImported.status  = 'replaces '+theExisting.title;		// mark item for replace
			theImported.status += ' - '+theExisting.modified.formatString("MM/DD/YYYY hh:mm:ss");
			theImported.status += ' by '+theExisting.modifier;
			theAskPanel.style.display='none';
			config.macros.importTiddlers.index=importTiddlers(config.macros.importTiddlers.index);	// resume with THIS item
			importStopped();
			break;
		case 'importListSmaller':		// decrease current listbox size, minimum=5
			if (theList.options.length==1) break;
			theList.size-=(theList.size>5)?1:0;
			config.macros.importTiddlers.listsize=theList.size;
			break;
		case 'importListLarger':		// increase current listbox size, maximum=number of items in list
			if (theList.options.length==1) break;
			theList.size+=(theList.size<theList.options.length)?1:0;
			config.macros.importTiddlers.listsize=theList.size;
			break;
		case 'importListMaximize':	// toggle listbox size between current and maximum
			if (theList.options.length==1) break;
			theList.size=(theList.size==theList.options.length)?config.macros.importTiddlers.listsize:theList.options.length;
			break;
		}
}
//}}}

// // re-entrant processing for handling import with interactive collision prompting
//{{{
function importTiddlers(startIndex)
{
	if (!config.macros.importTiddlers.inbound) return -1;

	var theList = document.getElementById('importList');
	if (!theList) return;
	var t;
	// if starting new import, reset import status flags
	if (startIndex==0)
		for (var t=0;t<config.macros.importTiddlers.inbound.length;t++)
			config.macros.importTiddlers.inbound[t].status="";
	for (var i=startIndex; i<theList.options.length; i++)
		{
		// if list item is not selected or is a heading (i.e., has no value), skip it
		if ((!theList.options[i].selected) || ((t=theList.options[i].value)==""))
			continue;
		for (var j=0;j<config.macros.importTiddlers.inbound.length;j++)
			if (config.macros.importTiddlers.inbound[j].title==t) break;
		var theImported = config.macros.importTiddlers.inbound[j];
		var theExisting = store.getTiddler(theImported.title);
		// avoid redundant import for tiddlers that are listed multiple times (when 'by tags')
		if (theImported.status=="added")
			continue;
		// don't import the "ImportedTiddlers" history from the other document...
		if (theImported.title=='ImportedTiddlers')
			continue;
		// if tiddler exists and import not marked for replace or merge, stop importing
		if (theExisting && (theImported.status.substr(0,7)!="replace") && (theImported.status.substr(0,5)!="merge"))
			return i;
		// assemble tags (remote + existing + added)
		var newTags = "";
		if (config.macros.importTiddlers.importTags)
			newTags+=theImported.getTags()	// import remote tags
		if (config.macros.importTiddlers.keepTags && theExisting)
			newTags+=" "+theExisting.getTags(); // keep existing tags
		if (config.macros.importTiddlers.addTags && config.macros.importTiddlers.newTags.trim().length)
			newTags+=" "+config.macros.importTiddlers.newTags; // add new tags
		theImported.set(null,null,null,null,newTags.trim());
		// set the status to 'added' (if not already set by the 'ask the user' UI)
		theImported.status=(theImported.status=="")?'added':theImported.status;
		// do the import!
		store.addTiddler(theImported);
		store.setDirty(true);
		}
	return(-1);	// signals that we really finished the entire list
}
//}}}

//{{{
function importStopped()
{
	var theList     = document.getElementById('importList');
	var theNewTitle = document.getElementById('importNewTitle');
	if (!theList) return;
	if (config.macros.importTiddlers.index==-1)
		importReport();		// import finished... generate the report
	else
		{
		// DEBUG alert('import stopped at: '+config.macros.importTiddlers.index);
		// import collision... show the ask panel and set the title edit field
		document.getElementById('importAskPanel').style.display='block';
		theNewTitle.value=theList.options[config.macros.importTiddlers.index].value;
		}
}
//}}}
/***

''Inspired by [[TiddlyPom|http://www.warwick.ac.uk/~tuspam/tiddlypom.html]]''

|Name|SplashScreenPlugin|
|Created by|SaqImtiaz|
|Location|http://lewcid.googlepages.com/lewcid.html#SplashScreenPlugin|
|Version|0.21 |
|Requires|~TW2.08+|
!Description:
Provides a simple splash screen that is visible while the TW is loading.

!Installation
Copy the source text of this tiddler to your TW in a new tiddler, tag it with systemConfig and save and reload. The SplashScreen will now be installed and will be visible the next time you reload your TW.

!Customizing
Once the SplashScreen has been installed and you have reloaded your TW, the splash screen html will be present in the MarkupPreHead tiddler. You can edit it and customize to your needs.

!History
* 20-07-06 : version 0.21, modified to hide contentWrapper while SplashScreen is displayed.
* 26-06-06 : version 0.2, first release

!Code
***/
//{{{
var old_lewcid_splash_restart=restart;

restart = function()
{   if (document.getElementById("SplashScreen"))
        document.getElementById("SplashScreen").style.display = "none";
      if (document.getElementById("contentWrapper"))
        document.getElementById("contentWrapper").style.display = "block";

    old_lewcid_splash_restart();

    if (splashScreenInstall)
       {if(config.options.chkAutoSave)
			{saveChanges();}
        displayMessage("TW SplashScreen has been installed, please save and refresh your TW.");
        }
}


var oldText = store.getTiddlerText("MarkupPreHead");
if (oldText.indexOf("SplashScreen")==-1)
   {var siteTitle = store.getTiddlerText("SiteTitle");
   var splasher='\n\n<style type="text/css">#contentWrapper {display:none;}</style><div id="SplashScreen" style="border: 3px solid #ccc; display: block; text-align: center; width: 320px; margin: 100px auto; padding: 50px; color:#000; font-size: 28px; font-family:Tahoma; background-color:#eee;"><b>'+siteTitle +'</b> is loading<blink> ...</blink><br><br><span style="font-size: 14px; color:red;">Requires Javascript.</span></div>';
   if (! store.tiddlerExists("MarkupPreHead"))
       {var myTiddler = store.createTiddler("MarkupPreHead");}
   else
      {var myTiddler = store.getTiddler("MarkupPreHead");}
      myTiddler.set(myTiddler.title,oldText+splasher,config.options.txtUserName,null,null);
      store.setDirty(true);
      var splashScreenInstall = true;
}
//}}}
config.macros.listTags = { text: "Hello" };
config.macros.listTags.handler = function(place,macroName,params)
{
 var tagged = store.getTaggedTiddlers(params[0]);
 var ul = createTiddlyElement(place,"ul",null,null,"");
 for(var r=0;r<tagged.length;r++)
 {
 var li = createTiddlyElement(ul,"li",null,null,"");
 createTiddlyLink(li,tagged[r].title,true);
 }
}
http://cctiddly.sourceforge.net
http://tiddlytools.com
http://tiddlywiki.bidix.info
http://tiddlywikitips.com
http://visualtw.ouvaton.org/VisualTW.html
You can also get free webspace from some public servers out there (such as [[byethost|http://byethost.com/]] and [[lycos (tripod)|http://www.tripod.lycos.co.uk/]]. Whichever providers you choose, you will need:
*~PHP4/5
*~MySQL

''Benefit''
*Free (as in beer)
*Uptime (depending on your provider, but usually not as good as paid hosting)
*Saves time from maintaining server

''Issues''
*Advertising on your page
*Database is "not as private" since your provider now have access to it

Here is a ''step-by-step'' installation tutorial for [[Byethost|Installing on byethost]] and [[Lycos|Installing on lycos]]
!!~RippleRap Resources

[[HomePage|http://www.ripplerap.com/]]

[[Write-up at OsmoSoft|http://osmosoft.com/#RippleRap]]
/***
|Name|RearrangeTiddlersPlugin|
|Source|http://www.TiddlyTools.com/#RearrangeTiddlersPlugin|
|Version|0.0.0|
|Author|Joe Raii|
|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.refreshTiddler|
|Description|drag tiddlers by title to re-order story column display|

adapted from: http://www.cs.utexas.edu/~joeraii/dragn/#Draggable
changes by ELS:
* hijack refreshTiddler() instead of overridding createTiddler()
* find title element by className instead of elementID
* set cursor style via code instead of stylesheet
* set tooltip help text
* set tiddler "position:relative" when starting drag event, restore saved value when drag ends
* update 2006.08.07: use getElementsByTagName("*") to find title element, even when it is 'buried' deep in tiddler DOM elements (due to custom template usage)
* update 2007.03.01: use apply() to invoke hijacked core function
* update 2008.01.13: only hijack core function once.  (allows for dynamic loading of plugin via bookmarklet)

***/
//{{{

if (Story.prototype.rearrangeTiddlersHijack_refreshTiddler===undefined) {
Story.prototype.rearrangeTiddlersHijack_refreshTiddler = Story.prototype.refreshTiddler;
Story.prototype.refreshTiddler = function(title,template)
{
	this.rearrangeTiddlersHijack_refreshTiddler.apply(this,arguments);
	var theTiddler = document.getElementById(this.idPrefix + title); if (!theTiddler) return;
	var theHandle;
	var children=theTiddler.getElementsByTagName("*");
	for (var i=0; i<children.length; i++) if (hasClass(children[i],"title")) { theHandle=children[i]; break; }
	if (!theHandle) return theTiddler;

	Drag.init(theHandle, theTiddler, 0, 0, null, null);
	theHandle.style.cursor="move";
	theHandle.title="drag title to re-arrange tiddlers"
	theTiddler.onDrag = function(x,y,myElem) {
		if (this.style.position!="relative")
			{ this.savedstyle=this.style.position; this.style.position="relative"; }
		y = myElem.offsetTop;
		var next = myElem.nextSibling;
		var prev = myElem.previousSibling;
		if (next && y + myElem.offsetHeight > next.offsetTop + next.offsetHeight/2) { 
			myElem.parentNode.removeChild(myElem);
			next.parentNode.insertBefore(myElem, next.nextSibling);//elems[pos+1]);
			myElem.style["top"] = -next.offsetHeight/2+"px";
		}
		if (prev && y < prev.offsetTop + prev.offsetHeight/2) { 
			myElem.parentNode.removeChild(myElem);
			prev.parentNode.insertBefore(myElem, prev);
			myElem.style["top"] = prev.offsetHeight/2+"px";
		}
	};
	theTiddler.onDragEnd = function(x,y,myElem) {
		myElem.style["top"] = "0px";
		if (this.savedstyle!=undefined)
			this.style.position=this.savedstyle;
	}
	return theTiddler;
}
}

/**************************************************
 * dom-drag.js
 * 09.25.2001
 * www.youngpup.net
 **************************************************
 * 10.28.2001 - fixed minor bug where events
 * sometimes fired off the handle, not the root.
 **************************************************/

var Drag = {
	obj:null,

	init:
	function(o, oRoot, minX, maxX, minY, maxY) {
		o.onmousedown = Drag.start;
		o.root = oRoot && oRoot != null ? oRoot : o ;
		if (isNaN(parseInt(o.root.style.left))) o.root.style.left="0px";
		if (isNaN(parseInt(o.root.style.top))) o.root.style.top="0px";
		o.minX = typeof minX != 'undefined' ? minX : null;
		o.minY = typeof minY != 'undefined' ? minY : null;
		o.maxX = typeof maxX != 'undefined' ? maxX : null;
		o.maxY = typeof maxY != 'undefined' ? maxY : null;
		o.root.onDragStart = new Function();
		o.root.onDragEnd = new Function();
		o.root.onDrag = new Function();
	},

	start:
	function(e) {
		var o = Drag.obj = this;
		e = Drag.fixE(e);
		var y = parseInt(o.root.style.top);
		var x = parseInt(o.root.style.left);
		o.root.onDragStart(x, y, Drag.obj.root);
		o.lastMouseX = e.clientX;
		o.lastMouseY = e.clientY;
		if (o.minX != null) o.minMouseX = e.clientX - x + o.minX;
		if (o.maxX != null) o.maxMouseX = o.minMouseX + o.maxX - o.minX;
		if (o.minY != null) o.minMouseY = e.clientY - y + o.minY;
		if (o.maxY != null) o.maxMouseY = o.minMouseY + o.maxY - o.minY;
		document.onmousemove = Drag.drag;
		document.onmouseup = Drag.end;
		Drag.obj.root.style["z-index"] = "10";
		return false;
	},

	drag:
	function(e) {
		e = Drag.fixE(e);
		var o = Drag.obj;
		var ey = e.clientY;
		var ex = e.clientX;
		var y = parseInt(o.root.style.top);
		var x = parseInt(o.root.style.left);
		var nx, ny;
		if (o.minX != null) ex = Math.max(ex, o.minMouseX);
		if (o.maxX != null) ex = Math.min(ex, o.maxMouseX);
		if (o.minY != null) ey = Math.max(ey, o.minMouseY);
		if (o.maxY != null) ey = Math.min(ey, o.maxMouseY);
		nx = x + (ex - o.lastMouseX);
		ny = y + (ey - o.lastMouseY);
		Drag.obj.root.style["left"] = nx + "px";
		Drag.obj.root.style["top"] = ny + "px";
		Drag.obj.lastMouseX = ex;
		Drag.obj.lastMouseY = ey;
		Drag.obj.root.onDrag(nx, ny, Drag.obj.root);
		return false;
	},

	end:
	function() {
		document.onmousemove = null;
		document.onmouseup = null;
		Drag.obj.root.style["z-index"] = "0";
		Drag.obj.root.onDragEnd(parseInt(Drag.obj.root.style["left"]), parseInt(Drag.obj.root.style["top"]), Drag.obj.root);
		Drag.obj = null;
	},

	fixE:
	function(e) {
		if (typeof e == 'undefined') e = window.event;
		if (typeof e.layerX == 'undefined') e.layerX = e.offsetX;
		if (typeof e.layerY == 'undefined') e.layerY = e.offsetY;
		return e;
	}
};
//}}}
If you want to renting webspace, you will need access to
*~PHP4/5
*~MySQL

''Benefit''
*Uptime (depending on your provider)
*Saves time from maintaining server
*No advertising

''Issues''
*Database is "not as private" since your provider now have access to it
*Cost a bit of money, but they are relatively cheap nowadays
*Need to get a domain

<<tag requirements>>
!!!Requirements
ccTiddly can be hosted using the following environment (click on the link to see details)
#+++^[Public free web server]<<tiddler "Public free web server">>===

#+++^[Rent some webspace from web providers]<<tiddler "Rent some webspace from web providers">>===

#+++^[Setup your own server]<<tiddler "Setup your own server">>===

After picking your server environment, you can proceed to install.

<<tag requirements>>
see irc://irc.freenode.net/tiddlywiki

<<slider chkSliderOptionsPanel ccTWRes 'ccTiddly ยป' 'A list of sites'>>

<<slider chkSliderOptionsPanel TWRes 'TIddlyWiki ยป' 'A list of sites'>>

<<slider chkSliderOptionsPanel RRapRes 'RippleRap ยป' 'A list of sites'>>

[[TWRes]] [[ccTWRes]] [[RRapRes]]

----
<<slider chkSliderOptionsPanel GettingStarted 'Getting Started ยป' 'A list of sites'>>

<<tag resources>>
/***
|''Name:''|~SectionMacro|
|''Version:''|0.9.4 (20-Apr-2007)|
|''Author:''|[[Jack]]|
|''Type:''|Macro|
!Description
Allows you to create collapsable sections just like the slider macro but without needing to create new tiddlers for these sections.
!Usage
{{{<<section Title Tiddler Text goes here...
and can be multi-
line and include {${${monospace text}$}$}.
>>}}}
<<section Title Tiddler Text goes here...
and can be multi-
line and include {${${monospace text}$}$}.
>>
!Revision History
* Original by [[Jack]] 0.9
* Nested sliders and cookie persistence 0.9.1
* Removed crappy cookie persistance 0.9.2
* Bug-fix with quoted 2st parameter (thanks M. Macolio) 0.9.3
* Bug-fix with monospace text (thanks M. Macolio) 0.9.4
!Code
***/
//{{{
version.extensions.section = {major: 0, minor: 9, revision: 4, date: new Date("Apr 20, 2007")};

config.macros.section = {count:0,display:'none'};
config.macros.section.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
 this.slider(place,"chkSection" + this.count++,paramString.substr(params[0].length+(paramString.substr(params[0].length+1,1).match(/['"]/)?2:1)).replace(/\$\>/g, '>').replace(/}\$}\$}/, '}}}').replace(/{\${\${/, '{{{'),params[0], "tooltip");
}

config.macros.section.slider = function(place,cookie,text,title,tooltips) {
 var btn = createTiddlyButton(place,title,tooltips,config.macros.slider.onClickSlider,"tiddlyLink tiddlyLinkExisting"); 
 var panel = createTiddlyElement(place,"div",null,"timelineSliderPanel",null);
 panel.setAttribute("cookie",cookie);
 panel.style.display = config.options[cookie] ? "block" : "none";
 panel.style.display=this.display;
 if(text) wikify(text,panel);
};
//}}}
Setting up your own server would require
*internet connection
*[[HTTP server|http://httpd.apache.org]]
*[[PHP4/5|http://php.net]]
*[[MySQL|http://mysql.com]]

''Benefit''
*no cash required apart from your internet connection
*Database is kept private
*No advertising

''Issues''
*Spending time to maintain the server (such as learn to set one up, keep server up to date)
*Require a domain (you can get them free from [[here|http://no-ip.com]]
*Security
*Uptime (if your internet connection is down at home, you wont be able to access it at work)
*Computer switch on all the time (hidden cost in electricity)

see [[Installing on lycos]] for some configuration data

<<tag requirements>>
<<tabs txtMainTab "Timeline" "Timeline" TabTimeline "All" "All tiddlers" TabAll "Tags" "All tags" TabTags "More" "More lists" TabMore>>
<<slider chkSliderContents [[SideBarContents]] '* contents ยป' 'contents'>>
It's about discourse! (TiddlyWiki on bentrem.sycks.net)
Participatory Deliberation -
@@display:none;clear:both;@@
*Of interest:
**{{myclass{
*[[TWFaq at TiddlySpot|http://twfaq.tiddlyspot.com/]] and [[CheatSheet (PDF)|http://nothickmanuals.info/lib/exe/fetch.php/cheatsheets:tiddlywiki_cheatsheet.pdf]]
*[[Daniel Baird's UserGuide|http://danielbaird.com/tiddlywikiguides/userguide-sample.html#TiddlyWiki User's Guide]]
*[[TW Resources on TiddlyWiki.org's Wiki|http://www.tiddlywiki.org/wiki/TiddlyWiki_Resources]]
*[[Jim Barr's fully enhanced TW|http://tiddlywikitips.com/]]
}}}
*Advanced:
**{{myclass{
*[[Plugin Development|http://tiddlywiki.org/wiki/Plugin_Development]]
}}}
*To Be Explored:
**{{myclass{
*[["Tiddler Parts" plugin|http://tiddlywiki.abego-software.de/#PartTiddlerPlugin]] by [[Udo Borkowski|http://www.abego-software.de/]] (see also [[list of his plugins|http://tiddlywiki.abego-software.de/#Plugins]])
*[[FND's DevPad|http://devpad.tiddlyspot.com/]]
*[[Some useful reference stuff by Jules|http://knighjm.googlepages.com/knightnet-default-tw.html#Reference]] including lists of built-in macros, formatting rules and useful javascript methods for developers.
*[[Repository for BidiX's TiddlyWiki Extensions|http://tiddlywiki.bidix.info/]]
*[[Extension Repository|http://tw.lewcid.org/]] from [[LewCid.org|http://lewcid.org/]]
}}}
<<accordion>>
<<tag demo>>
!!~TiddlyWiki Resources

*[[Main TiddlyWiki site|http://www.tiddlywiki.com]] and [[Developers' site|http://www.tiddlywiki.org/wiki/TiddlyWeb]]
*[[TWFaq at TiddlySpot|http://twfaq.tiddlyspot.com/]]
*[[Julian Knight's references|http://knighjm.googlepages.com/knightnet-default-tw.html]]

*[[Google Group|http://groups.google.com/group/TiddlyWiki]]
*[[Developers Google Group|http://groups.google.com/group/TiddlyWikiDev]]

*[[Write-up at OsmoSoft|http://osmosoft.com/#TiddlyWiki]]




/***
|Name|TaggedTemplateTweak|
|Source|http://www.TiddlyTools.com/#TaggedTemplateTweak|
|Documentation|http://www.TiddlyTools.com/#TaggedTemplateTweakInfo|
|Version|1.2.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|Story.prototype.chooseTemplateForTiddler()|
|Description|use alternative ViewTemplate/EditTemplate for tiddler's tagged with specific tag values|
This tweak extends story.chooseTemplateForTiddler() so that ''whenever a tiddler is marked with a specific tag value, it can be viewed and/or edited using alternatives to the standard tiddler templates.'' 
!!!!!Documentation
>see [[TaggedTemplateTweakInfo]]
!!!!!Revisions
<<<
2008.04.01 [1.2.0] added support for using systemTheme section-based template definitions (requested by Phil Hawksworth)
2008.01.22 [*.*.*] plugin size reduction - documentation moved to [[TaggedTemplateTweakInfo]]
2007.06.23 [1.1.0] re-written to use automatic 'tag prefix' search instead of hard coded check for each tag.  Allows new custom tags to be used without requiring code changes to this plugin.
| please see [[TaggedTemplateTweakInfo]] for previous revision details |
2007.06.11 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.taggedTemplate= {major: 1, minor: 2, revision: 0, date: new Date(2008,4,1)};
Story.prototype.taggedTemplate_chooseTemplateForTiddler = Story.prototype.chooseTemplateForTiddler
Story.prototype.chooseTemplateForTiddler = function(title,template)
{
	// get default template from core
	var template=this.taggedTemplate_chooseTemplateForTiddler.apply(this,arguments);

	// if the tiddler to be rendered doesn't exist yet, just return core result
	var tiddler=store.getTiddler(title); if (!tiddler) return template;

	// look for template whose prefix matches a tag on this tiddler
	for (i=0; i<tiddler.tags.length; i++) {
		var t=tiddler.tags[i]+template; // add tag prefix
		var c=t.substr(0,1).toUpperCase()+t.substr(1); // capitalized for WikiWord title
		var s=config.options.txtTheme+"##"; // systemTheme section prefix
		if (store.tiddlerExists(t)) { template=t; break; }
		if (store.tiddlerExists(c)) { template=c; break; }
		if (store.getTiddlerText(s+t)) { template=s+t; break; }
		if (store.getTiddlerText(s+c)) { template=s+c; break; }
	}
	return template;
}
//}}}
<<tabs referencelabel [[A1]] "Not much" [[subtabA1]] [[B1]]
"Just a bit" [[subtabB1]] >>

<<tag demo>>
just a test
/***
|''Name:''|DropDownMenuPlugin|
|''Description:''|Create dropdown menus from unordered lists|
|''Author:''|Saq Imtiaz ( lewcid@gmail.com )|
|''Source:''|http://tw.lewcid.org/#DropDownMenuPlugin|
|''Code Repository:''|http://tw.lewcid.org/svn/plugins|
|''Version:''|2.1|
|''Date:''|11/04/2007|
|''License:''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''~CoreVersion:''|2.2.5|

!!Usage:
* create a two-level unordered list using wiki syntax, and place {{{<<dropMenu>>}}} on the line after it.
* to create a vertical menu use {{{<<dropMenu vertical>>}}} instead.
* to assign custom classes to the list, just pass them as parameters to the macro {{{<<dropMenu className1 className2 className3>>}}}

!!Features:
*Supports just a single level of drop-downs, as anything more usually provides a poor experience for the user.
* Very light weight, about 1.5kb of JavaScript and 4kb of CSS.
* Comes with two built in css 'themes', the default horizontal and vertical. 

!!Customizing:
* to customize the appearance of the menu's, you can either add a custom class as described above or, you can edit the CSS via the StyleSheetDropDownMenu shadow tiddler.

!!Examples:
* [[DropDownMenuDemo]]

***/
// /%
//!BEGIN-PLUGIN-CODE
config.macros.dropMenu={

	dropdownchar: "\u25bc",

	handler : function(place,macroName,params,wikifier,paramString,tiddler){
		list = findRelated(place.lastChild,"UL","tagName","previousSibling");
		if (!list)
			return;
		addClass(list,"suckerfish");
		if (params.length){
			addClass(list,paramString);
		}
		this.fixLinks(list);
	},
	
	fixLinks : function(el){
		var els = el.getElementsByTagName("li");
		for(var i = 0; i < els.length; i++) {
			if(els[i].getElementsByTagName("ul").length>0){
				var link = findRelated(els[i].firstChild,"A","tagName","nextSibling");
				if(!link){
					var ih = els[i].firstChild.data;
					els[i].removeChild(els[i].firstChild);
					var d = createTiddlyElement(null,"a",null,null,ih+this.dropdownchar,{href:"javascript:;"});
					els[i].insertBefore(d,els[i].firstChild);
				}
				else{
					link.firstChild.data = link.firstChild.data + this.dropdownchar;
					removeClass(link,"tiddlyLinkNonExisting");
				}
			}
			els[i].onmouseover = function() {
				addClass(this, "sfhover");
			};
			els[i].onmouseout = function() {
				removeClass(this, "sfhover");
			};
		}
	}	
};

config.shadowTiddlers["StyleSheetDropDownMenuPlugin"] = 
	 "/*{{{*/\n"+
	 "/***** LAYOUT STYLES -  DO NOT EDIT! *****/\n"+
	 "ul.suckerfish, ul.suckerfish ul {\n"+
	 "	margin: 0;\n"+
	 "	padding: 0;\n"+
	 "	list-style: none;\n"+
	 "	line-height:1.4em;\n"+
	 "}\n\n"+
	 "ul.suckerfish  li {\n"+
	 "	display: inline-block; \n"+
	 "	display: block;\n"+
	 "	float: left; \n"+
	 "}\n\n"+
	 "ul.suckerfish li ul {\n"+
	 "	position: absolute;\n"+
	 "	left: -999em;\n"+
	 "}\n\n"+
	 "ul.suckerfish li:hover ul, ul.suckerfish li.sfhover ul {\n"+
	 "	left: auto;\n"+
	 "}\n\n"+
	 "ul.suckerfish ul li {\n"+
	 "	float: none;\n"+
	 "	border-right: 0;\n"+
	 "	border-left:0;\n"+
	 "}\n\n"+
	 "ul.suckerfish a, ul.suckerfish a:hover {\n"+
	 "	display: block;\n"+
	 "}\n\n"+
	 "ul.suckerfish li a.tiddlyLink, ul.suckerfish li a, #mainMenu ul.suckerfish li a {font-weight:bold;}\n"+
	 "/**** END LAYOUT STYLES *****/\n"+
	 "\n\n"+
	 "/**** COLORS AND APPEARANCE - DEFAULT *****/\n"+
	 "ul.suckerfish li a {\n"+
	 "	padding: 0.5em 1.5em;\n"+
	 "	color: #FFF;\n"+
	 "	background: #3278FC;\n"+
	 "	border-bottom: 0;\n"+
	 "	font-weight:bold;\n"+
	 "}\n\n"+
	 "ul.suckerfish li:hover a, ul.suckerfish li.sfhover a{\n"+
	 "	background: #00558F;\n"+
	 "}\n\n"+
	 "ul.suckerfish li:hover ul a, ul.suckerfish li.sfhover ul a{\n"+
	 "	color: #000;\n"+
	 "	background: #eff3fa;\n"+
	 "	border-top:1px solid #FFF;\n"+
	 "}\n\n"+
	 "ul.suckerfish ul li a:hover {\n"+
	 "	background: #e0e8f5;\n"+
	 "}\n\n"+
	 "ul.suckerfish li a{\n"+
	 "	width:9em;\n"+
	 "}\n\n"+
	 "ul.suckerfish ul li a, ul.suckerfish ul li a:hover{\n"+
	 "	display:inline-block;\n"+
	 "	width:9em;\n"+
	 "}\n\n"+
	 "ul.suckerfish li {\n"+
	 "	border-left: 1px solid #00558F;\n"+
	 "}\n"+
	 "/***** END COLORS AND APPEARANCE - DEFAULT *****/\n"+
	 "\n\n"+
	 "/***** LAYOUT AND APPEARANCE: VERTICAL *****/\n"+
	 "ul.suckerfish.vertical li{\n"+
	 "	width:10em;\n"+
	 "	border-left: 0px solid #00558f;\n"+
	 "}\n\n"+
	 "ul.suckerfish.vertical ul li, ul.suckerfish.vertical li a, ul.suckerfish.vertical li:hover a, ul.suckerfish.vertical li.sfhover a {\n"+
	 "	border-left: 0.8em solid #00558f;\n"+
	 "}\n\n"+
	 "ul.suckerfish.vertical li a, ul.suckerfish.vertical li:hover a, ul.suckerfish.vertical li.sfhover a,  ul.suckerfish.vertical li.sfhover a:hover{\n"+
	 "	width:8em;\n"+
	 "}\n\n"+
	 "ul.suckerfish.vertical {\n"+
	 "	width:10em; text-align:left;\n"+
	 "	float:left;\n"+
	 "}\n\n"+
	 "ul.suckerfish.vertical li a {\n"+
	 "	padding: 0.5em 1em 0.5em 1em;\n"+
	 "	border-top:1px solid  #fff;\n"+
	 "}\n\n"+
	 "ul.suckerfish.vertical, ul.suckerfish.vertical ul {\n"+
	 "	line-height:1.4em;\n"+
	 "}\n\n"+
	 "ul.suckerfish.vertical li:hover ul, ul.suckerfish.vertical li.sfhover ul { \n"+
	 "	margin: -2.4em 0 0 10.9em;\n"+
	 "}\n\n"+
	 "ul.suckerfish.vertical li:hover ul li a, ul.suckerfish.vertical li.sfhover ul li a {\n"+
	 "	border: 0px solid #FFF;\n"+
	 "}\n\n"+
	 "ul.suckerfish.vertical li:hover a, ul.suckerfish.vertical li.sfhover a{\n"+
	 "	padding-right:1.1em;\n"+
	 "}\n\n"+
	 "ul.suckerfish.vertical li:hover ul li, ul.suckerfish.vertical li.sfhover ul li {\n"+
	 "	border-bottom:1px solid  #fff;\n"+
	 "}\n\n"+
	 "/***** END LAYOUT AND APPEARANCE: VERTICAL *****/\n"+
	 "/*}}}*/";
store.addNotification("StyleSheetDropDownMenuPlugin",refreshStyles);
//!END-PLUGIN-CODE
// %/
/***
|''Name:''|DropDownMenuPlugin|
|''Description:''|Create dropdown menus from unordered lists|
|''Author:''|Saq Imtiaz ( lewcid@gmail.com )|
|''Source:''|http://tw.lewcid.org/#DropDownMenuPlugin|
|''Code Repository:''|http://tw.lewcid.org/svn/plugins|
|''Version:''|2.1|
|''Date:''|11/04/2007|
|''License:''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''~CoreVersion:''|2.2.5|

!!Usage:
* create a two-level unordered list using wiki syntax, and place {{{<<dropMenu>>}}} on the line after it.
* to create a vertical menu use {{{<<dropMenu vertical>>}}} instead.
* to assign custom classes to the list, just pass them as parameters to the macro {{{<<dropMenu className1 className2 className3>>}}}

!!Features:
*Supports just a single level of drop-downs, as anything more usually provides a poor experience for the user.
* Very light weight, about 1.5kb of JavaScript and 4kb of CSS.
* Comes with two built in css 'themes', the default horizontal and vertical. 

!!Customizing:
* to customize the appearance of the menu's, you can either add a custom class as described above or, you can edit the CSS via the StyleSheetDropDownMenu shadow tiddler.

!!Examples:
* [[DropDownMenuDemo]]

***/
// /%
//!BEGIN-PLUGIN-CODE
config.macros.dropMenu={

	dropdownchar: "\u25bc",

	handler : function(place,macroName,params,wikifier,paramString,tiddler){
		list = findRelated(place.lastChild,"UL","tagName","previousSibling");
		if (!list)
			return;
		addClass(list,"suckerfish");
		if (params.length){
			addClass(list,paramString);
		}
		this.fixLinks(list);
	},
	
	fixLinks : function(el){
		var els = el.getElementsByTagName("li");
		for(var i = 0; i < els.length; i++) {
			if(els[i].getElementsByTagName("ul").length>0){
				var link = findRelated(els[i].firstChild,"A","tagName","nextSibling");
				if(!link){
					var ih = els[i].firstChild.data;
					els[i].removeChild(els[i].firstChild);
					var d = createTiddlyElement(null,"a",null,null,ih+this.dropdownchar,{href:"javascript:;"});
					els[i].insertBefore(d,els[i].firstChild);
				}
				else{
					link.firstChild.data = link.firstChild.data + this.dropdownchar;
					removeClass(link,"tiddlyLinkNonExisting");
				}
			}
			els[i].onmouseover = function() {
				addClass(this, "sfhover");
			};
			els[i].onmouseout = function() {
				removeClass(this, "sfhover");
			};
		}
	}	
};

config.shadowTiddlers["StyleSheetDropDownMenuPlugin"] = 
	 "/*{{{*/\n"+
	 "/***** LAYOUT STYLES -  DO NOT EDIT! *****/\n"+
	 "ul.suckerfish, ul.suckerfish ul {\n"+
	 "	margin: 0;\n"+
	 "	padding: 0;\n"+
	 "	list-style: none;\n"+
	 "	line-height:1.4em;\n"+
	 "}\n\n"+
	 "ul.suckerfish  li {\n"+
	 "	display: inline-block; \n"+
	 "	display: block;\n"+
	 "	float: left; \n"+
	 "}\n\n"+
	 "ul.suckerfish li ul {\n"+
	 "	position: absolute;\n"+
	 "	left: -999em;\n"+
	 "}\n\n"+
	 "ul.suckerfish li:hover ul, ul.suckerfish li.sfhover ul {\n"+
	 "	left: auto;\n"+
	 "}\n\n"+
	 "ul.suckerfish ul li {\n"+
	 "	float: none;\n"+
	 "	border-right: 0;\n"+
	 "	border-left:0;\n"+
	 "}\n\n"+
	 "ul.suckerfish a, ul.suckerfish a:hover {\n"+
	 "	display: block;\n"+
	 "}\n\n"+
	 "ul.suckerfish li a.tiddlyLink, ul.suckerfish li a, #mainMenu ul.suckerfish li a {font-weight:bold;}\n"+
	 "/**** END LAYOUT STYLES *****/\n"+
	 "\n\n"+
	 "/**** COLORS AND APPEARANCE - DEFAULT *****/\n"+
	 "ul.suckerfish li a {\n"+
	 "	padding: 0.5em 1.5em;\n"+
	 "	color: #FFF;\n"+
	 "	background: #0066aa;\n"+
	 "	border-bottom: 0;\n"+
	 "	font-weight:bold;\n"+
	 "}\n\n"+
	 "ul.suckerfish li:hover a, ul.suckerfish li.sfhover a{\n"+
	 "	background: #00558F;\n"+
	 "}\n\n"+
	 "ul.suckerfish li:hover ul a, ul.suckerfish li.sfhover ul a{\n"+
	 "	color: #000;\n"+
	 "	background: #eff3fa;\n"+
	 "	border-top:1px solid #FFF;\n"+
	 "}\n\n"+
	 "ul.suckerfish ul li a:hover {\n"+
	 "	background: #e0e8f5;\n"+
	 "}\n\n"+
	 "ul.suckerfish li a{\n"+
	 "	width:9em;\n"+
	 "}\n\n"+
	 "ul.suckerfish ul li a, ul.suckerfish ul li a:hover{\n"+
	 "	display:inline-block;\n"+
	 "	width:9em;\n"+
	 "}\n\n"+
	 "ul.suckerfish li {\n"+
	 "	border-left: 1px solid #00558F;\n"+
	 "}\n"+
	 "/***** END COLORS AND APPEARANCE - DEFAULT *****/\n"+
	 "\n\n"+
	 "/***** LAYOUT AND APPEARANCE: VERTICAL *****/\n"+
	 "ul.suckerfish.vertical li{\n"+
	 "	width:10em;\n"+
	 "	border-left: 0px solid #00558f;\n"+
	 "}\n\n"+
	 "ul.suckerfish.vertical ul li, ul.suckerfish.vertical li a, ul.suckerfish.vertical li:hover a, ul.suckerfish.vertical li.sfhover a {\n"+
	 "	border-left: 0.8em solid #00558f;\n"+
	 "}\n\n"+
	 "ul.suckerfish.vertical li a, ul.suckerfish.vertical li:hover a, ul.suckerfish.vertical li.sfhover a,  ul.suckerfish.vertical li.sfhover a:hover{\n"+
	 "	width:8em;\n"+
	 "}\n\n"+
	 "ul.suckerfish.vertical {\n"+
	 "	width:10em; text-align:left;\n"+
	 "	float:left;\n"+
	 "}\n\n"+
	 "ul.suckerfish.vertical li a {\n"+
	 "	padding: 0.5em 1em 0.5em 1em;\n"+
	 "	border-top:1px solid  #fff;\n"+
	 "}\n\n"+
	 "ul.suckerfish.vertical, ul.suckerfish.vertical ul {\n"+
	 "	line-height:1.4em;\n"+
	 "}\n\n"+
	 "ul.suckerfish.vertical li:hover ul, ul.suckerfish.vertical li.sfhover ul { \n"+
	 "	margin: -2.4em 0 0 10.9em;\n"+
	 "}\n\n"+
	 "ul.suckerfish.vertical li:hover ul li a, ul.suckerfish.vertical li.sfhover ul li a {\n"+
	 "	border: 0px solid #FFF;\n"+
	 "}\n\n"+
	 "ul.suckerfish.vertical li:hover a, ul.suckerfish.vertical li.sfhover a{\n"+
	 "	padding-right:1.1em;\n"+
	 "}\n\n"+
	 "ul.suckerfish.vertical li:hover ul li, ul.suckerfish.vertical li.sfhover ul li {\n"+
	 "	border-bottom:1px solid  #fff;\n"+
	 "}\n\n"+
	 "/***** END LAYOUT AND APPEARANCE: VERTICAL *****/\n"+
	 "/*}}}*/";
store.addNotification("StyleSheetDropDownMenuPlugin",refreshStyles);
//!END-PLUGIN-CODE
// %/
/***
|''Name:''|TiddlerNotesPlugin|
|''Description:''|Add notes to tiddlers without modifying the original content|
|''Author:''|Saq Imtiaz ( lewcid@gmail.com )|
|''Source:''|http://tw.lewcid.org/#TiddlerNotesPlugin|
|''Code Repository:''|http://tw.lewcid.org/svn/plugins|
|''Version:''|2.1|
|''Date:''|26/10/07|
|''License:''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''~CoreVersion:''|2.2.3|

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

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

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

!!Demo:
* [[MySlide]]

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

if (!config.options.chkPrefillNotes)
	config.options.chkPrefillNotes = false;

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

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

config.macros.notes={

	cancelWarning: "Are you sure you want to abandon changes to your notes for '%0'?",
	editLabel: "edit notes",
	editTitle: "double click to edit",
	saveLabel: "save notes",
	saveTitle: "double click to save",
	cancelLabel: "cancel",
	heading: "Notes",
	suffix: "Notes",
	tag: "Notes",

	saveNotes: function(ev){
		e = ev? ev : window.event;
		var theTarget = resolveTarget(e);
		if (theTarget.nodeName.toLowerCase() == "textarea")
			return false;
		var title = story.findContainingTiddler(theTarget).getAttribute("tiddler");
		story.setDirty(title,false);
		var box = document.getElementById("notesContainer"+title);
		var textarea = document.getElementById("notesTextArea"+title);
		if(textarea.getAttribute("oldText")!=textarea.value && !hasClass(theTarget,"cancelNotesButton")){
			var suffix = box.getAttribute("suffix");
			var t = store.getTiddler(title+"-"+suffix);
			store.saveTiddler(title+"-"+suffix,title+"-"+suffix,textarea.value,config.options.txtUserName,new Date(),t?t.tags:box.getAttribute("tag"),t?t.fields:{});
		}
		story.refreshTiddler(title,1,true);
		autoSaveChanges(true);
		return false;
	},

	editNotes: function(box,tiddler){
		removeChildren(box);
		story.setDirty(tiddler,true);
		box.title = this.saveTitle;
		box.ondblclick = this.saveNotes;
		createTiddlyButton(box,this.cancelLabel,this.cancelLabel,this.saveNotes,"cancelNotesButton");
		createTiddlyButton(box,this.saveLabel,this.saveLabel,this.saveNotes,"saveNotesButton");
		wikify("!!"+box.getAttribute("heading")+"\n",box);
		addClass(box,"editor");
		var wrapper1 = createTiddlyElement(null,"fieldset",null,"fieldsetFix");
		var wrapper2 = createTiddlyElement(wrapper1,"div");
		var e = createTiddlyElement(wrapper2,"textarea","notesTextArea"+tiddler);
		var v = store.getValue(tiddler+"-"+box.getAttribute("suffix"),"text");
		if(!v)
			v = config.options.chkPrefillNotes? store.getValue(tiddler,"text"):'';
		e.value = v;
		e.setAttribute("oldText",v);
		var rows = 10;
		var lines = v.match(/\n/mg);
		var maxLines = Math.max(parseInt(config.options.txtMaxEditRows),5);
		if(lines != null && lines.length > rows)
			rows = lines.length + 5;
		rows = Math.min(rows,maxLines);
		e.setAttribute("rows",rows);
		box.appendChild(wrapper1);
	},

	editNotesButtonOnclick: function(e){
		var title = story.findContainingTiddler(this).getAttribute("tiddler");
		var box = document.getElementById("notesContainer"+title);
		config.macros.notes.editNotes(box,title);
		return false;
	},

	ondblclick : function(ev){
		e = ev? ev : window.event;
		var theTarget = resolveTarget(e);
		var title = story.findContainingTiddler(theTarget).getAttribute("tiddler");
		var box = document.getElementById("notesContainer"+title);
		config.macros.notes.editNotes(box,title);
		e.cancelBubble = true;
		if(e.stopPropagation) e.stopPropagation();
		return false;
	},

	handler : function(place,macroName,params,wikifier,paramString,tiddler){

		params = paramString.parseParams("anon",null,true,false,false);
		var heading = getParam(params,"heading",this.heading);
		var tag = getParam(params,"tag",this.tag);
		var suffix = getParam(params,"suffix",this.suffix);
		var box = createTiddlyElement(place,"div","notesContainer"+tiddler.title,"TiddlerNotes",null,{"source":tiddler.title,params:paramString,heading:heading,tag:tag,suffix:suffix});
		createTiddlyButton(box,this.editLabel,this.editLabel,this.editNotesButtonOnclick,"editNotesButton");
		wikify("!!"+heading+"\n",box);
		box.title=this.editTitle;
		box.ondblclick = this.ondblclick;
		wikify("<<tiddler [["+tiddler.title+"-"+suffix+"]]>>",box);
	}
};

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

setStylesheet(".TiddlerNotes {\n"+ " background:#eee;\n"+ " border:1px solid #ccc;\n"+ " padding:10px;\n"+ " margin:15px;\n"+ "}\n"+ "\n"+ ".cancelNotesButton,.editNotesButton, .saveNotesButton {\n"+ " float:right;\n"+ " border:1px solid #ccc;\n"+ " padding:2px 5px;\n"+ "}\n"+ "\n"+ ".saveNotesButton{\n"+ " margin-right:0.5em;\n"+ "}\n"+ "\n"+ ".TiddlerNotes.editor textarea{\n"+ " border:1px solid #ccc;\n"+ "}","NotesPluginStyles");
//!END-PLUGIN-CODE
// %/
NB: I just created this using [[TiddlySnip|http://tiddlysnip.com/]]

    * ategory, select it and then click Edit.
    * To delete a category, select it and choose Delete.
    * To add a new category, just type in its Name and Tags. Please remember that tags should be space separated, and if a tag contains spaces it should be enclosed in [[ ]].

Source: [[TiddlySnip - ConfigurationGuide|http://tiddlysnip.com/#ConfigurationGuide]]
This site is a ~TiddlyWiki!

~TiddlyWiki is a wiki packaged within a single html file, complete with all the content, the editing and saving functionality, search and tagging capabilities and much more. It can run locally from your hard drive (so it's great for taking notes or organising personal information) or on a server.

~TiddlyWiki is a single web page which contains not just content, but also the functionality needed to edit and save that content. Being a single web page makes it very portable, as it can easily be emailed or handed to somebody on a USB stick. It can also be accessed via the web in a conventional sense - as you likely did for this site.

~TiddlyWiki is very extensible; there are over 400 plugins developed by the ~TiddlyWiki community.
You can learn more about TiddlyWiki here:

Official ~TiddlyWiki site: http://www.tiddlywiki.com
Main ~TiddlyWiki developers site: http://www.tiddlywiki.org
~TiddlyWiki Google Group: http://groups.google.com/group/TiddlyWiki
~TiddlyWiki Developers Google Group: http://groups.google.com/group/TiddlyWikiDev

[[irc://irc.freenode.net/tiddlywiki|irc://irc.freenode.net/tiddlywiki]]
* http://groups.google.com/group/TiddlyWikiDev is the [[google groups page|http://groups.google.com/group/TiddlyWikiDev]]

~BenTrem's list of ~TiddlyWiki Resources
*[[Main TiddlyWiki site|http://www.tiddlywiki.com]] and [[Developers' site|http://www.tiddlywiki.org/wiki/TiddlyWeb]]
*[[TWFaq at TiddlySpot|http://twfaq.tiddlyspot.com/]]
*[[Julian Knight's references|http://knighjm.googlepages.com/knightnet-default-tw.html]]

*[[Google Group|http://groups.google.com/group/TiddlyWiki]]
*[[Developers Google Group|http://groups.google.com/group/TiddlyWikiDev]]

*[[Write-up at OsmoSoft|http://osmosoft.com/#TiddlyWiki]]
ripped from [[Giffmex.org/twfortherestofus.html|http://www.giffmex.org/twfortherestofus.html#[[Tips for speeding up performance on large TiddlyWikis]]]]

*''Disable the animations.'' It may be cute to have tiddlers open with cool animation, but the animation slows performance way down. Open the OptionsPanel and uncheck ~EnableAnimations.
*''Save less often.'' Uncheck 'Autosave' and 'Save backups', and save manually every few minutes instead of saving every single change.
*''Hide the growing tabbed lists in your SideBarTabs.'' Every time you create a new tiddler, TabAll and TabTimeline have to refresh to add the new tiddler's title. As the list of tiddlers gets longer, these tabs take longer to refresh, slowing down your ~TiddlyWiki. There are three ways I know of to hide these lists:
##The easiest way is to click on the More tab. The lists in More don't grow like the other lists. This should be a good enough solution for most users.
##You can use the ToggleRightSidebar plugin to hide the entire right hand sidebar of your ~TiddlyWiki screen. This plugin happens to be included in this tutorial.
##I don't necessarily recommend the following for newer users, but to remove the right hand sidebar tabs from view altogether, open PageTemplate and delete the following:
<!--{{{-->
	<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
<!--}}}-->
*''Michael Cimino offered this suggestion by e-mail:''
"...(1) add the following to the end of SidebarOptions: {{{<<slider chkSliderContents [[TabContents]] 'contents ยป' 'contents'>>}}}
(2) cut out the text from SidebarTabs and save it, leaving it blank.
(3) create a new tiddler TabContents and paste the text that used to be in SidebarTabs, which should be:
{{{<<tabs txtMainTab "Timeline" "Timeline" TabTimeline "All" "All tiddlers" TabAll "Tags" "All tags" TabTags "More" "More lists" TabMore>>}}}

Now, you can collapse that area of the Sidebar whenever you wish, and its state will be saved in a cookie! I hope this helps!"
| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |
| 28/06/2008 12:40:40 | BenTremblay | [[pardelib.html|file:///C:/buffer/tw/pardelib.html]] | [[store.php|http://bentrem.sycks.net/tw/store.php]] | . | [[pardelib.html | http://bentrem.sycks.net/tw/pardelib.html]] |  |
| 28/06/2008 12:41:09 | BenTremblay | [[pardelib.html|file:///C:/buffer/tw/pardelib.html]] | [[store.php|http://bentrem.sycks.net/tw/store.php]] | . | [[pardelib.html | http://bentrem.sycks.net/tw/pardelib.html]] |  | ok | ok |
| 28/06/2008 13:16:57 | BenTremblay | [[pardelib.html|file:///C:/buffer/tw/pardelib.html]] | [[store.php|http://bentrem.sycks.net/tw/store.php]] | . | [[pardelib.html | http://bentrem.sycks.net/tw/pardelib.html]] |  |
| 28/06/2008 13:17:27 | BenTremblay | [[pardelib.html|file:///C:/buffer/tw/pardelib.html]] | [[store.php|http://bentrem.sycks.net/tw/store.php]] | . | [[pardelib.html | http://bentrem.sycks.net/tw/pardelib.html]] |  | ok | ok |
| 29/06/2008 16:12:59 | BenTremblay | [[pardelib.html|file:///C:/buffer/tw/pardelib.html]] | [[|file:///C:/buffer/tw/]] | . | [[pardelib.html | file:///C:/buffer/tw/pardelib.html]] |  | failed |
| 29/06/2008 21:49:20 | BenTremblay | [[pardelib.html|file:///C:/buffer/tw/pardelib.html]] | [[store.php|http://bentrem.sycks.net/tw/store.php]] | . | [[pardelib.html | http://bentrem.sycks.net/tw/pardelib.html]] |  | ok |
| 29/06/2008 21:57:22 | BenTremblay | [[pardelib.html|file:///C:/buffer/tw/pardelib.html]] | [[store.php|http://bentrem.sycks.net/tw/store.php]] | . | [[pardelib.html | http://bentrem.sycks.net/tw/pardelib.html]] |  | ok |
| 29/06/2008 22:00:31 | BenTremblay | [[pardelib.html|file:///C:/buffer/tw/pardelib.html]] | [[store.php|http://bentrem.sycks.net/tw/store.php]] | . | [[pardelib.html | http://bentrem.sycks.net/tw/pardelib.html]] |  | ok |
| 29/06/2008 23:36:46 | BenTremblay | [[pardelib.html|file:///C:/buffer/tw/pardelib.html]] | [[store.php|http://bentrem.sycks.net/tw/store.php]] | . | [[pardelib.html | http://bentrem.sycks.net/tw/pardelib.html]] |  | ok |
| 10/07/2008 15:39:36 | BenTremblay | [[pardelib.html|file:///C:/buffer/tw/pardelib.html]] | [[store.php|http://bentrem.sycks.net/tw/store.php]] | . | [[pardelib.html | http://bentrem.sycks.net/tw/pardelib.html]] |  |
/***
|''Name:''|UploadPlugin|
|''Description:''|Save to web a TiddlyWiki|
|''Version:''|4.1.3|
|''Date:''|Feb 24, 2008|
|''Source:''|http://tiddlywiki.bidix.info/#UploadPlugin|
|''Documentation:''|http://tiddlywiki.bidix.info/#UploadPluginDoc|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0|
|''Requires:''|PasswordOptionPlugin|
***/
//{{{
version.extensions.UploadPlugin = {
	major: 4, minor: 1, revision: 3,
	date: new Date("Feb 24, 2008"),
	source: 'http://tiddlywiki.bidix.info/#UploadPlugin',
	author: 'BidiX (BidiX (at) bidix (dot) info',
	coreVersion: '2.2.0'
};

//
// Environment
//

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

//
// Upload Macro
//

config.macros.upload = {
// default values
	defaultBackupDir: '',	//no backup
	defaultStoreScript: "store.php",
	defaultToFilename: "index.html",
	defaultUploadDir: ".",
	authenticateUser: true	// UploadService Authenticate User
};

config.macros.upload.label = {
	promptOption: "Save and Upload this TiddlyWiki with UploadOptions",
	promptParamMacro: "Save and Upload this TiddlyWiki in %0",
	saveLabel: "save to web",
	saveToDisk: "save to disk",
	uploadLabel: "upload"
};

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

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

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

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

//
// uploadOptions Macro
//

config.macros.uploadOptions = {
	handler: function(place,macroName,params) {
		var wizard = new Wizard();
		wizard.createWizard(place,this.wizardTitle);
		wizard.addStep(this.step1Title,this.step1Html);
		var markList = wizard.getElement("markList");
		var listWrapper = document.createElement("div");
		markList.parentNode.insertBefore(listWrapper,markList);
		wizard.setValue("listWrapper",listWrapper);
		this.refreshOptions(listWrapper,false);
		var uploadCaption;
		if (document.location.toString().substr(0,4) == "http")
			uploadCaption = config.macros.upload.label.saveLabel;
		else
			uploadCaption = config.macros.upload.label.uploadLabel;

		wizard.setButtons([
				{caption: uploadCaption, tooltip: config.macros.upload.label.promptOption,
					onClick: config.macros.upload.action},
				{caption: this.cancelButton, tooltip: this.cancelButtonPrompt, onClick: this.onCancel}

			]);
	},
	options: [
		"txtUploadUserName",
		"pasUploadPassword",
		"txtUploadStoreUrl",
		"txtUploadDir",
		"txtUploadFilename",
		"txtUploadBackupDir",
		"chkUploadLog",
		"txtUploadLogMaxLine"
	],
	refreshOptions: function(listWrapper) {
		var opts = [];
		for(i=0; i<this.options.length; i++) {
			var opt = {};
			opts.push();
			opt.option = "";
			n = this.options[i];
			opt.name = n;
			opt.lowlight = !config.optionsDesc[n];
			opt.description = opt.lowlight ? this.unknownDescription : config.optionsDesc[n];
			opts.push(opt);
		}
		var listview = ListView.create(listWrapper,opts,this.listViewTemplate);
		for(n=0; n<opts.length; n++) {
			var type = opts[n].name.substr(0,3);
			var h = config.macros.option.types[type];
			if (h && h.create) {
				h.create(opts[n].colElements['option'],type,opts[n].name,opts[n].name,"no");
			}
		}

	},
	onCancel: function(e)
	{
		backstage.switchTab(null);
		return false;
	},

	wizardTitle: "Upload with options",
	step1Title: "These options are saved in cookies in your browser",
	step1Html: "<input type='hidden' name='markList'></input><br>",
	cancelButton: "Cancel",
	cancelButtonPrompt: "Cancel prompt",
	listViewTemplate: {
		columns: [
			{name: 'Description', field: 'description', title: "Description", type: 'WikiText'},
			{name: 'Option', field: 'option', title: "Option", type: 'String'},
			{name: 'Name', field: 'name', title: "Name", type: 'String'}
			],
		rowClasses: [
			{className: 'lowlight', field: 'lowlight'}
			]}
};

//
// upload functions
//

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

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

bidix.upload.uploadChanges = function(onlyIfDirty,tiddlers,storeUrl,toFilename,uploadDir,backupDir,username,password)
{
	var callback = function(status,uploadParams,original,url,xhr) {
		if (!status) {
			displayMessage(bidix.upload.messages.loadOriginalHttpPostError);
			return;
		}
		if (bidix.debugMode)
			alert(original.substr(0,500)+"\n...");
		// Locate the storeArea div's
		var posDiv = locateStoreArea(original);
		if((posDiv[0] == -1) || (posDiv[1] == -1)) {
			alert(config.messages.invalidFileError.format([localPath]));
			return;
		}
		bidix.upload.uploadRss(uploadParams,original,posDiv);
	};

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

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

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

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

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

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

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

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

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

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

//
// Utilities
//

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

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

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

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

//
// Initializations
//

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

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

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

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


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


//}}}

when creating a link using ''[''''['', it may open a new window depending on its settings. One can now override this behaviour by using a ''~'' at the begining of the link like
[[a link to google|~http://google.com]]

NB: this isn't working
!!ccTiddly Resources

[[ccTiddly at TiddlyWiki.org|http://tiddlywiki.org/wiki/CcTiddly]] and [[Sourceforge Homepage|http://cctiddly.sourceforge.net/]] (see [[Requirements]])

[[ccTiddly hosting at OsmoSoft|http://wiki.osmosoft.com/alpha]]

[[Google user group|http://groups.google.com/group/ccTiddly]]
[[SourceForge Forum|http://sourceforge.net/forum/forum.php?forum_id=523746]]

Blogs: [[Simon's blog|http://wordpress.com/tag/cctiddly/]] and [[Matthew |http://coolcold.wordpress.com/category/cctiddly/]].
!!!!Welcome to ccTiddly 1.6 alpha!
This site is created and presented with ccTiddlyWiki ... and ''ccTiddly'' is a server-side implementation of TiddlyWiki created by [[Osmosoft]] to provide a centralised location for teams looking for a collaboration platform.

You can use this tool to create multiple editions of ~TiddlyWiki (we call each edition a 'workspace'), which can be seen and edited by whomever you wish. If you don't already have an account please [[register|Register]] for one.  (Note that user registration is a new feature and still requires some work.)

If you have any problems with this deployment please contact simon@osmosoft.com. Feedback is welcomed!
<!--{{{-->
<div class="toolbar" macro="toolbar closeTiddler closeOthers"></div>
<div class="title" macro="view title"></div>
<div class="subtitle"></div>
<div class="viewer" macro="view text wikified"></div>
<div class="tagClear"></div>
<!--}}}-->
<?php
/***
! User settings
Edit these lines according to your need
***/
//{{{
$AUTHENTICATE_USER = true;	// true | false
$USERS = array(
	'BenTremblay'=>'benztiddly',
	'UserName2'=>'Password2',
	'UserName3'=>'Password3'); // set usernames and strong passwords
$DEBUG = false;				// true | false
$CLEAN_BACKUP = true; 		// during backuping a file, remove overmuch backups
$FOLD_JS = true; 			// if javascript files have been expanded during download the fold them
error_reporting(E_ERROR | E_WARNING | E_PARSE);
//}}}
/***
!Code
No change needed under
***/
//{{{

/***
 * store.php - upload a file in this directory
 * version :1.6.1 - 2007/08/01 - BidiX@BidiX.info
 *
 * see :
 *	http://tiddlywiki.bidi.info/#UploadPlugin for usage
 *	http://www.php.net/manual/en/features.file-upload.php
 *		for details on uploading files
 * usage :
 *	POST
 *		UploadPlugin[backupDir=<backupdir>;user=<user>;password=<password>;uploadir=<uploaddir>;[debug=1];;]
 *		userfile <file>
 *	GET
 *
 * each external javascript file included by download.php is change by a reference (src=...)
 *
 * Revision history
 * V1.6.1 - 2007/08/01
 * Enhancement: Add javascript folding
 * V1.6.0 - 2007/05/17
 * Enhancement: Add backup management
 * V1.5.2 - 2007/02/13
 * Enhancement: Add optional debug option in client parameters
 * V1.5.1 - 2007/02/01
 * Enhancement: Check value of file_uploads in php.ini. Thanks to Didier Corbiรจre
 * V1.5.0 - 2007/01/15
 * Correct: a bug in moving uploadFile in uploadDir thanks to DaniGutiรฉrrez for reporting
 * Refactoring
 * V 1.4.3 - 2006/10/17
 * Test if $filename.lock exists for GroupAuthoring compatibility
 * return mtime, destfile and backupfile after the message line
 * V 1.4.2 - 2006/10/12
 *  add error_reporting(E_PARSE);
 * v 1.4.1 - 2006/03/15
 *	add chmo 0664 on the uploadedFile
 * v 1.4 - 2006/02/23
 * 	add uploaddir option :  a path for the uploaded file relative to the current directory
 *	backupdir is a relative path
 *	make recusively directories if necessary for backupDir and uploadDir
 * v 1.3 - 2006/02/17
 *	presence and value of user are checked with $USERS Array (thanks to PauloSoares)
 * v 1.2 - 2006/02/12
  *	POST
 *		UploadPlugin[backupDir=<backupdir>;user=<user>;password=<password>;]
 *		userfile <file>
*	if $AUTHENTICATE_USER
 *		presence and value of user and password are checked with
 *		$USER and $PASSWORD
 * v 1.1 - 2005/12/23
 *	POST  UploadPlugin[backupDir=<backupdir>]  userfile <file>
 * v 1.0 - 2005/12/12
 *	POST userfile <file>
 *
 * Copyright (c) BidiX@BidiX.info 2005-2007
 ***/
//}}}

//{{{

if ($_SERVER['REQUEST_METHOD'] == 'GET') {
	/*
	 * GET Request
	 */
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
		<title>BidiX.info - TiddlyWiki UploadPlugin - Store script</title>
	</head>
	<body>
		<p>
		<p>store.php V 1.6.1
		<p>BidiX@BidiX.info
		<p>&nbsp;</p>
		<p>&nbsp;</p>
		<p>&nbsp;</p>
		<p align="center">This page is designed to upload a <a href="http://www.tiddlywiki.com/">TiddlyWiki<a>.</p>
		<p align="center">for details see : <a href="http://TiddlyWiki.bidix.info/#HowToUpload">TiddlyWiki.bidix.info/#HowToUpload<a>.</p>
	</body>
</html>
<?php
exit;
}

/*
 * POST Request
 */

// Recursive mkdir
function mkdirs($dir) {
	if( is_null($dir) || $dir === "" ){
		return false;
	}
	if( is_dir($dir) || $dir === "/" ){
		return true;
	}
	if( mkdirs(dirname($dir)) ){
		return mkdir($dir);
	}
	return false;
}

function toExit() {
	global $DEBUG, $filename, $backupFilename, $options;
	if ($DEBUG) {
		echo ("\nHere is some debugging info : \n");
		echo("\$filename : $filename \n");
		echo("\$backupFilename : $backupFilename \n");
		print ("\$_FILES : \n");
		print_r($_FILES);
		print ("\$options : \n");
		print_r($options);
}
exit;
}

function ParseTWFileDate($s) {
	// parse date element
	preg_match ( '/^(\d\d\d\d)(\d\d)(\d\d)\.(\d\d)(\d\d)(\d\d)/', $s , $m );
	// make a date object
	$d = mktime($m[4], $m[5], $m[6], $m[2], $m[3], $m[1]);
	// get the week number
	$w = date("W",$d);

	return array(
		'year' => $m[1],
		'mon' => $m[2],
		'mday' => $m[3],
		'hours' => $m[4],
		'minutes' => $m[5],
		'seconds' => $m[6],
		'week' => $w);
}

function cleanFiles($dirname, $prefix) {
	$now = getdate();
	$now['week'] = date("W");

	$hours = Array();
	$mday = Array();
	$year = Array();

	$toDelete = Array();

	// need files recent first
	$files = Array();
	($dir = opendir($dirname)) || die ("can't open dir '$dirname'");
	while (false !== ($file = readdir($dir))) {
		if (preg_match("/^$prefix/", $file))
        array_push($files, $file);
    }
	$files = array_reverse($files);

	// decides for each file
	foreach ($files as $file) {
		$fileTime = ParseTWFileDate(substr($file,strpos($file, '.')+1,strrpos($file,'.') - strpos($file, '.') -1));
		if (($now['year'] == $fileTime['year']) &&
			($now['mon'] == $fileTime['mon']) &&
			($now['mday'] == $fileTime['mday']) &&
			($now['hours'] == $fileTime['hours']))
				continue;
		elseif (($now['year'] == $fileTime['year']) &&
			($now['mon'] == $fileTime['mon']) &&
			($now['mday'] == $fileTime['mday'])) {
				if (isset($hours[$fileTime['hours']]))
					array_push($toDelete, $file);
				else
					$hours[$fileTime['hours']] = true;
			}
		elseif 	(($now['year'] == $fileTime['year']) &&
			($now['mon'] == $fileTime['mon'])) {
				if (isset($mday[$fileTime['mday']]))
					array_push($toDelete, $file);
				else
					$mday[$fileTime['mday']] = true;
			}
		else {
			if (isset($year[$fileTime['year']][$fileTime['mon']]))
				array_push($toDelete, $file);
			else
				$year[$fileTime['year']][$fileTime['mon']] = true;
		}
	}
	return $toDelete;
}

function replaceJSContentIn($content) {
	if (preg_match ("/(.*?)<!--DOWNLOAD-INSERT-FILE:\"(.*?)\"--><script\s+type=\"text\/javascript\">(.*)/ms", $content,$matches)) {
		$front = $matches[1];
		$js = $matches[2];
		$tail = $matches[3];
		if (preg_match ("/<\/script>(.*)/ms", $tail,$matches2)) {
			$tail = $matches2[1];
		}
		$jsContent = "<script type=\"text/javascript\" src=\"$js\"></script>";
		$tail = replaceJSContentIn($tail);
		return($front.$jsContent.$tail);
	}
	else
		return $content;
}

// Check if file_uploads is active in php config
if (ini_get('file_uploads') != '1') {
   echo "Error : File upload is not active in php.ini\n";
   toExit();
}

// var definitions
$uploadDir = './';
$uploadDirError = false;
$backupError = false;
$optionStr = $_POST['UploadPlugin'];
$optionArr=explode(';',$optionStr);
$options = array();
$backupFilename = '';
$filename = $_FILES['userfile']['name'];
$destfile = $filename;

// get options
foreach($optionArr as $o) {
	list($key, $value) = split('=', $o);
	$options[$key] = $value;
}

// debug activated by client
if ($options['debug'] == 1) {
	$DEBUG = true;
}

// authenticate User
if (($AUTHENTICATE_USER)
	&& ((!$options['user']) || (!$options['password']) || ($USERS[$options['user']] != $options['password']))) {
	echo "Error : UserName or Password do not match \n";
	echo "UserName : [".$options['user']. "] Password : [". $options['password'] . "]\n";
	toExit();
}



// make uploadDir
if ($options['uploaddir']) {
	$uploadDir = $options['uploaddir'];
	// path control for uploadDir
    if (!(strpos($uploadDir, "../") === false)) {
        echo "Error: directory to upload specifies a parent folder";
        toExit();
	}
	if (! is_dir($uploadDir)) {
		mkdirs($uploadDir);
	}
	if (! is_dir($uploadDir)) {
		echo "UploadDirError : $uploadDirError - File NOT uploaded !\n";
		toExit();
	}
	if ($uploadDir{strlen($uploadDir)-1} != '/') {
		$uploadDir = $uploadDir . '/';
	}
}
$destfile = $uploadDir . $filename;

// backup existing file
if (file_exists($destfile) && ($options['backupDir'])) {
	if (! is_dir($options['backupDir'])) {
		mkdirs($options['backupDir']);
		if (! is_dir($options['backupDir'])) {
			$backupError = "backup mkdir error";
		}
	}
	$backupFilename = $options['backupDir'].'/'.substr($filename, 0, strrpos($filename, '.'))
				.date('.Ymd.His').substr($filename,strrpos($filename,'.'));
	rename($destfile, $backupFilename) or ($backupError = "rename error");
	// remove overmuch backup
	if ($CLEAN_BACKUP) {
		$toDelete = cleanFiles($options['backupDir'], substr($filename, 0, strrpos($filename, '.')));
		foreach ($toDelete as $file) {
			$f = $options['backupDir'].'/'.$file;
			if($DEBUG) {
				echo "delete : ".$options['backupDir'].'/'.$file."\n";
			}
			unlink($options['backupDir'].'/'.$file);
		}
	}
}

// move uploaded file to uploadDir
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $destfile)) {
	if ($FOLD_JS) {
		// rewrite the file to replace JS content
		$fileContent = file_get_contents ($destfile);
		$fileContent = replaceJSContentIn($fileContent);
		if (!$handle = fopen($destfile, 'w')) {
	         echo "Cannot open file ($destfile)";
	         exit;
	    }
	    if (fwrite($handle, $fileContent) === FALSE) {
	        echo "Cannot write to file ($destfile)";
	        exit;
	    }
	    fclose($handle);
	}

	chmod($destfile, 0644);
	if($DEBUG) {
		echo "Debug mode \n\n";
	}
	if (!$backupError) {
		echo "0 - File successfully loaded in " .$destfile. "\n";
	} else {
		echo "BackupError : $backupError - File successfully loaded in " .$destfile. "\n";
	}
	echo("destfile:$destfile \n");
	if (($backupFilename) && (!$backupError)) {
		echo "backupfile:$backupFilename\n";
	}
	$mtime = filemtime($destfile);
	echo("mtime:$mtime");
}
else {
	echo "Error : " . $_FILES['error']." - File NOT uploaded !\n";

}
toExit();
//}}}
?>
Hope hope hope
So this is contents